<commit_before>module.exports = function (app, db, common) {

  // This could become a middleware in an ideal reality.
  //
  // Ecmascript 6 would make this easier...
  // let [ fields, start, size, sort ] = handle_parameters(req);
  function handle_parameters (req, callback) {
    if (req.params.server == null) {
      req.params.server = undefined;
    }

    if (req.params.version == null) {
      req.params.version = undefined;
    }

    var fields = ((req.query.fields == null ? 'slug,plugin_name,description' : req.query.fields).split(','));
    var start = req.query.start == null ? undefined : parseInt(req.query.start);
    var size = req.query.size == null ? undefined : parseInt(req.query.size);
    var sort = req.query.sort == null ? 'slug' : req.query.sort;

    return callback(fields, start, size, sort);
  }

  function geninfo (req, res, next) {
    handle_parameters(req, function (fields, start, size, sort) {
      common.list_geninfo(size, function (callback) {
        res.send(callback);
      });
    });
  }

  function plugin_list (req, res, next) {
    handle_parameters(req, function (fields, start, size, sort) {
      common.list_plugins(req.params.server, fields, sort, start, size, function (callback) {
        res.send(callback);
      });
    });
  }

  function plugin_details (req, res, next) {
    handle_parameters(req, function (fields, start, size, sort) {
      common.plugin_details(req.params.server, req.params.slug, req.params.version, fields, function (data) {
        if (data == null) {
          return res.send(404, "Plugin Does Not Exist");
        }

        if (size != undefined) {
          data['versions'].length = size;
        }

        res.send(data);
      });
    });
  }

  function author_plugins (req, res, next) {
    handle_parameters(req, function (fields, start, size, sort) {
      common.list_author_plugins(req.params.server, req.params.name, fields, sort, start, size, function (callback) {
        res.send(callback);
      });
    });
  }

  function category_plugins (req, res, next) {
    handle_parameters(req, function (fields, start, size, sort) {
      common.list_category_plugins(req.params.server, req.params.name, fields, sort, start, size, function (callback) {
        res.send(callback);
      });
    });
  }

  app.get('/3', function (req, res, next) {
    geninfo(req, res, next);
  });

  app.get('/3/geninfo', function (req, res, next) {
    geninfo(req, res, next);
  });

  app.get('/3/geninfo/:idnum', function (req, res, next) {
    common.get_geninfo(req.params.idnum, function (callback) {
      res.send(callback);
    });
  });

  app.get('/3/plugins', function (req, res, next) {
    plugin_list(req, res, next);
  });

  app.get('/3/plugins/:server', function (req, res, next) {
    plugin_list(req, res, next);
  });

  app.get('/3/plugins/:server/:slug', function (req, res, next) {
    plugin_details(req, res, next);
  });

  app.get('/3/plugins/:server/:slug/:version', function (req, res, next) {
    plugin_details(req, res, next);
  });

  app.get('/3/plugins/:server/:slug/:version/download', function (req, res, next) {
    common.plugin_details(req.params.server, req.params.slug, req.params.version, {}, function(data) {
      if (data == null) {
        res.send(404, "Plugin Does Not Exist");
      }

      if (req.params.version.toLowerCase() == "latest") {
        res.header('Location', data['versions'][0]['download']);
        res.send(302);
      } else {
        for (var i = 0, il = data['versions'].length; i < il; i++) {
          if (data['versions'][i]['version'] == req.params.version) {
            res.header('Location', data['versions'][i]['download']);
            res.send(302);
          }
        }
      }

      res.send(404, {"error": "could not find version"});
    });
  });

  app.get('/3/authors', function (req, res, next) {
    common.list_authors(function (callback) {
      res.send(callback);
    });
  });

  app.get('/3/authors/:name', function (req, res, next) {
    author_plugins(req, res, next);
  });

  app.get('/3/authors/:server/:name', function (req, res, next) {
    author_plugins(req, res, next);
  });

  app.get('/3/categories', function (req, res, next) {
    common.list_categories(function (callback) {
      res.send(callback);
    });
  });

  app.get('/3/categories/:name', function (req, res, next) {
    category_plugins(req, res, next);
  });

  app.get('/3/categories/:server/:name', function (req, res, next) {
    category_plugins(req, res, next);
  });

  app.post('/3/updates', function (req, res, next) {
    var slugs = (req.params.slugs == null ? '' : req.params.slugs).split(',');
    var server = req.params.server == null ? 'bukkit' : req.params.server;
    common.plugins_up_to_date(slugs, server, function (callback) {
      res.send(callback);
    });
  });

  app.get('/3/updates', function (req, res, next) {
    var slugs = (req.query.slugs == null ? '' : req.query.slugs).split(',');
    var server = req.query.server == null ? 'bukkit' : req.query.server;

    common.plugins_up_to_date(slugs, server, function (callback) {
      res.send(callback);
    });
  });

  function search (req, res, next) {
    var filters = []

    if (req.method == 'GET') {
      var fields = ((req.query.fields == null ? 'slug,plugin_name,description' : req.query.fields).split(','));
      var start = req.query.start == null ? undefined : parseInt(req.query.start);
      var size = req.query.size == null ? undefined : parseInt(req.query.size);
      var sort = req.query.sort == null ? 'slug' : req.query.sort;
      var field = req.params[0];
      var value = req.params[2];
      filters = [{
        'field': field,
        'action': req.params[1],
        'value': value
      }];
    } else {
      var filters = req.params.filters == null ? [] : JSON.parse(req.params.filters);
      var fields = ((req.params.fields == null ? 'slug,plugin_name,description' : req.params.fields).split(','));
      var start = req.params.start == null ? undefined : parseInt(req.params.start);
      var size = req.params.size == null ? undefined : parseInt(req.params.size);
      var sort = req.params.sort == null ? 'slug' : req.params.sort;
    }

    common.plugin_search(filters, fields, sort, start, size, false, function (callback) {
      if (callback == null) {
        return res.send(400, {
          "error": "invalid search"
        });
      }

      res.send(callback);
    });
  }

  app.post('/3/search', function (req, res, next) {
    search(req, res, next);
  });

  app.get(/^\/3\/search\/([a-zA-Z0-9_\.~-]+)\/(\=|\!\=|\<|\<\=|\>|\>\=|[a-z]+)\/([a-zA-Z0-9_\.~-]+)/, function (req, res, next) {
    search(req, res, next);
  });
}<commit_msg>Woops<commit_after>module.exports = function (app, db, common) {

  // This could become a middleware in an ideal reality.
  //
  // Ecmascript 6 would make this easier...
  // let [ fields, start, size, sort ] = handle_parameters(req);
  function handle_parameters (req, callback) {
    if (req.params.server == null) {
      req.params.server = undefined;
    }

    if (req.params.version == null) {
      req.params.version = undefined;
    }

    var fields = ((req.query.fields == null ? 'slug,plugin_name,description' : req.query.fields).split(','));
    var start = req.query.start == null ? undefined : parseInt(req.query.start);
    var size = req.query.size == null ? undefined : parseInt(req.query.size);
    var sort = req.query.sort == null ? 'slug' : req.query.sort;

    return callback(fields, start, size, sort);
  }

  function geninfo (req, res, next) {
    handle_parameters(req, function (fields, start, size, sort) {
      common.list_geninfo(size, function (callback) {
        res.send(callback);
      });
    });
  }

  function plugin_list (req, res, next) {
    handle_parameters(req, function (fields, start, size, sort) {
      common.list_plugins(req.params.server, fields, sort, start, size, function (callback) {
        res.send(callback);
      });
    });
  }

  function plugin_details (req, res, next) {
    handle_parameters(req, function (fields, start, size, sort) {
      common.plugin_details(req.params.server, req.params.slug, req.params.version, fields, function (data) {
        if (data == null) {
          return res.send(404, "Plugin Does Not Exist");
        }

        if (size != undefined && data['versions'] != null) {
          data['versions'].length = size;
        }

        res.send(data);
      });
    });
  }

  function author_plugins (req, res, next) {
    handle_parameters(req, function (fields, start, size, sort) {
      common.list_author_plugins(req.params.server, req.params.name, fields, sort, start, size, function (callback) {
        res.send(callback);
      });
    });
  }

  function category_plugins (req, res, next) {
    handle_parameters(req, function (fields, start, size, sort) {
      common.list_category_plugins(req.params.server, req.params.name, fields, sort, start, size, function (callback) {
        res.send(callback);
      });
    });
  }

  app.get('/3', function (req, res, next) {
    geninfo(req, res, next);
  });

  app.get('/3/geninfo', function (req, res, next) {
    geninfo(req, res, next);
  });

  app.get('/3/geninfo/:idnum', function (req, res, next) {
    common.get_geninfo(req.params.idnum, function (callback) {
      res.send(callback);
    });
  });

  app.get('/3/plugins', function (req, res, next) {
    plugin_list(req, res, next);
  });

  app.get('/3/plugins/:server', function (req, res, next) {
    plugin_list(req, res, next);
  });

  app.get('/3/plugins/:server/:slug', function (req, res, next) {
    plugin_details(req, res, next);
  });

  app.get('/3/plugins/:server/:slug/:version', function (req, res, next) {
    plugin_details(req, res, next);
  });

  app.get('/3/plugins/:server/:slug/:version/download', function (req, res, next) {
    common.plugin_details(req.params.server, req.params.slug, req.params.version, {}, function(data) {
      if (data == null) {
        res.send(404, "Plugin Does Not Exist");
      }

      if (req.params.version.toLowerCase() == "latest") {
        res.header('Location', data['versions'][0]['download']);
        res.send(302);
      } else {
        for (var i = 0, il = data['versions'].length; i < il; i++) {
          if (data['versions'][i]['version'] == req.params.version) {
            res.header('Location', data['versions'][i]['download']);
            res.send(302);
          }
        }
      }

      res.send(404, {"error": "could not find version"});
    });
  });

  app.get('/3/authors', function (req, res, next) {
    common.list_authors(function (callback) {
      res.send(callback);
    });
  });

  app.get('/3/authors/:name', function (req, res, next) {
    author_plugins(req, res, next);
  });

  app.get('/3/authors/:server/:name', function (req, res, next) {
    author_plugins(req, res, next);
  });

  app.get('/3/categories', function (req, res, next) {
    common.list_categories(function (callback) {
      res.send(callback);
    });
  });

  app.get('/3/categories/:name', function (req, res, next) {
    category_plugins(req, res, next);
  });

  app.get('/3/categories/:server/:name', function (req, res, next) {
    category_plugins(req, res, next);
  });

  app.post('/3/updates', function (req, res, next) {
    var slugs = (req.params.slugs == null ? '' : req.params.slugs).split(',');
    var server = req.params.server == null ? 'bukkit' : req.params.server;
    common.plugins_up_to_date(slugs, server, function (callback) {
      res.send(callback);
    });
  });

  app.get('/3/updates', function (req, res, next) {
    var slugs = (req.query.slugs == null ? '' : req.query.slugs).split(',');
    var server = req.query.server == null ? 'bukkit' : req.query.server;

    common.plugins_up_to_date(slugs, server, function (callback) {
      res.send(callback);
    });
  });

  function search (req, res, next) {
    var filters = []

    if (req.method == 'GET') {
      var fields = ((req.query.fields == null ? 'slug,plugin_name,description' : req.query.fields).split(','));
      var start = req.query.start == null ? undefined : parseInt(req.query.start);
      var size = req.query.size == null ? undefined : parseInt(req.query.size);
      var sort = req.query.sort == null ? 'slug' : req.query.sort;
      var field = req.params[0];
      var value = req.params[2];
      filters = [{
        'field': field,
        'action': req.params[1],
        'value': value
      }];
    } else {
      var filters = req.params.filters == null ? [] : JSON.parse(req.params.filters);
      var fields = ((req.params.fields == null ? 'slug,plugin_name,description' : req.params.fields).split(','));
      var start = req.params.start == null ? undefined : parseInt(req.params.start);
      var size = req.params.size == null ? undefined : parseInt(req.params.size);
      var sort = req.params.sort == null ? 'slug' : req.params.sort;
    }

    common.plugin_search(filters, fields, sort, start, size, false, function (callback) {
      if (callback == null) {
        return res.send(400, {
          "error": "invalid search"
        });
      }

      res.send(callback);
    });
  }

  app.post('/3/search', function (req, res, next) {
    search(req, res, next);
  });

  app.get(/^\/3\/search\/([a-zA-Z0-9_\.~-]+)\/(\=|\!\=|\<|\<\=|\>|\>\=|[a-z]+)\/([a-zA-Z0-9_\.~-]+)/, function (req, res, next) {
    search(req, res, next);
  });
}<|endoftext|>


<commit_before>var gulp = require('gulp');
var ghPages = require('gulp-gh-pages');
var markdown = require('gulp-markdown');
var rename = require("gulp-rename");
var htmlreplace = require('gulp-html-replace');

gulp.task('markdown', function () {
    return gulp.src('README.md')
        .pipe(rename("index.md"))
        .pipe(markdown())
        .pipe(gulp.dest('examples'));
});

gulp.task('copy-minitracker', function () {
    return gulp.src('build/minitracker.js')
        .pipe(gulp.dest('dist'));
});

gulp.task('build', ['copy-minitracker', 'markdown'], function () {
    return gulp.src('examples/**/*')
        .pipe(htmlreplace({
            'minitracker': '../minitracker.js'
        }))
        .pipe(gulp.dest('dist'));
});

gulp.task('deploy', ['build'], function() {
    return gulp.src('./examples/**/*')
        .pipe(ghPages());
});
<commit_msg>Update build example process<commit_after>var gulp = require('gulp');
var ghPages = require('gulp-gh-pages');
var markdown = require('gulp-markdown');
var rename = require("gulp-rename");
var htmlreplace = require('gulp-html-replace');

gulp.task('markdown', function () {
    return gulp.src('README.md')
        .pipe(rename("index.md"))
        .pipe(markdown())
        .pipe(gulp.dest('examples'));
});

gulp.task('copy-minitracker', function () {
    return gulp.src('build/minitracker.js')
        .pipe(gulp.dest('dist'));
});

gulp.task('copy-examples', function () {
    return gulp.src('examples/**/*')
        .pipe(gulp.dest('dist'));
});

gulp.task('build', ['copy-examples', 'copy-minitracker', 'markdown'], function () {
    return gulp.src('examples/**/*.html')
        .pipe(htmlreplace({
            'minitracker': '../minitracker.js'
        }))
        .pipe(gulp.dest('dist'));
});

gulp.task('deploy', ['build'], function() {
    return gulp.src('./dist/**/*')
        .pipe(ghPages());
});
<|endoftext|>


<commit_before>/*
Copyright Microsoft Corporation

Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at

http://www.apache.org/licenses/LICENSE-2.0

THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
ARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.

See the Apache 2 License for the specific language governing permissions and
limitations under the License. */

(function (mstats) {
    mstats.ajax = function (require) {

        var rootUrl = require('rootUrl'),
            $ = require('$');

        var cache = {},
        namedParametersPattern = /:(\w)*/g;

        var invalidations = {
            '/Vehicle/Add': ['/', '/Charts'],
            '/Vehicle/:id/Fillup/Add': ['/', '/Charts', '/Vehicle/:id/Fillup/List', '/Vehicle/:id/Details'],
            '/Vehicle/:id/Edit': ['/', '/Charts', '/Vehicle/:id/Details'],
            '/Vehicle/Delete/:id': ['/', '/Charts', '/Vehicle/:id/Details'],
            '/Vehicle/:id/Reminder/Add': ['/', '/Vehicle/:id/Reminder/ListByGroup'],
            '/Vehicle/:id/Reminder/:reminderId/Fulfill': ['/', '/Vehicle/:id/Reminder/ListByGroup', '/Vehicle/:id/Reminder/:reminderId/Details']
        };

        function buildRegExpForMatching(route) {
            var pattern = route.replace(/\//g, '\\/').replace(namedParametersPattern, '(\\w+)') + '$';
            return new RegExp(pattern);
        }

        function get(token) {
            return cache[token];
        }

        function set(token, payload) {
            cache[token] = payload;
        }

        function clear(token) {
            if (cache[token]) {
                delete cache[token];
            }
        }

        function enforceInvalidations(url) {
            var entry,
                re,
                params,
                routesToRemove,
                actualUrls;

            for (entry in invalidations) {
                re = buildRegExpForMatching(entry);
                if (url.match(re)) {
                    params = extractedNameParameters(re, entry, url);
                    routesToRemove = invalidations[entry];
                    actualUrls = combineValuesWithRoutes(params, routesToRemove);
                    invalidate(actualUrls);
                }
            }
        }

        function invalidate(entries) {
            forEach(entries, clear);
        }

        function extractedNameParameters(re, entry, url) {
            var named, i;
            var values = url.match(re);
            var names = entry.match(namedParametersPattern);

            var params = {};

            if (names) {
                for (i = 0; i < names.length; i++) {
                    named = ':' + names[i].slice(1);
                    params[named] = values[i + 1];
                }
            }

            return params;
        }

        function combineValuesWithRoutes(params, routes) {

            var urls = [];

            forEach(routes, function (route) {
                var name;
                for (name in params) {
                    route = route.replace(name, params[name]);
                    route = route.replace('/', rootUrl);
                }
                urls.push(route);
            });

            return urls;
        }

        function forEach(array, op) {
            var len = array.length,
                index = 0;

            for (; index < len; index++) {
                op(array[index]);
            }
        }

        function request(options) {
            var url = options.url.replace('?format=json', ''),
                success = options.success,
                cachedData = get(url);

            if (cachedData) {
                options.success(cachedData);
                return;
            }

            options.success = function (data) {
                set(url, data);
                success(data);
            };

            $.ajax(options);
        }

        function post(options) {
            var url = options.url,
                success = options.success;

            options.success = function (data) {
                enforceInvalidations(url);
                success(data);
            };

            $.ajax(options);
        }

        return {
            request: request,
            post: post
        };
    };
} (this.mstats = this.mstats || {}));<commit_msg>#405, #406 and #408. fixed misspelling of /Chart route and expiring Fillup Add page when Fillup Add is hit.<commit_after>/*
Copyright Microsoft Corporation

Licensed under the Apache License, Version 2.0 (the "License"); you may not
use this file except in compliance with the License. You may obtain a copy of
the License at

http://www.apache.org/licenses/LICENSE-2.0

THIS CODE IS PROVIDED *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED
ARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE,
MERCHANTABLITY OR NON-INFRINGEMENT.

See the Apache 2 License for the specific language governing permissions and
limitations under the License. */

(function (mstats) {
    mstats.ajax = function (require) {

        var rootUrl = require('rootUrl'),
            $ = require('$');

        var cache = {},
        namedParametersPattern = /:(\w)*/g;

        var invalidations = {
            '/Vehicle/Add': ['/', '/Chart'],
            '/Vehicle/:id/Fillup/Add': ['/', '/Chart', '/Vehicle/:id/Fillup/List', '/Vehicle/:id/Details', '/Vehicle/:id/Fillup/Add'],
            '/Vehicle/:id/Edit': ['/', '/Chart', '/Vehicle/:id/Details'],
            '/Vehicle/Delete/:id': ['/', '/Chart', '/Vehicle/:id/Details'],
            '/Vehicle/:id/Reminder/Add': ['/', '/Vehicle/:id/Reminder/ListByGroup'],
            '/Vehicle/:id/Reminder/:reminderId/Fulfill': ['/', '/Vehicle/:id/Reminder/ListByGroup', '/Vehicle/:id/Reminder/:reminderId/Details']
        };

        function buildRegExpForMatching(route) {
            var pattern = route.replace(/\//g, '\\/').replace(namedParametersPattern, '(\\w+)') + '$';
            return new RegExp(pattern);
        }

        function get(token) {
            return cache[token];
        }

        function set(token, payload) {
            cache[token] = payload;
        }

        function clear(token) {
            if (cache[token]) {
                delete cache[token];
            }
        }

        function enforceInvalidations(url) {
            var entry,
                re,
                params,
                routesToRemove,
                actualUrls;

            for (entry in invalidations) {
                re = buildRegExpForMatching(entry);
                if (url.match(re)) {
                    params = extractedNameParameters(re, entry, url);
                    routesToRemove = invalidations[entry];
                    actualUrls = combineValuesWithRoutes(params, routesToRemove);
                    invalidate(actualUrls);
                }
            }
        }

        function invalidate(entries) {
            forEach(entries, clear);
        }

        function extractedNameParameters(re, entry, url) {
            var named, i;
            var values = url.match(re);
            var names = entry.match(namedParametersPattern);

            var params = {};

            if (names) {
                for (i = 0; i < names.length; i++) {
                    named = ':' + names[i].slice(1);
                    params[named] = values[i + 1];
                }
            }

            return params;
        }

        function combineValuesWithRoutes(params, routes) {

            var urls = [];

            forEach(routes, function (route) {
                var name;
                for (name in params) {
                    route = route.replace(name, params[name]);
                    route = route.replace('/', rootUrl);
                }
                urls.push(route);
            });

            return urls;
        }

        function forEach(array, op) {
            var len = array.length,
                index = 0;

            for (; index < len; index++) {
                op(array[index]);
            }
        }

        function request(options) {
            var url = options.url.replace('?format=json', ''),
                success = options.success,
                cachedData = get(url);

            if (cachedData) {
                options.success(cachedData);
                return;
            }

            options.success = function (data) {
                set(url, data);
                success(data);
            };

            $.ajax(options);
        }

        function post(options) {
            var url = options.url,
                success = options.success;

            options.success = function (data) {
                enforceInvalidations(url);
                success(data);
            };

            $.ajax(options);
        }

        return {
            request: request,
            post: post
        };
    };
} (this.mstats = this.mstats || {}));<|endoftext|>


<commit_before>enyo.kind({
	name: "Ares",
	kind: "Control",
	classes: "app onyx",
	fit: true,
	components: [
		{kind: "Panels", /*arrangerKind: "CarouselArranger",*/ classes: "enyo-fit", components: [
			{kind: "Phobos", onSaveDocument: "saveDocument", onCloseDocument: "closeDocument", onDesignDocument: "designDocument", onEditedChanged: "documentEdited"},
			{kind: "Deimos", onCloseDesigner: "closeDesigner"}
		]},
		{kind: "Slideable", layoutKind: "FittableRowsLayout", classes: "onyx ares-files-slider", axis: "v", value: 0, min: -500, max: 0, unit: "px", draggable: false, onAnimateFinish: "finishedSliding", components: [
			{kind: "ProjectView", fit: true, classes: "onyx", onFileDblClick: "doubleclickFile"},
			{name: "bottomBar", kind: "DocumentToolbar",
			    onGrabberTap: "toggleFiles",
				onSwitchFile: "switchFile",
				onSave: "bounceSave",
				onDesign: "bounceDesign",
				onNewKind: "bounceNew",
				onClose: "bounceClose"
			}
		]},
		{kind: "ServiceRegistry"}
	],
	handlers: {
		onReloadServices: "handleReloadServices"
	},
	phobosViewIndex: 0,
	deimosViewIndex: 1,
	create: function() {
		if (this.runTest) {
			ProjectList.underTest = true;
		}
		this.inherited(arguments);
		this.$.panels.setIndex(this.phobosViewIndex);

		window.onbeforeunload = enyo.bind(this, "handleBeforeUnload");
		if (this.runTest) {
			// in charge of Ares Test Suite when Ares Ide launch with runTest option
			this.createComponent({kind: "ares.TestController"});
		}
		this.calcSlideableLimit();
	},
	rendered: function() {
		this.inherited(arguments);
		this.calcSlideableLimit();
	},
	openFiles: {},
	draggable: false,
	handleReloadServices: function(inSender, inEvent) {
		this.$.serviceRegistry.reloadServices();
	},
	doubleclickFile: function(inSender, inEvent) {
		var f = inEvent.file;
		var d = this.openFiles[inEvent.file.id];
		if (d) {
			this.switchToDocument(d);
		} else {
			this.$.bottomBar.createFileTab(f.name, f.id);
			this.$.slideable.setDraggable(true);
			this.openDocument(inSender, inEvent);
		}
	},
	openDocument: function(inSender, inEvent) {
		var f = inEvent.file;
		var projectData = inEvent.projectData;
		var service = projectData.getService();
		var ext = f.name.split(".").pop();
		this.$.phobos.beginOpenDoc();
		service.getFile(f.id)
			.response(this, function(inEvent, inData) {
				if (inData.content) {
					inData=inData.content;
				} else {
					// no data? Empty file
					inData="";
				}
				if (this.openFiles[f.id]) {
					alert("Duplicate File ID in cache!");
				}
				var doc = {
					file: f,
					data: inData,
					extension: ext,
					projectData: projectData,
					edited: false
				};
				this.openFiles[f.id] = doc;
				this.switchToDocument(doc);
			})
			.error(this, function(inEvent, inData) {
				enyo.log("Open failed", inData);
				this.$.phobos.hideWaitPopup();
			});
	},
	saveDocument: function(inSender, inEvent) {
		var service = inEvent.file.service;
		service.putFile(inEvent.file.id, inEvent.content)
			.response(this, function(inEvent, inData) {
				inSender.saveComplete();
				this.$.deimos.saveComplete();
			})
			.error(this, function(inEvent, inData) {
				inSender.saveFailed(inData);
			});
	},
	closeDocument: function(inSender, inEvent) {
		var id = inSender.file.id;
		// remove file from cache
		delete this.openFiles[id];
		this.$.bottomBar.removeTab(id);
		this.$.slideable.setDraggable(Object.keys(this.openFiles).count > 0);
		this.showFiles();
	},
	designDocument: function(inSender, inEvent) {
		this.$.deimos.load(inEvent);
		this.$.panels.setIndex(this.deimosViewIndex);
	},
	closeDesigner: function(inSender, inEvent) {
		if (inEvent.docHasChanged) {
			this.$.phobos.updateComponents(inSender, inEvent);
		}
		this.$.panels.setIndex(this.phobosViewIndex);
	},
	handleBeforeUnload: function() {
		if (window.location.search.indexOf("debug") == -1) {
			return 'You may have some unsaved data';
		}
	},
	hideFiles: function(inSender, inEvent) {
		this.$.slideable.animateToMin();
	},
	showFiles: function(inSender, inEvent) {
		this.$.slideable.animateToMax();
	},
	toggleFiles: function(inSender, inEvent) {
		if (this.$.slideable.value < 0 || Object.keys(this.openFiles).length === 0) {
			this.showFiles();
		} else {
			this.hideFiles();
		}
	},
	resizeHandler: function(inSender, inEvent) {
		this.inherited(arguments);
		this.calcSlideableLimit();
		if (this.$.slideable.value < 0) {
			this.$.slideable.setValue(this.$.slideable.min);
		}
	},
	calcSlideableLimit: function() {
		var min = this.getBounds().height-this.$.bottomBar.getBounds().height;
		this.$.slideable.setMin(-min);
	},
	switchFile: function(inSender, inEvent) {
		var d = this.openFiles[inEvent.id];
		if (d) {
			this.switchToDocument(d);
		} else {
			alert("File ID not found in cache!");
		}
	},
	switchToDocument: function(d) {
		// save document state
		if (this.activeDocument) {
			this.activeDocument.data = this.$.phobos.getEditorContent();
		}
		if (!this.activeDocument || d !== this.activeDocument) {
			this.$.phobos.openDoc(d.file, d.data, d.extension, d.projectData, d.edited);
		}
		this.$.panels.setIndex(this.phobosViewIndex);
		this.$.bottomBar.activateFileWithId(d.file.id);
		this.hideFiles();
		this.activeDocument = d;
	},
	finishedSliding: function(inSender, inEvent) {
		if (this.$.slideable.value < 0) {
			this.$.bottomBar.showControls();
		} else {
			this.$.bottomBar.hideControls();
		}
	},
	// FIXME: This trampoline function probably needs some refactoring
	bounceSave: function(inSender, inEvent) {
		this.$.phobos.saveDocAction(inSender, inEvent);
	},
	// FIXME: This trampoline function probably needs some refactoring
	bounceDesign: function(inSender, inEvent) {
		var editorMode = this.$.panels.getIndex() == this.phobosViewIndex;
		this.adjustBarMode();
		if (editorMode) {
			this.$.phobos.designerAction(inSender, inEvent);
		} else {
			this.$.deimos.closeDesignerAction();
		}
	},
	adjustBarMode: function() {
		var designMode = this.$.panels.getIndex() == this.deimosViewIndex;
		this.$.bottomBar.setDesignMode(designMode);
	},
	// FIXME: This trampoline function probably needs some refactoring
	bounceNew: function(inSender, inEvent) {
		this.$.phobos.newKindAction(inSender, inEvent);
	},
	// FIXME: This trampoline function probably needs some refactoring
	// Close is a special case, because it can be invoked on a document other than the currently-active one
	bounceClose: function(inSender, inEvent) {
		this.switchFile(inSender, inEvent);
		enyo.asyncMethod(this.$.phobos, "closeDocAction");
	},
	documentEdited: function(inSender, inEvent) {
		var id = inEvent.id;
		if (this.openFiles[id]) {
			this.openFiles[id].edited = inEvent.edited;
		} else {
			alert("File ID not found in cache!");
		}
	}
});
<commit_msg>Fix some inverted DocumentToolbar logic<commit_after>enyo.kind({
	name: "Ares",
	kind: "Control",
	classes: "app onyx",
	fit: true,
	components: [
		{kind: "Panels", /*arrangerKind: "CarouselArranger",*/ classes: "enyo-fit", components: [
			{kind: "Phobos", onSaveDocument: "saveDocument", onCloseDocument: "closeDocument", onDesignDocument: "designDocument", onEditedChanged: "documentEdited"},
			{kind: "Deimos", onCloseDesigner: "closeDesigner"}
		]},
		{kind: "Slideable", layoutKind: "FittableRowsLayout", classes: "onyx ares-files-slider", axis: "v", value: 0, min: -500, max: 0, unit: "px", draggable: false, onAnimateFinish: "finishedSliding", components: [
			{kind: "ProjectView", fit: true, classes: "onyx", onFileDblClick: "doubleclickFile"},
			{name: "bottomBar", kind: "DocumentToolbar",
			    onGrabberTap: "toggleFiles",
				onSwitchFile: "switchFile",
				onSave: "bounceSave",
				onDesign: "bounceDesign",
				onNewKind: "bounceNew",
				onClose: "bounceClose"
			}
		]},
		{kind: "ServiceRegistry"}
	],
	handlers: {
		onReloadServices: "handleReloadServices"
	},
	phobosViewIndex: 0,
	deimosViewIndex: 1,
	create: function() {
		if (this.runTest) {
			ProjectList.underTest = true;
		}
		this.inherited(arguments);
		this.$.panels.setIndex(this.phobosViewIndex);
		this.adjustBarMode();

		window.onbeforeunload = enyo.bind(this, "handleBeforeUnload");
		if (this.runTest) {
			// in charge of Ares Test Suite when Ares Ide launch with runTest option
			this.createComponent({kind: "ares.TestController"});
		}
		this.calcSlideableLimit();
	},
	rendered: function() {
		this.inherited(arguments);
		this.calcSlideableLimit();
	},
	openFiles: {},
	draggable: false,
	handleReloadServices: function(inSender, inEvent) {
		this.$.serviceRegistry.reloadServices();
	},
	doubleclickFile: function(inSender, inEvent) {
		var f = inEvent.file;
		var d = this.openFiles[inEvent.file.id];
		if (d) {
			this.switchToDocument(d);
		} else {
			this.$.bottomBar.createFileTab(f.name, f.id);
			this.$.slideable.setDraggable(true);
			this.openDocument(inSender, inEvent);
		}
	},
	openDocument: function(inSender, inEvent) {
		var f = inEvent.file;
		var projectData = inEvent.projectData;
		var service = projectData.getService();
		var ext = f.name.split(".").pop();
		this.$.phobos.beginOpenDoc();
		service.getFile(f.id)
			.response(this, function(inEvent, inData) {
				if (inData.content) {
					inData=inData.content;
				} else {
					// no data? Empty file
					inData="";
				}
				if (this.openFiles[f.id]) {
					alert("Duplicate File ID in cache!");
				}
				var doc = {
					file: f,
					data: inData,
					extension: ext,
					projectData: projectData,
					edited: false
				};
				this.openFiles[f.id] = doc;
				this.switchToDocument(doc);
			})
			.error(this, function(inEvent, inData) {
				enyo.log("Open failed", inData);
				this.$.phobos.hideWaitPopup();
			});
	},
	saveDocument: function(inSender, inEvent) {
		var service = inEvent.file.service;
		service.putFile(inEvent.file.id, inEvent.content)
			.response(this, function(inEvent, inData) {
				inSender.saveComplete();
				this.$.deimos.saveComplete();
			})
			.error(this, function(inEvent, inData) {
				inSender.saveFailed(inData);
			});
	},
	closeDocument: function(inSender, inEvent) {
		var id = inSender.file.id;
		// remove file from cache
		delete this.openFiles[id];
		this.$.bottomBar.removeTab(id);
		this.$.slideable.setDraggable(Object.keys(this.openFiles).count > 0);
		this.showFiles();
	},
	designDocument: function(inSender, inEvent) {
		this.$.deimos.load(inEvent);
		this.$.panels.setIndex(this.deimosViewIndex);
		this.adjustBarMode();
	},
	closeDesigner: function(inSender, inEvent) {
		if (inEvent.docHasChanged) {
			this.$.phobos.updateComponents(inSender, inEvent);
		}
		this.$.panels.setIndex(this.phobosViewIndex);
		this.adjustBarMode();
	},
	handleBeforeUnload: function() {
		if (window.location.search.indexOf("debug") == -1) {
			return 'You may have some unsaved data';
		}
	},
	hideFiles: function(inSender, inEvent) {
		this.$.slideable.animateToMin();
	},
	showFiles: function(inSender, inEvent) {
		this.$.slideable.animateToMax();
	},
	toggleFiles: function(inSender, inEvent) {
		if (this.$.slideable.value < 0 || Object.keys(this.openFiles).length === 0) {
			this.showFiles();
		} else {
			this.hideFiles();
		}
	},
	resizeHandler: function(inSender, inEvent) {
		this.inherited(arguments);
		this.calcSlideableLimit();
		if (this.$.slideable.value < 0) {
			this.$.slideable.setValue(this.$.slideable.min);
		}
	},
	calcSlideableLimit: function() {
		var min = this.getBounds().height-this.$.bottomBar.getBounds().height;
		this.$.slideable.setMin(-min);
	},
	switchFile: function(inSender, inEvent) {
		var d = this.openFiles[inEvent.id];
		if (d) {
			this.switchToDocument(d);
		} else {
			alert("File ID not found in cache!");
		}
	},
	switchToDocument: function(d) {
		// save document state
		if (this.activeDocument) {
			this.activeDocument.data = this.$.phobos.getEditorContent();
		}
		if (!this.activeDocument || d !== this.activeDocument) {
			this.$.phobos.openDoc(d.file, d.data, d.extension, d.projectData, d.edited);
		}
		this.$.panels.setIndex(this.phobosViewIndex);
		this.adjustBarMode();
		this.$.bottomBar.activateFileWithId(d.file.id);
		this.hideFiles();
		this.activeDocument = d;
	},
	finishedSliding: function(inSender, inEvent) {
		if (this.$.slideable.value < 0) {
			this.$.bottomBar.showControls();
		} else {
			this.$.bottomBar.hideControls();
		}
	},
	// FIXME: This trampoline function probably needs some refactoring
	bounceSave: function(inSender, inEvent) {
		this.$.phobos.saveDocAction(inSender, inEvent);
	},
	// FIXME: This trampoline function probably needs some refactoring
	bounceDesign: function(inSender, inEvent) {
		var editorMode = this.$.panels.getIndex() == this.phobosViewIndex;
		if (editorMode) {
			this.$.phobos.designerAction(inSender, inEvent);
		} else {
			this.$.deimos.closeDesignerAction();
		}
	},
	adjustBarMode: function() {
		var designMode = this.$.panels.getIndex() == this.deimosViewIndex;
		this.$.bottomBar.setDesignMode(designMode);
	},
	// FIXME: This trampoline function probably needs some refactoring
	bounceNew: function(inSender, inEvent) {
		this.$.phobos.newKindAction(inSender, inEvent);
	},
	// FIXME: This trampoline function probably needs some refactoring
	// Close is a special case, because it can be invoked on a document other than the currently-active one
	bounceClose: function(inSender, inEvent) {
		this.switchFile(inSender, inEvent);
		enyo.asyncMethod(this.$.phobos, "closeDocAction");
	},
	documentEdited: function(inSender, inEvent) {
		var id = inEvent.id;
		if (this.openFiles[id]) {
			this.openFiles[id].edited = inEvent.edited;
		} else {
			alert("File ID not found in cache!");
		}
	}
});
<|endoftext|>


<commit_before><commit_msg>refs #16612 dojox/mvc/StatefulArray should work without passing an array to the constructor. Thanks neonstalwart. !strict<commit_after><|endoftext|>


<commit_before>import ns from 'imajs/client/core/namespace.js';

ns.namespace('Core.Router');

/**
 * Regular expression matching all control characters used in regular
 * expressions. The regular expression is used to match these characters in
 * path expressions and replace them appropriately so the path expression can
 * be compiled to a regular expression.
 *
 * @const
 * @property
 * @type {RegExp}
 */
const CONTROL_CHARACTERS_REGEXP = /[\\.+*?\^$\[\](){}\/\'#]/g;

/**
 * Regular expression used to match and remove the strating and trailing
 * forward slashes from a path expression or a URL path.
 *
 * @const
 * @property
 * @type {RegExp}
 */
const LOOSE_SLASHES_REGEXP = /^\/|\/$/g;

/**
 * Regular expression used to match the parameter names from a path expression.
 *
 * @const
 * @property PARAMS_REGEXP
 * @type {RegExp}
 */
const PARAMS_REGEXP = /:([a-zA-Z0-9_-]*)/g;

/**
 * Utility for representing and manipulating a single route in the router's
 * configuration.
 *
 * @class Route
 * @namespace Core.Router
 * @module Core
 * @submodule Core.Router
 */
export default class Route {

	/**
	 * Initializes the route.
	 *
	 * @constructor
	 * @method constructor
	 * @param {string} name The unique name of this route, identifying it among
	 *        the rest of the routes in the application.
	 * @param {string} pathExpression A path expression specifying the URL path
	 *        part matching this route (must not contain a query string),
	 *        optionally containing named parameter placeholders specified as
	 *        {@code :parameterName}.
	 * @param {string} controller The full name of Object Container alias
	 *        identifying the controller associated with this route.
	 * @param {string} view The full name or Object Container alias identifying
	 *        the view class associated with this route.
	 * @param {{onlyUpdate: boolean, autoScroll: boolean}} [options={onlyUpdate: false, autoScroll: true}] The route additional options.
	 */
	constructor(name, pathExpression, controller, view, options = {onlyUpdate: false, autoScroll: true}) {
		/**
		 * The unique name of this route, identifying it among the rest of the
		 * routes in the application.
		 *
		 * @private
		 * @property _name
		 * @type {string}
		 */
		this._name = name;

		/**
		 * The original URL path expression from which this route was created.
		 *
		 * @private
		 * @property _pathExpression
		 * @type {string}
		 */
		this._pathExpression = pathExpression;

		/**
		 * The full name of Object Container alias identifying the controller
		 * associated with this route.
		 *
		 * @private
		 * @property _controller
		 * @type {string}
		 */
		this._controller = controller;

		/**
		 * The full name or Object Container alias identifying the view class
		 * associated with this route.
		 *
		 * @private
		 * @property _view
		 * @type {Vendor.React.Component}
		 */
		this._view = view;

		/**
		 * The route additional options.
		 *
		 * @private
		 * @property _options
		 * @type {{onlyUpdate: boolean}}
		 */
		this._options = options;

		/**
		 * The path expression with the trailing slashes trimmed.
		 *
		 * @private
		 * @property _trimmedPathExpression
		 * @type {string}
		 */
		this._trimmedPathExpression = this._getTrimmedPath(pathExpression);

		/**
		 * The names of the parameters in this route.
		 *
		 * @private
		 * @property _parameterNames
		 * @type {string[]}
		 */
		this._parameterNames = this._getParameterNames(pathExpression);

		/**
		 * Set to {@code true} if this route contains parameters in its path.
		 *
		 * @private
		 * @property _hasParameters
		 * @type {boolean}
		 */
		this._hasParameters = !!this._parameterNames.length;

		/**
		 * A regexp used to match URL path against this route and extract the
		 * parameter values from the matched URL paths.
		 *
		 * @private
		 * @property _matcher
		 * @type {RegExp}
		 */
		this._matcher = this._compileToRegExp(this._trimmedPathExpression);
	}

	/**
	 * Creates the URL and query parts of a URL by substituting the route's
	 * parameter placeholders by the provided parameter value.
	 *
	 * The extraneous parameters that do not match any of the route's
	 * placeholders will be appended as the query string.
	 *
	 * @method toPath
	 * @param {Object<string, (number|string)>} [params={}] The route parameter
	 *        values.
	 * @return {string} Path and, if neccessary, query parts of the URL
	 *         representing this route with its parameters replaced by the
	 *         provided parameter values.
	 */
	toPath(params = {}) {
		var path = this._pathExpression;
		var query = [];

		for (var paramName of Object.keys(params)) {
			if (path.indexOf(`:${paramName}`) > -1) {
				path = path.replace(`:${paramName}`, params[paramName], 'g');
			} else {
				var pair = [paramName, params[paramName]].map(encodeURIComponent);
				query.push(pair.join('='));
			}
		}

		path = query.length ? (path + '?' + query.join('&')) : path;
		path = this._getTrimmedPath(path);

		return path;
	}

	/**
	 * Returns the unique identifying name of this route.
	 *
	 * @method getName
	 * @return {string} The name of the route, identifying it.
	 */
	getName() {
		return this._name;
	}

	/**
	 * Returns the full name of the controller to use when this route is matched
	 * by the current URL, or an Object Container-registered alias of the
	 * controller.
	 *
	 * @method getController
	 * @return {string} The name of alias of the controller.
	 */
	getController() {
		return this._controller;
	}

	/**
	 * Returns the full name of the view class or an Object Container-registered
	 * alias for the view class, representing the view to use when this route is
	 * matched by the current URL.
	 *
	 * @method getView
	 * @return {string} The name or alias of the view class.
	 */
	getView() {
		return this._view;
	}

	/**
	 * Return route additional options.
	 *
	 * @method getOptions
	 * @return {{onlyUpdate: boolean}}
	 */
	getOptions() {
		return this._options;
	}

	/**
	 * Returns the path expression, which is the parametrized pattern matching
	 * the URL paths matched by this route.
	 *
	 * @method getPathExpression
	 * @return {string} The path expression.
	 */
	getPathExpression() {
		return this._pathExpression;
	}

	/**
	 * Tests whether the provided URL path matches this route. The provided path
	 * may contain the query.
	 *
	 * @method matches
	 * @param {string} path The URL path.
	 * @return {boolean} {@code true} if the provided path matches this route.
	 */
	matches(path) {
		var trimmedPath = this._getTrimmedPath(path);
		return this._matcher.test(trimmedPath);
	}

	/**
	 * Extracts the parameter values from the provided path. The method extracts
	 * both the in-path parameters and parses the query, allowing the query
	 * parameters to override the in-path parameters.
	 *
	 * The method returns an empty hash object if the path does not match this
	 * route.
	 *
	 * @method extractParameters
	 * @param {string} path
	 * @return {Object<string, ?string>} Map of parameter names to parameter
	 *         values.
	 */
	extractParameters(path) {
		var trimmedPath = this._getTrimmedPath(path);
		var parameters = this._getParameters(trimmedPath);
		var query = this._getQuery(trimmedPath);

		return Object.assign({}, parameters, query);
	}

	/**
	 * Compiles the path expression to a regular expression that can be used for
	 * easier matching of URL paths against this route, and extracting the path
	 * parameter values from the URL path.
	 *
	 * @private
	 * @method _compileToRegExp
	 * @param {string} pathExpression The path expression to compile.
	 * @return {RegExp} The compiled regular expression.
	 */
	_compileToRegExp(pathExpression) {
		var pattern = pathExpression
			.replace(LOOSE_SLASHES_REGEXP, '')
			.replace(CONTROL_CHARACTERS_REGEXP, '\\$&');

		// convert parameters to capture sequences
		pattern = pattern.replace(PARAMS_REGEXP, '([^/?]+)');

		// add path root
		pattern = '^/' + pattern;

		// add query parameters matcher
		var pairPattern = '[^=&;]*(?:=[^&;]*)?';
		pattern += `(?:\\?(?:${pairPattern})(?:[&;]${pairPattern})*)?$`;

		return new RegExp(pattern);
	}

	/**
	 * Parses the provided path and extract the in-path parameters. The method
	 * decodes the parameters and returns them in a hash object.
	 *
	 * @private
	 * @method _getParameters
	 * @param {string} path The URL path.
	 * @return {Object<string, string>} The parsed path parameters.
	 */
	_getParameters(path) {
		if (!this._hasParameters) {
			return {};
		}

		var parameterValues = path.match(this._matcher);
		if (!parameterValues) {
			return {};
		}

		var parameters = {};
		parameterValues.shift(); // remove the match on whole path
		for (var parameterName of this._parameterNames) {
			var decodedValue = decodeURIComponent(parameterValues.shift());
			parameters[parameterName] = decodedValue;
		}

		return parameters;
	}

	/**
	 * Extracts and decodes the query parameters from the provided URL path and
	 * query.
	 *
	 * @private
	 * @method _getQuery
	 * @param {string} path The URL path, including the optional query string (if
	 *        any).
	 * @return {Object<string, ?string>} Parsed query parameters.
	 */
	_getQuery(path) {
		var query = {};
		var queryStart = path.indexOf('?');
		var hasQuery = (queryStart > -1) && (queryStart !== (path.length - 1));

		if (hasQuery) {
			var pairs = path.substring(queryStart + 1).split(/[&;]/);

			for (var parameterPair of pairs) {
				var pair = parameterPair.split('=');
				query[decodeURIComponent(pair[0])] =
					(pair.length > 1) ? decodeURIComponent(pair[1]) : true;
			}
		}

		return query;
	}

	/**
	 * Trimms the trailing forward slash from the provided URL path.
	 *
	 * @private
	 * @method getLoosesPath
	 * @param {string} path The path to trim.
	 * @return {string} Trimmed path.
	 */
	_getTrimmedPath(path) {
		return `/${path.replace(LOOSE_SLASHES_REGEXP, '')}`;
	}

	/**
	 * Extracts the parameter names from the provided path expression.
	 *
	 * @private
	 * @method _getParameterNames
	 * @param {string} pathExpression The path expression.
	 * @return {string[]} The names of the parameters defined in the provided
	 *         path expression.
	 */
	_getParameterNames(pathExpression) {
		var rawNames = pathExpression.match(PARAMS_REGEXP) || [];

		return rawNames.map(rawParameterName => rawParameterName.substring(1));
	}
}

ns.Core.Router.Route = Route;
<commit_msg>#14 fix bug with default route options<commit_after>import ns from 'imajs/client/core/namespace.js';

ns.namespace('Core.Router');

/**
 * Regular expression matching all control characters used in regular
 * expressions. The regular expression is used to match these characters in
 * path expressions and replace them appropriately so the path expression can
 * be compiled to a regular expression.
 *
 * @const
 * @property
 * @type {RegExp}
 */
const CONTROL_CHARACTERS_REGEXP = /[\\.+*?\^$\[\](){}\/\'#]/g;

/**
 * Regular expression used to match and remove the strating and trailing
 * forward slashes from a path expression or a URL path.
 *
 * @const
 * @property
 * @type {RegExp}
 */
const LOOSE_SLASHES_REGEXP = /^\/|\/$/g;

/**
 * Regular expression used to match the parameter names from a path expression.
 *
 * @const
 * @property PARAMS_REGEXP
 * @type {RegExp}
 */
const PARAMS_REGEXP = /:([a-zA-Z0-9_-]*)/g;

/**
 * Utility for representing and manipulating a single route in the router's
 * configuration.
 *
 * @class Route
 * @namespace Core.Router
 * @module Core
 * @submodule Core.Router
 */
export default class Route {

	/**
	 * Initializes the route.
	 *
	 * @constructor
	 * @method constructor
	 * @param {string} name The unique name of this route, identifying it among
	 *        the rest of the routes in the application.
	 * @param {string} pathExpression A path expression specifying the URL path
	 *        part matching this route (must not contain a query string),
	 *        optionally containing named parameter placeholders specified as
	 *        {@code :parameterName}.
	 * @param {string} controller The full name of Object Container alias
	 *        identifying the controller associated with this route.
	 * @param {string} view The full name or Object Container alias identifying
	 *        the view class associated with this route.
	 * @param {{onlyUpdate: boolean, autoScroll: boolean}} [options] The route additional options.
	 */
	constructor(name, pathExpression, controller, view, options) {
		/**
		 * The unique name of this route, identifying it among the rest of the
		 * routes in the application.
		 *
		 * @private
		 * @property _name
		 * @type {string}
		 */
		this._name = name;

		/**
		 * The original URL path expression from which this route was created.
		 *
		 * @private
		 * @property _pathExpression
		 * @type {string}
		 */
		this._pathExpression = pathExpression;

		/**
		 * The full name of Object Container alias identifying the controller
		 * associated with this route.
		 *
		 * @private
		 * @property _controller
		 * @type {string}
		 */
		this._controller = controller;

		/**
		 * The full name or Object Container alias identifying the view class
		 * associated with this route.
		 *
		 * @private
		 * @property _view
		 * @type {Vendor.React.Component}
		 */
		this._view = view;

		/**
		 * The route additional options.
		 *
		 * @private
		 * @property _options
		 * @type {{onlyUpdate: boolean, autoScroll: boolean}}
		 * @default {onlyUpdate: false, autoScroll: true}
		 */
		this._options = Object.assign(
			{onlyUpdate: false, autoScroll: true},
			options
		);

		/**
		 * The path expression with the trailing slashes trimmed.
		 *
		 * @private
		 * @property _trimmedPathExpression
		 * @type {string}
		 */
		this._trimmedPathExpression = this._getTrimmedPath(pathExpression);

		/**
		 * The names of the parameters in this route.
		 *
		 * @private
		 * @property _parameterNames
		 * @type {string[]}
		 */
		this._parameterNames = this._getParameterNames(pathExpression);

		/**
		 * Set to {@code true} if this route contains parameters in its path.
		 *
		 * @private
		 * @property _hasParameters
		 * @type {boolean}
		 */
		this._hasParameters = !!this._parameterNames.length;

		/**
		 * A regexp used to match URL path against this route and extract the
		 * parameter values from the matched URL paths.
		 *
		 * @private
		 * @property _matcher
		 * @type {RegExp}
		 */
		this._matcher = this._compileToRegExp(this._trimmedPathExpression);
	}

	/**
	 * Creates the URL and query parts of a URL by substituting the route's
	 * parameter placeholders by the provided parameter value.
	 *
	 * The extraneous parameters that do not match any of the route's
	 * placeholders will be appended as the query string.
	 *
	 * @method toPath
	 * @param {Object<string, (number|string)>} [params={}] The route parameter
	 *        values.
	 * @return {string} Path and, if neccessary, query parts of the URL
	 *         representing this route with its parameters replaced by the
	 *         provided parameter values.
	 */
	toPath(params = {}) {
		var path = this._pathExpression;
		var query = [];

		for (var paramName of Object.keys(params)) {
			if (path.indexOf(`:${paramName}`) > -1) {
				path = path.replace(`:${paramName}`, params[paramName], 'g');
			} else {
				var pair = [paramName, params[paramName]].map(encodeURIComponent);
				query.push(pair.join('='));
			}
		}

		path = query.length ? (path + '?' + query.join('&')) : path;
		path = this._getTrimmedPath(path);

		return path;
	}

	/**
	 * Returns the unique identifying name of this route.
	 *
	 * @method getName
	 * @return {string} The name of the route, identifying it.
	 */
	getName() {
		return this._name;
	}

	/**
	 * Returns the full name of the controller to use when this route is matched
	 * by the current URL, or an Object Container-registered alias of the
	 * controller.
	 *
	 * @method getController
	 * @return {string} The name of alias of the controller.
	 */
	getController() {
		return this._controller;
	}

	/**
	 * Returns the full name of the view class or an Object Container-registered
	 * alias for the view class, representing the view to use when this route is
	 * matched by the current URL.
	 *
	 * @method getView
	 * @return {string} The name or alias of the view class.
	 */
	getView() {
		return this._view;
	}

	/**
	 * Return route additional options.
	 *
	 * @method getOptions
	 * @return {{onlyUpdate: boolean}}
	 */
	getOptions() {
		return this._options;
	}

	/**
	 * Returns the path expression, which is the parametrized pattern matching
	 * the URL paths matched by this route.
	 *
	 * @method getPathExpression
	 * @return {string} The path expression.
	 */
	getPathExpression() {
		return this._pathExpression;
	}

	/**
	 * Tests whether the provided URL path matches this route. The provided path
	 * may contain the query.
	 *
	 * @method matches
	 * @param {string} path The URL path.
	 * @return {boolean} {@code true} if the provided path matches this route.
	 */
	matches(path) {
		var trimmedPath = this._getTrimmedPath(path);
		return this._matcher.test(trimmedPath);
	}

	/**
	 * Extracts the parameter values from the provided path. The method extracts
	 * both the in-path parameters and parses the query, allowing the query
	 * parameters to override the in-path parameters.
	 *
	 * The method returns an empty hash object if the path does not match this
	 * route.
	 *
	 * @method extractParameters
	 * @param {string} path
	 * @return {Object<string, ?string>} Map of parameter names to parameter
	 *         values.
	 */
	extractParameters(path) {
		var trimmedPath = this._getTrimmedPath(path);
		var parameters = this._getParameters(trimmedPath);
		var query = this._getQuery(trimmedPath);

		return Object.assign({}, parameters, query);
	}

	/**
	 * Compiles the path expression to a regular expression that can be used for
	 * easier matching of URL paths against this route, and extracting the path
	 * parameter values from the URL path.
	 *
	 * @private
	 * @method _compileToRegExp
	 * @param {string} pathExpression The path expression to compile.
	 * @return {RegExp} The compiled regular expression.
	 */
	_compileToRegExp(pathExpression) {
		var pattern = pathExpression
			.replace(LOOSE_SLASHES_REGEXP, '')
			.replace(CONTROL_CHARACTERS_REGEXP, '\\$&');

		// convert parameters to capture sequences
		pattern = pattern.replace(PARAMS_REGEXP, '([^/?]+)');

		// add path root
		pattern = '^/' + pattern;

		// add query parameters matcher
		var pairPattern = '[^=&;]*(?:=[^&;]*)?';
		pattern += `(?:\\?(?:${pairPattern})(?:[&;]${pairPattern})*)?$`;

		return new RegExp(pattern);
	}

	/**
	 * Parses the provided path and extract the in-path parameters. The method
	 * decodes the parameters and returns them in a hash object.
	 *
	 * @private
	 * @method _getParameters
	 * @param {string} path The URL path.
	 * @return {Object<string, string>} The parsed path parameters.
	 */
	_getParameters(path) {
		if (!this._hasParameters) {
			return {};
		}

		var parameterValues = path.match(this._matcher);
		if (!parameterValues) {
			return {};
		}

		var parameters = {};
		parameterValues.shift(); // remove the match on whole path
		for (var parameterName of this._parameterNames) {
			var decodedValue = decodeURIComponent(parameterValues.shift());
			parameters[parameterName] = decodedValue;
		}

		return parameters;
	}

	/**
	 * Extracts and decodes the query parameters from the provided URL path and
	 * query.
	 *
	 * @private
	 * @method _getQuery
	 * @param {string} path The URL path, including the optional query string (if
	 *        any).
	 * @return {Object<string, ?string>} Parsed query parameters.
	 */
	_getQuery(path) {
		var query = {};
		var queryStart = path.indexOf('?');
		var hasQuery = (queryStart > -1) && (queryStart !== (path.length - 1));

		if (hasQuery) {
			var pairs = path.substring(queryStart + 1).split(/[&;]/);

			for (var parameterPair of pairs) {
				var pair = parameterPair.split('=');
				query[decodeURIComponent(pair[0])] =
					(pair.length > 1) ? decodeURIComponent(pair[1]) : true;
			}
		}

		return query;
	}

	/**
	 * Trimms the trailing forward slash from the provided URL path.
	 *
	 * @private
	 * @method getLoosesPath
	 * @param {string} path The path to trim.
	 * @return {string} Trimmed path.
	 */
	_getTrimmedPath(path) {
		return `/${path.replace(LOOSE_SLASHES_REGEXP, '')}`;
	}

	/**
	 * Extracts the parameter names from the provided path expression.
	 *
	 * @private
	 * @method _getParameterNames
	 * @param {string} pathExpression The path expression.
	 * @return {string[]} The names of the parameters defined in the provided
	 *         path expression.
	 */
	_getParameterNames(pathExpression) {
		var rawNames = pathExpression.match(PARAMS_REGEXP) || [];

		return rawNames.map(rawParameterName => rawParameterName.substring(1));
	}
}

ns.Core.Router.Route = Route;
<|endoftext|>


<commit_before>var Foolish = function() {

	var self = this;
	self.getIndex = _getIndex;
	self.getNextIndex = _getNextIndex;
	self.getPreviousIndex = _getPreviousIndex;
	self.isLast = _isLast;
	self.isFirst = _isFirst;

	function _isLast(array, element) {
		var lastIndex = array.length-1;
		var indexOfElement = array.indexOf(element);
		return indexOfElement === lastIndex;
	}

	 function _isFirst(array, element) {
		var indexOfElement = array.indexOf(element);
		return indexOfElement === 0;
	}

	function _getIndex(array, element) {
	  return array.indexOf(element);
	}

	function _getNextIndex(array, element) {
		var lastIndex = array.length-1;
		var indexOfElement = array.indexOf(element);
		if(indexOfElement === -1) {
			return -1;
		}
		if(indexOfElement === lastIndex) {
			return 0;
		}
		var nextIndex = indexOfElement + 1;
		return nextIndex;
	}

	function _getPreviousIndex(array, element) {
		var lastIndex = array.length-1;
		var indexOfElement = _getIndex(array, element);
		if(indexOfElement === -1) {
			return -1;
		}
		if(indexOfElement === 0) {
			return lastIndex;
		}
		var previousIndex = indexOfElement - 1;
		return previousIndex;
	}

};<commit_msg>new function for get the next indexes<commit_after>var Foolish = function() {

	var self = this;
	self.getIndex = _getIndex;
	self.getNextIndex = _getNextIndex;
	self.getPreviousIndex = _getPreviousIndex;
	self.isLast = _isLast;
	self.isFirst = _isFirst;

	function _isLast(array, element) {
		var lastIndex = array.length-1;
		var indexOfElement = array.indexOf(element);
		return indexOfElement === lastIndex;
	}

	 function _isFirst(array, element) {
		var indexOfElement = array.indexOf(element);
		return indexOfElement === 0;
	}

	function _getIndex(array, element) {
	  return array.indexOf(element);
	}

	function _getNextIndex(array, element) {
		var lastIndex = array.length-1;
		var indexOfElement = array.indexOf(element);
		if(indexOfElement === -1) {
			return -1;
		}
		if(indexOfElement === lastIndex) {
			return 0;
		}
		var nextIndex = indexOfElement + 1;
		return nextIndex;
	}

	function _getPreviousIndex(array, element) {
		var lastIndex = array.length-1;
		var indexOfElement = _getIndex(array, element);
		if(indexOfElement === -1) {
			return -1;
		}
		if(indexOfElement === 0) {
			return lastIndex;
		}
		var previousIndex = indexOfElement - 1;
		return previousIndex;
	}

	function _getNextIndexes(array, element, count) {
		var nextIndexes = [];
		var currentElement = element;
		for(i = 0; i < count; i++) {
			var nextIndex = _getNextIndex(array, currentElement);
			nextIndexes.push(nextIndex);
			currentElement = array[nextIndex];
		}
		return nextIndexes;
	}

};
<|endoftext|>


<commit_before>/*
 * Translated default messages for the jQuery validation plugin.
 * Locale: SK (Slovak; slovenčina, slovenský jazyk)
 */
$.extend( $.validator.messages, {
	required: "Povinné zadať.",
	maxlength: $.validator.format( "Maximálne {0} znakov." ),
	minlength: $.validator.format( "Minimálne {0} znakov." ),
	rangelength: $.validator.format( "Minimálne {0} a Maximálne {1} znakov." ),
	email: "E-mailová adresa musí byť platná.",
	url: "URL musí byť platný.",
	date: "Musí byť dátum.",
	number: "Musí byť číslo.",
	digits: "Môže obsahovať iba číslice.",
	equalTo: "Dva hodnoty sa musia rovnať.",
	range: $.validator.format( "Musí byť medzi {0} a {1}." ),
	max: $.validator.format( "Nemôže byť viac ako{0}." ),
	min: $.validator.format( "Nemôže byť menej ako{0}." ),
	creditcard: "Číslo platobnej karty musí byť platné."
} );
<commit_msg>Localisation: Updated messages_sk.js<commit_after>/*
 * Translated default messages for the jQuery validation plugin.
 * Locale: SK (Slovak; slovenčina, slovenský jazyk)
 */
$.extend( $.validator.messages, {
	required: "Povinné zadať.",
	maxlength: $.validator.format( "Maximálne {0} znakov." ),
	minlength: $.validator.format( "Minimálne {0} znakov." ),
	rangelength: $.validator.format( "Minimálne {0} a maximálne {1} znakov." ),
	email: "E-mailová adresa musí byť platná.",
	url: "URL musí byť platná.",
	date: "Musí byť dátum.",
	number: "Musí byť číslo.",
	digits: "Môže obsahovať iba číslice.",
	equalTo: "Dve hodnoty sa musia rovnať.",
	range: $.validator.format( "Musí byť medzi {0} a {1}." ),
	max: $.validator.format( "Nemôže byť viac ako {0}." ),
	min: $.validator.format( "Nemôže byť menej ako {0}." ),
	creditcard: "Číslo platobnej karty musí byť platné."
} );
<|endoftext|>


<commit_before>var assert = require('assert');

console.log(Date());

it('should fail', function(){
  assert(true);
});

/**
 * Create a function called `plus()` that accepts two `Strings`
 * representing English number words, e.g. "one", "two", "three",
 * and returns a `Number` representing their sum. For example:
 *
 *     assert.equal(plus("one", "one"), 2);
 *
 * @param String A English number word
 * @param String B English number word
 * @return Number sum of A and B
 */
function plus(A, B){
} // END plus<commit_msg>Incremental commit<commit_after>var assert = require('assert');

console.log(Date());

it('should have a `plus` function', function(){
  assert(plus);
  assert.equal(typeof plus, 'function');
});

it('should add "zeros"', function(){
  assert.equal(plus("zero", "zero"), 0);
  assert.equal(plus("zero", "one"), 1);
  assert.equal(plus("zero", "two"), 2);
  assert.equal(plus("zero", "three"), 3);
  assert.equal(plus("zero", "four"), 4);
});

/**
 * Create a function called `plus()` that accepts two `Strings`
 * representing English number words, e.g. "one", "two", "three",
 * and returns a `Number` representing their sum. For example:
 *
 *     assert.equal(plus("one", "one"), 2);
 *
 * @param String A English number word
 * @param String B English number word
 * @return Number sum of A and B
 */
function plus(A, B){
  if ( B == "three" ){
    return 3;
  }

  if ( B == "two" ){
    return 2;
  }

  if ( B == "one" ){
    return 1;
  }

  return 0;
} // END plus<|endoftext|>


<commit_before>var csv2geojson = require('csv2geojson'),
    togeojson = require('togeojson'),
    moment = require('moment'),
    fs = require('fs'),
    jsdom = require('jsdom').jsdom,
    turf = require('turf');

function geojsonToTrace(geojson) {
  var trace = {
        coordinates: []
      },
      feature;

  if (geojson &&
      geojson.features &&
      geojson.features.length &&
      geojson.features[0].geometry) {
    feature = geojson.features[0];

    trace.coordinates = feature.geometry.coordinates.map(function(d) {return [d[1], d[0]];});
    if (feature.properties &&
        feature.properties.coordTimes) {
      trace.timestamps = feature.properties.coordTimes.map(function(t) { return parseInt(t); });
    }
  }

  return trace;
}

function fileToGeoJSON(file, callback) {
  fs.readFile(file, 'utf-8', function(err, content) {
    if (err) {
        callback(err);
        return;
    }

    if (/\.gpx$/g.test(file)) {
      callback(null, togeojson.gpx(jsdom(content)));
    } else if (/\.csv$/g.test(file)) {
      csv2geojson.csv2geojson(content, function(error, geojson) {
        callback(error, geojson && csv2geojson.toLine(geojson));
      });
    } else {
      callback(new Error("Unknown file format: " + file));
    }
  });
}

// reduce sample rate to sane value filter blobs
function filterGeoJSON(geojson) {
  var outputLine = turf.linestring([]),
      outputGeoJSON = turf.featurecollection([]),
      minTimeDiff = 5, // 12 sampels / minute
      minDistance = 10;

  if (geojson &&
      geojson.features &&
      geojson.features.length &&
      geojson.features[0].geometry) {
    var feature = geojson.features[0],
        coords = feature.geometry.coordinates,
        times = feature.properties && feature.properties.coordTimes || null,
        prevCoord,
        prevTime,
        newCoords,
        newTimes = [];

    if (times && !times[0].match(/^\d+$/)) {
        // check if for special fucked up date format.
        if (times[0].match(/^\d\d\d\d-\d-\d\d/)) {
          times = times.map(function (t) {
              return Math.floor(moment(t, "YYYY-M-DDTHH:mm:ss") / 1000);
          });
        } else {
          times = times.map(function(t) {
              // js returns dates in milliseconds since epoch
              return Math.floor(Date.parse(t) / 1000);
          });
        }
    }

    newCoords = coords.filter(function(coord, i) {
      var p = turf.point(coord),
          takePoint = true;

      if (i !== 0) {
        takePoint = (times[i] - prevTime > minTimeDiff) &&
                    (turf.distance(prevCoord, p)*1000 > minDistance);
      }

      if (takePoint)
      {
        prevCoord = p;
        prevTime = times[i];
        newTimes.push(times[i]);
      }

      return takePoint;
    });

    if (newCoords.length > 1) {
      outputLine.geometry.coordinates = newCoords;
      outputLine.properties = { coordTimes: newTimes };
      outputGeoJSON.features.push(outputLine);
    }
  }

  return outputGeoJSON;
}

function matchTrace(osrm, file, callback) {
  fileToGeoJSON(file, function onGeojson(err, geojson) {
    if (err) {
      callback(err);
      return;
    }
    var trace = geojsonToTrace(filterGeoJSON(geojson));

    if (trace.coordinates.length < 2)
    {
        callback(new Error("Trace should at least contain two points!"));
        return;
    }

    trace.classify = true;

    osrm.match(trace, function(err, result) {
      if (err) {
        callback(err, null);
        return;
      }
      // also return original trace
      result.trace = trace;
      callback(null, result);
    });
  });
}

module.exports = matchTrace;
<commit_msg>Set 20m as threashold for blob removal.<commit_after>var csv2geojson = require('csv2geojson'),
    togeojson = require('togeojson'),
    moment = require('moment'),
    fs = require('fs'),
    jsdom = require('jsdom').jsdom,
    turf = require('turf');

function geojsonToTrace(geojson) {
  var trace = {
        coordinates: []
      },
      feature;

  if (geojson &&
      geojson.features &&
      geojson.features.length &&
      geojson.features[0].geometry) {
    feature = geojson.features[0];

    trace.coordinates = feature.geometry.coordinates.map(function(d) {return [d[1], d[0]];});
    if (feature.properties &&
        feature.properties.coordTimes) {
      trace.timestamps = feature.properties.coordTimes.map(function(t) { return parseInt(t); });
    }
  }

  return trace;
}

function fileToGeoJSON(file, callback) {
  fs.readFile(file, 'utf-8', function(err, content) {
    if (err) {
        callback(err);
        return;
    }

    if (/\.gpx$/g.test(file)) {
      callback(null, togeojson.gpx(jsdom(content)));
    } else if (/\.csv$/g.test(file)) {
      csv2geojson.csv2geojson(content, function(error, geojson) {
        callback(error, geojson && csv2geojson.toLine(geojson));
      });
    } else {
      callback(new Error("Unknown file format: " + file));
    }
  });
}

// reduce sample rate to sane value filter blobs
function filterGeoJSON(geojson) {
  var outputLine = turf.linestring([]),
      outputGeoJSON = turf.featurecollection([]),
      minTimeDiff = 5, // 12 sampels / minute
      minDistance = 20;

  if (geojson &&
      geojson.features &&
      geojson.features.length &&
      geojson.features[0].geometry) {
    var feature = geojson.features[0],
        coords = feature.geometry.coordinates,
        times = feature.properties && feature.properties.coordTimes || null,
        prevCoord,
        prevTime,
        newCoords,
        newTimes = [];

    if (times && !times[0].match(/^\d+$/)) {
        // check if for special fucked up date format.
        if (times[0].match(/^\d\d\d\d-\d-\d\d/)) {
          times = times.map(function (t) {
              return Math.floor(moment(t, "YYYY-M-DDTHH:mm:ss") / 1000);
          });
        } else {
          times = times.map(function(t) {
              // js returns dates in milliseconds since epoch
              return Math.floor(Date.parse(t) / 1000);
          });
        }
    }

    newCoords = coords.filter(function(coord, i) {
      var p = turf.point(coord),
          takePoint = true;

      if (i !== 0) {
        takePoint = (times[i] - prevTime > minTimeDiff) &&
                    (turf.distance(prevCoord, p)*1000 > minDistance);
      }

      if (takePoint)
      {
        prevCoord = p;
        prevTime = times[i];
        newTimes.push(times[i]);
      }

      return takePoint;
    });

    if (newCoords.length > 1) {
      outputLine.geometry.coordinates = newCoords;
      outputLine.properties = { coordTimes: newTimes };
      outputGeoJSON.features.push(outputLine);
    }
  }

  return outputGeoJSON;
}

function matchTrace(osrm, file, callback) {
  fileToGeoJSON(file, function onGeojson(err, geojson) {
    if (err) {
      callback(err);
      return;
    }
    var trace = geojsonToTrace(filterGeoJSON(geojson));

    if (trace.coordinates.length < 2)
    {
        callback(new Error("Trace should at least contain two points!"));
        return;
    }

    trace.classify = true;

    osrm.match(trace, function(err, result) {
      if (err) {
        callback(err, null);
        return;
      }
      // also return original trace
      result.trace = trace;
      callback(null, result);
    });
  });
}

module.exports = matchTrace;
<|endoftext|>


<commit_before>import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {interpolate} from 'd3-interpolate';
import {spring, Motion, presets} from 'react-motion';

const ANIMATION_PROPTYPES = PropTypes.oneOfType([
  PropTypes.string,
  PropTypes.shape({
    stiffness: PropTypes.number,
    nonAnimatedProps: PropTypes.arrayOf(PropTypes.string),
    damping: PropTypes.number
  }),
  PropTypes.bool
]);

const propTypes = {
  animatedProps: PropTypes.arrayOf(PropTypes.string).isRequired,
  animation: ANIMATION_PROPTYPES,
  onStart: PropTypes.func,
  onEnd: PropTypes.func
};

/**
 * Format the animation style object
 * @param {Object|String} animationStyle - The animation style property, either the name of a
 * presets are one of noWobble, gentle, wobbly, stiff
 */
function getAnimationStyle(animationStyle = presets.noWobble) {
  if (typeof animationStyle === 'string') {
    return presets[animationStyle] || presets.noWobble;
  }
  const {damping, stiffness} = animationStyle;
  return {
    damping: damping || presets.noWobble.damping,
    stiffness: stiffness || presets.noWobble.stiffness,
    ...animationStyle
  };
}

/**
 * Extract the animated props from the entire props object.
 * @param {Object} props Props.
 * @returns {Object} Object of animated props.
 */
export function extractAnimatedPropValues(props) {
  const {animatedProps, ...otherProps} = props;

  return animatedProps.reduce((result, animatedPropName) => {
    if (Object.prototype.hasOwnProperty.call(otherProps, animatedPropName)) {
      result[animatedPropName] = otherProps[animatedPropName];
    }
    return result;
  }, {});
}

class Animation extends PureComponent {
  constructor(props) {
    super(props);
    this._updateInterpolator(props);
  }

  // eslint-disable-next-line react/no-deprecated
  componentWillUpdate(props) {
    this._updateInterpolator(this.props, props);
    if (props.onStart) {
      props.onStart();
    }
  }

  _motionEndHandler = () => {
    if (this.props.onEnd) {
      this.props.onEnd();
    }
  };

  /**
   * Render the child into the parent.
   * @param {Number} i Number generated by the spring.
   * @returns {React.Component} Rendered react element.
   * @private
   */
  _renderChildren = ({i}) => {
    const {children} = this.props;
    const interpolator = this._interpolator;
    const child = React.Children.only(children);
    const interpolatedProps = interpolator ? interpolator(i) : interpolator;

    // interpolator doesnt play nice with deeply nested objected
    // so we expose an additional prop for situations like these, soit _data,
    // which stores the full tree and can be recombined with the sanitized version
    // after interpolation
    let data = (interpolatedProps && interpolatedProps.data) || null;
    if (data && child.props._data) {
      data = data.map((row, index) => {
        const correspondingCell = child.props._data[index];
        return {
          ...row,
          parent: correspondingCell.parent,
          children: correspondingCell.children
        };
      });
    }

    return React.cloneElement(child, {
      ...child.props,
      ...interpolatedProps,
      data: data || child.props.data || null,
      // enforce re-rendering
      _animation: Math.random()
    });
  };

  /**
   * Update the interpolator function and assign it to this._interpolator.
   * @param {Object} oldProps Old props.
   * @param {Object} newProps New props.
   * @private
   */
  _updateInterpolator(oldProps, newProps) {
    this._interpolator = interpolate(
      extractAnimatedPropValues(oldProps),
      newProps ? extractAnimatedPropValues(newProps) : null
    );
  }

  render() {
    const animationStyle = getAnimationStyle(this.props.animation);
    const defaultStyle = {i: 0};
    const style = {i: spring(1, animationStyle)};
    // In order to make Motion re-run animations each time, the random key is
    // always passed.
    // TODO: find a better solution for the spring.
    const key = Math.random();
    return (
      <Motion {...{defaultStyle, style, key}} onRest={this._motionEndHandler}>
        {this._renderChildren}
      </Motion>
    );
  }
}

Animation.propTypes = propTypes;
Animation.displayName = 'Animation';

export default Animation;

export const AnimationPropType = ANIMATION_PROPTYPES;
<commit_msg>Fix spread (#1344)<commit_after>import React, {PureComponent} from 'react';
import PropTypes from 'prop-types';
import {interpolate} from 'd3-interpolate';
import {spring, Motion, presets} from 'react-motion';

const ANIMATION_PROPTYPES = PropTypes.oneOfType([
  PropTypes.string,
  PropTypes.shape({
    stiffness: PropTypes.number,
    nonAnimatedProps: PropTypes.arrayOf(PropTypes.string),
    damping: PropTypes.number
  }),
  PropTypes.bool
]);

const propTypes = {
  animatedProps: PropTypes.arrayOf(PropTypes.string).isRequired,
  animation: ANIMATION_PROPTYPES,
  onStart: PropTypes.func,
  onEnd: PropTypes.func
};

/**
 * Format the animation style object
 * @param {Object|String} animationStyle - The animation style property, either the name of a
 * presets are one of noWobble, gentle, wobbly, stiff
 */
function getAnimationStyle(animationStyle = presets.noWobble) {
  if (typeof animationStyle === 'string') {
    return presets[animationStyle] || presets.noWobble;
  }
  const {damping, stiffness} = animationStyle;
  return {
    ...animationStyle,
    damping: damping || presets.noWobble.damping,
    stiffness: stiffness || presets.noWobble.stiffness
  };
}

/**
 * Extract the animated props from the entire props object.
 * @param {Object} props Props.
 * @returns {Object} Object of animated props.
 */
export function extractAnimatedPropValues(props) {
  const {animatedProps, ...otherProps} = props;

  return animatedProps.reduce((result, animatedPropName) => {
    if (Object.prototype.hasOwnProperty.call(otherProps, animatedPropName)) {
      result[animatedPropName] = otherProps[animatedPropName];
    }
    return result;
  }, {});
}

class Animation extends PureComponent {
  constructor(props) {
    super(props);
    this._updateInterpolator(props);
  }

  // eslint-disable-next-line react/no-deprecated
  componentWillUpdate(props) {
    this._updateInterpolator(this.props, props);
    if (props.onStart) {
      props.onStart();
    }
  }

  _motionEndHandler = () => {
    if (this.props.onEnd) {
      this.props.onEnd();
    }
  };

  /**
   * Render the child into the parent.
   * @param {Number} i Number generated by the spring.
   * @returns {React.Component} Rendered react element.
   * @private
   */
  _renderChildren = ({i}) => {
    const {children} = this.props;
    const interpolator = this._interpolator;
    const child = React.Children.only(children);
    const interpolatedProps = interpolator ? interpolator(i) : interpolator;

    // interpolator doesnt play nice with deeply nested objected
    // so we expose an additional prop for situations like these, soit _data,
    // which stores the full tree and can be recombined with the sanitized version
    // after interpolation
    let data = (interpolatedProps && interpolatedProps.data) || null;
    if (data && child.props._data) {
      data = data.map((row, index) => {
        const correspondingCell = child.props._data[index];
        return {
          ...row,
          parent: correspondingCell.parent,
          children: correspondingCell.children
        };
      });
    }

    return React.cloneElement(child, {
      ...child.props,
      ...interpolatedProps,
      data: data || child.props.data || null,
      // enforce re-rendering
      _animation: Math.random()
    });
  };

  /**
   * Update the interpolator function and assign it to this._interpolator.
   * @param {Object} oldProps Old props.
   * @param {Object} newProps New props.
   * @private
   */
  _updateInterpolator(oldProps, newProps) {
    this._interpolator = interpolate(
      extractAnimatedPropValues(oldProps),
      newProps ? extractAnimatedPropValues(newProps) : null
    );
  }

  render() {
    const animationStyle = getAnimationStyle(this.props.animation);
    const defaultStyle = {i: 0};
    const style = {i: spring(1, animationStyle)};
    // In order to make Motion re-run animations each time, the random key is
    // always passed.
    // TODO: find a better solution for the spring.
    const key = Math.random();
    return (
      <Motion {...{defaultStyle, style, key}} onRest={this._motionEndHandler}>
        {this._renderChildren}
      </Motion>
    );
  }
}

Animation.propTypes = propTypes;
Animation.displayName = 'Animation';

export default Animation;

export const AnimationPropType = ANIMATION_PROPTYPES;
<|endoftext|>


<commit_before>EditorUI.DragDrop = (function () {
    var Path = null;
    if ( Editor.isNative ) {
        Path = require('fire-path');
    }

    var _allowed = false;

    var DragDrop = {
        start: function ( dataTransfer, effect, type, items ) {
            var ids = items.map( function (item) {
                return item.id;
            } );
            dataTransfer.effectAllowed = effect;
            dataTransfer.dropEffect = 'none';
            dataTransfer.setData('editor/type', type);
            dataTransfer.setData('editor/items', ids.join());
            var img = this.getDragIcon(items);
            dataTransfer.setDragImage(img, -10, 10);
        },

        drop: function ( dataTransfer ) {
            var results = [];
            if ( _allowed ) {
                results = DragDrop.items(dataTransfer);
            }

            _allowed = false;

            return results;
        },

        end: function () {
            _allowed = false;
        },

        updateDropEffect: function ( dataTransfer, dropEffect ) {
            if ( _allowed ) {
                dataTransfer.dropEffect = dropEffect;
            }
            else {
                dataTransfer.dropEffect = 'none';
            }
        },

        allowDrop: function ( dataTransfer, allowed ) {
            _allowed = allowed;
            if ( !_allowed ) {
                dataTransfer.dropEffect = 'none';
            }
        },

        type: function ( dataTransfer ) {
            var type = dataTransfer.getData('editor/type');

            if ( type === '' && dataTransfer.files.length > 0 )
                return 'file';

            return type;
        },

        items: function ( dataTransfer ) {
            var type = DragDrop.type(dataTransfer);
            var items;

            if ( type === 'file' ) {
                var files = dataTransfer.files;
                items = [];

                for ( var i = 0; i < files.length; ++i ) {
                    var exists = false;

                    // filter out sub file paths if we have Path module
                    if ( Path ) {
                        for ( var j = 0; j < items.length; ++j ) {
                            if ( Path.contains( items[j], files[i].path ) ) {
                                exists = true;
                                break;
                            }
                        }
                    }

                    if ( !exists ) {
                        items.push( files[i].path );
                    }
                }
            }
            else {
                items = dataTransfer.getData('editor/items');
                if ( items !== '' ) {
                    items = items.split(',');
                }
                else {
                    items = [];
                }
            }

            return items;
        },

        // NOTE: The image will be blur in retina, still not find a solution.
        getDragIcon: function (items) {
            var icon = new Image();
            var canvas = document.createElement('canvas');
            var imgPanel = canvas.getContext('2d');
            imgPanel.font = 'normal 12px Arial';
            imgPanel.fillStyle = 'white';
            var top = 0;
            for ( var i = 0; i < items.length; ++i ) {
                var item = items[i];
                if ( i <= 4 ) {
                    icon.src = 'uuid://' + item.id + '?thumb';
                    imgPanel.drawImage(icon,0,top,16,16); // icon
                    imgPanel.fillText(item.name,20,top + 15); // text
                    top += 15;
                }
                else {
                    imgPanel.fillStyle = 'gray';
                    imgPanel.fillText('[more.....]',20,top + 15);
                    break;
                }

            }

            icon.src = canvas.toDataURL();
            return icon;
        },
    };

    Object.defineProperty( DragDrop, 'allowed', {
        get: function () { return _allowed; }
    });

    return DragDrop;
})();
<commit_msg>fix drag drop can not draw icon<commit_after>EditorUI.DragDrop = (function () {
    var Path = null;
    if ( Editor.isNative ) {
        Path = require('fire-path');
    }

    var _allowed = false;

    var DragDrop = {
        start: function ( dataTransfer, effect, type, items ) {
            var ids = items.map( function (item) {
                return item.id;
            } );
            dataTransfer.effectAllowed = effect;
            dataTransfer.dropEffect = 'none';
            dataTransfer.setData('editor/type', type);
            dataTransfer.setData('editor/items', ids.join());
            var img = this.getDragIcon(items);
            dataTransfer.setDragImage(img, -10, 10);
        },

        drop: function ( dataTransfer ) {
            var results = [];
            if ( _allowed ) {
                results = DragDrop.items(dataTransfer);
            }

            _allowed = false;

            return results;
        },

        end: function () {
            _allowed = false;
        },

        updateDropEffect: function ( dataTransfer, dropEffect ) {
            if ( _allowed ) {
                dataTransfer.dropEffect = dropEffect;
            }
            else {
                dataTransfer.dropEffect = 'none';
            }
        },

        allowDrop: function ( dataTransfer, allowed ) {
            _allowed = allowed;
            if ( !_allowed ) {
                dataTransfer.dropEffect = 'none';
            }
        },

        type: function ( dataTransfer ) {
            var type = dataTransfer.getData('editor/type');

            if ( type === '' && dataTransfer.files.length > 0 )
                return 'file';

            return type;
        },

        items: function ( dataTransfer ) {
            var type = DragDrop.type(dataTransfer);
            var items;

            if ( type === 'file' ) {
                var files = dataTransfer.files;
                items = [];

                for ( var i = 0; i < files.length; ++i ) {
                    var exists = false;

                    // filter out sub file paths if we have Path module
                    if ( Path ) {
                        for ( var j = 0; j < items.length; ++j ) {
                            if ( Path.contains( items[j], files[i].path ) ) {
                                exists = true;
                                break;
                            }
                        }
                    }

                    if ( !exists ) {
                        items.push( files[i].path );
                    }
                }
            }
            else {
                items = dataTransfer.getData('editor/items');
                if ( items !== '' ) {
                    items = items.split(',');
                }
                else {
                    items = [];
                }
            }

            return items;
        },

        // NOTE: The image will be blur in retina, still not find a solution.
        getDragIcon: function (items) {
            var icon = new Image();
            var canvas = document.createElement('canvas');
            var imgPanel = canvas.getContext('2d');
            imgPanel.font = 'normal 12px Arial';
            imgPanel.fillStyle = 'white';
            var top = 0;
            for ( var i = 0; i < items.length; ++i ) {
                var item = items[i];
                if ( i <= 4 ) {
                    // icon
                    if ( item.icon ) {
                        imgPanel.drawImage(item.icon,0,top,16,16);
                    }
                    // text
                    imgPanel.fillText(item.name,20,top + 15);
                    top += 15;
                }
                else {
                    imgPanel.fillStyle = 'gray';
                    imgPanel.fillText('[more.....]',20,top + 15);
                    break;
                }

            }

            icon.src = canvas.toDataURL();
            return icon;
        },
    };

    Object.defineProperty( DragDrop, 'allowed', {
        get: function () { return _allowed; }
    });

    return DragDrop;
})();
<|endoftext|>


<commit_before>var fetchdb = [
  'MATCH node',
  'OPTIONAL MATCH node-[rel]-x',
  'RETURN node, labels(node) as labels, collect(rel) as rels'
].join(' ');

function dbToJSON(db, cb) {
  db.query(fetchdb, function(err, data) {
    if (err) return cb(err);
    var normalized = {};
    data.forEach(function(row) {
      normalized['node_'+row.node.id] = {
        type: 'node',
        labels: row.labels,
        data: row.node
      };
      row.rels.forEach(function(rel) {
        normalized['rel_'+rel.id] = {
          type: 'rel',
          data: rel
        };
      });
    });
    cb(null, normalized);
  });
}

function JSONtoCypher(data, statementSplitSize) {
  var keys = Object.keys(data);
  var nodes = keys.filter(function(key) {
    return data[key].type == 'node';
  });
  var rels = keys.filter(function(key) {
    return data[key].type == 'rel';
  });
  var keymap = {};
  // can't use query params as we're exporting to a single string
  function createParamString(obj) {
    var kvs = Object.keys(obj).map(function(key) {
      return key + ':' + JSON.stringify(obj[key]);
    }).join(',');
    return '{' + kvs + '}';
  }
  var uniqueNameIndex = 0;
  function createUniqueName(type) {
    return type + (uniqueNameIndex++);
  }
  var creates = [];
  nodes.forEach(function(nodeKey) {
    var node = data[nodeKey];
    delete node.data.id;
    var name = keymap[nodeKey] = createUniqueName('node');
    var params = createParamString(node.data);
    var labels = node.labels.map(function(l) { return ':`' + l + '`' }).join('');
    creates.push('(' + name + labels + ' ' + params + ')');
  });
  rels.forEach(function(relKey) {
    var rel = data[relKey];
    var name = keymap[relKey] = createUniqueName('rel');
    var params = createParamString(rel.data.properties);
    var start = keymap["node_" + rel.data.start];
    var finish = keymap["node_" + rel.data.end];
    var type = '`' + rel.data.type + '`';
    creates.push(start + '-[' + name + ':' + type + ' ' + params + ']->' + finish);
  });
  if (!statementSplitSize) {
    return 'CREATE ' + creates.join(',');
  } else {
    var queries = [];
    for (var start = 0; start < creates.length; start += statementSplitSize) {
      queries.push('CREATE ' + creates.slice(start, start + statementSplitSize).join(','));
    }
    return queries;
  }
};

module.exports = {
  json: dbToJSON,
  jsonToCypher: JSONtoCypher,
  cypher: function(db, cb) {
    dbToJSON(db, function(err, data) {
      if (err) return cb(err);
      else cb(null, JSONtoCypher(data));
    });
  }
}
<commit_msg>serialize as statements<commit_after>var fetchdb = [
  'MATCH node',
  'OPTIONAL MATCH node-[rel]-x',
  'RETURN node, labels(node) as labels, collect(rel) as rels'
].join(' ');

function dbToJSON(db, cb) {
  db.query(fetchdb, function(err, data) {
    if (err) return cb(err);
    var normalized = {};
    data.forEach(function(row) {
      normalized['node_'+row.node.id] = {
        type: 'node',
        labels: row.labels,
        data: row.node
      };
      row.rels.forEach(function(rel) {
        normalized['rel_'+rel.id] = {
          type: 'rel',
          data: rel
        };
      });
    });
    cb(null, normalized);
  });
}

function JSONtoCypher(data) {
  var keys = Object.keys(data);
  var nodes = keys.filter(function(key) {
    return data[key].type == 'node';
  });
  var rels = keys.filter(function(key) {
    return data[key].type == 'rel';
  });
  var keymap = {};
  // can't use query params as we're exporting to a single string
  function createParamString(obj) {
    var kvs = Object.keys(obj).map(function(key) {
      return key + ':' + JSON.stringify(obj[key]);
    }).join(',');
    return '{' + kvs + '}';
  }
  var uniqueNameIndex = 0;
  function createUniqueName(type) {
    return type + (uniqueNameIndex++);
  }
  var creates = [];
  nodes.forEach(function(nodeKey) {
    var node = data[nodeKey];
    delete node.data.id;
    var name = keymap[nodeKey] = createUniqueName('node');
    var params = createParamString(node.data);
    var labels = node.labels.map(function(l) { return ':`' + l + '`' }).join('');
    creates.push({statement: '(' + name + labels + ' ' + params + ')', refs:[]});
  });
  rels.forEach(function(relKey) {
    var rel = data[relKey];
    var name = keymap[relKey] = createUniqueName('rel');
    var params = createParamString(rel.data.properties);
    var start = keymap["node_" + rel.data.start];
    var finish = keymap["node_" + rel.data.end];
    var type = '`' + rel.data.type + '`';
    creates.push({statement: start + '-[' + name + ':' + type + ' ' + params + ']->' + finish,refs:[start,finish]});
  });
  if (!statementSplitSize) {
    return 'CREATE ' + creates.join(',');
  } else {
    var queries = [];
    for (var start = 0; start < creates.length; start += statementSplitSize) {
      queries.push('CREATE ' + creates.slice(start, start + statementSplitSize).join(','));
    }
    return queries;
  }
};

module.exports = {
  json: dbToJSON,
  jsonToCypher: JSONtoCypher,
  cypher: function(db, cb) {
    dbToJSON(db, function(err, data) {
      if (err) return cb(err);
      else cb(null, JSONtoCypher(data));
    });
  }
}
<|endoftext|>