<commit_before>var App = (function() {
  var self = {};
  var navBar = document.querySelector("nav");

  ace.config.set("basePath", "js/ace");

  self.editor = ace.edit("content");
  self.editor.setTheme("ace/theme/monokai");
  self.editor.getSession().setMode("ace/mode/javascript");

  //Hide/Show the menu bar
  document.body.addEventListener("mousemove", function(e) {
    if(e.pageY < 30 && navBar.className === "hidden") navBar.className = "visible";
    else if(e.pageY >= 30 && navBar.className === "visible") navBar.className = "hidden";
  });

  //Helper functions
  var loadFileEntryToEditor = function(fileEntry) {
    fileEntry.file(function(file){
      var reader = new FileReader();
      reader.onload = function(e) {
        self.editor.setValue(e.target.result);
      };
      reader.readAsText(file);
    });

    self.currentFileEntry = fileEntry;
  };

  var saveEditorToFileEntry = function(fileEntry) {
    fileEntry.createWriter(function(fileWriter) {
      fileWriter.onwriteend = function() {
        console.log("Writing DONE");
      };

      fileWriter.onerror = function(err) {
        console.log("err", err, err.toString());
      }

      var blob = new Blob([self.editor.getValue()], {type: 'text/plain'});
      fileWriter.write(blob);
    }, function(err) {
      console.log("shit", err);
    });
  };

  //Adding button event listeners
  document.getElementById("new").addEventListener("click", function() {
    self.currentFileEntry = null;
    self.editor.setValue("");
  });

  document.getElementById("open").addEventListener("click", function() {
    chrome.fileSystem.chooseEntry({}, loadFileEntryToEditor);
  });

  document.getElementById("save").addEventListener("click", function() {
    if(!self.currentFileEntry) {
      chrome.fileSystem.chooseEntry({type: "saveFile"}, function(fileEntry) {
        self.currentFileEntry = fileEntry;
        chrome.fileSystem.getWritableEntry(self.currentFileEntry, saveEditorToFileEntry);
      });
    } else {
      chrome.fileSystem.getWritableEntry(self.currentFileEntry, saveEditorToFileEntry);
    }
  });

  // return the instance
  return self;
})();
<commit_msg>Mode sensing and proper highlighting<commit_after>var App = (function() {
  var self = {};
  var navBar = document.querySelector("nav");

  var SUPPORTED_MODES = {
    "js"     : "javascript",
    "html"   : "html",
    "css"    : "css",
    "coffee" : "coffee",
    "cs"     : "csharp",
    "go"     : "golang",
    "java"   : "java",
    "json"   : "json",
    "md"     : "markdown",
    "py"     : "python",
    "rb"     : "ruby",
    "sh"     : "sh",
    "sql"    : "sql",
    "xml"    : "xml",
    "yml"    : "yaml"
  };

  ace.config.set("basePath", "js/ace");

  self.editor = ace.edit("content");
  self.editor.setTheme("ace/theme/monokai");
  self.editor.getSession().setMode("ace/mode/javascript");

  //Hide/Show the menu bar
  document.body.addEventListener("mousemove", function(e) {
    if(e.pageY < 30 && navBar.className === "hidden") navBar.className = "visible";
    else if(e.pageY >= 30 && navBar.className === "visible") navBar.className = "hidden";
  });

  //Helper functions
  var setEditorModeForFileEntry = function(fileEntry) {
    var extension = fileEntry.name.split('.').pop();
    if(SUPPORTED_MODES[extension]) {
      self.editor.getSession().setMode("ace/mode/" + SUPPORTED_MODES[extension]);
    }
  }

  var loadFileEntryToEditor = function(fileEntry) {
    fileEntry.file(function(file){
      var reader = new FileReader();
      reader.onload = function(e) {
        self.editor.setValue(e.target.result);
      };
      reader.readAsText(file);
    });

    self.currentFileEntry = fileEntry;
    setEditorModeForFileEntry(fileEntry);
  };

  var saveEditorToFileEntry = function(fileEntry) {
    fileEntry.createWriter(function(fileWriter) {
      fileWriter.onwriteend = function() {
        console.log("Writing DONE");
      };

      fileWriter.onerror = function(err) {
        console.log("err", err, err.toString());
      }

      var blob = new Blob([self.editor.getValue()], {type: 'text/plain'});
      fileWriter.write(blob);
    }, function(err) {
      console.log("shit", err);
    });
  };

  //Adding button event listeners
  document.getElementById("new").addEventListener("click", function() {
    self.currentFileEntry = null;
    self.editor.setValue("");
  });

  document.getElementById("open").addEventListener("click", function() {
    chrome.fileSystem.chooseEntry({}, loadFileEntryToEditor);
  });

  document.getElementById("save").addEventListener("click", function() {
    if(!self.currentFileEntry) {
      chrome.fileSystem.chooseEntry({type: "saveFile"}, function(fileEntry) {
        self.currentFileEntry = fileEntry;
        chrome.fileSystem.getWritableEntry(self.currentFileEntry, saveEditorToFileEntry);
      });
    } else {
      chrome.fileSystem.getWritableEntry(self.currentFileEntry, saveEditorToFileEntry);
    }
  });

  // return the instance
  return self;
})();
<|endoftext|>


<commit_before>/*jslint devel:true*/
/*global module, require*/

(function () {

    'use strict';

    var path = require('path'),
        fs = require('fs'),
        exec = require("child_process").exec,
        async = require('async'),
        cheerio = require("cheerio"),
        defaults = require('lodash.defaults'),
        mkdirp = require('mkdirp');

    module.exports = function (params) {

        // Default options
        var options = defaults(params || {}, {

            // I/O
            source: null,
            dest: 'images',

            // Icon Types
            android: true,
            apple: true,
            coast: true,
            favicons: true,
            firefox: true,
            windows: true,

            // Miscellaneous
            html: null,
            background: '#1d1d1d',
            tileBlackWhite: true,
            manifest: null,
            trueColor: false,
            logging: false,
            callback: null

        }),

            elements = [],
            files = [],
            opts = ["-background", '"' + options.background + '"', "-flatten"];

        // Print to the console.
        function print(message) {
            if (message && options.logging) {
                console.log(message);
            }
        }

        // Determine whether HTML is to be produced
        function writeHTML() {
            return options.html && options.html !== '';
        }

        // Execute external command
        function execute(cmd, callback) {
            exec(cmd, function (error) {
                return error || callback();
            });
        }

        // Convert image with Imagemagick
        function convert(args, name, callback) {
            args.unshift('convert');
            execute(args.join(' '), function () {
                if (name) {
                    print('Created ' + name);
                }
                return callback();
            });
        }

        // Combine arguments into command
        function combine(src, dest, size, fname, opts) {
            var out = [src, "-resize", size].concat(opts);
            out.push(path.join(dest, fname));
            return out;
        }

        // Delete and rewrite HTML tags
        function writeTags(callback) {
            var $, html = '';
            if (options.html) {
                fs.readFile(options.html, function (error, data) {
                    if (error) {
                        return error;
                    }
                    $ = cheerio.load(data, { decodeEntities: false });
                    $('link[rel="shortcut icon"]').remove();
                    $('link[rel="icon"]').remove();
                    $('link[rel="apple-touch-icon"]').remove();
                    $('meta').each(function () {
                        var name = $(this).attr('name');
                        if (name && (name === 'msapplication-TileImage' || name === 'msapplication-TileColor' || name.indexOf('msapplication-square') >= 0 || name === 'mobile-web-app-capable')) {
                            $(this).remove();
                        }
                    });
                    html = $.html().replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g, '').replace(/\s+/g, ' ');
                    if (html === '') {
                        $ = cheerio.load('');
                    }
                    if ($('head').length > 0) {
                        $("head").append(elements.join('\n'));
                        return callback($.html());
                    }
                    return callback(elements.join('\n'));
                });
            } else {
                return callback(elements.join('\n'));
            }
        }

        // Make regular favicon files
        function makeFavicons(callback) {
            async.each([16, 32, 48], function (size, callback) {
                var dimensions = size + 'x' + size,
                    ext = path.extname(options.source),
                    basename = path.basename(options.source, ext),
                    dirname = path.dirname(options.source),
                    p = path.join(dirname, basename + "." + dimensions + ext),
                    saveTo = path.join(options.dest, dimensions + '.png'),
                    src = options.source;
                fs.exists(p, function (exists) {
                    if (exists) {
                        src = p;
                    }
                    convert([src, '-resize', dimensions, saveTo], null, function () {
                        files.push(saveTo);
                        return callback();
                    });
                });
            }, function () {
                convert(files.concat([
                    '-background none',
                    options.trueColor ? '' : '-bordercolor white -border 0 -colors 64',
                    path.join(options.dest, 'favicon.ico')
                ]), 'favicon.ico', function () {
                    convert([options.source, '-resize', "64x64", path.join(options.dest, 'favicon.png')], 'favicon.png', function () {
                        elements.push('<link rel="shortcut icon" href="favicon.ico" />', '<link rel="icon" type="image/png" sizes="64x64" href="favicon.png" />');
                        async.each([16, 32, 48], function (size, callback) {
                            var file = path.join(options.dest, size + 'x' + size + '.png');
                            fs.exists(file, function (exists) {
                                if (exists) {
                                    fs.unlink(file, function (error) {
                                        return error || callback();
                                    });
                                }
                            });
                        }, function (error) {
                            return error || callback();
                        });
                    });
                });
            });
        }

        // Make Apple touch icons
        function makeApple(callback) {
            async.each([57, 60, 72, 76, 144, 120, 144, 152], function (size, callback) {
                var dimensions = size + 'x' + size,
                    rule = (size === 57 ? '' : '-' + dimensions),
                    name = 'apple-touch-icon' + rule + '.png',
                    command = combine(options.source, options.dest, dimensions, name, opts);
                convert(command, name, function () {
                    elements.push('<link rel="apple-touch-icon" sizes="' + dimensions + '" href="' + name + '" />');
                    return callback();
                });
            }, function (error) {
                return error || callback();
            });
        }

        // Make Coast icon
        function makeCoast(callback) {
            var dimensions = '228x228',
                name = 'coast-icon-' + dimensions + '.png',
                command = combine(options.source, options.dest, dimensions, name, opts);
            convert(command, name, function () {
                elements.push('<link rel="icon" sizes="' + dimensions + '" href="' + name + '" />');
                return callback();
            });
        }

        // Make Android homescreen icon
        function makeAndroid(callback) {
            var dimensions = '196x196',
                name = 'homescreen-' + dimensions + '.png',
                command = combine(options.source, options.dest, dimensions, name, opts);
            convert(command, name, function () {
                elements.push('<meta name="mobile-web-app-capable" value="yes" />', '<link rel="icon" sizes="' + dimensions + '" href="' + name + '" />');
                return callback();
            });
        }

        // Make Firefox icons
        function makeFirefox(callback) {
            var updateManifest = (options.manifest && options.manifest !== ''),
                contentsFirefox,
                contentFirefox;
            if (updateManifest) {
                fs.readFile(options.manifest, function (error, data) {
                    if (error) {
                        return error;
                    }
                    contentsFirefox = data || '{}';
                    contentFirefox = JSON.parse(contentsFirefox);
                    contentFirefox.icons = {};
                });
            }
            async.each([16, 30, 32, 48, 60, 64, 90, 120, 128, 256], function (size, callback) {
                var dimensions = size + 'x' + size,
                    name = "firefox-icon-" + dimensions + ".png",
                    command = combine(options.source, options.dest, dimensions, name, opts);
                convert(command, name, function () {
                    if (updateManifest) {
                        contentFirefox.icons[size] = name;
                    }
                    return callback();
                });
            }, function (error) {
                if (updateManifest) {
                    print('Updating Firefox manifest... ');
                    fs.writeFile(options.manifest, JSON.stringify(contentFirefox, null, 2), function () {
                        return error || callback();
                    });
                } else {
                    return error || callback();
                }
            });
        }

        // Make Windows 8 tile icons
        function makeWindows(callback) {
            if (writeHTML()) {
                opts = [];
            }
            elements.push('<meta name="msapplication-TileColor" content="' + options.background + '" />');
            if (options.tileBlackWhite) {
                opts.push('-fuzz 100%', '-fill black', '-opaque red', '-fuzz 100%', '-fill black', '-opaque blue', '-fuzz 100%', '-fill white', '-opaque green');
            }
            async.each([70, 144, 150, 310], function (size, callback) {
                var dimensions = size + 'x' + size,
                    name = 'windows-tile-' + dimensions + '.png',
                    command = combine(options.source, options.dest, dimensions, name, opts);
                convert(command, name, function () {
                    if (size === 144) {
                        elements.push('<meta name="msapplication-TileImage" content="' + name + '" />');
                    } else {
                        elements.push('<meta name="msapplication-square' + dimensions + 'logo" content="' + name + '" />');
                    }
                    return callback();
                });
            }, function (error) {
                return error || callback();
            });
        }

        // Create the appropriate icons
        function makeIcons(callback) {
            async.parallel([
                function (callback) {
                    if (options.favicons) {
                        makeFavicons(function () {
                            callback(null);
                        });
                    }
                },
                function (callback) {
                    if (options.apple) {
                        makeApple(function () {
                            callback(null);
                        });
                    }
                },
                function (callback) {
                    if (options.coast) {
                        makeCoast(function () {
                            callback(null);
                        });
                    }
                },
                function (callback) {
                    if (options.android) {
                        makeAndroid(function () {
                            callback(null);
                        });
                    }
                },
                function (callback) {
                    if (options.firefox) {
                        makeFirefox(function () {
                            callback(null);
                        });
                    }
                },
                function (callback) {
                    if (options.windows) {
                        makeWindows(function () {
                            callback(null);
                        });
                    }
                }
            ], function () {
                return callback();
            });
        }

        // Initialise
        function init() {
            if (!options.source) {
                return console.log('A source image is required');
            }
            mkdirp.sync(options.dest);
            makeIcons(function () {
                writeTags(function (data) {
                    if (writeHTML()) {
                        fs.writeFile(options.html, data, function () {
                            if (options.callback) {
                                return options.callback('Generated favicons');
                            }
                        });
                    } else if (options.callback) {
                        return options.callback('Generated favicons', data);
                    }
                });
            });
        }

        init();

    };

}());
<commit_msg>Fixes and cleanup<commit_after>/*jslint devel:true*/
/*global module, require*/

(function () {

    'use strict';

    var path = require('path'),
        fs = require('fs'),
        exec = require('child_process').exec,
        async = require('async'),
        cheerio = require('cheerio'),
        defaults = require('lodash.defaults'),
        mkdirp = require('mkdirp');

    module.exports = function (params) {

        // Default options
        var options = defaults(params || {}, {

            // I/O
            source: null,
            dest: 'images',

            // Icon Types
            android: true,
            apple: true,
            coast: true,
            favicons: true,
            firefox: true,
            windows: true,

            // Miscellaneous
            html: null,
            background: '#1d1d1d',
            tileBlackWhite: true,
            manifest: null,
            trueColor: false,
            logging: false,
            callback: null

        }),

            elements = [],
            opts = ['-background', '"' + options.background + '"', '-flatten'];

        // Print to the console.
        function print(message) {
            if (message && options.logging) {
                console.log(message);
            }
        }

        // Determine whether HTML is to be produced
        function writeHTML() {
            return options.html && options.html !== '';
        }

        // Execute external command
        function execute(cmd, callback) {
            exec(cmd, function (error) {
                return error || callback();
            });
        }

        // Convert image with Imagemagick
        function convert(args, name, callback) {
            args.unshift('convert');
            execute(args.join(' '), function () {
                print('Created ' + name);
                return callback();
            });
        }

        // Combine arguments into command
        function combine(src, dest, size, fname, opts) {
            var out = [src, '-resize', size].concat(opts);
            out.push(path.join(dest, fname));
            return out;
        }

        // Clean unused files
        function clean(callback) {
            async.each([16, 32, 48], function (size, callback) {
                var file = path.join(options.dest, size + 'x' + size + '.png');
                fs.exists(file, function (exists) {
                    if (exists) {
                        fs.unlink(file, function (error) {
                            return error || callback();
                        });
                    }
                });
            }, function (error) {
                return error || callback();
            });
        }

        // Delete and rewrite HTML tags
        function writeTags(callback) {
            var $, html = '';
            if (options.html) {
                fs.readFile(options.html, function (error, data) {
                    if (error) {
                        return error;
                    }
                    $ = cheerio.load(data, { decodeEntities: false });
                    $('link[rel="shortcut icon"]', 'link[rel="icon"]', 'link[rel="apple-touch-icon"]').remove();
                    $('meta').each(function () {
                        var name = $(this).attr('name');
                        if (name && (name === 'msapplication-TileImage' || name === 'msapplication-TileColor' || name.indexOf('msapplication-square') >= 0 || name === 'mobile-web-app-capable')) {
                            $(this).remove();
                        }
                    });
                    html = $.html().replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g, '').replace(/\s+/g, ' ');
                    if (html === '') {
                        $ = cheerio.load('');
                    }
                    if ($('head').length > 0) {
                        $('head').append(elements.join('\n'));
                        return callback($.html());
                    }
                    return callback(elements.join('\n'));
                });
            } else {
                return callback(elements.join('\n'));
            }
        }

        // Make PNG favicon
        function makeNewFavicon(callback) {
            var dimensions = '64x64',
                name = 'favicon.png',
                command = combine(options.source, options.dest, dimensions, name, opts);
            convert(command, name, function () {
                elements.push('<link rel="icon" type="image/png" sizes="64x64" href="favicon.png" />');
                return callback();
            });
        }

        // Make regular favicon files
        function makeFavicons(callback) {
            var files = [];
            async.each([16, 32, 48], function (size, callback) {
                var dimensions = size + 'x' + size,
                    name = dimensions + '.png',
                    command = combine(options.source, options.dest, dimensions, name, opts);
                convert(command, name, function () {
                    files.push(path.join(options.dest, name));
                    return callback();
                });
            }, function (error) {
                convert(files.concat([
                    '-background none',
                    options.trueColor ? '' : '-bordercolor white -border 0 -colors 64',
                    path.join(options.dest, 'favicon.ico')
                ]), 'favicon.ico', function () {
                    elements.push('<link rel="shortcut icon" href="favicon.ico" />');
                    return error || clean(function (error) {
                        return error || callback();
                    });
                });
            });
        }

        // Make Apple touch icons
        function makeApple(callback) {
            async.each([57, 60, 72, 76, 144, 120, 144, 152], function (size, callback) {
                var dimensions = size + 'x' + size,
                    rule = (size === 57 ? '' : '-' + dimensions),
                    name = 'apple-touch-icon' + rule + '.png',
                    command = combine(options.source, options.dest, dimensions, name, opts);
                convert(command, name, function () {
                    elements.push('<link rel="apple-touch-icon" sizes="' + dimensions + '" href="' + name + '" />');
                    return callback();
                });
            }, function (error) {
                return error || callback();
            });
        }

        // Make Coast icon
        function makeCoast(callback) {
            var dimensions = '228x228',
                name = 'coast-icon-' + dimensions + '.png',
                command = combine(options.source, options.dest, dimensions, name, opts);
            convert(command, name, function () {
                elements.push('<link rel="icon" sizes="' + dimensions + '" href="' + name + '" />');
                return callback();
            });
        }

        // Make Android homescreen icon
        function makeAndroid(callback) {
            var dimensions = '196x196',
                name = 'homescreen-' + dimensions + '.png',
                command = combine(options.source, options.dest, dimensions, name, opts);
            convert(command, name, function () {
                elements.push('<meta name="mobile-web-app-capable" value="yes" />', '<link rel="icon" sizes="' + dimensions + '" href="' + name + '" />');
                return callback();
            });
        }

        // Make Firefox icons
        function makeFirefox(callback) {
            var updateManifest = (options.manifest && options.manifest !== ''),
                contentsFirefox,
                contentFirefox;
            if (updateManifest) {
                fs.readFile(options.manifest, function (error, data) {
                    if (error) {
                        return error;
                    }
                    contentsFirefox = data || '{}';
                    contentFirefox = JSON.parse(contentsFirefox);
                    contentFirefox.icons = {};
                });
            }
            async.each([16, 30, 32, 48, 60, 64, 90, 120, 128, 256], function (size, callback) {
                var dimensions = size + 'x' + size,
                    name = 'firefox-icon-' + dimensions + '.png',
                    command = combine(options.source, options.dest, dimensions, name, opts);
                convert(command, name, function () {
                    if (updateManifest) {
                        contentFirefox.icons[size] = name;
                    }
                    return callback();
                });
            }, function (error) {
                if (updateManifest) {
                    print('Updating Firefox manifest... ');
                    fs.writeFile(options.manifest, JSON.stringify(contentFirefox, null, 2), function () {
                        return error || callback();
                    });
                } else {
                    return error || callback();
                }
            });
        }

        // Make Windows 8 tile icons
        function makeWindows(callback) {
            if (writeHTML()) {
                opts = [];
            }
            elements.push('<meta name="msapplication-TileColor" content="' + options.background + '" />');
            if (options.tileBlackWhite) {
                opts.push('-fuzz 100%', '-fill black', '-opaque red', '-fuzz 100%', '-fill black', '-opaque blue', '-fuzz 100%', '-fill white', '-opaque green');
            }
            async.each([70, 144, 150, 310], function (size, callback) {
                var dimensions = size + 'x' + size,
                    name = 'windows-tile-' + dimensions + '.png',
                    command = combine(options.source, options.dest, dimensions, name, opts);
                convert(command, name, function () {
                    elements.push('<meta name="msapplication-' + (size === 144 ? 'TileImage' : 'square' + dimensions + 'logo') + '" content="' + name + '" />');
                    return callback();
                });
            }, function (error) {
                return error || callback();
            });
        }

        // Create the appropriate icons
        function makeIcons(callback) {
            async.parallel([
                function (callback) {
                    if (options.favicons) {
                        makeFavicons(function () {
                            callback(null);
                        });
                    }
                },
                function (callback) {
                    if (options.favicons) {
                        makeNewFavicon(function () {
                            callback(null);
                        });
                    }
                },
                function (callback) {
                    if (options.apple) {
                        makeApple(function () {
                            callback(null);
                        });
                    }
                },
                function (callback) {
                    if (options.coast) {
                        makeCoast(function () {
                            callback(null);
                        });
                    }
                },
                function (callback) {
                    if (options.android) {
                        makeAndroid(function () {
                            callback(null);
                        });
                    }
                },
                function (callback) {
                    if (options.firefox) {
                        makeFirefox(function () {
                            callback(null);
                        });
                    }
                },
                function (callback) {
                    if (options.windows) {
                        makeWindows(function () {
                            callback(null);
                        });
                    }
                }
            ], function () {
                return callback();
            });
        }

        // Initialise
        function init() {
            if (!options.source) {
                return console.log('A source image is required');
            }
            mkdirp(options.dest, function () {
                makeIcons(function () {
                    writeTags(function (data) {
                        if (writeHTML()) {
                            fs.writeFile(options.html, data, function () {
                                if (options.callback) {
                                    return options.callback('Generated favicons');
                                }
                            });
                        } else if (options.callback) {
                            return options.callback('Generated favicons', data);
                        }
                    });
                });
            });
        }

        init();

    };

}());
<|endoftext|>


<commit_before>module.exports = scale

function scale(parts, change) {
  var ranges = JSON.parse(parts[1])
    , dimensions = []
    , prev = []

  var update_range = this.create_part(parts[0], function(domains, ctx) {
    dimensions = new Array(Math.max(domains.length, ranges.length))

    for(var i = 0, l = dimensions.length; i < l; ++i) {
      dimensions[i] = {
          scale: (ranges[i][1] - ranges[i][0]) / (domains[i][1] - domains[i][0])
        , offset: domains[i][0]
      }
    }

    map(prev)
  })

  return map

  function map(data, ctx) {
    if(ctx) {
      prev = data

      return update_range(data, ctx)
    }

    var out = Array(data.length)

    for(var i = 0, l = data.length; i < l; ++i) {
      out[i] = Array(dimensions)

      for(var j = 0; j < dimensions.length; ++j) {
        out[i][j] = (data[i][j] - dimensions[j].offset) * dimensions[j].scale
      }
    }

    change(out)
  }
}
<commit_msg>fix inverted output<commit_after>module.exports = scale

function scale(parts, change) {
  var ranges = JSON.parse(parts[1])
    , dimensions = []
    , prev = []

  var update_range = this.create_part(parts[0], function(domains, ctx) {
    dimensions = new Array(Math.max(domains.length, ranges.length))

    for(var i = 0, l = dimensions.length; i < l; ++i) {
      dimensions[i] = {
          scale: (ranges[i][1] - ranges[i][0]) / (domains[i][1] - domains[i][0])
        , domain_offset: domains[i][0]
        , range_offset: ranges[i][0]
      }
    }

    map(prev)
  })

  return map

  function map(data, ctx) {
    if(ctx) {
      prev = data

      return update_range(data, ctx)
    }

    var out = Array(data.length)

    for(var i = 0, l = data.length; i < l; ++i) {
      out[i] = Array(dimensions)

      for(var j = 0; j < dimensions.length; ++j) {
        out[i][j] = (data[i][j] - dimensions[j].domain_offset) * dimensions[j].scale - dimensions[j].range_offset
      }
    }

    change(out)
  }
}
<|endoftext|>


<commit_before><commit_msg>fixed server app empty<commit_after>var monthNames = ["January", "February", "March", "April", "May", "June",
  "July", "August", "September", "October", "November", "December"
];

function replace_All(str, find, replace){
    while(str.indexOf(find) != -1){
        str = str.replace(find, replace);
    }
    return str;
}

angular.module('basecamp', ['ngSanitize'])

    .config(['$routeProvider','$locationProvider', function ($routeProvider, $locationProvider) {
        $routeProvider
            .when('/', {
                templateUrl: 'templates/home.html',
                controller: 'HomeController'
            })
            .when('/people/by-dept/', {
                templateUrl: 'templates/people-by-dept.html',
                controller: 'PeopleByDeptController'
            })
            .when('/people/by-name/', {
                templateUrl: 'templates/people-by-name.html',
                controller: 'PeopleByNameController'
            })
            .when('/people/:personId/', {
                templateUrl: 'templates/person.html',
                controller: 'PersonController'
            })
            .when('/projects/by-name/', {
                templateUrl: 'templates/projects-by-name.html',
                controller: 'ProjectsByNameController'
            })
            .when('/projects/by-dept/', {
                templateUrl: 'templates/projects-by-dept.html',
                controller: 'ProjectsByDeptController'
            })
            .when('/projects-old/:projectId/', {
                templateUrl: 'templates/project-orig.html',
                controller: 'ProjectController'
            })
            .when('/projects/:projectId/', {
                templateUrl: 'templates/project.html',
                controller: 'ProjectController'
            })
            .when('/projects/:projectId/todolists/:todoListId', {
                templateUrl: 'templates/todo-list.html',
                controller: 'TodoListController'
            })
            .when('/departments/:departmentName', {
                templateUrl: 'templates/department.html',
                controller: 'DepartmentController'
            })
            .otherwise({
                templateUrl: 'templates/404-error.html',
                controller: 'ErrorController'
            });
            //.when('/projects/:projectName', {})

            //.when('/departments/members', {})
            //.when('/departmenet/projects', {})
            //.when('/departments/:departmentName', {})

        $locationProvider.html5Mode(true);
    }])

    .value('basecamp.config', {
        debug: false // Set to false to disable logging to console
    })

/**
 * Main controller that holds some global data
 *
 * Fetches and stores some initial data in the main property to display global statistics
 */
    .controller('MainController', ['$scope', '$http', 'basecamp.config', function ($scope, $http, basecampConfig) {

        /**
         * Container for some global data
         */
        $scope.main = {
            people: [],
            projects: [],
            groups: [],
            projectCounts: {},
            activeTodoLists: [],
            completedTodoLists: [],
            activeTodoListsCompletedCount: 0,
            activeTodoListsRemainingCount: 0,
            completedTodoListsCompletedCount: 0,
            completedTodoListsRemainingCount: 0
        };

        /**
         * Get all people
         *
         * Returns promise so additional callbacks can be attached
         */
        $scope.getPeople = function () {
            // var rawPeople = $http.get('get.php?url=people.json');
            // var finalPeople = [];
            // for (var i = 0; i <= rawPeople.length; i++) {
            //     var personInfo = $http.get('get.php?url=people/' + rawPeople[i]["id"] +'.json');
            //     var personProj = $http.get('get.php?url=people/' + rawPeople[i]["id"] +'/projects.json');
            //     finalPeople.push( { "info" : personInfo, "projects" : personProj } );
            // }
            // return finalPeople;
            return $http.get('get.php?url=people.json')
                .error(function (data, status, headers, config) {
                    basecampConfig.debug && console.log('Error while getting projects: ' + data);
                })
        }

        $scope.getPersonInfo = function(personID) {
            return $http.get('get.php?url=people/' + personID +'.json')
                .error(function (data, status, headers, config) {
                    basecampConfig.debug && console.log('Error while getting projects: ' + data);
                })
        }

        $scope.getPersonProj = function(personID) {
            return $http.get('get.php?url=people/' + personID +'/projects.json')
                .error(function (data, status, headers, config) {
                    basecampConfig.debug && console.log('Error while getting projects: ' + data);
                })
        }

        $scope.getPersonEvents= function(personID, page) {
            if (page === 1) {
                return $http.get("get.php?url=people/" + personID + "/events.json%3Fsince=2015-01-01T00:00:00")
                    .error(function (data, status, headers, config) {
                        basecampConfig.debug && console.log('Error while getting completed todo lists: ' + data);
                    })
            } else {
                return $http.get("get.php?url=people/" + personID + "/events.json%3Fsince=2015-01-01T00:00:00&page=" + page)
                    .error(function (data, status, headers, config) {
                        basecampConfig.debug && console.log('Error while getting completed todo lists: ' + data);
                    })
            }
        }

        $scope.getGroups = function(){
            return $http.get('get.php?url=groups.json')
                .error(function (data, status, headers, config) {
                    basecampConfig.debug && console.log('Error while getting groups: ' + data);
                })
        }

        $scope.getGroup = function(groupId){
            return $http.get('get.php?url=groups/' + groupId + '.json')
                .error(function (data, status, headers, config) {
                    basecampConfig.debug && console.log('Error while getting group : ' + groupId + data);
                })
        }
        /**
         * Get all projects
         *
         * Returns promise so additional callbacks can be attached
         */
        $scope.getProjects = function () {
            return $http.get('get.php?url=projects.json')
                .error(function (data, status, headers, config) {
                    basecampConfig.debug && console.log('Error while getting projects: ' + data);
                })
        }

        $scope.getProject = function (id) {
            return $http.get('get.php?url=projects/' + id + '.json')
                .error(function (data, status, headers, config) {
                    basecampConfig.debug && console.log('Error while getting projects: ' + data);
                })
        }

        /**
         * Get all active todo lists
         *
         * Returns promise so additional callbacks can be attached
         */
        $scope.getActiveTodoLists = function () {
            return $http.get('get.php?url=todolists.json')
                .error(function (data, status, headers, config) {
                    basecampConfig.debug && console.log('Error while getting active todo lists: ' + data);
                });
        }

        /**
         * Get all completed todo lists
         *
         * Returns promise so additional callbacks can be attached
         */
        $scope.getCompletedTodoLists = function () {
            return $http.get('get.php?url=todolists/completed.json')
                .error(function (data, status, headers, config) {
                    basecampConfig.debug && console.log('Error while getting completed todo lists: ' + data);
                })
        }

        $scope.getProjectAccesses = function(id){
            return $http.get("get.php?url=projects/" + id + "/accesses.json")
                .error(function (data, status, headers, config) {
                    basecampConfig.debug && console.log('Error while getting project accesses: ' + data);
                })
        }

        $scope.getExtraPersonInfo = function(id){
            return $http.get("getRecord.php?table=person&id=" + id)
                .error(function (data, status, headers, config) {
                    basecampConfig.debug && console.log('Error while getting completed todo lists: ' + data);
                })
        }

        $scope.getExtraDeptInfo = function(id){
            return $http.get('getRecord.php?table=department&id=' + id)
                .error(function (data, status, headers, config) {
                    basecampConfig.debug && console.log('Error while getting completed todo lists: ' + data);
                })
        }

        $scope.getPersonPack = function(id){
            var per = {};
            $scope.getPersonInfo(id).success(function(data, status, headers, config) {
                per.id = data.id;
                per.name = data.name;
                per.email = data.email_address;
                per.assigned = data.assigned_todos.count;
                per.avatar_url = data.avatar_url;
                per.active = 0;
                per.archive = 0;

                $scope.getPersonProj(id).success(function(data, status, headers, config) {
                    angular.forEach(data, function(proj){
                        if (!proj.template) {
                            if(!proj.trashed) {
                                per.active++;
                            }else{
                                per.archive++;
                            }
                        }
                    })
                })
            })
            return per;
        }

        $scope.getProjectPack = function(id){
            var proj = {};
            $scope.getProject(id).success(function(data, status, headers, config) {
                proj.id = data.id;
                proj.name = data.name;
                proj.description = data.description;
                proj.creator = data.creator.name;
                proj.events = data.calendar_events.count
                proj.docs = data.documents.count;
                if(data.archived){
                    proj.status = "Archived";
                }else{
                    proj.status = "Active";
                }
            })
            return proj;
        }

        $scope.getPersonDepts = function(id){
            var departments = [];
            $scope.getGroups().success(function(data, status, headers, config) {
                angular.forEach(data,function(dept){
                    $scope.getGroup(dept.id).success(function(data, status, headers, config) {
                        angular.forEach(data.memberships, function(person){
                            if(person.id == id){
                                departments.push(data);
                            }
                        })
                    })
                })
            })
            return departments;
        }

        $scope.getProjectEvents= function(id, page){
            return $http.get("get.php?url=projects/" + id + "/events.json%3Fsince=2015-01-01T00:00:00%26page=" + page)
                .error(function (data, status, headers, config) {
                    basecampConfig.debug && console.log('Error while getting completed todo lists: ' + data);
                })
        }
        /**
         * Get project counts
         *
         * @param projectId
         * @returns {
         *     activeTodoListsCompletedCount: 0,
         *     activeTodoListsRemainingCount: 0,
         *     completedTodoListsCompletedCount: 0,
         *     completedTodoListsRemainingCount: 0,
         *     allTodoListsCompletedCount: 0,
         *     allTodoListsCompletedCount: 0,
         *     percentComplete: 0
         * }
         */
        $scope.getProjectCounts = function(projectId){

            var result = {
                activeTodoListsCompletedCount: 0,
                activeTodoListsRemainingCount: 0,
                completedTodoListsCompletedCount: 0,
                completedTodoListsRemainingCount: 0,
                allTodoListsCompletedCount: 0,
                allTodoListsCompletedCount: 0,
                percentComplete: 0
            };

            if(angular.isUndefined(projectId)){
                return result;
            }

            // Return cached result if there is one
            if(angular.isDefined($scope.main.projectCounts[projectId])){
                return $scope.main.projectCounts[projectId];
            }

            // Loop over active todo lists and count todo's
            angular.forEach($scope.main.activeTodoLists, function(todoList){
               if(todoList.bucket.id === projectId){
                   result.activeTodoListsCompletedCount += todoList.completed_count;
                   result.activeTodoListsRemainingCount += todoList.remaining_count;
               }
            });

            // Loop over completed todo lists and count todo's
            angular.forEach($scope.main.completedTodoLists, function(todoList){
                if(todoList.bucket.id === projectId){
                    result.completedTodoListsCompletedCount += todoList.completed_count;
                    result.completedTodoListsRemainingCount += todoList.remaining_count;
                }
            });

            // Only store result in cache if all data was fetched correctly so the numbers get updated
            // when todo lists are still being fetched
            if($scope.main.projects.length && $scope.main.activeTodoLists.length && $scope.main.completedTodoLists.length){

                // Calculate some extra statistics
                result.allTodoListsCompletedCount = result.activeTodoListsCompletedCount + result.completedTodoListsCompletedCount;
                result.allTodoListsRemainingCount = result.activeTodoListsRemainingCount + result.completedTodoListsRemainingCount;
                result.percentComplete = result.allTodoListsCompletedCount * (100 / (result.allTodoListsCompletedCount + result.allTodoListsRemainingCount));

                // Store in cache
                $scope.main.projectCounts[projectId] = result;
            }

            return result;
        }

        /**
         * Recalculate main counters when main active todo lists change
         */
        $scope.$watch('main.activeTodoLists', function (activeTodoLists, oldActiveTodoLists) {

            // Do nothing of nothing changed
            if (activeTodoLists === oldActiveTodoLists) {
                return;
            }

            basecampConfig.debug && console.log('Recalculate main active todo list counters');

            // Reset main counters
            $scope.main.activeTodoListsCompletedCount = 0;
            $scope.main.activeTodoListsRemainingCount = 0;

            // Increment counters
            angular.forEach(activeTodoLists, function (todoList) {

                // Increment main counters
                $scope.main.activeTodoListsCompletedCount += todoList.completed_count;
                $scope.main.activeTodoListsRemainingCount += todoList.remaining_count;
            })
        }, true);

        /**
         * Recalculate main counters when main completed todo lists change
         */
        $scope.$watch('main.completedTodoLists', function (completedTodoLists, oldCompletedTodoLists) {

            // Do nothing of nothing changed
            if (completedTodoLists === oldCompletedTodoLists) {
                return;
            }

            basecampConfig.debug && console.log('Recalculate main completed todo list counters');

            // Reset counters
            $scope.main.completedTodoListsCompletedCount = 0;
            $scope.main.completedTodoListsRemainingCount = 0;

            // Increment counters
            angular.forEach(completedTodoLists, function (todoList) {
                $scope.main.completedTodoListsCompletedCount += todoList.completed_count;
                $scope.main.completedTodoListsRemainingCount += todoList.remaining_count;
            })
        }, true);

        /**
         * Bootstrap data
         *
         * Get projects and if it succeeds also get the todo lists
         */
        $scope.bootstrapData = function(){

            $scope.getProjects().success(function (data, status, headers, config) {
                if (angular.isArray(data)) {
                    $scope.main.projects = data;
                    basecampConfig.debug && console.log('Projects:', data);

                    $scope.getActiveTodoLists().success(function (data, status, headers, config) {
                        if (angular.isArray(data)) {
                            $scope.main.activeTodoLists = data;
                            basecampConfig.debug && console.log('Active todo lists:', data);
                        }
                    });

                    $scope.getCompletedTodoLists().success(function (data, status, headers, config) {
                        if (angular.isArray(data)) {
                            $scope.main.completedTodoLists = data;
                            basecampConfig.debug && console.log('Completed todo lists:', data);
                        }
                    });
                }
            });

            $scope.getPeople().success(function (data, status, headers, config) {
                if (angular.isArray(data)) {
                    var rawPeople = data;
                    // basecampConfig.debug && console.log('People:', rawPeople);

                    angular.forEach (rawPeople, function (person) {
                        var personInfo = [];
                        var personProj = [];
                        $http.get('newRecord.php?table=person&id=' + person.id)
                            .error(function (data, status, headers, config) {
                                basecampConfig.debug && console.log('Error while inserting new person ' + data);
                            });
                        $scope.getPersonInfo(person.id).success(function (data, status, headers, config) {
                            var badEmails = ['sga@umbc.edu','berger@umbc.edu','saddison@umbc.edu'];
                            if (badEmails.indexOf(data.email_address) == -1) {
                                personInfo = data;
                                basecampConfig.debug && console.log('Person Info:', personInfo);

                                $scope.getPersonProj(person.id).success(function (data, status, headers, config) {
                                    // if (angular.isArray(data)) {
                                        personProj = data;
                                        basecampConfig.debug && console.log('Person Info:', personInfo);

                                        $scope.main.people.push( { 'info' : personInfo, 'proj' : personProj } );
                                    // }
                                })
                            }
                        })
                    })
                }
            });

            $scope.getGroups().success(function (data, status, headers, config) {
                if (angular.isArray(data)) {
                    var rawGroups = data;

                    angular.forEach (rawGroups, function (group) {
                        $http.get('newRecord.php?table=department&id=' + group.id)
                            .error(function (data, status, headers, config) {
                                basecampConfig.debug && console.log('Error while getting completed todo lists: ' + data);
                            });

                        $scope.getGroup(group.id).success(function (data, status, headers, config) {
                            var groupInfo = data;
                            var group_href = replace_All(replace_All(groupInfo.name.toLowerCase()," ", "-") , "&", "and");
                            groupInfo.group_href = group_href;

                            basecampConfig.debug && console.log('Group Info:', groupInfo);

                            $scope.main.groups.push( groupInfo );
                        })
                    })
                }
            });
        }

        $scope.bootstrapData();

    }])

/**
 * Controller for the home page that displays the project overview
 */
    .controller('HomeController', ['$scope','$http', function ($scope, $http) {
        $scope.featuredProjs = [];

        $scope.getProjects().success(function (data, status, headers, config) {
            if (angular.isArray(data)) {
                var rawProjects = data;

                angular.forEach(rawProjects, function (project) {
                    if (project.starred == true) {
                        $scope.featuredProjs.push(project);
                    }
                })
            }
        })
    }])

/**
 * Controller for the page that displays project details
 */
    .controller('ProjectController', ['$scope','$http', '$routeParams', function ($scope, $http, $routeParams) {

        $scope.project = {};
        $scope.events = [];

        $scope.activeTodoLists = [];
        $scope.completedTodoLists = [];

        $scope.activeTodoListsCompletedCount = 0;
        $scope.activeTodoListsRemainingCount = 0;

        $scope.completedTodoListsCompletedCount = 0;
        $scope.completedTodoListsRemainingCount = 0;

        $scope.prettyDate = function(dateTime){
          var dateStr = dateTime.substring(0,dateTime.indexOf('T'));
          var year = dateStr.substring(0,dateStr.indexOf('-'));
          var rest = dateStr.substring(dateStr.indexOf('-') + 1);
          var month = monthNames[parseInt(rest.substring(0,rest.indexOf('-'))) - 1];
          rest = rest.substring(rest.indexOf('-') + 1);
          var day = rest;
          var prettyDate = day + ' ' + month + ' ' + year;
          return prettyDate;
        }
        $http.get('get.php?url=projects/' + $routeParams.projectId + '.json')
            .success(function (data, status, headers, config) {
                // console.log('SUCCESS');
                // this callback will be called asynchronously
                // when the response is available
                var project = angular.fromJson(data);
                if (angular.isObject(project)) {
                    $scope.project = project;
                    // console.log(project);
                    $scope.project.created_at = $scope.prettyDate($scope.project.created_at);
                    $scope.project.updated_at = $scope.prettyDate($scope.project.updated_at);

                }
            }).
            error(function (data, status, headers, config) {
                // called asynchronously if an error occurs
                // or server returns response with an error status.
                console.log('ERROR');
            })

        $scope.page = 0;
        $scope.more = true;
        $scope.limit = 10;
        $scope.getEventSet = function(){
            if($scope.limit >= $scope.events.length){
                var curDate = '';
                $scope.getProjectEvents($routeParams.projectId, $scope.page).success(function (data, status, headers, config) {
                    if (data.length > 0) {
                        angular.forEach(data,function (event){
                            event.created_at = $scope.prettyDate(event.created_at);
                            event.updated_at = $scope.prettyDate(event.updated_at);

                            var date = event.created_at;
                            if (date === curDate){
                                event.created_at = '';
                            }

                            curDate = date;
                            $scope.events.push(event);
                        })
                    }else{
                        $scope.more = false;
                    }
                })
                $scope.page++;
            }
        }
        $scope.getEventSet();

        $scope.getProjectAccesses($routeParams.projectId).success(function (data, status, headers, config) {
          $scope.people = data;
        })

        // Get active todo lists
        $scope.activeTodoLists = $http.get('get.php?url=projects/' + $routeParams.projectId + '/todolists.json')
            .success(function (data, status, headers, config) {
                // console.log('SUCCESS');
                // this callback will be called asynchronously
                // when the response is available
                var activeTodoLists = angular.fromJson(data);
                if (angular.isArray(activeTodoLists)) {
                    $scope.activeTodoLists = activeTodoLists;
                    // console.log(activeTodoLists);
                }
            }).
            error(function (data, status, headers, config) {
                // called asynchronously if an error occurs
                // or server returns response with an error status.
                console.log('ERROR');
            })

        // Get active todo lists
        $scope.completedTodoLists = $http.get('get.php?url=projects/' + $routeParams.projectId + '/todolists/completed.json')
            .success(function (data, status, headers, config) {
                // console.log('SUCCESS');
                // this callback will be called asynchronously
                // when the response is available
                var completedTodoLists = angular.fromJson(data);
                if (angular.isArray(completedTodoLists)) {
                    $scope.completedTodoLists = completedTodoLists;
                    // console.log(completedTodoLists);
                }
            }).
            error(function (data, status, headers, config) {
                // called asynchronously if an error occurs
                // or server returns response with an error status.
                console.log('ERROR');
            })

        $scope.$watch('activeTodoLists', function (activeTodoLists, oldActiveTodoLists) {

            if (activeTodoLists === oldActiveTodoLists) {
                return;
            }

            $scope.activeTodoListsCompletedCount = 0;
            $scope.activeTodoListsRemainingCount = 0;

            angular.forEach(activeTodoLists, function (todoList) {
                $scope.activeTodoListsCompletedCount += todoList.completed_count;
                $scope.activeTodoListsRemainingCount += todoList.remaining_count;
            })

        }, true);

        $scope.$watch('completedTodoLists', function (completedTodoLists, oldCompletedTodoLists) {

            if (completedTodoLists === oldCompletedTodoLists) {
                return;
            }

            $scope.completedTodoListsCompletedCount = 0;
            $scope.completedTodoListsRemainingCount = 0;

            angular.forEach(completedTodoLists, function (todoList) {
                $scope.completedTodoListsCompletedCount += todoList.completed_count;
                $scope.completedTodoListsRemainingCount += todoList.remaining_count;
            })

        }, true);
    }])

/**
 * Controller for the page that shows the todo lists for a certain project
 */
    .controller('TodoListController', ['$scope','$http', '$routeParams', function ($scope, $http, $routeParams) {

        $scope.projectId = $routeParams.projectId;
        $scope.todoListId = $routeParams.todoListId;
        $scope.todoList = {};

        $scope.project = $http.get('get.php?url=projects/' + $routeParams.projectId + '.json')
            .success(function (data, status, headers, config) {
                console.log('SUCCESS');
                // this callback will be called asynchronously
                // when the response is available
                var project = angular.fromJson(data);
                if (angular.isObject(project)) {
                    $scope.project = project;
                    console.log(project);
                }
            }).
            error(function (data, status, headers, config) {
                // called asynchronously if an error occurs
                // or server returns response with an error status.
                console.log('ERROR');
            })

        // Get todo list including todo's
        $scope.todoList = $http.get('get.php?url=projects/' + $routeParams.projectId + '/todolists/' + $routeParams.todoListId + '.json')
            .success(function (data, status, headers, config) {
                console.log('SUCCESS');
                // this callback will be called asynchronously
                // when the response is available
                var todoList = angular.fromJson(data);
                if (angular.isObject(todoList)) {
                    $scope.todoList = todoList;
                    console.log(todoList);
                }
            }).
            error(function (data, status, headers, config) {
                // called asynchronously if an error occurs
                // or server returns response with an error status.
                console.log('ERROR');
            })
    }])

    .controller('PeopleByDeptController', ['$scope','$http', '$routeParams', function ($scope, $http, $routeParams) {
        $scope.depts = [];
        $scope.scrollTo = function(id) {
            console.log('go yo ' + id);
            $anchorScroll(id);
        }
        var badEmails = ['sga@umbc.edu','berger@umbc.edu','saddison@umbc.edu'];
        $scope.getGroups().success(function (data, status, headers, config) {
            angular.forEach(data,function(dept){
                var department = {};
                $scope.getGroup(dept.id).success(function (data, status, headers, config) {
                    department.name = data.name;
                    department.id = data.id;

                    var people = [];
                    angular.forEach(data.memberships, function(person){
                        if(badEmails.indexOf(person.email_address) == -1)
                            people.push($scope.getPersonPack(person.id));
                    })
                    department.people = people;
                    $scope.depts.push(department);
                })
            })
        })
    }])

    .controller('PeopleByNameController', ['$scope','$http', '$routeParams', function ($scope, $http, $routeParams) {
        $scope.people = {}
        var badEmails = ['sga@umbc.edu','berger@umbc.edu','saddison@umbc.edu'];
        $scope.scrollTo = function(id) {
            $anchorScroll(id);
        }
        $scope.alpha = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
        angular.forEach($scope.alpha, function(letter){
            $scope.people[letter] = [];
        })
        $scope.getPeople().success(function(data, status, headers, config) {
            angular.forEach(data, function(person){
                if(badEmails.indexOf(person.email_address) == -1){
                    var letter = person.name[0].toUpperCase();
                    $scope.people[letter].push($scope.getPersonPack(person.id));
                }
            })
        })
    }])

    .controller('ProjectsByDeptController', ['$scope','$http', '$routeParams', function ($scope, $http, $routeParams) {
        $scope.depts = [];
        $scope.scrollTo = function(id){
            $anchorScroll(id);
        }
        $scope.getGroups().success(function (data, status, headers, config) {
            angular.forEach(data,function(dept){
                var department = {};
                $scope.getGroup(dept.id).success(function (data, status, headers, config) {
                    department.name = data.name;
                    department.id = data.id;

                    var projects = [];
                    angular.forEach(data.memberships, function(person){
                        $scope.getPersonProj(person.id).success(function (data, status, headers, config) {
                            angular.forEach(data, function(proj){
                                if(!proj.template)
                                    projects.push($scope.getProjectPack(proj.id));
                            })
                        })
                    })
                    department.projects = projects;
                    $scope.depts.push(department);
                })
            })
        })
    }])

    .controller('ProjectsByNameController', ['$scope','$http', '$routeParams', function ($scope, $http, $routeParams) {
        $scope.projects = {};
        $scope.alpha = ['A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];
        angular.forEach($scope.alpha, function(letter){
            $scope.projects[letter] = [];
        })
        $scope.getProjects().success(function(data, status, headers, config) {
            angular.forEach(data,function(proj){
                var letter = proj.name[0];
                if(!proj.template)
                    $scope.projects[letter].push($scope.getProjectPack(proj.id));
            })
        })
    }])

    .controller('PersonController', ['$scope','$http', '$routeParams', function ($scope, $http, $routeParams) {
        $scope.events = [];

        $scope.getPersonInfo($routeParams.personId).success(function(data, status, headers, config) {
            $scope.person = data;
            $scope.getExtraPersonInfo($scope.person.id).success(function(data, status, headers, config) {
                $scope.person.bio = data.bio;
                $scope.person.major = data.mojor;
                $scope.person.classStanding = data.classStanding;
                $scope.person.hometown = data.hometown;
                $scope.person.fact = data.fact;
                $scope.person.position = data.personIdtion;
            })
        })

        $scope.depts = $scope.getPersonDepts($routeParams.personId);
        $scope.projs = [];
        $scope.getPersonProj($routeParams.personId).success(function(data, status, headers, config) {
            angular.forEach(data, function(proj){
                if(!proj.template)
                    $scope.projs.push($scope.getProjectPack(proj.id));
            })
        })

        $scope.prettyDate = function(dateTime){
            var dateStr = dateTime.substring(0,dateTime.indexOf('T'));
            var year = dateStr.substring(0,dateStr.indexOf('-'));
            var rest = dateStr.substring(dateStr.indexOf('-') + 1);

            var month = monthNames[parseInt(rest.substring(0,rest.indexOf('-'))) - 1];
            rest = rest.substring(rest.indexOf('-') + 1);
            var day = rest;
            var prettyDate = day + ' ' + month + ' ' + year;
            return prettyDate;
        }

        $scope.page = 1;
        $scope.more = true;
        $scope.limit = 10;
        $scope.getEventSet = function(){
            if($scope.limit >= $scope.events.length){
                var curDate = '';
                $scope.getPersonEvents($routeParams.personId, $scope.page).success(function (data, status, headers, config) {
                    if (data.length > 0) {
                        angular.forEach(data,function (event){
                            event.created_at = $scope.prettyDate(event.created_at);
                            event.updated_at = $scope.prettyDate(event.updated_at);

                            var date = event.created_at;
                            if (date === curDate) {
                                event.created_at = '';
                            }

                            curDate = date;
                            $scope.events.push(event);
                        })
                    }else{
                        $scope.more = false;
                    }
                })
            }
            $scope.page++;
        }
        $scope.getEventSet();

    }])

    .controller('ErrorController', ['$scope','$http', '$routeParams', function ($scope, $http, $routeParams) {
        // do we really need anything here?
    }])

    .controller('DepartmentController', ['$scope','$http', '$routeParams', function ($scope, $http, $routeParams) {
        $scope.id = 0;

        $scope.getGroups().success(function (data, status, headers, config) {
            angular.forEach(data, function(group){
                var group_href = replace_All(replace_All(group.name.toLowerCase()," ", "-") , "&", "and");
                if($routeParams.departmentName == group_href){
                    $scope.id = group.id;
                }
            })
            $scope.getGroup($scope.id).success(function (data, status, headers, config) {
                $scope.department = data;
            })
        })
    }])<|endoftext|>


<commit_before>import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import 'material-design-icons-iconfont/dist/material-design-icons.css';
import 'material-design-lite/material.css';
import 'material-design-lite/material.min';
import FocusDevTools from '../';
import {init, populate} from '../service/firebase';
import dispatcher from './dispatcher-mock';
import stores from './store-mock';
import logger from '../logger/dispatch-logger';
const routeLogger = d => console.log('route' , d)
const strs =  {
    'person': {
      name: 'person',
      getValue: () => ({name: 'Pierre', age: 28})
    },
    'search': {
      name: 'search',
      getValue: () => ({name: 'Don diego', test: [{name: 1}, {name: 1},{name: 1},{name: 3}]})
    }
  };
const routes = [{
  route: /^help(?:\?([\s\S]*))?$/,
  callback: routeLogger
},
{
  route: /^holp(?:\?([\s\S]*))?$/,
  callback: routeLogger
},
{
  route: /^azjbnfhzbfhebhf(?:\?([\s\S]*))?$/,
  callback: routeLogger
}];

init(() => populate(false));
logger(dispatcher, () => stores);
dispatcher.dispatch({action: {type:'DON_UPDATE', data: 'DON_UPDATO', source: 'sourceAction'}});
// Create the react component when the DOM is loaded.
document.addEventListener('DOMContentLoaded', (event) => {

    const rootElement = document.querySelector(`.${__ANCHOR_CLASS__}`);
    const PAGE_TITLE = 'Great example page';
    // The child must be wrapped in a function
    // to work around an issue in React 0.13.
    ReactDOM.render(

              {PAGE_TITLE}

                Link
                Link
                Link

            Notification Center

              Link
              Link
              Link
              Link

                  <FocusDevTools
                    isPanel={true}
                    user='pierr'
                    project='focus_devtools'
                    toggleVisibilityKey='ctrl-m'
                    routes={routes}
                    getStores={() => strs}
                    isDebugDevTools={false}
                  />

,
    rootElement);
});
<commit_msg>[stores]<commit_after>import 'babel-polyfill';
import React from 'react';
import ReactDOM from 'react-dom';
import 'material-design-icons-iconfont/dist/material-design-icons.css';
import 'material-design-lite/material.css';
import 'material-design-lite/material.min';
import FocusDevTools from '../';
import {init, populate} from '../service/firebase';
import dispatcher from './dispatcher-mock';
import stores from './store-mock';
import logger from '../logger/dispatch-logger';
const routeLogger = d => console.log('route' , d)
const strs =  {
    'person': {
      name: 'person',
      getValue: () => ({name: 'Pierre', age: 28})
    },
    'search': {
      name: 'search',
      getValue: () => ({name: 'Don diego', test: [{name: 1}, {name: 1},{name: 1},{name: 3}]})
    }
  };
const routes = [{
  route: /^help(?:\?([\s\S]*))?$/,
  callback: routeLogger
},
{
  route: /^holp(?:\?([\s\S]*))?$/,
  callback: routeLogger
},
{
  route: /^azjbnfhzbfhebhf(?:\?([\s\S]*))?$/,
  callback: routeLogger
}];

init(() => populate(false));
logger(dispatcher, () => stores);
dispatcher.dispatch({action: {type:'DON_UPDATE', data: 'DON_UPDATO', source: 'sourceAction'}});
// Create the react component when the DOM is loaded.
document.addEventListener('DOMContentLoaded', (event) => {

    const rootElement = document.querySelector(`.${__ANCHOR_CLASS__}`);
    const PAGE_TITLE = 'Great example page';
    // The child must be wrapped in a function
    // to work around an issue in React 0.13.
    ReactDOM.render(

              {PAGE_TITLE}

                Link
                Link
                Link

            Notification Center

              Link
              Link
              Link
              Link

                  <FocusDevTools
                    isPanel={true}
                    user='pierr'
                    project='focus_devtools'
                    toggleVisibilityKey='ctrl-m'
                    routes={routes}
                    getStores={() => stores}
                    isDebugDevTools={false}
                  />

,
    rootElement);
});
<|endoftext|>


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

  var A = [0];
  var pointer = 0;
  // because length call is expensive
  var length = 1;

  var code = [];
  var jump = [];
  var cursor = 0;

  var input = [];
  var output = [];

  var inputPtr = 0;
  var inputLength = 0;

  var resetBF = function() {
    A.length = 0;
    A.push(0);
    pointer = 0;
    length = 1;

    code.length = 0;
    jump.length = 0;
    cursor = 0;

    input.length = 0;
    output.length = 0;
    inputPtr = 0;
    inputLength = 0;
  };

  var $ = function(selector) {
    return document.querySelector(selector);
  };

  var $$ = function(selector, node) {
    return node.querySelector(selector);
  };

  var $$$ = function(selector) {
    return document.querySelectorAll(selector);
  };

  var mainEl = $('#main');
  var logEl = $$('#log', mainEl);
  var arrayEl = $$('#array', mainEl);
  var inputEl = $$('#input', mainEl);
  var outputEl = $$('#output', mainEl);
  var consoleEl = $$('#console', mainEl);

  var interpreter = function(token) {
    switch (token) {
      case '+':
        ++A[pointer];
        break;
      case '-':
        --A[pointer];
        break;
      case '>':
        pointer++;
        if (pointer == length) {
          length++;
          A.push(0);
        }
        break;
      case '<':
        if (pointer > 0) {
          pointer--;
        }
        break;
      case '.':
        output.push(String.fromCharCode(A[pointer]));
        break;
      case ',':
        if (inputPtr < input.length) {
          A[pointer] = input.charCodeAt(inputPtr);
          inputPtr++;
        }
        break;
      case '[':
        if (A[pointer] > 0) {
          jump.push(cursor);
        } else {
          var _sum = code.length;
          var _stack = 0;
          for (var i = cursor + 1; (i < _sum || cursor == i); i++) {
            if (code[i] == ']') {
              if (_stack === 0) {
                cursor = i;
              } else {
                _stack--;
              }
            } else if (code[i] == '[') {
              _stack++;
            }
          }
        }
        break;
      case ']':
        if (A[pointer] <= 0) {
          jump.pop();
        } else {
          cursor = jump[jump.length - 1];
          console.log('jump to '+cursor);
        }
        break;
      default:
    }
    cursor++;
  };

  var logToken = function(c, token) {
    console.log('A[' + pointer + '] = ' + A[pointer] + ' next: ' + token + ' line ' + c);
    console.log('  - ' + A);
  };

  var run = function() {
    code = consoleEl.value.split('');
    input = inputEl.value;
    var _sum = code.length;
    for (cursor = 0; cursor < _sum;) {
      logToken(cursor, code[cursor]);
      interpreter(code[cursor]);
    }
    logToken(cursor, code[cursor]);
    outputEl.value = output.join('');
  };

  var inputsBtn = $$$('.btnInput');
  for (var i = 0, sum = inputsBtn.length; i < sum; i++) {
    inputsBtn[i].onclick = function(e) {
      e.preventDefault();
      consoleEl.value += this.text;
      // consoleEl.focus();
    };
  }

  var backBtn = $('#btnBack');
  backBtn.onclick = function(e) {
    e.preventDefault();
    consoleEl.value = consoleEl.value.split('').slice(0, -1).join('');
    // consoleEl.focus();
  };

  var runBtn = $('#btnRun');
  runBtn.onclick = function(e) {
    e.preventDefault();
    this.disabled = true;
    resetBF();
    outputEl.value = '';
    run();
    this.disabled = false;
  };

  var resetBtn = $('#btnReset').onclick = function(e) {
    e.preventDefault();
    resetBF();
    consoleEl.value = '';
    // consoleEl.value = ' ++++++++++[>+++++++<-]>.';
  };

}());

// ++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
// ++++++++++[>+++++++<-]>.
// +++[>++<-]>.<commit_msg>Refactor<commit_after>(function(){
  'use strict';

  var Interpreter = {
    Memory: {
      cells: [0], pointer: 0, length: 1
    },
    Code: {
      source: [], jump: [], pointer: 0
    },
    Input: {
      pointer: 0, length: 0
    },
    input: [],
    output: [],
    process: function(token) {
      switch (token) {
        case '+':
          ++this.Memory.cells[this.Memory.pointer];
          break;
        case '-':
          --this.Memory.cells[this.Memory.pointer];
          break;
        case '>':
          this.Memory.pointer++;
          if (this.Memory.pointer == this.Memory.length) {
            this.Memory.length++;
            this.Memory.cells.push(0);
          }
          break;
        case '<':
          if (this.Memory.pointer > 0) {
            this.Memory.pointer--;
          }
          break;
        case '.':
          this.output.push(String.fromCharCode(this.Memory.cells[this.Memory.pointer]));
          break;
        case ',':
          if (this.Input.pointer < this.Input.length) {
            this.Memory.cells[this.Memory.pointer] = this.input.charCodeAt(this.Input.pointer);
            this.Input.pointer++;
          }
          break;
        case '[':
          if (this.Memory.cells[this.Memory.pointer] > 0) {
            this.Code.jump.push(this.Code.pointer);
          } else {
            var _sum = this.Code.source.length;
            var _stack = 0;
            for (var i = this.Code.pointer + 1; (i < _sum || this.Code.pointer == i); i++) {
              if (this.Code.source[i] == ']') {
                if (_stack === 0) {
                  this.Code.pointer = i;
                } else {
                  _stack--;
                }
              } else if (this.Code.source[i] == '[') {
                _stack++;
              }
            }
          }
          break;
        case ']':
          if (this.Memory.cells[this.Memory.pointer] <= 0) {
            this.Code.jump.pop();
          } else {
            this.Code.pointer = this.Code.jump[this.Code.jump.length - 1];
            console.log('Code.jump to '+this.Code.pointer);
          }
          break;
        default:
      }
      this.Code.pointer++;
    },
    run: function(codeArray, inputArray) {
      this.Code.source = codeArray;
      this.input = inputArray;
      var _sum = this.Code.source.length;
      for (this.Code.pointer = 0; this.Code.pointer < _sum;) {
        this.logToken(this.Code.pointer, this.Code.source[this.Code.pointer]);
        this.process(this.Code.source[this.Code.pointer]);
      }
      this.logToken(this.Code.pointer, this.Code.source[this.Code.pointer]);
      return this.output;
    },
    reset: function() {
      this.Memory.cells.length = 0;
      this.Memory.cells.push(0);
      this.Memory.pointer = 0;
      this.Memory.length = 1;

      this.Code.source.length = 0;
      this.Code.jump.length = 0;
      this.Code.pointer = 0;

      this.input.length = 0;
      this.output.length = 0;
      this.Input.pointer = 0;
      this.Input.length = 0;
    },
    logToken: function(c, token) {
      console.log('A[' + this.Memory.pointer + '] = ' + this.Memory.cells[this.Memory.pointer] + ' next: ' + token + ' line ' + c);
      console.log('  - ' + this.Memory.cells);
    }
  };

  // var interpreter = new Interpreter;

  var $ = function(selector) {
    return document.querySelector(selector);
  };

  var $$ = function(selector, node) {
    return node.querySelector(selector);
  };

  var $$$ = function(selector) {
    return document.querySelectorAll(selector);
  };

  var mainEl = $('#main');
  var logEl = $$('#log', mainEl);
  var arrayEl = $$('#array', mainEl);
  var inputEl = $$('#input', mainEl);
  var outputEl = $$('#output', mainEl);
  var consoleEl = $$('#console', mainEl);

  var logToken = function(c, token) {
    console.log('A[' + pointer + '] = ' + A[pointer] + ' next: ' + token + ' line ' + c);
    console.log('  - ' + A);
  };

  var inputsBtn = $$$('.btnInput');
  for (var i = 0, sum = inputsBtn.length; i < sum; i++) {
    inputsBtn[i].onclick = function(e) {
      e.preventDefault();
      consoleEl.value += this.text;
      // consoleEl.focus();
    };
  }

  var backBtn = $('#btnBack');
  backBtn.onclick = function(e) {
    e.preventDefault();
    consoleEl.value = consoleEl.value.split('').slice(0, -1).join('');
    // consoleEl.focus();
  };

  var runBtn = $('#btnRun');
  runBtn.onclick = function(e) {
    e.preventDefault();
    this.disabled = true;
    Interpreter.reset();
    outputEl.value = '';
    var _output = Interpreter.run(consoleEl.value.split(''), inputEl.value.split(''));
    console.log(_output);
    outputEl.value = _output.join('');
    this.disabled = false;
  };

  var resetBtn = $('#btnReset').onclick = function(e) {
    e.preventDefault();
    Interpreter.reset();
    consoleEl.value = '';
    // consoleEl.value = ' ++++++++++[>+++++++<-]>.';
  };

}());

// ++++++++++[>+++++++>++++++++++>+++>+<<<<-]>++.>+.+++++++..+++.>++.<<+++++++++++++++.>.+++.------.--------.>+.>.
// ++++++++++[>+++++++<-]>.
// +++[>++<-]>.<|endoftext|>


<commit_before>var _ = require('lodash');
var Duo = require('duo');

var through = require('through2');
var gutil = require('gulp-util');
var PluginError = gutil.PluginError;

const PLUGIN_NAME = 'gulp-duo';

function gulpDuo (opts, func) {

  var options = _.defaults(opts || {}, {
    root: process.cwd(),
    standalone: '',
    development: false,
    cache: true,
    copy: false,
    global: '',
    concurrency: 50
  });

  func = _.isFunction(func) ? func : function () {};

  function compile (path, callback) {
    var duo = Duo(options.root)
      .entry(path)
      .standalone(options.standalone)
      .development(options.development)
      .cache(options.cache)
      .copy(options.copy)
      .global(options.global)
      .concurrency(options.concurrency);
    func(duo);
    duo.run(function (err, bundle) {
      callback(null, bundle);
    });
  }

  function duo (file, encoding, callback) {
    if (file.isNull()) {
      return callback(null, file);
    }
    compile(file.path, function (err, bundle) {
      if (err) {
        return callback(err);
      }
      if (file.isStream()) {
        return callback(new PluginError(PLUGIN_NAME, 'Streams not supported!'));
      }
      if (file.isBuffer()) {
        file.contents = new Buffer(bundle.code);
      }
      callback(null, file);
    });
  }

  return through.obj(duo);
}

module.exports = gulpDuo;
<commit_msg>Fix missing error when calling callback<commit_after>var _ = require('lodash');
var Duo = require('duo');

var through = require('through2');
var gutil = require('gulp-util');
var PluginError = gutil.PluginError;

const PLUGIN_NAME = 'gulp-duo';

function gulpDuo (opts, func) {

  var options = _.defaults(opts || {}, {
    root: process.cwd(),
    standalone: '',
    development: false,
    cache: true,
    copy: false,
    global: '',
    concurrency: 50
  });

  func = _.isFunction(func) ? func : function () {};

  function compile (path, callback) {
    var duo = Duo(options.root)
      .entry(path)
      .standalone(options.standalone)
      .development(options.development)
      .cache(options.cache)
      .copy(options.copy)
      .global(options.global)
      .concurrency(options.concurrency);
    func(duo);
    duo.run(function (err, bundle) {
      callback(err, bundle);
    });
  }

  function duo (file, encoding, callback) {
    if (file.isNull()) {
      return callback(null, file);
    }
    compile(file.path, function (err, bundle) {
      if (err) {
        return callback(err);
      }
      if (file.isStream()) {
        return callback(new PluginError(PLUGIN_NAME, 'Streams not supported!'));
      }
      if (file.isBuffer()) {
        file.contents = new Buffer(bundle.code);
      }
      callback(null, file);
    });
  }

  return through.obj(duo);
}

module.exports = gulpDuo;
<|endoftext|>


<commit_before>import IconButton from 'material-ui/IconButton';
import IconMenu from 'material-ui/IconMenu';
import MenuItem from 'material-ui/MenuItem';
import RaisedButton from 'material-ui/RaisedButton';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import ArrowDown from 'material-ui/svg-icons/navigation/arrow-drop-down';
import React from 'react';
import Relay from 'react-relay';

import theme from '../theme';
import ProjectList from './ProjectList';
import ProjectForm from './ProjectForm';
import AddProjectMutation from '../mutations/addProject';

const showUpcomingProjects = 4;
const projectsPerPage = 10;

class Projects extends React.Component {
    static contextTypes = {
        relay: Relay.PropTypes.Environment,
    };

    static propTypes = {
        organization: React.PropTypes.object,
        relay: React.PropTypes.object,
        viewer: React.PropTypes.object,
    }

    static childContextTypes = {
        muiTheme: React.PropTypes.object.isRequired,
    }

    constructor(props) {
        super(props);
        this.muiTheme = getMuiTheme(theme);
    }

    state = {
        addProject: false,
    }

    getChildContext() {
        return { muiTheme: this.muiTheme };
    }

    loadMorePreviousProjects = () => {
        const projects = this.props.organization.previousProjects;
        this.props.relay.setVariables({
            showProjects: projects.edges.length + projectsPerPage,
        });
    }

    loadMoreUpcomongProjects = () => {
        const projects = this.props.organization.nextProjects;
        let next = projects.edges.length + projectsPerPage;

        // upcoming list has just a couple of projects, so at first refill,
        // use default page size
        if (projects.edges.length < projectsPerPage) {
            next = projectsPerPage;
        }
        this.props.relay.setVariables({
            showUpcomingProjects: next,
        });
    }

    toggleAddProject = () => {
        this.setState({ addProject: !this.state.addProject });
    }

    saveProject = (project, callbacks) => {
        this.context.relay.commitUpdate(new AddProjectMutation({
            organization: this.props.organization,
            ...project,
        }), {
            onSuccess: () => {
                if (callbacks && callbacks.onSuccess) {
                    callbacks.onSuccess();
                }
            },
        });
    }

    render() {
        const org = this.props.organization;
        const isMember = this.props.organization.isMember;
        return (

                {isMember
                        ? <ProjectForm
                            open={this.state.addProject}
                            save={this.saveProject}
                            toggle={this.toggleAddProject}
                            viewer={this.props.viewer}
                        />
                        : null
                }

                    {isMember
                        ? <IconMenu
                            iconButtonElement={<IconButton><ArrowDown /></IconButton>}
                            anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
                            targetOrigin={{ vertical: 'top', horizontal: 'right' }}
                        >
                            <MenuItem
                                primaryText="Nytt prosjekt"
                                onTouchTap={this.toggleAddProject}
                            />
                        </IconMenu>
                        : null
                    }

Kommende prosjekter

                        <ProjectList
                            projects={org.nextProjects}
                        />
                        {org.nextProjects.pageInfo.hasNextPage ?
                            <RaisedButton primary onClick={this.loadMoreUpcomongProjects}>Mer</RaisedButton>
                            :
                                null
                        }

Tidligere prosjekter

                        <ProjectList
                            projects={org.previousProjects}
                        />
                        {org.previousProjects.pageInfo.hasNextPage ?
                            <RaisedButton primary onClick={this.loadMorePreviousProjects}>Mer</RaisedButton>
                            :
                                null
                        }

        );
    }
}

export default Relay.createContainer(Projects, {
    initialVariables: {
        showUpcomingProjects,
        showProjects: projectsPerPage,
        projectsPerPage,
    },
    fragments: {
        organization: () => Relay.QL`
        fragment on Organization {
            isMember
            nextProjects(first:$showUpcomingProjects) {
                edges {
                    node {
                        id
                        title
                        start
                        end
                        year
                        tag
                        publicMdtext
                        poster {
                            filename
                            largePath
                        }
                    }
                }
                pageInfo {
                    hasNextPage
                }
            }
            previousProjects(first:$showProjects) {
                edges {
                    node {
                        id
                        title
                        start
                        end
                        year
                        tag
                        poster {
                            filename
                            normalPath
                        }
                    }
                }
                pageInfo {
                    hasNextPage
                }
            }
            ${AddProjectMutation.getFragment('organization')}
        }`,
        viewer: () => Relay.QL`
        fragment on User {
            id
            ${ProjectForm.getFragment('viewer')}
        }`,
    },
});
<commit_msg>Unsaved file, didn't get this in earlier.<commit_after>import IconButton from 'material-ui/IconButton';
import IconMenu from 'material-ui/IconMenu';
import MenuItem from 'material-ui/MenuItem';
import RaisedButton from 'material-ui/RaisedButton';
import getMuiTheme from 'material-ui/styles/getMuiTheme';
import ArrowDown from 'material-ui/svg-icons/navigation/arrow-drop-down';
import React from 'react';
import Relay from 'react-relay';

import theme from '../theme';
import ProjectList from './ProjectList';
import ProjectForm from './ProjectForm';
import AddProjectMutation from '../mutations/addProject';

const showUpcomingProjects = 4;
const projectsPerPage = 10;

class Projects extends React.Component {
    static contextTypes = {
        relay: Relay.PropTypes.Environment,
    };

    static propTypes = {
        organization: React.PropTypes.object,
        relay: React.PropTypes.object,
        viewer: React.PropTypes.object,
    }

    static childContextTypes = {
        muiTheme: React.PropTypes.object.isRequired,
    }

    constructor(props) {
        super(props);
        this.muiTheme = getMuiTheme(theme);
    }

    state = {
        addProject: false,
    }

    getChildContext() {
        return { muiTheme: this.muiTheme };
    }

    loadMorePreviousProjects = () => {
        const projects = this.props.organization.previousProjects;
        this.props.relay.setVariables({
            showProjects: projects.edges.length + projectsPerPage,
        });
    }

    loadMoreUpcomongProjects = () => {
        const projects = this.props.organization.nextProjects;
        let next = projects.edges.length + projectsPerPage;

        // upcoming list has just a couple of projects, so at first refill,
        // use default page size
        if (projects.edges.length < projectsPerPage) {
            next = projectsPerPage;
        }
        this.props.relay.setVariables({
            showUpcomingProjects: next,
        });
    }

    toggleAddProject = () => {
        this.setState({ addProject: !this.state.addProject });
    }

    saveProject = (project, callbacks) => {
        this.context.relay.commitUpdate(new AddProjectMutation({
            organization: this.props.organization,
            ...project,
        }), {
            onSuccess: () => {
                if (callbacks && callbacks.onSuccess) {
                    callbacks.onSuccess();
                }
            },
        });
    }

    render() {
        const org = this.props.organization;
        const isMember = this.props.organization.isMember;
        return (

                {isMember
                        ? <ProjectForm
                            open={this.state.addProject}
                            save={this.saveProject}
                            toggle={this.toggleAddProject}
                            viewer={this.props.viewer}
                        />
                        : null
                }

                    {isMember
                        ? <IconMenu
                            iconButtonElement={<IconButton><ArrowDown /></IconButton>}
                            anchorOrigin={{ vertical: 'top', horizontal: 'right' }}
                            targetOrigin={{ vertical: 'top', horizontal: 'right' }}
                        >
                            <MenuItem
                                primaryText="Nytt prosjekt"
                                onTouchTap={this.toggleAddProject}
                            />
                        </IconMenu>
                        : null
                    }

Kommende prosjekter

                        <ProjectList
                            projects={org.nextProjects}
                        />
                        {org.nextProjects.pageInfo.hasNextPage ?
                            <RaisedButton primary onClick={this.loadMoreUpcomongProjects}>Mer</RaisedButton>
                            :
                                null
                        }

Tidligere prosjekter

                        <ProjectList
                            projects={org.previousProjects}
                        />
                        {org.previousProjects.pageInfo.hasNextPage ?
                            <RaisedButton primary onClick={this.loadMorePreviousProjects}>Mer</RaisedButton>
                            :
                                null
                        }

        );
    }
}

export default Relay.createContainer(Projects, {
    initialVariables: {
        showUpcomingProjects,
        showProjects: projectsPerPage,
        projectsPerPage,
    },
    fragments: {
        organization: () => Relay.QL`
        fragment on Organization {
            isMember
            nextProjects(first:$showUpcomingProjects) {
                edges {
                    node {
                        id
                        title
                        start
                        end
                        year
                        tag
                        publicMdtext
                        poster {
                            filename
                            normalPath
                        }
                    }
                }
                pageInfo {
                    hasNextPage
                }
            }
            previousProjects(first:$showProjects) {
                edges {
                    node {
                        id
                        title
                        start
                        end
                        year
                        tag
                        poster {
                            filename
                            normalPath
                        }
                    }
                }
                pageInfo {
                    hasNextPage
                }
            }
            ${AddProjectMutation.getFragment('organization')}
        }`,
        viewer: () => Relay.QL`
        fragment on User {
            id
            ${ProjectForm.getFragment('viewer')}
        }`,
    },
});
<|endoftext|>


<commit_before>/**
 * Extends an existing reducer with additional handlers
 * @param {function} reducer - a reducer function
 * @param {object} handlers - handler object like used in createReducer()
 * @returns {function} returns a reducer
 */
export const extendReducer = (reducer, handlers) => (state, action) => {
  const stateForReducer = handlers.hasOwnProperty(action.type)
    ? handlers[action.type](state, action)
    : state;

  return reducer(stateForReducer, action);
};
<commit_msg>Improve jsdoc of extendReducer()<commit_after>/**
 * Extends an existing reducer with additional action type handlers
 * @param {function} reducer - a reducer function
 * @param {object} handlers
 *   handler object
 *     where key is the action type to be handled
 *           value is a reducer function with signature:
 *             (state, action) => newState
 * @returns {function} returns a reducer
 */
export const extendReducer = (reducer, handlers) => (state, action) => {
  const stateForReducer = handlers.hasOwnProperty(action.type)
    ? handlers[action.type](state, action)
    : state;

  return reducer(stateForReducer, action);
};
<|endoftext|>