├── .gitignore
├── App.vue
├── README
├── colorui
├── animation.css
├── components
│ └── cu-custom.vue
├── icon.css
└── main.css
├── components
└── jyf-parser
│ ├── jyf-parser.vue
│ └── libs
│ ├── CssHandler.js
│ ├── MpHtmlParser.js
│ ├── config.js
│ ├── handler.sjs
│ ├── handler.wxs
│ └── trees.vue
├── main.js
├── manifest.json
├── package.json
├── pages.json
├── pages
├── dynamic
│ └── dynamic.vue
├── index
│ ├── about.vue
│ ├── feedback.vue
│ └── index.vue
├── rss
│ ├── edit.vue
│ ├── index.vue
│ ├── main.vue
│ ├── rsslist.vue
│ └── subscribe.vue
└── user
│ ├── index.vue
│ ├── login.vue
│ ├── register.vue
│ ├── setting.vue
│ ├── update.vue
│ └── updatePwd.vue
├── plugin
└── tools.js
├── static
├── avatar.svg
├── bg.png
├── logo.png
└── user.jpeg
├── store
└── index.js
├── utils
├── api.js
├── database.js
├── refreshRss.js
└── request.js
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | /node_modules
2 | /unpackage
3 |
--------------------------------------------------------------------------------
/App.vue:
--------------------------------------------------------------------------------
1 |
63 |
64 |
72 |
--------------------------------------------------------------------------------
/README:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wyml/MTRR/eb9bdc7b228d680c0ae8fac19600fe9043585e2b/README
--------------------------------------------------------------------------------
/colorui/animation.css:
--------------------------------------------------------------------------------
1 | /*
2 | Animation 微动画
3 | 基于ColorUI组建库的动画模块 by 文晓港 2019年3月26日19:52:28
4 | */
5 |
6 | /* css 滤镜 控制黑白底色gif的 */
7 | .gif-black{
8 | mix-blend-mode: screen;
9 | }
10 | .gif-white{
11 | mix-blend-mode: multiply;
12 | }
13 |
14 |
15 | /* Animation css */
16 | [class*=animation-] {
17 | animation-duration: .5s;
18 | animation-timing-function: ease-out;
19 | animation-fill-mode: both
20 | }
21 |
22 | .animation-fade {
23 | animation-name: fade;
24 | animation-duration: .8s;
25 | animation-timing-function: linear
26 | }
27 |
28 | .animation-scale-up {
29 | animation-name: scale-up
30 | }
31 |
32 | .animation-scale-down {
33 | animation-name: scale-down
34 | }
35 |
36 | .animation-slide-top {
37 | animation-name: slide-top
38 | }
39 |
40 | .animation-slide-bottom {
41 | animation-name: slide-bottom
42 | }
43 |
44 | .animation-slide-left {
45 | animation-name: slide-left
46 | }
47 |
48 | .animation-slide-right {
49 | animation-name: slide-right
50 | }
51 |
52 | .animation-shake {
53 | animation-name: shake
54 | }
55 |
56 | .animation-reverse {
57 | animation-direction: reverse
58 | }
59 |
60 | @keyframes fade {
61 | 0% {
62 | opacity: 0
63 | }
64 |
65 | 100% {
66 | opacity: 1
67 | }
68 | }
69 |
70 | @keyframes scale-up {
71 | 0% {
72 | opacity: 0;
73 | transform: scale(.2)
74 | }
75 |
76 | 100% {
77 | opacity: 1;
78 | transform: scale(1)
79 | }
80 | }
81 |
82 | @keyframes scale-down {
83 | 0% {
84 | opacity: 0;
85 | transform: scale(1.8)
86 | }
87 |
88 | 100% {
89 | opacity: 1;
90 | transform: scale(1)
91 | }
92 | }
93 |
94 | @keyframes slide-top {
95 | 0% {
96 | opacity: 0;
97 | transform: translateY(-100%)
98 | }
99 |
100 | 100% {
101 | opacity: 1;
102 | transform: translateY(0)
103 | }
104 | }
105 |
106 | @keyframes slide-bottom {
107 | 0% {
108 | opacity: 0;
109 | transform: translateY(100%)
110 | }
111 |
112 | 100% {
113 | opacity: 1;
114 | transform: translateY(0)
115 | }
116 | }
117 |
118 | @keyframes shake {
119 |
120 | 0%,
121 | 100% {
122 | transform: translateX(0)
123 | }
124 |
125 | 10% {
126 | transform: translateX(-9px)
127 | }
128 |
129 | 20% {
130 | transform: translateX(8px)
131 | }
132 |
133 | 30% {
134 | transform: translateX(-7px)
135 | }
136 |
137 | 40% {
138 | transform: translateX(6px)
139 | }
140 |
141 | 50% {
142 | transform: translateX(-5px)
143 | }
144 |
145 | 60% {
146 | transform: translateX(4px)
147 | }
148 |
149 | 70% {
150 | transform: translateX(-3px)
151 | }
152 |
153 | 80% {
154 | transform: translateX(2px)
155 | }
156 |
157 | 90% {
158 | transform: translateX(-1px)
159 | }
160 | }
161 |
162 | @keyframes slide-left {
163 | 0% {
164 | opacity: 0;
165 | transform: translateX(-100%)
166 | }
167 |
168 | 100% {
169 | opacity: 1;
170 | transform: translateX(0)
171 | }
172 | }
173 |
174 | @keyframes slide-right {
175 | 0% {
176 | opacity: 0;
177 | transform: translateX(100%)
178 | }
179 |
180 | 100% {
181 | opacity: 1;
182 | transform: translateX(0)
183 | }
184 | }
--------------------------------------------------------------------------------
/colorui/components/cu-custom.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
62 |
63 |
66 |
--------------------------------------------------------------------------------
/components/jyf-parser/jyf-parser.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
613 |
614 |
638 |
--------------------------------------------------------------------------------
/components/jyf-parser/libs/CssHandler.js:
--------------------------------------------------------------------------------
1 | /*
2 | 解析和匹配 Css 的选择器
3 | github:https://github.com/jin-yufeng/Parser
4 | docs:https://jin-yufeng.github.io/Parser
5 | author:JinYufeng
6 | */
7 | const config = require("./config.js");
8 | class CssHandler {
9 | constructor(tagStyle = {}) {
10 | this.styles = Object.assign({}, tagStyle);
11 | };
12 | getStyle(data) {
13 | var style = '';
14 | data = data.replace(/<[sS][tT][yY][lL][eE][\s\S]*?>([\s\S]*?)<\/[sS][tT][yY][lL][eE][\s\S]*?>/g, function($, $1) {
15 | style += $1;
16 | return '';
17 | })
18 | this.styles = new CssParser(style, this.styles).parse();
19 | return data;
20 | };
21 | match(name, attrs) {
22 | var tmp, matched = (tmp = this.styles[name]) ? tmp + ';' : '';
23 | if (attrs.class) {
24 | var classes = attrs.class.split(' ');
25 | for (var i = 0; i < classes.length; i++)
26 | if (tmp = this.styles['.' + classes[i]])
27 | matched += tmp + ';';
28 | }
29 | if (tmp = this.styles['#' + attrs.id])
30 | matched += tmp + ';';
31 | return matched;
32 | };
33 | }
34 | module.exports = CssHandler;
35 | class CssParser {
36 | constructor(data, tagStyle) {
37 | this.data = data;
38 | this.res = tagStyle;
39 | for (var item in config.userAgentStyles) {
40 | if (tagStyle[item]) tagStyle[item] = config.userAgentStyles[item] + ';' + tagStyle[item];
41 | else tagStyle[item] = config.userAgentStyles[item];
42 | }
43 | this._comma = false;
44 | this._floor = 0;
45 | this._i = 0;
46 | this._list = [];
47 | this._start = 0;
48 | this._state = this.Space;
49 | };
50 | parse() {
51 | for (; this._i < this.data.length; this._i++)
52 | this._state(this.data[this._i]);
53 | return this.res;
54 | };
55 | // 状态机
56 | Space(c) {
57 | if (c == '.' || c == '#' || (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
58 | this._start = this._i;
59 | this._state = this.StyleName;
60 | } else if (c == '/' && this.data[this._i + 1] == '*')
61 | this.Comment();
62 | else if (!config.blankChar[c] && c != ';')
63 | this._state = this.Ignore;
64 | };
65 | Comment() {
66 | this._i = this.data.indexOf("*/", this._i) + 1;
67 | if (!this._i) this._i = this.data.length;
68 | this._state = this.Space;
69 | };
70 | Ignore(c) {
71 | if (c == '{') this._floor++;
72 | else if (c == '}' && !--this._floor) {
73 | this._list = [];
74 | this._state = this.Space;
75 | }
76 | };
77 | StyleName(c) {
78 | if (config.blankChar[c]) {
79 | if (this._start != this._i)
80 | this._list.push(this.data.substring(this._start, this._i));
81 | this._state = this.NameSpace;
82 | } else if (c == '{') {
83 | this._list.push(this.data.substring(this._start, this._i));
84 | this._start = this._i + 1;
85 | this.Content();
86 | } else if (c == ',') {
87 | this._list.push(this.data.substring(this._start, this._i));
88 | this._start = this._i + 1;
89 | this._comma = true;
90 | } else if ((c < 'a' || c > 'z') && (c < 'A' || c > 'Z') && (c < '0' || c > '9') && c != '.' && c != '#' && c != '-' &&
91 | c != '_')
92 | this._state = this.Ignore;
93 | };
94 | NameSpace(c) {
95 | if (c == '{') {
96 | this._start = this._i + 1;
97 | this.Content();
98 | } else if (c == ',') {
99 | this._comma = true;
100 | this._start = this._i + 1;
101 | this._state = this.StyleName;
102 | } else if (!config.blankChar[c]) {
103 | if (this._comma) {
104 | this._state = this.StyleName;
105 | this._start = this._i--;
106 | this._comma = false;
107 | } else this._state = this.Ignore;
108 | }
109 | };
110 | Content() {
111 | this._i = this.data.indexOf('}', this._i);
112 | if (this._i == -1) this._i = this.data.length;
113 | var content = this.data.substring(this._start, this._i);
114 | for (var i = this._list.length; i--;)
115 | this.res[this._list[i]] = (this.res[this._list[i]] || '') + content;
116 | this._list = [];
117 | this._state = this.Space;
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/components/jyf-parser/libs/MpHtmlParser.js:
--------------------------------------------------------------------------------
1 | /*
2 | 将 html 解析为适用于小程序 rich-text 的 DOM 结构
3 | github:https://github.com/jin-yufeng/Parser
4 | docs:https://jin-yufeng.github.io/Parser
5 | author:JinYufeng
6 | */
7 | const config = require("./config.js");
8 | const blankChar = config.blankChar;
9 | const CssHandler = require("./CssHandler.js");
10 | var emoji; // emoji 补丁包 https://jin-yufeng.github.io/Parser/#/instructions?id=emoji
11 | class MpHtmlParser {
12 | constructor(data, options = {}) {
13 | this.CssHandler = new CssHandler(options.tagStyle);
14 | this.data = data;
15 | this.DOM = [];
16 | this._attrName = '';
17 | this._attrValue = '';
18 | this._attrs = {};
19 | this._domain = options.domain;
20 | this._protocol = this._domain && this._domain.includes("://") ? this._domain.split("://")[0] : "http";
21 | this._i = 0;
22 | this._start = 0;
23 | this._state = this.Text;
24 | this._STACK = [];
25 | this._tagName = '';
26 | this._audioNum = 0;
27 | this._imgNum = 0;
28 | this._videoNum = 0;
29 | this._useAnchor = options.useAnchor;
30 | this._pre = false;
31 | };
32 | parse() {
33 | if (emoji) this.data = emoji.parseEmoji(this.data);
34 | // 高亮处理
35 | if (config.highlight)
36 | this.data = this.data.replace(/<[pP][rR][eE]([\s\S]*?)>([\s\S]+?)<\/[pP][rR][eE][\s\S]*?>/g, function($, $1, $2) {
37 | return `
${config.highlight($2, $1)}
`;
38 | })
39 | this.data = this.CssHandler.getStyle(this.data);
40 | for (var len = this.data.length; this._i < len; this._i++)
41 | this._state(this.data[this._i]);
42 | if (this._state == this.Text) this.setText();
43 | while (this._STACK.length) this.popNode(this._STACK.pop());
44 | // #ifdef MP-BAIDU || MP-TOUTIAO
45 | // 将顶层标签的一些样式提取出来给 rich-text
46 | function setContain(nodes) {
47 | for (var i = nodes.length, element; element = nodes[--i];) {
48 | if (element.type == "text") continue;
49 | if (!element.c) {
50 | var style = element.attrs.style;
51 | if (style) {
52 | var j, k, res = "";
53 | if ((j = style.indexOf("display")) != -1)
54 | res = style.substring(j, (k = style.indexOf(';', j)) == -1 ? style.length : k);
55 | if (style.indexOf("flex") != -1) res += ';' + style.match(getRegExp("flex[:-][^;]+/g")).join(';');
56 | element.attrs.containStyle = res;
57 | }
58 | } else setContain(element.children);
59 | }
60 | };
61 | setContain(this.DOM);
62 | // #endif
63 | if (this.DOM.length) this.DOM[0].PoweredBy = "Parser";
64 | return this.DOM;
65 | };
66 | // 设置属性
67 | setAttr() {
68 | if (config.trustAttrs[this._attrName]) {
69 | if (this._attrName == "src" && this._attrValue[0] == '/') {
70 | if (this._attrValue[1] == '/') this._attrValue = this._protocol + ':' + this._attrValue;
71 | else if (this._domain) this._attrValue = this._domain + this._attrValue;
72 | }
73 | this._attrs[this._attrName] = (this._attrValue ? this._attrValue : (this._attrName == "src" || this._attrName ==
74 | "alt" ? '' : 'T'));
75 | }
76 | this._attrValue = '';
77 | while (blankChar[this.data[this._i]]) this._i++;
78 | if (this.checkClose()) this.setNode();
79 | else this._state = this.AttrName;
80 | };
81 | // 设置文本节点
82 | setText() {
83 | var text = this.getSelection();
84 | if (!text) return;
85 | if (!this._pre) {
86 | // 移除空白符
87 | for (var tmp = [], i = text.length, has = false, c; c = text[--i];)
88 | if ((!blankChar[c] && (has = true)) || (!blankChar[tmp[0]] && (c = ' '))) tmp.unshift(c);
89 | if (!has) return;
90 | text = tmp.join('');
91 | }
92 | // 处理实体
93 | // #ifdef MP-BAIDU || MP-ALIPAY || MP-TOUTIAO
94 | var entities = {
95 | lt: "<",
96 | gt: ">",
97 | amp: "&",
98 | quot: '"',
99 | apos: "'",
100 | nbsp: "\u00A0",
101 | ensp: "\u2002",
102 | emsp: "\u2003",
103 | ndash: "–",
104 | mdash: "—",
105 | middot: "·",
106 | lsquo: "‘",
107 | rsquo: "’",
108 | ldquo: "“",
109 | rdquo: "”",
110 | bull: "•",
111 | hellip: "…",
112 | permil: "‰",
113 | copy: "©",
114 | reg: "®",
115 | trade: "™",
116 | times: "×",
117 | divide: "÷",
118 | cent: "¢",
119 | pound: "£",
120 | yen: "¥",
121 | euro: "€",
122 | sect: "§"
123 | };
124 | // #endif
125 | var i = text.indexOf('&'),
126 | j, u, decode;
127 | while (i != -1) {
128 | j = text.indexOf(';', i + 2);
129 | if (j == -1) break;
130 | if (text[i + 1] == '#') {
131 | u = parseInt((text[i + 2] == 'x' ? '0' : '') + text.substring(i + 2, j));
132 | if (!isNaN(u)) text = text.substring(0, i) + String.fromCharCode(u) + text.substring(j + 1);
133 | } else {
134 | u = text.substring(i + 1, j);
135 | // #ifdef MP-WEIXIN || MP-QQ || APP-PLUS
136 | if (u == "nbsp") text = text.substring(0, i) + '\u00A0' + text.substring(j + 1); // 解决连续 失效的问题
137 | else if (u != "lt" && u != "gt" && u != "amp" && u != "ensp" && u != "emsp") decode = true;
138 | // #endif
139 | // #ifdef MP-BAIDU || MP-ALIPAY || MP-TOUTIAO
140 | if (entities[u]) text = text.substring(0, i) + entities[u] + text.substring(j + 1);
141 | // #endif
142 | }
143 | i = text.indexOf('&', i + 1);
144 | }
145 | var slibings = this._STACK.length ? this._STACK[this._STACK.length - 1].children : this.DOM;
146 | if (slibings.length && slibings[slibings.length - 1].type == "text") {
147 | slibings[slibings.length - 1].text += text;
148 | if (decode) slibings[slibings.length - 1].decode = true;
149 | } else
150 | slibings.push({
151 | type: "text",
152 | text,
153 | decode
154 | })
155 | };
156 | // 设置元素节点
157 | setNode() {
158 | var slibings = this._STACK.length ? this._STACK[this._STACK.length - 1].children : this.DOM;
159 | var node = {
160 | name: this._tagName.toLowerCase(),
161 | attrs: this._attrs
162 | }
163 | config.LabelHandler(node, this);
164 | this._attrs = {};
165 | if (this.data[this._i] == '>') {
166 | if (!config.selfClosingTags[this._tagName]) {
167 | if (config.ignoreTags[node.name]) {
168 | var j = this._i;
169 | // 处理要被移除的标签
170 | while (this._i < this.data.length) {
171 | (this._i = this.data.indexOf("", this._i + 1)) == -1 ? this._i = this.data.length : null;
172 | this._i += 2;
173 | this._start = this._i;
174 | while (!blankChar[this.data[this._i]] && this.data[this._i] != '>' && this.data[this._i] != '/') this._i++;
175 | if (this.data.substring(this._start, this._i).toLowerCase() == node.name) {
176 | this._i = this.data.indexOf('>', this._i);
177 | if (this._i == -1) this._i = this.data.length;
178 | else this._start = this._i + 1;
179 | this._state = this.Text;
180 | // 处理 svg
181 | if (node.name == "svg") {
182 | var src = this.data.substring(j, this._i + 1);
183 | if (!node.attrs.xmlns) src = " xmlns=\"http://www.w3.org/2000/svg\"" + src;
184 | this._i = j;
185 | while (this.data[j] != '<') j--;
186 | src = this.data.substring(j, this._i) + src;
187 | this._i = this._start - 1;
188 | node.name = "img";
189 | node.attrs = {
190 | src: "data:image/svg+xml;utf8," + src.replace(/#/g, "%23"),
191 | ignore: 'T'
192 | }
193 | slibings.push(node);
194 | }
195 | break;
196 | }
197 | }
198 | return;
199 | } else this._STACK.push(node);
200 | node.children = [];
201 | }
202 | } else this._i++;
203 | this._start = this._i + 1;
204 | this._state = this.Text;
205 | if (!config.ignoreTags[node.name]) {
206 | // 检查空白符是否有效
207 | if (node.name == "pre" || (node.attrs.style && node.attrs.style.includes("white-space") && node.attrs.style.includes(
208 | "pre"))) {
209 | this._pre = true;
210 | node.pre = true;
211 | }
212 | slibings.push(node);
213 | }
214 | };
215 | // 标签出栈处理
216 | popNode(node) {
217 | // 替换一些标签名
218 | if (node.name == "picture") {
219 | node.name = "img";
220 | if (!node.attrs.src && node.children.length && node.children[0].name == "img")
221 | node.attrs.src = node.children[0].attrs.src;
222 | if (node.attrs.src && !node.attrs.ignore)
223 | node.attrs.i = (this._imgNum++).toString();
224 | return node.children = void 0;
225 | }
226 | if (config.blockTags[node.name]) node.name = "div";
227 | else if (!config.trustTags[node.name]) node.name = "span";
228 | // 空白符处理
229 | if (node.pre) {
230 | this._pre = false;
231 | node.pre = undefined;
232 | for (var i = this._STACK.length; i--;)
233 | if (this._STACK[i].pre)
234 | this._pre = true;
235 | }
236 | // 处理列表
237 | if (node.c) {
238 | if (node.name == "ul") {
239 | var floor = 1;
240 | for (var i = this._STACK.length; i--;)
241 | if (this._STACK[i].name == "ul") floor++;
242 | if (floor != 1)
243 | for (i = node.children.length; i--;)
244 | node.children[i].floor = floor;
245 | } else if (node.name == "ol") {
246 | function convert(num, type) {
247 | if (type == 'a') return String.fromCharCode(97 + (num - 1) % 26);
248 | if (type == 'A') return String.fromCharCode(65 + (num - 1) % 26);
249 | if (type == 'i' || type == 'I') {
250 | num = (num - 1) % 99 + 1;
251 | var one = ['I', "II", "III", "IV", 'V', "VI", "VII", "VIII", "IX"],
252 | ten = ['X', "XX", "XXX", "XL", 'L', "LX", "LXX", "LXXX", "XC"],
253 | res = (ten[Math.floor(num / 10) - 1] || '') + (one[num % 10 - 1] || '');
254 | if (type == 'i') return res.toLowerCase();
255 | return res;
256 | }
257 | return num;
258 | }
259 | for (var i = 0, num = 1, child; child = node.children[i++];)
260 | if (child.name == "li") {
261 | child.type = "ol";
262 | child.num = convert(num++, node.attrs.type) + '.';
263 | }
264 | }
265 | }
266 | // 处理表格的边框
267 | if (node.name == "table") {
268 | if (node.attrs.border)
269 | node.attrs.style = `border:${node.attrs.border}px solid gray;${node.attrs.style || ''}`;
270 | if (node.attrs.hasOwnProperty("cellspacing"))
271 | node.attrs.style = `border-spacing:${node.attrs.cellspacing}px;${node.attrs.style || ''}`;
272 |
273 | function setBorder(elem) {
274 | if (elem.name == "th" || elem.name == "td") {
275 | if (node.attrs.border)
276 | elem.attrs.style = `border:${node.attrs.border}px solid gray;${elem.attrs.style || ''}`;
277 | if (node.attrs.hasOwnProperty("cellpadding"))
278 | elem.attrs.style = `padding:${node.attrs.cellpadding}px;${elem.attrs.style || ''}`;
279 | return;
280 | }
281 | if (elem.type == "text") return;
282 | for (var i = 0; i < (elem.children || []).length; i++)
283 | setBorder(elem.children[i]);
284 | }
285 | if (node.attrs.border || node.attrs.hasOwnProperty("cellpadding"))
286 | for (var i = 0; i < node.children.length; i++)
287 | setBorder(node.children[i]);
288 | }
289 | // 后代选择器处理
290 | this.CssHandler.pop && this.CssHandler.pop(node);
291 | };
292 | // 工具函数
293 | checkClose() {
294 | if (this.data[this._i] == '>' || (this.data[this._i] == '/' && this.data[this._i + 1] == '>'))
295 | return true;
296 | return false;
297 | };
298 | getSelection(trim) {
299 | var str = (this._start == this._i ? '' : this.data.substring(this._start, this._i));
300 | while (trim && (blankChar[this.data[++this._i]] || (this._i--, false)));
301 | this._start = this._i + 1;
302 | return str;
303 | };
304 | // 状态机
305 | Text(c) {
306 | if (c == '<') {
307 | var next = this.data[this._i + 1];
308 | if ((next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z')) {
309 | this.setText();
310 | this._state = this.TagName;
311 | } else if (next == '/') {
312 | this.setText();
313 | this._i++;
314 | next = this.data[this._i + 1];
315 | if ((next >= 'a' && next <= 'z') || (next >= 'A' && next <= 'Z')) {
316 | this._start = this._i + 1;
317 | this._state = this.EndTag;
318 | } else
319 | this._state = this.Comment;
320 | } else if (next == '!') {
321 | this.setText();
322 | this._state = this.Comment;
323 | }
324 | }
325 | };
326 | Comment() {
327 | if (this.data.substring(this._i + 1, this._i + 3) == "--" || this.data.substring(this._i + 1, this._i + 7) ==
328 | "[CDATA[") {
329 | this._i = this.data.indexOf("-->", this._i + 1);
330 | if (this._i == -1) return this._i = this.data.length;
331 | else this._i = this._i + 2;
332 | } else
333 | (this._i = this.data.indexOf('>', this._i + 1)) == -1 ? this._i = this.data.length : null;
334 | this._start = this._i + 1;
335 | this._state = this.Text;
336 | };
337 | TagName(c) {
338 | if (blankChar[c]) {
339 | this._tagName = this.getSelection(true);
340 | if (this.checkClose()) this.setNode();
341 | else this._state = this.AttrName;
342 | } else if (this.checkClose()) {
343 | this._tagName = this.getSelection();
344 | this.setNode();
345 | }
346 | };
347 | AttrName(c) {
348 | if (blankChar[c]) {
349 | this._attrName = this.getSelection(true).toLowerCase();
350 | if (this.data[this._i] == '=') {
351 | while (blankChar[this.data[++this._i]]);
352 | this._start = this._i--;
353 | this._state = this.AttrValue;
354 | } else this.setAttr();
355 | } else if (c == '=') {
356 | this._attrName = this.getSelection().toLowerCase();
357 | while (blankChar[this.data[++this._i]]);
358 | this._start = this._i--;
359 | this._state = this.AttrValue;
360 | } else if (this.checkClose()) {
361 | this._attrName = this.getSelection().toLowerCase();
362 | this.setAttr();
363 | }
364 | };
365 | AttrValue(c) {
366 | if (c == '"' || c == "'") {
367 | this._start++;
368 | if ((this._i = this.data.indexOf(c, this._i + 1)) == -1) return this._i = this.data.length;
369 | } else
370 | for (; !blankChar[this.data[this._i]] && this.data[this._i] != '>'; this._i++);
371 | this._attrValue = this.getSelection();
372 | while (this._attrValue.includes(""")) this._attrValue = this._attrValue.replace(""", '"');
373 | this.setAttr();
374 | };
375 | EndTag(c) {
376 | if (blankChar[c] || c == '>' || c == '/') {
377 | var name = this.getSelection().toLowerCase();
378 | var flag = false;
379 | for (var i = this._STACK.length; i--;)
380 | if (this._STACK[i].name == name) {
381 | flag = true;
382 | break;
383 | }
384 | if (flag) {
385 | var node;
386 | while (flag) {
387 | node = this._STACK.pop();
388 | if (node.name == name) flag = false;
389 | this.popNode(node);
390 | }
391 | } else if (name == 'p' || name == "br") {
392 | var slibings = this._STACK.length ? this._STACK[this._STACK.length - 1].children : this.DOM;
393 | slibings.push({
394 | name,
395 | attrs: {}
396 | });
397 | }
398 | this._i = this.data.indexOf('>', this._i);
399 | if (this._i == -1) this._i = this.data.length;
400 | else this._state = this.Text;
401 | }
402 | };
403 | };
404 | module.exports = MpHtmlParser;
405 |
--------------------------------------------------------------------------------
/components/jyf-parser/libs/config.js:
--------------------------------------------------------------------------------
1 | /* 配置文件 */
2 | function makeMap(str, obj = {}) {
3 | var map = obj,
4 | list = str.split(',');
5 | for (var i = list.length; i--;)
6 | map[list[i]] = true;
7 | return map;
8 | }
9 | // 信任的属性列表,不在列表中的属性将被移除
10 | const trustAttrs = makeMap(
11 | "align,allowfullscreen,alt,app-id,appid,apid,author,autoplay,border,cellpadding,cellspacing,class,color,colspan,controls,data-src,dir,face,frameborder,height,href,id,ignore,loop,media,muted,name,path,poster,rowspan,size,span,src,start,style,type,unit-id,unitId,width,xmlns"
12 | );
13 | // 信任的标签,将保持标签名不变
14 | const trustTags = makeMap(
15 | "a,abbr,ad,audio,b,blockquote,br,code,col,colgroup,dd,del,dl,dt,div,em,fieldset,h1,h2,h3,h4,h5,h6,hr,i,img,ins,label,legend,li,ol,p,q,source,span,strong,sub,sup,table,tbody,td,tfoot,th,thead,tr,title,u,ul,video"
16 | // #ifdef APP-PLUS
17 | +
18 | ",embed,iframe"
19 | // #endif
20 | );
21 | // 块级标签,将被转为 div
22 | const blockTags = makeMap("address,article,aside,body,center,cite,footer,header,html,nav,pre,section");
23 | // 被移除的标签(其中 svg 系列标签会被转为图片)
24 | const ignoreTags = makeMap(
25 | "area,base,basefont,canvas,circle,command,ellipse,frame,head,input,isindex,keygen,line,link,map,meta,param,path,polygon,rect,script,source,svg,textarea,track,use,wbr"
26 | // #ifndef APP-PLUS
27 | +
28 | ",embed,iframe"
29 | // #endif
30 | );
31 | // 只能用 rich-text 显示的标签(其中图片不能预览、不能显示视频、音频等)
32 | const richOnlyTags = makeMap("a,colgroup,fieldset,legend,picture,table,tbody,td,tfoot,th,thead,tr");
33 | // 自闭合标签
34 | const selfClosingTags = makeMap(
35 | "area,base,basefont,br,col,circle,ellipse,embed,frame,hr,img,input,isindex,keygen,line,link,meta,param,path,polygon,rect,source,track,use,wbr"
36 | );
37 | // 空白字符
38 | const blankChar = makeMap(" ,\u00A0,\t,\r,\n,\f");
39 | // 默认的标签样式
40 | var userAgentStyles = {
41 | a: "color:#366092;word-break:break-all;padding:1.5px 0 1.5px 0",
42 | address: "font-style:italic",
43 | big: "display:inline;font-size:1.2em",
44 | blockquote: "background-color:#f6f6f6;border-left:3px solid #dbdbdb;color:#6c6c6c;padding:5px 0 5px 10px",
45 | center: "text-align:center",
46 | cite: "font-style:italic",
47 | dd: "margin-left:40px",
48 | img: "max-width:100%",
49 | mark: "background-color:yellow",
50 | picture: "max-width:100%",
51 | pre: "font-family:monospace;white-space:pre;overflow:scroll",
52 | s: "text-decoration:line-through",
53 | small: "display:inline;font-size:0.8em",
54 | u: "text-decoration:underline"
55 | };
56 | const screenWidth = wx.getSystemInfoSync().screenWidth;
57 | // #ifdef MP-WEIXIN
58 | // 版本兼容
59 | if (wx.canIUse("editor")) {
60 | makeMap("bdi,bdo,caption,rt,ruby,pre", trustTags);
61 | makeMap("bdi,bdo,caption,rt,ruby,pre", richOnlyTags);
62 | ignoreTags.rp = true;
63 | blockTags.pre = undefined;
64 | } else
65 | // #endif
66 | blockTags.caption = true;
67 |
68 | function bubbling(Parser) {
69 | for (var i = Parser._STACK.length; i--;) {
70 | if (!richOnlyTags[Parser._STACK[i].name])
71 | Parser._STACK[i].c = 1;
72 | else return false;
73 | }
74 | return true;
75 | }
76 | module.exports = {
77 | // 高亮处理函数
78 | highlight: null,
79 | // 处理标签的属性,需要通过组件递归方式显示的标签需要调用 bubbling(Parser)
80 | LabelHandler(node, Parser) {
81 | var attrs = node.attrs;
82 | attrs.style = Parser.CssHandler.match(node.name, attrs, node) + (attrs.style || '');
83 | switch (node.name) {
84 | case "div":
85 | case 'p':
86 | if (attrs.align) {
87 | attrs.style = `text-align:${attrs.align};${attrs.style}`;
88 | attrs.align = void 0;
89 | }
90 | break;
91 | case "img":
92 | if (attrs["data-src"]) {
93 | attrs.src = attrs.src || attrs["data-src"];
94 | attrs["data-src"] = void 0;
95 | }
96 | if (attrs.width && parseInt(attrs.width) > screenWidth)
97 | attrs.style += ";height:auto !important";
98 | if (attrs.src && !attrs.ignore) {
99 | if (bubbling(Parser)) attrs.i = (Parser._imgNum++).toString();
100 | else attrs.ignore = 'T';
101 | }
102 | break;
103 | case 'a':
104 | case "ad":
105 | // #ifdef APP-PLUS
106 | case "iframe":
107 | case "embed":
108 | // #endif
109 | bubbling(Parser);
110 | break;
111 | case "font":
112 | if (attrs.color) {
113 | attrs.style = `color:${attrs.color};${attrs.style}`;
114 | attrs.color = void 0;
115 | }
116 | if (attrs.face) {
117 | attrs.style = `font-family:${attrs.face};${attrs.style}`;
118 | attrs.face = void 0;
119 | }
120 | if (attrs.size) {
121 | var size = parseInt(attrs.size);
122 | if (size < 1) size = 1;
123 | else if (size > 7) size = 7;
124 | var map = ["xx-small", "x-small", "small", "medium", "large", "x-large", "xx-large"];
125 | attrs.style = `font-size:${map[size - 1]};${attrs.style}`;
126 | attrs.size = void 0;
127 | }
128 | break;
129 | case "video":
130 | case "audio":
131 | if (attrs.id) Parser[`_${node.name}Num`]++;
132 | else attrs.id = (node.name + (++Parser[`_${node.name}Num`]));
133 | if (node.name == "video") {
134 | attrs.style = attrs.style || '';
135 | if (attrs.width) {
136 | attrs.style = `width:${parseFloat(attrs.width) + attrs.width.includes('%') ? '%' : "px"};${attrs.style}`;
137 | attrs.width = void 0;
138 | }
139 | if (attrs.height) {
140 | attrs.style = `height:${parseFloat(attrs.height) + attrs.height.includes('%') ? '%' : "px"};${attrs.style}`;
141 | attrs.height = void 0;
142 | }
143 | if (Parser._videoNum > 3) node.lazyLoad = true;
144 | }
145 | attrs.source = [];
146 | if (attrs.src) attrs.source.push(attrs.src);
147 | if (!attrs.controls && !attrs.autoplay)
148 | console.warn(`存在没有 controls 属性的 ${node.name} 标签,可能导致无法播放`, node);
149 | bubbling(Parser);
150 | break;
151 | case "source":
152 | var i, parent = Parser._STACK[Parser._STACK.length - 1];
153 | if (!parent || !attrs.src) break;
154 | if (parent.name == "video" || parent.name == "audio")
155 | parent.attrs.source.push(attrs.src);
156 | else {
157 | var i, media = attrs.media;
158 | if (parent.name == "picture" && !parent.attrs.src && (!media || (media.includes("px") &&
159 | (((i = media.indexOf("min-width")) != -1 && (i = media.indexOf(':', i + 8)) != -1 &&
160 | screenWidth > parseInt(media.substring(i + 1))) ||
161 | ((i = media.indexOf("max-width")) != -1 && (i = media.indexOf(':', i + 8)) != -1 &&
162 | screenWidth < parseInt(media.substring(i + 1)))))))
163 | parent.attrs.src = attrs.src;
164 | }
165 | }
166 | // 压缩 style
167 | var styles = attrs.style.split(';'),
168 | compressed = {};
169 | attrs.style = "";
170 | for (var i = 0, len = styles.length; i < len; i++) {
171 | var info = styles[i].split(':');
172 | if (info.length < 2) continue;
173 | var key = info[0].trim().toLowerCase(),
174 | value = info.slice(1).join(':').trim();
175 | // 填充链接
176 | if (value.includes("url")) {
177 | var j = value.indexOf('(');
178 | if (j++ != -1) {
179 | while (value[j] == '"' || value[j] == "'" || blankChar[value[j]]) j++;
180 | if (value[j] == '/') {
181 | if (value[j + 1] == '/') value = value.substring(0, j) + Parser._protocol + ':' + value.substring(j);
182 | else if (Parser._domain) value = value.substring(0, j) + Parser._domain + value.substring(j);
183 | }
184 | }
185 | }
186 | // 转换 rpx
187 | else if (value.includes("rpx"))
188 | value = value.replace(/[0-9.]*rpx/g, function($) {
189 | return parseFloat($) * screenWidth / 750 + "px";
190 | })
191 | if (value.includes("-webkit") || value.includes("-moz") || value.includes("-ms") || value.includes("-o") || value.includes(
192 | "safe"))
193 | attrs.style += `;${key}:${value}`;
194 | else if (!compressed[key] || value.includes("import") || !compressed[key].includes("import"))
195 | compressed[key] = value;
196 | }
197 | if (node.name == "img" && compressed.width && compressed.width.includes("%") && parseInt(compressed.width) >
198 | screenWidth)
199 | compressed.height = "auto !important";
200 | for (var key in compressed)
201 | attrs.style += `;${key}:${compressed[key]}`;
202 | attrs.style = attrs.style.substr(1);
203 | if (!attrs.style) attrs.style = void 0;
204 | if (Parser._useAnchor && attrs.id) bubbling(Parser);
205 | },
206 | trustAttrs,
207 | trustTags,
208 | blockTags,
209 | ignoreTags,
210 | selfClosingTags,
211 | blankChar,
212 | userAgentStyles,
213 | screenWidth
214 | }
215 |
--------------------------------------------------------------------------------
/components/jyf-parser/libs/handler.sjs:
--------------------------------------------------------------------------------
1 | var inlineTags = {
2 | abbr: 1,
3 | b: 1,
4 | big: 1,
5 | code: 1,
6 | del: 1,
7 | em: 1,
8 | i: 1,
9 | ins: 1,
10 | label: 1,
11 | q: 1,
12 | small: 1,
13 | span: 1,
14 | strong: 1
15 | }
16 | export default {
17 | // 从 rich-text 顶层标签的样式中取出一些给 rich-text
18 | getStyle: function(style, display) {
19 | if (style) {
20 | var i, j, res = "";
21 | if ((i = style.indexOf("display")) != -1)
22 | res = style.substring(i, (j = style.indexOf(';', i)) == -1 ? style.length : j);
23 | else res = "display:" + display;
24 | if (style.indexOf("flex") != -1) res += ';' + style.match(getRegExp("flex[:-][^;]+/g")).join(';');
25 | return res;
26 | } else return "display:" + display;
27 | },
28 | getNode: function(item) {
29 | return [item];
30 | },
31 | // 是否通过 rich-text 显示
32 | useRichText: function(item) {
33 | // rich-text 不支持 inline
34 | if (item.c || inlineTags[item.name] || (item.attrs.style && item.attrs.style.indexOf("display:inline") != -1))
35 | return false;
36 | return true;
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/components/jyf-parser/libs/handler.wxs:
--------------------------------------------------------------------------------
1 | var inlineTags = {
2 | abbr: 1,
3 | b: 1,
4 | big: 1,
5 | code: 1,
6 | del: 1,
7 | em: 1,
8 | i: 1,
9 | ins: 1,
10 | label: 1,
11 | q: 1,
12 | small: 1,
13 | span: 1,
14 | strong: 1
15 | }
16 | module.exports = {
17 | // 从 rich-text 顶层标签的样式中取出一些给 rich-text
18 | getStyle: function(style, display) {
19 | if (style) {
20 | var i, j, res = "";
21 | if ((i = style.indexOf("display")) != -1)
22 | res = style.substring(i, (j = style.indexOf(';', i)) == -1 ? style.length : j);
23 | else res = "display:" + display;
24 | if (style.indexOf("flex") != -1) res += ';' + style.match(getRegExp("flex[:-][^;]+/g")).join(';');
25 | return res;
26 | } else return "display:" + display;
27 | },
28 | // 处理懒加载
29 | getNode: function(item, imgLoad) {
30 | if (!imgLoad) {
31 | var img = {
32 | name: "img",
33 | attrs: JSON.parse(JSON.stringify(item.attrs))
34 | }
35 | delete img.attrs.src;
36 | img.attrs.style += ";width:20px !important;height:20px !important";
37 | return [img];
38 | } else return [item];
39 | },
40 | // 是否通过 rich-text 显示
41 | useRichText: function(item) {
42 | // rich-text 不支持 inline
43 | if (item.c || inlineTags[item.name] || (item.attrs.style && item.attrs.style.indexOf("display:inline") != -1))
44 | return false;
45 | return true;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/components/jyf-parser/libs/trees.vue:
--------------------------------------------------------------------------------
1 |
8 |
9 |
10 |
11 |
12 |
13 |
15 |
16 |
17 |
19 |
20 |
21 |
22 | {{item.text}}
23 |
24 |
25 |
26 | {{item.text}}
27 |
28 | \n
29 |
30 |
31 |
32 |
34 |
35 |
36 |
38 |
39 |
42 |
43 |
44 |
48 |
49 |
51 |
52 |
53 |
54 |
55 |
57 |
58 |
59 |
61 |
62 |
63 |
65 |
66 |
67 |
68 | {{item.num}}
69 |
70 | █
71 |
72 | █
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
86 |
88 |
89 |
90 |
91 |
93 |
94 |
95 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
265 |
266 |
458 |
--------------------------------------------------------------------------------
/main.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import App from './App'
3 | import store from 'store'
4 |
5 | // 加入HTTP
6 | import {
7 | http
8 | } from './utils/api'
9 | Vue.prototype.$http = http;
10 |
11 | import hot from './pages/rss/index.vue'
12 | import dynamic from './pages/dynamic/dynamic.vue'
13 | import user from './pages/user/index.vue'
14 | import cuCustom from './colorui/components/cu-custom.vue'
15 | Vue.component('hot', hot)
16 | Vue.component('dynamic', dynamic)
17 | Vue.component('user', user)
18 | Vue.component('cu-custom', cuCustom)
19 |
20 | Vue.config.productionTip = false
21 |
22 | App.mpType = 'app'
23 |
24 | const app = new Vue({
25 | store,
26 | ...App
27 | })
28 | app.$mount()
29 |
--------------------------------------------------------------------------------
/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "MlTreeRssReader",
3 | "appid" : "__UNI__E0511EA",
4 | "description" : "",
5 | "versionName" : "MlTreeRssReader1.0.0",
6 | "versionCode" : 100,
7 | "transformPx" : false,
8 | "app-plus" :
9 | {
10 | /* 5+App特有相关 */
11 | "modules" : {},
12 | /* 模块配置 */
13 | "distribute" :
14 | {
15 | /* 应用发布信息 */
16 | "android" :
17 | {
18 | /* android打包配置 */
19 | "permissions" :
20 | [
21 | "",
22 | "",
23 | "",
24 | "",
25 | "",
26 | "",
27 | "",
28 | "",
29 | "",
30 | "",
31 | "",
32 | "",
33 | "",
34 | "",
35 | "",
36 | "",
37 | "",
38 | "",
39 | "",
40 | "",
41 | "",
42 | ""
43 | ],
44 | "abiFilters" :
45 | [
46 | "armeabi-v7a",
47 | "arm64-v8a",
48 | "x86"
49 | ]
50 | },
51 | "ios" : {},
52 | /* ios打包配置 */
53 | "sdkConfigs" :
54 | {
55 | "ad" : null
56 | },
57 | "icons" :
58 | {
59 | "android" :
60 | {
61 | "hdpi" : "unpackage/res/icons/72x72.png",
62 | "xhdpi" : "unpackage/res/icons/96x96.png",
63 | "xxhdpi" : "unpackage/res/icons/144x144.png",
64 | "xxxhdpi" : "unpackage/res/icons/192x192.png"
65 | },
66 | "ios" :
67 | {
68 | "appstore" : "unpackage/res/icons/1024x1024.png",
69 | "ipad" :
70 | {
71 | "app" : "unpackage/res/icons/76x76.png",
72 | "app@2x" : "unpackage/res/icons/152x152.png",
73 | "notification" : "unpackage/res/icons/20x20.png",
74 | "notification@2x" : "unpackage/res/icons/40x40.png",
75 | "proapp@2x" : "unpackage/res/icons/167x167.png",
76 | "settings" : "unpackage/res/icons/29x29.png",
77 | "settings@2x" : "unpackage/res/icons/58x58.png",
78 | "spotlight" : "unpackage/res/icons/40x40.png",
79 | "spotlight@2x" : "unpackage/res/icons/80x80.png"
80 | },
81 | "iphone" :
82 | {
83 | "app@2x" : "unpackage/res/icons/120x120.png",
84 | "app@3x" : "unpackage/res/icons/180x180.png",
85 | "notification@2x" : "unpackage/res/icons/40x40.png",
86 | "notification@3x" : "unpackage/res/icons/60x60.png",
87 | "settings@2x" : "unpackage/res/icons/58x58.png",
88 | "settings@3x" : "unpackage/res/icons/87x87.png",
89 | "spotlight@2x" : "unpackage/res/icons/80x80.png",
90 | "spotlight@3x" : "unpackage/res/icons/120x120.png"
91 | }
92 | }
93 | },
94 | "splashscreen" :
95 | {
96 | "android" :
97 | {
98 | "hdpi" : "",
99 | "xhdpi" : "",
100 | "xxhdpi" : ""
101 | }
102 | }
103 | },
104 | "compilerVersion" : 3,
105 | "usingComponents" : true,
106 | "splashscreen" :
107 | {
108 | "waiting" : false
109 | },
110 | "nvueLaunchMode" : "fast"
111 | },
112 | /* SDK配置 */
113 | "quickapp" : {},
114 | /* 快应用特有相关 */
115 | "mp-weixin" :
116 | {
117 | /* 小程序特有相关 */
118 | "appid" : "",
119 | "setting" :
120 | {
121 | "urlCheck" : true,
122 | "es6" : true,
123 | "postcss" : true,
124 | "minified" : true
125 | },
126 | "permission" : {},
127 | "usingComponents" : true
128 | },
129 | "h5" :
130 | {
131 | "title" : "MlTree Forum",
132 | "domain" : "demo.color-ui.com",
133 | "optimization" :
134 | {
135 | "treeShaking" :
136 | {
137 | "enable" : true
138 | }
139 | },
140 | "router" :
141 | {
142 | "mode" : "history"
143 | }
144 | },
145 | "mp-alipay" :
146 | {
147 | "usingComponents" : true
148 | },
149 | "mp-baidu" :
150 | {
151 | "usingComponents" : true
152 | },
153 | "mp-toutiao" :
154 | {
155 | "setting" :
156 | {
157 | "postcss" : true,
158 | "minified" : true,
159 | "es6" : true
160 | },
161 | "usingComponents" : true
162 | },
163 | "mp-qq" :
164 | {
165 | "appid" : "",
166 | "setting" :
167 | {
168 | "es6" : true,
169 | "postcss" : true,
170 | "minified" : true
171 | }
172 | }
173 | }
174 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "mltree",
3 | "version": "1.0.0",
4 | "description": "MlTreeForum小程序",
5 | "main": "main.js",
6 | "dependencies": {
7 | "cheerio": "^1.0.0-rc.3",
8 | "dayjs": "^1.8.21",
9 | "got": "^10.6.0",
10 | "marked": "^0.8.0",
11 | "prettier": "^1.12.1"
12 | },
13 | "devDependencies": {},
14 | "scripts": {
15 | "test": "echo \"Error: no test specified\" && exit 1"
16 | },
17 | "keywords": [],
18 | "author": "",
19 | "license": "ISC"
20 | }
21 |
--------------------------------------------------------------------------------
/pages.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages": [{
3 | "path": "pages/index/index"
4 | }, {
5 | "path": "pages/user/index"
6 | }, {
7 | "path": "pages/user/login"
8 | }, {
9 | "path": "pages/user/register"
10 | }, {
11 | "path": "pages/rss/index"
12 | }, {
13 | "path": "pages/rss/main"
14 | }, {
15 | "path": "pages/rss/rsslist"
16 | }, {
17 | "path": "pages/rss/subscribe",
18 | "style": {}
19 | }, {
20 | "path": "pages/dynamic/dynamic",
21 | "style": {}
22 | }, {
23 | "path": "pages/rss/edit",
24 | "style": {}
25 | }, {
26 | "path": "pages/user/setting",
27 | "style": {}
28 | }, {
29 | "path": "pages/index/about",
30 | "style": {}
31 | }, {
32 | "path": "pages/user/update",
33 | "style": {}
34 | }, {
35 | "path": "pages/user/updatePwd",
36 | "style": {}
37 | }, {
38 | "path": "pages/index/feedback",
39 | "style": {}
40 | }],
41 | "globalStyle": {
42 | "mp-alipay": {
43 | /* 支付宝小程序特有相关 */
44 | "transparentTitle": "always",
45 | "allowsBounceVertical": "NO"
46 | },
47 | "navigationBarBackgroundColor": "#0081ff",
48 | "navigationBarTitleText": "MlTreeRssReader",
49 | "navigationStyle": "custom",
50 | "navigationBarTextStyle": "white"
51 | },
52 | "usingComponts": true,
53 | "condition": { //模式配置,仅开发期间生效
54 | "current": 0 //当前激活的模式(list 的索引项)
55 | }
56 |
57 | }
58 |
--------------------------------------------------------------------------------
/pages/dynamic/dynamic.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
19 |
20 |
21 |
22 | RSS列表
23 |
24 |
25 |
26 |
27 |
67 |
--------------------------------------------------------------------------------
/pages/index/about.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 返回
5 | 关于
6 |
7 |
8 |
9 | MTRR Version:{{version}}
10 |
11 |
25 |
26 | MlTreeRSSReader(简称:MTRR)是一款依托于UNIAPP编写的RSS阅读器。MTRR灵感来源于平时的朋友圈阅读。因为现有的RSS阅读器对于我来说不够友好,因此制作了这一款阅读器。
27 | 现有的阅读器源一般在国外,并且添加的方式并不友好。所以我依托RSSHub收集了源,在此感谢RSSHub!以及对RSSHub提供规则的大家!
28 |
29 |
30 | MTRR
31 | RSSHub
32 |
33 |
34 |
35 |
36 |
53 |
54 |
57 |
--------------------------------------------------------------------------------
/pages/index/feedback.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 返回
5 | 反馈
6 |
7 |
8 | 问题和意见
9 | 快速键入
10 |
11 |
12 |
13 |
14 |
15 | 图片(选填,提供问题截图,总大小10M以下)
16 |
17 |
18 |
19 |
20 | 点击预览图片
21 | {{imageList.length}}/8
22 |
23 |
24 |
25 |
26 |
27 |
28 | x
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | QQ/邮箱
40 |
41 |
42 |
43 |
44 |
45 | 应用评分
46 |
47 |
48 |
49 |
50 |
51 |
52 | 我们收到反馈后会第一时间进行查看、修复
53 |
54 |
55 |
56 |
57 |
151 |
152 |
317 |
--------------------------------------------------------------------------------
/pages/index/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | {{PageTitle}}
5 |
6 |
7 |
8 |
9 |
20 |
21 |
22 |
23 |
37 |
38 |
41 |
--------------------------------------------------------------------------------
/pages/rss/edit.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 返回
5 | {{title}}
6 |
7 |
25 |
26 |
27 |
28 |
29 | RSS源由各网站提供,MTRR不保证源的有效性。RSS内容由源提供与MTRR无关且MTRR不负责
30 | MTRR源 fork on RSSHub
31 |
32 |
33 |
34 |
35 |
81 |
82 |
85 |
--------------------------------------------------------------------------------
/pages/rss/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | 你尚未订阅任何一个内容呢。快去订阅一个吧~
6 |
7 | 去订阅
8 |
9 |
10 |
11 |
13 |
14 |
15 | {{item.title}}
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | {{item.from}}
24 | {{item.pubDate}}
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
124 |
--------------------------------------------------------------------------------
/pages/rss/main.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 返回
5 | {{title}}
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
29 |
30 |
33 |
--------------------------------------------------------------------------------
/pages/rss/rsslist.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 返回
5 | RSS源列表
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
32 |
33 |
34 |
35 |
36 |
115 |
116 |
118 |
--------------------------------------------------------------------------------
/pages/rss/subscribe.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 返回
5 | 订阅源
6 |
7 |
8 |
9 | 源信息
10 |
11 |
12 |
13 |
33 |
34 |
35 | 编辑源
36 |
37 |
38 |
39 |
62 |
63 |
64 |
65 |
66 | RSS源由各网站提供,MTRR不保证源的有效性。RSS内容由源提供与MTRR无关且MTRR不负责
67 | MTRR源 fork on RSSHub
68 |
69 |
70 |
71 |
72 |
73 |
74 | {{modal.title}}
75 |
76 |
77 |
78 |
79 |
80 | {{modal.content}}
81 |
82 |
83 |
84 |
85 |
86 |
87 |
194 |
--------------------------------------------------------------------------------
/pages/user/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 | {{isLogin?user.username:'点击头像登录'}}
10 |
11 |
12 |
13 |
14 |
15 |
16 | 添加源
17 |
18 |
19 |
20 | 扫描
21 |
22 |
23 |
24 | 设置
25 |
26 |
27 |
28 |
29 |
30 | 已订阅源
31 |
32 |
33 |
34 |
50 |
51 |
52 |
53 |
54 |
121 |
122 |
124 |
--------------------------------------------------------------------------------
/pages/user/login.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 登录
7 |
8 |
9 |
10 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
78 |
79 |
81 |
--------------------------------------------------------------------------------
/pages/user/register.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 注册
7 |
8 |
9 |
10 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
95 |
96 |
98 |
--------------------------------------------------------------------------------
/pages/user/setting.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 返回
5 | 设置
6 |
7 |
68 |
69 |
70 |
71 |
183 |
184 |
187 |
--------------------------------------------------------------------------------
/pages/user/update.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 返回
5 | 修改信息
6 |
7 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
47 |
48 |
51 |
--------------------------------------------------------------------------------
/pages/user/updatePwd.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 返回
5 | 修改密码
6 |
7 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
72 |
73 |
76 |
--------------------------------------------------------------------------------
/plugin/tools.js:
--------------------------------------------------------------------------------
1 | import dayjs from 'dayjs';
2 |
3 |
4 | function timeFormat(val) {
5 | let now = dayjs();
6 | let day1 = dayjs(val);
7 |
8 | let diff = {
9 | second: now.diff(day1, 'second'),
10 | minute: now.diff(day1, 'minute'),
11 | hour: now.diff(day1, 'hour'),
12 | day: now.diff(day1, 'day'),
13 | year: now.diff(day1, 'year'),
14 | }
15 |
16 | if (diff.second <= 60) {
17 | return diff.second + '秒前';
18 | } else if (diff.minute < 60) {
19 | return diff.minute + '分钟前';
20 | } else if (diff.hour < 24) {
21 | return diff.hour + '小时前';
22 | } else if (diff.day < 365) {
23 | return diff.day + '天前';
24 | } else {
25 | return diff.year + '年前';
26 | }
27 | }
28 |
29 |
30 | export {
31 | timeFormat
32 | }
33 |
--------------------------------------------------------------------------------
/static/avatar.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/static/bg.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wyml/MTRR/eb9bdc7b228d680c0ae8fac19600fe9043585e2b/static/bg.png
--------------------------------------------------------------------------------
/static/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wyml/MTRR/eb9bdc7b228d680c0ae8fac19600fe9043585e2b/static/logo.png
--------------------------------------------------------------------------------
/static/user.jpeg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/wyml/MTRR/eb9bdc7b228d680c0ae8fac19600fe9043585e2b/static/user.jpeg
--------------------------------------------------------------------------------
/store/index.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import Vuex from 'vuex'
3 |
4 | Vue.use(Vuex);
5 | const store = new Vuex.Store({
6 | state: {
7 | isLogin: false,
8 | user: {},
9 | rsslist: []
10 | },
11 | mutations: {
12 | login(state, userInfo) {
13 | state.user = userInfo;
14 | state.isLogin = true;
15 | uni.setStorage({
16 | key: 'user',
17 | data: JSON.stringify(userInfo)
18 | });
19 | uni.setStorage({
20 | key: 'isLogin',
21 | data: JSON.stringify(true)
22 | });
23 | },
24 | logout(state) {
25 | state.user = {},
26 | state.isLogin = false;
27 | uni.removeStorage({
28 | key: 'user'
29 | });
30 | uni.removeStorage({
31 | key: 'isLogin'
32 | });
33 | },
34 | pushRssList(state, rss) {
35 | state.rsslist.push(rss);
36 | uni.setStorage({
37 | key: 'rsslist',
38 | data: JSON.stringify(state.rsslist)
39 | })
40 | },
41 | editRssList(state, param) {
42 | state.rsslist[param.index] = param.form;
43 | uni.setStorage({
44 | key: 'rsslist',
45 | data: JSON.stringify(state.rsslist)
46 | })
47 | },
48 | removeRssList(state, index) {
49 | state.rsslist = state.rsslist.splice(index, 1);
50 | uni.setStorage({
51 | key: 'rsslist',
52 | data: JSON.stringify(state.rsslist)
53 | })
54 | }
55 | },
56 | actions: {
57 |
58 | }
59 | });
60 |
61 | export default store;
62 |
--------------------------------------------------------------------------------
/utils/api.js:
--------------------------------------------------------------------------------
1 | import request from './request';
2 |
3 | const http = new request();
4 | http.setConfig((config) => {
5 | config.baseUrl = 'https://rss.kingsr.cc';
6 | config.header = {
7 | ...config.header,
8 | Authorization: uni.getStorageSync('token') || null,
9 | }
10 | return config;
11 | });
12 |
13 | const uploadRssList = async function() {
14 | function upload() {
15 | return new Promise((resolve, reject) => {
16 | let list = JSON.parse(uni.getStorageSync('rsslist'));
17 | http.post("/member/uploadRss", {
18 | rsslist: list
19 | })
20 | .then(res => {
21 | resolve(res);
22 | })
23 | .catch(res => {
24 | reject(res);
25 | })
26 | })
27 | }
28 | return await upload();
29 | }
30 |
31 | export {
32 | http,
33 | uploadRssList
34 | }
35 |
--------------------------------------------------------------------------------
/utils/database.js:
--------------------------------------------------------------------------------
1 | const get = uni.getStorageSync();
2 | const set = uni.setStorageSync();
3 |
4 | class database
5 | {
6 | this.where(key,val){
7 |
8 | }
9 | }
--------------------------------------------------------------------------------
/utils/refreshRss.js:
--------------------------------------------------------------------------------
1 | function getRss() {
2 |
3 | }
4 | const refresh = function() {
5 | var timer = setInterval(() => {
6 |
7 | }, 60000);
8 | }
9 |
--------------------------------------------------------------------------------
/utils/request.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Request 1.0.5
3 | * @Class Request
4 | * @description luch-request 1.0.4 http请求插件
5 | * @Author lu-ch
6 | * @Date 2019-12-12
7 | * @Email webwork.s@qq.com
8 | * http://ext.dcloud.net.cn/plugin?id=392
9 | */
10 | export default class Request {
11 | config = {
12 | baseUrl: '',
13 | header: {
14 | 'content-type': 'application/json;charset=UTF-8'
15 | },
16 | method: 'GET',
17 | dataType: 'json',
18 | // #ifndef MP-ALIPAY || APP-PLUS
19 | responseType: 'text',
20 | // #endif
21 | custom: {},
22 | // #ifdef MP-ALIPAY
23 | timeout: 30000,
24 | // #endif
25 | // #ifdef APP-PLUS
26 | sslVerify: true
27 | // #endif
28 | }
29 |
30 | static posUrl (url) { /* 判断url是否为绝对路径 */
31 | return /(http|https):\/\/([\w.]+\/?)\S*/.test(url)
32 | }
33 |
34 | static addQueryString (params) {
35 | let paramsData = ''
36 | Object.keys(params).forEach(function (key) {
37 | paramsData += key + '=' + encodeURIComponent(params[key]) + '&'
38 | })
39 | return paramsData.substring(0, paramsData.length - 1)
40 | }
41 |
42 | /**
43 | * @property {Function} request 请求拦截器
44 | * @property {Function} response 响应拦截器
45 | * @type {{request: Request.interceptor.request, response: Request.interceptor.response}}
46 | */
47 | interceptor = {
48 | /**
49 | * @param {Request~requestCallback} cb - 请求之前拦截,接收一个函数(config, cancel)=> {return config}。第一个参数为全局config,第二个参数为函数,调用则取消本次请求。
50 | */
51 | request: (cb) => {
52 | if (cb) {
53 | this.requestBeforeFun = cb
54 | }
55 | },
56 | /**
57 | * @param {Request~responseCallback} cb 响应拦截器,对响应数据做点什么
58 | * @param {Request~responseErrCallback} ecb 响应拦截器,对响应错误做点什么
59 | */
60 | response: (cb, ecb) => {
61 | if (cb && ecb) {
62 | this.requestComFun = cb
63 | this.requestComFail = ecb
64 | }
65 | }
66 | }
67 |
68 | requestBeforeFun (config) {
69 | return config
70 | }
71 |
72 | requestComFun (response) {
73 | return response
74 | }
75 |
76 | requestComFail (response) {
77 | return response
78 | }
79 |
80 | /**
81 | * 自定义验证器,如果返回true 则进入响应拦截器的响应成功函数(resolve),否则进入响应拦截器的响应错误函数(reject)
82 | * @param { Number } statusCode - 请求响应体statusCode(只读)
83 | * @return { Boolean } 如果为true,则 resolve, 否则 reject
84 | */
85 | validateStatus (statusCode) {
86 | return statusCode === 200
87 | }
88 |
89 | /**
90 | * @Function
91 | * @param {Request~setConfigCallback} f - 设置全局默认配置
92 | */
93 | setConfig (f) {
94 | this.config = f(this.config)
95 | }
96 |
97 | /**
98 | * @Function
99 | * @param {Object} options - 请求配置项
100 | * @prop {String} options.url - 请求路径
101 | * @prop {Object} options.data - 请求参数
102 | * @prop {Object} [options.responseType = config.responseType] [text|arraybuffer] - 响应的数据类型
103 | * @prop {Object} [options.dataType = config.dataType] - 如果设为 json,会尝试对返回的数据做一次 JSON.parse
104 | * @prop {Object} [options.header = config.header] - 请求header
105 | * @prop {Object} [options.method = config.method] - 请求方法
106 | * @returns {Promise}
107 | */
108 | async request (options = {}) {
109 | options.baseUrl = this.config.baseUrl
110 | options.dataType = options.dataType || this.config.dataType
111 | // #ifndef MP-ALIPAY || APP-PLUS
112 | options.responseType = options.responseType || this.config.responseType
113 | // #endif
114 | // #ifdef MP-ALIPAY
115 | options.timeout = options.timeout || this.config.timeout
116 | // #endif
117 | options.url = options.url || ''
118 | options.data = options.data || {}
119 | options.params = options.params || {}
120 | options.header = options.header || this.config.header
121 | options.method = options.method || this.config.method
122 | options.custom = { ...this.config.custom, ...(options.custom || {}) }
123 | // #ifdef APP-PLUS
124 | options.sslVerify = options.sslVerify === undefined ? this.config.sslVerify : options.sslVerify
125 | // #endif
126 | return new Promise((resolve, reject) => {
127 | let next = true
128 |
129 | let handleRe = {}
130 | options.complete = (response) => {
131 | response.config = handleRe
132 | if (this.validateStatus(response.statusCode)) { // 成功
133 | response = this.requestComFun(response)
134 | resolve(response)
135 | } else {
136 | response = this.requestComFail(response)
137 | reject(response)
138 | }
139 | }
140 | const cancel = (t = 'handle cancel', config = options) => {
141 | const err = {
142 | errMsg: t,
143 | config: config
144 | }
145 | reject(err)
146 | next = false
147 | }
148 |
149 | handleRe = { ...this.requestBeforeFun(options, cancel) }
150 | const _config = { ...handleRe }
151 | if (!next) return
152 | delete _config.custom
153 | let mergeUrl = Request.posUrl(_config.url) ? _config.url : (_config.baseUrl + _config.url)
154 | if (JSON.stringify(_config.params) !== '{}') {
155 | const paramsH = Request.addQueryString(_config.params)
156 | mergeUrl += mergeUrl.indexOf('?') === -1 ? `?${paramsH}` : `&${paramsH}`
157 | }
158 | _config.url = mergeUrl
159 | uni.request(_config)
160 | })
161 | }
162 |
163 | get (url, options = {}) {
164 | return this.request({
165 | url,
166 | method: 'GET',
167 | ...options
168 | })
169 | }
170 |
171 | post (url, data, options = {}) {
172 | return this.request({
173 | url,
174 | data,
175 | method: 'POST',
176 | ...options
177 | })
178 | }
179 |
180 | // #ifndef MP-ALIPAY
181 | put (url, data, options = {}) {
182 | return this.request({
183 | url,
184 | data,
185 | method: 'PUT',
186 | ...options
187 | })
188 | }
189 |
190 | // #endif
191 |
192 | // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
193 | delete (url, data, options = {}) {
194 | return this.request({
195 | url,
196 | data,
197 | method: 'DELETE',
198 | ...options
199 | })
200 | }
201 |
202 | // #endif
203 |
204 | // #ifdef APP-PLUS || H5 || MP-WEIXIN
205 | connect (url, data, options = {}) {
206 | return this.request({
207 | url,
208 | data,
209 | method: 'CONNECT',
210 | ...options
211 | })
212 | }
213 |
214 | // #endif
215 |
216 | // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
217 | head (url, data, options = {}) {
218 | return this.request({
219 | url,
220 | data,
221 | method: 'HEAD',
222 | ...options
223 | })
224 | }
225 |
226 | // #endif
227 |
228 | // #ifdef APP-PLUS || H5 || MP-WEIXIN || MP-BAIDU
229 | options (url, data, options = {}) {
230 | return this.request({
231 | url,
232 | data,
233 | method: 'OPTIONS',
234 | ...options
235 | })
236 | }
237 |
238 | // #endif
239 |
240 | // #ifdef APP-PLUS || H5 || MP-WEIXIN
241 | trace (url, data, options = {}) {
242 | return this.request({
243 | url,
244 | data,
245 | method: 'TRACE',
246 | ...options
247 | })
248 | }
249 |
250 | // #endif
251 |
252 | upload (url, {
253 | // #ifdef APP-PLUS
254 | files,
255 | // #endif
256 | // #ifdef MP-ALIPAY
257 | fileType,
258 | // #endif
259 | filePath,
260 | name,
261 | header,
262 | formData,
263 | custom
264 | }) {
265 | return new Promise((resolve, reject) => {
266 | let next = true
267 | let handleRe = {}
268 | const globalHeader = { ...this.config.header }
269 | delete globalHeader['content-type']
270 | const pubConfig = {
271 | baseUrl: this.config.baseUrl,
272 | url,
273 | // #ifdef APP-PLUS
274 | files,
275 | // #endif
276 | // #ifdef MP-ALIPAY
277 | fileType,
278 | // #endif
279 | filePath,
280 | method: 'UPLOAD',
281 | name,
282 | header: header || globalHeader,
283 | formData,
284 | custom: { ...this.config.custom, ...(custom || {}) },
285 | complete: (response) => {
286 | response.config = handleRe
287 | if (response.statusCode === 200) { // 成功
288 | response = this.requestComFun(response)
289 | resolve(response)
290 | } else {
291 | response = this.requestComFail(response)
292 | reject(response)
293 | }
294 | }
295 | }
296 | const cancel = (t = 'handle cancel', config = pubConfig) => {
297 | const err = {
298 | errMsg: t,
299 | config: config
300 | }
301 | reject(err)
302 | next = false
303 | }
304 |
305 | handleRe = { ...this.requestBeforeFun(pubConfig, cancel) }
306 | const _config = { ...handleRe }
307 | if (!next) return
308 | delete _config.custom
309 | _config.url = Request.posUrl(_config.url) ? _config.url : (_config.baseUrl + _config.url)
310 | uni.uploadFile(_config)
311 | })
312 | }
313 | }
314 |
315 | /**
316 | * setConfig回调
317 | * @return {Object} - 返回操作后的config
318 | * @callback Request~setConfigCallback
319 | * @param {Object} config - 全局默认config
320 | */
321 | /**
322 | * 请求拦截器回调
323 | * @return {Object} - 返回操作后的config
324 | * @callback Request~requestCallback
325 | * @param {Object} config - 全局config
326 | * @param {Function} [cancel] - 取消请求钩子,调用会取消本次请求
327 | */
328 | /**
329 | * 响应拦截器回调
330 | * @return {Object} - 返回操作后的response
331 | * @callback Request~responseCallback
332 | * @param {Object} response - 请求结果 response
333 | */
334 | /**
335 | * 响应错误拦截器回调
336 | * @return {Object} - 返回操作后的response
337 | * @callback Request~responseErrCallback
338 | * @param {Object} response - 请求结果 response
339 | */
340 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@sindresorhus/is@^2.0.0":
6 | version "2.1.0"
7 | resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-2.1.0.tgz#6ad4ca610f696098e92954ab431ff83bea0ce13f"
8 | integrity sha512-lXKXfypKo644k4Da4yXkPCrwcvn6SlUW2X2zFbuflKHNjf0w9htru01bo26uMhleMXsDmnZ12eJLdrAZa9MANg==
9 |
10 | "@szmarczak/http-timer@^4.0.0":
11 | version "4.0.5"
12 | resolved "https://registry.yarnpkg.com/@szmarczak/http-timer/-/http-timer-4.0.5.tgz#bfbd50211e9dfa51ba07da58a14cdfd333205152"
13 | integrity sha512-PyRA9sm1Yayuj5OIoJ1hGt2YISX45w9WcFbh6ddT0Z/0yaFxOtGLInr4jUfU1EAFVs0Yfyfev4RNwBlUaHdlDQ==
14 | dependencies:
15 | defer-to-connect "^2.0.0"
16 |
17 | "@types/cacheable-request@^6.0.1":
18 | version "6.0.1"
19 | resolved "https://registry.yarnpkg.com/@types/cacheable-request/-/cacheable-request-6.0.1.tgz#5d22f3dded1fd3a84c0bbeb5039a7419c2c91976"
20 | integrity sha512-ykFq2zmBGOCbpIXtoVbz4SKY5QriWPh3AjyU4G74RYbtt5yOc5OfaY75ftjg7mikMOla1CTGpX3lLbuJh8DTrQ==
21 | dependencies:
22 | "@types/http-cache-semantics" "*"
23 | "@types/keyv" "*"
24 | "@types/node" "*"
25 | "@types/responselike" "*"
26 |
27 | "@types/http-cache-semantics@*":
28 | version "4.0.0"
29 | resolved "https://registry.yarnpkg.com/@types/http-cache-semantics/-/http-cache-semantics-4.0.0.tgz#9140779736aa2655635ee756e2467d787cfe8a2a"
30 | integrity sha512-c3Xy026kOF7QOTn00hbIllV1dLR9hG9NkSrLQgCVs8NF6sBU+VGWjD3wLPhmh1TYAc7ugCFsvHYMN4VcBN1U1A==
31 |
32 | "@types/keyv@*":
33 | version "3.1.1"
34 | resolved "https://registry.yarnpkg.com/@types/keyv/-/keyv-3.1.1.tgz#e45a45324fca9dab716ab1230ee249c9fb52cfa7"
35 | integrity sha512-MPtoySlAZQ37VoLaPcTHCu1RWJ4llDkULYZIzOYxlhxBqYPB0RsRlmMU0R6tahtFe27mIdkHV+551ZWV4PLmVw==
36 | dependencies:
37 | "@types/node" "*"
38 |
39 | "@types/node@*":
40 | version "13.7.7"
41 | resolved "https://registry.yarnpkg.com/@types/node/-/node-13.7.7.tgz#1628e6461ba8cc9b53196dfeaeec7b07fa6eea99"
42 | integrity sha512-Uo4chgKbnPNlxQwoFmYIwctkQVkMMmsAoGGU4JKwLuvBefF0pCq4FybNSnfkfRCpC7ZW7kttcC/TrRtAJsvGtg==
43 |
44 | "@types/responselike@*":
45 | version "1.0.0"
46 | resolved "https://registry.yarnpkg.com/@types/responselike/-/responselike-1.0.0.tgz#251f4fe7d154d2bad125abe1b429b23afd262e29"
47 | integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==
48 | dependencies:
49 | "@types/node" "*"
50 |
51 | boolbase@~1.0.0:
52 | version "1.0.0"
53 | resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
54 | integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
55 |
56 | cacheable-lookup@^2.0.0:
57 | version "2.0.0"
58 | resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-2.0.0.tgz#33b1e56f17507f5cf9bb46075112d65473fb7713"
59 | integrity sha512-s2piO6LvA7xnL1AR03wuEdSx3BZT3tIJpZ56/lcJwzO/6DTJZlTs7X3lrvPxk6d1PlDe6PrVe2TjlUIZNFglAQ==
60 | dependencies:
61 | keyv "^4.0.0"
62 |
63 | cacheable-request@^7.0.1:
64 | version "7.0.1"
65 | resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-7.0.1.tgz#062031c2856232782ed694a257fa35da93942a58"
66 | integrity sha512-lt0mJ6YAnsrBErpTMWeu5kl/tg9xMAWjavYTN6VQXM1A/teBITuNcccXsCxF0tDQQJf9DfAaX5O4e0zp0KlfZw==
67 | dependencies:
68 | clone-response "^1.0.2"
69 | get-stream "^5.1.0"
70 | http-cache-semantics "^4.0.0"
71 | keyv "^4.0.0"
72 | lowercase-keys "^2.0.0"
73 | normalize-url "^4.1.0"
74 | responselike "^2.0.0"
75 |
76 | cheerio@^1.0.0-rc.3:
77 | version "1.0.0-rc.3"
78 | resolved "https://registry.yarnpkg.com/cheerio/-/cheerio-1.0.0-rc.3.tgz#094636d425b2e9c0f4eb91a46c05630c9a1a8bf6"
79 | integrity sha512-0td5ijfUPuubwLUu0OBoe98gZj8C/AA+RW3v67GPlGOrvxWjZmBXiBCRU+I8VEiNyJzjth40POfHiz2RB3gImA==
80 | dependencies:
81 | css-select "~1.2.0"
82 | dom-serializer "~0.1.1"
83 | entities "~1.1.1"
84 | htmlparser2 "^3.9.1"
85 | lodash "^4.15.0"
86 | parse5 "^3.0.1"
87 |
88 | clone-response@^1.0.2:
89 | version "1.0.2"
90 | resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b"
91 | integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws=
92 | dependencies:
93 | mimic-response "^1.0.0"
94 |
95 | css-select@~1.2.0:
96 | version "1.2.0"
97 | resolved "https://registry.yarnpkg.com/css-select/-/css-select-1.2.0.tgz#2b3a110539c5355f1cd8d314623e870b121ec858"
98 | integrity sha1-KzoRBTnFNV8c2NMUYj6HCxIeyFg=
99 | dependencies:
100 | boolbase "~1.0.0"
101 | css-what "2.1"
102 | domutils "1.5.1"
103 | nth-check "~1.0.1"
104 |
105 | css-what@2.1:
106 | version "2.1.3"
107 | resolved "https://registry.yarnpkg.com/css-what/-/css-what-2.1.3.tgz#a6d7604573365fe74686c3f311c56513d88285f2"
108 | integrity sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==
109 |
110 | dayjs@^1.8.21:
111 | version "1.8.21"
112 | resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.8.21.tgz#98299185b72b9b679f31c7ed987b63923c961552"
113 | integrity sha512-1kbWK0hziklUHkGgiKr7xm59KwAg/K3Tp7H/8X+f58DnNCwY3pKYjOCJpIlVs125FRBukGVZdKZojC073D0IeQ==
114 |
115 | decompress-response@^5.0.0:
116 | version "5.0.0"
117 | resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-5.0.0.tgz#7849396e80e3d1eba8cb2f75ef4930f76461cb0f"
118 | integrity sha512-TLZWWybuxWgoW7Lykv+gq9xvzOsUjQ9tF09Tj6NSTYGMTCHNXzrPnD6Hi+TgZq19PyTAGH4Ll/NIM/eTGglnMw==
119 | dependencies:
120 | mimic-response "^2.0.0"
121 |
122 | defer-to-connect@^2.0.0:
123 | version "2.0.0"
124 | resolved "https://registry.yarnpkg.com/defer-to-connect/-/defer-to-connect-2.0.0.tgz#83d6b199db041593ac84d781b5222308ccf4c2c1"
125 | integrity sha512-bYL2d05vOSf1JEZNx5vSAtPuBMkX8K9EUutg7zlKvTqKXHt7RhWJFbmd7qakVuf13i+IkGmp6FwSsONOf6VYIg==
126 |
127 | dom-serializer@0:
128 | version "0.2.2"
129 | resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.2.2.tgz#1afb81f533717175d478655debc5e332d9f9bb51"
130 | integrity sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==
131 | dependencies:
132 | domelementtype "^2.0.1"
133 | entities "^2.0.0"
134 |
135 | dom-serializer@~0.1.1:
136 | version "0.1.1"
137 | resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0"
138 | integrity sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==
139 | dependencies:
140 | domelementtype "^1.3.0"
141 | entities "^1.1.1"
142 |
143 | domelementtype@1, domelementtype@^1.3.0, domelementtype@^1.3.1:
144 | version "1.3.1"
145 | resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.3.1.tgz#d048c44b37b0d10a7f2a3d5fee3f4333d790481f"
146 | integrity sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==
147 |
148 | domelementtype@^2.0.1:
149 | version "2.0.1"
150 | resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.0.1.tgz#1f8bdfe91f5a78063274e803b4bdcedf6e94f94d"
151 | integrity sha512-5HOHUDsYZWV8FGWN0Njbr/Rn7f/eWSQi1v7+HsUVwXgn8nWWlL64zKDkS0n8ZmQ3mlWOMuXOnR+7Nx/5tMO5AQ==
152 |
153 | domhandler@^2.3.0:
154 | version "2.4.2"
155 | resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.4.2.tgz#8805097e933d65e85546f726d60f5eb88b44f803"
156 | integrity sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==
157 | dependencies:
158 | domelementtype "1"
159 |
160 | domutils@1.5.1:
161 | version "1.5.1"
162 | resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.5.1.tgz#dcd8488a26f563d61079e48c9f7b7e32373682cf"
163 | integrity sha1-3NhIiib1Y9YQeeSMn3t+Mjc2gs8=
164 | dependencies:
165 | dom-serializer "0"
166 | domelementtype "1"
167 |
168 | domutils@^1.5.1:
169 | version "1.7.0"
170 | resolved "https://registry.yarnpkg.com/domutils/-/domutils-1.7.0.tgz#56ea341e834e06e6748af7a1cb25da67ea9f8c2a"
171 | integrity sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==
172 | dependencies:
173 | dom-serializer "0"
174 | domelementtype "1"
175 |
176 | duplexer3@^0.1.4:
177 | version "0.1.4"
178 | resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
179 | integrity sha1-7gHdHKwO08vH/b6jfcCo8c4ALOI=
180 |
181 | end-of-stream@^1.1.0:
182 | version "1.4.4"
183 | resolved "https://registry.yarnpkg.com/end-of-stream/-/end-of-stream-1.4.4.tgz#5ae64a5f45057baf3626ec14da0ca5e4b2431eb0"
184 | integrity sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==
185 | dependencies:
186 | once "^1.4.0"
187 |
188 | entities@^1.1.1, entities@~1.1.1:
189 | version "1.1.2"
190 | resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.2.tgz#bdfa735299664dfafd34529ed4f8522a275fea56"
191 | integrity sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==
192 |
193 | entities@^2.0.0:
194 | version "2.0.0"
195 | resolved "https://registry.yarnpkg.com/entities/-/entities-2.0.0.tgz#68d6084cab1b079767540d80e56a39b423e4abf4"
196 | integrity sha512-D9f7V0JSRwIxlRI2mjMqufDrRDnx8p+eEOz7aUM9SuvF8gsBzra0/6tbjl1m8eQHrZlYj6PxqE00hZ1SAIKPLw==
197 |
198 | get-stream@^5.0.0, get-stream@^5.1.0:
199 | version "5.1.0"
200 | resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-5.1.0.tgz#01203cdc92597f9b909067c3e656cc1f4d3c4dc9"
201 | integrity sha512-EXr1FOzrzTfGeL0gQdeFEvOMm2mzMOglyiOXSTpPC+iAjAKftbr3jpCMWynogwYnM+eSj9sHGc6wjIcDvYiygw==
202 | dependencies:
203 | pump "^3.0.0"
204 |
205 | got@^10.6.0:
206 | version "10.6.0"
207 | resolved "https://registry.yarnpkg.com/got/-/got-10.6.0.tgz#ac3876261a4d8e5fc4f81186f79955ce7b0501dc"
208 | integrity sha512-3LIdJNTdCFbbJc+h/EH0V5lpNpbJ6Bfwykk21lcQvQsEcrzdi/ltCyQehFHLzJ/ka0UMH4Slg0hkYvAZN9qUDg==
209 | dependencies:
210 | "@sindresorhus/is" "^2.0.0"
211 | "@szmarczak/http-timer" "^4.0.0"
212 | "@types/cacheable-request" "^6.0.1"
213 | cacheable-lookup "^2.0.0"
214 | cacheable-request "^7.0.1"
215 | decompress-response "^5.0.0"
216 | duplexer3 "^0.1.4"
217 | get-stream "^5.0.0"
218 | lowercase-keys "^2.0.0"
219 | mimic-response "^2.1.0"
220 | p-cancelable "^2.0.0"
221 | p-event "^4.0.0"
222 | responselike "^2.0.0"
223 | to-readable-stream "^2.0.0"
224 | type-fest "^0.10.0"
225 |
226 | htmlparser2@^3.9.1:
227 | version "3.10.1"
228 | resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-3.10.1.tgz#bd679dc3f59897b6a34bb10749c855bb53a9392f"
229 | integrity sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==
230 | dependencies:
231 | domelementtype "^1.3.1"
232 | domhandler "^2.3.0"
233 | domutils "^1.5.1"
234 | entities "^1.1.1"
235 | inherits "^2.0.1"
236 | readable-stream "^3.1.1"
237 |
238 | http-cache-semantics@^4.0.0:
239 | version "4.1.0"
240 | resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390"
241 | integrity sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==
242 |
243 | inherits@^2.0.1, inherits@^2.0.3:
244 | version "2.0.4"
245 | resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c"
246 | integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==
247 |
248 | json-buffer@3.0.1:
249 | version "3.0.1"
250 | resolved "https://registry.yarnpkg.com/json-buffer/-/json-buffer-3.0.1.tgz#9338802a30d3b6605fbe0613e094008ca8c05a13"
251 | integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==
252 |
253 | keyv@^4.0.0:
254 | version "4.0.0"
255 | resolved "https://registry.yarnpkg.com/keyv/-/keyv-4.0.0.tgz#2d1dab694926b2d427e4c74804a10850be44c12f"
256 | integrity sha512-U7ioE8AimvRVLfw4LffyOIRhL2xVgmE8T22L6i0BucSnBUyv4w+I7VN/zVZwRKHOI6ZRUcdMdWHQ8KSUvGpEog==
257 | dependencies:
258 | json-buffer "3.0.1"
259 |
260 | lodash@^4.15.0:
261 | version "4.17.15"
262 | resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
263 | integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
264 |
265 | lowercase-keys@^2.0.0:
266 | version "2.0.0"
267 | resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-2.0.0.tgz#2603e78b7b4b0006cbca2fbcc8a3202558ac9479"
268 | integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==
269 |
270 | marked@^0.8.0:
271 | version "0.8.0"
272 | resolved "https://registry.yarnpkg.com/marked/-/marked-0.8.0.tgz#ec5c0c9b93878dc52dd54be8d0e524097bd81a99"
273 | integrity sha512-MyUe+T/Pw4TZufHkzAfDj6HarCBWia2y27/bhuYkTaiUnfDYFnCP3KUN+9oM7Wi6JA2rymtVYbQu3spE0GCmxQ==
274 |
275 | mimic-response@^1.0.0:
276 | version "1.0.1"
277 | resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-1.0.1.tgz#4923538878eef42063cb8a3e3b0798781487ab1b"
278 | integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==
279 |
280 | mimic-response@^2.0.0, mimic-response@^2.1.0:
281 | version "2.1.0"
282 | resolved "https://registry.yarnpkg.com/mimic-response/-/mimic-response-2.1.0.tgz#d13763d35f613d09ec37ebb30bac0469c0ee8f43"
283 | integrity sha512-wXqjST+SLt7R009ySCglWBCFpjUygmCIfD790/kVbiGmUgfYGuB14PiTd5DwVxSV4NcYHjzMkoj5LjQZwTQLEA==
284 |
285 | normalize-url@^4.1.0:
286 | version "4.5.0"
287 | resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-4.5.0.tgz#453354087e6ca96957bd8f5baf753f5982142129"
288 | integrity sha512-2s47yzUxdexf1OhyRi4Em83iQk0aPvwTddtFz4hnSSw9dCEsLEGf6SwIO8ss/19S9iBb5sJaOuTvTGDeZI00BQ==
289 |
290 | nth-check@~1.0.1:
291 | version "1.0.2"
292 | resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-1.0.2.tgz#b2bd295c37e3dd58a3bf0700376663ba4d9cf05c"
293 | integrity sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==
294 | dependencies:
295 | boolbase "~1.0.0"
296 |
297 | once@^1.3.1, once@^1.4.0:
298 | version "1.4.0"
299 | resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
300 | integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
301 | dependencies:
302 | wrappy "1"
303 |
304 | p-cancelable@^2.0.0:
305 | version "2.0.0"
306 | resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-2.0.0.tgz#4a3740f5bdaf5ed5d7c3e34882c6fb5d6b266a6e"
307 | integrity sha512-wvPXDmbMmu2ksjkB4Z3nZWTSkJEb9lqVdMaCKpZUGJG9TMiNp9XcbG3fn9fPKjem04fJMJnXoyFPk2FmgiaiNg==
308 |
309 | p-event@^4.0.0:
310 | version "4.1.0"
311 | resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.1.0.tgz#e92bb866d7e8e5b732293b1c8269d38e9982bf8e"
312 | integrity sha512-4vAd06GCsgflX4wHN1JqrMzBh/8QZ4j+rzp0cd2scXRwuBEv+QR3wrVA5aLhWDLw4y2WgDKvzWF3CCLmVM1UgA==
313 | dependencies:
314 | p-timeout "^2.0.1"
315 |
316 | p-finally@^1.0.0:
317 | version "1.0.0"
318 | resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae"
319 | integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4=
320 |
321 | p-timeout@^2.0.1:
322 | version "2.0.1"
323 | resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038"
324 | integrity sha512-88em58dDVB/KzPEx1X0N3LwFfYZPyDc4B6eF38M1rk9VTZMbxXXgjugz8mmwpS9Ox4BDZ+t6t3QP5+/gazweIA==
325 | dependencies:
326 | p-finally "^1.0.0"
327 |
328 | parse5@^3.0.1:
329 | version "3.0.3"
330 | resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c"
331 | integrity sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==
332 | dependencies:
333 | "@types/node" "*"
334 |
335 | prettier@^1.12.1:
336 | version "1.19.1"
337 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.19.1.tgz#f7d7f5ff8a9cd872a7be4ca142095956a60797cb"
338 | integrity sha512-s7PoyDv/II1ObgQunCbB9PdLmUcBZcnWOcxDh7O0N/UwDEsHyqkW+Qh28jW+mVuCdx7gLB0BotYI1Y6uI9iyew==
339 |
340 | pump@^3.0.0:
341 | version "3.0.0"
342 | resolved "https://registry.yarnpkg.com/pump/-/pump-3.0.0.tgz#b4a2116815bde2f4e1ea602354e8c75565107a64"
343 | integrity sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==
344 | dependencies:
345 | end-of-stream "^1.1.0"
346 | once "^1.3.1"
347 |
348 | readable-stream@^3.1.1:
349 | version "3.6.0"
350 | resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.0.tgz#337bbda3adc0706bd3e024426a286d4b4b2c9198"
351 | integrity sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==
352 | dependencies:
353 | inherits "^2.0.3"
354 | string_decoder "^1.1.1"
355 | util-deprecate "^1.0.1"
356 |
357 | responselike@^2.0.0:
358 | version "2.0.0"
359 | resolved "https://registry.yarnpkg.com/responselike/-/responselike-2.0.0.tgz#26391bcc3174f750f9a79eacc40a12a5c42d7723"
360 | integrity sha512-xH48u3FTB9VsZw7R+vvgaKeLKzT6jOogbQhEe/jewwnZgzPcnyWui2Av6JpoYZF/91uueC+lqhWqeURw5/qhCw==
361 | dependencies:
362 | lowercase-keys "^2.0.0"
363 |
364 | safe-buffer@~5.2.0:
365 | version "5.2.0"
366 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.0.tgz#b74daec49b1148f88c64b68d49b1e815c1f2f519"
367 | integrity sha512-fZEwUGbVl7kouZs1jCdMLdt95hdIv0ZeHg6L7qPeciMZhZ+/gdesW4wgTARkrFWEpspjEATAzUGPG8N2jJiwbg==
368 |
369 | string_decoder@^1.1.1:
370 | version "1.3.0"
371 | resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e"
372 | integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==
373 | dependencies:
374 | safe-buffer "~5.2.0"
375 |
376 | to-readable-stream@^2.0.0:
377 | version "2.1.0"
378 | resolved "https://registry.yarnpkg.com/to-readable-stream/-/to-readable-stream-2.1.0.tgz#82880316121bea662cdc226adb30addb50cb06e8"
379 | integrity sha512-o3Qa6DGg1CEXshSdvWNX2sN4QHqg03SPq7U6jPXRahlQdl5dK8oXjkU/2/sGrnOZKeGV1zLSO8qPwyKklPPE7w==
380 |
381 | type-fest@^0.10.0:
382 | version "0.10.0"
383 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.10.0.tgz#7f06b2b9fbfc581068d1341ffabd0349ceafc642"
384 | integrity sha512-EUV9jo4sffrwlg8s0zDhP0T2WD3pru5Xi0+HTE3zTUmBaZNhfkite9PdSJwdXLwPVW0jnAHT56pZHIOYckPEiw==
385 |
386 | util-deprecate@^1.0.1:
387 | version "1.0.2"
388 | resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
389 | integrity sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=
390 |
391 | wrappy@1:
392 | version "1.0.2"
393 | resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
394 | integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
395 |
--------------------------------------------------------------------------------