UNPKG

17.6 kBJavaScriptView Raw
1/**
2 * SVG captcha.
3 * DO NOT use svg base captcha in production, since it may be parsable by bots.
4 * You need to convert to bitmap like png beforehand.
5 * @class ApCaptchaSvg
6 */
7
8'use strict';
9
10Object.defineProperty(exports, "__esModule", {
11 value: true
12});
13
14var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
15
16var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
17
18var _react = require('react');
19
20var _react2 = _interopRequireDefault(_react);
21
22var _randomval = require('randomval');
23
24var _randomval2 = _interopRequireDefault(_randomval);
25
26function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
27
28function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
29
30function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
31
32function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
33
34/** @lends ApCaptchaSvg */
35var ApCaptchaSvg = function (_Component) {
36 _inherits(ApCaptchaSvg, _Component);
37
38 function ApCaptchaSvg() {
39 _classCallCheck(this, ApCaptchaSvg);
40
41 return _possibleConstructorReturn(this, Object.getPrototypeOf(ApCaptchaSvg).apply(this, arguments));
42 }
43
44 _createClass(ApCaptchaSvg, [{
45 key: 'render',
46 value: function render() {
47 var s = this;
48 var props = s.props;
49
50
51 var color = '#555';
52
53 var width = props.width;
54 var height = props.height;
55
56
57 var backgrounds = [0, 1, 2, 3].map(function (val, i, _ref) {
58 var length = _ref.length;
59
60 var margin = width * 0.2;
61 var rate = (i + 0.5) / length;
62 return s._stripeBlock(rate, color, {
63 key: 'bg-' + i,
64 width: parseInt(width / length + margin * 2),
65 height: parseInt(height + margin * 2),
66 x: parseInt(width * rate - margin),
67 y: parseInt(0 - margin)
68 });
69 });
70
71 var texts = props.text.split('').map(function (letter, i, letters) {
72 var indices = [0, 1, 2, 3, 4, 5];
73 var real = _randomval2.default.randomInt(0, indices.length - 1);
74 var texts = indices.map(function (j) {
75 var rate = i / letters.length;
76 var key = 'letter-' + i + '-' + j;
77 if (j === real) {
78 return s.renderLetter(letter, rate, {
79 key: key,
80 fill: color
81 });
82 } else {
83 return s.renderLetter(s._dummyLetter(), rate, {
84 key: key,
85 fill: 'rgba(255,255,255,' + 0.01 * _randomval2.default.randomInt(0, 30) + ')'
86 });
87 }
88 });
89 return _react2.default.createElement(
90 'g',
91 { key: 'letter-group-' + i },
92 texts
93 );
94 });
95 return _react2.default.createElement(
96 'svg',
97 { version: props.version,
98 width: width,
99 height: height,
100 xmlns: props.xmlns,
101 viewBox: '0 0 ' + width + ' ' + height
102 },
103 _react2.default.createElement(
104 'g',
105 null,
106 backgrounds
107 ),
108 _react2.default.createElement(
109 'g',
110 null,
111 texts
112 )
113 );
114 }
115
116 // --------------------
117 // Specs
118 // --------------------
119
120 }, {
121 key: 'renderLetter',
122 value: function renderLetter(letter, rate, textProps) {
123 var s = this;
124 var props = s.props;
125
126
127 var padding = 16;
128
129 var w = props.width - padding * 2;
130 var h = props.height;
131
132 var moveRange = h / 20;
133 var move = _randomval2.default.randomInt.bind(_randomval2.default, moveRange * -1, moveRange);
134
135 var fontSize = h * 0.8;
136 var x = padding + w * rate + fontSize / 4;
137 var y = fontSize;
138 var rotateRange = 40;
139 var rotate = _randomval2.default.randomInt(-rotateRange, rotateRange);
140
141 return _react2.default.createElement(
142 'text',
143 _extends({ x: parseInt(x),
144 y: parseInt(y),
145 fontSize: parseInt(fontSize),
146 transform: 'translate(' + move() + ', ' + move() + ') rotate(' + parseInt(rotate) + ', ' + parseInt(x) + ', ' + parseInt(y) + ')'
147 }, textProps),
148 letter
149 );
150 }
151 }, {
152 key: '_dummyLetter',
153 value: function _dummyLetter() {
154 var letters = '1234567890abcdefg';
155 var len = letters.length;
156 return letters[_randomval2.default.randomInt(0, len - 1)];
157 }
158 }, {
159 key: '_stripeBlock',
160 value: function _stripeBlock(rate, color, blockProps) {
161 var s = this;
162 var props = s.props;
163
164
165 var rotate = _randomval2.default.randomInt(-90, 90);
166
167 var lines = [];
168 var lineWidth = 1;
169 var w = blockProps.width;
170 var h = blockProps.height;
171
172 var left = w * -0.5;
173 var right = w * 1.5;
174
175 for (var x = left; x < right; x += lineWidth * 6) {
176 lines.push(_react2.default.createElement('line', { x1: parseInt(x),
177 y1: parseInt(0),
178 x2: parseInt(x),
179 y2: parseInt(h),
180 key: 'line-' + x,
181 stroke: color
182 }));
183 }
184
185 return _react2.default.createElement(
186 'svg',
187 blockProps,
188 _react2.default.createElement(
189 'g',
190 {
191 transform: 'scale(1.3) rotate(' + parseInt(rotate) + ', ' + parseInt(blockProps.width / 2) + ', ' + parseInt(blockProps.height / 2) + ')' },
192 lines
193 )
194 );
195 }
196 }]);
197
198 return ApCaptchaSvg;
199}(_react.Component);
200
201Object.assign(ApCaptchaSvg, {
202 // --------------------
203 // Specs
204 // --------------------
205
206 propsTypes: {
207 version: _react.PropTypes.string,
208 text: _react.PropTypes.string.isRequired,
209 width: _react.PropTypes.number,
210 height: _react.PropTypes.number
211 },
212
213 defaultProps: {
214 version: '1.1',
215 xmlns: 'http://www.w3.org/2000/svg',
216 text: '',
217 width: 256,
218 height: 92
219 }
220});
221
222exports.default = ApCaptchaSvg;
223//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImFwX2NhcHRjaGFfc3ZnLmpzeCJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7OztBQU9BOzs7Ozs7Ozs7O0FBRUE7Ozs7QUFDQTs7Ozs7Ozs7Ozs7O0FBRUE7SUFDTSxZOzs7Ozs7Ozs7Ozs2QkFDTTtBQUNSLFVBQU0sSUFBSSxJQUFWO0FBRFEsVUFFRixLQUZFLEdBRVEsQ0FGUixDQUVGLEtBRkU7OztBQUlSLFVBQUksUUFBUSxNQUFaOztBQUpRLFVBTUYsS0FORSxHQU1nQixLQU5oQixDQU1GLEtBTkU7QUFBQSxVQU1LLE1BTkwsR0FNZ0IsS0FOaEIsQ0FNSyxNQU5MOzs7QUFRUixVQUFJLGNBQWMsQ0FBRSxDQUFGLEVBQUssQ0FBTCxFQUFRLENBQVIsRUFBVyxDQUFYLEVBQWUsR0FBZixDQUFtQixVQUFDLEdBQUQsRUFBTSxDQUFOLFFBQXdCO0FBQUEsWUFBYixNQUFhLFFBQWIsTUFBYTs7QUFDM0QsWUFBSSxTQUFTLFFBQVEsR0FBckI7QUFDQSxZQUFJLE9BQU8sQ0FBQyxJQUFJLEdBQUwsSUFBWSxNQUF2QjtBQUNBLGVBQU8sRUFBRSxZQUFGLENBQWUsSUFBZixFQUFxQixLQUFyQixFQUE0QjtBQUNqQyx1QkFBVyxDQURzQjtBQUVqQyxpQkFBTyxTQUFTLFFBQVEsTUFBUixHQUFrQixTQUFTLENBQXBDLENBRjBCO0FBR2pDLGtCQUFRLFNBQVMsU0FBVSxTQUFTLENBQTVCLENBSHlCO0FBSWpDLGFBQUcsU0FBUyxRQUFRLElBQVIsR0FBZSxNQUF4QixDQUo4QjtBQUtqQyxhQUFHLFNBQVMsSUFBSSxNQUFiO0FBTDhCLFNBQTVCLENBQVA7QUFPRCxPQVZpQixDQUFsQjs7QUFZQSxVQUFJLFFBQVEsTUFBTSxJQUFOLENBQVcsS0FBWCxDQUFpQixFQUFqQixFQUFxQixHQUFyQixDQUF5QixVQUFDLE1BQUQsRUFBUyxDQUFULEVBQVksT0FBWixFQUF3QjtBQUMzRCxZQUFJLFVBQVUsQ0FBRSxDQUFGLEVBQUssQ0FBTCxFQUFRLENBQVIsRUFB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LEVBQVo7QUFDQSxVQUFJLFlBQVksQ0FBaEI7QUFDQSxVQUFJLElBQUksV0FBVyxLQUFuQjtBQUNBLFVBQUksSUFBSSxXQUFXLE1BQW5COztBQUVBLFVBQUksT0FBTyxJQUFJLENBQUMsR0FBaEI7QUFDQSxVQUFJLFFBQVEsSUFBSSxHQUFoQjs7QUFFQSxXQUFLLElBQUksSUFBSSxJQUFiLEVBQW1CLElBQUksS0FBdkIsRUFBOEIsS0FBSyxZQUFZLENBQS9DLEVBQWtEO0FBQ2hELGNBQU0sSUFBTixDQUNFLHdDQUFNLElBQUksU0FBUyxDQUFULENBQVY7QUFDTSxjQUFJLFNBQVMsQ0FBVCxDQURWO0FBRU0sY0FBSSxTQUFTLENBQVQsQ0FGVjtBQUdNLGNBQUksU0FBUyxDQUFULENBSFY7QUFJTSx5QkFBYSxDQUpuQjtBQUtNLGtCQUFRO0FBTGQsVUFERjtBQVNEOztBQUVELGFBQ0U7QUFBQTtBQUFVLGtCQUFWO0FBQ0U7QUFBQTtBQUFBO0FBQ0UsOENBQWdDLFNBQVMsTUFBVCxDQUFoQyxVQUFxRCxTQUFTLFdBQVcsS0FBWCxHQUFtQixDQUE1QixDQUFyRCxVQUF3RixTQUFTLFdBQVcsTUFBWCxHQUFvQixDQUE3QixDQUF4RixNQURGO0FBRUk7QUFGSjtBQURGLE9BREY7QUFRRDs7Ozs7O0FBRUgsT0FBTyxNQUFQLENBQWMsWUFBZCxFQUE0QjtBQUMxQjtBQUNBO0FBQ0E7O0FBRUEsY0FBWTtBQUNWLGFBQVMsaUJBQU0sTUFETDtBQUVWLFVBQU0saUJBQU0sTUFBTixDQUFhLFVBRlQ7QUFHVixXQUFPLGlCQUFNLE1BSEg7QUFJVixZQUFRLGlCQUFNO0FBSkosR0FMYzs7QUFZMUIsZ0JBQWM7QUFDWixhQUFTLEtBREc7QUFFWixXQUFPLDRCQUZLO0FBR1osVUFBTSxFQUhNO0FBSVosV0FBTyxHQUpLO0FBS1osWUFBUTtBQUxJO0FBWlksQ0FBNUI7O2tCQXFCZSxZIiwiZmlsZSI6ImFwX2NhcHRjaGFfc3ZnLmpzeCIsInNvdXJjZVJvb3QiOiJsaWIiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFNWRyBjYXB0Y2hhLlxuICogRE8gTk9UIHVzZSBzdmcgYmFzZSBjYXB0Y2hhIGluIHByb2R1Y3Rpb24sIHNpbmNlIGl0IG1heSBiZSBwYXJzYWJsZSBieSBib3RzLlxuICogWW91IG5lZWQgdG8gY29udmVydCB0byBiaXRtYXAgbGlrZSBwbmcgYmVmb3JlaGFuZC5cbiAqIEBjbGFzcyBBcENhcHRjaGFTdmdcbiAqL1xuXG4ndXNlIHN0cmljdCdcblxuaW1wb3J0IFJlYWN0LCB7Q29tcG9uZW50LCBQcm9wVHlwZXMgYXMgdHlwZXN9IGZyb20gJ3JlYWN0J1xuaW1wb3J0IHJhbmRvbXZhbCBmcm9tICdyYW5kb212YWwnXG5cbi8qKiBAbGVuZHMgQXBDYXB0Y2hhU3ZnICovXG5jbGFzcyBBcENhcHRjaGFTdmcgZXh0ZW5kcyBDb21wb25lbnQge1xuICByZW5kZXIgKCkge1xuICAgIGNvbnN0IHMgPSB0aGlzXG4gICAgbGV0IHsgcHJvcHMgfSA9IHNcblxuICAgIGxldCBjb2xvciA9ICcjNTU1J1xuXG4gICAgbGV0IHsgd2lkdGgsIGhlaWdodCB9ID0gcHJvcHNcblxuICAgIGxldCBiYWNrZ3JvdW5kcyA9IFsgMCwgMSwgMiwgMyBdLm1hcCgodmFsLCBpLCB7IGxlbmd0aCB9KSA9PiB7XG4gICAgICBsZXQgbWFyZ2luID0gd2lkdGggKiAwLjJcbiAgICAgIGxldCByYXRlID0gKGkgKyAwLjUpIC8gbGVuZ3RoXG4gICAgICByZXR1cm4gcy5fc3RyaXBlQmxvY2socmF0ZSwgY29sb3IsIHtcbiAgICAgICAga2V5OiBgYmctJHtpfWAsXG4gICAgICAgIHdpZHRoOiBwYXJzZUludCh3aWR0aCAvIGxlbmd0aCArIChtYXJnaW4gKiAyKSksXG4gICAgICAgIGhlaWdodDogcGFyc2VJbnQoaGVpZ2h0ICsgKG1hcmdpbiAqIDIpKSxcbiAgICAgICAgeDogcGFyc2VJbnQod2lkdGggKiByYXRlIC0gbWFyZ2luKSxcbiAgICAgICAgeTogcGFyc2VJbnQoMCAtIG1hcmdpbilcbiAgICAgIH0pXG4gICAgfSlcblxuICAgIGxldCB0ZXh0cyA9IHByb3BzLnRleHQuc3BsaXQoJycpLm1hcCgobGV0dGVyLCBpLCBsZXR0ZXJzKSA9PiB7XG4gICAgICBsZXQgaW5kaWNlcyA9IFsgMCwgMSwgMiwgMywgNCwgNSBdXG4gICAgICBsZXQgcmVhbCA9IHJhbmRvbXZhbC5yYW5kb21JbnQoMCwgaW5kaWNlcy5sZW5ndGggLSAxKVxuICAgICAgbGV0IHRleHRzID0gaW5kaWNlcy5tYXAoKGopID0+IHtcbiAgICAgICAgbGV0IHJhdGUgPSBpIC8gbGV0dGVycy5sZW5ndGhcbiAgICAgICAgbGV0IGtleSA9IGBsZXR0ZXItJHtpfS0ke2p9YFxuICAgICAgICBpZiAoaiA9PT0gcmVhbCkge1xuICAgICAgICAgIHJldHVybiBzLnJlbmRlckxldHRlcihsZXR0ZXIsIHJhdGUsIHtcbiAgICAgICAgICAgIGtleToga2V5LFxuICAgICAgICAgICAgZmlsbDogY29sb3JcbiAgICAgICAgICB9KVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJldHVybiBzLnJlbmRlckxldHRlcihzLl9kdW1teUxldHRlcigpLCByYXRlLCB7XG4gICAgICAgICAgICBrZXk6IGtleSxcbiAgICAgICAgICAgIGZpbGw6IGByZ2JhKDI1NSwyNTUsMjU1LCR7MC4wMSAqIHJhbmRvbXZhbC5yYW5kb21JbnQoMCwgMzApfSlgXG4gICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgICAgfSlcbiAgICAgIHJldHVybiAoXG4gICAgICAgIDxnIGtleT17YGxldHRlci1ncm91cC0ke2l9YH0+eyB0ZXh0cyB9PC9nPlxuICAgICAgKVxuICAgIH0pXG4gICAgcmV0dXJuIChcbiAgICAgIDxzdmcgdmVyc2lvbj17IHByb3BzLnZlcnNpb24gfVxuICAgICAgICAgICB3aWR0aD17IHdpZHRoIH1cbiAgICAgICAgICAgaGVpZ2h0PXsgaGVpZ2h0IH1cbiAgICAgICAgICAgeG1sbnM9eyBwcm9wcy54bWxucyB9XG4gICAgICAgICAgIHZpZXdCb3g9e2AwIDAgJHt3aWR0aH0gJHtoZWlnaHR9YH1cbiAgICAgID5cbiAgICAgICAgPGc+e2JhY2tncm91bmRzfTwvZz5cbiAgICAgICAgPGc+e3RleHRzfTwvZz5cbiAgICAgIDwvc3ZnPlxuICAgIClcbiAgfVxuXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIFNwZWNzXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgcmVuZGVyTGV0dGVyIChsZXR0ZXIsIHJhdGUsIHRleHRQcm9wcykge1xuICAgIGNvbnN0IHMgPSB0aGlzXG4gICAgbGV0IHsgcHJvcHMgfSA9IHNcblxuICAgIGxldCBwYWRkaW5nID0gMTZcblxuICAgIGxldCB3ID0gcHJvcHMud2lkdGggLSAocGFkZGluZyAqIDIpXG4gICAgbGV0IGggPSBwcm9wcy5oZWlnaHRcblxuICAgIGxldCBtb3ZlUmFuZ2UgPSBoIC8gMjBcbiAgICBsZXQgbW92ZSA9IHJhbmRvbXZhbC5yYW5kb21JbnQuYmluZChyYW5kb212YWwsIG1vdmVSYW5nZSAqIC0xLCBtb3ZlUmFuZ2UpXG5cbiAgICBsZXQgZm9udFNpemUgPSBoICogMC44XG4gICAgbGV0IHggPSBwYWRkaW5nICsgdyAqIHJhdGUgKyAoZm9udFNpemUgLyA0KVxuICAgIGxldCB5ID0gZm9udFNpemVcbiAgICBsZXQgcm90YXRlUmFuZ2UgPSA0MFxuICAgIGxldCByb3RhdGUgPSByYW5kb212YWwucmFuZG9tSW50KC1yb3RhdGVSYW5nZSwgcm90YXRlUmFuZ2UpXG5cbiAgICByZXR1cm4gKFxuICAgICAgPHRleHQgeD17IHBhcnNlSW50KHgpIH1cbiAgICAgICAgICAgIHk9eyBwYXJzZUludCh5KSB9XG4gICAgICAgICAgICBmb250U2l6ZT17IHBhcnNlSW50KGZvbnRTaXplKSB9XG4gICAgICAgICAgICB0cmFuc2Zvcm09eyBgdHJhbnNsYXRlKCR7bW92ZSgpfSwgJHttb3ZlKCl9KSByb3RhdGUoJHtwYXJzZUludChyb3RhdGUpfSwgJHtwYXJzZUludCh4KX0sICR7cGFyc2VJbnQoeSl9KWAgfVxuICAgICAgICAgICAgey4uLnRleHRQcm9wc31cbiAgICAgID57IGxldHRlciB9PC90ZXh0PlxuICAgIClcbiAgfVxuXG4gIF9kdW1teUxldHRlciAoKSB7XG4gICAgY29uc3QgbGV0dGVycyA9ICcxMjM0NTY3ODkwYWJjZGVmZydcbiAgICBsZXQgbGVuID0gbGV0dGVycy5sZW5ndGhcbiAgICByZXR1cm4gbGV0dGVyc1sgcmFuZG9tdmFsLnJhbmRvbUludCgwLCBsZW4gLSAxKSBdXG4gIH1cblxuICBfc3RyaXBlQmxvY2sgKHJhdGUsIGNvbG9yLCBibG9ja1Byb3BzKSB7XG4gICAgY29uc3QgcyA9IHRoaXNcbiAgICBsZXQgeyBwcm9wcyB9ID0gc1xuXG4gICAgbGV0IHJvdGF0ZSA9IHJhbmRvbXZhbC5yYW5kb21JbnQoLTkwLCA5MClcblxuICAgIGxldCBsaW5lcyA9IFtdXG4gICAgbGV0IGxpbmVXaWR0aCA9IDFcbiAgICBsZXQgdyA9IGJsb2NrUHJvcHMud2lkdGhcbiAgICBsZXQgaCA9IGJsb2NrUHJvcHMuaGVpZ2h0XG5cbiAgICBsZXQgbGVmdCA9IHcgKiAtMC41XG4gICAgbGV0IHJpZ2h0ID0gdyAqIDEuNVxuXG4gICAgZm9yIChsZXQgeCA9IGxlZnQ7IHggPCByaWdodDsgeCArPSBsaW5lV2lkdGggKiA2KSB7XG4gICAgICBsaW5lcy5wdXNoKFxuICAgICAgICA8bGluZSB4MT17cGFyc2VJbnQoeCl9XG4gICAgICAgICAgICAgIHkxPXtwYXJzZUludCgwKX1cbiAgICAgICAgICAgICAgeDI9e3BhcnNlSW50KHgpfVxuICAgICAgICAgICAgICB5Mj17cGFyc2VJbnQoaCl9XG4gICAgICAgICAgICAgIGtleT17YGxpbmUtJHt4fWB9XG4gICAgICAgICAgICAgIHN0cm9rZT17Y29sb3J9XG4gICAgICAgIC8+XG4gICAgICApXG4gICAgfVxuXG4gICAgcmV0dXJuIChcbiAgICAgIDxzdmcgeyAuLi5ibG9ja1Byb3BzIH0+XG4gICAgICAgIDxnXG4gICAgICAgICAgdHJhbnNmb3JtPXtgc2NhbGUoMS4zKSByb3RhdGUoJHtwYXJzZUludChyb3RhdGUpfSwgJHtwYXJzZUludChibG9ja1Byb3BzLndpZHRoIC8gMil9LCAke3BhcnNlSW50KGJsb2NrUHJvcHMuaGVpZ2h0IC8gMil9KWB9PlxuICAgICAgICAgIHsgbGluZXMgfVxuICAgICAgICA8L2c+XG4gICAgICA8L3N2Zz5cbiAgICApXG4gIH1cbn1cbk9iamVjdC5hc3NpZ24oQXBDYXB0Y2hhU3ZnLCB7XG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gIC8vIFNwZWNzXG4gIC8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbiAgcHJvcHNUeXBlczoge1xuICAgIHZlcnNpb246IHR5cGVzLnN0cmluZyxcbiAgICB0ZXh0OiB0eXBlcy5zdHJpbmcuaXNSZXF1aXJlZCxcbiAgICB3aWR0aDogdHlwZXMubnVtYmVyLFxuICAgIGhlaWdodDogdHlwZXMubnVtYmVyXG4gIH0sXG5cbiAgZGVmYXVsdFByb3BzOiB7XG4gICAgdmVyc2lvbjogJzEuMScsXG4gICAgeG1sbnM6ICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZycsXG4gICAgdGV4dDogJycsXG4gICAgd2lkdGg6IDI1NixcbiAgICBoZWlnaHQ6IDkyXG4gIH1cbn0pXG5cbmV4cG9ydCBkZWZhdWx0IEFwQ2FwdGNoYVN2Z1xuIl19
\No newline at end of file