UNPKG

canonical

Version:

Canonical code style linter and formatter for JavaScript, SCSS, CSS and JSON.

282 lines (224 loc) 20.6 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _stringify = require('babel-runtime/core-js/json/stringify'); var _stringify2 = _interopRequireDefault(_stringify); var _set = require('babel-runtime/core-js/set'); var _set2 = _interopRequireDefault(_set); var _classCallCheck2 = require('babel-runtime/helpers/classCallCheck'); var _classCallCheck3 = _interopRequireDefault(_classCallCheck2); var _createClass2 = require('babel-runtime/helpers/createClass'); var _createClass3 = _interopRequireDefault(_createClass2); var _map = require('babel-runtime/core-js/map'); var _map2 = _interopRequireDefault(_map); exports.recursivePatternCapture = recursivePatternCapture; var _fs = require('fs'); var fs = _interopRequireWildcard(_fs); var _crypto = require('crypto'); var _parse2 = require('./parse'); var _parse3 = _interopRequireDefault(_parse2); var _resolve = require('./resolve'); var _resolve2 = _interopRequireDefault(_resolve); var _ignore = require('./ignore'); var _ignore2 = _interopRequireDefault(_ignore); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj.default = obj; return newObj; } } function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } // map from settings sha1 => path => export map objects var exportCaches = new _map2.default(); var ExportMap = function () { function ExportMap(context) { (0, _classCallCheck3.default)(this, ExportMap); this.context = context; this.named = new _set2.default(); this.errors = []; } (0, _createClass3.default)(ExportMap, [{ key: 'resolveReExport', value: function resolveReExport(node, base) { var remotePath = _resolve2.default.relative(node.source.value, base, this.settings); if (remotePath == null) return null; return ExportMap.for(remotePath, this.context); } }, { key: 'captureDefault', value: function captureDefault(n) { if (n.type !== 'ExportDefaultDeclaration') return; this.named.add('default'); } /** * capture all named exports from remote module. * * returns null if this node wasn't an ExportAllDeclaration * returns false if it was not resolved * returns true if it was resolved + parsed * * @param {node} n * @param {string} path - the path of the module currently parsing * @return {boolean?} */ }, { key: 'captureAll', value: function captureAll(n, path) { if (n.type !== 'ExportAllDeclaration') return null; var remoteMap = this.resolveReExport(n, path); if (remoteMap == null) return false; remoteMap.named.forEach(function (name) { this.named.add(name); }.bind(this)); return true; } }, { key: 'captureNamedDeclaration', value: function captureNamedDeclaration(n, path) { var _this = this; if (n.type !== 'ExportNamedDeclaration') return; // capture declaration if (n.declaration != null) { switch (n.declaration.type) { case 'FunctionDeclaration': case 'ClassDeclaration': case 'TypeAlias': // flowtype with babel-eslint parser this.named.add(n.declaration.id.name); break; case 'VariableDeclaration': n.declaration.declarations.forEach(function (d) { return recursivePatternCapture(d.id, function (id) { return _this.named.add(id.name); }); }); break; } } // capture specifiers var remoteMap = undefined; if (n.source) remoteMap = this.resolveReExport(n, path); n.specifiers.forEach(function (s) { if (s.type === 'ExportDefaultSpecifier') { // don't add it if it is not present in the exported module if (!remoteMap || !remoteMap.hasDefault) return; } this.named.add(s.exported.name); }.bind(this)); } }, { key: 'reportErrors', value: function reportErrors(context, declaration) { context.report({ node: declaration.source, message: 'Parse errors in imported module \'' + declaration.source.value + '\': ' + ('' + this.errors.map(function (e) { return e.message + ' (' + e.lineNumber + ':' + e.column + ')'; }).join(', ')) }); } }, { key: 'settings', get: function get() { return this.context && this.context.settings; } }, { key: 'hasDefault', get: function get() { return this.named.has('default'); } }, { key: 'hasNamed', get: function get() { return this.named.size > (this.hasDefault ? 1 : 0); } }], [{ key: 'get', value: function get(source, context) { var path = (0, _resolve2.default)(source, context); if (path == null) return null; return ExportMap.for(path, context); } }, { key: 'for', value: function _for(path, context) { var exportMap = undefined; var cacheKey = hashObject({ settings: context.settings, parserPath: context.parserPath, parserOptions: context.parserOptions }); var exportCache = exportCaches.get(cacheKey); if (exportCache === undefined) { exportCache = new _map2.default(); exportCaches.set(cacheKey, exportCache); } exportMap = exportCache.get(path); // return cached ignore if (exportMap === null) return null; var stats = fs.statSync(path); if (exportMap != null) { // date equality check if (exportMap.mtime - stats.mtime === 0) { return exportMap; } // future: check content equality? } exportMap = ExportMap.parse(path, context); exportMap.mtime = stats.mtime; // ignore empties, optionally if (exportMap.named.size === 0 && (0, _ignore2.default)(path, context)) { exportMap = null; } exportCache.set(path, exportMap); return exportMap; } }, { key: 'parse', value: function parse(path, context) { var m = new ExportMap(context); try { var ast = (0, _parse3.default)(path, context); } catch (err) { m.errors.push(err); return m; // can't continue } ast.body.forEach(function (n) { m.captureDefault(n); m.captureAll(n, path); m.captureNamedDeclaration(n, path); }); return m; } }]); return ExportMap; }(); /** * Traverse a patter/identifier node, calling 'callback' * for each leaf identifier. * @param {node} pattern * @param {Function} callback * @return {void} */ exports.default = ExportMap; function recursivePatternCapture(pattern, callback) { switch (pattern.type) { case 'Identifier': // base case callback(pattern); break; case 'ObjectPattern': pattern.properties.forEach(function (_ref) { var value = _ref.value; recursivePatternCapture(value, callback); }); break; case 'ArrayPattern': pattern.elements.forEach(function (element) { if (element == null) return; recursivePatternCapture(element, callback); }); break; } } function hashObject(object) { var settingsShasum = (0, _crypto.createHash)('sha1'); settingsShasum.update((0, _stringify2.default)(object)); return settingsShasum.digest('hex'); } //# sourceMappingURL=data:application/json;base64,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QkFBRixDQUEwQixDQUExQixFQUE2QixJQUE3QixFQUg0QjtPQUFiLENBQWpCLENBVjBCOztBQWdCMUIsYUFBTyxDQUFQLENBaEIwQjs7O1NBN0RUOzs7Ozs7Ozs7Ozs7O0FBcUtkLFNBQVMsdUJBQVQsQ0FBaUMsT0FBakMsRUFBMEMsUUFBMUMsRUFBb0Q7QUFDekQsVUFBUSxRQUFRLElBQVI7QUFDTixTQUFLLFlBQUw7O0FBQ0UsZUFBUyxPQUFULEVBREY7QUFFRSxZQUZGOztBQURGLFNBS08sZUFBTDtBQUNFLGNBQVEsVUFBUixDQUFtQixPQUFuQixDQUEyQixnQkFBZTtZQUFaLG1CQUFZOztBQUN4QyxnQ0FBd0IsS0FBeEIsRUFBK0IsUUFBL0IsRUFEd0M7T0FBZixDQUEzQixDQURGO0FBSUUsWUFKRjs7QUFMRixTQVdPLGNBQUw7QUFDRSxjQUFRLFFBQVIsQ0FBaUIsT0FBakIsQ0FBeUIsVUFBQyxPQUFELEVBQWE7QUFDcEMsWUFBSSxXQUFXLElBQVgsRUFBaUIsT0FBckI7QUFDQSxnQ0FBd0IsT0FBeEIsRUFBaUMsUUFBakMsRUFGb0M7T0FBYixDQUF6QixDQURGO0FBS0UsWUFMRjtBQVhGLEdBRHlEO0NBQXBEOztBQXFCUCxTQUFTLFVBQVQsQ0FBb0IsTUFBcEIsRUFBNEI7QUFDMUIsTUFBTSxpQkFBaUIsd0JBQVcsTUFBWCxDQUFqQixDQURvQjtBQUUxQixpQkFBZSxNQUFmLENBQXNCLHlCQUFlLE1BQWYsQ0FBdEIsRUFGMEI7QUFHMUIsU0FBTyxlQUFlLE1BQWYsQ0FBc0IsS0FBdEIsQ0FBUCxDQUgwQjtDQUE1QiIsImZpbGUiOiJjb3JlL2dldEV4cG9ydHMuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBmcyBmcm9tICdmcydcblxuaW1wb3J0IHsgY3JlYXRlSGFzaCB9IGZyb20gJ2NyeXB0bydcblxuaW1wb3J0IHBhcnNlIGZyb20gJy4vcGFyc2UnXG5pbXBvcnQgcmVzb2x2ZSBmcm9tICcuL3Jlc29sdmUnXG5pbXBvcnQgaXNJZ25vcmVkIGZyb20gJy4vaWdub3JlJ1xuXG4vLyBtYXAgZnJvbSBzZXR0aW5ncyBzaGExID0+IHBhdGggPT4gZXhwb3J0IG1hcCBvYmplY3RzXG5jb25zdCBleHBvcnRDYWNoZXMgPSBuZXcgTWFwKClcblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgRXhwb3J0TWFwIHtcbiAgY29uc3RydWN0b3IoY29udGV4dCkge1xuICAgIHRoaXMuY29udGV4dCA9IGNvbnRleHRcbiAgICB0aGlzLm5hbWVkID0gbmV3IFNldCgpXG5cbiAgICB0aGlzLmVycm9ycyA9IFtdXG4gIH1cblxuICBnZXQgc2V0dGluZ3MoKSB7IHJldHVybiB0aGlzLmNvbnRleHQgJiYgdGhpcy5jb250ZXh0LnNldHRpbmdzIH1cblxuICBnZXQgaGFzRGVmYXVsdCgpIHsgcmV0dXJuIHRoaXMubmFtZWQuaGFzKCdkZWZhdWx0JykgfVxuICBnZXQgaGFzTmFtZWQoKSB7IHJldHVybiB0aGlzLm5hbWVkLnNpemUgPiAodGhpcy5oYXNEZWZhdWx0ID8gMSA6IDApIH1cblxuICBzdGF0aWMgZ2V0KHNvdXJjZSwgY29udGV4dCkge1xuXG4gICAgdmFyIHBhdGggPSByZXNvbHZlKHNvdXJjZSwgY29udGV4dClcbiAgICBpZiAocGF0aCA9PSBudWxsKSByZXR1cm4gbnVsbFxuXG4gICAgcmV0dXJuIEV4cG9ydE1hcC5mb3IocGF0aCwgY29udGV4dClcbiAgfVxuXG4gIHN0YXRpYyBmb3IocGF0aCwgY29udGV4dCkge1xuICAgIGxldCBleHBvcnRNYXBcblxuICAgIGNvbnN0IGNhY2hlS2V5ID0gaGFzaE9iamVjdCh7XG4gICAgICBzZXR0aW5nczogY29udGV4dC5zZXR0aW5ncyxcbiAgICAgIHBhcnNlclBhdGg6IGNvbnRleHQucGFyc2VyUGF0aCxcbiAgICAgIHBhcnNlck9wdGlvbnM6IGNvbnRleHQucGFyc2VyT3B0aW9ucyxcbiAgICB9KVxuICAgIGxldCBleHBvcnRDYWNoZSA9IGV4cG9ydENhY2hlcy5nZXQoY2FjaGVLZXkpXG4gICAgaWYgKGV4cG9ydENhY2hlID09PSB1bmRlZmluZWQpIHtcbiAgICAgIGV4cG9ydENhY2hlID0gbmV3IE1hcCgpXG4gICAgICBleHBvcnRDYWNoZXMuc2V0KGNhY2hlS2V5LCBleHBvcnRDYWNoZSlcbiAgICB9XG5cbiAgICBleHBvcnRNYXAgPSBleHBvcnRDYWNoZS5nZXQocGF0aClcbiAgICAvLyByZXR1cm4gY2FjaGVkIGlnbm9yZVxuICAgIGlmIChleHBvcnRNYXAgPT09IG51bGwpIHJldHVybiBudWxsXG5cbiAgICBjb25zdCBzdGF0cyA9IGZzLnN0YXRTeW5jKHBhdGgpXG4gICAgaWYgKGV4cG9ydE1hcCAhPSBudWxsKSB7XG4gICAgICAvLyBkYXRlIGVxdWFsaXR5IGNoZWNrXG4gICAgICBpZiAoZXhwb3J0TWFwLm10aW1lIC0gc3RhdHMubXRpbWUgPT09IDApIHtcbiAgICAgICAgcmV0dXJuIGV4cG9ydE1hcFxuICAgICAgfVxuICAgICAgLy8gZnV0dXJlOiBjaGVjayBjb250ZW50IGVxdWFsaXR5P1xuICAgIH1cblxuICAgIGV4cG9ydE1hcCA9IEV4cG9ydE1hcC5wYXJzZShwYXRoLCBjb250ZXh0KVxuICAgIGV4cG9ydE1hcC5tdGltZSA9IHN0YXRzLm10aW1lXG5cbiAgICAvLyBpZ25vcmUgZW1wdGllcywgb3B0aW9uYWxseVxuICAgIGlmIChleHBvcnRNYXAubmFtZWQuc2l6ZSA9PT0gMCAmJiBpc0lnbm9yZWQocGF0aCwgY29udGV4dCkpIHtcbiAgICAgIGV4cG9ydE1hcCA9IG51bGxcbiAgICB9XG5cbiAgICBleHBvcnRDYWNoZS5zZXQocGF0aCwgZXhwb3J0TWFwKVxuXG4gICAgcmV0dXJuIGV4cG9ydE1hcFxuICB9XG5cbiAgc3RhdGljIHBhcnNlKHBhdGgsIGNvbnRleHQpIHtcbiAgICB2YXIgbSA9IG5ldyBFeHBvcnRNYXAoY29udGV4dClcblxuICAgIHRyeSB7XG4gICAgICB2YXIgYXN0ID0gcGFyc2UocGF0aCwgY29udGV4dClcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIG0uZXJyb3JzLnB1c2goZXJyKVxuICAgICAgcmV0dXJuIG0gLy8gY2FuJ3QgY29udGludWVcbiAgICB9XG5cbiAgICBhc3QuYm9keS5mb3JFYWNoKGZ1bmN0aW9uIChuKSB7XG4gICAgICBtLmNhcHR1cmVEZWZhdWx0KG4pXG4gICAgICBtLmNhcHR1cmVBbGwobiwgcGF0aClcbiAgICAgIG0uY2FwdHVyZU5hbWVkRGVjbGFyYXRpb24obiwgcGF0aClcbiAgICB9KVxuXG4gICAgcmV0dXJuIG1cbiAgfVxuXG4gIHJlc29sdmVSZUV4cG9ydChub2RlLCBiYXNlKSB7XG4gICAgdmFyIHJlbW90ZVBhdGggPSByZXNvbHZlLnJlbGF0aXZlKG5vZGUuc291cmNlLnZhbHVlLCBiYXNlLCB0aGlzLnNldHRpbmdzKVxuICAgIGlmIChyZW1vdGVQYXRoID09IG51bGwpIHJldHVybiBudWxsXG5cbiAgICByZXR1cm4gRXhwb3J0TWFwLmZvcihyZW1vdGVQYXRoLCB0aGlzLmNvbnRleHQpXG4gIH1cblxuICBjYXB0dXJlRGVmYXVsdChuKSB7XG4gICAgaWYgKG4udHlwZSAhPT0gJ0V4cG9ydERlZmF1bHREZWNsYXJhdGlvbicpIHJldHVyblxuICAgIHRoaXMubmFtZWQuYWRkKCdkZWZhdWx0JylcbiAgfVxuXG4gIC8qKlxuICAgKiBjYXB0dXJlIGFsbCBuYW1lZCBleHBvcnRzIGZyb20gcmVtb3RlIG1vZHVsZS5cbiAgICpcbiAgICogcmV0dXJucyBudWxsIGlmIHRoaXMgbm9kZSB3YXNuJ3QgYW4gRXhwb3J0QWxsRGVjbGFyYXRpb25cbiAgICogcmV0dXJucyBmYWxzZSBpZiBpdCB3YXMgbm90IHJlc29sdmVkXG4gICAqIHJldHVybnMgdHJ1ZSBpZiBpdCB3YXMgcmVzb2x2ZWQgKyBwYXJzZWRcbiAgICpcbiAgICogQHBhcmFtICB7bm9kZX0gblxuICAgKiBAcGFyYW0gIHtzdHJpbmd9IHBhdGggLSB0aGUgcGF0aCBvZiB0aGUgbW9kdWxlIGN1cnJlbnRseSBwYXJzaW5nXG4gICAqIEByZXR1cm4ge2Jvb2xlYW4/fVxuICAgKi9cbiAgY2FwdHVyZUFsbChuLCBwYXRoKSB7XG4gICAgaWYgKG4udHlwZSAhPT0gJ0V4cG9ydEFsbERlY2xhcmF0aW9uJykgcmV0dXJuIG51bGxcblxuICAgIHZhciByZW1vdGVNYXAgPSB0aGlzLnJlc29sdmVSZUV4cG9ydChuLCBwYXRoKVxuICAgIGlmIChyZW1vdGVNYXAgPT0gbnVsbCkgcmV0dXJuIGZhbHNlXG5cbiAgICByZW1vdGVNYXAubmFtZWQuZm9yRWFjaChmdW5jdGlvbiAobmFtZSkgeyB0aGlzLm5hbWVkLmFkZChuYW1lKSB9LmJpbmQodGhpcykpXG5cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgY2FwdHVyZU5hbWVkRGVjbGFyYXRpb24obiwgcGF0aCkge1xuICAgIGlmIChuLnR5cGUgIT09ICdFeHBvcnROYW1lZERlY2xhcmF0aW9uJykgcmV0dXJuXG5cbiAgICAvLyBjYXB0dXJlIGRlY2xhcmF0aW9uXG4gICAgaWYgKG4uZGVjbGFyYXRpb24gIT0gbnVsbCkge1xuICAgICAgc3dpdGNoIChuLmRlY2xhcmF0aW9uLnR5cGUpIHtcbiAgICAgICAgY2FzZSAnRnVuY3Rpb25EZWNsYXJhdGlvbic6XG4gICAgICAgIGNhc2UgJ0NsYXNzRGVjbGFyYXRpb24nOlxuICAgICAgICBjYXNlICdUeXBlQWxpYXMnOiAvLyBmbG93dHlwZSB3aXRoIGJhYmVsLWVzbGludCBwYXJzZXJcbiAgICAgICAgICB0aGlzLm5hbWVkLmFkZChuLmRlY2xhcmF0aW9uLmlkLm5hbWUpXG4gICAgICAgICAgYnJlYWtcbiAgICAgICAgY2FzZSAnVmFyaWFibGVEZWNsYXJhdGlvbic6XG4gICAgICAgICAgbi5kZWNsYXJhdGlvbi5kZWNsYXJhdGlvbnMuZm9yRWFjaCgoZCkgPT5cbiAgICAgICAgICAgIHJlY3Vyc2l2ZVBhdHRlcm5DYXB0dXJlKGQuaWQsIGlkID0+IHRoaXMubmFtZWQuYWRkKGlkLm5hbWUpKSlcbiAgICAgICAgICBicmVha1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIGNhcHR1cmUgc3BlY2lmaWVyc1xuICAgIGxldCByZW1vdGVNYXBcbiAgICBpZiAobi5zb3VyY2UpIHJlbW90ZU1hcCA9IHRoaXMucmVzb2x2ZVJlRXhwb3J0KG4sIHBhdGgpXG5cbiAgICBuLnNwZWNpZmllcnMuZm9yRWFjaChmdW5jdGlvbiAocykge1xuICAgICAgaWYgKHMudHlwZSA9PT0gJ0V4cG9ydERlZmF1bHRTcGVjaWZpZXInKSB7XG4gICAgICAgIC8vIGRvbid0IGFkZCBpdCBpZiBpdCBpcyBub3QgcHJlc2VudCBpbiB0aGUgZXhwb3J0ZWQgbW9kdWxlXG4gICAgICAgIGlmICghcmVtb3RlTWFwIHx8ICFyZW1vdGVNYXAuaGFzRGVmYXVsdCkgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIHRoaXMubmFtZWQuYWRkKHMuZXhwb3J0ZWQubmFtZSlcbiAgICB9LmJpbmQodGhpcykpXG4gIH1cblxuICByZXBvcnRFcnJvcnMoY29udGV4dCwgZGVjbGFyYXRpb24pIHtcbiAgICBjb250ZXh0LnJlcG9ydCh7XG4gICAgICBub2RlOiBkZWNsYXJhdGlvbi5zb3VyY2UsXG4gICAgICBtZXNzYWdlOiBgUGFyc2UgZXJyb3JzIGluIGltcG9ydGVkIG1vZHVsZSAnJHtkZWNsYXJhdGlvbi5zb3VyY2UudmFsdWV9JzogYCArXG4gICAgICAgICAgICAgICAgICBgJHt0aGlzLmVycm9yc1xuICAgICAgICAgICAgICAgICAgICAgICAgLm1hcChlID0+IGAke2UubWVzc2FnZX0gKCR7ZS5saW5lTnVtYmVyfToke2UuY29sdW1ufSlgKVxuICAgICAgICAgICAgICAgICAgICAgICAgLmpvaW4oJywgJyl9YCxcbiAgICB9KVxuICB9XG59XG5cblxuLyoqXG4gKiBUcmF2ZXJzZSBhIHBhdHRlci9pZGVudGlmaWVyIG5vZGUsIGNhbGxpbmcgJ2NhbGxiYWNrJ1xuICogZm9yIGVhY2ggbGVhZiBpZGVudGlmaWVyLlxuICogQHBhcmFtICB7bm9kZX0gICBwYXR0ZXJuXG4gKiBAcGFyYW0gIHtGdW5jdGlvbn0gY2FsbGJhY2tcbiAqIEByZXR1cm4ge3ZvaWR9XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZWN1cnNpdmVQYXR0ZXJuQ2FwdHVyZShwYXR0ZXJuLCBjYWxsYmFjaykge1xuICBzd2l0Y2ggKHBhdHRlcm4udHlwZSkge1xuICAgIGNhc2UgJ0lkZW50aWZpZXInOiAvLyBiYXNlIGNhc2VcbiAgICAgIGNhbGxiYWNrKHBhdHRlcm4pXG4gICAgICBicmVha1xuXG4gICAgY2FzZSAnT2JqZWN0UGF0dGVybic6XG4gICAgICBwYXR0ZXJuLnByb3BlcnRpZXMuZm9yRWFjaCgoeyB2YWx1ZSB9KSA9PiB7XG4gICAgICAgIHJlY3Vyc2l2ZVBhdHRlcm5DYXB0dXJlKHZhbHVlLCBjYWxsYmFjaylcbiAgICAgIH0pXG4gICAgICBicmVha1xuXG4gICAgY2FzZSAnQXJyYXlQYXR0ZXJuJzpcbiAgICAgIHBhdHRlcm4uZWxlbWVudHMuZm9yRWFjaCgoZWxlbWVudCkgPT4ge1xuICAgICAgICBpZiAoZWxlbWVudCA9PSBudWxsKSByZXR1cm5cbiAgICAgICAgcmVjdXJzaXZlUGF0dGVybkNhcHR1cmUoZWxlbWVudCwgY2FsbGJhY2spXG4gICAgICB9KVxuICAgICAgYnJlYWtcbiAgfVxufVxuXG5mdW5jdGlvbiBoYXNoT2JqZWN0KG9iamVjdCkge1xuICBjb25zdCBzZXR0aW5nc1NoYXN1bSA9IGNyZWF0ZUhhc2goJ3NoYTEnKVxuICBzZXR0aW5nc1NoYXN1bS51cGRhdGUoSlNPTi5zdHJpbmdpZnkob2JqZWN0KSlcbiAgcmV0dXJuIHNldHRpbmdzU2hhc3VtLmRpZ2VzdCgnaGV4Jylcbn1cbiJdfQ==