diff --git a/.gitignore b/.gitignore index 530c414..e87e55e 100644 --- a/.gitignore +++ b/.gitignore @@ -15,3 +15,5 @@ results node_modules npm-debug.log + +lib/ diff --git a/lib/index.js b/lib/index.js deleted file mode 100644 index 9f33864..0000000 --- a/lib/index.js +++ /dev/null @@ -1,940 +0,0 @@ -// Generated by CoffeeScript 1.8.0 -(function() { - var ANDROID_RELATIONS, BASE_FIELDS, EXTRA_FIELDS, IM_VENDORS, IOS_IM_VENDORS, IOS_SERVICE_LABELS, IOS_SERVICE_TYPES, PHONETIC_FIELDS, SOCIAL_URLS, VCardParser, capitalizeFirstLetter, exportAbout, exportAdr, exportAlerts, exportBaseFields, exportChat, exportDefault, exportExtraFields, exportName, exportOther, exportPicture, exportRelation, exportRev, exportSocial, exportTags, exportUid, exportUrl, getAndroidItem, isValidDate, quotedPrintable, regexps, utf8, - __indexOf = [].indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, - __slice = [].slice; - - if (typeof module !== "undefined" && module !== null ? module.exports : void 0) { - utf8 = require('utf8'); - quotedPrintable = require('quoted-printable'); - } else { - utf8 = window.utf8; - quotedPrintable = window.quotedPrintable; - } - - regexps = { - begin: /^BEGIN:VCARD$/i, - end: /^END:VCARD$/i, - beginNonVCard: /^BEGIN:(.*)$/i, - endNonVCard: /^END:(.*)$/i, - simple: /^(version|fn|n|title|org|note|categories|bday|url|nickname|uid|tz|lang|geo|gender|kind)(;CHARSET=UTF-8)?(;ENCODING=QUOTED-PRINTABLE)?\:(.+)$/i, - composedkey: /^item(\d{1,2})\.([^\:]+):(.+)$/, - complex: /^([^\:\;]+);([^\:]+)\:(.+)$/, - property: /^(.+)=(.+)$/, - extended: /^X-([^\:]+)\:(.+)$/i, - applebday: /^(version|fn|n|title|org|note|categories|bday|url);value=date:(.+)$/i, - android: /^x-android-custom\:(.+)$/i - }; - - IM_VENDORS = ['skype', 'skype-username', 'aim', 'msn', 'yahoo', 'qq', 'google-talk', 'gtalk', 'icq', 'jabber', 'sip', 'gad']; - - IOS_IM_VENDORS = ['aim', 'jabber', 'msn', 'yahoo', 'icq']; - - PHONETIC_FIELDS = ['phonetic-first-name', 'phonetic-middle-name', 'phonetic-last-name']; - - ANDROID_RELATIONS = ['custom', 'assistant', 'brother', 'child', 'domestic partner', 'father', 'friend', 'manager', 'mother', 'parent', 'partner', 'referred by', 'relative', 'sister', 'spouse']; - - BASE_FIELDS = ['fn', 'bday', 'org', 'title', 'url', 'note', 'nickname', 'uid']; - - EXTRA_FIELDS = ['tz', 'lang', 'geo', 'gender', 'kind']; - - SOCIAL_URLS = { - twitter: "http://twitter.com/", - facebook: "http://facebook.com/", - flickr: "http://www.flickr.com/photos/", - linkedin: "http://www.linkedin.com/in/", - myspace: "http://www.myspace.com/", - sina: "http://weibo.com/n/" - }; - - IOS_SERVICE_TYPES = { - 'msn': 'MSN:msnim', - 'skype': 'Skype:skype', - 'google-talk': 'GoogleTalk:xmpp', - 'googletalk': 'GoogleTalk:xmpp', - 'gtalk': 'GoogleTalk:xmpp', - 'facebook': 'Facebook:xmpp', - 'aim': 'AIM:aim', - 'yahoo': 'Yahoo:aim', - 'icq': 'ICQ:aim', - 'jabber': 'Jabber:xmpp', - 'qq': 'QQ:x-apple', - 'gadugadu': 'GaduGadu:x-apple' - }; - - IOS_SERVICE_LABELS = { - 'msn': 'MSN', - 'skype': 'Skype', - 'google-talk': 'GoogleTalk', - 'googletalk': 'GoogleTalk', - 'gtalk': 'GoogleTalk', - 'facebook': 'Facebook', - 'aim': 'AIM', - 'yahoo': 'Yahoo:', - 'icq': 'ICQ', - 'jabber': 'Jabber', - 'qq': 'QQ', - 'gadugadu': 'GaduGadu' - }; - - isValidDate = function(date) { - var d, m, matches, res, y; - matches = /^(\d{4})[-\/](\d{2})[-\/](\d{2})$/.exec(date); - if (matches === null) { - return false; - } else { - y = parseInt(matches[1]); - m = parseInt(matches[2] - 1); - d = parseInt(matches[3]); - date = new Date(y, m, d); - res = date.getDate() === d; - res = res && date.getMonth() === m; - res = res && date.getFullYear() === y; - return res; - } - }; - - capitalizeFirstLetter = function(string) { - if (string != null) { - return "" + (string.charAt(0).toUpperCase()) + (string.toLowerCase().slice(1)); - } else { - return ''; - } - }; - - getAndroidItem = function(type, key, value) { - var index, length, prefix; - key = key.toLowerCase().replace('_', ' '); - if (key === 'anniversary') { - index = 1; - } else if (key === 'died') { - index = 2; - } else { - index = 0; - length = ANDROID_RELATIONS.length; - while (index < length && ANDROID_RELATIONS[index] !== key) { - index++; - } - if (index === length) { - key = null; - } - } - if (key) { - prefix = 'X-ANDROID-CUSTOM:vnd.android.cursor.item/'; - return "" + prefix + type + ";" + value + ";" + index + ";;;;;;;;;;;;;"; - } else { - return null; - } - }; - - VCardParser = (function() { - function VCardParser(vcf) { - this.reset(); - if (vcf) { - this.read(vcf); - } - } - - VCardParser.prototype.reset = function() { - this.contacts = []; - this.currentContact = null; - this.currentDatapoint = null; - this.currentIndex = null; - return this.currentVersion = "3.0"; - }; - - VCardParser.prototype.storeCurrentDatapoint = function() { - if (this.currentDatapoint) { - this.currentContact.datapoints.push(this.currentDatapoint); - return this.currentDatapoint = null; - } - }; - - VCardParser.prototype.addDatapoint = function(name, type, value) { - this.storeCurrentDatapoint(); - return this.currentContact.datapoints.push({ - name: name, - type: type, - value: value - }); - }; - - VCardParser.prototype.addTypeProperty = function(dp, pvalue) { - if ((dp.type != null) && dp.type !== 'internet') { - return dp.type = "" + dp.type + " " + pvalue; - } else { - return dp.type = pvalue; - } - }; - - VCardParser.prototype.storeCurrentContact = function() { - var _ref; - if ((this.currentContact.n == null) && (this.currentContact.fn == null)) { - console.error('There should be at least a N field or a FN field'); - } - if ((this.currentContact.n == null) || ((_ref = this.currentContact.n) === '' || _ref === ';;;;')) { - this.currentContact.n = VCardParser.fnToN(this.currentContact.fn).join(';'); - } - if ((this.currentContact.fn == null) || this.currentContact.fn === '') { - this.currentContact.fn = VCardParser.nToFN(this.currentContact.n); - } - return this.contacts.push(this.currentContact); - }; - - VCardParser.prototype.read = function(vcard) { - var line, _i, _len, _ref, _results; - _ref = this.splitLines(vcard); - _results = []; - for (_i = 0, _len = _ref.length; _i < _len; _i++) { - line = _ref[_i]; - _results.push(this.handleLine(line)); - } - return _results; - }; - - VCardParser.prototype.splitLines = function(vcard) { - var inQuotedPrintable, lines, sourcelines; - sourcelines = vcard.split(/\r?\n/); - lines = []; - inQuotedPrintable = false; - sourcelines.forEach(function(line) { - var lineIndex; - if (!((line == null) || line === '')) { - if (line[0] === ' ' || inQuotedPrintable) { - if (line[0] === ' ') { - line = line.slice(1); - } - if (inQuotedPrintable) { - if (line[line.length - 1] === '=') { - line = line.slice(0, -1); - } else { - inQuotedPrintable = false; - } - } - lineIndex = lines.length - 1; - if (lineIndex >= 0) { - return lines[lineIndex] = lines[lineIndex] + line; - } else { - return lines.push(line); - } - } else { - if (/^(.+)ENCODING=QUOTED-PRINTABLE(.+)=$/i.test(line)) { - inQuotedPrintable = true; - line = line.slice(0, -1); - } - return lines.push(line); - } - } - }); - return lines; - }; - - VCardParser.prototype.handleLine = function(line) { - if (this.nonVCard) { - if (regexps.endNonVCard.test(line)) { - if (line.match(regexps.endNonVCard)[1] === this.nonVCard) { - return this.nonVCard = false; - } - } - } else if (regexps.begin.test(line)) { - return this.currentContact = { - datapoints: [] - }; - } else if (regexps.beginNonVCard.test(line)) { - return this.nonVCard = line.match(regexps.beginNonVCard)[1]; - } else if (regexps.end.test(line)) { - this.storeCurrentDatapoint(); - return this.storeCurrentContact(); - } else if (regexps.simple.test(line)) { - return this.handleSimpleLine(line); - } else if (regexps.applebday.test(line)) { - return this.handleSimpleLine(line, true); - } else if (regexps.android.test(line)) { - return this.handleAndroidLine(line); - } else if (regexps.extended.test(line)) { - return this.handleExtendedLine(line); - } else if (regexps.composedkey.test(line)) { - return this.handleComposedLine(line); - } else if (regexps.complex.test(line)) { - return this.handleComplexLine(line); - } - }; - - VCardParser.prototype.handleSimpleLine = function(line, apple) { - var all, key, nParts, nPartsCleaned, quoted, utf, value, values, _ref, _ref1; - if (apple == null) { - apple = false; - } - if (apple) { - _ref = line.match(regexps.applebday), all = _ref[0], key = _ref[1], value = _ref[2]; - } else { - _ref1 = line.match(regexps.simple), all = _ref1[0], key = _ref1[1], utf = _ref1[2], quoted = _ref1[3], value = _ref1[4]; - } - if (quoted != null) { - value = VCardParser.unquotePrintable(value); - } - value = VCardParser.unescapeText(value); - key = key.toLowerCase(); - if (key === 'version') { - return this.currentversion = value; - } else if (key === 'rev') { - return this.currentContact.revision = value; - } else if (key === 'categories') { - return this.currentContact.tags = value.split(/(?!\\),/).map(VCardParser.unescapeText); - } else if (key === 'n') { - nParts = value.split(/(?!\\);/); - if (nParts.length === 5) { - return this.currentContact['n'] = value; - } else { - nPartsCleaned = ['', '', '', '', '']; - if (nParts.length <= 5) { - nParts.forEach(function(part, index) { - return nPartsCleaned[index] = part; - }); - } else if (nParts.length === 6) { - nPartsCleaned.push(''); - nParts.forEach(function(part, index) { - return nPartsCleaned[index] = part; - }); - } else { - nPartsCleaned[2] = nParts.join(' '); - } - return this.currentContact['n'] = nPartsCleaned.join(';'); - } - } else if (__indexOf.call(BASE_FIELDS, key) >= 0) { - if (key === 'org') { - values = value.split(';'); - if (values.length === 2) { - this.currentContact.org = values[0]; - return this.currentContact.department = values[1]; - } else { - return this.currentContact.org = value; - } - } else { - return this.currentContact[key.toLowerCase()] = value; - } - } else if (__indexOf.call(EXTRA_FIELDS, key) >= 0) { - return this.currentContact[key.toLowerCase()] = value; - } - }; - - VCardParser.prototype.handleExtendedLine = function(line) { - var all, elements, key, keyvalues, kv, splitted, type, user, vals, value, _i, _len, _ref; - _ref = line.match(regexps.extended), all = _ref[0], key = _ref[1], value = _ref[2]; - if (key != null) { - key = key.toLowerCase(); - if (__indexOf.call(IM_VENDORS, key) >= 0) { - return this.currentContact.datapoints.push({ - name: 'chat', - type: key, - value: value - }); - } else if (__indexOf.call(PHONETIC_FIELDS, key) >= 0) { - key = key.replace(/-/g, ' '); - return this.currentContact.datapoints.push({ - name: 'about', - type: key, - value: value - }); - } else if (key.indexOf('socialprofile') === 0) { - keyvalues = key.split(';'); - elements = {}; - for (_i = 0, _len = keyvalues.length; _i < _len; _i++) { - kv = keyvalues[_i]; - splitted = kv.split('='); - elements[splitted[0].replace('x-', '')] = splitted[1]; - } - if (!elements.user) { - elements['user'] = value; - } - if (elements.type && elements.user) { - type = elements['type']; - user = elements['user']; - return this.currentContact.datapoints.push({ - name: 'social', - type: type, - value: user - }); - } - } else if (key === 'activity-alert') { - vals = value.split(','); - if (vals.length > 1) { - type = vals.splice(0, 1)[0]; - type = type != null ? type.split('=')[1].replace(/\\/g, '') : void 0; - value = vals.join(','); - } - return this.currentContact.datapoints.push({ - name: 'alerts', - type: type, - value: value - }); - } - } - }; - - VCardParser.prototype.handleAndroidLine = function(line) { - var all, parts, raw, type, value, _ref, _ref1; - _ref = line.match(regexps.android), all = _ref[0], raw = _ref[1]; - parts = raw.split(';'); - switch (parts[0].replace('vnd.android.cursor.item/', '')) { - case 'contact_event': - value = parts[1]; - type = (_ref1 = parts[2]) === '0' || _ref1 === '2' ? parts[3] : parts[2] === '1' ? 'anniversary' : 'birthday'; - return this.currentContact.datapoints.push({ - name: 'about', - type: type, - value: value - }); - case 'relation': - value = parts[1]; - type = ANDROID_RELATIONS[+parts[2]]; - if (type === 'custom') { - type = parts[3]; - } - return this.currentContact.datapoints.push({ - name: 'relation', - type: type, - value: value - }); - case 'nickname': - value = parts[1]; - return this.currentContact.nickname = value; - } - }; - - VCardParser.prototype.handleCurrentSpecialCases = function() { - var dp, _ref, _ref1; - dp = this.currentDatapoint; - if (_ref = dp != null ? dp.type : void 0, __indexOf.call(IM_VENDORS, _ref) >= 0) { - dp.name = 'chat'; - if (dp['x-service-type'] != null) { - dp.value = dp.value.split(':')[1]; - if (_ref1 = dp['x-service-type'], __indexOf.call(IM_VENDORS, _ref1) < 0) { - dp.type = dp['x-service-type']; - } - } - } - if ((dp != null ? dp.name : void 0) === 'impp') { - dp.name = 'chat'; - return dp.value = dp.value.split(':')[1]; - } - }; - - VCardParser.prototype.handleComposedLine = function(line) { - var all, itemidx, key, part, properties, value, _ref; - _ref = line.match(regexps.composedkey), all = _ref[0], itemidx = _ref[1], part = _ref[2], value = _ref[3]; - if (this.currentIndex === null || this.currentIndex !== itemidx || !this.currentDatapoint) { - this.handleCurrentSpecialCases(); - this.storeCurrentDatapoint(); - this.currentDatapoint = {}; - } - this.currentIndex = itemidx; - part = part.split(';'); - key = part[0]; - properties = part.splice(1); - value = value.split(';'); - if (value.length === 1) { - value = value[0].replace('_$!<', '').replace('>!$_', '').replace('\\:', ':'); - } - key = key.toLowerCase(); - if (key === 'x-ablabel' || key === 'x-abadr') { - return this.addTypeProperty(this.currentDatapoint, value.toLowerCase()); - } else { - this.handleProperties(this.currentDatapoint, properties); - if (key === 'x-abdate') { - key = 'about'; - } - if (key === 'x-abrelatednames') { - key = 'relation'; - } - if (key === 'adr') { - if (Array.isArray(value)) { - value = value.map(VCardParser.unescapeText); - } else { - value = ['', '', VCardParser.unescapeText(value), '', '', '', '']; - } - } - this.currentDatapoint['name'] = key.toLowerCase(); - return this.currentDatapoint['value'] = value; - } - }; - - VCardParser.prototype.handleComplexLine = function(line) { - var all, key, properties, value, _ref; - _ref = line.match(regexps.complex), all = _ref[0], key = _ref[1], properties = _ref[2], value = _ref[3]; - this.storeCurrentDatapoint(); - this.currentDatapoint = {}; - value = value.split(';'); - if (value.length === 1) { - value = value[0]; - } - key = key.toLowerCase(); - if (key === 'photo') { - this.currentContact['photo'] = value; - return this.currentDatapoint = null; - } else if (!(key === 'email' || key === 'tel' || key === 'adr' || key === 'url')) { - return this.currentDatapoint = null; - } else { - this.currentDatapoint['name'] = key; - if (key === 'adr') { - if (Array.isArray(value)) { - value = value.map(VCardParser.unescapeText); - } else { - value = ['', '', VCardParser.unescapeText(value), '', '', '', '']; - } - } - this.handleProperties(this.currentDatapoint, properties.split(';')); - if (this.currentDatapoint.encoding === 'quoted-printable') { - if (Array.isArray(value)) { - value = value.map(VCardParser.unquotePrintable); - } else { - value = VCardParser.unquotePrintable(value); - } - delete this.currentDatapoint.encoding; - } - return this.currentDatapoint.value = value; - } - }; - - VCardParser.prototype.handleProperties = function(dp, properties) { - var all, match, pname, previousValue, property, pvalue, _i, _len, _results; - _results = []; - for (_i = 0, _len = properties.length; _i < _len; _i++) { - property = properties[_i]; - if (match = property.match(regexps.property)) { - all = match[0], pname = match[1], pvalue = match[2]; - pvalue = pvalue.toLowerCase(); - previousValue = dp[pname.toLowerCase()]; - if ((previousValue != null) && previousValue !== 'internet') { - pvalue = "" + previousValue + " " + pvalue; - } - } else if (property === 'PREF') { - pname = 'pref'; - pvalue = true; - if (dp.type != null) { - dp.type = "" + dp.type + " " + (property.toLowerCase()); - } else { - dp.type = property.toLowerCase(); - } - } else { - pname = 'type'; - if (dp.type != null) { - pvalue = "" + dp.type + " " + (property.toLowerCase()); - } else { - pvalue = property.toLowerCase(); - } - } - if (pname === 'type' && pvalue === 'pref') { - pname = 'pref'; - pvalue = true; - } - _results.push(dp[pname.toLowerCase()] = pvalue); - } - return _results; - }; - - return VCardParser; - - })(); - - VCardParser.unquotePrintable = function(value) { - var error; - value = value || ''; - try { - return utf8.decode(quotedPrintable.decode(value)); - } catch (_error) { - error = _error; - return value; - } - }; - - VCardParser.escapeText = function(value) { - var text; - if (value == null) { - return value; - } else { - text = value.replace(/([,;\\])/ig, "\\$1"); - text = text.replace(/\n/g, '\\n'); - return text; - } - }; - - VCardParser.unescapeText = function(t) { - var s; - if (t == null) { - return t; - } else { - s = t.replace(/\\n/ig, '\n'); - s = s.replace(/\\([,;\\])/ig, "$1"); - return s; - } - }; - - VCardParser.toVCF = function(model, picture, mode) { - var currentType, datapoint, formattedType, i, itemCounter, key, options, out, type, types, value, _i, _len, _ref, _ref1; - if (picture == null) { - picture = null; - } - if (mode == null) { - mode = 'google'; - } - itemCounter = 0; - out = ["BEGIN:VCARD"]; - out.push("VERSION:3.0"); - exportUid(out, model); - if (model.revision != null) { - exportRev(out, model); - } - if (model.n != null) { - exportName(out, model); - } - exportBaseFields(out, model); - exportExtraFields(out, model); - if ((model.tags != null) && model.tags.length > 0) { - exportTags(out, model); - } - _ref = model.datapoints; - for (i in _ref) { - datapoint = _ref[i]; - if (!((datapoint.name != null) && (datapoint.value != null))) { - continue; - } - key = datapoint.name.toUpperCase(); - type = ((_ref1 = datapoint.type) != null ? _ref1.toUpperCase() : void 0) || null; - value = datapoint.value; - if (Array.isArray(value)) { - value = value.map(VCardParser.escapeText); - } else { - value = VCardParser.escapeText(value); - } - formattedType = ""; - if (type != null) { - types = type.split(' '); - for (_i = 0, _len = types.length; _i < _len; _i++) { - currentType = types[_i]; - formattedType += ";TYPE=" + currentType; - } - } - options = { - out: out, - type: type, - formattedType: formattedType, - value: value, - mode: mode, - itemCounter: itemCounter, - key: key - }; - switch (key) { - case 'ABOUT': - itemCounter = exportAbout(options); - break; - case 'OTHER': - itemCounter = exportOther(options); - break; - case 'CHAT': - itemCounter = exportChat(options); - break; - case 'URL': - itemCounter = exportUrl(options); - break; - case 'RELATION': - itemCounter = exportRelation(options); - break; - case 'ADR': - itemCounter = exportAdr(options); - break; - case 'SOCIAL': - itemCounter = exportSocial(options); - break; - case 'ALERTS': - itemCounter = exportAlerts(options); - break; - default: - itemCounter = exportDefault(options); - } - } - if (picture != null) { - exportPicture(out, picture); - } - out.push("END:VCARD"); - return out.join("\n") + "\n"; - }; - - exportUid = function(out, model) { - var uid, uri; - uri = model.carddavuri; - uid = (uri != null ? uri.substring(0, uri.length - 4) : void 0) || model.id; - if (uid != null) { - return out.push("UID:" + uid); - } - }; - - exportBaseFields = function(out, model) { - var department, prop, value, _i, _len, _results; - _results = []; - for (_i = 0, _len = BASE_FIELDS.length; _i < _len; _i++) { - prop = BASE_FIELDS[_i]; - value = model[prop]; - if (value) { - value = VCardParser.escapeText(value); - } - if (prop === 'org') { - if ((model.department != null) && model.department.length > 0) { - department = VCardParser.escapeText(model.department); - value = "" + value + ";" + department; - } - } - if (value) { - _results.push(out.push("" + (prop.toUpperCase()) + ":" + value)); - } else { - _results.push(void 0); - } - } - return _results; - }; - - exportExtraFields = function(out, model) { - var prop, value, _i, _len, _results; - _results = []; - for (_i = 0, _len = EXTRA_FIELDS.length; _i < _len; _i++) { - prop = EXTRA_FIELDS[_i]; - value = model[prop]; - if (prop === 'geo') { - if (value) { - value = "geo:" + value[0] + ":" + value[1]; - } - } else { - if (value) { - value = VCardParser.escapeText(value); - } - } - if (value) { - _results.push(out.push("" + (prop.toUpperCase()) + ":" + value)); - } else { - _results.push(void 0); - } - } - return _results; - }; - - exportName = function(out, model) { - return out.push("N:" + model.n); - }; - - exportRev = function(out, model) { - if (typeof model.revision === 'date') { - return out.push("REV:" + (model.revision.toISOString())); - } else { - return out.push("REV:" + model.revision); - } - }; - - exportTags = function(out, model) { - var value; - value = model.tags.map(VCardParser.escapeText).join(','); - return out.push("CATEGORIES:" + value); - }; - - exportAbout = function(options) { - var formattedType, itemCounter, mode, out, type, value; - out = options.out, type = options.type, formattedType = options.formattedType, value = options.value, mode = options.mode, itemCounter = options.itemCounter; - if (type === 'DIED' || type === 'ANNIVERSARY') { - if (mode === 'android') { - out.push(getAndroidItem('contact_event', type, value)); - } else { - itemCounter++; - out.push("item" + itemCounter + ".X-ABDATE:" + value); - formattedType = capitalizeFirstLetter(type); - out.push("item" + itemCounter + ".X-ABLabel:" + formattedType); - } - } else if ((type != null ? type.indexOf('PHONETIC') : void 0) === 0) { - out.push("X-" + (type != null ? type.replace(/\s/g, '-') : void 0) + ":" + value); - } else if (isValidDate(value)) { - itemCounter++; - out.push("item" + itemCounter + ".X-ABDATE:" + value); - formattedType = capitalizeFirstLetter(type); - out.push("item" + itemCounter + ".X-ABLabel:" + formattedType); - } else { - out.push("X-" + type + ":" + value); - } - return itemCounter; - }; - - exportOther = function(options) { - var formattedType, itemCounter, mode, out, type, value; - out = options.out, type = options.type, formattedType = options.formattedType, value = options.value, mode = options.mode, itemCounter = options.itemCounter; - out.push("X-EVENT" + formattedType + ":" + value); - return itemCounter; - }; - - exportChat = function(options) { - var formattedType, itemCounter, line, mode, out, serviceType, type, value; - out = options.out, type = options.type, formattedType = options.formattedType, value = options.value, mode = options.mode, itemCounter = options.itemCounter; - if (type === 'SKYPE' && mode === 'android') { - out.push("X-SKYPE-USERNAME:" + value); - } else { - if (mode === 'ios') { - itemCounter++; - serviceType = IOS_SERVICE_TYPES[type != null ? type.toLowerCase() : void 0]; - if (serviceType != null) { - line = "item" + itemCounter + ".IMPP;"; - line += "X-SERVICE-TYPE=" + serviceType + ":" + value; - out.push(line); - } else { - type = capitalizeFirstLetter(type != null ? type.toLowerCase() : void 0); - line = "item" + itemCounter + ".IMPP;"; - line += "X-SERVICE-TYPE=" + type + ":x-apple:" + value; - out.push(line); - } - } else { - out.push("X-" + type + ":" + value); - } - } - return itemCounter; - }; - - exportUrl = function(options) { - var formattedType, itemCounter, mode, out, type, value; - out = options.out, type = options.type, formattedType = options.formattedType, value = options.value, mode = options.mode, itemCounter = options.itemCounter; - if (type != null) { - itemCounter++; - out.push("item" + itemCounter + ".URL:" + value); - if (type !== 'PROFILE' && type !== 'BLOG') { - formattedType = capitalizeFirstLetter(type != null ? type.toLowerCase() : void 0); - if ((mode === 'ios') && (type === 'HOME' || type === 'WORK' || type === 'OTHER')) { - out.push("item" + itemCounter + ".X-ABLabel:_$!<" + formattedType + ">!$_"); - } else if (mode === 'ios') { - out.push("item" + itemCounter + ".X-ABLabel:" + formattedType); - } else { - out.push("item" + itemCounter + ".X-ABLabel:_$!<" + formattedType + ">!$_"); - } - } else { - out.push("item" + itemCounter + ".X-ABLabel:" + type); - } - } else { - out.push("URL:" + value); - } - return itemCounter; - }; - - exportRelation = function(options) { - var formattedType, itemCounter, line, mode, out, type, value; - out = options.out, type = options.type, formattedType = options.formattedType, value = options.value, mode = options.mode, itemCounter = options.itemCounter; - if (mode === 'android') { - line = getAndroidItem('relation', type, value); - if (line) { - out.push(line); - } - } else { - itemCounter++; - out.push("item" + itemCounter + ".X-ABRELATEDNAMES:" + value); - formattedType = capitalizeFirstLetter(type != null ? type.toLowerCase() : void 0); - out.push("item" + itemCounter + ".X-ABLabel:_$!<" + formattedType + ">!$_"); - } - return itemCounter; - }; - - exportAdr = function(options) { - var formattedType, itemCounter, key, mode, out, type, value; - out = options.out, type = options.type, formattedType = options.formattedType, value = options.value, mode = options.mode, itemCounter = options.itemCounter, key = options.key; - if (Array.isArray(value)) { - value = value.join(';'); - } - out.push("" + key + formattedType + ":" + value); - return itemCounter; - }; - - exportSocial = function(options) { - var formattedType, itemCounter, key, mode, out, res, type, url, urlPrefix, value; - out = options.out, type = options.type, formattedType = options.formattedType, value = options.value, mode = options.mode, itemCounter = options.itemCounter, key = options.key; - url = value; - urlPrefix = SOCIAL_URLS[type != null ? type.toLowerCase() : void 0]; - if (urlPrefix != null) { - url = "" + urlPrefix + value; - } else { - formattedType = capitalizeFirstLetter(type != null ? type.toLowerCase() : void 0); - formattedType = ";TYPE=" + formattedType; - } - res = "X-SOCIALPROFILE" + formattedType + ";x-user=" + value + ":" + url; - out.push(res); - return itemCounter; - }; - - exportAlerts = function(options) { - var formattedType, itemCounter, key, mode, out, res, type, value; - out = options.out, type = options.type, formattedType = options.formattedType, value = options.value, mode = options.mode, itemCounter = options.itemCounter, key = options.key; - type = type != null ? type.toLowerCase() : void 0; - value = value.replace(/\\\\\\/g, "\\"); - res = "X-ACTIVITY-ALERT:type=" + type + "\\," + value; - out.push(res); - return itemCounter; - }; - - exportDefault = function(options) { - var formattedType, itemCounter, key, mode, out, type, value; - out = options.out, type = options.type, formattedType = options.formattedType, value = options.value, mode = options.mode, itemCounter = options.itemCounter, key = options.key; - out.push("" + key + formattedType + ":" + value); - return itemCounter; - }; - - exportPicture = function(out, picture) { - var folded, pictureString; - folded = picture.match(/.{1,75}/g).join('\n '); - pictureString = "PHOTO;ENCODING=B;TYPE=JPEG;VALUE=BINARY:\n " + folded; - return out.push(pictureString); - }; - - VCardParser.nToFN = function(n) { - var familly, given, middle, parts, prefix, suffix; - n = n || []; - familly = n[0], given = n[1], middle = n[2], prefix = n[3], suffix = n[4]; - parts = [prefix, given, middle, familly, suffix]; - parts = parts.filter(function(part) { - return (part != null) && part !== ''; - }); - return parts.join(' '); - }; - - VCardParser.fnToN = function(fn) { - fn = fn || ''; - return ['', fn, '', '', '']; - }; - - VCardParser.fnToNLastnameNFirstname = function(fn) { - var familly, given, middle, parts, _i, _ref; - fn = fn || ''; - _ref = fn.split(' '), given = _ref[0], middle = 3 <= _ref.length ? __slice.call(_ref, 1, _i = _ref.length - 1) : (_i = 1, []), familly = _ref[_i++]; - parts = [familly, given, middle.join(' '), '', '']; - return parts; - }; - - VCardParser.adrArrayToString = function(value) { - var countryPart, flat, streetPart, structuredToFlat; - value = value || []; - structuredToFlat = function(t) { - t = t.filter(function(part) { - return (part != null) && part !== ''; - }); - return t.join(', '); - }; - streetPart = structuredToFlat(value.slice(0, 3)); - countryPart = structuredToFlat(value.slice(3, 7)); - flat = streetPart; - if (countryPart !== '') { - flat += '\n' + countryPart; - } - return flat; - }; - - VCardParser.adrStringToArray = function(s) { - s = s || ''; - return ['', '', s, '', '', '', '']; - }; - - if (typeof module !== "undefined" && module !== null ? module.exports : void 0) { - module.exports = VCardParser; - } else { - window.VCardParser = VCardParser; - } - -}).call(this); diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..c996615 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,830 @@ +{ + "name": "cozy-vcard", + "version": "0.2.18", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@ungap/promise-all-settled": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", + "integrity": "sha512-sL/cEvJWAnClXw0wHk85/2L0G6Sj8UB0Ctc1TEMbKSsmpRosqhwj9gWgFRZSrBr2f9tiXISwNhCPmlfqUqyb9Q==", + "dev": true + }, + "ansi-colors": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/ansi-colors/-/ansi-colors-4.1.1.tgz", + "integrity": "sha512-JoX0apGbHaUJBNl6yF+p6JAFYZ666/hhCGKN5t9QFjbJQKUU/g8MNbFDbvfrgKXvI1QpZplPOnwIo99lX/AAmA==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "anymatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.2.tgz", + "integrity": "sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg==", + "dev": true, + "requires": { + "normalize-path": "^3.0.0", + "picomatch": "^2.0.4" + } + }, + "argparse": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz", + "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", + "dev": true + }, + "assertion-error": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-1.0.0.tgz", + "integrity": "sha1-x/hUOP3UZrx8oWq5DIFRN5el0js=", + "dev": true + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "binary-extensions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", + "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz", + "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==", + "dev": true, + "requires": { + "fill-range": "^7.0.1" + } + }, + "browser-stdout": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz", + "integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==", + "dev": true + }, + "camelcase": { + "version": "6.2.0", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-6.2.0.tgz", + "integrity": "sha512-c7wVvbw3f37nuobQNtgsgG9POC9qMbNuMQmTCqZv23b6MIz0fcYpBiOlv9gEN/hdLdnZTDQhg6e9Dq5M1vKvfg==", + "dev": true + }, + "chai": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/chai/-/chai-1.10.0.tgz", + "integrity": "sha1-5AMcyHZURhp1lD5aNatG6vOcHrk=", + "dev": true, + "requires": { + "assertion-error": "1.0.0", + "deep-eql": "0.1.3" + } + }, + "chalk": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.1.tgz", + "integrity": "sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg==", + "dev": true, + "requires": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "dependencies": { + "supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + } + } + }, + "chokidar": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.5.1.tgz", + "integrity": "sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw==", + "dev": true, + "requires": { + "anymatch": "~3.1.1", + "braces": "~3.0.2", + "fsevents": "~2.3.1", + "glob-parent": "~5.1.0", + "is-binary-path": "~2.1.0", + "is-glob": "~4.0.1", + "normalize-path": "~3.0.0", + "readdirp": "~3.5.0" + } + }, + "cliui": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", + "integrity": "sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.0", + "wrap-ansi": "^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "coffeescript": { + "version": "1.12.7", + "resolved": "https://registry.npmjs.org/coffeescript/-/coffeescript-1.12.7.tgz", + "integrity": "sha512-pLXHFxQMPklVoEekowk8b3erNynC+DVJzChxS/LCBBgR6/8AJkHivkm//zbowcfc7BTCAjryuhx6gPqPRfsFoA==", + "dev": true + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", + "dev": true, + "requires": { + "ms": "2.1.2" + }, + "dependencies": { + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "decamelize": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-4.0.0.tgz", + "integrity": "sha512-9iE1PgSik9HeIIw2JO94IidnE3eBoQrFJ3w7sFuzSX4DpmZ3v5sZpUiV5Swcf6mQEF+Y0ru8Neo+p+nyh2J+hQ==", + "dev": true + }, + "deep-eql": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-0.1.3.tgz", + "integrity": "sha1-71WKyrjeJSBs1xOQbXTlaTDrafI=", + "dev": true, + "requires": { + "type-detect": "0.1.1" + } + }, + "diff": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.0.0.tgz", + "integrity": "sha512-/VTCrvm5Z0JGty/BWHljh+BAiw3IK+2j87NGMu8Nwc/f48WoDAC395uomO9ZD117ZOBaHmkX1oyLvkVM/aIT3w==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "escalade": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.1.tgz", + "integrity": "sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==", + "dev": true + }, + "escape-string-regexp": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", + "integrity": "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==", + "dev": true + }, + "fill-range": { + "version": "7.0.1", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", + "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==", + "dev": true, + "requires": { + "to-regex-range": "^5.0.1" + } + }, + "find-up": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", + "integrity": "sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==", + "dev": true, + "requires": { + "locate-path": "^6.0.0", + "path-exists": "^4.0.0" + } + }, + "flat": { + "version": "5.0.2", + "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", + "integrity": "sha512-b6suED+5/3rTpUBdG1gupIl8MPFCAMA0QXwmljLhvCUKcUvdE4gWky9zpuGCcXHOsz4J9wPGNWq6OKpmIzz3hQ==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.2.tgz", + "integrity": "sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==", + "dev": true, + "optional": true + }, + "get-caller-file": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz", + "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==", + "dev": true + }, + "glob": { + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz", + "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==", + "dev": true, + "requires": { + "is-glob": "^4.0.1" + } + }, + "growl": { + "version": "1.10.5", + "resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz", + "integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==", + "dev": true + }, + "has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true + }, + "he": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", + "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-binary-path": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz", + "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==", + "dev": true, + "requires": { + "binary-extensions": "^2.0.0" + } + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", + "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==", + "dev": true + }, + "is-plain-obj": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", + "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "js-yaml": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.0.0.tgz", + "integrity": "sha512-pqon0s+4ScYUvX30wxQi3PogGFAlUyH0awepWvwkj4jD4v+ova3RiYw8bmA6x2rDrEaj8i/oWKoRxpVNW+Re8Q==", + "dev": true, + "requires": { + "argparse": "^2.0.1" + } + }, + "locate-path": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz", + "integrity": "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==", + "dev": true, + "requires": { + "p-locate": "^5.0.0" + } + }, + "log-symbols": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/log-symbols/-/log-symbols-4.0.0.tgz", + "integrity": "sha512-FN8JBzLx6CzeMrB0tg6pqlGU1wCrXW+ZXGH481kfsBqer0hToTIiHdjH4Mq8xJUbvATujKCvaREGWpGUionraA==", + "dev": true, + "requires": { + "chalk": "^4.0.0" + } + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "mocha": { + "version": "8.4.0", + "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", + "integrity": "sha512-hJaO0mwDXmZS4ghXsvPVriOhsxQ7ofcpQdm8dE+jISUOKopitvnXFQmpRR7jd2K6VBG6E26gU3IAbXXGIbu4sQ==", + "dev": true, + "requires": { + "@ungap/promise-all-settled": "1.1.2", + "ansi-colors": "4.1.1", + "browser-stdout": "1.3.1", + "chokidar": "3.5.1", + "debug": "4.3.1", + "diff": "5.0.0", + "escape-string-regexp": "4.0.0", + "find-up": "5.0.0", + "glob": "7.1.6", + "growl": "1.10.5", + "he": "1.2.0", + "js-yaml": "4.0.0", + "log-symbols": "4.0.0", + "minimatch": "3.0.4", + "ms": "2.1.3", + "nanoid": "3.1.20", + "serialize-javascript": "5.0.1", + "strip-json-comments": "3.1.1", + "supports-color": "8.1.1", + "which": "2.0.2", + "wide-align": "1.1.3", + "workerpool": "6.1.0", + "yargs": "16.2.0", + "yargs-parser": "20.2.4", + "yargs-unparser": "2.0.0" + } + }, + "ms": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", + "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", + "dev": true + }, + "nanoid": { + "version": "3.1.20", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.20.tgz", + "integrity": "sha512-a1cQNyczgKbLX9jwbS/+d7W8fX/RfgYR7lVWwWOGIPNgK2m0MWvrGF6/m4kk6U3QcFMnZf3RIhL0v2Jgh/0Uxw==", + "dev": true + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "p-limit": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", + "integrity": "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==", + "dev": true, + "requires": { + "yocto-queue": "^0.1.0" + } + }, + "p-locate": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-5.0.0.tgz", + "integrity": "sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==", + "dev": true, + "requires": { + "p-limit": "^3.0.2" + } + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "picomatch": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.0.tgz", + "integrity": "sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw==", + "dev": true + }, + "quoted-printable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/quoted-printable/-/quoted-printable-1.0.1.tgz", + "integrity": "sha1-nuv16z0R7vAismT9LStrK7O4TMM=", + "requires": { + "utf8": "^2.1.0" + }, + "dependencies": { + "utf8": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.2.tgz", + "integrity": "sha1-H6DZJw6b6FDZsFAn9jUZv0ZFfZY=" + } + } + }, + "randombytes": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", + "integrity": "sha512-vYl3iOX+4CKUWuxGi9Ukhie6fsqXqS9FE2Zaic4tNFD2N2QQaXOMFbuKK4QmDHC0JO6B1Zp41J0LpT0oR68amQ==", + "dev": true, + "requires": { + "safe-buffer": "^5.1.0" + } + }, + "readdirp": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.5.0.tgz", + "integrity": "sha512-cMhu7c/8rdhkHXWsY+osBhfSy0JikwpHK/5+imo+LpeasTF8ouErHrlYkwT0++njiyuDvc7OFY5T3ukvZ8qmFQ==", + "dev": true, + "requires": { + "picomatch": "^2.2.1" + } + }, + "require-directory": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", + "integrity": "sha1-jGStX9MNqxyXbiNE/+f3kqam30I=", + "dev": true + }, + "safe-buffer": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz", + "integrity": "sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==", + "dev": true + }, + "serialize-javascript": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-5.0.1.tgz", + "integrity": "sha512-SaaNal9imEO737H2c05Og0/8LUXG7EnsZyMa8MzkmuHoELfT6txuj0cMqRj6zfPKnmQ1yasR4PCJc8x+M4JSPA==", + "dev": true, + "requires": { + "randombytes": "^2.1.0" + } + }, + "should": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/should/-/should-1.3.0.tgz", + "integrity": "sha1-ILcaCbXtFhRrkDAivTBu8zLv6HM=", + "dev": true + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-json-comments": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", + "integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==", + "dev": true + }, + "supports-color": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz", + "integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==", + "dev": true, + "requires": { + "has-flag": "^4.0.0" + } + }, + "to-regex-range": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz", + "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==", + "dev": true, + "requires": { + "is-number": "^7.0.0" + } + }, + "type-detect": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/type-detect/-/type-detect-0.1.1.tgz", + "integrity": "sha1-C6XsKohWQORw6k6FBZcZANrFiCI=", + "dev": true + }, + "underscore": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/underscore/-/underscore-1.13.1.tgz", + "integrity": "sha512-hzSoAVtJF+3ZtiFX0VgfFPHEDRm7Y/QPjGyNo4TVdnDTdft3tr8hEkD25a1jC+TjTuE7tkHGKkhwCgs9dgBB2g==", + "dev": true + }, + "utf8": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/utf8/-/utf8-3.0.0.tgz", + "integrity": "sha512-E8VjFIQ/TyQgp+TZfS6l8yp/xWppSAHzidGiRrqe4bK4XP9pTRyKFgGJpO3SN7zdX4DeomTrwaseCHovfpFcqQ==" + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wide-align": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/wide-align/-/wide-align-1.1.3.tgz", + "integrity": "sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA==", + "dev": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "workerpool": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/workerpool/-/workerpool-6.1.0.tgz", + "integrity": "sha512-toV7q9rWNYha963Pl/qyeZ6wG+3nnsyvolaNUS8+R5Wtw6qJPTxIlOP1ZSvcGhEJw+l3HMMmtiNo9Gl61G4GVg==", + "dev": true + }, + "wrap-ansi": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "y18n": { + "version": "5.0.8", + "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz", + "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==", + "dev": true + }, + "yargs": { + "version": "16.2.0", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-16.2.0.tgz", + "integrity": "sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==", + "dev": true, + "requires": { + "cliui": "^7.0.2", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.0", + "y18n": "^5.0.5", + "yargs-parser": "^20.2.2" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + } + } + }, + "yargs-parser": { + "version": "20.2.4", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-20.2.4.tgz", + "integrity": "sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==", + "dev": true + }, + "yargs-unparser": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/yargs-unparser/-/yargs-unparser-2.0.0.tgz", + "integrity": "sha512-7pRTIA9Qc1caZ0bZ6RYRGbHJthJWuakf+WmHK0rVeLkNrrGhfoabBNdue6kdINI6r4if7ocq9aD/n7xwKOdzOA==", + "dev": true, + "requires": { + "camelcase": "^6.0.0", + "decamelize": "^4.0.0", + "flat": "^5.0.2", + "is-plain-obj": "^2.1.0" + } + }, + "yocto-queue": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", + "integrity": "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==", + "dev": true + } + } +} diff --git a/package.json b/package.json index 254f83b..e875bad 100644 --- a/package.json +++ b/package.json @@ -3,10 +3,13 @@ "version": "0.2.18", "description": "Cozy-vcard provides vcard Parser and Objects", "main": "lib/index.js", + "files": [ + "lib" + ], "scripts": { - "test": "mocha test/index.coffee --reporter spec --compilers coffee:coffee-script/register --colors", + "test": "mocha test/index.coffee --reporter spec --require coffeescript/register --colors", "build": "coffee --compile --output lib/ src/", - "prepublish": "npm run build" + "prepare": "npm run build" }, "repository": { "type": "git", @@ -24,14 +27,14 @@ "license": "see LICENSE", "readmeFilename": "README.md", "dependencies": { - "quoted-printable": "0.2.1", - "utf8": "2.0.0" + "quoted-printable": "^1.0.1", + "utf8": "^3.0.0" }, "devDependencies": { - "chai": "1.7.2", - "coffee-script": "1.8.0", - "mocha": "1.12.0", - "should": "1.2.0", - "underscore": "1.8.2" + "chai": "^1.7.2", + "coffeescript": "^1.8.0", + "mocha": "^8.4.0", + "should": "^1.2.0", + "underscore": "^1.8.2" } } diff --git a/src/index.coffee b/src/index.coffee index 049a457..2890a3f 100644 --- a/src/index.coffee +++ b/src/index.coffee @@ -22,7 +22,7 @@ regexps = endNonVCard: /^END:(.*)$/i # vCard 2.1 files can use quoted-printable text. - simple: /^(version|fn|n|title|org|note|categories|bday|url|nickname|uid|tz|lang|geo|gender|kind)(;CHARSET=UTF-8)?(;ENCODING=QUOTED-PRINTABLE)?\:(.+)$/i + simple: /^(version|fn|n|title|org|note|categories|bday|url|nickname|uid|tz|lang|geo|gender|kind|photo)(;CHARSET=UTF-8)?(;ENCODING=QUOTED-PRINTABLE)?\:(.+)$/i composedkey: /^item(\d{1,2})\.([^\:]+):(.+)$/ complex: /^([^\:\;]+);([^\:]+)\:(.+)$/ property: /^(.+)=(.+)$/ @@ -58,7 +58,7 @@ ANDROID_RELATIONS = [ BASE_FIELDS = ['fn', 'bday', 'org', 'title', 'url', 'note', 'nickname', 'uid'] -EXTRA_FIELDS = ['tz', 'lang', 'geo', 'gender', 'kind'] +EXTRA_FIELDS = ['tz', 'lang', 'geo', 'gender', 'kind', 'photo'] SOCIAL_URLS = twitter: "http://twitter.com/" @@ -185,9 +185,6 @@ class VCardParser # same way. Some vCard have one or ther other, or both. # If both are present, we keep them. # If only one is present, we compute the other one. - if not @currentContact.n? and not @currentContact.fn? - console.error 'There should be at least a N field or a FN field' - if (not @currentContact.n?) or @currentContact.n in ['', ';;;;'] @currentContact.n = VCardParser.fnToN(@currentContact.fn).join ';' diff --git a/test/index.coffee b/test/index.coffee index 662234b..386889e 100644 --- a/test/index.coffee +++ b/test/index.coffee @@ -102,7 +102,9 @@ describe 'Contact instances tools', -> describe 'vCard Import', -> describe 'Vendor VCards - simple set', -> - parser = new VCardParser() + parser = null + beforeEach -> + parser = new VCardParser() it "Google", -> parser.read fs.readFileSync 'test/google.vcf', 'utf8' @@ -114,29 +116,41 @@ describe 'vCard Import', -> parser.read fs.readFileSync 'test/apple.vcf', 'utf8' properties = ['datapoints', 'n', 'fn', 'org', 'title', 'note', 'bday'] properties.forEach (property) -> - parser.contacts[1].should.have.property property + parser.contacts[0].should.have.property property + + it "iOS", -> + parser.read fs.readFileSync 'test/ios-imported-contact.vcf', 'utf8' + properties = ['datapoints', 'n', 'fn', 'photo', 'tags'] + properties.forEach (property) -> + parser.contacts[0].should.have.property property it "Android", -> parser.read fs.readFileSync 'test/android.vcf', 'utf8' properties = ['datapoints', 'n', 'fn', 'org', 'title', 'note'] properties.forEach (property) -> - parser.contacts[2].should.have.property property + parser.contacts[0].should.have.property property it "Android with quoted-printable text", -> filePath = 'test/android-quotedprintable.vcf' parser.read fs.readFileSync filePath, 'utf8' properties = ['datapoints', 'n', 'fn', 'org', 'title', 'note'] properties.forEach (property) -> - parser.contacts[3].should.have.property property + parser.contacts[0].should.have.property property it "Cozycloud", -> parser.read fs.readFileSync 'test/cozy.vcf', 'utf8' properties = ['datapoints', 'n', 'fn', 'photo'] properties.forEach (property) -> - parser.contacts[4].should.have.property property - parser.contacts[4].datapoints.length is 3 + parser.contacts[0].should.have.property property + parser.contacts[0].datapoints.length is 3 it "Export and import", -> + parser.read fs.readFileSync 'test/google.vcf', 'utf8' + parser.read fs.readFileSync 'test/apple.vcf', 'utf8' + parser.read fs.readFileSync 'test/android.vcf', 'utf8' + parser.read fs.readFileSync 'test/ios-imported-contact.vcf', 'utf8' + parser.read fs.readFileSync 'test/cozy.vcf', 'utf8' + reparser = new VCardParser() reparser.read VCardParser.toVCF parser.contacts[0], null, false reparser.read VCardParser.toVCF parser.contacts[1], null, false diff --git a/test/ios-imported-contact.vcf b/test/ios-imported-contact.vcf new file mode 100644 index 0000000..ec31bf5 --- /dev/null +++ b/test/ios-imported-contact.vcf @@ -0,0 +1,9 @@ +BEGIN:VCARD +VERSION:3.0 +FN:Antonio Gumilio +N:Gumilio;Antonio;;; +TEL;TYPE=CELL:+38099999999 +PHOTO:https://lh5.googleusercontent.com/-nYUP0csP_co/YLUBlXvW7hI/AAAAAAAAAA + A/VIDmFXwusD8Pne2hsVv3ksGqKE2c5H6DgCOQCEAE/photo.jpg +CATEGORIES:myContacts +END:VCARD