-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathindex.html
1175 lines (781 loc) · 258 KB
/
index.html
1
2
3
4
5
6
7
8
9
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="renderer" content="webkit">
<meta http-equiv="X-UA-Compatible" content="IE=edge" >
<link rel="dns-prefetch" href="http://yoursite.com">
<title>Block Chain</title>
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta property="og:type" content="website">
<meta property="og:title" content="Block Chain">
<meta property="og:url" content="http://yoursite.com/index.html">
<meta property="og:site_name" content="Block Chain">
<meta name="twitter:card" content="summary">
<meta name="twitter:title" content="Block Chain">
<link rel="alternative" href="/atom.xml" title="Block Chain" type="application/atom+xml">
<link rel="icon" href="/favicon.png">
<link rel="stylesheet" type="text/css" href="/./main.b3331d.css">
<style type="text/css">
#container.show {
background: linear-gradient(200deg,#a0cfe4,#e8c37e);
}
</style>
</head>
<body>
<div id="container" q-class="show:isCtnShow">
<canvas id="anm-canvas" class="anm-canvas"></canvas>
<div class="left-col" q-class="show:isShow">
<div class="overlay" style="background: #4d4d4d"></div>
<div class="intrude-less">
<header id="header" class="inner">
<a href="/" class="profilepic">
<img src="/img/gavin.jpg" class="js-avatar">
</a>
<hgroup>
<h1 class="header-author"><a href="/">Gavin</a></h1>
</hgroup>
<nav class="header-menu">
<ul>
<li><a href="/">主页</a></li>
<li><a href="/">随笔</a></li>
</ul>
</nav>
<nav class="header-smart-menu">
<a q-on="click: openSlider(e, 'innerArchive')" href="javascript:void(0)">所有文章</a>
<a q-on="click: openSlider(e, 'friends')" href="javascript:void(0)">web3</a>
<a q-on="click: openSlider(e, 'aboutme')" href="javascript:void(0)">about me</a>
</nav>
<nav class="header-nav">
<div class="social">
<a class="github" target="_blank" href="https://github.com/gguoss" title="github"><i class="icon-github"></i></a>
<a class="twitter" target="_blank" href="https://twitter.com/gguoss" title="twitter"><i class="icon-twitter"></i></a>
<a class="linkedin" target="_blank" href="https://www.linkedin.com/in/%E5%85%89%E5%8D%8E-%E9%83%AD-964b199a/" title="linkedin"><i class="icon-linkedin"></i></a>
</div>
</nav>
</header>
</div>
</div>
<div class="mid-col" q-class="show:isShow,hide:isShow|isFalse">
<nav id="mobile-nav">
<div class="overlay js-overlay" style="background: #4d4d4d"></div>
<div class="btnctn js-mobile-btnctn">
<div class="slider-trigger list" q-on="click: openSlider(e)"><i class="icon icon-sort"></i></div>
</div>
<div class="intrude-less">
<header id="header" class="inner">
<div class="profilepic">
<img src="/img/gavin.jpg" class="js-avatar">
</div>
<hgroup>
<h1 class="header-author js-header-author">Gavin</h1>
</hgroup>
<nav class="header-nav">
<div class="social">
<a class="github" target="_blank" href="https://github.com/gguoss" title="github"><i class="icon-github"></i></a>
<a class="twitter" target="_blank" href="https://twitter.com/gguoss" title="twitter"><i class="icon-twitter"></i></a>
<a class="linkedin" target="_blank" href="https://www.linkedin.com/in/%E5%85%89%E5%8D%8E-%E9%83%AD-964b199a/" title="linkedin"><i class="icon-linkedin"></i></a>
</div>
</nav>
<nav class="header-menu js-header-menu">
<ul style="width: 50%">
<li style="width: 50%"><a href="/">主页</a></li>
<li style="width: 50%"><a href="/">随笔</a></li>
</ul>
</nav>
</header>
</div>
<div class="mobile-mask" style="display:none" q-show="isShow"></div>
</nav>
<div id="wrapper" class="body-wrap">
<div class="menu-l">
<div class="canvas-wrap">
<canvas data-colors="#eaeaea" data-sectionHeight="100" data-contentId="js-content" id="myCanvas1" class="anm-canvas"></canvas>
</div>
<div id="js-content" class="content-ll">
<article id="post-郭大侠的2018" class="article article-type-post article-index" itemscope itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2018/02/19/郭大侠的2018/">郭大侠的2018</a>
</h1>
<a href="/2018/02/19/郭大侠的2018/" class="archive-article-date">
<time datetime="2018-02-19T12:59:00.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2018-02-19</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<p>梁启超先生说:”<strong> 侠之大者,为国为民。侠之小者,为友为邻。</strong>“ 然而在区块链的世界里, 梁先生的话具有时代的局限性,区块链无国界。在区块链的世界,<strong> 侠之大者, 为真理, 为未来, 为人们 </strong>。<img src="/img/大侠.jpeg" alt=""> </p>
<p>当今世界,我能看得上眼的链就5个半。可能真正有用的链也多不了几个。</p>
<ul>
<li>1 Bitcoin, 区块链的鼻祖, 伟大的发明, 打开了我们对区块链的认识。(算1个)</li>
<li>2 Ethereum, VB,Gavin Wood 杰出才能的结合,账户模型智能合约时代的到来。(算1个)</li>
<li>3 Cardano, IOHK最强区块链人才库的支持,以及对BTC和ETH认知的结合。(算1个)</li>
<li>4 EOS, 在我眼里,这不属于公有链, 但有BM这样人的技术尝试。 (算半个)</li>
<li>5 Polkadot, Gavin Wood 力做的多链技术, 因为明年才能落地。 (算半个)</li>
<li>6 Cosmos, 强大的Tendermint 共识, 但在我这里, 也不属于公有链。 (算半个)</li>
<li>7 Zcash, 零知识证明, 密码学的大尝试。 (算半个)</li>
<li>8 Filecoin , 有成熟的IPFS协议做支撑, 但filecoin 的落地,还是未知数。 (算半个)</li>
</ul>
<p>再告诉大家简单判断公有链的几条准则:</p>
<ul>
<li>1, 凡是在ethereum上发行代币并且代币是流通的, 而正在做公有链的, 链发起人肯定没多大理想抱负,只想挣点快钱,然后希望先有钱再做事情。</li>
<li>2,低于2500亿市值的代币,和技术价值不成正比, 因为小马哥的个人资产都有这个数, 操作这市值,太多的人能够做到。</li>
<li>3, 在区块链炒币能够挣钱是正常的, 大家都是希望涨, 涨对大家来说,都是互利的, 至少币的市值没到不可操作的点时, 大家都是有好处的。</li>
</ul>
<p>在区块链一路走来, 我也学了些, 也有些小成就, 也有些长远目标, 说出来, 以此明志:</p>
<ul>
<li>1,参与设计架构Cita。</li>
<li>2,独自设计架构完成Chainmint(Tendermint + Chain)。</li>
<li>3,主导设计架构Bytom。</li>
<li>4, 在Cardano 的计算层, 实现自己的有意义的側链。(准备做)</li>
<li>5, 在polkadot上, 实现自己有意义的平行链。 (准备做)</li>
<li>6, 在filecoin上, 实现小额电脑挖矿算力共享。(思考中)</li>
</ul>
</div>
<div class="article-info article-info-index">
<p class="article-more-link">
<a class="article-more-a" href="/2018/02/19/郭大侠的2018/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<article id="post-如何编译运行CardanoSL" class="article article-type-post article-index" itemscope itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2017/12/24/如何编译运行CardanoSL/">如何编译运行cardano SL?</a>
</h1>
<a href="/2017/12/24/如何编译运行CardanoSL/" class="archive-article-date">
<time datetime="2017-12-24T07:25:05.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2017-12-24</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<h3 id="什么是Cardano-SL?"><a href="#什么是Cardano-SL?" class="headerlink" title="什么是Cardano SL?"></a>什么是Cardano SL?</h3><p>Cardano SL是由IOHK与爱丁堡大学、雅典大学以及康涅狄格大学协作设计开发的加密货币。Cardano SL是基于Haskell实现的,可以看看由Aggelos Kiayias, Alexander Russell, Bernardo David和Roman Oliynykov所写的白皮书 <a href="https://iohk.io/research/papers/#9BKRHCSI" target="_blank" rel="external">Ouroboros协议</a>。你可以将Cardano SL想象成比特币重新构想的一种可以自由修复比特币设计缺陷的升级版比特币。请阅读<a href="https://cardanodocs.com/introduction/#what-makes-cardano-sl-special" target="_blank" rel="external">Cardano SL的与众不同</a>来获取关于Cardano SL与比特币相似点与不同处的更多信息。</p>
<h3 id="Cardano-的分层结构"><a href="#Cardano-的分层结构" class="headerlink" title="Cardano 的分层结构"></a>Cardano 的分层结构</h3><p>Cardano的设计是分层的,Cardano SL是Cardano平台的第一个组成部分, 也就是第一层。最终,它会拓展到”控制层”,作为可信任的计算框架来评估特殊的证明,保证一定量的计算被正确的执行。在游戏和赌博中,这种系统用来验证随机数产生和游戏结果的真实性。加上侧链,可以完成像游戏中可证明的公平分配奖金的任务。不过控制层的应用远远超出了游戏和赌博。身份管理、信用卡系统等等都会成为Cardano平台的一部分。我们还致力于将Cardano SL的钱包应用Daedalus发展成一个通用的加密货币钱包,具有自动化的加密货币之间的交易以及加密货币与法币之间的交易。</p>
<h3 id="如何在nix-模式编译Cardano-SL?"><a href="#如何在nix-模式编译Cardano-SL?" class="headerlink" title="如何在nix 模式编译Cardano SL?"></a>如何在nix 模式编译Cardano SL?</h3><ul>
<li><p>1.安装 Nix (full instructions at <a href="https://nixos.org/nix/download.html" target="_blank" rel="external">https://nixos.org/nix/download.html</a>)</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line"> $ curl https://nixos.org/nix/install | sh</div></pre></td></tr></table></figure>
</li>
<li><p>2.在/etc/nix/nix.conf 下增加索引</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">$ sudo mkdir -p /etc/nix</div><div class="line">$ sudo vi /etc/nix/nix.conf <span class="comment"># ..or any other editor, if you prefer</span></div></pre></td></tr></table></figure>
<p> ..如下两行添加到/etc/nix/nix.conf</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">binary-caches = https://cache.nixos.org https://hydra.iohk.io</div><div class="line">binary-caches-public-keys = hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ=</div></pre></td></tr></table></figure>
</li>
<li><p>3.进入nix-shell模式</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ nix-shell</div></pre></td></tr></table></figure>
</li>
<li><p>4.编译</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ ./scripts/build/cardano-sl.sh</div></pre></td></tr></table></figure>
</li>
</ul>
<p>编译好后, 所有编译好的组件会在cardano-sl/.stack-work/install/x86_64-linux-nix(体系架构不同,该目录不同)/lts-9.1/8.0.2/bin/ 目录下</p>
<h3 id="如何运行Cardano-SL-链接主网?"><a href="#如何运行Cardano-SL-链接主网?" class="headerlink" title="如何运行Cardano SL 链接主网?"></a>如何运行Cardano SL 链接主网?</h3><ul>
<li>1.拷贝 可执行文件<strong>cardano-node</strong> 到cardano-sl 目录下</li>
<li>2.生成topology-mainnet文件./cardano-sl目录下,配置如下:<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div></pre></td><td class="code"><pre><div class="line">wallet:</div><div class="line"> relays: [[{ host: relays.cardano-mainnet.iohk.io }]]</div><div class="line"> valency: 1</div><div class="line"> fallbacks: 7</div></pre></td></tr></table></figure>
</li>
</ul>
<ul>
<li><p>3.运行如下启动命令:</p>
<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$ ./cardano-node --web --no-ntp --configuration-key mainnet_full --tlscert ./scripts/tls-files/server.crt --tlskey ./scripts/tls-files/server.key --tlsca ./scripts/tls-files/ca.crt --log-config ./scripts/<span class="built_in">log</span>-templates/<span class="built_in">log</span>-config-qa.yaml --topology <span class="string">"topology-mainnet"</span> --logs-prefix <span class="string">"state-wallet-mainnet/logs"</span> --db-path <span class="string">"state-wallet-mainnet/db"</span> --wallet-db-path <span class="string">'state-wallet-mainnet/wallet-db'</span></div></pre></td></tr></table></figure>
<p>数据最后都存储在cardano-sl/state-wallet-mainnet</p>
</li>
</ul>
</div>
<div class="article-info article-info-index">
<p class="article-more-link">
<a class="article-more-a" href="/2017/12/24/如何编译运行CardanoSL/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<article id="post-Bytom" class="article article-type-post article-index" itemscope itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2017/12/02/Bytom/">Bytom</a>
</h1>
<a href="/2017/12/02/Bytom/" class="archive-article-date">
<time datetime="2017-12-02T12:52:30.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2017-12-02</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<h3 id="初始化测试网络配置文件"><a href="#初始化测试网络配置文件" class="headerlink" title="初始化测试网络配置文件"></a>初始化测试网络配置文件</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$./bytomd init --chain_id testnet</div></pre></td></tr></table></figure>
<p><img src="/img/bytom_init.png" alt="初始化测试网络配置文件"></p>
<h3 id="启动节点"><a href="#启动节点" class="headerlink" title="启动节点"></a>启动节点</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$./bytomd node --wallet.enable</div></pre></td></tr></table></figure>
<p><img src="/img/启动节点同步中.png" alt="启动节点"></p>
<h3 id="使用bytomcli-查看当前信息"><a href="#使用bytomcli-查看当前信息" class="headerlink" title="使用bytomcli 查看当前信息"></a>使用bytomcli 查看当前信息</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$./bytomcli net-info</div></pre></td></tr></table></figure>
<p><img src="/img/net-info.png" alt="查看邻居节点信息"><br>该图展示了当前节点的邻居节点的相关信息</p>
<h3 id="创建账户"><a href="#创建账户" class="headerlink" title="创建账户"></a>创建账户</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$./bytomcli create-account [account id]</div></pre></td></tr></table></figure>
<p><img src="/img/create-account.png" alt="创建账户"></p>
<p>这时一定要记住自己的私钥xprv, 和账户account id</p>
<h3 id="创建属于你账户的control-program"><a href="#创建属于你账户的control-program" class="headerlink" title="创建属于你账户的control program"></a>创建属于你账户的control program</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$./bytomcli create-account-receiver [account id]</div></pre></td></tr></table></figure>
<p><img src="/img/account_control_program.png" alt="创建资产转移control program"></p>
<p><code>注意:</code> 这时可以把你的control program 记下来, 以后有人给你转btm,或者其他资产, 都是通过这个control program转给你</p>
<p><code>注意:</code> 接下来只有有btm的人才能给你发送btm(两种途径获得。1,能自己同步完,并且挖到矿。2,找bytom官方要)</p>
<h3 id="转移btm"><a href="#转移btm" class="headerlink" title="转移btm"></a>转移btm</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$./bytomcli sub-control-receiver-tx [account xprv] [account id] [asset id] [spend amount] [control_program]</div></pre></td></tr></table></figure>
<p><img src="/img/submit_tx.png" alt="btm转移"><br>等该交易的块被同步完成时,发送者和接收方都可以用如下命令来查看余额<br><figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$./bytomcli list-balances</div></pre></td></tr></table></figure></p>
<p><img src="/img/list_somthing.png" alt="list-balances"></p>
<h3 id="发布资产"><a href="#发布资产" class="headerlink" title="发布资产"></a>发布资产</h3><ul>
<li>1.创建资产<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$./bytomcli create-asset silver</div></pre></td></tr></table></figure>
</li>
</ul>
<p><img src="/img/create-asset.png" alt="创建资产"></p>
<ul>
<li>2.发布资产<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$./bytomcli sub-create-issue-tx [account id] [asset id] [issue amount] [asset xprv] [account xprv]</div></pre></td></tr></table></figure>
</li>
</ul>
<p><img src="/img/isue-asset.png" alt="发布资产"></p>
<ul>
<li>3.查看资产<figure class="highlight bash"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">$./bytomcli list-assets</div></pre></td></tr></table></figure>
</li>
</ul>
<p><img src="/img/list-assets.png" alt="查看资产"></p>
<p><strong>转移其他资产类似于转移btm,只是asset-id 不同</strong></p>
</div>
<div class="article-info article-info-index">
<p class="article-more-link">
<a class="article-more-a" href="/2017/12/02/Bytom/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<article id="post-兰花协议" class="article article-type-post article-index" itemscope itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2017/10/30/兰花协议/">兰花协议</a>
</h1>
<a href="/2017/10/30/兰花协议/" class="archive-article-date">
<time datetime="2017-10-30T08:02:30.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2017-10-30</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<h2 id="兰花《一个通过带宽挖矿激励的完全分布式的匿名代理网络》"><a href="#兰花《一个通过带宽挖矿激励的完全分布式的匿名代理网络》" class="headerlink" title="兰花《一个通过带宽挖矿激励的完全分布式的匿名代理网络》"></a>兰花《一个通过带宽挖矿激励的完全分布式的匿名代理网络》</h2><ul>
<li>作者: David L. Salamon, Brian J. Fox, Jay Freeman, and Gustav Simonsson with Stephen F. Bell, and Dr. Steven Waterhouse, Ph.D.</li>
<li>Version 0.9.0</li>
<li><a href="https://orchidprotocol.com/whitepaper.pdf" target="_blank" rel="external">原文</a> </li>
</ul>
<p><img src="/img/orchildprotocol.png" alt=""> </p>
<h3 id="摘要"><a href="#摘要" class="headerlink" title="摘要"></a>摘要</h3><p>互联网的飞速发展, 越来越多的方法和途径可以很有效的快速发现和查找个人及组织的隐私, 因此, 大众对匿名化保护隐私的需求越来越迫切。 虽然现在有些方法(如I2P和洋葱网络)被广泛采用,但是这些网络只有几千名志愿者愿意加入中继和出口节点, 这样会导致攻击者可以用很少数量的节点轻易的监视整个加密网络。我们提出基于市场的“带宽挖矿“的方法, 来激励大家加入中继和出口节点。<br>本文旨在描述一个一直在开发的系统。因此会实时的更新该文内容,用以描述在实施当中遇到问题而对系统的调整; 并且该系统可以灵活的使用库组件和特定的加密算法。然而, 不管怎样调整系统,系统的本质会保持目标和目的不变。<br>我们的设计内容包括:</p>
<ul>
<li>基于区块链(具有顺序打包交易的数据)的随机支付机制</li>
<li>带宽销售规格的商品说明书</li>
<li>归纳证明一个在对等分布式系统中使得Eclipse攻击非常困难的方法</li>
<li>在攻击者可能会将其出价作为攻击的一部分的情况下,适用于销售带宽的高效安全硬化拍卖机制</li>
<li>完全分布式的匿名带宽市场</li>
</ul>
<h3 id="1-介绍"><a href="#1-介绍" class="headerlink" title="1. 介绍"></a>1. 介绍</h3><p>兰花协议将带宽卖家组织成一个刚性结构化的对等(P2P)网络,称为兰花市场。客户连接到兰花市场,并向多个带宽卖家做支付,形成特定网络服务器的代理链。 代理链允许客户从全球互联网发送和接收数据。<br><img src="/img/Orchid_connect.png" alt=""><br>与从全球互联网发送和接收数据的更常见的方法不同,兰花市场中的代理链自然地将关于数据的来源和目的信息分离;没有一个中继或代理同时持有两条信息,或者知道某人的身份。兰花市场的刚性结构进一步支持信息分离,提供强大的抵抗串通攻击的能力 — 一组带宽卖家克服知识分离的能力。不同于互联网数据常用的传输方法,兰花市场提供固定速率中继,以防止流量分析,并通过代币激励大家发现检举隐藏或者信息无关的参与的参与节点。在我们描述系统的细节之前,我们将简要回顾一下解决的核心问题,以及我们为系统基础选择的一般解决方案。</p>
<h4 id="1-1-信息加密传送问题"><a href="#1-1-信息加密传送问题" class="headerlink" title="1.1. 信息加密传送问题"></a>1.1. 信息加密传送问题</h4><p><strong>问题陈述</strong>:想象一下,你在一个充满数学家的食堂里,希望在没有任何人知道这个事实的情况下,向你的朋友发送消息。 您尚未通过指定协议传递消息,因此所有实施细节都必须向所有人公开声明。 可以怎么做呢?<br>Chaum在1981年提出的这个问题的一个特别优雅的解决方案是让每个人都作为一个中继和一个接收者。 在这个方案中,参与者准备加密的消息,它们是数字等效的“包含信封的信封” - 向Alice发送消息,你会计算<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">Enc(“T oBob 00 ||Enc(“T oAlice 00 ||Enc(message, Alice), Bob), Carol)</div></pre></td></tr></table></figure></p>
<p>并将该消息发送给Carol,他们将其解密并发送给Bob,Bob将其解密并发送给Alice。 为了防止流量分析,每个周期都会发送固定数量的消息。 为了处理返回地址,我们可以让Bob和Carol记住一个唯一的消息标识符,然后沿着这一条链路发送消息。<br>对使用上述方法的系统特别重要的是共谋的可能性。 如果Bob和Carol合作,他们可能会决定谁发送给定的消息以及发送给谁的消息。</p>
<h4 id="1-2-女巫问题"><a href="#1-2-女巫问题" class="headerlink" title="1.2. 女巫问题"></a>1.2. 女巫问题</h4><p>上述食堂问题陈述使用每个人本身来防止女巫攻击 - 一个参与者可能假装是任意大量的用户的情况。 不幸的是,在数字系统中,这种方法是不能使用的。<br><strong>问题陈述</strong>:我们如何知道某人在纯数字环境中是“真实的”?<br>这个问题的解决方案可以在Hashcash [81]中找到。如果我们要求声称是“真实的”来消耗计算资源的话,那么我们可以把女巫攻击者置于只有拥有不可思议的计算资源才有能力攻击的位置。</p>
<h4 id="1-3-随机选择问题"><a href="#1-3-随机选择问题" class="headerlink" title="1.3. 随机选择问题"></a>1.3. 随机选择问题</h4><p>上述食堂问题陈述假定了一种向系统的每个其他用户发送消息的简单方法(例如,横跨自助餐厅)。为了实现最大限度地抵抗“共谋攻击”的Chaumian组合,我们需要能够从那些“真实”的中继节点中随机选择。无论何时加入或离开网络,都需要收到通知。不幸的是,在现实世界的P2P网络中,每个用户维护这样的列表将导致不可接受的网络流量(O(n 2)通知)。<br><strong> 问题描述 </strong>:我们如何维护所有当前“真实”中继节点的分布式列表,以最大限度地减少网络开销,并支持高效率的随机选择对等体?<br>Chord [81]分布式哈希表(DHT)中可以找到一个特别优雅的解决方案。 在该方案中,对等体在大空间中分配唯一的地址,然后以在O(log(n))时间内执行查找的方式连接。 添加或删除用户只需要通知O(log(n))对等体。</p>
<h4 id="1-4-系统总览"><a href="#1-4-系统总览" class="headerlink" title="1.4. 系统总览"></a>1.4. 系统总览</h4><p>“兰花协议”的核心是上述解决方案的组合。在我们的方法中,同行们需要制作奖章来证明他们的“真实性”,然后被组织成一个称为兰花市场的分布式P2P网络。为了保持兰花市场的参与者诚实,每个同行都会检查其邻居行为的正确性。客户然后使用兰花市场为Chaumian消息转发选择随机对等体。为了激励参与,我们的客户以每转发字节为单位向中继节点支付报酬。<br>这想法虽然简单,但依然需要魔鬼的细节。系统要完全分散,完全自主,完全匿名,并且能做金融交易。因此,本设计文件的大部分内容集中在防止对客户安全,系统性能和系统经济性的攻击稳健。虽然攻击分析是重要的,并且将占用我们大部分时间,但最终只不过是市场运行背景下的必要条件; 如果你发现自己“迷失在森林里”,我们希望你将使用前面的总览作为你的北极星 - 系统的设计细节都是为了实现上述三个问题的真实解决方案。</p>
<h3 id="2-攻击"><a href="#2-攻击" class="headerlink" title="2. 攻击"></a>2. 攻击</h3><p>本文的大部分内容都是针对攻击预防,我们首先回顾一下关于这些攻击的文献对P2P网络尤其常见。</p>
<h4 id="2-1-攻击目标"><a href="#2-1-攻击目标" class="headerlink" title="2.1. 攻击目标"></a>2.1. 攻击目标</h4><p>2.1.1. 信息收集<br>兰花协议必须保卫的最大的攻击类型是 揭示有关其用户的信息。因为兰花被实现为现有互联网上的叠加层,一些信息不可避免地与一些同行共享。 在下面的列表中,这样的信息被标记为“*”。任何未被明确列出的信息在本文档中不可避免地共享,但是发现了一种方法来发现信息被称为信息攻击,并被Orchid的White Hat Bug Bounty所覆盖。有关共享内容的更多信息,请参见第8节中的协议规范和第9.2节中的串通讨论以及网络参考实现[1]。<br>被认为是攻击者感兴趣的数据的类型(永恒的):</p>
<ul>
<li>现实世界的身份信息。 如用户的姓名, SSN, 地址等。</li>
<li>网站帐户信息。用户帐户在特定的网站。 注意这可以查找不同现实世界身份信息。</li>
<li>*IP信息。 用户访问兰花网络的IP地址。 请注意,在某些使用场景中,这可能等同于知道“真实世界身份信息”。</li>
<li><em>ethereum信息。 与用户钱包相关联的</em>公钥和私钥。 请注意,在某些使用场景中,这可能等同于知道“真实世界身份信息”。</li>
<li><em>兰花网络信息。 与兰花网络上的节点当前业务相关联的密钥(</em>公钥或私钥)。<br>被认为是攻击者感兴趣的行为信息的类型(时间和链相关联数据):</li>
<li>*客户识别。 攻击者探悉客户的IP地址。</li>
<li>*中继识别。 攻击者探悉中继的IP地址。</li>
<li>*代理识别。 攻击者探悉代理的IP地址。</li>
<li>*链接识别。 攻击者探悉到在链中使用了两个IP地址。</li>
<li>*网站访问。 攻击者探悉到兰花网络进行了outbound连接到一个特定的网站。</li>
<li>*Web服务器访问。攻击者了解到,从兰花网络到特定的网络服务器(可能会托管多个网站)进行了出站连接。</li>
<li>*以太坊联系。 攻击者了解到,一个兰花用户持有一个Ethereum公钥。</li>
<li>*购买联系。 攻击者了解到两个交易共享一个付款人。</li>
<li>*购买信息。 攻击者了解通过链发送的带宽的数量和时间。<br>尽管上述行为信息在正常操作期间与兰花网络上的其他节点共享,如下所述,在大多数情况下,假设用户只有在行为信息收集时才会受到直接的伤害,如果攻击者可以快速探悉几条信息。例如,要说用户X访问了网站Y,攻击者将需要:买方识别,网站访问信息和几条链接标识。 因此,遵循参考规格的同行不会存储或共享上述任何信息,除非提供客户购买的服务所需。<h4 id="2-2-经济攻击"><a href="#2-2-经济攻击" class="headerlink" title="2.2. 经济攻击"></a>2.2. 经济攻击</h4>与相关系统不同, 兰花协议必须关心支付机制的攻击。本文归纳两大类如下:<br>-1. 经济利益。 有利的不良行为,例如用户提供“免费样品”带宽,允许用户专门使用免费样品带宽。<br>-2. 经济拒绝服务(EDoS)。 使用付款来淹没兰花网络上的另一个节点进行购买,从而使其脱机。<h4 id="2-3-服务质量攻击"><a href="#2-3-服务质量攻击" class="headerlink" title="2.3. 服务质量攻击"></a>2.3. 服务质量攻击</h4>一些对手可能会通过放慢兰花网络用户的系统性能来满足,从而潜在地减少使用。<h4 id="2-4-中间人攻击"><a href="#2-4-中间人攻击" class="headerlink" title="2.4. 中间人攻击"></a>2.4. 中间人攻击</h4>只有在两个互动方之间插入自己才能执行的操作统称为中间人攻击。可以记录加密的信息用于分析元数据(第2.8节),而非加密数据可能另外被更改为控制行为。如果密钥交换没有得到保障,中间人也可能会欺骗双方使其错误地认为攻击者的密钥是对方的密钥。<h4 id="2-5-女巫攻击"><a href="#2-5-女巫攻击" class="headerlink" title="2.5. 女巫攻击"></a>2.5. 女巫攻击</h4>伪装成多个用户执行恶意行为称为Sybil攻击,使被攻击者承受多方伪装用户的假冒数据。这种攻击的应用包括:</li>
<li>向Yelp, Amazon 等平台提供多个reviews。</li>
<li>通过假装是多个倾听者来实现BitTorrent从而可以快速下载[72]。<h4 id="2-6-日蚀攻击"><a href="#2-6-日蚀攻击" class="headerlink" title="2.6. 日蚀攻击"></a>2.6. 日蚀攻击</h4>在日蚀攻击中,攻击者的目标是隐藏系统的一部分。 采用的方法是一般网络相当于特权升级攻击:获得网络位置的控制权更多地控制网络,然后使用该控制来获取更多的控制权。</li>
<li>比特币的p2p,所有节点都是平等地位,端口数是有限制的,需要”51%”攻击的比特币网络把临近节点的端口数全被攻击者给占用,以致用小于51%的算力通过欺骗临近节点加入自己的网络,对比特币形成“51%“攻击。</li>
<li>通过接管与磁链接相关联的地址空间,从BitTorrent DHT中删除文件[83]。<h4 id="2-7-拒绝服务攻击"><a href="#2-7-拒绝服务攻击" class="headerlink" title="2.7. 拒绝服务攻击"></a>2.7. 拒绝服务攻击</h4>拒绝服务攻击即是攻击者想办法让目标机器停止提供服务。 “意外”情况下的系统行为通常指定和测试不足。 DoS攻击对P2P网络中的节点进行去匿名化是非常有用的。</li>
<li>对特定目标DoS攻击结合女巫攻击来监测Tor的流量从而获悉匿名化的信息[53]。</li>
<li>只需要20个女巫节点,Dos就能 完全可以泛滥式攻击I2P的数据库使其脱机,从而对网络上的所有流量进行归档。<h4 id="2-8-推理攻击"><a href="#2-8-推理攻击" class="headerlink" title="2.8. 推理攻击"></a>2.8. 推理攻击</h4>源于系统行为的统计建模的去匿名化被称为推理攻击或监视攻击。这些通常与精心制作或定时的“探测动作”相结合请求或其他攻击,例如DoS将特定对等体脱离网络并观察流量模式<br>响应。</li>
<li>从SSL加密的Web流量推断医疗疾病、家庭收入和最终用户的投资选择[ 58 ]。</li>
<li>来自全球传输日志的Tor,I2P和兰花流量的分析去除匿名[60]。</li>
<li>通过时序分析学习OpenSSL服务器的私钥[55]。<h4 id="2-9-黑客"><a href="#2-9-黑客" class="headerlink" title="2.9. 黑客"></a>2.9. 黑客</h4>通过将历史上可信赖的对等体转换为攻击向量,激励的攻击者可能会直接危及网络上的节点。当使用链部署带宽时,迭代黑客可能最终允许攻击者“回溯”连接。这种攻击具有重要的安全隐患,但不符合兰花网络的范围。 如果兰花网的设计达到目标,这将是对系统用户的主要攻击。<h3 id="3-可替代的方法"><a href="#3-可替代的方法" class="headerlink" title="3. 可替代的方法"></a>3. 可替代的方法</h3><h4 id="3-1-不受保护的互联网访问"><a href="#3-1-不受保护的互联网访问" class="headerlink" title="3.1. 不受保护的互联网访问"></a>3.1. 不受保护的互联网访问</h4>在没有保护的情况下访问互联网的用户将其完整的浏览历史记录和网站使用情况提供给ISP,然后他们可以共享或出售该数据。<h4 id="3-2-虚拟专用网络(VPN)服务"><a href="#3-2-虚拟专用网络(VPN)服务" class="headerlink" title="3.2. 虚拟专用网络(VPN)服务"></a>3.2. 虚拟专用网络(VPN)服务</h4>虚拟专用网(VPN)使用加密技术将VPN用户的流量安全地传输到更大的不安全网络。 一旦VPN接收到流量,它将被解密并通过不同的大型不安全网络重新传输。 重传可以帮助用户规避网站的访问限制,并在较小的程度上减少对他们网站浏览习惯的跟踪。加密防止用户的ISP看到他们的流量,从而防止监视攻击。 这是通过使VPN成为用户的新ISP来实现的。 以前ISP可以执行的任何攻击都可以由VPN提供商轻松执行。<br>VPN用户不应该认为他们的VPN提供商是值得信赖的。 尽管VPN服务提供商面临比ISP更多的竞争,但他们最终从相同的来源获得人才,并且具有类似的带宽 - 强制型商业模式。 VPN提供商不可能不会受到导致用户不信任他们的ISP的同样的激励。 另外,在VPN设置中重复使用IP地址来中继流量,可以相对容易地阻止商业网站的使用[13]。<h4 id="3-3-Tor"><a href="#3-3-Tor" class="headerlink" title="3.3. Tor"></a>3.3. Tor</h4>Tor [61]是一个免费软件项目,以向更广泛的受众介绍洋葱路由的思想而闻名。 在这个系统中,用户下载一个中继和出口节点的全局列表,随机从列表中选择,并从他们的选择形成洋葱路线。 洋葱路线是中继的有序列表; 为每个对等体轮流发送的数据包依次加密,确保每个节点都必须收到一个数据包才能被出口节点理解。结果是,除非有多个节点被同一个用户入侵或运行,否则两个中继都不知道谁发送了一个数据包,也不知道它到了哪里。<h3 id="4-扩展库"><a href="#4-扩展库" class="headerlink" title="4. 扩展库"></a>4. 扩展库</h3>兰花的功能是建立在几个重要的组件上。 由于一些读者可能不熟悉这些原语,或者不熟悉兰花网络中使用的特定属性,我们在这里简要总结一下。<h4 id="4-1-WebRTC"><a href="#4-1-WebRTC" class="headerlink" title="4.1. WebRTC"></a>4.1. WebRTC</h4>WebRTC [48]是最初设计用来促进Web浏览器之间实时通信的系统。 它提供了优秀的NAT和防火墙穿越方法,包括STUN,ICE,TURN和RTP-over-TCP。 通过选择WebRTC作为我们网络协议的基础,而不是定制编码的TCP和UDP网络代码,我们都获得了这些技术的世界级实施,并且(在一定程度上)将用户的流量掩盖为一般的网络流量。<h4 id="4-2-NACL"><a href="#4-2-NACL" class="headerlink" title="4.2. NACL"></a>4.2. NACL</h4>NaCL [49](发音为“salt”)是Daniel J.Bernstein等人的一个密码学库,专注于构建构建高级加密工具所需的核心操作。 它被选为这个项目的密码原语的来源,因为它和它的作者的英镑声誉。 下面介绍的所有加密操作都是使用NaCL实现的,除了以太坊智能合约加密代码。<h4 id="4-3-以太坊"><a href="#4-3-以太坊" class="headerlink" title="4.3. 以太坊"></a>4.3. 以太坊</h4>以太坊[56]是一个分散的区块链平台,包括一个本地货币(ETH)和Turingcomplete智能合约。 这些智能合约对于Orchid的设计非常有用,使我们能够减轻与追踪付款余额有关的大量设计问题,以及Orchid付款门票的验证和公正性。<h3 id="5-奖章"><a href="#5-奖章" class="headerlink" title="5. 奖章"></a>5. 奖章</h3>完全分散的,完匿名的数字系统遭受单个恶意用户假装成千上万用户(Sybil攻击)的攻击。<br>为了打击这类攻击,兰花协议使用奖章 - 数据表明给定的公钥在给定时间拥有相当数量的计算。 由于计算是一种昂贵的资源,因此使用奖章会对给定的攻击者假冒多个用户的能力造成预算限制。<h4 id="5-1-奖章规则"><a href="#5-1-奖章规则" class="headerlink" title="5.1. 奖章规则"></a>5.1. 奖章规则</h4>为了生成奖章,对等体采用公钥K,并且最近的以太坊块哈希E,然后(迭代地或并行地)定位盐S,使得H(K,E,S)≥ N,其中N是一些 难度缩放因子。<br>因为它是特定的密钥,所以不能用来模拟多个公钥。 因为它被绑在一个以太坊块哈希,不能预先计算。<h4 id="5-2-证明类型的选择"><a href="#5-2-证明类型的选择" class="headerlink" title="5.2. 证明类型的选择"></a>5.2. 证明类型的选择</h4>熟悉其他基于分布式市场的网络的读者将会认可Medallion在工作证明系统(比特币等)的前提下是相似的,并且可能会倾向于问:为什么不使用权益证明(proof-of-stake), 空闲证明(proof-of-idle),还是其他不那么有力的浪费方法来证明“真实性”?<br>权益证明取决于没有攻击者将控制大多数代币的假设。 由于我们的攻击模式包括压迫政府,这是不能指望的。 即使比特币的惊人的市值也远远低于一个中等规模国家的国内生产总值。更为复杂的是,在不久的将来,我们打算将这个系统扩大到支持匿名支付,这将使得发现这种“敌意收购”变得更加困难。简而言之:我们并没有使用权益证明,因为我们不想设计一个系统,让我们的用户的隐私权可以出售给出价最高的人。<br>空间证明(proof-of-space)看起来更有趣。尽管我们不确定将找到合适的方法,但我们会在即将到来的兰花协议版本中使用空间证明。 例如,这将允许用户在家中安装旧的智能电话作为中继和代理。有关这个想法的更多信息,请参见15.1节。<br>空闲证明基于额外的假设,即周期性同步工作证明足以证明用户对全局计算能力的分享。<br>遗憾的是,在网络尚处于起步阶段(少于1,000万传播者)的情况下,任何一家控制超级计算中心的公司都只要牺牲1%的计算能力就能控制网络。正如我们所指出的,在我们没有拥有足够数量的传播者之前,我们不会使用空闲证明。<h3 id="6-奖章式工作证明"><a href="#6-奖章式工作证明" class="headerlink" title="6. 奖章式工作证明"></a>6. 奖章式工作证明</h3>奖章构成了我们核心安全假设与整个网络之间的桥梁。由于我们的基本安全目标是限制激励攻击者获得对兰花网络的控制权,因此我们选择的奖章创作必须符合以下条件:</li>
</ul>
<ol>
<li>对于非恶意节点来说,创建奖章必须非常容易。</li>
<li>奖章必须很容易验证。</li>
<li>奖章必须难以批量创建。<br>有了这些条件,我们将难度定义为在时间和金钱上的高度可伸缩性。 简而言之,我们需要一个工作证明系统,在这个系统中,一个正常的节点很容易进入网络,但攻击者难以进入网络。 我们将讨论我们选择的工作证明,而不是其他方法,例如权益证明或者空间证明。<br>目前存在两种主要的方法来满足上述要求:质询-响应协议和加密难题。不幸的是,质询- 响应协议可能不能在兰花模型中提供足够的安全性,因为攻击者可能通过合谋预先计算质询并作出响应。这留下了今天有很多存在的加密难题[51,76],每个难题都有自己的权衡。同样,为了满足兰花的要求,只有这些密码拼图的一个子集是合适的。也就是说,平行化的密码拼图,制作成ASIC,或平凡地缩放这样的手段是非常困难的。最近,研究人员发现了一些算法,可以产生易于验证的结果,这些结果具有可调的创建难度[51]。这些算法集合利用了内存和总硅片面积昂贵的趋势[46,62]。这类算法被称为不对称记忆硬功能,我们用它们来创建奖章。这些功能有几种类型[51,73,82],但我们选择使用Equihash。Equihash基于k-XOR生日问题,通过时空折衷方案提供记忆硬度。由于Equihash是可调的,简单的,基于NP问题,并且已经在加密货币社区中被接受,所以我们相信使用这样的函数作为我们的工作证明基础提供了可接受的安全性和面向未来的水平。<br>为了产生奖章,一个同伴拿一个公钥K,以前的以太坊块散列E,然后进行一系列的计算,以便定位一个盐S,使得F(K,E,S,…)≥N 其中N是一些难度缩放因子。 当一个新的以太坊块被添加到链中时,必须计算一个新的S来保持当前的奖章。</li>
</ol>
<h3 id="7-支付"><a href="#7-支付" class="headerlink" title="7. 支付"></a>7. 支付</h3><h4 id="7-1-兰花支付需求"><a href="#7-1-兰花支付需求" class="headerlink" title="7.1. 兰花支付需求"></a>7.1. 兰花支付需求</h4><p>支付带宽是一个相当独特的挑战。 在大多数其他支付系统中,物品的成本远远高于发送包的成本,因此联网成本可能被安全成本忽略,被包括在交易成本中。然而,在兰花网络中,一个包的成本就是支付的价格,所以即使支付的交易成本低于一个包,它们的购买成本也是相同的。<br>因此,我们要求交易费用足够低,以便用户可以(自动通过Orchid客户端)支付任意数量的中继流量,直至单个数据包。除了低交易费用之外,支付机制必须足够精细,以至于可以进行微支付甚至纳支付。这不仅要求支付机制的效率,而且要求支付基础物品或可核实记录的可分性。<br>由于兰花网络的目的是为了摆脱网络监控和审查制度,支付机制的其他要求还包括不可靠,匿名,不依赖于可信任的第三方。即使底层网络不受监视和审查,如果付款机制不是,那么它就将使得用户可以被审查和跟踪。同样,可信赖的第三方可能在影响支付提供商的国家行为体和其他强大实体的干涉之下暴露兰花网络暴。<br>因此,兰花网络的支付需求包括:<br><em>1. 不可伪造性,只有拥有付款接受的抵押物品或可核实记录的所有者才能够使用它进行付款。
</em>2. 可用性,意味着没有人可以阻止用户发送兰花付款,也没有人可以阻止收款人收到付款。<br><em>3. 不可逆转性,即使是付款方,也不可能扭转过去的付款。
</em>4. 匿名,定义为发件人和收件人的不可链接性,无论是按帐户地址,金额还是时间,都找不到用户信息走过的痕迹。 理想情况下,匿名会达到如下的效果: 不仅是在恶意的观察者的攻击下,还是发送者或接收者的恶意攻击下,都能是匿名的。<br>在下面的章节中,我们将讨论支付的潜在解决方案,牢记这些要求。我们会辩证的去讨论,兰花支付(7.12节)完成除匿名要求以外的所有内容。下面,我们继续讨论支付匿名,效率的扩展和改进。</p>
<h4 id="7-2-数据包的成本"><a href="#7-2-数据包的成本" class="headerlink" title="7.2. 数据包的成本"></a>7.2. 数据包的成本</h4><p>为了讨论的目的,假设一个数据包长度为1×103个字节。 为了计算上限,我们观察到亚马逊网络服务的新加坡CloudFront是最昂贵的云服务之一,每1×109字节收费0.14美元。 这产生了每个数据包的成本为1.4×10-5($ 0.00000014)。由于带宽是一种浪费(任何未售出的带宽永远丢失),实际价格可能会明显低于这个上限。</p>
<h4 id="7-3-传统支付"><a href="#7-3-传统支付" class="headerlink" title="7.3. 传统支付"></a>7.3. 传统支付</h4><p>在目前的金融支付系统中,交易是通过两个或两个以上的实体(如银行或支付服务提供商[2])之间的谈判来解决的,支付卡采用ISO / IEC 7816 [3],银行支付采用EBICS [4]。这些协议运行在SWIFT [5]和NYCE [6]等网络上,以支持国内和国际交易。组成这些网络的实体每个都保留自己的分类账,并不断从电子支付收据和手动调解中更新它们[7]。<br>连接到传统的支付网络通常需要大多数司法管辖区的特殊许可以及连接实体之间的逐案业务协议。由此产生的全球金融网络可以被看作是连接企业和协议和网络混合的一个许可的临时网络。每一个分类账都代表一个单一的失败点,缺乏密码的完整性,并可以随意的控制业务实体。<br>虽然传统的支付协议通常不会自行定义交易费用,但是运行协议的实体却增加了收费。 每笔交易费用可以从支付卡交易的几美分[8]到国际电汇[75]的75美元不等。 许多系统反过来又收取了一笔交易金额的百分比费用,对于银行转账支付可能高达13%[10],对支付卡支付则为3.5%[11]。<br>由于传统付款取决于可信任的各方,因此在不牺牲我们所需的性能的情况下,实际上不可能使用兰花网络。特别是,可逆性是以逆转交易的形式设计出来的[75]。 交易通常很难伪造,但信用卡欺诈是常见的,身份盗窃或黑客攻击可能导致用户帐户被盗用。此外,这些支付系统仅提供部分可用性,因为它们往往在不方便的时候发生故障并定期遭受停机。由于管理支付的可信方通常不仅有发送者,接收者,支付金额和时间的记录,而且经常还有关于发送者的身份信息,所以缺乏匿名性。 最后,我们将在下面的章节中看到,传统支付的交易费用相对于兰花市场来说,将非常昂贵。</p>
<h4 id="7-4-区块链支付"><a href="#7-4-区块链支付" class="headerlink" title="7.4. 区块链支付"></a>7.4. 区块链支付</h4><p>比特币彻底改变了传统支付系统的现状,并继续扰乱全球支付和国际转移市场。比特币是一个全球性的网络和协议,不知道地理边界。 应用公钥密码术,交易在用户自己生成的地址之间转移比特币金额,而不需要任何可信任的方。 用户生成密钥对,其中公钥的散列可以用作支付地址,要求私钥签名从地址传输[12]。 比特币支付是不可伪造的,不可逆转的[77](在合理的时间内以计算区块确认)。 比特币网络自成立以来停机时间最短,而矿工(除了第7.6节进一步讨论的)不太可能出现活跃的审查情况,因此可以将其视为普遍可用。比特币支付是伪匿名的,匿名程度在很大程度上取决于 如何使用网络[68]。<br>一般来说,分散式加密货币允许人类和计算机系统在历史上第一次在没有可信赖的第三方的情况下进行价值交易 - 激励的分布式覆盖网络(如兰花)。<br>比特币的交易费用不是由交易金额决定的,而是由交易数据结构的大小乘以发件人配置的因子决定的。 直到2017年,平均交易费仍远低于1美元,但随着比特币网络达到最大交易容量,2017年2月费用迅速上涨。 平均费用上涨了13美元,高达8美元,使得依靠比特币网络上的低费用的应用程序成为可能。<br>以太坊网络也植根于公钥密码学,并通过像比特币这样的工作证明进行保护,从而获得了不可伪造性,可用性和(非经典)不可逆性的相同属性。 以太坊拥有更高的动态可调整的交易容量,自2015年推出以来,网络的收费水平一直很低。但是,由于交易数量增加以及以太坊基础本地代币Ether的交易费用(称为gas )已经增长[14],平均为0.20美元,最高达到1.00美元。 执行智能合同代码的交易成本更高,与执行多少计算成比例。<br>流行的公共区块链网络中的交易费用的增长,阻碍了他们直接处理小额支付的潜力,将小额支付推向支付通道等第二层解决方案。</p>
<h4 id="7-5-以太坊交易成本"><a href="#7-5-以太坊交易成本" class="headerlink" title="7.5. 以太坊交易成本"></a>7.5. 以太坊交易成本</h4><p>以太坊智能合约允许创建复杂的支付机制,利用以太坊虚拟机[85](EVM)的能力和灵活性,在经济范围内提供图灵完整的执行环境。 以太坊智能合约执行的每条指令都会增加原始交易的交易费用。<br>每个EVM指令花费一定量的gas,以太坊交易费用定义为交易所花费的总gas量乘以发送方设置的gas价格。 矿工选择任何有效的交易纳入其开采块,可以包括交易与任何gas价格,包括零。 选择gas价较高的交易可能导致更多的利润,因为每个区块都有可以包含多少交易的限制。 同样,接受较低的gas价格也可能导致更多的利润,因为如果网络没有以最大容量运行,它可以允许矿工填满他们的区块。 这种机制创造了一个不断变化但稳定的博弈理论平衡,这个平衡被以太坊加油站这样的网站跟踪[15]。<br>截至2017年10月,在几个区块内获得高概率的交易成本为0.026美元。 要在15分钟内确认,$ 0.006就足够了。 这些估计是交易的基本成本 - 21,000gas,无需执行任何明智的合同代码即可进行简单的以太币转移交易。 如果交易执行智能合约代码,则每个EVM指令都会增加额外的gas成本。 例如,在智能合约存储中永久存储新的256位值需要花费20,000个gas,更新现有值需要花费5,000个gas。<br>作为Ethereum ERC20分类账本仅仅是账户地址到余额的映射,ERC20代币转账的成本应该是:新账户需要21,000 + 20,000gas,随后老账户转账需要21,000 + 5,000gas(因为收款人账户已经有了 代币分类帐本)。 观察现场[16] ERC20交易,我们看到gas成本稍高,约52,000和37,000gas转移到新的和现有的帐户。 不同之处在于智能合同代码执行不变式验证,例如发件人是否具有足够的余额以及其他实现细节(如付款收据的记录)。 50,000gas需要交易费用0.014美元至0.062美元之间,这取决于我们希望交易确认的速度。</p>
<h4 id="7-6-兰花代币"><a href="#7-6-兰花代币" class="headerlink" title="7.6. 兰花代币"></a>7.6. 兰花代币</h4><p>兰花网络使用基于以太坊的ERC20代币,以满足不可伪造性,可用性和不可逆性的支付要求。 以下部分将讨论我们如何降低ERC20转帐的交易费用以实现任意小的代币数额。 匿名在7.17节中讨论。<br>兰花代币(OCT)用于兰花网络内的支付。 兰花代币是基于以太坊发行的固定供应量的ERC20代币。 供给固定在1×10^8个, 每个代币有1×10^18个不可分割的子单元(与Ether相同的可分解性)。<br>乍一看,以下部分详细介绍的兰花支付系统可以配置为使用Ether或任何ERC20代币。 事实上,使用以太币将简化票务合同,稍微降低交易费成本,提高可用性,因为用户只需要Ether,而不必同时购买兰花代币和Ether(交易费用)。<br>然而,以太坊计划未来的协议升级,允许交易费用由任意机制支付,包括ERC20代币[17] [18]。 这将消除使用新代币的大部分缺点; gas成本没有任何差别,用户只需要购买一个代币。 也可以将gas价格设置为零,并在合约执行中向采矿者添加ERC20代币付款(使用EVM COINBASE [85]操作码)[19]。 这需要矿工的明确支持,因为他们需要将其采矿策略配置为接受零gas价格,并验证交易执行包括将ERC20代币转移到coinbase地址。<br>但是,引入新的代币而不是简单地使用Ether的决定是出于社会经济而非技术原因。 通过创建一个新的代币,并使其成为兰花网络中唯一有效的支付选项,我们设计出了我们认为足够重要的社会经济效应,以保证增加的复杂性。</p>
<h5 id="7-6-1-激励"><a href="#7-6-1-激励" class="headerlink" title="7.6.1. 激励"></a>7.6.1. 激励</h5><p>激励是通过赋予人们对网络的部分所有权来引导新的协议和网络的一种方式[20]。<br>像兰花这样的新型去中心化网络受到鸡和鸡蛋的困扰。 代理和中继节点越多,网络为用户提供的实用程序就越多。 而用户越多,运行代理或中继节点就越有价值。 通过部署一个新的网络代币,可以加速网络效应,因为所有潜在的用户都被激励来尽早使用网络。</p>
<h5 id="7-6-2-解耦"><a href="#7-6-2-解耦" class="headerlink" title="7.6.2. 解耦"></a>7.6.2. 解耦</h5><p>在去中心化系统中做去中心化系统,新的代币将新系统的市场价值从基础系统中分离出来。 例如,截至2017年10月,Ether的市值约为300亿美元,日均全球交易量为5亿美元[21]。 以太网的价格受多种因素影响,如加密货币的整体猜测,以太坊矿工的哈希能力以及以太坊建立的数百个项目的成败。 然而,单个项目的失败或成功可能不会对以太网的价格产生重大影响,但会对所涉及的项目具有显着的影响。 使用新的代币解耦市场价值,创造了一个更好的项目和系统的规模和健康的指标,有效地预测该市场的未来。</p>
<h5 id="7-6-3-流动市场"><a href="#7-6-3-流动市场" class="headerlink" title="7.6.3. 流动市场"></a>7.6.3. 流动市场</h5><p>对于系统特定的代币而言,流动性市场可以使严重依赖系统的用户通过做空仓位来对冲潜在的系统故障。 如果这看起来很远,我们应该注意到,金融衍生工具的初衷是允许企业对不幸的未来事件进行对冲。随着0x [22]和etherdelta [23]等去中心化交易以及Augur [24]和Gnosis [25]等预测市场的出现,基于以太坊的代币和系统的衍生品也不算太远。 事实上,这样的衍生工具可能比传统的金融衍生工具更有效[26],因为前者没有信任方,没有权限,甚至可能是匿名的。</p>
<h5 id="7-6-4-新代币"><a href="#7-6-4-新代币" class="headerlink" title="7.6.4. 新代币"></a>7.6.4. 新代币</h5><p>新的代币也可以更容易地为利益相关者设计具体的激励措施; 因为代币完全是从新系统中获得价值的,所以它们对任何为了系统成功而努力的人都是强有力的激励。 以太坊智能合约可以实现代币的自主锁定,以确保代币持有者只能根据定义的时间表访问其代币。 这种激励措施随着时间的推移而调整,并将代币持有者的重点放在系统的长期成功上,而不是像特定团队或相关公司这样的社会结构。 如果兰花网络使用了Ether,并且利益相关者被锁定了Ether,他们实际上会更加激励地为以太坊的整体成功而努力,而不是使用以太坊的任何特定系统。 可以认为,这样的结果将不是一个兰花网络和项目的最佳激励调整。</p>
<h4 id="7-7-以太坊审查制度的抵制"><a href="#7-7-以太坊审查制度的抵制" class="headerlink" title="7.7. 以太坊审查制度的抵制"></a>7.7. 以太坊审查制度的抵制</h4><p>与大多数公链类似,除非验证者(以太坊网络中的矿工)选择不将兰花交易打包,否则一定会对以太坊交易进行审查验证。由于所有矿工都是随机打包出块,与哈希能力成正比,这就要求大部分矿工主动审查兰花付款来保护兰花网络。例如,即使90%的算力选择不打包兰花相关的交易,兰花网络仍然会运作,只是交易所需的平均时间是正常的十倍。如果一大群51%的矿工选择通过拒绝包括他们在内的区块来审查兰花相关交易,那么更严格的审查形式就是如此[71]。根据以太坊协议规则,这是有效的,并有效地创建一个软分叉。但是,组织大规模的矿工勾结制造这样一个软叉有很大的利润损失风险;如果软叉未能获得足够的哈希能力,那么勾结的矿工就会错过他们的区块奖励。除了利润风险之外,考虑到以太坊矿工的去中心化性和对区块链采矿策略的法律和法规限制,我们认为这种可能性极小。</p>
<h4 id="7-8-在宏支付上建立微支付"><a href="#7-8-在宏支付上建立微支付" class="headerlink" title="7.8. 在宏支付上建立微支付"></a>7.8. 在宏支付上建立微支付</h4><p>现在讨论交易成本和支付令牌的选择,现在让我们看看可行的支付方式。 以区块链为基础的小额支付面临的一个根本性挑战是如何避免交易费用。 想象一下,如果我们发送一分钱作为一个简单的以太坊ERC20交易,我们会支付1.4美分 - 140%的交易费每次支付! 有效的小额支付要求降低交易费几个数量级。<br>在MojoNation [27]中采用的一个潜在有趣的方法是在每对节点之间建立一个“贸易平衡”。 当带宽在它们之间流动时,等交易费从0达到了一定的值时,它们会定期结算。 但是,正如我们所看到的,使用以太坊交易结算付款的交易成本至少会导致0.014美元的交易费用。 根据之前讨论的上限,我们可以看到这个价格大约等于140兆字节的带宽。 这种方法的第二个问题是,恶意邻近节点会知道这个事实,并试图断开连接并创建一个新的身份,而不是支付费用。</p>
<h4 id="7-9-支付通道"><a href="#7-9-支付通道" class="headerlink" title="7.9. 支付通道"></a>7.9. 支付通道</h4><p>在比特币网络上首次出现的区块链应用中流行的技术是支付通道[28]。由中本聪[66]部分描述,后来由Hearn和Spilman [29]定义和实施,支付通道后来由Poon和Dryja [ 30]把它应用在比特币闪电网络。支付通道允许发送者和接收者在彼此之间发送任意数量的交易,并且仅支付两笔交易的交易费 - 一个用于设置支付通道,另一个用于关闭它。这是通过首先让发送者发送一笔交易来锁定一些代币,这些代币可以被发送给收件人或发回给发送者。通常,代币只能在将来的某个时间T被发回给发送者。同时,代币可以(递增或全部)发送给接受者。发送者持续签署的交易花费越来越多的代币给收件人,并直接发送给收款人,无需发布在区块链上。收款人可以在任何时候,向区块链发布他们最后收到的交易要求汇总的金额, 直到时间T后,发送者没有意义,正式确定了他们多次协商后的交易。<br>支付通道为发款人提供一个有效的方式,为收款人提供连续付款的密码证据。 由于中间付款不会产生任何交易费用,所以可以随意小额付款,任意发送。 在实践中,瓶颈成为验证交易的计算开销以及发送它们的带宽要求。<br>尽管支付通道有效地为任意数量的中间支付提供了不变的交易费用复杂性,但不是在所有的情况下,这些支付通道效率有这么高。 特别是在有大量发送者和接收者的系统中,他们经常与他们互动,他们不断创建新的支付渠道可能太昂贵了。 同样,对于提供的非常小的或短期的服务(如单个HTTP请求或10秒的视频流),所需链上交易的交易费用可能太高。</p>
<h4 id="7-10-概率支付"><a href="#7-10-概率支付" class="headerlink" title="7.10. 概率支付"></a>7.10. 概率支付</h4><p>如果我们无法避免必须在区块链上做支付结算并产生交易手续费,那么理论上的最低成本就是单个交易的成本,因为区块链需要至少一个交易来执行状态转换。 为了解决一些(微)支付,我们至少需要一笔交易。<br>如果我们可以取消支付通道所需的设置交易(也就是为了建立通道而产生的第一笔交易),并且仍然能够向收件人证明他们正在获得付款,那该怎么办?<br>幸运的是,在区块链行业有一个类似的解决问题:矿池算力共享[31]。 随着像比特币这样的网络工作的工作难度的增加,矿工们开始将他们的计算能力集中在一起,以避免单个矿工花费数年的时间寻找块解决方案(也就是挖矿合适的nonce查找)来产生块。 矿池按矿工算力占矿池比率给予奖励,个别矿工通过哈希证明他们的哈希能力不断发送解决方[32],在相同的区块上做哈希计算,但会选择一个较低的难度。 该技术使得矿池能够以密码方式验证每个池成员的哈希能力,而不管该池成员是否找到满足实际工作证明目标的解决方案。<br>如果我们将相同的思想应用于支付通道,我们可以构建概率支付方案,发件人不断向受方证明他们是平均支付的,而不管实际支付是否发生。 这使我们能够创建概率性的微支付,而不需要设置交易(闪电网络和雷电网络需要在建立通道时向区块链发送第一笔交易用于锁定定量的代币),接收者只需在“兑现”时支付交易费用。<br>在我们研究如何使用以太坊智能合约来构建这样的概率微支付之前,让我们退一步观察一下,概率支付的最初概念早于区块链技术,并于1996年由David Wheeler [84]首次发表。Wheeler描述了核心 概率支付的概念以及如何将其应用于使用随机数字承诺的电子协议,使得发件人和收件人(论文的术语中的买方和卖方)都不能操纵概率事件的结果,同时也证明他们之间的获胜的概率是多少。<br>有几篇论文跟随惠勒的想法,1997年Ronald Rivest [79]发表了一篇论文,描述了如何在电子微支付中应用概率支付。 2015年,Pass和Shelat [78]描述了如何将可能性微支付应用于比特币等去中心化货币,并指出先前的方案都依赖于可信的第三方。 第二年,Chiesa,Green,Liu,Miao,Miers和Mishra [59]将这项研究扩展到零知识证明,提供适用于加密货币协议的去中心化和匿名微支付。<br>鉴于最近在以太坊系统中支付通道的兴趣和普遍性,从支付通道的角度来看待可能的支付可能是有价值的。 为了省略第一次设置交易,我们失去了保证发送确切金额的能力,取而代之的只是一个概率保证。 然而,我们将通过调整支付概率,支付金额和支付频率来展示可能的小额支付,以便它们能够取代几类基于区块链的应用的支付通道,而不存在明显的缺陷。<br>从本质上讲,我们可以避免初始设置交易,我们可以从同一个发送者帐户中为任意数量的收件者支付任意小的服务会话,同时还向每个人证明支付金额的确切概率。假设服务提供商(兰花网络中的一个中继或代理节点)提供了足够的服务量,那么概率支出的变化就会很快达到平衡。</p>
<h4 id="7-11-基于区块链的概率微支付"><a href="#7-11-基于区块链的概率微支付" class="headerlink" title="7.11. 基于区块链的概率微支付"></a>7.11. 基于区块链的概率微支付</h4><p>为了更容易地传达如何将概率支付应用于区块链协议的核心思想,我们将在这里详述几个细节。 在引用的原文中提供了对MICROPAY1方案的正式描述,而兰花的概率支付方案在7.12节。<br>Pass和Shelat描述了MICROPAY1 [78],组合了数字签名和承诺方案,来达到发布精确概率的随机结果的条件。发件人首先通过将比特币转移到新生成的密钥的托管地址来进行“存款”。 然后,收款人(MICROPAY1条款中的商家)挑选一个随机数字,并将此号码的承诺发送给发款人。除了承诺,收款人还提供了一个新的比特币地址。发款人也挑选一个随机数字,并对这个数字(明文的形式),收款人的承诺和其他付款数据(如收件人提供的付款目的地地址)等一系列数据签名。<br>验证所产生的票据包括检查收款人的承诺是否符合他所披露的数字,以及验证发款人的签名是否与比特币存款的地址相符。如果来自发款人和收款人的随机数字的XOR的最后两位数字是00,那么票据通过验证,并且可以由收款人使用。<br>直觉上,我们可以把这个方案中的“抛硬币”看作是没有偏见的,除非发送方可以打破承诺的约束性(或伪造签名),或者用户可以打破承诺的隐藏性。<br>请注意,发款人可以通过向多个收款人并行的发行票据来“双花”其存款,通过在收款人看到票据声明前广播花费,达到在收款人之前发费该存款的目的。MICROPAY1的作者讨论了如何通过“惩罚托管”来解决这个问题,由发款人存入的第二笔金额做抵押,可以在未来某个时间点返回给发款人,但这笔抵押可以被任何可以为同一付款托管提交两张有效票据的人“削减”或“烧毁”。这可以防止发款人与收款人勾结或作为自己的收件人。<br>MICROPAY1的作者在MICROPAY2和MICROPAY3中构造了迭代改进,其中引入了一个可信方,在票据上执行一些计算验证步骤,并在计算正确的情况下释放签名。</p>
<h4 id="7-12-兰花支付方案"><a href="#7-12-兰花支付方案" class="headerlink" title="7.12. 兰花支付方案"></a>7.12. 兰花支付方案</h4><p>现在我们已经为我们的支付找到了合适的抽象, 接下来是该如何去实施?<br>除了第7.1节中讨论的要求外,我们还要满足:</p>
<ul>
<li>可重用性,构建每张新票据时不需要每一张票据都产生交易费或必须上链交易,否则交易费将再次成为问题。</li>
<li>必须防止双花, 否则会给收款人造成损失。</li>
<li>就计算成本而言,系统必须具有足够的性能,以免超出数据包的成本。<br>在这些要求中,最后一个要素可能是最麻烦的。 据我们所知,不存在不需要按照验证ECDSA签名的顺序进行计算的方法在以太坊上构建彩票的dapp。正如本节所详细描述的,从发件人的要求来看,不仅要证明收件人的票据金额和获胜的可能性,而且还要求发件人的以太坊账户有足够数量被锁定的兰花代币作为发送的门票。<br>出于这个原因,虽然单靠使用还不够,但我们不得不采用与上述类似的贸易平衡方法。这反过来导致了一个新的要求,即“贸易平衡必须保持足够小,以免在贸易过程中造成激励断开”。由于这是一个由实现实际问题而引起的机制设计问题,现在让我们通过假设一个解决方案来关注实现,并推迟到7.15节进一步的讨论。<br>兰花支付方案受MICROPAY1和相关构造的启发,是一个伪造的匿名,概率微支付方案,。通过利用以太坊智能合约和代币锁定抵押惩罚机制,它可以减少运行前和并行(包括双花)支出攻击,而不需要可信任的第三方。兰花支付的伪匿名等同于在以太坊定期交易中可以实现的功能(尽管兰花客户使用额外的隐私技术,例如一次性地址和节点身份与支付地址之间的关键分离以实现有限的匿名)。<br>MICROPAY2和MICROPAY3中引入的信任方可以被Ethereum智能合约代码有效替代。EVM允许在验证微支付票据时实现任意逻辑(在计算的经济范围内),并为ECDSA [70]恢复操作以及加密哈希函数提供原语[85]。<h5 id="7-12-1-支付票据的定义"><a href="#7-12-1-支付票据的定义" class="headerlink" title="7.12.1. 支付票据的定义"></a>7.12.1. 支付票据的定义</h5>兰花支付票据有如下字段:<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">H(function) --- 哈希函数(更多细节在7.12.2)</div><div class="line">timestamp(uint32) --- Unix时间表示票据的值何时开始呈指数下降 </div><div class="line">rand(uint256) --- 收件人选择的随机整数</div><div class="line">nonce(uint256) --- 票据发送者的随机整数</div><div class="line">faceValue(uint256) --- 赢得票据的值</div><div class="line">minValueMarket(uint256) --- 基于带宽市场的票据值</div><div class="line">minValueAccepted(uint256) --- 基于收件人所接受的内容的预期值</div><div class="line">winProb(uint256) --- 特定票据赢取发送者面值的概率</div><div class="line">recipient(uint160) --- 票据接收者在以太坊上160位以太坊账户地址</div><div class="line">randHash(uint256) --- 随机数哈希摘要</div><div class="line">ticketHash(uint256) --- randHash,recipient,faceValue,winProb,nonce的哈希摘要</div><div class="line">(v1,r1,s1)(tuple) --- 票据发送者的ECDSA签名元素</div><div class="line">(v2,r2,s2)(tuple) --- 接收者的ECDSA签名元素</div></pre></td></tr></table></figure>
</li>
</ul>
<h5 id="7-12-2-支付票据加密库选择"><a href="#7-12-2-支付票据加密库选择" class="headerlink" title="7.12.2. 支付票据加密库选择"></a>7.12.2. 支付票据加密库选择</h5><p>为了降低兰花小额支付的成本,我们选择了某些密码功能,因为与其他任意函数相比,以太坊的gas成本降低了。<br>H — - Keccak-256 - 由于具有最低的gas成本(用于哈希32个字节需要花费36个gas[85]),所以在EVM中可用的所有哈希函数中花费是最低的。<br>ECDSA — secp256k1与Keccak-256,由于EVM支持ECDSA恢复此曲线以及兼容现有区块链软件库和工具。</p>
<h5 id="7-12-3-生成支付票据"><a href="#7-12-3-生成支付票据" class="headerlink" title="7.12.3. 生成支付票据"></a>7.12.3. 生成支付票据</h5><p>Alice 作为接收者,Bob 做为发送者。<br>-1. Alice挑选一个随机的256位数rand,计算randHash,并将摘要发送给Bob<br>-2. Bob 初始化参数(nonce, faceValue, winProb,recipient)<br>-3. Bob 计算票据哈希<br>-4. Bob 产生签名(私钥,票据hash)<br>-5. 票据定义后产生的内容:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div></pre></td><td class="code"><pre><div class="line">(a) randHash</div><div class="line">(b) recipient</div><div class="line">(c) faceValue</div><div class="line">(d) winProb</div><div class="line">(e) nonce</div><div class="line">(f) ticketHash</div><div class="line">(g) creator (签名ticketHash的发件人密钥的地址)</div><div class="line">(h) creatorSig (发件人对tickerHash的签名)</div></pre></td></tr></table></figure></p>
<p>请注意,虽然此票据只要收件人可以完全验证就是有效的,但收件人需要对其签名(请参见下文),以便能够在以太坊上的兰花支付合约中声明。</p>
<h5 id="7-12-4-支付合约的验证"><a href="#7-12-4-支付合约的验证" class="headerlink" title="7.12.4. 支付合约的验证"></a>7.12.4. 支付合约的验证</h5><p>Alice (带宽销售者) 可以执行下面的操作,<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div></pre></td><td class="code"><pre><div class="line">Verify:</div><div class="line">(a) randHash == H(rand)</div><div class="line">(b) faceValue >= minValueMarket</div><div class="line">(c) winProb >= minValueAccepted</div><div class="line">(d) recipient == {接收者公布的以太坊帐号地址}</div><div class="line">(e) creator == {发送者公布的以太坊帐号地址}</div><div class="line">Validate:</div><div class="line">(a) Validate: 用公钥验证是否是该公钥对应的私钥所做的签名</div><div class="line">Check:</div><div class="line">(a)Validate: 交易发送者在兰花支付合约中锁定了足够的兰花代币</div></pre></td></tr></table></figure></p>
<p>现在票据被证明是有效的,并且可能是一张中奖票</p>
<h5 id="7-12-5-领取票据中的付款"><a href="#7-12-5-领取票据中的付款" class="headerlink" title="7.12.5. 领取票据中的付款"></a>7.12.5. 领取票据中的付款</h5><p>虽然接收者可以在本地充分验证票据是否有效,并且如果它是中奖票据,中奖票据中代币的实际支付是通过兰花支付智能合约完成的。<br>这个智能合约公开了一个以输入为参数的Solidity API:<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div></pre></td><td class="code"><pre><div class="line">1. rand</div><div class="line">2. nonce</div><div class="line">3. faceValue</div><div class="line">4. winProb</div><div class="line">5. receipient</div><div class="line">6. recipientSig (接收者对票据hash的签名)</div><div class="line">7. creatorSig (发送者对ticketHash的签名)</div></pre></td></tr></table></figure></p>
<h5 id="7-12-6-合约的执行"><a href="#7-12-6-合约的执行" class="headerlink" title="7.12.6. 合约的执行"></a>7.12.6. 合约的执行</h5><p>假设Alice是希望购买带宽的用户。 Alice必须有一个以太坊帐户地址addressAlice和兰花代币。 请注意,该地址将具有关联的公钥PubKeyAlice。Alice还必须将兰花代币锁定在以前部分定义的以太坊智能合约中,并使用PubKeyAlice锁定。 在上一节中,Alice的地址就是以太坊帐户地址,等于从ticketHash上creatorSig恢复的公钥。<br>假设SLASH是一个临时布尔值,它被设置为FALSE,PubKey是通过ticketHash从recipientSig恢复的公钥,<br><figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div></pre></td><td class="code"><pre><div class="line">计算:(a) ticketHash</div><div class="line">验证:</div><div class="line">(a) randHash; 如果不是, 结束执行。</div><div class="line">(b) PubKey == recipient address; 如果不是,结束执行。</div><div class="line">(c) addressAlice将代币锁在罚金托管账户。如果不是,结束执行。</div><div class="line">(d) addressAlice已经有足够的兰花代币被锁定在门票帐户中以支付门票。 如果不是,则将SLASH设置为TRUE并继续执行。</div><div class="line">(e) H(ticketHash, rand) <= winProb。 如果不是,结束执行。</div><div class="line">判断:</div><div class="line">(a) 如果SLASH == FALSE,则支付票款:faceValue从创建者的票据转移到收件人。</div><div class="line">(b) 如果SLASH = TRUE,则创建者锁定的代币中扣减。</div><div class="line">结算:</div><div class="line">(a) 发送创建者的票据资金(如果有的话)给收件人(这是来自之前的验证,保证小于faceValue)。</div><div class="line">(b) 将创建者的惩罚托管帐户设置为零(销毁/删除这些代币)。</div></pre></td></tr></table></figure></p>
<p>请注意,虽然惩罚抵押机制消除了发送者潜在的双花作恶,但票据发送者仍然有大规模超支的危险。为了解决这个问题,获胜票据的额度应该在时间戳上呈指数下降,从而为获胜者立即兑现提供了强有力的激励。接收者可以使用这种直接性来计算发送者的兰花代币余额的“浪费率”。</p>
<h4 id="7-13-兰花gas成本"><a href="#7-13-兰花gas成本" class="headerlink" title="7.13. 兰花gas成本"></a>7.13. 兰花gas成本</h4><p>我们已经从上述方案的可靠性原型实施中测量了约87,000的gas成本。这个成本消耗在对获胜票据声明的API调用中。对票据合约的执行过程包括对兰花代币转账API的子调用。所有兰花智能合约在密码审查和外部安全审计之后, 会部署到以太坊主网并开源。</p>
<h4 id="7-14-可验证的随机函数"><a href="#7-14-可验证的随机函数" class="headerlink" title="7.14. 可验证的随机函数"></a>7.14. 可验证的随机函数</h4><p>通过用可验证的随机函数(VRF)替换接收者的随机数字承诺,可以减少前面部分中描述的支付票据的交互性。 由Micali,Rabin和Vadhan [80]于1999年首次发表,IETF VRF草案最近由Goldberg和Papadopoulos [33]提出。该草案规定了两种对VRF的构造,一个使用RSA,一个使用椭圆曲线(EC-VRF)。<br>使用VRF,兰花支付票据的发件人将能够在无需得到每个票据接收者的承诺。 相反,发件人只需要知道收件人的公钥。 发件人将用此公钥替换之前描述的票据方案中的随机数哈希。 为了提高效率,这可以是接收票据中已经存在的资金的接收方公钥,但要坚持密钥分离的密码原理,可能需要第二个密钥。<br>然而,验证兰花支付合约中的EC-VRF将需要明确的EVM加速椭圆曲线操作,因为直接以solidity语言或EVM 代码组装方式实施它们在gas成本方面将是非常昂贵的。<br>幸运的是,在以太坊 Byzantium [34]版本中,以太坊网络增加了对椭圆曲线标量加法和乘法的EVM支持[35]以及alt bn128曲线的配对检查[36]。 EC-VRF结构是针对任何椭圆曲线而定义的,IETF草案特别将EC-VRFP256-SHA256定义为EC-VRF密码组(其中P256是NIST-P256曲线[54])。 但是,似乎没有理由 在同样足够安全的级别下,不去使用alt bn128曲线。 而且,SHA256可以用Keccak-256来代替。 这将允许在以太坊智能合约中进行VRF验证,从而与兰花智能合约进行整合。<br>然而,尽管在zcash中使用了alt bn128曲线,但是与P256相比,这是一个更年轻的曲线,并且没有被研究。 也许更重要的是,EC-VRF的构建是一个早期草案,正在等待审查,EVM拜占庭升级发生在撰写本文时,并且尚未在现场系统中证明具有重大价值。 因此,在兰花概率微支付中使用EC-VRF并不是立即可行的,兰花项目的目标是进一步研究使用,例如 可以先试用EVM验证的EC-VRF-ALTBN128-KECCAK256结构。</p>
<h4 id="7-15-贸易平衡"><a href="#7-15-贸易平衡" class="headerlink" title="7.15. 贸易平衡"></a>7.15. 贸易平衡</h4><p>如前所述,对称加密性能的现实阻碍了我们每个数据包的支付,所以我们需要很好地理解采用“贸易平衡”方法所固有的风险。 我们这样做的一般情况是:想象一下Alice和Bob希望以完全匿名的方式进行交易。 Bob要执行一些他所要求的任务,而Alice每工作一次就要付一次钱。 不幸的是,匿名的性质是这样的,没有事先交易,Alice和Bob没有机制互相信任。 他们能合作吗?<br>如果Alice和Bob的关系有一些启动成本(SAlice,SBob s.t. SAlice> xy,SBob> xy),答案是肯定的:逃避金钱或工作不再是经济上的理性,除非(1)Alice所要求的总工作量≤xy或(2)Bob能够完成的工作总量≤xy。正如我们在讨论兰花市场时(第11节)所看到的那样,兰花网上存在的启动成本超过1×103数据包就会贸易不平衡。因为兰花市场的卖家一般比买家支付更高的启动成本,而且由于客户不对称地知道需要多少工作,兰花网络有客户预付款。</p>
<h4 id="7-16-改良"><a href="#7-16-改良" class="headerlink" title="7.16. 改良"></a>7.16. 改良</h4><h4 id="7-17-匿名"><a href="#7-17-匿名" class="headerlink" title="7.17. 匿名"></a>7.17. 匿名</h4><p>前面几节讨论的兰花支付与普通以太坊交易一样是伪匿名的; 所有交易都是公开的,包括金额以及发件人和收件人帐户。兰花客户旨在通过现代钱包技术(如一次性地址[37]和使用分层钱包[38])来改进公共区块链交易的默认伪匿名性,并使用分层钱包[38]来提供尽管使用单个根密钥的支付地址的不可链接性。<br>随着以太坊拜占廷版本的发布,现在可以通过利用新的EVM椭圆曲线原语操作码来实现具有合理gas成本的可链接环签名[39]。 将以太坊智能合约与隐藏地址(如HD钱包和可链接环签名提供的地址)相结合,可实现一类混合技术,如M¨obius [74]混合服务。如M¨obius提供了强大的匿名性保证,通过使用基于博弈的安全模型对混合服务进行密码验证。然而,与以前的混合技术不同的是,它提供了针对恶意观察者和发送者的匿名,而不是针对恶意接收者。 将M¨obius等服务与兰花概率小额支付相结合,使我们更接近于我们对付款的最终要求 - 匿名。<br>为了实现完全匿名保证,防止任何恶意行为者,无论是观察员,发送者还是接收者,我们都要依靠零知识证明技术。<br>在zcash网络[40]中应用的zk-SNARK [47]技术与环签名相比可以提供更强的匿名性保证。 在zcash中,屏蔽地址之间的交易提供了发送者,接收者和金额的完全匿名。</p>
<h4 id="7-18-非交互式"><a href="#7-18-非交互式" class="headerlink" title="7.18. 非交互式"></a>7.18. 非交互式</h4><p>在7.14节中,我们表明,通过用VRF替换兰花付款方案中的随机数承诺,通过去除与随机数承诺相关联的通信步骤使得该方案更加非互动。 接收方不必在发送者构造票据之前将承诺传达给发送者,而只需从公开的接收方信息中立即构建票据单。<br>每个接收者将生成一个专门用于VRF的新密钥对,并将公钥与其他公共接收者信息一起发布,详见11.1节。发送者只需在票据中配置该公钥,而收件人将使用相应的私钥对收到的票据进行签名。在7.12.4节中定义的票据验证逻辑将把接收者VRF签名解释为它与获胜概率阈值进行比较的值。<br>正如7.14节所讨论的那样,虽然这将是对支付方案的相对简单的修改,但在EVM中验证VRF的可行性需要进一步的研究。</p>
<h4 id="7-19-性能"><a href="#7-19-性能" class="headerlink" title="7.19. 性能"></a>7.19. 性能</h4><p>虽然兰花智能合约是不可变的,但是他们可以通过部署新的合约和升级兰花客户端软件来指向他们(如果有需要的话也可以向后兼容旧合约)来有效地进行升级。以太坊智能合约支持多层优化以降低gas成本,我们预计兰花支付智能合约的未来版本将使用 例如EVM 原语[41](也就是预编译的代码)来优化gas成本,类似于常规软件系统常常用内联组装代替昂贵的子程序。<br>然而,兰花支付票据的验证瓶颈是诸如ECDSA recovery 等密码学相关操作的执行以及兰花代币发送者和接收者的以太坊账户的状态更新。在这里,一个改进可能是两次使用接收者对有效数据交易的签名。 目前,由于兰花客户灵活性的原因,兰花计划在那里定义了两个签名,并且使得在不依赖以太坊细节的情况下更容易指定和推理付款方案。 更简单的优化包括紧密包装票据字段并将单个256位字中的多个内部变量进行编码,以与EVM堆栈字和永久契约存储插槽(均为256位)对齐。<br>另一方面,为了实现更大的匿名性,可选或甚至强制使用混合技术可能会大大增加兰花支付合约的gas成本。 使用基于可链接环签名的混合服务很容易导致大约高出一个数量级的交易费用[39]。但是,这能提供给用户强有力的匿名保证,用户可能会觉得这是值得的。 因为我们可以很容易地调整兰花支付的概率变量 - 票据频率,获胜概率和获胜金额 - 我们可以调整票证之间的平均时间来减少交易费用(特别是对于长期运行的节点,可以隔个几天才做结算一次)。<br>最后,零知识技术如zk-SNARKs的一个非常有趣的属性是大大减少任意计算的计算开销,如以太坊智能合约执行[42]。虽然生成zk-SNARK证明是昂贵的,但验证更便宜 - 甚至与原始代码相比。 由于只有验证需要在链上执行,所以在兰花票据中采用零知识证明比原始验证码更便宜。<br>进一步来说,递归SNARKs [52]有可能将一组SNAK证明集合成一个证明。虽然它们可能更适用于区块链共识协议[43],但它们也可能对兰花协议有用,例如 将多个票据索赔批量化为单个智能合约交易,同时避免线性gas成本叠加。</p>
<h3 id="8-带宽挖矿"><a href="#8-带宽挖矿" class="headerlink" title="8. 带宽挖矿"></a>8. 带宽挖矿</h3><p><img src="/img/带宽挖矿.png" alt=" " title="客户经过三层链路由的示列图"><br>在这章我们将描述中继的规则和代理的行为,以及讨论这些无法审查的,匿名网页浏览的节点如何“连接在一起的“</p>
<h4 id="8-1-带宽销售规范"><a href="#8-1-带宽销售规范" class="headerlink" title="8.1. 带宽销售规范"></a>8.1. 带宽销售规范</h4><p>中继节点实现相对简单的行为模式如下:</p>
<ul>
<li>保持一个或多个连接,每个都有自己的加密密钥。</li>
<li>检查收到的任何票据和获得的入账。</li>
<li>监控交易的平衡,如果超过预先确定的额度,则断开连接。</li>
<li>从任何打开的连接接收数据,并在消息边界执行解密。</li>
<li>处理解密消息如下:<br>—将任何非控制段转发到消息中指定的连接。<br>—处理控制字段如下:<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div></pre></td><td class="code"><pre><div class="line">* 空数据。 指示中继丢弃这个字段。</div><div class="line">* 数据转发速率。指示中继以固定速率通过链接发送数据,根据需要对数据包进行排队并生成数据以保持速率。</div><div class="line">* 棘轮票据。指示中继将一个票据传递给一个对等节, 该对等节点是原来数据来源点。</div><div class="line">* 初始化链接。 指示当建立和断开链接的过程时,中继建立一个新链接。</div><div class="line">* 初始化网页链接。(仅限代理)指示代理打开指定主机的SSL连接。为了支持白名单,这不能是一个原生IP地址。</div></pre></td></tr></table></figure>
</li>
</ul>
<p>上述行为中的一个重要考虑是需要中继节点持续不断地的工作证明。当与我们所有的WebRTC链接结合起来时,网站就可能通过运行纯粹的JavaScript中继代码来获利。<br>有关通过控制字段扩展应用程序的讨论,请参见第15节。</p>
<h4 id="8-2-节点保护和“带宽燃烧“"><a href="#8-2-节点保护和“带宽燃烧“" class="headerlink" title="8.2. 节点保护和“带宽燃烧“"></a>8.2. 节点保护和“带宽燃烧“</h4><p>客户连接的中继有一个非常重要的信息:客户的IP地址。 我们假设客户希望尽可能保持私密性,所以默认的客户端会长时间作为第一跳对等节点。<br>另一个关于第一跳节点的问题,我们在讨论由共谋(9.2节)引起的信息攻击方面进行了深入的讨论,他们坐在一个理想的位置来执行定时攻击。为了防止这些攻击,我们建议有隐私意识的用户采用一种称为“带宽燃烧”的方法,向第二跳节点支付金额来获得固定数量的带宽。由于这种方法使用的数据会和网络使用的数据完全不相关,从而可以防止攻击者无法看到中继3的入站流量。<br>为了给寻求逃避的用户提供帮助(第12节),带宽燃烧也将支持由流行的非兰花WebRTC协议的统计特性确定的非固定速率。</p>
<h4 id="8-3-链路"><a href="#8-3-链路" class="headerlink" title="8.3. 链路"></a>8.3. 链路</h4><p>对使用中继进行匿名访问感兴趣的客户将使用上述规范来创建中继的“链路”。</p>
<h3 id="9-链路串谋攻击"><a href="#9-链路串谋攻击" class="headerlink" title="9. 链路串谋攻击"></a>9. 链路串谋攻击</h3><p>在本节中,我们将探讨攻击者可以通过控制或监视多个中继和/或互联网服务提供商(ISP) 来推断或推导哪些类型的信息。假定中继和代理是随机选择(ISP也同样做此假定),我们建立了一个给定攻击可能以不同链长进行的概率模型。</p>
<h4 id="9-1-个人中继和代理有用的信息"><a href="#9-1-个人中继和代理有用的信息" class="headerlink" title="9.1. 个人中继和代理有用的信息"></a>9.1. 个人中继和代理有用的信息</h4><p>由于基于IP的网络固有结构以及兰花协议使用基于以太坊的支付,中继和代理节点及其入侵防御系统可以访问以下信息</p>
<ul>
<li>他们所连接的所有计算机的IP地址。</li>
<li>他们转发的数据包的大小,时间和数量。</li>
<li>控制支付代币的公钥。</li>
<li>针对它们的数据包控制字段的内容。<br>此外,代理节点及入侵防御系统可以访问以下信息:</li>
<li>Web服务器的主机名和SSL / TLS会话协商的明文部分。<h4 id="9-2-潜在的合谋者"><a href="#9-2-潜在的合谋者" class="headerlink" title="9.2. 潜在的合谋者"></a>9.2. 潜在的合谋者</h4>在兰花网络中, 以下的角色可能被攻击者监视或者串谋:</li>
<li>互联网服务提供商以客户,中继,代理,web服务器的角色加入兰花网络。不可靠概率用s表示。</li>
<li>网站。 链接到代理的网站服务器。 不可靠概率用w表示。</li>
<li>Relayn。 链路中的第n个中继节点。 不可靠概率用r/n 表示。</li>
<li>代理。 有流量通过中继到网站服务器的代理。不可靠概率用x/n 表示。<br>我们已经分离出上面的r和x,原因是:虽然攻击者无法控制他们可用于计算工作量计算的总计算量,但他们可以控制如何在中继和代理节点之间分配计算。<h4 id="9-3-攻击类型"><a href="#9-3-攻击类型" class="headerlink" title="9.3. 攻击类型"></a>9.3. 攻击类型</h4>共谋攻击的核心目标是将特定的兰花客户与特定的SSL连接相链接。 主要可以采用如下方法:</li>
<li>关系。攻击者可以通过观察消息路由过程中的节点来推断出一个客户正在和一个给定的网站通话。</li>
<li>记时。 攻击者可以通过控制并观察数据包的时间规律来推断客户正在与给定网站通话。</li>
<li>未燃烧的带宽花费。 尽管客户可以使用带宽燃烧的方式掩盖自己的流量,但攻击者仍然可以执行定时攻击。<h4 id="9-4-“常规”互联网访问:零中继,零代理"><a href="#9-4-“常规”互联网访问:零中继,零代理" class="headerlink" title="9.4. “常规”互联网访问:零中继,零代理"></a>9.4. “常规”互联网访问:零中继,零代理</h4>虽然当客户直接连接网站时,兰花系统不被使用,但我们在接下来的类容会分析在客户启动中存在的风险。<br><img src="/img/OrchidAccess.png" alt=""><br>在上表中,“X”表示参与共谋,互联网服务商 有x的概率采用关系攻击类型。网站有w的概率采用关系攻击类型。<h4 id="9-5-VPN-零中继,-零代理"><a href="#9-5-VPN-零中继,-零代理" class="headerlink" title="9.5. VPN: 零中继, 零代理"></a>9.5. VPN: 零中继, 零代理</h4>为了进行分析,我们也提出了VPN访问固有的合谋风险<br><img src="/home/gavin/work/shell/blog/themes/yilia/source/img/OrchidVPN.png" alt=""><br>g是VPN提供商被监控或者与对手勾结的可能性。 请注意,g可能会随着时间的推移而变化导致难以建模,例如,由于您的VPN使用情况。<h4 id="9-6-零中继,一个代理"><a href="#9-6-零中继,一个代理" class="headerlink" title="9.6. 零中继,一个代理"></a>9.6. 零中继,一个代理</h4><img src="/home/gavin/work/shell/blog/themes/yilia/source/img/0Relay1Proxy.png" alt=""><br>毫无疑问,这种情况下的风险与VPN使用的风险很相似。 不使用中继的链相当于在每个浏览会话之前随机选择新的VPN提供商的VPN,并且VPN提供商不存储个人信息。<h4 id="9-7-一个中继,一个代理"><a href="#9-7-一个中继,一个代理" class="headerlink" title="9.7. 一个中继,一个代理"></a>9.7. 一个中继,一个代理</h4><img src="/home/gavin/work/shell/blog/themes/yilia/source/img/1Relay1Proxy.png" alt=""><br>如果在这种配置中使用带宽燃烧,所有的定时攻击都会被缓解。 </li>
</ul>
<h3 id="15-未来的工作"><a href="#15-未来的工作" class="headerlink" title="15. 未来的工作"></a>15. 未来的工作</h3><p>本节中的内容分为两类:好的方面和我们像公众展示的内部矛盾特征。不够我们相信这种矛盾都是很普遍的——虽然几乎所有人都有一个自己最喜欢的将权利用作歧途的例子,但是同样也有无数的将权利用作正途的例子。兰花这种协议是没有自己的判断力,无法告知它被自由战士,还是被恐怖分子,坏人还是英雄所用。</p>
<h4 id="15-1-空间证明"><a href="#15-1-空间证明" class="headerlink" title="15.1. 空间证明"></a>15.1. 空间证明</h4><p>如第5节所述,我们非常有兴趣探索其他证明类型。这是一个重要的问题,因为工作证明系统的环境影响,以及我们目前的工作证明算法要求全面的计算机充当网络路由器。<br>我们很高兴能够探索使用磁盘空间成为我们安全核心的稀缺资源的可能性,这可能会让旧手机或类似硬件有利地参与到兰花网络中。</p>
<h4 id="15-2-内容主机的保护"><a href="#15-2-内容主机的保护" class="headerlink" title="15.2. 内容主机的保护"></a>15.2. 内容主机的保护</h4><p>许多先前的方法(第3节)发现内容主机寻求与网络用户类似的保护。我们在这方面内部是有矛盾的,因为我们确实认为有一些内容不符合公共利益(例如有关制造核武器的信息)。但是,如果情况不符合要求,兰花可以扩展到支持这种“无限制的,未受到威胁的主机”,如下图所示:<br><img src="/home/gavin/work/shell/blog/themes/yilia/source/img/OrichidFigure3.png" alt=""> </p>
<h4 id="15-3-以太坊支付模块的安全保证"><a href="#15-3-以太坊支付模块的安全保证" class="headerlink" title="15.3. 以太坊支付模块的安全保证"></a>15.3. 以太坊支付模块的安全保证</h4><p>正如我们在防火墙规避部分(第12节)中所讨论的,客户端的以太坊网络流量很可能是安全的薄弱环节。因为所有的节点都必须维护这个信息,所以使用兰花协议来<br>分发以太坊信息似乎是天作之合。<br>不幸的是,依靠那些你正在付钱的信息会导致棘手的问题。我们希望在不久的将来添加处理这个问题的功能,但不会在我们最初发布的版本加入此功能。</p>
<h4 id="15-4-兰花平台"><a href="#15-4-兰花平台" class="headerlink" title="15.4. 兰花平台"></a>15.4. 兰花平台</h4><p>尽管我们预计核心系统的设计将在不久的将来占用我们大部分的时间,我们也会添加以下用例的相关的功能, 因为这样做, 可以为兰花网络增加大量的流量。</p>
<ul>
<li>1.直接访问网络的API接口加入代币服务。</li>
<li>2.网络上的文件存储和静态网站托管。</li>
<li>3.文件共享。</li>
<li>4.电子邮件/消息服务。</li>
<li>5.仲裁/调解服务。</li>
</ul>
</div>
<div class="article-info article-info-index">
<p class="article-more-link">
<a class="article-more-a" href="/2017/10/30/兰花协议/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<article id="post-chainmint" class="article article-type-post article-index" itemscope itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2017/09/03/chainmint/">chainmint</a>
</h1>
<a href="/2017/09/03/chainmint/" class="archive-article-date">
<time datetime="2017-09-03T03:55:12.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2017-09-03</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<h2 id="chainmint-Chain-Tendermint"><a href="#chainmint-Chain-Tendermint" class="headerlink" title="chainmint =Chain + Tendermint"></a><a href="https://github.com/chainx-org/chainmint" target="_blank" rel="external">chainmint</a> <strong>=</strong><a href="https://chain.com/" target="_blank" rel="external">Chain</a> <strong>+</strong> <a href="https://tendermint.com/" target="_blank" rel="external">Tendermint</a></h2><p>chainmint 是基于tendermint 共识,继承了Chain的UTXO, CVM的区块链。将来会成为cosmos的一个zone, 用于Chain(纳斯达克股市采用的区块链技术)和 cosmos hub之间通信转帐。</p>
<h2 id="组成"><a href="#组成" class="headerlink" title="组成"></a>组成</h2><ul>
<li>tendermint(<a href="https://github.com/tendermint/tendermint" target="_blank" rel="external">https://github.com/tendermint/tendermint</a>) 共识模块, 和chainmint 通信, 组织chainmint 的交易序例。</li>
<li>chainmint(<a href="https://github.com/chainx-org/chainmint" target="_blank" rel="external">https://github.com/chainx-org/chainmint</a>) 实现了abci接口的交易具体逻辑。</li>
<li>postgreSql(<a href="https://github.com/postgres/postgres" target="_blank" rel="external">https://github.com/postgres/postgres</a>) chainmint的数据存储模块。</li>
<li>chainmintcli(<a href="https://github.com/chainx-org/chainmint/tree/master/cmd/chainmintcli" target="_blank" rel="external">https://github.com/chainx-org/chainmint/tree/master/cmd/chainmintcli</a>) chainmint的客户端,用于和chainmint 通信。</li>
</ul>
</div>
<div class="article-info article-info-index">
<p class="article-more-link">
<a class="article-more-a" href="/2017/09/03/chainmint/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<article id="post-软件设计模式之Reactor" class="article article-type-post article-index" itemscope itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2017/08/01/软件设计模式之Reactor/">软件设计模式之Reactor</a>
</h1>
<a href="/2017/08/01/软件设计模式之Reactor/" class="archive-article-date">
<time datetime="2017-08-01T05:54:32.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2017-08-01</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<h2 id="反应堆设计模式"><a href="#反应堆设计模式" class="headerlink" title="反应堆设计模式"></a>反应堆设计模式</h2><p>是一种并行处理服务请求分发的事件模型。服务处理器分离收到的请求并调度相对用的请求处理器同步的处理各自的请求。</p>
<h3 id="组成结构"><a href="#组成结构" class="headerlink" title="组成结构"></a>组成结构</h3><p><strong><em>Resources(可以被监听的事件)</em></strong><br>任何可以向系统输入或者消耗输出的资源(linux 上对应的可以用epoll监听的事件)。<br><strong><em>Synchronous Event Demultiplexer(同步的事件解复用器)</em></strong><br>用一个EventLoop 阻塞所有的资源。解复用器触发调度器,同步的操作变为非阻塞的资源。(实例:</p>
<ul>
<li>同步系统调用read()函数 将会在没有数据可读时是阻塞的。</li>
<li>解复用器用select()函数来监听该资源,直到该资源变为可读时。</li>
<li>read()函数不会被阻塞, 解复用器可以将该资源发送给调度器。)<br><strong>Dispatcher(调度器)</strong><br>处理请求处理程序的注册和注销。将资源从多路分解器调度到相关联的请求处理程序。<br><strong>Request Handler(请求处理程序)</strong><br>应用程序定义的与它自己相关联资源的请求处理程序。<h3 id="属性"><a href="#属性" class="headerlink" title="属性"></a>属性</h3>所有反应堆系统都是单线程的,但可以存在于多线程环境中。<h3 id="优点"><a href="#优点" class="headerlink" title="优点"></a>优点</h3>反应堆模式完全将应用程序特定的代码与反应堆实现分离,这意味着应用程序组件可以分为模块化的,可重复使用的部分。此外,由于请求处理程序的同步调用,反应器模式允许简单的粗粒度并发,而不会将多个线程的复杂性增加到系统。<h3 id="缺点"><a href="#缺点" class="headerlink" title="缺点"></a>缺点</h3>由于反向控制流程,反应堆模式可能比由程序模式更难调试。而且,通过只同时调用请求处理程序,反应堆模式限制了最大的并发性,特别是在对称多处理硬件上。反应堆模式的可扩展性不仅受到同步调用请求处理程序的限制,还受到解复用器的限制。</li>
</ul>
<h3 id="tendermint-的reactor-模式实例"><a href="#tendermint-的reactor-模式实例" class="headerlink" title="tendermint 的reactor 模式实例"></a>tendermint 的reactor 模式实例</h3><p><strong><em>解复用器, EventLoop 循环, 将资源传送给调度器调用</em></strong><br><figure class="highlight go"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div><div class="line">20</div><div class="line">21</div><div class="line">22</div><div class="line">23</div><div class="line">24</div><div class="line">25</div><div class="line">26</div><div class="line">27</div><div class="line">28</div><div class="line">29</div><div class="line">30</div><div class="line">31</div><div class="line">32</div><div class="line">33</div><div class="line">34</div><div class="line">35</div><div class="line">36</div><div class="line">37</div><div class="line">38</div><div class="line">39</div><div class="line">40</div><div class="line">41</div><div class="line">42</div><div class="line">43</div><div class="line">44</div><div class="line">45</div><div class="line">46</div><div class="line">47</div><div class="line">48</div><div class="line">49</div><div class="line">50</div><div class="line">51</div><div class="line">52</div><div class="line">53</div><div class="line">54</div><div class="line">55</div><div class="line">56</div><div class="line">57</div><div class="line">58</div><div class="line">59</div><div class="line">60</div><div class="line">61</div><div class="line">62</div><div class="line">63</div><div class="line">64</div><div class="line">65</div><div class="line">66</div><div class="line">67</div><div class="line">68</div><div class="line">69</div><div class="line">70</div><div class="line">71</div><div class="line">72</div><div class="line">73</div><div class="line">74</div><div class="line">75</div><div class="line">76</div><div class="line">77</div><div class="line">78</div><div class="line">79</div><div class="line">80</div><div class="line">81</div><div class="line">82</div><div class="line">83</div><div class="line">84</div><div class="line">85</div><div class="line">86</div><div class="line">87</div><div class="line">88</div><div class="line">89</div><div class="line">90</div></pre></td><td class="code"><pre><div class="line"><span class="comment">// recvRoutine reads msgPackets and reconstructs the message using the channels' "recving" buffer.</span></div><div class="line"><span class="comment">// After a whole message has been assembled, it's pushed to onReceive().</span></div><div class="line"><span class="comment">// Blocks depending on how the connection is throttled.</span></div><div class="line"><span class="function"><span class="keyword">func</span> <span class="params">(c *MConnection)</span> <span class="title">recvRoutine</span><span class="params">()</span></span> {</div><div class="line"> <span class="keyword">defer</span> c._recover()</div><div class="line"></div><div class="line">FOR_LOOP:</div><div class="line"> <span class="keyword">for</span> {</div><div class="line"> <span class="comment">// Block until .recvMonitor says we can read.</span></div><div class="line"> c.recvMonitor.Limit(maxMsgPacketTotalSize, atomic.LoadInt64(&c.config.RecvRate), <span class="literal">true</span>)</div><div class="line"></div><div class="line"> <span class="comment">/*</span></div><div class="line"> // Peek into bufReader for debugging</div><div class="line"> if numBytes := c.bufReader.Buffered(); numBytes > 0 {</div><div class="line"> log.Info("Peek connection buffer", "numBytes", numBytes, "bytes", log15.Lazy{func() []byte {</div><div class="line"> bytes, err := c.bufReader.Peek(MinInt(numBytes, 100))</div><div class="line"> if err == nil {</div><div class="line"> return bytes</div><div class="line"> } else {</div><div class="line"> log.Warn("Error peeking connection buffer", "error", err)</div><div class="line"> return nil</div><div class="line"> }</div><div class="line"> }})</div><div class="line"> }</div><div class="line"> */</div><div class="line"></div><div class="line"> <span class="comment">// Read packet type</span></div><div class="line"> <span class="keyword">var</span> n <span class="keyword">int</span></div><div class="line"> <span class="keyword">var</span> err error</div><div class="line"> pktType := wire.ReadByte(c.bufReader, &n, &err)</div><div class="line"> c.recvMonitor.Update(<span class="keyword">int</span>(n))</div><div class="line"> <span class="keyword">if</span> err != <span class="literal">nil</span> {</div><div class="line"> <span class="keyword">if</span> c.IsRunning() {</div><div class="line"> c.Logger.Error(<span class="string">"Connection failed @ recvRoutine (reading byte)"</span>, <span class="string">"conn"</span>, c, <span class="string">"error"</span>, err)</div><div class="line"> c.stopForError(err)</div><div class="line"> }</div><div class="line"> <span class="keyword">break</span> FOR_LOOP</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// Read more depending on packet type.</span></div><div class="line"> <span class="keyword">switch</span> pktType {</div><div class="line"> <span class="keyword">case</span> packetTypePing:</div><div class="line"> <span class="comment">// <span class="doctag">TODO:</span> prevent abuse, as they cause flush()'s.</span></div><div class="line"> c.Logger.Debug(<span class="string">"Receive Ping"</span>)</div><div class="line"> c.pong <- <span class="keyword">struct</span>{}{}</div><div class="line"> <span class="keyword">case</span> packetTypePong:</div><div class="line"> <span class="comment">// do nothing</span></div><div class="line"> c.Logger.Debug(<span class="string">"Receive Pong"</span>)</div><div class="line"> <span class="keyword">case</span> packetTypeMsg:</div><div class="line"> pkt, n, err := msgPacket{}, <span class="keyword">int</span>(<span class="number">0</span>), error(<span class="literal">nil</span>)</div><div class="line"> wire.ReadBinaryPtr(&pkt, c.bufReader, maxMsgPacketTotalSize, &n, &err)</div><div class="line"> c.recvMonitor.Update(<span class="keyword">int</span>(n))</div><div class="line"> <span class="keyword">if</span> err != <span class="literal">nil</span> {</div><div class="line"> <span class="keyword">if</span> c.IsRunning() {</div><div class="line"> c.Logger.Error(<span class="string">"Connection failed @ recvRoutine"</span>, <span class="string">"conn"</span>, c, <span class="string">"error"</span>, err)</div><div class="line"> c.stopForError(err)</div><div class="line"> }</div><div class="line"> <span class="keyword">break</span> FOR_LOOP</div><div class="line"> }</div><div class="line"> channel, ok := c.channelsIdx[pkt.ChannelID]</div><div class="line"> <span class="keyword">if</span> !ok || channel == <span class="literal">nil</span> {</div><div class="line"> cmn.PanicQ(cmn.Fmt(<span class="string">"Unknown channel %X"</span>, pkt.ChannelID))</div><div class="line"> }</div><div class="line"> msgBytes, err := channel.recvMsgPacket(pkt)</div><div class="line"> <span class="keyword">if</span> err != <span class="literal">nil</span> {</div><div class="line"> <span class="keyword">if</span> c.IsRunning() {</div><div class="line"> c.Logger.Error(<span class="string">"Connection failed @ recvRoutine"</span>, <span class="string">"conn"</span>, c, <span class="string">"error"</span>, err)</div><div class="line"> c.stopForError(err)</div><div class="line"> }</div><div class="line"> <span class="keyword">break</span> FOR_LOOP</div><div class="line"> }</div><div class="line"> <span class="keyword">if</span> msgBytes != <span class="literal">nil</span> {</div><div class="line"> c.Logger.Debug(<span class="string">"Received bytes"</span>, <span class="string">"chID"</span>, pkt.ChannelID, <span class="string">"msgBytes"</span>, msgBytes)</div><div class="line"> c.onReceive(pkt.ChannelID, msgBytes)</div><div class="line"> }</div><div class="line"> <span class="keyword">default</span>:</div><div class="line"> cmn.PanicSanity(cmn.Fmt(<span class="string">"Unknown message type %X"</span>, pktType))</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// <span class="doctag">TODO:</span> shouldn't this go in the sendRoutine?</span></div><div class="line"> <span class="comment">// Better to send a ping packet when *we* haven't sent anything for a while.</span></div><div class="line"> c.pingTimer.Reset()</div><div class="line"> }</div><div class="line"></div><div class="line"> <span class="comment">// Cleanup</span></div><div class="line"> <span class="built_in">close</span>(c.pong)</div><div class="line"> <span class="keyword">for</span> _ = <span class="keyword">range</span> c.pong {</div><div class="line"> <span class="comment">// Drain</span></div><div class="line"> }</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p><strong><em>调度器 负责注册资源,以及资源和请求程序的绑定</em></strong><br><figure class="highlight go"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div></pre></td><td class="code"><pre><div class="line"><span class="function"><span class="keyword">func</span> <span class="params">(sw *Switch)</span> <span class="title">AddReactor</span><span class="params">(name <span class="keyword">string</span>, reactor Reactor)</span> <span class="title">Reactor</span></span> {</div><div class="line"> <span class="comment">// Validate the reactor.</span></div><div class="line"> <span class="comment">// No two reactors can share the same channel.</span></div><div class="line"> reactorChannels := reactor.GetChannels()</div><div class="line"> <span class="keyword">for</span> _, chDesc := <span class="keyword">range</span> reactorChannels {</div><div class="line"> chID := chDesc.ID</div><div class="line"> <span class="keyword">if</span> sw.reactorsByCh[chID] != <span class="literal">nil</span> {</div><div class="line"> cmn.PanicSanity(fmt.Sprintf(<span class="string">"Channel %X has multiple reactors %v & %v"</span>, chID, sw.reactorsByCh[chID], reactor))</div><div class="line"> }</div><div class="line"> sw.chDescs = <span class="built_in">append</span>(sw.chDescs, chDesc)</div><div class="line"> sw.reactorsByCh[chID] = reactor</div><div class="line"> }</div><div class="line"> sw.reactors[name] = reactor</div><div class="line"> reactor.SetSwitch(sw)</div><div class="line"> <span class="keyword">return</span> reactor</div><div class="line">}</div></pre></td></tr></table></figure></p>
<p><strong><em>抽象出来的接口, 编程只要继承这些接口即可</em></strong><br><figure class="highlight go"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div><div class="line">13</div><div class="line">14</div><div class="line">15</div><div class="line">16</div><div class="line">17</div><div class="line">18</div><div class="line">19</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">type</span> BaseReactor <span class="keyword">struct</span> {</div><div class="line"> cmn.BaseService <span class="comment">// Provides Start, Stop, .Quit</span></div><div class="line"> Switch *Switch</div><div class="line">}</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">func</span> <span class="title">NewBaseReactor</span><span class="params">(name <span class="keyword">string</span>, impl Reactor)</span> *<span class="title">BaseReactor</span></span> {</div><div class="line"> <span class="keyword">return</span> &BaseReactor{</div><div class="line"> BaseService: *cmn.NewBaseService(<span class="literal">nil</span>, name, impl),</div><div class="line"> Switch: <span class="literal">nil</span>,</div><div class="line"> }</div><div class="line">}</div><div class="line"></div><div class="line"><span class="function"><span class="keyword">func</span> <span class="params">(br *BaseReactor)</span> <span class="title">SetSwitch</span><span class="params">(sw *Switch)</span></span> {</div><div class="line"> br.Switch = sw</div><div class="line">}</div><div class="line"><span class="function"><span class="keyword">func</span> <span class="params">(_ *BaseReactor)</span> <span class="title">GetChannels</span><span class="params">()</span> []*<span class="title">ChannelDescriptor</span></span> { <span class="keyword">return</span> <span class="literal">nil</span> }</div><div class="line"><span class="function"><span class="keyword">func</span> <span class="params">(_ *BaseReactor)</span> <span class="title">AddPeer</span><span class="params">(peer *Peer)</span></span> {}</div><div class="line"><span class="function"><span class="keyword">func</span> <span class="params">(_ *BaseReactor)</span> <span class="title">RemovePeer</span><span class="params">(peer *Peer, reason <span class="keyword">interface</span>{})</span></span> {}</div><div class="line"><span class="function"><span class="keyword">func</span> <span class="params">(_ *BaseReactor)</span> <span class="title">Receive</span><span class="params">(chID <span class="keyword">byte</span>, peer *Peer, msgBytes []<span class="keyword">byte</span>)</span></span> {}</div></pre></td></tr></table></figure></p>
<p><strong><em>编写代码范本</em></strong><br><figure class="highlight go"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div><div class="line">4</div><div class="line">5</div><div class="line">6</div><div class="line">7</div><div class="line">8</div><div class="line">9</div><div class="line">10</div><div class="line">11</div><div class="line">12</div></pre></td><td class="code"><pre><div class="line"><span class="keyword">type</span> MyReactor <span class="keyword">struct</span>{}</div><div class="line"></div><div class="line"><span class="comment">// 对应于资源</span></div><div class="line"><span class="function"><span class="keyword">func</span> <span class="params">(reactor MyReactor)</span> <span class="title">GetChannels</span><span class="params">()</span> []*<span class="title">ChannelDescriptor</span></span> {</div><div class="line"> <span class="keyword">return</span> []*ChannelDescriptor{ChannelDescriptor{ID:MyChannelID, Priority: <span class="number">1</span>}}</div><div class="line">}</div><div class="line"><span class="comment">// 资源相对应的请求处理程序</span></div><div class="line"><span class="function"><span class="keyword">func</span> <span class="params">(reactor MyReactor)</span> <span class="title">Receive</span><span class="params">(chID <span class="keyword">byte</span>, peer *Peer, msgBytes []<span class="keyword">byte</span>)</span></span> {</div><div class="line"> r, n, err := bytes.NewBuffer(msgBytes), <span class="built_in">new</span>(<span class="keyword">int64</span>), <span class="built_in">new</span>(error)</div><div class="line"> msgString := ReadString(r, n, err)</div><div class="line"> fmt.Println(msgString)</div><div class="line">}</div></pre></td></tr></table></figure></p>
</div>
<div class="article-info article-info-index">
<p class="article-more-link">
<a class="article-more-a" href="/2017/08/01/软件设计模式之Reactor/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<article id="post-Bytom-s-data-structure" class="article article-type-post article-index" itemscope itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2017/06/28/Bytom-s-data-structure/">Bytom's data structure.</a>
</h1>
<a href="/2017/06/28/Bytom-s-data-structure/" class="archive-article-date">
<time datetime="2017-06-28T08:43:34.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2017-06-28</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<h2 id="引文"><a href="#引文" class="headerlink" title="引文"></a>引文</h2><p><strong>设计Bytom 数据结构,组合了许多技术点,如 patricia tree,utxo, bvm, account model,protobuf,sql,memcache 等。本文会对一些技术点做以下两点分析。</strong></p>
<ul>
<li>Bytom 为什么要采用该技术点?</li>
<li>Bytom 如何应用该技术点?<br><strong> 最后介绍综合这些技术点如何实现Bytom。</strong></li>
</ul>
<h2 id="patricial-tree"><a href="#patricial-tree" class="headerlink" title="patricial tree"></a><a href="http://www.allisons.org/ll/AlgDS/Tree/PATRICIA/" target="_blank" rel="external">patricial tree</a></h2><ul>
<li>为什么要采用PAT树?<br>-1.PAT树具有<a href="https://en.wikipedia.org/wiki/Radix_tree" target="_blank" rel="external">基数树</a> 的特点,内容可快速追踪。<br><img src="/img/radix_tree.png" alt="Radix tree"><br>-2.PAT树具有<a href="https://en.wikipedia.org/wiki/Merkle_tree" target="_blank" rel="external">merkle树</a> 的特点,数据可快速证明。<br><img src="/img/merkle_tree.png" alt="merkle tree"><br>在分布式系统中,一致性和有效性是十分关键的点。bytom采用PAT树,其中的数据可快速证明,可以快速证明每一份状态机是否一致。内容可快速追踪,可以使bytom在每一个快照状态下,快速查找其数据,并检验数据的有效性。 </li>
<li>Bytom 如何用PAT树?<br>Ethereum的PAT树是16叉基数树,分两层,第一层管理的是所有的账户,第二层管理是各账户的存储内容。<br><img src="/img/ethereum_pat.png" alt=""><br>Bytom 的PAT树与Ethereum 不同<br>-1. Bytom 的PAT树是二叉基数树。<br>-2. Bytom的PAT树是用来管理未花费的outputs。<br><img src="/img/bytom_pat.png" alt=""> </li>
</ul>
<h2 id="UTXO"><a href="#UTXO" class="headerlink" title="UTXO"></a><a href="https://bitcoin.org/en/glossary/unspent-transaction-output" target="_blank" rel="external">UTXO</a></h2><ul>
<li>为什么要使用UTXO?<br>UTXO诞生于比特币,和现实世界的RMB一样,从央行诞生的那一刻起,他流转无数人的账户,但他的价值面额始终和原来一样,这样以币为中心,而不是以人为中心,资产便于监管和统计。Bytom 就是用于资产的发布和管理的,所以,UTXO的这种以资产为中心的设计模式,是很适合Bytom上面的资产管理。</li>
<li><p>怎么使用UTXO?<br><img src="/img/utxo_structure.png" alt=""><br>相比比特币的UTXO, bytom的UTXO多了三个字段</p>
<ul>
<li>assertid, 因为bytom是一个多资产发布与管理的平台,所以使用该字段来唯一确定各种资产。</li>
<li>accountid, 这是便于各账户对utxo的索引和管理,bytom 相比bitcoin,引入了账户模型,后面会介绍。</li>
<li>program, 拥有该utxo的账户可以用Ivy语言编写自己想要的程序放在该字段,以便在交易时,图灵完备的BVM会执行该程序。<h2 id="BVM"><a href="#BVM" class="headerlink" title="BVM"></a>BVM</h2><img src="/img/snapshot.png" alt=""><br>BVM是在状态机的转化过程被启动运行,也就是excute(transaction)这一步骤。</li>
</ul>
</li>
<li><p>为什么需要使用BVM?<br>bitcoin 中的非图灵完备栈式脚本语言,所表达的功能极少,很难实现一些稍微复杂的功能,如verify_spv(跨链锚定验证的功能,如btc_relay),再如简单的去实现multi_lock(M人加密,只要收集N人私钥就能解密,0 < N < M)功能。<br>ethereum中的evm能简单的用solidity语言编写程序实现这些功能,但EVM过于复杂,它号称超级世界计算机,对于bytom这种只对资产有兴趣的区块链是没必要的。因此bytom不如基于<a href="https://chain.com/" target="_blank" rel="external">Chain</a> 公司的能用<a href="https://chain.com/docs/1.2/ivy-playground/docs" target="_blank" rel="external">Ivy</a> 高级语言编程的CVM去做自己的扩展,灵活易用。</p>
</li>
<li>如何应用BVM?<br><img src="/img/bytom_bvm.png" alt=""><br>用户在发送每一笔交易时,可以自己编写自己所需要的程序,等到交易打包进块时,BVM会去执行该代码,由于BVM是图灵完备的虚拟机,所以需要加入feed计价机制(feed 等同于ethereum的gas * gasprice)来解决停机问题。 <h2 id="account-model"><a href="#account-model" class="headerlink" title="account model"></a>account model</h2></li>
<li>为什么要采用账户模型?<br>账户模型易于管理相关数据,是以人为中心,十分的直观。对于BVM来说,基于账户代码去执行也十分便捷。再者我们引入了资产模型,类似于账户模型,这样易于资产的监管和查询。</li>
<li><p>bytom怎么去实现账户模型?<br>bytom 中的账户模型也分两类,但不同于ethereum中的个人帐户和合约账户, 它是指资产账户和个人账户。<br>-1 资产账户:<br><img src="/img/bytom_asset.png" alt=""> </p>
<ul>
<li>assetid 是全局唯一的资产识别id。</li>
<li>alias 是资产的别名,可便于记忆,如(gold, silver) 。</li>
<li>vmversion 是为了软分叉时,做到动态过度。</li>
<li>program 是指发布该资产时需要执行的程序。</li>
<li>initialblockhash 是指该资产是在哪个块高度被登记。</li>
<li>signer 管理公私钥对,以便用该资产的私钥签名,只有拥有该资产私钥的人才能发布该资产。</li>
<li><p>definition 对该资产的解释说明等。</p>
<p>-2 个人账户:<br><img src="/img/bytom_account.png" alt=""> </p>
<ul>
<li>accountid 全局唯一可识别账户id</li>
<li>alais 帐户名</li>
<li>signer, 私钥对,用于发送交易。</li>
<li>*utxos 该账户所有的未花费交易的索引,便于快速管理该账户下资产。</li>
<li>program, 该账户发送交易时可插入需要的程序。</li>
</ul>
</li>
</ul>
</li>
</ul>
<h2 id="综述"><a href="#综述" class="headerlink" title="综述"></a>综述</h2><p><img src="/img/bytom_asset_account.png" alt=""><br>UTXO的物理结构,用memcache 存着。UTXO的逻辑结构则是用二叉PAT树来管理。<br>个人账户 根据AccountId 能够快速的索引其相关的utxo。资产账户根据AssetId能够快速的管理相关的utxo。<br><img src="/img/bytom_uml.png" alt=""><br>上图是描述bytom主要数据结构的uml图。<br>Bytom 用PAT树来组织utxo作为世界状态树。<br>账户模型分两种,资产账户和个人账户,账户可以索引管理其相关的utxo。<br>UTXO 池会采用如memcache的内存数据库,落盘数据库会选择关系型数据库,数据会选择protobuf来序列化。<br>在账户做交易时,每个账户都可以从世界状态树去查找选择自己的utxo,并编写自己所需的资产程序,将其做为TxInput。<br>在交易打包进块时,验证节点会去实例化BVM,并执行该交易中所有TxInput中的程序。</p>
</div>
<div class="article-info article-info-index">
<p class="article-more-link">
<a class="article-more-a" href="/2017/06/28/Bytom-s-data-structure/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<article id="post-比原链设计思考-扩展性UTXO模型" class="article article-type-post article-index" itemscope itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2017/06/13/比原链设计思考-扩展性UTXO模型/">比原链设计思考: 扩展性UTXO模型</a>
</h1>
<a href="/2017/06/13/比原链设计思考-扩展性UTXO模型/" class="archive-article-date">
<time datetime="2017-06-13T01:41:44.357Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2017-06-13</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<h2 id="UTXO-的起源(来自高明的中本聪)"><a href="#UTXO-的起源(来自高明的中本聪)" class="headerlink" title="UTXO 的起源(来自高明的中本聪)"></a>UTXO 的起源(来自高明的中本聪)</h2><p>中本聪对比特币的设计,让整个世界进入了数字货币时代。比特币起源于中本聪,UTXO出自比特币。自然,UTXO来自高明的中本聪。UTXO的优点:</p>
<ul>
<li>1,在版本控制方面的考虑,svn 是中心化的数据库保持一份账本,这和区块链的设计自然是相违背的,git 是去中心化的数据库,但会保存太多冗余数据,对于分布式性能肯定是要大打折扣。UTXO数据库是抛弃了历史包袱的git, 只存储了最后一个版本。简易实用。<br><img src="/img/utxo.png" alt="高明的UTXO"></li>
<li>2,UTXO 具有天然的匿名效果,一个账户所对应的未花费交易是难以发现的,如门罗币就是采用混币的方式实现隐私的。</li>
</ul>
<h2 id="设计的易实现性-–-Gavin-Wood-弃UTXO用账户模型"><a href="#设计的易实现性-–-Gavin-Wood-弃UTXO用账户模型" class="headerlink" title="设计的易实现性 – Gavin Wood 弃UTXO用账户模型"></a>设计的易实现性 – Gavin Wood 弃UTXO用账户模型</h2><p>以太坊黄皮书的设计者Gavin Wood 对UTXO的理解,不可能不深刻, 既然UTXO有这么多的优点,他为什么弃用UTXO了? 这时你应该提出个问题,以太坊的最大亮点是什么?你肯定会回答:智能合约。是的,就是因为智能合约的考虑,Gavin Wood要基于UTXO去实现图灵完备的智能合约(功能多样性的超级电脑)是困难的。而账户模型是天然的面向对象的,对每一笔交易,都是在相对应账户上加一笔(nonce++), 多接地气阿。为了易于管理账户,而引入了世界状态,每一笔交易都会改变这个世界状态。这和现实世界是相对应的,每一个微小的改变,都会改变这个世界。<br><img src="/img/ethertransition.png" alt="现实的世界状态"> </p>
<h2 id="并行的思考-–-Gavin-Wood-弃cpp用rust"><a href="#并行的思考-–-Gavin-Wood-弃cpp用rust" class="headerlink" title="并行的思考 – Gavin Wood 弃cpp用rust"></a>并行的思考 – Gavin Wood 弃cpp用rust</h2><p>从以上讨论中不难看出,UTXO是函数式编程风格(haskell),以太坊账户模型是面向对象编程风格(cpp)。以太坊的账户模型很容易的实现了超级电脑模型。然而,性能一直是一道难以逾越的坎。在性能方面,utxo天然的可以并行运行,而基于世界状态的以太坊难以扩展。Gavin Wood当然是认识到这一点的,但要去改变,很难。那到不如用带有函数式编程特点的rust 去重写以太坊,也算是一种折中方案。</p>
<h2 id="我们的思考"><a href="#我们的思考" class="headerlink" title="我们的思考"></a>我们的思考</h2><p>马克思哲学的否定之否定规律,事物的发展变化是螺旋式上升的。在区块链领域也是适合的,前进一步,也需要后退半步,仔细思考后, 慎重前行。UTXO和状态模型的思考,正是如此。量子链看到了这一点,但至今还没有有效的代码开源出来。我们思考过,像量子链一样,基于比特币代码去拿以太坊EVM过来结合。这是几乎不可能的,也是不太实用的,这好比用haskell语言,去实现cpp风格的面向对象编程。我是看不到有什么实际的意义。<br>然而,我们比原链的功能是介于比特币和以太坊之间。实现数字资产方面的图灵完备的智能合约即可。比比特币非图灵完备智能合约进半步,比以太坊包容万象的智能合约退半步。我们可以用UTXO 加 Ivy式的轻量级虚拟机去包容他们两者的优点。既有了UTXO的并行性,又有了数字资产的发行和管理的功能。<br><img src="/img/bvm.jpg" alt="运行机制"><br>如上图,我们可能会采取如下的方案。<br>对于每一种资产都有相对应的轻量级世界状态(树型结构)存在,该树我们可能会选择以太坊的PAT树,或者cosmos的IVAL(不可更改的平衡二叉树) ,每一种资产在执行交易时,会实例化相对应的BVM去执行,可以支持多种不相关的资产并行运行。</p>
</div>
<div class="article-info article-info-index">
<p class="article-more-link">
<a class="article-more-a" href="/2017/06/13/比原链设计思考-扩展性UTXO模型/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<article id="post-ethermint" class="article article-type-post article-index" itemscope itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2017/06/08/ethermint/">Ethermint</a>
</h1>
<a href="/2017/06/08/ethermint/" class="archive-article-date">
<time datetime="2017-06-08T02:46:16.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2017-06-08</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<h2 id="综述"><a href="#综述" class="headerlink" title="综述"></a>综述</h2><p>Ethermint 把Ethereum的pow挖矿模块去掉了,不需要miners了,它实现了tendermint的ABCI接口并且以cosmos hub的身份运行。<br>这意味着Ethermint是一个换了共识模块(POW->Tendermint)的Ethereum。这使得Ethereum的现有工具链可以直接在Ethermint上使用。</p>
<h2 id="Ethermint-全局依赖图如下:"><a href="#Ethermint-全局依赖图如下:" class="headerlink" title="Ethermint 全局依赖图如下:"></a>Ethermint 全局依赖图如下:</h2><p><img src="/img/dependency-graph.png" alt=""> </p>
<h2 id="软件安装-Tendermint-geth-Ethermint"><a href="#软件安装-Tendermint-geth-Ethermint" class="headerlink" title="软件安装(Tendermint, geth, Ethermint)"></a>软件安装(Tendermint, geth, Ethermint)</h2><ul>
<li><p>1,Tendermint 安装</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">go get github.com/tendermint/tendermint/cmd/tendermint</div></pre></td></tr></table></figure>
</li>
<li><p>2,geth 安装</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">git clone https://github.com/ethereum/go-ethereum</div><div class="line">cd go-ethereum</div><div class="line">make geth & make install</div></pre></td></tr></table></figure>
</li>
<li><p>3,Ethermint 安装</p>
<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">git clone https://github.com/tendermint/ethermint.git</div><div class="line">make install</div></pre></td></tr></table></figure>
</li>
</ul>
<h3 id="注意点"><a href="#注意点" class="headerlink" title="注意点"></a>注意点</h3><p>由于谷歌被墙,会有一些库无法从golang.org下,可以更改路经到github。</p>
<h2 id="运行"><a href="#运行" class="headerlink" title="运行"></a>运行</h2><ul>
<li>1,Ethermint 运行<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div><div class="line">3</div></pre></td><td class="code"><pre><div class="line">ethermint --datadir ~/.ethermint init dev/genesis.json</div><div class="line">cp -r dev/keystore ~/.ethermint/keystore</div><div class="line">ethermint --datadir ~/.ethermint --rpc --rpcaddr=0.0.0.0 --ws --wsaddr=0.0.0.0 --rpcapi eth,net,web3,personal,admin</div></pre></td></tr></table></figure>
</li>
</ul>
<p><img src="/img/ethermint_start.png" alt="Ethermint 启动图"> </p>
<ul>
<li>2,Tendermint 运行<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div><div class="line">2</div></pre></td><td class="code"><pre><div class="line">tendermint init --home ~/.ethermint/tendermint</div><div class="line">tendermint node --home ~/.ethermint/tendermint</div></pre></td></tr></table></figure>
</li>
</ul>
<p><img src="/img/tendermint_start.png" alt="Tendermint 启动图"> </p>
<ul>
<li>3, Geth 运行<figure class="highlight plain"><table><tr><td class="gutter"><pre><div class="line">1</div></pre></td><td class="code"><pre><div class="line">geth attach ~/.ethermint/geth.ipc</div></pre></td></tr></table></figure>
</li>
</ul>
<p><img src="/img/geth_start.png" alt="Geth 启动图"> </p>
</div>
<div class="article-info article-info-index">
<p class="article-more-link">
<a class="article-more-a" href="/2017/06/08/ethermint/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<article id="post-BFT" class="article article-type-post article-index" itemscope itemprop="blogPost">
<div class="article-inner">
<header class="article-header">
<h1 itemprop="name">
<a class="article-title" href="/2017/06/06/BFT/">BFT</a>
</h1>
<a href="/2017/06/06/BFT/" class="archive-article-date">
<time datetime="2017-06-06T04:23:38.000Z" itemprop="datePublished"><i class="icon-calendar icon"></i>2017-06-06</time>
</a>
</header>
<div class="article-entry" itemprop="articleBody">
<p>比特币将世界的注意力引向到了区块链。但可惜的是,比特币版本的区块链不能解决区块链行业的很多问题。那是因为:</p>
<ul>
<li>比特币的POW共识会乱费大量能源。</li>
<li>交易非常缓慢, 一笔交易需要花一个小时甚至更长的时间。</li>
<li>没有什么激励机制来激励POW矿工忠于一条链,所以会导致升级很苦难。<br>我们需要一种安全的共识,并且不会给我们的星球施加巨大的能源成本。这种方法是基于拜占庭容错(BFT)的权益证明(<a href="https://bitcointalk.org/index.php?topic=27787.0" target="_blank" rel="external">POS</a> )。我们称之为BFT-PoS。<br>在我们深入了解BFT-PoS之前,我们只需要知道拜占庭错误,而不需要知道<a href="http://pages.cs.wisc.edu/~sschang/OS-Qual/reliability/byzantine.htm" target="_blank" rel="external">拜占庭将军问题</a> 的细节。<br>在分布式系统中,数据在数百或数千个节点上进行复制,需要有一些容错机制或共识算法,因为计算机时不时网络中断或脱机的简单事实。那么如果这些节点的一部分失败,整个系统仍然需要达成共识。<br>标准的容错共识算法(如<a href="https://raft.github.io/raft.pdf" target="_blank" rel="external">Raft</a> 和<a href="https://en.wikipedia.org/wiki/Paxos_(computer_science" target="_blank" rel="external">Paxos</a>) )假设当一个节点出现故障时,它只是停止工作,不会回复消息。谷歌,Facebook和一些现有的数据库产品已经在他们的防火墙内使用了这一系列的共识算法,使有故障机器产生时也能确保服务仍然可用。<br>但这些算法不适用于公共块链,因为公共块链中没有防火墙。任何拥有算力(PoW)或代币(PoS)的人都可以参与,甚至试图破坏网络。为了达成共识,我们需要拜占庭的容错能力。在拜占庭故障中,故障节点可以以完全任意的方式运行。节点甚至可以串通尝试作恶并最大限度地发挥其破坏力。<br>因此,本质上,BFT共识算法的目的是在不信任网络中(如万维网)的节点间建立信任。<br>BFT不是什么新概念,<a href="https://www.microsoft.com/en-us/research/publication/byzantine-generals-problem/?from=http%3A%2F%2Fresearch.microsoft.com%2Fen-us%2Fum%2Fpeople%2Flamport%2Fpubs%2Fbyz.pdf" target="_blank" rel="external">该概念首先在Lamport,Shostak和Pease于1982年的一篇学术论文中引入</a> 。但是Lamport等人只在同步环境中(所有的消息总是及时到达)演示了算法的理论可行性。<br>但在现实世界中,你不能真正地相信互联网能及时交付任何东西。所以在1988年,<a href="http://groups.csail.mit.edu/tds/papers/Lynch/jacm88.pdf" target="_blank" rel="external">Dwork,Lynch,Stockmeyer(DLS)</a> 提出了一种在大多数异步环境中工作的算法。 1999年晚些时候,<a href="http://pmg.csail.mit.edu/papers/osdi99.pdf" target="_blank" rel="external">米格尔·卡斯特罗和芭芭拉·里斯科夫</a> 提出了一个实际的解决方案,用于持续的BFT协商一致,这是迄今为止仍然是现在最先进的BFT算法。<br>但长久以来,主流媒体忽视了这些创作。 没有人明白BFT在学术界和诸如IBM和DARPA之类的主要机构之外的重要性,直到2009年Bitcoin来临。比特币是第一个开放式区中心化应用程序,为全球货币帐本提供BFT共识,但对拜占庭式将军的问题采用了一种全新的解决方案:PoW。<br>在PoW中,谁的算力最强,谁最有可能打包交易出块,获得该块交易费和新产生的比特币。今天,许多矿业公司在生产矿机,也有许多矿工正在加入矿池。<br>另一方面,PoS完全消除了PoW的能源依赖。在PoS中,矿工被替换为在系统中拥有股权的“验证者”。验证者不必投资昂贵的处理系统,但他们必须购买“股权代币”。任何普通笔记本电脑都足以解决算法。<br>Peercoin,BitShares,Nxt等已经使用了某种形式的PoS,而Ethereum正在计划在不久的将来进行PoS。然而,虽然PoS具有实际意义,但是很多人都反对使用PoS,声称这是不可能的。但这根本不是事实。使用BFT,您绝对可以保护PoS。只是我们还没有看到任何公有链实现了BFT-PoS。<br>虽然该理论可能难以解释或理解,但适当的BFT算法提供的最终结果很容易掌握。 与PoW区块链不同,BFT-PoS块链根本不分叉,如,获得双花攻击,除非1/3或更多的验证者协调此类攻击。而且,当1/3或更多的验证者确实导致双重花费攻击时,我们可以计算确定哪些验证者对攻击负责,摧毁它们的权益代币并将其从网络中剔除。就好像矿工联合起来控制整个链一样。至今,包括POW算法在内,还没有那种共识算法可以到达BFT-PoS的容错水平。<br>BFT-PoS表现非常出色。今天,在全球有几百个验证节点的公有链中,你可以在3s内轻松获得交易确认。这一理论的“即时确认“最佳容错阈值已经被tendermint证明。虽然随着验证节点的增加共识速度会变慢,但遵循着<a href="https://www.nngroup.com/articles/law-of-bandwidth/" target="_blank" rel="external">Nielsen 定律</a> ,每年都可以有增加一定的节点,而性能不会变。<br>此外,BFT-PoS还将增加移动钱包的安全性。目前存在的移动钱包很少充分利用了比特币提供的安全性,因为没有人愿意等待一个小时才能确认交易。相反,大多数钱包只是假设发送钱的人不会双花。而且,虽然我们没有时间在这里进行深入研究,但高效的移动钱包协议或“轻客户端SPV”协议是未来块链互操作性的关键。<br>虽然PoW在比特币方面表现很好,但代价昂贵,速度慢,环境不友好。现在最好的选择是BFT-PoS。它是一种持久,节能的解决方案,在异步环境中运行良好。最重要的是,由于BFT是计算机科学界最好和最聪明的开发机构证明是安全的。—-Jae Kwon</li>
</ul>
</div>
<div class="article-info article-info-index">
<p class="article-more-link">
<a class="article-more-a" href="/2017/06/06/BFT/">展开全文 >></a>
</p>
<div class="clearfix"></div>
</div>
</div>
</article>
<nav id="page-nav">
<span class="page-number current">1</span><a class="page-number" href="/page/2/">2</a><a class="extend next" rel="next" href="/page/2/">Next »</a>
</nav>
</div>
</div>
</div>
<footer id="footer">
<div class="outer">
<div id="footer-info">
<div class="footer-left">
© 2018 Gavin
</div>
<div class="footer-right">
<a href="http://hexo.io/" target="_blank">Hexo</a> Theme <a href="https://github.com/litten/hexo-theme-yilia" target="_blank">Yilia</a> by Litten
</div>
</div>
</div>
</footer>
</div>
<script>
var yiliaConfig = {
mathjax: false,
isHome: true,
isPost: false,
isArchive: false,
isTag: false,
isCategory: false,
open_in_new: false,
root: "/",
innerArchive: true,
showTags: false
}
</script>
<script>!function(t){function n(e){if(r[e])return r[e].exports;var i=r[e]={exports:{},id:e,loaded:!1};return t[e].call(i.exports,i,i.exports,n),i.loaded=!0,i.exports}var r={};n.m=t,n.c=r,n.p="./",n(0)}([function(t,n,r){r(194),t.exports=r(190)},function(t,n,r){var e=r(3),i=r(52),o=r(27),u=r(28),c=r(53),f="prototype",a=function(t,n,r){var s,l,h,v,p=t&a.F,d=t&a.G,y=t&a.S,g=t&a.P,b=t&a.B,m=d?e:y?e[n]||(e[n]={}):(e[n]||{})[f],x=d?i:i[n]||(i[n]={}),w=x[f]||(x[f]={});d&&(r=n);for(s in r)l=!p&&m&&void 0!==m[s],h=(l?m:r)[s],v=b&&l?c(h,e):g&&"function"==typeof h?c(Function.call,h):h,m&&u(m,s,h,t&a.U),x[s]!=h&&o(x,s,v),g&&w[s]!=h&&(w[s]=h)};e.core=i,a.F=1,a.G=2,a.S=4,a.P=8,a.B=16,a.W=32,a.U=64,a.R=128,t.exports=a},function(t,n,r){var e=r(6);t.exports=function(t){if(!e(t))throw TypeError(t+" is not an object!");return t}},function(t,n){var r=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=r)},function(t,n){t.exports=function(t){try{return!!t()}catch(t){return!0}}},function(t,n){var r=t.exports="undefined"!=typeof window&&window.Math==Math?window:"undefined"!=typeof self&&self.Math==Math?self:Function("return this")();"number"==typeof __g&&(__g=r)},function(t,n){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,n,r){var e=r(126)("wks"),i=r(76),o=r(3).Symbol,u="function"==typeof o;(t.exports=function(t){return e[t]||(e[t]=u&&o[t]||(u?o:i)("Symbol."+t))}).store=e},function(t,n){var r={}.hasOwnProperty;t.exports=function(t,n){return r.call(t,n)}},function(t,n,r){var e=r(94),i=r(33);t.exports=function(t){return e(i(t))}},function(t,n,r){t.exports=!r(4)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,n,r){var e=r(2),i=r(167),o=r(50),u=Object.defineProperty;n.f=r(10)?Object.defineProperty:function(t,n,r){if(e(t),n=o(n,!0),e(r),i)try{return u(t,n,r)}catch(t){}if("get"in r||"set"in r)throw TypeError("Accessors not supported!");return"value"in r&&(t[n]=r.value),t}},function(t,n,r){t.exports=!r(18)(function(){return 7!=Object.defineProperty({},"a",{get:function(){return 7}}).a})},function(t,n,r){var e=r(14),i=r(22);t.exports=r(12)?function(t,n,r){return e.f(t,n,i(1,r))}:function(t,n,r){return t[n]=r,t}},function(t,n,r){var e=r(20),i=r(58),o=r(42),u=Object.defineProperty;n.f=r(12)?Object.defineProperty:function(t,n,r){if(e(t),n=o(n,!0),e(r),i)try{return u(t,n,r)}catch(t){}if("get"in r||"set"in r)throw TypeError("Accessors not supported!");return"value"in r&&(t[n]=r.value),t}},function(t,n,r){var e=r(40)("wks"),i=r(23),o=r(5).Symbol,u="function"==typeof o;(t.exports=function(t){return e[t]||(e[t]=u&&o[t]||(u?o:i)("Symbol."+t))}).store=e},function(t,n,r){var e=r(67),i=Math.min;t.exports=function(t){return t>0?i(e(t),9007199254740991):0}},function(t,n,r){var e=r(46);t.exports=function(t){return Object(e(t))}},function(t,n){t.exports=function(t){try{return!!t()}catch(t){return!0}}},function(t,n,r){var e=r(63),i=r(34);t.exports=Object.keys||function(t){return e(t,i)}},function(t,n,r){var e=r(21);t.exports=function(t){if(!e(t))throw TypeError(t+" is not an object!");return t}},function(t,n){t.exports=function(t){return"object"==typeof t?null!==t:"function"==typeof t}},function(t,n){t.exports=function(t,n){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:n}}},function(t,n){var r=0,e=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++r+e).toString(36))}},function(t,n){var r={}.hasOwnProperty;t.exports=function(t,n){return r.call(t,n)}},function(t,n){var r=t.exports={version:"2.4.0"};"number"==typeof __e&&(__e=r)},function(t,n){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,n,r){var e=r(11),i=r(66);t.exports=r(10)?function(t,n,r){return e.f(t,n,i(1,r))}:function(t,n,r){return t[n]=r,t}},function(t,n,r){var e=r(3),i=r(27),o=r(24),u=r(76)("src"),c="toString",f=Function[c],a=(""+f).split(c);r(52).inspectSource=function(t){return f.call(t)},(t.exports=function(t,n,r,c){var f="function"==typeof r;f&&(o(r,"name")||i(r,"name",n)),t[n]!==r&&(f&&(o(r,u)||i(r,u,t[n]?""+t[n]:a.join(String(n)))),t===e?t[n]=r:c?t[n]?t[n]=r:i(t,n,r):(delete t[n],i(t,n,r)))})(Function.prototype,c,function(){return"function"==typeof this&&this[u]||f.call(this)})},function(t,n,r){var e=r(1),i=r(4),o=r(46),u=function(t,n,r,e){var i=String(o(t)),u="<"+n;return""!==r&&(u+=" "+r+'="'+String(e).replace(/"/g,""")+'"'),u+">"+i+"</"+n+">"};t.exports=function(t,n){var r={};r[t]=n(u),e(e.P+e.F*i(function(){var n=""[t]('"');return n!==n.toLowerCase()||n.split('"').length>3}),"String",r)}},function(t,n,r){var e=r(115),i=r(46);t.exports=function(t){return e(i(t))}},function(t,n,r){var e=r(116),i=r(66),o=r(30),u=r(50),c=r(24),f=r(167),a=Object.getOwnPropertyDescriptor;n.f=r(10)?a:function(t,n){if(t=o(t),n=u(n,!0),f)try{return a(t,n)}catch(t){}if(c(t,n))return i(!e.f.call(t,n),t[n])}},function(t,n,r){var e=r(24),i=r(17),o=r(145)("IE_PROTO"),u=Object.prototype;t.exports=Object.getPrototypeOf||function(t){return t=i(t),e(t,o)?t[o]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?u:null}},function(t,n){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},function(t,n){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,n){t.exports={}},function(t,n){t.exports=!0},function(t,n){n.f={}.propertyIsEnumerable},function(t,n,r){var e=r(14).f,i=r(8),o=r(15)("toStringTag");t.exports=function(t,n,r){t&&!i(t=r?t:t.prototype,o)&&e(t,o,{configurable:!0,value:n})}},function(t,n,r){var e=r(40)("keys"),i=r(23);t.exports=function(t){return e[t]||(e[t]=i(t))}},function(t,n,r){var e=r(5),i="__core-js_shared__",o=e[i]||(e[i]={});t.exports=function(t){return o[t]||(o[t]={})}},function(t,n){var r=Math.ceil,e=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?e:r)(t)}},function(t,n,r){var e=r(21);t.exports=function(t,n){if(!e(t))return t;var r,i;if(n&&"function"==typeof(r=t.toString)&&!e(i=r.call(t)))return i;if("function"==typeof(r=t.valueOf)&&!e(i=r.call(t)))return i;if(!n&&"function"==typeof(r=t.toString)&&!e(i=r.call(t)))return i;throw TypeError("Can't convert object to primitive value")}},function(t,n,r){var e=r(5),i=r(25),o=r(36),u=r(44),c=r(14).f;t.exports=function(t){var n=i.Symbol||(i.Symbol=o?{}:e.Symbol||{});"_"==t.charAt(0)||t in n||c(n,t,{value:u.f(t)})}},function(t,n,r){n.f=r(15)},function(t,n){var r={}.toString;t.exports=function(t){return r.call(t).slice(8,-1)}},function(t,n){t.exports=function(t){if(void 0==t)throw TypeError("Can't call method on "+t);return t}},function(t,n,r){var e=r(4);t.exports=function(t,n){return!!t&&e(function(){n?t.call(null,function(){},1):t.call(null)})}},function(t,n,r){var e=r(53),i=r(115),o=r(17),u=r(16),c=r(202);t.exports=function(t,n){var r=1==t,f=2==t,a=3==t,s=4==t,l=6==t,h=5==t||l,v=n||c;return function(n,c,p){for(var d,y,g=o(n),b=i(g),m=e(c,p,3),x=u(b.length),w=0,S=r?v(n,x):f?v(n,0):void 0;x>w;w++)if((h||w in b)&&(d=b[w],y=m(d,w,g),t))if(r)S[w]=y;else if(y)switch(t){case 3:return!0;case 5:return d;case 6:return w;case 2:S.push(d)}else if(s)return!1;return l?-1:a||s?s:S}}},function(t,n,r){var e=r(1),i=r(52),o=r(4);t.exports=function(t,n){var r=(i.Object||{})[t]||Object[t],u={};u[t]=n(r),e(e.S+e.F*o(function(){r(1)}),"Object",u)}},function(t,n,r){var e=r(6);t.exports=function(t,n){if(!e(t))return t;var r,i;if(n&&"function"==typeof(r=t.toString)&&!e(i=r.call(t)))return i;if("function"==typeof(r=t.valueOf)&&!e(i=r.call(t)))return i;if(!n&&"function"==typeof(r=t.toString)&&!e(i=r.call(t)))return i;throw TypeError("Can't convert object to primitive value")}},function(t,n,r){var e=r(5),i=r(25),o=r(91),u=r(13),c="prototype",f=function(t,n,r){var a,s,l,h=t&f.F,v=t&f.G,p=t&f.S,d=t&f.P,y=t&f.B,g=t&f.W,b=v?i:i[n]||(i[n]={}),m=b[c],x=v?e:p?e[n]:(e[n]||{})[c];v&&(r=n);for(a in r)(s=!h&&x&&void 0!==x[a])&&a in b||(l=s?x[a]:r[a],b[a]=v&&"function"!=typeof x[a]?r[a]:y&&s?o(l,e):g&&x[a]==l?function(t){var n=function(n,r,e){if(this instanceof t){switch(arguments.length){case 0:return new t;case 1:return new t(n);case 2:return new t(n,r)}return new t(n,r,e)}return t.apply(this,arguments)};return n[c]=t[c],n}(l):d&&"function"==typeof l?o(Function.call,l):l,d&&((b.virtual||(b.virtual={}))[a]=l,t&f.R&&m&&!m[a]&&u(m,a,l)))};f.F=1,f.G=2,f.S=4,f.P=8,f.B=16,f.W=32,f.U=64,f.R=128,t.exports=f},function(t,n){var r=t.exports={version:"2.4.0"};"number"==typeof __e&&(__e=r)},function(t,n,r){var e=r(26);t.exports=function(t,n,r){if(e(t),void 0===n)return t;switch(r){case 1:return function(r){return t.call(n,r)};case 2:return function(r,e){return t.call(n,r,e)};case 3:return function(r,e,i){return t.call(n,r,e,i)}}return function(){return t.apply(n,arguments)}}},function(t,n,r){var e=r(183),i=r(1),o=r(126)("metadata"),u=o.store||(o.store=new(r(186))),c=function(t,n,r){var i=u.get(t);if(!i){if(!r)return;u.set(t,i=new e)}var o=i.get(n);if(!o){if(!r)return;i.set(n,o=new e)}return o},f=function(t,n,r){var e=c(n,r,!1);return void 0!==e&&e.has(t)},a=function(t,n,r){var e=c(n,r,!1);return void 0===e?void 0:e.get(t)},s=function(t,n,r,e){c(r,e,!0).set(t,n)},l=function(t,n){var r=c(t,n,!1),e=[];return r&&r.forEach(function(t,n){e.push(n)}),e},h=function(t){return void 0===t||"symbol"==typeof t?t:String(t)},v=function(t){i(i.S,"Reflect",t)};t.exports={store:u,map:c,has:f,get:a,set:s,keys:l,key:h,exp:v}},function(t,n,r){"use strict";if(r(10)){var e=r(69),i=r(3),o=r(4),u=r(1),c=r(127),f=r(152),a=r(53),s=r(68),l=r(66),h=r(27),v=r(73),p=r(67),d=r(16),y=r(75),g=r(50),b=r(24),m=r(180),x=r(114),w=r(6),S=r(17),_=r(137),O=r(70),E=r(32),P=r(71).f,j=r(154),F=r(76),M=r(7),A=r(48),N=r(117),T=r(146),I=r(155),k=r(80),L=r(123),R=r(74),C=r(130),D=r(160),U=r(11),W=r(31),G=U.f,B=W.f,V=i.RangeError,z=i.TypeError,q=i.Uint8Array,K="ArrayBuffer",J="Shared"+K,Y="BYTES_PER_ELEMENT",H="prototype",$=Array[H],X=f.ArrayBuffer,Q=f.DataView,Z=A(0),tt=A(2),nt=A(3),rt=A(4),et=A(5),it=A(6),ot=N(!0),ut=N(!1),ct=I.values,ft=I.keys,at=I.entries,st=$.lastIndexOf,lt=$.reduce,ht=$.reduceRight,vt=$.join,pt=$.sort,dt=$.slice,yt=$.toString,gt=$.toLocaleString,bt=M("iterator"),mt=M("toStringTag"),xt=F("typed_constructor"),wt=F("def_constructor"),St=c.CONSTR,_t=c.TYPED,Ot=c.VIEW,Et="Wrong length!",Pt=A(1,function(t,n){return Tt(T(t,t[wt]),n)}),jt=o(function(){return 1===new q(new Uint16Array([1]).buffer)[0]}),Ft=!!q&&!!q[H].set&&o(function(){new q(1).set({})}),Mt=function(t,n){if(void 0===t)throw z(Et);var r=+t,e=d(t);if(n&&!m(r,e))throw V(Et);return e},At=function(t,n){var r=p(t);if(r<0||r%n)throw V("Wrong offset!");return r},Nt=function(t){if(w(t)&&_t in t)return t;throw z(t+" is not a typed array!")},Tt=function(t,n){if(!(w(t)&&xt in t))throw z("It is not a typed array constructor!");return new t(n)},It=function(t,n){return kt(T(t,t[wt]),n)},kt=function(t,n){for(var r=0,e=n.length,i=Tt(t,e);e>r;)i[r]=n[r++];return i},Lt=function(t,n,r){G(t,n,{get:function(){return this._d[r]}})},Rt=function(t){var n,r,e,i,o,u,c=S(t),f=arguments.length,s=f>1?arguments[1]:void 0,l=void 0!==s,h=j(c);if(void 0!=h&&!_(h)){for(u=h.call(c),e=[],n=0;!(o=u.next()).done;n++)e.push(o.value);c=e}for(l&&f>2&&(s=a(s,arguments[2],2)),n=0,r=d(c.length),i=Tt(this,r);r>n;n++)i[n]=l?s(c[n],n):c[n];return i},Ct=function(){for(var t=0,n=arguments.length,r=Tt(this,n);n>t;)r[t]=arguments[t++];return r},Dt=!!q&&o(function(){gt.call(new q(1))}),Ut=function(){return gt.apply(Dt?dt.call(Nt(this)):Nt(this),arguments)},Wt={copyWithin:function(t,n){return D.call(Nt(this),t,n,arguments.length>2?arguments[2]:void 0)},every:function(t){return rt(Nt(this),t,arguments.length>1?arguments[1]:void 0)},fill:function(t){return C.apply(Nt(this),arguments)},filter:function(t){return It(this,tt(Nt(this),t,arguments.length>1?arguments[1]:void 0))},find:function(t){return et(Nt(this),t,arguments.length>1?arguments[1]:void 0)},findIndex:function(t){return it(Nt(this),t,arguments.length>1?arguments[1]:void 0)},forEach:function(t){Z(Nt(this),t,arguments.length>1?arguments[1]:void 0)},indexOf:function(t){return ut(Nt(this),t,arguments.length>1?arguments[1]:void 0)},includes:function(t){return ot(Nt(this),t,arguments.length>1?arguments[1]:void 0)},join:function(t){return vt.apply(Nt(this),arguments)},lastIndexOf:function(t){return st.apply(Nt(this),arguments)},map:function(t){return Pt(Nt(this),t,arguments.length>1?arguments[1]:void 0)},reduce:function(t){return lt.apply(Nt(this),arguments)},reduceRight:function(t){return ht.apply(Nt(this),arguments)},reverse:function(){for(var t,n=this,r=Nt(n).length,e=Math.floor(r/2),i=0;i<e;)t=n[i],n[i++]=n[--r],n[r]=t;return n},some:function(t){return nt(Nt(this),t,arguments.length>1?arguments[1]:void 0)},sort:function(t){return pt.call(Nt(this),t)},subarray:function(t,n){var r=Nt(this),e=r.length,i=y(t,e);return new(T(r,r[wt]))(r.buffer,r.byteOffset+i*r.BYTES_PER_ELEMENT,d((void 0===n?e:y(n,e))-i))}},Gt=function(t,n){return It(this,dt.call(Nt(this),t,n))},Bt=function(t){Nt(this);var n=At(arguments[1],1),r=this.length,e=S(t),i=d(e.length),o=0;if(i+n>r)throw V(Et);for(;o<i;)this[n+o]=e[o++]},Vt={entries:function(){return at.call(Nt(this))},keys:function(){return ft.call(Nt(this))},values:function(){return ct.call(Nt(this))}},zt=function(t,n){return w(t)&&t[_t]&&"symbol"!=typeof n&&n in t&&String(+n)==String(n)},qt=function(t,n){return zt(t,n=g(n,!0))?l(2,t[n]):B(t,n)},Kt=function(t,n,r){return!(zt(t,n=g(n,!0))&&w(r)&&b(r,"value"))||b(r,"get")||b(r,"set")||r.configurable||b(r,"writable")&&!r.writable||b(r,"enumerable")&&!r.enumerable?G(t,n,r):(t[n]=r.value,t)};St||(W.f=qt,U.f=Kt),u(u.S+u.F*!St,"Object",{getOwnPropertyDescriptor:qt,defineProperty:Kt}),o(function(){yt.call({})})&&(yt=gt=function(){return vt.call(this)});var Jt=v({},Wt);v(Jt,Vt),h(Jt,bt,Vt.values),v(Jt,{slice:Gt,set:Bt,constructor:function(){},toString:yt,toLocaleString:Ut}),Lt(Jt,"buffer","b"),Lt(Jt,"byteOffset","o"),Lt(Jt,"byteLength","l"),Lt(Jt,"length","e"),G(Jt,mt,{get:function(){return this[_t]}}),t.exports=function(t,n,r,f){f=!!f;var a=t+(f?"Clamped":"")+"Array",l="Uint8Array"!=a,v="get"+t,p="set"+t,y=i[a],g=y||{},b=y&&E(y),m=!y||!c.ABV,S={},_=y&&y[H],j=function(t,r){var e=t._d;return e.v[v](r*n+e.o,jt)},F=function(t,r,e){var i=t._d;f&&(e=(e=Math.round(e))<0?0:e>255?255:255&e),i.v[p](r*n+i.o,e,jt)},M=function(t,n){G(t,n,{get:function(){return j(this,n)},set:function(t){return F(this,n,t)},enumerable:!0})};m?(y=r(function(t,r,e,i){s(t,y,a,"_d");var o,u,c,f,l=0,v=0;if(w(r)){if(!(r instanceof X||(f=x(r))==K||f==J))return _t in r?kt(y,r):Rt.call(y,r);o=r,v=At(e,n);var p=r.byteLength;if(void 0===i){if(p%n)throw V(Et);if((u=p-v)<0)throw V(Et)}else if((u=d(i)*n)+v>p)throw V(Et);c=u/n}else c=Mt(r,!0),u=c*n,o=new X(u);for(h(t,"_d",{b:o,o:v,l:u,e:c,v:new Q(o)});l<c;)M(t,l++)}),_=y[H]=O(Jt),h(_,"constructor",y)):L(function(t){new y(null),new y(t)},!0)||(y=r(function(t,r,e,i){s(t,y,a);var o;return w(r)?r instanceof X||(o=x(r))==K||o==J?void 0!==i?new g(r,At(e,n),i):void 0!==e?new g(r,At(e,n)):new g(r):_t in r?kt(y,r):Rt.call(y,r):new g(Mt(r,l))}),Z(b!==Function.prototype?P(g).concat(P(b)):P(g),function(t){t in y||h(y,t,g[t])}),y[H]=_,e||(_.constructor=y));var A=_[bt],N=!!A&&("values"==A.name||void 0==A.name),T=Vt.values;h(y,xt,!0),h(_,_t,a),h(_,Ot,!0),h(_,wt,y),(f?new y(1)[mt]==a:mt in _)||G(_,mt,{get:function(){return a}}),S[a]=y,u(u.G+u.W+u.F*(y!=g),S),u(u.S,a,{BYTES_PER_ELEMENT:n,from:Rt,of:Ct}),Y in _||h(_,Y,n),u(u.P,a,Wt),R(a),u(u.P+u.F*Ft,a,{set:Bt}),u(u.P+u.F*!N,a,Vt),u(u.P+u.F*(_.toString!=yt),a,{toString:yt}),u(u.P+u.F*o(function(){new y(1).slice()}),a,{slice:Gt}),u(u.P+u.F*(o(function(){return[1,2].toLocaleString()!=new y([1,2]).toLocaleString()})||!o(function(){_.toLocaleString.call([1,2])})),a,{toLocaleString:Ut}),k[a]=N?A:T,e||N||h(_,bt,T)}}else t.exports=function(){}},function(t,n){var r={}.toString;t.exports=function(t){return r.call(t).slice(8,-1)}},function(t,n,r){var e=r(21),i=r(5).document,o=e(i)&&e(i.createElement);t.exports=function(t){return o?i.createElement(t):{}}},function(t,n,r){t.exports=!r(12)&&!r(18)(function(){return 7!=Object.defineProperty(r(57)("div"),"a",{get:function(){return 7}}).a})},function(t,n,r){"use strict";var e=r(36),i=r(51),o=r(64),u=r(13),c=r(8),f=r(35),a=r(96),s=r(38),l=r(103),h=r(15)("iterator"),v=!([].keys&&"next"in[].keys()),p="keys",d="values",y=function(){return this};t.exports=function(t,n,r,g,b,m,x){a(r,n,g);var w,S,_,O=function(t){if(!v&&t in F)return F[t];switch(t){case p:case d:return function(){return new r(this,t)}}return function(){return new r(this,t)}},E=n+" Iterator",P=b==d,j=!1,F=t.prototype,M=F[h]||F["@@iterator"]||b&&F[b],A=M||O(b),N=b?P?O("entries"):A:void 0,T="Array"==n?F.entries||M:M;if(T&&(_=l(T.call(new t)))!==Object.prototype&&(s(_,E,!0),e||c(_,h)||u(_,h,y)),P&&M&&M.name!==d&&(j=!0,A=function(){return M.call(this)}),e&&!x||!v&&!j&&F[h]||u(F,h,A),f[n]=A,f[E]=y,b)if(w={values:P?A:O(d),keys:m?A:O(p),entries:N},x)for(S in w)S in F||o(F,S,w[S]);else i(i.P+i.F*(v||j),n,w);return w}},function(t,n,r){var e=r(20),i=r(100),o=r(34),u=r(39)("IE_PROTO"),c=function(){},f="prototype",a=function(){var t,n=r(57)("iframe"),e=o.length;for(n.style.display="none",r(93).appendChild(n),n.src="javascript:",t=n.contentWindow.document,t.open(),t.write("<script>document.F=Object<\/script>"),t.close(),a=t.F;e--;)delete a[f][o[e]];return a()};t.exports=Object.create||function(t,n){var r;return null!==t?(c[f]=e(t),r=new c,c[f]=null,r[u]=t):r=a(),void 0===n?r:i(r,n)}},function(t,n,r){var e=r(63),i=r(34).concat("length","prototype");n.f=Object.getOwnPropertyNames||function(t){return e(t,i)}},function(t,n){n.f=Object.getOwnPropertySymbols},function(t,n,r){var e=r(8),i=r(9),o=r(90)(!1),u=r(39)("IE_PROTO");t.exports=function(t,n){var r,c=i(t),f=0,a=[];for(r in c)r!=u&&e(c,r)&&a.push(r);for(;n.length>f;)e(c,r=n[f++])&&(~o(a,r)||a.push(r));return a}},function(t,n,r){t.exports=r(13)},function(t,n,r){var e=r(76)("meta"),i=r(6),o=r(24),u=r(11).f,c=0,f=Object.isExtensible||function(){return!0},a=!r(4)(function(){return f(Object.preventExtensions({}))}),s=function(t){u(t,e,{value:{i:"O"+ ++c,w:{}}})},l=function(t,n){if(!i(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!o(t,e)){if(!f(t))return"F";if(!n)return"E";s(t)}return t[e].i},h=function(t,n){if(!o(t,e)){if(!f(t))return!0;if(!n)return!1;s(t)}return t[e].w},v=function(t){return a&&p.NEED&&f(t)&&!o(t,e)&&s(t),t},p=t.exports={KEY:e,NEED:!1,fastKey:l,getWeak:h,onFreeze:v}},function(t,n){t.exports=function(t,n){return{enumerable:!(1&t),configurable:!(2&t),writable:!(4&t),value:n}}},function(t,n){var r=Math.ceil,e=Math.floor;t.exports=function(t){return isNaN(t=+t)?0:(t>0?e:r)(t)}},function(t,n){t.exports=function(t,n,r,e){if(!(t instanceof n)||void 0!==e&&e in t)throw TypeError(r+": incorrect invocation!");return t}},function(t,n){t.exports=!1},function(t,n,r){var e=r(2),i=r(173),o=r(133),u=r(145)("IE_PROTO"),c=function(){},f="prototype",a=function(){var t,n=r(132)("iframe"),e=o.length;for(n.style.display="none",r(135).appendChild(n),n.src="javascript:",t=n.contentWindow.document,t.open(),t.write("<script>document.F=Object<\/script>"),t.close(),a=t.F;e--;)delete a[f][o[e]];return a()};t.exports=Object.create||function(t,n){var r;return null!==t?(c[f]=e(t),r=new c,c[f]=null,r[u]=t):r=a(),void 0===n?r:i(r,n)}},function(t,n,r){var e=r(175),i=r(133).concat("length","prototype");n.f=Object.getOwnPropertyNames||function(t){return e(t,i)}},function(t,n,r){var e=r(175),i=r(133);t.exports=Object.keys||function(t){return e(t,i)}},function(t,n,r){var e=r(28);t.exports=function(t,n,r){for(var i in n)e(t,i,n[i],r);return t}},function(t,n,r){"use strict";var e=r(3),i=r(11),o=r(10),u=r(7)("species");t.exports=function(t){var n=e[t];o&&n&&!n[u]&&i.f(n,u,{configurable:!0,get:function(){return this}})}},function(t,n,r){var e=r(67),i=Math.max,o=Math.min;t.exports=function(t,n){return t=e(t),t<0?i(t+n,0):o(t,n)}},function(t,n){var r=0,e=Math.random();t.exports=function(t){return"Symbol(".concat(void 0===t?"":t,")_",(++r+e).toString(36))}},function(t,n,r){var e=r(33);t.exports=function(t){return Object(e(t))}},function(t,n,r){var e=r(7)("unscopables"),i=Array.prototype;void 0==i[e]&&r(27)(i,e,{}),t.exports=function(t){i[e][t]=!0}},function(t,n,r){var e=r(53),i=r(169),o=r(137),u=r(2),c=r(16),f=r(154),a={},s={},n=t.exports=function(t,n,r,l,h){var v,p,d,y,g=h?function(){return t}:f(t),b=e(r,l,n?2:1),m=0;if("function"!=typeof g)throw TypeError(t+" is not iterable!");if(o(g)){for(v=c(t.length);v>m;m++)if((y=n?b(u(p=t[m])[0],p[1]):b(t[m]))===a||y===s)return y}else for(d=g.call(t);!(p=d.next()).done;)if((y=i(d,b,p.value,n))===a||y===s)return y};n.BREAK=a,n.RETURN=s},function(t,n){t.exports={}},function(t,n,r){var e=r(11).f,i=r(24),o=r(7)("toStringTag");t.exports=function(t,n,r){t&&!i(t=r?t:t.prototype,o)&&e(t,o,{configurable:!0,value:n})}},function(t,n,r){var e=r(1),i=r(46),o=r(4),u=r(150),c="["+u+"]",f="
",a=RegExp("^"+c+c+"*"),s=RegExp(c+c+"*$"),l=function(t,n,r){var i={},c=o(function(){return!!u[t]()||f[t]()!=f}),a=i[t]=c?n(h):u[t];r&&(i[r]=a),e(e.P+e.F*c,"String",i)},h=l.trim=function(t,n){return t=String(i(t)),1&n&&(t=t.replace(a,"")),2&n&&(t=t.replace(s,"")),t};t.exports=l},function(t,n,r){t.exports={default:r(86),__esModule:!0}},function(t,n,r){t.exports={default:r(87),__esModule:!0}},function(t,n,r){"use strict";function e(t){return t&&t.__esModule?t:{default:t}}n.__esModule=!0;var i=r(84),o=e(i),u=r(83),c=e(u),f="function"==typeof c.default&&"symbol"==typeof o.default?function(t){return typeof t}:function(t){return t&&"function"==typeof c.default&&t.constructor===c.default&&t!==c.default.prototype?"symbol":typeof t};n.default="function"==typeof c.default&&"symbol"===f(o.default)?function(t){return void 0===t?"undefined":f(t)}:function(t){return t&&"function"==typeof c.default&&t.constructor===c.default&&t!==c.default.prototype?"symbol":void 0===t?"undefined":f(t)}},function(t,n,r){r(110),r(108),r(111),r(112),t.exports=r(25).Symbol},function(t,n,r){r(109),r(113),t.exports=r(44).f("iterator")},function(t,n){t.exports=function(t){if("function"!=typeof t)throw TypeError(t+" is not a function!");return t}},function(t,n){t.exports=function(){}},function(t,n,r){var e=r(9),i=r(106),o=r(105);t.exports=function(t){return function(n,r,u){var c,f=e(n),a=i(f.length),s=o(u,a);if(t&&r!=r){for(;a>s;)if((c=f[s++])!=c)return!0}else for(;a>s;s++)if((t||s in f)&&f[s]===r)return t||s||0;return!t&&-1}}},function(t,n,r){var e=r(88);t.exports=function(t,n,r){if(e(t),void 0===n)return t;switch(r){case 1:return function(r){return t.call(n,r)};case 2:return function(r,e){return t.call(n,r,e)};case 3:return function(r,e,i){return t.call(n,r,e,i)}}return function(){return t.apply(n,arguments)}}},function(t,n,r){var e=r(19),i=r(62),o=r(37);t.exports=function(t){var n=e(t),r=i.f;if(r)for(var u,c=r(t),f=o.f,a=0;c.length>a;)f.call(t,u=c[a++])&&n.push(u);return n}},function(t,n,r){t.exports=r(5).document&&document.documentElement},function(t,n,r){var e=r(56);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==e(t)?t.split(""):Object(t)}},function(t,n,r){var e=r(56);t.exports=Array.isArray||function(t){return"Array"==e(t)}},function(t,n,r){"use strict";var e=r(60),i=r(22),o=r(38),u={};r(13)(u,r(15)("iterator"),function(){return this}),t.exports=function(t,n,r){t.prototype=e(u,{next:i(1,r)}),o(t,n+" Iterator")}},function(t,n){t.exports=function(t,n){return{value:n,done:!!t}}},function(t,n,r){var e=r(19),i=r(9);t.exports=function(t,n){for(var r,o=i(t),u=e(o),c=u.length,f=0;c>f;)if(o[r=u[f++]]===n)return r}},function(t,n,r){var e=r(23)("meta"),i=r(21),o=r(8),u=r(14).f,c=0,f=Object.isExtensible||function(){return!0},a=!r(18)(function(){return f(Object.preventExtensions({}))}),s=function(t){u(t,e,{value:{i:"O"+ ++c,w:{}}})},l=function(t,n){if(!i(t))return"symbol"==typeof t?t:("string"==typeof t?"S":"P")+t;if(!o(t,e)){if(!f(t))return"F";if(!n)return"E";s(t)}return t[e].i},h=function(t,n){if(!o(t,e)){if(!f(t))return!0;if(!n)return!1;s(t)}return t[e].w},v=function(t){return a&&p.NEED&&f(t)&&!o(t,e)&&s(t),t},p=t.exports={KEY:e,NEED:!1,fastKey:l,getWeak:h,onFreeze:v}},function(t,n,r){var e=r(14),i=r(20),o=r(19);t.exports=r(12)?Object.defineProperties:function(t,n){i(t);for(var r,u=o(n),c=u.length,f=0;c>f;)e.f(t,r=u[f++],n[r]);return t}},function(t,n,r){var e=r(37),i=r(22),o=r(9),u=r(42),c=r(8),f=r(58),a=Object.getOwnPropertyDescriptor;n.f=r(12)?a:function(t,n){if(t=o(t),n=u(n,!0),f)try{return a(t,n)}catch(t){}if(c(t,n))return i(!e.f.call(t,n),t[n])}},function(t,n,r){var e=r(9),i=r(61).f,o={}.toString,u="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],c=function(t){try{return i(t)}catch(t){return u.slice()}};t.exports.f=function(t){return u&&"[object Window]"==o.call(t)?c(t):i(e(t))}},function(t,n,r){var e=r(8),i=r(77),o=r(39)("IE_PROTO"),u=Object.prototype;t.exports=Object.getPrototypeOf||function(t){return t=i(t),e(t,o)?t[o]:"function"==typeof t.constructor&&t instanceof t.constructor?t.constructor.prototype:t instanceof Object?u:null}},function(t,n,r){var e=r(41),i=r(33);t.exports=function(t){return function(n,r){var o,u,c=String(i(n)),f=e(r),a=c.length;return f<0||f>=a?t?"":void 0:(o=c.charCodeAt(f),o<55296||o>56319||f+1===a||(u=c.charCodeAt(f+1))<56320||u>57343?t?c.charAt(f):o:t?c.slice(f,f+2):u-56320+(o-55296<<10)+65536)}}},function(t,n,r){var e=r(41),i=Math.max,o=Math.min;t.exports=function(t,n){return t=e(t),t<0?i(t+n,0):o(t,n)}},function(t,n,r){var e=r(41),i=Math.min;t.exports=function(t){return t>0?i(e(t),9007199254740991):0}},function(t,n,r){"use strict";var e=r(89),i=r(97),o=r(35),u=r(9);t.exports=r(59)(Array,"Array",function(t,n){this._t=u(t),this._i=0,this._k=n},function(){var t=this._t,n=this._k,r=this._i++;return!t||r>=t.length?(this._t=void 0,i(1)):"keys"==n?i(0,r):"values"==n?i(0,t[r]):i(0,[r,t[r]])},"values"),o.Arguments=o.Array,e("keys"),e("values"),e("entries")},function(t,n){},function(t,n,r){"use strict";var e=r(104)(!0);r(59)(String,"String",function(t){this._t=String(t),this._i=0},function(){var t,n=this._t,r=this._i;return r>=n.length?{value:void 0,done:!0}:(t=e(n,r),this._i+=t.length,{value:t,done:!1})})},function(t,n,r){"use strict";var e=r(5),i=r(8),o=r(12),u=r(51),c=r(64),f=r(99).KEY,a=r(18),s=r(40),l=r(38),h=r(23),v=r(15),p=r(44),d=r(43),y=r(98),g=r(92),b=r(95),m=r(20),x=r(9),w=r(42),S=r(22),_=r(60),O=r(102),E=r(101),P=r(14),j=r(19),F=E.f,M=P.f,A=O.f,N=e.Symbol,T=e.JSON,I=T&&T.stringify,k="prototype",L=v("_hidden"),R=v("toPrimitive"),C={}.propertyIsEnumerable,D=s("symbol-registry"),U=s("symbols"),W=s("op-symbols"),G=Object[k],B="function"==typeof N,V=e.QObject,z=!V||!V[k]||!V[k].findChild,q=o&&a(function(){return 7!=_(M({},"a",{get:function(){return M(this,"a",{value:7}).a}})).a})?function(t,n,r){var e=F(G,n);e&&delete G[n],M(t,n,r),e&&t!==G&&M(G,n,e)}:M,K=function(t){var n=U[t]=_(N[k]);return n._k=t,n},J=B&&"symbol"==typeof N.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof N},Y=function(t,n,r){return t===G&&Y(W,n,r),m(t),n=w(n,!0),m(r),i(U,n)?(r.enumerable?(i(t,L)&&t[L][n]&&(t[L][n]=!1),r=_(r,{enumerable:S(0,!1)})):(i(t,L)||M(t,L,S(1,{})),t[L][n]=!0),q(t,n,r)):M(t,n,r)},H=function(t,n){m(t);for(var r,e=g(n=x(n)),i=0,o=e.length;o>i;)Y(t,r=e[i++],n[r]);return t},$=function(t,n){return void 0===n?_(t):H(_(t),n)},X=function(t){var n=C.call(this,t=w(t,!0));return!(this===G&&i(U,t)&&!i(W,t))&&(!(n||!i(this,t)||!i(U,t)||i(this,L)&&this[L][t])||n)},Q=function(t,n){if(t=x(t),n=w(n,!0),t!==G||!i(U,n)||i(W,n)){var r=F(t,n);return!r||!i(U,n)||i(t,L)&&t[L][n]||(r.enumerable=!0),r}},Z=function(t){for(var n,r=A(x(t)),e=[],o=0;r.length>o;)i(U,n=r[o++])||n==L||n==f||e.push(n);return e},tt=function(t){for(var n,r=t===G,e=A(r?W:x(t)),o=[],u=0;e.length>u;)!i(U,n=e[u++])||r&&!i(G,n)||o.push(U[n]);return o};B||(N=function(){if(this instanceof N)throw TypeError("Symbol is not a constructor!");var t=h(arguments.length>0?arguments[0]:void 0),n=function(r){this===G&&n.call(W,r),i(this,L)&&i(this[L],t)&&(this[L][t]=!1),q(this,t,S(1,r))};return o&&z&&q(G,t,{configurable:!0,set:n}),K(t)},c(N[k],"toString",function(){return this._k}),E.f=Q,P.f=Y,r(61).f=O.f=Z,r(37).f=X,r(62).f=tt,o&&!r(36)&&c(G,"propertyIsEnumerable",X,!0),p.f=function(t){return K(v(t))}),u(u.G+u.W+u.F*!B,{Symbol:N});for(var nt="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),rt=0;nt.length>rt;)v(nt[rt++]);for(var nt=j(v.store),rt=0;nt.length>rt;)d(nt[rt++]);u(u.S+u.F*!B,"Symbol",{for:function(t){return i(D,t+="")?D[t]:D[t]=N(t)},keyFor:function(t){if(J(t))return y(D,t);throw TypeError(t+" is not a symbol!")},useSetter:function(){z=!0},useSimple:function(){z=!1}}),u(u.S+u.F*!B,"Object",{create:$,defineProperty:Y,defineProperties:H,getOwnPropertyDescriptor:Q,getOwnPropertyNames:Z,getOwnPropertySymbols:tt}),T&&u(u.S+u.F*(!B||a(function(){var t=N();return"[null]"!=I([t])||"{}"!=I({a:t})||"{}"!=I(Object(t))})),"JSON",{stringify:function(t){if(void 0!==t&&!J(t)){for(var n,r,e=[t],i=1;arguments.length>i;)e.push(arguments[i++]);return n=e[1],"function"==typeof n&&(r=n),!r&&b(n)||(n=function(t,n){if(r&&(n=r.call(this,t,n)),!J(n))return n}),e[1]=n,I.apply(T,e)}}}),N[k][R]||r(13)(N[k],R,N[k].valueOf),l(N,"Symbol"),l(Math,"Math",!0),l(e.JSON,"JSON",!0)},function(t,n,r){r(43)("asyncIterator")},function(t,n,r){r(43)("observable")},function(t,n,r){r(107);for(var e=r(5),i=r(13),o=r(35),u=r(15)("toStringTag"),c=["NodeList","DOMTokenList","MediaList","StyleSheetList","CSSRuleList"],f=0;f<5;f++){var a=c[f],s=e[a],l=s&&s.prototype;l&&!l[u]&&i(l,u,a),o[a]=o.Array}},function(t,n,r){var e=r(45),i=r(7)("toStringTag"),o="Arguments"==e(function(){return arguments}()),u=function(t,n){try{return t[n]}catch(t){}};t.exports=function(t){var n,r,c;return void 0===t?"Undefined":null===t?"Null":"string"==typeof(r=u(n=Object(t),i))?r:o?e(n):"Object"==(c=e(n))&&"function"==typeof n.callee?"Arguments":c}},function(t,n,r){var e=r(45);t.exports=Object("z").propertyIsEnumerable(0)?Object:function(t){return"String"==e(t)?t.split(""):Object(t)}},function(t,n){n.f={}.propertyIsEnumerable},function(t,n,r){var e=r(30),i=r(16),o=r(75);t.exports=function(t){return function(n,r,u){var c,f=e(n),a=i(f.length),s=o(u,a);if(t&&r!=r){for(;a>s;)if((c=f[s++])!=c)return!0}else for(;a>s;s++)if((t||s in f)&&f[s]===r)return t||s||0;return!t&&-1}}},function(t,n,r){"use strict";var e=r(3),i=r(1),o=r(28),u=r(73),c=r(65),f=r(79),a=r(68),s=r(6),l=r(4),h=r(123),v=r(81),p=r(136);t.exports=function(t,n,r,d,y,g){var b=e[t],m=b,x=y?"set":"add",w=m&&m.prototype,S={},_=function(t){var n=w[t];o(w,t,"delete"==t?function(t){return!(g&&!s(t))&&n.call(this,0===t?0:t)}:"has"==t?function(t){return!(g&&!s(t))&&n.call(this,0===t?0:t)}:"get"==t?function(t){return g&&!s(t)?void 0:n.call(this,0===t?0:t)}:"add"==t?function(t){return n.call(this,0===t?0:t),this}:function(t,r){return n.call(this,0===t?0:t,r),this})};if("function"==typeof m&&(g||w.forEach&&!l(function(){(new m).entries().next()}))){var O=new m,E=O[x](g?{}:-0,1)!=O,P=l(function(){O.has(1)}),j=h(function(t){new m(t)}),F=!g&&l(function(){for(var t=new m,n=5;n--;)t[x](n,n);return!t.has(-0)});j||(m=n(function(n,r){a(n,m,t);var e=p(new b,n,m);return void 0!=r&&f(r,y,e[x],e),e}),m.prototype=w,w.constructor=m),(P||F)&&(_("delete"),_("has"),y&&_("get")),(F||E)&&_(x),g&&w.clear&&delete w.clear}else m=d.getConstructor(n,t,y,x),u(m.prototype,r),c.NEED=!0;return v(m,t),S[t]=m,i(i.G+i.W+i.F*(m!=b),S),g||d.setStrong(m,t,y),m}},function(t,n,r){"use strict";var e=r(27),i=r(28),o=r(4),u=r(46),c=r(7);t.exports=function(t,n,r){var f=c(t),a=r(u,f,""[t]),s=a[0],l=a[1];o(function(){var n={};return n[f]=function(){return 7},7!=""[t](n)})&&(i(String.prototype,t,s),e(RegExp.prototype,f,2==n?function(t,n){return l.call(t,this,n)}:function(t){return l.call(t,this)}))}
},function(t,n,r){"use strict";var e=r(2);t.exports=function(){var t=e(this),n="";return t.global&&(n+="g"),t.ignoreCase&&(n+="i"),t.multiline&&(n+="m"),t.unicode&&(n+="u"),t.sticky&&(n+="y"),n}},function(t,n){t.exports=function(t,n,r){var e=void 0===r;switch(n.length){case 0:return e?t():t.call(r);case 1:return e?t(n[0]):t.call(r,n[0]);case 2:return e?t(n[0],n[1]):t.call(r,n[0],n[1]);case 3:return e?t(n[0],n[1],n[2]):t.call(r,n[0],n[1],n[2]);case 4:return e?t(n[0],n[1],n[2],n[3]):t.call(r,n[0],n[1],n[2],n[3])}return t.apply(r,n)}},function(t,n,r){var e=r(6),i=r(45),o=r(7)("match");t.exports=function(t){var n;return e(t)&&(void 0!==(n=t[o])?!!n:"RegExp"==i(t))}},function(t,n,r){var e=r(7)("iterator"),i=!1;try{var o=[7][e]();o.return=function(){i=!0},Array.from(o,function(){throw 2})}catch(t){}t.exports=function(t,n){if(!n&&!i)return!1;var r=!1;try{var o=[7],u=o[e]();u.next=function(){return{done:r=!0}},o[e]=function(){return u},t(o)}catch(t){}return r}},function(t,n,r){t.exports=r(69)||!r(4)(function(){var t=Math.random();__defineSetter__.call(null,t,function(){}),delete r(3)[t]})},function(t,n){n.f=Object.getOwnPropertySymbols},function(t,n,r){var e=r(3),i="__core-js_shared__",o=e[i]||(e[i]={});t.exports=function(t){return o[t]||(o[t]={})}},function(t,n,r){for(var e,i=r(3),o=r(27),u=r(76),c=u("typed_array"),f=u("view"),a=!(!i.ArrayBuffer||!i.DataView),s=a,l=0,h="Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array".split(",");l<9;)(e=i[h[l++]])?(o(e.prototype,c,!0),o(e.prototype,f,!0)):s=!1;t.exports={ABV:a,CONSTR:s,TYPED:c,VIEW:f}},function(t,n){"use strict";var r={versions:function(){var t=window.navigator.userAgent;return{trident:t.indexOf("Trident")>-1,presto:t.indexOf("Presto")>-1,webKit:t.indexOf("AppleWebKit")>-1,gecko:t.indexOf("Gecko")>-1&&-1==t.indexOf("KHTML"),mobile:!!t.match(/AppleWebKit.*Mobile.*/),ios:!!t.match(/\(i[^;]+;( U;)? CPU.+Mac OS X/),android:t.indexOf("Android")>-1||t.indexOf("Linux")>-1,iPhone:t.indexOf("iPhone")>-1||t.indexOf("Mac")>-1,iPad:t.indexOf("iPad")>-1,webApp:-1==t.indexOf("Safari"),weixin:-1==t.indexOf("MicroMessenger")}}()};t.exports=r},function(t,n,r){"use strict";var e=r(85),i=function(t){return t&&t.__esModule?t:{default:t}}(e),o=function(){function t(t,n,e){return n||e?String.fromCharCode(n||e):r[t]||t}function n(t){return e[t]}var r={""":'"',"<":"<",">":">","&":"&"," ":" "},e={};for(var u in r)e[r[u]]=u;return r["'"]="'",e["'"]="'",{encode:function(t){return t?(""+t).replace(/['<> "&]/g,n).replace(/\r?\n/g,"<br/>").replace(/\s/g," "):""},decode:function(n){return n?(""+n).replace(/<br\s*\/?>/gi,"\n").replace(/"|<|>|&| |'|&#(\d+);|&#(\d+)/g,t).replace(/\u00a0/g," "):""},encodeBase16:function(t){if(!t)return t;t+="";for(var n=[],r=0,e=t.length;e>r;r++)n.push(t.charCodeAt(r).toString(16).toUpperCase());return n.join("")},encodeBase16forJSON:function(t){if(!t)return t;t=t.replace(/[\u4E00-\u9FBF]/gi,function(t){return escape(t).replace("%u","\\u")});for(var n=[],r=0,e=t.length;e>r;r++)n.push(t.charCodeAt(r).toString(16).toUpperCase());return n.join("")},decodeBase16:function(t){if(!t)return t;t+="";for(var n=[],r=0,e=t.length;e>r;r+=2)n.push(String.fromCharCode("0x"+t.slice(r,r+2)));return n.join("")},encodeObject:function(t){if(t instanceof Array)for(var n=0,r=t.length;r>n;n++)t[n]=o.encodeObject(t[n]);else if("object"==(void 0===t?"undefined":(0,i.default)(t)))for(var e in t)t[e]=o.encodeObject(t[e]);else if("string"==typeof t)return o.encode(t);return t},loadScript:function(t){var n=document.createElement("script");document.getElementsByTagName("body")[0].appendChild(n),n.setAttribute("src",t)},addLoadEvent:function(t){var n=window.onload;"function"!=typeof window.onload?window.onload=t:window.onload=function(){n(),t()}}}}();t.exports=o},function(t,n,r){"use strict";var e=r(17),i=r(75),o=r(16);t.exports=function(t){for(var n=e(this),r=o(n.length),u=arguments.length,c=i(u>1?arguments[1]:void 0,r),f=u>2?arguments[2]:void 0,a=void 0===f?r:i(f,r);a>c;)n[c++]=t;return n}},function(t,n,r){"use strict";var e=r(11),i=r(66);t.exports=function(t,n,r){n in t?e.f(t,n,i(0,r)):t[n]=r}},function(t,n,r){var e=r(6),i=r(3).document,o=e(i)&&e(i.createElement);t.exports=function(t){return o?i.createElement(t):{}}},function(t,n){t.exports="constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf".split(",")},function(t,n,r){var e=r(7)("match");t.exports=function(t){var n=/./;try{"/./"[t](n)}catch(r){try{return n[e]=!1,!"/./"[t](n)}catch(t){}}return!0}},function(t,n,r){t.exports=r(3).document&&document.documentElement},function(t,n,r){var e=r(6),i=r(144).set;t.exports=function(t,n,r){var o,u=n.constructor;return u!==r&&"function"==typeof u&&(o=u.prototype)!==r.prototype&&e(o)&&i&&i(t,o),t}},function(t,n,r){var e=r(80),i=r(7)("iterator"),o=Array.prototype;t.exports=function(t){return void 0!==t&&(e.Array===t||o[i]===t)}},function(t,n,r){var e=r(45);t.exports=Array.isArray||function(t){return"Array"==e(t)}},function(t,n,r){"use strict";var e=r(70),i=r(66),o=r(81),u={};r(27)(u,r(7)("iterator"),function(){return this}),t.exports=function(t,n,r){t.prototype=e(u,{next:i(1,r)}),o(t,n+" Iterator")}},function(t,n,r){"use strict";var e=r(69),i=r(1),o=r(28),u=r(27),c=r(24),f=r(80),a=r(139),s=r(81),l=r(32),h=r(7)("iterator"),v=!([].keys&&"next"in[].keys()),p="keys",d="values",y=function(){return this};t.exports=function(t,n,r,g,b,m,x){a(r,n,g);var w,S,_,O=function(t){if(!v&&t in F)return F[t];switch(t){case p:case d:return function(){return new r(this,t)}}return function(){return new r(this,t)}},E=n+" Iterator",P=b==d,j=!1,F=t.prototype,M=F[h]||F["@@iterator"]||b&&F[b],A=M||O(b),N=b?P?O("entries"):A:void 0,T="Array"==n?F.entries||M:M;if(T&&(_=l(T.call(new t)))!==Object.prototype&&(s(_,E,!0),e||c(_,h)||u(_,h,y)),P&&M&&M.name!==d&&(j=!0,A=function(){return M.call(this)}),e&&!x||!v&&!j&&F[h]||u(F,h,A),f[n]=A,f[E]=y,b)if(w={values:P?A:O(d),keys:m?A:O(p),entries:N},x)for(S in w)S in F||o(F,S,w[S]);else i(i.P+i.F*(v||j),n,w);return w}},function(t,n){var r=Math.expm1;t.exports=!r||r(10)>22025.465794806718||r(10)<22025.465794806718||-2e-17!=r(-2e-17)?function(t){return 0==(t=+t)?t:t>-1e-6&&t<1e-6?t+t*t/2:Math.exp(t)-1}:r},function(t,n){t.exports=Math.sign||function(t){return 0==(t=+t)||t!=t?t:t<0?-1:1}},function(t,n,r){var e=r(3),i=r(151).set,o=e.MutationObserver||e.WebKitMutationObserver,u=e.process,c=e.Promise,f="process"==r(45)(u);t.exports=function(){var t,n,r,a=function(){var e,i;for(f&&(e=u.domain)&&e.exit();t;){i=t.fn,t=t.next;try{i()}catch(e){throw t?r():n=void 0,e}}n=void 0,e&&e.enter()};if(f)r=function(){u.nextTick(a)};else if(o){var s=!0,l=document.createTextNode("");new o(a).observe(l,{characterData:!0}),r=function(){l.data=s=!s}}else if(c&&c.resolve){var h=c.resolve();r=function(){h.then(a)}}else r=function(){i.call(e,a)};return function(e){var i={fn:e,next:void 0};n&&(n.next=i),t||(t=i,r()),n=i}}},function(t,n,r){var e=r(6),i=r(2),o=function(t,n){if(i(t),!e(n)&&null!==n)throw TypeError(n+": can't set as prototype!")};t.exports={set:Object.setPrototypeOf||("__proto__"in{}?function(t,n,e){try{e=r(53)(Function.call,r(31).f(Object.prototype,"__proto__").set,2),e(t,[]),n=!(t instanceof Array)}catch(t){n=!0}return function(t,r){return o(t,r),n?t.__proto__=r:e(t,r),t}}({},!1):void 0),check:o}},function(t,n,r){var e=r(126)("keys"),i=r(76);t.exports=function(t){return e[t]||(e[t]=i(t))}},function(t,n,r){var e=r(2),i=r(26),o=r(7)("species");t.exports=function(t,n){var r,u=e(t).constructor;return void 0===u||void 0==(r=e(u)[o])?n:i(r)}},function(t,n,r){var e=r(67),i=r(46);t.exports=function(t){return function(n,r){var o,u,c=String(i(n)),f=e(r),a=c.length;return f<0||f>=a?t?"":void 0:(o=c.charCodeAt(f),o<55296||o>56319||f+1===a||(u=c.charCodeAt(f+1))<56320||u>57343?t?c.charAt(f):o:t?c.slice(f,f+2):u-56320+(o-55296<<10)+65536)}}},function(t,n,r){var e=r(122),i=r(46);t.exports=function(t,n,r){if(e(n))throw TypeError("String#"+r+" doesn't accept regex!");return String(i(t))}},function(t,n,r){"use strict";var e=r(67),i=r(46);t.exports=function(t){var n=String(i(this)),r="",o=e(t);if(o<0||o==1/0)throw RangeError("Count can't be negative");for(;o>0;(o>>>=1)&&(n+=n))1&o&&(r+=n);return r}},function(t,n){t.exports="\t\n\v\f\r \u2028\u2029\ufeff"},function(t,n,r){var e,i,o,u=r(53),c=r(121),f=r(135),a=r(132),s=r(3),l=s.process,h=s.setImmediate,v=s.clearImmediate,p=s.MessageChannel,d=0,y={},g="onreadystatechange",b=function(){var t=+this;if(y.hasOwnProperty(t)){var n=y[t];delete y[t],n()}},m=function(t){b.call(t.data)};h&&v||(h=function(t){for(var n=[],r=1;arguments.length>r;)n.push(arguments[r++]);return y[++d]=function(){c("function"==typeof t?t:Function(t),n)},e(d),d},v=function(t){delete y[t]},"process"==r(45)(l)?e=function(t){l.nextTick(u(b,t,1))}:p?(i=new p,o=i.port2,i.port1.onmessage=m,e=u(o.postMessage,o,1)):s.addEventListener&&"function"==typeof postMessage&&!s.importScripts?(e=function(t){s.postMessage(t+"","*")},s.addEventListener("message",m,!1)):e=g in a("script")?function(t){f.appendChild(a("script"))[g]=function(){f.removeChild(this),b.call(t)}}:function(t){setTimeout(u(b,t,1),0)}),t.exports={set:h,clear:v}},function(t,n,r){"use strict";var e=r(3),i=r(10),o=r(69),u=r(127),c=r(27),f=r(73),a=r(4),s=r(68),l=r(67),h=r(16),v=r(71).f,p=r(11).f,d=r(130),y=r(81),g="ArrayBuffer",b="DataView",m="prototype",x="Wrong length!",w="Wrong index!",S=e[g],_=e[b],O=e.Math,E=e.RangeError,P=e.Infinity,j=S,F=O.abs,M=O.pow,A=O.floor,N=O.log,T=O.LN2,I="buffer",k="byteLength",L="byteOffset",R=i?"_b":I,C=i?"_l":k,D=i?"_o":L,U=function(t,n,r){var e,i,o,u=Array(r),c=8*r-n-1,f=(1<<c)-1,a=f>>1,s=23===n?M(2,-24)-M(2,-77):0,l=0,h=t<0||0===t&&1/t<0?1:0;for(t=F(t),t!=t||t===P?(i=t!=t?1:0,e=f):(e=A(N(t)/T),t*(o=M(2,-e))<1&&(e--,o*=2),t+=e+a>=1?s/o:s*M(2,1-a),t*o>=2&&(e++,o/=2),e+a>=f?(i=0,e=f):e+a>=1?(i=(t*o-1)*M(2,n),e+=a):(i=t*M(2,a-1)*M(2,n),e=0));n>=8;u[l++]=255&i,i/=256,n-=8);for(e=e<<n|i,c+=n;c>0;u[l++]=255&e,e/=256,c-=8);return u[--l]|=128*h,u},W=function(t,n,r){var e,i=8*r-n-1,o=(1<<i)-1,u=o>>1,c=i-7,f=r-1,a=t[f--],s=127&a;for(a>>=7;c>0;s=256*s+t[f],f--,c-=8);for(e=s&(1<<-c)-1,s>>=-c,c+=n;c>0;e=256*e+t[f],f--,c-=8);if(0===s)s=1-u;else{if(s===o)return e?NaN:a?-P:P;e+=M(2,n),s-=u}return(a?-1:1)*e*M(2,s-n)},G=function(t){return t[3]<<24|t[2]<<16|t[1]<<8|t[0]},B=function(t){return[255&t]},V=function(t){return[255&t,t>>8&255]},z=function(t){return[255&t,t>>8&255,t>>16&255,t>>24&255]},q=function(t){return U(t,52,8)},K=function(t){return U(t,23,4)},J=function(t,n,r){p(t[m],n,{get:function(){return this[r]}})},Y=function(t,n,r,e){var i=+r,o=l(i);if(i!=o||o<0||o+n>t[C])throw E(w);var u=t[R]._b,c=o+t[D],f=u.slice(c,c+n);return e?f:f.reverse()},H=function(t,n,r,e,i,o){var u=+r,c=l(u);if(u!=c||c<0||c+n>t[C])throw E(w);for(var f=t[R]._b,a=c+t[D],s=e(+i),h=0;h<n;h++)f[a+h]=s[o?h:n-h-1]},$=function(t,n){s(t,S,g);var r=+n,e=h(r);if(r!=e)throw E(x);return e};if(u.ABV){if(!a(function(){new S})||!a(function(){new S(.5)})){S=function(t){return new j($(this,t))};for(var X,Q=S[m]=j[m],Z=v(j),tt=0;Z.length>tt;)(X=Z[tt++])in S||c(S,X,j[X]);o||(Q.constructor=S)}var nt=new _(new S(2)),rt=_[m].setInt8;nt.setInt8(0,2147483648),nt.setInt8(1,2147483649),!nt.getInt8(0)&&nt.getInt8(1)||f(_[m],{setInt8:function(t,n){rt.call(this,t,n<<24>>24)},setUint8:function(t,n){rt.call(this,t,n<<24>>24)}},!0)}else S=function(t){var n=$(this,t);this._b=d.call(Array(n),0),this[C]=n},_=function(t,n,r){s(this,_,b),s(t,S,b);var e=t[C],i=l(n);if(i<0||i>e)throw E("Wrong offset!");if(r=void 0===r?e-i:h(r),i+r>e)throw E(x);this[R]=t,this[D]=i,this[C]=r},i&&(J(S,k,"_l"),J(_,I,"_b"),J(_,k,"_l"),J(_,L,"_o")),f(_[m],{getInt8:function(t){return Y(this,1,t)[0]<<24>>24},getUint8:function(t){return Y(this,1,t)[0]},getInt16:function(t){var n=Y(this,2,t,arguments[1]);return(n[1]<<8|n[0])<<16>>16},getUint16:function(t){var n=Y(this,2,t,arguments[1]);return n[1]<<8|n[0]},getInt32:function(t){return G(Y(this,4,t,arguments[1]))},getUint32:function(t){return G(Y(this,4,t,arguments[1]))>>>0},getFloat32:function(t){return W(Y(this,4,t,arguments[1]),23,4)},getFloat64:function(t){return W(Y(this,8,t,arguments[1]),52,8)},setInt8:function(t,n){H(this,1,t,B,n)},setUint8:function(t,n){H(this,1,t,B,n)},setInt16:function(t,n){H(this,2,t,V,n,arguments[2])},setUint16:function(t,n){H(this,2,t,V,n,arguments[2])},setInt32:function(t,n){H(this,4,t,z,n,arguments[2])},setUint32:function(t,n){H(this,4,t,z,n,arguments[2])},setFloat32:function(t,n){H(this,4,t,K,n,arguments[2])},setFloat64:function(t,n){H(this,8,t,q,n,arguments[2])}});y(S,g),y(_,b),c(_[m],u.VIEW,!0),n[g]=S,n[b]=_},function(t,n,r){var e=r(3),i=r(52),o=r(69),u=r(182),c=r(11).f;t.exports=function(t){var n=i.Symbol||(i.Symbol=o?{}:e.Symbol||{});"_"==t.charAt(0)||t in n||c(n,t,{value:u.f(t)})}},function(t,n,r){var e=r(114),i=r(7)("iterator"),o=r(80);t.exports=r(52).getIteratorMethod=function(t){if(void 0!=t)return t[i]||t["@@iterator"]||o[e(t)]}},function(t,n,r){"use strict";var e=r(78),i=r(170),o=r(80),u=r(30);t.exports=r(140)(Array,"Array",function(t,n){this._t=u(t),this._i=0,this._k=n},function(){var t=this._t,n=this._k,r=this._i++;return!t||r>=t.length?(this._t=void 0,i(1)):"keys"==n?i(0,r):"values"==n?i(0,t[r]):i(0,[r,t[r]])},"values"),o.Arguments=o.Array,e("keys"),e("values"),e("entries")},function(t,n){function r(t,n){t.classList?t.classList.add(n):t.className+=" "+n}t.exports=r},function(t,n){function r(t,n){if(t.classList)t.classList.remove(n);else{var r=new RegExp("(^|\\b)"+n.split(" ").join("|")+"(\\b|$)","gi");t.className=t.className.replace(r," ")}}t.exports=r},function(t,n){function r(){throw new Error("setTimeout has not been defined")}function e(){throw new Error("clearTimeout has not been defined")}function i(t){if(s===setTimeout)return setTimeout(t,0);if((s===r||!s)&&setTimeout)return s=setTimeout,setTimeout(t,0);try{return s(t,0)}catch(n){try{return s.call(null,t,0)}catch(n){return s.call(this,t,0)}}}function o(t){if(l===clearTimeout)return clearTimeout(t);if((l===e||!l)&&clearTimeout)return l=clearTimeout,clearTimeout(t);try{return l(t)}catch(n){try{return l.call(null,t)}catch(n){return l.call(this,t)}}}function u(){d&&v&&(d=!1,v.length?p=v.concat(p):y=-1,p.length&&c())}function c(){if(!d){var t=i(u);d=!0;for(var n=p.length;n;){for(v=p,p=[];++y<n;)v&&v[y].run();y=-1,n=p.length}v=null,d=!1,o(t)}}function f(t,n){this.fun=t,this.array=n}function a(){}var s,l,h=t.exports={};!function(){try{s="function"==typeof setTimeout?setTimeout:r}catch(t){s=r}try{l="function"==typeof clearTimeout?clearTimeout:e}catch(t){l=e}}();var v,p=[],d=!1,y=-1;h.nextTick=function(t){var n=new Array(arguments.length-1);if(arguments.length>1)for(var r=1;r<arguments.length;r++)n[r-1]=arguments[r];p.push(new f(t,n)),1!==p.length||d||i(c)},f.prototype.run=function(){this.fun.apply(null,this.array)},h.title="browser",h.browser=!0,h.env={},h.argv=[],h.version="",h.versions={},h.on=a,h.addListener=a,h.once=a,h.off=a,h.removeListener=a,h.removeAllListeners=a,h.emit=a,h.prependListener=a,h.prependOnceListener=a,h.listeners=function(t){return[]},h.binding=function(t){throw new Error("process.binding is not supported")},h.cwd=function(){return"/"},h.chdir=function(t){throw new Error("process.chdir is not supported")},h.umask=function(){return 0}},function(t,n,r){var e=r(45);t.exports=function(t,n){if("number"!=typeof t&&"Number"!=e(t))throw TypeError(n);return+t}},function(t,n,r){"use strict";var e=r(17),i=r(75),o=r(16);t.exports=[].copyWithin||function(t,n){var r=e(this),u=o(r.length),c=i(t,u),f=i(n,u),a=arguments.length>2?arguments[2]:void 0,s=Math.min((void 0===a?u:i(a,u))-f,u-c),l=1;for(f<c&&c<f+s&&(l=-1,f+=s-1,c+=s-1);s-- >0;)f in r?r[c]=r[f]:delete r[c],c+=l,f+=l;return r}},function(t,n,r){var e=r(79);t.exports=function(t,n){var r=[];return e(t,!1,r.push,r,n),r}},function(t,n,r){var e=r(26),i=r(17),o=r(115),u=r(16);t.exports=function(t,n,r,c,f){e(n);var a=i(t),s=o(a),l=u(a.length),h=f?l-1:0,v=f?-1:1;if(r<2)for(;;){if(h in s){c=s[h],h+=v;break}if(h+=v,f?h<0:l<=h)throw TypeError("Reduce of empty array with no initial value")}for(;f?h>=0:l>h;h+=v)h in s&&(c=n(c,s[h],h,a));return c}},function(t,n,r){"use strict";var e=r(26),i=r(6),o=r(121),u=[].slice,c={},f=function(t,n,r){if(!(n in c)){for(var e=[],i=0;i<n;i++)e[i]="a["+i+"]";c[n]=Function("F,a","return new F("+e.join(",")+")")}return c[n](t,r)};t.exports=Function.bind||function(t){var n=e(this),r=u.call(arguments,1),c=function(){var e=r.concat(u.call(arguments));return this instanceof c?f(n,e.length,e):o(n,e,t)};return i(n.prototype)&&(c.prototype=n.prototype),c}},function(t,n,r){"use strict";var e=r(11).f,i=r(70),o=r(73),u=r(53),c=r(68),f=r(46),a=r(79),s=r(140),l=r(170),h=r(74),v=r(10),p=r(65).fastKey,d=v?"_s":"size",y=function(t,n){var r,e=p(n);if("F"!==e)return t._i[e];for(r=t._f;r;r=r.n)if(r.k==n)return r};t.exports={getConstructor:function(t,n,r,s){var l=t(function(t,e){c(t,l,n,"_i"),t._i=i(null),t._f=void 0,t._l=void 0,t[d]=0,void 0!=e&&a(e,r,t[s],t)});return o(l.prototype,{clear:function(){for(var t=this,n=t._i,r=t._f;r;r=r.n)r.r=!0,r.p&&(r.p=r.p.n=void 0),delete n[r.i];t._f=t._l=void 0,t[d]=0},delete:function(t){var n=this,r=y(n,t);if(r){var e=r.n,i=r.p;delete n._i[r.i],r.r=!0,i&&(i.n=e),e&&(e.p=i),n._f==r&&(n._f=e),n._l==r&&(n._l=i),n[d]--}return!!r},forEach:function(t){c(this,l,"forEach");for(var n,r=u(t,arguments.length>1?arguments[1]:void 0,3);n=n?n.n:this._f;)for(r(n.v,n.k,this);n&&n.r;)n=n.p},has:function(t){return!!y(this,t)}}),v&&e(l.prototype,"size",{get:function(){return f(this[d])}}),l},def:function(t,n,r){var e,i,o=y(t,n);return o?o.v=r:(t._l=o={i:i=p(n,!0),k:n,v:r,p:e=t._l,n:void 0,r:!1},t._f||(t._f=o),e&&(e.n=o),t[d]++,"F"!==i&&(t._i[i]=o)),t},getEntry:y,setStrong:function(t,n,r){s(t,n,function(t,n){this._t=t,this._k=n,this._l=void 0},function(){for(var t=this,n=t._k,r=t._l;r&&r.r;)r=r.p;return t._t&&(t._l=r=r?r.n:t._t._f)?"keys"==n?l(0,r.k):"values"==n?l(0,r.v):l(0,[r.k,r.v]):(t._t=void 0,l(1))},r?"entries":"values",!r,!0),h(n)}}},function(t,n,r){var e=r(114),i=r(161);t.exports=function(t){return function(){if(e(this)!=t)throw TypeError(t+"#toJSON isn't generic");return i(this)}}},function(t,n,r){"use strict";var e=r(73),i=r(65).getWeak,o=r(2),u=r(6),c=r(68),f=r(79),a=r(48),s=r(24),l=a(5),h=a(6),v=0,p=function(t){return t._l||(t._l=new d)},d=function(){this.a=[]},y=function(t,n){return l(t.a,function(t){return t[0]===n})};d.prototype={get:function(t){var n=y(this,t);if(n)return n[1]},has:function(t){return!!y(this,t)},set:function(t,n){var r=y(this,t);r?r[1]=n:this.a.push([t,n])},delete:function(t){var n=h(this.a,function(n){return n[0]===t});return~n&&this.a.splice(n,1),!!~n}},t.exports={getConstructor:function(t,n,r,o){var a=t(function(t,e){c(t,a,n,"_i"),t._i=v++,t._l=void 0,void 0!=e&&f(e,r,t[o],t)});return e(a.prototype,{delete:function(t){if(!u(t))return!1;var n=i(t);return!0===n?p(this).delete(t):n&&s(n,this._i)&&delete n[this._i]},has:function(t){if(!u(t))return!1;var n=i(t);return!0===n?p(this).has(t):n&&s(n,this._i)}}),a},def:function(t,n,r){var e=i(o(n),!0);return!0===e?p(t).set(n,r):e[t._i]=r,t},ufstore:p}},function(t,n,r){t.exports=!r(10)&&!r(4)(function(){return 7!=Object.defineProperty(r(132)("div"),"a",{get:function(){return 7}}).a})},function(t,n,r){var e=r(6),i=Math.floor;t.exports=function(t){return!e(t)&&isFinite(t)&&i(t)===t}},function(t,n,r){var e=r(2);t.exports=function(t,n,r,i){try{return i?n(e(r)[0],r[1]):n(r)}catch(n){var o=t.return;throw void 0!==o&&e(o.call(t)),n}}},function(t,n){t.exports=function(t,n){return{value:n,done:!!t}}},function(t,n){t.exports=Math.log1p||function(t){return(t=+t)>-1e-8&&t<1e-8?t-t*t/2:Math.log(1+t)}},function(t,n,r){"use strict";var e=r(72),i=r(125),o=r(116),u=r(17),c=r(115),f=Object.assign;t.exports=!f||r(4)(function(){var t={},n={},r=Symbol(),e="abcdefghijklmnopqrst";return t[r]=7,e.split("").forEach(function(t){n[t]=t}),7!=f({},t)[r]||Object.keys(f({},n)).join("")!=e})?function(t,n){for(var r=u(t),f=arguments.length,a=1,s=i.f,l=o.f;f>a;)for(var h,v=c(arguments[a++]),p=s?e(v).concat(s(v)):e(v),d=p.length,y=0;d>y;)l.call(v,h=p[y++])&&(r[h]=v[h]);return r}:f},function(t,n,r){var e=r(11),i=r(2),o=r(72);t.exports=r(10)?Object.defineProperties:function(t,n){i(t);for(var r,u=o(n),c=u.length,f=0;c>f;)e.f(t,r=u[f++],n[r]);return t}},function(t,n,r){var e=r(30),i=r(71).f,o={}.toString,u="object"==typeof window&&window&&Object.getOwnPropertyNames?Object.getOwnPropertyNames(window):[],c=function(t){try{return i(t)}catch(t){return u.slice()}};t.exports.f=function(t){return u&&"[object Window]"==o.call(t)?c(t):i(e(t))}},function(t,n,r){var e=r(24),i=r(30),o=r(117)(!1),u=r(145)("IE_PROTO");t.exports=function(t,n){var r,c=i(t),f=0,a=[];for(r in c)r!=u&&e(c,r)&&a.push(r);for(;n.length>f;)e(c,r=n[f++])&&(~o(a,r)||a.push(r));return a}},function(t,n,r){var e=r(72),i=r(30),o=r(116).f;t.exports=function(t){return function(n){for(var r,u=i(n),c=e(u),f=c.length,a=0,s=[];f>a;)o.call(u,r=c[a++])&&s.push(t?[r,u[r]]:u[r]);return s}}},function(t,n,r){var e=r(71),i=r(125),o=r(2),u=r(3).Reflect;t.exports=u&&u.ownKeys||function(t){var n=e.f(o(t)),r=i.f;return r?n.concat(r(t)):n}},function(t,n,r){var e=r(3).parseFloat,i=r(82).trim;t.exports=1/e(r(150)+"-0")!=-1/0?function(t){var n=i(String(t),3),r=e(n);return 0===r&&"-"==n.charAt(0)?-0:r}:e},function(t,n,r){var e=r(3).parseInt,i=r(82).trim,o=r(150),u=/^[\-+]?0[xX]/;t.exports=8!==e(o+"08")||22!==e(o+"0x16")?function(t,n){var r=i(String(t),3);return e(r,n>>>0||(u.test(r)?16:10))}:e},function(t,n){t.exports=Object.is||function(t,n){return t===n?0!==t||1/t==1/n:t!=t&&n!=n}},function(t,n,r){var e=r(16),i=r(149),o=r(46);t.exports=function(t,n,r,u){var c=String(o(t)),f=c.length,a=void 0===r?" ":String(r),s=e(n);if(s<=f||""==a)return c;var l=s-f,h=i.call(a,Math.ceil(l/a.length));return h.length>l&&(h=h.slice(0,l)),u?h+c:c+h}},function(t,n,r){n.f=r(7)},function(t,n,r){"use strict";var e=r(164);t.exports=r(118)("Map",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{get:function(t){var n=e.getEntry(this,t);return n&&n.v},set:function(t,n){return e.def(this,0===t?0:t,n)}},e,!0)},function(t,n,r){r(10)&&"g"!=/./g.flags&&r(11).f(RegExp.prototype,"flags",{configurable:!0,get:r(120)})},function(t,n,r){"use strict";var e=r(164);t.exports=r(118)("Set",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{add:function(t){return e.def(this,t=0===t?0:t,t)}},e)},function(t,n,r){"use strict";var e,i=r(48)(0),o=r(28),u=r(65),c=r(172),f=r(166),a=r(6),s=u.getWeak,l=Object.isExtensible,h=f.ufstore,v={},p=function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},d={get:function(t){if(a(t)){var n=s(t);return!0===n?h(this).get(t):n?n[this._i]:void 0}},set:function(t,n){return f.def(this,t,n)}},y=t.exports=r(118)("WeakMap",p,d,f,!0,!0);7!=(new y).set((Object.freeze||Object)(v),7).get(v)&&(e=f.getConstructor(p),c(e.prototype,d),u.NEED=!0,i(["delete","has","get","set"],function(t){var n=y.prototype,r=n[t];o(n,t,function(n,i){if(a(n)&&!l(n)){this._f||(this._f=new e);var o=this._f[t](n,i);return"set"==t?this:o}return r.call(this,n,i)})}))},,,function(t,n){"use strict";function r(){var t=document.querySelector("#page-nav");if(t&&!document.querySelector("#page-nav .extend.prev")&&(t.innerHTML='<a class="extend prev disabled" rel="prev">« Prev</a>'+t.innerHTML),t&&!document.querySelector("#page-nav .extend.next")&&(t.innerHTML=t.innerHTML+'<a class="extend next disabled" rel="next">Next »</a>'),yiliaConfig&&yiliaConfig.open_in_new){document.querySelectorAll(".article-entry a:not(.article-more-a)").forEach(function(t){var n=t.getAttribute("target");n&&""!==n||t.setAttribute("target","_blank")})}var n=document.querySelector("#js-aboutme");n&&0!==n.length&&(n.innerHTML=n.innerText)}t.exports={init:r}},function(t,n,r){"use strict";function e(t){return t&&t.__esModule?t:{default:t}}function i(t,n){var r=/\/|index.html/g;return t.replace(r,"")===n.replace(r,"")}function o(){for(var t=document.querySelectorAll(".js-header-menu li a"),n=window.location.pathname,r=0,e=t.length;r<e;r++){var o=t[r];i(n,o.getAttribute("href"))&&(0,h.default)(o,"active")}}function u(t){for(var n=t.offsetLeft,r=t.offsetParent;null!==r;)n+=r.offsetLeft,r=r.offsetParent;return n}function c(t){for(var n=t.offsetTop,r=t.offsetParent;null!==r;)n+=r.offsetTop,r=r.offsetParent;return n}function f(t,n,r,e,i){var o=u(t),f=c(t)-n;if(f-r<=i){var a=t.$newDom;a||(a=t.cloneNode(!0),(0,d.default)(t,a),t.$newDom=a,a.style.position="fixed",a.style.top=(r||f)+"px",a.style.left=o+"px",a.style.zIndex=e||2,a.style.width="100%",a.style.color="#fff"),a.style.visibility="visible",t.style.visibility="hidden"}else{t.style.visibility="visible";var s=t.$newDom;s&&(s.style.visibility="hidden")}}function a(){var t=document.querySelector(".js-overlay"),n=document.querySelector(".js-header-menu");f(t,document.body.scrollTop,-63,2,0),f(n,document.body.scrollTop,1,3,0)}function s(){document.querySelector("#container").addEventListener("scroll",function(t){a()}),window.addEventListener("scroll",function(t){a()}),a()}var l=r(156),h=e(l),v=r(157),p=(e(v),r(381)),d=e(p),y=r(128),g=e(y),b=r(189),m=e(b),x=r(129);(function(){g.default.versions.mobile&&window.screen.width<800&&(o(),s())})(),(0,x.addLoadEvent)(function(){m.default.init()}),t.exports={}},,,,function(t,n,r){(function(t){"use strict";function n(t,n,r){t[n]||Object[e](t,n,{writable:!0,configurable:!0,value:r})}if(r(380),r(390),r(197),t._babelPolyfill)throw new Error("only one instance of babel-polyfill is allowed");t._babelPolyfill=!0;var e="defineProperty";n(String.prototype,"padLeft","".padStart),n(String.prototype,"padRight","".padEnd),"pop,reverse,shift,keys,values,entries,indexOf,every,some,forEach,map,filter,find,findIndex,includes,join,slice,concat,push,splice,unshift,sort,lastIndexOf,reduce,reduceRight,copyWithin,fill".split(",").forEach(function(t){[][t]&&n(Array,t,Function.call.bind([][t]))})}).call(n,function(){return this}())},,,function(t,n,r){r(209),t.exports=r(52).RegExp.escape},,,,function(t,n,r){var e=r(6),i=r(138),o=r(7)("species");t.exports=function(t){var n;return i(t)&&(n=t.constructor,"function"!=typeof n||n!==Array&&!i(n.prototype)||(n=void 0),e(n)&&null===(n=n[o])&&(n=void 0)),void 0===n?Array:n}},function(t,n,r){var e=r(201);t.exports=function(t,n){return new(e(t))(n)}},function(t,n,r){"use strict";var e=r(2),i=r(50),o="number";t.exports=function(t){if("string"!==t&&t!==o&&"default"!==t)throw TypeError("Incorrect hint");return i(e(this),t!=o)}},function(t,n,r){var e=r(72),i=r(125),o=r(116);t.exports=function(t){var n=e(t),r=i.f;if(r)for(var u,c=r(t),f=o.f,a=0;c.length>a;)f.call(t,u=c[a++])&&n.push(u);return n}},function(t,n,r){var e=r(72),i=r(30);t.exports=function(t,n){for(var r,o=i(t),u=e(o),c=u.length,f=0;c>f;)if(o[r=u[f++]]===n)return r}},function(t,n,r){"use strict";var e=r(207),i=r(121),o=r(26);t.exports=function(){for(var t=o(this),n=arguments.length,r=Array(n),u=0,c=e._,f=!1;n>u;)(r[u]=arguments[u++])===c&&(f=!0);return function(){var e,o=this,u=arguments.length,a=0,s=0;if(!f&&!u)return i(t,r,o);if(e=r.slice(),f)for(;n>a;a++)e[a]===c&&(e[a]=arguments[s++]);for(;u>s;)e.push(arguments[s++]);return i(t,e,o)}}},function(t,n,r){t.exports=r(3)},function(t,n){t.exports=function(t,n){var r=n===Object(n)?function(t){return n[t]}:n;return function(n){return String(n).replace(t,r)}}},function(t,n,r){var e=r(1),i=r(208)(/[\\^$*+?.()|[\]{}]/g,"\\$&");e(e.S,"RegExp",{escape:function(t){return i(t)}})},function(t,n,r){var e=r(1);e(e.P,"Array",{copyWithin:r(160)}),r(78)("copyWithin")},function(t,n,r){"use strict";var e=r(1),i=r(48)(4);e(e.P+e.F*!r(47)([].every,!0),"Array",{every:function(t){return i(this,t,arguments[1])}})},function(t,n,r){var e=r(1);e(e.P,"Array",{fill:r(130)}),r(78)("fill")},function(t,n,r){"use strict";var e=r(1),i=r(48)(2);e(e.P+e.F*!r(47)([].filter,!0),"Array",{filter:function(t){return i(this,t,arguments[1])}})},function(t,n,r){"use strict";var e=r(1),i=r(48)(6),o="findIndex",u=!0;o in[]&&Array(1)[o](function(){u=!1}),e(e.P+e.F*u,"Array",{findIndex:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}}),r(78)(o)},function(t,n,r){"use strict";var e=r(1),i=r(48)(5),o="find",u=!0;o in[]&&Array(1)[o](function(){u=!1}),e(e.P+e.F*u,"Array",{find:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}}),r(78)(o)},function(t,n,r){"use strict";var e=r(1),i=r(48)(0),o=r(47)([].forEach,!0);e(e.P+e.F*!o,"Array",{forEach:function(t){return i(this,t,arguments[1])}})},function(t,n,r){"use strict";var e=r(53),i=r(1),o=r(17),u=r(169),c=r(137),f=r(16),a=r(131),s=r(154);i(i.S+i.F*!r(123)(function(t){Array.from(t)}),"Array",{from:function(t){var n,r,i,l,h=o(t),v="function"==typeof this?this:Array,p=arguments.length,d=p>1?arguments[1]:void 0,y=void 0!==d,g=0,b=s(h);if(y&&(d=e(d,p>2?arguments[2]:void 0,2)),void 0==b||v==Array&&c(b))for(n=f(h.length),r=new v(n);n>g;g++)a(r,g,y?d(h[g],g):h[g]);else for(l=b.call(h),r=new v;!(i=l.next()).done;g++)a(r,g,y?u(l,d,[i.value,g],!0):i.value);return r.length=g,r}})},function(t,n,r){"use strict";var e=r(1),i=r(117)(!1),o=[].indexOf,u=!!o&&1/[1].indexOf(1,-0)<0;e(e.P+e.F*(u||!r(47)(o)),"Array",{indexOf:function(t){return u?o.apply(this,arguments)||0:i(this,t,arguments[1])}})},function(t,n,r){var e=r(1);e(e.S,"Array",{isArray:r(138)})},function(t,n,r){"use strict";var e=r(1),i=r(30),o=[].join;e(e.P+e.F*(r(115)!=Object||!r(47)(o)),"Array",{join:function(t){return o.call(i(this),void 0===t?",":t)}})},function(t,n,r){"use strict";var e=r(1),i=r(30),o=r(67),u=r(16),c=[].lastIndexOf,f=!!c&&1/[1].lastIndexOf(1,-0)<0;e(e.P+e.F*(f||!r(47)(c)),"Array",{lastIndexOf:function(t){if(f)return c.apply(this,arguments)||0;var n=i(this),r=u(n.length),e=r-1;for(arguments.length>1&&(e=Math.min(e,o(arguments[1]))),e<0&&(e=r+e);e>=0;e--)if(e in n&&n[e]===t)return e||0;return-1}})},function(t,n,r){"use strict";var e=r(1),i=r(48)(1);e(e.P+e.F*!r(47)([].map,!0),"Array",{map:function(t){return i(this,t,arguments[1])}})},function(t,n,r){"use strict";var e=r(1),i=r(131);e(e.S+e.F*r(4)(function(){function t(){}return!(Array.of.call(t)instanceof t)}),"Array",{of:function(){for(var t=0,n=arguments.length,r=new("function"==typeof this?this:Array)(n);n>t;)i(r,t,arguments[t++]);return r.length=n,r}})},function(t,n,r){"use strict";var e=r(1),i=r(162);e(e.P+e.F*!r(47)([].reduceRight,!0),"Array",{reduceRight:function(t){return i(this,t,arguments.length,arguments[1],!0)}})},function(t,n,r){"use strict";var e=r(1),i=r(162);e(e.P+e.F*!r(47)([].reduce,!0),"Array",{reduce:function(t){return i(this,t,arguments.length,arguments[1],!1)}})},function(t,n,r){"use strict";var e=r(1),i=r(135),o=r(45),u=r(75),c=r(16),f=[].slice;e(e.P+e.F*r(4)(function(){i&&f.call(i)}),"Array",{slice:function(t,n){var r=c(this.length),e=o(this);if(n=void 0===n?r:n,"Array"==e)return f.call(this,t,n);for(var i=u(t,r),a=u(n,r),s=c(a-i),l=Array(s),h=0;h<s;h++)l[h]="String"==e?this.charAt(i+h):this[i+h];return l}})},function(t,n,r){"use strict";var e=r(1),i=r(48)(3);e(e.P+e.F*!r(47)([].some,!0),"Array",{some:function(t){return i(this,t,arguments[1])}})},function(t,n,r){"use strict";var e=r(1),i=r(26),o=r(17),u=r(4),c=[].sort,f=[1,2,3];e(e.P+e.F*(u(function(){f.sort(void 0)})||!u(function(){f.sort(null)})||!r(47)(c)),"Array",{sort:function(t){return void 0===t?c.call(o(this)):c.call(o(this),i(t))}})},function(t,n,r){r(74)("Array")},function(t,n,r){var e=r(1);e(e.S,"Date",{now:function(){return(new Date).getTime()}})},function(t,n,r){"use strict";var e=r(1),i=r(4),o=Date.prototype.getTime,u=function(t){return t>9?t:"0"+t};e(e.P+e.F*(i(function(){return"0385-07-25T07:06:39.999Z"!=new Date(-5e13-1).toISOString()})||!i(function(){new Date(NaN).toISOString()})),"Date",{toISOString:function(){if(!isFinite(o.call(this)))throw RangeError("Invalid time value");var t=this,n=t.getUTCFullYear(),r=t.getUTCMilliseconds(),e=n<0?"-":n>9999?"+":""
;return e+("00000"+Math.abs(n)).slice(e?-6:-4)+"-"+u(t.getUTCMonth()+1)+"-"+u(t.getUTCDate())+"T"+u(t.getUTCHours())+":"+u(t.getUTCMinutes())+":"+u(t.getUTCSeconds())+"."+(r>99?r:"0"+u(r))+"Z"}})},function(t,n,r){"use strict";var e=r(1),i=r(17),o=r(50);e(e.P+e.F*r(4)(function(){return null!==new Date(NaN).toJSON()||1!==Date.prototype.toJSON.call({toISOString:function(){return 1}})}),"Date",{toJSON:function(t){var n=i(this),r=o(n);return"number"!=typeof r||isFinite(r)?n.toISOString():null}})},function(t,n,r){var e=r(7)("toPrimitive"),i=Date.prototype;e in i||r(27)(i,e,r(203))},function(t,n,r){var e=Date.prototype,i="Invalid Date",o="toString",u=e[o],c=e.getTime;new Date(NaN)+""!=i&&r(28)(e,o,function(){var t=c.call(this);return t===t?u.call(this):i})},function(t,n,r){var e=r(1);e(e.P,"Function",{bind:r(163)})},function(t,n,r){"use strict";var e=r(6),i=r(32),o=r(7)("hasInstance"),u=Function.prototype;o in u||r(11).f(u,o,{value:function(t){if("function"!=typeof this||!e(t))return!1;if(!e(this.prototype))return t instanceof this;for(;t=i(t);)if(this.prototype===t)return!0;return!1}})},function(t,n,r){var e=r(11).f,i=r(66),o=r(24),u=Function.prototype,c="name",f=Object.isExtensible||function(){return!0};c in u||r(10)&&e(u,c,{configurable:!0,get:function(){try{var t=this,n=(""+t).match(/^\s*function ([^ (]*)/)[1];return o(t,c)||!f(t)||e(t,c,i(5,n)),n}catch(t){return""}}})},function(t,n,r){var e=r(1),i=r(171),o=Math.sqrt,u=Math.acosh;e(e.S+e.F*!(u&&710==Math.floor(u(Number.MAX_VALUE))&&u(1/0)==1/0),"Math",{acosh:function(t){return(t=+t)<1?NaN:t>94906265.62425156?Math.log(t)+Math.LN2:i(t-1+o(t-1)*o(t+1))}})},function(t,n,r){function e(t){return isFinite(t=+t)&&0!=t?t<0?-e(-t):Math.log(t+Math.sqrt(t*t+1)):t}var i=r(1),o=Math.asinh;i(i.S+i.F*!(o&&1/o(0)>0),"Math",{asinh:e})},function(t,n,r){var e=r(1),i=Math.atanh;e(e.S+e.F*!(i&&1/i(-0)<0),"Math",{atanh:function(t){return 0==(t=+t)?t:Math.log((1+t)/(1-t))/2}})},function(t,n,r){var e=r(1),i=r(142);e(e.S,"Math",{cbrt:function(t){return i(t=+t)*Math.pow(Math.abs(t),1/3)}})},function(t,n,r){var e=r(1);e(e.S,"Math",{clz32:function(t){return(t>>>=0)?31-Math.floor(Math.log(t+.5)*Math.LOG2E):32}})},function(t,n,r){var e=r(1),i=Math.exp;e(e.S,"Math",{cosh:function(t){return(i(t=+t)+i(-t))/2}})},function(t,n,r){var e=r(1),i=r(141);e(e.S+e.F*(i!=Math.expm1),"Math",{expm1:i})},function(t,n,r){var e=r(1),i=r(142),o=Math.pow,u=o(2,-52),c=o(2,-23),f=o(2,127)*(2-c),a=o(2,-126),s=function(t){return t+1/u-1/u};e(e.S,"Math",{fround:function(t){var n,r,e=Math.abs(t),o=i(t);return e<a?o*s(e/a/c)*a*c:(n=(1+c/u)*e,r=n-(n-e),r>f||r!=r?o*(1/0):o*r)}})},function(t,n,r){var e=r(1),i=Math.abs;e(e.S,"Math",{hypot:function(t,n){for(var r,e,o=0,u=0,c=arguments.length,f=0;u<c;)r=i(arguments[u++]),f<r?(e=f/r,o=o*e*e+1,f=r):r>0?(e=r/f,o+=e*e):o+=r;return f===1/0?1/0:f*Math.sqrt(o)}})},function(t,n,r){var e=r(1),i=Math.imul;e(e.S+e.F*r(4)(function(){return-5!=i(4294967295,5)||2!=i.length}),"Math",{imul:function(t,n){var r=65535,e=+t,i=+n,o=r&e,u=r&i;return 0|o*u+((r&e>>>16)*u+o*(r&i>>>16)<<16>>>0)}})},function(t,n,r){var e=r(1);e(e.S,"Math",{log10:function(t){return Math.log(t)/Math.LN10}})},function(t,n,r){var e=r(1);e(e.S,"Math",{log1p:r(171)})},function(t,n,r){var e=r(1);e(e.S,"Math",{log2:function(t){return Math.log(t)/Math.LN2}})},function(t,n,r){var e=r(1);e(e.S,"Math",{sign:r(142)})},function(t,n,r){var e=r(1),i=r(141),o=Math.exp;e(e.S+e.F*r(4)(function(){return-2e-17!=!Math.sinh(-2e-17)}),"Math",{sinh:function(t){return Math.abs(t=+t)<1?(i(t)-i(-t))/2:(o(t-1)-o(-t-1))*(Math.E/2)}})},function(t,n,r){var e=r(1),i=r(141),o=Math.exp;e(e.S,"Math",{tanh:function(t){var n=i(t=+t),r=i(-t);return n==1/0?1:r==1/0?-1:(n-r)/(o(t)+o(-t))}})},function(t,n,r){var e=r(1);e(e.S,"Math",{trunc:function(t){return(t>0?Math.floor:Math.ceil)(t)}})},function(t,n,r){"use strict";var e=r(3),i=r(24),o=r(45),u=r(136),c=r(50),f=r(4),a=r(71).f,s=r(31).f,l=r(11).f,h=r(82).trim,v="Number",p=e[v],d=p,y=p.prototype,g=o(r(70)(y))==v,b="trim"in String.prototype,m=function(t){var n=c(t,!1);if("string"==typeof n&&n.length>2){n=b?n.trim():h(n,3);var r,e,i,o=n.charCodeAt(0);if(43===o||45===o){if(88===(r=n.charCodeAt(2))||120===r)return NaN}else if(48===o){switch(n.charCodeAt(1)){case 66:case 98:e=2,i=49;break;case 79:case 111:e=8,i=55;break;default:return+n}for(var u,f=n.slice(2),a=0,s=f.length;a<s;a++)if((u=f.charCodeAt(a))<48||u>i)return NaN;return parseInt(f,e)}}return+n};if(!p(" 0o1")||!p("0b1")||p("+0x1")){p=function(t){var n=arguments.length<1?0:t,r=this;return r instanceof p&&(g?f(function(){y.valueOf.call(r)}):o(r)!=v)?u(new d(m(n)),r,p):m(n)};for(var x,w=r(10)?a(d):"MAX_VALUE,MIN_VALUE,NaN,NEGATIVE_INFINITY,POSITIVE_INFINITY,EPSILON,isFinite,isInteger,isNaN,isSafeInteger,MAX_SAFE_INTEGER,MIN_SAFE_INTEGER,parseFloat,parseInt,isInteger".split(","),S=0;w.length>S;S++)i(d,x=w[S])&&!i(p,x)&&l(p,x,s(d,x));p.prototype=y,y.constructor=p,r(28)(e,v,p)}},function(t,n,r){var e=r(1);e(e.S,"Number",{EPSILON:Math.pow(2,-52)})},function(t,n,r){var e=r(1),i=r(3).isFinite;e(e.S,"Number",{isFinite:function(t){return"number"==typeof t&&i(t)}})},function(t,n,r){var e=r(1);e(e.S,"Number",{isInteger:r(168)})},function(t,n,r){var e=r(1);e(e.S,"Number",{isNaN:function(t){return t!=t}})},function(t,n,r){var e=r(1),i=r(168),o=Math.abs;e(e.S,"Number",{isSafeInteger:function(t){return i(t)&&o(t)<=9007199254740991}})},function(t,n,r){var e=r(1);e(e.S,"Number",{MAX_SAFE_INTEGER:9007199254740991})},function(t,n,r){var e=r(1);e(e.S,"Number",{MIN_SAFE_INTEGER:-9007199254740991})},function(t,n,r){var e=r(1),i=r(178);e(e.S+e.F*(Number.parseFloat!=i),"Number",{parseFloat:i})},function(t,n,r){var e=r(1),i=r(179);e(e.S+e.F*(Number.parseInt!=i),"Number",{parseInt:i})},function(t,n,r){"use strict";var e=r(1),i=r(67),o=r(159),u=r(149),c=1..toFixed,f=Math.floor,a=[0,0,0,0,0,0],s="Number.toFixed: incorrect invocation!",l="0",h=function(t,n){for(var r=-1,e=n;++r<6;)e+=t*a[r],a[r]=e%1e7,e=f(e/1e7)},v=function(t){for(var n=6,r=0;--n>=0;)r+=a[n],a[n]=f(r/t),r=r%t*1e7},p=function(){for(var t=6,n="";--t>=0;)if(""!==n||0===t||0!==a[t]){var r=String(a[t]);n=""===n?r:n+u.call(l,7-r.length)+r}return n},d=function(t,n,r){return 0===n?r:n%2==1?d(t,n-1,r*t):d(t*t,n/2,r)},y=function(t){for(var n=0,r=t;r>=4096;)n+=12,r/=4096;for(;r>=2;)n+=1,r/=2;return n};e(e.P+e.F*(!!c&&("0.000"!==8e-5.toFixed(3)||"1"!==.9.toFixed(0)||"1.25"!==1.255.toFixed(2)||"1000000000000000128"!==(0xde0b6b3a7640080).toFixed(0))||!r(4)(function(){c.call({})})),"Number",{toFixed:function(t){var n,r,e,c,f=o(this,s),a=i(t),g="",b=l;if(a<0||a>20)throw RangeError(s);if(f!=f)return"NaN";if(f<=-1e21||f>=1e21)return String(f);if(f<0&&(g="-",f=-f),f>1e-21)if(n=y(f*d(2,69,1))-69,r=n<0?f*d(2,-n,1):f/d(2,n,1),r*=4503599627370496,(n=52-n)>0){for(h(0,r),e=a;e>=7;)h(1e7,0),e-=7;for(h(d(10,e,1),0),e=n-1;e>=23;)v(1<<23),e-=23;v(1<<e),h(1,1),v(2),b=p()}else h(0,r),h(1<<-n,0),b=p()+u.call(l,a);return a>0?(c=b.length,b=g+(c<=a?"0."+u.call(l,a-c)+b:b.slice(0,c-a)+"."+b.slice(c-a))):b=g+b,b}})},function(t,n,r){"use strict";var e=r(1),i=r(4),o=r(159),u=1..toPrecision;e(e.P+e.F*(i(function(){return"1"!==u.call(1,void 0)})||!i(function(){u.call({})})),"Number",{toPrecision:function(t){var n=o(this,"Number#toPrecision: incorrect invocation!");return void 0===t?u.call(n):u.call(n,t)}})},function(t,n,r){var e=r(1);e(e.S+e.F,"Object",{assign:r(172)})},function(t,n,r){var e=r(1);e(e.S,"Object",{create:r(70)})},function(t,n,r){var e=r(1);e(e.S+e.F*!r(10),"Object",{defineProperties:r(173)})},function(t,n,r){var e=r(1);e(e.S+e.F*!r(10),"Object",{defineProperty:r(11).f})},function(t,n,r){var e=r(6),i=r(65).onFreeze;r(49)("freeze",function(t){return function(n){return t&&e(n)?t(i(n)):n}})},function(t,n,r){var e=r(30),i=r(31).f;r(49)("getOwnPropertyDescriptor",function(){return function(t,n){return i(e(t),n)}})},function(t,n,r){r(49)("getOwnPropertyNames",function(){return r(174).f})},function(t,n,r){var e=r(17),i=r(32);r(49)("getPrototypeOf",function(){return function(t){return i(e(t))}})},function(t,n,r){var e=r(6);r(49)("isExtensible",function(t){return function(n){return!!e(n)&&(!t||t(n))}})},function(t,n,r){var e=r(6);r(49)("isFrozen",function(t){return function(n){return!e(n)||!!t&&t(n)}})},function(t,n,r){var e=r(6);r(49)("isSealed",function(t){return function(n){return!e(n)||!!t&&t(n)}})},function(t,n,r){var e=r(1);e(e.S,"Object",{is:r(180)})},function(t,n,r){var e=r(17),i=r(72);r(49)("keys",function(){return function(t){return i(e(t))}})},function(t,n,r){var e=r(6),i=r(65).onFreeze;r(49)("preventExtensions",function(t){return function(n){return t&&e(n)?t(i(n)):n}})},function(t,n,r){var e=r(6),i=r(65).onFreeze;r(49)("seal",function(t){return function(n){return t&&e(n)?t(i(n)):n}})},function(t,n,r){var e=r(1);e(e.S,"Object",{setPrototypeOf:r(144).set})},function(t,n,r){"use strict";var e=r(114),i={};i[r(7)("toStringTag")]="z",i+""!="[object z]"&&r(28)(Object.prototype,"toString",function(){return"[object "+e(this)+"]"},!0)},function(t,n,r){var e=r(1),i=r(178);e(e.G+e.F*(parseFloat!=i),{parseFloat:i})},function(t,n,r){var e=r(1),i=r(179);e(e.G+e.F*(parseInt!=i),{parseInt:i})},function(t,n,r){"use strict";var e,i,o,u=r(69),c=r(3),f=r(53),a=r(114),s=r(1),l=r(6),h=r(26),v=r(68),p=r(79),d=r(146),y=r(151).set,g=r(143)(),b="Promise",m=c.TypeError,x=c.process,w=c[b],x=c.process,S="process"==a(x),_=function(){},O=!!function(){try{var t=w.resolve(1),n=(t.constructor={})[r(7)("species")]=function(t){t(_,_)};return(S||"function"==typeof PromiseRejectionEvent)&&t.then(_)instanceof n}catch(t){}}(),E=function(t,n){return t===n||t===w&&n===o},P=function(t){var n;return!(!l(t)||"function"!=typeof(n=t.then))&&n},j=function(t){return E(w,t)?new F(t):new i(t)},F=i=function(t){var n,r;this.promise=new t(function(t,e){if(void 0!==n||void 0!==r)throw m("Bad Promise constructor");n=t,r=e}),this.resolve=h(n),this.reject=h(r)},M=function(t){try{t()}catch(t){return{error:t}}},A=function(t,n){if(!t._n){t._n=!0;var r=t._c;g(function(){for(var e=t._v,i=1==t._s,o=0;r.length>o;)!function(n){var r,o,u=i?n.ok:n.fail,c=n.resolve,f=n.reject,a=n.domain;try{u?(i||(2==t._h&&I(t),t._h=1),!0===u?r=e:(a&&a.enter(),r=u(e),a&&a.exit()),r===n.promise?f(m("Promise-chain cycle")):(o=P(r))?o.call(r,c,f):c(r)):f(e)}catch(t){f(t)}}(r[o++]);t._c=[],t._n=!1,n&&!t._h&&N(t)})}},N=function(t){y.call(c,function(){var n,r,e,i=t._v;if(T(t)&&(n=M(function(){S?x.emit("unhandledRejection",i,t):(r=c.onunhandledrejection)?r({promise:t,reason:i}):(e=c.console)&&e.error&&e.error("Unhandled promise rejection",i)}),t._h=S||T(t)?2:1),t._a=void 0,n)throw n.error})},T=function(t){if(1==t._h)return!1;for(var n,r=t._a||t._c,e=0;r.length>e;)if(n=r[e++],n.fail||!T(n.promise))return!1;return!0},I=function(t){y.call(c,function(){var n;S?x.emit("rejectionHandled",t):(n=c.onrejectionhandled)&&n({promise:t,reason:t._v})})},k=function(t){var n=this;n._d||(n._d=!0,n=n._w||n,n._v=t,n._s=2,n._a||(n._a=n._c.slice()),A(n,!0))},L=function(t){var n,r=this;if(!r._d){r._d=!0,r=r._w||r;try{if(r===t)throw m("Promise can't be resolved itself");(n=P(t))?g(function(){var e={_w:r,_d:!1};try{n.call(t,f(L,e,1),f(k,e,1))}catch(t){k.call(e,t)}}):(r._v=t,r._s=1,A(r,!1))}catch(t){k.call({_w:r,_d:!1},t)}}};O||(w=function(t){v(this,w,b,"_h"),h(t),e.call(this);try{t(f(L,this,1),f(k,this,1))}catch(t){k.call(this,t)}},e=function(t){this._c=[],this._a=void 0,this._s=0,this._d=!1,this._v=void 0,this._h=0,this._n=!1},e.prototype=r(73)(w.prototype,{then:function(t,n){var r=j(d(this,w));return r.ok="function"!=typeof t||t,r.fail="function"==typeof n&&n,r.domain=S?x.domain:void 0,this._c.push(r),this._a&&this._a.push(r),this._s&&A(this,!1),r.promise},catch:function(t){return this.then(void 0,t)}}),F=function(){var t=new e;this.promise=t,this.resolve=f(L,t,1),this.reject=f(k,t,1)}),s(s.G+s.W+s.F*!O,{Promise:w}),r(81)(w,b),r(74)(b),o=r(52)[b],s(s.S+s.F*!O,b,{reject:function(t){var n=j(this);return(0,n.reject)(t),n.promise}}),s(s.S+s.F*(u||!O),b,{resolve:function(t){if(t instanceof w&&E(t.constructor,this))return t;var n=j(this);return(0,n.resolve)(t),n.promise}}),s(s.S+s.F*!(O&&r(123)(function(t){w.all(t).catch(_)})),b,{all:function(t){var n=this,r=j(n),e=r.resolve,i=r.reject,o=M(function(){var r=[],o=0,u=1;p(t,!1,function(t){var c=o++,f=!1;r.push(void 0),u++,n.resolve(t).then(function(t){f||(f=!0,r[c]=t,--u||e(r))},i)}),--u||e(r)});return o&&i(o.error),r.promise},race:function(t){var n=this,r=j(n),e=r.reject,i=M(function(){p(t,!1,function(t){n.resolve(t).then(r.resolve,e)})});return i&&e(i.error),r.promise}})},function(t,n,r){var e=r(1),i=r(26),o=r(2),u=(r(3).Reflect||{}).apply,c=Function.apply;e(e.S+e.F*!r(4)(function(){u(function(){})}),"Reflect",{apply:function(t,n,r){var e=i(t),f=o(r);return u?u(e,n,f):c.call(e,n,f)}})},function(t,n,r){var e=r(1),i=r(70),o=r(26),u=r(2),c=r(6),f=r(4),a=r(163),s=(r(3).Reflect||{}).construct,l=f(function(){function t(){}return!(s(function(){},[],t)instanceof t)}),h=!f(function(){s(function(){})});e(e.S+e.F*(l||h),"Reflect",{construct:function(t,n){o(t),u(n);var r=arguments.length<3?t:o(arguments[2]);if(h&&!l)return s(t,n,r);if(t==r){switch(n.length){case 0:return new t;case 1:return new t(n[0]);case 2:return new t(n[0],n[1]);case 3:return new t(n[0],n[1],n[2]);case 4:return new t(n[0],n[1],n[2],n[3])}var e=[null];return e.push.apply(e,n),new(a.apply(t,e))}var f=r.prototype,v=i(c(f)?f:Object.prototype),p=Function.apply.call(t,v,n);return c(p)?p:v}})},function(t,n,r){var e=r(11),i=r(1),o=r(2),u=r(50);i(i.S+i.F*r(4)(function(){Reflect.defineProperty(e.f({},1,{value:1}),1,{value:2})}),"Reflect",{defineProperty:function(t,n,r){o(t),n=u(n,!0),o(r);try{return e.f(t,n,r),!0}catch(t){return!1}}})},function(t,n,r){var e=r(1),i=r(31).f,o=r(2);e(e.S,"Reflect",{deleteProperty:function(t,n){var r=i(o(t),n);return!(r&&!r.configurable)&&delete t[n]}})},function(t,n,r){"use strict";var e=r(1),i=r(2),o=function(t){this._t=i(t),this._i=0;var n,r=this._k=[];for(n in t)r.push(n)};r(139)(o,"Object",function(){var t,n=this,r=n._k;do{if(n._i>=r.length)return{value:void 0,done:!0}}while(!((t=r[n._i++])in n._t));return{value:t,done:!1}}),e(e.S,"Reflect",{enumerate:function(t){return new o(t)}})},function(t,n,r){var e=r(31),i=r(1),o=r(2);i(i.S,"Reflect",{getOwnPropertyDescriptor:function(t,n){return e.f(o(t),n)}})},function(t,n,r){var e=r(1),i=r(32),o=r(2);e(e.S,"Reflect",{getPrototypeOf:function(t){return i(o(t))}})},function(t,n,r){function e(t,n){var r,c,s=arguments.length<3?t:arguments[2];return a(t)===s?t[n]:(r=i.f(t,n))?u(r,"value")?r.value:void 0!==r.get?r.get.call(s):void 0:f(c=o(t))?e(c,n,s):void 0}var i=r(31),o=r(32),u=r(24),c=r(1),f=r(6),a=r(2);c(c.S,"Reflect",{get:e})},function(t,n,r){var e=r(1);e(e.S,"Reflect",{has:function(t,n){return n in t}})},function(t,n,r){var e=r(1),i=r(2),o=Object.isExtensible;e(e.S,"Reflect",{isExtensible:function(t){return i(t),!o||o(t)}})},function(t,n,r){var e=r(1);e(e.S,"Reflect",{ownKeys:r(177)})},function(t,n,r){var e=r(1),i=r(2),o=Object.preventExtensions;e(e.S,"Reflect",{preventExtensions:function(t){i(t);try{return o&&o(t),!0}catch(t){return!1}}})},function(t,n,r){var e=r(1),i=r(144);i&&e(e.S,"Reflect",{setPrototypeOf:function(t,n){i.check(t,n);try{return i.set(t,n),!0}catch(t){return!1}}})},function(t,n,r){function e(t,n,r){var f,h,v=arguments.length<4?t:arguments[3],p=o.f(s(t),n);if(!p){if(l(h=u(t)))return e(h,n,r,v);p=a(0)}return c(p,"value")?!(!1===p.writable||!l(v)||(f=o.f(v,n)||a(0),f.value=r,i.f(v,n,f),0)):void 0!==p.set&&(p.set.call(v,r),!0)}var i=r(11),o=r(31),u=r(32),c=r(24),f=r(1),a=r(66),s=r(2),l=r(6);f(f.S,"Reflect",{set:e})},function(t,n,r){var e=r(3),i=r(136),o=r(11).f,u=r(71).f,c=r(122),f=r(120),a=e.RegExp,s=a,l=a.prototype,h=/a/g,v=/a/g,p=new a(h)!==h;if(r(10)&&(!p||r(4)(function(){return v[r(7)("match")]=!1,a(h)!=h||a(v)==v||"/a/i"!=a(h,"i")}))){a=function(t,n){var r=this instanceof a,e=c(t),o=void 0===n;return!r&&e&&t.constructor===a&&o?t:i(p?new s(e&&!o?t.source:t,n):s((e=t instanceof a)?t.source:t,e&&o?f.call(t):n),r?this:l,a)};for(var d=u(s),y=0;d.length>y;)!function(t){t in a||o(a,t,{configurable:!0,get:function(){return s[t]},set:function(n){s[t]=n}})}(d[y++]);l.constructor=a,a.prototype=l,r(28)(e,"RegExp",a)}r(74)("RegExp")},function(t,n,r){r(119)("match",1,function(t,n,r){return[function(r){"use strict";var e=t(this),i=void 0==r?void 0:r[n];return void 0!==i?i.call(r,e):new RegExp(r)[n](String(e))},r]})},function(t,n,r){r(119)("replace",2,function(t,n,r){return[function(e,i){"use strict";var o=t(this),u=void 0==e?void 0:e[n];return void 0!==u?u.call(e,o,i):r.call(String(o),e,i)},r]})},function(t,n,r){r(119)("search",1,function(t,n,r){return[function(r){"use strict";var e=t(this),i=void 0==r?void 0:r[n];return void 0!==i?i.call(r,e):new RegExp(r)[n](String(e))},r]})},function(t,n,r){r(119)("split",2,function(t,n,e){"use strict";var i=r(122),o=e,u=[].push,c="split",f="length",a="lastIndex";if("c"=="abbc"[c](/(b)*/)[1]||4!="test"[c](/(?:)/,-1)[f]||2!="ab"[c](/(?:ab)*/)[f]||4!="."[c](/(.?)(.?)/)[f]||"."[c](/()()/)[f]>1||""[c](/.?/)[f]){var s=void 0===/()??/.exec("")[1];e=function(t,n){var r=String(this);if(void 0===t&&0===n)return[];if(!i(t))return o.call(r,t,n);var e,c,l,h,v,p=[],d=(t.ignoreCase?"i":"")+(t.multiline?"m":"")+(t.unicode?"u":"")+(t.sticky?"y":""),y=0,g=void 0===n?4294967295:n>>>0,b=new RegExp(t.source,d+"g");for(s||(e=new RegExp("^"+b.source+"$(?!\\s)",d));(c=b.exec(r))&&!((l=c.index+c[0][f])>y&&(p.push(r.slice(y,c.index)),!s&&c[f]>1&&c[0].replace(e,function(){for(v=1;v<arguments[f]-2;v++)void 0===arguments[v]&&(c[v]=void 0)}),c[f]>1&&c.index<r[f]&&u.apply(p,c.slice(1)),h=c[0][f],y=l,p[f]>=g));)b[a]===c.index&&b[a]++;return y===r[f]?!h&&b.test("")||p.push(""):p.push(r.slice(y)),p[f]>g?p.slice(0,g):p}}else"0"[c](void 0,0)[f]&&(e=function(t,n){return void 0===t&&0===n?[]:o.call(this,t,n)});return[function(r,i){var o=t(this),u=void 0==r?void 0:r[n];return void 0!==u?u.call(r,o,i):e.call(String(o),r,i)},e]})},function(t,n,r){"use strict";r(184);var e=r(2),i=r(120),o=r(10),u="toString",c=/./[u],f=function(t){r(28)(RegExp.prototype,u,t,!0)};r(4)(function(){return"/a/b"!=c.call({source:"a",flags:"b"})})?f(function(){var t=e(this);return"/".concat(t.source,"/","flags"in t?t.flags:!o&&t instanceof RegExp?i.call(t):void 0)}):c.name!=u&&f(function(){return c.call(this)})},function(t,n,r){"use strict";r(29)("anchor",function(t){return function(n){return t(this,"a","name",n)}})},function(t,n,r){"use strict";r(29)("big",function(t){return function(){return t(this,"big","","")}})},function(t,n,r){"use strict";r(29)("blink",function(t){return function(){return t(this,"blink","","")}})},function(t,n,r){"use strict";r(29)("bold",function(t){return function(){return t(this,"b","","")}})},function(t,n,r){"use strict";var e=r(1),i=r(147)(!1);e(e.P,"String",{codePointAt:function(t){return i(this,t)}})},function(t,n,r){"use strict";var e=r(1),i=r(16),o=r(148),u="endsWith",c=""[u];e(e.P+e.F*r(134)(u),"String",{endsWith:function(t){var n=o(this,t,u),r=arguments.length>1?arguments[1]:void 0,e=i(n.length),f=void 0===r?e:Math.min(i(r),e),a=String(t);return c?c.call(n,a,f):n.slice(f-a.length,f)===a}})},function(t,n,r){"use strict";r(29)("fixed",function(t){return function(){return t(this,"tt","","")}})},function(t,n,r){"use strict";r(29)("fontcolor",function(t){return function(n){return t(this,"font","color",n)}})},function(t,n,r){"use strict";r(29)("fontsize",function(t){return function(n){return t(this,"font","size",n)}})},function(t,n,r){var e=r(1),i=r(75),o=String.fromCharCode,u=String.fromCodePoint;e(e.S+e.F*(!!u&&1!=u.length),"String",{fromCodePoint:function(t){for(var n,r=[],e=arguments.length,u=0;e>u;){if(n=+arguments[u++],i(n,1114111)!==n)throw RangeError(n+" is not a valid code point");r.push(n<65536?o(n):o(55296+((n-=65536)>>10),n%1024+56320))}return r.join("")}})},function(t,n,r){"use strict";var e=r(1),i=r(148),o="includes";e(e.P+e.F*r(134)(o),"String",{includes:function(t){return!!~i(this,t,o).indexOf(t,arguments.length>1?arguments[1]:void 0)}})},function(t,n,r){"use strict";r(29)("italics",function(t){return function(){return t(this,"i","","")}})},function(t,n,r){"use strict";var e=r(147)(!0);r(140)(String,"String",function(t){this._t=String(t),this._i=0},function(){var t,n=this._t,r=this._i;return r>=n.length?{value:void 0,done:!0}:(t=e(n,r),this._i+=t.length,{value:t,done:!1})})},function(t,n,r){"use strict";r(29)("link",function(t){return function(n){return t(this,"a","href",n)}})},function(t,n,r){var e=r(1),i=r(30),o=r(16);e(e.S,"String",{raw:function(t){for(var n=i(t.raw),r=o(n.length),e=arguments.length,u=[],c=0;r>c;)u.push(String(n[c++])),c<e&&u.push(String(arguments[c]));return u.join("")}})},function(t,n,r){var e=r(1);e(e.P,"String",{repeat:r(149)})},function(t,n,r){"use strict";r(29)("small",function(t){return function(){return t(this,"small","","")}})},function(t,n,r){"use strict";var e=r(1),i=r(16),o=r(148),u="startsWith",c=""[u];e(e.P+e.F*r(134)(u),"String",{startsWith:function(t){var n=o(this,t,u),r=i(Math.min(arguments.length>1?arguments[1]:void 0,n.length)),e=String(t);return c?c.call(n,e,r):n.slice(r,r+e.length)===e}})},function(t,n,r){"use strict";r(29)("strike",function(t){return function(){return t(this,"strike","","")}})},function(t,n,r){"use strict";r(29)("sub",function(t){return function(){return t(this,"sub","","")}})},function(t,n,r){"use strict";r(29)("sup",function(t){return function(){return t(this,"sup","","")}})},function(t,n,r){"use strict";r(82)("trim",function(t){return function(){return t(this,3)}})},function(t,n,r){"use strict";var e=r(3),i=r(24),o=r(10),u=r(1),c=r(28),f=r(65).KEY,a=r(4),s=r(126),l=r(81),h=r(76),v=r(7),p=r(182),d=r(153),y=r(205),g=r(204),b=r(138),m=r(2),x=r(30),w=r(50),S=r(66),_=r(70),O=r(174),E=r(31),P=r(11),j=r(72),F=E.f,M=P.f,A=O.f,N=e.Symbol,T=e.JSON,I=T&&T.stringify,k="prototype",L=v("_hidden"),R=v("toPrimitive"),C={}.propertyIsEnumerable,D=s("symbol-registry"),U=s("symbols"),W=s("op-symbols"),G=Object[k],B="function"==typeof N,V=e.QObject,z=!V||!V[k]||!V[k].findChild,q=o&&a(function(){return 7!=_(M({},"a",{get:function(){return M(this,"a",{value:7}).a}})).a})?function(t,n,r){var e=F(G,n);e&&delete G[n],M(t,n,r),e&&t!==G&&M(G,n,e)}:M,K=function(t){var n=U[t]=_(N[k]);return n._k=t,n},J=B&&"symbol"==typeof N.iterator?function(t){return"symbol"==typeof t}:function(t){return t instanceof N},Y=function(t,n,r){return t===G&&Y(W,n,r),m(t),n=w(n,!0),m(r),i(U,n)?(r.enumerable?(i(t,L)&&t[L][n]&&(t[L][n]=!1),r=_(r,{enumerable:S(0,!1)})):(i(t,L)||M(t,L,S(1,{})),t[L][n]=!0),q(t,n,r)):M(t,n,r)},H=function(t,n){m(t);for(var r,e=g(n=x(n)),i=0,o=e.length;o>i;)Y(t,r=e[i++],n[r]);return t},$=function(t,n){return void 0===n?_(t):H(_(t),n)},X=function(t){var n=C.call(this,t=w(t,!0));return!(this===G&&i(U,t)&&!i(W,t))&&(!(n||!i(this,t)||!i(U,t)||i(this,L)&&this[L][t])||n)},Q=function(t,n){if(t=x(t),n=w(n,!0),t!==G||!i(U,n)||i(W,n)){var r=F(t,n);return!r||!i(U,n)||i(t,L)&&t[L][n]||(r.enumerable=!0),r}},Z=function(t){for(var n,r=A(x(t)),e=[],o=0;r.length>o;)i(U,n=r[o++])||n==L||n==f||e.push(n);return e},tt=function(t){for(var n,r=t===G,e=A(r?W:x(t)),o=[],u=0;e.length>u;)!i(U,n=e[u++])||r&&!i(G,n)||o.push(U[n]);return o};B||(N=function(){if(this instanceof N)throw TypeError("Symbol is not a constructor!");var t=h(arguments.length>0?arguments[0]:void 0),n=function(r){this===G&&n.call(W,r),i(this,L)&&i(this[L],t)&&(this[L][t]=!1),q(this,t,S(1,r))};return o&&z&&q(G,t,{configurable:!0,set:n}),K(t)},c(N[k],"toString",function(){return this._k}),E.f=Q,P.f=Y,r(71).f=O.f=Z,r(116).f=X,r(125).f=tt,o&&!r(69)&&c(G,"propertyIsEnumerable",X,!0),p.f=function(t){return K(v(t))}),u(u.G+u.W+u.F*!B,{Symbol:N});for(var nt="hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables".split(","),rt=0;nt.length>rt;)v(nt[rt++]);for(var nt=j(v.store),rt=0;nt.length>rt;)d(nt[rt++]);u(u.S+u.F*!B,"Symbol",{for:function(t){return i(D,t+="")?D[t]:D[t]=N(t)},keyFor:function(t){if(J(t))return y(D,t);throw TypeError(t+" is not a symbol!")},useSetter:function(){z=!0},useSimple:function(){z=!1}}),u(u.S+u.F*!B,"Object",{create:$,defineProperty:Y,defineProperties:H,getOwnPropertyDescriptor:Q,getOwnPropertyNames:Z,getOwnPropertySymbols:tt}),T&&u(u.S+u.F*(!B||a(function(){var t=N();return"[null]"!=I([t])||"{}"!=I({a:t})||"{}"!=I(Object(t))})),"JSON",{stringify:function(t){if(void 0!==t&&!J(t)){for(var n,r,e=[t],i=1;arguments.length>i;)e.push(arguments[i++]);return n=e[1],"function"==typeof n&&(r=n),!r&&b(n)||(n=function(t,n){if(r&&(n=r.call(this,t,n)),!J(n))return n}),e[1]=n,I.apply(T,e)}}}),N[k][R]||r(27)(N[k],R,N[k].valueOf),l(N,"Symbol"),l(Math,"Math",!0),l(e.JSON,"JSON",!0)},function(t,n,r){"use strict";var e=r(1),i=r(127),o=r(152),u=r(2),c=r(75),f=r(16),a=r(6),s=r(3).ArrayBuffer,l=r(146),h=o.ArrayBuffer,v=o.DataView,p=i.ABV&&s.isView,d=h.prototype.slice,y=i.VIEW,g="ArrayBuffer";e(e.G+e.W+e.F*(s!==h),{ArrayBuffer:h}),e(e.S+e.F*!i.CONSTR,g,{isView:function(t){return p&&p(t)||a(t)&&y in t}}),e(e.P+e.U+e.F*r(4)(function(){return!new h(2).slice(1,void 0).byteLength}),g,{slice:function(t,n){if(void 0!==d&&void 0===n)return d.call(u(this),t);for(var r=u(this).byteLength,e=c(t,r),i=c(void 0===n?r:n,r),o=new(l(this,h))(f(i-e)),a=new v(this),s=new v(o),p=0;e<i;)s.setUint8(p++,a.getUint8(e++));return o}}),r(74)(g)},function(t,n,r){var e=r(1);e(e.G+e.W+e.F*!r(127).ABV,{DataView:r(152).DataView})},function(t,n,r){r(55)("Float32",4,function(t){return function(n,r,e){return t(this,n,r,e)}})},function(t,n,r){r(55)("Float64",8,function(t){return function(n,r,e){return t(this,n,r,e)}})},function(t,n,r){r(55)("Int16",2,function(t){return function(n,r,e){return t(this,n,r,e)}})},function(t,n,r){r(55)("Int32",4,function(t){return function(n,r,e){return t(this,n,r,e)}})},function(t,n,r){r(55)("Int8",1,function(t){return function(n,r,e){return t(this,n,r,e)}})},function(t,n,r){r(55)("Uint16",2,function(t){return function(n,r,e){return t(this,n,r,e)}})},function(t,n,r){r(55)("Uint32",4,function(t){return function(n,r,e){return t(this,n,r,e)}})},function(t,n,r){r(55)("Uint8",1,function(t){return function(n,r,e){return t(this,n,r,e)}})},function(t,n,r){r(55)("Uint8",1,function(t){return function(n,r,e){return t(this,n,r,e)}},!0)},function(t,n,r){"use strict";var e=r(166);r(118)("WeakSet",function(t){return function(){return t(this,arguments.length>0?arguments[0]:void 0)}},{add:function(t){return e.def(this,t,!0)}},e,!1,!0)},function(t,n,r){"use strict";var e=r(1),i=r(117)(!0);e(e.P,"Array",{includes:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0)}}),r(78)("includes")},function(t,n,r){var e=r(1),i=r(143)(),o=r(3).process,u="process"==r(45)(o);e(e.G,{asap:function(t){var n=u&&o.domain;i(n?n.bind(t):t)}})},function(t,n,r){var e=r(1),i=r(45);e(e.S,"Error",{isError:function(t){return"Error"===i(t)}})},function(t,n,r){var e=r(1);e(e.P+e.R,"Map",{toJSON:r(165)("Map")})},function(t,n,r){var e=r(1);e(e.S,"Math",{iaddh:function(t,n,r,e){var i=t>>>0,o=n>>>0,u=r>>>0;return o+(e>>>0)+((i&u|(i|u)&~(i+u>>>0))>>>31)|0}})},function(t,n,r){var e=r(1);e(e.S,"Math",{imulh:function(t,n){var r=65535,e=+t,i=+n,o=e&r,u=i&r,c=e>>16,f=i>>16,a=(c*u>>>0)+(o*u>>>16);return c*f+(a>>16)+((o*f>>>0)+(a&r)>>16)}})},function(t,n,r){var e=r(1);e(e.S,"Math",{isubh:function(t,n,r,e){var i=t>>>0,o=n>>>0,u=r>>>0;return o-(e>>>0)-((~i&u|~(i^u)&i-u>>>0)>>>31)|0}})},function(t,n,r){var e=r(1);e(e.S,"Math",{umulh:function(t,n){var r=65535,e=+t,i=+n,o=e&r,u=i&r,c=e>>>16,f=i>>>16,a=(c*u>>>0)+(o*u>>>16);return c*f+(a>>>16)+((o*f>>>0)+(a&r)>>>16)}})},function(t,n,r){"use strict";var e=r(1),i=r(17),o=r(26),u=r(11);r(10)&&e(e.P+r(124),"Object",{__defineGetter__:function(t,n){u.f(i(this),t,{get:o(n),enumerable:!0,configurable:!0})}})},function(t,n,r){"use strict";var e=r(1),i=r(17),o=r(26),u=r(11);r(10)&&e(e.P+r(124),"Object",{__defineSetter__:function(t,n){u.f(i(this),t,{set:o(n),enumerable:!0,configurable:!0})}})},function(t,n,r){var e=r(1),i=r(176)(!0);e(e.S,"Object",{entries:function(t){return i(t)}})},function(t,n,r){var e=r(1),i=r(177),o=r(30),u=r(31),c=r(131);e(e.S,"Object",{getOwnPropertyDescriptors:function(t){for(var n,r=o(t),e=u.f,f=i(r),a={},s=0;f.length>s;)c(a,n=f[s++],e(r,n));return a}})},function(t,n,r){"use strict";var e=r(1),i=r(17),o=r(50),u=r(32),c=r(31).f;r(10)&&e(e.P+r(124),"Object",{__lookupGetter__:function(t){var n,r=i(this),e=o(t,!0);do{if(n=c(r,e))return n.get}while(r=u(r))}})},function(t,n,r){"use strict";var e=r(1),i=r(17),o=r(50),u=r(32),c=r(31).f;r(10)&&e(e.P+r(124),"Object",{__lookupSetter__:function(t){var n,r=i(this),e=o(t,!0);do{if(n=c(r,e))return n.set}while(r=u(r))}})},function(t,n,r){var e=r(1),i=r(176)(!1);e(e.S,"Object",{values:function(t){return i(t)}})},function(t,n,r){"use strict";var e=r(1),i=r(3),o=r(52),u=r(143)(),c=r(7)("observable"),f=r(26),a=r(2),s=r(68),l=r(73),h=r(27),v=r(79),p=v.RETURN,d=function(t){return null==t?void 0:f(t)},y=function(t){var n=t._c;n&&(t._c=void 0,n())},g=function(t){return void 0===t._o},b=function(t){g(t)||(t._o=void 0,y(t))},m=function(t,n){a(t),this._c=void 0,this._o=t,t=new x(this);try{var r=n(t),e=r;null!=r&&("function"==typeof r.unsubscribe?r=function(){e.unsubscribe()}:f(r),this._c=r)}catch(n){return void t.error(n)}g(this)&&y(this)};m.prototype=l({},{unsubscribe:function(){b(this)}});var x=function(t){this._s=t};x.prototype=l({},{next:function(t){var n=this._s;if(!g(n)){var r=n._o;try{var e=d(r.next);if(e)return e.call(r,t)}catch(t){try{b(n)}finally{throw t}}}},error:function(t){var n=this._s;if(g(n))throw t;var r=n._o;n._o=void 0;try{var e=d(r.error);if(!e)throw t;t=e.call(r,t)}catch(t){try{y(n)}finally{throw t}}return y(n),t},complete:function(t){var n=this._s;if(!g(n)){var r=n._o;n._o=void 0;try{var e=d(r.complete);t=e?e.call(r,t):void 0}catch(t){try{y(n)}finally{throw t}}return y(n),t}}});var w=function(t){s(this,w,"Observable","_f")._f=f(t)};l(w.prototype,{subscribe:function(t){return new m(t,this._f)},forEach:function(t){var n=this;return new(o.Promise||i.Promise)(function(r,e){f(t);var i=n.subscribe({next:function(n){try{return t(n)}catch(t){e(t),i.unsubscribe()}},error:e,complete:r})})}}),l(w,{from:function(t){var n="function"==typeof this?this:w,r=d(a(t)[c]);if(r){var e=a(r.call(t));return e.constructor===n?e:new n(function(t){return e.subscribe(t)})}return new n(function(n){var r=!1;return u(function(){if(!r){try{if(v(t,!1,function(t){if(n.next(t),r)return p})===p)return}catch(t){if(r)throw t;return void n.error(t)}n.complete()}}),function(){r=!0}})},of:function(){for(var t=0,n=arguments.length,r=Array(n);t<n;)r[t]=arguments[t++];return new("function"==typeof this?this:w)(function(t){var n=!1;return u(function(){if(!n){for(var e=0;e<r.length;++e)if(t.next(r[e]),n)return;t.complete()}}),function(){n=!0}})}}),h(w.prototype,c,function(){return this}),e(e.G,{Observable:w}),r(74)("Observable")},function(t,n,r){var e=r(54),i=r(2),o=e.key,u=e.set;e.exp({defineMetadata:function(t,n,r,e){u(t,n,i(r),o(e))}})},function(t,n,r){var e=r(54),i=r(2),o=e.key,u=e.map,c=e.store;e.exp({deleteMetadata:function(t,n){var r=arguments.length<3?void 0:o(arguments[2]),e=u(i(n),r,!1);if(void 0===e||!e.delete(t))return!1;if(e.size)return!0;var f=c.get(n);return f.delete(r),!!f.size||c.delete(n)}})},function(t,n,r){var e=r(185),i=r(161),o=r(54),u=r(2),c=r(32),f=o.keys,a=o.key,s=function(t,n){var r=f(t,n),o=c(t);if(null===o)return r;var u=s(o,n);return u.length?r.length?i(new e(r.concat(u))):u:r};o.exp({getMetadataKeys:function(t){return s(u(t),arguments.length<2?void 0:a(arguments[1]))}})},function(t,n,r){var e=r(54),i=r(2),o=r(32),u=e.has,c=e.get,f=e.key,a=function(t,n,r){if(u(t,n,r))return c(t,n,r);var e=o(n);return null!==e?a(t,e,r):void 0};e.exp({getMetadata:function(t,n){return a(t,i(n),arguments.length<3?void 0:f(arguments[2]))}})},function(t,n,r){var e=r(54),i=r(2),o=e.keys,u=e.key;e.exp({getOwnMetadataKeys:function(t){return o(i(t),arguments.length<2?void 0:u(arguments[1]))}})},function(t,n,r){var e=r(54),i=r(2),o=e.get,u=e.key;e.exp({getOwnMetadata:function(t,n){
return o(t,i(n),arguments.length<3?void 0:u(arguments[2]))}})},function(t,n,r){var e=r(54),i=r(2),o=r(32),u=e.has,c=e.key,f=function(t,n,r){if(u(t,n,r))return!0;var e=o(n);return null!==e&&f(t,e,r)};e.exp({hasMetadata:function(t,n){return f(t,i(n),arguments.length<3?void 0:c(arguments[2]))}})},function(t,n,r){var e=r(54),i=r(2),o=e.has,u=e.key;e.exp({hasOwnMetadata:function(t,n){return o(t,i(n),arguments.length<3?void 0:u(arguments[2]))}})},function(t,n,r){var e=r(54),i=r(2),o=r(26),u=e.key,c=e.set;e.exp({metadata:function(t,n){return function(r,e){c(t,n,(void 0!==e?i:o)(r),u(e))}}})},function(t,n,r){var e=r(1);e(e.P+e.R,"Set",{toJSON:r(165)("Set")})},function(t,n,r){"use strict";var e=r(1),i=r(147)(!0);e(e.P,"String",{at:function(t){return i(this,t)}})},function(t,n,r){"use strict";var e=r(1),i=r(46),o=r(16),u=r(122),c=r(120),f=RegExp.prototype,a=function(t,n){this._r=t,this._s=n};r(139)(a,"RegExp String",function(){var t=this._r.exec(this._s);return{value:t,done:null===t}}),e(e.P,"String",{matchAll:function(t){if(i(this),!u(t))throw TypeError(t+" is not a regexp!");var n=String(this),r="flags"in f?String(t.flags):c.call(t),e=new RegExp(t.source,~r.indexOf("g")?r:"g"+r);return e.lastIndex=o(t.lastIndex),new a(e,n)}})},function(t,n,r){"use strict";var e=r(1),i=r(181);e(e.P,"String",{padEnd:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0,!1)}})},function(t,n,r){"use strict";var e=r(1),i=r(181);e(e.P,"String",{padStart:function(t){return i(this,t,arguments.length>1?arguments[1]:void 0,!0)}})},function(t,n,r){"use strict";r(82)("trimLeft",function(t){return function(){return t(this,1)}},"trimStart")},function(t,n,r){"use strict";r(82)("trimRight",function(t){return function(){return t(this,2)}},"trimEnd")},function(t,n,r){r(153)("asyncIterator")},function(t,n,r){r(153)("observable")},function(t,n,r){var e=r(1);e(e.S,"System",{global:r(3)})},function(t,n,r){for(var e=r(155),i=r(28),o=r(3),u=r(27),c=r(80),f=r(7),a=f("iterator"),s=f("toStringTag"),l=c.Array,h=["NodeList","DOMTokenList","MediaList","StyleSheetList","CSSRuleList"],v=0;v<5;v++){var p,d=h[v],y=o[d],g=y&&y.prototype;if(g){g[a]||u(g,a,l),g[s]||u(g,s,d),c[d]=l;for(p in e)g[p]||i(g,p,e[p],!0)}}},function(t,n,r){var e=r(1),i=r(151);e(e.G+e.B,{setImmediate:i.set,clearImmediate:i.clear})},function(t,n,r){var e=r(3),i=r(1),o=r(121),u=r(206),c=e.navigator,f=!!c&&/MSIE .\./.test(c.userAgent),a=function(t){return f?function(n,r){return t(o(u,[].slice.call(arguments,2),"function"==typeof n?n:Function(n)),r)}:t};i(i.G+i.B+i.F*f,{setTimeout:a(e.setTimeout),setInterval:a(e.setInterval)})},function(t,n,r){r(329),r(268),r(270),r(269),r(272),r(274),r(279),r(273),r(271),r(281),r(280),r(276),r(277),r(275),r(267),r(278),r(282),r(283),r(235),r(237),r(236),r(285),r(284),r(255),r(265),r(266),r(256),r(257),r(258),r(259),r(260),r(261),r(262),r(263),r(264),r(238),r(239),r(240),r(241),r(242),r(243),r(244),r(245),r(246),r(247),r(248),r(249),r(250),r(251),r(252),r(253),r(254),r(316),r(321),r(328),r(319),r(311),r(312),r(317),r(322),r(324),r(307),r(308),r(309),r(310),r(313),r(314),r(315),r(318),r(320),r(323),r(325),r(326),r(327),r(230),r(232),r(231),r(234),r(233),r(219),r(217),r(223),r(220),r(226),r(228),r(216),r(222),r(213),r(227),r(211),r(225),r(224),r(218),r(221),r(210),r(212),r(215),r(214),r(229),r(155),r(301),r(306),r(184),r(302),r(303),r(304),r(305),r(286),r(183),r(185),r(186),r(341),r(330),r(331),r(336),r(339),r(340),r(334),r(337),r(335),r(338),r(332),r(333),r(287),r(288),r(289),r(290),r(291),r(294),r(292),r(293),r(295),r(296),r(297),r(298),r(300),r(299),r(342),r(368),r(371),r(370),r(372),r(373),r(369),r(374),r(375),r(353),r(356),r(352),r(350),r(351),r(354),r(355),r(345),r(367),r(376),r(344),r(346),r(348),r(347),r(349),r(358),r(359),r(361),r(360),r(363),r(362),r(364),r(365),r(366),r(343),r(357),r(379),r(378),r(377),t.exports=r(52)},function(t,n){function r(t,n){if("string"==typeof n)return t.insertAdjacentHTML("afterend",n);var r=t.nextSibling;return r?t.parentNode.insertBefore(n,r):t.parentNode.appendChild(n)}t.exports=r},,,,,,,,,function(t,n,r){(function(n,r){!function(n){"use strict";function e(t,n,r,e){var i=n&&n.prototype instanceof o?n:o,u=Object.create(i.prototype),c=new p(e||[]);return u._invoke=s(t,r,c),u}function i(t,n,r){try{return{type:"normal",arg:t.call(n,r)}}catch(t){return{type:"throw",arg:t}}}function o(){}function u(){}function c(){}function f(t){["next","throw","return"].forEach(function(n){t[n]=function(t){return this._invoke(n,t)}})}function a(t){function n(r,e,o,u){var c=i(t[r],t,e);if("throw"!==c.type){var f=c.arg,a=f.value;return a&&"object"==typeof a&&m.call(a,"__await")?Promise.resolve(a.__await).then(function(t){n("next",t,o,u)},function(t){n("throw",t,o,u)}):Promise.resolve(a).then(function(t){f.value=t,o(f)},u)}u(c.arg)}function e(t,r){function e(){return new Promise(function(e,i){n(t,r,e,i)})}return o=o?o.then(e,e):e()}"object"==typeof r&&r.domain&&(n=r.domain.bind(n));var o;this._invoke=e}function s(t,n,r){var e=P;return function(o,u){if(e===F)throw new Error("Generator is already running");if(e===M){if("throw"===o)throw u;return y()}for(r.method=o,r.arg=u;;){var c=r.delegate;if(c){var f=l(c,r);if(f){if(f===A)continue;return f}}if("next"===r.method)r.sent=r._sent=r.arg;else if("throw"===r.method){if(e===P)throw e=M,r.arg;r.dispatchException(r.arg)}else"return"===r.method&&r.abrupt("return",r.arg);e=F;var a=i(t,n,r);if("normal"===a.type){if(e=r.done?M:j,a.arg===A)continue;return{value:a.arg,done:r.done}}"throw"===a.type&&(e=M,r.method="throw",r.arg=a.arg)}}}function l(t,n){var r=t.iterator[n.method];if(r===g){if(n.delegate=null,"throw"===n.method){if(t.iterator.return&&(n.method="return",n.arg=g,l(t,n),"throw"===n.method))return A;n.method="throw",n.arg=new TypeError("The iterator does not provide a 'throw' method")}return A}var e=i(r,t.iterator,n.arg);if("throw"===e.type)return n.method="throw",n.arg=e.arg,n.delegate=null,A;var o=e.arg;return o?o.done?(n[t.resultName]=o.value,n.next=t.nextLoc,"return"!==n.method&&(n.method="next",n.arg=g),n.delegate=null,A):o:(n.method="throw",n.arg=new TypeError("iterator result is not an object"),n.delegate=null,A)}function h(t){var n={tryLoc:t[0]};1 in t&&(n.catchLoc=t[1]),2 in t&&(n.finallyLoc=t[2],n.afterLoc=t[3]),this.tryEntries.push(n)}function v(t){var n=t.completion||{};n.type="normal",delete n.arg,t.completion=n}function p(t){this.tryEntries=[{tryLoc:"root"}],t.forEach(h,this),this.reset(!0)}function d(t){if(t){var n=t[w];if(n)return n.call(t);if("function"==typeof t.next)return t;if(!isNaN(t.length)){var r=-1,e=function n(){for(;++r<t.length;)if(m.call(t,r))return n.value=t[r],n.done=!1,n;return n.value=g,n.done=!0,n};return e.next=e}}return{next:y}}function y(){return{value:g,done:!0}}var g,b=Object.prototype,m=b.hasOwnProperty,x="function"==typeof Symbol?Symbol:{},w=x.iterator||"@@iterator",S=x.asyncIterator||"@@asyncIterator",_=x.toStringTag||"@@toStringTag",O="object"==typeof t,E=n.regeneratorRuntime;if(E)return void(O&&(t.exports=E));E=n.regeneratorRuntime=O?t.exports:{},E.wrap=e;var P="suspendedStart",j="suspendedYield",F="executing",M="completed",A={},N={};N[w]=function(){return this};var T=Object.getPrototypeOf,I=T&&T(T(d([])));I&&I!==b&&m.call(I,w)&&(N=I);var k=c.prototype=o.prototype=Object.create(N);u.prototype=k.constructor=c,c.constructor=u,c[_]=u.displayName="GeneratorFunction",E.isGeneratorFunction=function(t){var n="function"==typeof t&&t.constructor;return!!n&&(n===u||"GeneratorFunction"===(n.displayName||n.name))},E.mark=function(t){return Object.setPrototypeOf?Object.setPrototypeOf(t,c):(t.__proto__=c,_ in t||(t[_]="GeneratorFunction")),t.prototype=Object.create(k),t},E.awrap=function(t){return{__await:t}},f(a.prototype),a.prototype[S]=function(){return this},E.AsyncIterator=a,E.async=function(t,n,r,i){var o=new a(e(t,n,r,i));return E.isGeneratorFunction(n)?o:o.next().then(function(t){return t.done?t.value:o.next()})},f(k),k[_]="Generator",k.toString=function(){return"[object Generator]"},E.keys=function(t){var n=[];for(var r in t)n.push(r);return n.reverse(),function r(){for(;n.length;){var e=n.pop();if(e in t)return r.value=e,r.done=!1,r}return r.done=!0,r}},E.values=d,p.prototype={constructor:p,reset:function(t){if(this.prev=0,this.next=0,this.sent=this._sent=g,this.done=!1,this.delegate=null,this.method="next",this.arg=g,this.tryEntries.forEach(v),!t)for(var n in this)"t"===n.charAt(0)&&m.call(this,n)&&!isNaN(+n.slice(1))&&(this[n]=g)},stop:function(){this.done=!0;var t=this.tryEntries[0],n=t.completion;if("throw"===n.type)throw n.arg;return this.rval},dispatchException:function(t){function n(n,e){return o.type="throw",o.arg=t,r.next=n,e&&(r.method="next",r.arg=g),!!e}if(this.done)throw t;for(var r=this,e=this.tryEntries.length-1;e>=0;--e){var i=this.tryEntries[e],o=i.completion;if("root"===i.tryLoc)return n("end");if(i.tryLoc<=this.prev){var u=m.call(i,"catchLoc"),c=m.call(i,"finallyLoc");if(u&&c){if(this.prev<i.catchLoc)return n(i.catchLoc,!0);if(this.prev<i.finallyLoc)return n(i.finallyLoc)}else if(u){if(this.prev<i.catchLoc)return n(i.catchLoc,!0)}else{if(!c)throw new Error("try statement without catch or finally");if(this.prev<i.finallyLoc)return n(i.finallyLoc)}}}},abrupt:function(t,n){for(var r=this.tryEntries.length-1;r>=0;--r){var e=this.tryEntries[r];if(e.tryLoc<=this.prev&&m.call(e,"finallyLoc")&&this.prev<e.finallyLoc){var i=e;break}}i&&("break"===t||"continue"===t)&&i.tryLoc<=n&&n<=i.finallyLoc&&(i=null);var o=i?i.completion:{};return o.type=t,o.arg=n,i?(this.method="next",this.next=i.finallyLoc,A):this.complete(o)},complete:function(t,n){if("throw"===t.type)throw t.arg;return"break"===t.type||"continue"===t.type?this.next=t.arg:"return"===t.type?(this.rval=this.arg=t.arg,this.method="return",this.next="end"):"normal"===t.type&&n&&(this.next=n),A},finish:function(t){for(var n=this.tryEntries.length-1;n>=0;--n){var r=this.tryEntries[n];if(r.finallyLoc===t)return this.complete(r.completion,r.afterLoc),v(r),A}},catch:function(t){for(var n=this.tryEntries.length-1;n>=0;--n){var r=this.tryEntries[n];if(r.tryLoc===t){var e=r.completion;if("throw"===e.type){var i=e.arg;v(r)}return i}}throw new Error("illegal catch attempt")},delegateYield:function(t,n,r){return this.delegate={iterator:d(t),resultName:n,nextLoc:r},"next"===this.method&&(this.arg=g),A}}}("object"==typeof n?n:"object"==typeof window?window:"object"==typeof self?self:this)}).call(n,function(){return this}(),r(158))}])</script><script src="/./main.b3331d.js"></script><script>!function(){!function(e){var t=document.createElement("script");document.getElementsByTagName("body")[0].appendChild(t),t.setAttribute("src",e)}("/slider.445162.js")}()</script>
<div class="tools-col" q-class="show:isShow,hide:isShow|isFalse" q-on="click:stop(e)">
<div class="tools-nav header-menu">