{"version":3,"sources":["jsdelivr-header.js","/npm/nodebb-plugin-import-smf@0.2.5/index.js"],"names":[],"mappings":"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","file":"/npm/nodebb-plugin-import-smf@0.2.5/index.js","sourceRoot":"","sourcesContent":["/**\n * Minified by jsDelivr using Terser v5.37.0.\n * Original file: /npm/nodebb-plugin-import-smf@0.2.5/index.js\n *\n * Do NOT use SRI with dynamically generated files! More information: https://www.jsdelivr.com/using-sri-with-dynamic-files\n */\n","\nvar async = require('async');\nvar extend = require('extend');\nvar mysql = require('mysql');\nvar _ = require('underscore');\nvar fs = require('fs-extra');\nvar path = require('path');\nvar sanitize = require(\"sanitize-filename\");\nvar noop = function(){};\nvar logPrefix = '[nodebb-plugin-import-smf]';\n\nvar MIGRATED_FOLDER = 'migrated';\nvar ATTACHMENTS_ORIGINALS_DIR = path.join(__dirname, '/tmp/attachments/originals');\nvar ATTACHMENTS_MIGRATED_DIR = path.join(__dirname, '/tmp/attachments/' + MIGRATED_FOLDER);\n\n(function(Exporter) {\n\n\tExporter.setup = function(config, callback) {\n\t\tExporter.log('setup');\n\n\t\t// mysql db only config\n\t\t// extract them from the configs passed by the nodebb-plugin-import adapter\n\t\tvar _config = {\n\t\t\thost: config.dbhost || config.host || 'localhost',\n\t\t\tuser: config.dbuser || config.user || 'root',\n\t\t\tpassword: config.dbpass || config.pass || config.password || '',\n\t\t\tport: config.dbport || config.port || 3306,\n\t\t\tdatabase: config.dbname || config.name || config.database || 'smf'\n\t\t};\n\n\t\tExporter.log(_config);\n\n\t\tExporter.config(_config);\n\t\tExporter.config('prefix', config.prefix || config.tablePrefix || '');\n\n\t\tconfig.custom = config.custom || {};\n\t\tif (typeof config.custom === 'string') {\n\t\t\ttry {\n\t\t\t\tconfig.custom = JSON.parse(config.custom)\n\t\t\t} catch (e) {}\n\t\t}\n\n\t\tconfig.custom = config.custom || {};\n\t\tconfig.custom.timemachine = config.custom.timemachine || {};\n\t\tconfig.custom = extend(true, {}, {\n\t\t\t/* TODO: ADD TIMEMACHINE SUPPORT */\n\t\t}, config.custom);\n\n\t\tExporter.config('custom', config.custom);\n\n\t\tExporter.connection = mysql.createConnection(_config);\n\t\tExporter.connection.connect();\n\n\t\tsetInterval(function() {\n\t\t\tExporter.connection.query(\"SELECT 1\", function(){});\n\t\t}, 60000);\n\n\t\tfs.ensureDirSync(ATTACHMENTS_ORIGINALS_DIR);\n\t\tfs.ensureDirSync(ATTACHMENTS_MIGRATED_DIR);\n\n\t\tcallback(null, Exporter.config());\n\t};\n\n\tExporter.getGroups = function(callback) {\n\t\treturn Exporter.getPaginatedGroups(0, -1, callback)\n\t};\n\n\tExporter.getPaginatedGroups = function(start, limit, callback) {\n\t\tExporter.log('getPaginatedGroups');\n\t\tcallback = !_.isFunction(callback) ? noop : callback;\n\n\t\tvar err;\n\t\tvar prefix = Exporter.config('prefix');\n\t\tvar query = 'SELECT '\n\t\t\t+ '\\n' +  prefix + 'membergroups.id_group as _gid, '\n\t\t\t+ '\\n' +  prefix + 'membergroups.group_name as _name, '\n\t\t\t+ '\\n' +  prefix + 'membergroups.description as _description, '\n\t\t\t+ '\\n' +  prefix + 'membergroups.hidden as _hidden '\n\t\t\t+ '\\n' +  'FROM ' + prefix + 'membergroups '\n\t\t\t+ '\\n' + (start >= 0 && limit >= 0 ? ' LIMIT ' + start + ',' + limit : '');\n\n\n\t\tif (!Exporter.connection) {\n\t\t\terr = {error: 'MySQL connection is not setup. Run setup(config) first'};\n\t\t\tExporter.error(err.error);\n\t\t\treturn callback(err);\n\t\t}\n\n\t\tExporter.connection.query(query,\n\t\t\tfunction(err, rows) {\n\t\t\t\tif (err) {\n\t\t\t\t\tExporter.error(err);\n\t\t\t\t\treturn callback(err);\n\t\t\t\t}\n\t\t\t\t//normalize here\n\t\t\t\tvar map = {};\n\t\t\t\trows.forEach(function(row) {\n\t\t\t\t\tmap[row._gid] = row;\n\t\t\t\t});\n\t\t\t\tcallback(null, map);\n\t\t\t});\n\t};\n\n\tExporter.getUsers = function(callback) {\n\t\tExporter.getPaginatedUsers(0, -1, callback);\n\t};\n\n\tExporter.getPaginatedUsers = function(start, limit, callback) {\n\t\tExporter.log('getPaginatedUsers');\n\t\tcallback = !_.isFunction(callback) ? noop : callback;\n\n\t\tvar err;\n\t\tvar prefix = Exporter.config('prefix');\n\t\tvar query = 'SELECT '\n\t\t\t+ '\\n' + prefix + 'members.id_member as _uid, '\n\t\t\t+ '\\n' + prefix + 'members.member_name as _username, '\n\t\t\t+ '\\n' + prefix + 'members.email_address as _email, '\n\t\t\t+ '\\n' + prefix + 'members.real_name as _alternativeUsername, '\n\t\t\t+ '\\n' + prefix + 'members.signature as _signature, '\n\t\t\t+ '\\n' + '(' + prefix + 'members.last_login * 1000) as _lastonline, '\n\t\t\t+ '\\n' + '(' + prefix + 'members.date_registered * 1000) as _joindate , '\n\t\t\t+ '\\n' + prefix + 'members.location as _location, '\n\t\t\t+ '\\n' + prefix + 'members.birthdate as _birthday, '\n\t\t\t+ '\\n' + prefix + 'members.website_url as _website, '\n\t\t\t+ '\\n CONCAT(\"/assets/uploads/_imported_profiles/avatars/\", ' + prefix + 'attachments.filename) AS _picture, '\n\t\t\t+ '\\n CONCAT(' + prefix + 'members.id_group, \\',\\', ' + prefix + 'members.additional_groups) AS _groups, '\n\t\t\t+ '\\n' + prefix + 'membergroups.group_name as _level, '\n\t\t\t+ '\\n (' + prefix + 'ban_groups.cannot_access + ' + prefix + 'ban_groups.cannot_register + ' + prefix + 'ban_groups.cannot_post + ' + prefix + 'ban_groups.cannot_login) > 0 as _banned '\n\t\t\t+ '\\n' + 'FROM ' + prefix + 'members '\n\t\t\t+ '\\n' + 'LEFT JOIN ' + prefix + 'membergroups ON ' + prefix + 'membergroups.id_group = ' + prefix + 'members.id_group '\n\t\t\t+ '\\n' + 'LEFT JOIN ' + prefix + 'ban_groups ON ' + prefix + 'ban_groups.name = ' + prefix + 'members.member_name '\n\t\t\t+ '\\n' + 'LEFT JOIN ' + prefix + 'attachments ON ' + prefix + 'attachments.id_member = ' + prefix + 'members.id_member '\n\t\t\t+ '\\n' + 'WHERE ' + prefix + 'members.id_member = ' + prefix + 'members.id_member '\n\t\t\t+ '\\n' + 'ORDER BY ' + prefix + 'members.id_member '\n\t\t\t+ '\\n' + (start >= 0 && limit >= 0 ? ' LIMIT ' + start + ',' + limit : '');\n\n\t\tif (!Exporter.connection) {\n\t\t\terr = {error: 'MySQL connection is not setup. Run setup(config) first'};\n\t\t\tExporter.error(err.error);\n\t\t\treturn callback(err);\n\t\t}\n\t\tExporter.connection.query(query,\n\t\t\tfunction(err, rows) {\n\t\t\t\tif (err) {\n\t\t\t\t\tExporter.error(err);\n\t\t\t\t\treturn callback(err);\n\t\t\t\t}\n\n\t\t\t\t//normalize here\n\t\t\t\tvar map = {};\n\t\t\t\trows.forEach(function(row) {\n\t\t\t\t\tif (/moderator/i.test(row._level)) {\n\t\t\t\t\t\trow._level = 'moderator';\n\t\t\t\t\t} else if (! /administrator/i.test(row._level)) {\n\t\t\t\t\t\tdelete row._level;\n\t\t\t\t\t}\n\t\t\t\t\trow._groups = csvToArray(row._groups)\n\t\t\t\t\t\t.filter(function (_gid, i, arr) {\n\t\t\t\t\t\t\treturn _gid && parseInt(_gid, 10) > 0 && arr.indexOf(_gid) === i;\n\t\t\t\t\t\t});\n\t\t\t\t\tmap[row._uid] = row;\n\t\t\t\t});\n\n\t\t\t\t// keep a copy of the users in memory here\n\t\t\t\tExporter._users = map;\n\n\t\t\t\tcallback(null, map);\n\t\t\t});\n\t};\n\n\tExporter.getCategories = function(callback) {\n\t\treturn Exporter.getPaginatedCategories(0, -1, callback);\n\t};\n\n\tExporter.getPaginatedCategories = function(start, limit, callback) {\n\t\tExporter.log('getPaginatedCategories');\n\t\tcallback = !_.isFunction(callback) ? noop : callback;\n\n\t\tvar err;\n\t\tvar prefix = Exporter.config('prefix');\n\t\tvar query = 'SELECT '\n\t\t\t+ '\\n' +  prefix + 'boards.id_board as _cid, '\n\t\t\t+ '\\n' +  prefix + 'boards.id_parent as _parentCid, '\n\t\t\t+ '\\n' +  prefix + 'boards.name as _name, '\n\t\t\t+ '\\n' +  prefix + 'boards.description as _description, '\n\t\t\t+ '\\n' +  prefix + 'boards.board_order as _order '\n\t\t\t+ '\\n' +  'FROM ' + prefix + 'boards '\n\t\t\t+ '\\n' + (start >= 0 && limit >= 0 ? ' LIMIT ' + start + ',' + limit : '');\n\n\n\t\tif (!Exporter.connection) {\n\t\t\terr = {error: 'MySQL connection is not setup. Run setup(config) first'};\n\t\t\tExporter.error(err.error);\n\t\t\treturn callback(err);\n\t\t}\n\n\t\tExporter.connection.query(query,\n\t\t\tfunction(err, rows) {\n\t\t\t\tif (err) {\n\t\t\t\t\tExporter.error(err);\n\t\t\t\t\treturn callback(err);\n\t\t\t\t}\n\t\t\t\tvar map = {};\n\t\t\t\trows.forEach(function(row) {\n\t\t\t\t\trow._description = row._description || 'No decsciption available';\n\t\t\t\t\tmap[row._cid] = row;\n\t\t\t\t});\n\n\t\t\t\tcallback(null, map);\n\t\t\t});\n\t};\n\n\n\tExporter.getMessages = function(callback) {\n\t\treturn Exporter.getPaginatedMessages(0, -1, callback);\n\t};\n\n\tExporter.getPaginatedMessages = function(start, limit, callback) {\n\t\tExporter.log('getPaginatedMessages');\n\t\tcallback = !_.isFunction(callback) ? noop : callback;\n\n\t\tvar err;\n\t\tvar prefix = Exporter.config('prefix');\n\t\tvar query = 'SELECT '\n\t\t\t+ '\\n' +  prefix + 'personal_messages.id_pm as _mid, '\n\t\t\t+ '\\n' +  prefix + 'personal_messages.id_member_from as _fromuid, '\n\t\t\t+ '\\n' +  prefix + 'pm_recipients.id_member as _touid, '\n\t\t\t+ '\\n' +  prefix + 'personal_messages.body as _content, '\n\t\t\t+ '\\n (' +  prefix + 'personal_messages.msgtime * 1000) as _timestamp '\n\t\t\t+ '\\n' +  'FROM ' + prefix + 'personal_messages '\n\t\t\t+ '\\n' + 'JOIN ' + prefix + 'pm_recipients ON ' + prefix + 'pm_recipients.id_pm = ' + prefix + 'personal_messages.id_pm '\n\t\t\t+ '\\n' + (start >= 0 && limit >= 0 ? ' LIMIT ' + start + ',' + limit : '');\n\n\t\tif (!Exporter.connection) {\n\t\t\terr = {error: 'MySQL connection is not setup. Run setup(config) first'};\n\t\t\tExporter.error(err.error);\n\t\t\treturn callback(err);\n\t\t}\n\n\t\tExporter.connection.query(query,\n\t\t\tfunction(err, rows) {\n\t\t\t\tif (err) {\n\t\t\t\t\tExporter.error(err);\n\t\t\t\t\treturn callback(err);\n\t\t\t\t}\n\t\t\t\tvar map = {};\n\t\t\t\trows.forEach(function(row) {\n\t\t\t\t\tmap[row._mid] = row;\n\t\t\t\t});\n\n\t\t\t\tcallback(null, map);\n\t\t\t});\n\t};\n\n\n\t// this whole thing is crap\n\tvar copyAttachmentAndGetNewUrl = Exporter.copyDATAttachmentAndGetNewUrl = function (_aid, filename) {\n\n\t\tvar baseUrl = '/uploads/_imported_attachments';\n\t\tvar newFileUrlPath = '/' + MIGRATED_FOLDER + '/' + _aid + '_' + encodeURIComponent(filename);\n\n\t\tvar originalFile = path.join(ATTACHMENTS_ORIGINALS_DIR, '/' + _aid);\n\n\t\tvar newFilename = _aid + '_' + filename;\n\t\tvar newFileFullFSPath = path.join(ATTACHMENTS_MIGRATED_DIR, newFilename);\n\n\t\t// TODO: wtf is that? sync copy? meh\n\t\tif (!fs.existsSync(newFileFullFSPath) && fs.existsSync(originalFile)) {\n\t\t\tfs.copySync(originalFile, newFileFullFSPath);\n\t\t}\n\t\treturn baseUrl + newFileUrlPath;\n\t};\n\n\n\tvar getAttachmentsMap = function (callback) {\n\t\tcallback = !_.isFunction(callback) ? noop : callback;\n\t\tvar prefix = Exporter.config('prefix');\n\n\t\tif (Exporter['_attachmentsMap_']) {\n\t\t\treturn callback(null, Exporter['_attachmentsMap_']);\n\t\t}\n\t\tvar query = 'SELECT '\n\t\t\t+ '\\n' +  prefix + 'attachments.id_attach as _aid, '\n\t\t\t+ '\\n' +  prefix + 'attachments.id_msg as _pid, '\n\t\t\t+ '\\n' +  prefix + 'attachments.id_member as _uid, '\n\t\t\t+ '\\n' +  prefix + 'attachments.attachment_type as _type, '\n\t\t\t+ '\\n' +  prefix + 'attachments.filename as _filen, '\n\t\t\t+ '\\n' +  prefix + 'attachments.id_folder as _folderid, '\n\t\t\t+ '\\n' +  prefix + 'attachments.downloads as _downloads, '\n\t\t\t+ '\\n' +  prefix + 'attachments.width as _width, '\n\t\t\t+ '\\n' +  prefix + 'attachments.height as _height '\n\t\t\t+ '\\n' +  'FROM ' + prefix + 'attachments '\n\t\t\t+ '\\n' + 'WHERE (' + prefix + 'attachments.id_thumb > 0 OR ' + prefix + 'attachments.width = 0) '\n\t\t\t+ '\\n' +  'AND ' + prefix + 'attachments.id_member = 0 ' ;\n\n\t\tExporter.connection.query(query,\n\t\t\tfunction(err, rows) {\n\t\t\t\tif (err) {\n\t\t\t\t\tExporter.error(err);\n\t\t\t\t\treturn callback(err);\n\t\t\t\t}\n\t\t\t\tvar map = {};\n\t\t\t\trows.forEach(function(row) {\n\t\t\t\t\tmap[row._pid] = map[row._pid] || [];\n\t\t\t\t\trow._filen = sanitize(row._filen);\n\t\t\t\t\t// alias\n\t\t\t\t\trow._filenname = row._filen;\n\t\t\t\t\tmap[row._pid].push({\n\t\t\t\t\t\turl: copyAttachmentAndGetNewUrl(row._aid, row._filen),\n\t\t\t\t\t\tfilename: row._filen,\n\t\t\t\t\t\tisImage: !!row._width\n\t\t\t\t\t});\n\t\t\t\t});\n\t\t\t\tExporter['_attachmentsMap_'] = map;\n\t\t\t\tcallback(null, map);\n\t\t\t});\n\t};\n\n\tExporter.getTopics = function(callback) {\n\t\treturn Exporter.getPaginatedTopics(0, -1, callback);\n\t};\n\n\tExporter.getPaginatedTopics = function(start, limit, callback) {\n\t\tExporter.log('getPaginatedTopics');\n\t\tcallback = !_.isFunction(callback) ? noop : callback;\n\n\t\tvar err;\n\t\tvar prefix = Exporter.config('prefix');\n\t\tvar query = 'SELECT '\n\t\t\t+ '\\n' +  prefix + 'messages.id_topic as _tid, '\n\t\t\t+ '\\n' +  prefix + 'messages.id_msg as _pid, '\n\t\t\t+ '\\n' +  prefix + 'messages.id_board as _cid, '\n\t\t\t+ '\\n' +  prefix + 'messages.id_member as _uid, '\n\t\t\t+ '\\n' +  prefix + 'messages.subject as _title, '\n\t\t\t+ '\\n' +  prefix + 'messages.body as _content, '\n\t\t\t+ '\\n (' +  prefix + 'messages.poster_time * 1000) as _timestamp, '\n\t\t\t+ '\\n (' +  prefix + 'messages.modified_time * 1000) as _edited, '\n\t\t\t+ '\\n' +  prefix + 'topics.num_views as _viewcount, '\n\t\t\t+ '\\n' +  prefix + 'messages.poster_ip as _ip, '\n\t\t\t+ '\\n' +  prefix + 'messages.poster_email as _uemail, '\n\t\t\t+ '\\n' +  prefix + 'messages.poster_name as _guest, '\n\t\t\t+ '\\n' +  prefix + 'messages.approved as _approved, '\n\t\t\t+ '\\n' +  prefix + 'topics.locked as _locked, '\n\t\t\t+ '\\n' +  prefix + 'topics.is_sticky as _pinned '\n\t\t\t+ '\\n' +  'FROM ' + prefix + 'topics '\n\t\t\t+ '\\n' + 'JOIN ' + prefix + 'messages ON ' + prefix + 'messages.id_msg = ' + prefix + 'topics.id_first_msg '\n\t\t\t+ '\\n' + (start >= 0 && limit >= 0 ? ' LIMIT ' + start + ',' + limit : '');\n\n\n\t\tif (!Exporter.connection) {\n\t\t\terr = {error: 'MySQL connection is not setup. Run setup(config) first'};\n\t\t\tExporter.error(err.error);\n\t\t\treturn callback(err);\n\t\t}\n\n\t\tgetAttachmentsMap(function (err, attachmentsMap) {\n\t\t\tif (err) {\n\t\t\t\tExporter.error(err);\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tExporter.connection.query(query,\n\t\t\t\tfunction(err, rows) {\n\t\t\t\t\tvar map = {};\n\t\t\t\t\tif (err) {\n\t\t\t\t\t\tExporter.error(err);\n\t\t\t\t\t\treturn callback(err);\n\t\t\t\t\t}\n\t\t\t\t\trows.forEach(function(row) {\n\t\t\t\t\t\tvar attachments = attachmentsMap[row._pid] || [];\n\t\t\t\t\t\trow._images = attachments.filter(function (attachment) {\n\t\t\t\t\t\t\treturn attachment.isImage;\n\t\t\t\t\t\t});\n\t\t\t\t\t\trow._attachments = attachments.filter(function (attachment) {\n\t\t\t\t\t\t\treturn !attachment.isImage;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tmap[row._tid] = row;\n\t\t\t\t\t});\n\t\t\t\t\tcallback(null, map);\n\t\t\t\t});\n\t\t});\n\t};\n\n\tExporter.getPosts = function(callback) {\n\t\treturn Exporter.getPaginatedPosts(0, -1, callback)\n\t};\n\n\tExporter.getPaginatedPosts = function(start, limit, callback) {\n\t\tExporter.log('getPaginatedPosts');\n\t\tcallback = !_.isFunction(callback) ? noop : callback;\n\n\t\tvar err;\n\t\tvar prefix = Exporter.config('prefix');\n\t\tvar query = 'SELECT '\n\t\t\t+ prefix + 'messages.id_msg as _pid, '\n\t\t\t+ '\\n' +  prefix + 'messages.id_topic as _tid, '\n\t\t\t+ '\\n' +  prefix + 'messages.id_member as _uid, '\n\t\t\t+ '\\n' +  prefix + 'messages.body as _content, '\n\t\t\t+ '\\n (' +  prefix + 'messages.poster_time * 1000) as _timestamp, '\n\t\t\t+ '\\n (' +  prefix + 'messages.modified_time * 1000) as _edited, '\n\t\t\t+ '\\n' +  prefix + 'messages.poster_ip as _ip, '\n\t\t\t+ '\\n' +  prefix + 'messages.poster_name as _guest, '\n\t\t\t+ '\\n' +  prefix + 'messages.approved as _approved '\n\t\t\t+ '\\n FROM ' + prefix + 'messages '\n\t\t\t+ '\\n WHERE ' + prefix + 'messages.id_topic > 0 AND ' + prefix + 'messages.id_msg NOT IN (SELECT id_first_msg FROM ' + prefix + 'topics) '\n\t\t\t+ '\\n' + (start >= 0 && limit >= 0 ? ' LIMIT ' + start + ',' + limit : '');\n\n\t\tif (!Exporter.connection) {\n\t\t\terr = {error: 'MySQL connection is not setup. Run setup(config) first'};\n\t\t\tExporter.error(err.error);\n\t\t\treturn callback(err);\n\t\t}\n\n\t\tgetAttachmentsMap(function (err, attachmentsMap) {\n\t\t\tif (err) {\n\t\t\t\tExporter.error(err);\n\t\t\t\treturn callback(err);\n\t\t\t}\n\t\t\tExporter.connection.query(query,\n\t\t\t\tfunction(err, rows) {\n\t\t\t\t\tvar map = {};\n\t\t\t\t\tif (err) {\n\t\t\t\t\t\tExporter.error(err);\n\t\t\t\t\t\treturn callback(err);\n\t\t\t\t\t}\n\t\t\t\t\trows.forEach(function(row) {\n\n\t\t\t\t\t\tvar attachments = attachmentsMap[row._pid] || [];\n\t\t\t\t\t\trow._images = attachments.filter(function (attachment) {\n\t\t\t\t\t\t\treturn attachment.isImage;\n\t\t\t\t\t\t});\n\t\t\t\t\t\trow._attachments = attachments.filter(function (attachment) {\n\t\t\t\t\t\t\treturn !attachment.isImage;\n\t\t\t\t\t\t});\n\t\t\t\t\t\tmap[row._pid] = row;\n\t\t\t\t\t});\n\t\t\t\t\tcallback(null, map);\n\t\t\t\t});\n\t\t});\n\t};\n\n\tExporter.teardown = function(callback) {\n\t\tExporter.log('teardown');\n\t\tExporter.connection.end();\n\n\t\tExporter.log('Done');\n\t\tcallback();\n\t};\n\n\tExporter.testrun = function(config, callback) {\n\t\tasync.series([\n\t\t\tfunction(next) {\n\t\t\t\tExporter.setup(config, next);\n\t\t\t},\n\t\t\tfunction(next) {\n\t\t\t\tExporter.getGroups(next);\n\t\t\t},\n\t\t\tfunction(next) {\n\t\t\t\tExporter.getUsers(next);\n\t\t\t},\n\t\t\tfunction(next) {\n\t\t\t\tExporter.getMessages(next);\n\t\t\t},\n\t\t\tfunction(next) {\n\t\t\t\tExporter.getCategories(next);\n\t\t\t},\n\t\t\tfunction(next) {\n\t\t\t\tExporter.getTopics(next);\n\t\t\t},\n\t\t\tfunction(next) {\n\t\t\t\tExporter.getPosts(next);\n\t\t\t},\n\t\t\tfunction(next) {\n\t\t\t\tExporter.teardown(next);\n\t\t\t}\n\t\t], callback);\n\t};\n\n\tExporter.paginatedTestrun = function(config, callback) {\n\t\tasync.series([\n\t\t\tfunction(next) {\n\t\t\t\tExporter.setup(config, next);\n\t\t\t},\n\t\t\tfunction(next) {\n\t\t\t\tExporter.getPaginatedGroups(0, 1000, next);\n\t\t\t},\n\t\t\tfunction(next) {\n\t\t\t\tExporter.getPaginatedUsers(0, 1000, next);\n\t\t\t},\n\t\t\tfunction(next) {\n\t\t\t\tExporter.getPaginatedMessages(0, 1000, next);\n\t\t\t},\n\t\t\tfunction(next) {\n\t\t\t\tExporter.getPaginatedCategories(0, 1000, next);\n\t\t\t},\n\t\t\tfunction(next) {\n\t\t\t\tExporter.getPaginatedTopics(0, 1000, next);\n\t\t\t},\n\t\t\tfunction(next) {\n\t\t\t\tExporter.getPaginatedPosts(1001, 2000, next);\n\t\t\t},\n\t\t\tfunction(next) {\n\t\t\t\tExporter.teardown(next);\n\t\t\t}\n\t\t], callback);\n\t};\n\n\tExporter.warn = function() {\n\t\tvar args = _.toArray(arguments);\n\t\targs.unshift(logPrefix);\n\t\tconsole.warn.apply(console, args);\n\t};\n\n\tExporter.log = function() {\n\t\tvar args = _.toArray(arguments);\n\t\targs.unshift(logPrefix);\n\t\tconsole.log.apply(console, args);\n\t};\n\n\tExporter.error = function() {\n\t\tvar args = _.toArray(arguments);\n\t\targs.unshift(logPrefix);\n\t\tconsole.error.apply(console, args);\n\t};\n\n\tExporter.config = function(config, val) {\n\t\tif (config != null) {\n\t\t\tif (typeof config === 'object') {\n\t\t\t\tExporter._config = config;\n\t\t\t} else if (typeof config === 'string') {\n\t\t\t\tif (val != null) {\n\t\t\t\t\tExporter._config = Exporter._config || {};\n\t\t\t\t\tExporter._config[config] = val;\n\t\t\t\t}\n\t\t\t\treturn Exporter._config[config];\n\t\t\t}\n\t\t}\n\t\treturn Exporter._config;\n\t};\n\n\tvar csvToArray = function(v) {\n\t\treturn !Array.isArray(v) ? ('' + v).split(',').map(function(s) { return s.trim(); }) : v;\n\t};\n\n\t// from Angular https://github.com/angular/angular.js/blob/master/src/ng/directive/input.js#L11\n\tExporter.validateUrl = function(url) {\n\t\tvar pattern = /^(ftp|http|https):\\/\\/(\\w+:{0,1}\\w*@)?(\\S+)(:[0-9]+)?(\\/|\\/([\\w#!:.?+=&%@!\\-\\/]))?$/;\n\t\treturn url && url.length < 2083 && url.match(pattern) ? url : '';\n\t};\n\n\tExporter.truncateStr = function(str, len) {\n\t\tif (typeof str != 'string') return str;\n\t\tlen = _.isNumber(len) && len > 3 ? len : 20;\n\t\treturn str.length <= len ? str : str.substr(0, len - 3) + '...';\n\t};\n\n\tExporter.whichIsFalsy = function(arr) {\n\t\tfor (var i = 0; i < arr.length; i++) {\n\t\t\tif (!arr[i])\n\t\t\t\treturn i;\n\t\t}\n\t\treturn null;\n\t};\n\n})(module.exports);\n"]}