From 79a396f3d5ac874de72eeba0f01383d0258c96a9 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Wed, 8 Jul 2015 15:57:51 +1000 Subject: [PATCH 01/86] Adding ?basic dataset support to item/get API --- admin/api/item/get.js | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/admin/api/item/get.js b/admin/api/item/get.js index d4ba350276..e6a5718cab 100644 --- a/admin/api/item/get.js +++ b/admin/api/item/get.js @@ -6,6 +6,11 @@ module.exports = function(req, res) { var query = req.list.model.findById(req.params.id); + var fields = req.query.fields; + if (req.query.basic !== undefined) { + fields = false; + } + if (req.list.tracking && req.list.tracking.createdBy) { query.populate(req.list.tracking.createdBy); } From 5f6c45605b334b67d120ef07259cf8a7bcb605ff Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Wed, 8 Jul 2015 15:58:49 +1000 Subject: [PATCH 02/86] Simplifying data structure returned by item/get API --- admin/api/item/get.js | 6 ++---- admin/src/components/ItemViewHeader.js | 4 ++-- admin/src/views/item.js | 22 ++++++++++++---------- 3 files changed, 16 insertions(+), 16 deletions(-) diff --git a/admin/api/item/get.js b/admin/api/item/get.js index e6a5718cab..f37428de6a 100644 --- a/admin/api/item/get.js +++ b/admin/api/item/get.js @@ -24,7 +24,6 @@ module.exports = function(req, res) { if (err) return res.status(500).json({ err: 'database error', detail: err }); if (!item) return res.status(404).json({ err: 'not found', id: req.params.id }); - var tasks = []; var drilldown; var relationships; @@ -152,11 +151,10 @@ module.exports = function(req, res) { detail: err }); } - res.json({ - data: req.list.getData(item, req.query.fields), + res.json(_.assign(req.list.getData(item, fields), { drilldown: drilldown, relationships: relationships - }); + })); }); }); }; diff --git a/admin/src/components/ItemViewHeader.js b/admin/src/components/ItemViewHeader.js index 5542c47a65..e9ef59e04b 100644 --- a/admin/src/components/ItemViewHeader.js +++ b/admin/src/components/ItemViewHeader.js @@ -62,8 +62,8 @@ var Header = React.createClass({ renderDrilldownItems: function() { - var list = this.props.list, - items = this.props.drilldown.items; + var list = this.props.list; + var items = this.props.data.drilldown ? this.props.data.drilldown.items : []; var els = items.map(function(dd) { diff --git a/admin/src/views/item.js b/admin/src/views/item.js index 96f98dd756..f877c2aa74 100644 --- a/admin/src/views/item.js +++ b/admin/src/views/item.js @@ -13,26 +13,28 @@ var View = React.createClass({ return { createIsVisible: false, list: Keystone.list, - itemData: null, - itemDrilldown: null + itemData: null }; }, componentDidMount: function() { + this.loadItemData(); + }, + + loadItemData: function() { request.get('/keystone/api/' + Keystone.list.path + '/' + this.props.itemId + '?drilldown=true') .set('Accept', 'application/json') - .end(function(err, res) {//eslint-disable-line no-unused-vars, handle-callback-err - if (!res.ok) { + .end((err, res) => { + if (err || !res.ok) { // TODO: nicer error handling - console.log('Error loading item data:', res.text); + console.log('Error loading item data:', res ? res.text : err); alert('Error loading data (details logged to console)'); return; } - this.setState({//eslint-disable-line react/no-did-mount-set-state - itemData: res.body.data, - itemDrilldown: res.body.drilldown + this.setState({ + itemData: res.body }); - }.bind(this)); + }); }, toggleCreate: function(visible) { @@ -51,7 +53,7 @@ var View = React.createClass({ return (
{this.renderCreateForm()} -
+
); From c378f109a96d2a3a41bcee7617ff9e83cd811715 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Wed, 8 Jul 2015 16:00:38 +1000 Subject: [PATCH 03/86] Using new item/get API in Select2 Relationship fields --- admin/public/js/common/ui.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/admin/public/js/common/ui.js b/admin/public/js/common/ui.js index 43f253a4ba..8185b13158 100644 --- a/admin/public/js/common/ui.js +++ b/admin/public/js/common/ui.js @@ -161,11 +161,7 @@ jQuery(function($) { }; $.each(ids, function() { - $.ajax('/keystone/api/' + refPath + '/get', { - data: { - id: this, - dataset: 'simple' - }, + $.ajax('/keystone/api/' + refPath + '/' + this + '?simple', { dataType: 'json' }).done(loaded); }); From dd027fef67b1fa81df5808589411c731b8aba8b2 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Wed, 8 Jul 2015 16:02:25 +1000 Subject: [PATCH 04/86] Using new item/get API in Relationship Field Class --- fields/types/relationship/RelationshipField.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fields/types/relationship/RelationshipField.js b/fields/types/relationship/RelationshipField.js index 4516a58e6d..84f297a2c2 100644 --- a/fields/types/relationship/RelationshipField.js +++ b/fields/types/relationship/RelationshipField.js @@ -61,7 +61,7 @@ module.exports = Field.create({ value: input }); superagent - .get('/keystone/api/' + self.props.refList.path + '/get?dataset=simple&id=' + input) + .get('/keystone/api/' + self.props.refList.path + '/' + input + '?simple') .set('Accept', 'application/json') .end(function (err, res) { if (err) throw err; From 119dc116cf4d2c7333bdc7a80790c8838a07336c Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Wed, 8 Jul 2015 16:02:38 +1000 Subject: [PATCH 05/86] Removing old list/get API endpoint --- admin/api/list.js | 20 -------------------- lib/core/routes.js | 2 +- 2 files changed, 1 insertion(+), 21 deletions(-) diff --git a/admin/api/list.js b/admin/api/list.js index c5e956f898..697b0af3a3 100644 --- a/admin/api/list.js +++ b/admin/api/list.js @@ -74,26 +74,6 @@ exports = module.exports = function(req, res) { break; - case 'get': - - req.list.model.findById(req.query.id).exec(function(err, item) { - - if (err) return sendError('database error', err); - if (!item) return sendResponse({ name: req.query.id, id: req.query.id }); - - switch (req.query.dataset) { - case 'simple': - return sendResponse({ - name: req.list.getDocumentName(item, false), - id: item.id - }); - default: - return sendResponse(item); - } - }); - - break; - case 'order': if (!keystone.security.csrf.validate(req)) { diff --git a/lib/core/routes.js b/lib/core/routes.js index 2e5d2033b5..515f51323a 100644 --- a/lib/core/routes.js +++ b/lib/core/routes.js @@ -109,7 +109,7 @@ function routes(app) { // Generic Lists API debug('setting generic list api'); - app.all('/keystone/api/:list/:action(autocomplete|get|order|create|fetch)', initList(), require('../../admin/api/list')); + app.all('/keystone/api/:list/:action(autocomplete|order|create|fetch)', initList(), require('../../admin/api/list')); app.post('/keystone/api/:list/delete', initList(), require('../../admin/api/list/delete')); app.get('/keystone/api/:list/:id', initList(), require('../../admin/api/item/get')); app.post('/keystone/api/:list/:id/delete', initList(), require('../../admin/api/item/delete')); From 2a6f18f9404b19d5a7091566d7a4e6b12d5d0e09 Mon Sep 17 00:00:00 2001 From: Matthias Tylkowski Date: Wed, 8 Jul 2015 12:10:06 +0200 Subject: [PATCH 06/86] Fix for #1280, href was not added to the paths #700 --- fields/types/localfiles/LocalFilesType.js | 1 + 1 file changed, 1 insertion(+) diff --git a/fields/types/localfiles/LocalFilesType.js b/fields/types/localfiles/LocalFilesType.js index b035d28feb..56eb7896e9 100644 --- a/fields/types/localfiles/LocalFilesType.js +++ b/fields/types/localfiles/LocalFilesType.js @@ -85,6 +85,7 @@ localfiles.prototype.addToSchema = function() { filetype: this._path.append('.filetype'), // virtuals exists: this._path.append('.exists'), + href: this._path.append('.href'), upload: this._path.append('_upload'), action: this._path.append('_action'), order: this._path.append('_order') From d47fe97a1942f9a9a93483cf0a045c07a4d3e17f Mon Sep 17 00:00:00 2001 From: Matthias Tylkowski Date: Wed, 8 Jul 2015 15:53:24 +0200 Subject: [PATCH 07/86] Now really fix for #1280 - removed href from path again - added virtual function href to nested schema --- fields/types/localfiles/LocalFilesType.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fields/types/localfiles/LocalFilesType.js b/fields/types/localfiles/LocalFilesType.js index 56eb7896e9..fdb15fd932 100644 --- a/fields/types/localfiles/LocalFilesType.js +++ b/fields/types/localfiles/LocalFilesType.js @@ -85,7 +85,6 @@ localfiles.prototype.addToSchema = function() { filetype: this._path.append('.filetype'), // virtuals exists: this._path.append('.exists'), - href: this._path.append('.href'), upload: this._path.append('_upload'), action: this._path.append('_action'), order: this._path.append('_order') @@ -99,6 +98,11 @@ localfiles.prototype.addToSchema = function() { filetype: String }); + // The .href virtual returns the public path of the file + schemaPaths.virtual('href').get(function() { + return field.href.call(field, this); + }); + schema.add(this._path.addTo({}, [schemaPaths])); var exists = function(item, element_id) { From f39d5b8917f487003fbae3c587189ec76f860b27 Mon Sep 17 00:00:00 2001 From: Matthias Tylkowski Date: Wed, 8 Jul 2015 15:56:02 +0200 Subject: [PATCH 08/86] aligned formatting - removed mixed tabs spaces - removed tabs on empty lines --- fields/types/localfiles/LocalFilesType.js | 48 +++++++++++------------ 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/fields/types/localfiles/LocalFilesType.js b/fields/types/localfiles/LocalFilesType.js index fdb15fd932..002de78082 100644 --- a/fields/types/localfiles/LocalFilesType.js +++ b/fields/types/localfiles/LocalFilesType.js @@ -33,7 +33,7 @@ function localfiles(list, path, options) { throw new Error('Invalid Configuration\n\n' + 'localfiles fields (' + list.key + '.' + path + ') do not currently support being used as initial fields.\n'); } - + if (options.overwrite !== false) { options.overwrite = true; } @@ -54,7 +54,7 @@ function localfiles(list, path, options) { if (options.post && options.post.move) { this.post('move', options.post.move); } - + } /*! @@ -79,9 +79,9 @@ localfiles.prototype.addToSchema = function() { var paths = this.paths = { // fields filename: this._path.append('.filename'), - path: this._path.append('.path'), - originalname: this._path.append('.originalname'), - size: this._path.append('.size'), + path: this._path.append('.path'), + originalname: this._path.append('.originalname'), + size: this._path.append('.size'), filetype: this._path.append('.filetype'), // virtuals exists: this._path.append('.exists'), @@ -92,7 +92,7 @@ localfiles.prototype.addToSchema = function() { var schemaPaths = new mongoose.Schema({ filename: String, - originalname: String, + originalname: String, path: String, size: Number, filetype: String @@ -279,33 +279,33 @@ localfiles.prototype.updateItem = function(item, data) {//eslint-disable-line no */ localfiles.prototype.uploadFiles = function(item, files, update, callback) { - + var field = this; - + if ('function' === typeof update) { callback = update; update = false; } - + async.map(files, function(file, processedFile) { - + var prefix = field.options.datePrefix ? moment().format(field.options.datePrefix) + '-' : '', filename = prefix + file.name, filetype = file.mimetype || file.type; - + if (field.options.allowedTypes && !_.contains(field.options.allowedTypes, filetype)) { return processedFile(new Error('Unsupported File Type: ' + filetype)); } - + var doMove = function(doneMove) { - + if ('function' === typeof field.options.filename) { filename = field.options.filename(item, file); } - + fs.move(file.path, path.join(field.options.dest, filename), { clobber: field.options.overwrite }, function(err) { if (err) return doneMove(err); - + var fileData = { filename: filename, originalname: file.originalname, @@ -313,19 +313,19 @@ localfiles.prototype.uploadFiles = function(item, files, update, callback) { size: file.size, filetype: filetype }; - + if (update) { item.get(field.path).push(fileData); } - + doneMove(null, fileData); }); - + }; - + field.callHook('pre:move', [item, file], function(err) { if (err) return processedFile(err); - + doMove(function(err, fileData) { if (err) return processedFile(err); field.callHook('post:move', [item, file, fileData], function(err) { @@ -333,9 +333,9 @@ localfiles.prototype.uploadFiles = function(item, files, update, callback) { }); }); }); - + }, callback); - + }; @@ -396,7 +396,7 @@ localfiles.prototype.getRequestHandler = function(item, req, paths, callback) { // Upload new files if (req.files) { - + var upFiles = req.files[paths.upload]; if (upFiles) { if (!Array.isArray(upFiles)) { @@ -405,7 +405,7 @@ localfiles.prototype.getRequestHandler = function(item, req, paths, callback) { if (upFiles.length > 0) { upFiles = _.filter(upFiles, function(f) { return typeof f.name !== 'undefined' && f.name.length > 0; }); - + if (upFiles.length > 0) { console.log('uploading files:'); console.log(upFiles); From 39c3432f41cf2bcb6bd22268aac5ffbda8cfa3ad Mon Sep 17 00:00:00 2001 From: jeffreypriebe Date: Wed, 8 Jul 2015 20:27:29 -0700 Subject: [PATCH 09/86] Updated TinyMCE Icons (& .ie7) to correct value for BlockQuote button icon. --- .../js/lib/tinymce/skins/keystone/less/Icons.Ie7.less | 2 +- admin/public/js/lib/tinymce/skins/keystone/less/Icons.less | 6 ++++-- admin/public/js/lib/tinymce/skins/keystone/skin.min.css | 2 +- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/admin/public/js/lib/tinymce/skins/keystone/less/Icons.Ie7.less b/admin/public/js/lib/tinymce/skins/keystone/less/Icons.Ie7.less index 433b54d008..ef6a6d3f89 100755 --- a/admin/public/js/lib/tinymce/skins/keystone/less/Icons.Ie7.less +++ b/admin/public/js/lib/tinymce/skins/keystone/less/Icons.Ie7.less @@ -64,7 +64,7 @@ .mce-i-numlist { -ie7-icon: "\e00b"; } .mce-i-indent { -ie7-icon: "\e00c"; } .mce-i-outdent { -ie7-icon: "\e00d"; } -.mce-i-blockquote { -ie7-icon: "\e00e"; } +.mce-i-blockquote { -ie7-icon: "\e801"; } .mce-i-undo { -ie7-icon: "\e00f"; } .mce-i-redo { -ie7-icon: "\e010"; } .mce-i-link { -ie7-icon: "\e011"; } diff --git a/admin/public/js/lib/tinymce/skins/keystone/less/Icons.less b/admin/public/js/lib/tinymce/skins/keystone/less/Icons.less index eb551b01bf..39b12f5eef 100755 --- a/admin/public/js/lib/tinymce/skins/keystone/less/Icons.less +++ b/admin/public/js/lib/tinymce/skins/keystone/less/Icons.less @@ -45,6 +45,8 @@ .mce-i-indent { &:before { content: '\e83f'; } } .mce-i-outdent { &:before { content: '\e840'; } } +.mce-i-blockquote { &:before { content: '\e801'; } } + .mce-i-bullist { &:before { content: '\e83e'; } } .mce-i-numlist { &:before { content: '\e83d'; } } @@ -74,7 +76,7 @@ .mce-i-numlist:before { content: "\e00b"; } .mce-i-indent:before { content: "\e00c"; } .mce-i-outdent:before { content: "\e00d"; } -.mce-i-blockquote:before { content: "\e00e"; } +.mce-i-blockquote:before { content: "\e801"; } .mce-i-undo:before { content: "\e00f"; } .mce-i-redo:before { content: "\e010"; } .mce-i-link:before { content: "\e011"; } @@ -188,7 +190,7 @@ i.mce-i-backcolor { text-shadow: none; background: @colorbtn-backcolo .mce-i-numlist:before { content: "\e00b"; } .mce-i-indent:before { content: "\e00c"; } .mce-i-outdent:before { content: "\e00d"; } -.mce-i-blockquote:before { content: "\e00e"; } +.mce-i-blockquote:before { content: "\e801"; } .mce-i-undo:before { content: "\e00f"; } .mce-i-redo:before { content: "\e010"; } .mce-i-link:before { content: "\e011"; } diff --git a/admin/public/js/lib/tinymce/skins/keystone/skin.min.css b/admin/public/js/lib/tinymce/skins/keystone/skin.min.css index 266342e258..b917fcfd2c 100644 --- a/admin/public/js/lib/tinymce/skins/keystone/skin.min.css +++ b/admin/public/js/lib/tinymce/skins/keystone/skin.min.css @@ -1 +1 @@ -.mce-container,.mce-container *,.mce-widget,.mce-widget *{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:transparent;text-decoration:none;color:#333;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;-webkit-tap-highlight-color:transparent;line-height:normal;font-weight:normal;text-align:left;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr}.mce-widget button{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.mce-container *[unselectable]{-moz-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none}.mce-container ::-webkit-scrollbar{width:8px;height:8px;-webkit-border-radius:4px}.mce-container ::-webkit-scrollbar-track,.mce-container ::-webkit-scrollbar-track-piece{background-color:transparent}.mce-container ::-webkit-scrollbar-thumb{background-color:rgba(53,57,71,0.3);width:6px;height:6px;-webkit-border-radius:4px}.mce-fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.mce-fade.mce-in{opacity:1}.mce-tinymce{visibility:visible !important;position:relative}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;height:100%;z-index:100}div.mce-fullscreen{position:fixed;top:0;left:0;width:100%;height:auto}.mce-tinymce{display:block;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.mce-wordcount{position:absolute;top:0;right:0;padding:8px}div.mce-edit-area{background:#fff;filter:none}.mce-statusbar{position:relative}.mce-statusbar .mce-container-body{position:relative}.mce-fullscreen .mce-resizehandle{display:none}.mce-charmap{border-collapse:collapse}.mce-charmap td{cursor:default;border:1px solid #ddd;width:20px;height:20px;line-height:20px;text-align:center;vertical-align:middle;padding:2px}.mce-charmap td div{text-align:center}.mce-charmap td:hover{background:#ddd}.mce-grid td div{border:1px solid #d6d6d6;width:12px;height:12px;margin:2px;cursor:pointer}.mce-grid{border-spacing:2px;border-collapse:separate}.mce-grid a{display:block;border:1px solid transparent}.mce-grid a:hover{border-color:#a1a1a1}.mce-grid-border{margin:0 4px 0 4px}.mce-grid-border a{border-color:#d6d6d6;width:13px;height:13px}.mce-grid-border a:hover,.mce-grid-border a.mce-active{border-color:#a1a1a1;background:#c8def4}.mce-text-center{text-align:center}div.mce-tinymce-inline{width:100%;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-container,.mce-container-body{display:block}.mce-autoscroll{overflow:hidden}.mce-scrollbar{position:absolute;width:7px;height:100%;top:2px;right:2px;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-scrollbar-h{top:auto;right:auto;left:2px;bottom:2px;width:100%;height:7px}.mce-scrollbar-thumb{position:absolute;background-color:#000;border:1px solid #888;border-color:rgba(85,85,85,0.6);width:5px;height:100%;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scrollbar-h .mce-scrollbar-thumb{width:100%;height:5px}.mce-scrollbar:hover,.mce-scrollbar.mce-active{background-color:#aaa;opacity:.6;filter:alpha(opacity=60);zoom:1;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scroll{position:relative}.mce-floatpanel{position:absolute;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2)}.mce-floatpanel.mce-fixed{position:fixed}.mce-floatpanel .mce-arrow,.mce-floatpanel .mce-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.mce-floatpanel .mce-arrow{border-width:11px}.mce-floatpanel .mce-arrow:after{border-width:10px;content:""}.mce-floatpanel.mce-popover{top:0;left:0;background:#fff;border:1px solid #000;border:1px solid rgba(0,0,0,0.25);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2)}.mce-floatpanel.mce-popover.mce-bottom{margin-top:10px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#000;border-bottom-color:rgba(0,0,0,0.25);top:-11px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.mce-floatpanel.mce-popover.mce-bottom.mce-start{margin-left:-22px}.mce-floatpanel.mce-popover.mce-bottom.mce-start>.mce-arrow{left:20px}.mce-floatpanel.mce-popover.mce-bottom.mce-end{margin-left:22px}.mce-floatpanel.mce-popover.mce-bottom.mce-end>.mce-arrow{right:10px;left:auto}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#fff;height:100%}div.mce-fullscreen{position:fixed;top:0;left:0}#mce-modal-block{opacity:0;filter:alpha(opacity=0);zoom:1;position:fixed;left:0;top:0;width:100%;height:100%;background:#000}#mce-modal-block.mce-in{opacity:.3;filter:alpha(opacity=30);zoom:1}.mce-window-move{cursor:move}.mce-window{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;background:#fff;position:fixed;top:0;left:0;opacity:0;-webkit-transition:opacity 150ms ease-in;transition:opacity 150ms ease-in;border:1px solid #999}.mce-window.mce-in{opacity:1}.mce-window-head{padding:9px 15px;border-bottom:1px solid #f9f9f9;position:relative}.mce-window-head .mce-close{position:absolute;right:15px;top:9px;font-size:20px;font-weight:bold;line-height:20px;color:#da8888;cursor:pointer;height:20px;overflow:hidden}.mce-close:hover{color:#c64545}.mce-window-head .mce-title{display:inline-block;*display:inline;*zoom:1;line-height:27px;font-size:20px;padding-right:10px}.mce-window .mce-container-body{display:block}.mce-foot{display:block;background-color:#fff;border-top:1px solid #f9f9f9;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.mce-window-head .mce-dragh{position:absolute;top:0;left:0;cursor:move;width:90%;height:100%}.mce-window iframe{width:100%;height:100%}.mce-window.mce-fullscreen,.mce-window.mce-fullscreen .mce-foot{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-abs-layout{position:relative}body .mce-abs-layout-item,.mce-abs-end{position:absolute}.mce-abs-end{width:1px;height:1px}.mce-container-body.mce-abs-layout{overflow:hidden}.mce-tooltip{position:absolute;padding:5px;opacity:.8;filter:alpha(opacity=80);zoom:1}.mce-tooltip-inner{font-size:11px;background-color:#000;color:white;max-width:200px;padding:5px 8px 4px 8px;text-align:center;white-space:normal}.mce-tooltip-inner{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-tooltip-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.mce-tooltip-arrow-n{border-bottom-color:#000}.mce-tooltip-arrow-s{border-top-color:#000}.mce-tooltip-arrow-e{border-left-color:#000}.mce-tooltip-arrow-w{border-right-color:#000}.mce-tooltip-nw,.mce-tooltip-sw{margin-left:-14px}.mce-tooltip-n .mce-tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-nw .mce-tooltip-arrow{top:0;left:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-ne .mce-tooltip-arrow{top:0;right:10px;border-bottom-style:solid;border-top:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-s .mce-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-sw .mce-tooltip-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-se .mce-tooltip-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:none;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-e .mce-tooltip-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:none;border-top-color:transparent;border-bottom-color:transparent}.mce-tooltip-w .mce-tooltip-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:none;border-top-color:transparent;border-bottom-color:transparent}.mce-btn{border:1px solid #ddd;border-color:#ddd #ddd #ddd #ddd;position:relative;text-shadow:0 1px 1px rgba(255,255,255,0.75);display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-btn:hover,.mce-btn:focus{color:#333;background:#f9f9f9}.mce-btn.mce-disabled button,.mce-btn.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-btn.mce-active,.mce-btn.mce-active:hover,.mce-btn:not(.mce-disabled):active{background:#f9f9f9;border-color:#c4c4c4 #c4c4c4 #c4c4c4 #c4c4c4;-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15)}.mce-btn button{padding:4px 10px;font-size:14px;line-height:20px;*line-height:16px;cursor:pointer;color:#333;text-align:center;overflow:visible;-webkit-appearance:none}.mce-btn button::-moz-focus-inner{border:0;padding:0}.mce-btn i{text-shadow:1px 1px white}.mce-primary{min-width:50px;color:#07628f;border:1px solid #f5f5f5;border-color:#86ccef #86ccef #86ccef #86ccef;background:white;background-color:#f9fcfd;background-image:-moz-linear-gradient(top, #fff, #f1f8fb);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#f1f8fb));background-image:-webkit-linear-gradient(top, #fff, #f1f8fb);background-image:-o-linear-gradient(top, #fff, #f1f8fb);background-image:linear-gradient(to bottom, #fff, #f1f8fb);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff1f8fb', GradientType=0);zoom:1}.mce-primary:hover,.mce-primary:focus{background-color:#f0f7fc;background-image:-moz-linear-gradient(top, #fff, #d9eaf8);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fff), to(#d9eaf8));background-image:-webkit-linear-gradient(top, #fff, #d9eaf8);background-image:-o-linear-gradient(top, #fff, #d9eaf8);background-image:linear-gradient(to bottom, #fff, #d9eaf8);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffd9eaf8', GradientType=0);zoom:1}.mce-primary.mce-disabled button,.mce-primary.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-primary.mce-active,.mce-primary.mce-active:hover,.mce-primary:not(.mce-disabled):active{border-color:#2ca6e3 #2ca6e3 #2ca6e3 #2ca6e3;background:#d7e9f7;-webkit-box-shadow:inset 0 2px 4px #93b3cc;-moz-box-shadow:inset 0 2px 4px #93b3cc;box-shadow:inset 0 2px 4px #93b3cc}.mce-primary button,.mce-primary button i{color:#07628f;text-shadow:1px 1px #fff}.mce-btn-large button{padding:9px 14px;font-size:16px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.mce-btn-large i{margin-top:2px}.mce-btn-small button{padding:3px 5px;font-size:12px;line-height:15px}.mce-btn-small i{margin-top:0}.mce-btn .mce-caret{margin-top:8px;*margin-top:6px;margin-left:0}.mce-btn-small .mce-caret{margin-top:6px;*margin-top:4px;margin-left:0}.mce-caret{display:inline-block;*display:inline;*zoom:1;width:0;height:0;vertical-align:top;border-top:4px solid #333;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.mce-disabled .mce-caret{border-top-color:#aaa}.mce-caret.mce-up{border-bottom:4px solid #333;border-top:0}.mce-btn-group .mce-btn{border-width:1px 0 1px 1px;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-btn-group .mce-first{border-left:1px solid #ddd;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.mce-btn-group .mce-last{border-right:1px solid #ddd;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.mce-btn-group .mce-first.mce-last{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-btn-group .mce-btn.mce-flow-layout-item{margin:0}.mce-checkbox{cursor:pointer}i.mce-i-checkbox{margin:0 3px 0 0;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 0 rgba(255, 255, 255, 0.2), 0 1px 2px rgba(0, 0, 0, 0.05);background-color:#f1f1f1;background-image:-moz-linear-gradient(top, white, #ddd);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(white), to(#ddd));background-image:-webkit-linear-gradient(top, white, #ddd);background-image:-o-linear-gradient(top, white, #ddd);background-image:linear-gradient(to bottom, white, #ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffdddddd', GradientType=0);zoom:1;text-indent:-10em;*font-size:0;*line-height:0;*text-indent:0;overflow:hidden}.mce-checked i.mce-i-checkbox{color:#333;font-size:16px;line-height:16px;text-indent:0}.mce-checkbox:focus i.mce-i-checkbox,.mce-checkbox.mce-focus i.mce-i-checkbox{border:1px solid rgba(82,168,236,0.8);-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px rgba(82, 168, 236, 0.65)}.mce-checkbox.mce-disabled .mce-label,.mce-checkbox.mce-disabled i.mce-i-checkbox{color:#adadad}.mce-colorbutton .mce-ico{position:relative}.mce-colorbutton-grid{margin:4px}.mce-colorbutton button{padding-right:4px}.mce-colorbutton .mce-preview{padding-right:3px;display:block;position:absolute;left:50%;top:50%;margin-left:-14px;margin-top:7px;background:gray;width:13px;height:2px;overflow:hidden}.mce-colorbutton.mce-btn-small .mce-preview{margin-left:-17px;padding-right:0;width:16px}.mce-colorbutton .mce-open{padding-left:4px;border-left:1px solid transparent;border-right:1px solid transparent}.mce-colorbutton:hover .mce-open{border-left-color:#bdbdbd;border-right-color:#bdbdbd}.mce-combobox{display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075)}.mce-combobox input{border:1px solid #c5c5c5;border-right-color:#c5c5c5;height:28px}.mce-combobox.mce-disabled input{color:#adadad}.mce-combobox.mce-has-open input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.mce-combobox .mce-btn{border-left:0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.mce-combobox button{padding-right:8px;padding-left:8px}.mce-combobox.mce-disabled .mce-btn button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-path{display:inline-block;*display:inline;*zoom:1;padding-top:5px;white-space:normal}.mce-path .mce-txt{display:inline-block;color:#666;font-size:12px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;padding:2px 6px 3px}.mce-path .mce-path-body{display:inline-block}.mce-path-item{display:inline-block;*display:inline;*zoom:1;cursor:pointer;color:#666;font-size:12px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;padding:2px 6px 3px;border:1px solid #eee;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-path-item:hover{color:#666;background-color:#f9f9f9;border-color:#ddd}.mce-path-item:focus{color:#666;background-color:#eee;border-color:#ccc}.mce-path .mce-divider{display:inline-block;font-size:12px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;padding:2px 4px 3px;color:#666}.mce-fieldset{border:0 solid #9e9e9e;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-fieldset>.mce-container-body{margin-top:-15px}.mce-fieldset-title{margin-left:5px;padding:0 5px 0 5px}.mce-fit-layout{display:inline-block;*display:inline;*zoom:1}.mce-fit-layout-item{position:absolute}.mce-flow-layout-item{display:inline-block;*display:inline;*zoom:1}.mce-flow-layout-item{margin-bottom:4px;margin-right:4px}.mce-flow-layout{white-space:normal}.mce-tinymce-inline .mce-flow-layout{white-space:nowrap}.mce-iframe{border:0 solid #ddd;width:100%;height:100%}.mce-label{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,0.75);border:0;overflow:hidden}.mce-label.mce-autoscroll{overflow:auto}.mce-label-disabled .mce-text{color:#aaa}.mce-label.mce-multiline{white-space:pre-wrap}.mce-menubar .mce-menubtn{border-color:transparent;background:transparent;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:none}.mce-menubar{border:1px solid #ebebeb}.mce-menubar .mce-menubtn button span{color:#333}.mce-menubar .mce-caret{border-top-color:#333}.mce-menubar .mce-menubtn:hover,.mce-menubar .mce-menubtn.mce-active,.mce-menubar .mce-menubtn:focus{border-color:transparent;background:#e6e6e6;filter:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-menubtn.mce-disabled span{color:#aaa}.mce-menubtn span{color:#333;margin-right:2px;line-height:20px;*line-height:16px}.mce-menubtn.mce-btn-small span{font-size:12px;line-height:15px;*line-height:16px}.mce-menubtn.mce-fixed-width span{display:inline-block;overflow-x:hidden;text-overflow:ellipsis;width:90px}.mce-menubtn.mce-fixed-width.mce-btn-small span{width:70px}.mce-listbox button{text-align:left;padding-right:20px;position:relative}.mce-listbox .mce-caret{position:absolute;margin-top:-2px;right:8px;top:50%}.mce-menu-item{display:block;padding:6px 15px 6px 12px;clear:both;font-weight:normal;line-height:20px;color:#333;white-space:nowrap;cursor:pointer;line-height:normal;border-left:4px solid transparent;margin-bottom:1px}.mce-menu-item .mce-ico,.mce-menu-item .mce-text{color:#333}.mce-menu-item.mce-disabled .mce-text,.mce-menu-item.mce-disabled .mce-ico{color:#adadad}.mce-menu-item:hover .mce-text,.mce-menu-item.mce-selected .mce-text{color:white}.mce-menu-item:hover .mce-ico,.mce-menu-item.mce-selected .mce-ico,.mce-menu-item:focus .mce-ico{color:white}.mce-menu-item.mce-disabled:hover{background:#ccc}.mce-menu-shortcut{display:inline-block;color:#adadad}.mce-menu-shortcut{display:inline-block;*display:inline;*zoom:1;padding:0 15px 0 20px}.mce-menu-item:hover .mce-menu-shortcut,.mce-menu-item.mce-selected .mce-menu-shortcut,.mce-menu-item:focus .mce-menu-shortcut{color:white}.mce-menu-item .mce-caret{margin-top:4px;*margin-top:3px;margin-right:6px;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid #333}.mce-menu-item.mce-selected .mce-caret,.mce-menu-item:focus .mce-caret,.mce-menu-item:hover .mce-caret{border-left-color:white}.mce-menu-align .mce-menu-shortcut{*margin-top:-2px}.mce-menu-align .mce-menu-shortcut,.mce-menu-align .mce-caret{position:absolute;right:0}.mce-menu-item.mce-active i{visibility:visible}.mce-menu-item-normal.mce-active{background-color:#c8def4}.mce-menu-item-preview.mce-active{border-left:5px solid #aaa}.mce-menu-item-normal.mce-active .mce-text{color:#333}.mce-menu-item-normal.mce-active:hover .mce-text,.mce-menu-item-normal.mce-active:hover .mce-ico{color:white}.mce-menu-item:hover,.mce-menu-item.mce-selected,.mce-menu-item:focus{text-decoration:none;color:white;background-color:#0081c2;background-image:-moz-linear-gradient(top, #08c, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#08c), to(#0077b3));background-image:-webkit-linear-gradient(top, #08c, #0077b3);background-image:-o-linear-gradient(top, #08c, #0077b3);background-image:linear-gradient(to bottom, #08c, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);zoom:1}.mce-menu-item-sep,.mce-menu-item-sep:hover{border:0;padding:0;height:1px;margin:9px 1px;overflow:hidden;background:#cbcbcb;border-bottom:1px solid #fff;cursor:default;filter:none}.mce-menu{filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);background:transparent;z-index:1000;padding:5px 0 5px 0;margin:2px 0 0;min-width:160px;background:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,0.2);z-index:1002;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);max-height:400px;overflow:auto;overflow-x:hidden}.mce-menu i{display:none}.mce-menu-has-icons i{display:inline-block;*display:inline;*zoom:1}.mce-menu-sub-tr-tl{margin:-6px 0 0 -1px}.mce-menu-sub-br-bl{margin:6px 0 0 -1px}.mce-menu-sub-tl-tr{margin:-6px 0 0 1px}.mce-menu-sub-bl-br{margin:6px 0 0 1px}.mce-container-body .mce-resizehandle{position:absolute;right:0;bottom:0;width:16px;height:16px;visibility:visible;cursor:s-resize;margin:0}.mce-container-body .mce-resizehandle-both{cursor:se-resize}i.mce-i-resize{color:#333}.mce-spacer{visibility:hidden}.mce-splitbtn .mce-open{border-left:1px solid transparent;border-right:1px solid transparent}.mce-splitbtn:hover .mce-open{border-left-color:#bdbdbd;border-right-color:#bdbdbd}.mce-splitbtn button{padding-right:4px}.mce-splitbtn .mce-open{padding-left:4px}.mce-splitbtn .mce-open.mce-active{-webkit-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:inset 0 2px 4px rgba(0, 0, 0, 0.15), 0 1px 2px rgba(0, 0, 0, 0.05)}.mce-stack-layout-item{display:block}.mce-tabs{display:block;border-bottom:1px solid #c5c5c5}.mce-tab{display:inline-block;*display:inline;*zoom:1;border:1px solid #c5c5c5;border-width:0 1px 0 0;background:#e3e3e3;padding:8px;text-shadow:0 1px 1px rgba(255,255,255,0.75);height:13px;cursor:pointer}.mce-tab:hover{background:#fdfdfd}.mce-tab.mce-active{background:#fdfdfd;border-bottom-color:transparent;margin-bottom:-1px;height:14px}.mce-textbox{background:#fff;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);display:inline-block;-webkit-transition:border linear .2s;transition:border linear .2s;height:28px;resize:none;padding:0 4px 0 4px;white-space:pre-wrap;*white-space:pre;color:#333}.mce-textbox:focus,.mce-textbox.mce-focus{border-color:rgba(82,168,236,0.8)}.mce-placeholder .mce-textbox{color:#aaa}.mce-textbox.mce-multiline{padding:4px}.mce-textbox.mce-disabled{color:#adadad}.mce-throbber{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.6;filter:alpha(opacity=60);zoom:1;background:#fff url('img/loader.gif') no-repeat center center}@font-face{font-family:'wysiwyg';src:url('fonts/wysiwyg.eot?2140760');src:url('fonts/wysiwyg.eot?2140760#iefix') format('embedded-opentype'),url('fonts/wysiwyg.woff?2140760') format('woff'),url('fonts/wysiwyg.ttf?2140760') format('truetype'),url('fonts/wysiwyg.svg?2140760#wysiwyg') format('svg')}.mce-ico{position:relative;top:4px;display:inline-block;font-family:'wysiwyg';font-style:normal;font-weight:normal;line-height:1;-webkit-font-smoothing:antialiased}.mce-i-bold:before{content:'\e838'}.mce-i-italic:before{content:'\e839'}.mce-i-link:before{content:'\e84c'}.mce-i-alignleft:before{content:'\e844'}.mce-i-aligncenter:before{content:'\e843'}.mce-i-alignright:before{content:'\e842'}.mce-i-alignjustify:before{content:'\e841'}.mce-i-indent:before{content:'\e83f'}.mce-i-outdent:before{content:'\e840'}.mce-i-bullist:before{content:'\e83e'}.mce-i-numlist:before{content:'\e83d'}.mce-i-code:before{content:"\e84f"}.mce-i-preview:before{content:"\e850"}.mce-i-save:before{content:"\e851"}.mce-i-image:before{content:"\e84e"}.mce-i-resize:before{content:"\e853"}.mce-i-checkbox:before,.mce-i-selected:before{content:"\e033"}.mce-i-selected{visibility:hidden}i.mce-i-backcolor{text-shadow:none;background:#bbb}.mce-edit-area{border:1px solid #ddd;border-width:1px !important;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.mce-edit-area iframe{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.is-focused .mce-edit-area{box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 0 5px -1px rgba(0,128,191,0.5);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,0.1),0 0 5px -1px rgba(0,128,191,0.5);border-color:#0080bf #0091d9 #0091d9;border:1px solid #0080bf}.mce-window textarea{font-size:12px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace} \ No newline at end of file +.mce-container,.mce-container *,.mce-widget,.mce-widget *{margin:0;padding:0;border:0;outline:0;vertical-align:top;background:0 0;text-decoration:none;color:#333;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:14px;text-shadow:none;float:none;position:static;width:auto;height:auto;white-space:nowrap;cursor:inherit;-webkit-tap-highlight-color:transparent;line-height:normal;font-weight:400;text-align:left;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box;direction:ltr}.mce-widget button{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}.mce-container [unselectable]{-moz-user-select:none;-webkit-user-select:none;-o-user-select:none;user-select:none}.mce-container ::-webkit-scrollbar{width:8px;height:8px;-webkit-border-radius:4px}.mce-container ::-webkit-scrollbar-track,.mce-container ::-webkit-scrollbar-track-piece{background-color:transparent}.mce-container ::-webkit-scrollbar-thumb{background-color:rgba(53,57,71,.3);width:6px;height:6px;-webkit-border-radius:4px}.mce-fade{opacity:0;-webkit-transition:opacity .15s linear;transition:opacity .15s linear}.mce-fade.mce-in{opacity:1}.mce-tinymce{visibility:visible!important;position:relative}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;height:100%;z-index:100}div.mce-fullscreen{position:fixed;top:0;left:0;width:100%;height:auto}.mce-tinymce{display:block;-webkit-border-radius:2px;-moz-border-radius:2px;border-radius:2px}.mce-wordcount{position:absolute;top:0;right:0;padding:8px}div.mce-edit-area{background:#FFF;filter:none}.mce-statusbar{position:relative}.mce-statusbar .mce-container-body{position:relative}.mce-fullscreen .mce-resizehandle{display:none}.mce-charmap{border-collapse:collapse}.mce-charmap td{cursor:default;border:1px solid #ddd;width:20px;height:20px;line-height:20px;text-align:center;vertical-align:middle;padding:2px}.mce-charmap td div{text-align:center}.mce-charmap td:hover{background:#ddd}.mce-grid td div{border:1px solid #d6d6d6;width:12px;height:12px;margin:2px;cursor:pointer}.mce-grid{border-spacing:2px;border-collapse:separate}.mce-grid a{display:block;border:1px solid transparent}.mce-grid a:hover{border-color:#a1a1a1}.mce-grid-border{margin:0 4px}.mce-grid-border a{border-color:#d6d6d6;width:13px;height:13px}.mce-grid-border a:hover,.mce-grid-border a.mce-active{border-color:#a1a1a1;background:#c8def4}.mce-text-center{text-align:center}div.mce-tinymce-inline{width:100%;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-container,.mce-container-body{display:block}.mce-autoscroll{overflow:hidden}.mce-scrollbar{position:absolute;width:7px;height:100%;top:2px;right:2px;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-scrollbar-h{top:auto;right:auto;left:2px;bottom:2px;width:100%;height:7px}.mce-scrollbar-thumb{position:absolute;background-color:#000;border:1px solid #888;border-color:rgba(85,85,85,.6);width:5px;height:100%;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scrollbar-h .mce-scrollbar-thumb{width:100%;height:5px}.mce-scrollbar:hover,.mce-scrollbar.mce-active{background-color:#AAA;opacity:.6;filter:alpha(opacity=60);zoom:1;-webkit-border-radius:7px;-moz-border-radius:7px;border-radius:7px}.mce-scroll{position:relative}.mce-floatpanel{position:absolute;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.mce-floatpanel.mce-fixed{position:fixed}.mce-floatpanel .mce-arrow,.mce-floatpanel .mce-arrow:after{position:absolute;display:block;width:0;height:0;border-color:transparent;border-style:solid}.mce-floatpanel .mce-arrow{border-width:11px}.mce-floatpanel .mce-arrow:after{border-width:10px;content:""}.mce-floatpanel.mce-popover{top:0;left:0;background:#fff;border:1px solid #000;border:1px solid rgba(0,0,0,.25);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2)}.mce-floatpanel.mce-popover.mce-bottom{margin-top:10px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow{left:50%;margin-left:-11px;border-top-width:0;border-bottom-color:#000;border-bottom-color:rgba(0,0,0,.25);top:-11px}.mce-floatpanel.mce-popover.mce-bottom>.mce-arrow:after{top:1px;margin-left:-10px;border-top-width:0;border-bottom-color:#fff}.mce-floatpanel.mce-popover.mce-bottom.mce-start{margin-left:-22px}.mce-floatpanel.mce-popover.mce-bottom.mce-start>.mce-arrow{left:20px}.mce-floatpanel.mce-popover.mce-bottom.mce-end{margin-left:22px}.mce-floatpanel.mce-popover.mce-bottom.mce-end>.mce-arrow{right:10px;left:auto}.mce-fullscreen{border:0;padding:0;margin:0;overflow:hidden;background:#fff;height:100%}div.mce-fullscreen{position:fixed;top:0;left:0}#mce-modal-block{opacity:0;filter:alpha(opacity=0);zoom:1;position:fixed;left:0;top:0;width:100%;height:100%;background:#000}#mce-modal-block.mce-in{opacity:.3;filter:alpha(opacity=30);zoom:1}.mce-window-move{cursor:move}.mce-window{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0,0,0,.3);-moz-box-shadow:0 3px 7px rgba(0,0,0,.3);box-shadow:0 3px 7px rgba(0,0,0,.3);filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background:0 0;background:#fff;position:fixed;top:0;left:0;opacity:0;-webkit-transition:opacity 150ms ease-in;transition:opacity 150ms ease-in;border:1px solid #999}.mce-window.mce-in{opacity:1}.mce-window-head{padding:9px 15px;border-bottom:1px solid #f9f9f9;position:relative}.mce-window-head .mce-close{position:absolute;right:15px;top:9px;font-size:20px;font-weight:700;line-height:20px;color:#da8888;cursor:pointer;height:20px;overflow:hidden}.mce-close:hover{color:#c64545}.mce-window-head .mce-title{display:inline-block;*display:inline;*zoom:1;line-height:27px;font-size:20px;padding-right:10px}.mce-window .mce-container-body{display:block}.mce-foot{display:block;background-color:#fff;border-top:1px solid #f9f9f9;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px}.mce-window-head .mce-dragh{position:absolute;top:0;left:0;cursor:move;width:90%;height:100%}.mce-window iframe{width:100%;height:100%}.mce-window.mce-fullscreen,.mce-window.mce-fullscreen .mce-foot{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-abs-layout{position:relative}body .mce-abs-layout-item,.mce-abs-end{position:absolute}.mce-abs-end{width:1px;height:1px}.mce-container-body.mce-abs-layout{overflow:hidden}.mce-tooltip{position:absolute;padding:5px;opacity:.8;filter:alpha(opacity=80);zoom:1}.mce-tooltip-inner{font-size:11px;background-color:#000;color:#fff;max-width:200px;padding:5px 8px 4px;text-align:center;white-space:normal}.mce-tooltip-inner{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-tooltip-arrow{position:absolute;width:0;height:0;line-height:0;border:5px dashed #000}.mce-tooltip-arrow-n{border-bottom-color:#000}.mce-tooltip-arrow-s{border-top-color:#000}.mce-tooltip-arrow-e{border-left-color:#000}.mce-tooltip-arrow-w{border-right-color:#000}.mce-tooltip-nw,.mce-tooltip-sw{margin-left:-14px}.mce-tooltip-n .mce-tooltip-arrow{top:0;left:50%;margin-left:-5px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-nw .mce-tooltip-arrow{top:0;left:10px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-ne .mce-tooltip-arrow{top:0;right:10px;border-bottom-style:solid;border-top:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-s .mce-tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-sw .mce-tooltip-arrow{bottom:0;left:10px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-se .mce-tooltip-arrow{bottom:0;right:10px;border-top-style:solid;border-bottom:0;border-left-color:transparent;border-right-color:transparent}.mce-tooltip-e .mce-tooltip-arrow{right:0;top:50%;margin-top:-5px;border-left-style:solid;border-right:0;border-top-color:transparent;border-bottom-color:transparent}.mce-tooltip-w .mce-tooltip-arrow{left:0;top:50%;margin-top:-5px;border-right-style:solid;border-left:0;border-top-color:transparent;border-bottom-color:transparent}.mce-btn{border:1px solid #ddd;border-color:#ddd;position:relative;text-shadow:0 1px 1px rgba(255,255,255,.75);display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-btn:hover,.mce-btn:focus{color:#333;background:#f9f9f9}.mce-btn.mce-disabled button,.mce-btn.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-btn.mce-active,.mce-btn.mce-active:hover,.mce-btn:not(.mce-disabled):active{background:#f9f9f9;border-color:#c4c4c4;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15);box-shadow:inset 0 2px 4px rgba(0,0,0,.15)}.mce-btn button{padding:4px 10px;font-size:14px;line-height:20px;*line-height:16px;cursor:pointer;color:#333;text-align:center;overflow:visible;-webkit-appearance:none}.mce-btn button::-moz-focus-inner{border:0;padding:0}.mce-btn i{text-shadow:1px 1px #fff}.mce-primary{min-width:50px;color:#07628f;border:1px solid #f5f5f5;border-color:#86ccef;background:#fff;background-color:#f9fcfd;background-image:-moz-linear-gradient(top,#fff,#f1f8fb);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#f1f8fb));background-image:-webkit-linear-gradient(top,#fff,#f1f8fb);background-image:-o-linear-gradient(top,#fff,#f1f8fb);background-image:linear-gradient(to bottom,#fff,#f1f8fb);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff1f8fb', GradientType=0);zoom:1}.mce-primary:hover,.mce-primary:focus{background-color:#f0f7fc;background-image:-moz-linear-gradient(top,#fff,#d9eaf8);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#d9eaf8));background-image:-webkit-linear-gradient(top,#fff,#d9eaf8);background-image:-o-linear-gradient(top,#fff,#d9eaf8);background-image:linear-gradient(to bottom,#fff,#d9eaf8);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffd9eaf8', GradientType=0);zoom:1}.mce-primary.mce-disabled button,.mce-primary.mce-disabled:hover button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-primary.mce-active,.mce-primary.mce-active:hover,.mce-primary:not(.mce-disabled):active{border-color:#2ca6e3;background:#d7e9f7;-webkit-box-shadow:inset 0 2px 4px #93b3cc;-moz-box-shadow:inset 0 2px 4px #93b3cc;box-shadow:inset 0 2px 4px #93b3cc}.mce-primary button,.mce-primary button i{color:#07628f;text-shadow:1px 1px #fff}.mce-btn-large button{padding:9px 14px;font-size:16px;line-height:normal;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px}.mce-btn-large i{margin-top:2px}.mce-btn-small button{padding:3px 5px;font-size:12px;line-height:15px}.mce-btn-small i{margin-top:0}.mce-btn .mce-caret{margin-top:8px;*margin-top:6px;margin-left:0}.mce-btn-small .mce-caret{margin-top:6px;*margin-top:4px;margin-left:0}.mce-caret{display:inline-block;*display:inline;*zoom:1;width:0;height:0;vertical-align:top;border-top:4px solid #333;border-right:4px solid transparent;border-left:4px solid transparent;content:""}.mce-disabled .mce-caret{border-top-color:#aaa}.mce-caret.mce-up{border-bottom:4px solid #333;border-top:0}.mce-btn-group .mce-btn{border-width:1px 0 1px 1px;margin:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0}.mce-btn-group .mce-first{border-left:1px solid #ddd;-webkit-border-radius:3px 0 0 3px;-moz-border-radius:3px 0 0 3px;border-radius:3px 0 0 3px}.mce-btn-group .mce-last{border-right:1px solid #ddd;-webkit-border-radius:0 3px 3px 0;-moz-border-radius:0 3px 3px 0;border-radius:0 3px 3px 0}.mce-btn-group .mce-first.mce-last{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-btn-group .mce-btn.mce-flow-layout-item{margin:0}.mce-checkbox{cursor:pointer}i.mce-i-checkbox{margin:0 3px 0 0;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2),0 1px 2px rgba(0,0,0,.05);background-color:#f1f1f1;background-image:-moz-linear-gradient(top,#fff,#ddd);background-image:-webkit-gradient(linear,0 0,0 100%,from(#fff),to(#ddd));background-image:-webkit-linear-gradient(top,#fff,#ddd);background-image:-o-linear-gradient(top,#fff,#ddd);background-image:linear-gradient(to bottom,#fff,#ddd);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffdddddd', GradientType=0);zoom:1;text-indent:-10em;*font-size:0;*line-height:0;*text-indent:0;overflow:hidden}.mce-checked i.mce-i-checkbox{color:#333;font-size:16px;line-height:16px;text-indent:0}.mce-checkbox:focus i.mce-i-checkbox,.mce-checkbox.mce-focus i.mce-i-checkbox{border:1px solid rgba(82,168,236,.8);-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(82,168,236,.65);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(82,168,236,.65);box-shadow:inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(82,168,236,.65)}.mce-checkbox.mce-disabled .mce-label,.mce-checkbox.mce-disabled i.mce-i-checkbox{color:#adadad}.mce-colorbutton .mce-ico{position:relative}.mce-colorbutton-grid{margin:4px}.mce-colorbutton button{padding-right:4px}.mce-colorbutton .mce-preview{padding-right:3px;display:block;position:absolute;left:50%;top:50%;margin-left:-14px;margin-top:7px;background:gray;width:13px;height:2px;overflow:hidden}.mce-colorbutton.mce-btn-small .mce-preview{margin-left:-17px;padding-right:0;width:16px}.mce-colorbutton .mce-open{padding-left:4px;border-left:1px solid transparent;border-right:1px solid transparent}.mce-colorbutton:hover .mce-open{border-left-color:#bdbdbd;border-right-color:#bdbdbd}.mce-combobox{display:inline-block;*display:inline;*zoom:1;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075)}.mce-combobox input{border:1px solid #c5c5c5;border-right-color:#c5c5c5;height:28px}.mce-combobox.mce-disabled input{color:#adadad}.mce-combobox.mce-has-open input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px}.mce-combobox .mce-btn{border-left:0;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0}.mce-combobox button{padding-right:8px;padding-left:8px}.mce-combobox.mce-disabled .mce-btn button{cursor:default;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;opacity:.4;filter:alpha(opacity=40);zoom:1}.mce-path{display:inline-block;*display:inline;*zoom:1;padding-top:5px;white-space:normal}.mce-path .mce-txt{display:inline-block;color:#666;font-size:12px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;padding:2px 6px 3px}.mce-path .mce-path-body{display:inline-block}.mce-path-item{display:inline-block;*display:inline;*zoom:1;cursor:pointer;color:#666;font-size:12px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;padding:2px 6px 3px;border:1px solid #eee;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-path-item:hover{color:#666;background-color:#f9f9f9;border-color:#ddd}.mce-path-item:focus{color:#666;background-color:#eee;border-color:#ccc}.mce-path .mce-divider{display:inline-block;font-size:12px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace;padding:2px 4px 3px;color:#666}.mce-fieldset{border:0 solid #9E9E9E;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.mce-fieldset>.mce-container-body{margin-top:-15px}.mce-fieldset-title{margin-left:5px;padding:0 5px}.mce-fit-layout{display:inline-block;*display:inline;*zoom:1}.mce-fit-layout-item{position:absolute}.mce-flow-layout-item{display:inline-block;*display:inline;*zoom:1}.mce-flow-layout-item{margin-bottom:4px;margin-right:4px}.mce-flow-layout{white-space:normal}.mce-tinymce-inline .mce-flow-layout{white-space:nowrap}.mce-iframe{border:0 solid #ddd;width:100%;height:100%}.mce-label{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 1px rgba(255,255,255,.75);border:0;overflow:hidden}.mce-label.mce-autoscroll{overflow:auto}.mce-label-disabled .mce-text{color:#aaa}.mce-label.mce-multiline{white-space:pre-wrap}.mce-menubar .mce-menubtn{border-color:transparent;background:0 0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;filter:none}.mce-menubar{border:1px solid #ebebeb}.mce-menubar .mce-menubtn button span{color:#333}.mce-menubar .mce-caret{border-top-color:#333}.mce-menubar .mce-menubtn:hover,.mce-menubar .mce-menubtn.mce-active,.mce-menubar .mce-menubtn:focus{border-color:transparent;background:#e6e6e6;filter:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none}.mce-menubtn.mce-disabled span{color:#aaa}.mce-menubtn span{color:#333;margin-right:2px;line-height:20px;*line-height:16px}.mce-menubtn.mce-btn-small span{font-size:12px;line-height:15px;*line-height:16px}.mce-menubtn.mce-fixed-width span{display:inline-block;overflow-x:hidden;text-overflow:ellipsis;width:90px}.mce-menubtn.mce-fixed-width.mce-btn-small span{width:70px}.mce-listbox button{text-align:left;padding-right:20px;position:relative}.mce-listbox .mce-caret{position:absolute;margin-top:-2px;right:8px;top:50%}.mce-menu-item{display:block;padding:6px 15px 6px 12px;clear:both;font-weight:400;line-height:20px;color:#333;white-space:nowrap;cursor:pointer;line-height:normal;border-left:4px solid transparent;margin-bottom:1px}.mce-menu-item .mce-ico,.mce-menu-item .mce-text{color:#333}.mce-menu-item.mce-disabled .mce-text,.mce-menu-item.mce-disabled .mce-ico{color:#adadad}.mce-menu-item:hover .mce-text,.mce-menu-item.mce-selected .mce-text{color:#fff}.mce-menu-item:hover .mce-ico,.mce-menu-item.mce-selected .mce-ico,.mce-menu-item:focus .mce-ico{color:#fff}.mce-menu-item.mce-disabled:hover{background:#ccc}.mce-menu-shortcut{display:inline-block;color:#adadad}.mce-menu-shortcut{display:inline-block;*display:inline;*zoom:1;padding:0 15px 0 20px}.mce-menu-item:hover .mce-menu-shortcut,.mce-menu-item.mce-selected .mce-menu-shortcut,.mce-menu-item:focus .mce-menu-shortcut{color:#fff}.mce-menu-item .mce-caret{margin-top:4px;*margin-top:3px;margin-right:6px;border-top:4px solid transparent;border-bottom:4px solid transparent;border-left:4px solid #333}.mce-menu-item.mce-selected .mce-caret,.mce-menu-item:focus .mce-caret,.mce-menu-item:hover .mce-caret{border-left-color:#fff}.mce-menu-align .mce-menu-shortcut{*margin-top:-2px}.mce-menu-align .mce-menu-shortcut,.mce-menu-align .mce-caret{position:absolute;right:0}.mce-menu-item.mce-active i{visibility:visible}.mce-menu-item-normal.mce-active{background-color:#c8def4}.mce-menu-item-preview.mce-active{border-left:5px solid #aaa}.mce-menu-item-normal.mce-active .mce-text{color:#333}.mce-menu-item-normal.mce-active:hover .mce-text,.mce-menu-item-normal.mce-active:hover .mce-ico{color:#fff}.mce-menu-item:hover,.mce-menu-item.mce-selected,.mce-menu-item:focus{text-decoration:none;color:#fff;background-color:#0081c2;background-image:-moz-linear-gradient(top,#08c,#0077b3);background-image:-webkit-gradient(linear,0 0,0 100%,from(#08c),to(#0077b3));background-image:-webkit-linear-gradient(top,#08c,#0077b3);background-image:-o-linear-gradient(top,#08c,#0077b3);background-image:linear-gradient(to bottom,#08c,#0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);zoom:1}.mce-menu-item-sep,.mce-menu-item-sep:hover{border:0;padding:0;height:1px;margin:9px 1px;overflow:hidden;background:#cbcbcb;border-bottom:1px solid #fff;cursor:default;filter:none}.mce-menu{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false);background:0 0;z-index:1000;padding:5px 0;margin:2px 0 0;min-width:160px;background:#fff;border:1px solid #999;border:1px solid rgba(0,0,0,.2);z-index:1002;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0,0,0,.2);-moz-box-shadow:0 5px 10px rgba(0,0,0,.2);box-shadow:0 5px 10px rgba(0,0,0,.2);max-height:400px;overflow:auto;overflow-x:hidden}.mce-menu i{display:none}.mce-menu-has-icons i{display:inline-block;*display:inline;*zoom:1}.mce-menu-sub-tr-tl{margin:-6px 0 0 -1px}.mce-menu-sub-br-bl{margin:6px 0 0 -1px}.mce-menu-sub-tl-tr{margin:-6px 0 0 1px}.mce-menu-sub-bl-br{margin:6px 0 0 1px}.mce-container-body .mce-resizehandle{position:absolute;right:0;bottom:0;width:16px;height:16px;visibility:visible;cursor:s-resize;margin:0}.mce-container-body .mce-resizehandle-both{cursor:se-resize}i.mce-i-resize{color:#333}.mce-spacer{visibility:hidden}.mce-splitbtn .mce-open{border-left:1px solid transparent;border-right:1px solid transparent}.mce-splitbtn:hover .mce-open{border-left-color:#bdbdbd;border-right-color:#bdbdbd}.mce-splitbtn button{padding-right:4px}.mce-splitbtn .mce-open{padding-left:4px}.mce-splitbtn .mce-open.mce-active{-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15),0 1px 2px rgba(0,0,0,.05)}.mce-stack-layout-item{display:block}.mce-tabs{display:block;border-bottom:1px solid #c5c5c5}.mce-tab{display:inline-block;*display:inline;*zoom:1;border:1px solid #c5c5c5;border-width:0 1px 0 0;background:#e3e3e3;padding:8px;text-shadow:0 1px 1px rgba(255,255,255,.75);height:13px;cursor:pointer}.mce-tab:hover{background:#fdfdfd}.mce-tab.mce-active{background:#fdfdfd;border-bottom-color:transparent;margin-bottom:-1px;height:14px}.mce-textbox{background:#fff;border:1px solid #c5c5c5;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);-moz-box-shadow:inset 0 1px 1px rgba(0,0,0,.075);box-shadow:inset 0 1px 1px rgba(0,0,0,.075);display:inline-block;-webkit-transition:border linear .2s;transition:border linear .2s;height:28px;resize:none;padding:0 4px;white-space:pre-wrap;*white-space:pre;color:#333}.mce-textbox:focus,.mce-textbox.mce-focus{border-color:rgba(82,168,236,.8)}.mce-placeholder .mce-textbox{color:#aaa}.mce-textbox.mce-multiline{padding:4px}.mce-textbox.mce-disabled{color:#adadad}.mce-throbber{position:absolute;top:0;left:0;width:100%;height:100%;opacity:.6;filter:alpha(opacity=60);zoom:1;background:#fff url(img/loader.gif) no-repeat center center}@font-face{font-family:wysiwyg;src:url(fonts/wysiwyg.eot?2140760);src:url(fonts/wysiwyg.eot?2140760#iefix) format('embedded-opentype'),url(fonts/wysiwyg.woff?2140760) format('woff'),url(fonts/wysiwyg.ttf?2140760) format('truetype'),url(fonts/wysiwyg.svg?2140760#wysiwyg) format('svg')}.mce-ico{position:relative;top:4px;display:inline-block;font-family:wysiwyg;font-style:normal;font-weight:400;line-height:1;-webkit-font-smoothing:antialiased}.mce-i-bold:before{content:'\e838'}.mce-i-italic:before{content:'\e839'}.mce-i-link:before{content:'\e84c'}.mce-i-alignleft:before{content:'\e844'}.mce-i-aligncenter:before{content:'\e843'}.mce-i-alignright:before{content:'\e842'}.mce-i-alignjustify:before{content:'\e841'}.mce-i-indent:before{content:'\e83f'}.mce-i-outdent:before{content:'\e840'}.mce-i-blockquote:before{content:'\e801'}.mce-i-bullist:before{content:'\e83e'}.mce-i-numlist:before{content:'\e83d'}.mce-i-code:before{content:"\e84f"}.mce-i-preview:before{content:"\e850"}.mce-i-save:before{content:"\e851"}.mce-i-image:before{content:"\e84e"}.mce-i-resize:before{content:"\e853"}.mce-i-checkbox:before,.mce-i-selected:before{content:"\e033"}.mce-i-selected{visibility:hidden}i.mce-i-backcolor{text-shadow:none;background:#bbb}.mce-edit-area{border:1px solid #ddd;border-width:1px!important;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s;-webkit-transition:border-color ease-in-out .15s,box-shadow ease-in-out .15s}.mce-edit-area iframe{-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px}.is-focused .mce-edit-area{box-shadow:inset 0 1px 2px rgba(0,0,0,.1),0 0 5px -1px rgba(0,128,191,.5);-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1),0 0 5px -1px rgba(0,128,191,.5);border-color:#0080bf #0091d9 #0091d9;border:1px solid #0080bf}.mce-window textarea{font-size:12px;font-family:Monaco,Menlo,Consolas,"Courier New",monospace} \ No newline at end of file From f07c7f0dadcf487e5d3fc1e80662822d743828d1 Mon Sep 17 00:00:00 2001 From: Vito Belgiorno-Zegna Date: Mon, 13 Jul 2015 14:28:01 +1000 Subject: [PATCH 10/86] #1433 - Added faint grey border on color picker field --- fields/types/color/ColorField.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/fields/types/color/ColorField.js b/fields/types/color/ColorField.js index 8e98bbd620..c10d8ed203 100644 --- a/fields/types/color/ColorField.js +++ b/fields/types/color/ColorField.js @@ -31,6 +31,9 @@ module.exports = Field.create({ width: 24, height: 24, borderRadius: 5, + borderStyle: 'solid', + borderWidth: '1px', + borderColor: '#E0E0E0', background: this.props.value }} /> ); From 6601dfaa811c70b8aaf42511814366e749d9cb4e Mon Sep 17 00:00:00 2001 From: netmml Date: Mon, 13 Jul 2015 18:04:02 -0400 Subject: [PATCH 11/86] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f0ef0dfd15..f85efa332d 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ![Build Status](https://travis-ci.org/keystonejs/keystone.svg) -[KeystoneJS](http://keystonejs.com) is a powerful Node.js content management system and web app framework built on [express](http://expressjs.com) and [mongoose](http://mongoosejs.com) that makes it easy to create sophisticated web sites and apps, and gives you a beautiful, auto-generated Admin UI. +[KeystoneJS](http://keystonejs.com) is a powerful Node.js content management system and web app framework built on [express](http://expressjs.com) and [mongoose](http://mongoosejs.com). Keystone makes it easy to create sophisticated web sites and apps, which also comes with a beautiful auto-generated Admin UI. Check out [keystonejs.com](http://keystonejs.com) for documentation and guides. From f347bc95e942593478e8ffb90af97227d94e3359 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Tue, 14 Jul 2015 23:33:49 +1000 Subject: [PATCH 12/86] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index f85efa332d..4d01bef722 100644 --- a/README.md +++ b/README.md @@ -3,7 +3,7 @@ ![Build Status](https://travis-ci.org/keystonejs/keystone.svg) -[KeystoneJS](http://keystonejs.com) is a powerful Node.js content management system and web app framework built on [express](http://expressjs.com) and [mongoose](http://mongoosejs.com). Keystone makes it easy to create sophisticated web sites and apps, which also comes with a beautiful auto-generated Admin UI. +[KeystoneJS](http://keystonejs.com) is a powerful Node.js content management system and web app framework built on [express](http://expressjs.com) and [mongoose](http://mongoosejs.com). Keystone makes it easy to create sophisticated web sites and apps, and comes with a beautiful auto-generated Admin UI. Check out [keystonejs.com](http://keystonejs.com) for documentation and guides. From 668ce6328943f3fd89bfa38841aafa4886df02ad Mon Sep 17 00:00:00 2001 From: jeffreypriebe Date: Tue, 14 Jul 2015 13:56:20 -0700 Subject: [PATCH 13/86] Added check for duplicate _revisions models. To avoid collision of inherited models (which reuse the same _revisions historyModel as the model inherited from), check for existance of _revisions model for inherited models and skip attempt to create a new model. (Inherited _revisions model will be used.) --- lib/schemaPlugins/history.js | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/lib/schemaPlugins/history.js b/lib/schemaPlugins/history.js index 04a5797cda..5ed8f08db8 100644 --- a/lib/schemaPlugins/history.js +++ b/lib/schemaPlugins/history.js @@ -1,8 +1,14 @@ var keystone = require('../../'); +var historyModelSuffix = '_revisions'; + +function getHistoryModelName (list) { + return list.options.schema.collection + historyModelSuffix; +} + function getHistoryModel(list, userModel) { - var collection = list.options.schema.collection + '_revisions'; + var collection = getHistoryModelName(list); var schema = new keystone.mongoose.Schema({ i: { type: keystone.mongoose.Schema.Types.ObjectId, ref: collection }, @@ -34,6 +40,16 @@ function getHistoryModel(list, userModel) { module.exports = function history() { var list = this; + + //If model already exists for a '_revisions' in an inherited model, log a warning but skip creating the new model (inherited _revisions model will be used). + var collectionName = getHistoryModelName(list); + if (list.get('inherits') && + collectionName.indexOf(historyModelSuffix, collectionName.length - historyModelSuffix.length) !== -1 && + keystone.mongoose.models[collectionName]) { + console.log('List/model already exists for ' + collectionName + '.\nWon\'t re-create, keystone continuing.'); + return; + } + var userModel = keystone.get('user model'); var HistoryModel = list.HistoryModel = getHistoryModel(this, userModel); From aa778dcf37b0eca1b8643ad975baf24078e29232 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Fri, 17 Jul 2015 16:25:38 +1000 Subject: [PATCH 14/86] Using getters for field types, speeds up init and fixes #1534 --- lib/fieldTypes.js | 64 +++++++++++++++++++++++++---------------------- 1 file changed, 34 insertions(+), 30 deletions(-) diff --git a/lib/fieldTypes.js b/lib/fieldTypes.js index a4dbda92de..551c007eb1 100644 --- a/lib/fieldTypes.js +++ b/lib/fieldTypes.js @@ -1,30 +1,34 @@ -exports.AzureFile = require('../fields/types/azurefile/AzureFileType'); -exports.Boolean = require('../fields/types/boolean/BooleanType'); -exports.CloudinaryImage = require('../fields/types/cloudinaryimage/CloudinaryImageType'); -exports.CloudinaryImages = require('../fields/types/cloudinaryimages/CloudinaryImagesType'); -exports.Code = require('../fields/types/code/CodeType'); -exports.Color = require('../fields/types/color/ColorType'); -exports.Date = require('../fields/types/date/DateType'); -exports.DateArray = require('../fields/types/datearray/DateArrayType'); -exports.Datetime = require('../fields/types/datetime/DatetimeType'); -exports.Email = require('../fields/types/email/EmailType'); -exports.Embedly = require('../fields/types/embedly/EmbedlyType'); -exports.GeoPoint = require('../fields/types/geopoint/GeoPointType'); -exports.Html = require('../fields/types/html/HtmlType'); -exports.Key = require('../fields/types/key/KeyType'); -exports.LocalFile = require('../fields/types/localfile/LocalFileType'); -exports.LocalFiles = require('../fields/types/localfiles/LocalFilesType'); -exports.Location = require('../fields/types/location/LocationType'); -exports.Markdown = require('../fields/types/markdown/MarkdownType'); -exports.Money = require('../fields/types/money/MoneyType'); -exports.Name = require('../fields/types/name/NameType'); -exports.Number = require('../fields/types/number/NumberType'); -exports.NumberArray = require('../fields/types/numberarray/NumberArrayType'); -exports.Password = require('../fields/types/password/PasswordType'); -exports.Relationship = require('../fields/types/relationship/RelationshipType'); -exports.S3File = require('../fields/types/s3file/S3FileType'); -exports.Select = require('../fields/types/select/SelectType'); -exports.Text = require('../fields/types/text/TextType'); -exports.TextArray = require('../fields/types/textarray/TextArrayType'); -exports.Textarea = require('../fields/types/textarea/TextareaType'); -exports.Url = require('../fields/types/url/UrlType'); +var fields = { + get AzureFile () { return require('../fields/types/azurefile/AzureFileType'); }, + get Boolean () { return require('../fields/types/boolean/BooleanType'); }, + get CloudinaryImage () { return require('../fields/types/cloudinaryimage/CloudinaryImageType'); }, + get CloudinaryImages () { return require('../fields/types/cloudinaryimages/CloudinaryImagesType'); }, + get Code () { return require('../fields/types/code/CodeType'); }, + get Color () { return require('../fields/types/color/ColorType'); }, + get Date () { return require('../fields/types/date/DateType'); }, + get DateArray () { return require('../fields/types/datearray/DateArrayType'); }, + get Datetime () { return require('../fields/types/datetime/DatetimeType'); }, + get Email () { return require('../fields/types/email/EmailType'); }, + get Embedly () { return require('../fields/types/embedly/EmbedlyType'); }, + get GeoPoint () { return require('../fields/types/geopoint/GeoPointType'); }, + get Html () { return require('../fields/types/html/HtmlType'); }, + get Key () { return require('../fields/types/key/KeyType'); }, + get LocalFile () { return require('../fields/types/localfile/LocalFileType'); }, + get LocalFiles () { return require('../fields/types/localfiles/LocalFilesType'); }, + get Location () { return require('../fields/types/location/LocationType'); }, + get Markdown () { return require('../fields/types/markdown/MarkdownType'); }, + get Money () { return require('../fields/types/money/MoneyType'); }, + get Name () { return require('../fields/types/name/NameType'); }, + get Number () { return require('../fields/types/number/NumberType'); }, + get NumberArray () { return require('../fields/types/numberarray/NumberArrayType'); }, + get Password () { return require('../fields/types/password/PasswordType'); }, + get Relationship () { return require('../fields/types/relationship/RelationshipType'); }, + get S3File () { return require('../fields/types/s3file/S3FileType'); }, + get Select () { return require('../fields/types/select/SelectType'); }, + get Text () { return require('../fields/types/text/TextType'); }, + get TextArray () { return require('../fields/types/textarray/TextArrayType'); }, + get Textarea () { return require('../fields/types/textarea/TextareaType'); }, + get Url () { return require('../fields/types/url/UrlType'); } +}; + +module.exports = fields; From bff5c6c4dc01781ed9603d40578f15d829ddd25b Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Fri, 17 Jul 2015 18:51:19 +1000 Subject: [PATCH 15/86] Disabling infix operator spacing, seems to be returning false positives --- .eslintrc | 1 + package.json | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintrc b/.eslintrc index 21d4e50b08..b7902c24e2 100644 --- a/.eslintrc +++ b/.eslintrc @@ -37,6 +37,7 @@ "react/self-closing-comp": 1, "react/wrap-multilines": 1, "semi": 2, + "space-infix-ops": 0, "strict": 0, "yoda": 0 }, diff --git a/package.json b/package.json index 40993e1302..7474368db1 100644 --- a/package.json +++ b/package.json @@ -69,7 +69,7 @@ "babel-eslint": "^3.1.18", "browserify": "~10.2.4", "codeclimate-test-reporter": "0.0.4", - "eslint": "^0.23.0", + "eslint": "^0.24.1", "eslint-plugin-react": "^2.5.2", "gulp": "~3.9.0", "gulp-git": "^1.2.4", From 6a4bd7583c5fc14483a641584a5f10afdcfda11e Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Fri, 17 Jul 2015 18:51:31 +1000 Subject: [PATCH 16/86] Handling err in item view --- admin/routes/views/item.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/admin/routes/views/item.js b/admin/routes/views/item.js index da83bdd9bb..7cf50bb28d 100644 --- a/admin/routes/views/item.js +++ b/admin/routes/views/item.js @@ -1,6 +1,6 @@ -var keystone = require('../../../'), - _ = require('underscore'), - async = require('async'); +var keystone = require('../../../'); +var _ = require('underscore'); +var async = require('async'); exports = module.exports = function(req, res) { @@ -8,6 +8,11 @@ exports = module.exports = function(req, res) { itemQuery.exec(function(err, item) { + if (err) { + req.flash('error', 'A database error occurred.'); + return res.redirect('/keystone/' + req.list.path); + } + if (!item) { req.flash('error', 'Item ' + req.params.item + ' could not be found.'); return res.redirect('/keystone/' + req.list.path); From bad9dc56e1cb437c9bba30693a2f2b85555b258d Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Fri, 17 Jul 2015 18:51:58 +1000 Subject: [PATCH 17/86] Formatting cleanup --- fields/types/Type.js | 38 +++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/fields/types/Type.js b/fields/types/Type.js index 0fc2a1abb3..e27072599f 100644 --- a/fields/types/Type.js +++ b/fields/types/Type.js @@ -2,11 +2,11 @@ * Module dependencies. */ -var _ = require('underscore'), - marked = require('marked'), - Path = require('../../lib/path'), - utils = require('keystone-utils'), - di = require('asyncdi'); +var _ = require('underscore'); +var marked = require('marked'); +var Path = require('../../lib/path'); +var utils = require('keystone-utils'); +var di = require('asyncdi'); /** * Field Constructor @@ -54,7 +54,7 @@ function Field(list, path, options) { // Convert notes from markdown to html var note = null; - Object.defineProperty(this, 'note', { + Object.defineProperty(this, 'note', { get: function() { return (note === null) ? (note = (this.options.note) ? marked(this.options.note) : '') : note; } @@ -67,11 +67,11 @@ function Field(list, path, options) { */ Field.prototype.getOptions = function() { - + if (!this.__options) { - + this.__options = {}; - + var optionKeys = [ 'path', 'paths', @@ -91,11 +91,11 @@ Field.prototype.getOptions = function() { 'collapse', 'dependsOn' ]; - + if (_.isArray(this._properties)) { optionKeys = optionKeys.concat(this._properties); } - + optionKeys.forEach(function(key) { if (this[key]) { this.__options[key] = this[key]; @@ -105,13 +105,13 @@ Field.prototype.getOptions = function() { if (this.getProperties) { _.extend(this.__options, this.getProperties()); } - + this.__options.defaultValue = this.getDefaultValue(); - + } - + return this.__options; - + }; /** @@ -337,19 +337,19 @@ Field.prototype.validateInput = function(data, required, item) { */ Field.prototype.updateItem = function(item, data) { - + var value = this.getValueFromData(data); - + // This is a deliberate type coercion so that numbers from forms play nice if (value !== undefined && value != item.get(this.path)) { // eslint-disable-line eqeqeq item.set(this.path, value); } - + }; /** * Retrieves the value from an object, whether the path is nested or flattened - * + * * @api public */ From 3908f8758d6374251d5e96d70148648a7a77e55f Mon Sep 17 00:00:00 2001 From: Javier Castro Date: Sat, 18 Jul 2015 02:04:07 -0300 Subject: [PATCH 18/86] Fixes #1440 Correctly display html returned by format(...) function --- templates/mixins/columns.jade | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/mixins/columns.jade b/templates/mixins/columns.jade index cbbb652c92..6a2f236b34 100644 --- a/templates/mixins/columns.jade +++ b/templates/mixins/columns.jade @@ -36,6 +36,8 @@ mixin column(list, col, item) +column_link(value, value, true) else if col.type == 'color' +column_color(value) + else if col.type == 'localfile' + +column_html(value) else +column_basic(value) From 97e5b2d5673035b146ea986e57096ff722aaafbd Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sat, 18 Jul 2015 21:40:55 +1000 Subject: [PATCH 19/86] Rolling back pro tip, I think it's better to have issues + PRs separate --- CONTRIBUTING.md | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 92ef4586e0..76ac590ab8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -14,23 +14,13 @@ early and is a good way to discuss what you're planning to do. * If you open an issue and are interested in working on a fix, please let us know. We'll help you get started, rather than adding it to the queue. * Make sure you do not add regressions by running `npm test`. Please also -[follow our established coding conventions](https://github.com/keystonejs/keystone/wiki/Coding-Standards) +[follow our established coding conventions](https://github.com/keystonejs/keystone/wiki/Coding-Standards) (with regards to formatting, etc) * You can also run `npm run lint` and `npm run style` - our linter is a WIP but please ensure there are not more violations than before your changes. * All new features and changes need documentation. They live over at the [Keystone-site](https://github.com/keystonejs/keystonejs-site) repo. * We have three translations so far, please read our [Documentation Translation Guidelines](https://github.com/keystonejs/keystone/wiki/Documentation-Translation-Guidelines). -* **PRO TIP**: If you've opened an issue and have come up with a solution -yourself, we prefer you to convert the already existing issue into a PR instead -of opening a new one. This can be done with the [hub command line tool](https://github.com/github/hub) - - Example: - ```sh - # convert issue 1239 into a pull-request sending all commits from `fix_hooks` branch in creynders' - # keystone fork to the `master` branch of the official repo - hub pull-request -i 1239 -b keystonejs/keystone:master -h creynders/keystone:fix_hooks - ``` If you are working on the React Admin UI, you'll also need to know this: From 080cc9b0a95ae4069a93bd789949b502af03d078 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sat, 18 Jul 2015 21:44:22 +1000 Subject: [PATCH 20/86] Limiting Travis badge to the master branch, fixes #1535 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 4d01bef722..0ed1a2740e 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ ![KeystoneJS](http://keystonejs.com/images/logo.svg) =================================== -![Build Status](https://travis-ci.org/keystonejs/keystone.svg) +[![Build Status](https://travis-ci.org/keystonejs/keystone.svg?branch=master)](https://travis-ci.org/keystonejs/keystone) [KeystoneJS](http://keystonejs.com) is a powerful Node.js content management system and web app framework built on [express](http://expressjs.com) and [mongoose](http://mongoosejs.com). Keystone makes it easy to create sophisticated web sites and apps, and comes with a beautiful auto-generated Admin UI. @@ -130,7 +130,7 @@ To understand how these settings are used, and how the Express application is in Keystone builds on the basic data types provided by mongo and allows you to easily add rich, functional fields to your application's models. -You get helper methods on your models for dealing with each field type easily (such as +You get helper methods on your models for dealing with each field type easily (such as formatting a date or number, resizing an image, getting an array of the available options for a select field, or using Google's Places API to improve addresses) as well as a beautiful, responsive admin UI to edit your data with. From 86b908473e70a928450d6e80f9ea97d9b40dbeb2 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sun, 19 Jul 2015 00:24:57 +1000 Subject: [PATCH 21/86] Cleanup --- fields/types/Type.js | 105 ++++++++++------------------------ fields/types/text/TextType.js | 15 ++--- lib/list.js | 5 +- 3 files changed, 36 insertions(+), 89 deletions(-) diff --git a/fields/types/Type.js b/fields/types/Type.js index e27072599f..e5301c8bef 100644 --- a/fields/types/Type.js +++ b/fields/types/Type.js @@ -1,13 +1,32 @@ /*! * Module dependencies. */ - var _ = require('underscore'); var marked = require('marked'); var Path = require('../../lib/path'); var utils = require('keystone-utils'); var di = require('asyncdi'); +var DEFAULT_OPTION_KEYS = [ + 'path', + 'paths', + 'type', + 'label', + 'note', + 'size', + 'initial', + 'required', + 'col', + 'noedit', + 'nocol', + 'nosort', + 'nofilter', + 'indent', + 'hidden', + 'collapse', + 'dependsOn' +]; + /** * Field Constructor * ================= @@ -16,7 +35,6 @@ var di = require('asyncdi'); * * @api public */ - function Field(list, path, options) { // Set field properties and options @@ -65,74 +83,44 @@ function Field(list, path, options) { /** * Gets the options for the Field, as used by the React components */ - Field.prototype.getOptions = function() { - if (!this.__options) { - this.__options = {}; - - var optionKeys = [ - 'path', - 'paths', - 'type', - 'label', - 'note', - 'size', - 'initial', - 'required', - 'col', - 'noedit', - 'nocol', - 'nosort', - 'nofilter', - 'indent', - 'hidden', - 'collapse', - 'dependsOn' - ]; - + var optionKeys = DEFAULT_OPTION_KEYS; if (_.isArray(this._properties)) { optionKeys = optionKeys.concat(this._properties); } - optionKeys.forEach(function(key) { if (this[key]) { this.__options[key] = this[key]; } - }.bind(this)); - + }, this); if (this.getProperties) { _.extend(this.__options, this.getProperties()); } - this.__options.defaultValue = this.getDefaultValue(); - } - return this.__options; - }; /** * Validates and returns the size of the field. * Defaults to deprecated 'width' option. */ - Field.prototype.getSize = function() { - if (this.__size) return this.__size; - var size = this._fixedSize || this.options.size || this.options.width; - if (size !== 'small' && size !== 'medium' && size !== 'large' && size !== 'full') { - size = this._defaultSize || 'large'; + if (!this.__size) { + var size = this._fixedSize || this.options.size || this.options.width; + if (size !== 'small' && size !== 'medium' && size !== 'large' && size !== 'full') { + size = this._defaultSize || 'large'; + } + this.__size = size; } - this.__size = size; - return size; + return this.__size; }; /** * Gets default value for the field, based on the option or default for the type */ - Field.prototype.getDefaultValue = function() { return this.options.default || ''; }; @@ -140,7 +128,6 @@ Field.prototype.getDefaultValue = function() { /** * Gets the field's data from an Item, as used by the React components */ - Field.prototype.getData = function(item) { return item.get(this.path); }; @@ -148,11 +135,9 @@ Field.prototype.getData = function(item) { /** * Field watching implementation */ - Field.prototype.getPreSaveWatcher = function() { - - var field = this, - applyValue; + var field = this; + var applyValue; if (this.options.watch === true) { // watch == true means always apply the value method @@ -211,12 +196,9 @@ Field.prototype.getPreSaveWatcher = function() { }; }; - exports = module.exports = Field; - /** Getter properties for the Field prototype */ - Object.defineProperty(Field.prototype, 'size', { get: function() { return this.getSize(); } }); Object.defineProperty(Field.prototype, 'initial', { get: function() { return this.options.initial || false; } }); Object.defineProperty(Field.prototype, 'required', { get: function() { return this.options.required || false; } }); @@ -230,32 +212,22 @@ Object.defineProperty(Field.prototype, 'collapse', { get: function() { return th Object.defineProperty(Field.prototype, 'hidden', { get: function() { return this.options.hidden || false; } }); Object.defineProperty(Field.prototype, 'dependsOn', { get: function() { return this.options.dependsOn || false; } }); - - /** * Default method to register the field on the List's Mongoose Schema. * Overridden by some fieldType Classes * * @api public */ - Field.prototype.addToSchema = function() { - var ops = (this._nativeType) ? _.defaults({ type: this._nativeType }, this.options) : this.options; - this.list.schema.path(this.path, ops); - this.bindUnderscoreMethods(); - }; Field.prototype.bindUnderscoreMethods = function(methods) { - var field = this; - // automatically bind underscore methods specified by the _underscoreMethods property // always include the 'update' method - (this._underscoreMethods || []).concat({ fn: 'updateItem', as: 'update' }, (methods || [])).forEach(function(method) { if ('string' === typeof method) { method = { fn: method, as: method }; @@ -268,55 +240,46 @@ Field.prototype.bindUnderscoreMethods = function(methods) { return field[method.fn].apply(field, args); }); }); - }; - /** * Adds a method to the underscoreMethods collection on the field's list, * with a path prefix to match this field's path and bound to the document * * @api public */ - Field.prototype.underscoreMethod = function(path, fn) { this.list.underscoreMethod(this.path + '.' + path, function() { return fn.apply(this, arguments); }); }; - /** * Default method to format the field value for display * Overridden by some fieldType Classes * * @api public */ - Field.prototype.format = function(item) { return item.get(this.path); }; - /** * Default method to detect whether the field has been modified in an item * Overridden by some fieldType Classes * * @api public */ - Field.prototype.isModified = function(item) { return item.isModified(this.path); }; - /** * Validates that a value for this field has been provided in a data object * Overridden by some fieldType Classes * * @api public */ - Field.prototype.validateInput = function(data, required, item) { if (!required) return true; var value = this.getValueFromData(data); @@ -328,23 +291,18 @@ Field.prototype.validateInput = function(data, required, item) { } }; - /** * Updates the value for this field in the item from a data object * Overridden by some fieldType Classes * * @api public */ - Field.prototype.updateItem = function(item, data) { - var value = this.getValueFromData(data); - // This is a deliberate type coercion so that numbers from forms play nice if (value !== undefined && value != item.get(this.path)) { // eslint-disable-line eqeqeq item.set(this.path, value); } - }; /** @@ -352,7 +310,6 @@ Field.prototype.updateItem = function(item, data) { * * @api public */ - Field.prototype.getValueFromData = function(data) { return this.path in data ? data[this.path] : this._path.get(data); }; diff --git a/fields/types/text/TextType.js b/fields/types/text/TextType.js index c38c38385e..7ab7c3123a 100644 --- a/fields/types/text/TextType.js +++ b/fields/types/text/TextType.js @@ -1,17 +1,15 @@ /*! * Module dependencies. */ - -var util = require('util'), - utils = require('keystone-utils'), - super_ = require('../Type'); +var util = require('util'); +var utils = require('keystone-utils'); +var super_ = require('../Type'); /** * Text FieldType Constructor * @extends Field * @api public */ - function text(list, path, options) { this._nativeType = String; this._underscoreMethods = ['crop']; @@ -21,23 +19,18 @@ function text(list, path, options) { /*! * Inherit from Field */ - util.inherits(text, super_); - /** * Crops the string to the specifed length. * * @api public */ - text.prototype.crop = function(item, length, append, preserveWords) { return utils.cropString(item.get(this.path), length, append, preserveWords); }; - /*! - * Export class + * Export Field */ - exports = module.exports = text; diff --git a/lib/list.js b/lib/list.js index 5881e8e7d4..e4f7979b5b 100644 --- a/lib/list.js +++ b/lib/list.js @@ -760,9 +760,6 @@ List.prototype.register = function() { return list; }); - - - if (!_.isEmpty(this.relationships)) { this.schema.methods.getRelated = schemaPlugins.methods.getRelated; this.schema.methods.populateRelated = schemaPlugins.methods.populateRelated; @@ -912,7 +909,7 @@ List.prototype.getSearchFilters = function(search, add) { if (add) { _.each(add, function(filter) { var cond, path = filter.key, value = filter.value; - + switch (filter.field.type) { case 'boolean': if (!value || value === 'false') { From 2398968cc3e7c365e519f0619d670e8d31b31243 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sun, 19 Jul 2015 00:51:06 +1000 Subject: [PATCH 22/86] New addFilterToQuery method for text fields --- fields/types/text/TextType.js | 36 ++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/fields/types/text/TextType.js b/fields/types/text/TextType.js index 7ab7c3123a..1076fc2fe3 100644 --- a/fields/types/text/TextType.js +++ b/fields/types/text/TextType.js @@ -1,9 +1,6 @@ -/*! - * Module dependencies. - */ var util = require('util'); var utils = require('keystone-utils'); -var super_ = require('../Type'); +var FieldType = require('../Type'); /** * Text FieldType Constructor @@ -15,22 +12,35 @@ function text(list, path, options) { this._underscoreMethods = ['crop']; text.super_.call(this, list, path, options); } - -/*! - * Inherit from Field - */ -util.inherits(text, super_); +util.inherits(text, FieldType); /** * Crops the string to the specifed length. - * - * @api public */ text.prototype.crop = function(item, length, append, preserveWords) { return utils.cropString(item.get(this.path), length, append, preserveWords); }; -/*! - * Export Field +/** + * Add filters to a query */ +text.prototype.addFilterToQuery = function(filter, query) { + query = query || {}; + if (filter.mode === 'match' && !filter.value) { + query[this.path] = filter.invert ? { $nin: ['', null] } : { $in: ['', null] }; + return; + } + var value = utils.escapeRegExp(filter.value); + if (filter.mode === 'startsWith') { + value = '^' + value; + } else if (filter.mode === 'endsWith') { + value = value + '$'; + } else if (filter.mode === 'match') { + value = '^' + value + '$'; + } + value = new RegExp(value, filter.caseSensitive ? '' : 'i'); + query[this.path] = filter.invert ? { $not: value } : value; +}; + +/* Export Field */ exports = module.exports = text; From f38d276c0de553eb41603c8aa3aa51fdce01cb50 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sun, 19 Jul 2015 01:00:40 +1000 Subject: [PATCH 23/86] Text-like fields inherit filtering from TextType --- fields/types/email/EmailType.js | 56 +++++---------------------- fields/types/html/HtmlType.js | 30 ++++---------- fields/types/key/KeyType.js | 50 ++++-------------------- fields/types/text/TextType.js | 4 +- fields/types/textarea/TextareaType.js | 43 +++++--------------- fields/types/url/UrlType.js | 31 ++++----------- 6 files changed, 42 insertions(+), 172 deletions(-) diff --git a/fields/types/email/EmailType.js b/fields/types/email/EmailType.js index 16f167b892..7aff6d9081 100644 --- a/fields/types/email/EmailType.js +++ b/fields/types/email/EmailType.js @@ -1,111 +1,73 @@ -/*! - * Module dependencies. - */ - -var util = require('util'), - utils = require('keystone-utils'), - super_ = require('../Type'), - crypto = require('crypto'); +var FieldType = require('../Type'); +var TextType = require('../text/TextType'); +var crypto = require('crypto'); +var util = require('util'); +var utils = require('keystone-utils'); /** * Email FieldType Constructor * @extends Field * @api public */ - function email(list, path, options) { - this._nativeType = String; this._underscoreMethods = ['gravatarUrl']; this._fixedSize = 'large'; - this.typeDescription = 'email address'; - email.super_.call(this, list, path, options); - } +util.inherits(email, FieldType); -/*! - * Inherit from Field - */ - -util.inherits(email, super_); - +/* Inherit from TextType prototype */ +email.prototype.addFilterToQuery = TextType.prototype.addFilterToQuery; /** * Validates that a valid email has been provided in a data object - * - * @api public */ - email.prototype.validateInput = function(data, required, item) { - var value = this.getValueFromData(data); - if (value) { return utils.isEmail(value); } else { return (!required || (value !== undefined && item && item.get(this.path))) ? true : false; } - }; - /** * Updates the value for this field in the item from a data object * Ensures that the email address is lowercase - * - * @api public */ - email.prototype.updateItem = function(item, data) { - var newValue = this.getValueFromData(data); - if ('string' === typeof newValue) { newValue = newValue.toLowerCase(); } - if (newValue !== undefined && newValue !== item.get(this.path)) { item.set(this.path, newValue); } - }; - /** * Generate a gravatar image request url - * - * @api public */ email.prototype.gravatarUrl = function(item, size, defaultImage, rating) { - var value = item.get(this.path); - if ('string' !== typeof value) { return ''; } - return [ // base url protocol-less for both http/https '//www.gravatar.com/avatar/', - // md5 hash the trimmed lowercase email crypto.createHash('md5').update(value.toLowerCase().trim()).digest('hex'), - // size of images ranging from 1 to 2048 pixels, square '?s=' + (/^(?:[1-9][0-9]{0,2}|1[0-9]{3}|20[0-3][0-9]|204[0-8])$/.test(size) ? size : 80), - // default image url encoded href or one of the built in options: 404, mm, identicon, monsterid, wavatar, retro, blank '&d=' + (defaultImage ? encodeURIComponent(defaultImage) : 'identicon'), - // rating, g, pg, r or x '&r=' + (/^(?:g|pg|r|x)$/i.test(rating) ? rating.toLowerCase() : 'g') ].join(''); }; -/*! - * Export class - */ - +/* Export Field Type */ exports = module.exports = email; diff --git a/fields/types/html/HtmlType.js b/fields/types/html/HtmlType.js index 2493b9f7e8..1e9cf8a39e 100644 --- a/fields/types/html/HtmlType.js +++ b/fields/types/html/HtmlType.js @@ -1,40 +1,24 @@ -/*! - * Module dependencies. - */ - -var util = require('util'), - super_ = require('../Type'); +var FieldType = require('../Type'); +var TextType = require('../text/TextType'); +var util = require('util'); /** * HTML FieldType Constructor * @extends Field * @api public */ - function html(list, path, options) { - this._nativeType = String; this._defaultSize = 'full'; - - // TODO: implement filtering, usage disabled for now - options.nofilter = true; this.wysiwyg = options.wysiwyg || false; this.height = options.height || 180; - this._properties = ['wysiwyg', 'height']; - html.super_.call(this, list, path, options); } +util.inherits(html, FieldType); -/*! - * Inherit from Field - */ - -util.inherits(html, super_); - - -/*! - * Export class - */ +/* Inherit from TextType prototype */ +html.prototype.addFilterToQuery = TextType.prototype.addFilterToQuery; +/* Export Field Type */ exports = module.exports = html; diff --git a/fields/types/key/KeyType.js b/fields/types/key/KeyType.js index 126430cbc5..97961f09f4 100644 --- a/fields/types/key/KeyType.js +++ b/fields/types/key/KeyType.js @@ -1,90 +1,56 @@ -/*! - * Module dependencies. - */ - -var util = require('util'), - utils = require('keystone-utils'), - super_ = require('../Type'); +var FieldType = require('../Type'); +var TextType = require('../text/TextType'); +var util = require('util'); +var utils = require('keystone-utils'); /** * Key FieldType Constructor * @extends Field * @api public */ - function key(list, path, options) { this._nativeType = String; this._defaultSize = 'medium'; - this.separator = options.separator || '-'; - key.super_.call(this, list, path, options); } +util.inherits(key, FieldType); -/*! - * Inherit from Field - */ - -util.inherits(key, super_); - +/* Inherit from TextType prototype */ +key.prototype.addFilterToQuery = TextType.prototype.addFilterToQuery; /** * Generates a valid key from a string - * - * @api public */ - key.prototype.generateKey = function(str) { return utils.slug(String(str), this.separator); }; - /** * Checks that a valid key has been provided in a data object - * - * @api public */ - key.prototype.validateInput = function(data, required, item) { - var value = this.getValueFromData(data); - if (value === undefined && item && item.get(this.path)) { return true; } - value = this.generateKey(value); - return (value || !required) ? true : false; - }; - /** * Updates the value for this field in the item from a data object - * - * @api public */ - key.prototype.updateItem = function(item, data) { - var value = this.getValueFromData(data); - if (value === undefined) { return; } - value = this.generateKey(value); - if (item.get(this.path) !== value) { item.set(this.path, value); } - }; - -/*! - * Export class - */ - +/* Export Field Type */ exports = module.exports = key; diff --git a/fields/types/text/TextType.js b/fields/types/text/TextType.js index 1076fc2fe3..f4a8cd4cc6 100644 --- a/fields/types/text/TextType.js +++ b/fields/types/text/TextType.js @@ -1,6 +1,6 @@ +var FieldType = require('../Type'); var util = require('util'); var utils = require('keystone-utils'); -var FieldType = require('../Type'); /** * Text FieldType Constructor @@ -42,5 +42,5 @@ text.prototype.addFilterToQuery = function(filter, query) { query[this.path] = filter.invert ? { $not: value } : value; }; -/* Export Field */ +/* Export Field Type */ exports = module.exports = text; diff --git a/fields/types/textarea/TextareaType.js b/fields/types/textarea/TextareaType.js index 917ef58638..ceae051688 100644 --- a/fields/types/textarea/TextareaType.js +++ b/fields/types/textarea/TextareaType.js @@ -1,58 +1,33 @@ -/*! - * Module dependencies. - */ - -var util = require('util'), - utils = require('keystone-utils'), - super_ = require('../Type'); +var FieldType = require('../Type'); +var TextType = require('../text/TextType'); +var util = require('util'); +var utils = require('keystone-utils'); /** * Text FieldType Constructor * @extends Field * @api public */ - function textarea(list, path, options) { this._nativeType = String; this._underscoreMethods = ['format', 'crop']; this.height = options.height || 90; - this._properties = ['height']; - textarea.super_.call(this, list, path, options); } +util.inherits(textarea, FieldType); -/*! - * Inherit from Field - */ - -util.inherits(textarea, super_); - +/* Inherit from TextType prototype */ +textarea.prototype.addFilterToQuery = TextType.prototype.addFilterToQuery; +textarea.prototype.crop = TextType.prototype.crop; /** * Formats the field value - * * @api public */ - textarea.prototype.format = function(item) { return utils.textToHTML(item.get(this.path)); }; - -/** - * Crops the string to the specifed length. - * - * @api public - */ - -textarea.prototype.crop = function(item, length, append, preserveWords) { - return utils.cropString(item.get(this.path), length, append, preserveWords); -}; - - -/*! - * Export class - */ - +/* Export Field Type */ exports = module.exports = textarea; diff --git a/fields/types/url/UrlType.js b/fields/types/url/UrlType.js index a3e063ad76..8a1a04972a 100644 --- a/fields/types/url/UrlType.js +++ b/fields/types/url/UrlType.js @@ -1,38 +1,27 @@ -/*! - * Module dependencies. - */ - -var util = require('util'), - super_ = require('../Type'); +var FieldType = require('../Type'); +var TextType = require('../text/TextType'); +var util = require('util'); /** * URL FieldType Constructor * @extends Field * @api public */ - function url(list, path, options) { this._nativeType = String; this._underscoreMethods = ['format']; this._formatUrl = options.format || removeProtocolPrefix; - url.super_.call(this, list, path, options); } +util.inherits(url, FieldType); -/*! - * Inherit from Field - */ - -util.inherits(url, super_); - +/* Inherit from TextType prototype */ +url.prototype.addFilterToQuery = TextType.prototype.addFilterToQuery; /** * Formats the field value using either a supplied format function or default * which strips the leading protocol from the value for simpler display - * - * @api public */ - url.prototype.format = function(item) { var url = (item.get(this.path) || ''); return this._formatUrl(url); @@ -40,8 +29,6 @@ url.prototype.format = function(item) { /** * Remove the protocol prefix from url - * - * @api private */ function removeProtocolPrefix(url) { return url.replace(/^[a-zA-Z]+\:\/\//, ''); @@ -49,9 +36,5 @@ function removeProtocolPrefix(url) { // TODO: Proper url validation - -/*! - * Export class - */ - +/* Export Field Type */ exports = module.exports = url; From 751c82955b481d85156470c317eb80c8c1e036ea Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sun, 19 Jul 2015 01:02:17 +1000 Subject: [PATCH 24/86] Exposing field.hasFilterMethod in Field options --- fields/types/Type.js | 1 + 1 file changed, 1 insertion(+) diff --git a/fields/types/Type.js b/fields/types/Type.js index e5301c8bef..6d4cbf0a93 100644 --- a/fields/types/Type.js +++ b/fields/types/Type.js @@ -98,6 +98,7 @@ Field.prototype.getOptions = function() { if (this.getProperties) { _.extend(this.__options, this.getProperties()); } + this.__options.hasFilterMethod = this.addFilterToQuery ? true : false; this.__options.defaultValue = this.getDefaultValue(); } return this.__options; From b51a757cb7af34208ded34d33498d852d27d6359 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sun, 19 Jul 2015 01:07:41 +1000 Subject: [PATCH 25/86] addFilterToQuery method for Boolean fields --- fields/types/boolean/BooleanType.js | 46 +++++++++-------------------- 1 file changed, 14 insertions(+), 32 deletions(-) diff --git a/fields/types/boolean/BooleanType.js b/fields/types/boolean/BooleanType.js index 0c8a6f3481..88633fcaca 100644 --- a/fields/types/boolean/BooleanType.js +++ b/fields/types/boolean/BooleanType.js @@ -1,42 +1,36 @@ -/*! - * Module dependencies. - */ - -var util = require('util'), - super_ = require('../Type'); +var util = require('util'); +var FieldType = require('../Type'); /** * Boolean FieldType Constructor * @extends Field * @api public */ - function boolean(list, path, options) { - this._nativeType = Boolean; this._properties = ['indent']; this._fixedSize = 'full'; this.indent = (options.indent) ? true : false; - boolean.super_.call(this, list, path, options); - } +util.inherits(boolean, FieldType); -/*! - * Inherit from Field +/** + * Add filters to a query */ - -util.inherits(boolean, super_); - +boolean.prototype.addFilterToQuery = function(filter, query) { + query = query || {}; + if (!filter.value || filter.value === 'false') { + query[this.path] = { $ne: true }; + } else { + query[this.path] = true; + } +}; /** * Validates that a truthy value for this field has been provided in a data object. - * * Useful for checkboxes that are required to be true (e.g. agreed to terms and cond's) - * - * @api public */ - boolean.prototype.validateInput = function(data, required) { if (required) { return (data[this.path] === true || data[this.path] === 'true') ? true : false; @@ -45,20 +39,13 @@ boolean.prototype.validateInput = function(data, required) { } }; - /** * Updates the value for this field in the item from a data object. * Only updates the value if it has changed. - * * Treats a falsy value or the string "false" as false, everything else as true. - * - * @api public */ - boolean.prototype.updateItem = function(item, data) { - var value = this.getValueFromData(data); - if (!value || value === 'false') { if (item.get(this.path) !== false) { item.set(this.path, false); @@ -66,12 +53,7 @@ boolean.prototype.updateItem = function(item, data) { } else if (!item.get(this.path)) { item.set(this.path, true); } - }; - -/*! - * Export class - */ - +/* Export Field Type */ exports = module.exports = boolean; From 35b58b2f2d4d53335389169dcc2a60bfdbafe1d7 Mon Sep 17 00:00:00 2001 From: Stefan Osorio Date: Sat, 18 Jul 2015 20:20:41 +0200 Subject: [PATCH 26/86] Use server api key instead of browser api key to enable geocoding. Add optional override. --- fields/types/location/LocationType.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fields/types/location/LocationType.js b/fields/types/location/LocationType.js index 41c83a858c..78ecdfdfc2 100644 --- a/fields/types/location/LocationType.js +++ b/fields/types/location/LocationType.js @@ -24,7 +24,7 @@ function location(list, path, options) { this._underscoreMethods = ['format', 'googleLookup', 'kmFrom', 'milesFrom']; this._fixedSize = 'full'; - this.enableMapsAPI = keystone.get('google api key') ? true : false; + this.enableMapsAPI = (options.geocodeGoogle===true || (options.geocodeGoogle !== false && keystone.get('google server api key'))) ? true : false; this._properties = ['enableMapsAPI']; From ed865028973ed6c2e0abc1a53014986276dad88a Mon Sep 17 00:00:00 2001 From: Stefan Osorio Date: Sat, 18 Jul 2015 21:39:00 +0200 Subject: [PATCH 27/86] Add Maps API Key to querystring if available --- fields/types/location/LocationType.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/fields/types/location/LocationType.js b/fields/types/location/LocationType.js index 78ecdfdfc2..114473e169 100644 --- a/fields/types/location/LocationType.js +++ b/fields/types/location/LocationType.js @@ -368,6 +368,10 @@ function doGoogleGeocodeRequest(address, region, callback) { options.region = region; } + if (keystone.get('google server api key')){ + options.key = keystone.get('google server api key'); + } + var endpoint = 'https://maps.googleapis.com/maps/api/geocode/json?' + querystring.stringify(options); https.get(endpoint, function(res) { From da0c4d512095199f17ad81be631a7ee012558019 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sun, 19 Jul 2015 23:01:15 +1000 Subject: [PATCH 28/86] Cleanup --- fields/types/Type.js | 2 +- fields/types/boolean/BooleanType.js | 2 +- fields/types/email/EmailType.js | 2 +- lib/list.js | 6 ++---- 4 files changed, 5 insertions(+), 7 deletions(-) diff --git a/fields/types/Type.js b/fields/types/Type.js index 6d4cbf0a93..1bf48a14d0 100644 --- a/fields/types/Type.js +++ b/fields/types/Type.js @@ -2,10 +2,10 @@ * Module dependencies. */ var _ = require('underscore'); +var di = require('asyncdi'); var marked = require('marked'); var Path = require('../../lib/path'); var utils = require('keystone-utils'); -var di = require('asyncdi'); var DEFAULT_OPTION_KEYS = [ 'path', diff --git a/fields/types/boolean/BooleanType.js b/fields/types/boolean/BooleanType.js index 88633fcaca..f6c8af466b 100644 --- a/fields/types/boolean/BooleanType.js +++ b/fields/types/boolean/BooleanType.js @@ -1,5 +1,5 @@ -var util = require('util'); var FieldType = require('../Type'); +var util = require('util'); /** * Boolean FieldType Constructor diff --git a/fields/types/email/EmailType.js b/fields/types/email/EmailType.js index 7aff6d9081..b41c48224d 100644 --- a/fields/types/email/EmailType.js +++ b/fields/types/email/EmailType.js @@ -1,6 +1,6 @@ +var crypto = require('crypto'); var FieldType = require('../Type'); var TextType = require('../text/TextType'); -var crypto = require('crypto'); var util = require('util'); var utils = require('keystone-utils'); diff --git a/lib/list.js b/lib/list.js index e4f7979b5b..0f104692c5 100644 --- a/lib/list.js +++ b/lib/list.js @@ -980,8 +980,7 @@ List.prototype.getSearchFilters = function(search, add) { else { filters[path] = null; } - } - else { + } else { value = utils.number(value); if ( !isNaN(value) ) { if (filter.operator === 'gt') { @@ -1013,8 +1012,7 @@ List.prototype.getSearchFilters = function(search, add) { $lte: moment(value[1]).endOf('day').toDate() }; } - } - else { + } else { value = moment(value); if (value && value.isValid()) { var start = moment(value).startOf('day').toDate(); From ec2e1f7dbde169102ff29aea94a7457d8c13e77d Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sun, 19 Jul 2015 23:43:01 +1000 Subject: [PATCH 29/86] New addFilterToQuery method for Date Type --- fields/types/date/DateType.js | 73 ++++++++++++++++------------------- 1 file changed, 34 insertions(+), 39 deletions(-) diff --git a/fields/types/date/DateType.js b/fields/types/date/DateType.js index a1c33f8712..c2d826c7c7 100644 --- a/fields/types/date/DateType.js +++ b/fields/types/date/DateType.js @@ -1,10 +1,6 @@ -/*! - * Module dependencies. - */ - -var util = require('util'); +var FieldType = require('../Type'); var moment = require('moment'); -var super_ = require('../Type'); +var util = require('util'); /** * Date FieldType Constructor @@ -13,37 +9,56 @@ var super_ = require('../Type'); */ function date(list, path, options) { - this._nativeType = Date; this._underscoreMethods = ['format', 'moment', 'parse']; this._fixedSize = 'large'; this._properties = ['formatString', 'yearRange', 'isUTC']; - this.parseFormatString = options.parseFormat || 'YYYY-MM-DD'; this.formatString = (options.format === false) ? false : (options.format || 'Do MMM YYYY'); this.yearRange = options.yearRange; this.isUTC = options.utc || false; - if (this.formatString && 'string' !== typeof this.formatString) { throw new Error('FieldType.Date: options.format must be a string.'); } - date.super_.call(this, list, path, options); } +util.inherits(date, FieldType); -/*! - * Inherit from Field +/** + * Add filters to a query */ - -util.inherits(date, super_); - +date.prototype.addFilterToQuery = function(filter, query) { + query = query || {}; + if (filter.mode === 'between') { + if (filter.after && filter.before) { + filter.after = moment(filter.after); + filter.before = moment(filter.before); + if (filter.after.isValid() && filter.before.isValid()) { + query[this.path] = { + $gte: filter.after.startOf('day').toDate(), + $lte: filter.before.endOf('day').toDate() + }; + } + } + } else if (filter.value) { + filter.value = moment(filter.value); + if (filter.value.isValid()) { + var after = filter.value.startOf('day').toDate(); + var before = filter.value.endOf('day').toDate(); + if (filter.mode === 'after') { + query[this.path] = { $gte: after }; + } else if (filter.mode === 'before') { + query[this.path] = { $lte: before }; + } else { + query[this.path] = { $gte: after, $lte: before }; + } + } + } +}; /** * Formats the field value - * - * @api public */ - date.prototype.format = function(item, format) { if (format || this.formatString) { return item.get(this.path) ? this.moment(item).format(format || this.formatString) : ''; @@ -52,26 +67,18 @@ date.prototype.format = function(item, format) { } }; - /** * Returns a new `moment` object with the field value - * - * @api public */ - date.prototype.moment = function(item) { var m = moment(item.get(this.path)); if (this.isUTC) m.utc(); return m; }; - /** * Parses input using moment, sets the value, and returns the moment object. - * - * @api public */ - date.prototype.parse = function(item) { var m = this.isUTC ? moment.utc : moment; var newValue = m.apply(m, Array.prototype.slice.call(arguments, 1)); @@ -81,12 +88,8 @@ date.prototype.parse = function(item) { /** * Checks that a valid date has been provided in a data object - * * An empty value clears the stored value and is considered valid - * - * @api public */ - date.prototype.validateInput = function(data, required, item) { if (!(this.path in data) && item && item.get(this.path)) return true; var newValue = moment(data[this.path], this.parseFormatString); @@ -99,13 +102,9 @@ date.prototype.validateInput = function(data, required, item) { } }; - /** * Updates the value for this field in the item from a data object - * - * @api public */ - date.prototype.updateItem = function(item, data) { if (!(this.path in data)) { return; @@ -121,9 +120,5 @@ date.prototype.updateItem = function(item, data) { } }; - -/*! - * Export class - */ - +/* Export Field Type */ exports = module.exports = date; From 079c16ab771dd55de2d940d0056a2c086d1c817e Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sun, 19 Jul 2015 23:43:18 +1000 Subject: [PATCH 30/86] Datetime Type inherits from Date Type --- fields/types/datetime/DatetimeType.js | 89 ++++----------------------- 1 file changed, 11 insertions(+), 78 deletions(-) diff --git a/fields/types/datetime/DatetimeType.js b/fields/types/datetime/DatetimeType.js index f8c03801f4..6cbf78cdcc 100644 --- a/fields/types/datetime/DatetimeType.js +++ b/fields/types/datetime/DatetimeType.js @@ -1,10 +1,7 @@ -/*! - * Module dependencies. - */ - -var util = require('util'); var moment = require('moment'); -var super_ = require('../Type'); +var DateType = require('../date/DateType'); +var FieldType = require('../Type'); +var util = require('util'); var parseFormats = ['YYYY-MM-DD', 'YYYY-MM-DD h:m:s a', 'YYYY-MM-DD h:m a', 'YYYY-MM-DD H:m:s', 'YYYY-MM-DD H:m']; @@ -13,86 +10,35 @@ var parseFormats = ['YYYY-MM-DD', 'YYYY-MM-DD h:m:s a', 'YYYY-MM-DD h:m a', 'YYY * @extends Field * @api public */ - function datetime(list, path, options) { - this._nativeType = Date; this._underscoreMethods = ['format', 'moment', 'parse']; this._fixedSize = 'large'; this._properties = ['formatString', 'isUTC']; - this.typeDescription = 'date and time'; this.parseFormatString = options.parseFormat || parseFormats; this.formatString = (options.format === false) ? false : (options.format || 'YYYY-MM-DD h:m:s a'); this.isUTC = options.utc || false; - if (this.formatString && 'string' !== typeof this.formatString) { throw new Error('FieldType.DateTime: options.format must be a string.'); } - - datetime.super_.call(this, list, path, options); - + datetime.super_.call(this, list, path, options) this.paths = { date: this._path.append('_date'), time: this._path.append('_time') }; - } +util.inherits(datetime, FieldType); -/*! - * Inherit from Field - */ - -util.inherits(datetime, super_); - - -/** - * Formats the field value - * - * @api public - */ -datetime.prototype.format = function(item, format) { - if (format || this.formatString) { - return item.get(this.path) ? this.moment(item).format(format || this.formatString) : ''; - } else { - return item.get(this.path) || ''; - } -}; - - -/** - * Returns a new `moment` object with the field value - * - * @api public - */ - -datetime.prototype.moment = function(item) { - var m = moment(item.get(this.path)); - if (this.isUTC) m.utc(); - return m; -}; - - -/** - * Parses input using moment, sets the value, and returns the moment object. - * - * @api public - */ - -datetime.prototype.parse = function(item) { - var m = this.isUTC ? moment.utc : moment; - var newValue = m.apply(m, Array.prototype.slice.call(arguments, 1)); - item.set(this.path, (newValue && newValue.isValid()) ? newValue.toDate() : null); - return newValue; -}; - +/* Inherit from DateType prototype */ +datetime.prototype.addFilterToQuery = DateType.prototype.addFilterToQuery; +datetime.prototype.format = DateType.prototype.format; +datetime.prototype.moment = DateType.prototype.moment; +datetime.prototype.parse = DateType.prototype.parse; /** * Get the value from a data object; may be simple or a pair of fields - * - * @api private */ - datetime.prototype.getInputFromData = function(data) { if (this.paths.date in data && this.paths.time in data) { return (data[this.paths.date] + ' ' + data[this.paths.time]).trim(); @@ -101,15 +47,10 @@ datetime.prototype.getInputFromData = function(data) { } }; - /** * Checks that a valid date has been provided in a data object - * * An empty value clears the stored value and is considered valid - * - * @api public */ - datetime.prototype.validateInput = function(data, required, item) { if (!(this.path in data && !(this.paths.date in data && this.paths.time in data)) && item && item.get(this.path)) return true; var newValue = moment(this.getInputFromData(data), parseFormats); @@ -122,13 +63,9 @@ datetime.prototype.validateInput = function(data, required, item) { } }; - /** * Updates the value for this field in the item from a data object - * - * @api public */ - datetime.prototype.updateItem = function(item, data) { if (!(this.path in data || (this.paths.date in data && this.paths.time in data))) { return; @@ -144,9 +81,5 @@ datetime.prototype.updateItem = function(item, data) { } }; - -/*! - * Export class - */ - +/* Export Field Type */ exports = module.exports = datetime; From 169cbffac6f64fa2042e95a065a6c1b1b9df676e Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Mon, 20 Jul 2015 13:42:18 +1000 Subject: [PATCH 31/86] Adding Numeric filter, ref #1539 --- fields/types/number/NumberType.js | 75 ++++++++++++++++--------------- 1 file changed, 38 insertions(+), 37 deletions(-) diff --git a/fields/types/number/NumberType.js b/fields/types/number/NumberType.js index c6f23916e8..d2ef3ce228 100644 --- a/fields/types/number/NumberType.js +++ b/fields/types/number/NumberType.js @@ -1,46 +1,64 @@ -/*! - * Module dependencies. - */ - -var util = require('util'), - numeral = require('numeral'), - utils = require('keystone-utils'), - super_ = require('../Type'); +var FieldType = require('../Type'); +var numeral = require('numeral'); +var util = require('util'); +var utils = require('keystone-utils'); /** * Number FieldType Constructor * @extends Field * @api public */ - function number(list, path, options) { - this._nativeType = Number; this._fixedSize = 'small'; this._underscoreMethods = ['format']; this._formatString = (options.format === false) ? false : (options.format || '0,0[.][000000000000]'); - if (this._formatString && 'string' !== typeof this._formatString) { throw new Error('FieldType.Number: options.format must be a string.'); } - number.super_.call(this, list, path, options); - } - -/*! - * Inherit from Field - */ - util.inherits(number, super_); +/** + * Add filters to a query + */ +number.prototype.addFilterToQuery = function(filter, query) { + query = query || {}; + if (filter.mode === 'equals' && !filter.value) { + query[this.path] = filter.invert ? { $nin: ['', 0, null] } : { $in: ['', 0, null] }; + return; + } + if (filter.mode === 'between') { + var min = utils.number(value.min); + var max = utils.number(value.max); + if (!isNaN(min) && !isNaN(max)) { + query[this.path] = { + $gte: min, + $lte: max + }; + } + return; + } + var value = utils.number(filter.value); + if (!isNaN(value)) { + if (filter.mode === 'gt') { + query[this.path] = { $gt: value }; + } + else if (filter.mode === 'lt') { + query[this.path] = { $lt: value }; + } + else { + query[this.path] = value; + } + } +}; /** * Formats the field value * * @api public */ - number.prototype.format = function(item, format) { if (format || this._formatString) { return ('number' === typeof item.get(this.path)) ? numeral(item.get(this.path)).format(format || this._formatString) : ''; @@ -49,7 +67,6 @@ number.prototype.format = function(item, format) { } }; - /** * Checks that a valid number has been provided in a data object * @@ -57,42 +74,31 @@ number.prototype.format = function(item, format) { * * @api public */ - number.prototype.validateInput = function(data, required, item) { - var value = this.getValueFromData(data); - if ((value === undefined || value === '') && item && (item.get(this.path) || item.get(this.path) === 0)) { return true; } - if (value === undefined || value === '') { return (required) ? false : true; } else { var newValue = utils.number(value); return (!isNaN(newValue)); } - }; - /** * Updates the value for this field in the item from a data object * * @api public */ - number.prototype.updateItem = function(item, data) { - var value = this.getValueFromData(data); - if ((value === undefined || value === '') && 'number' === typeof item.get(this.path)) { item.set(this.path, null); return; } - var newValue = utils.number(value); - if (!isNaN(newValue)) { if (newValue !== item.get(this.path)) { item.set(this.path, newValue); @@ -100,12 +106,7 @@ number.prototype.updateItem = function(item, data) { } else if ('number' === typeof item.get(this.path)) { item.set(this.path, null); } - }; - -/*! - * Export class - */ - +/* Export Field Type */ exports = module.exports = number; From a89741c6c6c18010d1ca9830eb5b0d1e34d8498e Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Mon, 20 Jul 2015 13:49:01 +1000 Subject: [PATCH 32/86] NumberType should not null values when updateItem value is undefined Matches the base implementation in fields/Type.js --- fields/types/number/NumberType.js | 32 ++++++++++++------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/fields/types/number/NumberType.js b/fields/types/number/NumberType.js index d2ef3ce228..4e7bf41522 100644 --- a/fields/types/number/NumberType.js +++ b/fields/types/number/NumberType.js @@ -56,8 +56,6 @@ number.prototype.addFilterToQuery = function(filter, query) { /** * Formats the field value - * - * @api public */ number.prototype.format = function(item, format) { if (format || this._formatString) { @@ -69,10 +67,7 @@ number.prototype.format = function(item, format) { /** * Checks that a valid number has been provided in a data object - * * An empty value clears the stored value and is considered valid - * - * @api public */ number.prototype.validateInput = function(data, required, item) { var value = this.getValueFromData(data); @@ -89,23 +84,20 @@ number.prototype.validateInput = function(data, required, item) { /** * Updates the value for this field in the item from a data object - * - * @api public */ number.prototype.updateItem = function(item, data) { - var value = this.getValueFromData(data); - if ((value === undefined || value === '') && 'number' === typeof item.get(this.path)) { - item.set(this.path, null); - return; - } - var newValue = utils.number(value); - if (!isNaN(newValue)) { - if (newValue !== item.get(this.path)) { - item.set(this.path, newValue); - } - } else if ('number' === typeof item.get(this.path)) { - item.set(this.path, null); - } + var value = this.getValueFromData(data); + if (value === undefined) { + return; + } + var newValue = utils.number(value); + if (!isNaN(newValue)) { + if (newValue !== item.get(this.path)) { + item.set(this.path, newValue); + } + } else if ('number' === typeof item.get(this.path)) { + item.set(this.path, null); + } }; /* Export Field Type */ From e8e5df751e92f4e56f089ec3d43aa6c2c99b492c Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Mon, 20 Jul 2015 13:50:36 +1000 Subject: [PATCH 33/86] Fixing reference to FieldType --- fields/types/number/NumberType.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fields/types/number/NumberType.js b/fields/types/number/NumberType.js index 4e7bf41522..5bfcd9e306 100644 --- a/fields/types/number/NumberType.js +++ b/fields/types/number/NumberType.js @@ -18,7 +18,7 @@ function number(list, path, options) { } number.super_.call(this, list, path, options); } -util.inherits(number, super_); +util.inherits(number, FieldType); /** * Add filters to a query From 61e8204863bec75b7a5fdf0a56cc69377f945bd8 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Mon, 20 Jul 2015 13:51:49 +1000 Subject: [PATCH 34/86] Tests were incorrect; fixing to match the correct implementation --- fields/types/number/test/server.js | 35 +++++++++++++++++++----------- 1 file changed, 22 insertions(+), 13 deletions(-) diff --git a/fields/types/number/test/server.js b/fields/types/number/test/server.js index 2bf95f0ddc..00ba08448d 100644 --- a/fields/types/number/test/server.js +++ b/fields/types/number/test/server.js @@ -12,7 +12,7 @@ exports.initList = function(List) { exports.testFieldType = function(List) { var testItem = new List.model(); - + it('should validate numeric input', function() { demand(List.fields.number.validateInput({ number: 0 @@ -27,7 +27,7 @@ exports.testFieldType = function(List) { number: 1.1 })).be(true); }); - + it('should validate string input', function() { demand(List.fields.number.validateInput({ number: '0' @@ -42,7 +42,7 @@ exports.testFieldType = function(List) { number: '1.1' })).be(true); }); - + it('should validate no input', function() { demand(List.fields.number.validateInput({})).be(true); demand(List.fields.number.validateInput({}, true)).be(false); @@ -50,7 +50,7 @@ exports.testFieldType = function(List) { demand(List.fields.number.validateInput({}, true, testItem)).be(true); testItem.number = undefined; }); - + it('should validate empty strings', function() { demand(List.fields.number.validateInput({ number: '' @@ -64,7 +64,7 @@ exports.testFieldType = function(List) { }, true, testItem)).be(true); testItem.number = undefined; }); - + it('should invalidate invalid input', function() { demand(List.fields.number.validateInput({ number: {} @@ -76,7 +76,7 @@ exports.testFieldType = function(List) { number: 'a' })).be(false); }); - + it('should update top level fields', function() { List.fields.number.updateItem(testItem, { number: 42 @@ -84,7 +84,7 @@ exports.testFieldType = function(List) { demand(testItem.number).be(42); testItem.number = undefined; }); - + it('should update nested fields', function() { List.fields['nested.number'].updateItem(testItem, { nested: { @@ -94,7 +94,7 @@ exports.testFieldType = function(List) { demand(testItem.nested.number).be(42); testItem.nested.number = undefined; }); - + it('should update nested fields with flat paths', function() { List.fields['nested.number'].updateItem(testItem, { 'nested.number': 42 @@ -102,7 +102,7 @@ exports.testFieldType = function(List) { demand(testItem.nested.number).be(42); testItem.nested.number = undefined; }); - + it('should null value with empty string', function() { testItem.number = 1; List.fields.number.updateItem(testItem, { @@ -111,16 +111,25 @@ exports.testFieldType = function(List) { demand(testItem.number).be(null); testItem.number = undefined; }); - - it('should null value when undefined', function() { + + it('should not null value when null', function() { testItem.number = 1; List.fields.number.updateItem(testItem, { - number: undefined + number: null }); demand(testItem.number).be(null); testItem.number = undefined; }); - + + it('should not null value when undefined', function() { + testItem.number = 1; + List.fields.number.updateItem(testItem, { + number: undefined + }); + demand(testItem.number).be(1); + testItem.number = undefined; + }); + it('should convert string values', function() { testItem.number = 1; List.fields.number.updateItem(testItem, { From 64edea6d7d4efbb8856ef43d25d6935d0afee461 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Mon, 20 Jul 2015 14:14:28 +1000 Subject: [PATCH 35/86] Fixing another Number type issue: blank strings should not be valid when required. --- fields/types/number/NumberType.js | 8 ++++---- fields/types/number/test/server.js | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/fields/types/number/NumberType.js b/fields/types/number/NumberType.js index 5bfcd9e306..8ef71a4e54 100644 --- a/fields/types/number/NumberType.js +++ b/fields/types/number/NumberType.js @@ -71,14 +71,14 @@ number.prototype.format = function(item, format) { */ number.prototype.validateInput = function(data, required, item) { var value = this.getValueFromData(data); - if ((value === undefined || value === '') && item && (item.get(this.path) || item.get(this.path) === 0)) { + if (value === undefined && item && (item.get(this.path) || item.get(this.path) === 0)) { return true; } - if (value === undefined || value === '') { - return (required) ? false : true; - } else { + if (value !== undefined && value !== '') { var newValue = utils.number(value); return (!isNaN(newValue)); + } else { + return (required) ? false : true; } }; diff --git a/fields/types/number/test/server.js b/fields/types/number/test/server.js index 00ba08448d..fe57634aed 100644 --- a/fields/types/number/test/server.js +++ b/fields/types/number/test/server.js @@ -61,7 +61,7 @@ exports.testFieldType = function(List) { testItem.number = 1; demand(List.fields.number.validateInput({ number: '' - }, true, testItem)).be(true); + }, true, testItem)).be(false); testItem.number = undefined; }); From a7dc09ea2ca01ce6282f446bfce518f272653d98 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Mon, 20 Jul 2015 14:14:55 +1000 Subject: [PATCH 36/86] MoneyType inherits from NumberType, ref #1539 --- fields/types/money/MoneyType.js | 91 ++++----------------------------- 1 file changed, 10 insertions(+), 81 deletions(-) diff --git a/fields/types/money/MoneyType.js b/fields/types/money/MoneyType.js index 81b02a164a..0bee5e0336 100644 --- a/fields/types/money/MoneyType.js +++ b/fields/types/money/MoneyType.js @@ -1,49 +1,35 @@ -/*! - * Module dependencies. - */ - -var util = require('util'), - numeral = require('numeral'), - utils = require('keystone-utils'), - super_ = require('../Type'); +var FieldType = require('../Type'); +var NumberType = require('../number/NumberType'); +var numeral = require('numeral'); +var util = require('util'); +var utils = require('keystone-utils'); /** * Money FieldType Constructor * @extends Field * @api public */ - function money(list, path, options) { - this.currency = options.currency; - this._nativeType = Number; this._underscoreMethods = ['format']; this._properties = ['currency']; this._fixedSize = 'small'; this._formatString = (options.format === false) ? false : (options.format || '$0,0.00'); - if (this._formatString && 'string' !== typeof this._formatString) { throw new Error('FieldType.Money: options.format must be a string.'); } - money.super_.call(this, list, path, options); - } +util.inherits(money, FieldType); -/*! - * Inherit from Field - */ - -util.inherits(money, super_); - +/* Inherit from NumberType prototype */ +money.prototype.updateItem = NumberType.prototype.updateItem; +money.prototype.validateInput = NumberType.prototype.validateInput; /** * Formats the field value - * - * @api public */ - money.prototype.format = function(item, format) { if (this.currency) { try { @@ -60,62 +46,5 @@ money.prototype.format = function(item, format) { } }; - -/** - * Checks that a valid number has been provided in a data object - * - * An empty value clears the stored value and is considered valid - * - * @api public - */ - -money.prototype.validateInput = function(data, required, item) { - - var value = this.getValueFromData(data); - - if (value === undefined && item && (item.get(this.path) || item.get(this.path) === 0)) { - return true; - } - - if (value !== undefined && value !== '') { - var newValue = utils.number(value); - return (!isNaN(newValue)); - } else { - return (required) ? false : true; - } - -}; - - -/** - * Updates the value for this field in the item from a data object - * - * @api public - */ - -money.prototype.updateItem = function(item, data) { - - var value = this.getValueFromData(data); - - if (value === undefined) { - return; - } - - var newValue = utils.number(value); - - if (!isNaN(newValue)) { - if (newValue !== item.get(this.path)) { - item.set(this.path, newValue); - } - } else if ('number' === typeof item.get(this.path)) { - item.set(this.path, null); - } - -}; - - -/*! - * Export class - */ - +/* Export Field Type */ exports = module.exports = money; From ca6b931328ab2b416c9c65d20c76893476681230 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Mon, 20 Jul 2015 14:17:26 +1000 Subject: [PATCH 37/86] Fixing method ordering in Field Types --- fields/types/email/EmailType.js | 44 ++++++++++++++++----------------- fields/types/text/TextType.js | 14 +++++------ 2 files changed, 29 insertions(+), 29 deletions(-) diff --git a/fields/types/email/EmailType.js b/fields/types/email/EmailType.js index b41c48224d..675209140b 100644 --- a/fields/types/email/EmailType.js +++ b/fields/types/email/EmailType.js @@ -21,6 +21,28 @@ util.inherits(email, FieldType); /* Inherit from TextType prototype */ email.prototype.addFilterToQuery = TextType.prototype.addFilterToQuery; +/** + * Generate a gravatar image request url + */ +email.prototype.gravatarUrl = function(item, size, defaultImage, rating) { + var value = item.get(this.path); + if ('string' !== typeof value) { + return ''; + } + return [ + // base url protocol-less for both http/https + '//www.gravatar.com/avatar/', + // md5 hash the trimmed lowercase email + crypto.createHash('md5').update(value.toLowerCase().trim()).digest('hex'), + // size of images ranging from 1 to 2048 pixels, square + '?s=' + (/^(?:[1-9][0-9]{0,2}|1[0-9]{3}|20[0-3][0-9]|204[0-8])$/.test(size) ? size : 80), + // default image url encoded href or one of the built in options: 404, mm, identicon, monsterid, wavatar, retro, blank + '&d=' + (defaultImage ? encodeURIComponent(defaultImage) : 'identicon'), + // rating, g, pg, r or x + '&r=' + (/^(?:g|pg|r|x)$/i.test(rating) ? rating.toLowerCase() : 'g') + ].join(''); +}; + /** * Validates that a valid email has been provided in a data object */ @@ -47,27 +69,5 @@ email.prototype.updateItem = function(item, data) { } }; -/** - * Generate a gravatar image request url - */ -email.prototype.gravatarUrl = function(item, size, defaultImage, rating) { - var value = item.get(this.path); - if ('string' !== typeof value) { - return ''; - } - return [ - // base url protocol-less for both http/https - '//www.gravatar.com/avatar/', - // md5 hash the trimmed lowercase email - crypto.createHash('md5').update(value.toLowerCase().trim()).digest('hex'), - // size of images ranging from 1 to 2048 pixels, square - '?s=' + (/^(?:[1-9][0-9]{0,2}|1[0-9]{3}|20[0-3][0-9]|204[0-8])$/.test(size) ? size : 80), - // default image url encoded href or one of the built in options: 404, mm, identicon, monsterid, wavatar, retro, blank - '&d=' + (defaultImage ? encodeURIComponent(defaultImage) : 'identicon'), - // rating, g, pg, r or x - '&r=' + (/^(?:g|pg|r|x)$/i.test(rating) ? rating.toLowerCase() : 'g') - ].join(''); -}; - /* Export Field Type */ exports = module.exports = email; diff --git a/fields/types/text/TextType.js b/fields/types/text/TextType.js index f4a8cd4cc6..8c9ebb78bb 100644 --- a/fields/types/text/TextType.js +++ b/fields/types/text/TextType.js @@ -14,13 +14,6 @@ function text(list, path, options) { } util.inherits(text, FieldType); -/** - * Crops the string to the specifed length. - */ -text.prototype.crop = function(item, length, append, preserveWords) { - return utils.cropString(item.get(this.path), length, append, preserveWords); -}; - /** * Add filters to a query */ @@ -42,5 +35,12 @@ text.prototype.addFilterToQuery = function(filter, query) { query[this.path] = filter.invert ? { $not: value } : value; }; +/** + * Crops the string to the specifed length. + */ +text.prototype.crop = function(item, length, append, preserveWords) { + return utils.cropString(item.get(this.path), length, append, preserveWords); +}; + /* Export Field Type */ exports = module.exports = text; From c45b5ee3ed589612876c6d7637ea863536fa2724 Mon Sep 17 00:00:00 2001 From: Albert Baldassarre Date: Mon, 20 Jul 2015 15:14:52 -0400 Subject: [PATCH 38/86] Escape special characters in email before creating a RegExp for case-insensitive lookup --- lib/session.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/session.js b/lib/session.js index 58ece08c77..fb8d7ed58d 100644 --- a/lib/session.js +++ b/lib/session.js @@ -85,8 +85,12 @@ var doSignin = function(lookup, req, res, onSuccess, onFail) { } var User = keystone.list(keystone.get('user model')); if ('string' === typeof lookup.email && 'string' === typeof lookup.password) { + + // create regex for email lookup with special characters escaped + var emailRegExp = new RegExp(lookup.email.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'), 'i'); + // match email address and password - User.model.findOne({ email: new RegExp(lookup.email, 'i') }).exec(function(err, user) { + User.model.findOne({ email: emailRegExp }).exec(function(err, user) { if (user) { user._.password.compare(lookup.password, function(err, isMatch) { if (!err && isMatch) { From 87e534a221051ec5b67e97826da77ca2bfed5e12 Mon Sep 17 00:00:00 2001 From: Albert Baldassarre Date: Mon, 20 Jul 2015 17:30:25 -0400 Subject: [PATCH 39/86] Add anchors to regex used for email lookup --- lib/session.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/session.js b/lib/session.js index fb8d7ed58d..b71b7c48b3 100644 --- a/lib/session.js +++ b/lib/session.js @@ -85,9 +85,8 @@ var doSignin = function(lookup, req, res, onSuccess, onFail) { } var User = keystone.list(keystone.get('user model')); if ('string' === typeof lookup.email && 'string' === typeof lookup.password) { - // create regex for email lookup with special characters escaped - var emailRegExp = new RegExp(lookup.email.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&'), 'i'); + var emailRegExp = new RegExp('^' + lookup.email.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&') + '$', 'i'); // match email address and password User.model.findOne({ email: emailRegExp }).exec(function(err, user) { From 484c603dc2afd12cc8029e5708b416ac42250786 Mon Sep 17 00:00:00 2001 From: Albert Baldassarre Date: Mon, 20 Jul 2015 22:49:51 -0400 Subject: [PATCH 40/86] Update to use escapeRegExp --- lib/session.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/session.js b/lib/session.js index b71b7c48b3..9e002e1401 100644 --- a/lib/session.js +++ b/lib/session.js @@ -1,6 +1,7 @@ var crypto = require('crypto'); var keystone = require('../'); var scmp = require('scmp'); +var utils = require('keystone-utils'); /** * Creates a hash of str with Keystone's cookie secret. @@ -86,7 +87,7 @@ var doSignin = function(lookup, req, res, onSuccess, onFail) { var User = keystone.list(keystone.get('user model')); if ('string' === typeof lookup.email && 'string' === typeof lookup.password) { // create regex for email lookup with special characters escaped - var emailRegExp = new RegExp('^' + lookup.email.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&') + '$', 'i'); + var emailRegExp = new RegExp('^' + utils.escapeRegExp(lookup.email) + '$', 'i'); // match email address and password User.model.findOne({ email: emailRegExp }).exec(function(err, user) { From 7edf6cdb45dedae81bf210da26422be49e331ac7 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Tue, 21 Jul 2015 19:02:54 +1000 Subject: [PATCH 41/86] Cleaning up Select field type --- fields/types/select/SelectType.js | 69 ++++--------------------------- 1 file changed, 8 insertions(+), 61 deletions(-) diff --git a/fields/types/select/SelectType.js b/fields/types/select/SelectType.js index af97fe3057..5dfb4ebccd 100644 --- a/fields/types/select/SelectType.js +++ b/fields/types/select/SelectType.js @@ -1,35 +1,25 @@ -/*! - * Module dependencies. - */ - -var _ = require('underscore'), - util = require('util'), - utils = require('keystone-utils'), - super_ = require('../Type'); +var _ = require('underscore'); +var FieldType = require('../Type'); +var util = require('util'); +var utils = require('keystone-utils'); /** * Select FieldType Constructor * @extends Field * @api public */ - function select(list, path, options) { - this.ui = options.ui || 'select'; this.numeric = options.numeric ? true : false; - this._nativeType = (options.numeric) ? Number : String; this._underscoreMethods = ['format']; this._properties = ['ops', 'numeric']; - if (typeof options.options === 'string') { options.options = options.options.split(','); } - if (!Array.isArray(options.options)) { throw new Error('Select fields require an options array.'); } - this.ops = options.options.map(function(i) { var op = _.isString(i) ? { value: i.trim(), label: utils.keyToLabel(i) } : i; if (!_.isObject(op)) { @@ -40,28 +30,19 @@ function select(list, path, options) { } return op; }); - // undefined options.emptyOption defaults to true if (options.emptyOption === undefined) { options.emptyOption = true; } - // ensure this.emptyOption is a boolean this.emptyOption = options.emptyOption ? true : false; - // cached maps for options, labels and values this.map = utils.optionsMap(this.ops); this.labels = utils.optionsMap(this.ops, 'label'); this.values = _.pluck(this.ops, 'value'); - select.super_.call(this, list, path, options); } - -/*! - * Inherit from Field - */ - -util.inherits(select, super_); +util.inherits(select, FieldType); /** * Registers the field on the List's Mongoose Schema. @@ -69,22 +50,16 @@ util.inherits(select, super_); * Adds a virtual for accessing the label of the selected value, * and statics to the Schema for converting a value to a label, * and retrieving all of the defined options. - * - * @api public */ - select.prototype.addToSchema = function() { - - var field = this, - schema = this.list.schema; - + var field = this; + var schema = this.list.schema; this.paths = { data: this.options.dataPath || this._path.append('Data'), label: this.options.labelPath || this._path.append('Label'), options: this.options.optionsPath || this._path.append('Options'), map: this.options.optionsMapPath || this._path.append('OptionsMap') }; - schema.path(this.path, _.defaults({ type: this._nativeType, enum: this.values, @@ -92,84 +67,56 @@ select.prototype.addToSchema = function() { return (val === '' || val === null || val === false) ? undefined : val; } }, this.options)); - schema.virtual(this.paths.data).get(function () { return field.map[this.get(field.path)]; }); - schema.virtual(this.paths.label).get(function () { return field.labels[this.get(field.path)]; }); - schema.virtual(this.paths.options).get(function() { return field.ops; }); - schema.virtual(this.paths.map).get(function() { return field.map; }); - this.underscoreMethod('pluck', function(property, d) { var option = this.get(field.paths.data); return (option) ? option[property] : d; }); - this.bindUnderscoreMethods(); - }; /** * Retrieves a shallow clone of the options array - * - * @api public */ - select.prototype.cloneOps = function() { return _.map(this.ops, _.clone); }; - /** * Retrieves a shallow clone of the options map - * - * @api public */ - select.prototype.cloneMap = function() { return utils.optionsMap(this.ops, true); }; - /** * Validates that a valid option has been provided in a data object - * - * @api public */ - select.prototype.validateInput = function(data, required, item) { - if (data[this.path]) { return (data[this.path] in this.map) ? true : false; } else { return (!required || (!(this.path in data) && item && item.get(this.path))) ? true : false; } - }; - /** * Formats the field value - * - * @api public */ - select.prototype.format = function(item) { return this.labels[item.get(this.path)]; }; - -/*! - * Export class - */ - +/* Export Field Type */ exports = module.exports = select; From e8355f21aaf603e891eed59b522db4fdb20c356f Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Tue, 21 Jul 2015 19:04:08 +1000 Subject: [PATCH 42/86] Adding select.prototype.addFilterToQuery --- fields/types/select/SelectType.js | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/fields/types/select/SelectType.js b/fields/types/select/SelectType.js index 5dfb4ebccd..f344df9d32 100644 --- a/fields/types/select/SelectType.js +++ b/fields/types/select/SelectType.js @@ -100,6 +100,18 @@ select.prototype.cloneMap = function() { return utils.optionsMap(this.ops, true); }; +/** + * Add filters to a query + */ +select.prototype.addFilterToQuery = function(filter, query) { + query = query || {}; + if (filter.value) { + query[this.path] = (filter.invert) ? { $ne: value } : value; + } else { + query[this.path] = (filter.inverse) ? { $nin: ['', null] } : { $in: ['', null] }; + } +}; + /** * Validates that a valid option has been provided in a data object */ From cee1ea2b4ab104cba78fa10ffcdac3e1edc821ca Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Tue, 21 Jul 2015 23:32:53 +1000 Subject: [PATCH 43/86] Cleaning up Relationship field type --- fields/types/relationship/RelationshipType.js | 103 +++--------------- lib/list.js | 3 - 2 files changed, 17 insertions(+), 89 deletions(-) diff --git a/fields/types/relationship/RelationshipType.js b/fields/types/relationship/RelationshipType.js index 751c3d2d42..f847d9270e 100644 --- a/fields/types/relationship/RelationshipType.js +++ b/fields/types/relationship/RelationshipType.js @@ -1,43 +1,28 @@ -/*! - * Module dependencies. - */ - -var _ = require('underscore'), - keystone = require('../../../'), - util = require('util'), - utils = require('keystone-utils'), - super_ = require('../Type'); +var _ = require('underscore'); +var FieldType = require('../Type'); +var keystone = require('../../../'); +var util = require('util'); +var utils = require('keystone-utils'); /** * Relationship FieldType Constructor * @extends Field * @api public */ - function relationship(list, path, options) { - this.many = (options.many) ? true : false; this.filters = options.filters; - this._defaultSize = this.many ? 'full' : 'large'; this._nativeType = keystone.mongoose.Schema.Types.ObjectId; this._underscoreMethods = ['format']; this._properties = ['isValid', 'many', 'filters']; - relationship.super_.call(this, list, path, options); - } - -/*! - * Inherit from Field - */ - -util.inherits(relationship, super_); +util.inherits(relationship, FieldType); /** * Get client-side properties to pass to react field. */ - relationship.prototype.getProperties = function () { var refList = this.refList; return { @@ -51,19 +36,10 @@ relationship.prototype.getProperties = function () { /** * Registers the field on the List's Mongoose Schema. - * - * @api public */ - relationship.prototype.addToSchema = function() { - - var field = this, - schema = this.list.schema; - - this.paths = { - refList: this.options.refListPath || this._path.append('RefList') - }; - + var field = this; + var schema = this.list.schema; var def = { type: this._nativeType, ref: this.options.ref, @@ -71,13 +47,13 @@ relationship.prototype.addToSchema = function() { required: (this.options.required ? true : false), unique: (this.options.unique ? true : false) }; - + this.paths = { + refList: this.options.refListPath || this._path.append('RefList') + }; schema.path(this.path, this.many ? [def] : def); - schema.virtual(this.paths.refList).get(function () { return keystone.list(field.options.ref); }); - if (this.many) { this.underscoreMethod('contains', function(find) { var value = this.populated(field.path) || this.get(field.path); @@ -90,78 +66,55 @@ relationship.prototype.addToSchema = function() { return result; }); } - this.bindUnderscoreMethods(); - }; /** * Formats the field value - * - * @api public */ relationship.prototype.format = function(item) { var value = item.get(this.path); - // force the formatted value to be a - unexpected things happen with ObjectIds. + // force the formatted value to be a string - unexpected things happen with ObjectIds. return this.many ? value.join(', ') : (value || '') + ''; }; - /** * Validates that a value for this field has been provided in a data object - * - * @api public */ - relationship.prototype.validateInput = function(data, required, item) { - if (!required) return true; if (!(this.path in data) && item && ((this.many && item.get(this.path).length) || item.get(this.path))) return true; - if ('string' === typeof data[this.path]) { return (data[this.path].trim()) ? true : false; } else { return (data[this.path]) ? true : false; } - }; - /** * Updates the value for this field in the item from a data object. * Only updates the value if it has changed. * Treats an empty string as a null value. - * - * @api public */ - relationship.prototype.updateItem = function(item, data) { - if (!(this.path in data)) { return; } - if (item.populated(this.path)) { throw new Error('fieldTypes.relationship.updateItem() Error - You cannot update populated relationships.'); } - if (this.many) { - - var arr = item.get(this.path), - _old = arr.map(function(i) { return String(i); }), - _new = data[this.path]; - + var arr = item.get(this.path); + var _old = arr.map(function(i) { return String(i); }); + var _new = data[this.path]; if (!utils.isArray(_new)) { _new = String(_new || '').split(','); } - _new = _.compact(_new); - // Only update if the lists aren't the same if (!_.isEqual(_old, _new)) { item.set(this.path, _new); } - } else { if (data[this.path]) { if (data[this.path] !== item.get(this.path)) { @@ -171,57 +124,40 @@ relationship.prototype.updateItem = function(item, data) { item.set(this.path, null); } } - }; - /** * Returns true if the relationship configuration is valid - * - * @api public */ - Object.defineProperty(relationship.prototype, 'isValid', { get: function() { return keystone.list(this.options.ref) ? true : false; } }); - /** * Returns the Related List - * - * @api public */ - Object.defineProperty(relationship.prototype, 'refList', { get: function() { return keystone.list(this.options.ref); } }); - /** * Whether the field has any filters defined - * - * @api public */ - Object.defineProperty(relationship.prototype, 'hasFilters', { get: function() { return (this.filters && _.keys(this.filters).length); } }); - /** * Adds relationship filters to a query - * - * @api public */ - +// TODO: Deprecate this? Not sure it's used anywhere - JW relationship.prototype.addFilters = function(query, item) { - _.each(this.filters, function(filters, path) { if (!utils.isObject(filters)) { filters = { equals: filters }; @@ -237,12 +173,7 @@ relationship.prototype.addFilters = function(query, item) { query[method](value); }); }); - }; - -/*! - * Export class - */ - +/* Export Field Type */ exports = module.exports = relationship; diff --git a/lib/list.js b/lib/list.js index 0f104692c5..4eca59682d 100644 --- a/lib/list.js +++ b/lib/list.js @@ -951,9 +951,6 @@ List.prototype.getSearchFilters = function(search, add) { filters[path] = (filter.inverse) ? { $ne: null } : null; } } - // TODO: Searching on "not linked to" (null) values seems to return all results. - // console.log(filter.field.path + ':'); - // console.log(filters[filter.field.path]); break; case 'select': From 0f03b34521003289a274a7b7a9ab606e8ddfbdfb Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Tue, 21 Jul 2015 23:33:06 +1000 Subject: [PATCH 44/86] Adding relationship.prototype.addFilterToQuery --- fields/types/relationship/RelationshipType.js | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/fields/types/relationship/RelationshipType.js b/fields/types/relationship/RelationshipType.js index f847d9270e..db13cde77c 100644 --- a/fields/types/relationship/RelationshipType.js +++ b/fields/types/relationship/RelationshipType.js @@ -69,6 +69,26 @@ relationship.prototype.addToSchema = function() { this.bindUnderscoreMethods(); }; +/** + * Add filters to a query + */ +relationship.prototype.addFilterToQuery = function(filter, query) { + query = query || {}; + if (this.many) { + if (filter.value) { + query[this.path] = (filter.inverse) ? { $nin: [filter.value] } : { $in: [filter.value] }; + } else { + query[this.path] = (filter.inverse) ? { $not: { $size: 0 } } : { $size: 0 }; + } + } else { + if (filter.value) { + query[this.path] = (filter.inverse) ? { $ne: filter.value } : filter.value; + } else { + query[this.path] = (filter.inverse) ? { $ne: null } : null; + } + } +}; + /** * Formats the field value */ From 71e529877a73df341db61d8c017098ee882ca861 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Tue, 21 Jul 2015 23:36:08 +1000 Subject: [PATCH 45/86] Cleaning up Code Field Type and inheriting from TextType --- fields/types/code/CodeType.js | 35 ++++++++++------------------------- 1 file changed, 10 insertions(+), 25 deletions(-) diff --git a/fields/types/code/CodeType.js b/fields/types/code/CodeType.js index ac11b176ec..f3a4ef69c7 100644 --- a/fields/types/code/CodeType.js +++ b/fields/types/code/CodeType.js @@ -1,41 +1,26 @@ -/*! - * Module dependencies. - */ - -var _ = require('underscore'), - util = require('util'), - super_ = require('../Type'); +var _ = require('underscore'); +var FieldType = require('../Type'); +var TextType = require('../text/TextType'); +var util = require('util'); /** - * Code FieldType Constructor + * HTML FieldType Constructor * @extends Field * @api public */ - function code(list, path, options) { - this._nativeType = String; this._defaultSize = 'full'; - this.height = options.height || 180; - this.lang = options.lang || options.language; + this._properties = ['editor', 'height']; this.codemirror = options.codemirror || {}; this.editor = _.defaults(this.codemirror, { mode : this.lang }); - - this._properties = [ 'editor' ]; - code.super_.call(this, list, path, options); - } +util.inherits(code, FieldType); -/*! - * Inherit from Field - */ - -util.inherits(code, super_); - -/*! - * Export class - */ +/* Inherit from TextType prototype */ +code.prototype.addFilterToQuery = TextType.prototype.addFilterToQuery; +/* Export Field Type */ exports = module.exports = code; From c764765bc90979671f4cbc30f61452f8ae3174eb Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Tue, 21 Jul 2015 23:37:35 +1000 Subject: [PATCH 46/86] Fixing mixed spaces and tabs in NumberType --- fields/types/number/NumberType.js | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/fields/types/number/NumberType.js b/fields/types/number/NumberType.js index 8ef71a4e54..495999c1c5 100644 --- a/fields/types/number/NumberType.js +++ b/fields/types/number/NumberType.js @@ -86,18 +86,18 @@ number.prototype.validateInput = function(data, required, item) { * Updates the value for this field in the item from a data object */ number.prototype.updateItem = function(item, data) { - var value = this.getValueFromData(data); - if (value === undefined) { - return; - } - var newValue = utils.number(value); - if (!isNaN(newValue)) { - if (newValue !== item.get(this.path)) { - item.set(this.path, newValue); - } - } else if ('number' === typeof item.get(this.path)) { - item.set(this.path, null); - } + var value = this.getValueFromData(data); + if (value === undefined) { + return; + } + var newValue = utils.number(value); + if (!isNaN(newValue)) { + if (newValue !== item.get(this.path)) { + item.set(this.path, newValue); + } + } else if ('number' === typeof item.get(this.path)) { + item.set(this.path, null); + } }; /* Export Field Type */ From 8b2a6ed508a65efe7c2d0d70b89528d061fa79fb Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Tue, 21 Jul 2015 23:38:04 +1000 Subject: [PATCH 47/86] Fixing missing filter in SelectType --- fields/types/select/SelectType.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fields/types/select/SelectType.js b/fields/types/select/SelectType.js index f344df9d32..229f579377 100644 --- a/fields/types/select/SelectType.js +++ b/fields/types/select/SelectType.js @@ -106,7 +106,7 @@ select.prototype.cloneMap = function() { select.prototype.addFilterToQuery = function(filter, query) { query = query || {}; if (filter.value) { - query[this.path] = (filter.invert) ? { $ne: value } : value; + query[this.path] = (filter.invert) ? { $ne: filter.value } : filter.value; } else { query[this.path] = (filter.inverse) ? { $nin: ['', null] } : { $in: ['', null] }; } From 2f0d12306062cb38e13912022655825430ac5cf0 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Tue, 21 Jul 2015 23:38:58 +1000 Subject: [PATCH 48/86] Fixing linter errors --- fields/types/datetime/DatetimeType.js | 2 +- fields/types/money/MoneyType.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/fields/types/datetime/DatetimeType.js b/fields/types/datetime/DatetimeType.js index 6cbf78cdcc..374307b7f5 100644 --- a/fields/types/datetime/DatetimeType.js +++ b/fields/types/datetime/DatetimeType.js @@ -22,7 +22,7 @@ function datetime(list, path, options) { if (this.formatString && 'string' !== typeof this.formatString) { throw new Error('FieldType.DateTime: options.format must be a string.'); } - datetime.super_.call(this, list, path, options) + datetime.super_.call(this, list, path, options); this.paths = { date: this._path.append('_date'), time: this._path.append('_time') diff --git a/fields/types/money/MoneyType.js b/fields/types/money/MoneyType.js index 0bee5e0336..19eaa6aba2 100644 --- a/fields/types/money/MoneyType.js +++ b/fields/types/money/MoneyType.js @@ -2,7 +2,6 @@ var FieldType = require('../Type'); var NumberType = require('../number/NumberType'); var numeral = require('numeral'); var util = require('util'); -var utils = require('keystone-utils'); /** * Money FieldType Constructor From acbe81ee7f4635607ff0dd230c0fc3b6377e12d8 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Wed, 22 Jul 2015 00:24:52 +1000 Subject: [PATCH 49/86] Restoring language property in Code field (oops!) --- fields/types/code/CodeType.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fields/types/code/CodeType.js b/fields/types/code/CodeType.js index f3a4ef69c7..a763eca6e5 100644 --- a/fields/types/code/CodeType.js +++ b/fields/types/code/CodeType.js @@ -12,7 +12,8 @@ function code(list, path, options) { this._nativeType = String; this._defaultSize = 'full'; this.height = options.height || 180; - this._properties = ['editor', 'height']; + this.lang = options.lang || options.language; + this._properties = ['editor', 'height', 'lang']; this.codemirror = options.codemirror || {}; this.editor = _.defaults(this.codemirror, { mode : this.lang }); code.super_.call(this, list, path, options); From c4da7acc3b3c0d25b4e082cd432dbc84c7045bfd Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Wed, 22 Jul 2015 17:12:30 +1000 Subject: [PATCH 50/86] Cleaning up list.js --- lib/list.js | 304 ++++++++++++---------------------------------------- 1 file changed, 69 insertions(+), 235 deletions(-) diff --git a/lib/list.js b/lib/list.js index 4eca59682d..bbc837e0d2 100644 --- a/lib/list.js +++ b/lib/list.js @@ -13,7 +13,6 @@ var utils = require('keystone-utils'); * * @param {String} key * @param {Object} options - * @api public */ function List(key, options) { @@ -36,6 +35,9 @@ function List(key, options) { defaultColumns: '__name__' }; + // initialFields values are initialised on demand by the getter + var initialFields; + // Inherit default options from parent list if it exists if (options && options.inherits) { if (options.inherits.options && options.inherits.options.inherits) { @@ -46,6 +48,7 @@ function List(key, options) { this.options = utils.options(defaultOptions, options); + // init properties this.key = key; this.path = this.get('path') || utils.keyToPath(key, true); this.schema = new keystone.mongoose.Schema({}, this.options.schema); @@ -55,7 +58,6 @@ function List(key, options) { this.fields = {}; this.fieldTypes = {}; this.relationships = {}; - this.mappings = { name: null, createdBy: null, @@ -64,93 +66,90 @@ function List(key, options) { modifiedOn: null }; - // set mappings + // init mappings _.each(this.options.map, function(val, key) { this.map(key, val); }, this); - Object.defineProperty(this, 'label', { - get: function() { - return this.get('label') || this.set('label', utils.plural(utils.keyToLabel(key))); - } - }); - - Object.defineProperty(this, 'singular', { - get: function() { - return this.get('singular') || this.set('singular', utils.singular(this.label)); - } - }); - - Object.defineProperty(this, 'plural', { - get: function() { - return this.get('plural') || this.set('plural', utils.plural(this.singular)); - } - }); - - Object.defineProperty(this, 'namePath', { - get: function() { - return this.mappings.name || '_id'; - } - }); - - Object.defineProperty(this, 'nameField', { - get: function() { - return this.fields[this.mappings.name]; - } - }); - - Object.defineProperty(this, 'nameIsVirtual', { - get: function() { - return this.model.schema.virtuals[this.mappings.name] ? true : false; - } - }); - - Object.defineProperty(this, 'nameIsEditable', { - get: function() { - return (this.fields[this.mappings.name] && this.fields[this.mappings.name].type === 'text') ? !this.fields[this.mappings.name].noedit : false; - } - }); - - Object.defineProperty(this, 'nameIsInitial', { - get: function() { - return (this.fields[this.mappings.name] && this.fields[this.mappings.name].options.initial === undefined); - } - }); - - var initialFields; // initialFields values are initialised once, on demand - Object.defineProperty(this, 'initialFields', { - get: function() { - return initialFields || (initialFields = _.filter(this.fields, function(i) { return i.initial; })); - } - }); - + // define property getters + Object.defineProperty(this, 'label', { get: function() { + return this.get('label') || this.set('label', utils.plural(utils.keyToLabel(key))); + } }); + Object.defineProperty(this, 'singular', { get: function() { + return this.get('singular') || this.set('singular', utils.singular(this.label)); + } }); + Object.defineProperty(this, 'plural', { get: function() { + return this.get('plural') || this.set('plural', utils.plural(this.singular)); + } }); + Object.defineProperty(this, 'namePath', { get: function() { + return this.mappings.name || '_id'; + } }); + Object.defineProperty(this, 'nameField', { get: function() { + return this.fields[this.mappings.name]; + } }); + Object.defineProperty(this, 'nameIsVirtual', { get: function() { + return this.model.schema.virtuals[this.mappings.name] ? true : false; + } }); + Object.defineProperty(this, 'nameIsEditable', { get: function() { + return (this.fields[this.mappings.name] && this.fields[this.mappings.name].type === 'text') ? !this.fields[this.mappings.name].noedit : false; + } }); + Object.defineProperty(this, 'nameIsInitial', { get: function() { + return (this.fields[this.mappings.name] && this.fields[this.mappings.name].options.initial === undefined); + } }); + Object.defineProperty(this, 'initialFields', { get: function() { + return initialFields || (initialFields = _.filter(this.fields, function(i) { return i.initial; })); + } }); if (this.get('sortable')) { schemaPlugins.sortable.apply(this); } - if (this.get('autokey')) { schemaPlugins.autokey.apply(this); } - if (this.get('track')) { schemaPlugins.track.apply(this); } - if (this.get('history')) { schemaPlugins.history.apply(this); } - if (this.get('inherits')) { var parentFields = this.get('inherits').schemaFields; this.add.apply(this, parentFields); } } +/** + * Gets the data from an Item ready to be serialised for client-side use, as + * used by the React components + */ +List.prototype.getData = function(item, fields) { + var data = { + id: item.id, + name: this.getDocumentName(item) + }; + if (this.autokey) { + data[this.autokey.path] = item.get(this.autokey.path); + } + if (fields === undefined) { + fields = Object.keys(this.fields); + } + if (fields) { + if (typeof fields === 'string') { + fields = fields.split(' '); + } + if (!Array.isArray(fields)) { + throw new Error('List.getData: fields must be undefined, a string, or an array.'); + } + data.fields = {}; + fields.forEach(function(path) { + var field = this.fields[path]; + if (!field) return; + data.fields[field.path] = field.getData(item); + }, this); + } + return data; +}; /** * Gets the options for the List, as used by the React components - * - * @api public */ - List.prototype.getOptions = function() { var ops = { key: this.key, @@ -212,55 +211,12 @@ List.prototype.getOptions = function() { return ops; }; - -/** - * Gets the data from an Item ready to be serialised for client-side use, as - * used by the React components - * - * @api public - */ - -List.prototype.getData = function(item, fields) { - var data = { - id: item.id, - name: this.getDocumentName(item) - }; - if (this.autokey) { - data[this.autokey.path] = item.get(this.autokey.path); - } - if (fields === undefined) { - fields = Object.keys(this.fields); - } - if (fields) { - if (typeof fields === 'string') { - fields = fields.split(' '); - } - if (!Array.isArray(fields)) { - throw new Error('List.getData: fields must be undefined, a string, or an array.'); - } - data.fields = {}; - _.each(fields, function(path) { - var field = this.fields[path]; - if (!field) return; - data.fields[field.path] = field.getData(item); - }, this); - } - return data; -}; - - /** * Sets list options * - * ####Example: - * + * Example: * list.set('test', value) // sets the 'test' option to `value` - * - * @param {String} key - * @param {String} value - * @api public */ - List.prototype.set = function(key, value) { if (arguments.length === 1) { return this.options[key]; @@ -273,24 +229,15 @@ List.prototype.set = function(key, value) { /** * Gets list options * - * ####Example: - * + * Example: * list.get('test') // returns the 'test' value - * - * @param {String} key - * @method get - * @api public */ - List.prototype.get = List.prototype.set; /** * Maps a built-in field (e.g. name) to a specific path - * - * @api public */ - List.prototype.map = function(field, path) { if (path) { this.mappings[field] = path; @@ -302,10 +249,7 @@ List.prototype.map = function(field, path) { /** * Checks to see if a field path matches a currently unmapped path, and * if so, adds a mapping for it. - * - * @api private */ - List.prototype.automap = function(field) { if (_.has(this.mappings, field.path) && !this.mappings[field.path]) { this.map(field.path, field.path); @@ -317,10 +261,7 @@ List.prototype.automap = function(field) { /** * Adds one or more fields to the List * Based on Mongoose's Schema.add - * - * @api public */ - List.prototype.add = function() { var add = function(obj, prefix) { prefix = prefix || ''; @@ -395,10 +336,7 @@ List.prototype.add = function() { /** * Check whether or not a `path` is a reserved path. This restricts the use * of `Object.prototype` method keys as well as internal mongo paths. - * - * @api public */ - List.prototype.isReserved = function(path) { return List.reservedPaths.indexOf(path) >= 0; }; @@ -425,32 +363,23 @@ List.reservedPaths = [ /** * Creates a new field at the specified path, with the provided options. * If no options are provides, returns the field at the specified path. - * - * @api public */ - List.prototype.field = function(path, options) { - if (arguments.length === 1) { return this.fields[path]; } - if ('function' === typeof options) { options = { type: options }; } - if (this.get('noedit')) { options.noedit = true; } - if (!options.note && this.get('notes')) { options.note = this.get('notes')[path]; } - if ('function' !== typeof options.type) { throw new Error('Fields must be specified with a type function'); } - if (options.type.prototype.__proto__ !== Field.prototype) { // Convert native field types to their default Keystone counterpart if (options.type === String) { @@ -475,44 +404,31 @@ List.prototype.field = function(path, options) { } var field = new options.type(this, path, options); - this.fields[path] = field; return field; - }; /** * Adds a method to the underscoreMethods collection on the list, which is then * added to the schema before the list is registered with mongoose. - * - * @api public */ - List.prototype.underscoreMethod = function(path, fn) { - var target = this.underscoreMethods; path = path.split('.'); var last = path.pop(); - path.forEach(function(part) { if (!target[part]) target[part] = {}; target = target[part]; }); - target[last] = fn; - return this; - }; /** * Default Sort Field - * - * @api public */ - Object.defineProperty(List.prototype, 'defaultSort', { get: function() { var ds = this.get('defaultSort'); @@ -522,7 +438,6 @@ Object.defineProperty(List.prototype, 'defaultSort', { } }); - /** * Expands a comma-separated string or array of columns into valid column objects. * @@ -537,57 +452,41 @@ Object.defineProperty(List.prototype, 'defaultSort', { * * The field or path for the name of the item (defaults to ID if not set or detected) * is automatically prepended if not explicitly included. - * - * @api private */ - List.prototype.expandColumns = function(cols) { - if (typeof cols === 'string') { cols = cols.split(','); } - if (!Array.isArray(cols)) { throw new Error('List.expandColumns: cols must be an array.'); } - var list = this; var expanded = []; var nameCol = false; - var getCol = function(def) { - if (def.path === '__name__') { def.path = list.namePath; } - var field = list.fields[def.path]; var col = null; - if (field) { - col = { field: field, path: field.path, type: field.type, label: def.label || field.label }; - if (col.type === 'relationship') { - col.refList = col.field.refList; - if (col.refList) { col.refPath = def.subpath || col.refList.namePath; col.subField = col.refList.fields[col.refPath]; col.populate = { path: col.field.path, subpath: col.refPath }; } - if (!def.label && def.subpath) { col.label = field.label + ': ' + (col.subField ? col.subField.label : utils.keyToLabel(def.subpath)); } } - } else if (list.model.schema.paths[def.path] || list.model.schema.virtuals[def.path]) { // column refers to a path in the schema // TODO: this needs to handle sophisticated types, including arrays, nested Schemas, and mixed types @@ -596,7 +495,6 @@ List.prototype.expandColumns = function(cols) { label: def.label || utils.keyToLabel(def.path) }; } - if (col) { col.width = def.width; if (col.path === list.namePath) { @@ -607,13 +505,10 @@ List.prototype.expandColumns = function(cols) { _.extend(col, field.col); } } - return col; }; - for (var i = 0; i < cols.length; i++) { var def = {}; - if (typeof cols[i] === 'string') { var parts = cols[i].trim().split('|'); def.width = parts[1] || false; @@ -621,26 +516,21 @@ List.prototype.expandColumns = function(cols) { def.path = parts[0]; def.subpath = parts[1]; } - if (!utils.isObject(def) || !def.path) { throw new Error('List.expandColumns: column definition must contain a path.'); } - var col = getCol(def); if (col) { expanded.push(col); } } - if (!nameCol) { nameCol = getCol({ path: list.namePath }); if (nameCol) { expanded.unshift(nameCol); } } - return expanded; - }; @@ -649,17 +539,12 @@ List.prototype.expandColumns = function(cols) { * * @param {Query} query * @param {Array} columns - * @api private */ - List.prototype.selectColumns = function(q, cols) { - // Populate relationship columns - var select = []; var populate = {}; var path; - cols.forEach(function(col) { select.push(col.path); if (col.populate) { @@ -669,22 +554,17 @@ List.prototype.selectColumns = function(q, cols) { populate[col.populate.path].push(col.populate.subpath); } }); - q.select(select.join(' ')); - for (path in populate) { if ( populate.hasOwnProperty(path) ) { q.populate(path, populate[path].join(' ')); } } - }; /** * Default Column Fields - * - * @api public */ Object.defineProperty(List.prototype, 'defaultColumns', { @@ -699,47 +579,36 @@ Object.defineProperty(List.prototype, 'defaultColumns', { } }); - /** * Registers relationships to this list defined on others - * - * @api public */ - List.prototype.relationship = function(def) { if (arguments.length > 1) { _.map(arguments, function(def) { this.relationship(def); }, this); return this; } - if ('string' === typeof def) { def = { ref: def }; } - if (!def.ref) { throw new Error('List Relationships must be specified with an object containing ref (' + this.key + ')'); } - if (!def.refPath) { def.refPath = utils.downcase(this.key); } - if (!def.path) { def.path = utils.keyToProperty(def.ref, true); } - Object.defineProperty(def, 'refList', { get: function() { return keystone.list(def.ref); } }); - Object.defineProperty(def, 'isValid', { get: function() { return keystone.list(def.ref) ? true : false; } }); - this.relationships[def.path] = def; return this; }; @@ -749,43 +618,33 @@ List.prototype.relationship = function(def) { * Registers the Schema with Mongoose, and the List with Keystone * * Also adds default fields and virtuals to the schema for the list - * - * @api public */ - List.prototype.register = function() { var list = this; - this.schema.virtual('list').get(function () { return list; }); - if (!_.isEmpty(this.relationships)) { this.schema.methods.getRelated = schemaPlugins.methods.getRelated; this.schema.methods.populateRelated = schemaPlugins.methods.populateRelated; if (!this.schema.options.toObject) this.schema.options.toObject = {}; this.schema.options.toObject.transform = schemaPlugins.options.transform; } - this.schema.virtual('_').get(function() { if (!this.__methods) { this.__methods = utils.bindMethods(list.underscoreMethods, this); } return this.__methods; }); - this.schema.method('getUpdateHandler', function(req, res, ops) { return new UpdateHandler(list, this, req, res, ops); }); - if (this.get('inherits')) { this.model = this.get('inherits').model.discriminator(this.key, this.schema); } else { this.model = keystone.mongoose.model(this.key, this.schema); } - require('../').list(this); - return this; }; @@ -793,15 +652,12 @@ List.prototype.register = function() { /** * Gets the name of the provided document from the correct path * - * ####Example: - * + * Example: * var name = list.getDocumentName(item) * * @param {Object} item * @param {Boolean} escape - causes HTML entities to be encoded - * @api public */ - List.prototype.getDocumentName = function(doc, escape) { var name = String(this.nameField ? this.nameField.format(doc) : doc.get(this.namePath)); return (escape) ? utils.encodeHTMLEntities(name) : name; @@ -812,9 +668,7 @@ List.prototype.getDocumentName = function(doc, escape) { * Processes a filter string into a filters object * * @param {String} filters - * @api private */ - List.prototype.processFilters = function(q) { var list = this; var filters = {}; @@ -834,15 +688,12 @@ List.prototype.processFilters = function(q) { * Also accepts a filters object from `processFilters()`, any of which may * override the search string. * - * ####Example: - * + * Example: * list.getSearchFilters('jed') // returns { name: /jed/i } * * @param {String} query * @param {Object} additional filters - * @api public */ - List.prototype.getSearchFilters = function(search, add) { var filters = {}; var list = this; @@ -1061,9 +912,7 @@ List.prototype.getSearchFilters = function(search, add) { * * @param {Object} data * @param {Function} callback (optional) - * @api public */ - List.prototype.updateAll = function(data, callback) { if ('function' === typeof data) { callback = data; @@ -1101,19 +950,15 @@ List.prototype.updateAll = function(data, callback) { * @param {Function} generator method to call to generate a new value * @param {Number} the maximum number of attempts (optional, defaults to 10) * @param {Function} callback(err, uniqueValue) - * @api public */ - List.prototype.getUniqueValue = function(path, generator, limit, callback) { var model = this.model; var count = 0; var value; - if (utils.isFunction(limit)) { callback = limit; limit = 10; } - if (utils.isArray(generator)) { var fn = generator[0]; var args = generator.slice(1); @@ -1121,7 +966,6 @@ List.prototype.getUniqueValue = function(path, generator, limit, callback) { return fn.apply(this, args); }; } - var check = function() { if (count++ > 10) { return callback(undefined, undefined); @@ -1133,7 +977,6 @@ List.prototype.getUniqueValue = function(path, generator, limit, callback) { callback(undefined, value); }); }; - check(); }; @@ -1142,7 +985,6 @@ List.prototype.getUniqueValue = function(path, generator, limit, callback) { * * @param {Number} the maximum number pages to display in the pagination * @param {Object} page options - * @api public */ List.prototype.getPages = function(options, maxPages) { var surround = Math.floor(maxPages / 2); @@ -1150,20 +992,15 @@ List.prototype.getPages = function(options, maxPages) { var padRight = Math.max(((options.currentPage - surround) - 1) * -1, 0); var lastPage = maxPages ? Math.min(options.totalPages, options.currentPage + surround + padRight) : options.totalPages; var padLeft = Math.max(((options.currentPage + surround) - lastPage), 0); - options.pages = []; - firstPage = Math.max(Math.min(firstPage, firstPage - padLeft), 1); - for (var i = firstPage; i <= lastPage; i++) { options.pages.push(i); } - if (firstPage !== 1) { options.pages.shift(); options.pages.unshift('...'); } - if (lastPage !== Number(options.totalPages)) { options.pages.pop(); options.pages.push('...'); @@ -1173,8 +1010,7 @@ List.prototype.getPages = function(options, maxPages) { /** * Gets a special Query object that will paginate documents in the list * - * ####Example: - * + * Example: * list.paginate({ * page: 1, * perPage: 100, @@ -1185,9 +1021,7 @@ List.prototype.getPages = function(options, maxPages) { * * @param {Object} options * @param {Function} callback (optional) - * @api public */ - List.prototype.paginate = function(options, callback) { var list = this; var model = this.model; From c5c99bc0a6bacdd91afa9965ef229733ee98271b Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Wed, 22 Jul 2015 17:15:31 +1000 Subject: [PATCH 51/86] Splitting out getData and getOptions from list.js --- lib/list.js | 100 ++--------------------------------------- lib/list/getData.js | 34 ++++++++++++++ lib/list/getOptions.js | 67 +++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 97 deletions(-) create mode 100644 lib/list/getData.js create mode 100644 lib/list/getOptions.js diff --git a/lib/list.js b/lib/list.js index bbc837e0d2..b72faa10ab 100644 --- a/lib/list.js +++ b/lib/list.js @@ -115,101 +115,9 @@ function List(key, options) { } } -/** - * Gets the data from an Item ready to be serialised for client-side use, as - * used by the React components - */ -List.prototype.getData = function(item, fields) { - var data = { - id: item.id, - name: this.getDocumentName(item) - }; - if (this.autokey) { - data[this.autokey.path] = item.get(this.autokey.path); - } - if (fields === undefined) { - fields = Object.keys(this.fields); - } - if (fields) { - if (typeof fields === 'string') { - fields = fields.split(' '); - } - if (!Array.isArray(fields)) { - throw new Error('List.getData: fields must be undefined, a string, or an array.'); - } - data.fields = {}; - fields.forEach(function(path) { - var field = this.fields[path]; - if (!field) return; - data.fields[field.path] = field.getData(item); - }, this); - } - return data; -}; - -/** - * Gets the options for the List, as used by the React components - */ -List.prototype.getOptions = function() { - var ops = { - key: this.key, - path: this.path, - label: this.label, - singular: this.singular, - plural: this.plural, - namePath: this.namePath, - nameField: this.nameField ? this.nameField.getOptions() : null, - nameIsVirtual: this.nameIsVirtual, - nameIsEditable: this.nameIsEditable, - nameIsInitial: this.nameIsInitial, - noedit: this.options.noedit, - nocreate: this.options.nocreate, - nodelete: this.options.nodelete, - autocreate: this.options.autocreate, - sortable: this.options.sortable, - hidden: this.options.hidden, - searchFields: this.options.searchFields, - defaultSort: this.options.defaultSort, - defaultColumns: this.options.defaultColumns, - track: this.options.track, - tracking: this.tracking, - autokey: this.autokey, - fields: {}, - uiElements: [], - initialFields: _.pluck(this.initialFields, 'path') - }; - _.each(this.uiElements, function(el) { - switch (el.type) { - // TODO: handle indentation - case 'field': - // add the field options by path - ops.fields[el.field.path] = el.field.getOptions(); - // don't output the name field as a ui element if it's editable as it'll - // appear as an input in the header - if (el.field === this.nameField && this.nameIsEditable) { - return; - } - // don't output hidden fields - if (el.field.hidden) { - return; - } - // add the field to the elements array - ops.uiElements.push({ - type: 'field', - field: el.field.path - }); - break; - case 'heading': - ops.uiElements.push({ - type: 'heading', - content: el.heading, - options: el.options - }); - break; - } - }, this); - return ops; -}; +// Add prototype methods +List.prototype.getData = require('./list/getData'); +List.prototype.getOptions = require('./list/getOptions'); /** * Sets list options @@ -1097,9 +1005,7 @@ List.prototype.paginate = function(options, callback) { } }; - /*! * Export class */ - exports = module.exports = List; diff --git a/lib/list/getData.js b/lib/list/getData.js new file mode 100644 index 0000000000..3b005d6c5b --- /dev/null +++ b/lib/list/getData.js @@ -0,0 +1,34 @@ +/** + * Gets the data from an Item ready to be serialised for client-side use, as + * used by the React components + */ + +function getData(item, fields) { + var data = { + id: item.id, + name: this.getDocumentName(item) + }; + if (this.autokey) { + data[this.autokey.path] = item.get(this.autokey.path); + } + if (fields === undefined) { + fields = Object.keys(this.fields); + } + if (fields) { + if (typeof fields === 'string') { + fields = fields.split(' '); + } + if (!Array.isArray(fields)) { + throw new Error('List.getData: fields must be undefined, a string, or an array.'); + } + data.fields = {}; + fields.forEach(function(path) { + var field = this.fields[path]; + if (!field) return; + data.fields[field.path] = field.getData(item); + }, this); + } + return data; +} + +module.exports = getData; diff --git a/lib/list/getOptions.js b/lib/list/getOptions.js new file mode 100644 index 0000000000..4a717434e7 --- /dev/null +++ b/lib/list/getOptions.js @@ -0,0 +1,67 @@ +var _ = require('underscore'); + +/** + * Gets the options for the List, as used by the React components + */ +function getOptions() { + var ops = { + key: this.key, + path: this.path, + label: this.label, + singular: this.singular, + plural: this.plural, + namePath: this.namePath, + nameField: this.nameField ? this.nameField.getOptions() : null, + nameIsVirtual: this.nameIsVirtual, + nameIsEditable: this.nameIsEditable, + nameIsInitial: this.nameIsInitial, + noedit: this.options.noedit, + nocreate: this.options.nocreate, + nodelete: this.options.nodelete, + autocreate: this.options.autocreate, + sortable: this.options.sortable, + hidden: this.options.hidden, + searchFields: this.options.searchFields, + defaultSort: this.options.defaultSort, + defaultColumns: this.options.defaultColumns, + track: this.options.track, + tracking: this.tracking, + autokey: this.autokey, + fields: {}, + uiElements: [], + initialFields: _.pluck(this.initialFields, 'path') + }; + _.each(this.uiElements, function(el) { + switch (el.type) { + // TODO: handle indentation + case 'field': + // add the field options by path + ops.fields[el.field.path] = el.field.getOptions(); + // don't output the name field as a ui element if it's editable as it'll + // appear as an input in the header + if (el.field === this.nameField && this.nameIsEditable) { + return; + } + // don't output hidden fields + if (el.field.hidden) { + return; + } + // add the field to the elements array + ops.uiElements.push({ + type: 'field', + field: el.field.path + }); + break; + case 'heading': + ops.uiElements.push({ + type: 'heading', + content: el.heading, + options: el.options + }); + break; + } + }, this); + return ops; +} + +module.exports = getOptions; From f93d9238038c8ee21038e6882b53ac52c0dfe38c Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Thu, 23 Jul 2015 23:51:57 +1000 Subject: [PATCH 52/86] Cleaning up PasswordType --- fields/types/password/PasswordType.js | 58 +++++---------------------- 1 file changed, 9 insertions(+), 49 deletions(-) diff --git a/fields/types/password/PasswordType.js b/fields/types/password/PasswordType.js index 231fa15d54..a07d1e0542 100644 --- a/fields/types/password/PasswordType.js +++ b/fields/types/password/PasswordType.js @@ -1,41 +1,24 @@ -/*! - * Module dependencies. - */ - var _ = require('underscore'), - util = require('util'), - bcrypt = require('bcrypt-nodejs'), - super_ = require('../Type'); +var bcrypt = require('bcrypt-nodejs'); +var FieldType = require('../Type'); +var util = require('util'); /** * password FieldType Constructor * @extends Field * @api public */ - function password(list, path, options) { - this._nativeType = String; this._underscoreMethods = ['format', 'compare']; this._fixedSize = 'large'; - // You can't sort on password fields options.nosort = true; - - // TODO: implement filtering, hard-coded as disabled for now - options.nofilter = true; - + options.nofilter = true; // TODO: remove this when 0.4 is merged this.workFactor = options.workFactor || 10; - password.super_.call(this, list, path, options); - } - -/*! - * Inherit from Field - */ - -util.inherits(password, super_); +util.inherits(password, FieldType); /** * Registers the field on the List's Mongoose Schema. @@ -45,10 +28,8 @@ util.inherits(password, super_); * @api public */ password.prototype.addToSchema = function() { - - var field = this, - schema = this.list.schema; - + var field = this; + var schema = this.list.schema; var needs_hashing = '__' + field.path + '_needs_hashing'; this.paths = { @@ -63,48 +44,38 @@ password.prototype.addToSchema = function() { return newValue; } }, this.options)); - + schema.virtual(this.paths.hash).set(function(newValue) { this.set(field.path, newValue); this[needs_hashing] = false; }); schema.pre('save', function(next) { - if (!this.isModified(field.path) || !this[needs_hashing]) { return next(); } - if (!this.get(field.path)) { this.set(field.path, undefined); return next(); } - var item = this; - bcrypt.genSalt(field.workFactor, function(err, salt) { if (err) { return next(err); } - bcrypt.hash(item.get(field.path), salt, function () {}, function(err, hash) { if (err) { return next(err); } - // override the cleartext password with the hashed one item.set(field.path, hash); next(); }); }); - }); - this.bindUnderscoreMethods(); - }; - /** * Formats the field value * @@ -114,7 +85,6 @@ password.prototype.addToSchema = function() { * * @api public */ - password.prototype.format = function(item) { if (!item.get(this.path)) return ''; var len = Math.round(Math.random() * 4) + 6; @@ -123,13 +93,11 @@ password.prototype.format = function(item) { return stars; }; - /** * Compares * * @api public */ - password.prototype.compare = function(item, candidate, callback) { if ('function' !== typeof callback) throw new Error('Password.compare() requires a callback function.'); var value = item.get(this.path); @@ -137,7 +105,6 @@ password.prototype.compare = function(item, candidate, callback) { bcrypt.compare(candidate, item.get(this.path), callback); }; - /** * If password fields are required, check that either a value has been * provided or already exists in the field. @@ -147,7 +114,6 @@ password.prototype.compare = function(item, candidate, callback) { * * @api public */ - password.prototype.validateInput = function(data, required, item) { if (data[this.path] && this.paths.confirm in data) { return data[this.path] === data[this.paths.confirm] ? true : false; @@ -156,7 +122,6 @@ password.prototype.validateInput = function(data, required, item) { return required ? false : true; }; - /** * Updates the value for this field in the item from a data object * @@ -164,7 +129,6 @@ password.prototype.validateInput = function(data, required, item) { * * @api public */ - password.prototype.updateItem = function(item, data) { if (this.path in data) { item.set(this.path, data[this.path]); @@ -173,9 +137,5 @@ password.prototype.updateItem = function(item, data) { } }; - -/*! - * Export class - */ - +/* Export Field Type */ exports = module.exports = password; From 6dd37f724ea919ffb09cf2faca0d8a67d56263d4 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Thu, 23 Jul 2015 23:52:11 +1000 Subject: [PATCH 53/86] Adding password.prototype.addFilterToQuery --- fields/types/password/PasswordType.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/fields/types/password/PasswordType.js b/fields/types/password/PasswordType.js index a07d1e0542..a7870c29a5 100644 --- a/fields/types/password/PasswordType.js +++ b/fields/types/password/PasswordType.js @@ -76,6 +76,14 @@ password.prototype.addToSchema = function() { this.bindUnderscoreMethods(); }; +/** + * Add filters to a query + */ +password.prototype.addFilterToQuery = function(filter, query) { + query = query || {}; + query[this.path] = (filter.exists) ? { $ne: null } : null; +}; + /** * Formats the field value * From 941f5b2593d3c4f8e2b8fb681d96a42606ba6eb3 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Thu, 23 Jul 2015 23:56:07 +1000 Subject: [PATCH 54/86] Cleaning up Name field type --- fields/types/name/NameType.js | 71 +++++------------------------------ 1 file changed, 9 insertions(+), 62 deletions(-) diff --git a/fields/types/name/NameType.js b/fields/types/name/NameType.js index 2d5d75f3dd..1d3add54e0 100644 --- a/fields/types/name/NameType.js +++ b/fields/types/name/NameType.js @@ -1,32 +1,18 @@ -/*! - * Module dependencies. - */ - -var _ = require('underscore'), - util = require('util'), - super_ = require('../Type'); +var _ = require('underscore'); +var FieldType = require('../Type'); +var util = require('util'); /** * Name FieldType Constructor * @extends Field * @api public */ - function name(list, path, options) { - this._fixedSize = 'large'; - - // TODO: implement filtering, hard-coded as disabled for now - options.nofilter = true; + options.nofilter = true; // TODO: remove this when 0.4 is merged name.super_.call(this, list, path, options); - } - -/*! - * Inherit from Field - */ - -util.inherits(name, super_); +util.inherits(name, FieldType); /** @@ -39,9 +25,7 @@ util.inherits(name, super_); */ name.prototype.addToSchema = function() { - var schema = this.list.schema; - var paths = this.paths = { first: this._path.append('.first'), last: this._path.append('.last'), @@ -59,123 +43,86 @@ name.prototype.addToSchema = function() { }); schema.virtual(paths.full).set(function(value) { - if (typeof value !== 'string') { this.set(paths.first, undefined); this.set(paths.last, undefined); return; } - var split = value.split(' '); this.set(paths.first, split.shift()); this.set(paths.last, split.join(' ') || undefined); - }); this.bindUnderscoreMethods(); }; - /** * Formats the field value - * - * @api public */ name.prototype.format = function(item) { return item.get(this.paths.full); }; - /** * Validates that a value for this field has been provided in a data object - * - * @api public */ - name.prototype.validateInput = function(data, required, item) { - // Input is valid if none was provided, but the item has data if (!(this.path in data || this.paths.first in data || this.paths.last in data || this.paths.full in data) && item && item.get(this.paths.full)) return true; - // Input is valid if the field is not required if (!required) return true; - - // Otherwise check for valid strings in the provided data, + // Otherwise check for valid strings in the provided data, // which may be nested or use flattened paths. - if (_.isObject(data[this.path])) { return (data[this.path].full || data[this.path].first || data[this.path].last) ? true : false; } else { return (data[this.paths.full] || data[this.paths.first] || data[this.paths.last]) ? true : false; } - }; - /** * Detects whether the field has been modified * * @api public */ - name.prototype.isModified = function(item) { return item.isModified(this.paths.first) || item.isModified(this.paths.last); }; - /** * Updates the value for this field in the item from a data object * * @api public */ - name.prototype.updateItem = function(item, data) { - if (!_.isObject(data)) return; - - var paths = this.paths, - setValue; - + var paths = this.paths; + var setValue; if (this.path in data && _.isString(data[this.path])) { - // Allow the root path as an alias to {path}.full - item.set(paths.full, data[this.path]); - } else if (this.path in data && _.isObject(data[this.path])) { - // Allow a nested object like { path: { first: 'Jed' } } - var valueObj = data[this.path]; - setValue = function(key) { if (key in valueObj && valueObj[key] !== item.get(paths[key])) { item.set(paths[key], valueObj[key]); } }; - } else { - // Default to flattened paths like { 'path.first': 'Jed' } - setValue = function(key) { if (paths[key] in data && data[paths[key]] !== item.get(paths[key])) { item.set(paths[key], data[paths[key]]); } }; - } - if (setValue) { _.each(['full', 'first', 'last'], setValue); } - }; -/*! - * Export class - */ - +/* Export Field Type */ exports = module.exports = name; From 34d1280ee7cde02586ab69f579de8a0a32859807 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Thu, 23 Jul 2015 23:57:10 +1000 Subject: [PATCH 55/86] Fixing syntax error --- fields/types/password/PasswordType.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fields/types/password/PasswordType.js b/fields/types/password/PasswordType.js index a7870c29a5..c48bf12273 100644 --- a/fields/types/password/PasswordType.js +++ b/fields/types/password/PasswordType.js @@ -1,4 +1,4 @@ -var _ = require('underscore'), +var _ = require('underscore'); var bcrypt = require('bcrypt-nodejs'); var FieldType = require('../Type'); var util = require('util'); From daa016429028912072129b4914913d75da50786a Mon Sep 17 00:00:00 2001 From: Javier Castro Date: Tue, 28 Jul 2015 13:28:27 -0300 Subject: [PATCH 56/86] Fix error when trying to use 'file limit' configuration Fixes #1412, caused when trying to use 'file limit' configuration --- lib/core/mount.js | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/core/mount.js b/lib/core/mount.js index 8ae8da0d37..2d210bc26d 100644 --- a/lib/core/mount.js +++ b/lib/core/mount.js @@ -348,14 +348,17 @@ function mount(mountPath, parentApp, events) { app.use(morgan(this.get('logger'), this.get('logger options'))); } + var bodyParserParams = {}; + if (this.get('file limit')) { debug('adding file limit'); - app.use(express.limit(this.get('file limit'))); + bodyParserParams.limit = this.get('file limit'); } debug('adding standard middleware'); - app.use(bodyParser.json()); - app.use(bodyParser.urlencoded({ extended: true })); + app.use(bodyParser.json(bodyParserParams)); + bodyParserParams.extended = true; + app.use(bodyParser.urlencoded(bodyParserParams)); app.use(methodOverride()); app.use(sessionOptions.cookieParser); app.use(this.get('express session')); From c541f7d7847aeb71b7a5362767ef711d7467d6de Mon Sep 17 00:00:00 2001 From: webteckie Date: Thu, 30 Jul 2015 19:04:58 -0400 Subject: [PATCH 57/86] Load CodeMirror only in the item form if and only if a code field is defined. This should speed up loading of all other pages in the Admin UI as well as the item form if no code field is defined. --- admin/public/styles/keystone/forms.less | 3 +++ templates/layout/base.jade | 2 +- templates/views/item.jade | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/admin/public/styles/keystone/forms.less b/admin/public/styles/keystone/forms.less index 2c65c293bd..8a4ef7adf4 100644 --- a/admin/public/styles/keystone/forms.less +++ b/admin/public/styles/keystone/forms.less @@ -299,6 +299,9 @@ label.checkbox { background: transparent; border-radius: @input-border-radius; } + .CodeMirror-linenumber{ + margin-left:-30px; + } } // Related Items diff --git a/templates/layout/base.jade b/templates/layout/base.jade index 70d2cc7f85..1caee5efd0 100644 --- a/templates/layout/base.jade +++ b/templates/layout/base.jade @@ -97,7 +97,7 @@ html script(src="/keystone/js/lib/pikaday/pikaday.jquery-1.1.0.js") script(src="/keystone/js/lib/jquery-placeholder-shim/jquery-placeholder-shim.js") script(src="/keystone/js/lib/tinymce/tinymce.min.js") - script(src="/keystone/js/lib/codemirror/codemirror-compressed.js") + block js_codemirror //- App script. diff --git a/templates/views/item.jade b/templates/views/item.jade index 0673293dd8..3ecb1a6cac 100644 --- a/templates/views/item.jade +++ b/templates/views/item.jade @@ -14,6 +14,10 @@ block js script(src='/keystone/js/packages.js') script(src='/keystone/js/fields.js') script(src='/keystone/js/item.js') + +block js_codemirror + if list.fieldTypes.code + script(src="/keystone/js/lib/codemirror/codemirror-compressed.js") block content // Attach point for new React View From c66d584e4ebeef67eb88232a4178acaeacb79e54 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Fri, 31 Jul 2015 23:59:56 +1000 Subject: [PATCH 58/86] Updating dependencies --- package.json | 68 ++++++++++++++++++++++++++-------------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/package.json b/package.json index 7474368db1..cf9b5907b8 100644 --- a/package.json +++ b/package.json @@ -8,78 +8,78 @@ "url": "https://github.com/keystonejs/keystone.git" }, "dependencies": { - "async": "~1.2.1", + "async": "~1.4.0", "asyncdi": "^1.1.0", "azure": "~0.10.6", - "babel-core": "^5.6.7", - "babel-plugin-object-assign": "^1.2.0", - "babelify": "^6.1.2", + "babel-core": "^5.8.19", + "babel-plugin-object-assign": "^1.2.1", + "babelify": "^6.1.3", "babyparse": "^0.4.3", "bcrypt-nodejs": "~0.0.3", "blacklist": "^1.1.2", - "bluebird": "~2.9.30", - "body-parser": "~1.13.1", - "browserify-shim": "^3.8.9", + "bluebird": "~2.9.34", + "body-parser": "~1.13.2", + "browserify-shim": "^3.8.10", "bytes": "^2.1.0", "caller-id": "^0.1.0", - "chalk": "^1.0.0", - "classnames": "^2.1.2", - "cloudinary": "~1.2.1", - "codemirror": "^5.3.0", - "compression": "~1.5.0", + "chalk": "^1.1.0", + "classnames": "^2.1.3", + "cloudinary": "~1.2.2", + "codemirror": "^5.5.0", + "compression": "~1.5.2", "connect-flash": "~0.1.1", "cookie-parser": "~1.3.5", "debug": "^2.2.0", "embedly": "~1.0.4", - "errorhandler": "^1.4.0", - "express": "~4.13.0", + "errorhandler": "^1.4.2", + "express": "~4.13.1", "express-session": "~1.11.3", - "fs-extra": "~0.20.1", + "fs-extra": "~0.22.1", "grappling-hook": "^2.5.0", "jade": "~1.11.0", "jquery": "~2.1.4", - "keystone-utils": "~0.2.0", + "keystone-utils": "~0.3.0", "knox": "~0.9.2", "less-middleware": "~2.0.1", "mandrill-api": "~1.0.45", - "marked": "~0.3.3", - "method-override": "~2.3.3", - "moment": "~2.10.3", - "mongoose": "~3.8.29", - "morgan": "~1.6.0", + "marked": "~0.3.5", + "method-override": "~2.3.4", + "moment": "~2.10.6", + "mongoose": "~3.8.34", + "morgan": "~1.6.1", "mpromise": "~0.5.5", - "multer": "~0.1.8", + "multer": "~1.0.1", "numeral": "~1.5.3", - "pikaday": "^1.3.2", + "pikaday": "^1.3.3", "queryfilter": "~0.0.4", "range_check": "~0.0.5", "react": "~0.13.3", "react-alt-text": "^1.1.0", - "react-select": "~0.5.1", + "react-select": "~0.5.6", "scmp": "~1.0.0", - "semver": "~4.3.6", + "semver": "~5.0.1", "serve-favicon": "~2.3.0", - "store-prototype": "^1.1.0", + "store-prototype": "^1.1.1", "superagent": "^1.2.0", "underscore": "^1.8.3", "vkey": "^1.0.0", - "watchify": "^3.2.3" + "watchify": "^3.3.1" }, "devDependencies": { - "babel-eslint": "^3.1.18", - "browserify": "~10.2.4", - "codeclimate-test-reporter": "0.0.4", + "babel-eslint": "^4.0.5", + "browserify": "~11.0.1", + "codeclimate-test-reporter": "0.1.0", "eslint": "^0.24.1", - "eslint-plugin-react": "^2.5.2", + "eslint-plugin-react": "^3.1.0", "gulp": "~3.9.0", "gulp-git": "^1.2.4", "gulp-streamify": "0.0.5", "gulp-uglify": "^1.2.0", - "istanbul": "^0.3.16", + "istanbul": "^0.3.17", "mocha": "^2.2.5", "must": ">= 0.12 < 1", - "rimraf": "^2.4.0", - "sinon": "~1.15.3", + "rimraf": "^2.4.2", + "sinon": "~1.15.4", "supertest": "~1.0.1", "vinyl-source-stream": "~1.1.0" }, From a04bc1f903f346781cfabe27fb1d4b02ca17593d Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sat, 1 Aug 2015 01:58:30 +1000 Subject: [PATCH 59/86] Rolling back multer version for compatibility, ref #1563 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index cf9b5907b8..e00aa6e238 100644 --- a/package.json +++ b/package.json @@ -48,7 +48,7 @@ "mongoose": "~3.8.34", "morgan": "~1.6.1", "mpromise": "~0.5.5", - "multer": "~1.0.1", + "multer": "~0.1.8", "numeral": "~1.5.3", "pikaday": "^1.3.3", "queryfilter": "~0.0.4", From 9f9359ed8d50f399a61766b81086daf59f0dbab4 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sat, 1 Aug 2015 01:59:26 +1000 Subject: [PATCH 60/86] Updating packages build --- admin/public/js/packages.js | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/admin/public/js/packages.js b/admin/public/js/packages.js index 4ef3a3851a..cba93304fb 100644 --- a/admin/public/js/packages.js +++ b/admin/public/js/packages.js @@ -1,11 +1,12 @@ -require=function e(t,n,r){function o(a,s){if(!n[a]){if(!t[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(i)return i(a,!0);var l=new Error("Cannot find module '"+a+"'");throw l.code="MODULE_NOT_FOUND",l}var c=n[a]={exports:{}};t[a][0].call(c.exports,function(e){var n=t[a][1][e];return o(n?n:e)},c,c.exports,e,t,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;a/g,">"),t=this.props.style||{};t.display="inline-block";var n=this.props.inputStyle||{};n.width=this.state.inputWidth;var a=this.props.placeholder?o.createElement("div",{ref:"placeholderSizer",style:i},this.props.placeholder):null;return o.createElement("div",{className:this.props.className,style:t},o.createElement("input",r({},this.props,{ref:"input",className:this.props.inputClassName,style:n})),o.createElement("div",{ref:"sizer",style:i,dangerouslySetInnerHTML:{__html:e}}),a)}});t.exports=a},{react:"react"}],4:[function(e,t,n){"use strict";var r=e("./focusNode"),o={componentDidMount:function(){this.props.autoFocus&&r(this.getDOMNode())}};t.exports=o},{"./focusNode":137}],5:[function(e,t,n){"use strict";function r(){var e=window.opera;return"object"==typeof e&&"function"==typeof e.version&&parseInt(e.version(),10)<=12}function o(e){return(e.ctrlKey||e.altKey||e.metaKey)&&!(e.ctrlKey&&e.altKey)}function i(e){switch(e){case x.topCompositionStart:return T.compositionStart;case x.topCompositionEnd:return T.compositionEnd;case x.topCompositionUpdate:return T.compositionUpdate}}function a(e,t){return e===x.topKeyDown&&t.keyCode===b}function s(e,t){switch(e){case x.topKeyUp:return-1!==C.indexOf(t.keyCode);case x.topKeyDown:return t.keyCode!==b;case x.topKeyPress:case x.topMouseDown:case x.topBlur:return!0;default:return!1}}function u(e){var t=e.detail;return"object"==typeof t&&"data"in t?t.data:null}function l(e,t,n,r){var o,l;if(E?o=i(e):P?s(e,r)&&(o=T.compositionEnd):a(e,r)&&(o=T.compositionStart),!o)return null;w&&(P||o!==T.compositionStart?o===T.compositionEnd&&P&&(l=P.getData()):P=v.getPooled(t));var c=g.getPooled(o,n,r);if(l)c.data=l;else{var p=u(r);null!==p&&(c.data=p)}return f.accumulateTwoPhaseDispatches(c),c}function c(e,t){switch(e){case x.topCompositionEnd:return u(t);case x.topKeyPress:var n=t.which;return n!==D?null:(k=!0,O);case x.topTextInput:var r=t.data;return r===O&&k?null:r;default:return null}}function p(e,t){if(P){if(e===x.topCompositionEnd||s(e,t)){var n=P.getData();return v.release(P),P=null,n}return null}switch(e){case x.topPaste:return null;case x.topKeyPress:return t.which&&!o(t)?String.fromCharCode(t.which):null;case x.topCompositionEnd:return w?null:t.data;default:return null}}function d(e,t,n,r){var o;if(o=R?c(e,r):p(e,r),!o)return null;var i=y.getPooled(T.beforeInput,n,r);return i.data=o,f.accumulateTwoPhaseDispatches(i),i}var h=e("./EventConstants"),f=e("./EventPropagators"),m=e("./ExecutionEnvironment"),v=e("./FallbackCompositionState"),g=e("./SyntheticCompositionEvent"),y=e("./SyntheticInputEvent"),_=e("./keyOf"),C=[9,13,27,32],b=229,E=m.canUseDOM&&"CompositionEvent"in window,M=null;m.canUseDOM&&"documentMode"in document&&(M=document.documentMode);var R=m.canUseDOM&&"TextEvent"in window&&!M&&!r(),w=m.canUseDOM&&(!E||M&&M>8&&11>=M),D=32,O=String.fromCharCode(D),x=h.topLevelTypes,T={beforeInput:{phasedRegistrationNames:{bubbled:_({onBeforeInput:null}),captured:_({onBeforeInputCapture:null})},dependencies:[x.topCompositionEnd,x.topKeyPress,x.topTextInput,x.topPaste]},compositionEnd:{phasedRegistrationNames:{bubbled:_({onCompositionEnd:null}),captured:_({onCompositionEndCapture:null})},dependencies:[x.topBlur,x.topCompositionEnd,x.topKeyDown,x.topKeyPress,x.topKeyUp,x.topMouseDown]},compositionStart:{phasedRegistrationNames:{bubbled:_({onCompositionStart:null}),captured:_({onCompositionStartCapture:null})},dependencies:[x.topBlur,x.topCompositionStart,x.topKeyDown,x.topKeyPress,x.topKeyUp,x.topMouseDown]},compositionUpdate:{phasedRegistrationNames:{bubbled:_({onCompositionUpdate:null}),captured:_({onCompositionUpdateCapture:null})},dependencies:[x.topBlur,x.topCompositionUpdate,x.topKeyDown,x.topKeyPress,x.topKeyUp,x.topMouseDown]}},k=!1,P=null,S={eventTypes:T,extractEvents:function(e,t,n,r){return[l(e,t,n,r),d(e,t,n,r)]}};t.exports=S},{"./EventConstants":18,"./EventPropagators":23,"./ExecutionEnvironment":24,"./FallbackCompositionState":25,"./SyntheticCompositionEvent":109,"./SyntheticInputEvent":113,"./keyOf":160}],6:[function(e,t,n){var r=e("./invariant"),o={addClass:function(e,t){return r(!/\s/.test(t)),t&&(e.classList?e.classList.add(t):o.hasClass(e,t)||(e.className=e.className+" "+t)),e},removeClass:function(e,t){return r(!/\s/.test(t)),t&&(e.classList?e.classList.remove(t):o.hasClass(e,t)&&(e.className=e.className.replace(new RegExp("(^|\\s)"+t+"(?:\\s|$)","g"),"$1").replace(/\s+/g," ").replace(/^\s*|\s*$/g,""))),e},conditionClass:function(e,t,n){return(n?o.addClass:o.removeClass)(e,t)},hasClass:function(e,t){return r(!/\s/.test(t)),e.classList?!!t&&e.classList.contains(t):(" "+e.className+" ").indexOf(" "+t+" ")>-1}};t.exports=o},{"./invariant":153}],7:[function(e,t,n){"use strict";function r(e,t){return e+t.charAt(0).toUpperCase()+t.substring(1)}var o={boxFlex:!0,boxFlexGroup:!0,columnCount:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,strokeDashoffset:!0,strokeOpacity:!0,strokeWidth:!0},i=["Webkit","ms","Moz","O"];Object.keys(o).forEach(function(e){i.forEach(function(t){o[r(t,e)]=o[e]})});var a={background:{backgroundImage:!0,backgroundPosition:!0,backgroundRepeat:!0,backgroundColor:!0},border:{borderWidth:!0,borderStyle:!0,borderColor:!0},borderBottom:{borderBottomWidth:!0,borderBottomStyle:!0,borderBottomColor:!0},borderLeft:{borderLeftWidth:!0,borderLeftStyle:!0,borderLeftColor:!0},borderRight:{borderRightWidth:!0,borderRightStyle:!0,borderRightColor:!0},borderTop:{borderTopWidth:!0,borderTopStyle:!0,borderTopColor:!0},font:{fontStyle:!0,fontVariant:!0,fontWeight:!0,fontSize:!0,lineHeight:!0,fontFamily:!0}},s={isUnitlessNumber:o,shorthandPropertyExpansions:a};t.exports=s},{}],8:[function(e,t,n){"use strict";var r=e("./CSSProperty"),o=e("./ExecutionEnvironment"),i=(e("./camelizeStyleName"),e("./dangerousStyleValue")),a=e("./hyphenateStyleName"),s=e("./memoizeStringOnly"),u=(e("./warning"),s(function(e){return a(e)})),l="cssFloat";o.canUseDOM&&void 0===document.documentElement.style.cssFloat&&(l="styleFloat");var c={createMarkupForStyles:function(e){var t="";for(var n in e)if(e.hasOwnProperty(n)){var r=e[n];null!=r&&(t+=u(n)+":",t+=i(n,r)+";")}return t||null},setValueForStyles:function(e,t){var n=e.style;for(var o in t)if(t.hasOwnProperty(o)){var a=i(o,t[o]);if("float"===o&&(o=l),a)n[o]=a;else{var s=r.shorthandPropertyExpansions[o];if(s)for(var u in s)n[u]="";else n[o]=""}}}};t.exports=c},{"./CSSProperty":7,"./ExecutionEnvironment":24,"./camelizeStyleName":124,"./dangerousStyleValue":131,"./hyphenateStyleName":151,"./memoizeStringOnly":162,"./warning":174}],9:[function(e,t,n){"use strict";function r(){this._callbacks=null,this._contexts=null}var o=e("./PooledClass"),i=e("./Object.assign"),a=e("./invariant");i(r.prototype,{enqueue:function(e,t){this._callbacks=this._callbacks||[],this._contexts=this._contexts||[],this._callbacks.push(e),this._contexts.push(t)},notifyAll:function(){var e=this._callbacks,t=this._contexts;if(e){a(e.length===t.length),this._callbacks=null,this._contexts=null;for(var n=0,r=e.length;r>n;n++)e[n].call(t[n]);e.length=0,t.length=0}},reset:function(){this._callbacks=null,this._contexts=null},destructor:function(){this.reset()}}),o.addPoolingTo(r),t.exports=r},{"./Object.assign":31,"./PooledClass":32,"./invariant":153}],10:[function(e,t,n){"use strict";function r(e){return"SELECT"===e.nodeName||"INPUT"===e.nodeName&&"file"===e.type}function o(e){var t=M.getPooled(x.change,k,e);C.accumulateTwoPhaseDispatches(t),E.batchedUpdates(i,t)}function i(e){_.enqueueEvents(e),_.processEventQueue()}function a(e,t){T=e,k=t,T.attachEvent("onchange",o)}function s(){T&&(T.detachEvent("onchange",o),T=null,k=null)}function u(e,t,n){return e===O.topChange?n:void 0}function l(e,t,n){e===O.topFocus?(s(),a(t,n)):e===O.topBlur&&s()}function c(e,t){T=e,k=t,P=e.value,S=Object.getOwnPropertyDescriptor(e.constructor.prototype,"value"),Object.defineProperty(T,"value",A),T.attachEvent("onpropertychange",d)}function p(){T&&(delete T.value,T.detachEvent("onpropertychange",d),T=null,k=null,P=null,S=null)}function d(e){if("value"===e.propertyName){var t=e.srcElement.value;t!==P&&(P=t,o(e))}}function h(e,t,n){return e===O.topInput?n:void 0}function f(e,t,n){e===O.topFocus?(p(),c(t,n)):e===O.topBlur&&p()}function m(e,t,n){return e!==O.topSelectionChange&&e!==O.topKeyUp&&e!==O.topKeyDown||!T||T.value===P?void 0:(P=T.value,k)}function v(e){return"INPUT"===e.nodeName&&("checkbox"===e.type||"radio"===e.type)}function g(e,t,n){return e===O.topClick?n:void 0}var y=e("./EventConstants"),_=e("./EventPluginHub"),C=e("./EventPropagators"),b=e("./ExecutionEnvironment"),E=e("./ReactUpdates"),M=e("./SyntheticEvent"),R=e("./isEventSupported"),w=e("./isTextInputElement"),D=e("./keyOf"),O=y.topLevelTypes,x={change:{phasedRegistrationNames:{bubbled:D({onChange:null}),captured:D({onChangeCapture:null})},dependencies:[O.topBlur,O.topChange,O.topClick,O.topFocus,O.topInput,O.topKeyDown,O.topKeyUp,O.topSelectionChange]}},T=null,k=null,P=null,S=null,I=!1;b.canUseDOM&&(I=R("change")&&(!("documentMode"in document)||document.documentMode>8));var N=!1;b.canUseDOM&&(N=R("input")&&(!("documentMode"in document)||document.documentMode>9));var A={get:function(){return S.get.call(this)},set:function(e){P=""+e,S.set.call(this,e)}},L={eventTypes:x,extractEvents:function(e,t,n,o){var i,a;if(r(t)?I?i=u:a=l:w(t)?N?i=h:(i=m,a=f):v(t)&&(i=g),i){var s=i(e,t,n);if(s){var c=M.getPooled(x.change,s,o);return C.accumulateTwoPhaseDispatches(c),c}}a&&a(e,t,n)}};t.exports=L},{"./EventConstants":18,"./EventPluginHub":20,"./EventPropagators":23,"./ExecutionEnvironment":24,"./ReactUpdates":102,"./SyntheticEvent":111,"./isEventSupported":154,"./isTextInputElement":156,"./keyOf":160}],11:[function(e,t,n){"use strict";var r=0,o={createReactRootIndex:function(){return r++}};t.exports=o},{}],12:[function(e,t,n){"use strict";function r(e,t,n){e.insertBefore(t,e.childNodes[n]||null)}var o=e("./Danger"),i=e("./ReactMultiChildUpdateTypes"),a=e("./setTextContent"),s=e("./invariant"),u={dangerouslyReplaceNodeWithMarkup:o.dangerouslyReplaceNodeWithMarkup,updateTextContent:a,processUpdates:function(e,t){for(var n,u=null,l=null,c=0;ct||o.hasOverloadedBooleanValue[e]&&t===!1}var o=e("./DOMProperty"),i=e("./quoteAttributeValueForBrowser"),a=(e("./warning"),{createMarkupForID:function(e){return o.ID_ATTRIBUTE_NAME+"="+i(e)},createMarkupForProperty:function(e,t){if(o.isStandardName.hasOwnProperty(e)&&o.isStandardName[e]){if(r(e,t))return"";var n=o.getAttributeName[e];return o.hasBooleanValue[e]||o.hasOverloadedBooleanValue[e]&&t===!0?n:n+"="+i(t)}return o.isCustomAttribute(e)?null==t?"":e+"="+i(t):null},setValueForProperty:function(e,t,n){if(o.isStandardName.hasOwnProperty(t)&&o.isStandardName[t]){var i=o.getMutationMethod[t];if(i)i(e,n);else if(r(t,n))this.deleteValueForProperty(e,t);else if(o.mustUseAttribute[t])e.setAttribute(o.getAttributeName[t],""+n);else{var a=o.getPropertyName[t];o.hasSideEffects[t]&&""+e[a]==""+n||(e[a]=n)}}else o.isCustomAttribute(t)&&(null==n?e.removeAttribute(t):e.setAttribute(t,""+n))},deleteValueForProperty:function(e,t){if(o.isStandardName.hasOwnProperty(t)&&o.isStandardName[t]){var n=o.getMutationMethod[t];if(n)n(e,void 0);else if(o.mustUseAttribute[t])e.removeAttribute(o.getAttributeName[t]);else{var r=o.getPropertyName[t],i=o.getDefaultValueForProperty(e.nodeName,r);o.hasSideEffects[t]&&""+e[r]===i||(e[r]=i)}}else o.isCustomAttribute(t)&&e.removeAttribute(t)}});t.exports=a},{"./DOMProperty":13,"./quoteAttributeValueForBrowser":166,"./warning":174}],15:[function(e,t,n){"use strict";function r(e){return e.substring(1,e.indexOf(" "))}var o=e("./ExecutionEnvironment"),i=e("./createNodesFromMarkup"),a=e("./emptyFunction"),s=e("./getMarkupWrap"),u=e("./invariant"),l=/^(<[^ \/>]+)/,c="data-danger-index",p={dangerouslyRenderMarkup:function(e){u(o.canUseDOM);for(var t,n={},p=0;pu;u++){var c=s[u];if(c){var p=c.extractEvents(e,t,n,o);p&&(a=i(a,p))}}return a},enqueueEvents:function(e){e&&(l=i(l,e))},processEventQueue:function(){var e=l;l=null,a(e,c),s(!l)},__purge:function(){u={}},__getListenerBank:function(){return u}};t.exports=d},{"./EventPluginRegistry":21,"./EventPluginUtils":22,"./accumulateInto":121,"./forEachAccumulated":138,"./invariant":153}],21:[function(e,t,n){"use strict";function r(){if(s)for(var e in u){var t=u[e],n=s.indexOf(e);if(a(n>-1),!l.plugins[n]){a(t.extractEvents),l.plugins[n]=t;var r=t.eventTypes;for(var i in r)a(o(r[i],t,i))}}}function o(e,t,n){a(!l.eventNameDispatchConfigs.hasOwnProperty(n)),l.eventNameDispatchConfigs[n]=e;var r=e.phasedRegistrationNames;if(r){for(var o in r)if(r.hasOwnProperty(o)){var s=r[o];i(s,t,n)}return!0}return e.registrationName?(i(e.registrationName,t,n),!0):!1}function i(e,t,n){a(!l.registrationNameModules[e]),l.registrationNameModules[e]=t,l.registrationNameDependencies[e]=t.eventTypes[n].dependencies}var a=e("./invariant"),s=null,u={},l={plugins:[],eventNameDispatchConfigs:{},registrationNameModules:{},registrationNameDependencies:{},injectEventPluginOrder:function(e){a(!s),s=Array.prototype.slice.call(e),r()},injectEventPluginsByName:function(e){var t=!1;for(var n in e)if(e.hasOwnProperty(n)){var o=e[n];u.hasOwnProperty(n)&&u[n]===o||(a(!u[n]),u[n]=o,t=!0)}t&&r()},getPluginModuleForEvent:function(e){var t=e.dispatchConfig;if(t.registrationName)return l.registrationNameModules[t.registrationName]||null;for(var n in t.phasedRegistrationNames)if(t.phasedRegistrationNames.hasOwnProperty(n)){var r=l.registrationNameModules[t.phasedRegistrationNames[n]];if(r)return r}return null},_resetEventPlugins:function(){s=null;for(var e in u)u.hasOwnProperty(e)&&delete u[e];l.plugins.length=0;var t=l.eventNameDispatchConfigs;for(var n in t)t.hasOwnProperty(n)&&delete t[n];var r=l.registrationNameModules;for(var o in r)r.hasOwnProperty(o)&&delete r[o]}};t.exports=l},{"./invariant":153}],22:[function(e,t,n){"use strict";function r(e){return e===v.topMouseUp||e===v.topTouchEnd||e===v.topTouchCancel}function o(e){return e===v.topMouseMove||e===v.topTouchMove}function i(e){return e===v.topMouseDown||e===v.topTouchStart}function a(e,t){var n=e._dispatchListeners,r=e._dispatchIDs;if(Array.isArray(n))for(var o=0;oe&&n[e]===o[e];e++);var a=r-e;for(t=1;a>=t&&n[r-t]===o[i-t];t++);var s=t>1?1-t:void 0;return this._fallbackText=o.slice(e,s),this._fallbackText}}),o.addPoolingTo(r),t.exports=r},{"./Object.assign":31,"./PooledClass":32,"./getTextContentAccessor":148}],26:[function(e,t,n){"use strict";var r,o=e("./DOMProperty"),i=e("./ExecutionEnvironment"),a=o.injection.MUST_USE_ATTRIBUTE,s=o.injection.MUST_USE_PROPERTY,u=o.injection.HAS_BOOLEAN_VALUE,l=o.injection.HAS_SIDE_EFFECTS,c=o.injection.HAS_NUMERIC_VALUE,p=o.injection.HAS_POSITIVE_NUMERIC_VALUE,d=o.injection.HAS_OVERLOADED_BOOLEAN_VALUE;if(i.canUseDOM){var h=document.implementation;r=h&&h.hasFeature&&h.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")}var f={isCustomAttribute:RegExp.prototype.test.bind(/^(data|aria)-[a-z_][a-z\d_.\-]*$/),Properties:{accept:null,acceptCharset:null,accessKey:null,action:null,allowFullScreen:a|u,allowTransparency:a,alt:null,async:u,autoComplete:null,autoPlay:u,cellPadding:null,cellSpacing:null,charSet:a,checked:s|u,classID:a,className:r?a:s,cols:a|p,colSpan:null,content:null,contentEditable:null,contextMenu:a,controls:s|u,coords:null,crossOrigin:null,data:null,dateTime:a,defer:u,dir:null,disabled:a|u,download:d,draggable:null,encType:null,form:a,formAction:a,formEncType:a,formMethod:a,formNoValidate:u,formTarget:a,frameBorder:a,headers:null,height:a,hidden:a|u,high:null,href:null,hrefLang:null,htmlFor:null,httpEquiv:null,icon:null,id:s,label:null,lang:null,list:a,loop:s|u,low:null,manifest:a,marginHeight:null,marginWidth:null,max:null,maxLength:a,media:a,mediaGroup:null,method:null,min:null,multiple:s|u,muted:s|u,name:null,noValidate:u,open:u,optimum:null,pattern:null,placeholder:null,poster:null,preload:null,radioGroup:null,readOnly:s|u,rel:null,required:u,role:a,rows:a|p,rowSpan:null,sandbox:null,scope:null,scoped:u,scrolling:null,seamless:a|u,selected:s|u,shape:null,size:a|p,sizes:a,span:p,spellCheck:null,src:null,srcDoc:s,srcSet:a,start:c,step:null,style:null,tabIndex:null,target:null,title:null,type:null,useMap:null,value:s|l,width:a,wmode:a,autoCapitalize:null,autoCorrect:null,itemProp:a,itemScope:a|u,itemType:a,itemID:a,itemRef:a,property:null,unselectable:a},DOMAttributeNames:{acceptCharset:"accept-charset",className:"class",htmlFor:"for",httpEquiv:"http-equiv"},DOMPropertyNames:{autoCapitalize:"autocapitalize",autoComplete:"autocomplete",autoCorrect:"autocorrect",autoFocus:"autofocus",autoPlay:"autoplay",encType:"encoding",hrefLang:"hreflang",radioGroup:"radiogroup",spellCheck:"spellcheck",srcDoc:"srcdoc",srcSet:"srcset"}};t.exports=f},{"./DOMProperty":13,"./ExecutionEnvironment":24}],27:[function(e,t,n){"use strict";var r=e("./ReactLink"),o=e("./ReactStateSetters"),i={linkState:function(e){return new r(this.state[e],o.createStateKeySetter(this,e))}};t.exports=i},{"./ReactLink":77,"./ReactStateSetters":96}],28:[function(e,t,n){"use strict";function r(e){l(null==e.props.checkedLink||null==e.props.valueLink)}function o(e){r(e),l(null==e.props.value&&null==e.props.onChange)}function i(e){r(e),l(null==e.props.checked&&null==e.props.onChange)}function a(e){this.props.valueLink.requestChange(e.target.value)}function s(e){this.props.checkedLink.requestChange(e.target.checked)}var u=e("./ReactPropTypes"),l=e("./invariant"),c={button:!0,checkbox:!0,image:!0,hidden:!0,radio:!0,reset:!0,submit:!0},p={Mixin:{propTypes:{value:function(e,t,n){return!e[t]||c[e.type]||e.onChange||e.readOnly||e.disabled?null:new Error("You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.")},checked:function(e,t,n){return!e[t]||e.onChange||e.readOnly||e.disabled?null:new Error("You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`."); +require=function e(t,n,r){function o(a,s){if(!n[a]){if(!t[a]){var u="function"==typeof require&&require;if(!s&&u)return u(a,!0);if(i)return i(a,!0);var l=new Error("Cannot find module '"+a+"'");throw l.code="MODULE_NOT_FOUND",l}var c=n[a]={exports:{}};t[a][0].call(c.exports,function(e){var n=t[a][1][e];return o(n?n:e)},c,c.exports,e,t,n,r)}return n[a].exports}for(var i="function"==typeof require&&require,a=0;a/g,">"),t=this.props.style||{};t.display="inline-block";var n=this.props.inputStyle||{};n.width=this.state.inputWidth;var a=this.props.placeholder?o.createElement("div",{ref:"placeholderSizer",style:i},this.props.placeholder):null;return o.createElement("div",{className:this.props.className,style:t},o.createElement("input",r({},this.props,{ref:"input",className:this.props.inputClassName,style:n})),o.createElement("div",{ref:"sizer",style:i,dangerouslySetInnerHTML:{__html:e}}),a)}});t.exports=a},{react:"react"}],4:[function(e,t,n){"use strict";var r=e("./focusNode"),o={componentDidMount:function(){this.props.autoFocus&&r(this.getDOMNode())}};t.exports=o},{"./focusNode":137}],5:[function(e,t,n){"use strict";function r(){var e=window.opera;return"object"==typeof e&&"function"==typeof e.version&&parseInt(e.version(),10)<=12}function o(e){return(e.ctrlKey||e.altKey||e.metaKey)&&!(e.ctrlKey&&e.altKey)}function i(e){switch(e){case x.topCompositionStart:return T.compositionStart;case x.topCompositionEnd:return T.compositionEnd;case x.topCompositionUpdate:return T.compositionUpdate}}function a(e,t){return e===x.topKeyDown&&t.keyCode===C}function s(e,t){switch(e){case x.topKeyUp:return-1!==b.indexOf(t.keyCode);case x.topKeyDown:return t.keyCode!==C;case x.topKeyPress:case x.topMouseDown:case x.topBlur:return!0;default:return!1}}function u(e){var t=e.detail;return"object"==typeof t&&"data"in t?t.data:null}function l(e,t,n,r){var o,l;if(E?o=i(e):k?s(e,r)&&(o=T.compositionEnd):a(e,r)&&(o=T.compositionStart),!o)return null;w&&(k||o!==T.compositionStart?o===T.compositionEnd&&k&&(l=k.getData()):k=v.getPooled(t));var c=g.getPooled(o,n,r);if(l)c.data=l;else{var p=u(r);null!==p&&(c.data=p)}return f.accumulateTwoPhaseDispatches(c),c}function c(e,t){switch(e){case x.topCompositionEnd:return u(t);case x.topKeyPress:var n=t.which;return n!==D?null:(S=!0,O);case x.topTextInput:var r=t.data;return r===O&&S?null:r;default:return null}}function p(e,t){if(k){if(e===x.topCompositionEnd||s(e,t)){var n=k.getData();return v.release(k),k=null,n}return null}switch(e){case x.topPaste:return null;case x.topKeyPress:return t.which&&!o(t)?String.fromCharCode(t.which):null;case x.topCompositionEnd:return w?null:t.data;default:return null}}function d(e,t,n,r){var o;if(o=R?c(e,r):p(e,r),!o)return null;var i=y.getPooled(T.beforeInput,n,r);return i.data=o,f.accumulateTwoPhaseDispatches(i),i}var h=e("./EventConstants"),f=e("./EventPropagators"),m=e("./ExecutionEnvironment"),v=e("./FallbackCompositionState"),g=e("./SyntheticCompositionEvent"),y=e("./SyntheticInputEvent"),_=e("./keyOf"),b=[9,13,27,32],C=229,E=m.canUseDOM&&"CompositionEvent"in window,M=null;m.canUseDOM&&"documentMode"in document&&(M=document.documentMode);var R=m.canUseDOM&&"TextEvent"in window&&!M&&!r(),w=m.canUseDOM&&(!E||M&&M>8&&11>=M),D=32,O=String.fromCharCode(D),x=h.topLevelTypes,T={beforeInput:{phasedRegistrationNames:{bubbled:_({onBeforeInput:null}),captured:_({onBeforeInputCapture:null})},dependencies:[x.topCompositionEnd,x.topKeyPress,x.topTextInput,x.topPaste]},compositionEnd:{phasedRegistrationNames:{bubbled:_({onCompositionEnd:null}),captured:_({onCompositionEndCapture:null})},dependencies:[x.topBlur,x.topCompositionEnd,x.topKeyDown,x.topKeyPress,x.topKeyUp,x.topMouseDown]},compositionStart:{phasedRegistrationNames:{bubbled:_({onCompositionStart:null}),captured:_({onCompositionStartCapture:null})},dependencies:[x.topBlur,x.topCompositionStart,x.topKeyDown,x.topKeyPress,x.topKeyUp,x.topMouseDown]},compositionUpdate:{phasedRegistrationNames:{bubbled:_({onCompositionUpdate:null}),captured:_({onCompositionUpdateCapture:null})},dependencies:[x.topBlur,x.topCompositionUpdate,x.topKeyDown,x.topKeyPress,x.topKeyUp,x.topMouseDown]}},S=!1,k=null,P={eventTypes:T,extractEvents:function(e,t,n,r){return[l(e,t,n,r),d(e,t,n,r)]}};t.exports=P},{"./EventConstants":18,"./EventPropagators":23,"./ExecutionEnvironment":24,"./FallbackCompositionState":25,"./SyntheticCompositionEvent":109,"./SyntheticInputEvent":113,"./keyOf":160}],6:[function(e,t,n){var r=e("./invariant"),o={addClass:function(e,t){return r(!/\s/.test(t)),t&&(e.classList?e.classList.add(t):o.hasClass(e,t)||(e.className=e.className+" "+t)),e},removeClass:function(e,t){return r(!/\s/.test(t)),t&&(e.classList?e.classList.remove(t):o.hasClass(e,t)&&(e.className=e.className.replace(new RegExp("(^|\\s)"+t+"(?:\\s|$)","g"),"$1").replace(/\s+/g," ").replace(/^\s*|\s*$/g,""))),e},conditionClass:function(e,t,n){return(n?o.addClass:o.removeClass)(e,t)},hasClass:function(e,t){return r(!/\s/.test(t)),e.classList?!!t&&e.classList.contains(t):(" "+e.className+" ").indexOf(" "+t+" ")>-1}};t.exports=o},{"./invariant":153}],7:[function(e,t,n){"use strict";function r(e,t){return e+t.charAt(0).toUpperCase()+t.substring(1)}var o={boxFlex:!0,boxFlexGroup:!0,columnCount:!0,flex:!0,flexGrow:!0,flexPositive:!0,flexShrink:!0,flexNegative:!0,fontWeight:!0,lineClamp:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0,fillOpacity:!0,strokeDashoffset:!0,strokeOpacity:!0,strokeWidth:!0},i=["Webkit","ms","Moz","O"];Object.keys(o).forEach(function(e){i.forEach(function(t){o[r(t,e)]=o[e]})});var a={background:{backgroundImage:!0,backgroundPosition:!0,backgroundRepeat:!0,backgroundColor:!0},border:{borderWidth:!0,borderStyle:!0,borderColor:!0},borderBottom:{borderBottomWidth:!0,borderBottomStyle:!0,borderBottomColor:!0},borderLeft:{borderLeftWidth:!0,borderLeftStyle:!0,borderLeftColor:!0},borderRight:{borderRightWidth:!0,borderRightStyle:!0,borderRightColor:!0},borderTop:{borderTopWidth:!0,borderTopStyle:!0,borderTopColor:!0},font:{fontStyle:!0,fontVariant:!0,fontWeight:!0,fontSize:!0,lineHeight:!0,fontFamily:!0}},s={isUnitlessNumber:o,shorthandPropertyExpansions:a};t.exports=s},{}],8:[function(e,t,n){"use strict";var r=e("./CSSProperty"),o=e("./ExecutionEnvironment"),i=(e("./camelizeStyleName"),e("./dangerousStyleValue")),a=e("./hyphenateStyleName"),s=e("./memoizeStringOnly"),u=(e("./warning"),s(function(e){return a(e)})),l="cssFloat";o.canUseDOM&&void 0===document.documentElement.style.cssFloat&&(l="styleFloat");var c={createMarkupForStyles:function(e){var t="";for(var n in e)if(e.hasOwnProperty(n)){var r=e[n];null!=r&&(t+=u(n)+":",t+=i(n,r)+";")}return t||null},setValueForStyles:function(e,t){var n=e.style;for(var o in t)if(t.hasOwnProperty(o)){var a=i(o,t[o]);if("float"===o&&(o=l),a)n[o]=a;else{var s=r.shorthandPropertyExpansions[o];if(s)for(var u in s)n[u]="";else n[o]=""}}}};t.exports=c},{"./CSSProperty":7,"./ExecutionEnvironment":24,"./camelizeStyleName":124,"./dangerousStyleValue":131,"./hyphenateStyleName":151,"./memoizeStringOnly":162,"./warning":174}],9:[function(e,t,n){"use strict";function r(){this._callbacks=null,this._contexts=null}var o=e("./PooledClass"),i=e("./Object.assign"),a=e("./invariant");i(r.prototype,{enqueue:function(e,t){this._callbacks=this._callbacks||[],this._contexts=this._contexts||[],this._callbacks.push(e),this._contexts.push(t)},notifyAll:function(){var e=this._callbacks,t=this._contexts;if(e){a(e.length===t.length),this._callbacks=null,this._contexts=null;for(var n=0,r=e.length;r>n;n++)e[n].call(t[n]);e.length=0,t.length=0}},reset:function(){this._callbacks=null,this._contexts=null},destructor:function(){this.reset()}}),o.addPoolingTo(r),t.exports=r},{"./Object.assign":31,"./PooledClass":32,"./invariant":153}],10:[function(e,t,n){"use strict";function r(e){return"SELECT"===e.nodeName||"INPUT"===e.nodeName&&"file"===e.type}function o(e){var t=M.getPooled(x.change,S,e);b.accumulateTwoPhaseDispatches(t),E.batchedUpdates(i,t)}function i(e){_.enqueueEvents(e),_.processEventQueue()}function a(e,t){T=e,S=t,T.attachEvent("onchange",o)}function s(){T&&(T.detachEvent("onchange",o),T=null,S=null)}function u(e,t,n){return e===O.topChange?n:void 0}function l(e,t,n){e===O.topFocus?(s(),a(t,n)):e===O.topBlur&&s()}function c(e,t){T=e,S=t,k=e.value,P=Object.getOwnPropertyDescriptor(e.constructor.prototype,"value"),Object.defineProperty(T,"value",A),T.attachEvent("onpropertychange",d)}function p(){T&&(delete T.value,T.detachEvent("onpropertychange",d),T=null,S=null,k=null,P=null)}function d(e){if("value"===e.propertyName){var t=e.srcElement.value;t!==k&&(k=t,o(e))}}function h(e,t,n){return e===O.topInput?n:void 0}function f(e,t,n){e===O.topFocus?(p(),c(t,n)):e===O.topBlur&&p()}function m(e,t,n){return e!==O.topSelectionChange&&e!==O.topKeyUp&&e!==O.topKeyDown||!T||T.value===k?void 0:(k=T.value,S)}function v(e){return"INPUT"===e.nodeName&&("checkbox"===e.type||"radio"===e.type)}function g(e,t,n){return e===O.topClick?n:void 0}var y=e("./EventConstants"),_=e("./EventPluginHub"),b=e("./EventPropagators"),C=e("./ExecutionEnvironment"),E=e("./ReactUpdates"),M=e("./SyntheticEvent"),R=e("./isEventSupported"),w=e("./isTextInputElement"),D=e("./keyOf"),O=y.topLevelTypes,x={change:{phasedRegistrationNames:{bubbled:D({onChange:null}),captured:D({onChangeCapture:null})},dependencies:[O.topBlur,O.topChange,O.topClick,O.topFocus,O.topInput,O.topKeyDown,O.topKeyUp,O.topSelectionChange]}},T=null,S=null,k=null,P=null,I=!1;C.canUseDOM&&(I=R("change")&&(!("documentMode"in document)||document.documentMode>8));var N=!1;C.canUseDOM&&(N=R("input")&&(!("documentMode"in document)||document.documentMode>9));var A={get:function(){return P.get.call(this)},set:function(e){k=""+e,P.set.call(this,e)}},L={eventTypes:x,extractEvents:function(e,t,n,o){var i,a;if(r(t)?I?i=u:a=l:w(t)?N?i=h:(i=m,a=f):v(t)&&(i=g),i){var s=i(e,t,n);if(s){var c=M.getPooled(x.change,s,o);return b.accumulateTwoPhaseDispatches(c),c}}a&&a(e,t,n)}};t.exports=L},{"./EventConstants":18,"./EventPluginHub":20,"./EventPropagators":23,"./ExecutionEnvironment":24,"./ReactUpdates":102,"./SyntheticEvent":111,"./isEventSupported":154,"./isTextInputElement":156,"./keyOf":160}],11:[function(e,t,n){"use strict";var r=0,o={createReactRootIndex:function(){return r++}};t.exports=o},{}],12:[function(e,t,n){"use strict";function r(e,t,n){e.insertBefore(t,e.childNodes[n]||null)}var o=e("./Danger"),i=e("./ReactMultiChildUpdateTypes"),a=e("./setTextContent"),s=e("./invariant"),u={dangerouslyReplaceNodeWithMarkup:o.dangerouslyReplaceNodeWithMarkup,updateTextContent:a,processUpdates:function(e,t){for(var n,u=null,l=null,c=0;ct||o.hasOverloadedBooleanValue[e]&&t===!1}var o=e("./DOMProperty"),i=e("./quoteAttributeValueForBrowser"),a=(e("./warning"),{createMarkupForID:function(e){return o.ID_ATTRIBUTE_NAME+"="+i(e)},createMarkupForProperty:function(e,t){if(o.isStandardName.hasOwnProperty(e)&&o.isStandardName[e]){if(r(e,t))return"";var n=o.getAttributeName[e];return o.hasBooleanValue[e]||o.hasOverloadedBooleanValue[e]&&t===!0?n:n+"="+i(t)}return o.isCustomAttribute(e)?null==t?"":e+"="+i(t):null},setValueForProperty:function(e,t,n){if(o.isStandardName.hasOwnProperty(t)&&o.isStandardName[t]){var i=o.getMutationMethod[t];if(i)i(e,n);else if(r(t,n))this.deleteValueForProperty(e,t);else if(o.mustUseAttribute[t])e.setAttribute(o.getAttributeName[t],""+n);else{var a=o.getPropertyName[t];o.hasSideEffects[t]&&""+e[a]==""+n||(e[a]=n)}}else o.isCustomAttribute(t)&&(null==n?e.removeAttribute(t):e.setAttribute(t,""+n))},deleteValueForProperty:function(e,t){if(o.isStandardName.hasOwnProperty(t)&&o.isStandardName[t]){var n=o.getMutationMethod[t];if(n)n(e,void 0);else if(o.mustUseAttribute[t])e.removeAttribute(o.getAttributeName[t]);else{var r=o.getPropertyName[t],i=o.getDefaultValueForProperty(e.nodeName,r);o.hasSideEffects[t]&&""+e[r]===i||(e[r]=i)}}else o.isCustomAttribute(t)&&e.removeAttribute(t)}});t.exports=a},{"./DOMProperty":13,"./quoteAttributeValueForBrowser":166,"./warning":174}],15:[function(e,t,n){"use strict";function r(e){return e.substring(1,e.indexOf(" "))}var o=e("./ExecutionEnvironment"),i=e("./createNodesFromMarkup"),a=e("./emptyFunction"),s=e("./getMarkupWrap"),u=e("./invariant"),l=/^(<[^ \/>]+)/,c="data-danger-index",p={dangerouslyRenderMarkup:function(e){u(o.canUseDOM);for(var t,n={},p=0;pu;u++){var c=s[u];if(c){var p=c.extractEvents(e,t,n,o);p&&(a=i(a,p))}}return a},enqueueEvents:function(e){e&&(l=i(l,e))},processEventQueue:function(){var e=l;l=null,a(e,c),s(!l)},__purge:function(){u={}},__getListenerBank:function(){return u}};t.exports=d},{"./EventPluginRegistry":21,"./EventPluginUtils":22,"./accumulateInto":121,"./forEachAccumulated":138,"./invariant":153}],21:[function(e,t,n){"use strict";function r(){if(s)for(var e in u){var t=u[e],n=s.indexOf(e);if(a(n>-1),!l.plugins[n]){a(t.extractEvents),l.plugins[n]=t;var r=t.eventTypes;for(var i in r)a(o(r[i],t,i))}}}function o(e,t,n){a(!l.eventNameDispatchConfigs.hasOwnProperty(n)),l.eventNameDispatchConfigs[n]=e;var r=e.phasedRegistrationNames;if(r){for(var o in r)if(r.hasOwnProperty(o)){var s=r[o];i(s,t,n)}return!0}return e.registrationName?(i(e.registrationName,t,n),!0):!1}function i(e,t,n){a(!l.registrationNameModules[e]),l.registrationNameModules[e]=t,l.registrationNameDependencies[e]=t.eventTypes[n].dependencies}var a=e("./invariant"),s=null,u={},l={plugins:[],eventNameDispatchConfigs:{},registrationNameModules:{},registrationNameDependencies:{},injectEventPluginOrder:function(e){a(!s),s=Array.prototype.slice.call(e),r()},injectEventPluginsByName:function(e){var t=!1;for(var n in e)if(e.hasOwnProperty(n)){var o=e[n];u.hasOwnProperty(n)&&u[n]===o||(a(!u[n]),u[n]=o,t=!0)}t&&r()},getPluginModuleForEvent:function(e){var t=e.dispatchConfig;if(t.registrationName)return l.registrationNameModules[t.registrationName]||null;for(var n in t.phasedRegistrationNames)if(t.phasedRegistrationNames.hasOwnProperty(n)){var r=l.registrationNameModules[t.phasedRegistrationNames[n]];if(r)return r}return null},_resetEventPlugins:function(){s=null;for(var e in u)u.hasOwnProperty(e)&&delete u[e];l.plugins.length=0;var t=l.eventNameDispatchConfigs;for(var n in t)t.hasOwnProperty(n)&&delete t[n];var r=l.registrationNameModules;for(var o in r)r.hasOwnProperty(o)&&delete r[o]}};t.exports=l},{"./invariant":153}],22:[function(e,t,n){"use strict";function r(e){return e===v.topMouseUp||e===v.topTouchEnd||e===v.topTouchCancel}function o(e){return e===v.topMouseMove||e===v.topTouchMove}function i(e){return e===v.topMouseDown||e===v.topTouchStart}function a(e,t){var n=e._dispatchListeners,r=e._dispatchIDs;if(Array.isArray(n))for(var o=0;oe&&n[e]===o[e];e++);var a=r-e;for(t=1;a>=t&&n[r-t]===o[i-t];t++);var s=t>1?1-t:void 0;return this._fallbackText=o.slice(e,s),this._fallbackText}}),o.addPoolingTo(r),t.exports=r},{"./Object.assign":31,"./PooledClass":32,"./getTextContentAccessor":148}],26:[function(e,t,n){"use strict";var r,o=e("./DOMProperty"),i=e("./ExecutionEnvironment"),a=o.injection.MUST_USE_ATTRIBUTE,s=o.injection.MUST_USE_PROPERTY,u=o.injection.HAS_BOOLEAN_VALUE,l=o.injection.HAS_SIDE_EFFECTS,c=o.injection.HAS_NUMERIC_VALUE,p=o.injection.HAS_POSITIVE_NUMERIC_VALUE,d=o.injection.HAS_OVERLOADED_BOOLEAN_VALUE;if(i.canUseDOM){var h=document.implementation;r=h&&h.hasFeature&&h.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure","1.1")}var f={isCustomAttribute:RegExp.prototype.test.bind(/^(data|aria)-[a-z_][a-z\d_.\-]*$/),Properties:{accept:null,acceptCharset:null,accessKey:null,action:null,allowFullScreen:a|u,allowTransparency:a,alt:null,async:u,autoComplete:null,autoPlay:u,cellPadding:null,cellSpacing:null,charSet:a,checked:s|u,classID:a,className:r?a:s,cols:a|p,colSpan:null,content:null,contentEditable:null,contextMenu:a,controls:s|u,coords:null,crossOrigin:null,data:null,dateTime:a,defer:u,dir:null,disabled:a|u,download:d,draggable:null,encType:null,form:a,formAction:a,formEncType:a,formMethod:a,formNoValidate:u,formTarget:a,frameBorder:a,headers:null,height:a,hidden:a|u,high:null,href:null,hrefLang:null,htmlFor:null,httpEquiv:null,icon:null,id:s,label:null,lang:null,list:a,loop:s|u,low:null,manifest:a,marginHeight:null,marginWidth:null,max:null,maxLength:a,media:a,mediaGroup:null,method:null,min:null,multiple:s|u,muted:s|u,name:null,noValidate:u,open:u,optimum:null,pattern:null,placeholder:null,poster:null,preload:null,radioGroup:null,readOnly:s|u,rel:null,required:u,role:a,rows:a|p,rowSpan:null,sandbox:null,scope:null,scoped:u,scrolling:null,seamless:a|u,selected:s|u,shape:null,size:a|p,sizes:a,span:p,spellCheck:null,src:null,srcDoc:s,srcSet:a,start:c,step:null,style:null,tabIndex:null,target:null,title:null,type:null,useMap:null,value:s|l,width:a,wmode:a,autoCapitalize:null,autoCorrect:null,itemProp:a,itemScope:a|u,itemType:a,itemID:a,itemRef:a,property:null,unselectable:a},DOMAttributeNames:{acceptCharset:"accept-charset",className:"class",htmlFor:"for",httpEquiv:"http-equiv"},DOMPropertyNames:{autoCapitalize:"autocapitalize",autoComplete:"autocomplete",autoCorrect:"autocorrect",autoFocus:"autofocus",autoPlay:"autoplay",encType:"encoding",hrefLang:"hreflang",radioGroup:"radiogroup",spellCheck:"spellcheck",srcDoc:"srcdoc",srcSet:"srcset"}};t.exports=f},{"./DOMProperty":13,"./ExecutionEnvironment":24}],27:[function(e,t,n){"use strict";var r=e("./ReactLink"),o=e("./ReactStateSetters"),i={linkState:function(e){return new r(this.state[e],o.createStateKeySetter(this,e))}};t.exports=i},{"./ReactLink":77,"./ReactStateSetters":96}],28:[function(e,t,n){"use strict";function r(e){l(null==e.props.checkedLink||null==e.props.valueLink)}function o(e){r(e),l(null==e.props.value&&null==e.props.onChange)}function i(e){r(e),l(null==e.props.checked&&null==e.props.onChange)}function a(e){this.props.valueLink.requestChange(e.target.value)}function s(e){this.props.checkedLink.requestChange(e.target.checked)}var u=e("./ReactPropTypes"),l=e("./invariant"),c={button:!0,checkbox:!0,image:!0,hidden:!0,radio:!0,reset:!0,submit:!0},p={Mixin:{propTypes:{value:function(e,t,n){return!e[t]||c[e.type]||e.onChange||e.readOnly||e.disabled?null:new Error("You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.")},checked:function(e,t,n){return!e[t]||e.onChange||e.readOnly||e.disabled?null:new Error("You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`."); -},onChange:u.func}},getValue:function(e){return e.props.valueLink?(o(e),e.props.valueLink.value):e.props.value},getChecked:function(e){return e.props.checkedLink?(i(e),e.props.checkedLink.value):e.props.checked},getOnChange:function(e){return e.props.valueLink?(o(e),a):e.props.checkedLink?(i(e),s):e.props.onChange}};t.exports=p},{"./ReactPropTypes":88,"./invariant":153}],29:[function(e,t,n){"use strict";function r(e){e.remove()}var o=e("./ReactBrowserEventEmitter"),i=e("./accumulateInto"),a=e("./forEachAccumulated"),s=e("./invariant"),u={trapBubbledEvent:function(e,t){s(this.isMounted());var n=this.getDOMNode();s(n);var r=o.trapBubbledEvent(e,t,n);this._localEventListeners=i(this._localEventListeners,r)},componentWillUnmount:function(){this._localEventListeners&&a(this._localEventListeners,r)}};t.exports=u},{"./ReactBrowserEventEmitter":35,"./accumulateInto":121,"./forEachAccumulated":138,"./invariant":153}],30:[function(e,t,n){"use strict";var r=e("./EventConstants"),o=e("./emptyFunction"),i=r.topLevelTypes,a={eventTypes:null,extractEvents:function(e,t,n,r){if(e===i.topTouchStart){var a=r.target;a&&!a.onclick&&(a.onclick=o)}}};t.exports=a},{"./EventConstants":18,"./emptyFunction":132}],31:[function(e,t,n){"use strict";function r(e,t){if(null==e)throw new TypeError("Object.assign target cannot be null or undefined");for(var n=Object(e),r=Object.prototype.hasOwnProperty,o=1;ol;l++){var d=s[l];i.hasOwnProperty(d)&&i[d]||(d===u.topWheel?c("wheel")?v.ReactEventListener.trapBubbledEvent(u.topWheel,"wheel",n):c("mousewheel")?v.ReactEventListener.trapBubbledEvent(u.topWheel,"mousewheel",n):v.ReactEventListener.trapBubbledEvent(u.topWheel,"DOMMouseScroll",n):d===u.topScroll?c("scroll",!0)?v.ReactEventListener.trapCapturedEvent(u.topScroll,"scroll",n):v.ReactEventListener.trapBubbledEvent(u.topScroll,"scroll",v.ReactEventListener.WINDOW_HANDLE):d===u.topFocus||d===u.topBlur?(c("focus",!0)?(v.ReactEventListener.trapCapturedEvent(u.topFocus,"focus",n),v.ReactEventListener.trapCapturedEvent(u.topBlur,"blur",n)):c("focusin")&&(v.ReactEventListener.trapBubbledEvent(u.topFocus,"focusin",n),v.ReactEventListener.trapBubbledEvent(u.topBlur,"focusout",n)),i[u.topBlur]=!0,i[u.topFocus]=!0):f.hasOwnProperty(d)&&v.ReactEventListener.trapBubbledEvent(d,f[d],n),i[d]=!0)}},trapBubbledEvent:function(e,t,n){return v.ReactEventListener.trapBubbledEvent(e,t,n)},trapCapturedEvent:function(e,t,n){return v.ReactEventListener.trapCapturedEvent(e,t,n)},ensureScrollValueMonitoring:function(){if(!d){var e=u.refreshScrollValues;v.ReactEventListener.monitorScrollValue(e),d=!0}},eventNameDispatchConfigs:i.eventNameDispatchConfigs,registrationNameModules:i.registrationNameModules,putListener:i.putListener,getListener:i.getListener,deleteListener:i.deleteListener,deleteAllListeners:i.deleteAllListeners});t.exports=v},{"./EventConstants":18,"./EventPluginHub":20,"./EventPluginRegistry":21,"./Object.assign":31,"./ReactEventEmitterMixin":69,"./ViewportMetrics":120,"./isEventSupported":154}],36:[function(e,t,n){"use strict";var r=e("./React"),o=e("./Object.assign"),i=r.createFactory(e("./ReactTransitionGroup")),a=r.createFactory(e("./ReactCSSTransitionGroupChild")),s=r.createClass({displayName:"ReactCSSTransitionGroup",propTypes:{transitionName:r.PropTypes.string.isRequired,transitionAppear:r.PropTypes.bool,transitionEnter:r.PropTypes.bool,transitionLeave:r.PropTypes.bool},getDefaultProps:function(){return{transitionAppear:!1,transitionEnter:!0,transitionLeave:!0}},_wrapChild:function(e){return a({name:this.props.transitionName,appear:this.props.transitionAppear,enter:this.props.transitionEnter,leave:this.props.transitionLeave},e)},render:function(){return i(o({},this.props,{childFactory:this._wrapChild}))}});t.exports=s},{"./Object.assign":31,"./React":33,"./ReactCSSTransitionGroupChild":37,"./ReactTransitionGroup":100}],37:[function(e,t,n){"use strict";var r=e("./React"),o=e("./CSSCore"),i=e("./ReactTransitionEvents"),a=e("./onlyChild"),s=(e("./warning"),17),u=r.createClass({displayName:"ReactCSSTransitionGroupChild",transition:function(e,t){var n=this.getDOMNode(),r=this.props.name+"-"+e,a=r+"-active",s=function(e){e&&e.target!==n||(o.removeClass(n,r),o.removeClass(n,a),i.removeEndEventListener(n,s),t&&t())};i.addEndEventListener(n,s),o.addClass(n,r),this.queueClass(a)},queueClass:function(e){this.classNameQueue.push(e),this.timeout||(this.timeout=setTimeout(this.flushClassNameQueue,s))},flushClassNameQueue:function(){this.isMounted()&&this.classNameQueue.forEach(o.addClass.bind(o,this.getDOMNode())),this.classNameQueue.length=0,this.timeout=null},componentWillMount:function(){this.classNameQueue=[]},componentWillUnmount:function(){this.timeout&&clearTimeout(this.timeout)},componentWillAppear:function(e){this.props.appear?this.transition("appear",e):e()},componentWillEnter:function(e){this.props.enter?this.transition("enter",e):e()},componentWillLeave:function(e){this.props.leave?this.transition("leave",e):e()},render:function(){return a(this.props.children)}});t.exports=u},{"./CSSCore":6,"./React":33,"./ReactTransitionEvents":99,"./onlyChild":163,"./warning":174}],38:[function(e,t,n){"use strict";var r=e("./ReactReconciler"),o=e("./flattenChildren"),i=e("./instantiateReactComponent"),a=e("./shouldUpdateReactComponent"),s={instantiateChildren:function(e,t,n){var r=o(e);for(var a in r)if(r.hasOwnProperty(a)){var s=r[a],u=i(s,null);r[a]=u}return r},updateChildren:function(e,t,n,s){var u=o(t);if(!u&&!e)return null;var l;for(l in u)if(u.hasOwnProperty(l)){var c=e&&e[l],p=c&&c._currentElement,d=u[l];if(a(p,d))r.receiveComponent(c,d,n,s),u[l]=c;else{c&&r.unmountComponent(c,l);var h=i(d,null);u[l]=h}}for(l in e)!e.hasOwnProperty(l)||u&&u.hasOwnProperty(l)||r.unmountComponent(e[l]);return u},unmountChildren:function(e){for(var t in e){var n=e[t];r.unmountComponent(n)}}};t.exports=s},{"./ReactReconciler":91,"./flattenChildren":136,"./instantiateReactComponent":152,"./shouldUpdateReactComponent":170}],39:[function(e,t,n){"use strict";function r(e,t){this.forEachFunction=e,this.forEachContext=t}function o(e,t,n,r){var o=e;o.forEachFunction.call(o.forEachContext,t,r)}function i(e,t,n){if(null==e)return e;var i=r.getPooled(t,n);h(e,o,i),r.release(i)}function a(e,t,n){this.mapResult=e,this.mapFunction=t,this.mapContext=n}function s(e,t,n,r){var o=e,i=o.mapResult,a=!i.hasOwnProperty(n);if(a){var s=o.mapFunction.call(o.mapContext,t,r);i[n]=s}}function u(e,t,n){if(null==e)return e;var r={},o=a.getPooled(r,t,n);return h(e,s,o),a.release(o),d.create(r)}function l(e,t,n,r){return null}function c(e,t){return h(e,l,null)}var p=e("./PooledClass"),d=e("./ReactFragment"),h=e("./traverseAllChildren"),f=(e("./warning"),p.twoArgumentPooler),m=p.threeArgumentPooler;p.addPoolingTo(r,f),p.addPoolingTo(a,m);var v={forEach:i,map:u,count:c};t.exports=v},{"./PooledClass":32,"./ReactFragment":71,"./traverseAllChildren":172,"./warning":174}],40:[function(e,t,n){"use strict";function r(e,t){var n=R.hasOwnProperty(t)?R[t]:null;D.hasOwnProperty(t)&&y(n===E.OVERRIDE_BASE),e.hasOwnProperty(t)&&y(n===E.DEFINE_MANY||n===E.DEFINE_MANY_MERGED)}function o(e,t){if(t){y("function"!=typeof t),y(!d.isValidElement(t));var n=e.prototype;t.hasOwnProperty(b)&&w.mixins(e,t.mixins);for(var o in t)if(t.hasOwnProperty(o)&&o!==b){var i=t[o];if(r(n,o),w.hasOwnProperty(o))w[o](e,i);else{var a=R.hasOwnProperty(o),l=n.hasOwnProperty(o),c=i&&i.__reactDontBind,p="function"==typeof i,h=p&&!a&&!l&&!c;if(h)n.__reactAutoBindMap||(n.__reactAutoBindMap={}),n.__reactAutoBindMap[o]=i,n[o]=i;else if(l){var f=R[o];y(a&&(f===E.DEFINE_MANY_MERGED||f===E.DEFINE_MANY)),f===E.DEFINE_MANY_MERGED?n[o]=s(n[o],i):f===E.DEFINE_MANY&&(n[o]=u(n[o],i))}else n[o]=i}}}}function i(e,t){if(t)for(var n in t){var r=t[n];if(t.hasOwnProperty(n)){var o=n in w;y(!o);var i=n in e;y(!i),e[n]=r}}}function a(e,t){y(e&&t&&"object"==typeof e&&"object"==typeof t);for(var n in t)t.hasOwnProperty(n)&&(y(void 0===e[n]),e[n]=t[n]);return e}function s(e,t){return function(){var n=e.apply(this,arguments),r=t.apply(this,arguments);if(null==n)return r;if(null==r)return n;var o={};return a(o,n),a(o,r),o}}function u(e,t){return function(){e.apply(this,arguments),t.apply(this,arguments)}}function l(e,t){var n=t.bind(e);return n}function c(e){for(var t in e.__reactAutoBindMap)if(e.__reactAutoBindMap.hasOwnProperty(t)){var n=e.__reactAutoBindMap[t];e[t]=l(e,h.guard(n,e.constructor.displayName+"."+t))}}var p=e("./ReactComponent"),d=(e("./ReactCurrentOwner"),e("./ReactElement")),h=e("./ReactErrorUtils"),f=e("./ReactInstanceMap"),m=e("./ReactLifeCycle"),v=(e("./ReactPropTypeLocations"),e("./ReactPropTypeLocationNames"),e("./ReactUpdateQueue")),g=e("./Object.assign"),y=e("./invariant"),_=e("./keyMirror"),C=e("./keyOf"),b=(e("./warning"),C({mixins:null})),E=_({DEFINE_ONCE:null,DEFINE_MANY:null,OVERRIDE_BASE:null,DEFINE_MANY_MERGED:null}),M=[],R={mixins:E.DEFINE_MANY,statics:E.DEFINE_MANY,propTypes:E.DEFINE_MANY,contextTypes:E.DEFINE_MANY,childContextTypes:E.DEFINE_MANY,getDefaultProps:E.DEFINE_MANY_MERGED,getInitialState:E.DEFINE_MANY_MERGED,getChildContext:E.DEFINE_MANY_MERGED,render:E.DEFINE_ONCE,componentWillMount:E.DEFINE_MANY,componentDidMount:E.DEFINE_MANY,componentWillReceiveProps:E.DEFINE_MANY,shouldComponentUpdate:E.DEFINE_ONCE,componentWillUpdate:E.DEFINE_MANY,componentDidUpdate:E.DEFINE_MANY,componentWillUnmount:E.DEFINE_MANY,updateComponent:E.OVERRIDE_BASE},w={displayName:function(e,t){e.displayName=t},mixins:function(e,t){if(t)for(var n=0;n";return this._createOpenTagMarkupAndPutListeners(t)+this._createContentMarkup(t,n)+o},_createOpenTagMarkupAndPutListeners:function(e){var t=this._currentElement.props,n="<"+this._tag;for(var r in t)if(t.hasOwnProperty(r)){var i=t[r];if(null!=i)if(b.hasOwnProperty(r))o(this._rootNodeID,r,i,e);else{r===M&&(i&&(i=this._previousStyleCopy=m({},t.style)),i=s.createMarkupForStyles(i));var a=l.createMarkupForProperty(r,i);a&&(n+=" "+a)}}if(e.renderToStaticMarkup)return n+">";var u=l.createMarkupForID(this._rootNodeID);return n+" "+u+">"},_createContentMarkup:function(e,t){var n="";("listing"===this._tag||"pre"===this._tag||"textarea"===this._tag)&&(n="\n");var r=this._currentElement.props,o=r.dangerouslySetInnerHTML;if(null!=o){if(null!=o.__html)return n+o.__html}else{var i=E[typeof r.children]?r.children:null,a=null!=i?null:r.children;if(null!=i)return n+v(i);if(null!=a){var s=this.mountChildren(a,e,t);return n+s.join("")}}return n},receiveComponent:function(e,t,n){var r=this._currentElement;this._currentElement=e,this.updateComponent(t,r,e,n)},updateComponent:function(e,t,n,o){r(this._currentElement.props),this._updateDOMProperties(t.props,e),this._updateDOMChildren(t.props,e,o)},_updateDOMProperties:function(e,t){var n,r,i,a=this._currentElement.props;for(n in e)if(!a.hasOwnProperty(n)&&e.hasOwnProperty(n))if(n===M){var s=this._previousStyleCopy;for(r in s)s.hasOwnProperty(r)&&(i=i||{},i[r]="");this._previousStyleCopy=null}else b.hasOwnProperty(n)?_(this._rootNodeID,n):(u.isStandardName[n]||u.isCustomAttribute(n))&&w.deletePropertyByID(this._rootNodeID,n);for(n in a){var l=a[n],c=n===M?this._previousStyleCopy:e[n];if(a.hasOwnProperty(n)&&l!==c)if(n===M)if(l?l=this._previousStyleCopy=m({},l):this._previousStyleCopy=null,c){for(r in c)!c.hasOwnProperty(r)||l&&l.hasOwnProperty(r)||(i=i||{},i[r]="");for(r in l)l.hasOwnProperty(r)&&c[r]!==l[r]&&(i=i||{},i[r]=l[r])}else i=l;else b.hasOwnProperty(n)?o(this._rootNodeID,n,l,t):(u.isStandardName[n]||u.isCustomAttribute(n))&&w.updatePropertyByID(this._rootNodeID,n,l)}i&&w.updateStylesByID(this._rootNodeID,i)},_updateDOMChildren:function(e,t,n){var r=this._currentElement.props,o=E[typeof e.children]?e.children:null,i=E[typeof r.children]?r.children:null,a=e.dangerouslySetInnerHTML&&e.dangerouslySetInnerHTML.__html,s=r.dangerouslySetInnerHTML&&r.dangerouslySetInnerHTML.__html,u=null!=o?null:e.children,l=null!=i?null:r.children,c=null!=o||null!=a,p=null!=i||null!=s;null!=u&&null==l?this.updateChildren(null,t,n):c&&!p&&this.updateTextContent(""),null!=i?o!==i&&this.updateTextContent(""+i):null!=s?a!==s&&w.updateInnerHTMLByID(this._rootNodeID,s):null!=l&&this.updateChildren(l,t,n)},unmountComponent:function(){this.unmountChildren(),c.deleteAllListeners(this._rootNodeID),p.unmountIDFromEnvironment(this._rootNodeID),this._rootNodeID=null}},f.measureMethods(a,"ReactDOMComponent",{mountComponent:"mountComponent",updateComponent:"updateComponent"}),m(a.prototype,a.Mixin,h.Mixin),a.injection={injectIDOperations:function(e){a.BackendIDOperations=w=e; +},onChange:u.func}},getValue:function(e){return e.props.valueLink?(o(e),e.props.valueLink.value):e.props.value},getChecked:function(e){return e.props.checkedLink?(i(e),e.props.checkedLink.value):e.props.checked},getOnChange:function(e){return e.props.valueLink?(o(e),a):e.props.checkedLink?(i(e),s):e.props.onChange}};t.exports=p},{"./ReactPropTypes":88,"./invariant":153}],29:[function(e,t,n){"use strict";function r(e){e.remove()}var o=e("./ReactBrowserEventEmitter"),i=e("./accumulateInto"),a=e("./forEachAccumulated"),s=e("./invariant"),u={trapBubbledEvent:function(e,t){s(this.isMounted());var n=this.getDOMNode();s(n);var r=o.trapBubbledEvent(e,t,n);this._localEventListeners=i(this._localEventListeners,r)},componentWillUnmount:function(){this._localEventListeners&&a(this._localEventListeners,r)}};t.exports=u},{"./ReactBrowserEventEmitter":35,"./accumulateInto":121,"./forEachAccumulated":138,"./invariant":153}],30:[function(e,t,n){"use strict";var r=e("./EventConstants"),o=e("./emptyFunction"),i=r.topLevelTypes,a={eventTypes:null,extractEvents:function(e,t,n,r){if(e===i.topTouchStart){var a=r.target;a&&!a.onclick&&(a.onclick=o)}}};t.exports=a},{"./EventConstants":18,"./emptyFunction":132}],31:[function(e,t,n){"use strict";function r(e,t){if(null==e)throw new TypeError("Object.assign target cannot be null or undefined");for(var n=Object(e),r=Object.prototype.hasOwnProperty,o=1;ol;l++){var d=s[l];i.hasOwnProperty(d)&&i[d]||(d===u.topWheel?c("wheel")?v.ReactEventListener.trapBubbledEvent(u.topWheel,"wheel",n):c("mousewheel")?v.ReactEventListener.trapBubbledEvent(u.topWheel,"mousewheel",n):v.ReactEventListener.trapBubbledEvent(u.topWheel,"DOMMouseScroll",n):d===u.topScroll?c("scroll",!0)?v.ReactEventListener.trapCapturedEvent(u.topScroll,"scroll",n):v.ReactEventListener.trapBubbledEvent(u.topScroll,"scroll",v.ReactEventListener.WINDOW_HANDLE):d===u.topFocus||d===u.topBlur?(c("focus",!0)?(v.ReactEventListener.trapCapturedEvent(u.topFocus,"focus",n),v.ReactEventListener.trapCapturedEvent(u.topBlur,"blur",n)):c("focusin")&&(v.ReactEventListener.trapBubbledEvent(u.topFocus,"focusin",n),v.ReactEventListener.trapBubbledEvent(u.topBlur,"focusout",n)),i[u.topBlur]=!0,i[u.topFocus]=!0):f.hasOwnProperty(d)&&v.ReactEventListener.trapBubbledEvent(d,f[d],n),i[d]=!0)}},trapBubbledEvent:function(e,t,n){return v.ReactEventListener.trapBubbledEvent(e,t,n)},trapCapturedEvent:function(e,t,n){return v.ReactEventListener.trapCapturedEvent(e,t,n)},ensureScrollValueMonitoring:function(){if(!d){var e=u.refreshScrollValues;v.ReactEventListener.monitorScrollValue(e),d=!0}},eventNameDispatchConfigs:i.eventNameDispatchConfigs,registrationNameModules:i.registrationNameModules,putListener:i.putListener,getListener:i.getListener,deleteListener:i.deleteListener,deleteAllListeners:i.deleteAllListeners});t.exports=v},{"./EventConstants":18,"./EventPluginHub":20,"./EventPluginRegistry":21,"./Object.assign":31,"./ReactEventEmitterMixin":69,"./ViewportMetrics":120,"./isEventSupported":154}],36:[function(e,t,n){"use strict";var r=e("./React"),o=e("./Object.assign"),i=r.createFactory(e("./ReactTransitionGroup")),a=r.createFactory(e("./ReactCSSTransitionGroupChild")),s=r.createClass({displayName:"ReactCSSTransitionGroup",propTypes:{transitionName:r.PropTypes.string.isRequired,transitionAppear:r.PropTypes.bool,transitionEnter:r.PropTypes.bool,transitionLeave:r.PropTypes.bool},getDefaultProps:function(){return{transitionAppear:!1,transitionEnter:!0,transitionLeave:!0}},_wrapChild:function(e){return a({name:this.props.transitionName,appear:this.props.transitionAppear,enter:this.props.transitionEnter,leave:this.props.transitionLeave},e)},render:function(){return i(o({},this.props,{childFactory:this._wrapChild}))}});t.exports=s},{"./Object.assign":31,"./React":33,"./ReactCSSTransitionGroupChild":37,"./ReactTransitionGroup":100}],37:[function(e,t,n){"use strict";var r=e("./React"),o=e("./CSSCore"),i=e("./ReactTransitionEvents"),a=e("./onlyChild"),s=(e("./warning"),17),u=r.createClass({displayName:"ReactCSSTransitionGroupChild",transition:function(e,t){var n=this.getDOMNode(),r=this.props.name+"-"+e,a=r+"-active",s=function(e){e&&e.target!==n||(o.removeClass(n,r),o.removeClass(n,a),i.removeEndEventListener(n,s),t&&t())};i.addEndEventListener(n,s),o.addClass(n,r),this.queueClass(a)},queueClass:function(e){this.classNameQueue.push(e),this.timeout||(this.timeout=setTimeout(this.flushClassNameQueue,s))},flushClassNameQueue:function(){this.isMounted()&&this.classNameQueue.forEach(o.addClass.bind(o,this.getDOMNode())),this.classNameQueue.length=0,this.timeout=null},componentWillMount:function(){this.classNameQueue=[]},componentWillUnmount:function(){this.timeout&&clearTimeout(this.timeout)},componentWillAppear:function(e){this.props.appear?this.transition("appear",e):e()},componentWillEnter:function(e){this.props.enter?this.transition("enter",e):e()},componentWillLeave:function(e){this.props.leave?this.transition("leave",e):e()},render:function(){return a(this.props.children)}});t.exports=u},{"./CSSCore":6,"./React":33,"./ReactTransitionEvents":99,"./onlyChild":163,"./warning":174}],38:[function(e,t,n){"use strict";var r=e("./ReactReconciler"),o=e("./flattenChildren"),i=e("./instantiateReactComponent"),a=e("./shouldUpdateReactComponent"),s={instantiateChildren:function(e,t,n){var r=o(e);for(var a in r)if(r.hasOwnProperty(a)){var s=r[a],u=i(s,null);r[a]=u}return r},updateChildren:function(e,t,n,s){var u=o(t);if(!u&&!e)return null;var l;for(l in u)if(u.hasOwnProperty(l)){var c=e&&e[l],p=c&&c._currentElement,d=u[l];if(a(p,d))r.receiveComponent(c,d,n,s),u[l]=c;else{c&&r.unmountComponent(c,l);var h=i(d,null);u[l]=h}}for(l in e)!e.hasOwnProperty(l)||u&&u.hasOwnProperty(l)||r.unmountComponent(e[l]);return u},unmountChildren:function(e){for(var t in e){var n=e[t];r.unmountComponent(n)}}};t.exports=s},{"./ReactReconciler":91,"./flattenChildren":136,"./instantiateReactComponent":152,"./shouldUpdateReactComponent":170}],39:[function(e,t,n){"use strict";function r(e,t){this.forEachFunction=e,this.forEachContext=t}function o(e,t,n,r){var o=e;o.forEachFunction.call(o.forEachContext,t,r)}function i(e,t,n){if(null==e)return e;var i=r.getPooled(t,n);h(e,o,i),r.release(i)}function a(e,t,n){this.mapResult=e,this.mapFunction=t,this.mapContext=n}function s(e,t,n,r){var o=e,i=o.mapResult,a=!i.hasOwnProperty(n);if(a){var s=o.mapFunction.call(o.mapContext,t,r);i[n]=s}}function u(e,t,n){if(null==e)return e;var r={},o=a.getPooled(r,t,n);return h(e,s,o),a.release(o),d.create(r)}function l(e,t,n,r){return null}function c(e,t){return h(e,l,null)}var p=e("./PooledClass"),d=e("./ReactFragment"),h=e("./traverseAllChildren"),f=(e("./warning"),p.twoArgumentPooler),m=p.threeArgumentPooler;p.addPoolingTo(r,f),p.addPoolingTo(a,m);var v={forEach:i,map:u,count:c};t.exports=v},{"./PooledClass":32,"./ReactFragment":71,"./traverseAllChildren":172,"./warning":174}],40:[function(e,t,n){"use strict";function r(e,t){var n=R.hasOwnProperty(t)?R[t]:null;D.hasOwnProperty(t)&&y(n===E.OVERRIDE_BASE),e.hasOwnProperty(t)&&y(n===E.DEFINE_MANY||n===E.DEFINE_MANY_MERGED)}function o(e,t){if(t){y("function"!=typeof t),y(!d.isValidElement(t));var n=e.prototype;t.hasOwnProperty(C)&&w.mixins(e,t.mixins);for(var o in t)if(t.hasOwnProperty(o)&&o!==C){var i=t[o];if(r(n,o),w.hasOwnProperty(o))w[o](e,i);else{var a=R.hasOwnProperty(o),l=n.hasOwnProperty(o),c=i&&i.__reactDontBind,p="function"==typeof i,h=p&&!a&&!l&&!c;if(h)n.__reactAutoBindMap||(n.__reactAutoBindMap={}),n.__reactAutoBindMap[o]=i,n[o]=i;else if(l){var f=R[o];y(a&&(f===E.DEFINE_MANY_MERGED||f===E.DEFINE_MANY)),f===E.DEFINE_MANY_MERGED?n[o]=s(n[o],i):f===E.DEFINE_MANY&&(n[o]=u(n[o],i))}else n[o]=i}}}}function i(e,t){if(t)for(var n in t){var r=t[n];if(t.hasOwnProperty(n)){var o=n in w;y(!o);var i=n in e;y(!i),e[n]=r}}}function a(e,t){y(e&&t&&"object"==typeof e&&"object"==typeof t);for(var n in t)t.hasOwnProperty(n)&&(y(void 0===e[n]),e[n]=t[n]);return e}function s(e,t){return function(){var n=e.apply(this,arguments),r=t.apply(this,arguments);if(null==n)return r;if(null==r)return n;var o={};return a(o,n),a(o,r),o}}function u(e,t){return function(){e.apply(this,arguments),t.apply(this,arguments)}}function l(e,t){var n=t.bind(e);return n}function c(e){for(var t in e.__reactAutoBindMap)if(e.__reactAutoBindMap.hasOwnProperty(t)){var n=e.__reactAutoBindMap[t];e[t]=l(e,h.guard(n,e.constructor.displayName+"."+t))}}var p=e("./ReactComponent"),d=(e("./ReactCurrentOwner"),e("./ReactElement")),h=e("./ReactErrorUtils"),f=e("./ReactInstanceMap"),m=e("./ReactLifeCycle"),v=(e("./ReactPropTypeLocations"),e("./ReactPropTypeLocationNames"),e("./ReactUpdateQueue")),g=e("./Object.assign"),y=e("./invariant"),_=e("./keyMirror"),b=e("./keyOf"),C=(e("./warning"),b({mixins:null})),E=_({DEFINE_ONCE:null,DEFINE_MANY:null,OVERRIDE_BASE:null,DEFINE_MANY_MERGED:null}),M=[],R={mixins:E.DEFINE_MANY,statics:E.DEFINE_MANY,propTypes:E.DEFINE_MANY,contextTypes:E.DEFINE_MANY,childContextTypes:E.DEFINE_MANY,getDefaultProps:E.DEFINE_MANY_MERGED,getInitialState:E.DEFINE_MANY_MERGED,getChildContext:E.DEFINE_MANY_MERGED,render:E.DEFINE_ONCE,componentWillMount:E.DEFINE_MANY,componentDidMount:E.DEFINE_MANY,componentWillReceiveProps:E.DEFINE_MANY,shouldComponentUpdate:E.DEFINE_ONCE,componentWillUpdate:E.DEFINE_MANY,componentDidUpdate:E.DEFINE_MANY,componentWillUnmount:E.DEFINE_MANY,updateComponent:E.OVERRIDE_BASE},w={displayName:function(e,t){e.displayName=t},mixins:function(e,t){if(t)for(var n=0;n";return this._createOpenTagMarkupAndPutListeners(t)+this._createContentMarkup(t,n)+o},_createOpenTagMarkupAndPutListeners:function(e){var t=this._currentElement.props,n="<"+this._tag;for(var r in t)if(t.hasOwnProperty(r)){var i=t[r];if(null!=i)if(C.hasOwnProperty(r))o(this._rootNodeID,r,i,e);else{r===M&&(i&&(i=this._previousStyleCopy=m({},t.style)),i=s.createMarkupForStyles(i));var a=l.createMarkupForProperty(r,i);a&&(n+=" "+a)}}if(e.renderToStaticMarkup)return n+">";var u=l.createMarkupForID(this._rootNodeID);return n+" "+u+">"},_createContentMarkup:function(e,t){var n="";("listing"===this._tag||"pre"===this._tag||"textarea"===this._tag)&&(n="\n");var r=this._currentElement.props,o=r.dangerouslySetInnerHTML;if(null!=o){if(null!=o.__html)return n+o.__html}else{var i=E[typeof r.children]?r.children:null,a=null!=i?null:r.children;if(null!=i)return n+v(i);if(null!=a){var s=this.mountChildren(a,e,t);return n+s.join("")}}return n},receiveComponent:function(e,t,n){var r=this._currentElement;this._currentElement=e,this.updateComponent(t,r,e,n)},updateComponent:function(e,t,n,o){r(this._currentElement.props),this._updateDOMProperties(t.props,e),this._updateDOMChildren(t.props,e,o)},_updateDOMProperties:function(e,t){var n,r,i,a=this._currentElement.props;for(n in e)if(!a.hasOwnProperty(n)&&e.hasOwnProperty(n))if(n===M){var s=this._previousStyleCopy;for(r in s)s.hasOwnProperty(r)&&(i=i||{},i[r]="");this._previousStyleCopy=null}else C.hasOwnProperty(n)?_(this._rootNodeID,n):(u.isStandardName[n]||u.isCustomAttribute(n))&&w.deletePropertyByID(this._rootNodeID,n);for(n in a){var l=a[n],c=n===M?this._previousStyleCopy:e[n];if(a.hasOwnProperty(n)&&l!==c)if(n===M)if(l?l=this._previousStyleCopy=m({},l):this._previousStyleCopy=null,c){for(r in c)!c.hasOwnProperty(r)||l&&l.hasOwnProperty(r)||(i=i||{},i[r]="");for(r in l)l.hasOwnProperty(r)&&c[r]!==l[r]&&(i=i||{},i[r]=l[r])}else i=l;else C.hasOwnProperty(n)?o(this._rootNodeID,n,l,t):(u.isStandardName[n]||u.isCustomAttribute(n))&&w.updatePropertyByID(this._rootNodeID,n,l)}i&&w.updateStylesByID(this._rootNodeID,i)},_updateDOMChildren:function(e,t,n){var r=this._currentElement.props,o=E[typeof e.children]?e.children:null,i=E[typeof r.children]?r.children:null,a=e.dangerouslySetInnerHTML&&e.dangerouslySetInnerHTML.__html,s=r.dangerouslySetInnerHTML&&r.dangerouslySetInnerHTML.__html,u=null!=o?null:e.children,l=null!=i?null:r.children,c=null!=o||null!=a,p=null!=i||null!=s;null!=u&&null==l?this.updateChildren(null,t,n):c&&!p&&this.updateTextContent(""),null!=i?o!==i&&this.updateTextContent(""+i):null!=s?a!==s&&w.updateInnerHTMLByID(this._rootNodeID,s):null!=l&&this.updateChildren(l,t,n)},unmountComponent:function(){this.unmountChildren(),c.deleteAllListeners(this._rootNodeID),p.unmountIDFromEnvironment(this._rootNodeID),this._rootNodeID=null}},f.measureMethods(a,"ReactDOMComponent",{mountComponent:"mountComponent",updateComponent:"updateComponent"}),m(a.prototype,a.Mixin,h.Mixin),a.injection={injectIDOperations:function(e){a.BackendIDOperations=w=e; -}},t.exports=a},{"./CSSPropertyOperations":8,"./DOMProperty":13,"./DOMPropertyOperations":14,"./Object.assign":31,"./ReactBrowserEventEmitter":35,"./ReactComponentBrowserEnvironment":42,"./ReactMount":79,"./ReactMultiChild":80,"./ReactPerf":84,"./escapeTextContentForBrowser":134,"./invariant":153,"./isEventSupported":154,"./keyOf":160,"./warning":174}],51:[function(e,t,n){"use strict";var r=e("./EventConstants"),o=e("./LocalEventTrapMixin"),i=e("./ReactBrowserComponentMixin"),a=e("./ReactClass"),s=e("./ReactElement"),u=s.createFactory("form"),l=a.createClass({displayName:"ReactDOMForm",tagName:"FORM",mixins:[i,o],render:function(){return u(this.props)},componentDidMount:function(){this.trapBubbledEvent(r.topLevelTypes.topReset,"reset"),this.trapBubbledEvent(r.topLevelTypes.topSubmit,"submit")}});t.exports=l},{"./EventConstants":18,"./LocalEventTrapMixin":29,"./ReactBrowserComponentMixin":34,"./ReactClass":40,"./ReactElement":65}],52:[function(e,t,n){"use strict";var r=e("./CSSPropertyOperations"),o=e("./DOMChildrenOperations"),i=e("./DOMPropertyOperations"),a=e("./ReactMount"),s=e("./ReactPerf"),u=e("./invariant"),l=e("./setInnerHTML"),c={dangerouslySetInnerHTML:"`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.",style:"`style` must be set using `updateStylesByID()`."},p={updatePropertyByID:function(e,t,n){var r=a.getNode(e);u(!c.hasOwnProperty(t)),null!=n?i.setValueForProperty(r,t,n):i.deleteValueForProperty(r,t)},deletePropertyByID:function(e,t,n){var r=a.getNode(e);u(!c.hasOwnProperty(t)),i.deleteValueForProperty(r,t,n)},updateStylesByID:function(e,t){var n=a.getNode(e);r.setValueForStyles(n,t)},updateInnerHTMLByID:function(e,t){var n=a.getNode(e);l(n,t)},updateTextContentByID:function(e,t){var n=a.getNode(e);o.updateTextContent(n,t)},dangerouslyReplaceNodeWithMarkupByID:function(e,t){var n=a.getNode(e);o.dangerouslyReplaceNodeWithMarkup(n,t)},dangerouslyProcessChildrenUpdates:function(e,t){for(var n=0;nl;l++){var f=u[l];if(f!==i&&f.form===i.form){var v=c.getID(f);h(v);var g=m[v];h(g),p.asap(r,g)}}}return t}});t.exports=v},{"./AutoFocusMixin":4,"./DOMPropertyOperations":14,"./LinkedValueUtils":28,"./Object.assign":31,"./ReactBrowserComponentMixin":34,"./ReactClass":40,"./ReactElement":65,"./ReactMount":79,"./ReactUpdates":102,"./invariant":153}],56:[function(e,t,n){"use strict";var r=e("./ReactBrowserComponentMixin"),o=e("./ReactClass"),i=e("./ReactElement"),a=(e("./warning"),i.createFactory("option")),s=o.createClass({displayName:"ReactDOMOption",tagName:"OPTION",mixins:[r],componentWillMount:function(){},render:function(){return a(this.props,this.props.children)}});t.exports=s},{"./ReactBrowserComponentMixin":34,"./ReactClass":40,"./ReactElement":65,"./warning":174}],57:[function(e,t,n){"use strict";function r(){if(this._pendingUpdate){this._pendingUpdate=!1;var e=s.getValue(this);null!=e&&this.isMounted()&&i(this,e)}}function o(e,t,n){if(null==e[t])return null;if(e.multiple){if(!Array.isArray(e[t]))return new Error("The `"+t+"` prop supplied to must be a scalar value if `multiple` is false.")}function i(e,t){var n,r,o,i=e.getDOMNode().options;if(e.props.multiple){for(n={},r=0,o=t.length;o>r;r++)n[""+t[r]]=!0;for(r=0,o=i.length;o>r;r++){var a=n.hasOwnProperty(i[r].value);i[r].selected!==a&&(i[r].selected=a)}}else{for(n=""+t,r=0,o=i.length;o>r;r++)if(i[r].value===n)return void(i[r].selected=!0);i.length&&(i[0].selected=!0)}}var a=e("./AutoFocusMixin"),s=e("./LinkedValueUtils"),u=e("./ReactBrowserComponentMixin"),l=e("./ReactClass"),c=e("./ReactElement"),p=e("./ReactUpdates"),d=e("./Object.assign"),h=c.createFactory("select"),f=l.createClass({displayName:"ReactDOMSelect",tagName:"SELECT",mixins:[a,s.Mixin,u],propTypes:{defaultValue:o,value:o},render:function(){var e=d({},this.props);return e.onChange=this._handleChange,e.value=null,h(e,this.props.children)},componentWillMount:function(){this._pendingUpdate=!1},componentDidMount:function(){var e=s.getValue(this);null!=e?i(this,e):null!=this.props.defaultValue&&i(this,this.props.defaultValue)},componentDidUpdate:function(e){var t=s.getValue(this);null!=t?(this._pendingUpdate=!1,i(this,t)):!e.multiple!=!this.props.multiple&&(null!=this.props.defaultValue?i(this,this.props.defaultValue):i(this,this.props.multiple?[]:""))},_handleChange:function(e){var t,n=s.getOnChange(this);return n&&(t=n.call(this,e)),this._pendingUpdate=!0,p.asap(r,this),t}});t.exports=f},{"./AutoFocusMixin":4,"./LinkedValueUtils":28,"./Object.assign":31,"./ReactBrowserComponentMixin":34,"./ReactClass":40,"./ReactElement":65,"./ReactUpdates":102}],58:[function(e,t,n){"use strict";function r(e,t,n,r){return e===n&&t===r}function o(e){var t=document.selection,n=t.createRange(),r=n.text.length,o=n.duplicate();o.moveToElementText(e),o.setEndPoint("EndToStart",n);var i=o.text.length,a=i+r;return{start:i,end:a}}function i(e){var t=window.getSelection&&window.getSelection();if(!t||0===t.rangeCount)return null;var n=t.anchorNode,o=t.anchorOffset,i=t.focusNode,a=t.focusOffset,s=t.getRangeAt(0),u=r(t.anchorNode,t.anchorOffset,t.focusNode,t.focusOffset),l=u?0:s.toString().length,c=s.cloneRange();c.selectNodeContents(e),c.setEnd(s.startContainer,s.startOffset);var p=r(c.startContainer,c.startOffset,c.endContainer,c.endOffset),d=p?0:c.toString().length,h=d+l,f=document.createRange();f.setStart(n,o),f.setEnd(i,a);var m=f.collapsed;return{start:m?h:d,end:m?d:h}}function a(e,t){var n,r,o=document.selection.createRange().duplicate();"undefined"==typeof t.end?(n=t.start,r=n):t.start>t.end?(n=t.end,r=t.start):(n=t.start,r=t.end),o.moveToElementText(e),o.moveStart("character",n),o.setEndPoint("EndToStart",o),o.moveEnd("character",r-n),o.select()}function s(e,t){if(window.getSelection){var n=window.getSelection(),r=e[c()].length,o=Math.min(t.start,r),i="undefined"==typeof t.end?o:Math.min(t.end,r);if(!n.extend&&o>i){var a=i;i=o,o=a}var s=l(e,o),u=l(e,i);if(s&&u){var p=document.createRange();p.setStart(s.node,s.offset),n.removeAllRanges(),o>i?(n.addRange(p),n.extend(u.node,u.offset)):(p.setEnd(u.node,u.offset),n.addRange(p))}}}var u=e("./ExecutionEnvironment"),l=e("./getNodeForCharacterOffset"),c=e("./getTextContentAccessor"),p=u.canUseDOM&&"selection"in document&&!("getSelection"in window),d={getOffsets:p?o:i,setOffsets:p?a:s};t.exports=d},{"./ExecutionEnvironment":24,"./getNodeForCharacterOffset":146,"./getTextContentAccessor":148}],59:[function(e,t,n){"use strict";var r=e("./DOMPropertyOperations"),o=e("./ReactComponentBrowserEnvironment"),i=e("./ReactDOMComponent"),a=e("./Object.assign"),s=e("./escapeTextContentForBrowser"),u=function(e){};a(u.prototype,{construct:function(e){this._currentElement=e,this._stringText=""+e,this._rootNodeID=null,this._mountIndex=0},mountComponent:function(e,t,n){this._rootNodeID=e;var o=s(this._stringText);return t.renderToStaticMarkup?o:""+o+""},receiveComponent:function(e,t){if(e!==this._currentElement){this._currentElement=e;var n=""+e;n!==this._stringText&&(this._stringText=n,i.BackendIDOperations.updateTextContentByID(this._rootNodeID,n))}},unmountComponent:function(){o.unmountIDFromEnvironment(this._rootNodeID)}}),t.exports=u},{"./DOMPropertyOperations":14,"./Object.assign":31,"./ReactComponentBrowserEnvironment":42,"./ReactDOMComponent":50,"./escapeTextContentForBrowser":134}],60:[function(e,t,n){"use strict";function r(){this.isMounted()&&this.forceUpdate()}var o=e("./AutoFocusMixin"),i=e("./DOMPropertyOperations"),a=e("./LinkedValueUtils"),s=e("./ReactBrowserComponentMixin"),u=e("./ReactClass"),l=e("./ReactElement"),c=e("./ReactUpdates"),p=e("./Object.assign"),d=e("./invariant"),h=(e("./warning"),l.createFactory("textarea")),f=u.createClass({displayName:"ReactDOMTextarea",tagName:"TEXTAREA",mixins:[o,a.Mixin,s],getInitialState:function(){var e=this.props.defaultValue,t=this.props.children;null!=t&&(d(null==e),Array.isArray(t)&&(d(t.length<=1),t=t[0]),e=""+t),null==e&&(e="");var n=a.getValue(this);return{initialValue:""+(null!=n?n:e)}},render:function(){var e=p({},this.props);return d(null==e.dangerouslySetInnerHTML),e.defaultValue=null,e.value=null,e.onChange=this._handleChange,h(e,this.state.initialValue)},componentDidUpdate:function(e,t,n){var r=a.getValue(this);if(null!=r){var o=this.getDOMNode();i.setValueForProperty(o,"value",""+r)}},_handleChange:function(e){var t,n=a.getOnChange(this);return n&&(t=n.call(this,e)),c.asap(r,this),t}});t.exports=f},{"./AutoFocusMixin":4,"./DOMPropertyOperations":14,"./LinkedValueUtils":28,"./Object.assign":31,"./ReactBrowserComponentMixin":34,"./ReactClass":40,"./ReactElement":65,"./ReactUpdates":102,"./invariant":153,"./warning":174}],61:[function(e,t,n){"use strict";function r(){this.reinitializeTransaction()}var o=e("./ReactUpdates"),i=e("./Transaction"),a=e("./Object.assign"),s=e("./emptyFunction"),u={initialize:s,close:function(){d.isBatchingUpdates=!1}},l={initialize:s,close:o.flushBatchedUpdates.bind(o)},c=[l,u];a(r.prototype,i.Mixin,{getTransactionWrappers:function(){return c}});var p=new r,d={isBatchingUpdates:!1,batchedUpdates:function(e,t,n,r,o){var i=d.isBatchingUpdates;d.isBatchingUpdates=!0,i?e(t,n,r,o):p.perform(e,null,t,n,r,o)}};t.exports=d},{"./Object.assign":31,"./ReactUpdates":102,"./Transaction":119,"./emptyFunction":132}],62:[function(e,t,n){"use strict";function r(e){return f.createClass({tagName:e.toUpperCase(),render:function(){return new x(e,null,null,null,null,this.props)}})}function o(){k.EventEmitter.injectReactEventListener(T),k.EventPluginHub.injectEventPluginOrder(u),k.EventPluginHub.injectInstanceHandle(P),k.EventPluginHub.injectMount(S),k.EventPluginHub.injectEventPluginsByName({SimpleEventPlugin:L,EnterLeaveEventPlugin:l,ChangeEventPlugin:a,MobileSafariClickEventPlugin:d,SelectEventPlugin:N,BeforeInputEventPlugin:i}),k.NativeComponent.injectGenericComponentClass(g),k.NativeComponent.injectTextComponentClass(O),k.NativeComponent.injectAutoWrapper(r),k.Class.injectMixin(h),k.NativeComponent.injectComponentClasses({button:y,form:_,iframe:E,img:C,input:M,option:R,select:w,textarea:D,html:F("html"),head:F("head"),body:F("body")}),k.DOMProperty.injectDOMPropertyConfig(p),k.DOMProperty.injectDOMPropertyConfig(U),k.EmptyComponent.injectEmptyComponent("noscript"),k.Updates.injectReconcileTransaction(I),k.Updates.injectBatchingStrategy(v),k.RootIndex.injectCreateReactRootIndex(c.canUseDOM?s.createReactRootIndex:A.createReactRootIndex),k.Component.injectEnvironment(m),k.DOMComponent.injectIDOperations(b)}var i=e("./BeforeInputEventPlugin"),a=e("./ChangeEventPlugin"),s=e("./ClientReactRootIndex"),u=e("./DefaultEventPluginOrder"),l=e("./EnterLeaveEventPlugin"),c=e("./ExecutionEnvironment"),p=e("./HTMLDOMPropertyConfig"),d=e("./MobileSafariClickEventPlugin"),h=e("./ReactBrowserComponentMixin"),f=e("./ReactClass"),m=e("./ReactComponentBrowserEnvironment"),v=e("./ReactDefaultBatchingStrategy"),g=e("./ReactDOMComponent"),y=e("./ReactDOMButton"),_=e("./ReactDOMForm"),C=e("./ReactDOMImg"),b=e("./ReactDOMIDOperations"),E=e("./ReactDOMIframe"),M=e("./ReactDOMInput"),R=e("./ReactDOMOption"),w=e("./ReactDOMSelect"),D=e("./ReactDOMTextarea"),O=e("./ReactDOMTextComponent"),x=e("./ReactElement"),T=e("./ReactEventListener"),k=e("./ReactInjection"),P=e("./ReactInstanceHandles"),S=e("./ReactMount"),I=e("./ReactReconcileTransaction"),N=e("./SelectEventPlugin"),A=e("./ServerReactRootIndex"),L=e("./SimpleEventPlugin"),U=e("./SVGDOMPropertyConfig"),F=e("./createFullPageComponent");t.exports={inject:o}},{"./BeforeInputEventPlugin":5,"./ChangeEventPlugin":10,"./ClientReactRootIndex":11,"./DefaultEventPluginOrder":16,"./EnterLeaveEventPlugin":17,"./ExecutionEnvironment":24,"./HTMLDOMPropertyConfig":26,"./MobileSafariClickEventPlugin":30,"./ReactBrowserComponentMixin":34,"./ReactClass":40,"./ReactComponentBrowserEnvironment":42,"./ReactDOMButton":49,"./ReactDOMComponent":50,"./ReactDOMForm":51,"./ReactDOMIDOperations":52,"./ReactDOMIframe":53,"./ReactDOMImg":54,"./ReactDOMInput":55,"./ReactDOMOption":56,"./ReactDOMSelect":57,"./ReactDOMTextComponent":59,"./ReactDOMTextarea":60,"./ReactDefaultBatchingStrategy":61,"./ReactDefaultPerf":63,"./ReactElement":65,"./ReactEventListener":70,"./ReactInjection":72,"./ReactInstanceHandles":74,"./ReactMount":79,"./ReactReconcileTransaction":90,"./SVGDOMPropertyConfig":104,"./SelectEventPlugin":105,"./ServerReactRootIndex":106,"./SimpleEventPlugin":107,"./createFullPageComponent":128}],63:[function(e,t,n){"use strict";function r(e){return Math.floor(100*e)/100}function o(e,t,n){e[t]=(e[t]||0)+n}var i=e("./DOMProperty"),a=e("./ReactDefaultPerfAnalysis"),s=e("./ReactMount"),u=e("./ReactPerf"),l=e("./performanceNow"),c={_allMeasurements:[],_mountStack:[0],_injected:!1,start:function(){c._injected||u.injection.injectMeasure(c.measure),c._allMeasurements.length=0,u.enableMeasure=!0},stop:function(){u.enableMeasure=!1},getLastMeasurements:function(){return c._allMeasurements},printExclusive:function(e){e=e||c._allMeasurements;var t=a.getExclusiveSummary(e);console.table(t.map(function(e){return{"Component class name":e.componentName,"Total inclusive time (ms)":r(e.inclusive),"Exclusive mount time (ms)":r(e.exclusive),"Exclusive render time (ms)":r(e.render),"Mount time per instance (ms)":r(e.exclusive/e.count),"Render time per instance (ms)":r(e.render/e.count),Instances:e.count}}))},printInclusive:function(e){e=e||c._allMeasurements;var t=a.getInclusiveSummary(e);console.table(t.map(function(e){return{"Owner > component":e.componentName,"Inclusive time (ms)":r(e.time),Instances:e.count}})),console.log("Total time:",a.getTotalTime(e).toFixed(2)+" ms")},getMeasurementsSummaryMap:function(e){var t=a.getInclusiveSummary(e,!0);return t.map(function(e){return{"Owner > component":e.componentName,"Wasted time (ms)":e.time,Instances:e.count}})},printWasted:function(e){e=e||c._allMeasurements,console.table(c.getMeasurementsSummaryMap(e)),console.log("Total time:",a.getTotalTime(e).toFixed(2)+" ms")},printDOM:function(e){e=e||c._allMeasurements;var t=a.getDOMSummary(e);console.table(t.map(function(e){var t={};return t[i.ID_ATTRIBUTE_NAME]=e.id,t.type=e.type,t.args=JSON.stringify(e.args),t})),console.log("Total time:",a.getTotalTime(e).toFixed(2)+" ms")},_recordWrite:function(e,t,n,r){var o=c._allMeasurements[c._allMeasurements.length-1].writes;o[e]=o[e]||[],o[e].push({type:t,time:n,args:r})},measure:function(e,t,n){return function(){for(var r=[],i=0,a=arguments.length;a>i;i++)r.push(arguments[i]);var u,p,d;if("_renderNewRootComponent"===t||"flushBatchedUpdates"===t)return c._allMeasurements.push({exclusive:{},inclusive:{},render:{},counts:{},writes:{},displayNames:{},totalTime:0}),d=l(),p=n.apply(this,r),c._allMeasurements[c._allMeasurements.length-1].totalTime=l()-d,p;if("_mountImageIntoNode"===t||"ReactDOMIDOperations"===e){if(d=l(),p=n.apply(this,r),u=l()-d,"_mountImageIntoNode"===t){var h=s.getID(r[1]);c._recordWrite(h,t,u,r[0])}else"dangerouslyProcessChildrenUpdates"===t?r[0].forEach(function(e){var t={};null!==e.fromIndex&&(t.fromIndex=e.fromIndex),null!==e.toIndex&&(t.toIndex=e.toIndex),null!==e.textContent&&(t.textContent=e.textContent),null!==e.markupIndex&&(t.markup=r[1][e.markupIndex]),c._recordWrite(e.parentID,e.type,u,t)}):c._recordWrite(r[0],t,u,Array.prototype.slice.call(r,1));return p}if("ReactCompositeComponent"!==e||"mountComponent"!==t&&"updateComponent"!==t&&"_renderValidatedComponent"!==t)return n.apply(this,r);if("string"==typeof this._currentElement.type)return n.apply(this,r);var f="mountComponent"===t?r[0]:this._rootNodeID,m="_renderValidatedComponent"===t,v="mountComponent"===t,g=c._mountStack,y=c._allMeasurements[c._allMeasurements.length-1];if(m?o(y.counts,f,1):v&&g.push(0),d=l(),p=n.apply(this,r),u=l()-d,m)o(y.render,f,u);else if(v){var _=g.pop();g[g.length-1]+=u,o(y.exclusive,f,u-_),o(y.inclusive,f,u)}else o(y.inclusive,f,u);return y.displayNames[f]={current:this.getName(),owner:this._currentElement._owner?this._currentElement._owner.getName():""},p}}};t.exports=c},{"./DOMProperty":13,"./ReactDefaultPerfAnalysis":64,"./ReactMount":79,"./ReactPerf":84,"./performanceNow":165}],64:[function(e,t,n){function r(e){for(var t=0,n=0;n=l&&s.push(n[t]);return s.sort(function(e,t){return t.exclusive-e.exclusive}),s}function a(e,t){for(var n,r={},o=0;o "+d.current,r[n]=r[n]||{componentName:n,time:0,count:0},a.inclusive[p]&&(r[n].time+=a.inclusive[p]),a.counts[p]&&(r[n].count+=a.counts[p])}}var h=[];for(n in r)r[n].time>=l&&h.push(r[n]);return h.sort(function(e,t){return t.time-e.time}),h}function s(e){var t={},n=Object.keys(e.writes),r=u({},e.exclusive,e.inclusive);for(var o in r){for(var i=!1,a=0;a0&&(t[o]=!0)}return t}var u=e("./Object.assign"),l=1.2,c={_mountImageIntoNode:"set innerHTML",INSERT_MARKUP:"set innerHTML",MOVE_EXISTING:"move",REMOVE_NODE:"remove",TEXT_CONTENT:"set textContent",updatePropertyByID:"update attribute",deletePropertyByID:"delete attribute",updateStylesByID:"update styles",updateInnerHTMLByID:"set innerHTML",dangerouslyReplaceNodeWithMarkupByID:"replace"},p={getExclusiveSummary:i,getInclusiveSummary:a,getDOMSummary:o,getTotalTime:r};t.exports=p},{"./Object.assign":31}],65:[function(e,t,n){"use strict";var r=e("./ReactContext"),o=e("./ReactCurrentOwner"),i=e("./Object.assign"),a=(e("./warning"),{key:!0,ref:!0}),s=function(e,t,n,r,o,i){this.type=e,this.key=t,this.ref=n,this._owner=r,this._context=o,this.props=i};s.prototype={_isReactElement:!0},s.createElement=function(e,t,n){var i,u={},l=null,c=null;if(null!=t){c=void 0===t.ref?null:t.ref,l=void 0===t.key?null:""+t.key;for(i in t)t.hasOwnProperty(i)&&!a.hasOwnProperty(i)&&(u[i]=t[i])}var p=arguments.length-2;if(1===p)u.children=n;else if(p>1){for(var d=Array(p),h=0;p>h;h++)d[h]=arguments[h+2];u.children=d}if(e&&e.defaultProps){var f=e.defaultProps;for(i in f)"undefined"==typeof u[i]&&(u[i]=f[i])}return new s(e,l,c,o.current,r.current,u)},s.createFactory=function(e){var t=s.createElement.bind(null,e);return t.type=e,t},s.cloneAndReplaceProps=function(e,t){var n=new s(e.type,e.key,e.ref,e._owner,e._context,t);return n},s.cloneElement=function(e,t,n){var r,u=i({},e.props),l=e.key,c=e.ref,p=e._owner;if(null!=t){void 0!==t.ref&&(c=t.ref,p=o.current),void 0!==t.key&&(l=""+t.key);for(r in t)t.hasOwnProperty(r)&&!a.hasOwnProperty(r)&&(u[r]=t[r])}var d=arguments.length-2;if(1===d)u.children=n;else if(d>1){for(var h=Array(d),f=0;d>f;f++)h[f]=arguments[f+2];u.children=h}return new s(e.type,l,c,p,e._context,u)},s.isValidElement=function(e){var t=!(!e||!e._isReactElement);return t},t.exports=s},{"./Object.assign":31,"./ReactContext":46,"./ReactCurrentOwner":47,"./warning":174}],66:[function(e,t,n){"use strict";function r(){if(y.current){var e=y.current.getName();if(e)return" Check the render method of `"+e+"`."}return""}function o(e){var t=e&&e.getPublicInstance();if(!t)return void 0;var n=t.constructor;return n?n.displayName||n.name||void 0:void 0}function i(){var e=y.current;return e&&o(e)||void 0}function a(e,t){e._store.validated||null!=e.key||(e._store.validated=!0,u('Each child in an array or iterator should have a unique "key" prop.',e,t))}function s(e,t,n){R.test(e)&&u("Child objects should have non-numeric keys so ordering is preserved.",t,n)}function u(e,t,n){var r=i(),a="string"==typeof n?n:n.displayName||n.name,s=r||a,u=E[e]||(E[e]={});if(!u.hasOwnProperty(s)){u[s]=!0;var l="";if(t&&t._owner&&t._owner!==y.current){var c=o(t._owner);l=" It was passed a child from "+c+"."}}}function l(e,t){if(Array.isArray(e))for(var n=0;n");var s="";o&&(s=" The element was created by "+o+".")}}function d(e,t){return e!==e?t!==t:0===e&&0===t?1/e===1/t:e===t}function h(e){if(e._store){var t=e._store.originalProps,n=e.props;for(var r in n)n.hasOwnProperty(r)&&(t.hasOwnProperty(r)&&d(t[r],n[r])||(p(r,e),t[r]=n[r]))}}function f(e){if(null!=e.type){var t=_.getComponentClassForElement(e),n=t.displayName||t.name;t.propTypes&&c(n,t.propTypes,e.props,g.prop),"function"==typeof t.getDefaultProps}}var m=e("./ReactElement"),v=e("./ReactFragment"),g=e("./ReactPropTypeLocations"),y=(e("./ReactPropTypeLocationNames"),e("./ReactCurrentOwner")),_=e("./ReactNativeComponent"),C=e("./getIteratorFn"),b=e("./invariant"),E=(e("./warning"),{}),M={},R=/^\d+$/,w={},D={checkAndWarnForMutatedProps:h,createElement:function(e,t,n){var r=m.createElement.apply(this,arguments);if(null==r)return r;for(var o=2;oo;o++){t=e.ancestors[o];var a=p.getID(t)||"";v._handleTopLevel(e.topLevelType,t,a,e.nativeEvent)}}function a(e){var t=m(window);e(t)}var s=e("./EventListener"),u=e("./ExecutionEnvironment"),l=e("./PooledClass"),c=e("./ReactInstanceHandles"),p=e("./ReactMount"),d=e("./ReactUpdates"),h=e("./Object.assign"),f=e("./getEventTarget"),m=e("./getUnboundedScrollPosition");h(o.prototype,{destructor:function(){this.topLevelType=null,this.nativeEvent=null,this.ancestors.length=0}}),l.addPoolingTo(o,l.twoArgumentPooler);var v={_enabled:!0,_handleTopLevel:null,WINDOW_HANDLE:u.canUseDOM?window:null,setHandleTopLevel:function(e){v._handleTopLevel=e},setEnabled:function(e){v._enabled=!!e},isEnabled:function(){return v._enabled},trapBubbledEvent:function(e,t,n){var r=n;return r?s.listen(r,t,v.dispatchEvent.bind(null,e)):null},trapCapturedEvent:function(e,t,n){var r=n;return r?s.capture(r,t,v.dispatchEvent.bind(null,e)):null},monitorScrollValue:function(e){var t=a.bind(null,e);s.listen(window,"scroll",t)},dispatchEvent:function(e,t){if(v._enabled){var n=o.getPooled(e,t);try{d.batchedUpdates(i,n)}finally{o.release(n)}}}};t.exports=v},{"./EventListener":19,"./ExecutionEnvironment":24,"./Object.assign":31,"./PooledClass":32,"./ReactInstanceHandles":74,"./ReactMount":79,"./ReactUpdates":102,"./getEventTarget":143,"./getUnboundedScrollPosition":149}],71:[function(e,t,n){"use strict";var r=(e("./ReactElement"),e("./warning"),{create:function(e){return e},extract:function(e){return e},extractIfFragment:function(e){return e}});t.exports=r},{"./ReactElement":65,"./warning":174}],72:[function(e,t,n){"use strict";var r=e("./DOMProperty"),o=e("./EventPluginHub"),i=e("./ReactComponentEnvironment"),a=e("./ReactClass"),s=e("./ReactEmptyComponent"),u=e("./ReactBrowserEventEmitter"),l=e("./ReactNativeComponent"),c=e("./ReactDOMComponent"),p=e("./ReactPerf"),d=e("./ReactRootIndex"),h=e("./ReactUpdates"),f={Component:i.injection,Class:a.injection,DOMComponent:c.injection,DOMProperty:r.injection,EmptyComponent:s.injection,EventPluginHub:o.injection,EventEmitter:u.injection,NativeComponent:l.injection,Perf:p.injection,RootIndex:d.injection,Updates:h.injection};t.exports=f},{"./DOMProperty":13,"./EventPluginHub":20,"./ReactBrowserEventEmitter":35,"./ReactClass":40,"./ReactComponentEnvironment":43,"./ReactDOMComponent":50,"./ReactEmptyComponent":67,"./ReactNativeComponent":82,"./ReactPerf":84,"./ReactRootIndex":93,"./ReactUpdates":102}],73:[function(e,t,n){"use strict";function r(e){return i(document.documentElement,e)}var o=e("./ReactDOMSelection"),i=e("./containsNode"),a=e("./focusNode"),s=e("./getActiveElement"),u={hasSelectionCapabilities:function(e){return e&&("INPUT"===e.nodeName&&"text"===e.type||"TEXTAREA"===e.nodeName||"true"===e.contentEditable)},getSelectionInformation:function(){var e=s();return{focusedElem:e,selectionRange:u.hasSelectionCapabilities(e)?u.getSelection(e):null}},restoreSelection:function(e){var t=s(),n=e.focusedElem,o=e.selectionRange;t!==n&&r(n)&&(u.hasSelectionCapabilities(n)&&u.setSelection(n,o),a(n))},getSelection:function(e){var t;if("selectionStart"in e)t={start:e.selectionStart,end:e.selectionEnd};else if(document.selection&&"INPUT"===e.nodeName){var n=document.selection.createRange();n.parentElement()===e&&(t={start:-n.moveStart("character",-e.value.length),end:-n.moveEnd("character",-e.value.length)})}else t=o.getOffsets(e);return t||{start:0,end:0}},setSelection:function(e,t){var n=t.start,r=t.end;if("undefined"==typeof r&&(r=n),"selectionStart"in e)e.selectionStart=n,e.selectionEnd=Math.min(r,e.value.length);else if(document.selection&&"INPUT"===e.nodeName){var i=e.createTextRange();i.collapse(!0),i.moveStart("character",n),i.moveEnd("character",r-n),i.select()}else o.setOffsets(e,t)}};t.exports=u},{"./ReactDOMSelection":58,"./containsNode":126,"./focusNode":137,"./getActiveElement":139}],74:[function(e,t,n){"use strict";function r(e){return h+e.toString(36)}function o(e,t){return e.charAt(t)===h||t===e.length}function i(e){return""===e||e.charAt(0)===h&&e.charAt(e.length-1)!==h}function a(e,t){return 0===t.indexOf(e)&&o(t,e.length)}function s(e){return e?e.substr(0,e.lastIndexOf(h)):""}function u(e,t){if(d(i(e)&&i(t)),d(a(e,t)),e===t)return e;var n,r=e.length+f;for(n=r;n=a;a++)if(o(e,a)&&o(t,a))r=a;else if(e.charAt(a)!==t.charAt(a))break;var s=e.substr(0,r);return d(i(s)),s}function c(e,t,n,r,o,i){e=e||"",t=t||"",d(e!==t);var l=a(t,e);d(l||a(e,t));for(var c=0,p=l?s:u,h=e;;h=p(h,t)){var f;if(o&&h===e||i&&h===t||(f=n(h,l,r)),f===!1||h===t)break;d(c++1){var t=e.indexOf(h,1);return t>-1?e.substr(0,t):e}return null},traverseEnterLeave:function(e,t,n,r,o){var i=l(e,t);i!==e&&c(e,i,n,r,!1,!0),i!==t&&c(i,t,n,o,!0,!1)},traverseTwoPhase:function(e,t,n){e&&(c("",e,t,n,!0,!1),c(e,"",t,n,!1,!0))},traverseAncestors:function(e,t,n){c("",e,t,n,!0,!1)},_getFirstCommonAncestorID:l,_getNextDescendantID:u,isAncestorIDOf:a,SEPARATOR:h};t.exports=v},{"./ReactRootIndex":93,"./invariant":153}],75:[function(e,t,n){"use strict";var r={remove:function(e){e._reactInternalInstance=void 0},get:function(e){return e._reactInternalInstance},has:function(e){return void 0!==e._reactInternalInstance},set:function(e,t){e._reactInternalInstance=t}};t.exports=r},{}],76:[function(e,t,n){"use strict";var r={currentlyMountingInstance:null,currentlyUnmountingInstance:null};t.exports=r},{}],77:[function(e,t,n){"use strict";function r(e,t){this.value=e,this.requestChange=t}function o(e){var t={value:"undefined"==typeof e?i.PropTypes.any.isRequired:e.isRequired,requestChange:i.PropTypes.func.isRequired};return i.PropTypes.shape(t)}var i=e("./React");r.PropTypes={link:o},t.exports=r},{"./React":33}],78:[function(e,t,n){"use strict";var r=e("./adler32"),o={CHECKSUM_ATTR_NAME:"data-react-checksum",addChecksumToMarkup:function(e){var t=r(e);return e.replace(">"," "+o.CHECKSUM_ATTR_NAME+'="'+t+'">')},canReuseMarkup:function(e,t){var n=t.getAttribute(o.CHECKSUM_ATTR_NAME);n=n&&parseInt(n,10);var i=r(e);return i===n}};t.exports=o},{"./adler32":122}],79:[function(e,t,n){"use strict";function r(e,t){for(var n=Math.min(e.length,t.length),r=0;n>r;r++)if(e.charAt(r)!==t.charAt(r))return r;return e.length===t.length?-1:n}function o(e){var t=T(e);return t&&W.getID(t)}function i(e){var t=a(e);if(t)if(L.hasOwnProperty(t)){var n=L[t];n!==e&&(P(!c(n,t)),L[t]=e)}else L[t]=e;return t}function a(e){return e&&e.getAttribute&&e.getAttribute(A)||""}function s(e,t){var n=a(e);n!==t&&delete L[n],e.setAttribute(A,t),L[t]=e}function u(e){return L.hasOwnProperty(e)&&c(L[e],e)||(L[e]=W.findReactNodeByID(e)),L[e]}function l(e){var t=b.get(e)._rootNodeID;return _.isNullComponentID(t)?null:(L.hasOwnProperty(t)&&c(L[t],t)||(L[t]=W.findReactNodeByID(t)),L[t])}function c(e,t){if(e){P(a(e)===t);var n=W.findReactContainerForID(t);if(n&&x(n,e))return!0}return!1}function p(e){delete L[e]}function d(e){var t=L[e];return t&&c(t,e)?void(Y=t):!1}function h(e){Y=null,C.traverseAncestors(e,d);var t=Y;return Y=null,t}function f(e,t,n,r,o){var i=R.mountComponent(e,t,r,O);e._isTopLevel=!0,W._mountImageIntoNode(i,n,o)}function m(e,t,n,r){var o=D.ReactReconcileTransaction.getPooled();o.perform(f,null,e,t,n,o,r),D.ReactReconcileTransaction.release(o)}var v=e("./DOMProperty"),g=e("./ReactBrowserEventEmitter"),y=(e("./ReactCurrentOwner"),e("./ReactElement")),_=(e("./ReactElementValidator"),e("./ReactEmptyComponent")),C=e("./ReactInstanceHandles"),b=e("./ReactInstanceMap"),E=e("./ReactMarkupChecksum"),M=e("./ReactPerf"),R=e("./ReactReconciler"),w=e("./ReactUpdateQueue"),D=e("./ReactUpdates"),O=e("./emptyObject"),x=e("./containsNode"),T=e("./getReactRootElementInContainer"),k=e("./instantiateReactComponent"),P=e("./invariant"),S=e("./setInnerHTML"),I=e("./shouldUpdateReactComponent"),N=(e("./warning"),C.SEPARATOR),A=v.ID_ATTRIBUTE_NAME,L={},U=1,F=9,j={},B={},V=[],Y=null,W={_instancesByReactRootID:j,scrollMonitor:function(e,t){t()},_updateRootComponent:function(e,t,n,r){return W.scrollMonitor(n,function(){w.enqueueElementInternal(e,t),r&&w.enqueueCallbackInternal(e,r)}),e},_registerComponent:function(e,t){P(t&&(t.nodeType===U||t.nodeType===F)),g.ensureScrollValueMonitoring();var n=W.registerContainer(t);return j[n]=e,n},_renderNewRootComponent:function(e,t,n){var r=k(e,null),o=W._registerComponent(r,t);return D.batchedUpdates(m,r,o,t,n),r},render:function(e,t,n){P(y.isValidElement(e));var r=j[o(t)];if(r){var i=r._currentElement;if(I(i,e))return W._updateRootComponent(r,e,t,n).getPublicInstance();W.unmountComponentAtNode(t)}var a=T(t),s=a&&W.isRenderedByReact(a),u=s&&!r,l=W._renderNewRootComponent(e,t,u).getPublicInstance();return n&&n.call(l),l},constructAndRenderComponent:function(e,t,n){var r=y.createElement(e,t);return W.render(r,n)},constructAndRenderComponentByID:function(e,t,n){var r=document.getElementById(n);return P(r),W.constructAndRenderComponent(e,t,r)},registerContainer:function(e){var t=o(e);return t&&(t=C.getReactRootIDFromNodeID(t)),t||(t=C.createReactRootID()),B[t]=e,t},unmountComponentAtNode:function(e){P(e&&(e.nodeType===U||e.nodeType===F));var t=o(e),n=j[t];return n?(W.unmountComponentFromNode(n,e),delete j[t],delete B[t],!0):!1},unmountComponentFromNode:function(e,t){for(R.unmountComponent(e),t.nodeType===F&&(t=t.documentElement);t.lastChild;)t.removeChild(t.lastChild)},findReactContainerForID:function(e){var t=C.getReactRootIDFromNodeID(e),n=B[t];return n},findReactNodeByID:function(e){var t=W.findReactContainerForID(e);return W.findComponentRoot(t,e)},isRenderedByReact:function(e){if(1!==e.nodeType)return!1;var t=W.getID(e);return t?t.charAt(0)===N:!1},getFirstReactDOM:function(e){for(var t=e;t&&t.parentNode!==t;){if(W.isRenderedByReact(t))return t;t=t.parentNode}return null},findComponentRoot:function(e,t){var n=V,r=0,o=h(t)||e;for(n[0]=o.firstChild,n.length=1;r>",E=s(),M=d(),R={array:o("array"),bool:o("boolean"),func:o("function"),number:o("number"),object:o("object"),string:o("string"),any:i(),arrayOf:a,element:E,instanceOf:u,node:M,objectOf:c,oneOf:l,oneOfType:p,shape:h};t.exports=R},{"./ReactElement":65,"./ReactFragment":71,"./ReactPropTypeLocationNames":86,"./emptyFunction":132}],89:[function(e,t,n){"use strict";function r(){this.listenersToPut=[]}var o=e("./PooledClass"),i=e("./ReactBrowserEventEmitter"),a=e("./Object.assign");a(r.prototype,{enqueuePutListener:function(e,t,n){this.listenersToPut.push({rootNodeID:e,propKey:t,propValue:n})},putListeners:function(){for(var e=0;en;n++){var r=g[n],o=r._pendingCallbacks;if(r._pendingCallbacks=null,h.performUpdateIfNecessary(r,e.reconcileTransaction),o)for(var i=0;i":">","<":"<",'"':""","'":"'"},a=/[&><"']/g;t.exports=o},{}],135:[function(e,t,n){"use strict";function r(e){return null==e?null:s(e)?e:o.has(e)?i.getNodeFromInstance(e):(a(null==e.render||"function"!=typeof e.render),void a(!1))}{var o=(e("./ReactCurrentOwner"),e("./ReactInstanceMap")),i=e("./ReactMount"),a=e("./invariant"),s=e("./isNode");e("./warning")}t.exports=r},{"./ReactCurrentOwner":47,"./ReactInstanceMap":75,"./ReactMount":79,"./invariant":153,"./isNode":155,"./warning":174}],136:[function(e,t,n){"use strict";function r(e,t,n){var r=e,o=!r.hasOwnProperty(n);o&&null!=t&&(r[n]=t)}function o(e){if(null==e)return e;var t={};return i(e,r,t),t}{var i=e("./traverseAllChildren");e("./warning")}t.exports=o},{"./traverseAllChildren":172,"./warning":174}],137:[function(e,t,n){"use strict";function r(e){try{e.focus()}catch(t){}}t.exports=r},{}],138:[function(e,t,n){"use strict";var r=function(e,t,n){Array.isArray(e)?e.forEach(t,n):e&&t.call(n,e)};t.exports=r},{}],139:[function(e,t,n){function r(){try{return document.activeElement||document.body}catch(e){return document.body}}t.exports=r},{}],140:[function(e,t,n){"use strict";function r(e){var t,n=e.keyCode;return"charCode"in e?(t=e.charCode,0===t&&13===n&&(t=13)):t=n,t>=32||13===t?t:0}t.exports=r},{}],141:[function(e,t,n){"use strict";function r(e){if(e.key){var t=i[e.key]||e.key;if("Unidentified"!==t)return t}if("keypress"===e.type){var n=o(e);return 13===n?"Enter":String.fromCharCode(n)}return"keydown"===e.type||"keyup"===e.type?a[e.keyCode]||"Unidentified":""}var o=e("./getEventCharCode"),i={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},a={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"};t.exports=r},{"./getEventCharCode":140}],142:[function(e,t,n){"use strict";function r(e){var t=this,n=t.nativeEvent;if(n.getModifierState)return n.getModifierState(e);var r=i[e];return r?!!n[r]:!1}function o(e){return r}var i={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};t.exports=o},{}],143:[function(e,t,n){"use strict";function r(e){var t=e.target||e.srcElement||window;return 3===t.nodeType?t.parentNode:t}t.exports=r},{}],144:[function(e,t,n){"use strict";function r(e){var t=e&&(o&&e[o]||e[i]);return"function"==typeof t?t:void 0}var o="function"==typeof Symbol&&Symbol.iterator,i="@@iterator";t.exports=r},{}],145:[function(e,t,n){function r(e){return i(!!a),d.hasOwnProperty(e)||(e="*"),s.hasOwnProperty(e)||(a.innerHTML="*"===e?"":"<"+e+">",s[e]=!a.firstChild),s[e]?d[e]:null}var o=e("./ExecutionEnvironment"),i=e("./invariant"),a=o.canUseDOM?document.createElement("div"):null,s={circle:!0,clipPath:!0,defs:!0,ellipse:!0,g:!0,line:!0,linearGradient:!0,path:!0,polygon:!0,polyline:!0,radialGradient:!0,rect:!0,stop:!0,text:!0},u=[1,'"],l=[1,"","
"],c=[3,"","
"],p=[1,"",""],d={"*":[1,"?
","
"],area:[1,"",""],col:[2,"","
"],legend:[1,"
","
"],param:[1,"",""],tr:[2,"","
"],optgroup:u,option:u,caption:l,colgroup:l,tbody:l,tfoot:l,thead:l,td:c,th:c,circle:p,clipPath:p,defs:p,ellipse:p,g:p,line:p,linearGradient:p,path:p,polygon:p,polyline:p,radialGradient:p,rect:p,stop:p,text:p};t.exports=r},{"./ExecutionEnvironment":24,"./invariant":153}],146:[function(e,t,n){"use strict";function r(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function o(e){for(;e;){if(e.nextSibling)return e.nextSibling;e=e.parentNode}}function i(e,t){for(var n=r(e),i=0,a=0;n;){if(3===n.nodeType){if(a=i+n.textContent.length,t>=i&&a>=t)return{node:n,offset:t-i};i=a}n=r(o(n))}}t.exports=i},{}],147:[function(e,t,n){"use strict";function r(e){return e?e.nodeType===o?e.documentElement:e.firstChild:null}var o=9;t.exports=r},{}],148:[function(e,t,n){"use strict";function r(){return!i&&o.canUseDOM&&(i="textContent"in document.documentElement?"textContent":"innerText"),i}var o=e("./ExecutionEnvironment"),i=null;t.exports=r},{"./ExecutionEnvironment":24}],149:[function(e,t,n){"use strict";function r(e){return e===window?{x:window.pageXOffset||document.documentElement.scrollLeft,y:window.pageYOffset||document.documentElement.scrollTop}:{x:e.scrollLeft,y:e.scrollTop}}t.exports=r},{}],150:[function(e,t,n){function r(e){return e.replace(o,"-$1").toLowerCase()}var o=/([A-Z])/g;t.exports=r},{}],151:[function(e,t,n){"use strict";function r(e){return o(e).replace(i,"-ms-")}var o=e("./hyphenate"),i=/^ms-/;t.exports=r},{"./hyphenate":150}],152:[function(e,t,n){"use strict";function r(e){return"function"==typeof e&&"undefined"!=typeof e.prototype&&"function"==typeof e.prototype.mountComponent&&"function"==typeof e.prototype.receiveComponent}function o(e,t){var n;if((null===e||e===!1)&&(e=a.emptyElement),"object"==typeof e){var o=e;n=t===o.type&&"string"==typeof o.type?s.createInternalComponent(o):r(o.type)?new o.type(o):new c}else"string"==typeof e||"number"==typeof e?n=s.createInstanceForText(e):l(!1);return n.construct(e),n._mountIndex=0,n._mountImage=null,n}var i=e("./ReactCompositeComponent"),a=e("./ReactEmptyComponent"),s=e("./ReactNativeComponent"),u=e("./Object.assign"),l=e("./invariant"),c=(e("./warning"),function(){});u(c.prototype,i.Mixin,{_instantiateReactComponent:o}),t.exports=o},{"./Object.assign":31,"./ReactCompositeComponent":45,"./ReactEmptyComponent":67,"./ReactNativeComponent":82,"./invariant":153,"./warning":174}],153:[function(e,t,n){"use strict";var r=function(e,t,n,r,o,i,a,s){if(!e){var u;if(void 0===t)u=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var l=[n,r,o,i,a,s],c=0;u=new Error("Invariant Violation: "+t.replace(/%s/g,function(){return l[c++]}))}throw u.framesToPop=1,u}};t.exports=r},{}],154:[function(e,t,n){"use strict";function r(e,t){if(!i.canUseDOM||t&&!("addEventListener"in document))return!1;var n="on"+e,r=n in document;if(!r){var a=document.createElement("div");a.setAttribute(n,"return;"),r="function"==typeof a[n]}return!r&&o&&"wheel"===e&&(r=document.implementation.hasFeature("Events.wheel","3.0")),r}var o,i=e("./ExecutionEnvironment");i.canUseDOM&&(o=document.implementation&&document.implementation.hasFeature&&document.implementation.hasFeature("","")!==!0),t.exports=r},{"./ExecutionEnvironment":24}],155:[function(e,t,n){function r(e){return!(!e||!("function"==typeof Node?e instanceof Node:"object"==typeof e&&"number"==typeof e.nodeType&&"string"==typeof e.nodeName))}t.exports=r},{}],156:[function(e,t,n){"use strict";function r(e){return e&&("INPUT"===e.nodeName&&o[e.type]||"TEXTAREA"===e.nodeName)}var o={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};t.exports=r},{}],157:[function(e,t,n){function r(e){return o(e)&&3==e.nodeType}var o=e("./isNode");t.exports=r},{"./isNode":155}],158:[function(e,t,n){"use strict";function r(e){e||(e="");var t,n=arguments.length;if(n>1)for(var r=1;n>r;r++)t=arguments[r],t&&(e=(e?e+" ":"")+t);return e}t.exports=r},{}],159:[function(e,t,n){"use strict";var r=e("./invariant"),o=function(e){var t,n={};r(e instanceof Object&&!Array.isArray(e));for(t in e)e.hasOwnProperty(t)&&(n[t]=t);return n};t.exports=o},{"./invariant":153}],160:[function(e,t,n){var r=function(e){var t;for(t in e)if(e.hasOwnProperty(t))return t;return null};t.exports=r},{}],161:[function(e,t,n){"use strict";function r(e,t,n){if(!e)return null;var r={};for(var i in e)o.call(e,i)&&(r[i]=t.call(n,e[i],i,e));return r}var o=Object.prototype.hasOwnProperty;t.exports=r},{}],162:[function(e,t,n){"use strict";function r(e){var t={};return function(n){return t.hasOwnProperty(n)||(t[n]=e.call(this,n)),t[n]}}t.exports=r},{}],163:[function(e,t,n){"use strict";function r(e){return i(o.isValidElement(e)),e}var o=e("./ReactElement"),i=e("./invariant");t.exports=r},{"./ReactElement":65,"./invariant":153}],164:[function(e,t,n){"use strict";var r,o=e("./ExecutionEnvironment");o.canUseDOM&&(r=window.performance||window.msPerformance||window.webkitPerformance),t.exports=r||{}},{"./ExecutionEnvironment":24}],165:[function(e,t,n){var r=e("./performance");r&&r.now||(r=Date);var o=r.now.bind(r);t.exports=o},{"./performance":164}],166:[function(e,t,n){"use strict";function r(e){return'"'+o(e)+'"'}var o=e("./escapeTextContentForBrowser");t.exports=r},{"./escapeTextContentForBrowser":134}],167:[function(e,t,n){"use strict";var r=e("./ExecutionEnvironment"),o=/^[ \r\n\t\f]/,i=/<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/,a=function(e,t){e.innerHTML=t};if("undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction&&(a=function(e,t){MSApp.execUnsafeLocalFunction(function(){ -e.innerHTML=t})}),r.canUseDOM){var s=document.createElement("div");s.innerHTML=" ",""===s.innerHTML&&(a=function(e,t){if(e.parentNode&&e.parentNode.replaceChild(e,e),o.test(t)||"<"===t[0]&&i.test(t)){e.innerHTML="\ufeff"+t;var n=e.firstChild;1===n.data.length?e.removeChild(n):n.deleteData(0,1)}else e.innerHTML=t})}t.exports=a},{"./ExecutionEnvironment":24}],168:[function(e,t,n){"use strict";var r=e("./ExecutionEnvironment"),o=e("./escapeTextContentForBrowser"),i=e("./setInnerHTML"),a=function(e,t){e.textContent=t};r.canUseDOM&&("textContent"in document.documentElement||(a=function(e,t){i(e,o(t))})),t.exports=a},{"./ExecutionEnvironment":24,"./escapeTextContentForBrowser":134,"./setInnerHTML":167}],169:[function(e,t,n){"use strict";function r(e,t){if(e===t)return!0;var n;for(n in e)if(e.hasOwnProperty(n)&&(!t.hasOwnProperty(n)||e[n]!==t[n]))return!1;for(n in t)if(t.hasOwnProperty(n)&&!e.hasOwnProperty(n))return!1;return!0}t.exports=r},{}],170:[function(e,t,n){"use strict";function r(e,t){if(null!=e&&null!=t){var n=typeof e,r=typeof t;if("string"===n||"number"===n)return"string"===r||"number"===r;if("object"===r&&e.type===t.type&&e.key===t.key){var o=e._owner===t._owner;return o}}return!1}e("./warning");t.exports=r},{"./warning":174}],171:[function(e,t,n){function r(e){var t=e.length;if(o(!Array.isArray(e)&&("object"==typeof e||"function"==typeof e)),o("number"==typeof t),o(0===t||t-1 in e),e.hasOwnProperty)try{return Array.prototype.slice.call(e)}catch(n){}for(var r=Array(t),i=0;t>i;i++)r[i]=e[i];return r}var o=e("./invariant");t.exports=r},{"./invariant":153}],172:[function(e,t,n){"use strict";function r(e){return v[e]}function o(e,t){return e&&null!=e.key?a(e.key):t.toString(36)}function i(e){return(""+e).replace(g,r)}function a(e){return"$"+i(e)}function s(e,t,n,r,i){var u=typeof e;if(("undefined"===u||"boolean"===u)&&(e=null),null===e||"string"===u||"number"===u||l.isValidElement(e))return r(i,e,""===t?f+o(e,0):t,n),1;var p,v,g,y=0;if(Array.isArray(e))for(var _=0;_r;++r)n[r].apply(this,t)}return this},r.prototype.listeners=function(e){return this._callbacks=this._callbacks||{},this._callbacks[e]||[]},r.prototype.hasListeners=function(e){return!!this.listeners(e).length}},{}],176:[function(e,t,n){t.exports=function(e,t,n){for(var r=0,o=e.length,i=3==arguments.length?n:e[r++];o>r;)i=t.call(null,i,e[r],++r,e);return i}},{}],177:[function(e,t,n){var r,o="undefined"!=typeof window?window.navigator.userAgent:"",i=/OS X/.test(o),a=/Opera/.test(o),s=!/like Gecko/.test(o)&&!a,u=t.exports={0:i?"":"",1:"",2:"",3:"",4:"",5:"",6:"",8:"",9:"",12:"",13:"",16:"",17:"",18:"",19:"",20:"",21:"",23:"",24:"",25:"",27:"",28:"",29:"",30:"",31:"",27:"",32:"",33:"",34:"",35:"",36:"",37:"",38:"",39:"",40:"",41:"'+s.join("")+"",d(c.yearRange)?(i=c.yearRange[0],a=c.yearRange[1]+1):(i=n-c.yearRange,a=1+n+c.yearRange),s=[];a>i&&i<=c.maxYear;i++)i>=c.minYear&&s.push('");return l='
'+n+c.yearSuffix+'
",f+=c.showMonthAfterYear?l+u:u+l,p&&(0===r||c.minMonth>=r)&&(m=!1),h&&(11===r||c.maxMonth<=r)&&(v=!1),0===t&&(f+='"),t===e._o.numberOfMonths-1&&(f+='"),f+=""},T=function(e,t){return''+O(e)+D(t)+"
"},k=function(a){var s=this,u=s.config(a);s._onMouseDown=function(e){if(s._v){e=e||window.event;var t=e.target||e.srcElement;if(t){if(!l(t,"is-disabled")){if(l(t,"pika-button")&&!l(t,"is-empty"))return s.setDate(new Date(t.getAttribute("data-pika-year"),t.getAttribute("data-pika-month"),t.getAttribute("data-pika-day"))),void(u.bound&&o(function(){s.hide(),u.field&&u.field.blur()},100));l(t,"pika-prev")?s.prevMonth():l(t,"pika-next")&&s.nextMonth()}if(l(t,"pika-select"))s._c=!0;else{if(!e.preventDefault)return e.returnValue=!1,!1;e.preventDefault()}}}},s._onChange=function(e){e=e||window.event;var t=e.target||e.srcElement;t&&(l(t,"pika-select-month")?s.gotoMonth(t.value):l(t,"pika-select-year")&&s.gotoYear(t.value))},s._onInputChange=function(n){var r;n.firedBy!==s&&(t?(r=e(u.field.value,u.format),r=r&&r.isValid()?r.toDate():null):r=new Date(Date.parse(u.field.value)),s.setDate(h(r)?r:null),s._v||s.show())},s._onInputFocus=function(){s.show()},s._onInputClick=function(){s.show()},s._onInputBlur=function(){var e=r.activeElement;do if(l(e,"pika-single"))return;while(e=e.parentNode);s._c||(s._b=o(function(){s.hide()},50)),s._c=!1},s._onClick=function(e){e=e||window.event;var t=e.target||e.srcElement,r=t;if(t){!n&&l(t,"pika-select")&&(t.onchange||(t.setAttribute("onchange","return;"),i(t,"change",s._onChange)));do if(l(r,"pika-single")||r===u.trigger)return;while(r=r.parentNode);s._v&&t!==u.trigger&&r!==u.trigger&&s.hide()}},s.el=r.createElement("div"),s.el.className="pika-single"+(u.isRTL?" is-rtl":""),i(s.el,"mousedown",s._onMouseDown,!0),i(s.el,"change",s._onChange),u.field&&(u.container?u.container.appendChild(s.el):u.bound?r.body.appendChild(s.el):u.field.parentNode.insertBefore(s.el,u.field.nextSibling),i(u.field,"change",s._onInputChange),u.defaultDate||(u.defaultDate=t&&u.field.value?e(u.field.value,u.format).toDate():new Date(Date.parse(u.field.value)),u.setDefaultDate=!0));var c=u.defaultDate;h(c)?u.setDefaultDate?s.setDate(c,!0):s.gotoDate(c):s.gotoDate(new Date),u.bound?(this.hide(),s.el.className+=" is-bound",i(u.trigger,"click",s._onInputClick),i(u.trigger,"focus",s._onInputFocus),i(u.trigger,"blur",s._onInputBlur)):this.show()};return k.prototype={config:function(e){this._o||(this._o=_({},b,!0));var t=_(this._o,e,!0);t.isRTL=!!t.isRTL,t.field=t.field&&t.field.nodeName?t.field:null,t.bound=!!(void 0!==t.bound?t.field&&t.bound:t.field),t.trigger=t.trigger&&t.trigger.nodeName?t.trigger:t.field,t.disableWeekends=!!t.disableWeekends,t.disableDayFn="function"==typeof t.disableDayFn?t.disableDayFn:null;var n=parseInt(t.numberOfMonths,10)||1;if(t.numberOfMonths=n>4?4:n,h(t.minDate)||(t.minDate=!1),h(t.maxDate)||(t.maxDate=!1),t.minDate&&t.maxDate&&t.maxDate100&&(t.yearRange=100);return t},toString:function(n){return h(this._d)?t?e(this._d).format(n||this._o.format):this._d.toDateString():""},getMoment:function(){return t?e(this._d):null},setMoment:function(n,r){t&&e.isMoment(n)&&this.setDate(n.toDate(),r)},getDate:function(){return h(this._d)?new Date(this._d.getTime()):null},setDate:function(e,t){if(!e)return this._d=null,this._o.field&&(this._o.field.value="",s(this._o.field,"change",{firedBy:this})),this.draw();if("string"==typeof e&&(e=new Date(Date.parse(e))),h(e)){var n=this._o.minDate,r=this._o.maxDate;h(n)&&n>e?e=n:h(r)&&e>r&&(e=r),this._d=new Date(e.getTime()),g(this._d),this.gotoDate(this._d),this._o.field&&(this._o.field.value=this.toString(),s(this._o.field,"change",{firedBy:this})),t||"function"!=typeof this._o.onSelect||this._o.onSelect.call(this,this.getDate())}},gotoDate:function(e){var t=!0;if(h(e)){if(this.calendars){var n=new Date(this.calendars[0].year,this.calendars[0].month,1),r=new Date(this.calendars[this.calendars.length-1].year,this.calendars[this.calendars.length-1].month,1),o=e.getTime();r.setMonth(r.getMonth()+1),r.setDate(r.getDate()-1),t=o=r&&(this._y=r,!isNaN(a)&&this._m>a&&(this._m=a));for(var u=0;u'+x(this,u,this.calendars[u].year,this.calendars[u].month,this.calendars[0].year)+this.render(this.calendars[u].year,this.calendars[u].month)+"";if(this.el.innerHTML=s,t.bound&&"hidden"!==t.field.type&&o(function(){t.trigger.focus()},1),"function"==typeof this._o.onDraw){var l=this;o(function(){l._o.onDraw.call(l)},0)}}},adjustPosition:function(){if(!this._o.container){var e,t,n,o=this._o.trigger,i=o,a=this.el.offsetWidth,s=this.el.offsetHeight,u=window.innerWidth||r.documentElement.clientWidth,l=window.innerHeight||r.documentElement.clientHeight,c=window.pageYOffset||r.body.scrollTop||r.documentElement.scrollTop;if("function"==typeof o.getBoundingClientRect)n=o.getBoundingClientRect(),e=n.left+window.pageXOffset,t=n.bottom+window.pageYOffset;else for(e=i.offsetLeft,t=i.offsetTop+i.offsetHeight;i=i.offsetParent;)e+=i.offsetLeft,t+=i.offsetTop;(this._o.reposition&&e+a>u||this._o.position.indexOf("right")>-1&&e-a+o.offsetWidth>0)&&(e=e-a+o.offsetWidth),(this._o.reposition&&t+s>l+c||this._o.position.indexOf("top")>-1&&t-s-o.offsetHeight>0)&&(t=t-s-o.offsetHeight),this.el.style.cssText=["position: absolute","left: "+e+"px","top: "+t+"px"].join(";")}},render:function(e,t){var n=this._o,r=new Date,o=v(e,t),i=new Date(e,t,1).getDay(),a=[],s=[];g(r),n.firstDay>0&&(i-=n.firstDay,0>i&&(i+=7));for(var u=o+i,l=u;l>7;)l-=7;u+=7-l;for(var c=0,p=0;u>c;c++){var d=new Date(e,t,1+(c-i)),m=h(this._d)?y(d,this._d):!1,_=y(d,r),C=i>c||c>=o+i,b=n.minDate&&dn.maxDate||n.disableWeekends&&f(d)||n.disableDayFn&&n.disableDayFn(d);s.push(M(1+(c-i),t,e,m,_,b,C)),7===++p&&(n.showWeekNumber&&s.unshift(R(c-i,t,e)),a.push(w(s,n.isRTL)),s=[],p=0)}return T(n,a)},isVisible:function(){return this._v},show:function(){this._v||(p(this.el,"is-hidden"),this._v=!0,this.draw(),this._o.bound&&(i(r,"click",this._onClick),this.adjustPosition()),"function"==typeof this._o.onOpen&&this._o.onOpen.call(this))},hide:function(){var e=this._v;e!==!1&&(this._o.bound&&a(r,"click",this._onClick),this.el.style.cssText="",c(this.el,"is-hidden"),this._v=!1,void 0!==e&&"function"==typeof this._o.onClose&&this._o.onClose.call(this))},destroy:function(){this.hide(),a(this.el,"mousedown",this._onMouseDown,!0),a(this.el,"change",this._onChange),this._o.field&&(a(this._o.field,"change",this._onInputChange),this._o.bound&&(a(this._o.trigger,"click",this._onInputClick),a(this._o.trigger,"focus",this._onInputFocus),a(this._o.trigger,"blur",this._onInputBlur))),this.el.parentNode&&this.el.parentNode.removeChild(this.el)}},k})},{moment:"moment"}],"react-alt-text":[function(e,t,n){var r=e("react"),o=e("blacklist"),i=e("vkey"),a=r.createClass({displayName:"AltText",getDefaultProps:function(){return{component:"span",modifier:"",normal:"",modified:""}},getInitialState:function(){return{modified:!1}},componentDidMount:function(){document.body.addEventListener("keydown",this.handleKeyDown,!1),document.body.addEventListener("keyup",this.handleKeyUp,!1)},handleKeyDown:function(e){i[e.keyCode]===this.props.modifier&&this.setState({modified:!0})},handleKeyUp:function(e){i[e.keyCode]===this.props.modifier&&this.setState({modified:!1})},componentWillUnmount:function(){document.body.removeEventListener("keydown",this.handleKeyDown),document.body.removeEventListener("keyup",this.handleKeyUp)},render:function(){var e=o(this.props,"component","modifier","normal","modified");return r.createElement(this.props.component,e,this.state.modified?this.props.modified:this.props.normal)}});t.exports=a},{blacklist:1,react:"react",vkey:177}],"react-select":[function(e,t,n){"use strict";var r=Object.assign||function(e){for(var t=1;to.bottom||r.top-1)return!1;if(this.props.filterOption)return this.props.filterOption.call(this,e,n);var t=String(e.value),o=String(e.label);return this.props.ignoreCase&&(t=t.toLowerCase(),o=o.toLowerCase(),n=n.toLowerCase()),n&&"start"!==this.props.matchPos?"label"!==this.props.matchProp&&t.indexOf(n)>=0||"value"!==this.props.matchProp&&o.indexOf(n)>=0:"label"!==this.props.matchProp&&t.substr(0,n.length)===n||"value"!==this.props.matchProp&&o.substr(0,n.length)===n};return(e||[]).filter(o,this)},selectFocusedOption:function(){return this.selectValue(this.props.allowCreate&&!this.state.focusedOption?this.state.inputValue:this.state.focusedOption)},focusOption:function(e){this.setState({focusedOption:e})},focusNextOption:function(){this.focusAdjacentOption("next")},focusPreviousOption:function(){this.focusAdjacentOption("previous")},focusAdjacentOption:function(e){this._focusedOptionReveal=!0;var t=this.state.filteredOptions;if(!this.state.isOpen)return void this.setState({isOpen:!0,inputValue:"",focusedOption:this.state.focusedOption||t["next"===e?0:t.length-1]},this._bindCloseMenuIfClickedOutside);if(t.length){for(var n=-1,r=0;r-1&&n0?t[n-1]:t[t.length-1]),this.setState({focusedOption:o})}},unfocusOption:function(e){this.state.focusedOption===e&&this.setState({focusedOption:null})},buildMenu:function(){var e=this.state.focusedOption?this.state.focusedOption.value:null,t=this.props.optionRenderer||function(e){return e.label};if(this.state.filteredOptions.length>0&&(e=null==e?this.state.filteredOptions[0]:e),this.props.allowCreate&&this.state.inputValue.trim()){var n=this.state.inputValue;this.state.filteredOptions.unshift({value:n,label:n,create:!0})}var r=Object.keys(this.state.filteredOptions).map(function(n){var r=this.state.filteredOptions[n],i=e===r.value,s=a({"Select-option":!0,"is-focused":i,"is-disabled":r.disabled}),u=i?"focused":null,l=this.focusOption.bind(this,r),c=this.unfocusOption.bind(this,r),p=this.selectValue.bind(this,r),d=t(r);return r.disabled?o.createElement("div",{ref:u,key:"option-"+r.value,className:s},d):o.createElement("div",{ref:u,key:"option-"+r.value,className:s,onMouseEnter:l,onMouseLeave:c,onMouseDown:p,onClick:p},r.create?"Add "+r.label+" ?":d)},this);return r.length?r:o.createElement("div",{className:"Select-noresults"},this.props.asyncOptions&&!this.state.inputValue?this.props.searchPromptText:this.props.noResultsText)},handleOptionLabelClick:function(e,t){this.props.onOptionLabelClick&&this.props.onOptionLabelClick(e,t)},render:function(){var e=a("Select",this.props.className,{"is-multi":this.props.multi,"is-searchable":this.props.searchable,"is-open":this.state.isOpen,"is-focused":this.state.isFocused,"is-loading":this.state.isLoading,"is-disabled":this.props.disabled,"has-value":this.state.value}),t=[];this.props.multi&&this.state.values.forEach(function(e){t.push(o.createElement(s,{key:e.value,option:e,renderer:this.props.valueRenderer,optionLabelClick:!!this.props.onOptionLabelClick,onOptionLabelClick:this.handleOptionLabelClick.bind(this,e),onRemove:this.removeValue.bind(this,e),disabled:this.props.disabled}))},this),this.state.inputValue||this.props.multi&&t.length||t.push(o.createElement("div",{className:"Select-placeholder",key:"placeholder"},this.state.placeholder));var n,u,l=this.state.isLoading?o.createElement("span",{className:"Select-loading","aria-hidden":"true"}):null,c=this.props.clearable&&this.state.value&&!this.props.disabled?o.createElement("span",{className:"Select-clear",title:this.props.multi?this.props.clearAllText:this.props.clearValueText,"aria-label":this.props.multi?this.props.clearAllText:this.props.clearValueText,onMouseDown:this.clearValue,onClick:this.clearValue,dangerouslySetInnerHTML:{__html:"×"}}):null;this.state.isOpen&&(u={ref:"menu",className:"Select-menu"},this.props.multi&&(u.onMouseDown=this.handleMouseDown),n=o.createElement("div",{ref:"selectMenuContainer",className:"Select-menu-outer"},o.createElement("div",u,this.buildMenu())));var p,d={ref:"input",className:"Select-input",tabIndex:this.props.tabIndex||0,onFocus:this.handleInputFocus,onBlur:this.handleInputBlur};for(var h in this.props.inputProps)this.props.inputProps.hasOwnProperty(h)&&(d[h]=this.props.inputProps[h]);return this.props.disabled?this.props.multi&&this.state.values.length||(p=o.createElement("div",{className:"Select-input"}," ")):p=this.props.searchable?o.createElement(i,r({value:this.state.inputValue,onChange:this.handleInputChange,minWidth:"5"},d)):o.createElement("div",d," "),o.createElement("div",{ref:"wrapper",className:e},o.createElement("input",{type:"hidden",ref:"value",name:this.props.name,value:this.state.value,disabled:this.props.disabled}),o.createElement("div",{className:"Select-control",ref:"control",onKeyDown:this.handleKeyDown,onMouseDown:this.handleMouseDown,onTouchEnd:this.handleMouseDown},t,p,o.createElement("span",{className:"Select-arrow-zone",onMouseDown:this.handleMouseDownOnArrow}),o.createElement("span",{className:"Select-arrow",onMouseDown:this.handleMouseDownOnArrow}),l,c),n)}});t.exports=l},{"./Value":2,classnames:"classnames",react:"react","react-input-autosize":3}],"react/addons":[function(e,t,n){t.exports=e("./lib/ReactWithAddons")},{"./lib/ReactWithAddons":103}],react:[function(e,t,n){t.exports=e("./lib/React")},{"./lib/React":33}],superagent:[function(e,t,n){function r(){}function o(e){var t={}.toString.call(e);switch(t){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function i(e){return e===Object(e)}function a(e){if(!i(e))return e;var t=[];for(var n in e)null!=e[n]&&t.push(encodeURIComponent(n)+"="+encodeURIComponent(e[n]));return t.join("&")}function s(e){for(var t,n,r={},o=e.split("&"),i=0,a=o.length;a>i;++i)n=o[i],t=n.split("="),r[decodeURIComponent(t[0])]=decodeURIComponent(t[1]);return r}function u(e){var t,n,r,o,i=e.split(/\r?\n/),a={};i.pop();for(var s=0,u=i.length;u>s;++s)n=i[s],t=n.indexOf(":"),r=n.slice(0,t).toLowerCase(),o=g(n.slice(t+1)),a[r]=o;return a}function l(e){return e.split(/ *; */).shift()}function c(e){return m(e.split(/ *; */),function(e,t){var n=t.split(/ *= */),r=n.shift(),o=n.shift();return r&&o&&(e[r]=o),e},{})}function p(e,t){t=t||{},this.req=e,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=u(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function d(e,t){var n=this;f.call(this),this._query=this._query||[],this.method=e,this.url=t,this.header={},this._header={},this.on("end",function(){var e=null,t=null;try{t=new p(n)}catch(r){return e=new Error("Parser is unable to parse the response"),e.parse=!0,e.original=r,n.callback(e)}if(n.emit("response",t),e)return n.callback(e,t);if(t.status>=200&&t.status<300)return n.callback(e,t);var o=new Error(t.statusText||"Unsuccessful HTTP response");o.original=e,o.response=t,o.status=t.status,n.callback(e||o,t)})}function h(e,t){return"function"==typeof t?new d("GET",e).end(t):1==arguments.length?new d("GET",e):new d(e,t)}var f=e("emitter"),m=e("reduce"),v="undefined"==typeof window?this||self:window;h.getXHR=function(){if(!(!v.XMLHttpRequest||v.location&&"file:"==v.location.protocol&&v.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(e){}return!1};var g="".trim?function(e){return e.trim()}:function(e){return e.replace(/(^\s*|\s*$)/g,"")};h.serializeObject=a,h.parseString=s, -h.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},h.serialize={"application/x-www-form-urlencoded":a,"application/json":JSON.stringify},h.parse={"application/x-www-form-urlencoded":s,"application/json":JSON.parse},p.prototype.get=function(e){return this.header[e.toLowerCase()]},p.prototype.setHeaderProperties=function(e){var t=this.header["content-type"]||"";this.type=l(t);var n=c(t);for(var r in n)this[r]=n[r]},p.prototype.parseBody=function(e){var t=h.parse[this.type];return t&&e&&(e.length||e instanceof Object)?t(e):null},p.prototype.setStatusProperties=function(e){1223===e&&(e=204);var t=e/100|0;this.status=e,this.statusType=t,this.info=1==t,this.ok=2==t,this.clientError=4==t,this.serverError=5==t,this.error=4==t||5==t?this.toError():!1,this.accepted=202==e,this.noContent=204==e,this.badRequest=400==e,this.unauthorized=401==e,this.notAcceptable=406==e,this.notFound=404==e,this.forbidden=403==e},p.prototype.toError=function(){var e=this.req,t=e.method,n=e.url,r="cannot "+t+" "+n+" ("+this.status+")",o=new Error(r);return o.status=this.status,o.method=t,o.url=n,o},h.Response=p,f(d.prototype),d.prototype.use=function(e){return e(this),this},d.prototype.timeout=function(e){return this._timeout=e,this},d.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},d.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this)},d.prototype.set=function(e,t){if(i(e)){for(var n in e)this.set(n,e[n]);return this}return this._header[e.toLowerCase()]=t,this.header[e]=t,this},d.prototype.unset=function(e){return delete this._header[e.toLowerCase()],delete this.header[e],this},d.prototype.getHeader=function(e){return this._header[e.toLowerCase()]},d.prototype.type=function(e){return this.set("Content-Type",h.types[e]||e),this},d.prototype.accept=function(e){return this.set("Accept",h.types[e]||e),this},d.prototype.auth=function(e,t){var n=btoa(e+":"+t);return this.set("Authorization","Basic "+n),this},d.prototype.query=function(e){return"string"!=typeof e&&(e=a(e)),e&&this._query.push(e),this},d.prototype.field=function(e,t){return this._formData||(this._formData=new v.FormData),this._formData.append(e,t),this},d.prototype.attach=function(e,t,n){return this._formData||(this._formData=new v.FormData),this._formData.append(e,t,n),this},d.prototype.send=function(e){var t=i(e),n=this.getHeader("Content-Type");if(t&&i(this._data))for(var r in e)this._data[r]=e[r];else"string"==typeof e?(n||this.type("form"),n=this.getHeader("Content-Type"),this._data="application/x-www-form-urlencoded"==n?this._data?this._data+"&"+e:e:(this._data||"")+e):this._data=e;return!t||o(e)?this:(n||this.type("json"),this)},d.prototype.callback=function(e,t){var n=this._callback;this.clearTimeout(),n(e,t)},d.prototype.crossDomainError=function(){var e=new Error("Origin is not allowed by Access-Control-Allow-Origin");e.crossDomain=!0,this.callback(e)},d.prototype.timeoutError=function(){var e=this._timeout,t=new Error("timeout of "+e+"ms exceeded");t.timeout=e,this.callback(t)},d.prototype.withCredentials=function(){return this._withCredentials=!0,this},d.prototype.end=function(e){var t=this,n=this.xhr=h.getXHR(),i=this._query.join("&"),a=this._timeout,s=this._formData||this._data;this._callback=e||r,n.onreadystatechange=function(){if(4==n.readyState){var e;try{e=n.status}catch(r){e=0}if(0==e){if(t.timedout)return t.timeoutError();if(t.aborted)return;return t.crossDomainError()}t.emit("end")}};var u=function(e){e.total>0&&(e.percent=e.loaded/e.total*100),t.emit("progress",e)};this.hasListeners("progress")&&(n.onprogress=u);try{n.upload&&this.hasListeners("progress")&&(n.upload.onprogress=u)}catch(l){}if(a&&!this._timer&&(this._timer=setTimeout(function(){t.timedout=!0,t.abort()},a)),i&&(i=h.serializeObject(i),this.url+=~this.url.indexOf("?")?"&"+i:"?"+i),n.open(this.method,this.url,!0),this._withCredentials&&(n.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof s&&!o(s)){var c=h.serialize[this.getHeader("Content-Type")];c&&(s=c(s))}for(var p in this.header)null!=this.header[p]&&n.setRequestHeader(p,this.header[p]);return this.emit("request",this),n.send(s),this},h.Request=d,h.get=function(e,t,n){var r=h("GET",e);return"function"==typeof t&&(n=t,t=null),t&&r.query(t),n&&r.end(n),r},h.head=function(e,t,n){var r=h("HEAD",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},h.del=function(e,t){var n=h("DELETE",e);return t&&n.end(t),n},h.patch=function(e,t,n){var r=h("PATCH",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},h.post=function(e,t,n){var r=h("POST",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},h.put=function(e,t,n){var r=h("PUT",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},t.exports=h},{emitter:175,reduce:176}]},{},[]); \ No newline at end of file +}},t.exports=a},{"./CSSPropertyOperations":8,"./DOMProperty":13,"./DOMPropertyOperations":14,"./Object.assign":31,"./ReactBrowserEventEmitter":35,"./ReactComponentBrowserEnvironment":42,"./ReactMount":79,"./ReactMultiChild":80,"./ReactPerf":84,"./escapeTextContentForBrowser":134,"./invariant":153,"./isEventSupported":154,"./keyOf":160,"./warning":174}],51:[function(e,t,n){"use strict";var r=e("./EventConstants"),o=e("./LocalEventTrapMixin"),i=e("./ReactBrowserComponentMixin"),a=e("./ReactClass"),s=e("./ReactElement"),u=s.createFactory("form"),l=a.createClass({displayName:"ReactDOMForm",tagName:"FORM",mixins:[i,o],render:function(){return u(this.props)},componentDidMount:function(){this.trapBubbledEvent(r.topLevelTypes.topReset,"reset"),this.trapBubbledEvent(r.topLevelTypes.topSubmit,"submit")}});t.exports=l},{"./EventConstants":18,"./LocalEventTrapMixin":29,"./ReactBrowserComponentMixin":34,"./ReactClass":40,"./ReactElement":65}],52:[function(e,t,n){"use strict";var r=e("./CSSPropertyOperations"),o=e("./DOMChildrenOperations"),i=e("./DOMPropertyOperations"),a=e("./ReactMount"),s=e("./ReactPerf"),u=e("./invariant"),l=e("./setInnerHTML"),c={dangerouslySetInnerHTML:"`dangerouslySetInnerHTML` must be set using `updateInnerHTMLByID()`.",style:"`style` must be set using `updateStylesByID()`."},p={updatePropertyByID:function(e,t,n){var r=a.getNode(e);u(!c.hasOwnProperty(t)),null!=n?i.setValueForProperty(r,t,n):i.deleteValueForProperty(r,t)},deletePropertyByID:function(e,t,n){var r=a.getNode(e);u(!c.hasOwnProperty(t)),i.deleteValueForProperty(r,t,n)},updateStylesByID:function(e,t){var n=a.getNode(e);r.setValueForStyles(n,t)},updateInnerHTMLByID:function(e,t){var n=a.getNode(e);l(n,t)},updateTextContentByID:function(e,t){var n=a.getNode(e);o.updateTextContent(n,t)},dangerouslyReplaceNodeWithMarkupByID:function(e,t){var n=a.getNode(e);o.dangerouslyReplaceNodeWithMarkup(n,t)},dangerouslyProcessChildrenUpdates:function(e,t){for(var n=0;nl;l++){var f=u[l];if(f!==i&&f.form===i.form){var v=c.getID(f);h(v);var g=m[v];h(g),p.asap(r,g)}}}return t}});t.exports=v},{"./AutoFocusMixin":4,"./DOMPropertyOperations":14,"./LinkedValueUtils":28,"./Object.assign":31,"./ReactBrowserComponentMixin":34,"./ReactClass":40,"./ReactElement":65,"./ReactMount":79,"./ReactUpdates":102,"./invariant":153}],56:[function(e,t,n){"use strict";var r=e("./ReactBrowserComponentMixin"),o=e("./ReactClass"),i=e("./ReactElement"),a=(e("./warning"),i.createFactory("option")),s=o.createClass({displayName:"ReactDOMOption",tagName:"OPTION",mixins:[r],componentWillMount:function(){},render:function(){return a(this.props,this.props.children)}});t.exports=s},{"./ReactBrowserComponentMixin":34,"./ReactClass":40,"./ReactElement":65,"./warning":174}],57:[function(e,t,n){"use strict";function r(){if(this._pendingUpdate){this._pendingUpdate=!1;var e=s.getValue(this);null!=e&&this.isMounted()&&i(this,e)}}function o(e,t,n){if(null==e[t])return null;if(e.multiple){if(!Array.isArray(e[t]))return new Error("The `"+t+"` prop supplied to must be a scalar value if `multiple` is false.")}function i(e,t){var n,r,o,i=e.getDOMNode().options;if(e.props.multiple){for(n={},r=0,o=t.length;o>r;r++)n[""+t[r]]=!0;for(r=0,o=i.length;o>r;r++){var a=n.hasOwnProperty(i[r].value);i[r].selected!==a&&(i[r].selected=a)}}else{for(n=""+t,r=0,o=i.length;o>r;r++)if(i[r].value===n)return void(i[r].selected=!0);i.length&&(i[0].selected=!0)}}var a=e("./AutoFocusMixin"),s=e("./LinkedValueUtils"),u=e("./ReactBrowserComponentMixin"),l=e("./ReactClass"),c=e("./ReactElement"),p=e("./ReactUpdates"),d=e("./Object.assign"),h=c.createFactory("select"),f=l.createClass({displayName:"ReactDOMSelect",tagName:"SELECT",mixins:[a,s.Mixin,u],propTypes:{defaultValue:o,value:o},render:function(){var e=d({},this.props);return e.onChange=this._handleChange,e.value=null,h(e,this.props.children)},componentWillMount:function(){this._pendingUpdate=!1},componentDidMount:function(){var e=s.getValue(this);null!=e?i(this,e):null!=this.props.defaultValue&&i(this,this.props.defaultValue)},componentDidUpdate:function(e){var t=s.getValue(this);null!=t?(this._pendingUpdate=!1,i(this,t)):!e.multiple!=!this.props.multiple&&(null!=this.props.defaultValue?i(this,this.props.defaultValue):i(this,this.props.multiple?[]:""))},_handleChange:function(e){var t,n=s.getOnChange(this);return n&&(t=n.call(this,e)),this._pendingUpdate=!0,p.asap(r,this),t}});t.exports=f},{"./AutoFocusMixin":4,"./LinkedValueUtils":28,"./Object.assign":31,"./ReactBrowserComponentMixin":34,"./ReactClass":40,"./ReactElement":65,"./ReactUpdates":102}],58:[function(e,t,n){"use strict";function r(e,t,n,r){return e===n&&t===r}function o(e){var t=document.selection,n=t.createRange(),r=n.text.length,o=n.duplicate();o.moveToElementText(e),o.setEndPoint("EndToStart",n);var i=o.text.length,a=i+r;return{start:i,end:a}}function i(e){var t=window.getSelection&&window.getSelection();if(!t||0===t.rangeCount)return null;var n=t.anchorNode,o=t.anchorOffset,i=t.focusNode,a=t.focusOffset,s=t.getRangeAt(0),u=r(t.anchorNode,t.anchorOffset,t.focusNode,t.focusOffset),l=u?0:s.toString().length,c=s.cloneRange();c.selectNodeContents(e),c.setEnd(s.startContainer,s.startOffset);var p=r(c.startContainer,c.startOffset,c.endContainer,c.endOffset),d=p?0:c.toString().length,h=d+l,f=document.createRange();f.setStart(n,o),f.setEnd(i,a);var m=f.collapsed;return{start:m?h:d,end:m?d:h}}function a(e,t){var n,r,o=document.selection.createRange().duplicate();"undefined"==typeof t.end?(n=t.start,r=n):t.start>t.end?(n=t.end,r=t.start):(n=t.start,r=t.end),o.moveToElementText(e),o.moveStart("character",n),o.setEndPoint("EndToStart",o),o.moveEnd("character",r-n),o.select()}function s(e,t){if(window.getSelection){var n=window.getSelection(),r=e[c()].length,o=Math.min(t.start,r),i="undefined"==typeof t.end?o:Math.min(t.end,r);if(!n.extend&&o>i){var a=i;i=o,o=a}var s=l(e,o),u=l(e,i);if(s&&u){var p=document.createRange();p.setStart(s.node,s.offset),n.removeAllRanges(),o>i?(n.addRange(p),n.extend(u.node,u.offset)):(p.setEnd(u.node,u.offset),n.addRange(p))}}}var u=e("./ExecutionEnvironment"),l=e("./getNodeForCharacterOffset"),c=e("./getTextContentAccessor"),p=u.canUseDOM&&"selection"in document&&!("getSelection"in window),d={getOffsets:p?o:i,setOffsets:p?a:s};t.exports=d},{"./ExecutionEnvironment":24,"./getNodeForCharacterOffset":146,"./getTextContentAccessor":148}],59:[function(e,t,n){"use strict";var r=e("./DOMPropertyOperations"),o=e("./ReactComponentBrowserEnvironment"),i=e("./ReactDOMComponent"),a=e("./Object.assign"),s=e("./escapeTextContentForBrowser"),u=function(e){};a(u.prototype,{construct:function(e){this._currentElement=e,this._stringText=""+e,this._rootNodeID=null,this._mountIndex=0},mountComponent:function(e,t,n){this._rootNodeID=e;var o=s(this._stringText);return t.renderToStaticMarkup?o:""+o+""},receiveComponent:function(e,t){if(e!==this._currentElement){this._currentElement=e;var n=""+e;n!==this._stringText&&(this._stringText=n,i.BackendIDOperations.updateTextContentByID(this._rootNodeID,n))}},unmountComponent:function(){o.unmountIDFromEnvironment(this._rootNodeID)}}),t.exports=u},{"./DOMPropertyOperations":14,"./Object.assign":31,"./ReactComponentBrowserEnvironment":42,"./ReactDOMComponent":50,"./escapeTextContentForBrowser":134}],60:[function(e,t,n){"use strict";function r(){this.isMounted()&&this.forceUpdate()}var o=e("./AutoFocusMixin"),i=e("./DOMPropertyOperations"),a=e("./LinkedValueUtils"),s=e("./ReactBrowserComponentMixin"),u=e("./ReactClass"),l=e("./ReactElement"),c=e("./ReactUpdates"),p=e("./Object.assign"),d=e("./invariant"),h=(e("./warning"),l.createFactory("textarea")),f=u.createClass({displayName:"ReactDOMTextarea",tagName:"TEXTAREA",mixins:[o,a.Mixin,s],getInitialState:function(){var e=this.props.defaultValue,t=this.props.children;null!=t&&(d(null==e),Array.isArray(t)&&(d(t.length<=1),t=t[0]),e=""+t),null==e&&(e="");var n=a.getValue(this);return{initialValue:""+(null!=n?n:e)}},render:function(){var e=p({},this.props);return d(null==e.dangerouslySetInnerHTML),e.defaultValue=null,e.value=null,e.onChange=this._handleChange,h(e,this.state.initialValue)},componentDidUpdate:function(e,t,n){var r=a.getValue(this);if(null!=r){var o=this.getDOMNode();i.setValueForProperty(o,"value",""+r)}},_handleChange:function(e){var t,n=a.getOnChange(this);return n&&(t=n.call(this,e)),c.asap(r,this),t}});t.exports=f},{"./AutoFocusMixin":4,"./DOMPropertyOperations":14,"./LinkedValueUtils":28,"./Object.assign":31,"./ReactBrowserComponentMixin":34,"./ReactClass":40,"./ReactElement":65,"./ReactUpdates":102,"./invariant":153,"./warning":174}],61:[function(e,t,n){"use strict";function r(){this.reinitializeTransaction()}var o=e("./ReactUpdates"),i=e("./Transaction"),a=e("./Object.assign"),s=e("./emptyFunction"),u={initialize:s,close:function(){d.isBatchingUpdates=!1}},l={initialize:s,close:o.flushBatchedUpdates.bind(o)},c=[l,u];a(r.prototype,i.Mixin,{getTransactionWrappers:function(){return c}});var p=new r,d={isBatchingUpdates:!1,batchedUpdates:function(e,t,n,r,o){var i=d.isBatchingUpdates;d.isBatchingUpdates=!0,i?e(t,n,r,o):p.perform(e,null,t,n,r,o)}};t.exports=d},{"./Object.assign":31,"./ReactUpdates":102,"./Transaction":119,"./emptyFunction":132}],62:[function(e,t,n){"use strict";function r(e){return f.createClass({tagName:e.toUpperCase(),render:function(){return new x(e,null,null,null,null,this.props)}})}function o(){S.EventEmitter.injectReactEventListener(T),S.EventPluginHub.injectEventPluginOrder(u),S.EventPluginHub.injectInstanceHandle(k),S.EventPluginHub.injectMount(P),S.EventPluginHub.injectEventPluginsByName({SimpleEventPlugin:L,EnterLeaveEventPlugin:l,ChangeEventPlugin:a,MobileSafariClickEventPlugin:d,SelectEventPlugin:N,BeforeInputEventPlugin:i}),S.NativeComponent.injectGenericComponentClass(g),S.NativeComponent.injectTextComponentClass(O),S.NativeComponent.injectAutoWrapper(r),S.Class.injectMixin(h),S.NativeComponent.injectComponentClasses({button:y,form:_,iframe:E,img:b,input:M,option:R,select:w,textarea:D,html:F("html"),head:F("head"),body:F("body")}),S.DOMProperty.injectDOMPropertyConfig(p),S.DOMProperty.injectDOMPropertyConfig(U),S.EmptyComponent.injectEmptyComponent("noscript"),S.Updates.injectReconcileTransaction(I),S.Updates.injectBatchingStrategy(v),S.RootIndex.injectCreateReactRootIndex(c.canUseDOM?s.createReactRootIndex:A.createReactRootIndex),S.Component.injectEnvironment(m),S.DOMComponent.injectIDOperations(C)}var i=e("./BeforeInputEventPlugin"),a=e("./ChangeEventPlugin"),s=e("./ClientReactRootIndex"),u=e("./DefaultEventPluginOrder"),l=e("./EnterLeaveEventPlugin"),c=e("./ExecutionEnvironment"),p=e("./HTMLDOMPropertyConfig"),d=e("./MobileSafariClickEventPlugin"),h=e("./ReactBrowserComponentMixin"),f=e("./ReactClass"),m=e("./ReactComponentBrowserEnvironment"),v=e("./ReactDefaultBatchingStrategy"),g=e("./ReactDOMComponent"),y=e("./ReactDOMButton"),_=e("./ReactDOMForm"),b=e("./ReactDOMImg"),C=e("./ReactDOMIDOperations"),E=e("./ReactDOMIframe"),M=e("./ReactDOMInput"),R=e("./ReactDOMOption"),w=e("./ReactDOMSelect"),D=e("./ReactDOMTextarea"),O=e("./ReactDOMTextComponent"),x=e("./ReactElement"),T=e("./ReactEventListener"),S=e("./ReactInjection"),k=e("./ReactInstanceHandles"),P=e("./ReactMount"),I=e("./ReactReconcileTransaction"),N=e("./SelectEventPlugin"),A=e("./ServerReactRootIndex"),L=e("./SimpleEventPlugin"),U=e("./SVGDOMPropertyConfig"),F=e("./createFullPageComponent");t.exports={inject:o}},{"./BeforeInputEventPlugin":5,"./ChangeEventPlugin":10,"./ClientReactRootIndex":11,"./DefaultEventPluginOrder":16,"./EnterLeaveEventPlugin":17,"./ExecutionEnvironment":24,"./HTMLDOMPropertyConfig":26,"./MobileSafariClickEventPlugin":30,"./ReactBrowserComponentMixin":34,"./ReactClass":40,"./ReactComponentBrowserEnvironment":42,"./ReactDOMButton":49,"./ReactDOMComponent":50,"./ReactDOMForm":51,"./ReactDOMIDOperations":52,"./ReactDOMIframe":53,"./ReactDOMImg":54,"./ReactDOMInput":55,"./ReactDOMOption":56,"./ReactDOMSelect":57,"./ReactDOMTextComponent":59,"./ReactDOMTextarea":60,"./ReactDefaultBatchingStrategy":61,"./ReactDefaultPerf":63,"./ReactElement":65,"./ReactEventListener":70,"./ReactInjection":72,"./ReactInstanceHandles":74,"./ReactMount":79,"./ReactReconcileTransaction":90,"./SVGDOMPropertyConfig":104,"./SelectEventPlugin":105,"./ServerReactRootIndex":106,"./SimpleEventPlugin":107,"./createFullPageComponent":128}],63:[function(e,t,n){"use strict";function r(e){return Math.floor(100*e)/100}function o(e,t,n){e[t]=(e[t]||0)+n}var i=e("./DOMProperty"),a=e("./ReactDefaultPerfAnalysis"),s=e("./ReactMount"),u=e("./ReactPerf"),l=e("./performanceNow"),c={_allMeasurements:[],_mountStack:[0],_injected:!1,start:function(){c._injected||u.injection.injectMeasure(c.measure),c._allMeasurements.length=0,u.enableMeasure=!0},stop:function(){u.enableMeasure=!1},getLastMeasurements:function(){return c._allMeasurements},printExclusive:function(e){e=e||c._allMeasurements;var t=a.getExclusiveSummary(e);console.table(t.map(function(e){return{"Component class name":e.componentName,"Total inclusive time (ms)":r(e.inclusive),"Exclusive mount time (ms)":r(e.exclusive),"Exclusive render time (ms)":r(e.render),"Mount time per instance (ms)":r(e.exclusive/e.count),"Render time per instance (ms)":r(e.render/e.count),Instances:e.count}}))},printInclusive:function(e){e=e||c._allMeasurements;var t=a.getInclusiveSummary(e);console.table(t.map(function(e){return{"Owner > component":e.componentName,"Inclusive time (ms)":r(e.time),Instances:e.count}})),console.log("Total time:",a.getTotalTime(e).toFixed(2)+" ms")},getMeasurementsSummaryMap:function(e){var t=a.getInclusiveSummary(e,!0);return t.map(function(e){return{"Owner > component":e.componentName,"Wasted time (ms)":e.time,Instances:e.count}})},printWasted:function(e){e=e||c._allMeasurements,console.table(c.getMeasurementsSummaryMap(e)),console.log("Total time:",a.getTotalTime(e).toFixed(2)+" ms")},printDOM:function(e){e=e||c._allMeasurements;var t=a.getDOMSummary(e);console.table(t.map(function(e){var t={};return t[i.ID_ATTRIBUTE_NAME]=e.id,t.type=e.type,t.args=JSON.stringify(e.args),t})),console.log("Total time:",a.getTotalTime(e).toFixed(2)+" ms")},_recordWrite:function(e,t,n,r){var o=c._allMeasurements[c._allMeasurements.length-1].writes;o[e]=o[e]||[],o[e].push({type:t,time:n,args:r})},measure:function(e,t,n){return function(){for(var r=[],i=0,a=arguments.length;a>i;i++)r.push(arguments[i]);var u,p,d;if("_renderNewRootComponent"===t||"flushBatchedUpdates"===t)return c._allMeasurements.push({exclusive:{},inclusive:{},render:{},counts:{},writes:{},displayNames:{},totalTime:0}),d=l(),p=n.apply(this,r),c._allMeasurements[c._allMeasurements.length-1].totalTime=l()-d,p;if("_mountImageIntoNode"===t||"ReactDOMIDOperations"===e){if(d=l(),p=n.apply(this,r),u=l()-d,"_mountImageIntoNode"===t){var h=s.getID(r[1]);c._recordWrite(h,t,u,r[0])}else"dangerouslyProcessChildrenUpdates"===t?r[0].forEach(function(e){var t={};null!==e.fromIndex&&(t.fromIndex=e.fromIndex),null!==e.toIndex&&(t.toIndex=e.toIndex),null!==e.textContent&&(t.textContent=e.textContent),null!==e.markupIndex&&(t.markup=r[1][e.markupIndex]),c._recordWrite(e.parentID,e.type,u,t)}):c._recordWrite(r[0],t,u,Array.prototype.slice.call(r,1));return p}if("ReactCompositeComponent"!==e||"mountComponent"!==t&&"updateComponent"!==t&&"_renderValidatedComponent"!==t)return n.apply(this,r);if("string"==typeof this._currentElement.type)return n.apply(this,r);var f="mountComponent"===t?r[0]:this._rootNodeID,m="_renderValidatedComponent"===t,v="mountComponent"===t,g=c._mountStack,y=c._allMeasurements[c._allMeasurements.length-1];if(m?o(y.counts,f,1):v&&g.push(0),d=l(),p=n.apply(this,r),u=l()-d,m)o(y.render,f,u);else if(v){var _=g.pop();g[g.length-1]+=u,o(y.exclusive,f,u-_),o(y.inclusive,f,u)}else o(y.inclusive,f,u);return y.displayNames[f]={current:this.getName(),owner:this._currentElement._owner?this._currentElement._owner.getName():""},p}}};t.exports=c},{"./DOMProperty":13,"./ReactDefaultPerfAnalysis":64,"./ReactMount":79,"./ReactPerf":84,"./performanceNow":165}],64:[function(e,t,n){function r(e){for(var t=0,n=0;n=l&&s.push(n[t]);return s.sort(function(e,t){return t.exclusive-e.exclusive}),s}function a(e,t){for(var n,r={},o=0;o "+d.current,r[n]=r[n]||{componentName:n,time:0,count:0},a.inclusive[p]&&(r[n].time+=a.inclusive[p]),a.counts[p]&&(r[n].count+=a.counts[p])}}var h=[];for(n in r)r[n].time>=l&&h.push(r[n]);return h.sort(function(e,t){return t.time-e.time}),h}function s(e){var t={},n=Object.keys(e.writes),r=u({},e.exclusive,e.inclusive);for(var o in r){for(var i=!1,a=0;a0&&(t[o]=!0)}return t}var u=e("./Object.assign"),l=1.2,c={_mountImageIntoNode:"set innerHTML",INSERT_MARKUP:"set innerHTML",MOVE_EXISTING:"move",REMOVE_NODE:"remove",TEXT_CONTENT:"set textContent",updatePropertyByID:"update attribute",deletePropertyByID:"delete attribute",updateStylesByID:"update styles",updateInnerHTMLByID:"set innerHTML",dangerouslyReplaceNodeWithMarkupByID:"replace"},p={getExclusiveSummary:i,getInclusiveSummary:a,getDOMSummary:o,getTotalTime:r};t.exports=p},{"./Object.assign":31}],65:[function(e,t,n){"use strict";var r=e("./ReactContext"),o=e("./ReactCurrentOwner"),i=e("./Object.assign"),a=(e("./warning"),{key:!0,ref:!0}),s=function(e,t,n,r,o,i){this.type=e,this.key=t,this.ref=n,this._owner=r,this._context=o,this.props=i};s.prototype={_isReactElement:!0},s.createElement=function(e,t,n){var i,u={},l=null,c=null;if(null!=t){c=void 0===t.ref?null:t.ref,l=void 0===t.key?null:""+t.key;for(i in t)t.hasOwnProperty(i)&&!a.hasOwnProperty(i)&&(u[i]=t[i])}var p=arguments.length-2;if(1===p)u.children=n;else if(p>1){for(var d=Array(p),h=0;p>h;h++)d[h]=arguments[h+2];u.children=d}if(e&&e.defaultProps){var f=e.defaultProps;for(i in f)"undefined"==typeof u[i]&&(u[i]=f[i])}return new s(e,l,c,o.current,r.current,u)},s.createFactory=function(e){var t=s.createElement.bind(null,e);return t.type=e,t},s.cloneAndReplaceProps=function(e,t){var n=new s(e.type,e.key,e.ref,e._owner,e._context,t);return n},s.cloneElement=function(e,t,n){var r,u=i({},e.props),l=e.key,c=e.ref,p=e._owner;if(null!=t){void 0!==t.ref&&(c=t.ref,p=o.current),void 0!==t.key&&(l=""+t.key);for(r in t)t.hasOwnProperty(r)&&!a.hasOwnProperty(r)&&(u[r]=t[r])}var d=arguments.length-2;if(1===d)u.children=n;else if(d>1){for(var h=Array(d),f=0;d>f;f++)h[f]=arguments[f+2];u.children=h}return new s(e.type,l,c,p,e._context,u)},s.isValidElement=function(e){var t=!(!e||!e._isReactElement);return t},t.exports=s},{"./Object.assign":31,"./ReactContext":46,"./ReactCurrentOwner":47,"./warning":174}],66:[function(e,t,n){"use strict";function r(){if(y.current){var e=y.current.getName();if(e)return" Check the render method of `"+e+"`."}return""}function o(e){var t=e&&e.getPublicInstance();if(!t)return void 0;var n=t.constructor;return n?n.displayName||n.name||void 0:void 0}function i(){var e=y.current;return e&&o(e)||void 0}function a(e,t){e._store.validated||null!=e.key||(e._store.validated=!0,u('Each child in an array or iterator should have a unique "key" prop.',e,t))}function s(e,t,n){R.test(e)&&u("Child objects should have non-numeric keys so ordering is preserved.",t,n)}function u(e,t,n){var r=i(),a="string"==typeof n?n:n.displayName||n.name,s=r||a,u=E[e]||(E[e]={});if(!u.hasOwnProperty(s)){u[s]=!0;var l="";if(t&&t._owner&&t._owner!==y.current){var c=o(t._owner);l=" It was passed a child from "+c+"."}}}function l(e,t){if(Array.isArray(e))for(var n=0;n");var s="";o&&(s=" The element was created by "+o+".")}}function d(e,t){return e!==e?t!==t:0===e&&0===t?1/e===1/t:e===t}function h(e){if(e._store){var t=e._store.originalProps,n=e.props;for(var r in n)n.hasOwnProperty(r)&&(t.hasOwnProperty(r)&&d(t[r],n[r])||(p(r,e),t[r]=n[r]))}}function f(e){if(null!=e.type){var t=_.getComponentClassForElement(e),n=t.displayName||t.name;t.propTypes&&c(n,t.propTypes,e.props,g.prop),"function"==typeof t.getDefaultProps}}var m=e("./ReactElement"),v=e("./ReactFragment"),g=e("./ReactPropTypeLocations"),y=(e("./ReactPropTypeLocationNames"),e("./ReactCurrentOwner")),_=e("./ReactNativeComponent"),b=e("./getIteratorFn"),C=e("./invariant"),E=(e("./warning"),{}),M={},R=/^\d+$/,w={},D={checkAndWarnForMutatedProps:h,createElement:function(e,t,n){var r=m.createElement.apply(this,arguments);if(null==r)return r;for(var o=2;oo;o++){t=e.ancestors[o];var a=p.getID(t)||"";v._handleTopLevel(e.topLevelType,t,a,e.nativeEvent)}}function a(e){var t=m(window);e(t)}var s=e("./EventListener"),u=e("./ExecutionEnvironment"),l=e("./PooledClass"),c=e("./ReactInstanceHandles"),p=e("./ReactMount"),d=e("./ReactUpdates"),h=e("./Object.assign"),f=e("./getEventTarget"),m=e("./getUnboundedScrollPosition");h(o.prototype,{destructor:function(){this.topLevelType=null,this.nativeEvent=null,this.ancestors.length=0}}),l.addPoolingTo(o,l.twoArgumentPooler);var v={_enabled:!0,_handleTopLevel:null,WINDOW_HANDLE:u.canUseDOM?window:null,setHandleTopLevel:function(e){v._handleTopLevel=e},setEnabled:function(e){v._enabled=!!e},isEnabled:function(){return v._enabled},trapBubbledEvent:function(e,t,n){var r=n;return r?s.listen(r,t,v.dispatchEvent.bind(null,e)):null},trapCapturedEvent:function(e,t,n){var r=n;return r?s.capture(r,t,v.dispatchEvent.bind(null,e)):null},monitorScrollValue:function(e){var t=a.bind(null,e);s.listen(window,"scroll",t)},dispatchEvent:function(e,t){if(v._enabled){var n=o.getPooled(e,t);try{d.batchedUpdates(i,n)}finally{o.release(n)}}}};t.exports=v},{"./EventListener":19,"./ExecutionEnvironment":24,"./Object.assign":31,"./PooledClass":32,"./ReactInstanceHandles":74,"./ReactMount":79,"./ReactUpdates":102,"./getEventTarget":143,"./getUnboundedScrollPosition":149}],71:[function(e,t,n){"use strict";var r=(e("./ReactElement"),e("./warning"),{create:function(e){return e},extract:function(e){return e},extractIfFragment:function(e){return e}});t.exports=r},{"./ReactElement":65,"./warning":174}],72:[function(e,t,n){"use strict";var r=e("./DOMProperty"),o=e("./EventPluginHub"),i=e("./ReactComponentEnvironment"),a=e("./ReactClass"),s=e("./ReactEmptyComponent"),u=e("./ReactBrowserEventEmitter"),l=e("./ReactNativeComponent"),c=e("./ReactDOMComponent"),p=e("./ReactPerf"),d=e("./ReactRootIndex"),h=e("./ReactUpdates"),f={Component:i.injection,Class:a.injection,DOMComponent:c.injection,DOMProperty:r.injection,EmptyComponent:s.injection,EventPluginHub:o.injection,EventEmitter:u.injection,NativeComponent:l.injection,Perf:p.injection,RootIndex:d.injection,Updates:h.injection};t.exports=f},{"./DOMProperty":13,"./EventPluginHub":20,"./ReactBrowserEventEmitter":35,"./ReactClass":40,"./ReactComponentEnvironment":43,"./ReactDOMComponent":50,"./ReactEmptyComponent":67,"./ReactNativeComponent":82,"./ReactPerf":84,"./ReactRootIndex":93,"./ReactUpdates":102}],73:[function(e,t,n){"use strict";function r(e){return i(document.documentElement,e)}var o=e("./ReactDOMSelection"),i=e("./containsNode"),a=e("./focusNode"),s=e("./getActiveElement"),u={hasSelectionCapabilities:function(e){return e&&("INPUT"===e.nodeName&&"text"===e.type||"TEXTAREA"===e.nodeName||"true"===e.contentEditable)},getSelectionInformation:function(){var e=s();return{focusedElem:e,selectionRange:u.hasSelectionCapabilities(e)?u.getSelection(e):null}},restoreSelection:function(e){var t=s(),n=e.focusedElem,o=e.selectionRange;t!==n&&r(n)&&(u.hasSelectionCapabilities(n)&&u.setSelection(n,o),a(n))},getSelection:function(e){var t;if("selectionStart"in e)t={start:e.selectionStart,end:e.selectionEnd};else if(document.selection&&"INPUT"===e.nodeName){var n=document.selection.createRange();n.parentElement()===e&&(t={start:-n.moveStart("character",-e.value.length),end:-n.moveEnd("character",-e.value.length)})}else t=o.getOffsets(e);return t||{start:0,end:0}},setSelection:function(e,t){var n=t.start,r=t.end;if("undefined"==typeof r&&(r=n),"selectionStart"in e)e.selectionStart=n,e.selectionEnd=Math.min(r,e.value.length);else if(document.selection&&"INPUT"===e.nodeName){var i=e.createTextRange();i.collapse(!0),i.moveStart("character",n),i.moveEnd("character",r-n),i.select()}else o.setOffsets(e,t)}};t.exports=u},{"./ReactDOMSelection":58,"./containsNode":126,"./focusNode":137,"./getActiveElement":139}],74:[function(e,t,n){"use strict";function r(e){return h+e.toString(36)}function o(e,t){return e.charAt(t)===h||t===e.length}function i(e){return""===e||e.charAt(0)===h&&e.charAt(e.length-1)!==h}function a(e,t){return 0===t.indexOf(e)&&o(t,e.length)}function s(e){return e?e.substr(0,e.lastIndexOf(h)):""}function u(e,t){if(d(i(e)&&i(t)),d(a(e,t)),e===t)return e;var n,r=e.length+f;for(n=r;n=a;a++)if(o(e,a)&&o(t,a))r=a;else if(e.charAt(a)!==t.charAt(a))break;var s=e.substr(0,r);return d(i(s)),s}function c(e,t,n,r,o,i){e=e||"",t=t||"",d(e!==t);var l=a(t,e);d(l||a(e,t));for(var c=0,p=l?s:u,h=e;;h=p(h,t)){var f;if(o&&h===e||i&&h===t||(f=n(h,l,r)),f===!1||h===t)break;d(c++1){var t=e.indexOf(h,1);return t>-1?e.substr(0,t):e}return null},traverseEnterLeave:function(e,t,n,r,o){var i=l(e,t);i!==e&&c(e,i,n,r,!1,!0),i!==t&&c(i,t,n,o,!0,!1)},traverseTwoPhase:function(e,t,n){e&&(c("",e,t,n,!0,!1),c(e,"",t,n,!1,!0))},traverseAncestors:function(e,t,n){c("",e,t,n,!0,!1)},_getFirstCommonAncestorID:l,_getNextDescendantID:u,isAncestorIDOf:a,SEPARATOR:h};t.exports=v},{"./ReactRootIndex":93,"./invariant":153}],75:[function(e,t,n){"use strict";var r={remove:function(e){e._reactInternalInstance=void 0},get:function(e){return e._reactInternalInstance},has:function(e){return void 0!==e._reactInternalInstance},set:function(e,t){e._reactInternalInstance=t}};t.exports=r},{}],76:[function(e,t,n){"use strict";var r={currentlyMountingInstance:null,currentlyUnmountingInstance:null};t.exports=r},{}],77:[function(e,t,n){"use strict";function r(e,t){this.value=e,this.requestChange=t}function o(e){var t={value:"undefined"==typeof e?i.PropTypes.any.isRequired:e.isRequired,requestChange:i.PropTypes.func.isRequired};return i.PropTypes.shape(t)}var i=e("./React");r.PropTypes={link:o},t.exports=r},{"./React":33}],78:[function(e,t,n){"use strict";var r=e("./adler32"),o={CHECKSUM_ATTR_NAME:"data-react-checksum",addChecksumToMarkup:function(e){var t=r(e);return e.replace(">"," "+o.CHECKSUM_ATTR_NAME+'="'+t+'">')},canReuseMarkup:function(e,t){var n=t.getAttribute(o.CHECKSUM_ATTR_NAME);n=n&&parseInt(n,10);var i=r(e);return i===n}};t.exports=o},{"./adler32":122}],79:[function(e,t,n){"use strict";function r(e,t){for(var n=Math.min(e.length,t.length),r=0;n>r;r++)if(e.charAt(r)!==t.charAt(r))return r;return e.length===t.length?-1:n}function o(e){var t=T(e);return t&&W.getID(t)}function i(e){var t=a(e);if(t)if(L.hasOwnProperty(t)){var n=L[t];n!==e&&(k(!c(n,t)),L[t]=e)}else L[t]=e;return t}function a(e){return e&&e.getAttribute&&e.getAttribute(A)||""}function s(e,t){var n=a(e);n!==t&&delete L[n],e.setAttribute(A,t),L[t]=e}function u(e){return L.hasOwnProperty(e)&&c(L[e],e)||(L[e]=W.findReactNodeByID(e)),L[e]}function l(e){var t=C.get(e)._rootNodeID;return _.isNullComponentID(t)?null:(L.hasOwnProperty(t)&&c(L[t],t)||(L[t]=W.findReactNodeByID(t)),L[t])}function c(e,t){if(e){k(a(e)===t);var n=W.findReactContainerForID(t);if(n&&x(n,e))return!0}return!1}function p(e){delete L[e]}function d(e){var t=L[e];return t&&c(t,e)?void(Y=t):!1}function h(e){Y=null,b.traverseAncestors(e,d);var t=Y;return Y=null,t}function f(e,t,n,r,o){var i=R.mountComponent(e,t,r,O);e._isTopLevel=!0,W._mountImageIntoNode(i,n,o)}function m(e,t,n,r){var o=D.ReactReconcileTransaction.getPooled();o.perform(f,null,e,t,n,o,r),D.ReactReconcileTransaction.release(o)}var v=e("./DOMProperty"),g=e("./ReactBrowserEventEmitter"),y=(e("./ReactCurrentOwner"),e("./ReactElement")),_=(e("./ReactElementValidator"),e("./ReactEmptyComponent")),b=e("./ReactInstanceHandles"),C=e("./ReactInstanceMap"),E=e("./ReactMarkupChecksum"),M=e("./ReactPerf"),R=e("./ReactReconciler"),w=e("./ReactUpdateQueue"),D=e("./ReactUpdates"),O=e("./emptyObject"),x=e("./containsNode"),T=e("./getReactRootElementInContainer"),S=e("./instantiateReactComponent"),k=e("./invariant"),P=e("./setInnerHTML"),I=e("./shouldUpdateReactComponent"),N=(e("./warning"),b.SEPARATOR),A=v.ID_ATTRIBUTE_NAME,L={},U=1,F=9,j={},B={},V=[],Y=null,W={_instancesByReactRootID:j,scrollMonitor:function(e,t){t()},_updateRootComponent:function(e,t,n,r){return W.scrollMonitor(n,function(){w.enqueueElementInternal(e,t),r&&w.enqueueCallbackInternal(e,r)}),e},_registerComponent:function(e,t){k(t&&(t.nodeType===U||t.nodeType===F)),g.ensureScrollValueMonitoring();var n=W.registerContainer(t);return j[n]=e,n},_renderNewRootComponent:function(e,t,n){var r=S(e,null),o=W._registerComponent(r,t);return D.batchedUpdates(m,r,o,t,n),r},render:function(e,t,n){k(y.isValidElement(e));var r=j[o(t)];if(r){var i=r._currentElement;if(I(i,e))return W._updateRootComponent(r,e,t,n).getPublicInstance();W.unmountComponentAtNode(t)}var a=T(t),s=a&&W.isRenderedByReact(a),u=s&&!r,l=W._renderNewRootComponent(e,t,u).getPublicInstance();return n&&n.call(l),l},constructAndRenderComponent:function(e,t,n){var r=y.createElement(e,t);return W.render(r,n)},constructAndRenderComponentByID:function(e,t,n){var r=document.getElementById(n);return k(r),W.constructAndRenderComponent(e,t,r)},registerContainer:function(e){var t=o(e);return t&&(t=b.getReactRootIDFromNodeID(t)),t||(t=b.createReactRootID()),B[t]=e,t},unmountComponentAtNode:function(e){k(e&&(e.nodeType===U||e.nodeType===F));var t=o(e),n=j[t];return n?(W.unmountComponentFromNode(n,e),delete j[t],delete B[t],!0):!1},unmountComponentFromNode:function(e,t){for(R.unmountComponent(e),t.nodeType===F&&(t=t.documentElement);t.lastChild;)t.removeChild(t.lastChild)},findReactContainerForID:function(e){var t=b.getReactRootIDFromNodeID(e),n=B[t];return n},findReactNodeByID:function(e){var t=W.findReactContainerForID(e);return W.findComponentRoot(t,e)},isRenderedByReact:function(e){if(1!==e.nodeType)return!1;var t=W.getID(e);return t?t.charAt(0)===N:!1},getFirstReactDOM:function(e){for(var t=e;t&&t.parentNode!==t;){if(W.isRenderedByReact(t))return t;t=t.parentNode}return null},findComponentRoot:function(e,t){var n=V,r=0,o=h(t)||e;for(n[0]=o.firstChild,n.length=1;r>",E=s(),M=d(),R={array:o("array"),bool:o("boolean"),func:o("function"),number:o("number"),object:o("object"),string:o("string"),any:i(),arrayOf:a,element:E,instanceOf:u,node:M,objectOf:c,oneOf:l,oneOfType:p,shape:h};t.exports=R},{"./ReactElement":65,"./ReactFragment":71,"./ReactPropTypeLocationNames":86,"./emptyFunction":132}],89:[function(e,t,n){"use strict";function r(){this.listenersToPut=[]}var o=e("./PooledClass"),i=e("./ReactBrowserEventEmitter"),a=e("./Object.assign");a(r.prototype,{enqueuePutListener:function(e,t,n){this.listenersToPut.push({rootNodeID:e,propKey:t,propValue:n})},putListeners:function(){for(var e=0;en;n++){var r=g[n],o=r._pendingCallbacks;if(r._pendingCallbacks=null,h.performUpdateIfNecessary(r,e.reconcileTransaction),o)for(var i=0;i":">","<":"<",'"':""","'":"'"},a=/[&><"']/g;t.exports=o},{}],135:[function(e,t,n){"use strict";function r(e){return null==e?null:s(e)?e:o.has(e)?i.getNodeFromInstance(e):(a(null==e.render||"function"!=typeof e.render),void a(!1))}{var o=(e("./ReactCurrentOwner"),e("./ReactInstanceMap")),i=e("./ReactMount"),a=e("./invariant"),s=e("./isNode");e("./warning")}t.exports=r},{"./ReactCurrentOwner":47,"./ReactInstanceMap":75,"./ReactMount":79,"./invariant":153,"./isNode":155,"./warning":174}],136:[function(e,t,n){"use strict";function r(e,t,n){var r=e,o=!r.hasOwnProperty(n);o&&null!=t&&(r[n]=t)}function o(e){if(null==e)return e;var t={};return i(e,r,t),t}{var i=e("./traverseAllChildren");e("./warning")}t.exports=o},{"./traverseAllChildren":172,"./warning":174}],137:[function(e,t,n){"use strict";function r(e){try{e.focus()}catch(t){}}t.exports=r},{}],138:[function(e,t,n){"use strict";var r=function(e,t,n){Array.isArray(e)?e.forEach(t,n):e&&t.call(n,e)};t.exports=r},{}],139:[function(e,t,n){function r(){try{return document.activeElement||document.body}catch(e){return document.body}}t.exports=r},{}],140:[function(e,t,n){"use strict";function r(e){var t,n=e.keyCode;return"charCode"in e?(t=e.charCode,0===t&&13===n&&(t=13)):t=n,t>=32||13===t?t:0}t.exports=r},{}],141:[function(e,t,n){"use strict";function r(e){if(e.key){var t=i[e.key]||e.key;if("Unidentified"!==t)return t}if("keypress"===e.type){var n=o(e);return 13===n?"Enter":String.fromCharCode(n)}return"keydown"===e.type||"keyup"===e.type?a[e.keyCode]||"Unidentified":""}var o=e("./getEventCharCode"),i={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},a={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"};t.exports=r},{"./getEventCharCode":140}],142:[function(e,t,n){"use strict";function r(e){var t=this,n=t.nativeEvent;if(n.getModifierState)return n.getModifierState(e);var r=i[e];return r?!!n[r]:!1}function o(e){return r}var i={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};t.exports=o},{}],143:[function(e,t,n){"use strict";function r(e){var t=e.target||e.srcElement||window;return 3===t.nodeType?t.parentNode:t}t.exports=r},{}],144:[function(e,t,n){"use strict";function r(e){var t=e&&(o&&e[o]||e[i]);return"function"==typeof t?t:void 0}var o="function"==typeof Symbol&&Symbol.iterator,i="@@iterator";t.exports=r},{}],145:[function(e,t,n){function r(e){return i(!!a),d.hasOwnProperty(e)||(e="*"),s.hasOwnProperty(e)||(a.innerHTML="*"===e?"":"<"+e+">",s[e]=!a.firstChild),s[e]?d[e]:null}var o=e("./ExecutionEnvironment"),i=e("./invariant"),a=o.canUseDOM?document.createElement("div"):null,s={circle:!0,clipPath:!0,defs:!0,ellipse:!0,g:!0,line:!0,linearGradient:!0,path:!0,polygon:!0,polyline:!0,radialGradient:!0,rect:!0,stop:!0,text:!0},u=[1,'"],l=[1,"","
"],c=[3,"","
"],p=[1,"",""],d={"*":[1,"?
","
"],area:[1,"",""],col:[2,"","
"],legend:[1,"
","
"],param:[1,"",""],tr:[2,"","
"],optgroup:u,option:u,caption:l,colgroup:l,tbody:l,tfoot:l,thead:l,td:c,th:c,circle:p,clipPath:p,defs:p,ellipse:p,g:p,line:p,linearGradient:p,path:p,polygon:p,polyline:p,radialGradient:p,rect:p,stop:p,text:p};t.exports=r},{"./ExecutionEnvironment":24,"./invariant":153}],146:[function(e,t,n){"use strict";function r(e){for(;e&&e.firstChild;)e=e.firstChild;return e}function o(e){for(;e;){if(e.nextSibling)return e.nextSibling;e=e.parentNode}}function i(e,t){for(var n=r(e),i=0,a=0;n;){if(3===n.nodeType){if(a=i+n.textContent.length,t>=i&&a>=t)return{node:n,offset:t-i};i=a}n=r(o(n))}}t.exports=i},{}],147:[function(e,t,n){"use strict";function r(e){return e?e.nodeType===o?e.documentElement:e.firstChild:null}var o=9;t.exports=r},{}],148:[function(e,t,n){"use strict";function r(){return!i&&o.canUseDOM&&(i="textContent"in document.documentElement?"textContent":"innerText"),i}var o=e("./ExecutionEnvironment"),i=null;t.exports=r},{"./ExecutionEnvironment":24}],149:[function(e,t,n){"use strict";function r(e){return e===window?{x:window.pageXOffset||document.documentElement.scrollLeft,y:window.pageYOffset||document.documentElement.scrollTop}:{x:e.scrollLeft,y:e.scrollTop}}t.exports=r},{}],150:[function(e,t,n){function r(e){return e.replace(o,"-$1").toLowerCase()}var o=/([A-Z])/g;t.exports=r},{}],151:[function(e,t,n){"use strict";function r(e){return o(e).replace(i,"-ms-")}var o=e("./hyphenate"),i=/^ms-/;t.exports=r},{"./hyphenate":150}],152:[function(e,t,n){"use strict";function r(e){return"function"==typeof e&&"undefined"!=typeof e.prototype&&"function"==typeof e.prototype.mountComponent&&"function"==typeof e.prototype.receiveComponent}function o(e,t){var n;if((null===e||e===!1)&&(e=a.emptyElement),"object"==typeof e){var o=e;n=t===o.type&&"string"==typeof o.type?s.createInternalComponent(o):r(o.type)?new o.type(o):new c}else"string"==typeof e||"number"==typeof e?n=s.createInstanceForText(e):l(!1);return n.construct(e),n._mountIndex=0,n._mountImage=null,n}var i=e("./ReactCompositeComponent"),a=e("./ReactEmptyComponent"),s=e("./ReactNativeComponent"),u=e("./Object.assign"),l=e("./invariant"),c=(e("./warning"),function(){});u(c.prototype,i.Mixin,{_instantiateReactComponent:o}),t.exports=o},{"./Object.assign":31,"./ReactCompositeComponent":45,"./ReactEmptyComponent":67,"./ReactNativeComponent":82,"./invariant":153,"./warning":174}],153:[function(e,t,n){"use strict";var r=function(e,t,n,r,o,i,a,s){if(!e){var u;if(void 0===t)u=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var l=[n,r,o,i,a,s],c=0;u=new Error("Invariant Violation: "+t.replace(/%s/g,function(){return l[c++]}))}throw u.framesToPop=1,u}};t.exports=r},{}],154:[function(e,t,n){"use strict";function r(e,t){if(!i.canUseDOM||t&&!("addEventListener"in document))return!1;var n="on"+e,r=n in document;if(!r){var a=document.createElement("div");a.setAttribute(n,"return;"),r="function"==typeof a[n]}return!r&&o&&"wheel"===e&&(r=document.implementation.hasFeature("Events.wheel","3.0")),r}var o,i=e("./ExecutionEnvironment");i.canUseDOM&&(o=document.implementation&&document.implementation.hasFeature&&document.implementation.hasFeature("","")!==!0),t.exports=r},{"./ExecutionEnvironment":24}],155:[function(e,t,n){function r(e){return!(!e||!("function"==typeof Node?e instanceof Node:"object"==typeof e&&"number"==typeof e.nodeType&&"string"==typeof e.nodeName))}t.exports=r},{}],156:[function(e,t,n){"use strict";function r(e){return e&&("INPUT"===e.nodeName&&o[e.type]||"TEXTAREA"===e.nodeName)}var o={color:!0,date:!0,datetime:!0,"datetime-local":!0,email:!0,month:!0,number:!0,password:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0};t.exports=r},{}],157:[function(e,t,n){function r(e){return o(e)&&3==e.nodeType}var o=e("./isNode");t.exports=r},{"./isNode":155}],158:[function(e,t,n){"use strict";function r(e){e||(e="");var t,n=arguments.length;if(n>1)for(var r=1;n>r;r++)t=arguments[r],t&&(e=(e?e+" ":"")+t);return e}t.exports=r},{}],159:[function(e,t,n){"use strict";var r=e("./invariant"),o=function(e){var t,n={};r(e instanceof Object&&!Array.isArray(e));for(t in e)e.hasOwnProperty(t)&&(n[t]=t);return n};t.exports=o},{"./invariant":153}],160:[function(e,t,n){var r=function(e){var t;for(t in e)if(e.hasOwnProperty(t))return t;return null};t.exports=r},{}],161:[function(e,t,n){"use strict";function r(e,t,n){if(!e)return null;var r={};for(var i in e)o.call(e,i)&&(r[i]=t.call(n,e[i],i,e));return r}var o=Object.prototype.hasOwnProperty;t.exports=r},{}],162:[function(e,t,n){"use strict";function r(e){var t={};return function(n){return t.hasOwnProperty(n)||(t[n]=e.call(this,n)),t[n]}}t.exports=r},{}],163:[function(e,t,n){"use strict";function r(e){return i(o.isValidElement(e)),e}var o=e("./ReactElement"),i=e("./invariant");t.exports=r},{"./ReactElement":65,"./invariant":153}],164:[function(e,t,n){"use strict";var r,o=e("./ExecutionEnvironment");o.canUseDOM&&(r=window.performance||window.msPerformance||window.webkitPerformance),t.exports=r||{}},{"./ExecutionEnvironment":24}],165:[function(e,t,n){var r=e("./performance");r&&r.now||(r=Date);var o=r.now.bind(r);t.exports=o},{"./performance":164}],166:[function(e,t,n){"use strict";function r(e){return'"'+o(e)+'"'}var o=e("./escapeTextContentForBrowser");t.exports=r},{"./escapeTextContentForBrowser":134}],167:[function(e,t,n){"use strict";var r=e("./ExecutionEnvironment"),o=/^[ \r\n\t\f]/,i=/<(!--|link|noscript|meta|script|style)[ \r\n\t\f\/>]/,a=function(e,t){e.innerHTML=t};if("undefined"!=typeof MSApp&&MSApp.execUnsafeLocalFunction&&(a=function(e,t){MSApp.execUnsafeLocalFunction(function(){ +e.innerHTML=t})}),r.canUseDOM){var s=document.createElement("div");s.innerHTML=" ",""===s.innerHTML&&(a=function(e,t){if(e.parentNode&&e.parentNode.replaceChild(e,e),o.test(t)||"<"===t[0]&&i.test(t)){e.innerHTML="\ufeff"+t;var n=e.firstChild;1===n.data.length?e.removeChild(n):n.deleteData(0,1)}else e.innerHTML=t})}t.exports=a},{"./ExecutionEnvironment":24}],168:[function(e,t,n){"use strict";var r=e("./ExecutionEnvironment"),o=e("./escapeTextContentForBrowser"),i=e("./setInnerHTML"),a=function(e,t){e.textContent=t};r.canUseDOM&&("textContent"in document.documentElement||(a=function(e,t){i(e,o(t))})),t.exports=a},{"./ExecutionEnvironment":24,"./escapeTextContentForBrowser":134,"./setInnerHTML":167}],169:[function(e,t,n){"use strict";function r(e,t){if(e===t)return!0;var n;for(n in e)if(e.hasOwnProperty(n)&&(!t.hasOwnProperty(n)||e[n]!==t[n]))return!1;for(n in t)if(t.hasOwnProperty(n)&&!e.hasOwnProperty(n))return!1;return!0}t.exports=r},{}],170:[function(e,t,n){"use strict";function r(e,t){if(null!=e&&null!=t){var n=typeof e,r=typeof t;if("string"===n||"number"===n)return"string"===r||"number"===r;if("object"===r&&e.type===t.type&&e.key===t.key){var o=e._owner===t._owner;return o}}return!1}e("./warning");t.exports=r},{"./warning":174}],171:[function(e,t,n){function r(e){var t=e.length;if(o(!Array.isArray(e)&&("object"==typeof e||"function"==typeof e)),o("number"==typeof t),o(0===t||t-1 in e),e.hasOwnProperty)try{return Array.prototype.slice.call(e)}catch(n){}for(var r=Array(t),i=0;t>i;i++)r[i]=e[i];return r}var o=e("./invariant");t.exports=r},{"./invariant":153}],172:[function(e,t,n){"use strict";function r(e){return v[e]}function o(e,t){return e&&null!=e.key?a(e.key):t.toString(36)}function i(e){return(""+e).replace(g,r)}function a(e){return"$"+i(e)}function s(e,t,n,r,i){var u=typeof e;if(("undefined"===u||"boolean"===u)&&(e=null),null===e||"string"===u||"number"===u||l.isValidElement(e))return r(i,e,""===t?f+o(e,0):t,n),1;var p,v,g,y=0;if(Array.isArray(e))for(var _=0;_r;++r)n[r].apply(this,t)}return this},r.prototype.listeners=function(e){return this._callbacks=this._callbacks||{},this._callbacks[e]||[]},r.prototype.hasListeners=function(e){return!!this.listeners(e).length}},{}],176:[function(e,t,n){t.exports=function(e,t,n){for(var r=0,o=e.length,i=3==arguments.length?n:e[r++];o>r;)i=t.call(null,i,e[r],++r,e);return i}},{}],177:[function(e,t,n){var r,o="undefined"!=typeof window?window.navigator.userAgent:"",i=/OS X/.test(o),a=/Opera/.test(o),s=!/like Gecko/.test(o)&&!a,u=t.exports={0:i?"":"",1:"",2:"",3:"",4:"",5:"",6:"",8:"",9:"",12:"",13:"",16:"",17:"",18:"",19:"",20:"",21:"",23:"",24:"",25:"",27:"",28:"",29:"",30:"",31:"",27:"",32:"",33:"",34:"",35:"",36:"",37:"",38:"",39:"",40:"",41:"'+s.join("")+"",d(c.yearRange)?(i=c.yearRange[0],a=c.yearRange[1]+1):(i=n-c.yearRange,a=1+n+c.yearRange),s=[];a>i&&i<=c.maxYear;i++)i>=c.minYear&&s.push('");return l='
'+n+c.yearSuffix+'
",f+=c.showMonthAfterYear?l+u:u+l,p&&(0===r||c.minMonth>=r)&&(m=!1),h&&(11===r||c.maxMonth<=r)&&(v=!1),0===t&&(f+='"),t===e._o.numberOfMonths-1&&(f+='"),f+=""},T=function(e,t){return''+O(e)+D(t)+"
"},S=function(a){var s=this,u=s.config(a);s._onMouseDown=function(e){if(s._v){e=e||window.event;var t=e.target||e.srcElement;if(t){if(!l(t.parentNode,"is-disabled")){if(l(t,"pika-button")&&!l(t,"is-empty"))return s.setDate(new Date(t.getAttribute("data-pika-year"),t.getAttribute("data-pika-month"),t.getAttribute("data-pika-day"))),void(u.bound&&o(function(){s.hide(),u.field&&u.field.blur()},100));l(t,"pika-prev")?s.prevMonth():l(t,"pika-next")&&s.nextMonth()}if(l(t,"pika-select"))s._c=!0;else{if(!e.preventDefault)return e.returnValue=!1,!1;e.preventDefault()}}}},s._onChange=function(e){e=e||window.event;var t=e.target||e.srcElement;t&&(l(t,"pika-select-month")?s.gotoMonth(t.value):l(t,"pika-select-year")&&s.gotoYear(t.value))},s._onInputChange=function(n){var r;n.firedBy!==s&&(t?(r=e(u.field.value,u.format),r=r&&r.isValid()?r.toDate():null):r=new Date(Date.parse(u.field.value)),h(r)&&s.setDate(r),s._v||s.show())},s._onInputFocus=function(){s.show()},s._onInputClick=function(){s.show()},s._onInputBlur=function(){var e=r.activeElement;do if(l(e,"pika-single"))return;while(e=e.parentNode);s._c||(s._b=o(function(){s.hide()},50)),s._c=!1},s._onClick=function(e){e=e||window.event;var t=e.target||e.srcElement,r=t;if(t){!n&&l(t,"pika-select")&&(t.onchange||(t.setAttribute("onchange","return;"),i(t,"change",s._onChange)));do if(l(r,"pika-single")||r===u.trigger)return;while(r=r.parentNode);s._v&&t!==u.trigger&&r!==u.trigger&&s.hide()}},s.el=r.createElement("div"),s.el.className="pika-single"+(u.isRTL?" is-rtl":"")+(u.theme?" "+u.theme:""),i(s.el,"ontouchend"in r?"touchend":"mousedown",s._onMouseDown,!0),i(s.el,"change",s._onChange),u.field&&(u.container?u.container.appendChild(s.el):u.bound?r.body.appendChild(s.el):u.field.parentNode.insertBefore(s.el,u.field.nextSibling),i(u.field,"change",s._onInputChange),u.defaultDate||(u.defaultDate=t&&u.field.value?e(u.field.value,u.format).toDate():new Date(Date.parse(u.field.value)),u.setDefaultDate=!0));var c=u.defaultDate;h(c)?u.setDefaultDate?s.setDate(c,!0):s.gotoDate(c):s.gotoDate(new Date),u.bound?(this.hide(),s.el.className+=" is-bound",i(u.trigger,"click",s._onInputClick),i(u.trigger,"focus",s._onInputFocus),i(u.trigger,"blur",s._onInputBlur)):this.show()};return S.prototype={config:function(e){this._o||(this._o=_({},C,!0));var t=_(this._o,e,!0);t.isRTL=!!t.isRTL,t.field=t.field&&t.field.nodeName?t.field:null,t.theme="string"==typeof t.theme&&t.theme?t.theme:null,t.bound=!!(void 0!==t.bound?t.field&&t.bound:t.field),t.trigger=t.trigger&&t.trigger.nodeName?t.trigger:t.field,t.disableWeekends=!!t.disableWeekends,t.disableDayFn="function"==typeof t.disableDayFn?t.disableDayFn:null;var n=parseInt(t.numberOfMonths,10)||1;if(t.numberOfMonths=n>4?4:n,h(t.minDate)||(t.minDate=!1),h(t.maxDate)||(t.maxDate=!1),t.minDate&&t.maxDate&&t.maxDate100&&(t.yearRange=100);return t},toString:function(n){return h(this._d)?t?e(this._d).format(n||this._o.format):this._d.toDateString():""},getMoment:function(){return t?e(this._d):null},setMoment:function(n,r){t&&e.isMoment(n)&&this.setDate(n.toDate(),r)},getDate:function(){return h(this._d)?new Date(this._d.getTime()):null},setDate:function(e,t){if(!e)return this._d=null,this._o.field&&(this._o.field.value="",s(this._o.field,"change",{firedBy:this})),this.draw();if("string"==typeof e&&(e=new Date(Date.parse(e))),h(e)){var n=this._o.minDate,r=this._o.maxDate;h(n)&&n>e?e=n:h(r)&&e>r&&(e=r),this._d=new Date(e.getTime()),g(this._d),this.gotoDate(this._d),this._o.field&&(this._o.field.value=this.toString(),s(this._o.field,"change",{firedBy:this})),t||"function"!=typeof this._o.onSelect||this._o.onSelect.call(this,this.getDate())}},gotoDate:function(e){var t=!0;if(h(e)){if(this.calendars){var n=new Date(this.calendars[0].year,this.calendars[0].month,1),r=new Date(this.calendars[this.calendars.length-1].year,this.calendars[this.calendars.length-1].month,1),o=e.getTime();r.setMonth(r.getMonth()+1),r.setDate(r.getDate()-1),t=o=r&&(this._y=r,!isNaN(a)&&this._m>a&&(this._m=a));for(var u=0;u'+x(this,u,this.calendars[u].year,this.calendars[u].month,this.calendars[0].year)+this.render(this.calendars[u].year,this.calendars[u].month)+"";if(this.el.innerHTML=s,t.bound&&"hidden"!==t.field.type&&o(function(){t.trigger.focus()},1),"function"==typeof this._o.onDraw){var l=this;o(function(){l._o.onDraw.call(l)},0)}}},adjustPosition:function(){var e,t,n,o,i,a,s,u,l,c;if(!this._o.container){if(this.el.style.position="absolute",e=this._o.trigger,t=e,n=this.el.offsetWidth,o=this.el.offsetHeight,i=window.innerWidth||r.documentElement.clientWidth,a=window.innerHeight||r.documentElement.clientHeight,s=window.pageYOffset||r.body.scrollTop||r.documentElement.scrollTop,"function"==typeof e.getBoundingClientRect)c=e.getBoundingClientRect(),u=c.left+window.pageXOffset,l=c.bottom+window.pageYOffset;else for(u=t.offsetLeft,l=t.offsetTop+t.offsetHeight;t=t.offsetParent;)u+=t.offsetLeft,l+=t.offsetTop;(this._o.reposition&&u+n>i||this._o.position.indexOf("right")>-1&&u-n+e.offsetWidth>0)&&(u=u-n+e.offsetWidth),(this._o.reposition&&l+o>a+s||this._o.position.indexOf("top")>-1&&l-o-e.offsetHeight>0)&&(l=l-o-e.offsetHeight),this.el.style.left=u+"px",this.el.style.top=l+"px"}},render:function(e,t){var n=this._o,r=new Date,o=v(e,t),i=new Date(e,t,1).getDay(),a=[],s=[];g(r),n.firstDay>0&&(i-=n.firstDay,0>i&&(i+=7));for(var u=o+i,l=u;l>7;)l-=7;u+=7-l;for(var c=0,p=0;u>c;c++){var d,m=new Date(e,t,1+(c-i)),_=h(this._d)?y(m,this._d):!1,b=y(m,r),C=i>c||c>=o+i,E=n.startRange&&y(n.startRange,m),D=n.endRange&&y(n.endRange,m),O=n.startRange&&n.endRange&&n.startRangen.maxDate||n.disableWeekends&&f(m)||n.disableDayFn&&n.disableDayFn(m),d={day:1+(c-i),month:t,year:e,isSelected:_,isToday:b,isDisabled:x,isEmpty:C,isStartRange:E,isEndRange:D,isInRange:O};s.push(M(d)),7===++p&&(n.showWeekNumber&&s.unshift(R(c-i,t,e)),a.push(w(s,n.isRTL)),s=[],p=0)}return T(n,a)},isVisible:function(){return this._v},show:function(){this._v||(p(this.el,"is-hidden"),this._v=!0,this.draw(),this._o.bound&&(i(r,"click",this._onClick),this.adjustPosition()),"function"==typeof this._o.onOpen&&this._o.onOpen.call(this))},hide:function(){var e=this._v;e!==!1&&(this._o.bound&&a(r,"click",this._onClick),this.el.style.position="static",this.el.style.left="auto",this.el.style.top="auto",c(this.el,"is-hidden"),this._v=!1,void 0!==e&&"function"==typeof this._o.onClose&&this._o.onClose.call(this))},destroy:function(){this.hide(),a(this.el,"mousedown",this._onMouseDown,!0),a(this.el,"change",this._onChange),this._o.field&&(a(this._o.field,"change",this._onInputChange),this._o.bound&&(a(this._o.trigger,"click",this._onInputClick),a(this._o.trigger,"focus",this._onInputFocus),a(this._o.trigger,"blur",this._onInputBlur))),this.el.parentNode&&this.el.parentNode.removeChild(this.el)}},S})},{moment:"moment"}],"react-alt-text":[function(e,t,n){var r=e("react"),o=e("blacklist"),i=e("vkey"),a=r.createClass({displayName:"AltText",getDefaultProps:function(){return{component:"span",modifier:"",normal:"",modified:""}},getInitialState:function(){return{modified:!1}},componentDidMount:function(){document.body.addEventListener("keydown",this.handleKeyDown,!1),document.body.addEventListener("keyup",this.handleKeyUp,!1)},handleKeyDown:function(e){i[e.keyCode]===this.props.modifier&&this.setState({modified:!0})},handleKeyUp:function(e){i[e.keyCode]===this.props.modifier&&this.setState({modified:!1})},componentWillUnmount:function(){document.body.removeEventListener("keydown",this.handleKeyDown),document.body.removeEventListener("keyup",this.handleKeyUp)},render:function(){var e=o(this.props,"component","modifier","normal","modified");return r.createElement(this.props.component,e,this.state.modified?this.props.modified:this.props.normal)}});t.exports=a},{blacklist:1,react:"react",vkey:177}],"react-select":[function(e,t,n){"use strict";var r=Object.assign||function(e){for(var t=1;ti.bottom||r.top-1)return!1;if(this.props.filterOption)return this.props.filterOption.call(this,e,n);var t=String(e.value),o=String(e.label);return this.props.ignoreCase&&(t=t.toLowerCase(),o=o.toLowerCase(),n=n.toLowerCase()),n&&"start"!==this.props.matchPos?"label"!==this.props.matchProp&&t.indexOf(n)>=0||"value"!==this.props.matchProp&&o.indexOf(n)>=0:"label"!==this.props.matchProp&&t.substr(0,n.length)===n||"value"!==this.props.matchProp&&o.substr(0,n.length)===n};return(e||[]).filter(o,this)},selectFocusedOption:function(){return this.selectValue(this.props.allowCreate&&!this.state.focusedOption?this.state.inputValue:this.state.focusedOption)},focusOption:function(e){this.setState({focusedOption:e})},focusNextOption:function(){this.focusAdjacentOption("next")},focusPreviousOption:function(){this.focusAdjacentOption("previous")},focusAdjacentOption:function(e){this._focusedOptionReveal=!0;var t=this.state.filteredOptions;if(!this.state.isOpen)return void this.setState({isOpen:!0,inputValue:"",focusedOption:this.state.focusedOption||t["next"===e?0:t.length-1]},this._bindCloseMenuIfClickedOutside);if(t.length){for(var n=-1,r=0;r-1&&n0?t[n-1]:t[t.length-1]),this.setState({focusedOption:o})}},unfocusOption:function(e){this.state.focusedOption===e&&this.setState({focusedOption:null})},buildMenu:function(){var e=this.state.focusedOption?this.state.focusedOption.value:null,t=this.props.optionRenderer||function(e){return e.label};this.state.filteredOptions.length>0&&(e=null==e?this.state.filteredOptions[0]:e);var n=this.state.filteredOptions;if(this.props.allowCreate&&this.state.inputValue.trim()){var r=this.state.inputValue;n=n.slice(),n.unshift({value:r,label:r,create:!0})}var i=Object.keys(n).map(function(r){var i=n[r],s=this.state.value===i.value,u=e===i.value,l=a({"Select-option":!0,"is-selected":s,"is-focused":u,"is-disabled":i.disabled}),c=u?"focused":null,p=this.focusOption.bind(this,i),d=this.unfocusOption.bind(this,i),h=this.selectValue.bind(this,i),f=t(i);return i.disabled?o.createElement("div",{ref:c,key:"option-"+i.value,className:l},f):o.createElement("div",{ref:c,key:"option-"+i.value,className:l,onMouseEnter:p,onMouseLeave:d,onMouseDown:h,onClick:h},i.create?this.props.addLabelText.replace("{label}",i.label):f)},this);return i.length?i:o.createElement("div",{className:"Select-noresults"},this.props.asyncOptions&&!this.state.inputValue?this.props.searchPromptText:this.props.noResultsText)},handleOptionLabelClick:function(e,t){this.props.onOptionLabelClick&&this.props.onOptionLabelClick(e,t)},render:function(){var e=a("Select",this.props.className,{"is-multi":this.props.multi,"is-searchable":this.props.searchable,"is-open":this.state.isOpen,"is-focused":this.state.isFocused,"is-loading":this.state.isLoading,"is-disabled":this.props.disabled,"has-value":this.state.value}),t=[];this.props.multi&&this.state.values.forEach(function(e){t.push(o.createElement(s,{key:e.value,option:e,renderer:this.props.valueRenderer,optionLabelClick:!!this.props.onOptionLabelClick,onOptionLabelClick:this.handleOptionLabelClick.bind(this,e),onRemove:this.removeValue.bind(this,e),disabled:this.props.disabled}))},this),this.state.inputValue||this.props.multi&&t.length||t.push(o.createElement("div",{className:"Select-placeholder",key:"placeholder"},this.state.placeholder));var n,u,l=this.state.isLoading?o.createElement("span",{className:"Select-loading","aria-hidden":"true"}):null,c=this.props.clearable&&this.state.value&&!this.props.disabled?o.createElement("span",{className:"Select-clear",title:this.props.multi?this.props.clearAllText:this.props.clearValueText,"aria-label":this.props.multi?this.props.clearAllText:this.props.clearValueText,onMouseDown:this.clearValue,onClick:this.clearValue,dangerouslySetInnerHTML:{__html:"×"}}):null;this.state.isOpen&&(u={ref:"menu",className:"Select-menu"},this.props.multi&&(u.onMouseDown=this.handleMouseDown),n=o.createElement("div",{ref:"selectMenuContainer",className:"Select-menu-outer"},o.createElement("div",u,this.buildMenu())));var p,d={ref:"input",className:"Select-input",tabIndex:this.props.tabIndex||0,onFocus:this.handleInputFocus,onBlur:this.handleInputBlur};for(var h in this.props.inputProps)this.props.inputProps.hasOwnProperty(h)&&(d[h]=this.props.inputProps[h]);return this.props.disabled?this.props.multi&&this.state.values.length||(p=o.createElement("div",{className:"Select-input"}," ")):p=this.props.searchable?o.createElement(i,r({value:this.state.inputValue,onChange:this.handleInputChange,minWidth:"5"},d)):o.createElement("div",d," "),o.createElement("div",{ref:"wrapper",className:e},o.createElement("input",{type:"hidden",ref:"value",name:this.props.name,value:this.state.value,disabled:this.props.disabled}),o.createElement("div",{className:"Select-control",ref:"control",onKeyDown:this.handleKeyDown,onMouseDown:this.handleMouseDown,onTouchEnd:this.handleMouseDown},t,p,o.createElement("span",{className:"Select-arrow-zone",onMouseDown:this.handleMouseDownOnArrow}),o.createElement("span",{className:"Select-arrow",onMouseDown:this.handleMouseDownOnArrow}),l,c),n)}});t.exports=l},{"./Value":2,classnames:"classnames",react:"react","react-input-autosize":3}],"react/addons":[function(e,t,n){t.exports=e("./lib/ReactWithAddons")},{"./lib/ReactWithAddons":103}],react:[function(e,t,n){t.exports=e("./lib/React")},{"./lib/React":33}],superagent:[function(e,t,n){function r(){}function o(e){var t={}.toString.call(e);switch(t){case"[object File]":case"[object Blob]":case"[object FormData]":return!0;default:return!1}}function i(e){return e===Object(e)}function a(e){if(!i(e))return e;var t=[];for(var n in e)null!=e[n]&&t.push(encodeURIComponent(n)+"="+encodeURIComponent(e[n]));return t.join("&")}function s(e){for(var t,n,r={},o=e.split("&"),i=0,a=o.length;a>i;++i)n=o[i],t=n.split("="),r[decodeURIComponent(t[0])]=decodeURIComponent(t[1]); + +return r}function u(e){var t,n,r,o,i=e.split(/\r?\n/),a={};i.pop();for(var s=0,u=i.length;u>s;++s)n=i[s],t=n.indexOf(":"),r=n.slice(0,t).toLowerCase(),o=g(n.slice(t+1)),a[r]=o;return a}function l(e){return e.split(/ *; */).shift()}function c(e){return m(e.split(/ *; */),function(e,t){var n=t.split(/ *= */),r=n.shift(),o=n.shift();return r&&o&&(e[r]=o),e},{})}function p(e,t){t=t||{},this.req=e,this.xhr=this.req.xhr,this.text="HEAD"!=this.req.method&&(""===this.xhr.responseType||"text"===this.xhr.responseType)||"undefined"==typeof this.xhr.responseType?this.xhr.responseText:null,this.statusText=this.req.xhr.statusText,this.setStatusProperties(this.xhr.status),this.header=this.headers=u(this.xhr.getAllResponseHeaders()),this.header["content-type"]=this.xhr.getResponseHeader("content-type"),this.setHeaderProperties(this.header),this.body="HEAD"!=this.req.method?this.parseBody(this.text?this.text:this.xhr.response):null}function d(e,t){var n=this;f.call(this),this._query=this._query||[],this.method=e,this.url=t,this.header={},this._header={},this.on("end",function(){var e=null,t=null;try{t=new p(n)}catch(r){return e=new Error("Parser is unable to parse the response"),e.parse=!0,e.original=r,n.callback(e)}if(n.emit("response",t),e)return n.callback(e,t);if(t.status>=200&&t.status<300)return n.callback(e,t);var o=new Error(t.statusText||"Unsuccessful HTTP response");o.original=e,o.response=t,o.status=t.status,n.callback(e||o,t)})}function h(e,t){return"function"==typeof t?new d("GET",e).end(t):1==arguments.length?new d("GET",e):new d(e,t)}var f=e("emitter"),m=e("reduce"),v="undefined"==typeof window?this||self:window;h.getXHR=function(){if(!(!v.XMLHttpRequest||v.location&&"file:"==v.location.protocol&&v.ActiveXObject))return new XMLHttpRequest;try{return new ActiveXObject("Microsoft.XMLHTTP")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP.6.0")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP.3.0")}catch(e){}try{return new ActiveXObject("Msxml2.XMLHTTP")}catch(e){}return!1};var g="".trim?function(e){return e.trim()}:function(e){return e.replace(/(^\s*|\s*$)/g,"")};h.serializeObject=a,h.parseString=s,h.types={html:"text/html",json:"application/json",xml:"application/xml",urlencoded:"application/x-www-form-urlencoded",form:"application/x-www-form-urlencoded","form-data":"application/x-www-form-urlencoded"},h.serialize={"application/x-www-form-urlencoded":a,"application/json":JSON.stringify},h.parse={"application/x-www-form-urlencoded":s,"application/json":JSON.parse},p.prototype.get=function(e){return this.header[e.toLowerCase()]},p.prototype.setHeaderProperties=function(e){var t=this.header["content-type"]||"";this.type=l(t);var n=c(t);for(var r in n)this[r]=n[r]},p.prototype.parseBody=function(e){var t=h.parse[this.type];return t&&e&&(e.length||e instanceof Object)?t(e):null},p.prototype.setStatusProperties=function(e){1223===e&&(e=204);var t=e/100|0;this.status=e,this.statusType=t,this.info=1==t,this.ok=2==t,this.clientError=4==t,this.serverError=5==t,this.error=4==t||5==t?this.toError():!1,this.accepted=202==e,this.noContent=204==e,this.badRequest=400==e,this.unauthorized=401==e,this.notAcceptable=406==e,this.notFound=404==e,this.forbidden=403==e},p.prototype.toError=function(){var e=this.req,t=e.method,n=e.url,r="cannot "+t+" "+n+" ("+this.status+")",o=new Error(r);return o.status=this.status,o.method=t,o.url=n,o},h.Response=p,f(d.prototype),d.prototype.use=function(e){return e(this),this},d.prototype.timeout=function(e){return this._timeout=e,this},d.prototype.clearTimeout=function(){return this._timeout=0,clearTimeout(this._timer),this},d.prototype.abort=function(){return this.aborted?void 0:(this.aborted=!0,this.xhr.abort(),this.clearTimeout(),this.emit("abort"),this)},d.prototype.set=function(e,t){if(i(e)){for(var n in e)this.set(n,e[n]);return this}return this._header[e.toLowerCase()]=t,this.header[e]=t,this},d.prototype.unset=function(e){return delete this._header[e.toLowerCase()],delete this.header[e],this},d.prototype.getHeader=function(e){return this._header[e.toLowerCase()]},d.prototype.type=function(e){return this.set("Content-Type",h.types[e]||e),this},d.prototype.accept=function(e){return this.set("Accept",h.types[e]||e),this},d.prototype.auth=function(e,t){var n=btoa(e+":"+t);return this.set("Authorization","Basic "+n),this},d.prototype.query=function(e){return"string"!=typeof e&&(e=a(e)),e&&this._query.push(e),this},d.prototype.field=function(e,t){return this._formData||(this._formData=new v.FormData),this._formData.append(e,t),this},d.prototype.attach=function(e,t,n){return this._formData||(this._formData=new v.FormData),this._formData.append(e,t,n),this},d.prototype.send=function(e){var t=i(e),n=this.getHeader("Content-Type");if(t&&i(this._data))for(var r in e)this._data[r]=e[r];else"string"==typeof e?(n||this.type("form"),n=this.getHeader("Content-Type"),this._data="application/x-www-form-urlencoded"==n?this._data?this._data+"&"+e:e:(this._data||"")+e):this._data=e;return!t||o(e)?this:(n||this.type("json"),this)},d.prototype.callback=function(e,t){var n=this._callback;this.clearTimeout(),n(e,t)},d.prototype.crossDomainError=function(){var e=new Error("Origin is not allowed by Access-Control-Allow-Origin");e.crossDomain=!0,this.callback(e)},d.prototype.timeoutError=function(){var e=this._timeout,t=new Error("timeout of "+e+"ms exceeded");t.timeout=e,this.callback(t)},d.prototype.withCredentials=function(){return this._withCredentials=!0,this},d.prototype.end=function(e){var t=this,n=this.xhr=h.getXHR(),i=this._query.join("&"),a=this._timeout,s=this._formData||this._data;this._callback=e||r,n.onreadystatechange=function(){if(4==n.readyState){var e;try{e=n.status}catch(r){e=0}if(0==e){if(t.timedout)return t.timeoutError();if(t.aborted)return;return t.crossDomainError()}t.emit("end")}};var u=function(e){e.total>0&&(e.percent=e.loaded/e.total*100),t.emit("progress",e)};this.hasListeners("progress")&&(n.onprogress=u);try{n.upload&&this.hasListeners("progress")&&(n.upload.onprogress=u)}catch(l){}if(a&&!this._timer&&(this._timer=setTimeout(function(){t.timedout=!0,t.abort()},a)),i&&(i=h.serializeObject(i),this.url+=~this.url.indexOf("?")?"&"+i:"?"+i),n.open(this.method,this.url,!0),this._withCredentials&&(n.withCredentials=!0),"GET"!=this.method&&"HEAD"!=this.method&&"string"!=typeof s&&!o(s)){var c=h.serialize[this.getHeader("Content-Type")];c&&(s=c(s))}for(var p in this.header)null!=this.header[p]&&n.setRequestHeader(p,this.header[p]);return this.emit("request",this),n.send(s),this},h.Request=d,h.get=function(e,t,n){var r=h("GET",e);return"function"==typeof t&&(n=t,t=null),t&&r.query(t),n&&r.end(n),r},h.head=function(e,t,n){var r=h("HEAD",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},h.del=function(e,t){var n=h("DELETE",e);return t&&n.end(t),n},h.patch=function(e,t,n){var r=h("PATCH",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},h.post=function(e,t,n){var r=h("POST",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},h.put=function(e,t,n){var r=h("PUT",e);return"function"==typeof t&&(n=t,t=null),t&&r.send(t),n&&r.end(n),r},t.exports=h},{emitter:175,reduce:176}]},{},[]); \ No newline at end of file From 5cf1e9c774b1436e2da74d58c3f32a1f7f43bbed Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sat, 1 Aug 2015 23:25:11 +1000 Subject: [PATCH 61/86] Extracting getPages and paginate from core/list into separate files --- lib/list.js | 118 +------------------------------------------ lib/list/getPages.js | 28 ++++++++++ lib/list/paginate.js | 91 +++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+), 116 deletions(-) create mode 100644 lib/list/getPages.js create mode 100644 lib/list/paginate.js diff --git a/lib/list.js b/lib/list.js index b72faa10ab..fbf53b1dc5 100644 --- a/lib/list.js +++ b/lib/list.js @@ -888,122 +888,8 @@ List.prototype.getUniqueValue = function(path, generator, limit, callback) { check(); }; -/** - * Generate page array for pagination - * - * @param {Number} the maximum number pages to display in the pagination - * @param {Object} page options - */ -List.prototype.getPages = function(options, maxPages) { - var surround = Math.floor(maxPages / 2); - var firstPage = maxPages ? Math.max(1, options.currentPage - surround) : 1; - var padRight = Math.max(((options.currentPage - surround) - 1) * -1, 0); - var lastPage = maxPages ? Math.min(options.totalPages, options.currentPage + surround + padRight) : options.totalPages; - var padLeft = Math.max(((options.currentPage + surround) - lastPage), 0); - options.pages = []; - firstPage = Math.max(Math.min(firstPage, firstPage - padLeft), 1); - for (var i = firstPage; i <= lastPage; i++) { - options.pages.push(i); - } - if (firstPage !== 1) { - options.pages.shift(); - options.pages.unshift('...'); - } - if (lastPage !== Number(options.totalPages)) { - options.pages.pop(); - options.pages.push('...'); - } -}; - -/** - * Gets a special Query object that will paginate documents in the list - * - * Example: - * list.paginate({ - * page: 1, - * perPage: 100, - * maxPages: 10 - * }).exec(function(err, results) { - * // do something - * }); - * - * @param {Object} options - * @param {Function} callback (optional) - */ -List.prototype.paginate = function(options, callback) { - var list = this; - var model = this.model; - - options = options || {}; - - var query = model.find(options.filters); - - query._original_exec = query.exec; - query._original_sort = query.sort; - query._original_select = query.select; - - var currentPage = Number(options.page) || 1; - var resultsPerPage = Number(options.perPage) || 50; - var maxPages = Number(options.maxPages) || 10; - var skip = (currentPage - 1) * resultsPerPage; - - list.pagination = { maxPages: maxPages }; - - // as of mongoose 3.7.x, we need to defer sorting and field selection - // until after the count has been executed - - query.select = function() { - options.select = arguments[0]; - return query; - }; - - query.sort = function() { - options.sort = arguments[0]; - return query; - }; - - query.exec = function(callback) { - query.count(function(err, count) { - if (err) return callback(err); - - query.find().limit(resultsPerPage).skip(skip); - - // apply the select and sort options before calling exec - if (options.select) { - query._original_select(options.select); - } - - if (options.sort) { - query._original_sort(options.sort); - } - - query._original_exec(function(err, results) { - if (err) return callback(err); - var totalPages = Math.ceil(count / resultsPerPage); - var rtn = { - total: count, - results: results, - currentPage: currentPage, - totalPages: totalPages, - pages: [], - previous: (currentPage > 1) ? (currentPage - 1) : false, - next: (currentPage < totalPages) ? (currentPage + 1) : false, - first: skip + 1, - last: skip + results.length - }; - list.getPages(rtn, maxPages); - callback(err, rtn); - }); - }); - - }; - - if (callback) { - return query(callback); - } else { - return query; - } -}; +List.prototype.getPages = require('./list/getPages'); +List.prototype.paginate = require('./list/paginate'); /*! * Export class diff --git a/lib/list/getPages.js b/lib/list/getPages.js new file mode 100644 index 0000000000..d1dc1f90ec --- /dev/null +++ b/lib/list/getPages.js @@ -0,0 +1,28 @@ +/** + * Generate page array for pagination + * + * @param {Number} the maximum number pages to display in the pagination + * @param {Object} page options + */ +function getPages (options, maxPages) { + var surround = Math.floor(maxPages / 2); + var firstPage = maxPages ? Math.max(1, options.currentPage - surround) : 1; + var padRight = Math.max(((options.currentPage - surround) - 1) * -1, 0); + var lastPage = maxPages ? Math.min(options.totalPages, options.currentPage + surround + padRight) : options.totalPages; + var padLeft = Math.max(((options.currentPage + surround) - lastPage), 0); + options.pages = []; + firstPage = Math.max(Math.min(firstPage, firstPage - padLeft), 1); + for (var i = firstPage; i <= lastPage; i++) { + options.pages.push(i); + } + if (firstPage !== 1) { + options.pages.shift(); + options.pages.unshift('...'); + } + if (lastPage !== Number(options.totalPages)) { + options.pages.pop(); + options.pages.push('...'); + } +} + +module.exports = getPages; diff --git a/lib/list/paginate.js b/lib/list/paginate.js new file mode 100644 index 0000000000..205b1573bf --- /dev/null +++ b/lib/list/paginate.js @@ -0,0 +1,91 @@ +/** + * Gets a special Query object that will paginate documents in the list + * + * Example: + * list.paginate({ + * page: 1, + * perPage: 100, + * maxPages: 10 + * }).exec(function(err, results) { + * // do something + * }); + * + * @param {Object} options + * @param {Function} callback (optional) + */ +function paginate (options, callback) { + var list = this; + var model = this.model; + + options = options || {}; + + var query = model.find(options.filters); + + query._original_exec = query.exec; + query._original_sort = query.sort; + query._original_select = query.select; + + var currentPage = Number(options.page) || 1; + var resultsPerPage = Number(options.perPage) || 50; + var maxPages = Number(options.maxPages) || 10; + var skip = (currentPage - 1) * resultsPerPage; + + list.pagination = { maxPages: maxPages }; + + // as of mongoose 3.7.x, we need to defer sorting and field selection + // until after the count has been executed + + query.select = function () { + options.select = arguments[0]; + return query; + }; + + query.sort = function () { + options.sort = arguments[0]; + return query; + }; + + query.exec = function (callback) { + query.count(function (err, count) { + if (err) return callback(err); + + query.find().limit(resultsPerPage).skip(skip); + + // apply the select and sort options before calling exec + if (options.select) { + query._original_select(options.select); + } + + if (options.sort) { + query._original_sort(options.sort); + } + + query._original_exec(function (err, results) { + if (err) return callback(err); + var totalPages = Math.ceil(count / resultsPerPage); + var rtn = { + total: count, + results: results, + currentPage: currentPage, + totalPages: totalPages, + pages: [], + previous: (currentPage > 1) ? (currentPage - 1) : false, + next: (currentPage < totalPages) ? (currentPage + 1) : false, + first: skip + 1, + last: skip + results.length + }; + list.getPages(rtn, maxPages); + callback(err, rtn); + }); + }); + + }; + + if (callback) { + return query(callback); + } else { + return query; + } +} + +module.exports = paginate; From 921b9ffd641a4c46dfd196d2f6d721dd198f806f Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sat, 1 Aug 2015 23:26:44 +1000 Subject: [PATCH 62/86] Removing extraneous debug statements --- lib/core/routes.js | 3 --- 1 file changed, 3 deletions(-) diff --git a/lib/core/routes.js b/lib/core/routes.js index 515f51323a..29fb1c0926 100644 --- a/lib/core/routes.js +++ b/lib/core/routes.js @@ -108,17 +108,14 @@ function routes(app) { }); // Generic Lists API - debug('setting generic list api'); app.all('/keystone/api/:list/:action(autocomplete|order|create|fetch)', initList(), require('../../admin/api/list')); app.post('/keystone/api/:list/delete', initList(), require('../../admin/api/list/delete')); app.get('/keystone/api/:list/:id', initList(), require('../../admin/api/item/get')); app.post('/keystone/api/:list/:id/delete', initList(), require('../../admin/api/item/delete')); - debug('setting generic Lists download route'); app.all('/keystone/download/:list', initList(), require('../../admin/api/download')); // Admin-UI API - debug('setting list and item details admin routes'); app.all('/keystone/:list/:page([0-9]{1,5})?', initList(true), require('../../admin/routes/views/list')); app.all('/keystone/:list/:item', initList(true), require('../../admin/routes/views/item')); From 3bb94f84b56d4cd1672b723ebdfa288a8794678b Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sat, 1 Aug 2015 23:50:49 +1000 Subject: [PATCH 63/86] Breaking out list.getUniqueValue into its own file --- lib/list.js | 48 +------------------------------------- lib/list/getUniqueValue.js | 48 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 47 deletions(-) create mode 100644 lib/list/getUniqueValue.js diff --git a/lib/list.js b/lib/list.js index fbf53b1dc5..9482d3fc90 100644 --- a/lib/list.js +++ b/lib/list.js @@ -841,53 +841,7 @@ List.prototype.updateAll = function(data, callback) { }; -/** - * Gets a unique value from a generator method by checking for documents with the same value. - * - * To avoid infinite loops when a unique value cannot be found, it will bail and pass back an - * undefined value after 10 attemptes. - * - * WARNING: Because there will always be a small amount of time between checking for an - * existing value and saving a document, race conditions can occur and it is possible that - * another document has the 'unique' value assigned at the same time. - * - * Because of this, if true uniqueness is required, you should also create a unique index on - * the database path, and handle duplicate errors thrown on save. - * - * @param {String} path to check for uniqueness - * @param {Function} generator method to call to generate a new value - * @param {Number} the maximum number of attempts (optional, defaults to 10) - * @param {Function} callback(err, uniqueValue) - */ -List.prototype.getUniqueValue = function(path, generator, limit, callback) { - var model = this.model; - var count = 0; - var value; - if (utils.isFunction(limit)) { - callback = limit; - limit = 10; - } - if (utils.isArray(generator)) { - var fn = generator[0]; - var args = generator.slice(1); - generator = function() { - return fn.apply(this, args); - }; - } - var check = function() { - if (count++ > 10) { - return callback(undefined, undefined); - } - value = generator(); - model.count().where(path, value).exec(function(err, matches) { - if (err) return callback(err); - if (matches) return check(); - callback(undefined, value); - }); - }; - check(); -}; - +List.prototype.getUniqueValue = require('./list/getUniqueValue'); List.prototype.getPages = require('./list/getPages'); List.prototype.paginate = require('./list/paginate'); diff --git a/lib/list/getUniqueValue.js b/lib/list/getUniqueValue.js new file mode 100644 index 0000000000..234941322a --- /dev/null +++ b/lib/list/getUniqueValue.js @@ -0,0 +1,48 @@ +/** + * Gets a unique value from a generator method by checking for documents with the same value. + * + * To avoid infinite loops when a unique value cannot be found, it will bail and pass back an + * undefined value after 10 attemptes. + * + * WARNING: Because there will always be a small amount of time between checking for an + * existing value and saving a document, race conditions can occur and it is possible that + * another document has the 'unique' value assigned at the same time. + * + * Because of this, if true uniqueness is required, you should also create a unique index on + * the database path, and handle duplicate errors thrown on save. + * + * @param {String} path to check for uniqueness + * @param {Function} generator method to call to generate a new value + * @param {Number} the maximum number of attempts (optional, defaults to 10) + * @param {Function} callback(err, uniqueValue) + */ +function getUniqueValue (path, generator, limit, callback) { + var model = this.model; + var count = 0; + var value; + if (typeof limit === 'function') { + callback = limit; + limit = 10; + } + if (Array.isArray(generator)) { + var fn = generator[0]; + var args = generator.slice(1); + generator = function () { + return fn.apply(this, args); + }; + } + var check = function () { + if (count++ > 10) { + return callback(undefined, undefined); + } + value = generator(); + model.count().where(path, value).exec(function (err, matches) { + if (err) return callback(err); + if (matches) return check(); + callback(undefined, value); + }); + }; + check(); +} + +module.exports = getUniqueValue; From 3ed47d261b59b4b484fc442acc5cedf60710e76a Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sat, 1 Aug 2015 23:52:45 +1000 Subject: [PATCH 64/86] Breaking out list.updateAll into its own file --- lib/list.js | 29 +---------------------------- lib/list/updateAll.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 28 deletions(-) create mode 100644 lib/list/updateAll.js diff --git a/lib/list.js b/lib/list.js index 9482d3fc90..169e7a4878 100644 --- a/lib/list.js +++ b/lib/list.js @@ -1,5 +1,4 @@ var _ = require('underscore'); -var async = require('async'); var Field = require('../fields/types/Type'); var keystone = require('../'); var moment = require('moment'); @@ -814,33 +813,7 @@ List.prototype.getSearchFilters = function(search, add) { }; -/** - * Updates every document in a List, - * setting the provided data on each. - * - * @param {Object} data - * @param {Function} callback (optional) - */ -List.prototype.updateAll = function(data, callback) { - if ('function' === typeof data) { - callback = data; - data = null; - } - callback = callback || function() {}; - this.model.find(function(err, results) { - if (err) return callback(err); - async.eachSeries(results, function(doc, next) { - if (data) { - doc.set(data); - } - doc.save(next); - }, function(err) { - callback(err); - }); - }); -}; - - +List.prototype.updateAll = require('./list/updateAll'); List.prototype.getUniqueValue = require('./list/getUniqueValue'); List.prototype.getPages = require('./list/getPages'); List.prototype.paginate = require('./list/paginate'); diff --git a/lib/list/updateAll.js b/lib/list/updateAll.js new file mode 100644 index 0000000000..a8e6455d9d --- /dev/null +++ b/lib/list/updateAll.js @@ -0,0 +1,29 @@ +var async = require('async'); + +/** + * Updates every document in a List, + * setting the provided data on each. + * + * @param {Object} data + * @param {Function} callback (optional) + */ +function updateAll (data, callback) { + if ('function' === typeof data) { + callback = data; + data = null; + } + callback = callback || function() {}; + this.model.find(function(err, results) { + if (err) return callback(err); + async.eachSeries(results, function(doc, next) { + if (data) { + doc.set(data); + } + doc.save(next); + }, function(err) { + callback(err); + }); + }); +} + +module.exports = updateAll; From 52803c7180c9aa91ed50c9d999a479de344226bc Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sat, 1 Aug 2015 23:55:08 +1000 Subject: [PATCH 65/86] Implementing simple GET keystone/api/:list route for #1544 --- admin/api/list/get.js | 24 ++++++++++++++++++++++++ lib/core/routes.js | 1 + 2 files changed, 25 insertions(+) create mode 100644 admin/api/list/get.js diff --git a/admin/api/list/get.js b/admin/api/list/get.js new file mode 100644 index 0000000000..c3c1fb4b80 --- /dev/null +++ b/admin/api/list/get.js @@ -0,0 +1,24 @@ +var async = require('async'); + +module.exports = function(req, res) { + var query = req.list.model.find(); + async.series({ + count: function(next) { + query.count(next); + }, + items: function(next) { + query.find(); + query.limit(Number(req.query.limit) || 100); + query.skip(Number(req.query.skip) || 0); + query.exec(next); + } + }, function(err, results) { + if (err) return res.apiError('database error', err); + return res.json({ + results: results.items.map(function (item) { + return req.list.getData(item); + }), + count: results.count + }); + }); +}; diff --git a/lib/core/routes.js b/lib/core/routes.js index 29fb1c0926..530d062b35 100644 --- a/lib/core/routes.js +++ b/lib/core/routes.js @@ -110,6 +110,7 @@ function routes(app) { // Generic Lists API app.all('/keystone/api/:list/:action(autocomplete|order|create|fetch)', initList(), require('../../admin/api/list')); app.post('/keystone/api/:list/delete', initList(), require('../../admin/api/list/delete')); + app.get('/keystone/api/:list', initList(), require('../../admin/api/list/get')); app.get('/keystone/api/:list/:id', initList(), require('../../admin/api/item/get')); app.post('/keystone/api/:list/:id/delete', initList(), require('../../admin/api/item/delete')); From e2cc2c2168321b55aa248bfa991b51b434a55629 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sat, 1 Aug 2015 23:57:16 +1000 Subject: [PATCH 66/86] Implementing list-to-array package for converting various strings to arrays --- lib/list/getData.js | 4 +++- package.json | 1 + 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/lib/list/getData.js b/lib/list/getData.js index 3b005d6c5b..4dea7f0fc5 100644 --- a/lib/list/getData.js +++ b/lib/list/getData.js @@ -1,3 +1,5 @@ +var listToArray = require('list-to-array'); + /** * Gets the data from an Item ready to be serialised for client-side use, as * used by the React components @@ -16,7 +18,7 @@ function getData(item, fields) { } if (fields) { if (typeof fields === 'string') { - fields = fields.split(' '); + fields = listToArray(fields); } if (!Array.isArray(fields)) { throw new Error('List.getData: fields must be undefined, a string, or an array.'); diff --git a/package.json b/package.json index e00aa6e238..dd612b93ea 100644 --- a/package.json +++ b/package.json @@ -41,6 +41,7 @@ "keystone-utils": "~0.3.0", "knox": "~0.9.2", "less-middleware": "~2.0.1", + "list-to-array": "^1.0.0", "mandrill-api": "~1.0.45", "marked": "~0.3.5", "method-override": "~2.3.4", From b60ff08ceda25d71faa9f1e542d735afe2cd55e9 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sun, 2 Aug 2015 01:19:37 +1000 Subject: [PATCH 67/86] Implementing select query parameter for api/:list/get endpoint --- admin/api/list/get.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/api/list/get.js b/admin/api/list/get.js index c3c1fb4b80..e67a8fed13 100644 --- a/admin/api/list/get.js +++ b/admin/api/list/get.js @@ -16,7 +16,7 @@ module.exports = function(req, res) { if (err) return res.apiError('database error', err); return res.json({ results: results.items.map(function (item) { - return req.list.getData(item); + return req.list.getData(item, req.query.select); }), count: results.count }); From 96ca9f9d2b88d9e51fcf4e93e80f8c5e23eab557 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sun, 2 Aug 2015 01:26:11 +1000 Subject: [PATCH 68/86] Implementing sort functionality for api/:list/get endpoint --- admin/api/list/get.js | 1 + 1 file changed, 1 insertion(+) diff --git a/admin/api/list/get.js b/admin/api/list/get.js index e67a8fed13..857859a59d 100644 --- a/admin/api/list/get.js +++ b/admin/api/list/get.js @@ -10,6 +10,7 @@ module.exports = function(req, res) { query.find(); query.limit(Number(req.query.limit) || 100); query.skip(Number(req.query.skip) || 0); + query.sort(req.query.sort || req.list.defaultSort); query.exec(next); } }, function(err, results) { From ea966eac1d83943367397c29a5683f84fa1210c8 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sun, 2 Aug 2015 01:47:11 +1000 Subject: [PATCH 69/86] Returning query from all addFilterToQuery methods --- fields/types/boolean/BooleanType.js | 1 + fields/types/date/DateType.js | 1 + fields/types/number/NumberType.js | 1 + fields/types/password/PasswordType.js | 1 + fields/types/relationship/RelationshipType.js | 1 + fields/types/select/SelectType.js | 1 + fields/types/text/TextType.js | 1 + 7 files changed, 7 insertions(+) diff --git a/fields/types/boolean/BooleanType.js b/fields/types/boolean/BooleanType.js index f6c8af466b..04506be6f8 100644 --- a/fields/types/boolean/BooleanType.js +++ b/fields/types/boolean/BooleanType.js @@ -25,6 +25,7 @@ boolean.prototype.addFilterToQuery = function(filter, query) { } else { query[this.path] = true; } + return query; }; /** diff --git a/fields/types/date/DateType.js b/fields/types/date/DateType.js index c2d826c7c7..73cd536b31 100644 --- a/fields/types/date/DateType.js +++ b/fields/types/date/DateType.js @@ -54,6 +54,7 @@ date.prototype.addFilterToQuery = function(filter, query) { } } } + return query; }; /** diff --git a/fields/types/number/NumberType.js b/fields/types/number/NumberType.js index 495999c1c5..942490e923 100644 --- a/fields/types/number/NumberType.js +++ b/fields/types/number/NumberType.js @@ -52,6 +52,7 @@ number.prototype.addFilterToQuery = function(filter, query) { query[this.path] = value; } } + return query; }; /** diff --git a/fields/types/password/PasswordType.js b/fields/types/password/PasswordType.js index c48bf12273..96d57bf4a4 100644 --- a/fields/types/password/PasswordType.js +++ b/fields/types/password/PasswordType.js @@ -82,6 +82,7 @@ password.prototype.addToSchema = function() { password.prototype.addFilterToQuery = function(filter, query) { query = query || {}; query[this.path] = (filter.exists) ? { $ne: null } : null; + return query; }; /** diff --git a/fields/types/relationship/RelationshipType.js b/fields/types/relationship/RelationshipType.js index db13cde77c..361cc672d6 100644 --- a/fields/types/relationship/RelationshipType.js +++ b/fields/types/relationship/RelationshipType.js @@ -87,6 +87,7 @@ relationship.prototype.addFilterToQuery = function(filter, query) { query[this.path] = (filter.inverse) ? { $ne: null } : null; } } + return query; }; /** diff --git a/fields/types/select/SelectType.js b/fields/types/select/SelectType.js index 229f579377..a13635bb8f 100644 --- a/fields/types/select/SelectType.js +++ b/fields/types/select/SelectType.js @@ -110,6 +110,7 @@ select.prototype.addFilterToQuery = function(filter, query) { } else { query[this.path] = (filter.inverse) ? { $nin: ['', null] } : { $in: ['', null] }; } + return query; }; /** diff --git a/fields/types/text/TextType.js b/fields/types/text/TextType.js index 8c9ebb78bb..2d725c7e4c 100644 --- a/fields/types/text/TextType.js +++ b/fields/types/text/TextType.js @@ -33,6 +33,7 @@ text.prototype.addFilterToQuery = function(filter, query) { } value = new RegExp(value, filter.caseSensitive ? '' : 'i'); query[this.path] = filter.invert ? { $not: value } : value; + return query; }; /** From f00a1712a2c66c35e220729dc36b1d71ffd33b1f Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sun, 2 Aug 2015 01:47:31 +1000 Subject: [PATCH 70/86] New List.addFiltersToQuery method --- lib/list.js | 1 + lib/list/addFiltersToQuery.js | 12 ++++++++++++ 2 files changed, 13 insertions(+) create mode 100644 lib/list/addFiltersToQuery.js diff --git a/lib/list.js b/lib/list.js index 169e7a4878..fb0e650f33 100644 --- a/lib/list.js +++ b/lib/list.js @@ -117,6 +117,7 @@ function List(key, options) { // Add prototype methods List.prototype.getData = require('./list/getData'); List.prototype.getOptions = require('./list/getOptions'); +List.prototype.addFiltersToQuery = require('./list/addFiltersToQuery'); /** * Sets list options diff --git a/lib/list/addFiltersToQuery.js b/lib/list/addFiltersToQuery.js new file mode 100644 index 0000000000..2470493bfe --- /dev/null +++ b/lib/list/addFiltersToQuery.js @@ -0,0 +1,12 @@ +function addFiltersToQuery (filters, query) { + var fields = Object.keys(this.fields); + query = query || {}; + fields.forEach(function(path) { + var field = this.fields[path]; + if (!field.addFilterToQuery || !filters[field.path]) return; + field.addFilterToQuery(filters[field.path], query); + }, this); + return query; +} + +module.exports = addFiltersToQuery; From 0f73c7b3784b1b86ae1f641258eddaa606a9ecbf Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sun, 2 Aug 2015 01:48:11 +1000 Subject: [PATCH 71/86] Implementing filtering in api/:list/get endpoint --- admin/api/list/get.js | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/admin/api/list/get.js b/admin/api/list/get.js index 857859a59d..e0976643af 100644 --- a/admin/api/list/get.js +++ b/admin/api/list/get.js @@ -1,7 +1,16 @@ var async = require('async'); module.exports = function(req, res) { - var query = req.list.model.find(); + var filters; + if (req.query.filters) { + try { + filters = JSON.parse(req.query.filters); + } catch(e) { } + } + if (filters) { + filters = req.list.addFiltersToQuery(filters); + } + var query = req.list.model.find(filters); async.series({ count: function(next) { query.count(next); From d12705cbf7b16bc1686e5381f58cd4043db6a899 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sun, 2 Aug 2015 01:49:08 +1000 Subject: [PATCH 72/86] Cleanup --- lib/list/addFiltersToQuery.js | 2 +- lib/list/getData.js | 4 ++-- lib/list/getOptions.js | 4 ++-- lib/list/updateAll.js | 8 ++++---- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/list/addFiltersToQuery.js b/lib/list/addFiltersToQuery.js index 2470493bfe..c67bbd4f17 100644 --- a/lib/list/addFiltersToQuery.js +++ b/lib/list/addFiltersToQuery.js @@ -1,7 +1,7 @@ function addFiltersToQuery (filters, query) { var fields = Object.keys(this.fields); query = query || {}; - fields.forEach(function(path) { + fields.forEach(function (path) { var field = this.fields[path]; if (!field.addFilterToQuery || !filters[field.path]) return; field.addFilterToQuery(filters[field.path], query); diff --git a/lib/list/getData.js b/lib/list/getData.js index 4dea7f0fc5..b9a887d6a1 100644 --- a/lib/list/getData.js +++ b/lib/list/getData.js @@ -5,7 +5,7 @@ var listToArray = require('list-to-array'); * used by the React components */ -function getData(item, fields) { +function getData (item, fields) { var data = { id: item.id, name: this.getDocumentName(item) @@ -24,7 +24,7 @@ function getData(item, fields) { throw new Error('List.getData: fields must be undefined, a string, or an array.'); } data.fields = {}; - fields.forEach(function(path) { + fields.forEach(function (path) { var field = this.fields[path]; if (!field) return; data.fields[field.path] = field.getData(item); diff --git a/lib/list/getOptions.js b/lib/list/getOptions.js index 4a717434e7..193f45a333 100644 --- a/lib/list/getOptions.js +++ b/lib/list/getOptions.js @@ -3,7 +3,7 @@ var _ = require('underscore'); /** * Gets the options for the List, as used by the React components */ -function getOptions() { +function getOptions () { var ops = { key: this.key, path: this.path, @@ -31,7 +31,7 @@ function getOptions() { uiElements: [], initialFields: _.pluck(this.initialFields, 'path') }; - _.each(this.uiElements, function(el) { + _.each(this.uiElements, function (el) { switch (el.type) { // TODO: handle indentation case 'field': diff --git a/lib/list/updateAll.js b/lib/list/updateAll.js index a8e6455d9d..bbdef55e54 100644 --- a/lib/list/updateAll.js +++ b/lib/list/updateAll.js @@ -12,15 +12,15 @@ function updateAll (data, callback) { callback = data; data = null; } - callback = callback || function() {}; - this.model.find(function(err, results) { + callback = callback || function () {}; + this.model.find(function (err, results) { if (err) return callback(err); - async.eachSeries(results, function(doc, next) { + async.eachSeries(results, function (doc, next) { if (data) { doc.set(data); } doc.save(next); - }, function(err) { + }, function (err) { callback(err); }); }); From ad2c0c0e423dd9d4dcb33a07b5ec779ad7f7e51c Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sun, 2 Aug 2015 01:56:45 +1000 Subject: [PATCH 73/86] Fixing filters type detection in api/:list/get endpoint --- admin/api/list/get.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/admin/api/list/get.js b/admin/api/list/get.js index e0976643af..9d1ec5e3c7 100644 --- a/admin/api/list/get.js +++ b/admin/api/list/get.js @@ -1,13 +1,12 @@ var async = require('async'); module.exports = function(req, res) { - var filters; - if (req.query.filters) { - try { - filters = JSON.parse(req.query.filters); - } catch(e) { } + var filters = req.query.filters; + if (filters && typeof filters === 'string') { + try { filters = JSON.parse(req.query.filters); } + catch(e) { } } - if (filters) { + if (typeof filters === 'object') { filters = req.list.addFiltersToQuery(filters); } var query = req.list.model.find(filters); From 57b6b25734584bd9c74fb92dfc8dd9671270b8d4 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sun, 2 Aug 2015 01:59:48 +1000 Subject: [PATCH 74/86] Adding eslint ignore for empty catch block --- admin/api/list/get.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/admin/api/list/get.js b/admin/api/list/get.js index 9d1ec5e3c7..aaccb87899 100644 --- a/admin/api/list/get.js +++ b/admin/api/list/get.js @@ -4,7 +4,7 @@ module.exports = function(req, res) { var filters = req.query.filters; if (filters && typeof filters === 'string') { try { filters = JSON.parse(req.query.filters); } - catch(e) { } + catch(e) { } // eslint-disable-line no-empty } if (typeof filters === 'object') { filters = req.list.addFiltersToQuery(filters); From 8e1204826c4b678385960c69ba5fdb2a3eaa8286 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Sun, 2 Aug 2015 02:27:37 +1000 Subject: [PATCH 75/86] Adding sortContext to list.getOptions & sorting properties --- lib/list/getOptions.js | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/lib/list/getOptions.js b/lib/list/getOptions.js index 193f45a333..c87f0f4700 100644 --- a/lib/list/getOptions.js +++ b/lib/list/getOptions.js @@ -5,31 +5,32 @@ var _ = require('underscore'); */ function getOptions () { var ops = { + autocreate: this.options.autocreate, + autokey: this.autokey, + defaultColumns: this.options.defaultColumns, + defaultSort: this.options.defaultSort, + fields: {}, + hidden: this.options.hidden, + initialFields: _.pluck(this.initialFields, 'path'), key: this.key, - path: this.path, label: this.label, - singular: this.singular, - plural: this.plural, - namePath: this.namePath, nameField: this.nameField ? this.nameField.getOptions() : null, - nameIsVirtual: this.nameIsVirtual, nameIsEditable: this.nameIsEditable, nameIsInitial: this.nameIsInitial, - noedit: this.options.noedit, + nameIsVirtual: this.nameIsVirtual, + namePath: this.namePath, nocreate: this.options.nocreate, nodelete: this.options.nodelete, - autocreate: this.options.autocreate, - sortable: this.options.sortable, - hidden: this.options.hidden, + noedit: this.options.noedit, + path: this.path, + plural: this.plural, searchFields: this.options.searchFields, - defaultSort: this.options.defaultSort, - defaultColumns: this.options.defaultColumns, + singular: this.singular, + sortable: this.options.sortable, + sortContext: this.options.sortContext, track: this.options.track, tracking: this.tracking, - autokey: this.autokey, - fields: {}, - uiElements: [], - initialFields: _.pluck(this.initialFields, 'path') + uiElements: [] }; _.each(this.uiElements, function (el) { switch (el.type) { From 33d1ac9113aa61d89e6a4352a9f3a95f1d92233d Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Mon, 3 Aug 2015 21:11:55 +1000 Subject: [PATCH 76/86] Breaking out list.isReserved into its own file, deprecating List.reservedPaths --- lib/list.js | 27 +-------------------------- lib/list/isReserved.js | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 26 deletions(-) create mode 100644 lib/list/isReserved.js diff --git a/lib/list.js b/lib/list.js index fb0e650f33..458a0fe355 100644 --- a/lib/list.js +++ b/lib/list.js @@ -118,6 +118,7 @@ function List(key, options) { List.prototype.getData = require('./list/getData'); List.prototype.getOptions = require('./list/getOptions'); List.prototype.addFiltersToQuery = require('./list/addFiltersToQuery'); +List.prototype.isReserved = require('./list/isReserved'); /** * Sets list options @@ -241,32 +242,6 @@ List.prototype.add = function() { return this; }; -/** - * Check whether or not a `path` is a reserved path. This restricts the use - * of `Object.prototype` method keys as well as internal mongo paths. - */ -List.prototype.isReserved = function(path) { - return List.reservedPaths.indexOf(path) >= 0; -}; - -List.reservedPaths = [ - 'id', - '_id', - '_', - 'prototype', - '__proto__', - 'hasOwnProperty', - 'toString', - '__defineGetter__', - '__defineSetter__', - '__lookupGetter__', - '__lookupSetter__', - 'isPrototypeOf', - 'propertyIsEnumerable', - 'toLocaleString', - 'valueOf' -]; - /** * Creates a new field at the specified path, with the provided options. diff --git a/lib/list/isReserved.js b/lib/list/isReserved.js new file mode 100644 index 0000000000..6570672a57 --- /dev/null +++ b/lib/list/isReserved.js @@ -0,0 +1,28 @@ +/** + * Check whether or not a `path` is a reserved path. This restricts the use + * of `Object.prototype` method keys as well as internal mongo paths. + */ + +var reservedPaths = [ + 'id', + '_id', + '_', + 'prototype', + '__proto__', + 'hasOwnProperty', + 'toString', + '__defineGetter__', + '__defineSetter__', + '__lookupGetter__', + '__lookupSetter__', + 'isPrototypeOf', + 'propertyIsEnumerable', + 'toLocaleString', + 'valueOf' +]; + +function isReserved (path) { + return reservedPaths.indexOf(path) >= 0; +}; + +module.exports = isReserved; From de0006cea4abcccbc528b630917006b4ea71fcea Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Mon, 3 Aug 2015 21:17:48 +1000 Subject: [PATCH 77/86] Breaking out list.expandColumns and list.selectColumns --- lib/list.js | 126 +------------------------------------- lib/list/expandColumns.js | 98 +++++++++++++++++++++++++++++ lib/list/isReserved.js | 2 +- lib/list/selectColumns.js | 29 +++++++++ 4 files changed, 130 insertions(+), 125 deletions(-) create mode 100644 lib/list/expandColumns.js create mode 100644 lib/list/selectColumns.js diff --git a/lib/list.js b/lib/list.js index 458a0fe355..4d7559c07f 100644 --- a/lib/list.js +++ b/lib/list.js @@ -119,6 +119,8 @@ List.prototype.getData = require('./list/getData'); List.prototype.getOptions = require('./list/getOptions'); List.prototype.addFiltersToQuery = require('./list/addFiltersToQuery'); List.prototype.isReserved = require('./list/isReserved'); +List.prototype.expandColumns = require('./list/expandColumns'); +List.prototype.selectColumns = require('./list/selectColumns'); /** * Sets list options @@ -321,130 +323,6 @@ Object.defineProperty(List.prototype, 'defaultSort', { } }); -/** - * Expands a comma-separated string or array of columns into valid column objects. - * - * Columns can be: - * - A Field, in the format "field|width" - * - A Field in a single related List, in the format "list:field|width" - * - Any valid path in the Schema, in the format "path|width" - * - * The width part is optional, and can be in the format "n%" or "npx". - * - * The path __name__ is automatically mapped to the namePath of the List. - * - * The field or path for the name of the item (defaults to ID if not set or detected) - * is automatically prepended if not explicitly included. - */ -List.prototype.expandColumns = function(cols) { - if (typeof cols === 'string') { - cols = cols.split(','); - } - if (!Array.isArray(cols)) { - throw new Error('List.expandColumns: cols must be an array.'); - } - var list = this; - var expanded = []; - var nameCol = false; - var getCol = function(def) { - if (def.path === '__name__') { - def.path = list.namePath; - } - var field = list.fields[def.path]; - var col = null; - if (field) { - col = { - field: field, - path: field.path, - type: field.type, - label: def.label || field.label - }; - if (col.type === 'relationship') { - col.refList = col.field.refList; - if (col.refList) { - col.refPath = def.subpath || col.refList.namePath; - col.subField = col.refList.fields[col.refPath]; - col.populate = { path: col.field.path, subpath: col.refPath }; - } - if (!def.label && def.subpath) { - col.label = field.label + ': ' + (col.subField ? col.subField.label : utils.keyToLabel(def.subpath)); - } - } - } else if (list.model.schema.paths[def.path] || list.model.schema.virtuals[def.path]) { - // column refers to a path in the schema - // TODO: this needs to handle sophisticated types, including arrays, nested Schemas, and mixed types - col = { - path: def.path, - label: def.label || utils.keyToLabel(def.path) - }; - } - if (col) { - col.width = def.width; - if (col.path === list.namePath) { - col.isName = true; - nameCol = col; - } - if (field && field.col) { - _.extend(col, field.col); - } - } - return col; - }; - for (var i = 0; i < cols.length; i++) { - var def = {}; - if (typeof cols[i] === 'string') { - var parts = cols[i].trim().split('|'); - def.width = parts[1] || false; - parts = parts[0].split(':'); - def.path = parts[0]; - def.subpath = parts[1]; - } - if (!utils.isObject(def) || !def.path) { - throw new Error('List.expandColumns: column definition must contain a path.'); - } - var col = getCol(def); - if (col) { - expanded.push(col); - } - } - if (!nameCol) { - nameCol = getCol({ path: list.namePath }); - if (nameCol) { - expanded.unshift(nameCol); - } - } - return expanded; -}; - - -/** - * Specified select and populate options for a query based the provided columns. - * - * @param {Query} query - * @param {Array} columns - */ -List.prototype.selectColumns = function(q, cols) { - // Populate relationship columns - var select = []; - var populate = {}; - var path; - cols.forEach(function(col) { - select.push(col.path); - if (col.populate) { - if (!populate[col.populate.path]) { - populate[col.populate.path] = []; - } - populate[col.populate.path].push(col.populate.subpath); - } - }); - q.select(select.join(' ')); - for (path in populate) { - if ( populate.hasOwnProperty(path) ) { - q.populate(path, populate[path].join(' ')); - } - } -}; - /** * Default Column Fields diff --git a/lib/list/expandColumns.js b/lib/list/expandColumns.js new file mode 100644 index 0000000000..03338f7944 --- /dev/null +++ b/lib/list/expandColumns.js @@ -0,0 +1,98 @@ +var utils = require('keystone-utils'); + +/** + * Expands a comma-separated string or array of columns into valid column objects. + * + * Columns can be: + * - A Field, in the format "field|width" + * - A Field in a single related List, in the format "list:field|width" + * - Any valid path in the Schema, in the format "path|width" + * + * The width part is optional, and can be in the format "n%" or "npx". + * + * The path __name__ is automatically mapped to the namePath of the List. + * + * The field or path for the name of the item (defaults to ID if not set or detected) + * is automatically prepended if not explicitly included. + */ +function expandColumns(cols) { + if (typeof cols === 'string') { + cols = cols.split(','); + } + if (!Array.isArray(cols)) { + throw new Error('List.expandColumns: cols must be an array.'); + } + var list = this; + var expanded = []; + var nameCol = false; + var getCol = function(def) { + if (def.path === '__name__') { + def.path = list.namePath; + } + var field = list.fields[def.path]; + var col = null; + if (field) { + col = { + field: field, + path: field.path, + type: field.type, + label: def.label || field.label + }; + if (col.type === 'relationship') { + col.refList = col.field.refList; + if (col.refList) { + col.refPath = def.subpath || col.refList.namePath; + col.subField = col.refList.fields[col.refPath]; + col.populate = { path: col.field.path, subpath: col.refPath }; + } + if (!def.label && def.subpath) { + col.label = field.label + ': ' + (col.subField ? col.subField.label : utils.keyToLabel(def.subpath)); + } + } + } else if (list.model.schema.paths[def.path] || list.model.schema.virtuals[def.path]) { + // column refers to a path in the schema + // TODO: this needs to handle sophisticated types, including arrays, nested Schemas, and mixed types + col = { + path: def.path, + label: def.label || utils.keyToLabel(def.path) + }; + } + if (col) { + col.width = def.width; + if (col.path === list.namePath) { + col.isName = true; + nameCol = col; + } + if (field && field.col) { + _.extend(col, field.col); + } + } + return col; + }; + for (var i = 0; i < cols.length; i++) { + var def = {}; + if (typeof cols[i] === 'string') { + var parts = cols[i].trim().split('|'); + def.width = parts[1] || false; + parts = parts[0].split(':'); + def.path = parts[0]; + def.subpath = parts[1]; + } + if (!utils.isObject(def) || !def.path) { + throw new Error('List.expandColumns: column definition must contain a path.'); + } + var col = getCol(def); + if (col) { + expanded.push(col); + } + } + if (!nameCol) { + nameCol = getCol({ path: list.namePath }); + if (nameCol) { + expanded.unshift(nameCol); + } + } + return expanded; +} + +module.exports = expandColumns; diff --git a/lib/list/isReserved.js b/lib/list/isReserved.js index 6570672a57..6fc0823ba7 100644 --- a/lib/list/isReserved.js +++ b/lib/list/isReserved.js @@ -23,6 +23,6 @@ var reservedPaths = [ function isReserved (path) { return reservedPaths.indexOf(path) >= 0; -}; +} module.exports = isReserved; diff --git a/lib/list/selectColumns.js b/lib/list/selectColumns.js new file mode 100644 index 0000000000..6ec8953615 --- /dev/null +++ b/lib/list/selectColumns.js @@ -0,0 +1,29 @@ +/** + * Specified select and populate options for a query based the provided columns. + * + * @param {Query} query + * @param {Array} columns + */ +function selectColumns (q, cols) { + // Populate relationship columns + var select = []; + var populate = {}; + var path; + cols.forEach(function(col) { + select.push(col.path); + if (col.populate) { + if (!populate[col.populate.path]) { + populate[col.populate.path] = []; + } + populate[col.populate.path].push(col.populate.subpath); + } + }); + q.select(select.join(' ')); + for (path in populate) { + if (populate.hasOwnProperty(path)) { + q.populate(path, populate[path].join(' ')); + } + } +} + +module.exports = selectColumns; From 4c836664fe855a506e94f7cfe70779d987b9fbd9 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Mon, 3 Aug 2015 21:35:04 +1000 Subject: [PATCH 78/86] Updating changelog --- HISTORY.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/HISTORY.md b/HISTORY.md index c303cc2657..634b6d9f5e 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,6 +2,20 @@ KeystoneJS is maintained by [@JedWatson](https://github.com/JedWatson) and an amazing team of contributors. All contributions are given credit here except for Jed's. +## v0.3.13 / 2015-07-03 + +* improved; major speed increase for initialisation +* improved; codemirror is now only loaded as required, thanks [Carlos Colon](https://github.com/webteckie) +* fixed; correctly handling blank values in the DateInput component +* changed; switched to babyparse for CSV generation +* fixed; docs links now point to keystone site +* fixed; add Maps API key to request, allow override per model, check for server instead of browser key, thanks [stosorio](https://github.com/stosorio) +* fixed; added check for duplicate `_revisions` models, thanks [Jeffrey](https://github.com/jeffreypriebe) +* fixed; localFile .format property ignored by Admin U, thanks [Javier Castro](https://github.com/jacargentina) +* fixed; href working correctly on LocalFiles Type, thanks [Matthias Tylkowski](https://github.com/tylkomat) +* added; several new API endpoints for the Admin UI in preparation of the 0.4 release + + ## v0.3.12 / 2015-06-26 * fixed; `height` option for TextArea fields was not respected in the Admin UI, thanks [Eóin Martin](https://github.com/SlashmanX) From 76e52328e9dda4d30c301077325d82890ba51a7e Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Mon, 3 Aug 2015 21:35:14 +1000 Subject: [PATCH 79/86] v0.3.13 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index dd612b93ea..375db16e52 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "keystone", - "version": "0.3.12", + "version": "0.3.13", "description": "Web Application Framework and Admin GUI / Content Management System built on Express.js and Mongoose", "main": "index.js", "repository": { From d90a6f71601202a4225ae9a31a58ce415f16732b Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Mon, 3 Aug 2015 23:38:09 +1000 Subject: [PATCH 80/86] Fixing typo in changelog. It's August already! --- HISTORY.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/HISTORY.md b/HISTORY.md index 634b6d9f5e..d156ce7133 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -2,7 +2,7 @@ KeystoneJS is maintained by [@JedWatson](https://github.com/JedWatson) and an amazing team of contributors. All contributions are given credit here except for Jed's. -## v0.3.13 / 2015-07-03 +## v0.3.13 / 2015-08-03 * improved; major speed increase for initialisation * improved; codemirror is now only loaded as required, thanks [Carlos Colon](https://github.com/webteckie) From 76badd6b4f48533597eb6cdc266a36e5b67c6110 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Tue, 4 Aug 2015 21:32:45 +1000 Subject: [PATCH 81/86] Should be each, not map --- lib/list.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/list.js b/lib/list.js index 4d7559c07f..23338bc27c 100644 --- a/lib/list.js +++ b/lib/list.js @@ -345,7 +345,7 @@ Object.defineProperty(List.prototype, 'defaultColumns', { */ List.prototype.relationship = function(def) { if (arguments.length > 1) { - _.map(arguments, function(def) { this.relationship(def); }, this); + _.each(arguments, function(def) { this.relationship(def); }, this); return this; } if ('string' === typeof def) { From 2fcb1a56c8474a5a9f737f2a512c3d1dcab552e8 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Tue, 4 Aug 2015 21:41:24 +1000 Subject: [PATCH 82/86] Splitting out and optimising List.prototype.relationship --- lib/list.js | 35 +---------------------------------- lib/list/relationship.js | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 34 deletions(-) create mode 100644 lib/list/relationship.js diff --git a/lib/list.js b/lib/list.js index 23338bc27c..080a6b47ac 100644 --- a/lib/list.js +++ b/lib/list.js @@ -115,6 +115,7 @@ function List(key, options) { } // Add prototype methods +List.prototype.relationship = require('./list/relationship'); List.prototype.getData = require('./list/getData'); List.prototype.getOptions = require('./list/getOptions'); List.prototype.addFiltersToQuery = require('./list/addFiltersToQuery'); @@ -340,40 +341,6 @@ Object.defineProperty(List.prototype, 'defaultColumns', { } }); -/** - * Registers relationships to this list defined on others - */ -List.prototype.relationship = function(def) { - if (arguments.length > 1) { - _.each(arguments, function(def) { this.relationship(def); }, this); - return this; - } - if ('string' === typeof def) { - def = { ref: def }; - } - if (!def.ref) { - throw new Error('List Relationships must be specified with an object containing ref (' + this.key + ')'); - } - if (!def.refPath) { - def.refPath = utils.downcase(this.key); - } - if (!def.path) { - def.path = utils.keyToProperty(def.ref, true); - } - Object.defineProperty(def, 'refList', { - get: function() { - return keystone.list(def.ref); - } - }); - Object.defineProperty(def, 'isValid', { - get: function() { - return keystone.list(def.ref) ? true : false; - } - }); - this.relationships[def.path] = def; - return this; -}; - /** * Registers the Schema with Mongoose, and the List with Keystone diff --git a/lib/list/relationship.js b/lib/list/relationship.js new file mode 100644 index 0000000000..12c1bcfabc --- /dev/null +++ b/lib/list/relationship.js @@ -0,0 +1,40 @@ +var keystone = require('../../'); +var utils = require('keystone-utils'); + +/** + * Registers relationships to this list defined on others + */ +function relationship (def) { + if (arguments.length > 1) { + for (var i = 0; i < arguments.length; i++) { + this.relationship(arguments[i]); + } + return this; + } + if ('string' === typeof def) { + def = { ref: def }; + } + if (!def.ref) { + throw new Error('List Relationships must be specified with an object containing ref (' + this.key + ')'); + } + if (!def.refPath) { + def.refPath = utils.downcase(this.key); + } + if (!def.path) { + def.path = utils.keyToProperty(def.ref, true); + } + Object.defineProperty(def, 'refList', { + get: function() { + return keystone.list(def.ref); + } + }); + Object.defineProperty(def, 'isValid', { + get: function() { + return keystone.list(def.ref) ? true : false; + } + }); + this.relationships[def.path] = def; + return this; +} + +module.exports = relationship; From 765a0884c7cd08ebfa345bbd92d74eaf0ebfee12 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Tue, 4 Aug 2015 21:52:01 +1000 Subject: [PATCH 83/86] Splitting out List.prototype.underscoreMethod, list.prototype.getDocumentName --- lib/list.js | 33 +++------------------------------ lib/list/getDocumentName.js | 17 +++++++++++++++++ lib/list/underscoreMethod.js | 17 +++++++++++++++++ 3 files changed, 37 insertions(+), 30 deletions(-) create mode 100644 lib/list/getDocumentName.js create mode 100644 lib/list/underscoreMethod.js diff --git a/lib/list.js b/lib/list.js index 080a6b47ac..365fd93896 100644 --- a/lib/list.js +++ b/lib/list.js @@ -116,8 +116,10 @@ function List(key, options) { // Add prototype methods List.prototype.relationship = require('./list/relationship'); +List.prototype.underscoreMethod = require('./list/underscoreMethod'); List.prototype.getData = require('./list/getData'); List.prototype.getOptions = require('./list/getOptions'); +List.prototype.getDocumentName = require('./list/getDocumentName'); List.prototype.addFiltersToQuery = require('./list/addFiltersToQuery'); List.prototype.isReserved = require('./list/isReserved'); List.prototype.expandColumns = require('./list/expandColumns'); @@ -295,21 +297,7 @@ List.prototype.field = function(path, options) { }; -/** - * Adds a method to the underscoreMethods collection on the list, which is then - * added to the schema before the list is registered with mongoose. - */ -List.prototype.underscoreMethod = function(path, fn) { - var target = this.underscoreMethods; - path = path.split('.'); - var last = path.pop(); - path.forEach(function(part) { - if (!target[part]) target[part] = {}; - target = target[part]; - }); - target[last] = fn; - return this; -}; + /** @@ -377,21 +365,6 @@ List.prototype.register = function() { }; -/** - * Gets the name of the provided document from the correct path - * - * Example: - * var name = list.getDocumentName(item) - * - * @param {Object} item - * @param {Boolean} escape - causes HTML entities to be encoded - */ -List.prototype.getDocumentName = function(doc, escape) { - var name = String(this.nameField ? this.nameField.format(doc) : doc.get(this.namePath)); - return (escape) ? utils.encodeHTMLEntities(name) : name; -}; - - /** * Processes a filter string into a filters object * diff --git a/lib/list/getDocumentName.js b/lib/list/getDocumentName.js new file mode 100644 index 0000000000..1d515ee4e7 --- /dev/null +++ b/lib/list/getDocumentName.js @@ -0,0 +1,17 @@ +var utils = require('utils'); + +/** + * Gets the name of the provided document from the correct path + * + * Example: + * var name = list.getDocumentName(item) + * + * @param {Object} item + * @param {Boolean} escape - causes HTML entities to be encoded + */ +function getDocumentName(doc, escape) { + var name = String(this.nameField ? this.nameField.format(doc) : doc.get(this.namePath)); + return (escape) ? utils.encodeHTMLEntities(name) : name; +} + +module.exports = getDocumentName; diff --git a/lib/list/underscoreMethod.js b/lib/list/underscoreMethod.js new file mode 100644 index 0000000000..16c38e59c0 --- /dev/null +++ b/lib/list/underscoreMethod.js @@ -0,0 +1,17 @@ +/** + * Adds a method to the underscoreMethods collection on the list, which is then + * added to the schema before the list is registered with mongoose. + */ +function underscoreMethod (path, fn) { + var target = this.underscoreMethods; + path = path.split('.'); + var last = path.pop(); + path.forEach(function(part) { + if (!target[part]) target[part] = {}; + target = target[part]; + }); + target[last] = fn; + return this; +} + +module.exports = underscoreMethod; From a423702162585114b098c8964bb14a7e1690d636 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Tue, 4 Aug 2015 21:57:00 +1000 Subject: [PATCH 84/86] Splitting out and simplifying List.prototype.set/get --- lib/list.js | 25 ++----------------------- lib/list/set.js | 16 ++++++++++++++++ 2 files changed, 18 insertions(+), 23 deletions(-) create mode 100644 lib/list/set.js diff --git a/lib/list.js b/lib/list.js index 365fd93896..888276cb62 100644 --- a/lib/list.js +++ b/lib/list.js @@ -115,6 +115,8 @@ function List(key, options) { } // Add prototype methods +List.prototype.set = require('./list/set'); +List.prototype.get = List.prototype.set; List.prototype.relationship = require('./list/relationship'); List.prototype.underscoreMethod = require('./list/underscoreMethod'); List.prototype.getData = require('./list/getData'); @@ -125,29 +127,6 @@ List.prototype.isReserved = require('./list/isReserved'); List.prototype.expandColumns = require('./list/expandColumns'); List.prototype.selectColumns = require('./list/selectColumns'); -/** - * Sets list options - * - * Example: - * list.set('test', value) // sets the 'test' option to `value` - */ -List.prototype.set = function(key, value) { - if (arguments.length === 1) { - return this.options[key]; - } - this.options[key] = value; - return value; -}; - - -/** - * Gets list options - * - * Example: - * list.get('test') // returns the 'test' value - */ -List.prototype.get = List.prototype.set; - /** * Maps a built-in field (e.g. name) to a specific path diff --git a/lib/list/set.js b/lib/list/set.js new file mode 100644 index 0000000000..50b4252888 --- /dev/null +++ b/lib/list/set.js @@ -0,0 +1,16 @@ +/** + * Gets and Sets list options. Aliased as .get() + * + * Example: + * list.set('test') // returns the 'test' value + * list.set('test', value) // sets the 'test' option to `value` + */ +function set(key, value) { + if (arguments.length === 1) { + return this.options[key]; + } + this.options[key] = value; + return value; +} + +module.exports = set; From 9ffa474047aef6dfd0f14e92640fa063bfd427b6 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Tue, 4 Aug 2015 22:00:21 +1000 Subject: [PATCH 85/86] utils => keystone-utils --- lib/list/getDocumentName.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/list/getDocumentName.js b/lib/list/getDocumentName.js index 1d515ee4e7..ab0284b7ce 100644 --- a/lib/list/getDocumentName.js +++ b/lib/list/getDocumentName.js @@ -1,4 +1,4 @@ -var utils = require('utils'); +var utils = require('keystone-utils'); /** * Gets the name of the provided document from the correct path From ebe237477d78ab2e6d797903e357f23c56c32eb2 Mon Sep 17 00:00:00 2001 From: Jed Watson Date: Tue, 4 Aug 2015 22:01:49 +1000 Subject: [PATCH 86/86] Splitting out and optimising List.prototype.register --- lib/list.js | 37 +------------------------------------ lib/list/register.js | 40 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 36 deletions(-) create mode 100644 lib/list/register.js diff --git a/lib/list.js b/lib/list.js index 888276cb62..d9c30c043b 100644 --- a/lib/list.js +++ b/lib/list.js @@ -4,7 +4,6 @@ var keystone = require('../'); var moment = require('moment'); var queryfilterlib = require('queryfilter'); var schemaPlugins = require('./schemaPlugins'); -var UpdateHandler = require('./updateHandler'); var utils = require('keystone-utils'); /** @@ -119,6 +118,7 @@ List.prototype.set = require('./list/set'); List.prototype.get = List.prototype.set; List.prototype.relationship = require('./list/relationship'); List.prototype.underscoreMethod = require('./list/underscoreMethod'); +List.prototype.register = require('./list/register'); List.prototype.getData = require('./list/getData'); List.prototype.getOptions = require('./list/getOptions'); List.prototype.getDocumentName = require('./list/getDocumentName'); @@ -309,41 +309,6 @@ Object.defineProperty(List.prototype, 'defaultColumns', { }); -/** - * Registers the Schema with Mongoose, and the List with Keystone - * - * Also adds default fields and virtuals to the schema for the list - */ -List.prototype.register = function() { - var list = this; - this.schema.virtual('list').get(function () { - return list; - }); - if (!_.isEmpty(this.relationships)) { - this.schema.methods.getRelated = schemaPlugins.methods.getRelated; - this.schema.methods.populateRelated = schemaPlugins.methods.populateRelated; - if (!this.schema.options.toObject) this.schema.options.toObject = {}; - this.schema.options.toObject.transform = schemaPlugins.options.transform; - } - this.schema.virtual('_').get(function() { - if (!this.__methods) { - this.__methods = utils.bindMethods(list.underscoreMethods, this); - } - return this.__methods; - }); - this.schema.method('getUpdateHandler', function(req, res, ops) { - return new UpdateHandler(list, this, req, res, ops); - }); - if (this.get('inherits')) { - this.model = this.get('inherits').model.discriminator(this.key, this.schema); - } else { - this.model = keystone.mongoose.model(this.key, this.schema); - } - require('../').list(this); - return this; -}; - - /** * Processes a filter string into a filters object * diff --git a/lib/list/register.js b/lib/list/register.js new file mode 100644 index 0000000000..1a2164b195 --- /dev/null +++ b/lib/list/register.js @@ -0,0 +1,40 @@ +var keystone = require('../../'); +var schemaPlugins = require('../schemaPlugins'); +var UpdateHandler = require('../updateHandler'); +var utils = require('keystone-utils'); + +/** + * Registers the Schema with Mongoose, and the List with Keystone + * + * Also adds default fields and virtuals to the schema for the list + */ +function register() { + var list = this; + this.schema.virtual('list').get(function () { + return list; + }); + if (Object.keys(this.relationships).length) { + this.schema.methods.getRelated = schemaPlugins.methods.getRelated; + this.schema.methods.populateRelated = schemaPlugins.methods.populateRelated; + if (!this.schema.options.toObject) this.schema.options.toObject = {}; + this.schema.options.toObject.transform = schemaPlugins.options.transform; + } + this.schema.virtual('_').get(function() { + if (!this.__methods) { + this.__methods = utils.bindMethods(list.underscoreMethods, this); + } + return this.__methods; + }); + this.schema.method('getUpdateHandler', function(req, res, ops) { + return new UpdateHandler(list, this, req, res, ops); + }); + if (this.get('inherits')) { + this.model = this.get('inherits').model.discriminator(this.key, this.schema); + } else { + this.model = keystone.mongoose.model(this.key, this.schema); + } + keystone.list(this); + return this; +} + +module.exports = register;