From 0acf4e0774e0daeed2c386e4d9c0ac36da70a244 Mon Sep 17 00:00:00 2001 From: Noah Loomans Date: Mon, 5 Sep 2016 19:55:53 +0200 Subject: you can now search by name --- app.js | 2 + lib/getURLOfUsers.js | 45 + package.json | 2 + public/javascripts/bundle.js | 39759 ++++++++------------------------------- public/javascripts/getUsers.js | 51 +- public/javascripts/main.js | 13 +- public/stylesheets/style.css | 6 + routes/getUserIndex.js | 118 + routes/meetingpointProxy.js | 2 + 9 files changed, 8010 insertions(+), 31988 deletions(-) create mode 100644 lib/getURLOfUsers.js create mode 100644 routes/getUserIndex.js diff --git a/app.js b/app.js index 1a9bd3a..a0d0071 100644 --- a/app.js +++ b/app.js @@ -6,6 +6,7 @@ const bodyParser = require('body-parser') const routes = require('./routes/index') const meetingpointProxy = require('./routes/meetingpointProxy') +const getUserIndex = require('./routes/getUserIndex') const app = express() @@ -21,6 +22,7 @@ app.use(express.static(path.join(__dirname, 'public'))) app.use('/', routes) app.use('/meetingpointProxy', meetingpointProxy) +app.use('/getUserIndex', getUserIndex) // catch 404 and forward to error handler app.use(function (req, res, next) { diff --git a/lib/getURLOfUsers.js b/lib/getURLOfUsers.js new file mode 100644 index 0000000..8590ee4 --- /dev/null +++ b/lib/getURLOfUsers.js @@ -0,0 +1,45 @@ +const leftPad = require('left-pad') + +// copied from http://www.meetingpointmco.nl/Roosters-AL/doc/dagroosters/untisscripts.js, +// were using the same code as they do to be sure that we always get the same +// week number. +function getWeek () { + // Create a copy of this date object + var target = new Date() + + // ISO week date weeks start on monday + // so correct the day number + var dayNr = (target.getDay() + 6) % 7 + + // ISO 8601 states that week 1 is the week + // with the first thursday of that year. + // Set the target date to the thursday in the target week + target.setDate(target.getDate() - dayNr + 3) + + // Store the millisecond value of the target date + var firstThursday = target.valueOf() + + // Set the target to the first thursday of the year + // First set the target to january first + target.setMonth(0, 1) + // Not a thursday? Correct the date to the next thursday + if (target.getDay() !== 4) { + target.setMonth(0, 1 + ((4 - target.getDay()) + 7) % 7) + } + + // The weeknumber is the number of weeks between the + // first thursday of the year and the thursday in the target week + return 1 + Math.ceil((firstThursday - target) / 604800000) // 604800000 = 7 * 24 * 3600 * 1000 +} + +function getURLOfUsers (weekOffset, type, id) { + return `http://www.meetingpointmco.nl/Roosters-AL/doc/dagroosters/` + + `${getWeek() + weekOffset}/${type}/${type}${leftPad(id, 5, '0')}.htm` +} + +module.exports = getURLOfUsers + +module.exports.CLASS = 'c' +module.exports.TEACHERS = 't' +module.exports.ROOMS = 'r' +module.exports.STUDENTS = 's' diff --git a/package.json b/package.json index 0da9f21..c41cc7f 100644 --- a/package.json +++ b/package.json @@ -13,6 +13,8 @@ "cheerio": "^0.22.0", "cookie-parser": "~1.4.3", "debug": "~2.2.0", + "diacritics": "^1.2.3", + "encoding": "^0.1.12", "express": "~4.13.4", "fuzzy": "^0.1.1", "jade": "~1.11.0", diff --git a/public/javascripts/bundle.js b/public/javascripts/bundle.js index f0b523a..9f68601 100644 --- a/public/javascripts/bundle.js +++ b/public/javascripts/bundle.js @@ -35470,7 +35470,7 @@ BufferList.prototype.destroy = function destroy () { module.exports = BufferList }).call(this,require("buffer").Buffer) -},{"buffer":49,"readable-stream/duplex":314,"util":163}],179:[function(require,module,exports){ +},{"buffer":49,"readable-stream/duplex":251,"util":163}],179:[function(require,module,exports){ (function (process,global){ /* @preserve * The MIT License (MIT) @@ -41072,15 +41072,6 @@ module.exports = ret; }); ;if (typeof window !== 'undefined' && window !== null) { window.P = window.Promise; } else if (typeof self !== 'undefined' && self !== null) { self.P = self.Promise; } }).call(this,require('_process'),typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"_process":120}],180:[function(require,module,exports){ -module.exports = { - trueFunc: function trueFunc(){ - return true; - }, - falseFunc: function falseFunc(){ - return false; - } -}; -},{}],181:[function(require,module,exports){ function Caseless (dict) { this.dict = dict || {} } @@ -41148,32955 +41139,8950 @@ module.exports.httpify = function (resp, headers) { return c } -},{}],182:[function(require,module,exports){ -/** - * Export cheerio (with ) - */ - -exports = module.exports = require('./lib/cheerio'); - -/* - Export the version -*/ - -exports.version = require('./package.json').version; - -},{"./lib/cheerio":188,"./package.json":192}],183:[function(require,module,exports){ -var $ = require('../static'), - utils = require('../utils'), - isTag = utils.isTag, - domEach = utils.domEach, - hasOwn = Object.prototype.hasOwnProperty, - camelCase = utils.camelCase, - cssCase = utils.cssCase, - rspace = /\s+/, - dataAttrPrefix = 'data-', - _ = { - forEach: require('lodash.foreach'), - extend: require('lodash.assignin'), - some: require('lodash.some') - }, - - // Lookup table for coercing string data-* attributes to their corresponding - // JavaScript primitives - primitives = { - null: null, - true: true, - false: false - }, - - // Attributes that are booleans - rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, - // Matches strings that look like JSON objects or arrays - rbrace = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/; - - -var getAttr = function(elem, name) { - if (!elem || !isTag(elem)) return; - - if (!elem.attribs) { - elem.attribs = {}; - } - - // Return the entire attribs object if no attribute specified - if (!name) { - return elem.attribs; - } - - if (hasOwn.call(elem.attribs, name)) { - // Get the (decoded) attribute - return rboolean.test(name) ? name : elem.attribs[name]; - } - - // Mimic the DOM and return text content as value for `option's` - if (elem.name === 'option' && name === 'value') { - return $.text(elem.children); - } - - // Mimic DOM with default value for radios/checkboxes - if (elem.name === 'input' && - (elem.attribs.type === 'radio' || elem.attribs.type === 'checkbox') && - name === 'value') { - return 'on'; - } -}; +},{}],181:[function(require,module,exports){ +(function (Buffer){ +var util = require('util'); +var Stream = require('stream').Stream; +var DelayedStream = require('delayed-stream'); -var setAttr = function(el, name, value) { +module.exports = CombinedStream; +function CombinedStream() { + this.writable = false; + this.readable = true; + this.dataSize = 0; + this.maxDataSize = 2 * 1024 * 1024; + this.pauseStreams = true; - if (value === null) { - removeAttribute(el, name); - } else { - el.attribs[name] = value+''; - } -}; + this._released = false; + this._streams = []; + this._currentStream = null; +} +util.inherits(CombinedStream, Stream); -exports.attr = function(name, value) { - // Set the value (with attr map support) - if (typeof name === 'object' || value !== undefined) { - if (typeof value === 'function') { - return domEach(this, function(i, el) { - setAttr(el, name, value.call(el, i, el.attribs[name])); - }); - } - return domEach(this, function(i, el) { - if (!isTag(el)) return; +CombinedStream.create = function(options) { + var combinedStream = new this(); - if (typeof name === 'object') { - _.forEach(name, function(value, name) { - setAttr(el, name, value); - }); - } else { - setAttr(el, name, value); - } - }); + options = options || {}; + for (var option in options) { + combinedStream[option] = options[option]; } - return getAttr(this[0], name); -}; - -var getProp = function (el, name) { - if (!el || !isTag(el)) return; - - return el.hasOwnProperty(name) - ? el[name] - : rboolean.test(name) - ? getAttr(el, name) !== undefined - : getAttr(el, name); + return combinedStream; }; -var setProp = function (el, name, value) { - el[name] = rboolean.test(name) ? !!value : value; +CombinedStream.isStreamLike = function(stream) { + return (typeof stream !== 'function') + && (typeof stream !== 'string') + && (typeof stream !== 'boolean') + && (typeof stream !== 'number') + && (!Buffer.isBuffer(stream)); }; -exports.prop = function (name, value) { - var i = 0, - property; - - if (typeof name === 'string' && value === undefined) { - - switch (name) { - case 'style': - property = this.css(); - - _.forEach(property, function (v, p) { - property[i++] = p; - }); - - property.length = i; - - break; - case 'tagName': - case 'nodeName': - property = this[0].name.toUpperCase(); - break; - default: - property = getProp(this[0], name); - } - - return property; - } - - if (typeof name === 'object' || value !== undefined) { +CombinedStream.prototype.append = function(stream) { + var isStreamLike = CombinedStream.isStreamLike(stream); - if (typeof value === 'function') { - return domEach(this, function(i, el) { - setProp(el, name, value.call(el, i, getProp(el, name))); + if (isStreamLike) { + if (!(stream instanceof DelayedStream)) { + var newStream = DelayedStream.create(stream, { + maxDataSize: Infinity, + pauseStream: this.pauseStreams, }); + stream.on('data', this._checkDataSize.bind(this)); + stream = newStream; } - return domEach(this, function(i, el) { - if (!isTag(el)) return; - - if (typeof name === 'object') { - - _.forEach(name, function(val, name) { - setProp(el, name, val); - }); - - } else { - setProp(el, name, value); - } - }); - - } -}; - -var setData = function(el, name, value) { - if (!el.data) { - el.data = {}; - } - - if (typeof name === 'object') return _.extend(el.data, name); - if (typeof name === 'string' && value !== undefined) { - el.data[name] = value; - } else if (typeof name === 'object') { - _.extend(el.data, name); - } -}; - -// Read the specified attribute from the equivalent HTML5 `data-*` attribute, -// and (if present) cache the value in the node's internal data store. If no -// attribute name is specified, read *all* HTML5 `data-*` attributes in this -// manner. -var readData = function(el, name) { - var readAll = arguments.length === 1; - var domNames, domName, jsNames, jsName, value, idx, length; - - if (readAll) { - domNames = Object.keys(el.attribs).filter(function(attrName) { - return attrName.slice(0, dataAttrPrefix.length) === dataAttrPrefix; - }); - jsNames = domNames.map(function(domName) { - return camelCase(domName.slice(dataAttrPrefix.length)); - }); - } else { - domNames = [dataAttrPrefix + cssCase(name)]; - jsNames = [name]; - } - - for (idx = 0, length = domNames.length; idx < length; ++idx) { - domName = domNames[idx]; - jsName = jsNames[idx]; - if (hasOwn.call(el.attribs, domName)) { - value = el.attribs[domName]; - - if (hasOwn.call(primitives, value)) { - value = primitives[value]; - } else if (value === String(Number(value))) { - value = Number(value); - } else if (rbrace.test(value)) { - try { - value = JSON.parse(value); - } catch(e){ } - } + this._handleErrors(stream); - el.data[jsName] = value; + if (this.pauseStreams) { + stream.pause(); } } - return readAll ? el.data : value; + this._streams.push(stream); + return this; }; -exports.data = function(name, value) { - var elem = this[0]; +CombinedStream.prototype.pipe = function(dest, options) { + Stream.prototype.pipe.call(this, dest, options); + this.resume(); + return dest; +}; - if (!elem || !isTag(elem)) return; +CombinedStream.prototype._getNext = function() { + this._currentStream = null; + var stream = this._streams.shift(); - if (!elem.data) { - elem.data = {}; - } - // Return the entire data object if no data specified - if (!name) { - return readData(elem); + if (typeof stream == 'undefined') { + this.end(); + return; } - // Set the value (with attr map support) - if (typeof name === 'object' || value !== undefined) { - domEach(this, function(i, el) { - setData(el, name, value); - }); - return this; - } else if (hasOwn.call(elem.data, name)) { - return elem.data[name]; + if (typeof stream !== 'function') { + this._pipeNext(stream); + return; } - return readData(elem, name); -}; - -/** - * Get the value of an element - */ - -exports.val = function(value) { - var querying = arguments.length === 0, - element = this[0]; - - if(!element) return; + var getStream = stream; + getStream(function(stream) { + var isStreamLike = CombinedStream.isStreamLike(stream); + if (isStreamLike) { + stream.on('data', this._checkDataSize.bind(this)); + this._handleErrors(stream); + } - switch (element.name) { - case 'textarea': - return this.text(value); - case 'input': - switch (this.attr('type')) { - case 'radio': - if (querying) { - return this.attr('value'); - } else { - this.attr('value', value); - return this; - } - break; - default: - return this.attr('value', value); - } - return; - case 'select': - var option = this.find('option:selected'), - returnValue; - if (option === undefined) return undefined; - if (!querying) { - if (!this.attr().hasOwnProperty('multiple') && typeof value == 'object') { - return this; - } - if (typeof value != 'object') { - value = [value]; - } - this.find('option').removeAttr('selected'); - for (var i = 0; i < value.length; i++) { - this.find('option[value="' + value[i] + '"]').attr('selected', ''); - } - return this; - } - returnValue = option.attr('value'); - if (this.attr().hasOwnProperty('multiple')) { - returnValue = []; - domEach(option, function(i, el) { - returnValue.push(getAttr(el, 'value')); - }); - } - return returnValue; - case 'option': - if (!querying) { - this.attr('value', value); - return this; - } - return this.attr('value'); - } + this._pipeNext(stream); + }.bind(this)); }; -/** - * Remove an attribute - */ +CombinedStream.prototype._pipeNext = function(stream) { + this._currentStream = stream; -var removeAttribute = function(elem, name) { - if (!elem.attribs || !hasOwn.call(elem.attribs, name)) + var isStreamLike = CombinedStream.isStreamLike(stream); + if (isStreamLike) { + stream.on('end', this._getNext.bind(this)); + stream.pipe(this, {end: false}); return; + } - delete elem.attribs[name]; + var value = stream; + this.write(value); + this._getNext(); }; - -exports.removeAttr = function(name) { - domEach(this, function(i, elem) { - removeAttribute(elem, name); +CombinedStream.prototype._handleErrors = function(stream) { + var self = this; + stream.on('error', function(err) { + self._emitError(err); }); - - return this; }; -exports.hasClass = function(className) { - return _.some(this, function(elem) { - var attrs = elem.attribs, - clazz = attrs && attrs['class'], - idx = -1, - end; - - if (clazz) { - while ((idx = clazz.indexOf(className, idx+1)) > -1) { - end = idx + className.length; - - if ((idx === 0 || rspace.test(clazz[idx-1])) - && (end === clazz.length || rspace.test(clazz[end]))) { - return true; - } - } - } - }); +CombinedStream.prototype.write = function(data) { + this.emit('data', data); }; -exports.addClass = function(value) { - // Support functions - if (typeof value === 'function') { - return domEach(this, function(i, el) { - var className = el.attribs['class'] || ''; - exports.addClass.call([el], value.call(el, i, className)); - }); +CombinedStream.prototype.pause = function() { + if (!this.pauseStreams) { + return; } - // Return if no value or not a string or function - if (!value || typeof value !== 'string') return this; - - var classNames = value.split(rspace), - numElements = this.length; - - - for (var i = 0; i < numElements; i++) { - // If selected element isn't a tag, move on - if (!isTag(this[i])) continue; - - // If we don't already have classes - var className = getAttr(this[i], 'class'), - numClasses, - setClass; - - if (!className) { - setAttr(this[i], 'class', classNames.join(' ').trim()); - } else { - setClass = ' ' + className + ' '; - numClasses = classNames.length; - - // Check if class already exists - for (var j = 0; j < numClasses; j++) { - var appendClass = classNames[j] + ' '; - if (setClass.indexOf(' ' + appendClass) < 0) - setClass += appendClass; - } + if(this.pauseStreams && this._currentStream && typeof(this._currentStream.pause) == 'function') this._currentStream.pause(); + this.emit('pause'); +}; - setAttr(this[i], 'class', setClass.trim()); - } +CombinedStream.prototype.resume = function() { + if (!this._released) { + this._released = true; + this.writable = true; + this._getNext(); } - return this; + if(this.pauseStreams && this._currentStream && typeof(this._currentStream.resume) == 'function') this._currentStream.resume(); + this.emit('resume'); }; -var splitClass = function(className) { - return className ? className.trim().split(rspace) : []; +CombinedStream.prototype.end = function() { + this._reset(); + this.emit('end'); }; -exports.removeClass = function(value) { - var classes, - numClasses, - removeAll; - - // Handle if value is a function - if (typeof value === 'function') { - return domEach(this, function(i, el) { - exports.removeClass.call( - [el], value.call(el, i, el.attribs['class'] || '') - ); - }); - } - - classes = splitClass(value); - numClasses = classes.length; - removeAll = arguments.length === 0; - - return domEach(this, function(i, el) { - if (!isTag(el)) return; - - if (removeAll) { - // Short circuit the remove all case as this is the nice one - el.attribs.class = ''; - } else { - var elClasses = splitClass(el.attribs.class), - index, - changed; - - for (var j = 0; j < numClasses; j++) { - index = elClasses.indexOf(classes[j]); - - if (index >= 0) { - elClasses.splice(index, 1); - changed = true; +CombinedStream.prototype.destroy = function() { + this._reset(); + this.emit('close'); +}; - // We have to do another pass to ensure that there are not duplicate - // classes listed - j--; - } - } - if (changed) { - el.attribs.class = elClasses.join(' '); - } - } - }); +CombinedStream.prototype._reset = function() { + this.writable = false; + this._streams = []; + this._currentStream = null; }; -exports.toggleClass = function(value, stateVal) { - // Support functions - if (typeof value === 'function') { - return domEach(this, function(i, el) { - exports.toggleClass.call( - [el], - value.call(el, i, el.attribs['class'] || '', stateVal), - stateVal - ); - }); +CombinedStream.prototype._checkDataSize = function() { + this._updateDataSize(); + if (this.dataSize <= this.maxDataSize) { + return; } - // Return if no value or not a string or function - if (!value || typeof value !== 'string') return this; - - var classNames = value.split(rspace), - numClasses = classNames.length, - state = typeof stateVal === 'boolean' ? stateVal ? 1 : -1 : 0, - numElements = this.length, - elementClasses, - index; - - for (var i = 0; i < numElements; i++) { - // If selected element isn't a tag, move on - if (!isTag(this[i])) continue; - - elementClasses = splitClass(this[i].attribs.class); + var message = + 'DelayedStream#maxDataSize of ' + this.maxDataSize + ' bytes exceeded.'; + this._emitError(new Error(message)); +}; - // Check if class already exists - for (var j = 0; j < numClasses; j++) { - // Check if the class name is currently defined - index = elementClasses.indexOf(classNames[j]); +CombinedStream.prototype._updateDataSize = function() { + this.dataSize = 0; - // Add if stateValue === true or we are toggling and there is no value - if (state >= 0 && index < 0) { - elementClasses.push(classNames[j]); - } else if (state <= 0 && index >= 0) { - // Otherwise remove but only if the item exists - elementClasses.splice(index, 1); - } + var self = this; + this._streams.forEach(function(stream) { + if (!stream.dataSize) { + return; } - this[i].attribs.class = elementClasses.join(' '); - } - - return this; -}; + self.dataSize += stream.dataSize; + }); -exports.is = function (selector) { - if (selector) { - return this.filter(selector).length > 0; + if (this._currentStream && this._currentStream.dataSize) { + this.dataSize += this._currentStream.dataSize; } - return false; }; +CombinedStream.prototype._emitError = function(err) { + this._reset(); + this.emit('error', err); +}; -},{"../static":190,"../utils":191,"lodash.assignin":287,"lodash.foreach":292,"lodash.some":298}],184:[function(require,module,exports){ -var domEach = require('../utils').domEach, - _ = { - pick: require('lodash.pick'), - }; - -var toString = Object.prototype.toString; +}).call(this,{"isBuffer":require("../../../../../.nvm/versions/node/v6.4.0/lib/node_modules/browserify/node_modules/is-buffer/index.js")}) +},{"../../../../../.nvm/versions/node/v6.4.0/lib/node_modules/browserify/node_modules/is-buffer/index.js":98,"delayed-stream":183,"stream":152,"util":163}],182:[function(require,module,exports){ +(function (Buffer){ +// Copyright Joyent, Inc. and other Node contributors. +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to permit +// persons to whom the Software is furnished to do so, subject to the +// following conditions: +// +// The above copyright notice and this permission notice shall be included +// in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN +// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, +// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR +// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE +// USE OR OTHER DEALINGS IN THE SOFTWARE. -/** - * Set / Get css. - * - * @param {String|Object} prop - * @param {String} val - * @return {self} - * @api public - */ +// NOTE: These type checking functions intentionally don't use `instanceof` +// because it is fragile and can be easily faked with `Object.create()`. -exports.css = function(prop, val) { - if (arguments.length === 2 || - // When `prop` is a "plain" object - (toString.call(prop) === '[object Object]')) { - return domEach(this, function(idx, el) { - setCss(el, prop, val, idx); - }); - } else { - return getCss(this[0], prop); +function isArray(arg) { + if (Array.isArray) { + return Array.isArray(arg); } -}; - -/** - * Set styles of all elements. - * - * @param {String|Object} prop - * @param {String} val - * @param {Number} idx - optional index within the selection - * @return {self} - * @api private - */ + return objectToString(arg) === '[object Array]'; +} +exports.isArray = isArray; -function setCss(el, prop, val, idx) { - if ('string' == typeof prop) { - var styles = getCss(el); - if (typeof val === 'function') { - val = val.call(el, idx, styles[prop]); - } +function isBoolean(arg) { + return typeof arg === 'boolean'; +} +exports.isBoolean = isBoolean; - if (val === '') { - delete styles[prop]; - } else if (val != null) { - styles[prop] = val; - } +function isNull(arg) { + return arg === null; +} +exports.isNull = isNull; - el.attribs.style = stringify(styles); - } else if ('object' == typeof prop) { - Object.keys(prop).forEach(function(k){ - setCss(el, k, prop[k]); - }); - } +function isNullOrUndefined(arg) { + return arg == null; } +exports.isNullOrUndefined = isNullOrUndefined; -/** - * Get parsed styles of the first element. - * - * @param {String} prop - * @return {Object} - * @api private - */ +function isNumber(arg) { + return typeof arg === 'number'; +} +exports.isNumber = isNumber; -function getCss(el, prop) { - var styles = parse(el.attribs.style); - if (typeof prop === 'string') { - return styles[prop]; - } else if (Array.isArray(prop)) { - return _.pick(styles, prop); - } else { - return styles; - } +function isString(arg) { + return typeof arg === 'string'; } +exports.isString = isString; -/** - * Stringify `obj` to styles. - * - * @param {Object} obj - * @return {Object} - * @api private - */ +function isSymbol(arg) { + return typeof arg === 'symbol'; +} +exports.isSymbol = isSymbol; -function stringify(obj) { - return Object.keys(obj || {}) - .reduce(function(str, prop){ - return str += '' - + (str ? ' ' : '') - + prop - + ': ' - + obj[prop] - + ';'; - }, ''); +function isUndefined(arg) { + return arg === void 0; } +exports.isUndefined = isUndefined; -/** - * Parse `styles`. - * - * @param {String} styles - * @return {Object} - * @api private - */ +function isRegExp(re) { + return objectToString(re) === '[object RegExp]'; +} +exports.isRegExp = isRegExp; -function parse(styles) { - styles = (styles || '').trim(); - - if (!styles) return {}; - - return styles - .split(';') - .reduce(function(obj, str){ - var n = str.indexOf(':'); - // skip if there is no :, or if it is the first/last character - if (n < 1 || n === str.length-1) return obj; - obj[str.slice(0,n).trim()] = str.slice(n+1).trim(); - return obj; - }, {}); -} - -},{"../utils":191,"lodash.pick":295}],185:[function(require,module,exports){ -// https://github.com/jquery/jquery/blob/2.1.3/src/manipulation/var/rcheckableType.js -// https://github.com/jquery/jquery/blob/2.1.3/src/serialize.js -var submittableSelector = 'input,select,textarea,keygen', - r20 = /%20/g, - rCRLF = /\r?\n/g, - _ = { - map: require('lodash.map') - }; +function isObject(arg) { + return typeof arg === 'object' && arg !== null; +} +exports.isObject = isObject; -exports.serialize = function() { - // Convert form elements into name/value objects - var arr = this.serializeArray(); +function isDate(d) { + return objectToString(d) === '[object Date]'; +} +exports.isDate = isDate; - // Serialize each element into a key/value string - var retArr = _.map(arr, function(data) { - return encodeURIComponent(data.name) + '=' + encodeURIComponent(data.value); - }); +function isError(e) { + return (objectToString(e) === '[object Error]' || e instanceof Error); +} +exports.isError = isError; - // Return the resulting serialization - return retArr.join('&').replace(r20, '+'); -}; +function isFunction(arg) { + return typeof arg === 'function'; +} +exports.isFunction = isFunction; -exports.serializeArray = function() { - // Resolve all form elements from either forms or collections of form elements - var Cheerio = this.constructor; - return this.map(function() { - var elem = this; - var $elem = Cheerio(elem); - if (elem.name === 'form') { - return $elem.find(submittableSelector).toArray(); - } else { - return $elem.filter(submittableSelector).toArray(); - } - }).filter( - // Verify elements have a name (`attr.name`) and are not disabled (`:disabled`) - '[name!=""]:not(:disabled)' - // and cannot be clicked (`[type=submit]`) or are used in `x-www-form-urlencoded` (`[type=file]`) - + ':not(:submit, :button, :image, :reset, :file)' - // and are either checked/don't have a checkable state - + ':matches([checked], :not(:checkbox, :radio))' - // Convert each of the elements to its value(s) - ).map(function(i, elem) { - var $elem = Cheerio(elem); - var name = $elem.attr('name'); - var val = $elem.val(); - - // If there is no value set (e.g. `undefined`, `null`), then return nothing - if (val == null) { - return null; - } else { - // If we have an array of values (e.g. `