├── .gitignore
├── server
├── data
│ └── .gitkeep
├── recovery.html
├── strftime.js
├── index.html
└── server.js
├── capt1.png
├── capt2.png
├── Cargo.toml
├── README.md
├── spark
├── server.js
└── index.html
├── index.html
├── crawler_595732.html
├── src
└── main.rs
└── Cargo.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | /target
2 |
--------------------------------------------------------------------------------
/server/data/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/capt1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ayuusweetfish/treasure-hole/HEAD/capt1.png
--------------------------------------------------------------------------------
/capt2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ayuusweetfish/treasure-hole/HEAD/capt2.png
--------------------------------------------------------------------------------
/Cargo.toml:
--------------------------------------------------------------------------------
1 | [package]
2 | name = "treasurehole"
3 | version = "0.1.0"
4 | edition = "2021"
5 |
6 | [dependencies]
7 | reqwest = { version = "0.11", features = ["socks"] }
8 | tokio = { version = "1", features = ["full"] }
9 | serde_json = "1.0"
10 | bytebuffer = "0.2.1"
11 | bytes = "*"
12 | futures = "0.3"
13 | regex = "1"
14 | iui = { git = "https://github.com/rust-native-ui/libui-rs", branch = "trunk" }
15 | chrono = "0.4"
16 |
--------------------------------------------------------------------------------
/server/recovery.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Treasure hole
6 |
7 |
8 |
26 |
27 |
28 |
问题恢复
29 |
所有中途出现问题的备份会在整理后发布在这里,请使用抓取时使用的 token 访问。若不慎丢失,请通过 GitHub 联系。
30 |
31 |
32 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## 🌐 在线版
2 |
3 | 在线版位于 [hole.botany.run](https://hole.botany.run/)。登录凭据不会被保存,理论上也不会泄露,但为安全起见,完成备份后建议注销后重新登录。
4 |
5 | ⚠️ 在线版抓取到的文字和图片可能会被合并归档,参与其他的树洞备份项目。此过程不会保留任何个人信息(如关注列表、投票),独立的备份压缩包将在事后全部删除,望知晓。
6 |
7 | ## 说明
8 |
9 | 
10 |
11 | #### 操作方法
12 |
13 | 1. 首先获得自己的令牌(token),具体参见树洞 [#595705](https://web.thuhole.com/##595705)。
14 | 2. 把 token 粘贴在“身份令牌”一栏中。
15 | 3. 选择“引用层数”,如指定为 2,则会保存所有关注的树洞、它们提到的树洞以及【它们提到的树洞中提到的树洞】。
16 | 4. 取决于访问树洞的方式,可能需要填写网络代理。若不了解,可尝试留空。
17 | 5. 点击“开始”,等待即可。
18 |
19 | 备份的内容会集中存放到程序所在位置旁边,其中包含一个网页 `index.html`,用浏览器打开之即可。
20 |
21 | 
22 |
23 | #### 常见问题
24 |
25 | 1. 提示“登录凭据已过期”
26 | - token 由数字与字母组成,请检查是否粘贴了多余内容如冒号、空格等。
27 | 2. 点击开始后长时间无反应
28 | - 请在树洞中提问并附上当前访问树洞的方式。
29 |
30 | Enjoy
31 |
32 | ## crawler\_595732.html
33 |
34 | 另外,如果已经使用 [#595732](https://web.thuhole.com/##595732) 提供的方法爬取关注列表,请直接下载 [crawler\_595732.html](https://raw.githubusercontent.com/kawa-yoiko/treasure-hole/master/crawler_595732.html),在浏览器中打开,选择爬取到的 JSON 文件即可。
35 |
36 | ## 技术信息
37 |
38 | 主程序:使用 [Rust](https://www.rust-lang.org/) 编译器构建。
39 |
40 | ```sh
41 | cargo build --release
42 |
43 | # 运行图形界面
44 | cargo run --release
45 | # 从命令行获取参数
46 | cargo run --release -- []
47 | ```
48 |
49 | 服务端:使用 [Deno](https://deno.land/) 运行。
50 |
51 | ```sh
52 | cd server
53 | deno run --allow-net --allow-run --allow-read server.js
54 | ```
55 |
--------------------------------------------------------------------------------
/server/strftime.js:
--------------------------------------------------------------------------------
1 | /* Port of strftime() by T. H. Doan (https://thdoan.github.io/strftime/)
2 | *
3 | * Day of year (%j) code based on Joe Orost's answer:
4 | * http://stackoverflow.com/questions/8619879/javascript-calculate-the-day-of-the-year-1-366
5 | *
6 | * Week number (%V) code based on Taco van den Broek's prototype:
7 | * http://techblog.procurios.nl/k/news/view/33796/14863/calculate-iso-8601-week-and-year-in-javascript.html
8 | */
9 | export function strftime(sFormat, date) {
10 | if (!(date instanceof Date)) date = new Date();
11 | var nDay = date.getDay(),
12 | nDate = date.getDate(),
13 | nMonth = date.getMonth(),
14 | nYear = date.getFullYear(),
15 | nHour = date.getHours(),
16 | aDays = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
17 | aMonths = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'],
18 | aDayCount = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
19 | isLeapYear = function() {
20 | return (nYear%4===0 && nYear%100!==0) || nYear%400===0;
21 | },
22 | getThursday = function() {
23 | var target = new Date(date);
24 | target.setDate(nDate - ((nDay+6)%7) + 3);
25 | return target;
26 | },
27 | zeroPad = function(nNum, nPad) {
28 | return ((Math.pow(10, nPad) + nNum) + '').slice(1);
29 | };
30 | return sFormat.replace(/%[a-z]/gi, function(sMatch) {
31 | return (({
32 | '%a': aDays[nDay].slice(0,3),
33 | '%A': aDays[nDay],
34 | '%b': aMonths[nMonth].slice(0,3),
35 | '%B': aMonths[nMonth],
36 | '%c': date.toUTCString(),
37 | '%C': Math.floor(nYear/100),
38 | '%d': zeroPad(nDate, 2),
39 | '%e': nDate,
40 | '%F': date.toISOString().slice(0,10),
41 | '%G': getThursday().getFullYear(),
42 | '%g': (getThursday().getFullYear() + '').slice(2),
43 | '%H': zeroPad(nHour, 2),
44 | '%I': zeroPad((nHour+11)%12 + 1, 2),
45 | '%j': zeroPad(aDayCount[nMonth] + nDate + ((nMonth>1 && isLeapYear()) ? 1 : 0), 3),
46 | '%k': nHour,
47 | '%l': (nHour+11)%12 + 1,
48 | '%m': zeroPad(nMonth + 1, 2),
49 | '%n': nMonth + 1,
50 | '%M': zeroPad(date.getMinutes(), 2),
51 | '%p': (nHour<12) ? 'AM' : 'PM',
52 | '%P': (nHour<12) ? 'am' : 'pm',
53 | '%s': Math.round(date.getTime()/1000),
54 | '%S': zeroPad(date.getSeconds(), 2),
55 | '%u': nDay || 7,
56 | '%V': (function() {
57 | var target = getThursday(),
58 | n1stThu = target.valueOf();
59 | target.setMonth(0, 1);
60 | var nJan1 = target.getDay();
61 | if (nJan1!==4) target.setMonth(0, 1 + ((4-nJan1)+7)%7);
62 | return zeroPad(1 + Math.ceil((n1stThu-target)/604800000), 2);
63 | })(),
64 | '%w': nDay,
65 | '%x': date.toLocaleDateString(),
66 | '%X': date.toLocaleTimeString(),
67 | '%y': (nYear + '').slice(2),
68 | '%Y': nYear,
69 | '%z': date.toTimeString().replace(/.+GMT([+-]\d+).+/, '$1'),
70 | '%Z': date.toTimeString().replace(/.+\((.+?)\)$/, '$1')
71 | }[sMatch] || '') + '') || sMatch;
72 | });
73 | }
74 |
--------------------------------------------------------------------------------
/spark/server.js:
--------------------------------------------------------------------------------
1 | // deno run --allow-net --allow-read --allow-env %
2 |
3 | import { serve } from 'https://deno.land/std@0.117.0/http/server.ts';
4 | import { strftime } from '../server/strftime.js';
5 |
6 | // Do not go gentle into that good night
7 |
8 | const addr = ':1937';
9 |
10 | const indexHtmlContents = await Deno.readFile('index.html');
11 |
12 | // id => { log, fin, list };
13 | const ctx = {};
14 |
15 | Deno.env.set('TZ', 'Asia/Shanghai');
16 | const timestr = (ts) => strftime('%F %H:%M:%S', new Date(ts * 1000));
17 |
18 | const handler = async (req) => {
19 | const method = req.method;
20 | const path = new URL(req.url).pathname;
21 |
22 | if (method === 'GET' && path === '/') {
23 | return new Response(indexHtmlContents, { status: 200 });
24 | }
25 |
26 | const requestMatch = path.match(/^\/request\/([a-z0-9]{1,50})$/);
27 | if (method === 'POST' && requestMatch !== null) {
28 | const token = requestMatch[1];
29 | const date = strftime('%Y%m%d-%H%M%S');
30 | const id = `${date}-${token}`;
31 | if (ctx[id] !== undefined) {
32 | return new Response(null, { status: 400 });
33 | }
34 | const log = [];
35 | const list = [];
36 | ctx[id] = {
37 | log,
38 | list,
39 | };
40 | const worker = async () => {
41 | console.log(`${strftime('%F %H:%M:%S')} Starting ${id}`);
42 | let count = 0;
43 | for (let page = 1; ; page++) {
44 | const obj = await (await fetch(
45 | `https://tapi.thuhole.com/v3/contents/post/attentions?page=${page}`, {
46 | headers: { 'TOKEN': token },
47 | }
48 | )).json();
49 | if (obj.code !== 0) {
50 | log.splice(0, 0, `树洞返回错误:\n${obj.msg}\n======`);
51 | break;
52 | }
53 | if (obj.count === 0) break;
54 | for (const post of obj.data) {
55 | list.push(
56 | `=== #${post.pid} === ${timestr(post.timestamp)}
57 | ${post.text}`
58 | );
59 | const cmts = obj.comments[post.pid];
60 | if (cmts) {
61 | for (const cmt of cmts)
62 | list.push(
63 | `[${cmt.name}] ${timestr(cmt.timestamp)}
64 | ${cmt.text}`
65 | );
66 | if (post.reply > cmts.length) {
67 | list.push(
68 | `(还有 ${post.reply - cmts.length} 条)`
69 | );
70 | }
71 | }
72 | }
73 | count += obj.data.length;
74 | const word = (Math.random() <= 0.01 ? '咕咕。' : '咕嘟。');
75 | log.splice(0, 0, `${word}第 ${page} 页,合计 ${count} 条`);
76 | if (log.length >= 50) log.pop();
77 | }
78 | log.splice(0, 0, `完成`);
79 | log.splice(1, 0, `有效期 10 分钟,请及时下载~\n======`);
80 | ctx[id].fin = true;
81 | console.log(`${strftime('%F %H:%M:%S')} Finished ${id}`);
82 | // Remove after 10 minutes
83 | setTimeout(() => delete ctx[id], 600000);
84 | };
85 | worker(); // Do not await
86 | return new Response(id, { status: 200 });
87 | }
88 |
89 | const logMatch = path.match(/^\/log\/([a-z0-9\-]{1,50})$/);
90 | if (method === 'GET' && logMatch !== null) {
91 | const id = logMatch[1];
92 | const c = ctx[id];
93 | if (c === undefined) {
94 | return new Response('Not found', { status: 404 });
95 | }
96 | return new Response(JSON.stringify({
97 | fin: !!c.fin,
98 | log: c.log,
99 | }), { status: 200 });
100 | }
101 |
102 | const downloadMatch = path.match(/^\/download\/([a-z0-9\-]{1,50})$/);
103 | if (method === 'GET' && downloadMatch !== null) {
104 | const id = downloadMatch[1];
105 | const c = ctx[id];
106 | if (c === undefined) {
107 | return new Response('Not found', { status: 404 });
108 | }
109 | return new Response(c.list.join('\n\n'), {
110 | headers: {
111 | 'Content-Type': 'text/plain',
112 | 'Content-Disposition': 'attachment; filename="attentions.txt"',
113 | },
114 | status: 200,
115 | });
116 | }
117 |
118 | return new Response('Not found', { status: 404 });
119 | };
120 |
121 | console.log(`Running at http://localhost${addr}/`);
122 | await serve(handler, { addr });
123 |
--------------------------------------------------------------------------------
/spark/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Treasure hole
6 |
7 |
8 |
79 |
80 |
81 |
Token
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
142 |
143 |
--------------------------------------------------------------------------------
/server/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Treasure hole
6 |
7 |
8 |
79 |
80 |
81 |
Token
83 |
84 |
85 |
层数
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
147 |
148 |
--------------------------------------------------------------------------------
/server/server.js:
--------------------------------------------------------------------------------
1 | import { serve } from 'https://deno.land/std@0.117.0/http/server.ts';
2 | import { strftime } from './strftime.js';
3 | import staticFiles from "https://deno.land/x/static_files@1.1.4/mod.ts";
4 |
5 | const addr = ':1213';
6 |
7 | const EXEC_PATH = '../target/release/treasurehole';
8 | // Use proxy if needed, e.g.
9 | // const PROXY = 'http://127.0.0.1:1087';
10 | const PROXY = '';
11 |
12 | const indexHtmlContents = await Deno.readFile('index.html');
13 |
14 | const downloads = staticFiles('./data', {
15 | prefix: '/download'
16 | });
17 |
18 | // id => { log };
19 | const ctx = {};
20 |
21 | const retryRun = async (opts) => {
22 | while (true) {
23 | try {
24 | const proc = Deno.run(opts);
25 | return proc;
26 | } catch (ex) {
27 | console.log(`Arranging for retry: ${opts.cmd}`);
28 | await new Promise((resolve) => setTimeout(resolve, 5000))
29 | continue;
30 | }
31 | }
32 | }
33 |
34 | const handler = async (req) => {
35 | const method = req.method;
36 | const path = new URL(req.url).pathname;
37 |
38 | if (method === 'GET' && path === '/') {
39 | return new Response(indexHtmlContents, { status: 200 });
40 | }
41 |
42 | const requestMatch = path.match(/^\/request\/([a-z0-9]{1,50})\/(\d\d?)$/);
43 | if (method === 'POST' && requestMatch !== null) {
44 | const token = requestMatch[1];
45 | const levels = parseInt(requestMatch[2], 10);
46 | if (levels < 0 || levels > 10) {
47 | return new Response(null, { status: 400 });
48 | }
49 | const date = strftime('%Y%m%d-%H%M%S');
50 | const id = `${date}-${token}`;
51 | if (ctx[id] !== undefined) {
52 | return new Response(null, { status: 400 });
53 | }
54 | const log = [];
55 | ctx[id] = {
56 | log,
57 | };
58 | const worker = async () => {
59 | console.log(`Starting ${id} (levels = ${levels})`);
60 | const cmd = [
61 | EXEC_PATH,
62 | token,
63 | levels.toString(),
64 | `./data/${id}`,
65 | PROXY,
66 | ];
67 | const proc = await retryRun({
68 | cmd,
69 | stdout: 'null',
70 | stderr: 'piped',
71 | });
72 | const buf = new Uint8Array(4096);
73 | const decoder = new TextDecoder();
74 | const line = new Uint8Array(4096);
75 | let linePtr = 0;
76 | while (true) {
77 | const bytesRead = await proc.stderr.read(buf);
78 | if (bytesRead === null) break;
79 | for (let i = 0; i < bytesRead; i++) {
80 | if (buf[i] === 10) {
81 | log.splice(0, 0, decoder.decode(line.slice(0, linePtr)));
82 | if (log.length >= 100) log.pop();
83 | linePtr = 0;
84 | } else if (linePtr < line.length) {
85 | line[linePtr++] = buf[i];
86 | }
87 | }
88 | }
89 | if (linePtr !== 0) {
90 | log.splice(0, 0, decoder.decode(line.slice(0, linePtr)));
91 | if (log.length >= 100) log.pop();
92 | }
93 | // Successful?
94 | if (log[0] === '完成') {
95 | log.splice(0, 0, '压缩中\n======');
96 | // Compress
97 | const proc = await retryRun({
98 | cwd: './data',
99 | cmd: ['zip', id, '-r', id],
100 | stdout: 'null',
101 | stderr: 'null',
102 | });
103 | const { code } = await proc.status();
104 | if (code !== 0) {
105 | log.splice(0, 0, `压缩过程出现意外问题:${code}`);
106 | } else {
107 | log.splice(0, 0, '完成');
108 | }
109 | const rmProc = await retryRun({
110 | cmd: ['rm', '-rf', `./data/${id}`],
111 | stdout: 'null',
112 | stderr: 'null',
113 | });
114 | await rmProc.status();
115 | }
116 | ctx[id].fin = true;
117 | console.log(`Finished ${id}`);
118 | // Remove after 10 minutes
119 | setTimeout(() => delete ctx[id], 600000);
120 | };
121 | worker(); // Do not await
122 | return new Response(id, { status: 200 });
123 | }
124 |
125 | const logMatch = path.match(/^\/log\/([a-z0-9\-]{1,50})$/);
126 | if (method === 'GET' && logMatch !== null) {
127 | const id = logMatch[1];
128 | const c = ctx[id];
129 | if (c === undefined) {
130 | return new Response('Not found', { status: 404 });
131 | }
132 | return new Response(JSON.stringify({
133 | fin: !!c.fin,
134 | log: c.log,
135 | }), { status: 200 });
136 | }
137 |
138 | const zipMatch = path.match(/^\/download\/([a-z0-9\-]{1,50}).zip$/);
139 | if (method === 'GET' && zipMatch !== null) {
140 | const id = zipMatch[1];
141 | console.log(`Download ${id}`);
142 | return downloads({
143 | request: req,
144 | respondWith: r => r,
145 | });
146 | }
147 |
148 | if (method === 'GET' && path === '/recovery') {
149 | console.log(`Recovery`);
150 | const htmlContents = await Deno.readFile('recovery.html');
151 | return new Response(htmlContents, { status: 200 });
152 | }
153 |
154 | return new Response('Not found', { status: 404 });
155 | };
156 |
157 | console.log(`Running at http://localhost${addr}/`);
158 | await serve(handler, { addr });
159 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Treasure hole
6 |
7 |
8 |
9 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
↑
122 | 跳转
123 |
↓
124 |
125 |
※
126 |
131 |
132 |
133 |
![]()
134 |
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
147 |
148 |
149 |
150 |
![]()
151 |
152 |
153 |
154 |
155 |
160 |
161 |
162 | Re Bob: 正在做牌子,那到时候来C楼北边门口见吧
163 |
164 |
165 |
166 |
167 |
253 |
254 |
--------------------------------------------------------------------------------
/crawler_595732.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Treasure hole
6 |
7 |
8 |
9 |
113 |
114 |
115 |
122 |
160 |
161 |
162 |
163 |
164 |
165 |
166 |
167 |
168 |
↑
169 | 跳转
170 |
↓
171 |
172 |
※
173 |
178 |
179 |
180 |
![]()
181 |
182 |
183 |
184 |
185 |
186 |
187 |
188 |
189 |
194 |
195 |
196 |
197 |
![]()
198 |
199 |
200 |
201 |
202 |
207 |
208 |
209 | Re Bob: 正在做牌子,那到时候来C楼北边门口见吧
210 |
211 |
212 |
213 |
360 |
361 |
--------------------------------------------------------------------------------
/src/main.rs:
--------------------------------------------------------------------------------
1 | #![windows_subsystem = "windows"]
2 |
3 | use std::io::Write;
4 |
5 | #[derive(Debug)]
6 | pub struct StringError {
7 | s: String,
8 | }
9 |
10 | impl StringError {
11 | pub fn new(s: String) -> Self {
12 | Self { s }
13 | }
14 | }
15 |
16 | impl std::convert::From<&str> for StringError {
17 | fn from(s: &str) -> Self {
18 | Self { s: s.to_string() }
19 | }
20 | }
21 | impl std::convert::From for StringError {
22 | fn from(s: String) -> Self {
23 | Self { s }
24 | }
25 | }
26 |
27 | impl std::fmt::Display for StringError {
28 | fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
29 | write!(f, "{}", self.s)
30 | }
31 | }
32 | impl std::error::Error for StringError {}
33 |
34 | type DynResult = Result>;
35 |
36 | async fn fetch_bytes(client: &reqwest::Client, url: &str) -> DynResult {
37 | let resp = client.get(url).send().await?;
38 | let status = resp.status();
39 | if status.as_u16() != 200 {
40 | return Err(Box::new(StringError::from(format!("HTTP Status: {} {}",
41 | status.as_u16(),
42 | status.canonical_reason().unwrap_or("Unknown reason")))));
43 | }
44 |
45 | let body = resp.bytes().await?;
46 | Ok(body)
47 | }
48 |
49 | async fn fetch_json(client: &reqwest::Client, url: String) -> DynResult<(String, serde_json::Value)> {
50 | let body = fetch_bytes(client, &url).await?;
51 | let body = String::from_utf8((&body).to_vec())?;
52 | match serde_json::de::from_str::(&body) {
53 | Ok(r) => Ok((body, r)),
54 | _ => Err(Box::new(StringError::from("Cannot parse JSON document"))),
55 | }
56 | }
57 |
58 | macro_rules! expect_json_type {
59 | // Optional types
60 | ($value:expr, Option $variant:tt) => {
61 | match $value {
62 | Some(serde_json::Value::$variant(x)) => x,
63 | _ => return Err(Box::new(StringError::from(
64 | format!("Incorrect JSON format (line {})", line!())))),
65 | }
66 | };
67 | // Direct types
68 | ($value:expr, $variant:tt) => {
69 | match $value {
70 | serde_json::Value::$variant(x) => x,
71 | _ => return Err(Box::new(StringError::from(
72 | format!("Incorrect JSON format (line {})", line!())))),
73 | }
74 | };
75 | }
76 |
77 | async fn fetch_attn_pids(
78 | client: &reqwest::Client,
79 | tx: tokio::sync::mpsc::Sender<(bool, String)>,
80 | ) -> DynResult> {
81 | let mut pids = vec![];
82 |
83 | for page in 1.. {
84 | let url = format!("https://tapi.thuhole.com/v3/contents/post/attentions?page={}", page);
85 | let (_text, attns) = fetch_json(&client, url).await?;
86 |
87 | let attns = expect_json_type!(attns, Object);
88 | // println!("{:?}", attns);
89 |
90 | // Return code
91 | let code = expect_json_type!(attns.get("code"), Option Number).as_i64();
92 | match code {
93 | Some(code) if code != 0 => {
94 | return Err(Box::new(StringError::from(format!(
95 | "Incorrect code {}; message {}", code,
96 | expect_json_type!(attns.get("msg"), Option String)
97 | ))));
98 | },
99 | None => return Err(Box::new(StringError::from("Incorrect JSON format"))),
100 | _ => {},
101 | }
102 |
103 | let posts = expect_json_type!(attns.get("data"), Option Array);
104 | if posts.len() == 0 { break; }
105 |
106 | for post in posts {
107 | let pid = match expect_json_type!(post.get("pid"), Option Number).as_u64() {
108 | Some(x) => x,
109 | None => return Err(Box::new(StringError::from("Incorrect JSON format"))),
110 | };
111 | pids.push(pid);
112 | }
113 |
114 | tx.send((false, format!("获取收藏列表(第 {} 页,{} 条)", page, pids.len()))).await.unwrap();
115 | // XXX: debug use
116 | // if page >= 1 { break; }
117 | }
118 |
119 | // XXX: debug use
120 | // return Ok(pids[0..5].to_vec());
121 |
122 | Ok(pids)
123 | }
124 |
125 | async fn fetch_and_save_image(
126 | client: &reqwest::Client,
127 | url: &str,
128 | wd: &std::path::Path,
129 | ) -> DynResult {
130 | let url = format!("https://i.thuhole.com/{}", url);
131 | let bytes = fetch_bytes(client, &url).await?;
132 |
133 | let paths = url.split('/').collect::>();
134 | let mut wd_path = std::path::PathBuf::from(wd);
135 | wd_path.push("images");
136 | wd_path.push(paths.last().unwrap());
137 | let mut f = std::fs::File::create(&wd_path)?;
138 | f.write_all(&bytes)?;
139 |
140 | Ok(())
141 | }
142 |
143 | async fn fetch_and_save_posts(
144 | client: &reqwest::Client,
145 | tx: tokio::sync::mpsc::Sender<(bool, String)>,
146 | pids: &[u64],
147 | f: &mut std::fs::File,
148 | wd: &std::path::Path,
149 | ) -> DynResult> {
150 | let mut images = vec![];
151 | let mut ref_pids = vec![];
152 |
153 | let re_post_ref = regex::Regex::new(r"#(\d{1,})").unwrap();
154 |
155 | // Fetch each post and write to file
156 | for (i, pid_chunk) in pids.chunks(10).enumerate() {
157 | let text_futs = pid_chunk.iter().map(|&pid| {
158 | let url = format!("https://tapi.thuhole.com/v3/contents/post/detail?pid={}", pid);
159 | fetch_json(&client, url)
160 | });
161 | tx.send((false, format!("获取帖子内容({}/{},起始 #{})",
162 | std::cmp::min((i + 1) * 10, pids.len()),
163 | pids.len(),
164 | pid_chunk[0],
165 | ))).await.unwrap();
166 | let results = futures::future::try_join_all(text_futs).await?;
167 |
168 | for (post_text, post_json) in results {
169 | // Error?
170 | let code = expect_json_type!(post_json.get("code"), Option Number).as_i64();
171 | match code {
172 | Some(-101) => {
173 | /*tx.send((false, format!("跳过(信息:{})",
174 | expect_json_type!(post_json.get("msg"), Option String)
175 | ))).await.unwrap();*/
176 | continue;
177 | },
178 | Some(code) if code != 0 => {
179 | return Err(Box::new(StringError::from(format!(
180 | "Incorrect code {}; message {}", code,
181 | expect_json_type!(post_json.get("msg"), Option String)
182 | ))));
183 | },
184 | None => return Err(Box::new(StringError::from("Incorrect JSON format"))),
185 | _ => {},
186 | }
187 |
188 | f.write_all(post_text.as_bytes())?;
189 | f.write_all(",\n".as_bytes())?;
190 | f.flush()?;
191 |
192 | // Look for image contents
193 | // Post
194 | let post = expect_json_type!(post_json.get("post"), Option Object);
195 | let post_type = expect_json_type!(post.get("type"), Option String);
196 | if post_type == "image" {
197 | let image_url = expect_json_type!(post.get("url"), Option String);
198 | images.push(image_url.clone());
199 | }
200 | // Replies
201 | let replies = expect_json_type!(post_json.get("data"), Option Array);
202 | for reply in replies {
203 | let reply_type = expect_json_type!(reply.get("type"), Option String);
204 | if reply_type == "image" {
205 | let image_url = expect_json_type!(reply.get("url"), Option String);
206 | images.push(image_url.clone());
207 | }
208 | }
209 |
210 | // Look for post references
211 | // Post
212 | let post_text = expect_json_type!(post.get("text"), Option String);
213 | for cap in re_post_ref.captures_iter(post_text) {
214 | if let Ok(id) = cap[1].parse::() {
215 | ref_pids.push(id);
216 | }
217 | }
218 | }
219 | }
220 |
221 | for (i, image_chunk) in images.chunks(10).enumerate() {
222 | let image_futs = image_chunk.iter().map(
223 | |image_url| fetch_and_save_image(client, &image_url, wd)
224 | );
225 | tx.send((false, format!("保存图片({}/{})",
226 | std::cmp::min((i + 1) * 10, images.len()),
227 | images.len(),
228 | ))).await.unwrap();
229 | futures::future::try_join_all(image_futs).await?;
230 | }
231 |
232 | Ok(ref_pids)
233 | }
234 |
235 | async fn fetch_attn_all(
236 | client: &reqwest::Client,
237 | tx: tokio::sync::mpsc::Sender<(bool, String)>,
238 | wd: &std::path::Path,
239 | ref_levels: u32,
240 | ) -> DynResult {
241 | let attn_pids = fetch_attn_pids(&client, { let tx = tx.clone(); tx }).await?;
242 | // println!("{:?}", attn_pids);
243 |
244 | match std::fs::remove_dir_all(wd) {
245 | Err(e) if e.kind() != std::io::ErrorKind::NotFound => {
246 | return Err(Box::new(StringError::from("Cannot remove existing contents")));
247 | },
248 | _ => {},
249 | }
250 | std::fs::create_dir(wd)?;
251 |
252 | let mut wd_path = std::path::PathBuf::from(wd);
253 | wd_path.push("data.js");
254 | // tx.send((false, format!("database: {:?}", wd_path))).await.unwrap();
255 | let mut f = std::fs::File::create(wd_path)?;
256 | f.write_all("const posts = [\n".as_bytes())?;
257 |
258 | let mut img_wd_path = std::path::PathBuf::from(wd);
259 | img_wd_path.push("images");
260 | // tx.send((false, format!("images: {:?}", img_wd_path))).await.unwrap();
261 | std::fs::create_dir(img_wd_path)?;
262 |
263 | // Deduplication
264 | let mut fetched_pids = std::collections::HashSet::new();
265 |
266 | fetched_pids.extend(attn_pids.iter().copied());
267 | let mut ref_pids = fetch_and_save_posts(client, { let tx = tx.clone(); tx }, &attn_pids, &mut f, wd).await?;
268 |
269 | // Delimiter to denote 'reachable by references'
270 | f.write_all("'---',\n".as_bytes())?;
271 |
272 | for i in 0..ref_levels {
273 | tx.send((false, format!("=== 跟随第 {} 层引用 ===", i + 1))).await.unwrap();
274 | ref_pids = ref_pids.iter()
275 | .copied()
276 | .filter(|pid| !fetched_pids.contains(pid))
277 | .collect::>();
278 | fetched_pids.extend(attn_pids.iter().copied());
279 | // tx.send((false, format!("referenced: {:?}", ref_pids))).await.unwrap();
280 | ref_pids = fetch_and_save_posts(client, { let tx = tx.clone(); tx }, &ref_pids, &mut f, wd).await?;
281 | }
282 |
283 | f.write_all("];\n".as_bytes())?;
284 |
285 | // Write HTML
286 | let mut html_wd_path = std::path::PathBuf::from(wd);
287 | html_wd_path.push("index.html");
288 | tx.send((false, format!("保存位置为 {:?}", html_wd_path))).await.unwrap();
289 | let mut f = std::fs::File::create(html_wd_path)?;
290 | f.write_all(include_bytes!("../index.html"))?;
291 |
292 | Ok(())
293 | }
294 |
295 | async fn fetch_everything(
296 | token: &str, proxy: &str, target_dir: &std::path::Path,
297 | ref_levels: u32,
298 | tx: tokio::sync::mpsc::Sender<(bool, String)>,
299 | ) -> DynResult {
300 | tx.send((false, format!("开始备份,内容将保存在 {:?}\n======", target_dir))).await.unwrap();
301 |
302 | let mut headers = reqwest::header::HeaderMap::new();
303 | headers.insert("TOKEN", reqwest::header::HeaderValue::from_str(token)?);
304 | let mut client_builder = reqwest::Client::builder()
305 | .default_headers(headers);
306 | if proxy != "" {
307 | client_builder = client_builder.proxy(reqwest::Proxy::https(proxy)?);
308 | }
309 | let client = client_builder.build()?;
310 |
311 | fetch_attn_all(&client, tx, target_dir, ref_levels).await?;
312 |
313 | Ok(())
314 | }
315 |
316 | async fn main_gui() -> DynResult {
317 | let mut ui = iui::UI::init().unwrap();
318 |
319 | use iui::controls::*;
320 |
321 | let mut win = Window::new(&ui, "hole", 360, 540, WindowType::HasMenubar);
322 | let mut grid = LayoutGrid::new(&ui);
323 | grid.set_padded(&ui, true);
324 | win.set_child(&ui, grid.clone());
325 |
326 | let ent_token = Entry::new(&ui);
327 | let mut ent_reflv = Spinbox::new(&ui, 0, 10);
328 | let ent_proxy = Entry::new(&ui);
329 | let controls: [(&str, Control); 3] = [
330 | ("身份令牌", ent_token.clone().into()),
331 | ("引用层数", ent_reflv.clone().into()),
332 | ("网络代理", ent_proxy.clone().into()),
333 | ];
334 | ent_reflv.set_value(&ui, 2);
335 |
336 | for (i, (text, control)) in controls.iter().enumerate() {
337 | let label = Label::new(&ui, text);
338 | grid.append(&ui, label.clone(), 0, i as i32, 1, 1,
339 | GridExpand::Neither, GridAlignment::Fill, GridAlignment::Fill);
340 | grid.append(&ui, control.clone(), 1, i as i32, 1, 1,
341 | GridExpand::Horizontal, GridAlignment::Fill, GridAlignment::Fill);
342 | }
343 |
344 | let ent_reflv_text = Entry::new(&ui);
345 | grid.append(&ui, ent_reflv_text.clone(), 1, 1, 1, 1,
346 | GridExpand::Horizontal, GridAlignment::Fill, GridAlignment::Fill);
347 | ui.set_enabled(ent_reflv_text.clone(), false);
348 | ui.set_shown(ent_reflv_text.clone(), false);
349 |
350 | let mut btn_go = Button::new(&ui, "开始");
351 | grid.append(&ui, btn_go.clone(), 0, 4, 2, 1,
352 | GridExpand::Horizontal, GridAlignment::Fill, GridAlignment::Fill);
353 |
354 | let log_disp = MultilineEntry::new(&ui);
355 | ui.set_enabled(log_disp.clone(), false);
356 | ui.set_shown(log_disp.clone(), false);
357 | grid.append(&ui, log_disp.clone(), 0, 5, 2, 1,
358 | GridExpand::Both, GridAlignment::Fill, GridAlignment::Fill);
359 |
360 | let handle = tokio::runtime::Handle::current();
361 | let (tx, mut rx) = tokio::sync::mpsc::channel(10);
362 | let mut logs = vec![];
363 |
364 | btn_go.on_clicked(&ui, {
365 | let mut ui = ui.clone();
366 | let controls = controls.clone();
367 | let ent_reflv = ent_reflv.clone();
368 | let mut ent_reflv_text = ent_reflv_text.clone();
369 | let btn_go = btn_go.clone();
370 | let log_disp = log_disp.clone();
371 | move |_| {
372 | let token = ent_token.value(&ui);
373 | let proxy = ent_proxy.value(&ui);
374 | let reflv = ent_reflv.value(&ui) as u32;
375 | // Directory of executable
376 | let mut wd = std::env::current_exe().unwrap();
377 | wd.pop();
378 | let time = chrono::offset::Local::now().format("%Y%m%d-%H%M");
379 | wd.push(&format!("{}-{}", time, token));
380 |
381 | // Disable controls
382 | for (_, control) in &controls {
383 | ui.set_enabled(control.clone(), false);
384 | }
385 | ent_reflv_text.set_value(&ui, &ent_reflv.value(&ui).to_string());
386 | ui.set_shown(ent_reflv.clone(), false);
387 | ui.set_shown(ent_reflv_text.clone(), true);
388 | ui.set_enabled(btn_go.clone(), false);
389 | ui.set_shown(log_disp.clone(), true);
390 |
391 | // Spawn thread
392 | let tx = tx.clone();
393 | handle.spawn(async move {
394 | let msg = match fetch_everything(
395 | &token,
396 | &proxy,
397 | &wd,
398 | reflv,
399 | { let tx = tx.clone(); tx },
400 | ).await {
401 | Err(e) => format!("出现意外问题,请在汇报时附上以下信息:\n{}\n======", e),
402 | _ => "完成".to_string(),
403 | };
404 | tx.send((true, msg)).await.unwrap();
405 | });
406 | }
407 | });
408 |
409 | win.show(&ui);
410 |
411 | let mut event_loop = ui.event_loop();
412 | event_loop.on_tick(&ui, {
413 | let mut ui = ui.clone();
414 | let controls = controls.clone();
415 | let ent_reflv = ent_reflv.clone();
416 | let ent_reflv_text = ent_reflv_text.clone();
417 | let mut log_disp = log_disp.clone();
418 | let logs = &mut logs;
419 | move || {
420 | if let Ok((term, text)) = rx.try_recv() {
421 | // Add to log
422 | logs.insert(0, text);
423 | if logs.len() >= 500 { logs.pop(); }
424 | log_disp.set_value(&ui, &logs.join("\n"));
425 |
426 | if term {
427 | // Enable controls
428 | for (_, control) in &controls {
429 | ui.set_enabled(control.clone(), true);
430 | }
431 | ui.set_shown(ent_reflv.clone(), true);
432 | ui.set_shown(ent_reflv_text.clone(), false);
433 | ui.set_enabled(btn_go.clone(), true);
434 | }
435 | }
436 | }
437 | });
438 | event_loop.run_delay(&ui, 10);
439 |
440 | Ok(())
441 | }
442 |
443 | #[tokio::main]
444 | async fn main() -> DynResult {
445 | let args = std::env::args().collect::>();
446 | if args.len() >= 4 {
447 | let (tx, mut rx) = tokio::sync::mpsc::channel(10);
448 | let join_handle = tokio::runtime::Handle::current().spawn(async move {
449 | loop {
450 | if let Some((term, text)) = rx.recv().await {
451 | eprintln!("{}", text);
452 | std::io::stderr().flush().unwrap();
453 | if term { break; }
454 | } else {
455 | break;
456 | }
457 | }
458 | });
459 | let result = fetch_everything(
460 | &args[1],
461 | if args.len() >= 5 { &args[4] } else { "" },
462 | std::path::Path::new(&args[3]),
463 | args[2].parse()?,
464 | tx.clone(),
465 | ).await;
466 | if let Err(e) = result {
467 | tx.clone().send((true, format!("出现意外问题:\n{}\n======", e))).await.unwrap();
468 | } else {
469 | tx.clone().send((true, "完成".to_string())).await.unwrap();
470 | }
471 | join_handle.await?;
472 | std::io::stderr().flush().unwrap();
473 | } else {
474 | main_gui().await?;
475 | }
476 | Ok(())
477 | }
478 |
--------------------------------------------------------------------------------
/Cargo.lock:
--------------------------------------------------------------------------------
1 | # This file is automatically @generated by Cargo.
2 | # It is not intended for manual editing.
3 | version = 3
4 |
5 | [[package]]
6 | name = "addr2line"
7 | version = "0.17.0"
8 | source = "registry+https://github.com/rust-lang/crates.io-index"
9 | checksum = "b9ecd88a8c8378ca913a680cd98f0f13ac67383d35993f86c90a70e3f137816b"
10 | dependencies = [
11 | "gimli",
12 | ]
13 |
14 | [[package]]
15 | name = "adler"
16 | version = "1.0.2"
17 | source = "registry+https://github.com/rust-lang/crates.io-index"
18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe"
19 |
20 | [[package]]
21 | name = "aho-corasick"
22 | version = "0.7.18"
23 | source = "registry+https://github.com/rust-lang/crates.io-index"
24 | checksum = "1e37cfd5e7657ada45f742d6e99ca5788580b5c529dc78faf11ece6dc702656f"
25 | dependencies = [
26 | "memchr",
27 | ]
28 |
29 | [[package]]
30 | name = "ansi_term"
31 | version = "0.12.1"
32 | source = "registry+https://github.com/rust-lang/crates.io-index"
33 | checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2"
34 | dependencies = [
35 | "winapi",
36 | ]
37 |
38 | [[package]]
39 | name = "atty"
40 | version = "0.2.14"
41 | source = "registry+https://github.com/rust-lang/crates.io-index"
42 | checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8"
43 | dependencies = [
44 | "hermit-abi",
45 | "libc",
46 | "winapi",
47 | ]
48 |
49 | [[package]]
50 | name = "autocfg"
51 | version = "1.0.1"
52 | source = "registry+https://github.com/rust-lang/crates.io-index"
53 | checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a"
54 |
55 | [[package]]
56 | name = "backtrace"
57 | version = "0.3.63"
58 | source = "registry+https://github.com/rust-lang/crates.io-index"
59 | checksum = "321629d8ba6513061f26707241fa9bc89524ff1cd7a915a97ef0c62c666ce1b6"
60 | dependencies = [
61 | "addr2line",
62 | "cc",
63 | "cfg-if 1.0.0",
64 | "libc",
65 | "miniz_oxide",
66 | "object",
67 | "rustc-demangle",
68 | ]
69 |
70 | [[package]]
71 | name = "base64"
72 | version = "0.13.0"
73 | source = "registry+https://github.com/rust-lang/crates.io-index"
74 | checksum = "904dfeac50f3cdaba28fc6f57fdcddb75f49ed61346676a78c4ffe55877802fd"
75 |
76 | [[package]]
77 | name = "bindgen"
78 | version = "0.54.0"
79 | source = "registry+https://github.com/rust-lang/crates.io-index"
80 | checksum = "66c0bb6167449588ff70803f4127f0684f9063097eca5016f37eb52b92c2cf36"
81 | dependencies = [
82 | "bitflags",
83 | "cexpr",
84 | "cfg-if 0.1.10",
85 | "clang-sys",
86 | "clap",
87 | "env_logger",
88 | "lazy_static",
89 | "lazycell",
90 | "log",
91 | "peeking_take_while",
92 | "proc-macro2",
93 | "quote",
94 | "regex",
95 | "rustc-hash",
96 | "shlex",
97 | "which",
98 | ]
99 |
100 | [[package]]
101 | name = "bitflags"
102 | version = "1.3.2"
103 | source = "registry+https://github.com/rust-lang/crates.io-index"
104 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
105 |
106 | [[package]]
107 | name = "bumpalo"
108 | version = "3.8.0"
109 | source = "registry+https://github.com/rust-lang/crates.io-index"
110 | checksum = "8f1e260c3a9040a7c19a12468758f4c16f31a81a1fe087482be9570ec864bb6c"
111 |
112 | [[package]]
113 | name = "bytebuffer"
114 | version = "0.2.1"
115 | source = "registry+https://github.com/rust-lang/crates.io-index"
116 | checksum = "e822a21389d388828152aeae8bb43049196b09076e2a138f53351d8cf6576cf3"
117 | dependencies = [
118 | "byteorder",
119 | ]
120 |
121 | [[package]]
122 | name = "byteorder"
123 | version = "0.3.13"
124 | source = "registry+https://github.com/rust-lang/crates.io-index"
125 | checksum = "29b2aa490a8f546381308d68fc79e6bd753cd3ad839f7a7172897f1feedfa175"
126 |
127 | [[package]]
128 | name = "bytes"
129 | version = "1.1.0"
130 | source = "registry+https://github.com/rust-lang/crates.io-index"
131 | checksum = "c4872d67bab6358e59559027aa3b9157c53d9358c51423c17554809a8858e0f8"
132 |
133 | [[package]]
134 | name = "cc"
135 | version = "1.0.72"
136 | source = "registry+https://github.com/rust-lang/crates.io-index"
137 | checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
138 |
139 | [[package]]
140 | name = "cexpr"
141 | version = "0.4.0"
142 | source = "registry+https://github.com/rust-lang/crates.io-index"
143 | checksum = "f4aedb84272dbe89af497cf81375129abda4fc0a9e7c5d317498c15cc30c0d27"
144 | dependencies = [
145 | "nom",
146 | ]
147 |
148 | [[package]]
149 | name = "cfg-if"
150 | version = "0.1.10"
151 | source = "registry+https://github.com/rust-lang/crates.io-index"
152 | checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
153 |
154 | [[package]]
155 | name = "cfg-if"
156 | version = "1.0.0"
157 | source = "registry+https://github.com/rust-lang/crates.io-index"
158 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
159 |
160 | [[package]]
161 | name = "chrono"
162 | version = "0.4.19"
163 | source = "registry+https://github.com/rust-lang/crates.io-index"
164 | checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73"
165 | dependencies = [
166 | "libc",
167 | "num-integer",
168 | "num-traits",
169 | "time",
170 | "winapi",
171 | ]
172 |
173 | [[package]]
174 | name = "clang-sys"
175 | version = "0.29.3"
176 | source = "registry+https://github.com/rust-lang/crates.io-index"
177 | checksum = "fe6837df1d5cba2397b835c8530f51723267e16abbf83892e9e5af4f0e5dd10a"
178 | dependencies = [
179 | "glob",
180 | "libc",
181 | "libloading",
182 | ]
183 |
184 | [[package]]
185 | name = "clap"
186 | version = "2.34.0"
187 | source = "registry+https://github.com/rust-lang/crates.io-index"
188 | checksum = "a0610544180c38b88101fecf2dd634b174a62eef6946f84dfc6a7127512b381c"
189 | dependencies = [
190 | "ansi_term",
191 | "atty",
192 | "bitflags",
193 | "strsim",
194 | "textwrap",
195 | "unicode-width",
196 | "vec_map",
197 | ]
198 |
199 | [[package]]
200 | name = "core-foundation"
201 | version = "0.9.2"
202 | source = "registry+https://github.com/rust-lang/crates.io-index"
203 | checksum = "6888e10551bb93e424d8df1d07f1a8b4fceb0001a3a4b048bfc47554946f47b3"
204 | dependencies = [
205 | "core-foundation-sys",
206 | "libc",
207 | ]
208 |
209 | [[package]]
210 | name = "core-foundation-sys"
211 | version = "0.8.3"
212 | source = "registry+https://github.com/rust-lang/crates.io-index"
213 | checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc"
214 |
215 | [[package]]
216 | name = "either"
217 | version = "1.6.1"
218 | source = "registry+https://github.com/rust-lang/crates.io-index"
219 | checksum = "e78d4f1cc4ae33bbfc157ed5d5a5ef3bc29227303d595861deb238fcec4e9457"
220 |
221 | [[package]]
222 | name = "embed-resource"
223 | version = "1.6.5"
224 | source = "registry+https://github.com/rust-lang/crates.io-index"
225 | checksum = "85505eb239fc952b300f29f0556d2d884082a83566768d980278d8faf38c780d"
226 | dependencies = [
227 | "cc",
228 | "vswhom",
229 | "winreg 0.10.1",
230 | ]
231 |
232 | [[package]]
233 | name = "encoding_rs"
234 | version = "0.8.30"
235 | source = "registry+https://github.com/rust-lang/crates.io-index"
236 | checksum = "7896dc8abb250ffdda33912550faa54c88ec8b998dec0b2c55ab224921ce11df"
237 | dependencies = [
238 | "cfg-if 1.0.0",
239 | ]
240 |
241 | [[package]]
242 | name = "env_logger"
243 | version = "0.7.1"
244 | source = "registry+https://github.com/rust-lang/crates.io-index"
245 | checksum = "44533bbbb3bb3c1fa17d9f2e4e38bbbaf8396ba82193c4cb1b6445d711445d36"
246 | dependencies = [
247 | "atty",
248 | "humantime",
249 | "log",
250 | "regex",
251 | "termcolor",
252 | ]
253 |
254 | [[package]]
255 | name = "failure"
256 | version = "0.1.8"
257 | source = "registry+https://github.com/rust-lang/crates.io-index"
258 | checksum = "d32e9bd16cc02eae7db7ef620b392808b89f6a5e16bb3497d159c6b92a0f4f86"
259 | dependencies = [
260 | "backtrace",
261 | "failure_derive",
262 | ]
263 |
264 | [[package]]
265 | name = "failure_derive"
266 | version = "0.1.8"
267 | source = "registry+https://github.com/rust-lang/crates.io-index"
268 | checksum = "aa4da3c766cd7a0db8242e326e9e4e081edd567072893ed320008189715366a4"
269 | dependencies = [
270 | "proc-macro2",
271 | "quote",
272 | "syn",
273 | "synstructure",
274 | ]
275 |
276 | [[package]]
277 | name = "fnv"
278 | version = "1.0.7"
279 | source = "registry+https://github.com/rust-lang/crates.io-index"
280 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
281 |
282 | [[package]]
283 | name = "foreign-types"
284 | version = "0.3.2"
285 | source = "registry+https://github.com/rust-lang/crates.io-index"
286 | checksum = "f6f339eb8adc052cd2ca78910fda869aefa38d22d5cb648e6485e4d3fc06f3b1"
287 | dependencies = [
288 | "foreign-types-shared",
289 | ]
290 |
291 | [[package]]
292 | name = "foreign-types-shared"
293 | version = "0.1.1"
294 | source = "registry+https://github.com/rust-lang/crates.io-index"
295 | checksum = "00b0228411908ca8685dba7fc2cdd70ec9990a6e753e89b6ac91a84c40fbaf4b"
296 |
297 | [[package]]
298 | name = "form_urlencoded"
299 | version = "1.0.1"
300 | source = "registry+https://github.com/rust-lang/crates.io-index"
301 | checksum = "5fc25a87fa4fd2094bffb06925852034d90a17f0d1e05197d4956d3555752191"
302 | dependencies = [
303 | "matches",
304 | "percent-encoding",
305 | ]
306 |
307 | [[package]]
308 | name = "futures"
309 | version = "0.3.18"
310 | source = "registry+https://github.com/rust-lang/crates.io-index"
311 | checksum = "8cd0210d8c325c245ff06fd95a3b13689a1a276ac8cfa8e8720cb840bfb84b9e"
312 | dependencies = [
313 | "futures-channel",
314 | "futures-core",
315 | "futures-executor",
316 | "futures-io",
317 | "futures-sink",
318 | "futures-task",
319 | "futures-util",
320 | ]
321 |
322 | [[package]]
323 | name = "futures-channel"
324 | version = "0.3.18"
325 | source = "registry+https://github.com/rust-lang/crates.io-index"
326 | checksum = "7fc8cd39e3dbf865f7340dce6a2d401d24fd37c6fe6c4f0ee0de8bfca2252d27"
327 | dependencies = [
328 | "futures-core",
329 | "futures-sink",
330 | ]
331 |
332 | [[package]]
333 | name = "futures-core"
334 | version = "0.3.18"
335 | source = "registry+https://github.com/rust-lang/crates.io-index"
336 | checksum = "629316e42fe7c2a0b9a65b47d159ceaa5453ab14e8f0a3c5eedbb8cd55b4a445"
337 |
338 | [[package]]
339 | name = "futures-executor"
340 | version = "0.3.18"
341 | source = "registry+https://github.com/rust-lang/crates.io-index"
342 | checksum = "7b808bf53348a36cab739d7e04755909b9fcaaa69b7d7e588b37b6ec62704c97"
343 | dependencies = [
344 | "futures-core",
345 | "futures-task",
346 | "futures-util",
347 | ]
348 |
349 | [[package]]
350 | name = "futures-io"
351 | version = "0.3.18"
352 | source = "registry+https://github.com/rust-lang/crates.io-index"
353 | checksum = "e481354db6b5c353246ccf6a728b0c5511d752c08da7260546fc0933869daa11"
354 |
355 | [[package]]
356 | name = "futures-macro"
357 | version = "0.3.18"
358 | source = "registry+https://github.com/rust-lang/crates.io-index"
359 | checksum = "a89f17b21645bc4ed773c69af9c9a0effd4a3f1a3876eadd453469f8854e7fdd"
360 | dependencies = [
361 | "proc-macro2",
362 | "quote",
363 | "syn",
364 | ]
365 |
366 | [[package]]
367 | name = "futures-sink"
368 | version = "0.3.18"
369 | source = "registry+https://github.com/rust-lang/crates.io-index"
370 | checksum = "996c6442437b62d21a32cd9906f9c41e7dc1e19a9579843fad948696769305af"
371 |
372 | [[package]]
373 | name = "futures-task"
374 | version = "0.3.18"
375 | source = "registry+https://github.com/rust-lang/crates.io-index"
376 | checksum = "dabf1872aaab32c886832f2276d2f5399887e2bd613698a02359e4ea83f8de12"
377 |
378 | [[package]]
379 | name = "futures-util"
380 | version = "0.3.18"
381 | source = "registry+https://github.com/rust-lang/crates.io-index"
382 | checksum = "41d22213122356472061ac0f1ab2cee28d2bac8491410fd68c2af53d1cedb83e"
383 | dependencies = [
384 | "futures-channel",
385 | "futures-core",
386 | "futures-io",
387 | "futures-macro",
388 | "futures-sink",
389 | "futures-task",
390 | "memchr",
391 | "pin-project-lite",
392 | "pin-utils",
393 | "slab",
394 | ]
395 |
396 | [[package]]
397 | name = "getrandom"
398 | version = "0.2.3"
399 | source = "registry+https://github.com/rust-lang/crates.io-index"
400 | checksum = "7fcd999463524c52659517fe2cea98493cfe485d10565e7b0fb07dbba7ad2753"
401 | dependencies = [
402 | "cfg-if 1.0.0",
403 | "libc",
404 | "wasi",
405 | ]
406 |
407 | [[package]]
408 | name = "gimli"
409 | version = "0.26.1"
410 | source = "registry+https://github.com/rust-lang/crates.io-index"
411 | checksum = "78cc372d058dcf6d5ecd98510e7fbc9e5aec4d21de70f65fea8fecebcd881bd4"
412 |
413 | [[package]]
414 | name = "glob"
415 | version = "0.3.0"
416 | source = "registry+https://github.com/rust-lang/crates.io-index"
417 | checksum = "9b919933a397b79c37e33b77bb2aa3dc8eb6e165ad809e58ff75bc7db2e34574"
418 |
419 | [[package]]
420 | name = "h2"
421 | version = "0.3.9"
422 | source = "registry+https://github.com/rust-lang/crates.io-index"
423 | checksum = "8f072413d126e57991455e0a922b31e4c8ba7c2ffbebf6b78b4f8521397d65cd"
424 | dependencies = [
425 | "bytes",
426 | "fnv",
427 | "futures-core",
428 | "futures-sink",
429 | "futures-util",
430 | "http",
431 | "indexmap",
432 | "slab",
433 | "tokio",
434 | "tokio-util",
435 | "tracing",
436 | ]
437 |
438 | [[package]]
439 | name = "hashbrown"
440 | version = "0.11.2"
441 | source = "registry+https://github.com/rust-lang/crates.io-index"
442 | checksum = "ab5ef0d4909ef3724cc8cce6ccc8572c5c817592e9285f5464f8e86f8bd3726e"
443 |
444 | [[package]]
445 | name = "hermit-abi"
446 | version = "0.1.19"
447 | source = "registry+https://github.com/rust-lang/crates.io-index"
448 | checksum = "62b467343b94ba476dcb2500d242dadbb39557df889310ac77c5d99100aaac33"
449 | dependencies = [
450 | "libc",
451 | ]
452 |
453 | [[package]]
454 | name = "http"
455 | version = "0.2.5"
456 | source = "registry+https://github.com/rust-lang/crates.io-index"
457 | checksum = "1323096b05d41827dadeaee54c9981958c0f94e670bc94ed80037d1a7b8b186b"
458 | dependencies = [
459 | "bytes",
460 | "fnv",
461 | "itoa",
462 | ]
463 |
464 | [[package]]
465 | name = "http-body"
466 | version = "0.4.4"
467 | source = "registry+https://github.com/rust-lang/crates.io-index"
468 | checksum = "1ff4f84919677303da5f147645dbea6b1881f368d03ac84e1dc09031ebd7b2c6"
469 | dependencies = [
470 | "bytes",
471 | "http",
472 | "pin-project-lite",
473 | ]
474 |
475 | [[package]]
476 | name = "httparse"
477 | version = "1.5.1"
478 | source = "registry+https://github.com/rust-lang/crates.io-index"
479 | checksum = "acd94fdbe1d4ff688b67b04eee2e17bd50995534a61539e45adfefb45e5e5503"
480 |
481 | [[package]]
482 | name = "httpdate"
483 | version = "1.0.2"
484 | source = "registry+https://github.com/rust-lang/crates.io-index"
485 | checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421"
486 |
487 | [[package]]
488 | name = "humantime"
489 | version = "1.3.0"
490 | source = "registry+https://github.com/rust-lang/crates.io-index"
491 | checksum = "df004cfca50ef23c36850aaaa59ad52cc70d0e90243c3c7737a4dd32dc7a3c4f"
492 | dependencies = [
493 | "quick-error",
494 | ]
495 |
496 | [[package]]
497 | name = "hyper"
498 | version = "0.14.16"
499 | source = "registry+https://github.com/rust-lang/crates.io-index"
500 | checksum = "b7ec3e62bdc98a2f0393a5048e4c30ef659440ea6e0e572965103e72bd836f55"
501 | dependencies = [
502 | "bytes",
503 | "futures-channel",
504 | "futures-core",
505 | "futures-util",
506 | "h2",
507 | "http",
508 | "http-body",
509 | "httparse",
510 | "httpdate",
511 | "itoa",
512 | "pin-project-lite",
513 | "socket2",
514 | "tokio",
515 | "tower-service",
516 | "tracing",
517 | "want",
518 | ]
519 |
520 | [[package]]
521 | name = "hyper-tls"
522 | version = "0.5.0"
523 | source = "registry+https://github.com/rust-lang/crates.io-index"
524 | checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
525 | dependencies = [
526 | "bytes",
527 | "hyper",
528 | "native-tls",
529 | "tokio",
530 | "tokio-native-tls",
531 | ]
532 |
533 | [[package]]
534 | name = "idna"
535 | version = "0.2.3"
536 | source = "registry+https://github.com/rust-lang/crates.io-index"
537 | checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8"
538 | dependencies = [
539 | "matches",
540 | "unicode-bidi",
541 | "unicode-normalization",
542 | ]
543 |
544 | [[package]]
545 | name = "indexmap"
546 | version = "1.7.0"
547 | source = "registry+https://github.com/rust-lang/crates.io-index"
548 | checksum = "bc633605454125dec4b66843673f01c7df2b89479b32e0ed634e43a91cff62a5"
549 | dependencies = [
550 | "autocfg",
551 | "hashbrown",
552 | ]
553 |
554 | [[package]]
555 | name = "instant"
556 | version = "0.1.12"
557 | source = "registry+https://github.com/rust-lang/crates.io-index"
558 | checksum = "7a5bbe824c507c5da5956355e86a746d82e0e1464f65d862cc5e71da70e94b2c"
559 | dependencies = [
560 | "cfg-if 1.0.0",
561 | ]
562 |
563 | [[package]]
564 | name = "ipnet"
565 | version = "2.3.1"
566 | source = "registry+https://github.com/rust-lang/crates.io-index"
567 | checksum = "68f2d64f2edebec4ce84ad108148e67e1064789bee435edc5b60ad398714a3a9"
568 |
569 | [[package]]
570 | name = "itoa"
571 | version = "0.4.8"
572 | source = "registry+https://github.com/rust-lang/crates.io-index"
573 | checksum = "b71991ff56294aa922b450139ee08b3bfc70982c6b2c7562771375cf73542dd4"
574 |
575 | [[package]]
576 | name = "iui"
577 | version = "0.3.0"
578 | source = "git+https://github.com/rust-native-ui/libui-rs?branch=trunk#6ff94425b341cf718e29d07067dbf82f9215a6d5"
579 | dependencies = [
580 | "bitflags",
581 | "failure",
582 | "lazy_static",
583 | "libc",
584 | "regex",
585 | "ui-sys",
586 | ]
587 |
588 | [[package]]
589 | name = "js-sys"
590 | version = "0.3.55"
591 | source = "registry+https://github.com/rust-lang/crates.io-index"
592 | checksum = "7cc9ffccd38c451a86bf13657df244e9c3f37493cce8e5e21e940963777acc84"
593 | dependencies = [
594 | "wasm-bindgen",
595 | ]
596 |
597 | [[package]]
598 | name = "lazy_static"
599 | version = "1.4.0"
600 | source = "registry+https://github.com/rust-lang/crates.io-index"
601 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646"
602 |
603 | [[package]]
604 | name = "lazycell"
605 | version = "1.3.0"
606 | source = "registry+https://github.com/rust-lang/crates.io-index"
607 | checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
608 |
609 | [[package]]
610 | name = "libc"
611 | version = "0.2.109"
612 | source = "registry+https://github.com/rust-lang/crates.io-index"
613 | checksum = "f98a04dce437184842841303488f70d0188c5f51437d2a834dc097eafa909a01"
614 |
615 | [[package]]
616 | name = "libloading"
617 | version = "0.5.2"
618 | source = "registry+https://github.com/rust-lang/crates.io-index"
619 | checksum = "f2b111a074963af1d37a139918ac6d49ad1d0d5e47f72fd55388619691a7d753"
620 | dependencies = [
621 | "cc",
622 | "winapi",
623 | ]
624 |
625 | [[package]]
626 | name = "lock_api"
627 | version = "0.4.5"
628 | source = "registry+https://github.com/rust-lang/crates.io-index"
629 | checksum = "712a4d093c9976e24e7dbca41db895dabcbac38eb5f4045393d17a95bdfb1109"
630 | dependencies = [
631 | "scopeguard",
632 | ]
633 |
634 | [[package]]
635 | name = "log"
636 | version = "0.4.14"
637 | source = "registry+https://github.com/rust-lang/crates.io-index"
638 | checksum = "51b9bbe6c47d51fc3e1a9b945965946b4c44142ab8792c50835a980d362c2710"
639 | dependencies = [
640 | "cfg-if 1.0.0",
641 | ]
642 |
643 | [[package]]
644 | name = "matches"
645 | version = "0.1.9"
646 | source = "registry+https://github.com/rust-lang/crates.io-index"
647 | checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f"
648 |
649 | [[package]]
650 | name = "memchr"
651 | version = "2.4.1"
652 | source = "registry+https://github.com/rust-lang/crates.io-index"
653 | checksum = "308cc39be01b73d0d18f82a0e7b2a3df85245f84af96fdddc5d202d27e47b86a"
654 |
655 | [[package]]
656 | name = "mime"
657 | version = "0.3.16"
658 | source = "registry+https://github.com/rust-lang/crates.io-index"
659 | checksum = "2a60c7ce501c71e03a9c9c0d35b861413ae925bd979cc7a4e30d060069aaac8d"
660 |
661 | [[package]]
662 | name = "miniz_oxide"
663 | version = "0.4.4"
664 | source = "registry+https://github.com/rust-lang/crates.io-index"
665 | checksum = "a92518e98c078586bc6c934028adcca4c92a53d6a958196de835170a01d84e4b"
666 | dependencies = [
667 | "adler",
668 | "autocfg",
669 | ]
670 |
671 | [[package]]
672 | name = "mio"
673 | version = "0.7.14"
674 | source = "registry+https://github.com/rust-lang/crates.io-index"
675 | checksum = "8067b404fe97c70829f082dec8bcf4f71225d7eaea1d8645349cb76fa06205cc"
676 | dependencies = [
677 | "libc",
678 | "log",
679 | "miow",
680 | "ntapi",
681 | "winapi",
682 | ]
683 |
684 | [[package]]
685 | name = "miow"
686 | version = "0.3.7"
687 | source = "registry+https://github.com/rust-lang/crates.io-index"
688 | checksum = "b9f1c5b025cda876f66ef43a113f91ebc9f4ccef34843000e0adf6ebbab84e21"
689 | dependencies = [
690 | "winapi",
691 | ]
692 |
693 | [[package]]
694 | name = "native-tls"
695 | version = "0.2.8"
696 | source = "registry+https://github.com/rust-lang/crates.io-index"
697 | checksum = "48ba9f7719b5a0f42f338907614285fb5fd70e53858141f69898a1fb7203b24d"
698 | dependencies = [
699 | "lazy_static",
700 | "libc",
701 | "log",
702 | "openssl",
703 | "openssl-probe",
704 | "openssl-sys",
705 | "schannel",
706 | "security-framework",
707 | "security-framework-sys",
708 | "tempfile",
709 | ]
710 |
711 | [[package]]
712 | name = "nom"
713 | version = "5.1.2"
714 | source = "registry+https://github.com/rust-lang/crates.io-index"
715 | checksum = "ffb4262d26ed83a1c0a33a38fe2bb15797329c85770da05e6b828ddb782627af"
716 | dependencies = [
717 | "memchr",
718 | "version_check",
719 | ]
720 |
721 | [[package]]
722 | name = "ntapi"
723 | version = "0.3.6"
724 | source = "registry+https://github.com/rust-lang/crates.io-index"
725 | checksum = "3f6bb902e437b6d86e03cce10a7e2af662292c5dfef23b65899ea3ac9354ad44"
726 | dependencies = [
727 | "winapi",
728 | ]
729 |
730 | [[package]]
731 | name = "num-integer"
732 | version = "0.1.44"
733 | source = "registry+https://github.com/rust-lang/crates.io-index"
734 | checksum = "d2cc698a63b549a70bc047073d2949cce27cd1c7b0a4a862d08a8031bc2801db"
735 | dependencies = [
736 | "autocfg",
737 | "num-traits",
738 | ]
739 |
740 | [[package]]
741 | name = "num-traits"
742 | version = "0.2.14"
743 | source = "registry+https://github.com/rust-lang/crates.io-index"
744 | checksum = "9a64b1ec5cda2586e284722486d802acf1f7dbdc623e2bfc57e65ca1cd099290"
745 | dependencies = [
746 | "autocfg",
747 | ]
748 |
749 | [[package]]
750 | name = "num_cpus"
751 | version = "1.13.0"
752 | source = "registry+https://github.com/rust-lang/crates.io-index"
753 | checksum = "05499f3756671c15885fee9034446956fff3f243d6077b91e5767df161f766b3"
754 | dependencies = [
755 | "hermit-abi",
756 | "libc",
757 | ]
758 |
759 | [[package]]
760 | name = "object"
761 | version = "0.27.1"
762 | source = "registry+https://github.com/rust-lang/crates.io-index"
763 | checksum = "67ac1d3f9a1d3616fd9a60c8d74296f22406a238b6a72f5cc1e6f314df4ffbf9"
764 | dependencies = [
765 | "memchr",
766 | ]
767 |
768 | [[package]]
769 | name = "once_cell"
770 | version = "1.8.0"
771 | source = "registry+https://github.com/rust-lang/crates.io-index"
772 | checksum = "692fcb63b64b1758029e0a96ee63e049ce8c5948587f2f7208df04625e5f6b56"
773 |
774 | [[package]]
775 | name = "openssl"
776 | version = "0.10.38"
777 | source = "registry+https://github.com/rust-lang/crates.io-index"
778 | checksum = "0c7ae222234c30df141154f159066c5093ff73b63204dcda7121eb082fc56a95"
779 | dependencies = [
780 | "bitflags",
781 | "cfg-if 1.0.0",
782 | "foreign-types",
783 | "libc",
784 | "once_cell",
785 | "openssl-sys",
786 | ]
787 |
788 | [[package]]
789 | name = "openssl-probe"
790 | version = "0.1.4"
791 | source = "registry+https://github.com/rust-lang/crates.io-index"
792 | checksum = "28988d872ab76095a6e6ac88d99b54fd267702734fd7ffe610ca27f533ddb95a"
793 |
794 | [[package]]
795 | name = "openssl-sys"
796 | version = "0.9.71"
797 | source = "registry+https://github.com/rust-lang/crates.io-index"
798 | checksum = "7df13d165e607909b363a4757a6f133f8a818a74e9d3a98d09c6128e15fa4c73"
799 | dependencies = [
800 | "autocfg",
801 | "cc",
802 | "libc",
803 | "pkg-config",
804 | "vcpkg",
805 | ]
806 |
807 | [[package]]
808 | name = "parking_lot"
809 | version = "0.11.2"
810 | source = "registry+https://github.com/rust-lang/crates.io-index"
811 | checksum = "7d17b78036a60663b797adeaee46f5c9dfebb86948d1255007a1d6be0271ff99"
812 | dependencies = [
813 | "instant",
814 | "lock_api",
815 | "parking_lot_core",
816 | ]
817 |
818 | [[package]]
819 | name = "parking_lot_core"
820 | version = "0.8.5"
821 | source = "registry+https://github.com/rust-lang/crates.io-index"
822 | checksum = "d76e8e1493bcac0d2766c42737f34458f1c8c50c0d23bcb24ea953affb273216"
823 | dependencies = [
824 | "cfg-if 1.0.0",
825 | "instant",
826 | "libc",
827 | "redox_syscall",
828 | "smallvec",
829 | "winapi",
830 | ]
831 |
832 | [[package]]
833 | name = "peeking_take_while"
834 | version = "0.1.2"
835 | source = "registry+https://github.com/rust-lang/crates.io-index"
836 | checksum = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
837 |
838 | [[package]]
839 | name = "percent-encoding"
840 | version = "2.1.0"
841 | source = "registry+https://github.com/rust-lang/crates.io-index"
842 | checksum = "d4fd5641d01c8f18a23da7b6fe29298ff4b55afcccdf78973b24cf3175fee32e"
843 |
844 | [[package]]
845 | name = "pin-project-lite"
846 | version = "0.2.7"
847 | source = "registry+https://github.com/rust-lang/crates.io-index"
848 | checksum = "8d31d11c69a6b52a174b42bdc0c30e5e11670f90788b2c471c31c1d17d449443"
849 |
850 | [[package]]
851 | name = "pin-utils"
852 | version = "0.1.0"
853 | source = "registry+https://github.com/rust-lang/crates.io-index"
854 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184"
855 |
856 | [[package]]
857 | name = "pkg-config"
858 | version = "0.3.24"
859 | source = "registry+https://github.com/rust-lang/crates.io-index"
860 | checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
861 |
862 | [[package]]
863 | name = "ppv-lite86"
864 | version = "0.2.15"
865 | source = "registry+https://github.com/rust-lang/crates.io-index"
866 | checksum = "ed0cfbc8191465bed66e1718596ee0b0b35d5ee1f41c5df2189d0fe8bde535ba"
867 |
868 | [[package]]
869 | name = "proc-macro2"
870 | version = "1.0.33"
871 | source = "registry+https://github.com/rust-lang/crates.io-index"
872 | checksum = "fb37d2df5df740e582f28f8560cf425f52bb267d872fe58358eadb554909f07a"
873 | dependencies = [
874 | "unicode-xid",
875 | ]
876 |
877 | [[package]]
878 | name = "quick-error"
879 | version = "1.2.3"
880 | source = "registry+https://github.com/rust-lang/crates.io-index"
881 | checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
882 |
883 | [[package]]
884 | name = "quote"
885 | version = "1.0.10"
886 | source = "registry+https://github.com/rust-lang/crates.io-index"
887 | checksum = "38bc8cc6a5f2e3655e0899c1b848643b2562f853f114bfec7be120678e3ace05"
888 | dependencies = [
889 | "proc-macro2",
890 | ]
891 |
892 | [[package]]
893 | name = "rand"
894 | version = "0.8.4"
895 | source = "registry+https://github.com/rust-lang/crates.io-index"
896 | checksum = "2e7573632e6454cf6b99d7aac4ccca54be06da05aca2ef7423d22d27d4d4bcd8"
897 | dependencies = [
898 | "libc",
899 | "rand_chacha",
900 | "rand_core",
901 | "rand_hc",
902 | ]
903 |
904 | [[package]]
905 | name = "rand_chacha"
906 | version = "0.3.1"
907 | source = "registry+https://github.com/rust-lang/crates.io-index"
908 | checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
909 | dependencies = [
910 | "ppv-lite86",
911 | "rand_core",
912 | ]
913 |
914 | [[package]]
915 | name = "rand_core"
916 | version = "0.6.3"
917 | source = "registry+https://github.com/rust-lang/crates.io-index"
918 | checksum = "d34f1408f55294453790c48b2f1ebbb1c5b4b7563eb1f418bcfcfdbb06ebb4e7"
919 | dependencies = [
920 | "getrandom",
921 | ]
922 |
923 | [[package]]
924 | name = "rand_hc"
925 | version = "0.3.1"
926 | source = "registry+https://github.com/rust-lang/crates.io-index"
927 | checksum = "d51e9f596de227fda2ea6c84607f5558e196eeaf43c986b724ba4fb8fdf497e7"
928 | dependencies = [
929 | "rand_core",
930 | ]
931 |
932 | [[package]]
933 | name = "redox_syscall"
934 | version = "0.2.10"
935 | source = "registry+https://github.com/rust-lang/crates.io-index"
936 | checksum = "8383f39639269cde97d255a32bdb68c047337295414940c68bdd30c2e13203ff"
937 | dependencies = [
938 | "bitflags",
939 | ]
940 |
941 | [[package]]
942 | name = "regex"
943 | version = "1.5.4"
944 | source = "registry+https://github.com/rust-lang/crates.io-index"
945 | checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461"
946 | dependencies = [
947 | "aho-corasick",
948 | "memchr",
949 | "regex-syntax",
950 | ]
951 |
952 | [[package]]
953 | name = "regex-syntax"
954 | version = "0.6.25"
955 | source = "registry+https://github.com/rust-lang/crates.io-index"
956 | checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b"
957 |
958 | [[package]]
959 | name = "remove_dir_all"
960 | version = "0.5.3"
961 | source = "registry+https://github.com/rust-lang/crates.io-index"
962 | checksum = "3acd125665422973a33ac9d3dd2df85edad0f4ae9b00dafb1a05e43a9f5ef8e7"
963 | dependencies = [
964 | "winapi",
965 | ]
966 |
967 | [[package]]
968 | name = "reqwest"
969 | version = "0.11.7"
970 | source = "registry+https://github.com/rust-lang/crates.io-index"
971 | checksum = "07bea77bc708afa10e59905c3d4af7c8fd43c9214251673095ff8b14345fcbc5"
972 | dependencies = [
973 | "base64",
974 | "bytes",
975 | "encoding_rs",
976 | "futures-core",
977 | "futures-util",
978 | "http",
979 | "http-body",
980 | "hyper",
981 | "hyper-tls",
982 | "ipnet",
983 | "js-sys",
984 | "lazy_static",
985 | "log",
986 | "mime",
987 | "native-tls",
988 | "percent-encoding",
989 | "pin-project-lite",
990 | "serde",
991 | "serde_json",
992 | "serde_urlencoded",
993 | "tokio",
994 | "tokio-native-tls",
995 | "tokio-socks",
996 | "url",
997 | "wasm-bindgen",
998 | "wasm-bindgen-futures",
999 | "web-sys",
1000 | "winreg 0.7.0",
1001 | ]
1002 |
1003 | [[package]]
1004 | name = "rustc-demangle"
1005 | version = "0.1.21"
1006 | source = "registry+https://github.com/rust-lang/crates.io-index"
1007 | checksum = "7ef03e0a2b150c7a90d01faf6254c9c48a41e95fb2a8c2ac1c6f0d2b9aefc342"
1008 |
1009 | [[package]]
1010 | name = "rustc-hash"
1011 | version = "1.1.0"
1012 | source = "registry+https://github.com/rust-lang/crates.io-index"
1013 | checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2"
1014 |
1015 | [[package]]
1016 | name = "ryu"
1017 | version = "1.0.7"
1018 | source = "registry+https://github.com/rust-lang/crates.io-index"
1019 | checksum = "254df5081ce98661a883445175e52efe99d1cb2a5552891d965d2f5d0cad1c16"
1020 |
1021 | [[package]]
1022 | name = "schannel"
1023 | version = "0.1.19"
1024 | source = "registry+https://github.com/rust-lang/crates.io-index"
1025 | checksum = "8f05ba609c234e60bee0d547fe94a4c7e9da733d1c962cf6e59efa4cd9c8bc75"
1026 | dependencies = [
1027 | "lazy_static",
1028 | "winapi",
1029 | ]
1030 |
1031 | [[package]]
1032 | name = "scopeguard"
1033 | version = "1.1.0"
1034 | source = "registry+https://github.com/rust-lang/crates.io-index"
1035 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd"
1036 |
1037 | [[package]]
1038 | name = "security-framework"
1039 | version = "2.4.2"
1040 | source = "registry+https://github.com/rust-lang/crates.io-index"
1041 | checksum = "525bc1abfda2e1998d152c45cf13e696f76d0a4972310b22fac1658b05df7c87"
1042 | dependencies = [
1043 | "bitflags",
1044 | "core-foundation",
1045 | "core-foundation-sys",
1046 | "libc",
1047 | "security-framework-sys",
1048 | ]
1049 |
1050 | [[package]]
1051 | name = "security-framework-sys"
1052 | version = "2.4.2"
1053 | source = "registry+https://github.com/rust-lang/crates.io-index"
1054 | checksum = "a9dd14d83160b528b7bfd66439110573efcfbe281b17fc2ca9f39f550d619c7e"
1055 | dependencies = [
1056 | "core-foundation-sys",
1057 | "libc",
1058 | ]
1059 |
1060 | [[package]]
1061 | name = "serde"
1062 | version = "1.0.131"
1063 | source = "registry+https://github.com/rust-lang/crates.io-index"
1064 | checksum = "b4ad69dfbd3e45369132cc64e6748c2d65cdfb001a2b1c232d128b4ad60561c1"
1065 |
1066 | [[package]]
1067 | name = "serde_json"
1068 | version = "1.0.72"
1069 | source = "registry+https://github.com/rust-lang/crates.io-index"
1070 | checksum = "d0ffa0837f2dfa6fb90868c2b5468cad482e175f7dad97e7421951e663f2b527"
1071 | dependencies = [
1072 | "itoa",
1073 | "ryu",
1074 | "serde",
1075 | ]
1076 |
1077 | [[package]]
1078 | name = "serde_urlencoded"
1079 | version = "0.7.0"
1080 | source = "registry+https://github.com/rust-lang/crates.io-index"
1081 | checksum = "edfa57a7f8d9c1d260a549e7224100f6c43d43f9103e06dd8b4095a9b2b43ce9"
1082 | dependencies = [
1083 | "form_urlencoded",
1084 | "itoa",
1085 | "ryu",
1086 | "serde",
1087 | ]
1088 |
1089 | [[package]]
1090 | name = "shlex"
1091 | version = "0.1.1"
1092 | source = "registry+https://github.com/rust-lang/crates.io-index"
1093 | checksum = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
1094 |
1095 | [[package]]
1096 | name = "signal-hook-registry"
1097 | version = "1.4.0"
1098 | source = "registry+https://github.com/rust-lang/crates.io-index"
1099 | checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0"
1100 | dependencies = [
1101 | "libc",
1102 | ]
1103 |
1104 | [[package]]
1105 | name = "slab"
1106 | version = "0.4.5"
1107 | source = "registry+https://github.com/rust-lang/crates.io-index"
1108 | checksum = "9def91fd1e018fe007022791f865d0ccc9b3a0d5001e01aabb8b40e46000afb5"
1109 |
1110 | [[package]]
1111 | name = "smallvec"
1112 | version = "1.7.0"
1113 | source = "registry+https://github.com/rust-lang/crates.io-index"
1114 | checksum = "1ecab6c735a6bb4139c0caafd0cc3635748bbb3acf4550e8138122099251f309"
1115 |
1116 | [[package]]
1117 | name = "socket2"
1118 | version = "0.4.2"
1119 | source = "registry+https://github.com/rust-lang/crates.io-index"
1120 | checksum = "5dc90fe6c7be1a323296982db1836d1ea9e47b6839496dde9a541bc496df3516"
1121 | dependencies = [
1122 | "libc",
1123 | "winapi",
1124 | ]
1125 |
1126 | [[package]]
1127 | name = "strsim"
1128 | version = "0.8.0"
1129 | source = "registry+https://github.com/rust-lang/crates.io-index"
1130 | checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a"
1131 |
1132 | [[package]]
1133 | name = "syn"
1134 | version = "1.0.82"
1135 | source = "registry+https://github.com/rust-lang/crates.io-index"
1136 | checksum = "8daf5dd0bb60cbd4137b1b587d2fc0ae729bc07cf01cd70b36a1ed5ade3b9d59"
1137 | dependencies = [
1138 | "proc-macro2",
1139 | "quote",
1140 | "unicode-xid",
1141 | ]
1142 |
1143 | [[package]]
1144 | name = "synstructure"
1145 | version = "0.12.6"
1146 | source = "registry+https://github.com/rust-lang/crates.io-index"
1147 | checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f"
1148 | dependencies = [
1149 | "proc-macro2",
1150 | "quote",
1151 | "syn",
1152 | "unicode-xid",
1153 | ]
1154 |
1155 | [[package]]
1156 | name = "tempfile"
1157 | version = "3.2.0"
1158 | source = "registry+https://github.com/rust-lang/crates.io-index"
1159 | checksum = "dac1c663cfc93810f88aed9b8941d48cabf856a1b111c29a40439018d870eb22"
1160 | dependencies = [
1161 | "cfg-if 1.0.0",
1162 | "libc",
1163 | "rand",
1164 | "redox_syscall",
1165 | "remove_dir_all",
1166 | "winapi",
1167 | ]
1168 |
1169 | [[package]]
1170 | name = "termcolor"
1171 | version = "1.1.2"
1172 | source = "registry+https://github.com/rust-lang/crates.io-index"
1173 | checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4"
1174 | dependencies = [
1175 | "winapi-util",
1176 | ]
1177 |
1178 | [[package]]
1179 | name = "textwrap"
1180 | version = "0.11.0"
1181 | source = "registry+https://github.com/rust-lang/crates.io-index"
1182 | checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060"
1183 | dependencies = [
1184 | "unicode-width",
1185 | ]
1186 |
1187 | [[package]]
1188 | name = "thiserror"
1189 | version = "1.0.30"
1190 | source = "registry+https://github.com/rust-lang/crates.io-index"
1191 | checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
1192 | dependencies = [
1193 | "thiserror-impl",
1194 | ]
1195 |
1196 | [[package]]
1197 | name = "thiserror-impl"
1198 | version = "1.0.30"
1199 | source = "registry+https://github.com/rust-lang/crates.io-index"
1200 | checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
1201 | dependencies = [
1202 | "proc-macro2",
1203 | "quote",
1204 | "syn",
1205 | ]
1206 |
1207 | [[package]]
1208 | name = "time"
1209 | version = "0.1.43"
1210 | source = "registry+https://github.com/rust-lang/crates.io-index"
1211 | checksum = "ca8a50ef2360fbd1eeb0ecd46795a87a19024eb4b53c5dc916ca1fd95fe62438"
1212 | dependencies = [
1213 | "libc",
1214 | "winapi",
1215 | ]
1216 |
1217 | [[package]]
1218 | name = "tinyvec"
1219 | version = "1.5.1"
1220 | source = "registry+https://github.com/rust-lang/crates.io-index"
1221 | checksum = "2c1c1d5a42b6245520c249549ec267180beaffcc0615401ac8e31853d4b6d8d2"
1222 | dependencies = [
1223 | "tinyvec_macros",
1224 | ]
1225 |
1226 | [[package]]
1227 | name = "tinyvec_macros"
1228 | version = "0.1.0"
1229 | source = "registry+https://github.com/rust-lang/crates.io-index"
1230 | checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c"
1231 |
1232 | [[package]]
1233 | name = "tokio"
1234 | version = "1.14.0"
1235 | source = "registry+https://github.com/rust-lang/crates.io-index"
1236 | checksum = "70e992e41e0d2fb9f755b37446f20900f64446ef54874f40a60c78f021ac6144"
1237 | dependencies = [
1238 | "autocfg",
1239 | "bytes",
1240 | "libc",
1241 | "memchr",
1242 | "mio",
1243 | "num_cpus",
1244 | "once_cell",
1245 | "parking_lot",
1246 | "pin-project-lite",
1247 | "signal-hook-registry",
1248 | "tokio-macros",
1249 | "winapi",
1250 | ]
1251 |
1252 | [[package]]
1253 | name = "tokio-macros"
1254 | version = "1.6.0"
1255 | source = "registry+https://github.com/rust-lang/crates.io-index"
1256 | checksum = "c9efc1aba077437943f7515666aa2b882dfabfbfdf89c819ea75a8d6e9eaba5e"
1257 | dependencies = [
1258 | "proc-macro2",
1259 | "quote",
1260 | "syn",
1261 | ]
1262 |
1263 | [[package]]
1264 | name = "tokio-native-tls"
1265 | version = "0.3.0"
1266 | source = "registry+https://github.com/rust-lang/crates.io-index"
1267 | checksum = "f7d995660bd2b7f8c1568414c1126076c13fbb725c40112dc0120b78eb9b717b"
1268 | dependencies = [
1269 | "native-tls",
1270 | "tokio",
1271 | ]
1272 |
1273 | [[package]]
1274 | name = "tokio-socks"
1275 | version = "0.5.1"
1276 | source = "registry+https://github.com/rust-lang/crates.io-index"
1277 | checksum = "51165dfa029d2a65969413a6cc96f354b86b464498702f174a4efa13608fd8c0"
1278 | dependencies = [
1279 | "either",
1280 | "futures-util",
1281 | "thiserror",
1282 | "tokio",
1283 | ]
1284 |
1285 | [[package]]
1286 | name = "tokio-util"
1287 | version = "0.6.9"
1288 | source = "registry+https://github.com/rust-lang/crates.io-index"
1289 | checksum = "9e99e1983e5d376cd8eb4b66604d2e99e79f5bd988c3055891dcd8c9e2604cc0"
1290 | dependencies = [
1291 | "bytes",
1292 | "futures-core",
1293 | "futures-sink",
1294 | "log",
1295 | "pin-project-lite",
1296 | "tokio",
1297 | ]
1298 |
1299 | [[package]]
1300 | name = "tower-service"
1301 | version = "0.3.1"
1302 | source = "registry+https://github.com/rust-lang/crates.io-index"
1303 | checksum = "360dfd1d6d30e05fda32ace2c8c70e9c0a9da713275777f5a4dbb8a1893930c6"
1304 |
1305 | [[package]]
1306 | name = "tracing"
1307 | version = "0.1.29"
1308 | source = "registry+https://github.com/rust-lang/crates.io-index"
1309 | checksum = "375a639232caf30edfc78e8d89b2d4c375515393e7af7e16f01cd96917fb2105"
1310 | dependencies = [
1311 | "cfg-if 1.0.0",
1312 | "pin-project-lite",
1313 | "tracing-core",
1314 | ]
1315 |
1316 | [[package]]
1317 | name = "tracing-core"
1318 | version = "0.1.21"
1319 | source = "registry+https://github.com/rust-lang/crates.io-index"
1320 | checksum = "1f4ed65637b8390770814083d20756f87bfa2c21bf2f110babdc5438351746e4"
1321 | dependencies = [
1322 | "lazy_static",
1323 | ]
1324 |
1325 | [[package]]
1326 | name = "treasurehole"
1327 | version = "0.1.0"
1328 | dependencies = [
1329 | "bytebuffer",
1330 | "bytes",
1331 | "chrono",
1332 | "futures",
1333 | "iui",
1334 | "regex",
1335 | "reqwest",
1336 | "serde_json",
1337 | "tokio",
1338 | ]
1339 |
1340 | [[package]]
1341 | name = "try-lock"
1342 | version = "0.2.3"
1343 | source = "registry+https://github.com/rust-lang/crates.io-index"
1344 | checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642"
1345 |
1346 | [[package]]
1347 | name = "ui-sys"
1348 | version = "0.2.1"
1349 | source = "git+https://github.com/rust-native-ui/libui-rs?branch=trunk#6ff94425b341cf718e29d07067dbf82f9215a6d5"
1350 | dependencies = [
1351 | "bindgen",
1352 | "cc",
1353 | "embed-resource",
1354 | "libc",
1355 | "pkg-config",
1356 | ]
1357 |
1358 | [[package]]
1359 | name = "unicode-bidi"
1360 | version = "0.3.7"
1361 | source = "registry+https://github.com/rust-lang/crates.io-index"
1362 | checksum = "1a01404663e3db436ed2746d9fefef640d868edae3cceb81c3b8d5732fda678f"
1363 |
1364 | [[package]]
1365 | name = "unicode-normalization"
1366 | version = "0.1.19"
1367 | source = "registry+https://github.com/rust-lang/crates.io-index"
1368 | checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9"
1369 | dependencies = [
1370 | "tinyvec",
1371 | ]
1372 |
1373 | [[package]]
1374 | name = "unicode-width"
1375 | version = "0.1.9"
1376 | source = "registry+https://github.com/rust-lang/crates.io-index"
1377 | checksum = "3ed742d4ea2bd1176e236172c8429aaf54486e7ac098db29ffe6529e0ce50973"
1378 |
1379 | [[package]]
1380 | name = "unicode-xid"
1381 | version = "0.2.2"
1382 | source = "registry+https://github.com/rust-lang/crates.io-index"
1383 | checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
1384 |
1385 | [[package]]
1386 | name = "url"
1387 | version = "2.2.2"
1388 | source = "registry+https://github.com/rust-lang/crates.io-index"
1389 | checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c"
1390 | dependencies = [
1391 | "form_urlencoded",
1392 | "idna",
1393 | "matches",
1394 | "percent-encoding",
1395 | ]
1396 |
1397 | [[package]]
1398 | name = "vcpkg"
1399 | version = "0.2.15"
1400 | source = "registry+https://github.com/rust-lang/crates.io-index"
1401 | checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
1402 |
1403 | [[package]]
1404 | name = "vec_map"
1405 | version = "0.8.2"
1406 | source = "registry+https://github.com/rust-lang/crates.io-index"
1407 | checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191"
1408 |
1409 | [[package]]
1410 | name = "version_check"
1411 | version = "0.9.3"
1412 | source = "registry+https://github.com/rust-lang/crates.io-index"
1413 | checksum = "5fecdca9a5291cc2b8dcf7dc02453fee791a280f3743cb0905f8822ae463b3fe"
1414 |
1415 | [[package]]
1416 | name = "vswhom"
1417 | version = "0.1.0"
1418 | source = "registry+https://github.com/rust-lang/crates.io-index"
1419 | checksum = "be979b7f07507105799e854203b470ff7c78a1639e330a58f183b5fea574608b"
1420 | dependencies = [
1421 | "libc",
1422 | "vswhom-sys",
1423 | ]
1424 |
1425 | [[package]]
1426 | name = "vswhom-sys"
1427 | version = "0.1.0"
1428 | source = "registry+https://github.com/rust-lang/crates.io-index"
1429 | checksum = "fc2f5402d3d0e79a069714f7b48e3ecc60be7775a2c049cb839457457a239532"
1430 | dependencies = [
1431 | "cc",
1432 | "libc",
1433 | ]
1434 |
1435 | [[package]]
1436 | name = "want"
1437 | version = "0.3.0"
1438 | source = "registry+https://github.com/rust-lang/crates.io-index"
1439 | checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0"
1440 | dependencies = [
1441 | "log",
1442 | "try-lock",
1443 | ]
1444 |
1445 | [[package]]
1446 | name = "wasi"
1447 | version = "0.10.2+wasi-snapshot-preview1"
1448 | source = "registry+https://github.com/rust-lang/crates.io-index"
1449 | checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6"
1450 |
1451 | [[package]]
1452 | name = "wasm-bindgen"
1453 | version = "0.2.78"
1454 | source = "registry+https://github.com/rust-lang/crates.io-index"
1455 | checksum = "632f73e236b219150ea279196e54e610f5dbafa5d61786303d4da54f84e47fce"
1456 | dependencies = [
1457 | "cfg-if 1.0.0",
1458 | "wasm-bindgen-macro",
1459 | ]
1460 |
1461 | [[package]]
1462 | name = "wasm-bindgen-backend"
1463 | version = "0.2.78"
1464 | source = "registry+https://github.com/rust-lang/crates.io-index"
1465 | checksum = "a317bf8f9fba2476b4b2c85ef4c4af8ff39c3c7f0cdfeed4f82c34a880aa837b"
1466 | dependencies = [
1467 | "bumpalo",
1468 | "lazy_static",
1469 | "log",
1470 | "proc-macro2",
1471 | "quote",
1472 | "syn",
1473 | "wasm-bindgen-shared",
1474 | ]
1475 |
1476 | [[package]]
1477 | name = "wasm-bindgen-futures"
1478 | version = "0.4.28"
1479 | source = "registry+https://github.com/rust-lang/crates.io-index"
1480 | checksum = "8e8d7523cb1f2a4c96c1317ca690031b714a51cc14e05f712446691f413f5d39"
1481 | dependencies = [
1482 | "cfg-if 1.0.0",
1483 | "js-sys",
1484 | "wasm-bindgen",
1485 | "web-sys",
1486 | ]
1487 |
1488 | [[package]]
1489 | name = "wasm-bindgen-macro"
1490 | version = "0.2.78"
1491 | source = "registry+https://github.com/rust-lang/crates.io-index"
1492 | checksum = "d56146e7c495528bf6587663bea13a8eb588d39b36b679d83972e1a2dbbdacf9"
1493 | dependencies = [
1494 | "quote",
1495 | "wasm-bindgen-macro-support",
1496 | ]
1497 |
1498 | [[package]]
1499 | name = "wasm-bindgen-macro-support"
1500 | version = "0.2.78"
1501 | source = "registry+https://github.com/rust-lang/crates.io-index"
1502 | checksum = "7803e0eea25835f8abdc585cd3021b3deb11543c6fe226dcd30b228857c5c5ab"
1503 | dependencies = [
1504 | "proc-macro2",
1505 | "quote",
1506 | "syn",
1507 | "wasm-bindgen-backend",
1508 | "wasm-bindgen-shared",
1509 | ]
1510 |
1511 | [[package]]
1512 | name = "wasm-bindgen-shared"
1513 | version = "0.2.78"
1514 | source = "registry+https://github.com/rust-lang/crates.io-index"
1515 | checksum = "0237232789cf037d5480773fe568aac745bfe2afbc11a863e97901780a6b47cc"
1516 |
1517 | [[package]]
1518 | name = "web-sys"
1519 | version = "0.3.55"
1520 | source = "registry+https://github.com/rust-lang/crates.io-index"
1521 | checksum = "38eb105f1c59d9eaa6b5cdc92b859d85b926e82cb2e0945cd0c9259faa6fe9fb"
1522 | dependencies = [
1523 | "js-sys",
1524 | "wasm-bindgen",
1525 | ]
1526 |
1527 | [[package]]
1528 | name = "which"
1529 | version = "3.1.1"
1530 | source = "registry+https://github.com/rust-lang/crates.io-index"
1531 | checksum = "d011071ae14a2f6671d0b74080ae0cd8ebf3a6f8c9589a2cd45f23126fe29724"
1532 | dependencies = [
1533 | "libc",
1534 | ]
1535 |
1536 | [[package]]
1537 | name = "winapi"
1538 | version = "0.3.9"
1539 | source = "registry+https://github.com/rust-lang/crates.io-index"
1540 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
1541 | dependencies = [
1542 | "winapi-i686-pc-windows-gnu",
1543 | "winapi-x86_64-pc-windows-gnu",
1544 | ]
1545 |
1546 | [[package]]
1547 | name = "winapi-i686-pc-windows-gnu"
1548 | version = "0.4.0"
1549 | source = "registry+https://github.com/rust-lang/crates.io-index"
1550 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
1551 |
1552 | [[package]]
1553 | name = "winapi-util"
1554 | version = "0.1.5"
1555 | source = "registry+https://github.com/rust-lang/crates.io-index"
1556 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
1557 | dependencies = [
1558 | "winapi",
1559 | ]
1560 |
1561 | [[package]]
1562 | name = "winapi-x86_64-pc-windows-gnu"
1563 | version = "0.4.0"
1564 | source = "registry+https://github.com/rust-lang/crates.io-index"
1565 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
1566 |
1567 | [[package]]
1568 | name = "winreg"
1569 | version = "0.7.0"
1570 | source = "registry+https://github.com/rust-lang/crates.io-index"
1571 | checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69"
1572 | dependencies = [
1573 | "winapi",
1574 | ]
1575 |
1576 | [[package]]
1577 | name = "winreg"
1578 | version = "0.10.1"
1579 | source = "registry+https://github.com/rust-lang/crates.io-index"
1580 | checksum = "80d0f4e272c85def139476380b12f9ac60926689dd2e01d4923222f40580869d"
1581 | dependencies = [
1582 | "winapi",
1583 | ]
1584 |
--------------------------------------------------------------------------------