--- /dev/null
+
+/*!
+ * Express - Utils
+ * Copyright(c) 2010 TJ Holowaychuk <tj@vision-media.ca>
+ * MIT Licensed
+ */
+
+/**
+ * Merge object `b` with `a` giving precedence to
+ * values in object `a`.
+ *
+ * @param {Object} a
+ * @param {Object} b
+ * @return {Object} a
+ * @api private
+ */
+
+exports.union = function(a, b){
+ if (a && b) {
+ var keys = Object.keys(b)
+ , len = keys.length
+ , key;
+ for (var i = 0; i < len; ++i) {
+ key = keys[i];
+ if (!a.hasOwnProperty(key)) {
+ a[key] = b[key];
+ }
+ }
+ }
+ return a;
+};
+
+/**
+ * Flatten the given `arr`.
+ *
+ * @param {Array} arr
+ * @return {Array}
+ * @api private
+ */
+
+exports.flatten = function(arr, ret){
+ var ret = ret || []
+ , len = arr.length;
+ for (var i = 0; i < len; ++i) {
+ if (Array.isArray(arr[i])) {
+ exports.flatten(arr[i], ret);
+ } else {
+ ret.push(arr[i]);
+ }
+ }
+ return ret;
+};
+
+/**
+ * Parse mini markdown implementation.
+ * The following conversions are supported,
+ * primarily for the "flash" middleware:
+ *
+ * _foo_ or *foo* become <em>foo</em>
+ * __foo__ or **foo** become <strong>foo</strong>
+ * [A](B) becomes <a href="B">A</a>
+ *
+ * @param {String} str
+ * @return {String}
+ * @api private
+ */
+
+exports.miniMarkdown = function(str){
+ return String(str)
+ .replace(/(__|\*\*)(.*?)\1/g, '<strong>$2</strong>')
+ .replace(/(_|\*)(.*?)\1/g, '<em>$2</em>')
+ .replace(/\[([^\]]+)\]\(([^)]+)\)/g, '<a href="$2">$1</a>');
+};
+
+/**
+ * Escape special characters in the given string of html.
+ *
+ * @param {String} html
+ * @return {String}
+ * @api private
+ */
+
+exports.escape = function(html) {
+ return String(html)
+ .replace(/&/g, '&')
+ .replace(/"/g, '"')
+ .replace(/</g, '<')
+ .replace(/>/g, '>');
+};
+
+/**
+ * Parse "Range" header `str` relative to the given file `size`.
+ *
+ * @param {Number} size
+ * @param {String} str
+ * @return {Array}
+ * @api private
+ */
+
+exports.parseRange = function(size, str){
+ var valid = true;
+ var arr = str.substr(6).split(',').map(function(range){
+ var range = range.split('-')
+ , start = parseInt(range[0], 10)
+ , end = parseInt(range[1], 10);
+
+ // -500
+ if (isNaN(start)) {
+ start = size - end;
+ end = size - 1;
+ // 500-
+ } else if (isNaN(end)) {
+ end = size - 1;
+ }
+
+ // Invalid
+ if (isNaN(start) || isNaN(end) || start > end) valid = false;
+
+ return { start: start, end: end };
+ });
+ return valid ? arr : undefined;
+};