<commit_before>(function () {
    var $window = $(window);
    var $fileInput = $('#fileInput');
    var $preview = $('#preview');
    var $rotatekButtonWrapper = $('.rotate-button-wrapper');
    var $rotateButton = $('#rotateButton');
    var $facebookButtonWrapper = $('.fb-button-wrapper');
    var $facebookButton = $('#facebookButton');
    var $fileButtonWrapper = $('.file-button-wrapper');
    var $fileButton = $('#fileButton');
    var $downloadButtonWrapper = $('.download-button-wrapper');
    var $downloadButton = $('#downloadButton');
    var $restartButtonWrapper = $('.restart-button-wrapper');
    var $restartButton = $('#restartButton');
    var $loading = $('#loading');
    var $downloadFrame = $('#downloadFrame');
    var $title = $('.title');
    var $description = $('.description');
    var rotateCount = 0;
    var deferredUserImage = null;
    var deferredCandleImage = $.Deferred(function (deferred) {
        var candleImage = new Image();
        candleImage.src = '/img/candle.png';
        candleImage.onload = function () {
            deferred.resolve(this);
        };
    });
    var getDeferredCount = function () {
        return $.ajax('https://aidenahn.herokuapp.com/count', {dataType: 'json'})
            .then(function (result) {
                return result.count;
            });
    };

    var getDeferredUserImage = function (src, origin) {
        return $.Deferred(function (deferred) {
            var userImage = new Image();
            if (origin) userImage.setAttribute('crossOrigin', origin);
            userImage.setAttribute('src', src);
            userImage.onload = function () {
                deferred.resolve(this);
            };
        });
    };

    var getDeferredDataURI = function (file) {
        return $.Deferred(function (deferred) {
            var reader = new FileReader();
            reader.readAsDataURL(file);

            //로드 한 후
            reader.onload = function () {
                deferred.resolve(reader.result);
            };
        });
    };

    //사용자 이미지와 촛불 이미지를 합성해서 리턴
    var getImageDataURI = function (userImage, candleImage) {
        //캔버스 생성
        var canvas = document.createElement('canvas');
        canvas.width = 500; //가로 100px
        canvas.height = 500; //세로 100px
        var context = canvas.getContext('2d');
        context.globalCompositeOperation = 'source-over';

        context.save();

        //캔버스 회전
        context.translate(canvas.width / 2, canvas.height / 2);
        context.rotate(rotateCount * 90 * Math.PI / 180);
        context.translate(-canvas.width / 2, -canvas.height / 2);

        //정사각형
        if (userImage.width === userImage.height) {
            //이미지를 캔버스에 그리기
            context.drawImage(userImage, 0, 0, 500, 500);
        }
        //가로가 긴 경우 -> 세로를 기준으로
        else if (userImage.width > userImage.height) {
            var ratio = 500 / userImage.height;
            var width = Math.round(userImage.width * ratio);
            var widthMargin = -Math.round((width - 500) / 2);

            //이미지를 캔버스에 그리기
            context.drawImage(userImage, widthMargin, 0, width, 500);
        }
        //세로가 긴 경우 -> 가로를 기준으로
        else {
            var ratio = 500 / userImage.width;
            var height = Math.round(userImage.height * ratio);
            var heightMargin = -Math.round((height - 500) / 2);

            //이미지를 캔버스에 그리기
            context.drawImage(userImage, 0, heightMargin, 500, height);
        }

        context.restore();

        //이미지를 캔버스에 그리기
        context.drawImage(candleImage, 0, 0, 500, 500);

        //캔버스에 그린 이미지를 다시 data-uri 형태로 변환
        return canvas.toDataURL('image/png');
    };

    var createProfile = function () {
        $loading.show();

        $.when(deferredUserImage, deferredCandleImage, getDeferredCount())
        .then(function (userImage, candleImage, count) {

            //썸네일 이미지 보여주기
            $preview.attr('src', getImageDataURI(userImage, candleImage));

            $title.html(count + ' 번째
촛불이 밝혀졌습니다');
            $description.html('이미지를 다운로드 받으신 후
SNS에서 반드시 재업로드 하셔야 합니다.');
            $facebookButtonWrapper.hide();
            $fileButtonWrapper.hide();
            $downloadButtonWrapper.show();
            $restartButtonWrapper.show();
            $rotatekButtonWrapper.show();
            $window.scrollTop(0);

            $loading.hide();
        });
    };

    var rotateProfile = function () {
        $loading.show();

        $.when(deferredUserImage, deferredCandleImage)
        .then(function (userImage, candleImage) {

            //썸네일 이미지 보여주기
            $preview.attr('src', getImageDataURI(userImage, candleImage));
            $loading.hide();
        });
    };

    $fileButton.on('click', function () {
        $fileInput.trigger('click');
    });
    $fileInput.on('change', function () {
        $loading.show();

        getDeferredDataURI(this.files[0])
        .then(function (dataURI) {
            $loading.hide();
            $fileInput.val('');
            deferredUserImage = getDeferredUserImage(dataURI, null);
            createProfile();
        });
    });

    $facebookButton.on('click', function () {
        FB.login(function () {
            $loading.show();
            FB.api('/me/picture?width=500&height=500', function (response) {
                $loading.hide();
                deferredUserImage = getDeferredUserImage(response.data.url, 'anonymous');
                createProfile();
            });
        }, {
            scope: 'user_about_me'
        });
    });

    $rotateButton.on('click', function() {
        rotateCount += 1;
        rotateProfile();
    });

    $restartButton.on('click', function () {
        rotateCount = 0;
        $preview.attr('src', '');
        $title.html('우리의 촛불은
꺼지지 않습니다');
        $description.html('SNS 프로필에 촛불을 밝혀주세요.');
        $facebookButtonWrapper.show();
        $fileButtonWrapper.show();
        $downloadButtonWrapper.hide();
        $restartButtonWrapper.hide();
        $rotatekButtonWrapper.hide();
        $window.scrollTop(0);
    });

    $downloadButton.on('click', function () {
        $loading.show();

        $('<form action="https://aidenahn.herokuapp.com/download" method="post" target="downloadFrame"></form>')
        .append($('<input type="hidden" name="image">').val($preview.attr('src')))
        .appendTo('body').submit().remove();
    });

    $downloadFrame.on('load', function () {
        $loading.hide();
    });
}) ();
<commit_msg>파일 포맷을 jpeg 로 변경<commit_after>(function () {
    var $window = $(window);
    var $fileInput = $('#fileInput');
    var $preview = $('#preview');
    var $rotatekButtonWrapper = $('.rotate-button-wrapper');
    var $rotateButton = $('#rotateButton');
    var $facebookButtonWrapper = $('.fb-button-wrapper');
    var $facebookButton = $('#facebookButton');
    var $fileButtonWrapper = $('.file-button-wrapper');
    var $fileButton = $('#fileButton');
    var $downloadButtonWrapper = $('.download-button-wrapper');
    var $downloadButton = $('#downloadButton');
    var $restartButtonWrapper = $('.restart-button-wrapper');
    var $restartButton = $('#restartButton');
    var $loading = $('#loading');
    var $downloadFrame = $('#downloadFrame');
    var $title = $('.title');
    var $description = $('.description');
    var rotateCount = 0;
    var deferredUserImage = null;
    var deferredCandleImage = $.Deferred(function (deferred) {
        var candleImage = new Image();
        candleImage.src = '/img/candle.png';
        candleImage.onload = function () {
            deferred.resolve(this);
        };
    });
    var getDeferredCount = function () {
        return $.ajax('https://aidenahn.herokuapp.com/count', {dataType: 'json'})
            .then(function (result) {
                return result.count;
            });
    };

    var getDeferredUserImage = function (src, origin) {
        return $.Deferred(function (deferred) {
            var userImage = new Image();
            if (origin) userImage.setAttribute('crossOrigin', origin);
            userImage.setAttribute('src', src);
            userImage.onload = function () {
                deferred.resolve(this);
            };
        });
    };

    var getDeferredDataURI = function (file) {
        return $.Deferred(function (deferred) {
            var reader = new FileReader();
            reader.readAsDataURL(file);

            //로드 한 후
            reader.onload = function () {
                deferred.resolve(reader.result);
            };
        });
    };

    //사용자 이미지와 촛불 이미지를 합성해서 리턴
    var getImageDataURI = function (userImage, candleImage) {
        //캔버스 생성
        var canvas = document.createElement('canvas');
        canvas.width = 500; //가로 100px
        canvas.height = 500; //세로 100px
        var context = canvas.getContext('2d');
        context.globalCompositeOperation = 'source-over';

        context.save();

        //캔버스 회전
        context.translate(canvas.width / 2, canvas.height / 2);
        context.rotate(rotateCount * 90 * Math.PI / 180);
        context.translate(-canvas.width / 2, -canvas.height / 2);

        //정사각형
        if (userImage.width === userImage.height) {
            //이미지를 캔버스에 그리기
            context.drawImage(userImage, 0, 0, 500, 500);
        }
        //가로가 긴 경우 -> 세로를 기준으로
        else if (userImage.width > userImage.height) {
            var ratio = 500 / userImage.height;
            var width = Math.round(userImage.width * ratio);
            var widthMargin = -Math.round((width - 500) / 2);

            //이미지를 캔버스에 그리기
            context.drawImage(userImage, widthMargin, 0, width, 500);
        }
        //세로가 긴 경우 -> 가로를 기준으로
        else {
            var ratio = 500 / userImage.width;
            var height = Math.round(userImage.height * ratio);
            var heightMargin = -Math.round((height - 500) / 2);

            //이미지를 캔버스에 그리기
            context.drawImage(userImage, 0, heightMargin, 500, height);
        }

        context.restore();

        //이미지를 캔버스에 그리기
        context.drawImage(candleImage, 0, 0, 500, 500);

        //캔버스에 그린 이미지를 다시 data-uri 형태로 변환
        return canvas.toDataURL('image/jpeg', 0.9);
    };

    var createProfile = function () {
        $loading.show();

        $.when(deferredUserImage, deferredCandleImage, getDeferredCount())
        .then(function (userImage, candleImage, count) {

            //썸네일 이미지 보여주기
            $preview.attr('src', getImageDataURI(userImage, candleImage));

            $title.html(count + ' 번째
촛불이 밝혀졌습니다');
            $description.html('이미지를 다운로드 받으신 후
SNS에서 반드시 재업로드 하셔야 합니다.');
            $facebookButtonWrapper.hide();
            $fileButtonWrapper.hide();
            $downloadButtonWrapper.show();
            $restartButtonWrapper.show();
            $rotatekButtonWrapper.show();
            $window.scrollTop(0);

            $loading.hide();
        });
    };

    var rotateProfile = function () {
        $loading.show();

        $.when(deferredUserImage, deferredCandleImage)
        .then(function (userImage, candleImage) {

            //썸네일 이미지 보여주기
            $preview.attr('src', getImageDataURI(userImage, candleImage));
            $loading.hide();
        });
    };

    $fileButton.on('click', function () {
        $fileInput.trigger('click');
    });
    $fileInput.on('change', function () {
        $loading.show();

        getDeferredDataURI(this.files[0])
        .then(function (dataURI) {
            $loading.hide();
            $fileInput.val('');
            deferredUserImage = getDeferredUserImage(dataURI, null);
            createProfile();
        });
    });

    $facebookButton.on('click', function () {
        FB.login(function () {
            $loading.show();
            FB.api('/me/picture?width=500&height=500', function (response) {
                $loading.hide();
                deferredUserImage = getDeferredUserImage(response.data.url, 'anonymous');
                createProfile();
            });
        }, {
            scope: 'user_about_me'
        });
    });

    $rotateButton.on('click', function() {
        rotateCount += 1;
        rotateProfile();
    });

    $restartButton.on('click', function () {
        rotateCount = 0;
        $preview.attr('src', '');
        $title.html('우리의 촛불은
꺼지지 않습니다');
        $description.html('SNS 프로필에 촛불을 밝혀주세요.');
        $facebookButtonWrapper.show();
        $fileButtonWrapper.show();
        $downloadButtonWrapper.hide();
        $restartButtonWrapper.hide();
        $rotatekButtonWrapper.hide();
        $window.scrollTop(0);
    });

    $downloadButton.on('click', function () {
        $loading.show();

        $('<form action="https://aidenahn.herokuapp.com/download" method="post" target="downloadFrame"></form>')
        .append($('<input type="hidden" name="image">').val($preview.attr('src')))
        .appendTo('body').submit().remove();
    });

    $downloadFrame.on('load', function () {
        $loading.hide();
    });
}) ();
<|endoftext|>


<commit_before>(function($) {
  var ZoomableType = function(element) {
    this.copy     = null;
    this.original = element.bind('click.z', this, function(e) {
      if (e.data.copy) return;
      e.data.zoom();
      e.stopPropagation();
    });
  }

  $.extend(ZoomableType.prototype, {
    zoom: function() {
      this.copy = $('<span>', {className: 'zoomed'})
        .text(this.original.text())
        .appendTo('body')
        .bind('click.z', function(e) { e.stopPropagation(); });

      this.resize();

      $(document).bind('click.z keyup.z', this, function(e) { e.data.shrink(); });
      $(window).bind('resize.z', this, function(e) { e.data.resize(); });
    },

    shrink: function() {
      this.copy.remove();
      this.copy = null;

      $(document).unbind('.z');
      $(window).unbind('.z');
    },

    resize: function() {
      var w = $(window),
          wScale = w.width() * 0.9 / this.original.width(),
          hScale = w.height() * 0.9 / this.original.height();

      this.copy.css({
        fontSize: (wScale < hScale ? wScale : hScale) * 100 + '%'
      });
    }
  });

  $.fn.zoomabletype = function() {
    return this.each(function() { new ZoomableType($(this)); });
  }
})(jQuery);
<commit_msg>Stylize and cache document + window<commit_after>(function($) {
  var ZoomableType = {
    d: $(document),
    w: $(window),

    Element: function(element) {
      this.copy     = null;
      this.original = element.bind('click.zt', this, function(e) {
        if (this.copy != null) return;
        e.data.zoom();
        e.stopPropagation();
      });
    }
  }

  $.extend(ZoomableType.Element.prototype, {
    zoom: function() {
      this.copy = $('<span>', {className: 'zoomed'})
        .text(this.original.text())
        .appendTo('body')
        .bind('click.zt', function(e) { e.stopPropagation(); });

      this.resize();

      ZoomableType.d.bind('click.zt keyup.zt', this, function(e) {
        if (!e.keyCode || e.keyCode == 27) e.data.shrink();
      });
      ZoomableType.w.bind('resize.zt', this, function(e) {
        e.data.resize();
      });
    },

    shrink: function() {
      this.copy.remove();
      this.copy = null;

      ZoomableType.d.unbind('.zt');
      ZoomableType.w.unbind('.zt');
    },

    resize: function() {
      var width  = ZoomableType.w.width() * 0.9 / this.original.width() * 100,
          height = ZoomableType.w.height() * 0.9 / this.original.height() * 100;

      this.copy.css('font-size', (width < height ? width : height) + '%');
      this.stylize().center();
    },

    stylize: function() {
      var radius = this.copy.outerWidth() * 0.02;

      this.copy.css({
        padding: radius,
        webkitBorderRadius: radius,
        mozBorderRadius: radius,
        borderRadius: radius,
        textShadow: '#000 2px 2px ' + radius + 'px'
      });

      return this;
    },

    center: function() {
      this.copy.css({
        position: 'fixed',
        left: (ZoomableType.w.width() - this.copy.outerWidth()) / 2,
        top: (ZoomableType.w.height() - this.copy.outerHeight()) / 2
      });

      return this;
    }
  });

  $.fn.zoomabletype = function() {
    return this.each(function() { new ZoomableType.Element($(this)); });
  }
})(jQuery);
<|endoftext|>


<commit_before>/**
 * Copyright 2013 Ricard Aspeljung. All Rights Reserved.
 *
 * rest.js
 * crest
 */

var MongoClient = require("mongodb").MongoClient,
  BSON = require("mongodb").BSONPure,
  server = module.parent.exports.server,
  config = module.parent.exports.config,
  debug = module.parent.exports.debug,
  restify = module.parent.exports.restify,
  util = require("./util").util;

debug("rest.js is loaded");

/**
 * Query
 */
function handleGet(req, res, next) {
  debug("GET-request recieved");
  var query;
  // Providing an id overwrites giving a query in the URL
  if (req.params.id) {
    query = {
      '_id': new BSON.ObjectID(req.params.id)
    };
  } else {
    query = req.query.query ? util.parseJSON(req.query.query, next, restify) : {};
  }
  var options = req.params.options || {};

  var test = ['limit', 'sort', 'fields', 'skip', 'hint', 'explain', 'snapshot', 'timeout'];

  var v;
  for (v in req.query) {
    if (test.indexOf(v) !== -1) {
      options[v] = req.query[v];
    }
  }

  if (req.body.toString().length > 0) {
    var body = req.body.split(",");
    if (body[0]) {
      query = util.parseJSON(body[0], next);
    }
    if (body[1]) {
      options = util.parseJSON(body[1], next);
    }
  }

  MongoClient.connect(util.connectionURL(req.params.db, util.getAuthenticationFromRequest(req), config), function (err, db) {
    db.collection(req.params.collection, function (err, collection) {
      collection.find(query, options, function (err, cursor) {
        console.log('Query: '+JSON.stringify(query));
        cursor.toArray(function (err, docs) {

          if(err){
            console.log(err);
            res.json(500,err);
          }else{
            var result = [];
            if (req.params.id) {
              if (docs.length > 0) {
                result = util.flavorize(docs[0], "out");
                res.json(result, {'content-type': 'application/json; charset=utf-8'});
              } else {
                res.json(404);
              }
            } else {
              docs.forEach(function (doc) {
                result.push(util.flavorize(doc, "out"));
              });
              res.json(result, {'content-type': 'application/json; charset=utf-8'});
            }
          }
          db.close();
        });
      });
    });
  });
}

server.get('/:db/:collection/:id?', handleGet);
server.get('/:db/:collection', handleGet);

/**
 * Insert
 */
server.post('/:db/:collection', function (req, res) {
  debug("POST-request recieved");
  if (req.params) {
    MongoClient.connect(util.connectionURL(req.params.db, util.getAuthenticationFromRequest(req), config), function (err, db) {
      var collection = db.collection(req.params.collection);
      // We only support inserting one document at a time
      collection.insert(Array.isArray(req.params) ? util.cleanParams(req.params[0]) : util.cleanParams(req.params), function (err, docs) {
        res.header('Location', '/' + req.params.db + '/' + req.params.collection + '/' + docs[0]._id.toHexString());
        res.set('content-type', 'application/json; charset=utf-8');
        res.json(201, {"ok": 1});
        db.close();
      });
    });
  } else {
    res.set('content-type', 'application/json; charset=utf-8');
    res.json(200, {"ok": 0});
  }
});

/**
 * Update
 */
server.put('/:db/:collection/:id', function (req, res) {
  debug("PUT-request recieved");
  var spec = {
    '_id': new BSON.ObjectID(req.params.id)
  };
  MongoClient.connect(util.connectionURL(req.params.db, util.getAuthenticationFromRequest(req), config), function (err, db) {
    db.collection(req.params.collection, function (err, collection) {
      collection.update(spec, util.cleanParams(req.params), true, function (err, docs) {
        res.set('content-type', 'application/json; charset=utf-8');
        res.json({"ok": 1});
      });
    });
  });
});

/**
 * Delete
 */
server.del('/:db/:collection/:id', function (req, res) {
  debug("DELETE-request recieved");
  var spec = {
    '_id': new BSON.ObjectID(req.params.id)
  };
  MongoClient.connect(util.connectionURL(req.params.db, util.getAuthenticationFromRequest(req), config), function (err, db) {
    db.collection(req.params.collection, function (err, collection) {
      collection.remove(spec, function (err, docs) {
        res.set('content-type', 'application/json; charset=utf-8');
        res.json({"ok": 1});
        db.close();
      });
    });
  });
});
<commit_msg>initial commit<commit_after>/**
 * Copyright 2013 Ricard Aspeljung. All Rights Reserved.
 *
 * rest.js
 * crest
 */

var MongoClient = require("mongodb").MongoClient,
  BSON = require("mongodb").BSONPure,
  server = module.parent.exports.server,
  config = module.parent.exports.config,
  debug = module.parent.exports.debug,
  restify = module.parent.exports.restify,
  util = require("./util").util;

debug("rest.js is loaded");

/**
 * Query
 */
function handleGet(req, res, next) {
  debug("GET-request recieved");
  var query;
  // Providing an id overwrites giving a query in the URL
  if (req.params.id) {
    query = {
      '_id': new BSON.ObjectID(req.params.id)
    };
  } else {
    query = req.query.query ? util.parseJSON(req.query.query, next, restify) : {};
  }
  var options = req.params.options || {};

  var test = ['limit', 'sort', 'fields', 'skip', 'hint', 'explain', 'snapshot', 'timeout'];

  var v;
  for (v in req.query) {
    if (test.indexOf(v) !== -1) {
      options[v] = req.query[v];
    }
  }

  if (req.body.toString().length > 0) {
    var body = req.body.split(",");
    if (body[0]) {
      query = util.parseJSON(body[0], next);
    }
    if (body[1]) {
      options = util.parseJSON(body[1], next);
    }
  }

  MongoClient.connect(util.connectionURL(req.params.db, util.getAuthenticationFromRequest(req), config), function (err, db) {
    db.collection(req.params.collection, function (err, collection) {
      collection.find(query, options, function (err, cursor) {
        console.log('Query: '+JSON.stringify(query));
        cursor.toArray(function (err, docs) {
          console.log(docs);
          if(err){
            console.log(err);
            res.json(500,err);
          }else{
            var result = [];
            if (req.params.id) {
              if (docs.length > 0) {
                result = util.flavorize(docs[0], "out");
                res.json(result, {'content-type': 'application/json; charset=utf-8'});
              } else {
                res.json(404);
              }
            } else {
              docs.forEach(function (doc) {
                result.push(util.flavorize(doc, "out"));
              });
              res.json(result, {'content-type': 'application/json; charset=utf-8'});
            }
          }
          db.close();
        });
      });
    });
  });
}

server.get('/:db/:collection/:id?', handleGet);
server.get('/:db/:collection', handleGet);

/**
 * Insert
 */
server.post('/:db/:collection', function (req, res) {
  debug("POST-request recieved");
  if (req.params) {
    MongoClient.connect(util.connectionURL(req.params.db, util.getAuthenticationFromRequest(req), config), function (err, db) {
      var collection = db.collection(req.params.collection);
      // We only support inserting one document at a time
      collection.insert(Array.isArray(req.params) ? util.cleanParams(req.params[0]) : util.cleanParams(req.params), function (err, docs) {
        res.header('Location', '/' + req.params.db + '/' + req.params.collection + '/' + docs[0]._id.toHexString());
        res.set('content-type', 'application/json; charset=utf-8');
        res.json(201, {"ok": 1});
        db.close();
      });
    });
  } else {
    res.set('content-type', 'application/json; charset=utf-8');
    res.json(200, {"ok": 0});
  }
});

/**
 * Update
 */
server.put('/:db/:collection/:id', function (req, res) {
  debug("PUT-request recieved");
  var spec = {
    '_id': new BSON.ObjectID(req.params.id)
  };
  MongoClient.connect(util.connectionURL(req.params.db, util.getAuthenticationFromRequest(req), config), function (err, db) {
    db.collection(req.params.collection, function (err, collection) {
      collection.update(spec, util.cleanParams(req.params), true, function (err, docs) {
        res.set('content-type', 'application/json; charset=utf-8');
        res.json({"ok": 1});
      });
    });
  });
});

/**
 * Delete
 */
server.del('/:db/:collection/:id', function (req, res) {
  debug("DELETE-request recieved");
  var spec = {
    '_id': new BSON.ObjectID(req.params.id)
  };
  MongoClient.connect(util.connectionURL(req.params.db, util.getAuthenticationFromRequest(req), config), function (err, db) {
    db.collection(req.params.collection, function (err, collection) {
      collection.remove(spec, function (err, docs) {
        res.set('content-type', 'application/json; charset=utf-8');
        res.json({"ok": 1});
        db.close();
      });
    });
  });
});
<|endoftext|>


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

  $('.home-button')
    .on('click', function(){
      event.preventDefault();
      $('html,body').animate({scrollTop: 0}, 500);
    });

  $('.main-buttons')
    .on('click', 'a[href^="#"]', function(){
      event.preventDefault();
      var scrollTo = $($(this).attr('href')).offset().top;
      $('html,body').animate({scrollTop: scrollTo}, 500);
    });

  $('.circle')
    .on('click', function(){
      event.preventDefault();
      var scrollPort = $('#portfolio').offset().top;
      $('html,body').animate({scrollTop: scrollPort}, 500);
    });

  $('.navbar-nav li a').click(function(){
    var open = $('.navbar-toggle').is(':visible');
    if (open){
      $('.navbar-collapse').collapse('hide');
    }
  });

  $('.project')
    .on('mouseenter', 'div', function(){
      $(this).siblings().animate({
        opacity: .5
      });
    })
    .on('mouseleave', 'div', function(){
      $(this).siblings().animate({
        opacity: 1
      });
    })

  $('#older-portfolio')
    .on('click', function(){
      $('#older-portfolio-modal').modal('toggle');
    });

  $('#explore-outdoors')
    .on('click', function(){
      $('#explore-outdoors-modal').modal('toggle');
    });

  $('#iron-pong')
    .on('click', function(){
      $('#iron-pong-modal').modal('toggle');
    });

  $('.blog-post')
    .on('click', 'h4', function(){
      $(this).siblings().toggleClass('show');
    });

})();
<commit_msg>changed .animate to .css for mouseleave event on portfolio project thumbnails, removes delay in opacity that was previously occuring if scrolling too quickly<commit_after>(function() {
  'use strict';

  $('.home-button')
    .on('click', function(){
      event.preventDefault();
      $('html,body').animate({scrollTop: 0}, 500);
    });

  $('.main-buttons')
    .on('click', 'a[href^="#"]', function(){
      event.preventDefault();
      var scrollTo = $($(this).attr('href')).offset().top;
      $('html,body').animate({scrollTop: scrollTo}, 500);
    });

  $('.circle')
    .on('click', function(){
      event.preventDefault();
      var scrollPort = $('#portfolio').offset().top;
      $('html,body').animate({scrollTop: scrollPort}, 500);
    });

  $('.navbar-nav li a').click(function(){
    var open = $('.navbar-toggle').is(':visible');
    if (open){
      $('.navbar-collapse').collapse('hide');
    }
  });

  $('.project')
    .on('mouseenter', 'div', function(){
      $(this).siblings().animate({
        opacity: .5
      });
    })
    .on('mouseleave', 'div', function(){
      $(this).siblings().css({
        opacity: 1
      });
    })

  $('#older-portfolio')
    .on('click', function(){
      $('#older-portfolio-modal').modal('toggle');
    });

  $('#explore-outdoors')
    .on('click', function(){
      $('#explore-outdoors-modal').modal('toggle');
    });

  $('#iron-pong')
    .on('click', function(){
      $('#iron-pong-modal').modal('toggle');
    });

  $('.blog-post')
    .on('click', 'h4', function(){
      $(this).siblings().toggleClass('show');
    });

})();
<|endoftext|>


<commit_before>//Translated from hunter.rb using babyruby2js
'use strict';

var main = require('../../main');

var Grid = require('../../Grid');
var Heuristic = require('./Heuristic');
var inherits = require('util').inherits;

var ALWAYS = main.ALWAYS;

/** @class Hunters find threats to struggling enemy groups.
 *  Ladder attack fits in here. */
function Hunter(player) {
    Heuristic.call(this, player);

    this.takeLifeCoeff = this.getGene('takeLife', 1, 0.01, 2);

    this.snapbacks = null;
}
inherits(Hunter, Heuristic);
module.exports = Hunter;

/** Returns true if group g could get at least minLives by killing one of the
 *  enemy groups around in atari
 */
Hunter.prototype._gotLivesFromKillingAround = function (g, minLives) {
    var enemies = g.allEnemies();
    for (var n = enemies.length - 1; n >= 0; n--) {
        var eg = enemies[n];
        if (eg.lives > 1) continue;
        // found 1 enemy group in atari; killing it would give us its size in new lives
        var addedLives = eg.stones.length;
        if (addedLives >= minLives) return true;
        // this is not enough, so count lives we would get by connecting with our groups around eg
        var allies = eg.allEnemies();
        for (var a = allies.length - 1; a >= 0; a--) {
            addedLives += allies[a].lives - 1;
            if (addedLives >= minLives) return true;
        }
    }
    return false;
};

var KO_KILL_SCORE = 1;

/** Returns a score to measure what kind of kill a move is.
 *  Any number < 1.01 is sign of a "not so good" kill.
 *  E.g. in this board, black c5 has a bad "kill score" of 1.0001
 *  5 O@+OO
 *  4 O@O@+
 *  3 OO@@+
 *  2 ++@++
 *  1 ++@++
 *    abcde
 *  NB: kill score of a KO is 1 (KO_KILL_SCORE)
 */
Hunter.prototype._killScore = function (empty, color) {
    var numAllies = 0, numKill = 0, life = 0;
    for (var i = empty.neighbors.length - 1; i >= 0; i--) {
        var n = empty.neighbors[i];
        switch (n.color) {
        case main.EMPTY:
            life += 0.01;
            break;
        case color: // ally
            life += (n.group.lives - 1) * 0.01;
            if (n.group.isAlive === ALWAYS) life += 2;
            numAllies += 0.0001;
            break;
        default: // enemy
            if (n.group.lives > 1) break; // not a kill
            numKill += n.group.stones.length;
        }
    }
    return numKill + life + numAllies;
};

Hunter.prototype._countAtariThreat = function (enemies, level) {
    var atariThreat = 0, eg;
    for (var egNdx = enemies.length - 1; egNdx >= 0; egNdx--) {
        eg = enemies[egNdx];
        if (eg.lives !== 1) continue;
        // if we can take eg anytime later, no need to take it now
        //TODO also verify no group in "enemies" is strong
        if (!level && this._isAtariGroupCaught(eg, level) && !this._gotLivesFromKillingAround(eg, 1)) {
            continue;
        }
        atariThreat += this.groupThreat(eg);
    }
    return atariThreat;
};

Hunter.prototype._countPreAtariThreat = function (stone, enemies, empties, color, level, egroups) {
    var snapback = false, eg;
    var allies = stone.uniqueAllies(color);
    // now look for groups with 2 lives
    for (var egNdx = enemies.length - 1; egNdx >= 0; egNdx--) {
        eg = enemies[egNdx];
        if (eg.lives !== 2) continue;
        // no good if enemy can escape by killing one of our weak groups around
        if (this._gotLivesFromKillingAround(eg, 2)) continue; // >=2 because killing 1 stone is not enough to escape
        // same but for the group of our new stone; if should not become atari either
        if (empties.length === 0 && allies.length === 1 && allies[0].lives === 2) continue;

        if (empties.length === 1 && allies.length === 0) {
            // unless this is a snapback, this is a dumb move
            // it is a snapback if the last empty point (where the enemy will have to play)
            // would not make the enemy group connect to another enemy group
            // (equivalent to: the empty point has no other enemy group as neighbor)
            var enemiesAroundEmpty = empties[0].uniqueAllies(eg.color);
            if (enemiesAroundEmpty.length !== 1 || enemiesAroundEmpty[0] !== eg) {
                continue;
            }
            // here we know this is a snapback
            snapback = true;
            if (main.debug) main.log.debug('Hunter ' + Grid.colorName(color) + ' sees a snapback in ' + stone);
        }
        if (main.debug) main.log.debug('Hunter ' + Grid.colorName(color) + '(level ' + level + ') looking at threat ' + stone + ' on ' + eg);
        egroups.push(eg);
    }
    return snapback;
};

Hunter.prototype._countSimplePressure = function (enemies) {
    var threat = 0;
    for (var egNdx = enemies.length - 1; egNdx >= 0; egNdx--) {
        var egl = enemies[egNdx].lives;
        if (egl >= 2) threat += 1 / (egl + 1);
    }
    return threat * this.takeLifeCoeff;
};

Hunter.prototype._beforeEvalBoard = function () {
    this.snapbacks = [];
};

Hunter.prototype._evalMove = function (i, j, color, level) {
    level = level || 0;
    var stone = this.goban.stoneAt(i, j);
    var empties = stone.empties();
    var enemies = stone.uniqueEnemies(color);

    // count groups already in atari
    var threat1 = this._countAtariThreat(enemies, level);

    // count some profit in removing enemy lives
    if(level === 0) threat1 += this._countSimplePressure(enemies);

    // now look for groups with 2 lives
    var egroups = [];
    var snapback = this._countPreAtariThreat(stone, enemies, empties, color, level, egroups);
    if (level === 0 && snapback) {
        this.snapbacks.push(stone); // for other heuristics to look at...
    }
    // unless snapback, make sure our new stone's group can survive
    if (!snapback && empties.length <= 1) {
        var killScore = this._killScore(stone, color); //TODO: make this easier!
        if (killScore !== KO_KILL_SCORE &&
            (killScore < 0.02 || (killScore > 1 && killScore < 1.01))) {
            return 0; // REVIEW ME: return threat1 does not penalize snapback victim enough
        }
    }
    if (!egroups.length) return threat1;

    this.goban.tryAt(i, j, color); // our attack takes one of the 2 last lives (the one in i,j)

    // see attacks that fail
    var canEscape = [false, false, false];
    for (var g = egroups.length - 1; g >= 0; g--) {
        if (this._isAtariGroupCaught(egroups[g], level)) continue;
        if (egroups.length === 1) { egroups.pop(); break; }
        canEscape[g] = true;
    }

    this.goban.untry(); // important to undo before, so we compute threat right

    var threat2 = this._getMultipleChaseThreat(egroups, canEscape);

    if (main.debug && (threat1 || threat2)) main.log.debug('Hunter ' + Grid.colorName(color) +
        ' found a threat of ' + threat1 + ' + ' + threat2 + ' at ' + Grid.xy2move(i, j));
    return threat1 + threat2;
};

function basicSort(a, b) { return a - b; }

/** Returns the maximum threat we can hope for when several groups can be chased.
 *  Some of these chases might fail, but even so, the enemy can only defend one.
 *  Rule of thumb:
 *  - if 0 can escape => we capture the bigger one
 *  - if　1 or more can escape => we capture nothing if only 1, or the 2nd bigger if the 1st can escape
 */
Hunter.prototype._getMultipleChaseThreat = function (egroups, canEscape) {
    switch (egroups.length) {
    case 0: return 0;
    case 1: return canEscape[0] ? 0 : this.groupThreat(egroups[0]);
    case 2:
        if (!canEscape[0] && !canEscape[1]) return Math.max(this.groupThreat(egroups[0]), this.groupThreat(egroups[1]));
        if ( canEscape[0] &&  canEscape[1]) return Math.min(this.groupThreat(egroups[0]), this.groupThreat(egroups[1]));
        return canEscape[0] ? this.groupThreat(egroups[1]) : this.groupThreat(egroups[0]);
    case 3:
        var threats = [this.groupThreat(egroups[0]), this.groupThreat(egroups[1]), this.groupThreat(egroups[2])];
        if (!canEscape[0] && !canEscape[1] && !canEscape[2]) return Math.max(threats[0], threats[1], threats[2]);
        var sortedThreats = threats.concat().sort(basicSort);
        var bigger = threats.indexOf(sortedThreats[0]);
        if (!canEscape[bigger]) return threats[bigger];
        var secondBigger = threats.indexOf(sortedThreats[1]);
        return threats[secondBigger];
    default: throw new Error('Unexpected in Hunter#getMultipleChaseThreat');
    }
};

/** Evaluates if group g in atari (1 last escape move) can escape */
Hunter.prototype._isAtariGroupCaught = function (g, level) {
    var allLives = g.allLives();
    if (allLives.length !== 1) throw new Error('Unexpected: hunter #1: ' + allLives.length);

    var lastLife = allLives[0];
    var stone = this.goban.tryAt(lastLife.i, lastLife.j, g.color); // enemy's escape move
    var isCaught = this._escapingAtariThreat(stone, level) > 0;
    this.goban.untry();
    if (main.debug) main.log.debug('Hunter: group with last life ' + lastLife + ' would ' + (isCaught ? 'be caught: ' : 'escape: ') + g);
    return isCaught;
};

/** Returns true if played stone has put a nearby enemy group in atari */
Hunter.prototype._isStoneCreatingAtari = function (stone) {
    var enemyColor = 1 - stone.color;
    var neighbors = stone.neighbors;
    for (var n = neighbors.length - 1; n >= 0; n--) {
        if (neighbors[n].color !== enemyColor) continue;
        if (neighbors[n].group.lives === 1) {
            return true;
        }
    }
    return false;
};

/** @param stone is the enemy group's escape move (just been played)
 *  @param [level] - just to keep track for logging purposes
 *  @return the best score possible by chasing stone's group (could be the killing of a bystander though)
 */
Hunter.prototype._escapingAtariThreat = function (stone, level) {
    var g = stone.group;
    if (g.lives <= 1) return this.groupThreat(g); // caught
    if (g.lives > 2) {
        return 0; //TODO look better
    }
    // g.lives is 2

    // if escape move just put one of our groups in atari the chase fails
    if (this._isStoneCreatingAtari(stone)) return 0;

    // get 2 possible escape moves
    var empties = stone.empties();
    if (empties.length !== 2) {
        empties = g.allLives();
    }
    if (empties.length !== 2) throw new Error('Unexpected: hunter #2');
    var e1 = empties[0];
    var e2 = empties[1];
    if (main.debug) main.log.debug('Hunter: group has 2 lives left: ' + e1 + ' and ' + e2);

    // try blocking the 2 moves (recursive descent)
    var color = 1 - g.color;
    level = (level || 0) + 1;
    return Math.max(this._evalMove(e1.i, e1.j, color, level), this._evalMove(e2.i, e2.j, color, level));
};

/** @param stone is the enemy group's escape move (just been played)
 *  @return true if the group gets captured
 */
Hunter.prototype.isEscapingAtariCaught = function (stone) {
    return this._escapingAtariThreat(stone, 1);
};

Hunter.prototype.catchThreat = function (i, j, color) {
    return this._evalMove(i, j, color, 1);
};

/** Called by other heuristics to know if a stone is a snapback for current move */
Hunter.prototype.isSnapback = function (stone) {
    return this.snapbacks.indexOf(stone) !== -1;
};
<commit_msg>minor rename<commit_after>//Translated from hunter.rb using babyruby2js
'use strict';

var main = require('../../main');

var Grid = require('../../Grid');
var Heuristic = require('./Heuristic');
var inherits = require('util').inherits;

var ALWAYS = main.ALWAYS;

/** @class Hunters find threats to struggling enemy groups.
 *  Ladder attack fits in here. */
function Hunter(player) {
    Heuristic.call(this, player);

    this.takeLifeCoeff = this.getGene('takeLife', 1, 0.01, 2);

    this.snapbacks = null;
}
inherits(Hunter, Heuristic);
module.exports = Hunter;

/** Returns true if group g could get at least minLives by killing one of the
 *  enemy groups around in atari
 */
Hunter.prototype._gotLivesFromKillingAround = function (g, minLives) {
    var enemies = g.allEnemies();
    for (var n = enemies.length - 1; n >= 0; n--) {
        var eg = enemies[n];
        if (eg.lives > 1) continue;
        // found 1 enemy group in atari; killing it would give us its size in new lives
        var addedLives = eg.stones.length;
        if (addedLives >= minLives) return true;
        // this is not enough, so count lives we would get by connecting with our groups around eg
        var allies = eg.allEnemies();
        for (var a = allies.length - 1; a >= 0; a--) {
            addedLives += allies[a].lives - 1;
            if (addedLives >= minLives) return true;
        }
    }
    return false;
};

var KO_KILL_SCORE = 1;

/** Returns a score to measure what kind of kill a move is.
 *  Any number < 1.01 is sign of a "not so good" kill.
 *  E.g. in this board, black c5 has a bad "kill score" of 1.0001
 *  5 O@+OO
 *  4 O@O@+
 *  3 OO@@+
 *  2 ++@++
 *  1 ++@++
 *    abcde
 *  NB: kill score of a KO is 1 (KO_KILL_SCORE)
 */
Hunter.prototype._killScore = function (empty, color) {
    var numAllies = 0, numKill = 0, life = 0;
    for (var i = empty.neighbors.length - 1; i >= 0; i--) {
        var n = empty.neighbors[i];
        switch (n.color) {
        case main.EMPTY:
            life += 0.01;
            break;
        case color: // ally
            life += (n.group.lives - 1) * 0.01;
            if (n.group.isAlive === ALWAYS) life += 2;
            numAllies += 0.0001;
            break;
        default: // enemy
            if (n.group.lives > 1) break; // not a kill
            numKill += n.group.stones.length;
        }
    }
    return numKill + life + numAllies;
};

Hunter.prototype._countAtariThreat = function (enemies, level) {
    var atariThreat = 0, eg;
    for (var egNdx = enemies.length - 1; egNdx >= 0; egNdx--) {
        eg = enemies[egNdx];
        if (eg.lives !== 1) continue;
        // if we can take eg anytime later, no need to take it now
        //TODO also verify no group in "enemies" is strong
        if (!level && this._isAtariGroupCaught(eg, level) && !this._gotLivesFromKillingAround(eg, 1)) {
            continue;
        }
        atariThreat += this.groupThreat(eg);
    }
    return atariThreat;
};

Hunter.prototype._countPreAtariThreat = function (stone, enemies, empties, color, level, egroups) {
    var isSnapback = false, eg;
    var allies = stone.uniqueAllies(color);
    // now look for groups with 2 lives
    for (var egNdx = enemies.length - 1; egNdx >= 0; egNdx--) {
        eg = enemies[egNdx];
        if (eg.lives !== 2) continue;
        // no good if enemy can escape by killing one of our weak groups around
        if (this._gotLivesFromKillingAround(eg, 2)) continue; // >=2 because killing 1 stone is not enough to escape
        // same but for the group of our new stone; if should not become atari either
        if (empties.length === 0 && allies.length === 1 && allies[0].lives === 2) continue;

        if (empties.length === 1 && allies.length === 0) {
            // unless this is a snapback, this is a dumb move
            // it is a snapback if the last empty point (where the enemy will have to play)
            // would not make the enemy group connect to another enemy group
            // (equivalent to: the empty point has no other enemy group as neighbor)
            var enemiesAroundEmpty = empties[0].uniqueAllies(eg.color);
            if (enemiesAroundEmpty.length !== 1 || enemiesAroundEmpty[0] !== eg) {
                continue;
            }
            // here we know this is a snapback
            isSnapback = true;
            if (main.debug) main.log.debug('Hunter ' + Grid.colorName(color) + ' sees a snapback in ' + stone);
        }
        if (main.debug) main.log.debug('Hunter ' + Grid.colorName(color) + '(level ' + level + ') looking at threat ' + stone + ' on ' + eg);
        egroups.push(eg);
    }
    return isSnapback;
};

Hunter.prototype._countSimplePressure = function (enemies) {
    var threat = 0;
    for (var egNdx = enemies.length - 1; egNdx >= 0; egNdx--) {
        var egl = enemies[egNdx].lives;
        if (egl >= 2) threat += 1 / (egl + 1);
    }
    return threat * this.takeLifeCoeff;
};

Hunter.prototype._beforeEvalBoard = function () {
    this.snapbacks = [];
};

Hunter.prototype._evalMove = function (i, j, color, level) {
    level = level || 0;
    var stone = this.goban.stoneAt(i, j);
    var empties = stone.empties();
    var enemies = stone.uniqueEnemies(color);

    // count groups already in atari
    var threat1 = this._countAtariThreat(enemies, level);

    // count some profit in removing enemy lives
    if(level === 0) threat1 += this._countSimplePressure(enemies);

    // now look for groups with 2 lives
    var egroups = [];
    var snapback = this._countPreAtariThreat(stone, enemies, empties, color, level, egroups);
    if (level === 0 && snapback) {
        this.snapbacks.push(stone); // for other heuristics to look at...
    }
    // unless snapback, make sure our new stone's group can survive
    if (!snapback && empties.length <= 1) {
        var killScore = this._killScore(stone, color); //TODO: make this easier!
        if (killScore !== KO_KILL_SCORE &&
            (killScore < 0.02 || (killScore > 1 && killScore < 1.01))) {
            return 0; // REVIEW ME: return threat1 does not penalize snapback victim enough
        }
    }
    if (!egroups.length) return threat1;

    this.goban.tryAt(i, j, color); // our attack takes one of the 2 last lives (the one in i,j)

    // see attacks that fail
    var canEscape = [false, false, false];
    for (var g = egroups.length - 1; g >= 0; g--) {
        if (this._isAtariGroupCaught(egroups[g], level)) continue;
        if (egroups.length === 1) { egroups.pop(); break; }
        canEscape[g] = true;
    }

    this.goban.untry(); // important to undo before, so we compute threat right

    var threat2 = this._getMultipleChaseThreat(egroups, canEscape);

    if (main.debug && (threat1 || threat2)) main.log.debug('Hunter ' + Grid.colorName(color) +
        ' found a threat of ' + threat1 + ' + ' + threat2 + ' at ' + Grid.xy2move(i, j));
    return threat1 + threat2;
};

function basicSort(a, b) { return a - b; }

/** Returns the maximum threat we can hope for when several groups can be chased.
 *  Some of these chases might fail, but even so, the enemy can only defend one.
 *  Rule of thumb:
 *  - if 0 can escape => we capture the bigger one
 *  - if　1 or more can escape => we capture nothing if only 1, or the 2nd bigger if the 1st can escape
 */
Hunter.prototype._getMultipleChaseThreat = function (egroups, canEscape) {
    switch (egroups.length) {
    case 0: return 0;
    case 1: return canEscape[0] ? 0 : this.groupThreat(egroups[0]);
    case 2:
        if (!canEscape[0] && !canEscape[1]) return Math.max(this.groupThreat(egroups[0]), this.groupThreat(egroups[1]));
        if ( canEscape[0] &&  canEscape[1]) return Math.min(this.groupThreat(egroups[0]), this.groupThreat(egroups[1]));
        return canEscape[0] ? this.groupThreat(egroups[1]) : this.groupThreat(egroups[0]);
    case 3:
        var threats = [this.groupThreat(egroups[0]), this.groupThreat(egroups[1]), this.groupThreat(egroups[2])];
        if (!canEscape[0] && !canEscape[1] && !canEscape[2]) return Math.max(threats[0], threats[1], threats[2]);
        var sortedThreats = threats.concat().sort(basicSort);
        var bigger = threats.indexOf(sortedThreats[0]);
        if (!canEscape[bigger]) return threats[bigger];
        var secondBigger = threats.indexOf(sortedThreats[1]);
        return threats[secondBigger];
    default: throw new Error('Unexpected in Hunter#getMultipleChaseThreat');
    }
};

/** Evaluates if group g in atari (1 last escape move) can escape */
Hunter.prototype._isAtariGroupCaught = function (g, level) {
    var allLives = g.allLives();
    if (allLives.length !== 1) throw new Error('Unexpected: hunter #1: ' + allLives.length);

    var lastLife = allLives[0];
    var stone = this.goban.tryAt(lastLife.i, lastLife.j, g.color); // enemy's escape move
    var isCaught = this._escapingAtariThreat(stone, level) > 0;
    this.goban.untry();
    if (main.debug) main.log.debug('Hunter: group with last life ' + lastLife + ' would ' + (isCaught ? 'be caught: ' : 'escape: ') + g);
    return isCaught;
};

/** Returns true if played stone has put a nearby enemy group in atari */
Hunter.prototype._isStoneCreatingAtari = function (stone) {
    var enemyColor = 1 - stone.color;
    var neighbors = stone.neighbors;
    for (var n = neighbors.length - 1; n >= 0; n--) {
        if (neighbors[n].color !== enemyColor) continue;
        if (neighbors[n].group.lives === 1) {
            return true;
        }
    }
    return false;
};

/** @param stone is the enemy group's escape move (just been played)
 *  @param [level] - just to keep track for logging purposes
 *  @return the best score possible by chasing stone's group (could be the killing of a bystander though)
 */
Hunter.prototype._escapingAtariThreat = function (stone, level) {
    var g = stone.group;
    if (g.lives <= 1) return this.groupThreat(g); // caught
    if (g.lives > 2) {
        return 0; //TODO look better
    }
    // g.lives is 2

    // if escape move just put one of our groups in atari the chase fails
    if (this._isStoneCreatingAtari(stone)) return 0;

    // get 2 possible escape moves
    var empties = stone.empties();
    if (empties.length !== 2) {
        empties = g.allLives();
    }
    if (empties.length !== 2) throw new Error('Unexpected: hunter #2');
    var e1 = empties[0];
    var e2 = empties[1];
    if (main.debug) main.log.debug('Hunter: group has 2 lives left: ' + e1 + ' and ' + e2);

    // try blocking the 2 moves (recursive descent)
    var color = 1 - g.color;
    level = (level || 0) + 1;
    return Math.max(this._evalMove(e1.i, e1.j, color, level), this._evalMove(e2.i, e2.j, color, level));
};

/** @param stone is the enemy group's escape move (just been played)
 *  @return true if the group gets captured
 */
Hunter.prototype.isEscapingAtariCaught = function (stone) {
    return this._escapingAtariThreat(stone, 1);
};

Hunter.prototype.catchThreat = function (i, j, color) {
    return this._evalMove(i, j, color, 1);
};

/** Called by other heuristics to know if a stone is a snapback for current move */
Hunter.prototype.isSnapback = function (stone) {
    return this.snapbacks.indexOf(stone) !== -1;
};
<|endoftext|>


<commit_before>var _         = require('underscore'),
    ginga     = require('ginga'),
    params    = ginga.params,
    timestamp = require('monotonic-timestamp'),
    util      = require('./util'),
    queue     = require('./queue'),
    mapper    = require('./mapper');

function Roda(base, name){
  this.base = base;
  this.store = base.db.sublevel(name);

  this._name = name;
  this._clock = this.store.sublevel('clock');
  this._changes = this.store.sublevel('changes');
}
var R = ginga(Roda.prototype);

//util

R.name = function(){
  return this._name;
};

R.queue = queue;
R.mapper = mapper;

//Read
R.define('get', params('id:string','tx:object?'), function(ctx, done){
  if(ctx.params.tx && ctx.params.tx.db === this.base.db){
    ctx.params.tx.get(
      ctx.params.id, { prefix: this.store }, done
    );
  }else{
    this.store.get(ctx.params.id, done);
  }
});

R.createReadStream = function(options){
  //todo: prefix range
  return this.store.createValueStream(options);
};

R.createChangesStream = function(options){

};

R.define('clock', function(ctx, done){
  var result = {};
  this._clock.createReadStream()
    .on('data', function(data){
      result[data.key] = data.value;
    })
    .on('error', function(err){
      done(err, null);
    })
    .on('close', function(){
      done(null, result);
    });
});

//Hooks

R.define('validate', params('result'), function(ctx, next){
  ctx.result = _.clone(ctx.params.result);
  next();
}, function(ctx, done){
  done(null, ctx.result);
});

R.define('diff', params('current', 'result', 'tx'), function(ctx, next){
  ctx.current = ctx.params.current;
  ctx.result = _.clone(ctx.params.result);
  ctx.transaction = ctx.params.tx;
  next();
}, function(ctx, done){
  done(null, ctx.transaction);
});

//Write

function validate(ctx, next){
  this.validate(
    ctx.params.result,
    function(err, result){
      if(err) return next(err);

      ctx.result = result;
      next();
    }
  );
}

function prepare(ctx, next, end){
  //init transaction
  if(ctx.params.tx){
    if(ctx.params.tx.db !== this.base.db)
      return next(new Error('Transaction must be within the same database'));
    ctx.transaction = ctx.params.tx;
  }else{
    ctx.transaction = this.base.transaction();
  }
  //defer transaction for this method
  ctx.transaction.defer(end);

  //prepare result
  ctx.result = ctx.result || {};

  if('id' in ctx.params)
    ctx.result._id = ctx.params.id;
  else if(!ctx.result._id){
    //generate _id = monotonic timestamp encode + mid
    ctx.result._id = util.encode(timestamp()) + this.base.id();
  }
  var deleted = (!ctx.params.result) && ('id' in ctx.params);

  if(deleted)
    ctx.result._deleted = true;
  else
    delete ctx.result._deleted;

  next();
}
function current(ctx, next){
  this.get(ctx.result._id, ctx.transaction, function(err, res){
    if(res){
      ctx.current = res;
      //remove current change
      ctx.transaction.del(ctx.current._rev, {
        prefix: this._changes
      });
    }
    //todo: next if notfound error, otherwise real error
    next();
  });
}

function rev(ctx, next){
  var mid = this.base.id();

  ctx.transaction.get(
    mid, { prefix: this._clock },
    function(err, res){
      //increment
      var inc = util.encode(Math.max(
        res ? util.decode(res) : 0,
        ctx.current ? util.decode(ctx.current._rev.slice(8)) : 0
      ) + 1);

      //generate rev id (mid + inc)
      ctx.result._rev = mid + inc;

      //lamport clock update
      ctx.transaction.put(mid, inc, {
        prefix: this._clock
      });

      next();
    }
  );
}

function diff(ctx, next){
  this.diff(
    ctx.current || null,
    ctx.result._deleted ? null: ctx.result,
    ctx.transaction,
    function(err, res){
      if(err) return next(err);

      next();
    }
  );
}

function put(ctx, next){
  ctx.transaction
    .put(ctx.result._id, ctx.result, {
      prefix: this.store
    })
    .put(ctx.result._rev, ctx.result, {
      prefix: this._changes
    });
  next();
}

function del(ctx, next){
  ctx.transaction
    .del(ctx.result._id, {
      prefix: this.store
    })
    .put(ctx.result._rev, ctx.result, {
      prefix: this._changes
    });
  next();
}

function invoke(ctx, done){
  var result = _.clone(ctx.result);
  if(ctx.params.tx){
    //batched not yet committed
    done(null, result);
  }else{
    ctx.transaction.commit(function(err){
      if(err) done(err, null);
      else done(null, result);
    });
  }
}

R.define(
  'put', params('id:string?','result:object','tx:object?'),
  validate, prepare, current, rev, diff, put, invoke
);
R.define(
  'del', params('id:string','tx:object?'),
  prepare, current, rev, diff, del, invoke
);

module.exports = Roda;
<commit_msg>clean up<commit_after>var _         = require('underscore'),
    ginga     = require('ginga'),
    params    = ginga.params,
    timestamp = require('monotonic-timestamp'),
    util      = require('./util'),
    queue     = require('./queue'),
    mapper    = require('./mapper');

function Roda(base, name){
  this.base = base;
  this.store = base.db.sublevel(name);

  this._name = name;
  this._clock = this.store.sublevel('clock');
  this._changes = this.store.sublevel('changes');
}
var R = ginga(Roda.prototype);

//util

R.name = function(){
  return this._name;
};

R.queue = queue;
R.mapper = mapper;

//Read
R.define('get', params('id:string','tx:object?'), function(ctx, done){
  if(ctx.params.tx && ctx.params.tx.db === this.base.db){
    ctx.params.tx.get(
      ctx.params.id, { prefix: this.store }, done
    );
  }else{
    this.store.get(ctx.params.id, done);
  }
});

R.createReadStream = function(options){
  //todo: prefix range
  return this.store.createValueStream(options);
};

R.createChangesStream = function(options){

};

R.define('clock', function(ctx, done){
  var result = {};
  this._clock.createReadStream()
    .on('data', function(data){
      result[data.key] = data.value;
    })
    .on('error', function(err){
      done(err, null);
    })
    .on('close', function(){
      done(null, result);
    });
});

//Hooks

R.define('validate', params('result'), function(ctx, next){
  ctx.result = _.clone(ctx.params.result);
  next();
}, function(ctx, done){
  done(null, ctx.result);
});

R.define('diff', params('current', 'result', 'tx'), function(ctx, next){
  ctx.current = ctx.params.current;
  ctx.result = _.clone(ctx.params.result);
  ctx.transaction = ctx.params.tx;
  next();
}, function(ctx, done){
  done(null, ctx.transaction);
});

//Write

function validate(ctx, next){
  this.validate(
    ctx.params.result,
    function(err, result){
      if(err) return next(err);

      ctx.result = result;
      next();
    }
  );
}

function prepare(ctx, next, end){
  //init transaction
  if(ctx.params.tx){
    if(ctx.params.tx.db !== this.base.db)
      return next(new Error('Transaction must be within the same database'));
    ctx.transaction = ctx.params.tx;
  }else{
    ctx.transaction = this.base.transaction();
  }
  //defer transaction for this method
  ctx.transaction.defer(end);

  //prepare result
  ctx.result = ctx.result || {};

  if('id' in ctx.params)
    ctx.result._id = ctx.params.id;
  else if(!ctx.result._id){
    //generate _id = monotonic timestamp encode + mid
    ctx.result._id = util.encode(timestamp()) + this.base.id();
  }
  var deleted = (!ctx.params.result) && ('id' in ctx.params);

  if(deleted)
    ctx.result._deleted = true;
  else
    delete ctx.result._deleted;

  next();
}
function current(ctx, next){
  this.get(ctx.result._id, ctx.transaction, function(err, res){
    if(res){
      ctx.current = res;
      //remove current change
      ctx.transaction.del(ctx.current._rev, {
        prefix: this._changes
      });
    }
    //todo: next if notfound error, otherwise real error
    next();
  });
}

function rev(ctx, next){
  var mid = this.base.id();

  ctx.transaction.get(
    mid, { prefix: this._clock },
    function(err, res){
      //lamport timestamp
      var time = util.encode(Math.max(
        res ? util.decode(res) : 0,
        ctx.current ? util.decode(ctx.current._rev.slice(8)) : 0
      ) + 1);

      //generate rev id
      ctx.result._rev = mid + time;

      //lamport clock update
      ctx.transaction.put(mid, time, {
        prefix: this._clock
      });

      next();
    }
  );
}

function diff(ctx, next){
  this.diff(
    ctx.current || null,
    ctx.result._deleted ? null: ctx.result,
    ctx.transaction,
    function(err, res){
      if(err) return next(err);

      next();
    }
  );
}

function put(ctx, next){
  ctx.transaction
    .put(ctx.result._id, ctx.result, {
      prefix: this.store
    })
    .put(ctx.result._rev, ctx.result, {
      prefix: this._changes
    });
  next();
}

function del(ctx, next){
  ctx.transaction
    .del(ctx.result._id, {
      prefix: this.store
    })
    .put(ctx.result._rev, ctx.result, {
      prefix: this._changes
    });
  next();
}

function invoke(ctx, done){
  var result = _.clone(ctx.result);
  if(ctx.params.tx){
    //batched not yet committed
    done(null, result);
  }else{
    ctx.transaction.commit(function(err){
      if(err) done(err, null);
      else done(null, result);
    });
  }
}

R.define(
  'put', params('id:string?','result:object','tx:object?'),
  validate, prepare, current, rev, diff, put, invoke
);
R.define(
  'del', params('id:string','tx:object?'),
  prepare, current, rev, diff, del, invoke
);

module.exports = Roda;
<|endoftext|>


<commit_before>/* ============================================================
 * bootstrap-buttons.js v2.0.0
 * http://twitter.github.com/bootstrap/javascript.html#buttons
 * ============================================================
 * Copyright 2011 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ============================================================ */

!function( $ ){

  "use strict"

 /* BUTTON PUBLIC CLASS DEFINITION
  * ============================== */

  var Button = function ( element, options ) {
    this.$element = $(element)
    this.options = $.extend({}, $.fn.button.defaults, options)
  }

  Button.prototype = {

      constructor: Button

    , setState: function ( state ) {
        var d = 'disabled'
          , $el = this.$element
          , data = $el.data()
          , val = $el.is('input') ? 'val' : 'html'

        state = state + 'Text'
        data.resetText || $el.data('resetText', $el[val]())

        $el[val](data[state] || this.options[state])

        // push to event loop to allow forms to submit
        setTimeout(function () {
          state == 'loadingText' ?
            $el.addClass(d).attr(d, d) :
            $el.removeClass(d).removeAttr(d)
        }, 0)
      }

    , toggle: function () {
        var $parent = this.$element.parent('[data-toggle="buttons-radio"]')

        $parent && $parent
          .find('.active')
          .removeClass('active')

        this.$element.toggleClass('active')
      }

  }

 /* BUTTON PLUGIN DEFINITION
  * ======================== */

  $.fn.button = function ( option ) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('button')
        , options = typeof option == 'object' && option
      if (!data) $this.data('button', (data = new Button(this, options)))
      if (option == 'toggle') data.toggle()
      else if (option) data.setState(option)
    })
  }

  $.fn.button.defaults = {
    loadingText: 'loading...'
  }

  $.fn.button.Constructor = Button

 /* BUTTON DATA-API
  * =============== */

  $(function () {
    $('body').on('click.button.data-api', '[data-toggle^=button]', function ( e ) {
      $(e.srcElement).button('toggle')
    })
  })

}( window.jQuery )<commit_msg>fix buttons for firefox<commit_after>/* ============================================================
 * bootstrap-buttons.js v2.0.0
 * http://twitter.github.com/bootstrap/javascript.html#buttons
 * ============================================================
 * Copyright 2011 Twitter, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * ============================================================ */

!function( $ ){

  "use strict"

 /* BUTTON PUBLIC CLASS DEFINITION
  * ============================== */

  var Button = function ( element, options ) {
    this.$element = $(element)
    this.options = $.extend({}, $.fn.button.defaults, options)
  }

  Button.prototype = {

      constructor: Button

    , setState: function ( state ) {
        var d = 'disabled'
          , $el = this.$element
          , data = $el.data()
          , val = $el.is('input') ? 'val' : 'html'

        state = state + 'Text'
        data.resetText || $el.data('resetText', $el[val]())

        $el[val](data[state] || this.options[state])

        // push to event loop to allow forms to submit
        setTimeout(function () {
          state == 'loadingText' ?
            $el.addClass(d).attr(d, d) :
            $el.removeClass(d).removeAttr(d)
        }, 0)
      }

    , toggle: function () {
        var $parent = this.$element.parent('[data-toggle="buttons-radio"]')

        $parent && $parent
          .find('.active')
          .removeClass('active')

        this.$element.toggleClass('active')
      }

  }

 /* BUTTON PLUGIN DEFINITION
  * ======================== */

  $.fn.button = function ( option ) {
    return this.each(function () {
      var $this = $(this)
        , data = $this.data('button')
        , options = typeof option == 'object' && option
      if (!data) $this.data('button', (data = new Button(this, options)))
      if (option == 'toggle') data.toggle()
      else if (option) data.setState(option)
    })
  }

  $.fn.button.defaults = {
    loadingText: 'loading...'
  }

  $.fn.button.Constructor = Button

 /* BUTTON DATA-API
  * =============== */

  $(function () {
    $('body').on('click.button.data-api', '[data-toggle^=button]', function ( e ) {
      $(e.target).button('toggle')
    })
  })

}( window.jQuery )<|endoftext|>


<commit_before>define([
           'dojo/_base/declare',
           'dojo/query',

	   	   'dijit/form/Button',
           'JBrowse/Plugin'
       ],
       function(
           declare,
           query,

		   dijitButton,
           JBrowsePlugin
       ) {
return declare( JBrowsePlugin,
{
    constructor: function( args ) {

		var thisBrowser = this.browser;
        var makeFull = this.makeFullscreenButton();

		if (!document.mozFullScreenEnabled
			&& !document.webkitFullScreenEnabled
			&& !document.webkitFullscreenEnabled
			&& !document.msFullScreenEnabled
			&& !document.msFullscreenEnabled
			&& !document.fullScreenEnabled
			&& !document.fullscreenEnabled
		   ){
				console.log("fullscreen is not supported by your browser.");
				return;
			}

		thisBrowser.afterMilestone('initView', function() {

			var myMenu = thisBrowser.menuBar;

        	console.log( "fullscreen plugin starting" );

			myMenu.appendChild(makeFull);

		})

		console.log( "fullscreen plugin added" );
	},

    makeFullscreenButton: function () {

	var goFull = function(){
		var ele = document.body;
		var doc = document;
		// Recent api changes mean that browser might be looking for Fullscreen
		// or FullScreen

		if(		!doc.fullscreen
			&& 	!doc.fullScreen
			&& 	!doc.msFullscreenElement
			&& 	!doc.msFullScreenElement
			&& 	!doc.mozFullScreen
			&& 	!doc.webkitFullscreenElement
			&& 	!doc.webkitFullScreenElement){

			console.log("entering fullscreen");

			if (ele.requestFullScreen){
				ele.requestFullScreen();
			} else if (ele.requestFullscreen){
				ele.requestFullscreen();
			} else if (ele.msRequestFullScreen){
				ele.msRequestFullScreen();
			} else if (ele.msRequestFullscreen){
				ele.msRequestFullscreen();
			} else if (ele.mozRequestFullScreen){
				ele.mozRequestFullScreen();
			} else if (ele.webkitRequestFullScreen){
				ele.webkitRequestFullScreen();
			} else if (ele.webkitRequestFullscreen){
				ele.webkitRequestfullscreen();
			}
		// If already fullscreen toggle
		 } else {

		 	console.log("closing fullscreen");

		 	if (doc.exitFullScreen){
		 		doc.exitFullScreen();
		 	} else if (doc.exitFullscreen){
		 		doc.exitFullscreen();
		 	} else if (doc.msExitFullScreen){
		 		doc.msExitFullScreen();
		 	} else if (doc.msExitFullscreen){
		 		doc.msExitFullscreen();
		 	} else if (doc.mozCancelFullScreen){
		 		doc.mozCancelFullScreen();
		 	} else if (doc.webkitExitFullScreen){
		 		doc.webkitExitFullScreen();
		 	} else if (doc.webkitExitFullscreen){
		 		doc.webkitExitFullscreen();
			}
		 }
	};

	var selectFullButton = new dijitButton({
		className :"fullscreen-button",
		innerHTML:"Fullscreen",
		title: "Enable Fullscreen",
		onClick : function(){

			goFull();

		}
	});

	return selectFullButton.domNode;
    }
});
});
<commit_msg>added outerTrackColor automatically<commit_after>define([
           'dojo/_base/declare',
           'dojo/query',

	   	   'dijit/form/Button',
           'JBrowse/Plugin'
       ],
       function(
           declare,
           query,

		   dijitButton,
           JBrowsePlugin
       ) {
return declare( JBrowsePlugin,
{
    constructor: function( args ) {

		var thisBrowser = this.browser;
        var makeFull = this.makeFullscreenButton();

		if (!document.mozFullScreenEnabled
			&& !document.webkitFullScreenEnabled
			&& !document.webkitFullscreenEnabled
			&& !document.msFullScreenEnabled
			&& !document.msFullscreenEnabled
			&& !document.fullScreenEnabled
			&& !document.fullscreenEnabled
		   ){
				console.log("fullscreen is not supported by your browser.");
				return;
			}

		thisBrowser.afterMilestone('initView', function() {

			var myMenu = thisBrowser.menuBar;

        		console.log( "fullscreen plugin starting" );

			myMenu.appendChild(makeFull);
			// make certain outerTrackCoutainer actually has a color (white)
			var ot = document.getElementsByClassName("outerTrackContainer");
			ot[0].style.backgroundColor = 'white';
		})

		console.log( "fullscreen plugin added" );
	},

    makeFullscreenButton: function () {

	var goFull = function(){
		var ele = document.body;
		var doc = document;
		// Recent api changes mean that browser might be looking for Fullscreen
		// or FullScreen

		if(		!doc.fullscreen
			&& 	!doc.fullScreen
			&& 	!doc.msFullscreenElement
			&& 	!doc.msFullScreenElement
			&& 	!doc.mozFullScreen
			&& 	!doc.webkitFullscreenElement
			&& 	!doc.webkitFullScreenElement){

			console.log("entering fullscreen");

			if (ele.requestFullScreen){
				ele.requestFullScreen();
			} else if (ele.requestFullscreen){
				ele.requestFullscreen();
			} else if (ele.msRequestFullScreen){
				ele.msRequestFullScreen();
			} else if (ele.msRequestFullscreen){
				ele.msRequestFullscreen();
			} else if (ele.mozRequestFullScreen){
				ele.mozRequestFullScreen();
			} else if (ele.webkitRequestFullScreen){
				ele.webkitRequestFullScreen();
			} else if (ele.webkitRequestFullscreen){
				ele.webkitRequestfullscreen();
			}
		// If already fullscreen toggle
		 } else {

		 	console.log("closing fullscreen");

		 	if (doc.exitFullScreen){
		 		doc.exitFullScreen();
		 	} else if (doc.exitFullscreen){
		 		doc.exitFullscreen();
		 	} else if (doc.msExitFullScreen){
		 		doc.msExitFullScreen();
		 	} else if (doc.msExitFullscreen){
		 		doc.msExitFullscreen();
		 	} else if (doc.mozCancelFullScreen){
		 		doc.mozCancelFullScreen();
		 	} else if (doc.webkitExitFullScreen){
		 		doc.webkitExitFullScreen();
		 	} else if (doc.webkitExitFullscreen){
		 		doc.webkitExitFullscreen();
			}
		 }
	};

	var selectFullButton = new dijitButton({
		className :"fullscreen-button",
		innerHTML:"Fullscreen",
		title: "Enable Fullscreen",
		onClick : function(){

			goFull();

		}
	});

	return selectFullButton.domNode;
    }
});
});
<|endoftext|>


<commit_before>
// Wait for user finishing typing
// callback: The callback function
// wait: The number of milliseconds to wait after the the last key press before firing the callback
// highlight: Highlights the element when it receives focus
// allowSubmit: Allows a non-multiline element to be submitted (enter key) regardless of captureLength
// captureLength: Minimum # of characters necessary to fire the callback

$(document).ready(function() {

	alert("mainjs loaded");
	$('#street').typeWatch({
		captureLength: 2,
		wait: 1750,
    		highlight: true,
		callback: function(value) {
			//alert("typing finished");
			street_to_geo(value);
		}
	});
});

function street_to_geo(street){
      //encodes the street string into url friendly format
      var street_encoded = encodeURIComponent(street);
      var uri = "http://nominatim.openstreetmap.org/search/" + street_encoded + "?format=json";
      //alert(uri);
      //makes the the jquery call and gets json back
      $.getJSON(uri, function(data) {
        //make js obj containing lat and long
        var obj = {latitude: data[0].lat, longitude: data[0].lon};
        alert(obj.latitude + " " + obj.longitude);
        //return obj;
      });
}

function calc_distance(lat1, lon1, lat2, lon2) {
	var unit = "K";
	var radlat1 = Math.PI * lat1/180;
	var radlat2 = Math.PI * lat2/180;
	var theta = lon1-lon2;
	var radtheta = Math.PI * theta/180;
	var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
	dist = Math.acos(dist);
	dist = dist * 180/Math.PI;
	dist = dist * 60 * 1.1515;
	if (unit=="K") { dist = dist * 1.609344; }
	if (unit=="N") { dist = dist * 0.8684; }
	return dist;
}

<commit_msg>Update main.js<commit_after>
// Wait for user to finish typing
// callback: The callback function
// wait: The number of milliseconds to wait after the the last key press before firing the callback
// highlight: Highlights the element when it receives focus
// allowSubmit: Allows a non-multiline element to be submitted (enter key) regardless of captureLength
// captureLength: Minimum # of characters necessary to fire the callback

$(document).ready(function() {

	alert("mainjs loaded");
	$('#street').typeWatch({
		captureLength: 2,
		wait: 1750,
    		highlight: true,
		callback: function(value) {
			//alert("typing finished");
			street_to_geo(value);
		}
	});
});

function street_to_geo(street){
      //encodes the street string into url friendly format
      var street_encoded = encodeURIComponent(street);
      var uri = "http://nominatim.openstreetmap.org/search/" + street_encoded + "?format=json";
      //alert(uri);
      //makes the the jquery call and gets json back
      $.getJSON(uri, function(data) {
        //make js obj containing lat and long
        var obj = {latitude: data[0].lat, longitude: data[0].lon};
        alert(obj.latitude + " " + obj.longitude);
        //return obj;
      });
}

function calc_distance(lat1, lon1, lat2, lon2) {
	var unit = "K";
	var radlat1 = Math.PI * lat1/180;
	var radlat2 = Math.PI * lat2/180;
	var theta = lon1-lon2;
	var radtheta = Math.PI * theta/180;
	var dist = Math.sin(radlat1) * Math.sin(radlat2) + Math.cos(radlat1) * Math.cos(radlat2) * Math.cos(radtheta);
	dist = Math.acos(dist);
	dist = dist * 180/Math.PI;
	dist = dist * 60 * 1.1515;
	if (unit=="K") { dist = dist * 1.609344; }
	if (unit=="N") { dist = dist * 0.8684; }
	return dist;
}

<|endoftext|>


<commit_before>var codingBarrierApp = angular.module('codingBarrierApp', ['ngRoute', 'ngSanitize']);

// configure our routes
codingBarrierApp.config(function ($routeProvider, $locationProvider) {
    $locationProvider.html5Mode(true);

    $routeProvider

            // route for the home page
            .when('/', {
                title: 'Home',
                templateUrl: 'pages/home.html',
                controller: 'mainController'
            })

            // route for the about page
            .when('/resume', {
                title: 'Resume',
                templateUrl: 'pages/resume.html',
                controller: 'resumeController'
            })

            // route for the contact page
            .when('/contact', {
                title: 'Contact',
                templateUrl: 'pages/contact.html',
                controller: 'contactController'
            })

            .when('/blog', {
                title: 'Blog',
                templateUrl: 'pages/blog.html',
                controller: 'blogController'
            })

            .when('/blog/:year/:month/:postPath', {
                title: 'Post | Blog',
                templateUrl: 'pages/blogPost.html',
                controller: 'blogPostController'
            })

            .otherwise({
                title: '404',
                templateUrl: 'pages/404.html',
                controller: 'notFoundController'
            });

});

codingBarrierApp.run(['$rootScope', function ($rootScope) {
        $rootScope.$on('$routeChangeSuccess', function (event, current, previous) {
            $rootScope.title = current.title;
        });
    }]);

// create the controller and inject Angular's $scope
codingBarrierApp.controller('mainController', function ($rootScope, $location) {

    // create a message to display in our view
    $rootScope.header = 'Home Page';
    $rootScope.message = 'Coding Barrier under construction.';
    var fullUrl = $location.absUrl();
    if(fullUrl.indexOf("anthonybarrera.com") > -1){
        $rootScope.siteName = "Anthony Barrera";
    }else{
        $rootScope.siteName = "Coding Barrier";
    }
});

codingBarrierApp.controller('resumeController', function ($rootScope) {
    $rootScope.header = 'Resume';
    $rootScope.message = 'Anthony Barrera';
});

codingBarrierApp.controller('contactController', function ($rootScope) {
    $rootScope.header = 'Contact';
    $rootScope.message = 'This will be my contact page!';
});

codingBarrierApp.controller('notFoundController', function ($rootScope) {
    $rootScope.header = 'Page not Found';
    $rootScope.message = 'Sorry, but the page you were trying to view does not exist.';
});<commit_msg>formatting<commit_after>var codingBarrierApp = angular.module('codingBarrierApp', ['ngRoute', 'ngSanitize']);

// configure our routes
codingBarrierApp.config(function ($routeProvider, $locationProvider) {
    $locationProvider.html5Mode(true);

    $routeProvider

            // route for the home page
            .when('/', {
                title: 'Home',
                templateUrl: 'pages/home.html',
                controller: 'mainController'
            })

            // route for the about page
            .when('/resume', {
                title: 'Resume',
                templateUrl: 'pages/resume.html',
                controller: 'resumeController'
            })

            // route for the contact page
            .when('/contact', {
                title: 'Contact',
                templateUrl: 'pages/contact.html',
                controller: 'contactController'
            })

            .when('/blog', {
                title: 'Blog',
                templateUrl: 'pages/blog.html',
                controller: 'blogController'
            })

            .when('/blog/:year/:month/:postPath', {
                title: 'Post | Blog',
                templateUrl: 'pages/blogPost.html',
                controller: 'blogPostController'
            })

            .otherwise({
                title: '404',
                templateUrl: 'pages/404.html',
                controller: 'notFoundController'
            });

});

codingBarrierApp.run(['$rootScope', function ($rootScope) {
        $rootScope.$on('$routeChangeSuccess', function (event, current, previous) {
            $rootScope.title = current.title;
        });
    }]);

// create the controller and inject Angular's $scope
codingBarrierApp.controller('mainController', function ($rootScope, $scope, $location, $timeout) {

    // create a message to display in our view
    $rootScope.header = 'Home Page';
    $rootScope.message = 'Coding Barrier under construction.';
    var fullUrl = $location.absUrl();
    if (fullUrl.indexOf("anthonybarrera.com") > -1) {
        $rootScope.siteName = "Anthony Barrera";
    } else {
        $rootScope.siteName = "Coding Barrier";
    }
});

codingBarrierApp.controller('resumeController', function ($rootScope) {
    $rootScope.header = 'Resume';
    $rootScope.message = 'Anthony Barrera';
});

codingBarrierApp.controller('contactController', function ($rootScope) {
    $rootScope.header = 'Contact';
    $rootScope.message = 'This will be my contact page!';
});

codingBarrierApp.controller('notFoundController', function ($rootScope) {
    $rootScope.header = 'Page not Found';
    $rootScope.message = 'Sorry, but the page you were trying to view does not exist.';
});<|endoftext|>


<commit_before>// Copyright (c) 2011, Centrum Cyfrowe
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Centrum Cyfrowe nor the names of its contributors
//     may be used to endorse or promote products derived from this software
//     without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

var _table = (function () {

//  P U B L I C   I N T E R F A C E
    var that = {};

    that.clean_table = function () {
        $('thead').empty();
        $('tbody').empty();
    };

    that.init_table = function () {
        create_thead();
        create_tbody();

//        _gui.highlight_node();
        _gui.make_zebra();
    };

    that.add_node = function ( parent_id ) {
        var children = _store.active_rows().filter( function ( e ) {
            return e['data']['parent'] === parent_id;
        });

        add_rows( children );
    };

    return that;

//  P R I V A T E   I N T E R F A C E

    function create_thead() {
        var schema = _store.basic_schema();
        var html = [ '
' ];

        schema.forEach( function ( column ) {
            html.push( '' );
            html.push( column['label'] );
            html.push( '	' );
        });

        html.push( '
' );
        $('thead').append( html.join('') );
    }

    function create_tbody() {
        var level = 'a';
        var hashed_list = _utils.hash_list( _store.active_rows() );
        var selected_node;

        while( !!hashed_list[ level ] ) {
            if( level === 'a' ) {
                add_top_level( hashed_list[ level ] );
            }
            else {
                add_rows( hashed_list[ level ] );
            }

            level = _utils.next_letter( level );
        }

        // apply node selection(if there is selected node) to css classes
        selected_node = _store.active_rows().filter( function ( e ) {
            return e['state']['selected'];
        });
        if ( selected_node.length > 0 ) {
            apply_selection( selected_node[0]['data']['idef'] );
        }
    }

    function add_top_level( data ) {
        var i, len = data.length;
        var schema = _store.basic_schema();

        for( i = 0; i < len; ++i ) {
            $('tbody').append( generate_row({
                node: data[i],
                index: i,
                schema: schema
            }));
        }
    }

    function add_rows( data ) {
        var i = data.length - 1;
        var schema = _store.basic_schema();
        var parent;

        for( ; i >= 0; i -= 1 ) {
            parent = $( '#' + data[i]['data']['parent'] );
	    if( parent.attr( 'data-open' ) === 'false' ) {
	    	continue;
	    }
            parent.after( generate_row({
                node: data[i],
                schema: schema
            }));
        }
        _gui.make_zebra();
    }

    // generate a single table row
    function generate_row( args ) {
        var node = args['node'];
        var data = node['data'];
        var schema = args['schema'];
        var is_open = node['state']['open'];
        var is_selected = node['state']['selected'];
        var html = [];
        var row;

        // row definition
        html.push( '
' );

        // cells definition
        // TODO >> it can be sligthly slower than for loop - test it
        schema.forEach( function ( column ) {
            html.push( '' : '">' );
            html.push( data[column['key']] );
            html.push( '	' );
        });

        html.push( '
' );

        // create & arm row
        row = $( html.join('') );
        row.click( function ( event ) {
            // update css classes connected with node selection
            apply_selection( $(this).attr('id') );

            // open/close a subtree if it's a-level or already selected/open
            open_close_subtree( $(this), a_parent( $(this) ) );

            _gui.make_zebra();
        });

        return row;
    }

    function apply_selection( id ) {
        var node = $('#' + id);

        // a-level parent
        var a_root = a_parent( node );
        var a_root_id = a_root.attr('id');
        // next a-level node
        var a_root_index = parseInt( a_root.attr( 'data-index' ), 10 );
        var next = $('tr[data-index='+ (a_root_index + 1) +']');

        // dim everything outside this a-rooted subtree
        a_root
            .siblings()
            .not(':hidden')
            .addClass('dim');

        // make a-root background black
        $('tr.root').removeClass('root');
        a_root.addClass('root');

        // highlight the subtree
        _utils.with_subtree( a_root.attr('id'), function () {
            // uses 'this' instead of '$(this)' for fun.call reason
            this.removeClass( 'dim' );
        });

        // add the bottom border
        $('.next').removeClass('next');
        next.addClass('next');
    }

    function open_close_subtree( node, root ) {
        var a_root = root || a_parent( node );
        var a_root_id = a_root.attr('id');
        var is_a_open     = a_root.attr( 'data-open' );
        var is_a_selected = a_root.attr( 'data-selected' );
        var id = node.attr('id');
        var children;
        var previously_selected_id;

        if ( is_a_selected === is_a_open ) {
            // if the node is closed
            if( node.attr( 'data-open' ) === 'false' ) {

                // if children are hidden
                if( $('.'+id).length !== 0 ) {
                    _utils.with_subtree( id, $.fn.show );
                }
                // if children not loaded yet
                else {
                    _db.download_node( id );
                }

                // if there is previously selected node, unselect it in _store
                previously_selected_id = $('tr[data-selected=true]').attr('id');
                if ( !previously_selected_id ) {
                    _store.set_selected( previously_selected_id, false );
                }

                // mark subtree as open
                _store.set_open( id, true );
                node.attr( 'data-open', 'true' );

                // clear selected attributes and set selection to clicked tree
                _store.set_selected( a_root_id, true );
                $('tr[data-selected=true]').attr('data-selected', 'false');
                a_root.attr('data-selected', 'true');
            }
            // the node is closed
            else {
                // hide subtree
                _utils.with_subtree( id, $.fn.hide );

                // mark subtree as closed
                _store.set_open( id, false );
                node.attr( 'data-open', 'false' );

                // if it's a-level node - clear the css highlight/dim
                if( node.hasClass( 'a' ) ) {
                    node.removeClass( 'root' );
                    $('.dim').removeClass('dim');
                    $('.next').removeClass('next');

                    // clear selected attributes and set selection to clicked tree
                    _store.set_selected( a_root_id, false );
                    $('tr[data-selected=true]').attr('data-selected', 'false');
                }
            }
        }
        else if( a_root.attr( 'data-selected' ) === 'false' ) {
            // unselect previously selected node in _store
            previously_selected_id = $('tr[data-selected=true]').attr('id');
            _store.set_selected( previously_selected_id, false );

            _store.set_selected( a_root_id, true );
            $('tr[data-selected=true]').attr('data-selected', 'false');
            a_root.attr('data-selected', 'true');
        }
    }

    // return a-level parent of a given node
    function a_parent( node ) {
        if( node.hasClass( 'a' ) ) {
            return node;
        }
        var prev = node.prev();

        return prev.hasClass('a') ? prev : a_parent( prev );
    }

})();
<commit_msg>Typo fixed<commit_after>// Copyright (c) 2011, Centrum Cyfrowe
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistributions of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//   * Redistributions in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//   * Neither the name of the Centrum Cyfrowe nor the names of its contributors
//     may be used to endorse or promote products derived from this software
//     without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
// THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

var _table = (function () {

//  P U B L I C   I N T E R F A C E
    var that = {};

    that.clean_table = function () {
        $('thead').empty();
        $('tbody').empty();
    };

    that.init_table = function () {
        create_thead();
        create_tbody();

//        _gui.highlight_node();
        _gui.make_zebra();
    };

    that.add_node = function ( parent_id ) {
        var children = _store.active_rows().filter( function ( e ) {
            return e['data']['parent'] === parent_id;
        });

        add_rows( children );
    };

    return that;

//  P R I V A T E   I N T E R F A C E

    function create_thead() {
        var schema = _store.basic_schema();
        var html = [ '
' ];

        schema.forEach( function ( column ) {
            html.push( '' );
            html.push( column['label'] );
            html.push( '	' );
        });

        html.push( '
' );
        $('thead').append( html.join('') );
    }

    function create_tbody() {
        var level = 'a';
        var hashed_list = _utils.hash_list( _store.active_rows() );
        var selected_node;

        while( !!hashed_list[ level ] ) {
            if( level === 'a' ) {
                add_top_level( hashed_list[ level ] );
            }
            else {
                add_rows( hashed_list[ level ] );
            }

            level = _utils.next_letter( level );
        }

        // apply node selection(if there is selected node) to css classes
        selected_node = _store.active_rows().filter( function ( e ) {
            return e['state']['selected'];
        });
        if ( selected_node.length > 0 ) {
            apply_selection( selected_node[0]['data']['idef'] );
        }
    }

    function add_top_level( data ) {
        var i, len = data.length;
        var schema = _store.basic_schema();

        for( i = 0; i < len; ++i ) {
            $('tbody').append( generate_row({
                node: data[i],
                index: i,
                schema: schema
            }));
        }
    }

    function add_rows( data ) {
        var i = data.length - 1;
        var schema = _store.basic_schema();
        var parent;

        for( ; i >= 0; i -= 1 ) {
            parent = $( '#' + data[i]['data']['parent'] );
	    if( parent.attr( 'data-open' ) === 'false' ) {
	    	continue;
	    }
            parent.after( generate_row({
                node: data[i],
                schema: schema
            }));
        }
        _gui.make_zebra();
    }

    // generate a single table row
    function generate_row( args ) {
        var node = args['node'];
        var data = node['data'];
        var schema = args['schema'];
        var is_open = node['state']['open'];
        var is_selected = node['state']['selected'];
        var html = [];
        var row;

        // row definition
        html.push( '
' );

        // cells definition
        // TODO >> it can be sligthly slower than for loop - test it
        schema.forEach( function ( column ) {
            html.push( '' : '">' );
            html.push( data[column['key']] );
            html.push( '	' );
        });

        html.push( '
' );

        // create & arm row
        row = $( html.join('') );
        row.click( function ( event ) {
            // update css classes connected with node selection
            apply_selection( $(this).attr('id') );

            // open/close a subtree if it's a-level or already selected/open
            open_close_subtree( $(this), a_parent( $(this) ) );

            _gui.make_zebra();
        });

        return row;
    }

    function apply_selection( id ) {
        var node = $('#' + id);

        // a-level parent
        var a_root = a_parent( node );
        var a_root_id = a_root.attr('id');
        // next a-level node
        var a_root_index = parseInt( a_root.attr( 'data-index' ), 10 );
        var next = $('tr[data-index='+ (a_root_index + 1) +']');

        // dim everything outside this a-rooted subtree
        a_root
            .siblings()
            .not(':hidden')
            .addClass('dim');

        // make a-root background black
        $('tr.root').removeClass('root');
        a_root.addClass('root');

        // highlight the subtree
        _utils.with_subtree( a_root.attr('id'), function () {
            // uses 'this' instead of '$(this)' for fun.call reason
            this.removeClass( 'dim' );
        });

        // add the bottom border
        $('.next').removeClass('next');
        next.addClass('next');
    }

    function open_close_subtree( node, root ) {
        var a_root = root || a_parent( node );
        var a_root_id = a_root.attr('id');
        var is_a_open     = a_root.attr( 'data-open' );
        var is_a_selected = a_root.attr( 'data-selected' );
        var id = node.attr('id');
        var children;
        var previously_selected_id;

        if ( is_a_selected === is_a_open ) {
            // if the node is closed
            if( node.attr( 'data-open' ) === 'false' ) {

                // if children are hidden
                if( $('.'+id).length !== 0 ) {
                    _utils.with_subtree( id, $.fn.show );
                }
                // if children not loaded yet
                else {
                    _db.download_node( id );
                }

                // if there is previously selected node, unselect it in _store
                previously_selected_id = $('tr[data-selected=true]').attr('id');
                if ( !!previously_selected_id ) {
                    _store.set_selected( previously_selected_id, false );
                }

                // mark subtree as open
                _store.set_open( id, true );
                node.attr( 'data-open', 'true' );

                // clear selected attributes and set selection to clicked tree
                _store.set_selected( a_root_id, true );
                $('tr[data-selected=true]').attr('data-selected', 'false');
                a_root.attr('data-selected', 'true');
            }
            // the node is closed
            else {
                // hide subtree
                _utils.with_subtree( id, $.fn.hide );

                // mark subtree as closed
                _store.set_open( id, false );
                node.attr( 'data-open', 'false' );

                // if it's a-level node - clear the css highlight/dim
                if( node.hasClass( 'a' ) ) {
                    node.removeClass( 'root' );
                    $('.dim').removeClass('dim');
                    $('.next').removeClass('next');

                    // clear selected attributes and set selection to clicked tree
                    _store.set_selected( a_root_id, false );
                    $('tr[data-selected=true]').attr('data-selected', 'false');
                }
            }
        }
        else if( a_root.attr( 'data-selected' ) === 'false' ) {
            // unselect previously selected node in _store
            previously_selected_id = $('tr[data-selected=true]').attr('id');
            _store.set_selected( previously_selected_id, false );

            _store.set_selected( a_root_id, true );
            $('tr[data-selected=true]').attr('data-selected', 'false');
            a_root.attr('data-selected', 'true');
        }
    }

    // return a-level parent of a given node
    function a_parent( node ) {
        if( node.hasClass( 'a' ) ) {
            return node;
        }
        var prev = node.prev();

        return prev.hasClass('a') ? prev : a_parent( prev );
    }

})();
<|endoftext|>