<commit_before>var glide = glide || {};

/******************************************************************************
 *** Slideshow Param Defaults ***
 *****************************************************************************/
glide.param = {};
glide.param.name = "Slideshow";
glide.param.showDuration = 5000;
glide.param.animDuration = 2000;
glide.param.autoForward = true;
glide.param.bgColor = "#1e2426";
glide.param.animation = "NONE";
glide.param.picsJsonURI = "pics.json";   // pic catalog URI

/******************************************************************************
 *** Internal Vars ***
 *****************************************************************************/
glide.showTimeoutId = null;
glide.animIntervalId = null;
glide.lastAnimation = null;
glide.animations = {};

/******************************************************************************
 *** Helper Functions ***
 *****************************************************************************/
glide.isScalar = function (obj) {
    return (/string|number|boolean/).test(typeof obj);
};

glide.randSplice = function(array) {
    var i = Math.floor(Math.random() * array.length);
    var removed = array.splice(i, 1);
    return removed;
};

glide.randKey = function(obj) {
    var keys = Object.keys(obj);
    var i = Math.floor(Math.random() * keys.length);
    return keys[i];
};

/******************************************************************************
 *** Glide Functions ***
 *****************************************************************************/
glide.nextPic = function () {
    if (glide.i == glide.max) {
        glide.i = 0;
    } else {
        glide.i++;
    }
    return [{"key": glide.i, "src": glide.dataset.pics[glide.i]}];
};

glide.prevPic = function () {
    if (glide.i === 0) {
        glide.i = glide.max;
    } else {
        glide.i--;
    }
    return [{"key": glide.i, "src": glide.dataset.pics[glide.i]}];
};

glide.key = function (d) {
    return d.key;
};

glide.calcImgPosAndDims = function (img) {

    var height, width, x, y;

    if (img !== null) {  // new image
        glide.naturalHeight = img.naturalHeight;
        glide.naturalWidth = img.naturalWidth;
    }

    var wh = window.innerHeight;
    var ww = window.innerWidth;

    if (glide.naturalHeight <= wh && glide.naturalWidth <= ww) {  // image fits
        height = glide.naturalHeight;
        width = glide.naturalWidth;
    } else {    // scale
        var widthScale = ww / glide.naturalWidth;
        var heightScale = wh / glide.naturalHeight;
        var scale = Math.min(widthScale, heightScale);
        width = Math.round(glide.naturalWidth * scale);
        height = Math.round(glide.naturalHeight * scale);
    }

    x = (ww - width) / 2;
    y = (wh - height) / 2;

    return { "width": width,
             "height": height,
             "x": x,
             "y": y };
};

glide.updateParams = function () {
    Object.keys(glide.param).forEach(function(key, index) {
        if (glide.dataset.hasOwnProperty(key)) {
            var val = glide.dataset[key];
            if (glide.isScalar(val)) {
                console.log("Using custom slideshow param '" + key + "' : " + val);
                glide.param[key] = val;
            } else {
                console.log("Ignoring invalid slideshow param '" + key + "'.");
            }
        }
    });
};

glide.getRandAnimation = function () {
    var anim = glide.lastAnimation;
    while (anim == glide.lastAnimation) {
        anim = glide.randKey(glide.animations);
    }
    glide.lastAnimation = anim;
    return anim;
};

glide.setupCanvas = function () {
    d3.select("title")
      .text(glide.param.name);

    glide.svg = d3.select("body")
                  .attr("style", "background-color: " + glide.param.bgColor)
                  .append("svg")
                  .attr("width", window.innerWidth)
                  .attr("height", window.innerHeight)
                  .attr("id", "canvas");
};

glide.nextSlide = function () {
    // get pic...
    var nextPicSpec = glide.nextPic();

    // show slide...
    glide.showSlide(nextPicSpec);
};

glide.prevSlide = function () {
    // get pic...
    var nextPicSpec = glide.prevPic();

    // show slide...
    glide.showSlide(nextPicSpec);
};

glide.showSlide = function (nextPicSpec) {

    // cancel old timeout
    if (glide.param.autoForward
        && glide.showTimeoutId !== null) {
        clearTimeout(glide.showTimeoutId);
    }

    // select all image objects
    var pics = glide.svg.selectAll("image")
                        .data(nextPicSpec, glide.key);

    // show next pic using random or selected animation
    if (glide.param.animation == "RANDOM") {
        var anim = glide.getRandAnimation();
        glide.animations[anim](nextPicSpec, pics);
    } else if (glide.animations.hasOwnProperty(glide.param.animation)) {
        glide.animations[glide.param.animation](nextPicSpec, pics);
    } else {    // no animation
        glide.aniNone(nextPicSpec, pics);
    }
};

glide.picId = function (d) { return "pic_" + d.key; };

glide.picSrc = function (d) { return d.src; };

glide.triggerNextSlide = function (millis) {
    if (glide.param.autoForward) {
        glide.showTimeoutId = setTimeout(glide.nextSlide, millis);
    }
};

glide.aniNotImplemented = function (nextPicSpec, pics) {
    console.log("This animation is not yet implemented!");
    glide.aniNone(nextPicSpec, pics);
};

glide.aniNone = function (nextPicSpec, pics) {
    // (1) remove old pic (if exists)
    pics.exit()
        .remove();

    // (2) load new pic
    var img = new Image();
    img.onload = function () {
        var posAndDims = glide.calcImgPosAndDims(img);
        pics.enter()
           .append("image")
           .attr("xlink:href", glide.picSrc)
           .attr("id", glide.picId)
           .attr("width", posAndDims.width)
           .attr("height", posAndDims.height)
           .attr("x", posAndDims.x)
           .attr("y", posAndDims.y);

        glide.triggerNextSlide(glide.param.showDuration);
    };
    img.src = nextPicSpec[0].src;
};

glide.aniZoomIn = function (nextPicSpec, pics) {
    // (1) remove old pic (if exists)
    pics.exit()
        .remove();

    // (2) load new pic
    var img = new Image();
    img.onload = function () {
        var posAndDims = glide.calcImgPosAndDims(img);
        pics.enter()
           .append("image")
           .attr("xlink:href", glide.picSrc)
           .attr("id", glide.picId)
           .attr("width", 1)
           .attr("height", 1)
           .attr("x", window.innerWidth / 2)
           .attr("y", window.innerHeight / 2)
           .transition()
           .duration(glide.param.animDuration)
           .attr("width", posAndDims.width)
           .attr("height", posAndDims.height)
           .attr("x", posAndDims.x)
           .attr("y", posAndDims.y);

        glide.triggerNextSlide(glide.param.animDuration
            + glide.param.showDuration);
    };
    img.src = nextPicSpec[0].src;
};

glide.aniSlideRight = function (nextPicSpec, pics) {
    // (1) remove old pic (if exists)
    pics.exit()
        .transition()
        .duration(glide.param.animDuration)
        .attr("x", window.innerWidth)
        .remove();

    // (2) load new pic
    var img = new Image();
    img.onload = function () {
        var posAndDims = glide.calcImgPosAndDims(img);
        pics.enter()
            .append("image")
            .attr("xlink:href", glide.picSrc)
            .attr("id", glide.picId)
            .attr("width", posAndDims.width)
            .attr("height", posAndDims.height)
            .attr("x", 0 - posAndDims.width)
            .attr("y", posAndDims.y)
            .transition()
            .duration(glide.param.animDuration)
            .attr("x", posAndDims.x);

            glide.triggerNextSlide(glide.param.animDuration
                + glide.param.showDuration);
    };
    img.src = nextPicSpec[0].src;
};

glide.aniSlideTop = function (nextPicSpec, pics) {
    // (1) remove old pic (if exists)
    pics.exit()
        .transition()
        .duration(glide.param.animDuration)
        .attr("y", window.innerHeight)
        .remove();

    // (2) load new pic
    var img = new Image();
    img.onload = function () {
        var posAndDims = glide.calcImgPosAndDims(img);
        pics.enter()
            .append("image")
            .attr("xlink:href", glide.picSrc)
            .attr("id", glide.picId)
            .attr("width", posAndDims.width)
            .attr("height", posAndDims.height)
            .attr("x", posAndDims.x)
            .attr("y", 0 - posAndDims.height)
            .transition()
            .duration(glide.param.animDuration)
            .attr("y", posAndDims.y);

        glide.triggerNextSlide(glide.param.animDuration
            + glide.param.showDuration);
    };
    img.src = nextPicSpec[0].src;
};

glide.getSquareDims = function (picPosAndDims) {

    var squaresPerRow = 8;
    var positions = [];
    var sqWidth, numSqWide, numSqHigh, planeWidth, planeHeight;

    if (picPosAndDims.width > picPosAndDims.height) {
        // fill complete width with squares
        sqWidth = Math.ceil(picPosAndDims.width / squaresPerRow);
        numSqWide = squaresPerRow;
        numSqHigh = Math.ceil(picPosAndDims.height / sqWidth);
    } else {
        // fill complete height with squares
        sqWidth = Math.ceil(picPosAndDims.height / squaresPerRow);
        numSqHigh = squaresPerRow;
        numSqWide = Math.ceil(picPosAndDims.width / sqWidth);
    }

    planeWidth = sqWidth * numSqWide;
    planeHeight = sqWidth * numSqHigh;

    // calculate positions
    var startX = picPosAndDims.x - ((planeWidth - picPosAndDims.width) / 2);
    var startY = picPosAndDims.y - ((planeHeight - picPosAndDims.height) / 2);
    var count = 0;
    var xPos = startX;
    var yPos = startY;
    for (var i=1; i <= numSqHigh; i++) {
        for (var j=1; j <= numSqWide; j++) {
            count++;
            positions.push({ key: count, x: xPos, y: yPos });
            xPos += sqWidth;
        }
        yPos += sqWidth;
        xPos = startX;
    }

    return {
        width: sqWidth,
        squares: positions
    };
};

glide.aniMemory = function (nextPicSpec, pics) {
    // (0) remove old squares (if existing) --> BUG! PUT TO EXIT HANDLER!
    glide.svg.selectAll("rect")
             .data([], glide.key)
             .exit()
             .remove();

    // (1) remove old pic (if exists)
    pics.exit()
        .remove();

    // (2) load new pic
    var img = new Image();
    img.onload = function () {
        var posAndDims = glide.calcImgPosAndDims(img);
        pics.enter()
           .append("image")
           .attr("xlink:href", glide.picSrc)
           .attr("id", glide.picId)
           .attr("width", posAndDims.width)
           .attr("height", posAndDims.height)
           .attr("x", posAndDims.x)
           .attr("y", posAndDims.y);

       // (3) immediately draw squares
       var squareDims = glide.getSquareDims(posAndDims);
       var squareData = squareDims.squares;
       var squareShowTime = 100;
       var animDuration = squareData.length * squareShowTime;
       glide.svg.selectAll("rect")
                .data(squareData, glide.key)
                .enter()
                .append("rect")
                .attr("width", squareDims.width)
                .attr("height", squareDims.width)
                .attr("x", function (d) { return d.x; })
                .attr("y", function (d) { return d.y; })
                .attr("id", function (d) { return "sq_" + d.key; })
                .attr("stroke", glide.param.bgColor)
                .attr("fill", glide.param.bgColor);

       // (4) remove squares (one by one)
       glide.animIntervalId = setInterval(function () {
               if ( squareData.length > 0 ) {
                   glide.randSplice(squareData);
                   glide.svg.selectAll("rect")
                         .data(squareData, glide.key)
                         .exit()
                         .remove();
               } else {
                   clearInterval(glide.animIntervalId);
                   glide.animIntervalId = null;
               }
       },
       squareShowTime);

       glide.triggerNextSlide(animDuration + glide.param.showDuration);
    };
    img.src = nextPicSpec[0].src;
};

glide.registerAnimations = function () {
    glide.animations.ZOOM_IN = glide.aniZoomIn;
    glide.animations.SLIDE_RIGHT = glide.aniSlideRight;
    glide.animations.SLIDE_TOP = glide.aniSlideTop;
    glide.animations.MEMORY = glide.aniMemory;
};

glide.startShow = function (data) {
    glide.dataset = data;
    glide.max = glide.dataset.pics.length - 1;
    glide.i = -1;
    glide.updateParams();
    glide.registerAnimations();
    glide.setupCanvas();
    glide.nextSlide();
};

glide.stopShow = function () {
    if (glide.showTimeoutId !== null) {
        clearTimeout(glide.showTimeoutId);
        glide.showTimeoutId = null;
    }
};

/******************************************************************************
 *** Event Handler ***
 *****************************************************************************/
 // On click on body:
d3.select("body").on("click", function(e) {
    glide.nextSlide();
});

// On key press:
document.onkeypress = function (e) {
    e = e || window.event;
    switch (e.key) {
    case " ":   // Space
        glide.nextSlide();
      break;
    case "Backspace":
      glide.prevSlide();
      break;
    case "ArrowDown":
      glide.prevSlide();
      break;
    case "ArrowUp":
      glide.nextSlide();
      break;
    case "ArrowLeft":
      glide.prevSlide();
      break;
    case "ArrowRight":
      glide.nextSlide();
      break;
    case "Enter":
      glide.nextSlide();
      break;
    case "Escape":
      glide.stopShow();
      break;
    default:
      return;
  }
};

// On window resize:
window.onresize = function(e) {

    // resize canvas
    glide.svg.attr("width", window.innerWidth)
             .attr("height", window.innerHeight);

    // resize pic
    var posAndDims = glide.calcImgPosAndDims();
    glide.svg.selectAll("image")
           .attr("width", posAndDims.width)
           .attr("height", posAndDims.height)
           .attr("x", posAndDims.x)
           .attr("y", posAndDims.y);
};

// On page load:
d3.json(glide.param.picsJsonURI, function(data) {
    glide.startShow(data);
});
<commit_msg>fixed cancelling animations for MEMORY animation<commit_after>var glide = glide || {};

/******************************************************************************
 *** Slideshow Param Defaults ***
 *****************************************************************************/
glide.param = {};
glide.param.name = "Slideshow";
glide.param.showDuration = 5000;
glide.param.animDuration = 2000;
glide.param.autoForward = true;
glide.param.bgColor = "#1e2426";
glide.param.animation = "NONE";
glide.param.picsJsonURI = "pics.json";   // pic catalog URI

/******************************************************************************
 *** Internal Vars ***
 *****************************************************************************/
glide.showTimeoutId = null;
glide.lastAnimation = null;
glide.animIntervalId = null;
glide.cancelAnimation = null;
glide.animations = {};

/******************************************************************************
 *** Helper Functions ***
 *****************************************************************************/
glide.isScalar = function (obj) {
    return (/string|number|boolean/).test(typeof obj);
};

glide.randSplice = function(array) {
    var i = Math.floor(Math.random() * array.length);
    var removed = array.splice(i, 1);
    return removed;
};

glide.randKey = function(obj) {
    var keys = Object.keys(obj);
    var i = Math.floor(Math.random() * keys.length);
    return keys[i];
};

/******************************************************************************
 *** Glide Functions ***
 *****************************************************************************/
glide.nextPic = function () {
    if (glide.i == glide.max) {
        glide.i = 0;
    } else {
        glide.i++;
    }
    return [{"key": glide.i, "src": glide.dataset.pics[glide.i]}];
};

glide.prevPic = function () {
    if (glide.i === 0) {
        glide.i = glide.max;
    } else {
        glide.i--;
    }
    return [{"key": glide.i, "src": glide.dataset.pics[glide.i]}];
};

glide.key = function (d) {
    return d.key;
};

glide.calcImgPosAndDims = function (img) {

    var height, width, x, y;

    if (img !== null) {  // new image
        glide.naturalHeight = img.naturalHeight;
        glide.naturalWidth = img.naturalWidth;
    }

    var wh = window.innerHeight;
    var ww = window.innerWidth;

    if (glide.naturalHeight <= wh && glide.naturalWidth <= ww) {  // image fits
        height = glide.naturalHeight;
        width = glide.naturalWidth;
    } else {    // scale
        var widthScale = ww / glide.naturalWidth;
        var heightScale = wh / glide.naturalHeight;
        var scale = Math.min(widthScale, heightScale);
        width = Math.round(glide.naturalWidth * scale);
        height = Math.round(glide.naturalHeight * scale);
    }

    x = (ww - width) / 2;
    y = (wh - height) / 2;

    return { "width": width,
             "height": height,
             "x": x,
             "y": y };
};

glide.updateParams = function () {
    Object.keys(glide.param).forEach(function(key, index) {
        if (glide.dataset.hasOwnProperty(key)) {
            var val = glide.dataset[key];
            if (glide.isScalar(val)) {
                console.log("Using custom slideshow param '" + key + "' : " + val);
                glide.param[key] = val;
            } else {
                console.log("Ignoring invalid slideshow param '" + key + "'.");
            }
        }
    });
};

glide.getRandAnimation = function () {
    var anim = glide.lastAnimation;
    while (anim == glide.lastAnimation) {
        anim = glide.randKey(glide.animations);
    }
    glide.lastAnimation = anim;
    return anim;
};

glide.setupCanvas = function () {
    d3.select("title")
      .text(glide.param.name);

    glide.svg = d3.select("body")
                  .attr("style", "background-color: " + glide.param.bgColor)
                  .append("svg")
                  .attr("width", window.innerWidth)
                  .attr("height", window.innerHeight)
                  .attr("id", "canvas");
};

glide.nextSlide = function () {
    // get pic...
    var nextPicSpec = glide.nextPic();

    // show slide...
    glide.showSlide(nextPicSpec);
};

glide.prevSlide = function () {
    // get pic...
    var nextPicSpec = glide.prevPic();

    // show slide...
    glide.showSlide(nextPicSpec);
};

glide.showSlide = function (nextPicSpec) {

    // cancel old timeout
    if (glide.param.autoForward
        && glide.showTimeoutId !== null) {
        clearTimeout(glide.showTimeoutId);
    }

    // cancel old animation
    if (glide.cancelAnimation !== null) {
        glide.cancelAnimation();
    }

    // select all image objects
    var pics = glide.svg.selectAll("image")
                        .data(nextPicSpec, glide.key);

    // show next pic using random or selected animation
    if (glide.param.animation == "RANDOM") {
        var anim = glide.getRandAnimation();
        glide.animations[anim](nextPicSpec, pics);
    } else if (glide.animations.hasOwnProperty(glide.param.animation)) {
        glide.animations[glide.param.animation](nextPicSpec, pics);
    } else {    // no animation
        glide.aniNone(nextPicSpec, pics);
    }
};

glide.picId = function (d) { return "pic_" + d.key; };

glide.picSrc = function (d) { return d.src; };

glide.triggerNextSlide = function (millis) {
    if (glide.param.autoForward) {
        glide.showTimeoutId = setTimeout(glide.nextSlide, millis);
    }
};

glide.aniNotImplemented = function (nextPicSpec, pics) {
    console.log("This animation is not yet implemented!");
    glide.aniNone(nextPicSpec, pics);
};

glide.aniNone = function (nextPicSpec, pics) {
    // (1) remove old pic (if exists)
    pics.exit()
        .remove();

    // (2) load new pic
    var img = new Image();
    img.onload = function () {
        var posAndDims = glide.calcImgPosAndDims(img);
        pics.enter()
           .append("image")
           .attr("xlink:href", glide.picSrc)
           .attr("id", glide.picId)
           .attr("width", posAndDims.width)
           .attr("height", posAndDims.height)
           .attr("x", posAndDims.x)
           .attr("y", posAndDims.y);

        glide.triggerNextSlide(glide.param.showDuration);
    };
    img.src = nextPicSpec[0].src;
};

glide.aniZoomIn = function (nextPicSpec, pics) {
    // (1) remove old pic (if exists)
    pics.exit()
        .remove();

    // (2) load new pic
    var img = new Image();
    img.onload = function () {
        var posAndDims = glide.calcImgPosAndDims(img);
        pics.enter()
           .append("image")
           .attr("xlink:href", glide.picSrc)
           .attr("id", glide.picId)
           .attr("width", 1)
           .attr("height", 1)
           .attr("x", window.innerWidth / 2)
           .attr("y", window.innerHeight / 2)
           .transition()
           .duration(glide.param.animDuration)
           .attr("width", posAndDims.width)
           .attr("height", posAndDims.height)
           .attr("x", posAndDims.x)
           .attr("y", posAndDims.y);

        glide.triggerNextSlide(glide.param.animDuration
            + glide.param.showDuration);
    };
    img.src = nextPicSpec[0].src;
};

glide.aniSlideRight = function (nextPicSpec, pics) {
    // (1) remove old pic (if exists)
    pics.exit()
        .transition()
        .duration(glide.param.animDuration)
        .attr("x", window.innerWidth)
        .remove();

    // (2) load new pic
    var img = new Image();
    img.onload = function () {
        var posAndDims = glide.calcImgPosAndDims(img);
        pics.enter()
            .append("image")
            .attr("xlink:href", glide.picSrc)
            .attr("id", glide.picId)
            .attr("width", posAndDims.width)
            .attr("height", posAndDims.height)
            .attr("x", 0 - posAndDims.width)
            .attr("y", posAndDims.y)
            .transition()
            .duration(glide.param.animDuration)
            .attr("x", posAndDims.x);

            glide.triggerNextSlide(glide.param.animDuration
                + glide.param.showDuration);
    };
    img.src = nextPicSpec[0].src;
};

glide.aniSlideTop = function (nextPicSpec, pics) {
    // (1) remove old pic (if exists)
    pics.exit()
        .transition()
        .duration(glide.param.animDuration)
        .attr("y", window.innerHeight)
        .remove();

    // (2) load new pic
    var img = new Image();
    img.onload = function () {
        var posAndDims = glide.calcImgPosAndDims(img);
        pics.enter()
            .append("image")
            .attr("xlink:href", glide.picSrc)
            .attr("id", glide.picId)
            .attr("width", posAndDims.width)
            .attr("height", posAndDims.height)
            .attr("x", posAndDims.x)
            .attr("y", 0 - posAndDims.height)
            .transition()
            .duration(glide.param.animDuration)
            .attr("y", posAndDims.y);

        glide.triggerNextSlide(glide.param.animDuration
            + glide.param.showDuration);
    };
    img.src = nextPicSpec[0].src;
};

glide.getSquareDims = function (picPosAndDims) {

    var squaresPerRow = 8;
    var positions = [];
    var sqWidth, numSqWide, numSqHigh, planeWidth, planeHeight;

    if (picPosAndDims.width > picPosAndDims.height) {
        // fill complete width with squares
        sqWidth = Math.ceil(picPosAndDims.width / squaresPerRow);
        numSqWide = squaresPerRow;
        numSqHigh = Math.ceil(picPosAndDims.height / sqWidth);
    } else {
        // fill complete height with squares
        sqWidth = Math.ceil(picPosAndDims.height / squaresPerRow);
        numSqHigh = squaresPerRow;
        numSqWide = Math.ceil(picPosAndDims.width / sqWidth);
    }

    planeWidth = sqWidth * numSqWide;
    planeHeight = sqWidth * numSqHigh;

    // calculate positions
    var startX = picPosAndDims.x - ((planeWidth - picPosAndDims.width) / 2);
    var startY = picPosAndDims.y - ((planeHeight - picPosAndDims.height) / 2);
    var count = 0;
    var xPos = startX;
    var yPos = startY;
    for (var i=1; i <= numSqHigh; i++) {
        for (var j=1; j <= numSqWide; j++) {
            count++;
            positions.push({ key: count, x: xPos, y: yPos });
            xPos += sqWidth;
        }
        yPos += sqWidth;
        xPos = startX;
    }

    return {
        width: sqWidth,
        squares: positions
    };
};

glide.aniMemory = function (nextPicSpec, pics) {
    // (1) remove old pic (if exists)
    pics.exit()
        .remove();

    // (2) load new pic
    var img = new Image();
    img.onload = function () {
        var posAndDims = glide.calcImgPosAndDims(img);
        pics.enter()
           .append("image")
           .attr("xlink:href", glide.picSrc)
           .attr("id", glide.picId)
           .attr("width", posAndDims.width)
           .attr("height", posAndDims.height)
           .attr("x", posAndDims.x)
           .attr("y", posAndDims.y);

       // (3) immediately draw squares
       var squareDims = glide.getSquareDims(posAndDims);
       var squareData = squareDims.squares;
       var squareShowTime = 100;
       var animDuration = squareData.length * squareShowTime;
       glide.svg.selectAll("rect")
                .data(squareData, glide.key)
                .enter()
                .append("rect")
                .attr("width", squareDims.width)
                .attr("height", squareDims.width)
                .attr("x", function (d) { return d.x; })
                .attr("y", function (d) { return d.y; })
                .attr("id", function (d) { return "sq_" + d.key; })
                .attr("stroke", glide.param.bgColor)
                .attr("fill", glide.param.bgColor);

       // (4) define animation stopper
       glide.cancelAnimation = function () {
           if (glide.animIntervalId !== null) {
               clearInterval(glide.animIntervalId);
               glide.animIntervalId = null;

               glide.svg.selectAll("rect")
                        .data([], glide.key)
                        .exit()
                        .remove();

               glide.cancelAnimation = null;
           }
       };

       // (5) start animation: remove squares (one by one)
       glide.animIntervalId = setInterval(function () {
               if ( squareData.length > 0 ) {
                   glide.randSplice(squareData);
                   glide.svg.selectAll("rect")
                         .data(squareData, glide.key)
                         .exit()
                         .remove();
               } else {
                   clearInterval(glide.animIntervalId);
                   glide.animIntervalId = null;
                   glide.cancelAnimation = null;
               }
       },
       squareShowTime);

       glide.triggerNextSlide(animDuration + glide.param.showDuration);
    };
    img.src = nextPicSpec[0].src;
};

glide.registerAnimations = function () {
    glide.animations.ZOOM_IN = glide.aniZoomIn;
    glide.animations.SLIDE_RIGHT = glide.aniSlideRight;
    glide.animations.SLIDE_TOP = glide.aniSlideTop;
    glide.animations.MEMORY = glide.aniMemory;
};

glide.startShow = function (data) {
    glide.dataset = data;
    glide.max = glide.dataset.pics.length - 1;
    glide.i = -1;
    glide.updateParams();
    glide.registerAnimations();
    glide.setupCanvas();
    glide.nextSlide();
};

glide.stopShow = function () {
    if (glide.showTimeoutId !== null) {
        clearTimeout(glide.showTimeoutId);
        glide.showTimeoutId = null;
    }
};

/******************************************************************************
 *** Event Handler ***
 *****************************************************************************/
 // On click on body:
d3.select("body").on("click", function(e) {
    glide.nextSlide();
});

// On key press:
document.onkeypress = function (e) {
    e = e || window.event;
    switch (e.key) {
    case " ":   // Space
        glide.nextSlide();
      break;
    case "Backspace":
      glide.prevSlide();
      break;
    case "ArrowDown":
      glide.prevSlide();
      break;
    case "ArrowUp":
      glide.nextSlide();
      break;
    case "ArrowLeft":
      glide.prevSlide();
      break;
    case "ArrowRight":
      glide.nextSlide();
      break;
    case "Enter":
      glide.nextSlide();
      break;
    case "Escape":
      glide.stopShow();
      break;
    default:
      return;
  }
};

// On window resize:
window.onresize = function(e) {

    // resize canvas
    glide.svg.attr("width", window.innerWidth)
             .attr("height", window.innerHeight);

    // resize pic
    var posAndDims = glide.calcImgPosAndDims();
    glide.svg.selectAll("image")
           .attr("width", posAndDims.width)
           .attr("height", posAndDims.height)
           .attr("x", posAndDims.x)
           .attr("y", posAndDims.y);
};

// On page load:
d3.json(glide.param.picsJsonURI, function(data) {
    glide.startShow(data);
});
<|endoftext|>


<commit_before>
import './app.css'

import './pages/index/index'

import { render, WeElement, define } from 'omi'

//通过 config.pages 属性来判断是 app
define('my-app', class extends WeElement {

  config = {
    pages: [
      'pages/index/index'
    ],
    window: {
      backgroundTextStyle: 'light',
      navigationBarBackgroundColor: '#fff',
      navigationBarTitleText: 'WeChat',
      navigationBarTextStyle: 'black'
    }
  }

  componentWillMount() { }

  componentDidMount() { }

  componentWillUnmount() { }

  componentDidShow() { }

  componentDidHide() { }

  render() {
    return (
      <my-counter />
    )
  }
})

render(<my-app />, 'body')
<commit_msg>omix - modifying life cycle functions<commit_after>
import './app.css'

import './pages/index/index'

import { render, WeElement, define } from 'omi'

//通过 config.pages 属性来判断是 app
define('my-app', class extends WeElement {

  config = {
    pages: [
      'pages/index/index'
    ],
    window: {
      backgroundTextStyle: 'light',
      navigationBarBackgroundColor: '#fff',
      navigationBarTitleText: 'WeChat',
      navigationBarTextStyle: 'black'
    }
  }

  install() { }

  installed() { }

  uninstall() { }

  show() { }

  hide() { }

  render() {
    return (
      <my-counter />
    )
  }
})

render(<my-app />, 'body')
<|endoftext|>


<commit_before>function display(selector) {
    $(selector).removeClass("hidden");
}

function hide(selector) {
    $(selector).addClass("hidden");
}

function displayDetails(selector) {
  hide("#bm-home");
  hide(".bm-details");
  display(selector);
  display("#bm-main-interface");
}

function displayTransfers() {
  hide("#bm-menu-account");
  display("#bm-menu-type");
  display("#bm-menu-account-from");
  display("#bm-menu-account-to");
  displayDetails("#bm-transfers-details");
}

function displayBudget() {
  hide("#bm-menu-account");
  display("#bm-menu-type");
  hide("#bm-menu-account-from");
  hide("#bm-menu-account-to");
  displayDetails("#bm-budget-details");
}

function displayAccounts() {
  display("#bm-menu-account");
  hide("#bm-menu-type");
  hide("#bm-menu-account-from");
  hide("#bm-menu-account-to");
  displayDetails("#bm-accounts-details");

}

function refreshYearsCombobox() {
  var callback = function (data) {
      var yearsComboboxHtml = "";
      $.each( data, function() {
          yearsComboboxHtml += '<option>' + this + '</option>';
      });
      $('#bm-combo-year').html(yearsComboboxHtml);
      $('#bm-combo-year option:last').prop('selected', true);
  }

  return $.ajax({
      url: "../json/years",
      dataType: "json",
      success: callback
  });
}

function refreshTypesCombobox() {
  var callback = function (data) {
        var typesComboboxHtml = '<option>All types</option>';
        $.each( data, function() {
            typesComboboxHtml += '<option>' + this + '</option>';
        });
        $('#bm-combo-type').html(typesComboboxHtml);
    }

    return $.ajax({
        url: "../json/types",
        dataType: "json",
        success: callback
    });
}

function refreshAccountsComboboxes() {
  var callback = function (data) {
        var accountComboboxHtml = '<option>All account</option>';
        $.each( data, function() {
            accountComboboxHtml += '<option>' + this + '</option>';
        });
        $('#bm-combo-account').html(accountComboboxHtml);
        $('#bm-combo-account-from').html(accountComboboxHtml);
        $('#bm-combo-account-to').html(accountComboboxHtml);
    }

    return $.ajax({
        url: "../json/accounts",
        dataType: "json",
        success: callback
    });
}

function refreshTransfersTable() {
  var callback = function (data) {
    var bmTbodytransfer = "";
    var otherRow = false;
    $.each( data, function() {
      bmTbodytransfer += '
';
      bmTbodytransfer += '' + this.date + '';
      bmTbodytransfer += '' + this.type + '';
      bmTbodytransfer += '' + this.amount.toFixed(2) + ' ' + this.currency + '';
      bmTbodytransfer += '' + (this.srcAccount ? this.srcAccount : '-') + '';
      bmTbodytransfer += '' + (this.srcDate ? this.srcDate : '-') + '';
      bmTbodytransfer += '' + (this.tgtAccount ? this.tgtAccount : '-') + '';
      bmTbodytransfer += '' + (this.tgtDate ? this.tgtDate : '-') + '';
      bmTbodytransfer += '' + (this.comments ? this.comments : '-') + '';
      bmTbodytransfer += '
';
      otherRow = !otherRow;
    });
    $('#bm-transfers-tbody').html(bmTbodytransfer);
  }

  var year = $('#bm-combo-year').val();
  var month = $('#bm-combo-month').prop("selectedIndex");
  var allTypes = $('#bm-combo-type').prop("selectedIndex") == 0;
  var type = $('#bm-combo-type').val();
  var allAccounts = $('#bm-combo-account').prop("selectedIndex") == 0;
  var account = $('#bm-combo-account').val();
  var fromAllAccounts = $('#bm-combo-account-from').prop("selectedIndex") == 0;
  var fromAccount = $('#bm-combo-account-from').val();
  var toAllAccounts = $('#bm-combo-account-to').prop("selectedIndex") == 0;
  var toAccount = $('#bm-combo-account-to').val();
  $.ajax({
      url: '../json/transfers',
      data: {
        year: year,
        month: month == 0 ? undefined : month,
        type: allTypes ? undefined : type,
        account: allAccounts ? undefined : account,
        fromAccount: fromAllAccounts ? undefined : fromAccount,
        toAccount: toAllAccounts ? undefined : toAccount,
      },
      dataType: "json",
      success: callback
  });
}

function refreshBudgetTable() {
  var callback = function (data) {
    var bmTbodytransfer = "";
    var otherRow = false;
    $.each( data, function() {
      bmTbodytransfer += '
';
      bmTbodytransfer += '' + this.name + '';
      bmTbodytransfer += '' + this.balance.toFixed(2) + '';
	  bmTbodytransfer += '<button class="bm-budget-button-display" type="' + this.name + '">Display</button>';
      bmTbodytransfer += '
';
      otherRow = !otherRow;
    });
    $('#bm-budget-tbody').html(bmTbodytransfer);
  }

  var year = $('#bm-combo-year').val();
  var month = $('#bm-combo-month').prop("selectedIndex");
  var allTypes = $('#bm-combo-type').prop("selectedIndex") == 0;
  var type = $('#bm-combo-type').val();
  $.ajax({
      url: '../json/budget',
      data: {
        year: year,
        month: month == 0 ? undefined : month,
        type: allTypes ? "Budget" : type
      },
      dataType: "json",
      success: callback
  });
}

function refreshSubAccountsTable() {
  var callback = function (data) {
    var bmTbodytransfer = "";
    var otherRow = false;
    $.each( data, function() {
      bmTbodytransfer += '
';
      bmTbodytransfer += '' + this.name + '';
      bmTbodytransfer += '' + this.start.toFixed(2) + '';
      bmTbodytransfer += '' + this.end.toFixed(2) + '';
      bmTbodytransfer += '' + this.delta.toFixed(2) + '';
      bmTbodytransfer += '
';
      otherRow = !otherRow;
    });
    $('#bm-sub-accounts-tbody').html(bmTbodytransfer);
  }

  var year = $('#bm-combo-year').val();
  var month = $('#bm-combo-month').prop("selectedIndex");
  var allAccounts = $('#bm-combo-account').prop("selectedIndex") == 0;
  var account = $('#bm-combo-account').val();
  $.ajax({
      url: '../json/sub-accounts',
      data: {
        year: year,
        month: month == 0 ? undefined : month,
        account: allAccounts ? "Assets" : account
      },
      dataType: "json",
      success: callback
  });
}

function refreshIncomingTransfersTable() {
  var callback = function (data) {
    var bmTbodytransfer = "";
    var otherRow = false;
    $.each( data, function() {
      bmTbodytransfer += '
';
      bmTbodytransfer += '' + this.tgtDate + '';
      bmTbodytransfer += '' + this.type + '';
      bmTbodytransfer += '' + this.amount.toFixed(2) + ' ' + this.currency + '';
      bmTbodytransfer += '' + (this.srcAccount ? this.srcAccount : '-') + '';
      bmTbodytransfer += '' + (this.srcDate ? this.srcDate : '-') + '';
      bmTbodytransfer += '' + (this.comments ? this.comments : '-') + '';
      bmTbodytransfer += '
';
      otherRow = !otherRow;
    });
    $('#bm-accounts-inc-tbody').html(bmTbodytransfer);
  }

  var year = $('#bm-combo-year').val();
  var month = $('#bm-combo-month').prop("selectedIndex");
  var allAccounts = $('#bm-combo-account').prop("selectedIndex") == 0;
  var account = $('#bm-combo-account').val();
  $.ajax({
      url: '../json/incoming-transfers',
      data: {
        year: year,
        month: month == 0 ? undefined : month,
        account: allAccounts ? "Assets" : account
      },
      dataType: "json",
      success: callback
  });
}

function refreshOutgoingTransfersTable() {
  var callback = function (data) {
    var bmTbodytransfer = "";
    var otherRow = false;
    $.each( data, function() {
      bmTbodytransfer += '
';
      bmTbodytransfer += '' + this.srcDate + '';
      bmTbodytransfer += '' + this.type + '';
      bmTbodytransfer += '' + this.amount.toFixed(2) + ' ' + this.currency + '';
      bmTbodytransfer += '' + (this.tgtAccount ? this.srcAccount : '-') + '';
      bmTbodytransfer += '' + (this.tgtDate ? this.srcDate : '-') + '';
      bmTbodytransfer += '' + (this.comments ? this.comments : '-') + '';
      bmTbodytransfer += '
';
      otherRow = !otherRow;
    });
    $('#bm-accounts-out-tbody').html(bmTbodytransfer);
  }

  var year = $('#bm-combo-year').val();
  var month = $('#bm-combo-month').prop("selectedIndex");
  var allAccounts = $('#bm-combo-account').prop("selectedIndex") == 0;
  var account = $('#bm-combo-account').val();
  $.ajax({
      url: '../json/outgoing-transfers',
      data: {
        year: year,
        month: month == 0 ? undefined : month,
        account: allAccounts ? "Assets" : account
      },
      dataType: "json",
      success: callback
  });
}

var accountsChart;
function refreshAccountsGraph() {
  var callback = function (data) {
    var dataArray = [['Month','Amount']];
    var amount = data.initial;

    $.each(data.deltas, function() {
      dataArray.push([this.key, amount]);
      amount += this.value;
    });
    dataArray.push(['', amount]);

    var dataTable = google.visualization.arrayToDataTable(dataArray);

    var options = {
      title: $('#bm-combo-account').val(),
      legend: 'none',
      series: {
        0: {color: '#455a64'}
      },
      pointSize: 1,
      width:1200, /* TODO Solve */
      height:200
    };

    accountsChart.draw(dataTable, options);
  }

  var year = $('#bm-combo-year').val();
  var month = $('#bm-combo-month').prop("selectedIndex");
  var allAccounts = $('#bm-combo-account').prop("selectedIndex") == 0;
  var account = $('#bm-combo-account').val();
  $.ajax({
      url: '../json/deltas',
      data: {
        year: year,
        month: month == 0 ? undefined : month,
        account: allAccounts ? "Assets" : account
      },
      dataType: "json",
      success: callback
  });
}

$("#bm-nav-transfers").click(() => displayTransfers());
$("#bm-nav-budget").click(() => displayBudget());
$("#bm-nav-accounts").click(() => displayAccounts());

$(".bm-budget-button-display").click(() => alert("test"));

$( ".bm-menu-combo" ).change(function() {
    refreshTransfersTable();
	refreshBudgetTable();
    refreshSubAccountsTable();
    refreshIncomingTransfersTable();
    refreshOutgoingTransfersTable();
    refreshAccountsGraph();
});

$.when( refreshYearsCombobox(), refreshTypesCombobox(), refreshAccountsComboboxes() ).done(() => {
  refreshTransfersTable();

  refreshBudgetTable();

  refreshSubAccountsTable();
  refreshIncomingTransfersTable();
  refreshOutgoingTransfersTable();

  google.charts.load('current', {'packages':['corechart']});
  google.charts.setOnLoadCallback(() => {
    accountsChart = new google.visualization.LineChart(document.getElementById('accounts-chart'));
    refreshAccountsGraph()
  });

});

<commit_msg>QuickFix<commit_after>function display(selector) {
    $(selector).removeClass("hidden");
}

function hide(selector) {
    $(selector).addClass("hidden");
}

function displayDetails(selector) {
  hide("#bm-home");
  hide(".bm-details");
  display(selector);
  display("#bm-main-interface");
}

function displayTransfers() {
  hide("#bm-menu-account");
  display("#bm-menu-type");
  display("#bm-menu-account-from");
  display("#bm-menu-account-to");
  displayDetails("#bm-transfers-details");
}

function displayBudget() {
  hide("#bm-menu-account");
  display("#bm-menu-type");
  hide("#bm-menu-account-from");
  hide("#bm-menu-account-to");
  displayDetails("#bm-budget-details");
}

function displayAccounts() {
  display("#bm-menu-account");
  hide("#bm-menu-type");
  hide("#bm-menu-account-from");
  hide("#bm-menu-account-to");
  displayDetails("#bm-accounts-details");

}

function refreshYearsCombobox() {
  var callback = function (data) {
      var yearsComboboxHtml = "";
      $.each( data, function() {
          yearsComboboxHtml += '<option>' + this + '</option>';
      });
      $('#bm-combo-year').html(yearsComboboxHtml);
      $('#bm-combo-year option:last').prop('selected', true);
  }

  return $.ajax({
      url: "../json/years",
      dataType: "json",
      success: callback
  });
}

function refreshTypesCombobox() {
  var callback = function (data) {
        var typesComboboxHtml = '<option>All types</option>';
        $.each( data, function() {
            typesComboboxHtml += '<option>' + this + '</option>';
        });
        $('#bm-combo-type').html(typesComboboxHtml);
    }

    return $.ajax({
        url: "../json/types",
        dataType: "json",
        success: callback
    });
}

function refreshAccountsComboboxes() {
  var callback = function (data) {
        var accountComboboxHtml = '<option>All account</option>';
        $.each( data, function() {
            accountComboboxHtml += '<option>' + this + '</option>';
        });
        $('#bm-combo-account').html(accountComboboxHtml);
        $('#bm-combo-account-from').html(accountComboboxHtml);
        $('#bm-combo-account-to').html(accountComboboxHtml);
    }

    return $.ajax({
        url: "../json/accounts",
        dataType: "json",
        success: callback
    });
}

function refreshTransfersTable() {
  var callback = function (data) {
    var bmTbodytransfer = "";
    var otherRow = false;
    $.each( data, function() {
      bmTbodytransfer += '
';
      bmTbodytransfer += '' + this.date + '';
      bmTbodytransfer += '' + this.type + '';
      bmTbodytransfer += '' + this.amount.toFixed(2) + ' ' + this.currency + '';
      bmTbodytransfer += '' + (this.srcAccount ? this.srcAccount : '-') + '';
      bmTbodytransfer += '' + (this.srcDate ? this.srcDate : '-') + '';
      bmTbodytransfer += '' + (this.tgtAccount ? this.tgtAccount : '-') + '';
      bmTbodytransfer += '' + (this.tgtDate ? this.tgtDate : '-') + '';
      bmTbodytransfer += '' + (this.comments ? this.comments : '-') + '';
      bmTbodytransfer += '
';
      otherRow = !otherRow;
    });
    $('#bm-transfers-tbody').html(bmTbodytransfer);
  }

  var year = $('#bm-combo-year').val();
  var month = $('#bm-combo-month').prop("selectedIndex");
  var allTypes = $('#bm-combo-type').prop("selectedIndex") == 0;
  var type = $('#bm-combo-type').val();
  var allAccounts = $('#bm-combo-account').prop("selectedIndex") == 0;
  var account = $('#bm-combo-account').val();
  var fromAllAccounts = $('#bm-combo-account-from').prop("selectedIndex") == 0;
  var fromAccount = $('#bm-combo-account-from').val();
  var toAllAccounts = $('#bm-combo-account-to').prop("selectedIndex") == 0;
  var toAccount = $('#bm-combo-account-to').val();
  $.ajax({
      url: '../json/transfers',
      data: {
        year: year,
        month: month == 0 ? undefined : month,
        type: allTypes ? undefined : type,
        account: allAccounts ? undefined : account,
        fromAccount: fromAllAccounts ? undefined : fromAccount,
        toAccount: toAllAccounts ? undefined : toAccount
      },
      dataType: "json",
      success: callback
  });
}

function refreshBudgetTable() {
  var callback = function (data) {
    var bmTbodytransfer = "";
    var otherRow = false;
    $.each( data, function() {
      bmTbodytransfer += '
';
      bmTbodytransfer += '' + this.name + '';
      bmTbodytransfer += '' + this.balance.toFixed(2) + '';
	  bmTbodytransfer += '<button class="bm-budget-button-display" type="' + this.name + '">Display</button>';
      bmTbodytransfer += '
';
      otherRow = !otherRow;
    });
    $('#bm-budget-tbody').html(bmTbodytransfer);
  }

  var year = $('#bm-combo-year').val();
  var month = $('#bm-combo-month').prop("selectedIndex");
  var allTypes = $('#bm-combo-type').prop("selectedIndex") == 0;
  var type = $('#bm-combo-type').val();
  $.ajax({
      url: '../json/budget',
      data: {
        year: year,
        month: month == 0 ? undefined : month,
        type: allTypes ? "Budget" : type
      },
      dataType: "json",
      success: callback
  });
}

function refreshSubAccountsTable() {
  var callback = function (data) {
    var bmTbodytransfer = "";
    var otherRow = false;
    $.each( data, function() {
      bmTbodytransfer += '
';
      bmTbodytransfer += '' + this.name + '';
      bmTbodytransfer += '' + this.start.toFixed(2) + '';
      bmTbodytransfer += '' + this.end.toFixed(2) + '';
      bmTbodytransfer += '' + this.delta.toFixed(2) + '';
      bmTbodytransfer += '
';
      otherRow = !otherRow;
    });
    $('#bm-sub-accounts-tbody').html(bmTbodytransfer);
  }

  var year = $('#bm-combo-year').val();
  var month = $('#bm-combo-month').prop("selectedIndex");
  var allAccounts = $('#bm-combo-account').prop("selectedIndex") == 0;
  var account = $('#bm-combo-account').val();
  $.ajax({
      url: '../json/sub-accounts',
      data: {
        year: year,
        month: month == 0 ? undefined : month,
        account: allAccounts ? "Assets" : account
      },
      dataType: "json",
      success: callback
  });
}

function refreshIncomingTransfersTable() {
  var callback = function (data) {
    var bmTbodytransfer = "";
    var otherRow = false;
    $.each( data, function() {
      bmTbodytransfer += '
';
      bmTbodytransfer += '' + this.tgtDate + '';
      bmTbodytransfer += '' + this.type + '';
      bmTbodytransfer += '' + this.amount.toFixed(2) + ' ' + this.currency + '';
      bmTbodytransfer += '' + (this.srcAccount ? this.srcAccount : '-') + '';
      bmTbodytransfer += '' + (this.srcDate ? this.srcDate : '-') + '';
      bmTbodytransfer += '' + (this.comments ? this.comments : '-') + '';
      bmTbodytransfer += '
';
      otherRow = !otherRow;
    });
    $('#bm-accounts-inc-tbody').html(bmTbodytransfer);
  }

  var year = $('#bm-combo-year').val();
  var month = $('#bm-combo-month').prop("selectedIndex");
  var allAccounts = $('#bm-combo-account').prop("selectedIndex") == 0;
  var account = $('#bm-combo-account').val();
  $.ajax({
      url: '../json/incoming-transfers',
      data: {
        year: year,
        month: month == 0 ? undefined : month,
        account: allAccounts ? "Assets" : account
      },
      dataType: "json",
      success: callback
  });
}

function refreshOutgoingTransfersTable() {
  var callback = function (data) {
    var bmTbodytransfer = "";
    var otherRow = false;
    $.each( data, function() {
      bmTbodytransfer += '
';
      bmTbodytransfer += '' + this.srcDate + '';
      bmTbodytransfer += '' + this.type + '';
      bmTbodytransfer += '' + this.amount.toFixed(2) + ' ' + this.currency + '';
      bmTbodytransfer += '' + (this.tgtAccount ? this.srcAccount : '-') + '';
      bmTbodytransfer += '' + (this.tgtDate ? this.srcDate : '-') + '';
      bmTbodytransfer += '' + (this.comments ? this.comments : '-') + '';
      bmTbodytransfer += '
';
      otherRow = !otherRow;
    });
    $('#bm-accounts-out-tbody').html(bmTbodytransfer);
  }

  var year = $('#bm-combo-year').val();
  var month = $('#bm-combo-month').prop("selectedIndex");
  var allAccounts = $('#bm-combo-account').prop("selectedIndex") == 0;
  var account = $('#bm-combo-account').val();
  $.ajax({
      url: '../json/outgoing-transfers',
      data: {
        year: year,
        month: month == 0 ? undefined : month,
        account: allAccounts ? "Assets" : account
      },
      dataType: "json",
      success: callback
  });
}

var accountsChart;
function refreshAccountsGraph() {
  var callback = function (data) {
    var dataArray = [['Month','Amount']];
    var amount = data.initial;

    $.each(data.deltas, function() {
      dataArray.push([this.key, amount]);
      amount += this.value;
    });
    dataArray.push(['', amount]);

    var dataTable = google.visualization.arrayToDataTable(dataArray);

    var options = {
      title: $('#bm-combo-account').val(),
      legend: 'none',
      series: {
        0: {color: '#455a64'}
      },
      pointSize: 1,
      width:1200, /* TODO Solve */
      height:200
    };

    accountsChart.draw(dataTable, options);
  }

  var year = $('#bm-combo-year').val();
  var month = $('#bm-combo-month').prop("selectedIndex");
  var allAccounts = $('#bm-combo-account').prop("selectedIndex") == 0;
  var account = $('#bm-combo-account').val();
  $.ajax({
      url: '../json/deltas',
      data: {
        year: year,
        month: month == 0 ? undefined : month,
        account: allAccounts ? "Assets" : account
      },
      dataType: "json",
      success: callback
  });
}

$("#bm-nav-transfers").click(() => displayTransfers());
$("#bm-nav-budget").click(() => displayBudget());
$("#bm-nav-accounts").click(() => displayAccounts());

$(".bm-budget-button-display").click(() => alert("test"));

$( ".bm-menu-combo" ).change(function() {
    refreshTransfersTable();
	refreshBudgetTable();
    refreshSubAccountsTable();
    refreshIncomingTransfersTable();
    refreshOutgoingTransfersTable();
    refreshAccountsGraph();
});

$.when( refreshYearsCombobox(), refreshTypesCombobox(), refreshAccountsComboboxes() ).done(() => {
  refreshTransfersTable();

  refreshBudgetTable();

  refreshSubAccountsTable();
  refreshIncomingTransfersTable();
  refreshOutgoingTransfersTable();

  google.charts.load('current', {'packages':['corechart']});
  google.charts.setOnLoadCallback(() => {
    accountsChart = new google.visualization.LineChart(document.getElementById('accounts-chart'));
    refreshAccountsGraph()
  });

});

<|endoftext|>


<commit_before>const server = require('server-base')
const routes = require('./routes')

server(routes)
.config.assert(['PORT', 'STORAGE_PATH'])
.start()
<commit_msg>standard formatting fix<commit_after>const server = require('server-base')
const routes = require('./routes')

server(routes)
  .config.assert(['PORT', 'STORAGE_PATH'])
  .start()
<|endoftext|>


<commit_before>import React, { Component, createElement } from 'react';
import { gql, graphql, SimpleRoute, unflatten } from 'olymp';
import { orderBy, sortBy } from 'lodash';
import { queryPages } from './gql';
import { get, upperFirst, lowerFirst } from 'lodash';

// interpolate a string value using props
const interpolate = (value, propsOrFunc) => {
  if (typeof value !== 'string') {
    return value;
  }
  if (value.indexOf('{') === -1) {
    return value;
  }
  return value.replace(
    /\{\{?\:?(.+?)\}?\}/g,
    (m, v) =>
      typeof propsOrFunc === 'function'
        ? propsOrFunc(v, v)
        : get(propsOrFunc, v, v)
  );
};

const NavCache = {};
export const withNavigation = (Wrapped) => {
  // Prepare Data, gather bound navigation items
  const withNavigationPrepare = (Wrapped) => {
    // get PageList
    @queryPages
    class WithNavPrepareInner extends Component {
      render() {
        const { items } = this.props;
        const deco = items.filter(item => item.binding);
        const key = deco.map(x => `${x.id}-${x.binding}`).join('|');
        if (!NavCache[key]) {
          NavCache[key] = items
            .filter(item => item.binding && item.binding.type)
            .reduce((store, value) => {
              const { type, fields, query } = value.binding;
              const sort = value.sorting
                ? value.sorting.reduce((store, item) => {
                  const [c, ...rest] = item.split('');
                  store[rest.join('')] = c === '-' ? 'DESC' : 'ASC';
                  return store;
                }, {})
                : {};
              return graphql(
                gql`
                  query ${lowerFirst(type)}List(
                    $query: ${upperFirst(type)}Query,
                    $sort: ${upperFirst(type)}Sort
                  ) {
                    items: ${lowerFirst(type)}List(query: $query, sort: $sort) {
                      ${fields || 'id name slug'}
                    }
                  }
                `,
                {
                  name: `nav_${value.id}`,
                  options: () => ({ variables: { query, sort } }),
                }
              )(store);
            }, Wrapped);
        }
        const Comp = NavCache[key];

        return Comp ? <Comp {...this.props} /> : <Wrapped {...this.props} />;
      }
    }
    return WithNavPrepareInner;
  };

  // Compose Navigation from prepared data
  @withNavigationPrepare
  class WithNavInner extends Component {
    render() {
      const { data } = this.props;
      const items = (data && data.items) || [];
      const flatNavigation = [];
      let loading = true;
      const navigation = unflatten(items, {
        pathProp: 'pathname',
        sort: (children, parent) => {
          const sorting = parent ? parent.sorting || ['+order'] : ['+order'];
          children = children.reduce((state, child) => {
            const data = this.props[`nav_${child.id}`];
            if (data) {
              loading = loading && data.loading;
              (data.items || []).forEach((item) => {
                const slug = child.slug
                  ? interpolate(child.slug, item)
                  : item.slug;
                state.push({
                  ...child,
                  pageId: child.id,
                  bindingId: item.id,
                  bindingObj: item,
                  slug,
                  name: item.name,
                  id: item.id,
                });
              });
            } else {
              state.push(child);
            }
            return state;
          }, []);
          if (sorting.length) {
            const fields = [];
            const directions = [];
            sorting.forEach((sorter) => {
              fields.push(sorter.substr(1));
              directions.push(sorter[0] === '-' ? 'desc' : 'asc');
            });
            children = orderBy(children, fields, directions);
          } else {
            const sortIndex = sorting;
            children = sortBy(children, [
              (o) => {
                const index = sortIndex.indexOf(o.id);
                if (index === -1) {
                  return 99;
                }
                return index;
              },
            ]);
          }
          return children;
        },
        setPath: (current, { slug, ...rest }) => {
          const pathname = `${current || ''}${slug || ''}`.replace('//', '/');
          flatNavigation.push({ ...rest, slug, pathname });

          return pathname;
        },
      });

      return (
        <Wrapped
          {...this.props}
          loading={loading}
          navigation={!loading ? navigation : []}
          flatNavigation={!loading ? flatNavigation : []}
        />
      );
    }
  }
  return WithNavInner;
};

// DataRoute: Wrap pages with `binding` to their data items
let cache = {};
let lastType;
export const DataRoute = ({ binding, component, ...rest }) => {
  if (!binding || !binding.type) {
    return createElement(component || SimpleRoute, rest);
  }
  const { type, fields, query } = binding;
  const key = `route-${type}-${fields || 'id name slug'}`;
  if (lastType !== (component || SimpleRoute)) {
    // TODO better way to wipe cache
    cache = {};
    lastType = component || SimpleRoute;
  }
  if (!cache[key]) {
    cache[key] = withData(component || SimpleRoute, { fields, type });
  }
  return createElement(cache[key], rest);
};

// Helper for DataRoute, actual decorator
export const withData = (Wrapped, { type, fields }) =>
  graphql(
    gql`
    query ${type || 'page'}($id: String) {
      item: ${type || 'page'}(id: $id) {
        ${fields || 'id name'}
      }
    }
  `,
    {
      options: ({ bindingId }) => ({
        variables: {
          id: bindingId,
        },
      }),
      name: 'nav_data',
    }
  )(({ nav_data, ...rest }) => <Wrapped {...rest} binding={nav_data.item} />);
<commit_msg>fix sorting<commit_after>import React, { Component, createElement } from 'react';
import { gql, graphql, SimpleRoute, unflatten } from 'olymp';
import { orderBy, sortBy } from 'lodash';
import { queryPages } from './gql';
import { get, upperFirst, lowerFirst } from 'lodash';

// interpolate a string value using props
const interpolate = (value, propsOrFunc) => {
  if (typeof value !== 'string') {
    return value;
  }
  if (value.indexOf('{') === -1) {
    return value;
  }
  return value.replace(
    /\{\{?\:?(.+?)\}?\}/g,
    (m, v) =>
      typeof propsOrFunc === 'function'
        ? propsOrFunc(v, v)
        : get(propsOrFunc, v, v)
  );
};

const NavCache = {};
export const withNavigation = (Wrapped) => {
  // Prepare Data, gather bound navigation items
  const withNavigationPrepare = (Wrapped) => {
    // get PageList
    @queryPages
    class WithNavPrepareInner extends Component {
      render() {
        const { items } = this.props;
        const deco = items.filter(item => item.binding);
        const key = deco.map(x => `${x.id}-${x.binding}`).join('|');
        if (!NavCache[key]) {
          NavCache[key] = items
            .filter(item => item.binding && item.binding.type)
            .reduce((store, value) => {
              const { type, fields, query } = value.binding;
              const sort = value.sorting
                ? value.sorting.reduce((store, item) => {
                  const [c, ...rest] = item.split('');
                  store[rest.join('')] = c === '-' ? 'DESC' : 'ASC';
                  return store;
                }, {})
                : {};
              return graphql(
                gql`
                  query ${lowerFirst(type)}List(
                    $query: ${upperFirst(type)}Query,
                    $sort: ${upperFirst(type)}Sort
                  ) {
                    items: ${lowerFirst(type)}List(query: $query, sort: $sort) {
                      ${fields || 'id name slug'}
                    }
                  }
                `,
                {
                  name: `nav_${value.id}`,
                  options: () => ({ variables: { query, sort } }),
                }
              )(store);
            }, Wrapped);
        }
        const Comp = NavCache[key];

        return Comp ? <Comp {...this.props} /> : <Wrapped {...this.props} />;
      }
    }
    return WithNavPrepareInner;
  };

  // Compose Navigation from prepared data
  @withNavigationPrepare
  class WithNavInner extends Component {
    render() {
      const { data } = this.props;
      const items = (data && data.items) || [];
      const flatNavigation = [];
      let loading = false;

      const navigation = unflatten(items, {
        pathProp: 'pathname',
        sort: (children, parent) => {
          children = children.reduce((state, child) => {
            const data = this.props[`nav_${child.id}`];
            if (data) {
              loading = loading && data.loading;
              (data.items || []).forEach((item) => {
                const slug = child.slug
                  ? interpolate(child.slug, item)
                  : item.slug;
                state.push({
                  ...child,
                  pageId: child.id,
                  bindingId: item.id,
                  bindingObj: item,
                  slug,
                  name: item.name,
                  id: item.id,
                });
              });
            } else {
              state.push(child);
            }
            return state;
          }, []);
          if (!parent || !parent.sorting) {
            const fields = [];
            const directions = [];
            ['+order'].forEach((sorter) => {
              fields.push(sorter.substr(1));
              directions.push(sorter[0] === '-' ? 'desc' : 'asc');
            });
            children = orderBy(children, fields, directions);
          } else {
            const sortIndex = parent.sorting;
            children = sortBy(children, [
              (o) => {
                const index = sortIndex.indexOf(o.id);
                if (index === -1) {
                  return 99;
                }
                return index;
              },
            ]);
          }
          return children;
        },
        setPath: (current, { slug, ...rest }) => {
          const pathname = `${current || ''}${slug || ''}`.replace('//', '/');
          flatNavigation.push({ ...rest, slug, pathname });

          return pathname;
        },
      });

      return (
        <Wrapped
          {...this.props}
          loading={loading}
          navigation={!loading ? navigation : []}
          flatNavigation={!loading ? flatNavigation : []}
        />
      );
    }
  }
  return WithNavInner;
};

// DataRoute: Wrap pages with `binding` to their data items
let cache = {};
let lastType;
export const DataRoute = ({ binding, component, ...rest }) => {
  if (!binding || !binding.type) {
    return createElement(component || SimpleRoute, rest);
  }
  const { type, fields, query } = binding;
  const key = `route-${type}-${fields || 'id name slug'}`;
  if (lastType !== (component || SimpleRoute)) {
    // TODO better way to wipe cache
    cache = {};
    lastType = component || SimpleRoute;
  }
  if (!cache[key]) {
    cache[key] = withData(component || SimpleRoute, { fields, type });
  }
  return createElement(cache[key], rest);
};

// Helper for DataRoute, actual decorator
export const withData = (Wrapped, { type, fields }) =>
  graphql(
    gql`
    query ${type || 'page'}($id: String) {
      item: ${type || 'page'}(id: $id) {
        ${fields || 'id name'}
      }
    }
  `,
    {
      options: ({ bindingId }) => ({
        variables: {
          id: bindingId,
        },
      }),
      name: 'nav_data',
    }
  )(({ nav_data, ...rest }) => <Wrapped {...rest} binding={nav_data.item} />);
<|endoftext|>


<commit_before>'use strict';

const { uniq, difference, get, isUndefined, merge } = require('lodash');

module.exports = async function() {
  /** Utils */

  const middlewareConfig = this.config.middleware;

  // check if a middleware exists
  const middlewareExists = key => {
    return !isUndefined(this.middleware[key]);
  };

  // check if a middleware is enabled
  const middlewareEnabled = key =>
    get(middlewareConfig, ['settings', key, 'enabled'], false) === true;

  // list of enabled middlewares
  const enabledMiddlewares = Object.keys(this.middleware).filter(
    middlewareEnabled
  );

  // Method to initialize middlewares and emit an event.
  const initialize = middlewareKey => {
    if (this.middleware[middlewareKey].loaded === true) return;

    const module = this.middleware[middlewareKey].load;

    return new Promise((resolve, reject) => {
      const timeout = setTimeout(
        () =>
          reject(`(middleware: ${middlewareKey}) is taking too long to load.`),
        middlewareConfig.timeout || 1000
      );

      this.middleware[middlewareKey] = merge(
        this.middleware[middlewareKey],
        module
      );

      Promise.resolve()
        .then(() => module.initialize())
        .then(() => {
          clearTimeout(timeout);
          this.middleware[middlewareKey].loaded = true;
          resolve();
        })
        .catch(err => {
          clearTimeout(timeout);

          if (err) {
            return reject(err);
          }
        });
    });
  };

  /**
   * Run init functions
   */

  // Run beforeInitialize of every middleware
  await Promise.all(
    enabledMiddlewares.map(key => {
      const { beforeInitialize } = this.middleware[key].load;
      if (typeof beforeInitialize === 'function') {
        return beforeInitialize();
      }
    })
  );

  // run the initialization of an array of middlewares sequentially
  const initMiddlewaresSeq = async middlewareArr => {
    for (let key of uniq(middlewareArr)) {
      await initialize(key);
    }
  };

  const middlewaresBefore = get(middlewareConfig, 'load.before', [])
    .filter(middlewareExists)
    .filter(middlewareEnabled);

  const middlewaresAfter = get(middlewareConfig, 'load.after', [])
    .filter(middlewareExists)
    .filter(middlewareEnabled);

  const middlewaresOrder = get(middlewareConfig, 'load.order', [])
    .filter(middlewareExists)
    .filter(middlewareEnabled);

  const unspecifiedMiddlewares = difference(
    enabledMiddlewares,
    middlewaresBefore,
    middlewaresOrder,
    middlewaresAfter
  );

  // before
  await initMiddlewaresSeq(middlewaresBefore);

  // ordered // rest of middlewares
  await Promise.all([
    initMiddlewaresSeq(middlewaresOrder),
    Promise.all(unspecifiedMiddlewares.map(initialize)),
  ]);

  // after
  await initMiddlewaresSeq(middlewaresAfter);
};
<commit_msg>Fix removed header too soon<commit_after>'use strict';

const { uniq, difference, get, isUndefined, merge } = require('lodash');

module.exports = async function() {
  // Set if is admin destination for middleware application.
  this.app.use(async (ctx, next) => {
    if (ctx.request.header['origin'] === 'http://localhost:4000') {
      ctx.request.header['x-forwarded-host'] = 'strapi';
    }

    ctx.request.admin = ctx.request.header['x-forwarded-host'] === 'strapi';

    await next();
  });

  /** Utils */

  const middlewareConfig = this.config.middleware;

  // check if a middleware exists
  const middlewareExists = key => {
    return !isUndefined(this.middleware[key]);
  };

  // check if a middleware is enabled
  const middlewareEnabled = key =>
    get(middlewareConfig, ['settings', key, 'enabled'], false) === true;

  // list of enabled middlewares
  const enabledMiddlewares = Object.keys(this.middleware).filter(
    middlewareEnabled
  );

  // Method to initialize middlewares and emit an event.
  const initialize = middlewareKey => {
    if (this.middleware[middlewareKey].loaded === true) return;

    const module = this.middleware[middlewareKey].load;

    return new Promise((resolve, reject) => {
      const timeout = setTimeout(
        () =>
          reject(`(middleware: ${middlewareKey}) is taking too long to load.`),
        middlewareConfig.timeout || 1000
      );

      this.middleware[middlewareKey] = merge(
        this.middleware[middlewareKey],
        module
      );

      Promise.resolve()
        .then(() => module.initialize())
        .then(() => {
          clearTimeout(timeout);
          this.middleware[middlewareKey].loaded = true;
          resolve();
        })
        .catch(err => {
          clearTimeout(timeout);

          if (err) {
            return reject(err);
          }
        });
    });
  };

  /**
   * Run init functions
   */

  // Run beforeInitialize of every middleware
  await Promise.all(
    enabledMiddlewares.map(key => {
      const { beforeInitialize } = this.middleware[key].load;
      if (typeof beforeInitialize === 'function') {
        return beforeInitialize();
      }
    })
  );

  // run the initialization of an array of middlewares sequentially
  const initMiddlewaresSeq = async middlewareArr => {
    for (let key of uniq(middlewareArr)) {
      await initialize(key);
    }
  };

  const middlewaresBefore = get(middlewareConfig, 'load.before', [])
    .filter(middlewareExists)
    .filter(middlewareEnabled);

  const middlewaresAfter = get(middlewareConfig, 'load.after', [])
    .filter(middlewareExists)
    .filter(middlewareEnabled);

  const middlewaresOrder = get(middlewareConfig, 'load.order', [])
    .filter(middlewareExists)
    .filter(middlewareEnabled);

  const unspecifiedMiddlewares = difference(
    enabledMiddlewares,
    middlewaresBefore,
    middlewaresOrder,
    middlewaresAfter
  );

  // before
  await initMiddlewaresSeq(middlewaresBefore);

  // ordered // rest of middlewares
  await Promise.all([
    initMiddlewaresSeq(middlewaresOrder),
    Promise.all(unspecifiedMiddlewares.map(initialize)),
  ]);

  // after
  await initMiddlewaresSeq(middlewaresAfter);
};
<|endoftext|>


<commit_before>var DARK_BLUE = "#294172";
var LIGHT_BLUE = "#4872c7";
var BLACK = "#03060a";

function init() {
    var rgraph = new $jit.RGraph({
        //Where to append the visualization
        injectInto: 'mainvis',

        //Add navigation capabilities:
        //zooming by scrolling and panning.
        Navigation: {
            enable: true,
            panning: true,
            zooming: 10
        },

        //Set Node and Edge styles.
        Node: {
            color: DARK_BLUE,
        },

        Edge: {
            color: LIGHT_BLUE,
            lineWidth:1.5
        },

        onBeforeCompute: function(node){
            var header = "
" + node.name + "
";
            var body = "
" + node.data.description + "
";
            var button = "";
            if ( node.data.url != undefined ) {
                button += "";
                button += "Peep dat!";
                button += "";
            }
            $jit.id('details').innerHTML = header + body + button;
        },

        //Add the name of the node in the correponding label
        //and a click handler to move the graph.
        //This method is called once, on label creation.
        onCreateLabel: function(domElement, node){
            domElement.innerHTML = node.name;
            domElement.onclick = function(){
                rgraph.onClick(node.id, {
                    onComplete: function() {
                        // awesome
                    }
                });
            };
        },
        //Change some label dom properties.
        //This method is called each time a label is plotted.
        onPlaceLabel: function(domElement, node){
            var style = domElement.style;
            style.display = '';
            style.cursor = 'pointer';
            style.color = BLACK;

            if (node._depth == 0) {
                style.fontSize = "1em";
            } else if (node._depth <= 1) {
                style.fontSize = "0.8em";
            } else if(node._depth >= 2){
                style.fontSize = "0.6em";
            }

            var left = parseInt(style.left);
            var w = domElement.offsetWidth;
            style.left = (left - w / 2) + 'px';
        }
    });
    //load JSON data
    rgraph.loadJSON(json);
    //trigger small animation
    rgraph.graph.eachNode(function(n) {
        var pos = n.getPos();
        pos.setc(0, 0);
    });
    rgraph.compute('end');
    rgraph.fx.animate({
        modes:['polar'],
        duration: 2000
    });
}
<commit_msg>Remove navigation.<commit_after>var DARK_BLUE = "#294172";
var LIGHT_BLUE = "#4872c7";
var BLACK = "#03060a";

function init() {
    var rgraph = new $jit.RGraph({
        //Where to append the visualization
        injectInto: 'mainvis',

        //Set Node and Edge styles.
        Node: {
            color: DARK_BLUE,
        },

        Edge: {
            color: LIGHT_BLUE,
            lineWidth:1.5
        },

        onBeforeCompute: function(node){
            var header = "
" + node.name + "
";
            var body = "
" + node.data.description + "
";
            var button = "";
            if ( node.data.url != undefined ) {
                button += "";
                button += "Peep dat!";
                button += "";
            }
            $jit.id('details').innerHTML = header + body + button;
        },

        //Add the name of the node in the correponding label
        //and a click handler to move the graph.
        //This method is called once, on label creation.
        onCreateLabel: function(domElement, node){
            domElement.innerHTML = node.name;
            domElement.onclick = function(){
                rgraph.onClick(node.id, {
                    onComplete: function() {
                        // awesome
                    }
                });
            };
        },
        //Change some label dom properties.
        //This method is called each time a label is plotted.
        onPlaceLabel: function(domElement, node){
            var style = domElement.style;
            style.display = '';
            style.cursor = 'pointer';
            style.color = BLACK;

            if (node._depth == 0) {
                style.fontSize = "1em";
            } else if (node._depth <= 1) {
                style.fontSize = "0.8em";
            } else if(node._depth >= 2){
                style.fontSize = "0.6em";
            }

            var left = parseInt(style.left);
            var w = domElement.offsetWidth;
            style.left = (left - w / 2) + 'px';
        }
    });
    //load JSON data
    rgraph.loadJSON(json);
    //trigger small animation
    rgraph.graph.eachNode(function(n) {
        var pos = n.getPos();
        pos.setc(0, 0);
    });
    rgraph.compute('end');
    rgraph.fx.animate({
        modes:['polar'],
        duration: 2000
    });
}
<|endoftext|>


<commit_before>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import type {Wakeable, Thenable} from 'shared/ReactTypes';

import {REACT_LAZY_TYPE} from 'shared/ReactSymbols';

const Uninitialized = -1;
const Pending = 0;
const Resolved = 1;
const Rejected = 2;

type UninitializedPayload<T> = {
  _status: -1,
  _result: () => Thenable<{default: T, ...}>,
};

type PendingPayload = {
  _status: 0,
  _result: Wakeable,
};

type ResolvedPayload<T> = {
  _status: 1,
  _result: {default: T},
};

type RejectedPayload = {
  _status: 2,
  _result: mixed,
};

type Payload<T> =
  | UninitializedPayload<T>
  | PendingPayload
  | ResolvedPayload<T>
  | RejectedPayload;

export type LazyComponent<T, P> = {
  $$typeof: Symbol | number,
  _payload: P,
  _init: (payload: P) => T,
};

function lazyInitializer<T>(payload: Payload<T>): T {
  if (payload._status === Uninitialized) {
    const ctor = payload._result;
    const thenable = ctor();
    // Transition to the next state.
    // This might throw either because it's missing or throws. If so, we treat it
    // as still uninitialized and try again next time. Which is the same as what
    // happens if the ctor or any wrappers processing the ctor throws. This might
    // end up fixing it if the resolution was a concurrency bug.
    thenable.then(
      moduleObject => {
        if (payload._status === Pending || payload._status === Uninitialized) {
          // Transition to the next state.
          const resolved: ResolvedPayload<T> = (payload: any);
          resolved._status = Resolved;
          resolved._result = moduleObject;
        }
      },
      error => {
        if (payload._status === Pending || payload._status === Uninitialized) {
          // Transition to the next state.
          const rejected: RejectedPayload = (payload: any);
          rejected._status = Rejected;
          rejected._result = error;
        }
      },
    );
    if (payload._status === Uninitialized) {
      // In case, we're still uninitialized, then we're waiting for the thenable
      // to resolve. Set it as pending in the meantime.
      const pending: PendingPayload = (payload: any);
      pending._status = Pending;
      pending._result = thenable;
    }
  }
  if (payload._status === Resolved) {
    const moduleObject = payload._result;
    if (__DEV__) {
      if (moduleObject === undefined) {
        console.error(
          'lazy: Expected the result of a dynamic import() call. ' +
            'Instead received: %s\n\nYour code should look like: \n  ' +
            // Break up imports to avoid accidentally parsing them as dependencies.
            'const MyComponent = lazy(() => imp' +
            "ort('./MyComponent'))\n\n" +
            'Did you accidentally put curly braces around the import?',
          moduleObject,
        );
      }
    }
    if (__DEV__) {
      if (!('default' in moduleObject)) {
        console.error(
          'lazy: Expected the result of a dynamic import() call. ' +
            'Instead received: %s\n\nYour code should look like: \n  ' +
            // Break up imports to avoid accidentally parsing them as dependencies.
            'const MyComponent = lazy(() => imp' +
            "ort('./MyComponent'))",
          moduleObject,
        );
      }
    }
    return moduleObject.default;
  } else {
    throw payload._result;
  }
}

export function lazy<T>(
  ctor: () => Thenable<{default: T, ...}>,
): LazyComponent<T, Payload<T>> {
  const payload: Payload<T> = {
    // We use these fields to store the result.
    _status: -1,
    _result: ctor,
  };

  const lazyType: LazyComponent<T, Payload<T>> = {
    $$typeof: REACT_LAZY_TYPE,
    _payload: payload,
    _init: lazyInitializer,
  };

  if (__DEV__) {
    // In production, this would just set it on the object.
    let defaultProps;
    let propTypes;
    // $FlowFixMe
    Object.defineProperties(lazyType, {
      defaultProps: {
        configurable: true,
        get() {
          return defaultProps;
        },
        set(newDefaultProps) {
          console.error(
            'React.lazy(...): It is not supported to assign `defaultProps` to ' +
              'a lazy component import. Either specify them where the component ' +
              'is defined, or create a wrapping component around it.',
          );
          defaultProps = newDefaultProps;
          // Match production behavior more closely:
          // $FlowFixMe
          Object.defineProperty(lazyType, 'defaultProps', {
            enumerable: true,
          });
        },
      },
      propTypes: {
        configurable: true,
        get() {
          return propTypes;
        },
        set(newPropTypes) {
          console.error(
            'React.lazy(...): It is not supported to assign `propTypes` to ' +
              'a lazy component import. Either specify them where the component ' +
              'is defined, or create a wrapping component around it.',
          );
          propTypes = newPropTypes;
          // Match production behavior more closely:
          // $FlowFixMe
          Object.defineProperty(lazyType, 'propTypes', {
            enumerable: true,
          });
        },
      },
    });
  }

  return lazyType;
}
<commit_msg>break up import keyword to avoid being accidentally parsed as dynamic import statement in external code (#21918)<commit_after>/**
 * Copyright (c) Facebook, Inc. and its affiliates.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 *
 * @flow
 */

import type {Wakeable, Thenable} from 'shared/ReactTypes';

import {REACT_LAZY_TYPE} from 'shared/ReactSymbols';

const Uninitialized = -1;
const Pending = 0;
const Resolved = 1;
const Rejected = 2;

type UninitializedPayload<T> = {
  _status: -1,
  _result: () => Thenable<{default: T, ...}>,
};

type PendingPayload = {
  _status: 0,
  _result: Wakeable,
};

type ResolvedPayload<T> = {
  _status: 1,
  _result: {default: T},
};

type RejectedPayload = {
  _status: 2,
  _result: mixed,
};

type Payload<T> =
  | UninitializedPayload<T>
  | PendingPayload
  | ResolvedPayload<T>
  | RejectedPayload;

export type LazyComponent<T, P> = {
  $$typeof: Symbol | number,
  _payload: P,
  _init: (payload: P) => T,
};

function lazyInitializer<T>(payload: Payload<T>): T {
  if (payload._status === Uninitialized) {
    const ctor = payload._result;
    const thenable = ctor();
    // Transition to the next state.
    // This might throw either because it's missing or throws. If so, we treat it
    // as still uninitialized and try again next time. Which is the same as what
    // happens if the ctor or any wrappers processing the ctor throws. This might
    // end up fixing it if the resolution was a concurrency bug.
    thenable.then(
      moduleObject => {
        if (payload._status === Pending || payload._status === Uninitialized) {
          // Transition to the next state.
          const resolved: ResolvedPayload<T> = (payload: any);
          resolved._status = Resolved;
          resolved._result = moduleObject;
        }
      },
      error => {
        if (payload._status === Pending || payload._status === Uninitialized) {
          // Transition to the next state.
          const rejected: RejectedPayload = (payload: any);
          rejected._status = Rejected;
          rejected._result = error;
        }
      },
    );
    if (payload._status === Uninitialized) {
      // In case, we're still uninitialized, then we're waiting for the thenable
      // to resolve. Set it as pending in the meantime.
      const pending: PendingPayload = (payload: any);
      pending._status = Pending;
      pending._result = thenable;
    }
  }
  if (payload._status === Resolved) {
    const moduleObject = payload._result;
    if (__DEV__) {
      if (moduleObject === undefined) {
        console.error(
          'lazy: Expected the result of a dynamic imp' +
            'ort() call. ' +
            'Instead received: %s\n\nYour code should look like: \n  ' +
            // Break up imports to avoid accidentally parsing them as dependencies.
            'const MyComponent = lazy(() => imp' +
            "ort('./MyComponent'))\n\n" +
            'Did you accidentally put curly braces around the import?',
          moduleObject,
        );
      }
    }
    if (__DEV__) {
      if (!('default' in moduleObject)) {
        console.error(
          'lazy: Expected the result of a dynamic imp' +
            'ort() call. ' +
            'Instead received: %s\n\nYour code should look like: \n  ' +
            // Break up imports to avoid accidentally parsing them as dependencies.
            'const MyComponent = lazy(() => imp' +
            "ort('./MyComponent'))",
          moduleObject,
        );
      }
    }
    return moduleObject.default;
  } else {
    throw payload._result;
  }
}

export function lazy<T>(
  ctor: () => Thenable<{default: T, ...}>,
): LazyComponent<T, Payload<T>> {
  const payload: Payload<T> = {
    // We use these fields to store the result.
    _status: -1,
    _result: ctor,
  };

  const lazyType: LazyComponent<T, Payload<T>> = {
    $$typeof: REACT_LAZY_TYPE,
    _payload: payload,
    _init: lazyInitializer,
  };

  if (__DEV__) {
    // In production, this would just set it on the object.
    let defaultProps;
    let propTypes;
    // $FlowFixMe
    Object.defineProperties(lazyType, {
      defaultProps: {
        configurable: true,
        get() {
          return defaultProps;
        },
        set(newDefaultProps) {
          console.error(
            'React.lazy(...): It is not supported to assign `defaultProps` to ' +
              'a lazy component import. Either specify them where the component ' +
              'is defined, or create a wrapping component around it.',
          );
          defaultProps = newDefaultProps;
          // Match production behavior more closely:
          // $FlowFixMe
          Object.defineProperty(lazyType, 'defaultProps', {
            enumerable: true,
          });
        },
      },
      propTypes: {
        configurable: true,
        get() {
          return propTypes;
        },
        set(newPropTypes) {
          console.error(
            'React.lazy(...): It is not supported to assign `propTypes` to ' +
              'a lazy component import. Either specify them where the component ' +
              'is defined, or create a wrapping component around it.',
          );
          propTypes = newPropTypes;
          // Match production behavior more closely:
          // $FlowFixMe
          Object.defineProperty(lazyType, 'propTypes', {
            enumerable: true,
          });
        },
      },
    });
  }

  return lazyType;
}
<|endoftext|>


<commit_before>// @flow

import * as React from 'react';
import PropTypes from 'prop-types';
import invariant from 'invariant';

import API from 'swarm-api';
import type {Value} from 'swarm-api';

type Props = {
  to: Array<string>,
  swarm?: API,
  children?: ({
    unsubscribe: () => void,
    initialized: boolean,
    swarm: ?API,
    data: {[string]: Value},
  }) => React.Node,
};

type State = {
  initialized: boolean,
  data: {[string]: Value},
};

export default class Subscribe extends React.Component<Props, State> {
  swarm: ?API;
  cbks: {[string]: (Value) => void};

  constructor(props: Props, context: {swarm: ?API}) {
    super(props, context);
    this.swarm = context.swarm || this.props.swarm;
    invariant(
      this.swarm,
      `Could not find "swarm" in either the context or ` +
        `props of <Subscribe>. ` +
        `Either wrap the root component in a <Provider>, ` +
        `or explicitly pass "swarm" as a prop to <Subscribe>.`,
    );
    this.cbks = {};
    this.state = {
      initialized: !!this.swarm && !!this.swarm.client.clock,
      data: {},
    };

    if (!this.state.initialized && !!this.swarm) {
      this.swarm
        .ensure()
        .then(() => {
          this._subscribe();
          this.setState({initialized: true});
        })
        .catch(e => console.error(e));
    } else {
      this._subscribe();
    }

    // $FlowFixMe
    this._unsubscribe = this._unsubscribe.bind(this);
  }

  _subscribe(): void {
    if (!this.swarm) return;
    for (const k of this.props.to) {
      this.cbks[k] = (v: Value) => {
        const state = {
          ...this.state,
          data: {
            ...this.state.data,
            [k]: v || null,
          },
        };
        this.setState(state);
      };

      this.swarm && this.swarm.on(k, this.cbks[k]).catch(e => console.error(e));
    }
  }

  componentDidUpdate(prev: Props) {
    if (!shallowEqual(this.props.to, prev.to)) {
      this._unsubscribe();
      this._subscribe();
    }
  }

  componentWillUnmount() {
    this._unsubscribe();
  }

  _unsubscribe(): void {
    for (const k of Object.keys(this.cbks)) {
      if (this.swarm) this.swarm.off(k, this.cbks[k]);
    }
    this.cbks = {};
  }

  _filterData(): {[string]: Value} {
    const ret = {};
    for (const k of this.props.to) {
      ret[k] = this.state.data[k] || null;
    }
    return ret;
  }

  render() {
    return (
      this.props.children &&
      this.props.children.call(null, {
        unsubscribe: this._unsubscribe,
        initialized: this.state.initialized,
        swarm: this.swarm,
        data: this._filterData(),
      })
    );
  }
}

Subscribe.contextTypes = {
  swarm: PropTypes.shape({}).isRequired,
};

function shallowEqual(a: string[], b: string[]): boolean {
  if (!Array.isArray(a) || !Array.isArray(b)) return false;
  if (a === b) return true;
  if (a.length !== b.length) return false;
  for (const item of a) {
    if (b.indexOf(item) === -1) return false;
  }
  return true;
}
<commit_msg>react: propagate errors<commit_after>// @flow

import * as React from 'react';
import PropTypes from 'prop-types';
import invariant from 'invariant';

import API from 'swarm-api';
import type {Value} from 'swarm-api';

type Props = {
  to: Array<string>,
  swarm?: API,
  children?: ({
    unsubscribe: () => void,
    initialized: boolean,
    swarm: ?API,
    data: {[string]: Value},
    error?: Error | string,
  }) => React.Node,
};

type State = {
  initialized: boolean,
  data: {[string]: Value},
  error?: Error | string,
};

export default class Subscribe extends React.Component<Props, State> {
  swarm: ?API;
  cbks: {[string]: (Value) => void};

  constructor(props: Props, context: {swarm: ?API}) {
    super(props, context);
    this.swarm = context.swarm || this.props.swarm;
    invariant(
      this.swarm,
      `Could not find "swarm" in either the context or ` +
        `props of <Subscribe>. ` +
        `Either wrap the root component in a <Provider>, ` +
        `or explicitly pass "swarm" as a prop to <Subscribe>.`,
    );
    this.cbks = {};
    this.state = {
      initialized: !!this.swarm && !!this.swarm.client.clock,
      data: {},
    };

    if (!this.state.initialized && !!this.swarm) {
      this.swarm
        .ensure()
        .then(() => {
          this._subscribe();
          this.setState({initialized: true});
        })
        .catch(error => {
          this.setState({error});
        });
    } else {
      this._subscribe();
    }

    // $FlowFixMe
    this._unsubscribe = this._unsubscribe.bind(this);
  }

  _subscribe(): void {
    if (!this.swarm) return;
    for (const k of this.props.to) {
      this.cbks[k] = (v: Value) => {
        const state = {
          ...this.state,
          data: {
            ...this.state.data,
            [k]: v || null,
          },
        };
        this.setState(state);
      };

      this.swarm &&
        this.swarm.on(k, this.cbks[k]).catch(error => {
          this.setState({error});
        });
    }
  }

  componentDidUpdate(prev: Props) {
    if (!shallowEqual(this.props.to, prev.to)) {
      this._unsubscribe();
      this._subscribe();
    }
  }

  componentWillUnmount() {
    this._unsubscribe();
  }

  _unsubscribe(): void {
    for (const k of Object.keys(this.cbks)) {
      if (this.swarm) this.swarm.off(k, this.cbks[k]);
    }
    this.cbks = {};
  }

  _filterData(): {[string]: Value} {
    const ret = {};
    for (const k of this.props.to) {
      ret[k] = this.state.data[k] || null;
    }
    return ret;
  }

  render() {
    return (
      this.props.children &&
      this.props.children.call(null, {
        unsubscribe: this._unsubscribe,
        initialized: this.state.initialized,
        swarm: this.swarm,
        data: this._filterData(),
      })
    );
  }
}

Subscribe.contextTypes = {
  swarm: PropTypes.shape({}).isRequired,
};

function shallowEqual(a: string[], b: string[]): boolean {
  if (!Array.isArray(a) || !Array.isArray(b)) return false;
  if (a === b) return true;
  if (a.length !== b.length) return false;
  for (const item of a) {
    if (b.indexOf(item) === -1) return false;
  }
  return true;
}
<|endoftext|>


<commit_before>/**
 * Created by 77dfeba on 2015/11/19.
 */
$(document).ready(function(){
    $('#gscbcbtn').click(function(){
        var a11 = $('#angle1').val();
        var a12 = $('#angle2').val();
        var a21 = $('#angle3').val();
        var a22 = $('#angle4').val();
        var k = $('#k').val();
        var a11z = parseInt(a11);
        var a12z = parseInt(a12);
        var a21z = parseInt(a21);
        var a22z = parseInt(a22);
        var a11c = 100*(a11-a11z)+a11z*60;alert(a11c);
        var a12c = 100*(a12-a12z)+a12z*60;alert(a12c);
        var a21c = 100*(a21-a21z)+a21z*60;alert(a21c);
        var a22c = 100*(a22-a22z)+a22z*60;alert(a22c);
        var c = Math.abs(0.25*(a21c - a11c + a22c - a12c));
        c = c/60/180*Math.PI;
        var l = 0.0001*Math.sin(c)/k*Math.pow(10,9);
        $("#record").append("
 "+a11+"	 " +
            ""+a12+"	"  +
            ""+a21+"	 " +
            ""+a22+"	"  +
            ""+ l.toFixed(4)+"	 " +
            "
");
    });
});
<commit_msg>Revert "提交"<commit_after>/**
 * Created by 77dfeba on 2015/11/19.
 */
$(document).ready(function(){
    $('#gscbcbtn').click(function(){
        var a11 = $('#angle1').val();
        var a12 = $('#angle2').val();
        var a21 = $('#angle3').val();
        var a22 = $('#angle4').val();
        var k = $('#k').val();
        var a11z = parseInt(a11);
        var a12z = parseInt(a12);
        var a21z = parseInt(a21);
        var a22z = parseInt(a22);
        var a11c = 100*(a11-a11z)+a11z*60;alert(a11c);
        var a12c = 100*(a12-a12z)+a12z*60;alert(a12c);
        var a21c = 100*(a21-a21z)+a21z*60;alert(a21c);
        var a22c = 100*(a22-a22z)+a22z*60;alert(a22c);
        var c = Math.abs(0.25*(a21c - a11c + a22c - a12c));alert(c);
        c = c/60/180*Math.PI;alert(c);
        var l = 0.0001*Math.sin(c)/k*Math.pow(10,9);
        $("#record").append("
 "+a11+"	 " +
            ""+a12+"	"  +
            ""+a21+"	 " +
            ""+a22+"	"  +
            ""+ l.toFixed(4)+"	 " +
            "
");
    });
});
<|endoftext|>