UNPKG

17.7 kBJavaScriptView Raw
1"use strict";
2
3Object.defineProperty(exports, "__esModule", {
4 value: true
5});
6exports.mdnSupported = mdnSupported;
7exports.getUnsupportedTargets = getUnsupportedTargets;
8exports.default = void 0;
9
10var _astMetadataInferer = _interopRequireDefault(require("ast-metadata-inferer"));
11
12var _semver = _interopRequireDefault(require("semver"));
13
14function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
15
16function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; }
17
18function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
19
20const mdnRecords = new Map(_astMetadataInferer.default.map(e => [e.protoChainId, e]));
21/**
22 * Map ids of mdn targets to their "common/friendly" name
23 */
24
25const targetNameMappings = {
26 chrome: 'Chrome',
27 firefox: 'Firefox',
28 opera: 'Opera',
29 safari: 'Safari',
30 ie: 'IE',
31 edge: 'Edge',
32 safari_ios: 'iOS Safari',
33 opera_android: 'Opera Mobile',
34 chrome_android: 'Android Chrome',
35 edge_mobile: 'Edge Mobile',
36 firefox_android: 'Android Firefox',
37 webview_android: 'WebView Android',
38 samsunginternet_android: 'Samsung Browser',
39 nodes: 'Node.js'
40};
41/**
42 * Take a target's id and return it's full name by using `targetNameMappings`
43 * ex. {target: and_ff, version: 40} => 'Android FireFox 40'
44 */
45
46function formatTargetNames(target) {
47 return `${targetNameMappings[target.target]} ${target.version}`;
48}
49/**
50 * Convert '9' => '9.0.0'
51 */
52
53
54function customCoerce(version) {
55 return version.length === 1 ? [version, 0, 0].join('.') : version;
56}
57/*
58 * Return if MDN supports the API or not
59 */
60
61
62function mdnSupported(node, {
63 version,
64 target
65}) {
66 // If no record could be found, return false. Rules might not
67 // be found because they could belong to another provider
68 if (!mdnRecords.has(node.protoChainId)) return true;
69 const record = mdnRecords.get(node.protoChainId);
70 if (!record || !record.compat.support) return true;
71 const compatRecord = record.compat.support[target];
72 if (!compatRecord) return true;
73 if (!Array.isArray(compatRecord) && !('version_added' in compatRecord)) return true;
74 const {
75 version_added: versionAdded
76 } = Array.isArray(compatRecord) ? compatRecord.find(e => 'version_added' in e) : compatRecord; // If a version is true then it is supported but version is unsure
77
78 if (typeof versionAdded === 'boolean') return versionAdded;
79 if (versionAdded === null) return true; // A browser supports an API if its version is greater than or equal
80 // to the first version of the browser that API was added in
81
82 return _semver.default.gte(_semver.default.coerce(customCoerce(version)), _semver.default.coerce(customCoerce(versionAdded)));
83}
84/**
85 * Return an array of all unsupported targets
86 */
87
88
89function getUnsupportedTargets(node, targets) {
90 return targets.filter(target => !mdnSupported(node, target)).map(formatTargetNames);
91}
92/**
93 * Check if the node has matching object or properties
94 */
95
96
97function isValid(node, eslintNode, targets) {
98 switch (eslintNode.type) {
99 case 'CallExpression':
100 case 'NewExpression':
101 if (!eslintNode.callee) return true;
102 if (eslintNode.callee.name !== node.object) return true;
103 break;
104
105 case 'MemberExpression':
106 // Pass tests if non-matching object or property
107 if (!eslintNode.object || !eslintNode.property) return true;
108 if (eslintNode.object.name !== node.object) return true; // If the property is missing from the rule, it means that only the
109 // object is required to determine compatibility
110
111 if (!node.property) break;
112 if (eslintNode.property.name !== node.property) return true;
113 break;
114
115 default:
116 return true;
117 }
118
119 return !getUnsupportedTargets(node, targets).length;
120}
121
122function getMetadataName(metadata) {
123 switch (metadata.protoChain.length) {
124 case 1:
125 {
126 return metadata.protoChain[0];
127 }
128
129 default:
130 return `${metadata.protoChain.join('.')}()`;
131 }
132}
133
134const MdnProvider = _astMetadataInferer.default // Create entries for each ast node type
135.map(metadata => metadata.astNodeTypes.map(astNodeType => _objectSpread({}, metadata, {
136 name: getMetadataName(metadata),
137 id: metadata.protoChainId,
138 protoChainId: metadata.protoChainId,
139 astNodeType,
140 object: metadata.protoChain[0],
141 // @TODO Handle cases where 'prototype' is in protoChain
142 property: metadata.protoChain[1]
143}))) // Flatten the array of arrays
144.reduce((p, c) => [...p, ...c]) // Add rule and target support logic for each entry
145.map(rule => _objectSpread({}, rule, {
146 isValid,
147 getUnsupportedTargets
148}));
149
150var _default = MdnProvider;
151exports.default = _default;
152//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9wcm92aWRlcnMvTWRuUHJvdmlkZXIuanMiXSwibmFtZXMiOlsibWRuUmVjb3JkcyIsIk1hcCIsIkFzdE1ldGFkYXRhIiwibWFwIiwiZSIsInByb3RvQ2hhaW5JZCIsInRhcmdldE5hbWVNYXBwaW5ncyIsImNocm9tZSIsImZpcmVmb3giLCJvcGVyYSIsInNhZmFyaSIsImllIiwiZWRnZSIsInNhZmFyaV9pb3MiLCJvcGVyYV9hbmRyb2lkIiwiY2hyb21lX2FuZHJvaWQiLCJlZGdlX21vYmlsZSIsImZpcmVmb3hfYW5kcm9pZCIsIndlYnZpZXdfYW5kcm9pZCIsInNhbXN1bmdpbnRlcm5ldF9hbmRyb2lkIiwibm9kZXMiLCJmb3JtYXRUYXJnZXROYW1lcyIsInRhcmdldCIsInZlcnNpb24iLCJjdXN0b21Db2VyY2UiLCJsZW5ndGgiLCJqb2luIiwibWRuU3VwcG9ydGVkIiwibm9kZSIsImhhcyIsInJlY29yZCIsImdldCIsImNvbXBhdCIsInN1cHBvcnQiLCJjb21wYXRSZWNvcmQiLCJBcnJheSIsImlzQXJyYXkiLCJ2ZXJzaW9uX2FkZGVkIiwidmVyc2lvbkFkZGVkIiwiZmluZCIsInNlbXZlciIsImd0ZSIsImNvZXJjZSIsImdldFVuc3VwcG9ydGVkVGFyZ2V0cyIsInRhcmdldHMiLCJmaWx0ZXIiLCJpc1ZhbGlkIiwiZXNsaW50Tm9kZSIsInR5cGUiLCJjYWxsZWUiLCJuYW1lIiwib2JqZWN0IiwicHJvcGVydHkiLCJnZXRNZXRhZGF0YU5hbWUiLCJtZXRhZGF0YSIsInByb3RvQ2hhaW4iLCJNZG5Qcm92aWRlciIsImFzdE5vZGVUeXBlcyIsImFzdE5vZGVUeXBlIiwiaWQiLCJyZWR1Y2UiLCJwIiwiYyIsInJ1bGUiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQUFBOztBQUNBOzs7Ozs7OztBQXFCQSxNQUFNQSxVQUE4QyxHQUFHLElBQUlDLEdBQUosQ0FDckRDLDRCQUFZQyxHQUFaLENBQWdCQyxDQUFDLElBQUksQ0FBQ0EsQ0FBQyxD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LFFBQVEsQ0FBQ0MsVUFBVCxDQUFvQixDQUFwQixDQUFQO0FBQ0Q7O0FBQ0Q7QUFDRSxhQUFRLEdBQUVELFFBQVEsQ0FBQ0MsVUFBVCxDQUFvQjdCLElBQXBCLENBQXlCLEdBQXpCLENBQThCLElBQXhDO0FBTEo7QUFPRDs7QUFFRCxNQUFNOEIsV0FBd0IsR0FBR3RELDRCQUMvQjtBQUQrQixDQUU5QkMsR0FGOEIsQ0FFMUJtRCxRQUFRLElBQ1hBLFFBQVEsQ0FBQ0csWUFBVCxDQUFzQnRELEdBQXRCLENBQTBCdUQsV0FBVyxzQkFDaENKLFFBRGdDO0FBRW5DSixFQUFBQSxJQUFJLEVBQUVHLGVBQWUsQ0FBQ0MsUUFBRCxDQUZjO0FBR25DSyxFQUFBQSxFQUFFLEVBQUVMLFFBQVEsQ0FBQ2pELFlBSHNCO0FBSW5DQSxFQUFBQSxZQUFZLEVBQUVpRCxRQUFRLENBQUNqRCxZQUpZO0FBS25DcUQsRUFBQUEsV0FMbUM7QUFNbkNQLEVBQUFBLE1BQU0sRUFBRUcsUUFBUSxDQUFDQyxVQUFULENBQW9CLENBQXBCLENBTjJCO0FBT25DO0FBQ0FILEVBQUFBLFFBQVEsRUFBRUUsUUFBUSxDQUFDQyxVQUFULENBQW9CLENBQXBCO0FBUnlCLEVBQXJDLENBSDZCLEVBYy9CO0FBZCtCLENBZTlCSyxNQWY4QixDQWV2QixDQUFDQyxDQUFELEVBQUlDLENBQUosS0FBVSxDQUFDLEdBQUdELENBQUosRUFBTyxHQUFHQyxDQUFWLENBZmEsRUFnQi9CO0FBaEIrQixDQWlCOUIzRCxHQWpCOEIsQ0FpQjFCNEQsSUFBSSxzQkFDSkEsSUFESTtBQUVQakIsRUFBQUEsT0FGTztBQUdQSCxFQUFBQTtBQUhPLEVBakJzQixDQUFqQzs7ZUF1QmVhLFciLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgQXN0TWV0YWRhdGEgZnJvbSAnYXN0LW1ldGFkYXRhLWluZmVyZXInO1xuaW1wb3J0IHNlbXZlciBmcm9tICdzZW12ZXInO1xuaW1wb3J0IHR5cGUgeyBOb2RlLCBFU0xpbnROb2RlLCBUYXJnZXRzLCBUYXJnZXQgfSBmcm9tICcuLi9MaW50VHlwZXMnO1xuXG50eXBlIEFzdE1ldGFkYXRhUmVjb3JkVHlwZSA9IHtcbiAgYXBpVHlwZTogJ2pzLWFwaScgfCAnY3NzLWFwaScsXG4gIHR5cGU6ICdqcy1hcGknIHwgJ2Nzcy1hcGknLFxuICBwcm90b0NoYWluOiBBcnJheTxzdHJpbmc+LFxuICBwcm90b0NoYWluSWQ6IHN0cmluZyxcbiAgYXN0Tm9kZVR5cGVzOiBBcnJheTxzdHJpbmc+LFxuICBpc1N0YXRpYzogYm9vbGVhbixcbiAgY29tcGF0OiB7XG4gICAgc3VwcG9ydDoge1xuICAgICAgW2Jyb3dzZXJOYW1lOiBzdHJpbmddOiB7XG4gICAgICAgIC8vIElmIGEgdmVyc2lvbiBpcyB0cnVlIHRoZW4gaXQgaXMgc3VwcG9ydGVkIGJ1dCB2ZXJzaW9uIGlzIHVuc3VyZVxuICAgICAgICB2ZXJzaW9uX2FkZGVkOiBzdHJpbmcgfCBib29sZWFuXG4gICAgICB9XG4gICAgfSxcbiAgICBbeDogc3RyaW5nXTogYW55XG4gIH1cbn07XG5cbmNvbnN0IG1kblJlY29yZHM6IE1hcDxzdHJpbmcsIEFzdE1ldGFkYXRhUmVjb3JkVHlwZT4gPSBuZXcgTWFwKFxuICBBc3RNZXRhZGF0YS5tYXAoZSA9PiBbZS5wcm90b0NoYWluSWQsIGVdKVxuKTtcblxuLyoqXG4gKiBNYXAgaWRzIG9mIG1kbiB0YXJnZXRzIHRvIHRoZWlyIFwiY29tbW9uL2ZyaWVuZGx5XCIgbmFtZVxuICovXG5jb25zdCB0YXJnZXROYW1lTWFwcGluZ3MgPSB7XG4gIGNocm9tZTogJ0Nocm9tZScsXG4gIGZpcmVmb3g6ICdGaXJlZm94JyxcbiAgb3BlcmE6ICdPcGVyYScsXG4gIHNhZmFyaTogJ1NhZmFyaScsXG4gIGllOiAnSUUnLFxuICBlZGdlOiAnRWRnZScsXG4gIHNhZmFyaV9pb3M6ICdpT1MgU2FmYXJpJyxcbiAgb3BlcmFfYW5kcm9pZDogJ09wZXJhIE1vYmlsZScsXG4gIGNocm9tZV9hbmRyb2lkOiAnQW5kcm9pZCBDaHJvbWUnLFxuICBlZGdlX21vYmlsZTogJ0VkZ2UgTW9iaWxlJyxcbiAgZmlyZWZveF9hbmRyb2lkOiAnQW5kcm9pZCBGaXJlZm94JyxcbiAgd2Vidmlld19hbmRyb2lkOiAnV2ViVmlldyBBbmRyb2lkJyxcbiAgc2Ftc3VuZ2ludGVybmV0X2FuZHJvaWQ6ICdTYW1zdW5nIEJyb3dzZXInLFxuICBub2RlczogJ05vZGUuanMnXG59O1xuXG4vKipcbiAqIFRha2UgYSB0YXJnZXQncyBpZCBhbmQgcmV0dXJuIGl0J3MgZnVsbCBuYW1lIGJ5IHVzaW5nIGB0YXJnZXROYW1lTWFwcGluZ3NgXG4gKiBleC4ge3RhcmdldDogYW5kX2ZmLCB2ZXJzaW9uOiA0MH0gPT4gJ0FuZHJvaWQgRmlyZUZveCA0MCdcbiAqL1xuZnVuY3Rpb24gZm9ybWF0VGFyZ2V0TmFtZXModGFyZ2V0OiBUYXJnZXQpOiBzdHJpbmcge1xuICByZXR1cm4gYCR7dGFyZ2V0TmFtZU1hcHBpbmdzW3RhcmdldC50YXJnZXRdfSAke3RhcmdldC52ZXJzaW9ufWA7XG59XG5cbi8qKlxuICogQ29udmVydCAnOScgPT4gJzkuMC4wJ1xuICovXG5mdW5jdGlvbiBjdXN0b21Db2VyY2UodmVyc2lvbjogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHZlcnNpb24ubGVuZ3RoID09PSAxID8gW3ZlcnNpb24sIDAsIDBdLmpvaW4oJy4nKSA6IHZlcnNpb247XG59XG5cbi8qXG4gKiBSZXR1cm4gaWYgTUROIHN1cHBvcnRzIHRoZSBBUEkgb3Igbm90XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZG5TdXBwb3J0ZWQobm9kZTogTm9kZSwgeyB2ZXJzaW9uLCB0YXJnZXQgfTogVGFyZ2V0KTogYm9vbGVhbiB7XG4gIC8vIElmIG5vIHJlY29yZCBjb3VsZCBiZSBmb3VuZCwgcmV0dXJuIGZhbHNlLiBSdWxlcyBtaWdodCBub3RcbiAgLy8gYmUgZm91bmQgYmVjYXVzZSB0aGV5IGNvdWxkIGJlbG9uZyB0byBhbm90aGVyIHByb3ZpZGVyXG4gIGlmICghbWRuUmVjb3Jkcy5oYXMobm9kZS5wcm90b0NoYWluSWQpKSByZXR1cm4gdHJ1ZTtcbiAgY29uc3QgcmVjb3JkID0gbWRuUmVjb3Jkcy5nZXQobm9kZS5wcm90b0NoYWluSWQpO1xuICBpZiAoIXJlY29yZCB8fCAhcmVjb3JkLmNvbXBhdC5zdXBwb3J0KSByZXR1cm4gdHJ1ZTtcbiAgY29uc3QgY29tcGF0UmVjb3JkID0gcmVjb3JkLmNvbXBhdC5zdXBwb3J0W3RhcmdldF07XG4gIGlmICghY29tcGF0UmVjb3JkKSByZXR1cm4gdHJ1ZTtcbiAgaWYgKCFBcnJheS5pc0FycmF5KGNvbXBhdFJlY29yZCkgJiYgISgndmVyc2lvbl9hZGRlZCcgaW4gY29tcGF0UmVjb3JkKSlcbiAgICByZXR1cm4gdHJ1ZTtcbiAgY29uc3QgeyB2ZXJzaW9uX2FkZGVkOiB2ZXJzaW9uQWRkZWQgfSA9IEFycmF5LmlzQXJyYXkoY29tcGF0UmVjb3JkKVxuICAgID8gY29tcGF0UmVjb3JkLmZpbmQoZSA9PiAndmVyc2lvbl9hZGRlZCcgaW4gZSlcbiAgICA6IGNvbXBhdFJlY29yZDtcblxuICAvLyBJZiBhIHZlcnNpb24gaXMgdHJ1ZSB0aGVuIGl0IGlzIHN1cHBvcnRlZCBidXQgdmVyc2lvbiBpcyB1bnN1cmVcbiAgaWYgKHR5cGVvZiB2ZXJzaW9uQWRkZWQgPT09ICdib29sZWFuJykgcmV0dXJuIHZlcnNpb25BZGRlZDtcbiAgaWYgKHZlcnNpb25BZGRlZCA9PT0gbnVsbCkgcmV0dXJuIHRydWU7XG4gIC8vIEEgYnJvd3NlciBzdXBwb3J0cyBhbiBBUEkgaWYgaXRzIHZlcnNpb24gaXMgZ3JlYXRlciB0aGFuIG9yIGVxdWFsXG4gIC8vIHRvIHRoZSBmaXJzdCB2ZXJzaW9uIG9mIHRoZSBicm93c2VyIHRoYXQgQVBJIHdhcyBhZGRlZCBpblxuICByZXR1cm4gc2VtdmVyLmd0ZShcbiAgICBzZW12ZXIuY29lcmNlKGN1c3RvbUNvZXJjZSh2ZXJzaW9uKSksXG4gICAgc2VtdmVyLmNvZXJjZShjdXN0b21Db2VyY2UodmVyc2lvbkFkZGVkKSlcbiAgKTtcbn1cblxuLyoqXG4gKiBSZXR1cm4gYW4gYXJyYXkgb2YgYWxsIHVuc3VwcG9ydGVkIHRhcmdldHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFVuc3VwcG9ydGVkVGFyZ2V0cyhcbiAgbm9kZTogTm9kZSxcbiAgdGFyZ2V0czogVGFyZ2V0c1xuKTogQXJyYXk8c3RyaW5nPiB7XG4gIHJldHVybiB0YXJnZXRzXG4gICAgLmZpbHRlcih0YXJnZXQgPT4gIW1kblN1cHBvcnRlZChub2RlLCB0YXJnZXQpKVxuICAgIC5tYXAoZm9ybWF0VGFyZ2V0TmFtZXMpO1xufVxuXG4vKipcbiAqIENoZWNrIGlmIHRoZSBub2RlIGhhcyBtYXRjaGluZyBvYmplY3Qgb3IgcHJvcGVydGllc1xuICovXG5mdW5jdGlvbiBpc1ZhbGlkKFxuICBub2RlOiBOb2RlLFxuICBlc2xpbnROb2RlOiBFU0xpbnROb2RlLFxuICB0YXJnZXRzOiBUYXJnZXRzXG4pOiBib29sZWFuIHtcbiAgc3dpdGNoIChlc2xpbnROb2RlLnR5cGUpIHtcbiAgICBjYXNlICdDYWxsRXhwcmVzc2lvbic6XG4gICAgY2FzZSAnTmV3RXhwcmVzc2lvbic6XG4gICAgICBpZiAoIWVzbGludE5vZGUuY2FsbGVlKSByZXR1cm4gdHJ1ZTtcbiAgICAgIGlmIChlc2xpbnROb2RlLmNhbGxlZS5uYW1lICE9PSBub2RlLm9iamVjdCkgcmV0dXJuIHRydWU7XG4gICAgICBicmVhaztcbiAgICBjYXNlICdNZW1iZXJFeHByZXNzaW9uJzpcbiAgICAgIC8vIFBhc3MgdGVzdHMgaWYgbm9uLW1hdGNoaW5nIG9iamVjdCBvciBwcm9wZXJ0eVxuICAgICAgaWYgKCFlc2xpbnROb2RlLm9iamVjdCB8fCAhZXNsaW50Tm9kZS5wcm9wZXJ0eSkgcmV0dXJuIHRydWU7XG4gICAgICBpZiAoZXNsaW50Tm9kZS5vYmplY3QubmFtZSAhPT0gbm9kZS5vYmplY3QpIHJldHVybiB0cnVlO1xuXG4gICAgICAvLyBJZiB0aGUgcHJvcGVydHkgaXMgbWlzc2luZyBmcm9tIHRoZSBydWxlLCBpdCBtZWFucyB0aGF0IG9ubHkgdGhlXG4gICAgICAvLyBvYmplY3QgaXMgcmVxdWlyZWQgdG8gZGV0ZXJtaW5lIGNvbXBhdGliaWxpdHlcbiAgICAgIGlmICghbm9kZS5wcm9wZXJ0eSkgYnJlYWs7XG5cbiAgICAgIGlmIChlc2xpbnROb2RlLnByb3BlcnR5Lm5hbWUgIT09IG5vZGUucHJvcGVydHkpIHJldHVybiB0cnVlO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuICFnZXRVbnN1cHBvcnRlZFRhcmdldHMobm9kZSwgdGFyZ2V0cykubGVuZ3RoO1xufVxuXG5mdW5jdGlvbiBnZXRNZXRhZGF0YU5hbWUobWV0YWRhdGE6IE5vZGUpIHtcbiAgc3dpdGNoIChtZXRhZGF0YS5wcm90b0NoYWluLmxlbmd0aCkge1xuICAgIGNhc2UgMToge1xuICAgICAgcmV0dXJuIG1ldGFkYXRhLnByb3RvQ2hhaW5bMF07XG4gICAgfVxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gYCR7bWV0YWRhdGEucHJvdG9DaGFpbi5qb2luKCcuJyl9KClgO1xuICB9XG59XG5cbmNvbnN0IE1kblByb3ZpZGVyOiBBcnJheTxOb2RlPiA9IEFzdE1ldGFkYXRhXG4gIC8vIENyZWF0ZSBlbnRyaWVzIGZvciBlYWNoIGFzdCBub2RlIHR5cGVcbiAgLm1hcChtZXRhZGF0YSA9PlxuICAgIG1ldGFkYXRhLmFzdE5vZGVUeXBlcy5tYXAoYXN0Tm9kZVR5cGUgPT4gKHtcbiAgICAgIC4uLm1ldGFkYXRhLFxuICAgICAgbmFtZTogZ2V0TWV0YWRhdGFOYW1lKG1ldGFkYXRhKSxcbiAgICAgIGlkOiBtZXRhZGF0YS5wcm90b0NoYWluSWQsXG4gICAgICBwcm90b0NoYWluSWQ6IG1ldGFkYXRhLnByb3RvQ2hhaW5JZCxcbiAgICAgIGFzdE5vZGVUeXBlLFxuICAgICAgb2JqZWN0OiBtZXRhZGF0YS5wcm90b0NoYWluWzBdLFxuICAgICAgLy8gQFRPRE8gSGFuZGxlIGNhc2VzIHdoZXJlICdwcm90b3R5cGUnIGlzIGluIHByb3RvQ2hhaW5cbiAgICAgIHByb3BlcnR5OiBtZXRhZGF0YS5wcm90b0NoYWluWzFdXG4gICAgfSkpXG4gIClcbiAgLy8gRmxhdHRlbiB0aGUgYXJyYXkgb2YgYXJyYXlzXG4gIC5yZWR1Y2UoKHAsIGMpID0+IFsuLi5wLCAuLi5jXSlcbiAgLy8gQWRkIHJ1bGUgYW5kIHRhcmdldCBzdXBwb3J0IGxvZ2ljIGZvciBlYWNoIGVudHJ5XG4gIC5tYXAocnVsZSA9PiAoe1xuICAgIC4uLnJ1bGUsXG4gICAgaXNWYWxpZCxcbiAgICBnZXRVbnN1cHBvcnRlZFRhcmdldHNcbiAgfSkpO1xuXG5leHBvcnQgZGVmYXVsdCBNZG5Qcm92aWRlcjtcbiJdfQ==
\No newline at end of file