| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146 | var Qs = Npm.require('qs');Router = function () {  this._routes = [];  this._routesMap = {};  this.subscriptions = Function.prototype;  // holds onRoute callbacks  this._onRouteCallbacks = [];};Router.prototype.route = function(pathDef, options) {  if (!/^\/.*/.test(pathDef)) {    var message = "route's path must start with '/'";    throw new Error(message);  }    options = options || {};  var route = new Route(this, pathDef, options);  this._routes.push(route);  if (options.name) {    this._routesMap[options.name] = route;  }  this._triggerRouteRegister(route);  return route;};Router.prototype.group = function(options) {  return new Group(this, options);};Router.prototype.path = function(pathDef, fields, queryParams) {  if (this._routesMap[pathDef]) {    pathDef = this._routesMap[pathDef].path;  }  fields = fields || {};  var regExp = /(:[\w\(\)\\\+\*\.\?]+)+/g;  var path = pathDef.replace(regExp, function(key) {    var firstRegexpChar = key.indexOf("(");    // get the content behind : and (\\d+/)    key = key.substring(1, (firstRegexpChar > 0)? firstRegexpChar: undefined);    // remove +?*    key = key.replace(/[\+\*\?]+/g, "");    return fields[key] || "";  });  path = path.replace(/\/\/+/g, "/"); // Replace multiple slashes with single slash  // remove trailing slash  // but keep the root slash if it's the only one  path = path.match(/^\/{1}$/) ? path: path.replace(/\/$/, "");  var strQueryParams = Qs.stringify(queryParams || {});  if(strQueryParams) {    path += "?" + strQueryParams;  }  return path;};Router.prototype.onRouteRegister = function(cb) {  this._onRouteCallbacks.push(cb);};Router.prototype._triggerRouteRegister = function(currentRoute) {  // We should only need to send a safe set of fields on the route  // object.  // This is not to hide what's inside the route object, but to show   // these are the public APIs  var routePublicApi = _.pick(currentRoute, 'name', 'pathDef', 'path');  var omittingOptionFields = [    'triggersEnter', 'triggersExit', 'action', 'subscriptions', 'name'  ];  routePublicApi.options = _.omit(currentRoute.options, omittingOptionFields);  _.each(this._onRouteCallbacks, function(cb) {    cb(routePublicApi);  });};Router.prototype.go = function() {  // client only};Router.prototype.current = function() {  // client only};Router.prototype.triggers = {  enter: function() {    // client only  },  exit: function() {    // client only  }};Router.prototype.middleware = function() {  // client only};Router.prototype.getState = function() {  // client only};Router.prototype.getAllStates = function() {  // client only};Router.prototype.setState = function() {  // client only};Router.prototype.removeState = function() {  // client only};Router.prototype.clearStates = function() {  // client only};Router.prototype.ready = function() {  // client only};Router.prototype.initialize = function() {  // client only};Router.prototype.wait = function() {  // client only};
 |