From 2014efaa305779f372bdb35f924d73db72b14df2 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Tue, 6 Aug 2019 13:35:08 +0300 Subject: [PATCH 001/160] remove old images --- src/resources/Brithish flag.png | Bin 2260 -> 0 bytes src/resources/Cloud Icon Acitve.png | Bin 514 -> 0 bytes src/resources/Cloud Icon.png | Bin 3161 -> 0 bytes src/resources/CloudCoinLogo2.png | Bin 3220 -> 0 bytes src/resources/Envelope.png | Bin 624 -> 0 bytes src/resources/Gear icon.png | Bin 1335 -> 0 bytes src/resources/Help_Support Icon.png | Bin 1304 -> 0 bytes src/resources/Image 34.png | Bin 497 -> 0 bytes src/resources/Image 41.png | Bin 629 -> 0 bytes src/resources/Lock Icon Disabled.png | Bin 3080 -> 0 bytes src/resources/Lock Icon.png | Bin 460 -> 0 bytes src/resources/arrow.png | Bin 259 -> 0 bytes src/resources/checkbox.png | Bin 3023 -> 0 bytes src/resources/checkboxChecked.png | Bin 3625 -> 0 bytes src/resources/dummy.png | Bin 2819 -> 0 bytes src/resources/eye.png | Bin 5476 -> 0 bytes src/resources/lg.png | Bin 7964 -> 0 bytes src/resources/lg0.png | Bin 684 -> 0 bytes src/resources/radio.png | Bin 3301 -> 0 bytes src/resources/radio1.png | Bin 451 -> 0 bytes src/resources/radioChecked.png | Bin 3695 -> 0 bytes 21 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 src/resources/Brithish flag.png delete mode 100644 src/resources/Cloud Icon Acitve.png delete mode 100644 src/resources/Cloud Icon.png delete mode 100644 src/resources/CloudCoinLogo2.png delete mode 100644 src/resources/Envelope.png delete mode 100644 src/resources/Gear icon.png delete mode 100644 src/resources/Help_Support Icon.png delete mode 100644 src/resources/Image 34.png delete mode 100644 src/resources/Image 41.png delete mode 100644 src/resources/Lock Icon Disabled.png delete mode 100644 src/resources/Lock Icon.png delete mode 100644 src/resources/arrow.png delete mode 100644 src/resources/checkbox.png delete mode 100644 src/resources/checkboxChecked.png delete mode 100644 src/resources/dummy.png delete mode 100644 src/resources/eye.png delete mode 100644 src/resources/lg.png delete mode 100644 src/resources/lg0.png delete mode 100644 src/resources/radio.png delete mode 100644 src/resources/radio1.png delete mode 100644 src/resources/radioChecked.png diff --git a/src/resources/Brithish flag.png b/src/resources/Brithish flag.png deleted file mode 100644 index 702cea2558194fc6f4d7acece9175e2091143832..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2260 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 diff --git a/src/resources/CloudCoinLogo2.png b/src/resources/CloudCoinLogo2.png deleted file mode 100644 index a58e5fb92ca68323481e70b4067b0dce9b26ea66..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3220 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 diff --git a/src/resources/Help_Support Icon.png b/src/resources/Help_Support Icon.png deleted file mode 100644 index 84d2ac55d05929cb3ec738e669b70a63d6be9711..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1304 zcmV+z1?T#SP)Px((n&-?R9FeEm|cifRTRh1#~lYG0wE_gl4%N~EHs%ZuuzJ$!otWB5kiEdr=Sl) zd=LkTpbzr3r=W+%qC_oB=&_(DOR-@FWvrYS8gX(WN}V}#&hEFacb~h@zI&g!=Q`)I z*=w)$U;p(#AA6sDZWvTNlu}Dcd0GYPIr=`@l196g{vX=3G~#1X5S_q25r*Lv`h`Cb z^Ju2BA7~k^$}g2X$zL#4kgbCBSS1;L$w%S4`=-P}@B(6H7D$kmIs@<4j)al;R*9IA zRHcW&JVSec)=g@M90J%#;+!SwZ}AtAosHmm3hrr(e-3|PW`>%cz+%>x z-xrgE2p?vh`As`?557CdvR#2v{j{|~81@i5hdqKl9K`VudDk>v_vGC}ogW#S zbuLq<7yMO?tM^>qcdawH4ncnb)EMAjr;=n?&2f_cb^**LPyPV4X3ctXdka{Kth7P+ z4irF5LF*Bcl!&o~?sV}WV$c+YEf--$js@_Z1sDg=odcSJx|~-iNlqd1Fm1{q_Aj`W zIk>v1dC{yZI&vI=aWe>sb8%B?`kJHY9!*4E7x7P9FlqXx#+W_$ZDw8Ui}g5xek(9x zCYmlJCv9*zj#EU~W8fpV>G)ruH9Zee%~uS&(hl0O^?-$IP*1uPuzD=)1!B z#^AKWH{r5aPQFvA+#jU1#6&LCt7_=Iu3j0911QpfW?O&`l`ZG_>d zHtn8z-y-Z)?UyAe;L;6Smv5y8RP7Po$E};NZlAmj*7&%H^_umue-TlaO(!7PtW`e9 z+khC??EAQkjJzdgee6jQm6%RIaT$p##xn6Zg05OuNY<+%__|y<+9z?dKK87Lx@0;5 z$?Kx+1NOKqel{GFM+V#+L zrp7vP5@WBnuno~h%OuVpC3xkDoaR_P$)FXAwk ziBo@xK4K{*NA1>NUk_%$S_%|v)}Rk>`pMnns5xL_0`@YWTcBwY?=66=L8qd~TTQLP zUY+`fE&BS^S`P5KC2RtM-WG7f(TON>`lwM@u%#~k<+_e6p7n$0=TDxaU3%Q;S8$(C zlkkM)?`R0mlkojavbjLB?1wK)eJ?4A`>d-apW7*ycaYd3Z(>P6^2qmn_q|<`+6+Np z@7eYL01N$v+}x8l%lj?PPQH{2I|$7~C&Q=t6mb`;i z#LT-1b7`i)9r(BMhJTRhEdR_&6Q6vZU0~Y(%8T_3_BTv*?Px$t4TybR9Fe^mbpp#6NV-HioUV9x`v$Bg&J06YN1MF93FCfG*1 zU`Hvmg;r4)DjMQ!17+=1y;qvE6BK$j#p>impa+?MY1S*CZ4VhQWzR11AbI=PhfBVW z@`S)%q4av&FAY|J3rEPAQ#x%z#4(=L6wBO??VUuQc`)C_70_glk&g5m1@i5m@COCwVOZ-BDPDo+NqC0WF`1 zZQlme%#11SexO#{Lty1tj4Gy~$%5YDesr+v+ziPlQm3PaRp?og7qp3@byi`$bqCx5 ncfcKR2iyU7z#VW0{-XoGl$7zyh+ckU00000NkvXXu0mjfxIx?I diff --git a/src/resources/Image 41.png b/src/resources/Image 41.png deleted file mode 100644 index 955fbf6c2215eb0a0b57519324bbc22d78ec7269..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 629 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 W7f0;EjzYiy0000cFP} diff --git a/src/resources/Lock Icon.png b/src/resources/Lock Icon.png deleted file mode 100644 index 1eed2d8057c1a4fd1794f2f070058f7817c079f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 460 zcmV;-0WPx$hDk(0R7ef&le(%U5%`lvd3zV^f;yezJGeEYo|U&7Iv^ecuiCtoB-87gU(*>$j|I3}Kl9&pvogXU^8I<4kk!2(p0cDx1;phovF z17(_~DBCq(7i|*?omBH8$*L5(O!0(KCn?h*MOiL&KnjEKO}<6@nJF7v%p2#7ZzlE) zvh~yy^`16dX;E#)-H_~RL{HA7e2=W;HqMd+_JnTkH*sN~_FN}zLOFdCcSFkQxA{r# z#nFQ5BVIxFe<{D{IN2o_0>xIknXC4pWSnwpDe*Ggzz*o2F4P=Z{T{mZq0n!)2$@_9 zvt+Y_xM))yj`l`-gE$Z`QV<(`O`^R%XM*Ja#okXMZ(Dh6xfMbH0000d1`I-U*SYLi%5D~d|=+L24Etj}wR0w;YThV&&(2d913JV1U@AB4{s#U%< z5_WQ&#t78Q!0<<~I`?fs`BK?EPy3@5-`%?Q;oaV{?ELF-pF)2(9J5%Ye?RxRU_eIt z=XXx69AInCK7OtRPGGpJWa?R(E7q)h#^`*VEO{Wt~$(695oa BX~_Tp diff --git a/src/resources/checkbox.png b/src/resources/checkbox.png deleted file mode 100644 index 80d1414cfb117362523a80af4939f5ab2ea278a0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3023 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 RPXzz~002ovPDHLkV1m!Jn=1eS diff --git a/src/resources/checkboxChecked.png b/src/resources/checkboxChecked.png deleted file mode 100644 index 36db0b391c36e1310bb30415ef310bdcb241d63e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3625 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 diff --git a/src/resources/dummy.png b/src/resources/dummy.png deleted file mode 100644 index ec952465374d941803404d2b742844ca2e733f27..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2819 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 V12@!O*iirg002ovPDHLkV1hk)HroII diff --git a/src/resources/eye.png b/src/resources/eye.png deleted file mode 100644 index 80291a9881c8b464180d7b6b4845a0610d102cfc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 5476 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 diff --git a/src/resources/lg0.png b/src/resources/lg0.png deleted file mode 100644 index 81dfc7aff29d92640eaeaf61c783889cba8bf2d0..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 684 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 diff --git a/src/resources/radio1.png b/src/resources/radio1.png deleted file mode 100644 index 0e352e977325993fda709a9ae6ca7953eb872090..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 451 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 N002ovPDHLkV1m~U=CS|) From 38bb2f580651dae78373694bf70ddeb4e5152a03 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Tue, 6 Aug 2019 19:08:20 +0300 Subject: [PATCH 002/160] Agreement skin --- src/advclient/AdvancedClient.java | 465 +++++++++++++++++----------- src/advclient/AppUI.java | 24 +- src/advclient/ImageJPanel.java | 4 +- src/advclient/MyButton.java | 8 +- src/advclient/MyCheckBox.java | 5 + src/resources/CloudCoinLogo.png | Bin 0 -> 6622 bytes src/resources/CloudCoinText.png | Bin 0 -> 6367 bytes src/resources/bglogo.png | Bin 0 -> 5133 bytes src/resources/checkbox.png | Bin 0 -> 3012 bytes src/resources/checkboxchecked.png | Bin 0 -> 3252 bytes src/resources/coinsicon.png | Bin 0 -> 5861 bytes src/resources/coinsiconlight.png | Bin 0 -> 6213 bytes src/resources/depositicon.png | Bin 0 -> 4245 bytes src/resources/depositiconlight.png | Bin 0 -> 4267 bytes src/resources/gears.png | Bin 0 -> 4293 bytes src/resources/supporticon.png | Bin 0 -> 3109 bytes src/resources/transfericon.png | Bin 0 -> 5544 bytes src/resources/transfericonlight.png | Bin 0 -> 5724 bytes src/resources/vaulticon.png | Bin 0 -> 4626 bytes src/resources/vaulticonlight.png | Bin 0 -> 4671 bytes src/resources/walleticon.png | Bin 0 -> 3954 bytes src/resources/walleticonlight.png | Bin 0 -> 3845 bytes src/resources/walletlefticon.png | Bin 0 -> 3894 bytes 23 files changed, 312 insertions(+), 194 deletions(-) create mode 100644 src/resources/CloudCoinLogo.png create mode 100644 src/resources/CloudCoinText.png create mode 100644 src/resources/bglogo.png create mode 100644 src/resources/checkbox.png create mode 100644 src/resources/checkboxchecked.png create mode 100644 src/resources/coinsicon.png create mode 100644 src/resources/coinsiconlight.png create mode 100644 src/resources/depositicon.png create mode 100644 src/resources/depositiconlight.png create mode 100644 src/resources/gears.png create mode 100644 src/resources/supporticon.png create mode 100644 src/resources/transfericon.png create mode 100644 src/resources/transfericonlight.png create mode 100644 src/resources/vaulticon.png create mode 100644 src/resources/vaulticonlight.png create mode 100644 src/resources/walleticon.png create mode 100644 src/resources/walleticonlight.png create mode 100644 src/resources/walletlefticon.png diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index f3cd349..5cc70d7 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -44,6 +44,7 @@ import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.plaf.ColorUIResource; import javax.swing.plaf.MenuItemUI; +import javax.swing.plaf.basic.BasicScrollBarUI; import javax.swing.table.DefaultTableCellRenderer; @@ -55,7 +56,7 @@ public class AdvancedClient { JPanel headerPanel; JPanel mainPanel; - JPanel corePanel; + ImageJPanel corePanel; JPanel wpanel; JPanel lwrapperPanel; @@ -351,7 +352,7 @@ public void initMainScreen() { AppUI.setBoxLayout(mainPanel, true); AppUI.setSize(mainPanel, tw, th); - AppUI.setBackground(mainPanel, AppUI.getColor1()); + AppUI.setBackground(mainPanel, AppUI.getColor4()); mainFrame = AppUI.getMainFrame(version); mainFrame.setContentPane(mainPanel); @@ -418,179 +419,195 @@ public void fillHeaderPanel() { GridBagConstraints c = new GridBagConstraints(); //c.fill = GridBagConstraints.HORIZONTAL; c.anchor = GridBagConstraints.WEST; - c.insets = new Insets(0, 10, 0, 0); c.gridx = GridBagConstraints.RELATIVE; c.gridy = 0; JLabel icon0, icon1, icon2, icon3; + final JLabel depositIcon, transferIcon, coinsIcon; + final ImageIcon depositIi, transferIi, depositIiLight, transferIiLight; ImageIcon ii; try { Image img; - img = ImageIO.read(getClass().getClassLoader().getResource("resources/Gear icon.png")); - icon0 = new JLabel(new ImageIcon(img)); - + img = ImageIO.read(getClass().getClassLoader().getResource("resources/gears.png")); + icon0 = new JLabel(new ImageIcon(img)); ii = new ImageIcon(img); - img = ImageIO.read(getClass().getClassLoader().getResource("resources/Help_Support Icon.png")); + img = ImageIO.read(getClass().getClassLoader().getResource("resources/supporticon.png")); icon1 = new JLabel(new ImageIcon(img)); - img = ImageIO.read(getClass().getClassLoader().getResource("resources/CloudCoinLogo2.png")); + img = ImageIO.read(getClass().getClassLoader().getResource("resources/CloudCoinText.png")); + icon2 = new JLabel(new ImageIcon(img)); + + img = ImageIO.read(getClass().getClassLoader().getResource("resources/CloudCoinLogo.png")); icon3 = new JLabel(new ImageIcon(img)); + img = ImageIO.read(getClass().getClassLoader().getResource("resources/depositicon.png")); + depositIi = new ImageIcon(img); + depositIcon = new JLabel(new ImageIcon(img)); + + img = ImageIO.read(getClass().getClassLoader().getResource("resources/transfericon.png")); + transferIi = new ImageIcon(img); + transferIcon = new JLabel(new ImageIcon(img)); + + img = ImageIO.read(getClass().getClassLoader().getResource("resources/coinsicon.png")); + coinsIcon = new JLabel(new ImageIcon(img)); + + img = ImageIO.read(getClass().getClassLoader().getResource("resources/depositiconlight.png")); + depositIiLight = new ImageIcon(img); + + img = ImageIO.read(getClass().getClassLoader().getResource("resources/transfericonlight.png")); + transferIiLight = new ImageIcon(img); + } catch (Exception ex) { + wl.error(ltag, "Failed to open file: " + ex.getMessage()); return; } headerPanel.add(p); + + c.insets = new Insets(0, 12, 0, 0); gridbag.setConstraints(icon3, c); p.add(icon3); + c.insets = new Insets(0, 20, 0, 0); + gridbag.setConstraints(icon2, c); + p.add(icon2); + + JLabel wlabel = new JLabel("wallet"); + AppUI.setTitleFont(wlabel, 20); + AppUI.setColor(wlabel, AppUI.getColor1()); + c.insets = new Insets(6, 10, 0, 0); + gridbag.setConstraints(wlabel, c); + p.add(wlabel); + + JPanel wrp = new JPanel(); + AppUI.setBoxLayout(wrp, false); + AppUI.setSize(wrp, 296, headerHeight); + AppUI.noOpaque(wrp); + + + if (ps.currentScreen == ProgramState.SCREEN_AGREEMENT) { // Init Label - JLabel titleText = new JLabel("CloudCoin Wallet " + version); - AppUI.setTitleSemiBoldFont(titleText, 32); + JLabel titleText = new JLabel(""); + AppUI.setTitleFont(titleText, 20); c.anchor = GridBagConstraints.WEST; c.insets = new Insets(0, 10, 0, tw ); c.gridx = GridBagConstraints.RELATIVE; c.gridy = 0; - - - gridbag.setConstraints(titleText, c); - p.add(titleText); + gridbag.setConstraints(wrp, c); + wrp.add(titleText); + p.add(wrp); return; } else { - JLabel titleText = new JLabel("Total Coins: "); - AppUI.setTitleSemiBoldFont(titleText, 32); - c.insets = new Insets(0, 10, 0, 0); - gridbag.setConstraints(titleText, c); - p.add(titleText); - - - c.insets = new Insets(15, 10, 0, 0); - JPanel wrp = new JPanel(); - AppUI.setBoxLayout(wrp, false); - AppUI.setSize(wrp, 216, 32); - AppUI.noOpaque(wrp); + int bwidth = 168; + // Coins + wrp.add(coinsIcon); + wrp.add(AppUI.vr(16)); + JLabel titleText = new JLabel("Coins: "); + AppUI.setTitleFont(titleText, 20); + wrp.add(titleText); totalText = new JLabel("0"); - AppUI.setTitleFont(totalText, 32); - //AppUI.setSize(totalText, 100, 32); - //gridbag.setConstraints(totalText, c); - //p.add(totalText); - - + AppUI.setTitleFont(totalText, 26); + AppUI.setMargin(totalText, 0, 0, 4, 0); wrp.add(totalText); - - c.anchor = GridBagConstraints.NORTH; + titleText = new JLabel("cc"); AppUI.setTitleFont(titleText, 16); - AppUI.setSize(titleText, 40, 40); - AppUI.alignBottom(titleText); - AppUI.setMargin(titleText, 0, 6, 0, 0); - + AppUI.setMargin(titleText, 0, 6, 16, 0); wrp.add(titleText); - + + c.insets = new Insets(0, 32, 0, 0); + c.anchor = GridBagConstraints.NORTH; gridbag.setConstraints(wrp, c); p.add(wrp); - - c.anchor = GridBagConstraints.CENTER; - - // Pad - c.weightx = 1; - JLabel padd0 = new JLabel(); - gridbag.setConstraints(padd0, c); - //p.add(padd0); - c.weightx = 0; - c.insets = new Insets(0, 10, 0, 60); - - // Deposit Button - final JButton b0 = new JButton("Deposit"); - b0.setContentAreaFilled(false); - b0.setFocusPainted(false); - b0.setBorderPainted(false); - AppUI.noOpaque(b0); - AppUI.setTitleBoldFont(b0, 32); - if (ps.defaultWalletCreated) - AppUI.setHandCursor(b0); + // Deposit + JPanel wrpDeposit = new JPanel(); + AppUI.setBoxLayout(wrpDeposit, false); + AppUI.setSize(wrpDeposit, bwidth, headerHeight); + AppUI.setBackground(wrpDeposit, AppUI.getColor1()); + AppUI.noOpaque(wrpDeposit); + + wrpDeposit.add(AppUI.vr(12)); + + wrpDeposit.add(depositIcon); if (isDepositing()) { - AppUI.underLine(b0); - } else { - AppUI.noUnderLine(b0); + depositIcon.setIcon(depositIiLight); + } else { + AppUI.setHandCursor(wrpDeposit); + depositIcon.setIcon(depositIi); } + + wrpDeposit.add(AppUI.vr(6)); - gridbag.setConstraints(b0, c); - p.add(b0); - c.insets = new Insets(0, 10, 0, 0); - - // Transfer Button - final JButton b1 = new JButton("Transfer"); + titleText = new JLabel("Deposit"); + AppUI.setTitleFont(titleText, 20); + wrpDeposit.add(titleText); - b1.setContentAreaFilled(false); - b1.setBorderPainted(false); - b1.setFocusPainted(false); - AppUI.setTitleBoldFont(b1, 32); - if (ps.defaultWalletCreated) - AppUI.setHandCursor(b1); + c.insets = new Insets(0, 32, 0, 0); + c.anchor = GridBagConstraints.NORTH; + gridbag.setConstraints(wrpDeposit, c); + p.add(wrpDeposit); + + // Transfer + JPanel wrpTransfer = new JPanel(); + AppUI.setBoxLayout(wrpTransfer, false); + AppUI.setSize(wrpTransfer, bwidth, headerHeight); + AppUI.setBackground(wrpTransfer, AppUI.getColor1()); + AppUI.noOpaque(wrpTransfer); + + wrpTransfer.add(AppUI.vr(12)); if (isWithdrawing()) { - AppUI.underLine(b1); - } else { - AppUI.noUnderLine(b1); + transferIcon.setIcon(transferIiLight); + } else { + AppUI.setHandCursor(wrpTransfer); + transferIcon.setIcon(transferIi); } + + wrpTransfer.add(transferIcon); + wrpTransfer.add(AppUI.vr(12)); - gridbag.setConstraints(b1, c); - p.add(b1); - - ActionListener al0 = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (!ps.defaultWalletCreated) - return; - - JButton b = (JButton) e.getSource(); - - resetState(); - ps.currentScreen = ProgramState.SCREEN_PREDEPOSIT; - showScreen(); - } - }; + titleText = new JLabel("Transfer"); + AppUI.setTitleFont(titleText, 20); + wrpTransfer.add(titleText); - ActionListener al1 = new ActionListener() { - @Override - public void actionPerformed(ActionEvent e) { - if (!ps.defaultWalletCreated) - return; - - JButton b = (JButton) e.getSource(); - - resetState(); - ps.currentScreen = ProgramState.SCREEN_WITHDRAW; - showScreen(); - } - }; + c.insets = new Insets(0, 32, 0, 0); + c.anchor = GridBagConstraints.NORTH; + gridbag.setConstraints(wrpTransfer, c); + p.add(wrpTransfer); MouseAdapter ma0 = new MouseAdapter() { + public void mouseReleased(MouseEvent e) { + + } public void mouseEntered(MouseEvent e) { if (!ps.defaultWalletCreated) return; - JButton b = (JButton) e.getSource(); - - AppUI.underLine(b); + JPanel p = (JPanel) e.getSource(); + AppUI.opaque(p); + depositIcon.setIcon(depositIiLight); + p.revalidate(); + p.repaint(); } public void mouseExited(MouseEvent e) { if (!ps.defaultWalletCreated) return; - JButton b = (JButton) e.getSource(); - - if (!isDepositing()) - AppUI.noUnderLine(b); + JPanel p = (JPanel) e.getSource(); + if (!isDepositing()) { + AppUI.noOpaque(p); + depositIcon.setIcon(depositIi); + p.revalidate(); + p.repaint(); + } } }; @@ -599,34 +616,31 @@ public void mouseEntered(MouseEvent e) { if (!ps.defaultWalletCreated) return; - JButton b = (JButton) e.getSource(); - - AppUI.underLine(b); + JPanel p = (JPanel) e.getSource(); + AppUI.opaque(p); + transferIcon.setIcon(transferIiLight); + p.revalidate(); + p.repaint(); } public void mouseExited(MouseEvent e) { if (!ps.defaultWalletCreated) return; - JButton b = (JButton) e.getSource(); - - if (!isWithdrawing()) - AppUI.noUnderLine(b); + JPanel p = (JPanel) e.getSource(); + if (!isWithdrawing()) { + AppUI.noOpaque(p); + transferIcon.setIcon(transferIi); + p.revalidate(); + p.repaint(); + } } }; - - b0.addActionListener(al0); - b1.addActionListener(al1); - b0.addMouseListener(ma0); - b1.addMouseListener(ma1); - } - c.weightx = 1; - JLabel padd = new JLabel(); - gridbag.setConstraints(padd, c); - p.add(padd); - + wrpDeposit.addMouseListener(ma0); + wrpTransfer.addMouseListener(ma1); + } - c.fill = GridBagConstraints.NONE; + c.insets = new Insets(0, 42, 0, 0); c.gridwidth = 1; c.weightx = 0; c.fill = GridBagConstraints.NORTH; @@ -636,7 +650,7 @@ public void mouseExited(MouseEvent e) { AppUI.setHandCursor(icon0); gridbag.setConstraints(icon0, c); - AppUI.setSize(icon0, 52, 70); + AppUI.setSize(icon0, 52, 72); p.add(icon0); @@ -649,7 +663,7 @@ public void mouseExited(MouseEvent e) { final JPopupMenu popupMenu = new JPopupMenu() { @Override public void paintComponent(final Graphics g) { - g.setColor(AppUI.getColor6()); + g.setColor(AppUI.getColor1()); g.fillRect(0,0,getWidth(), getHeight()); } }; @@ -663,12 +677,12 @@ public void paintComponent(final Graphics g) { MouseAdapter ma = new MouseAdapter() { public void mouseEntered(MouseEvent evt) { JMenuItem jMenuItem = (JMenuItem) evt.getSource(); - jMenuItem.setBackground(AppUI.getColor0()); + jMenuItem.setBackground(AppUI.getColor2()); } public void mouseExited(MouseEvent evt) { JMenuItem jMenuItem = (JMenuItem) evt.getSource(); - jMenuItem.setBackground(AppUI.getColor6()); + jMenuItem.setBackground(AppUI.getColor1()); } public void mouseReleased(MouseEvent evt) { @@ -703,7 +717,7 @@ public void mouseReleased(MouseEvent evt) { AppUI.setFont(menuItem, 28); menuItem.setOpaque(true); - menuItem.setBackground(AppUI.getColor6()); + menuItem.setBackground(AppUI.getColor1()); menuItem.setBorder(BorderFactory.createEmptyBorder(0,0,0,0)); menuItem.setUI(new MenuItemUI() { public void paint (final Graphics g, final JComponent c) { @@ -754,7 +768,7 @@ public void mouseReleased(MouseEvent e) { if (!ps.defaultWalletCreated) return; ficon.setOpaque(true); - AppUI.setBackground(ficon, AppUI.getColor6()); + AppUI.setBackground(ficon, AppUI.getColor1()); ficon.repaint(); popupMenu.show(ficon, 0 - mWidth + ficon.getWidth(), ficon.getHeight()); @@ -763,7 +777,7 @@ public void mouseReleased(MouseEvent e) { // Icon Support - c.insets = new Insets(0, 10, 0, 20); + c.insets = new Insets(26, 24, 0, 20); AppUI.noOpaque(icon1); AppUI.setHandCursor(icon1); gridbag.setConstraints(icon1, c); @@ -774,23 +788,17 @@ public void mouseReleased(MouseEvent e) { showScreen(); } }); - - // Version - c.insets = new Insets(0, 0, 20, 10); - JLabel vl = new JLabel("v. " + version); - AppUI.noOpaque(vl); - AppUI.setTitleFont(vl, 14); - gridbag.setConstraints(vl, c); - p.add(vl); + headerPanel.add(p); } public void initCorePanel() { - corePanel = new JPanel(); + corePanel = new ImageJPanel("bglogo.png"); AppUI.setBoxLayout(corePanel, false); - AppUI.noOpaque(corePanel); + AppUI.setSize(corePanel, tw, th - headerHeight); + AppUI.setBackground(corePanel, AppUI.getColor4()); AppUI.alignLeft(corePanel); AppUI.setMargin(corePanel, 20); } @@ -817,8 +825,15 @@ public void resetState() { public void showScreen() { wl.debug(ltag, "SCREEN " + ps.currentScreen + ": " + ps.toString()); - clear(); + + ps.currentScreen = ProgramState.SCREEN_AGREEMENT; + clear(); + showAgreementScreen(); + if (1==1) + return; + + switch (ps.currentScreen) { case ProgramState.SCREEN_AGREEMENT: resetState(); @@ -7058,58 +7073,79 @@ public void mouseReleased(MouseEvent e) { return lpane; } - public void showAgreementScreen() { + public void showAgreementScreen() { + AppUI.setMargin(corePanel, 40, 120, 80, 120); + + // Agreement Panel + JPanel agreementPanel = new JPanel(); + AppUI.setBackground(agreementPanel, AppUI.getColor6()); + + GridBagLayout gridbag = new GridBagLayout(); + agreementPanel.setLayout(gridbag); + + int y = 0; + + GridBagConstraints c = new GridBagConstraints(); + c.weightx = 1; + c.anchor = GridBagConstraints.WEST; + c.insets = new Insets(40, 40, 40, 40); + c.gridx = 0; + c.gridy = y; + //c.gridwidth = 1; + //c.fill = GridBagConstraints.HORIZONTAL; - JPanel subInnerCore = AppUI.createRoundedPanel(corePanel); - // Title - JLabel text = new JLabel("CloudCoin Wallet"); - AppUI.alignCenter(text); - AppUI.setBoldFont(text, 24); - subInnerCore.add(text); - - // Agreement Panel - JPanel agreementPanel = AppUI.createRoundedPanel(subInnerCore); - AppUI.roundCorners(agreementPanel, AppUI.getColor3(), 20); - AppUI.alignCenter(agreementPanel); - // Title - text = new JLabel("Terms and Conditions"); - AppUI.alignCenter(text); - AppUI.setBoldFont(text, 24); + JLabel text = new JLabel("Terms and Conditions"); + AppUI.alignLeft(text); + AppUI.setFont(text, 30); + AppUI.setColor(text, AppUI.getColor1()); + gridbag.setConstraints(text, c); agreementPanel.add(text); + - // Space - AppUI.hr(agreementPanel, tw * 0.0082 * 2); - - + y++; + String aText = AppUI.getAgreementText(); aText = aText.replaceAll(".+", ""); // Text - text = new JLabel("
" + aText + "
"); - AppUI.alignCenter(text); + text = new JLabel("
" + aText + "
"); AppUI.setFont(text, 18); - + AppUI.setColor(text, AppUI.getColor5()); + + JPanel wrapperAgreement = new JPanel(); + //AppUI.setSize(wrapperAgreement, tw, th); AppUI.setBoxLayout(wrapperAgreement, true); - AppUI.alignCenter(wrapperAgreement); + AppUI.alignLeft(wrapperAgreement); AppUI.noOpaque(wrapperAgreement); wrapperAgreement.add(text); + // Checkbox MyCheckBox cb = new MyCheckBox("I have read and agree with the Terms and Conditions"); - cb.setBoldFont(); + cb.setFont(18, AppUI.getColor5()); + AppUI.alignLeft(cb.getCheckBox()); wrapperAgreement.add(cb.getCheckBox()); // Space - AppUI.hr(wrapperAgreement, 20); + AppUI.hr(wrapperAgreement, 40); + // JButton MyButton button = new MyButton("Continue"); + AppUI.alignRight(button.getButton()); button.disable(); - wrapperAgreement.add(button.getButton()); + JPanel buttonWrapper = new JPanel(); + AppUI.setSize(buttonWrapper, tw - 360, 50); + AppUI.setBoxLayout(buttonWrapper, true); + AppUI.noOpaque(buttonWrapper); + AppUI.alignLeft(buttonWrapper); + buttonWrapper.add(button.getButton()); + //wrapperAgreement.add(buttonWrapper); + final MyButton fbutton = button; cb.addListener(new ItemListener() { public void itemStateChanged(ItemEvent e) { @@ -7133,7 +7169,9 @@ public void actionPerformed(ActionEvent e) { showScreen(); } }); - + + + // ScrollBlock JScrollPane scrollPane = new JScrollPane(wrapperAgreement); JScrollBar scrollBar = new JScrollBar(JScrollBar.VERTICAL) { @@ -7149,10 +7187,77 @@ public boolean isVisible() { scrollPane.setOpaque(false); scrollPane.setBorder(BorderFactory.createEmptyBorder()); scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - // scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); + scrollPane.getVerticalScrollBar().setPreferredSize(new Dimension(10, 0)); + scrollPane.getVerticalScrollBar().setUI(new BasicScrollBarUI() { + @Override + protected JButton createDecreaseButton(int orientation) { + TriangleButton jbutton = new TriangleButton(false); + AppUI.setHandCursor(jbutton); + jbutton.setContentAreaFilled(false); + jbutton.setFocusPainted(false); + + JButton b = new JButton(); + AppUI.setSize(b, 0, 0); + + return b; + } + + @Override + protected JButton createIncreaseButton(int orientation) { + TriangleButton jbutton = new TriangleButton(true); + AppUI.setHandCursor(jbutton); + jbutton.setContentAreaFilled(false); + jbutton.setFocusPainted(false); + + JButton b = new JButton(); + AppUI.setSize(b, 0, 0); + + return b; + } + + @Override + protected void configureScrollBarColors(){ + this.trackColor = AppUI.getColor7(); + this.thumbColor = AppUI.getColor2(); + } + }); + + + // scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); + + + + c.weightx = 1; + c.weighty = 1; + c.anchor = GridBagConstraints.NORTH; + c.insets = new Insets(0, 40, 40, 40); + c.gridx = 0; + c.gridy = y; + c.gridwidth = 1; + //c.fill = GridBagConstraints.HORIZONTAL; + c.fill = GridBagConstraints.BOTH; + + + y++; + + gridbag.setConstraints(scrollPane, c); agreementPanel.add(scrollPane); + + c.weightx = 1; + c.weighty = 0; + c.anchor = GridBagConstraints.EAST; + c.insets = new Insets(0, 40, 40, 40); + c.gridx = 0; + c.gridy = y; + c.gridwidth = 1; + //c.fill = GridBagConstraints.HORIZONTAL; + c.fill = GridBagConstraints.BOTH; + + gridbag.setConstraints(buttonWrapper, c); + agreementPanel.add(buttonWrapper); + //agreementPanel.add(scrollPane); - subInnerCore.add(agreementPanel); + corePanel.add(agreementPanel); } public JPanel getModalJPanel(String title) { diff --git a/src/advclient/AppUI.java b/src/advclient/AppUI.java index 106679d..fd4dbc9 100644 --- a/src/advclient/AppUI.java +++ b/src/advclient/AppUI.java @@ -133,34 +133,34 @@ public static void setSize(Component c, int w, int h) { } public static Color getColor0() { - return new Color(0x0061E1); + return new Color(0x1C1F28); } public static Color getColor1() { - return new Color(0xC9DBEE); + return new Color(0x338FFF); } public static Color getColor2() { - return new Color(0xDFEAF5); + return new Color(0x2492E7); } public static Color getColor3() { //return new Color(0xBFFFFFFF, true); - return new Color(0xE9F0F8); + return new Color(0x303441); } public static Color getColor4() { - return new Color(0x665FA8FF, true); + return new Color(0x2C303D); } public static Color getColor5() { return Color.WHITE; } public static Color getColor6() { - return new Color(0x5FA8FF); + return new Color(0x1F222B); } public static Color getColor7() { - return new Color(0x90C1FE); + return new Color(0x14161E); } public static Color getColor8() { @@ -247,6 +247,10 @@ public static void alignLeft(JComponent c) { c.setAlignmentX(Component.LEFT_ALIGNMENT); } + public static void alignRight(JComponent c) { + c.setAlignmentX(Component.RIGHT_ALIGNMENT); + } + public static void alignCenter(JComponent c) { c.setAlignmentX(Component.CENTER_ALIGNMENT); } @@ -264,6 +268,10 @@ public static void noOpaque(JComponent c) { c.setOpaque(false); } + public static void opaque(JComponent c) { + c.setOpaque(true); + } + public static void vr(JComponent c, double size) { Component bc = Box.createRigidArea(new Dimension((int) size, 0)); c.add(bc); @@ -308,7 +316,7 @@ public static void noUnderLine(Component label) { public static void setTitleFont(Component c, int size) { - c.setFont(regFont.deriveFont(Font.PLAIN, size)); + c.setFont(osRegFont.deriveFont(Font.PLAIN, size)); c.setForeground(Color.WHITE); } diff --git a/src/advclient/ImageJPanel.java b/src/advclient/ImageJPanel.java index d85b2ec..83321bb 100644 --- a/src/advclient/ImageJPanel.java +++ b/src/advclient/ImageJPanel.java @@ -95,9 +95,9 @@ public void paintComponent(Graphics g) { //Graphics2D g2d = (Graphics2D) g; //g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); - //g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.3f)); + //g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.1f)); //g2d.setColor(Color.yellow); //g2d.fillOval(point.x, point.y, 120, 60); - g.drawImage(backgroundImage, 0, 0, this); + g.drawImage(backgroundImage, 32, 306, this); } } diff --git a/src/advclient/MyButton.java b/src/advclient/MyButton.java index 4d38d5e..3d23691 100644 --- a/src/advclient/MyButton.java +++ b/src/advclient/MyButton.java @@ -49,7 +49,7 @@ public void disable() { public void enable() { button.setEnabled(true); RoundedBorder rb = (RoundedBorder) button.getBorder(); - rb.setColor(AppUI.getColor0()); + rb.setColor(AppUI.getColor2()); button.repaint(); button.revalidate(); } @@ -73,11 +73,11 @@ public boolean doWork(Graphics g, JComponent c) { } }; - AppUI.roundCorners(button, AppUI.getColor0(), 18, cb); + AppUI.roundCorners(button, AppUI.getColor2(), 48, cb); AppUI.noOpaque(button); button.setContentAreaFilled(false); - AppUI.setSize(button, 224, 50); - AppUI.setBoldFont(button, 20); + AppUI.setSize(button, 214, 48); + AppUI.setFont(button, 18); AppUI.setHandCursor(button); JPanel p = new JPanel(); diff --git a/src/advclient/MyCheckBox.java b/src/advclient/MyCheckBox.java index 8bafb97..1c3ff62 100644 --- a/src/advclient/MyCheckBox.java +++ b/src/advclient/MyCheckBox.java @@ -51,6 +51,11 @@ public boolean isChecked() { return cb.isSelected(); } + public void setFont(int size, Color color) { + AppUI.setFont(txt, size); + AppUI.setColor(txt, color); + } + public void setBoldFont() { AppUI.setBoldFont(txt, 18); } diff --git a/src/resources/CloudCoinLogo.png b/src/resources/CloudCoinLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..7e450ca89cd47dc4a04f274faab5a692fcb0b7a1 GIT binary patch literal 6622 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 literal 0 HcmV?d00001 diff --git a/src/resources/CloudCoinText.png b/src/resources/CloudCoinText.png new file mode 100644 index 0000000000000000000000000000000000000000..1601296c6e0631e11eec50f5d2fa84a80aa6a9b6 GIT binary patch literal 6367 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 literal 0 HcmV?d00001 diff --git a/src/resources/bglogo.png b/src/resources/bglogo.png new file mode 100644 index 0000000000000000000000000000000000000000..dd29a3e3fdaf17f142b5fca772afe853478c57cf GIT binary patch literal 5133 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 QYP|*M>s-TBq3nbI4@wIqj{pDw literal 0 HcmV?d00001 diff --git a/src/resources/checkbox.png b/src/resources/checkbox.png new file mode 100644 index 0000000000000000000000000000000000000000..85744747ba94a23cb43426b48d90b4375ec6b69a GIT binary patch literal 3012 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 RZR9x(P*v1YsFJh#_#bBF_8b5J literal 0 HcmV?d00001 diff --git a/src/resources/depositicon.png b/src/resources/depositicon.png new file mode 100644 index 0000000000000000000000000000000000000000..da898b6ff6d38be17dbcfc2aaf44d24be868cd3c GIT binary patch literal 4245 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 literal 0 HcmV?d00001 diff --git a/src/resources/depositiconlight.png b/src/resources/depositiconlight.png new file mode 100644 index 0000000000000000000000000000000000000000..9f22005e2b02ae2547a23c8f59168d9bf403c2e7 GIT binary patch literal 4267 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 literal 0 HcmV?d00001 diff --git a/src/resources/transfericon.png b/src/resources/transfericon.png new file mode 100644 index 0000000000000000000000000000000000000000..6e7d22a916d9a9b670f19255fde0fbd24826b97d GIT binary patch literal 5544 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 IM6N<$f)jnqqW}N^ literal 0 HcmV?d00001 diff --git a/src/resources/vaulticonlight.png b/src/resources/vaulticonlight.png new file mode 100644 index 0000000000000000000000000000000000000000..ce618880e1ecb71ae236688ca82f0fa60461b916 GIT binary patch literal 4671 zcmV-F62R?=P)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z000MSNkl zvpeJL%>L~DSUc{lGyYkf4q~}Tl!A0|u|TVcfeHeJ+D0xRh+F~*A(xYo%h?|#ornT% zfn9uN&X4nc@AtgVeDj{~d%yP(qoboVUNevYprQ!t#Ee$H)5Qk(@d7=aX(kB(Gb&0M zALJUk(?x$jMNNAOIerYhh9FlPn%eu$iGsq<>=c2M*n--i`pA4@lgj3-YhA|4kQ4W ztOWGSu&|gkNRniG2*dtxFjkmL#|m=?6?*wlcSk{aN&et^oNN|@#bVOX7zrDj1mR4A zxn(Qe)ZTZlpdha|#@{7yTxnTs?s)W=YF9Pe*x?>n~1%b3Az24g zFIs5=CJTY22tj(aN{f1zJBz<1D;*a9ri9O-86CY74eHrRiL;x>8|B5v`q!INUVN;-rE};4wWNON zArKX3CI%FS#lI;55Wm`2N11htEH=yCh2=__VKrK4i!*BzD}D8IiEmu6SDaE$m=%wu zP_Rj6(HrW^IU_xd^cHr=S-tx((a2f{sK>l#`!?7lUU z<|wU3J>93G0Ep8f-j7W^(q^~2c>3iL07l0qTi$)A zcn$#GeW!SCbZoMPSQ)qb#-<)=6Q@PI@5r~UyNAI*%>h8)*pf^kAFH?9Ehd8k0NmW& zqa6M1?`ETZ!fsQ@$LjmWmSm26+bVidwa^a$ss&|_I6dk^yInIYzdW@_Q;8w`s2-WR zzom2dLXS+{pBTcAnp&i(rMZbKc3*LN)Q74CWsf7@_KKd7R|0^)zrXmokLz@qtsBopMu3{|4dCwy=X96 z{>J07xHXbnaVLxOzh4pf+3GnplIE!FyyFkG2D5?7AvyF4Pl!0}1^&<=VV00jI0Hbi z56R!)sf#A%nihG*~j@xTuDA^FedbyLffZe+bV%am^9*}QHl*oWl%@xbmH zp1oHjPP@F8ztKX_4Xx7OO{#7BEvu(T`Z^8|O;S$*AVA#NQuhnsOg(X}H5V(o}U}%zhI?~s1cs+ia1`2ahE}1Ph^OlLOI9+DjCvq0u z=^nYtW`ZG3kNn`R;**B@TkXfVuKY+(E=}$U2r79ru9clAF4O0vgr8wE!MM}?q;j9g zS!B=iwZLS6XqCz?yKqSEmfu{mlS3?^Sr6m^5-y!p{hJaN4qZ+7YKp3!VVTTB$2gUEf?XIVQ+5 zo2XecwbXmEIA7+se;2Sn|CRWAi^SozmCj5EDBNj%jwm7L z^>5aY0N~7FaT~w-_9Fmr;&A;rT-Tu0jy9Xkq+6VqZkG^OckdJigTa2`WHji;myJJ_ zy)p3#TmT?m%Rd3FQrQ(pgWv8wM`HZB0Y6MHD-D!U?YPpa`MI9$5|Wm%_g5?iFs#r# zdG2Pe)lL{Gz2Z61IVs`KT^u|5CK})$5Wrv%1VJ!wXVSjq9El*|OSscs5?EsskvAQ?@vi|gc1^^Ky4}ma4rFZ}U002ovPDHLkV1oLc B>2v@9 literal 0 HcmV?d00001 diff --git a/src/resources/walleticon.png b/src/resources/walleticon.png new file mode 100644 index 0000000000000000000000000000000000000000..984f762a14a39c4002859f5023bf359d851fe826 GIT binary patch literal 3954 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 Hu0mjfJq$l} literal 0 HcmV?d00001 diff --git a/src/resources/walletlefticon.png b/src/resources/walletlefticon.png new file mode 100644 index 0000000000000000000000000000000000000000..41805798d4f9d8e29b6a46f8e36a9986cfed2e19 GIT binary patch literal 3894 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 Eg2IGe)c^nh literal 0 HcmV?d00001 From 203b5d1de5699e144d726e5e77f19b37341fdbdb Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 7 Aug 2019 09:30:06 +0300 Subject: [PATCH 003/160] timeout --- src/advclient/AdvancedClient.java | 2 +- src/advclient/common/core/Config.java | 2 +- src/advclient/common/core/ServantManager.java | 7 +++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 5cc70d7..429eaca 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -52,7 +52,7 @@ * */ public class AdvancedClient { - String version = "2.1.7"; + String version = "2.1.8"; JPanel headerPanel; JPanel mainPanel; diff --git a/src/advclient/common/core/Config.java b/src/advclient/common/core/Config.java index 46c080b..6f4606e 100644 --- a/src/advclient/common/core/Config.java +++ b/src/advclient/common/core/Config.java @@ -40,7 +40,7 @@ public class Config { public static String DIR_MAIN_TRASH = "Trash"; public static String DIR_BACKUPS = "Backups"; - public static int THREAD_POOL_SIZE = 25; + public static int THREAD_POOL_SIZE = 30; public static int READ_TIMEOUT = 30000; // ms public static int CONNECTION_TIMEOUT = 7000; // ms diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index da635ba..996796f 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -315,8 +315,11 @@ public void startGraderService(CallbackInterface cb, ArrayList duplic public void startShowSkyCoinsService(CallbackInterface cb, int sn) { - if (sr.isRunning("ShowEnvelopeCoins")) - return; + while (sr.isRunning("ShowEnvelopeCoins")) { + try { + Thread.sleep(200); + } catch (InterruptedException e) {} + } ShowEnvelopeCoins sc = (ShowEnvelopeCoins) sr.getServant("ShowEnvelopeCoins"); sc.launch(sn, "sky", cb); From 999e39ee19208f83b3fac35ad0a31dd8b5c020fd Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 7 Aug 2019 19:31:33 +0300 Subject: [PATCH 004/160] new screens --- src/advclient/AdvancedClient.java | 1193 +++++++++++---------------- src/advclient/AppUI.java | 203 ++++- src/advclient/MyButton.java | 14 +- src/advclient/MyCheckBoxToggle.java | 91 ++ src/advclient/MyTextField.java | 4 +- src/advclient/RoundedTextField.java | 4 +- src/resources/arrowleft.png | Bin 0 -> 3114 bytes src/resources/arrowright.png | Bin 0 -> 3133 bytes src/resources/coinsinventory.png | Bin 0 -> 3831 bytes src/resources/toggleno.png | Bin 0 -> 4670 bytes src/resources/toggleyes.png | Bin 0 -> 4419 bytes 11 files changed, 769 insertions(+), 740 deletions(-) create mode 100644 src/advclient/MyCheckBoxToggle.java create mode 100644 src/resources/arrowleft.png create mode 100644 src/resources/arrowright.png create mode 100644 src/resources/coinsinventory.png create mode 100644 src/resources/toggleno.png create mode 100644 src/resources/toggleyes.png diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 429eaca..25c4174 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -486,9 +486,7 @@ public void fillHeaderPanel() { AppUI.setBoxLayout(wrp, false); AppUI.setSize(wrp, 296, headerHeight); AppUI.noOpaque(wrp); - - - + if (ps.currentScreen == ProgramState.SCREEN_AGREEMENT) { // Init Label JLabel titleText = new JLabel(""); @@ -539,9 +537,12 @@ public void fillHeaderPanel() { wrpDeposit.add(depositIcon); if (isDepositing()) { depositIcon.setIcon(depositIiLight); + AppUI.opaque(wrpDeposit); + } else { AppUI.setHandCursor(wrpDeposit); depositIcon.setIcon(depositIi); + } wrpDeposit.add(AppUI.vr(6)); @@ -566,6 +567,7 @@ public void fillHeaderPanel() { if (isWithdrawing()) { transferIcon.setIcon(transferIiLight); + AppUI.opaque(wrpTransfer); } else { AppUI.setHandCursor(wrpTransfer); transferIcon.setIcon(transferIi); @@ -585,7 +587,12 @@ public void fillHeaderPanel() { MouseAdapter ma0 = new MouseAdapter() { public void mouseReleased(MouseEvent e) { - + if (!ps.defaultWalletCreated) + return; + + resetState(); + ps.currentScreen = ProgramState.SCREEN_PREDEPOSIT; + showScreen(); } public void mouseEntered(MouseEvent e) { if (!ps.defaultWalletCreated) @@ -597,6 +604,7 @@ public void mouseEntered(MouseEvent e) { p.revalidate(); p.repaint(); } + public void mouseExited(MouseEvent e) { if (!ps.defaultWalletCreated) return; @@ -612,6 +620,15 @@ public void mouseExited(MouseEvent e) { }; MouseAdapter ma1 = new MouseAdapter() { + public void mouseReleased(MouseEvent e) { + if (!ps.defaultWalletCreated) + return; + + resetState(); + ps.currentScreen = ProgramState.SCREEN_WITHDRAW; + showScreen(); + } + public void mouseEntered(MouseEvent e) { if (!ps.defaultWalletCreated) return; @@ -777,7 +794,7 @@ public void mouseReleased(MouseEvent e) { // Icon Support - c.insets = new Insets(26, 24, 0, 20); + c.insets = new Insets(30, 24, 0, 20); AppUI.noOpaque(icon1); AppUI.setHandCursor(icon1); gridbag.setConstraints(icon1, c); @@ -787,6 +804,7 @@ public void mouseReleased(MouseEvent e) { ps.currentScreen = ProgramState.SCREEN_SUPPORT; showScreen(); } + }); @@ -825,15 +843,9 @@ public void resetState() { public void showScreen() { wl.debug(ltag, "SCREEN " + ps.currentScreen + ": " + ps.toString()); - - ps.currentScreen = ProgramState.SCREEN_AGREEMENT; clear(); - showAgreementScreen(); - if (1==1) - return; - - + switch (ps.currentScreen) { case ProgramState.SCREEN_AGREEMENT: resetState(); @@ -976,13 +988,11 @@ public void showScreen() { public void maybeShowError(JPanel p) { if (!ps.errText.isEmpty()) { - AppUI.hr(p, 10); - JLabel err = new JLabel(ps.errText); AppUI.setFont(err, 16); AppUI.setColor(err, AppUI.getErrorColor()); - AppUI.alignCenter(err); + AppUI.alignLeft(err); AppUI.hr(p, 2); p.add(err); @@ -1057,7 +1067,7 @@ private void setRAIDAFixingProgress(int raidaProcessed, int totalFilesProcessed, */ public void showFixingfrackedScreen() { - JPanel subInnerCore = getModalJPanel("Fixing in Progress"); + JPanel subInnerCore = getPanel("Fixing in Progress"); maybeShowError(subInnerCore); JPanel ct = new JPanel(); @@ -1134,7 +1144,7 @@ public void run(){ } public void showEchoRAIDAScreen() { - JPanel subInnerCore = getModalJPanel("Checking RAIDA"); + JPanel subInnerCore = getPanel("Checking RAIDA"); maybeShowError(subInnerCore); JPanel ct = new JPanel(); @@ -1152,7 +1162,7 @@ public void showEchoRAIDAScreen() { } public void showEchoRAIDAFinishedScreen() { - JPanel subInnerCore = getModalJPanel("RAIDA Status"); + JPanel subInnerCore = getPanel("RAIDA Status"); maybeShowError(subInnerCore); JPanel ct = new JPanel(); @@ -1257,7 +1267,7 @@ public int getSkyWalletSN() { } public void showMakingChangeScreen() { - JPanel subInnerCore = getModalJPanel("Request Change"); + JPanel subInnerCore = getPanel("Request Change"); maybeShowError(subInnerCore); JPanel ct = new JPanel(); @@ -1408,8 +1418,7 @@ public void run() { } public void showSendingScreen() { - JPanel subInnerCore = getModalJPanel("Transfer in Progress"); - maybeShowError(subInnerCore); + JPanel subInnerCore = getPanel("Transfer in Progress"); JPanel ct = new JPanel(); AppUI.noOpaque(ct); @@ -1558,8 +1567,7 @@ public void run(){ public void showImportingScreen() { - JPanel subInnerCore = getModalJPanel("Deposit in Progress"); - maybeShowError(subInnerCore); + JPanel subInnerCore = getPanel("Deposit in Progress"); //ps.dstWallet = sm.getWalletByName("Default Wallet"); @@ -1692,9 +1700,8 @@ public void showFixDoneScreen() { JPanel subInnerCore; if (isError) { - subInnerCore = getModalJPanel("Error"); + subInnerCore = getPanel("Error"); AppUI.hr(subInnerCore, 32); - maybeShowError(subInnerCore); resetState(); return; } @@ -1708,8 +1715,7 @@ public void showFixDoneScreen() { String totalFixedValue = AppCore.formatNumber(ps.statTotalFixedValue); //String totalFailedToFixValue = AppCore.formatNumber(ps.statTotalFrackedValue - ps.statTotalFixedValue); - subInnerCore = getModalJPanel("Fix Complete"); - maybeShowError(subInnerCore); + subInnerCore = getPanel("Fix Complete"); JPanel ct = new JPanel(); AppUI.noOpaque(ct); @@ -1788,14 +1794,13 @@ public void showBackupDoneScreen() { JPanel subInnerCore; if (isError) { - subInnerCore = getModalJPanel("Error"); + subInnerCore = getPanel("Error"); AppUI.hr(subInnerCore, 32); - maybeShowError(subInnerCore); resetState(); return; } - subInnerCore = getModalJPanel("Backup Complete"); + subInnerCore = getPanel("Backup Complete"); maybeShowError(subInnerCore); JPanel ct = new JPanel(); @@ -1905,17 +1910,15 @@ public void showTransferDoneScreen() { JPanel subInnerCore; if (isError) { - subInnerCore = getModalJPanel("Error"); + subInnerCore = getPanel("Error"); AppUI.hr(subInnerCore, 32); - maybeShowError(subInnerCore); resetState(); return; } - subInnerCore = getModalJPanel("Transfer Complete"); - maybeShowError(subInnerCore); + subInnerCore = getPanel("Transfer Complete"); JPanel ct = new JPanel(); AppUI.noOpaque(ct); @@ -1982,15 +1985,13 @@ public void showImportDoneScreen() { JPanel subInnerCore; if (isError) { - subInnerCore = getModalJPanel("Error"); + subInnerCore = getPanel("Error"); AppUI.hr(subInnerCore, 32); - maybeShowError(subInnerCore); resetState(); return; } - subInnerCore = getModalJPanel("Deposit Complete"); - maybeShowError(subInnerCore); + subInnerCore = getPanel("Deposit Complete"); JPanel ct = new JPanel(); AppUI.noOpaque(ct); @@ -2128,14 +2129,13 @@ public void showDeleteWalletDoneScreen() { JPanel subInnerCore; if (isError) { - subInnerCore = getModalJPanel("Error"); + subInnerCore = getPanel("Error"); AppUI.hr(subInnerCore, 32); - maybeShowError(subInnerCore); resetState(); return; } - subInnerCore = getModalJPanel("Confirmation"); + subInnerCore = getPanel("Confirmation"); // Container JPanel ct = new JPanel(); @@ -2177,14 +2177,13 @@ public void showClearDoneScreen() { JPanel subInnerCore; if (isError) { - subInnerCore = getModalJPanel("Error"); + subInnerCore = getPanel("Error"); AppUI.hr(subInnerCore, 32); - maybeShowError(subInnerCore); resetState(); return; } - subInnerCore = getModalJPanel("Confirmation"); + subInnerCore = getPanel("Confirmation"); // Container JPanel ct = new JPanel(); @@ -2226,7 +2225,7 @@ public void showClearDoneScreen() { } public void showConfirmClearScreen() { - JPanel subInnerCore = getModalJPanel("Confirmation"); + JPanel subInnerCore = getPanel("Confirmation"); // Container JPanel ct = new JPanel(); @@ -2291,8 +2290,7 @@ public void actionPerformed(ActionEvent e) { } public void showConfirmDeleteWalletScreen() { - JPanel subInnerCore = getModalJPanel("Confirmation"); - maybeShowError(subInnerCore); + JPanel subInnerCore = getPanel("Confirmation"); // Container JPanel ct = new JPanel(); @@ -2473,7 +2471,7 @@ public void run() { } public void showConfirmTransferScreen() { - JPanel subInnerCore = getModalJPanel("Transfer Confirmation"); + JPanel subInnerCore = getPanel("Transfer Confirmation"); // Container JPanel ct = new JPanel(); @@ -2650,94 +2648,50 @@ public void actionPerformed(ActionEvent e) { public void showSetEmailScreen() { - JPanel subInnerCore = getModalJPanel("Type Coin Recovery Email"); - maybeShowError(subInnerCore); - - // Space - //AppUI.hr(subInnerCore, 20); - - // Container - JPanel ct = new JPanel(); - AppUI.noOpaque(ct); - subInnerCore.add(ct); - - GridBagLayout gridbag = new GridBagLayout(); - GridBagConstraints c = new GridBagConstraints(); - ct.setLayout(gridbag); - int y = 0; - - // Text - c.anchor = GridBagConstraints.CENTER; - c.insets = new Insets(0, 0, 0, 0); - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = y; - + JLabel fname; + MyTextField tf0, tf1; - JLabel l = new JLabel("
The CloudCoin Consortium recommends you use
" - + "a free encrypted email account from
"); - AppUI.setFont(l, 16); - gridbag.setConstraints(l, c); - ct.add(l); - - - y++; - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = y; - - l = AppUI.getHyperLink("www.protonmail.com", "www.protonmail.com", 16); - AppUI.setFont(l, 16); - gridbag.setConstraints(l, c); - ct.add(l); - - - y++; - - // Email Label - JLabel x = new JLabel("Email"); - AppUI.setCommonFont(x); - c.gridwidth = 1; - c.anchor = GridBagConstraints.WEST; - c.insets = new Insets(20, 120, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); + JPanel subInnerCore = getPanel("Type Coin Recovery Email"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + JLabel warnText = AppUI.wrapDiv("The CloudCoin Consortium recommends you use a free encrypted email account from"); + AppUI.getGBRow(subInnerCore, null, warnText, y, gridbag); y++; + - MyTextField tf0 = new MyTextField("Email", false); - c.insets = new Insets(0, 120, 16, 0); - c.gridx = 0; - c.gridy = y; - gridbag.setConstraints(tf0.getTextField(), c); - tf0.requestFocus(); - ct.add(tf0.getTextField()); - + JLabel linkLabel = AppUI.getHyperLink("www.protonmail.com", "www.protonmail.com", 16); + //AppUI.setFont(l, 16); + AppUI.getGBRow(subInnerCore, null, linkLabel, y, gridbag); + AppUI.setColor(linkLabel, AppUI.getColor2()); + AppUI.underLine(linkLabel); y++; - - // Confirm Email Label - x = new JLabel("Confirm Email"); - AppUI.setCommonFont(x); - c.insets = new Insets(0, 120, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); - - + + fname = new JLabel("Email"); + tf0 = new MyTextField("Email", false); + tf0.requestFocus(); + AppUI.getGBRow(subInnerCore, fname, tf0.getTextField(), y, gridbag); + y++; + + fname = new JLabel("Confirm Email"); + tf1 = new MyTextField("Confirm Email", false); + AppUI.getGBRow(subInnerCore, fname, tf1.getTextField(), y, gridbag); + y++; + + AppUI.GBPad(subInnerCore, y, gridbag); y++; - - MyTextField tf1 = new MyTextField("Confirm Email", false); - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = y; - gridbag.setConstraints(tf1.getTextField(), c); - ct.add(tf1.getTextField()); - + + // Buttons final MyTextField ftf0 = tf0; final MyTextField ftf1 = tf1; - JPanel bp = getTwoButtonPanel(new ActionListener() { + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { public void actionPerformed(ActionEvent e) { String p0 = ftf0.getText(); String p1 = ftf1.getText(); @@ -2769,90 +2723,59 @@ public void actionPerformed(ActionEvent e) { initSystemUser(); - showScreen(); + showScreen(); } - }); - - - subInnerCore.add(bp); + }, y, gridbag); } public void showWalletCreatedScreen() { - boolean isError = !ps.errText.equals(""); + int y = 0; + JLabel fname; JPanel subInnerCore; - + boolean isError = !ps.errText.equals(""); + if (isError) { - subInnerCore = getModalJPanel("Error"); - AppUI.hr(subInnerCore, 32); - maybeShowError(subInnerCore); + subInnerCore = getPanel("Error"); resetState(); return; } - subInnerCore = getModalJPanel("Wallet " + ps.typedWalletName + " created"); - AppUI.hr(subInnerCore, 42); - - JLabel res; + subInnerCore = getPanel("Wallet " + ps.typedWalletName + " created"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + String text; if (!ps.typedPassword.equals("")) { - res = AppUI.getCommonLabel("The coins in this wallet are "); - subInnerCore.add(res); - AppUI.hr(subInnerCore, 12); - - res = AppUI.getCommonLabel("protected from theft by password. "); - subInnerCore.add(res); - AppUI.hr(subInnerCore, 12); - - res = AppUI.getCommonLabel("Please record your password in a secure location."); - subInnerCore.add(res); - AppUI.hr(subInnerCore, 12); + text = "The coins in this wallet are protected from theft by password. " + + "Please record your password in a secure location."; if (!ps.typedEmail.equals("")) { - res = AppUI.getCommonLabel("Your coins in this wallet are protected from loss."); - subInnerCore.add(res); - AppUI.hr(subInnerCore, 12); - - res = AppUI.getCommonLabel("Your loss recovery email is:"); - subInnerCore.add(res); - AppUI.hr(subInnerCore, 12); - - - res = AppUI.getCommonBoldLabel(ps.typedEmail); - subInnerCore.add(res); - AppUI.hr(subInnerCore, 12); + text += "

Your coins in this wallet are protected from loss. Your loss recovery email is:
"; + text += ps.typedEmail; } else { - res = AppUI.getCommonLabel("No recovery email was set."); - subInnerCore.add(res); - AppUI.hr(subInnerCore, 12); + text += "

No recovery email was set."; } } else if (!ps.typedEmail.equals("")) { - res = AppUI.getCommonLabel("Your coins in this wallet are protected from loss."); - subInnerCore.add(res); - AppUI.hr(subInnerCore, 12); - - res = AppUI.getCommonLabel("Your loss recovery email is:"); - subInnerCore.add(res); - AppUI.hr(subInnerCore, 12); - - res = AppUI.getCommonBoldLabel(ps.typedEmail); - subInnerCore.add(res); - AppUI.hr(subInnerCore, 12); + text = "

Your coins in this wallet are protected from loss. Your loss recovery email is:
"; + text += ps.typedEmail; } else { - res = AppUI.getCommonLabel("Wallet has been created successfully"); - subInnerCore.add(res); - AppUI.hr(subInnerCore, 12); + text = "Wallet has been created successfully"; } + + fname = AppUI.wrapDiv(text); + AppUI.getGBRow(subInnerCore, null, fname, 0, gridbag); + y++; - //resetState(); + AppUI.GBPad(subInnerCore, y, gridbag); + y++; - //JPanel bp = getOneButtonPanel(); - JPanel bp = getOneButtonPanelCustom("Continue", new ActionListener() { + AppUI.getTwoButtonPanel(subInnerCore, "", "Continue", null, new ActionListener() { public void actionPerformed(ActionEvent e) { sm.setActiveWallet(ps.typedWalletName); ps.currentScreen = ProgramState.SCREEN_SHOW_TRANSACTIONS; showScreen(); } - }); - subInnerCore.add(bp); + }, y, gridbag); } public void showSkyWalletCreatedScreen() { @@ -2860,14 +2783,13 @@ public void showSkyWalletCreatedScreen() { JPanel subInnerCore; if (isError) { - subInnerCore = getModalJPanel("Error"); + subInnerCore = getPanel("Error"); AppUI.hr(subInnerCore, 32); - maybeShowError(subInnerCore); resetState(); return; } - subInnerCore = getModalJPanel("Sky Wallet created"); + subInnerCore = getPanel("Sky Wallet created"); AppUI.hr(subInnerCore, 32); @@ -2901,42 +2823,41 @@ public void actionPerformed(ActionEvent e) { public void showUnderstandPasswordScreen() { - JPanel subInnerCore = getModalJPanel("Confirmation"); + int y = 0; + JLabel fname; + MyTextField tf0, tf1; - // Space - AppUI.hr(subInnerCore, 40); - - // Container - JPanel ct = new JPanel(); - AppUI.noOpaque(ct); - subInnerCore.add(ct); - + JPanel subInnerCore = getPanel("Confirmation"); GridBagLayout gridbag = new GridBagLayout(); - GridBagConstraints c = new GridBagConstraints(); - ct.setLayout(gridbag); - - // Checkbox + subInnerCore.setLayout(gridbag); + MyCheckBox cb0 = new MyCheckBox("I understand that if I lose my password
I will lose my coins and will need to recover them"); - c.anchor = GridBagConstraints.WEST; - c.insets = new Insets(0, 0, 12, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = 0; - gridbag.setConstraints(cb0.getCheckBox(), c); - ct.add(cb0.getCheckBox()); + cb0.setFont(16, AppUI.getColor5()); + AppUI.getGBRow(subInnerCore, null, cb0.getCheckBox(), y, gridbag); + y++; MyCheckBox cb1 = new MyCheckBox("I understand that no one can recover my password if
I lose or forget it"); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = 1; - gridbag.setConstraints(cb1.getCheckBox(), c); - ct.add(cb1.getCheckBox()); + cb1.setFont(16, AppUI.getColor5()); + AppUI.getGBRow(subInnerCore, null, cb1.getCheckBox(), y, gridbag); + y++; - MyCheckBox cb2 = new MyCheckBox("I have written down or otherwise stored
my password"); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = 2; - gridbag.setConstraints(cb2.getCheckBox(), c); - ct.add(cb2.getCheckBox()); - JPanel bp = getTwoButtonPanel(new ActionListener() { + MyCheckBox cb2 = new MyCheckBox("I have written down or otherwise stored
my password"); + cb2.setFont(16, AppUI.getColor5()); + AppUI.getGBRow(subInnerCore, null, cb2.getCheckBox(), y, gridbag); + y++; + + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + // Buttons + continueButton = AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { public void actionPerformed(ActionEvent e) { if (ps.cwalletRecoveryRequested) { ps.currentScreen = ProgramState.SCREEN_SET_EMAIL; @@ -2945,10 +2866,10 @@ public void actionPerformed(ActionEvent e) { initSystemUser(); } - showScreen(); + showScreen(); } - }); - + }, y, gridbag); + continueButton.disable(); final MyCheckBox fcb0 = cb0; @@ -2969,62 +2890,41 @@ public void itemStateChanged(ItemEvent e) { cb1.addListener(il); cb2.addListener(il); - subInnerCore.add(bp); + } public void showSetPasswordScreen() { - JPanel subInnerCore = getModalJPanel("Create Wallet Password"); - maybeShowError(subInnerCore); - - // Space - AppUI.hr(subInnerCore, 40); - - // Container - JPanel ct = new JPanel(); - AppUI.noOpaque(ct); - subInnerCore.add(ct); - + int y = 0; + JLabel fname; + MyTextField tf0, tf1; + + JPanel subInnerCore = getPanel("Create Wallet Password"); GridBagLayout gridbag = new GridBagLayout(); - GridBagConstraints c = new GridBagConstraints(); - ct.setLayout(gridbag); - - // Password Label - JLabel x = new JLabel("Password"); - AppUI.setCommonFont(x); - c.anchor = GridBagConstraints.WEST; - c.insets = new Insets(0, 0, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = 0; - gridbag.setConstraints(x, c); - ct.add(x); + subInnerCore.setLayout(gridbag); - MyTextField tf0 = new MyTextField("Password"); - c.insets = new Insets(0, 0, 16, 0); - c.gridx = 0; - c.gridy = 1; - gridbag.setConstraints(tf0.getTextField(), c); - tf0.requestFocus(); - ct.add(tf0.getTextField()); - - // Confirm Password Label - x = new JLabel("Confirm Password"); - AppUI.setCommonFont(x); - c.insets = new Insets(0, 0, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = 2; - gridbag.setConstraints(x, c); - ct.add(x); + fname = new JLabel("Password"); + tf0 = new MyTextField("Password"); + tf0.requestFocus(); + AppUI.getGBRow(subInnerCore, fname, tf0.getTextField(), y, gridbag); + y++; - MyTextField tf1 = new MyTextField("Confirm Password"); - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = 3; - gridbag.setConstraints(tf1.getTextField(), c); - ct.add(tf1.getTextField()); - + fname = new JLabel("Confirm Password"); + tf1 = new MyTextField("Confirm Password"); + AppUI.getGBRow(subInnerCore, fname, tf1.getTextField(), y, gridbag); + y++; + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + // Buttons final MyTextField ftf0 = tf0; final MyTextField ftf1 = tf1; - JPanel bp = getTwoButtonPanel(new ActionListener() { + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { public void actionPerformed(ActionEvent e) { String p0 = ftf0.getText(); String p1 = ftf1.getText(); @@ -3046,9 +2946,8 @@ public void actionPerformed(ActionEvent e) { showScreen(); } - }); - - subInnerCore.add(bp); + }, y, gridbag); + } @@ -3123,39 +3022,6 @@ public void callback(Object o) { } - public void updateWalletAmount2() { - if (wallets == null) - wallets = sm.getWallets(); - - if (ps.isUpdatedWallets) { - for (int i = 0; i < wallets.length; i++) { - walletSetTotal(wallets[i], wallets[i].getTotal()); - } - - setTotalCoins(); - return; - } else { - for (int i = 0; i < wallets.length; i++) { - JLabel cntLabel = (JLabel) wallets[i].getuiRef(); - if (cntLabel == null) - continue; - - cntLabel.setText("Counting"); - } - } - - if (!ps.isShowCoinsFinished) - return; - - ps.isShowCoinsFinished = false; - ps.isUpdatedWallets = true; - ps.currentWalletIdx = 0; - - showCoinsGoNext(); - setTotalCoins(); - - } - public void eraserGoNext() { if (wallets.length > ps.currentWalletIdx) { if (!wallets[ps.currentWalletIdx].isSkyWallet()) { @@ -5718,35 +5584,35 @@ public void actionPerformed(ActionEvent e) { public void showTransactionsScreen() { boolean isSky = sm.getActiveWallet().isSkyWallet() ? true : false; - showLeftScreen(); - - Wallet w = sm.getActiveWallet(); - - JPanel rightPanel = getRightPanel(AppUI.getColor4()); - JPanel ct = new JPanel(); - AppUI.setBoxLayout(ct, true); - AppUI.noOpaque(ct); - rightPanel.add(ct); - JLabel ltitle = AppUI.getTitle(w.getName() + " - " + w.getTotal() + " CC"); - ct.add(ltitle); - - AppUI.hr(ct, 10); + showLeftScreen(); + JPanel rightPanel = getRightPanel(); + Wallet w = sm.getActiveWallet(); + String rec = ""; if (!w.getEmail().isEmpty()) { - - // Email - JLabel el = new JLabel("Recovery Email: " + w.getEmail()); - AppUI.setFont(el, 14); - AppUI.alignCenter(el); - ct.add(el); - - AppUI.hr(ct, 10); + String colstr = "#" + Integer.toHexString(AppUI.getColor5().getRGB()).substring(2); + rec = "
Recovery Email: " + w.getEmail() + ""; } - - // Coins - int[][] counters = w.getCounters(); - if (counters != null && counters.length != 0) { + + String titleText = "" + w.getName() + " - " + + AppCore.formatNumber(w.getTotal()) + "cc" + rec + ""; + + JPanel hwrapper = new JPanel(); + AppUI.setBoxLayout(hwrapper, false); + AppUI.alignLeft(hwrapper); + AppUI.noOpaque(hwrapper); + + + JLabel title = new JLabel(titleText); + AppUI.alignLeft(title); + AppUI.alignTop(title); + AppUI.setFont(title, 30); + AppUI.setColor(title, AppUI.getColor1()); + hwrapper.add(title); + + int[][] counters = w.getCounters(); + if (!isSky && counters != null && counters.length != 0) { int t1, t5, t25, t100, t250; t1 = counters[Config.IDX_FOLDER_BANK][Config.IDX_1] + @@ -5769,21 +5635,53 @@ public void showTransactionsScreen() { counters[Config.IDX_FOLDER_FRACKED][Config.IDX_250] + counters[Config.IDX_FOLDER_VAULT][Config.IDX_250]; - String s; - - s = "1's: " + t1 + " | 5's: " + t5 + " | 25's: " + t25 - + " | 100's: " + t100 + " | 250's: " + t250 + " "; - + JPanel invPanel = new JPanel(); + AppUI.setBackground(invPanel, AppUI.getColor7()); + AppUI.alignTop(invPanel); + AppUI.setSize(invPanel, 520, 62); + AppUI.setMargin(invPanel, 8, 8, 8, 20); + //AppUI.noOpaque(invPanel); + + hwrapper.add(invPanel); - JLabel ml = new JLabel("
" + s + "
"); - AppUI.alignCenter(ml); - AppUI.setFont(ml, 14); - ct.add(ml); + try { + Image img = ImageIO.read(getClass().getClassLoader().getResource("resources/coinsinventory.png")); + JLabel icon = new JLabel(new ImageIcon(img)); + AppUI.setMargin(icon, 0, 0, 0, 0); + invPanel.add(icon); + } catch (Exception ex) { + } + + JLabel invLabel = new JLabel("Inventory:"); + AppUI.setSemiBoldFont(invLabel, 18); + AppUI.setColor(invLabel, AppUI.getColor5()); + AppUI.setMargin(invLabel, 0, 10, 0, 20); + invPanel.add(invLabel); + + + // 5 times + AppUI.addInvItem(invPanel, "1", t1); + AppUI.addInvItem(invPanel, "5", t5); + AppUI.addInvItem(invPanel, "25", t25); + AppUI.addInvItem(invPanel, "100", t100); + AppUI.addInvItem(invPanel, "250", t250); + - AppUI.hr(ct, 20); } + + rightPanel.add(hwrapper); + rightPanel.add(AppUI.hr(22)); + + JLabel thlabel = new JLabel("Transaction History"); + AppUI.alignLeft(thlabel); + AppUI.setFont(thlabel, 22); + AppUI.setColor(thlabel, AppUI.getColor5()); + rightPanel.add(thlabel); + + rightPanel.add(AppUI.hr(22)); + // File saver if (ps.sendType == ProgramState.SEND_TYPE_FOLDER) { if (Desktop.isDesktopSupported()) { @@ -5795,50 +5693,17 @@ public void showTransactionsScreen() { } } - /* - if (ps.sendType == ProgramState.SEND_TYPE_FOLDER) { - Thread t = new Thread(new Runnable() { - public void run(){ - //UIManager.put("FileChooser.readOnly", Boolean.TRUE); - JFileChooser c = new JFileChooser(ps.chosenFile); - // UIManager.put("FileChooser.readOnly", Boolean.FALSE); - c.setSelectedFile(new File(ps.typedAmount + ".CloudCoin." + ps.typedMemo + ".stack")); - - int rVal = c.showSaveDialog(null); - if (rVal == JFileChooser.APPROVE_OPTION) { - String file = c.getSelectedFile().getAbsolutePath(); - sm.setActiveWalletObj(ps.srcWallet); - ps.srcWallet.setPassword(ps.typedSrcPassword); - if (ps.srcWallet.isEncrypted()) { - sm.startSecureExporterService(Config.TYPE_STACK, ps.typedAmount, ps.typedMemo, file, false, new ExporterCb()); - } else { - sm.startExporterService(Config.TYPE_STACK, ps.typedAmount, ps.typedMemo, file, false, new ExporterCb()); - } - } - } - }); - - t.start(); - } - */ - - // Create transactions final String[][] trs; - JLabel trLabel; String[] headers; if (isSky) { Hashtable envelopes = sm.getActiveWallet().getEnvelopes(); - trLabel = new JLabel("Skywallet Contents. Click Deposit to Download"); + thlabel.setText("Skywallet Contents. Click Deposit to Download"); if (envelopes == null || envelopes.size() == 0) { - trLabel = new JLabel("No Coins"); - AppUI.setSemiBoldFont(trLabel, 20); - AppUI.alignCenter(trLabel); - ct.add(trLabel); + thlabel.setText("No Coins"); return; } - Enumeration enumeration = envelopes.keys(); trs = new String[envelopes.size()][]; @@ -5866,15 +5731,9 @@ public void run(){ trs = sm.getActiveWallet().getTransactions(); if (trs == null || trs.length == 0) { - trLabel = new JLabel("No transactions"); - AppUI.setSemiBoldFont(trLabel, 20); - AppUI.alignCenter(trLabel); - ct.add(trLabel); + thlabel.setText("No transactions"); return; } - - trLabel = new JLabel("Transaction History"); - headers = new String[] { "Memo (note)", "Date", @@ -5883,46 +5742,68 @@ public void run(){ "Total" }; } - AppUI.setSemiBoldFont(trLabel, 20); - AppUI.alignCenter(trLabel); - ct.add(trLabel); + + + final JLabel iconLeft, iconRight; + try { + Image img = ImageIO.read(getClass().getClassLoader().getResource("resources/arrowleft.png")); + iconLeft = new JLabel(new ImageIcon(img)); + + img = ImageIO.read(getClass().getClassLoader().getResource("resources/arrowright.png")); + iconRight = new JLabel(new ImageIcon(img)); + } catch (Exception ex) { + return; + } - //margin above transaction table - AppUI.hr(ct, 10); - - // Scrollbar & Table DefaultTableCellRenderer r = new DefaultTableCellRenderer() { JLabel lbl; @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); - + + JPanel cell = new JPanel(); + AppUI.setBoxLayout(cell, false); + //AppUI.noOpaque(cell); + AppUI.setBackground(cell, AppUI.getColor6()); + AppUI.setMargin(cell, 0, 20, 0, 0); + lbl = (JLabel) this; if (column == 0) { - String hash = trs[row][trs[0].length - 1]; + String hash = trs[row][trs[0].length - 1]; + String html = AppCore.getReceiptHtml(hash, sm.getActiveWallet().getName()); if (html != null) { - AppUI.setColor(lbl, AppUI.getColor0()); + AppUI.setColor(lbl, AppUI.getColor5()); AppUI.underLine(lbl); } + } if (column == 2) { + AppUI.setColor(lbl, AppUI.getColor13()); + } else if (column == 3) { + AppUI.setColor(lbl, AppUI.getColor12()); } else { - AppUI.setColor(lbl, Color.BLACK); + //AppUI.setColor(lbl, Color.BLACK); + AppUI.setColor(lbl, AppUI.getColor5()); } if (row % 2 == 0) { - AppUI.setBackground(lbl, AppUI.getColor3()); + AppUI.setBackground(lbl, AppUI.getColor6()); } else { - AppUI.setBackground(lbl, AppUI.getColor4()); + AppUI.setBackground(lbl, AppUI.getColor6()); } if (column == 0) { lbl.setHorizontalAlignment(JLabel.LEFT); } else if (column == 1) { - lbl.setHorizontalAlignment(JLabel.CENTER); + lbl.setHorizontalAlignment(JLabel.LEFT); } else { String d = (String) value; try { String total = AppCore.formatNumber(Integer.parseInt(d)); + if (column == 2) + total = "+ " + total; + else if (column == 3) + total = "- " + total; + lbl.setText(total); } catch (NumberFormatException e) { @@ -5933,16 +5814,30 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole AppUI.setHandCursor(lbl); AppUI.setMargin(lbl, 8); - + + if (column == 0) { + String income = trs[row][2]; + if (income.isEmpty()) + cell.add(iconLeft); + else + cell.add(iconRight); + AppUI.setMargin(lbl, 8, 20, 8, 8); + cell.add(lbl); + return cell; + } + return lbl; } }; - + + final JTable table = new JTable(); final JScrollPane scrollPane = AppUI.setupTable(table, headers, trs, r); - table.getColumnModel().getColumn(0).setPreferredWidth(220); - table.getColumnModel().getColumn(1).setPreferredWidth(160); + AppUI.alignLeft(scrollPane); + + table.getColumnModel().getColumn(0).setPreferredWidth(230); + table.getColumnModel().getColumn(1).setPreferredWidth(140); MouseAdapter ma = new MouseAdapter() { private int prevcolumn = -1; @@ -6011,13 +5906,18 @@ public void mouseExited(MouseEvent e) { table.addMouseListener(ma); table.addMouseMotionListener(ma); - ct.add(scrollPane); - + rightPanel.add(scrollPane); + JPanel subInnerCore = new JPanel(); + AppUI.alignLeft(subInnerCore); + AppUI.noOpaque(subInnerCore); + rightPanel.add(subInnerCore); - //print and export history from wallet - JPanel bp = getTwoButtonPanelCustom("Print", "Export History", new ActionListener() { + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + AppUI.getTwoButtonPanel(subInnerCore, "Print", "Export", new ActionListener() { public void actionPerformed(ActionEvent e) { try { table.print(); @@ -6045,10 +5945,37 @@ public void actionPerformed(ActionEvent e) { } } } - }); + }, 0, gridbag); + - AppUI.hr(rightPanel, 5); - rightPanel.add(bp); + /* + if (ps.sendType == ProgramState.SEND_TYPE_FOLDER) { + Thread t = new Thread(new Runnable() { + public void run(){ + //UIManager.put("FileChooser.readOnly", Boolean.TRUE); + JFileChooser c = new JFileChooser(ps.chosenFile); + // UIManager.put("FileChooser.readOnly", Boolean.FALSE); + c.setSelectedFile(new File(ps.typedAmount + ".CloudCoin." + ps.typedMemo + ".stack")); + + int rVal = c.showSaveDialog(null); + if (rVal == JFileChooser.APPROVE_OPTION) { + String file = c.getSelectedFile().getAbsolutePath(); + sm.setActiveWalletObj(ps.srcWallet); + ps.srcWallet.setPassword(ps.typedSrcPassword); + if (ps.srcWallet.isEncrypted()) { + sm.startSecureExporterService(Config.TYPE_STACK, ps.typedAmount, ps.typedMemo, file, false, new ExporterCb()); + } else { + sm.startExporterService(Config.TYPE_STACK, ps.typedAmount, ps.typedMemo, file, false, new ExporterCb()); + } + } + } + }); + + t.start(); + } + */ + + } @@ -6173,8 +6100,7 @@ public void mouseExited(MouseEvent e) { public void showDoingBackupScreen() { boolean isError = !ps.errText.equals(""); - JPanel subInnerCore = getModalJPanel("Doing Backup. Please wait..."); - maybeShowError(subInnerCore); + JPanel subInnerCore = getPanel("Doing Backup. Please wait..."); AppUI.hr(subInnerCore, 4); } @@ -6182,8 +6108,7 @@ public void showDoingBackupScreen() { public void showSetDNSRecordScreen() { boolean isError = !ps.errText.equals(""); - JPanel subInnerCore = getModalJPanel("Setting DNS Record. Please wait..."); - maybeShowError(subInnerCore); + JPanel subInnerCore = getPanel("Setting DNS Record. Please wait..."); AppUI.hr(subInnerCore, 4); } @@ -6198,8 +6123,7 @@ public void showCreateSkyWalletScreen() { chooser.setFileFilter(filter); - JPanel subInnerCore = getModalJPanel("Create Sky Wallet"); - maybeShowError(subInnerCore); + JPanel subInnerCore = getPanel("Create Sky Wallet"); AppUI.hr(subInnerCore, 4); @@ -6480,143 +6404,47 @@ public void run(){ subInnerCore.add(bp); } - public void showCreateWalletScreen() { - JLabel x; - String str; + public void showCreateWalletScreen() { + int y = 0; + JLabel fname; MyTextField walletName = null; - str = "Create Wallet"; - - JPanel subInnerCore = getModalJPanel(str); - maybeShowError(subInnerCore); - - // Outer Container - JPanel oct = new JPanel(); - AppUI.setBoxLayout(oct, true); - AppUI.noOpaque(oct); - subInnerCore.add(oct); - - // Space - AppUI.hr(oct, 22); - - //if (!ps.isDefaultWalletBeingCreated) { - JPanel hct = new JPanel(); - - AppUI.setBoxLayout(hct, false); - AppUI.setMargin(hct, 0, 28, 0, 0); - AppUI.noOpaque(hct); - - AppUI.setSize(hct, tw / 2, 50); - - // Name Label - x = new JLabel("Name"); - AppUI.setCommonFont(x); - hct.add(x); - - AppUI.vr(hct, 50); - - walletName = new MyTextField("Wallet Name", false); - walletName.requestFocus(); - hct.add(walletName.getTextField()); - - oct.add(hct); - //} + JPanel subInnerCore = getPanel("Create Wallet"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); - // GridHolder Container - JPanel ct = new JPanel(); - AppUI.noOpaque(ct); - oct.add(ct); + fname = new JLabel("Wallet Name"); + walletName = new MyTextField("Wallet Name", false); + walletName.requestFocus(); + AppUI.getGBRow(subInnerCore, fname, walletName.getTextField(), y, gridbag); + y++; - GridBagLayout gridbag = new GridBagLayout(); - GridBagConstraints c = new GridBagConstraints(); - ct.setLayout(gridbag); + fname = new JLabel("Password Protected Wallet"); + MyCheckBoxToggle cb0 = new MyCheckBoxToggle(); + AppUI.getGBRow(subInnerCore, fname, cb0.getCheckBox(), y, gridbag); + y++; + fname = new JLabel("Enable Coin Recovery By Email"); + MyCheckBoxToggle cb1 = new MyCheckBoxToggle(); + AppUI.getGBRow(subInnerCore, fname, cb1.getCheckBox(), y, gridbag); + y++; - int y = 0; - - - // Empty Label before "Yes/No" - x = new JLabel(); - c.gridwidth = 1; - c.anchor = GridBagConstraints.WEST; - c.insets = new Insets(18, 18, 0, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y + 1; - gridbag.setConstraints(x, c); - ct.add(x); - - x = new JLabel("Yes"); - gridbag.setConstraints(x, c); - AppUI.setCommonFont(x); - ct.add(x); - - x = new JLabel(" No"); - AppUI.setCommonFont(x); - gridbag.setConstraints(x, c); - ct.add(x); - - // Y - x = new JLabel("Password Protected Wallet"); - AppUI.setCommonFont(x); - c.gridx = 0; - c.gridy = y + 2; - gridbag.setConstraints(x, c); - ct.add(x); - - ButtonGroup passwordGroup = new ButtonGroup(); - MyRadioButton rb0 = new MyRadioButton(); - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = y + 2; - gridbag.setConstraints(rb0.getRadioButton(), c); - ct.add(rb0.getRadioButton()); - rb0.attachToGroup(passwordGroup); - - - MyRadioButton rb1 = new MyRadioButton(); - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = y + 2; - gridbag.setConstraints(rb1.getRadioButton(), c); - ct.add(rb1.getRadioButton()); - rb1.attachToGroup(passwordGroup); - rb1.select(); - - // Next Y - x = new JLabel("Enable Coin Recovery by Email"); - AppUI.setCommonFont(x); - c.gridx = 0; - c.gridy = y + 3; - gridbag.setConstraints(x, c); - ct.add(x); - - ButtonGroup recoveryGroup = new ButtonGroup(); - MyRadioButton rb2 = new MyRadioButton(); - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = y + 3; - gridbag.setConstraints(rb2.getRadioButton(), c); - ct.add(rb2.getRadioButton()); - rb2.attachToGroup(recoveryGroup); - + AppUI.GBPad(subInnerCore, y, gridbag); + y++; - MyRadioButton rb3 = new MyRadioButton(); - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = y + 3; - gridbag.setConstraints(rb3.getRadioButton(), c); - ct.add(rb3.getRadioButton()); - rb3.attachToGroup(recoveryGroup); - rb3.select(); - - // Buttons - final MyRadioButton frb0 = rb0; - final MyRadioButton frb2 = rb2; + final MyCheckBoxToggle fcb0 = cb0; + final MyCheckBoxToggle fcb1 = cb1; final MyTextField fwalletName = walletName; - - JPanel bp = getTwoButtonPanel(new ActionListener() { + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { public void actionPerformed(ActionEvent e) { - ps.cwalletPasswordRequested = frb0.isSelected(); - ps.cwalletRecoveryRequested = frb2.isSelected(); + ps.cwalletPasswordRequested = fcb0.isChecked(); + ps.cwalletRecoveryRequested = fcb1.isChecked(); - //if (!ps.isDefaultWalletBeingCreated && fwalletName != null) { - //if (fwalletName != null) { if (!Validator.walletName(fwalletName.getText())) { ps.errText = "Wallet name is incorrect"; showScreen(); @@ -6624,8 +6452,6 @@ public void actionPerformed(ActionEvent e) { } ps.typedWalletName = fwalletName.getText().trim(); - //} - if (ps.cwalletPasswordRequested) { ps.currentScreen = ProgramState.SCREEN_SET_PASSWORD; showScreen(); @@ -6643,10 +6469,8 @@ public void actionPerformed(ActionEvent e) { ps.defaultWalletCreated = true; showScreen(); } - }); - - AppUI.hr(subInnerCore, 20); - subInnerCore.add(bp); + }, y, gridbag); + } public JPanel getTwoButtonPanel(ActionListener al) { @@ -6751,28 +6575,27 @@ public void actionPerformed(ActionEvent e) { } public JPanel getRightPanel() { - return getRightPanel(AppUI.getColor2()); + return getRightPanel(AppUI.getColor6()); } - public JPanel getRightPanel(Color color) { + public JPanel getRightPanel(Color color) { JPanel mwrapperPanel = new JPanel(); - + AppUI.setBoxLayout(mwrapperPanel, true); - AppUI.noOpaque(mwrapperPanel); AppUI.alignLeft(mwrapperPanel); AppUI.alignTop(mwrapperPanel); - AppUI.setSize(mwrapperPanel, tw - 260, th); + AppUI.setBackground(mwrapperPanel, color); + AppUI.setMargin(mwrapperPanel, 32); + + AppUI.setSize(mwrapperPanel, tw - 260, th - headerHeight - 70); - JPanel subInnerCore = AppUI.createRoundedPanel(mwrapperPanel, color, 20); - AppUI.setSize(subInnerCore, tw - 260, th - headerHeight - 120); - corePanel.add(mwrapperPanel); updateWalletAmount(); if (!ps.isEchoFinished) sm.startEchoService(new EchoCb()); - return subInnerCore; + return mwrapperPanel; } public void showLeftScreen() { @@ -6788,21 +6611,21 @@ public void showLeftScreen() { AppUI.alignTop(wpanel); AppUI.noOpaque(wpanel); AppUI.setBoxLayout(wpanel, true); - - JLayeredPane walletWidget; - + // List wallets wallets = sm.getWallets(); for (int i = 0; i < wallets.length; i++) { // if (wallets[i].isSkyWallet()) // continue; - walletWidget = getWallet(wallets[i], 0); - wpanel.add(walletWidget); + + wpanel.add(getWallet(wallets[i], 0)); + wpanel.add(AppUI.hr(10)); } // "Add" Button wpanel.add(getWallet(null, TYPE_ADD_BUTTON)); + wpanel.add(AppUI.hr(10)); // "Add Sky Wallet" Button if (ps.defaultWalletCreated) @@ -6848,41 +6671,22 @@ public boolean isVisible() { corePanel.add(lwrapperPanel); } - public JLayeredPane getWallet(Wallet wallet, int type) { + public JPanel getWallet(Wallet wallet, int type) { + int y = 0; boolean isDisabled = true; if (wallet != null) isDisabled = !isActiveWallet(wallet); - // Pane - JLayeredPane lpane = new JLayeredPane(); - AppUI.noOpaque(lpane); - AppUI.setSize(lpane, 200, 140); - AppUI.alignLeft(lpane); - - // Rounded Background - Color color = isDisabled ? AppUI.getColor3() : AppUI.getColor4(); + final Color color = isDisabled ? AppUI.getColor6() : AppUI.getColor3(); - final JButton addBtn = new JButton(""); - addBtn.setBorder(new RoundedBorder(20, color)); - addBtn.setFocusPainted(false); - addBtn.setContentAreaFilled(false); - addBtn.setBounds(0, 0, 200, 120); - - - JPanel cx = new JPanel(); - cx.setBounds(0,12,200,100); - AppUI.noOpaque(cx); - + final JPanel wpanel = new JPanel(); + AppUI.setSize(wpanel, 200, 110); + //AppUI.setMargin(wpanel, 10); + AppUI.setBackground(wpanel, color); GridBagLayout gridbag = new GridBagLayout(); - cx.setLayout(gridbag); - - GridBagConstraints c = new GridBagConstraints(); - c.anchor = GridBagConstraints.CENTER; - c.insets = new Insets(0, 0, 0, 0); + wpanel.setLayout(gridbag); - int y = 0; - String name; if (wallet == null) { if (type == TYPE_ADD_BUTTON) @@ -6895,99 +6699,67 @@ else if (type == TYPE_ADD_SKY) name = wallet.getName(); } - JLabel l = new JLabel(name); - + JLabel labelName = new JLabel(name); if (isDisabled) { - AppUI.setColor(l, AppUI.getDisabledColor2()); - AppUI.setFont(l, 22); + AppUI.setColor(labelName, AppUI.getDisabledColor2()); + AppUI.setFont(labelName, 16); } else { - AppUI.setBoldFont(l, 22); + AppUI.setBoldFont(labelName, 16); + AppUI.setColor(labelName, AppUI.getColor5()); + wpanel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, AppUI.getColor0())); } - - AppUI.alignCenter(l); - c.gridwidth = 3; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - gridbag.setConstraints(l, c); - cx.add(l); - - y++; - - final JButton faddBtn = addBtn; - final boolean fisDisabled = isDisabled; - + + final boolean fisDisabled = isDisabled; if (wallet != null) { - String iconNameL, iconNameR; - ImageJPanel icon; - if (wallet.isSkyWallet()) { - if (isDisabled) - iconNameL = "Cloud Icon.png"; - else - iconNameL = "Cloud Icon Acitve.png"; - } else if (wallet.isEncrypted()) { - if (isDisabled) - iconNameL = "Lock Icon Disabled.png"; - else - iconNameL = "Lock Icon.png"; - } else { - iconNameL = "dummy.png"; - } - - if (!wallet.getEmail().equals("")) { - if (isDisabled) - iconNameR = "Image 41.png"; - else - iconNameR = "Envelope.png"; - } else { - iconNameR = "dummy.png"; - } - - JLabel iconl, iconr; + String iconName = wallet.isSkyWallet() ? "walleticon.png" : "walleticonlight.png"; + JLabel icon; try { Image img; - img = ImageIO.read(getClass().getClassLoader().getResource("resources/" + iconNameL)); - iconl = new JLabel(new ImageIcon(img)); - - img = ImageIO.read(getClass().getClassLoader().getResource("resources/" + iconNameR)); - iconr = new JLabel(new ImageIcon(img)); - AppUI.setMargin(iconr, 5, 0, 0, 0); + img = ImageIO.read(getClass().getClassLoader().getResource("resources/" + iconName)); + icon = new JLabel(new ImageIcon(img)); } catch (Exception ex) { return null; } - c.insets = new Insets(24, 12, 0, 8); - c.gridwidth = 1; + + + GridBagConstraints c = new GridBagConstraints(); + c.anchor = GridBagConstraints.CENTER; + c.insets = new Insets(0, 10, 0, 0); c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.WEST; - gridbag.setConstraints(iconl, c); - cx.add(iconl); - - c.insets = new Insets(32, 0, 0, 0); + c.gridy = y; + c.gridheight = 2; + gridbag.setConstraints(icon, c); + + wpanel.add(icon); + c.insets = new Insets(0, 20, 0, 0); + c.gridx = GridBagConstraints.RELATIVE; + c.weightx = 1; + c.anchor = GridBagConstraints.NORTHWEST; + c.gridheight = 1; + gridbag.setConstraints(labelName, c); + wpanel.add(labelName); + + y++; + // Amount (empty) - JLabel jxl = new JLabel(""); - AppUI.setFont(jxl, 18); + JLabel jxl = new JLabel("111"); + AppUI.setSemiBoldFont(jxl, 16); + AppUI.setColor(jxl, AppUI.getColor1()); AppUI.alignCenter(jxl); AppUI.noOpaque(jxl); - //amWrapper.add(jxl); - //inner.add(amWrapper); + + c.insets = new Insets(12, 20, 0, 0); c.gridx = GridBagConstraints.RELATIVE; c.gridy = y; c.weightx = 1; - c.anchor = GridBagConstraints.CENTER; + c.anchor = GridBagConstraints.NORTHWEST; gridbag.setConstraints(jxl, c); - cx.add(jxl); + wpanel.add(jxl); // Set ref between wallet and its ui wallet.setuiRef(jxl); - - c.insets = new Insets(24, 8, 0, 12); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.weightx = 0; - c.anchor = GridBagConstraints.EAST; - gridbag.setConstraints(iconr, c); - cx.add(iconr); + final Wallet fwallet = wallet; MouseAdapter ma = new MouseAdapter() { @@ -7003,30 +6775,50 @@ public void mouseEntered(MouseEvent e) { if (!fisDisabled) return; - AppUI.roundCorners(faddBtn, AppUI.getColor5(), 20); + // AppUI.setBackground(wpanel, AppUI.getColor1()); + // AppUI.roundCorners(faddBtn, AppUI.getColor5(), 20); } - public void mouseExited(MouseEvent e) { - Color color = fisDisabled ? AppUI.getColor3() : AppUI.getColor4(); - - AppUI.roundCorners(faddBtn, color, 20); + public void mouseExited(MouseEvent e) { + // AppUI.setBackground(wpanel, color); + // AppUI.roundCorners(faddBtn, color, 20); } }; - cx.addMouseListener(ma); + wpanel.addMouseListener(ma); } else { - final JLabel plus = new JLabel("+"); - AppUI.setFont(plus, 64); - if (isDisabled) - AppUI.setColor(plus, AppUI.getDisabledColor2()); - - c.gridwidth = 3; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; + String iconName = (type == TYPE_ADD_BUTTON) ? "walleticon.png" : "vaulticon.png"; + JLabel icon; + try { + Image img; + + img = ImageIO.read(getClass().getClassLoader().getResource("resources/" + iconName)); + icon = new JLabel(new ImageIcon(img)); + } catch (Exception ex) { + return null; + } + + + GridBagConstraints c = new GridBagConstraints(); c.anchor = GridBagConstraints.CENTER; - c.insets = new Insets(0, 0, 0, 0); - gridbag.setConstraints(plus, c); - cx.add(plus); + c.insets = new Insets(0, 8, 0, 0); + c.gridx = GridBagConstraints.RELATIVE; + c.gridy = y; + c.gridheight = 1; + gridbag.setConstraints(icon, c); + + wpanel.add(icon); + + + c.insets = new Insets(0, 20, 0, 0); + if (type == TYPE_ADD_SKY) + c.insets = new Insets(0, 10, 0, 0); + c.gridx = GridBagConstraints.RELATIVE; + c.weightx = 1; + c.anchor = GridBagConstraints.NORTHWEST; + c.gridheight = 1; + gridbag.setConstraints(labelName, c); + wpanel.add(labelName); final int ftype = type; MouseAdapter ma = new MouseAdapter() { @@ -7045,32 +6837,24 @@ public void mouseReleased(MouseEvent e) { } public void mouseEntered(MouseEvent e) { - AppUI.roundCorners(faddBtn, AppUI.getColor5(), 20); + // AppUI.roundCorners(faddBtn, AppUI.getColor5(), 20); } public void mouseExited(MouseEvent e) { - Color color = fisDisabled ? AppUI.getColor3() : AppUI.getColor4(); + // Color color = fisDisabled ? AppUI.getColor3() : AppUI.getColor4(); - AppUI.roundCorners(faddBtn, color, 20); + // AppUI.roundCorners(faddBtn, color, 20); } }; - cx.addMouseListener(ma); + wpanel.addMouseListener(ma); } - lpane.addMouseListener( new MouseAdapter() { - @Override - public void mouseReleased(MouseEvent e) { - addBtn.requestFocus(); - } - }); - - lpane.add(addBtn, new Integer(1)); - lpane.add(cx, new Integer(2)); + - AppUI.setHandCursor(lpane); + AppUI.setHandCursor(wpanel); - return lpane; + return wpanel; } public void showAgreementScreen() { @@ -7234,7 +7018,6 @@ protected void configureScrollBarColors(){ c.gridx = 0; c.gridy = y; c.gridwidth = 1; - //c.fill = GridBagConstraints.HORIZONTAL; c.fill = GridBagConstraints.BOTH; @@ -7260,25 +7043,29 @@ protected void configureScrollBarColors(){ corePanel.add(agreementPanel); } - public JPanel getModalJPanel(String title) { + public JPanel getPanel(String title) { showLeftScreen(); - JPanel rightPanel = getRightPanel(); + JPanel rightPanel = getRightPanel(); + if (title != null) { + JLabel text = new JLabel(title); + AppUI.alignLeft(text); + AppUI.setFont(text, 30); + AppUI.setColor(text, AppUI.getColor1()); + rightPanel.add(text); + rightPanel.add(AppUI.hr(22)); + } - JPanel xpanel = new JPanel(new GridBagLayout()); - AppUI.noOpaque(xpanel); - rightPanel.add(xpanel); + maybeShowError(rightPanel); - JPanel subInnerCore = AppUI.createRoundedPanel(xpanel, AppUI.getColor12(), 20); - AppUI.setSize(subInnerCore, 718, 446); + JPanel holder = new JPanel(); + AppUI.alignLeft(holder); + AppUI.noOpaque(holder); - AppUI.hr(subInnerCore, 14); - // Title - JLabel ltitle = AppUI.getTitle(title); - subInnerCore.add(ltitle); + rightPanel.add(holder); - return subInnerCore; + return holder; } @@ -7319,7 +7106,7 @@ public static void main(String[] args) { } - UIManager.put("ScrollBar.background", new ColorUIResource(AppUI.getColor0())); + UIManager.put("ScrollBar.background", new ColorUIResource(AppUI.getColor6())); SwingUtilities.invokeLater(new Runnable() { public void run() { new AdvancedClient(); diff --git a/src/advclient/AppUI.java b/src/advclient/AppUI.java index fd4dbc9..d70cbf1 100644 --- a/src/advclient/AppUI.java +++ b/src/advclient/AppUI.java @@ -16,6 +16,11 @@ import java.awt.Dimension; import java.awt.Font; import java.awt.GraphicsEnvironment; +import java.awt.GridBagConstraints; +import java.awt.GridBagLayout; +import java.awt.Insets; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.font.TextAttribute; @@ -154,7 +159,8 @@ public static Color getColor4() { } public static Color getColor5() { - return Color.WHITE; + return new Color(0xD4D4D4); + //return Color.WHITE; } public static Color getColor6() { return new Color(0x1F222B); @@ -164,27 +170,27 @@ public static Color getColor7() { } public static Color getColor8() { - return new Color(0xE5E5E5); + return new Color(0x1B1E26); } public static Color getColor9() { - return new Color(0x5FA8FF); + return new Color(0x65676B); } public static Color getColor10() { - return new Color(0x777777); + return new Color(0x43485A); } public static Color getColor11() { - return new Color(0xF2F6FB); + return new Color(0x4C5266); } public static Color getColor12() { - return new Color(0xF7F9FC); + return new Color(0xEB788B); } public static Color getColor13() { - return new Color(0x919396); + return new Color(0x62A459); } @@ -226,7 +232,7 @@ public static Color blendColors(Color c0, Color c1) { public static double getBoxWidth() { - return AppUI.tw / 3; + return AppUI.tw / 4; } public static double getBoxHeight() { @@ -345,7 +351,8 @@ public static void setBoldFont(Component c, int size) { public static void setCommonFont(Component c) { - AppUI.setFont(c, 25); + AppUI.setFont(c, 16); + AppUI.setColor(c, AppUI.getColor5()); } public static void setCommonBoldFont(Component c) { @@ -400,7 +407,7 @@ public static JFrame getMainFrame(String version) { } public static JPanel createRoundedPanel(JPanel parent) { - return createRoundedPanel(parent, AppUI.getColor2(), 60, 20); + return createRoundedPanel(parent, AppUI.getColor5(), 60, 20); } public static JPanel createRoundedPanel(JPanel parent, Color color, int sideMargin) { @@ -412,8 +419,9 @@ public static JPanel createRoundedPanel(JPanel parent, Color color, int sideMarg AppUI.setBoxLayout(p, true); AppUI.alignCenter(p); - AppUI.roundCorners(p, color, radius); + //AppUI.roundCorners(p, color, radius); AppUI.noOpaque(p); + AppUI.setBackground(p, color); JPanel subInnerCore = new JPanel(); AppUI.setBoxLayout(subInnerCore, true); @@ -490,7 +498,7 @@ public static JScrollPane setupTable(JTable table, String[] columnNames, String[ DefaultTableModel model = new DefaultTableModel(data.length, data[0].length - 1) { @Override public String getColumnName(int col) { - return fcolumnNames[col]; + return fcolumnNames[col].toUpperCase(); } @Override @@ -510,19 +518,20 @@ public boolean isCellEditable(int row, int column){ } } - table.setRowHeight(table.getRowHeight() + 15); + table.setRowHeight(table.getRowHeight() + 35); table.setDefaultRenderer(String.class, r); - table.setIntercellSpacing(new Dimension(1, 1)); + table.setIntercellSpacing(new Dimension(0, 1)); table.setFocusable(false); table.setRowSelectionAllowed(false); - table.setGridColor(AppUI.getColor7()); + table.setGridColor(AppUI.getColor10()); - JTableHeader header = table.getTableHeader(); - AppUI.setColor(header, Color.WHITE); + JTableHeader header = table.getTableHeader(); + AppUI.setColor(header, AppUI.getColor11()); AppUI.noOpaque(header); AppUI.setCommonTableFont(table); - AppUI.setCommonTableFont(header); + AppUI.setSemiBoldFont(header, 14); + final TableCellRenderer hr = table.getTableHeader().getDefaultRenderer(); header.setDefaultRenderer(new TableCellRenderer() { @@ -530,11 +539,18 @@ public boolean isCellEditable(int row, int column){ @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { lbl = (JLabel) hr.getTableCellRendererComponent(table, value, true, true, row, column); - lbl.setHorizontalAlignment(SwingConstants.LEFT); - - //internal transaction table margins - AppUI.setMargin(lbl, 2, 10, 2, 2); - AppUI.setBackground(lbl, AppUI.getColor0()); + //lbl.setHorizontalAlignment(SwingConstants.LEFT); + + if (column == 0 || column == 1) + lbl.setHorizontalAlignment(SwingConstants.LEFT); + else + lbl.setHorizontalAlignment(SwingConstants.RIGHT); + + lbl.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, AppUI.getColor10())); + lbl.setBorder(BorderFactory.createCompoundBorder(lbl.getBorder(), BorderFactory.createEmptyBorder(0, 6, 10, 0))); + + AppUI.setBackground(lbl, AppUI.getColor6()); + return lbl; } }); @@ -542,7 +558,8 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole //This is the wallet table size JScrollPane scrollPane = new JScrollPane(table); - AppUI.setSize(scrollPane, 660, 325); + AppUI.setSize(scrollPane, 880, 310); + scrollPane.getVerticalScrollBar().setPreferredSize(new Dimension(10, 0)); scrollPane.getVerticalScrollBar().setUI(new BasicScrollBarUI() { @Override protected JButton createDecreaseButton(int orientation) { @@ -551,7 +568,10 @@ protected JButton createDecreaseButton(int orientation) { jbutton.setContentAreaFilled(false); jbutton.setFocusPainted(false); - return jbutton; + JButton b = new JButton(); + AppUI.setSize(b, 0, 0); + + return b; } @Override @@ -561,13 +581,16 @@ protected JButton createIncreaseButton(int orientation) { jbutton.setContentAreaFilled(false); jbutton.setFocusPainted(false); - return jbutton; + JButton b = new JButton(); + AppUI.setSize(b, 0, 0); + + return b; } - - @Override + + @Override protected void configureScrollBarColors(){ - this.trackColor = AppUI.getColor6(); - this.thumbColor = AppUI.getColor7(); + this.trackColor = AppUI.getColor7(); + this.thumbColor = AppUI.getColor2(); } }); @@ -590,7 +613,7 @@ public static JLabel getHyperLink(String name, String url, int fontSize) { else AppUI.setFont(l, fontSize); - AppUI.setColor(l, AppUI.getColor0()); + AppUI.setColor(l, AppUI.getColor2()); AppUI.underLine(l); AppUI.setHandCursor(l); l.addMouseListener(new MouseAdapter() { @@ -612,4 +635,122 @@ public void mouseReleased(MouseEvent e) { return l; } + + public static void getGBRow(JComponent parent, JComponent left, JComponent right, int y, GridBagLayout gridbag) { + GridBagConstraints c = new GridBagConstraints(); + + c.anchor = GridBagConstraints.NORTHWEST; + c.insets = new Insets(20, 0, 0, 0); + c.gridy = y; + c.weightx = 0; + c.weighty = 0; + + if (left != null) { + if (left instanceof JLabel) { + AppUI.setCommonFont(left); + } + + gridbag.setConstraints(left, c); + parent.add(left); + } else { + c.gridwidth = 2; + } + + c.insets = new Insets(10, 0, 0, 0); + c.weightx = 1; + + if (right != null) { + if (right instanceof JLabel) { + AppUI.setCommonFont(right); + } + + gridbag.setConstraints(right, c); + parent.add(right); + } + } + + public static void GBPad(JComponent parent, int y, GridBagLayout gridbag) { + GridBagConstraints c = new GridBagConstraints(); + JPanel padder = new JPanel(); + AppUI.noOpaque(padder); + c.anchor = GridBagConstraints.NORTHWEST; + c.insets = new Insets(0, 0, 0, 0); + c.gridx = GridBagConstraints.RELATIVE; + c.gridy = y; + c.weightx = 1; + c.weighty = 1; + gridbag.setConstraints(padder, c); + parent.add(padder); + } + + public static MyButton getTwoButtonPanel(JComponent parent, String name0, String name1, + ActionListener al0, ActionListener al1, int y, GridBagLayout gridbag) { + GridBagConstraints c = new GridBagConstraints(); + + c.anchor = GridBagConstraints.NORTHEAST; + c.insets = new Insets(20, 0, 0, 10); + c.gridy = y; + c.weightx = 1; + c.weighty = 0; + c.gridwidth = 2; + + if (!name0.isEmpty()) { + MyButton cb0 = new MyButton(name0, AppUI.getColor3()); + cb0.addListener(al0); + + gridbag.setConstraints(cb0.getButton(), c); + parent.add(cb0.getButton()); + } + + MyButton cb1 = new MyButton(name1); + cb1.addListener(al1); + c.weightx = 0; + gridbag.setConstraints(cb1.getButton(), c); + parent.add(cb1.getButton()); + + return cb1; + } + + public static JLabel wrapDiv(String text) { + return new JLabel("
" + text + "
"); + } + + + public static void addInvItem(JComponent parent, String denomination, int count) { + JPanel invItem = new JPanel(); + AppUI.setMargin(invItem, 0, 0, 0, 0); + AppUI.noOpaque(invItem); + AppUI.setBoxLayout(invItem, true); + + JLabel l0 = new JLabel(AppCore.formatNumber(count)); + AppUI.alignCenter(l0); + + JPanel hyp = new JPanel(); + AppUI.setSize(hyp, 48, 1); + AppUI.setBackground(hyp, AppUI.getColor9()); + + JLabel l1 = new JLabel(denomination + "'s"); + AppUI.alignCenter(l1); + + AppUI.setFont(l0, 14); + AppUI.setFont(l1, 14); + if (count > 0) { + AppUI.setColor(l0, AppUI.getColor5()); + AppUI.setColor(l1, AppUI.getColor5()); + } else { + AppUI.setColor(l0, AppUI.getColor9()); + AppUI.setColor(l1, AppUI.getColor9()); + } + + AppUI.setMargin(l0, 0, 0, 0, 0); + AppUI.setMargin(l1, 4); + + + invItem.add(l0); + invItem.add(hyp); + invItem.add(l1); + + parent.add(invItem); + } + } diff --git a/src/advclient/MyButton.java b/src/advclient/MyButton.java index 3d23691..638f911 100644 --- a/src/advclient/MyButton.java +++ b/src/advclient/MyButton.java @@ -25,11 +25,19 @@ public class MyButton { JPanel core; JButton button; + Color color; public MyButton(String text) { + this.color = AppUI.getColor2(); core = makeUI(text); } + public MyButton(String text, Color color) { + this.color = color; + core = makeUI(text); + + } + public JPanel getButton() { return core; } @@ -49,7 +57,7 @@ public void disable() { public void enable() { button.setEnabled(true); RoundedBorder rb = (RoundedBorder) button.getBorder(); - rb.setColor(AppUI.getColor2()); + rb.setColor(this.color); button.repaint(); button.revalidate(); } @@ -73,10 +81,10 @@ public boolean doWork(Graphics g, JComponent c) { } }; - AppUI.roundCorners(button, AppUI.getColor2(), 48, cb); + AppUI.roundCorners(button, this.color, 48, cb); AppUI.noOpaque(button); button.setContentAreaFilled(false); - AppUI.setSize(button, 214, 48); + AppUI.setSize(button, 190, 48); AppUI.setFont(button, 18); AppUI.setHandCursor(button); diff --git a/src/advclient/MyCheckBoxToggle.java b/src/advclient/MyCheckBoxToggle.java new file mode 100644 index 0000000..e3a153d --- /dev/null +++ b/src/advclient/MyCheckBoxToggle.java @@ -0,0 +1,91 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package advclient; + +import java.awt.Color; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Image; +import java.awt.RenderingHints; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import javax.imageio.ImageIO; +import javax.swing.Icon; +import javax.swing.ImageIcon; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JLabel; +import javax.swing.JPanel; + +/** + * + * @author Alexander + */ +public class MyCheckBoxToggle { + + Icon imgUnchecked, imgChecked; + boolean isChecked; + + JPanel core; + JCheckBox cb; + + public MyCheckBoxToggle() { + core = makeUI(); + } + + public JPanel getCheckBox() { + return core; + } + + public void addListener(ItemListener i) { + cb.addItemListener(i); + } + + public boolean isChecked() { + return cb.isSelected(); + } + + public JPanel makeUI() { + cb = new JCheckBox(); + + try { + Image img; + + img = ImageIO.read(getClass().getClassLoader().getResource("resources/toggleno.png")); + imgUnchecked = new ImageIcon(img); + + img = ImageIO.read(getClass().getClassLoader().getResource("resources/toggleyes.png")); + imgChecked = new ImageIcon(img); + } catch (Exception ex) { + + } + + AppUI.noOpaque(cb); + cb.addItemListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + Icon img; + + img = (e.getStateChange() != ItemEvent.SELECTED) ? imgUnchecked : imgChecked; + cb.setIcon(img); + } + }); + + cb.setIcon(imgUnchecked); + + JPanel p = new JPanel(); + AppUI.setBoxLayout(p, false); + AppUI.noOpaque(p); + AppUI.setHandCursor(p); + + p.add(cb); + + return p; + } +} + + diff --git a/src/advclient/MyTextField.java b/src/advclient/MyTextField.java index e5986fa..4dc0d3f 100644 --- a/src/advclient/MyTextField.java +++ b/src/advclient/MyTextField.java @@ -80,11 +80,13 @@ public void setData(String text) { public JPanel makeUI(String placeholder) { tf = new RoundedTextField(placeholder); + tf.setCaretColor(Color.WHITE); AppUI.noOpaque(tf); AppUI.setSize(tf, (int) AppUI.getBoxWidth(), (int) AppUI.getBoxHeight()); - AppUI.setBackground(tf, AppUI.getColor4()); + AppUI.setBackground(tf, AppUI.getColor8()); AppUI.setFont(tf, 18); + AppUI.setColor(tf, AppUI.getColor5()); AppUI.setMargin(tf, 10); tf.setLayout(new BorderLayout()); diff --git a/src/advclient/RoundedTextField.java b/src/advclient/RoundedTextField.java index aa76889..17e7a28 100644 --- a/src/advclient/RoundedTextField.java +++ b/src/advclient/RoundedTextField.java @@ -84,7 +84,7 @@ protected void paintComponent(Graphics g) { g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); // g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.4f)); g.setColor(getBackground()); - g.fillRoundRect(0, 0, getWidth()-1, getHeight()-1, 15, 15); + g.fillRoundRect(0, 0, getWidth()-1, getHeight()-1, 42, 42); if (!placeholder.equals("")) { g.setColor(AppUI.getDisabledColor2()); int width = g.getFontMetrics().stringWidth(placeholder); @@ -109,7 +109,7 @@ protected void paintBorder(Graphics g) { public boolean contains(int x, int y) { if (shape == null || !shape.getBounds().equals(getBounds())) { - shape = new RoundRectangle2D.Float(0, 0, getWidth()-1, getHeight()-1, 15, 15); + shape = new RoundRectangle2D.Float(0, 0, getWidth()-1, getHeight()-1, 42, 42); } return shape.contains(x, y); } diff --git a/src/resources/arrowleft.png b/src/resources/arrowleft.png new file mode 100644 index 0000000000000000000000000000000000000000..9b9ab0300bf5367fca33e501ae8b7acccbb66b6b GIT binary patch literal 3114 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 Ef^iVl&;S4c literal 0 HcmV?d00001 diff --git a/src/resources/arrowright.png b/src/resources/arrowright.png new file mode 100644 index 0000000000000000000000000000000000000000..d2bb335eaf58c3355cd81f949dd7ac4cef34ae73 GIT binary patch literal 3133 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 X1KNCi)4i4Z00000NkvXXu0mjf;tT09 literal 0 HcmV?d00001 diff --git a/src/resources/coinsinventory.png b/src/resources/coinsinventory.png new file mode 100644 index 0000000000000000000000000000000000000000..1948dd98e974bfd0c3a64cd928adcc907b02033f GIT binary patch literal 3831 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 AFaQ7m literal 0 HcmV?d00001 diff --git a/src/resources/toggleyes.png b/src/resources/toggleyes.png new file mode 100644 index 0000000000000000000000000000000000000000..d408451e12fb69906b69dbe804c9772805595894 GIT binary patch literal 4419 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 Date: Wed, 7 Aug 2019 21:10:02 +0300 Subject: [PATCH 005/160] deposit screen --- src/advclient/AdvancedClient.java | 221 ++++++++--------------- src/advclient/RoundedCornerComboBox.java | 21 +-- 2 files changed, 81 insertions(+), 161 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 25c4174..8a11d23 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -341,9 +341,10 @@ public void clear() { corePanel.removeAll(); - corePanel.repaint(); - + corePanel.repaint(); corePanel.revalidate(); + + AppUI.setMargin(corePanel, 20); } public void initMainScreen() { @@ -845,7 +846,9 @@ public void showScreen() { wl.debug(ltag, "SCREEN " + ps.currentScreen + ": " + ps.toString()); clear(); - + + + switch (ps.currentScreen) { case ProgramState.SCREEN_AGREEMENT: resetState(); @@ -4113,53 +4116,14 @@ public void actionPerformed(ActionEvent e) { } public void showDepositScreen() { - boolean isError = !ps.errText.equals(""); - - showLeftScreen(); - - JPanel rightPanel = getRightPanel(); - - JPanel ct = new JPanel(); - AppUI.setBoxLayout(ct, true); - AppUI.noOpaque(ct); - rightPanel.add(ct); - - JLabel ltitle = AppUI.getTitle("Deposit"); - ct.add(ltitle); - AppUI.alignTop(ct); - AppUI.alignTop(ltitle); - - AppUI.hr(ct, 2); - - maybeShowError(ct); - - // Outer Container - JPanel oct = new JPanel(); - AppUI.noOpaque(oct); - int y = 0; - + JLabel fname; + MyTextField walletName = null; + + JPanel subInnerCore = getPanel("Deposit"); GridBagLayout gridbag = new GridBagLayout(); - GridBagConstraints c = new GridBagConstraints(); - c.gridwidth = 1; - c.anchor = GridBagConstraints.EAST; - c.insets = new Insets(12, 18, 0, 0); - oct.setLayout(gridbag); - - - // Deposit To - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.EAST; - JLabel x = new JLabel("Deposit To"); - gridbag.setConstraints(x, c); - AppUI.setCommonFont(x); - oct.add(x); - - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.WEST; - + subInnerCore.setLayout(gridbag); + int nonSkyCnt = 0; for (int i = 0; i < wallets.length; i++) if (!wallets[i].isSkyWallet()) @@ -4173,67 +4137,68 @@ public void showDepositScreen() { j++; } } - - final RoundedCornerComboBox cbox = new RoundedCornerComboBox(AppUI.getColor2(), "Select Destination", options); - gridbag.setConstraints(cbox.getComboBox(), c); - oct.add(cbox.getComboBox()); - - y++; - // Password - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.EAST; - final JLabel pText = new JLabel("Password"); - gridbag.setConstraints(pText, c); - AppUI.setCommonFont(pText); - oct.add(pText); + fname = new JLabel("Deposit To"); + final RoundedCornerComboBox cbox = new RoundedCornerComboBox(AppUI.getColor6(), "Select Destination", options); + AppUI.getGBRow(subInnerCore, fname, cbox.getComboBox(), y, gridbag); + y++; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.WEST; - final MyTextField password = new MyTextField("Wallet Password", true); - gridbag.setConstraints(password.getTextField(), c); - oct.add(password.getTextField()); + fname = new JLabel("Password"); + final JLabel pText = fname; + final MyTextField password = new MyTextField("Wallet Password", true); + AppUI.getGBRow(subInnerCore, fname, password.getTextField(), y, gridbag); + y++; + password.getTextField().setVisible(false); pText.setVisible(false); - y++; - // Memo - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.EAST; - x = new JLabel("Memo (Note)"); - gridbag.setConstraints(x, c); - AppUI.setCommonFont(x); - oct.add(x); - - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.WEST; + fname = new JLabel("Memo (Note)"); final MyTextField memo = new MyTextField("Optional", false); - gridbag.setConstraints(memo.getTextField(), c); - if (!ps.typedMemo.isEmpty()) memo.setData(ps.typedMemo); - oct.add(memo.getTextField()); - - - - // Total files selected + AppUI.getGBRow(subInnerCore, fname, memo.getTextField(), y, gridbag); + y++; + String totalCloudCoins = AppCore.calcCoinsFromFilenames(ps.files); final JLabel tl = new JLabel("Selected " + ps.files.size() + " files - " + totalCloudCoins + " CloudCoins"); - AppUI.setCommonFont(tl); - c.insets = new Insets(22, 18, 0, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridwidth = 2; - c.anchor = GridBagConstraints.CENTER; - c.gridy = y + 3; - gridbag.setConstraints(tl, c); - oct.add(tl); - + AppUI.getGBRow(subInnerCore, null, tl, y, gridbag); + y++; + + + int ddWidth = 701; + JPanel ddPanel = new JPanel(); + ddPanel.setLayout(new GridBagLayout()); + + JLabel l = new JLabel("
Drop files here or click
to select files
"); + AppUI.setColor(l, AppUI.getColor13()); + AppUI.setBoldFont(l, 32); + AppUI.noOpaque(ddPanel); + AppUI.setHandCursor(ddPanel); + ddPanel.setBorder(new DashedBorder(40, AppUI.getColor13())); + ddPanel.add(l); + + AppUI.setSize(ddPanel, (int) ddWidth, 150); + + AppUI.getGBRow(subInnerCore, null, ddPanel, y, gridbag); + y++; + + + + + + + + + + + + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + cbox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { String walletName = cbox.getSelectedValue(); @@ -4256,29 +4221,6 @@ public void actionPerformed(ActionEvent e) { } - int ddWidth = 701; - - // Drag and Drop - JPanel ddPanel = new JPanel(); - // AppUI.setBackground(ddPanel, AppUI.getColor0()); - ddPanel.setLayout(new GridBagLayout()); - - JLabel l = new JLabel("
Drop files here or click
to select files
"); - AppUI.setColor(l, AppUI.getColor13()); - AppUI.setBoldFont(l, 40); - AppUI.noOpaque(ddPanel); - AppUI.setHandCursor(ddPanel); - ddPanel.setBorder(new DashedBorder(40, AppUI.getColor13())); - ddPanel.add(l); - - c.insets = new Insets(8, 18, 0, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridwidth = 2; - c.anchor = GridBagConstraints.CENTER; - c.gridy = y + 4; - - AppUI.setSize(ddPanel, (int) ddWidth, 150); - gridbag.setConstraints(ddPanel, c); new FileDrop(null, ddPanel, new FileDrop.Listener() { public void filesDropped( java.io.File[] files ) { for( int i = 0; i < files.length; i++ ) { @@ -4316,14 +4258,15 @@ public void mouseReleased(MouseEvent e) { } } }); - - oct.add(ddPanel); - rightPanel.add(oct); - // Space - AppUI.hr(oct, 22); - JPanel bp = getTwoButtonPanel(new ActionListener() { + + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { public void actionPerformed(ActionEvent e) { String walletName = cbox.getSelectedValue(); Wallet w; @@ -4406,10 +4349,7 @@ public void actionPerformed(ActionEvent e) { showScreen(); } - }); - - AppUI.hr(rightPanel, 20); - rightPanel.add(bp); + }, y, gridbag); } public void showFoldersScreen() { @@ -6651,23 +6591,7 @@ public boolean isVisible() { scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); lwrapperPanel.add(scrollPane); - /* - //scrollBar.setValue(200); - InputMap im = scrollBar.getInputMap(JComponent.WHEN_FOCUSED); - ActionMap actMap = scrollBar.getActionMap(); - //InputMap im = scrollBar.getInputMap(); - - im.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "Up"); - im.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "Down"); - actMap.put("Up", new UpDownAction("Up", scrollPane.getVerticalScrollBar().getModel(), 42)); - actMap.put("Down", new UpDownAction("Down", scrollPane.getVerticalScrollBar().getModel(), 42)); - - */ - //lwrapperPanel.requestFocus(); - //lwrapperPanel.requestFocusInWindow(); - //lwrapperPanel.setFocusable(true); - corePanel.add(lwrapperPanel); } @@ -6857,7 +6781,7 @@ public void mouseExited(MouseEvent e) { return wpanel; } - public void showAgreementScreen() { + public void showAgreementScreen() { AppUI.setMargin(corePanel, 40, 120, 80, 120); // Agreement Panel @@ -7038,8 +6962,7 @@ protected void configureScrollBarColors(){ gridbag.setConstraints(buttonWrapper, c); agreementPanel.add(buttonWrapper); - //agreementPanel.add(scrollPane); - + corePanel.add(agreementPanel); } diff --git a/src/advclient/RoundedCornerComboBox.java b/src/advclient/RoundedCornerComboBox.java index 699d6a6..1d40231 100644 --- a/src/advclient/RoundedCornerComboBox.java +++ b/src/advclient/RoundedCornerComboBox.java @@ -100,10 +100,11 @@ public void addOption(String option) { public JPanel makeUI() { - background = AppUI.blendColors(AppUI.getColor4(), outerBgColor); + background = AppUI.blendColors(AppUI.getColor8(), outerBgColor); foreground = background; - UIManager.put("ComboBox.selectionForeground", Color.BLACK); + background = AppUI.getColor8(); + UIManager.put("ComboBox.selectionForeground", AppUI.getColor5()); UIManager.put("ComboBox.selectionBackground", background); combo1 = new JComboBox<>(); @@ -169,7 +170,7 @@ public void drop() { @Override public void setSelectedItem(Object anObject) { if (!placeholder.equals(anObject)) { - AppUI.setColor(combo1, Color.BLACK); + AppUI.setColor(combo1, AppUI.getColor5()); super.setSelectedItem(anObject); } else if (selectionAllowed) { AppUI.setColor(combo1, AppUI.getDisabledColor2()); @@ -226,7 +227,7 @@ public void popupMenuCanceled(PopupMenuEvent e) { class RoundedCornerBorder extends AbstractBorder { protected Color outerBgColor; - protected static final int ARC = 12; + protected static final int ARC = 32; public RoundedCornerBorder(Color outerBgColor) { this.outerBgColor = outerBgColor; @@ -284,9 +285,10 @@ public void paintBorder(Component c, Graphics g, int x, int y, int width, int he b.setBounds(b.x, b.y + r, b.width, b.height - r); round.add(new Area(b)); + Container parent = c.getParent(); if (parent != null) { - g2.setPaint(parent.getBackground()); + g2.setPaint(outerBgColor); Area corner = new Area(new Rectangle2D.Float(x, y, width, height)); corner.subtract(round); g2.fill(corner); @@ -334,14 +336,9 @@ public void paintBorder(Component c, Graphics g, int x, int y, int width, int he Area round = new Area(p); g2.setPaint(c.getBackground()); - //g2.setPaint(Color.RED); g2.fill(round); - - //g2.setPaint(c.getForeground()); - // g2.setPaint(Color.RED); - // g2.draw(round); g2.setPaint(c.getBackground()); - // g2.setPaint(Color.RED); + g2.drawLine(x + 1, y, x + width - 2, y); g2.dispose(); } @@ -423,7 +420,7 @@ public Component getListCellRendererComponent(JList list, Object value, if (index == 0) { text.setForeground(AppUI.getDisabledColor2()); } else if (index > -1) { - text.setForeground(Color.BLACK); + text.setForeground(AppUI.getColor5()); } if (isSelected) { From 34b0766a01e1ee009cce16de290a9bec6d4997e7 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 8 Aug 2019 13:36:59 +0300 Subject: [PATCH 006/160] deposit-transfer --- src/advclient/AdvancedClient.java | 969 ++++++++-------------------- src/advclient/AppUI.java | 1 + src/advclient/FancyProgressBar.java | 2 +- src/advclient/MyCheckBoxToggle.java | 4 + 4 files changed, 273 insertions(+), 703 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 8a11d23..fec56a0 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -409,6 +409,26 @@ public boolean isBackupping() { return false; } + public boolean isCreatingWallet() { + if (ps.currentScreen == ProgramState.SCREEN_CREATE_WALLET || + ps.currentScreen == ProgramState.SCREEN_SET_PASSWORD || + ps.currentScreen == ProgramState.SCREEN_SET_EMAIL || + ps.currentScreen == ProgramState.SCREEN_UNDERSTAND_PASSWORD || + ps.currentScreen == ProgramState.SCREEN_WALLET_CREATED) + return true; + + return false; + } + + public boolean isCreatingSkyWallet() { + if (ps.currentScreen == ProgramState.SCREEN_CREATE_SKY_WALLET || + ps.currentScreen == ProgramState.SCREEN_SKY_WALLET_CREATED) + return true; + + return false; + } + + public void fillHeaderPanel() { //fills header with objects JPanel p = new JPanel(); @@ -846,8 +866,6 @@ public void showScreen() { wl.debug(ltag, "SCREEN " + ps.currentScreen + ": " + ps.toString()); clear(); - - switch (ps.currentScreen) { case ProgramState.SCREEN_AGREEMENT: @@ -991,7 +1009,7 @@ public void showScreen() { public void maybeShowError(JPanel p) { if (!ps.errText.isEmpty()) { - JLabel err = new JLabel(ps.errText); + JLabel err = AppUI.wrapDiv(ps.errText); AppUI.setFont(err, 16); AppUI.setColor(err, AppUI.getErrorColor()); @@ -1442,8 +1460,8 @@ public void showSendingScreen() { int y = 0; // Info - JLabel x = new JLabel("
From Wallet " + fwallet + " To Wallet " + twallet + "
"); - AppUI.setFont(x, 18); + JLabel x = new JLabel("From Wallet " + fwallet + " To Wallet " + twallet + ""); + AppUI.setCommonFont(x); c.anchor = GridBagConstraints.CENTER; c.insets = new Insets(4, 0, 4, 0); c.gridx = GridBagConstraints.RELATIVE; @@ -1454,7 +1472,7 @@ public void showSendingScreen() { y++; // Warning Label - x = new JLabel("
Do not close the application until all CloudCoins are transferred!
"); + x = new JLabel("Do not close the application until all CloudCoins are transferred!"); AppUI.setCommonFont(x); AppUI.setColor(x, AppUI.getErrorColor()); c.anchor = GridBagConstraints.CENTER; @@ -1494,21 +1512,7 @@ public void showSendingScreen() { ct.add(pbar); y++; - - // Cancel Button - /* - JPanel bp = getOneButtonPanelCustom("Cancel", new ActionListener() { - public void actionPerformed(ActionEvent e) { - sm.cancel("Sender"); - ps.currentScreen = ProgramState.SCREEN_DEFAULT; - showScreen(); - } - }); - - - subInnerCore.add(bp); - */ subInnerCore.add(AppUI.hr(120)); Thread t = new Thread(new Runnable() { @@ -1571,8 +1575,6 @@ public void run(){ public void showImportingScreen() { JPanel subInnerCore = getPanel("Deposit in Progress"); - - //ps.dstWallet = sm.getWalletByName("Default Wallet"); JPanel ct = new JPanel(); AppUI.noOpaque(ct); @@ -1582,11 +1584,8 @@ public void showImportingScreen() { GridBagConstraints c = new GridBagConstraints(); ct.setLayout(gridbag); - // Password Label - //JLabel x = new JLabel("Do not close the application until all CloudCoins are deposited!"); - JLabel x = new JLabel("
Do not close the application until all CloudCoins are deposited!
"); + JLabel x = new JLabel("Do not close the application until all CloudCoins are deposited!"); AppUI.setCommonFont(x); - //AppUI.setBoldFont(x, 16); AppUI.setColor(x, AppUI.getErrorColor()); c.anchor = GridBagConstraints.CENTER; c.insets = new Insets(10, 0, 4, 0); @@ -1620,26 +1619,6 @@ public void showImportingScreen() { gridbag.setConstraints(pbar, c); ct.add(pbar); - // Cancel button - /* - JPanel bp = getOneButtonPanelCustom("Cancel", new ActionListener() { - public void actionPerformed(ActionEvent e) { - sm.cancel("Unpacker"); - - if (ps.isSkyDeposit) - sm.cancel("Sender"); - else { - sm.cancel("Authenticator"); - sm.cancel("FrackFixer"); - sm.cancel("LossFixer"); - } - - resetState(); - } - }); - - subInnerCore.add(bp); - */ subInnerCore.add(AppUI.hr(120)); Thread t = new Thread(new Runnable() { @@ -1994,121 +1973,51 @@ public void showImportDoneScreen() { return; } - subInnerCore = getPanel("Deposit Complete"); - - JPanel ct = new JPanel(); - AppUI.noOpaque(ct); - subInnerCore.add(ct); - + int y = 0; + JLabel fname, value; + MyTextField walletName = null; + + subInnerCore = getPanel("Deposit Complete"); GridBagLayout gridbag = new GridBagLayout(); - GridBagConstraints c = new GridBagConstraints(); - ct.setLayout(gridbag); - + subInnerCore.setLayout(gridbag); + String total = AppCore.formatNumber(ps.statToBankValue + ps.statFailedValue + ps.statLostValue); String totalBankValue = AppCore.formatNumber(ps.statToBankValue); String totalFailedValue = AppCore.formatNumber(ps.statFailedValue); String totalLostValue = AppCore.formatNumber(ps.statLostValue); + + //fname = AppUI.wrapDiv("Deposited " + total + " CloudCoins to " + ps.dstWallet.getName() + " "); + fname = AppUI.wrapDiv("Deposited " + total + " CloudCoins to xxx "); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; - JLabel x = new JLabel("
Deposited " + total + " CloudCoins to " + ps.dstWallet.getName() + "
"); - AppUI.setCommonFont(x); - - int y = 0; - - c.insets = new Insets(0, 0, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.gridwidth = 2; - gridbag.setConstraints(x, c); - ct.add(x); - - y++; - - // Auth - x = new JLabel("Total Authentic Coins:"); - AppUI.setCommonFont(x); - - c.weightx = 1; - c.anchor = GridBagConstraints.EAST; - c.insets = new Insets(50, 0, 4, 10); - c.gridx = 0; - c.gridy = y; - c.gridwidth = 1; - gridbag.setConstraints(x, c); - ct.add(x); - - x = new JLabel(totalBankValue); - AppUI.setCommonBoldFont(x); - - c.anchor = GridBagConstraints.WEST; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); - - y++; - - // Counterfeit - x = new JLabel("Total Counterfeit Coins:"); - AppUI.setCommonFont(x); - c.anchor = GridBagConstraints.EAST; - c.insets = new Insets(10, 0, 4, 10); - c.gridx = 0; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); - - x = new JLabel(totalFailedValue); - AppUI.setCommonBoldFont(x); - c.anchor = GridBagConstraints.WEST; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); - - y++; + fname = new JLabel("Total Authentic Coins:"); + value = new JLabel(totalBankValue); + AppUI.getGBRow(subInnerCore, fname, value, y, gridbag); + y++; - // Lost - x = new JLabel("Total Lost Coins:"); - AppUI.setCommonFont(x); - c.anchor = GridBagConstraints.EAST; - c.insets = new Insets(10, 0, 4, 10); - c.gridx = 0; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); + fname = new JLabel("Total Counterfeit Coins:"); + value = new JLabel(totalFailedValue); + AppUI.getGBRow(subInnerCore, fname, value, y, gridbag); + y++; - x = new JLabel(totalLostValue); - AppUI.setCommonBoldFont(x); - c.anchor = GridBagConstraints.WEST; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); + fname = new JLabel("Total Lost Coins:"); + value = new JLabel(totalLostValue); + AppUI.getGBRow(subInnerCore, fname, value, y, gridbag); + y++; - y++; - - // Previously imported if (ps.duplicates.size() > 0) { - x = new JLabel("Previously Imported Coins:"); - AppUI.setCommonFont(x); - c.anchor = GridBagConstraints.EAST; - c.insets = new Insets(10, 0, 4, 10); - c.gridx = 0; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); - - x = new JLabel("" + ps.duplicates.size()); - AppUI.setCommonBoldFont(x); - c.anchor = GridBagConstraints.WEST; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); - } + fname = new JLabel("Previously Imported Coins:"); + value = new JLabel("" + ps.duplicates.size()); + AppUI.getGBRow(subInnerCore, fname, value, y, gridbag); + y++; + } + AppUI.GBPad(subInnerCore, y, gridbag); + y++; - JPanel bp = getTwoButtonPanelCustom("Next Deposit", "Continue", new ActionListener() { + + AppUI.getTwoButtonPanel(subInnerCore, "Next Deposit", "Continue", new ActionListener() { public void actionPerformed(ActionEvent e) { resetState(); ps.currentScreen = ProgramState.SCREEN_PREDEPOSIT; @@ -2122,9 +2031,8 @@ public void actionPerformed(ActionEvent e) { //ps.currentScreen = ProgramState.SCREEN_DEFAULT; showScreen(); } - }); + }, y, gridbag); - subInnerCore.add(bp); } public void showDeleteWalletDoneScreen() { @@ -2474,55 +2382,38 @@ public void run() { } public void showConfirmTransferScreen() { - JPanel subInnerCore = getPanel("Transfer Confirmation"); - - // Container - JPanel ct = new JPanel(); - AppUI.noOpaque(ct); - subInnerCore.add(ct); - - GridBagLayout gridbag = new GridBagLayout(); - GridBagConstraints c = new GridBagConstraints(); - ct.setLayout(gridbag); - int y = 0; - // From Label - JLabel x = new JLabel("From: "); - AppUI.setCommonFont(x); - c.anchor = GridBagConstraints.EAST; - c.insets = new Insets(0, 0, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); + JLabel fname, value; + MyTextField walletName = null; - String name = ps.srcWallet.getName(); - //if (ps.srcWallet.isSkyWallet()) - // name += "." + Config.DDNS_DOMAIN; + JPanel subInnerCore = getPanel("Transfer Confirmation"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + String total = AppCore.formatNumber(ps.statToBankValue + ps.statFailedValue + ps.statLostValue); + String totalBankValue = AppCore.formatNumber(ps.statToBankValue); + String totalFailedValue = AppCore.formatNumber(ps.statFailedValue); + String totalLostValue = AppCore.formatNumber(ps.statLostValue); + + fname = new JLabel("Do you wish to continue?"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + + //fname = AppUI.wrapDiv("Deposited " + total + " CloudCoins to " + ps.dstWallet.getName() + " "); + JLabel fromLabel = new JLabel("From: "); + JLabel fromValue = new JLabel(ps.srcWallet.getName()); + AppUI.getGBRow(subInnerCore, fromLabel, fromValue, y, gridbag); + y++; - x = new JLabel(name); - AppUI.setCommonBoldFont(x); - c.anchor = GridBagConstraints.WEST; - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); - - y++; + JLabel toLabel = new JLabel("To: "); String to; if (ps.sendType == ProgramState.SEND_TYPE_WALLET) { - name = ps.dstWallet.getName(); - //if (ps.dstWallet.isSkyWallet()) - // name += "." + Config.DDNS_DOMAIN; - - to = name; - + to = ps.dstWallet.getName(); } else if (ps.sendType == ProgramState.SEND_TYPE_REMOTE) { to = ps.typedRemoteWallet; } else if (ps.sendType == ProgramState.SEND_TYPE_FOLDER) { to = ps.chosenFile; - } else { to = "?"; } @@ -2530,89 +2421,35 @@ public void showConfirmTransferScreen() { if (to.length() > 24) { to = to.substring(0, 24) + "..."; } + JLabel toValue = new JLabel(to); + AppUI.getGBRow(subInnerCore, toLabel, toValue, y, gridbag); + y++; - // To Label - x = new JLabel("To: "); - AppUI.setCommonFont(x); - c.anchor = GridBagConstraints.EAST; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); - - x = new JLabel(to); - AppUI.setCommonBoldFont(x); - c.anchor = GridBagConstraints.WEST; - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); - - y++; - - - - // Amount - x = new JLabel("Amount: "); - AppUI.setCommonFont(x); - c.insets = new Insets(32, 0, 4, 0); - c.anchor = GridBagConstraints.EAST; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); - - x = new JLabel(ps.typedAmount + " CC"); - AppUI.setCommonBoldFont(x); - c.anchor = GridBagConstraints.WEST; - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); - - y++; + fname = new JLabel("Amount: "); + JLabel amountValue = new JLabel(ps.typedAmount + " CC"); + AppUI.getGBRow(subInnerCore, fname, amountValue, y, gridbag); + y++; String memo = ps.typedMemo; if (memo.length() > 24) { memo = memo.substring(0, 24) + "..."; } - // Memo - x = new JLabel("Memo: "); - AppUI.setCommonFont(x); - c.insets = new Insets(0, 0, 4, 0); - c.anchor = GridBagConstraints.EAST; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); - - x = new JLabel(memo); - AppUI.setCommonBoldFont(x); - c.anchor = GridBagConstraints.WEST; - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); - + fname = new JLabel("Memo: "); + JLabel memoValue = new JLabel(memo); + AppUI.getGBRow(subInnerCore, fname, memoValue, y, gridbag); y++; - - - // Q - x = new JLabel("Do you wish to continue?"); - AppUI.setCommonFont(x); - c.insets = new Insets(32, 0, 4, 0); - c.anchor = GridBagConstraints.CENTER; - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = y; - c.gridwidth = 2; - gridbag.setConstraints(x, c); - ct.add(x); - y++; - - JPanel bp = getTwoButtonPanel(new ActionListener() { + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { public void actionPerformed(ActionEvent e) { ps.srcWallet.setPassword(ps.typedSrcPassword); @@ -2643,10 +2480,8 @@ public void actionPerformed(ActionEvent e) { showScreen(); } } - }); - + }, y, gridbag); - subInnerCore.add(bp); } @@ -2782,22 +2617,22 @@ public void actionPerformed(ActionEvent e) { } public void showSkyWalletCreatedScreen() { - boolean isError = !ps.errText.equals(""); + int y = 0; + JLabel fname; JPanel subInnerCore; - + boolean isError = !ps.errText.equals(""); + if (isError) { subInnerCore = getPanel("Error"); - AppUI.hr(subInnerCore, 32); resetState(); return; } - subInnerCore = getPanel("Sky Wallet created"); - AppUI.hr(subInnerCore, 32); - - - JLabel res = new JLabel("
" - + "You have now created a sky wallet on a third party trusted transfer server.
" + subInnerCore = getPanel("Sky Wallet created"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + fname = AppUI.wrapDiv("You have now created a sky wallet on a third party trusted transfer server.
" + "Your address is " + ps.domain + "." + ps.trustedServer + ".

" + "This sky wallet allows you to receive CloudCoins " + "that you know are authentic.
The sender will also know that " @@ -2806,22 +2641,22 @@ public void showSkyWalletCreatedScreen() { + "that the name is pointing to. The trusted transfer server that " + "SkyWallet.cc points to is called \"TeleportNow.\" TeleportNow has data supremacy " + "just like the RAIDA. Teleport now cannot be brought down or hacked " - + "and there is no information about transactions that are stored.
"); - - AppUI.setFont(res, 18); - AppUI.alignCenter(res); + + "and there is no information about transactions that are stored."); - subInnerCore.add(res); - + AppUI.getGBRow(subInnerCore, null, fname, 0, gridbag); + y++; - JPanel bp = getOneButtonPanelCustom("Continue", new ActionListener() { + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + AppUI.getTwoButtonPanel(subInnerCore, "", "Continue", null, new ActionListener() { public void actionPerformed(ActionEvent e) { sm.setActiveWallet(ps.domain + "." + ps.trustedServer); ps.currentScreen = ProgramState.SCREEN_SHOW_TRANSACTIONS; showScreen(); } - }); - subInnerCore.add(bp); + }, y, gridbag); + } @@ -3074,9 +2909,9 @@ public void showDefaultScreen() { } public String getNonEmptyFolderError(String folder) { - return "
" + folder + " Folder is not empty. Please remove coins from your " + folder + " Folder and try again. " + return AppUI.wrapDiv("" + folder + " Folder is not empty. Please remove coins from your " + folder + " Folder and try again. " + "Go to tools and then Show Folders to see the location of your " + folder + " Folder. Then cut your coins from the folder and put them in a place where you can find them. " - + "Please click cancel below to reset. Then deposit them again.
"; + + "Please click cancel below to reset. Then deposit them again.").getText(); } public void showDepositSkyWalletScreen() { @@ -3293,48 +3128,15 @@ public void actionPerformed(ActionEvent e) { } public void showTransferScreen() { - showLeftScreen(); - JPanel rightPanel = getRightPanel(); - - JPanel ct = new JPanel(); - AppUI.setBoxLayout(ct, true); - AppUI.noOpaque(ct); - rightPanel.add(ct); - - JLabel ltitle = AppUI.getTitle("Transfer"); - ct.add(ltitle); - AppUI.alignTop(ct); - AppUI.alignTop(ltitle); - - AppUI.hr(ct, 10); - - maybeShowError(ct); - - // Outer Container - JPanel oct = new JPanel(); - AppUI.noOpaque(oct); - int y = 0; - + JLabel fname; + MyTextField walletName = null; + + JPanel subInnerCore = getPanel("Transfer"); GridBagLayout gridbag = new GridBagLayout(); - GridBagConstraints c = new GridBagConstraints(); - c.gridwidth = 1; - c.anchor = GridBagConstraints.EAST; - c.insets = new Insets(12, 18, 0, 0); - oct.setLayout(gridbag); - - - // Transfer from - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - JLabel x = new JLabel(" Transfer From"); - gridbag.setConstraints(x, c); - AppUI.setCommonFont(x); - oct.add(x); + subInnerCore.setLayout(gridbag); + - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - int nonSkyCnt = 0; for (int i = 0; i < wallets.length; i++) if (!wallets[i].isSkyWallet()) @@ -3349,110 +3151,51 @@ public void showTransferScreen() { continue; String name = wallets[i].getName(); - options[j] = name + " - " + AppCore.formatNumber(wallets[i].getTotal()) + " CC"; idxs[j] = i; j++; } - - final RoundedCornerComboBox cboxfrom = new RoundedCornerComboBox(AppUI.getColor2(), "Make Selection", options); - gridbag.setConstraints(cboxfrom.getComboBox(), c); - oct.add(cboxfrom.getComboBox()); - - y++; - - // Password From - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - final JLabel spText = new JLabel("Password From"); - gridbag.setConstraints(spText, c); - AppUI.setCommonFont(spText); - oct.add(spText); + fname = new JLabel("Transfer From"); + final RoundedCornerComboBox cboxfrom = new RoundedCornerComboBox(AppUI.getColor6(), "Make Selection", options); + AppUI.getGBRow(subInnerCore, fname, cboxfrom.getComboBox(), y, gridbag); + y++; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; + final JLabel spText = new JLabel("Password From");; final MyTextField passwordSrc = new MyTextField("Wallet Password", true); - gridbag.setConstraints(passwordSrc.getTextField(), c); - oct.add(passwordSrc.getTextField()); - y++; + AppUI.getGBRow(subInnerCore, spText, passwordSrc.getTextField(), y, gridbag); + y++; passwordSrc.getTextField().setVisible(false); spText.setVisible(false); - // Transfer to - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - x = new JLabel("Transfer To"); - gridbag.setConstraints(x, c); - AppUI.setCommonFont(x); - oct.add(x); - - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - - final RoundedCornerComboBox cboxto = new RoundedCornerComboBox(AppUI.getColor2(), "Make Selection", options); + fname = new JLabel("Transfer To"); + final RoundedCornerComboBox cboxto = new RoundedCornerComboBox(AppUI.getColor6(), "Make Selection", options); cboxto.addOption(AppUI.getRemoteUserOption()); cboxto.addOption(AppUI.getLocalFolderOption()); - gridbag.setConstraints(cboxto.getComboBox(), c); - oct.add(cboxto.getComboBox()); - y++; - - - // Password To - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - final JLabel dpText = new JLabel("Password To"); - gridbag.setConstraints(dpText, c); - AppUI.setCommonFont(dpText); - oct.add(dpText); - - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; + AppUI.getGBRow(subInnerCore, fname, cboxto.getComboBox(), y, gridbag); + y++; + + final JLabel dpText = new JLabel("Password To");; final MyTextField passwordDst = new MyTextField("Wallet Password", true); - gridbag.setConstraints(passwordDst.getTextField(), c); - oct.add(passwordDst.getTextField()); - y++; - + AppUI.getGBRow(subInnerCore, dpText, passwordDst.getTextField(), y, gridbag); + y++; + passwordDst.getTextField().setVisible(false); dpText.setVisible(false); - - - - - // Remote User - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - final JLabel rwText = new JLabel("To Sky Wallet"); - gridbag.setConstraints(rwText, c); - AppUI.setCommonFont(rwText); - oct.add(rwText); - - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; + + final JLabel rwText = new JLabel("To SkyWallet");; final MyTextField remoteWalledId = new MyTextField("JohnDoe.SkyWallet.cc", false); - gridbag.setConstraints(remoteWalledId.getTextField(), c); if (!ps.typedRemoteWallet.isEmpty()) remoteWalledId.setData("" + ps.typedRemoteWallet); - oct.add(remoteWalledId.getTextField()); + AppUI.getGBRow(subInnerCore, rwText, remoteWalledId.getTextField(), y, gridbag); y++; remoteWalledId.getTextField().setVisible(false); rwText.setVisible(false); + - - - // Local folder - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; final JLabel lfText = new JLabel("Local folder"); - gridbag.setConstraints(lfText, c); - AppUI.setCommonFont(lfText); - oct.add(lfText); - - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - final JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); chooser.setAcceptAllFileFilterUsed(false); @@ -3468,49 +3211,31 @@ public void mouseReleased(MouseEvent e) { } } }); - gridbag.setConstraints(localFolder.getTextField(), c); - oct.add(localFolder.getTextField()); + AppUI.getGBRow(subInnerCore, lfText, localFolder.getTextField(), y, gridbag); y++; + localFolder.getTextField().setVisible(false); lfText.setVisible(false); - // Amount - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - x = new JLabel("Amount"); - gridbag.setConstraints(x, c); - AppUI.setCommonFont(x); - oct.add(x); - - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; + fname = new JLabel("Amount"); final MyTextField amount = new MyTextField("0 CC", false); - gridbag.setConstraints(amount.getTextField(), c); if (ps.typedAmount > 0) amount.setData("" + ps.typedAmount); - oct.add(amount.getTextField()); + AppUI.getGBRow(subInnerCore, fname, amount.getTextField(), y, gridbag); y++; - - // Memo - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - x = new JLabel("Memo (Note)"); - gridbag.setConstraints(x, c); - AppUI.setCommonFont(x); - oct.add(x); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; + + fname = new JLabel("Memo (Note)"); final MyTextField memo = new MyTextField("Optional", false); - gridbag.setConstraints(memo.getTextField(), c); if (!ps.typedMemo.isEmpty()) memo.setData(ps.typedMemo); - oct.add(memo.getTextField()); + AppUI.getGBRow(subInnerCore, fname, memo.getTextField(), y, gridbag); y++; - - rightPanel.add(oct); - + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + cboxfrom.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int srcIdx = cboxfrom.getSelectedIndex() - 1; @@ -3599,12 +3324,15 @@ public void actionPerformed(ActionEvent e) { if (ps.selectedToIdx > 0) { cboxto.setDefaultIdx(ps.selectedToIdx); - } - - // Space - AppUI.hr(oct, 22); + } - JPanel bp = getTwoButtonPanel(new ActionListener() { + + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { public void actionPerformed(ActionEvent e) { ps.typedMemo = memo.getText().trim(); @@ -3652,6 +3380,14 @@ public void actionPerformed(ActionEvent e) { return; } + if (dstIdx == idxs.length) { + if (ps.typedMemo.isEmpty()) { + ps.errText = "Memo cannot be empty"; + showScreen(); + return; + } + } + if (!Validator.memo(ps.typedMemo)) { ps.errText = "Memo: Non alpha number characters are not allowed"; showScreen(); @@ -3704,20 +3440,14 @@ public void actionPerformed(ActionEvent e) { showScreen(); return; } - - if (ps.typedMemo.isEmpty()) { - ps.errText = "Memo cannot be empty"; - showScreen(); - return; - } - + ps.dstWallet = null; ps.typedRemoteWallet = remoteWalledId.getText(); ps.sendType = ProgramState.SEND_TYPE_REMOTE; DNSSn d = new DNSSn(ps.typedRemoteWallet, null, wl); if (!d.recordExists()) { - ps.errText = "
Sky Wallet " + ps.typedRemoteWallet + " doesn't exist. If it is a newly created wallet please wait and try again later
"; + ps.errText = "Sky Wallet " + ps.typedRemoteWallet + " doesn't exist. If it is a newly created wallet please wait and try again later"; showScreen(); return; } @@ -3812,68 +3542,33 @@ public void actionPerformed(ActionEvent e) { ps.currentScreen = ProgramState.SCREEN_CONFIRM_TRANSFER; showScreen(); } - }); - - AppUI.hr(rightPanel, 20); - rightPanel.add(bp); + }, y, gridbag); + } public void showPredepositScreen() { - - showLeftScreen(); - - JPanel rightPanel = getRightPanel(); - - JPanel ct = new JPanel(); - AppUI.setBoxLayout(ct, true); - AppUI.noOpaque(ct); - rightPanel.add(ct); - - JLabel ltitle = AppUI.getTitle("Deposit"); - ct.add(ltitle); - AppUI.alignTop(ct); - AppUI.alignTop(ltitle); - - AppUI.hr(ct, 10); - - maybeShowError(ct); - - // Outer Container - JPanel oct = new JPanel(); - AppUI.noOpaque(oct); - int y = 0; - + JLabel fname; + MyTextField walletName = null; + + JPanel subInnerCore = getPanel("Deposit"); GridBagLayout gridbag = new GridBagLayout(); - GridBagConstraints c = new GridBagConstraints(); - c.gridwidth = 1; - c.anchor = GridBagConstraints.EAST; - c.insets = new Insets(12, 18, 0, 0); - oct.setLayout(gridbag); - - - // Deposit From - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.EAST; - JLabel x = new JLabel("Deposit From"); - gridbag.setConstraints(x, c); - AppUI.setCommonFont(x); - oct.add(x); - - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.WEST; - - int cnt = 0; - for (int i = 0; i < wallets.length; i++) + subInnerCore.setLayout(gridbag); + + fname = new JLabel("Deposit From"); + int cnt = 0, scnt = 0; + for (int i = 0; i < wallets.length; i++) { + if (wallets[i].isSkyWallet()) { + scnt++; + } if (wallets[i].isSkyWallet() && wallets[i].getTotal() > 0) cnt++; + } + System.out.println("sss=" + wallets.length + " cnt="+scnt); final String[] options = new String[cnt + 1]; - final String[] doptions = new String[wallets.length - cnt]; - int j = 0, k = 0; - + final String[] doptions = new String[wallets.length - scnt]; + int j = 0, k = 0; final int fidxs[], tidxs[]; fidxs = new int[cnt + 1]; @@ -3886,6 +3581,7 @@ public void showPredepositScreen() { j++; } } else { + doptions[k] = wallets[i].getName() + " - " + wallets[i].getTotal() + " CC"; tidxs[k] = i; k++; @@ -3898,64 +3594,34 @@ public void showPredepositScreen() { showScreen(); return; } - + System.out.println("i=e="+doptions.length); options[j++] = "- FileSystem"; - //options[j++] = "- Add Sky Wallet"; - final RoundedCornerComboBox cbox = new RoundedCornerComboBox(AppUI.getColor2(), "Select Source", options); - gridbag.setConstraints(cbox.getComboBox(), c); - oct.add(cbox.getComboBox()); - - y++; - - rightPanel.add(oct); + final RoundedCornerComboBox cbox = new RoundedCornerComboBox(AppUI.getColor6(), "Select Source", options); + AppUI.getGBRow(subInnerCore, fname, cbox.getComboBox(), y, gridbag); + y++; - // Deposit To - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.EAST; final JLabel dto = new JLabel("Deposit To"); - gridbag.setConstraints(dto, c); - AppUI.setCommonFont(dto); - oct.add(dto); - - //final optRv rv = setOptionsForWallets(false, false); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.WEST; - final RoundedCornerComboBox cboxto = new RoundedCornerComboBox(AppUI.getColor2(), "Select Destination", doptions); - gridbag.setConstraints(cboxto.getComboBox(), c); - oct.add(cboxto.getComboBox()); - + final RoundedCornerComboBox cboxto = new RoundedCornerComboBox(AppUI.getColor6(), "Select Destination", doptions); if (doptions.length == 1) cboxto.setDefaultIdx(1); + AppUI.getGBRow(subInnerCore, dto, cboxto.getComboBox(), y, gridbag); + y++; cboxto.getComboBox().setVisible(false); dto.setVisible(false); - y++; - - // Password - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.EAST; final JLabel pText = new JLabel("Password"); - gridbag.setConstraints(pText, c); - AppUI.setCommonFont(pText); - oct.add(pText); - - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.WEST; final MyTextField password = new MyTextField("Wallet Password", true); - gridbag.setConstraints(password.getTextField(), c); - oct.add(password.getTextField()); - + AppUI.getGBRow(subInnerCore, pText, password.getTextField(), y, gridbag); + y++; + password.getTextField().setVisible(false); pText.setVisible(false); + AppUI.GBPad(subInnerCore, y, gridbag); y++; - + cbox.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int cidx = cbox.getSelectedIndex(); @@ -4003,12 +3669,13 @@ public void actionPerformed(ActionEvent e) { } } }); - - - // Space - AppUI.hr(oct, 22); - JPanel bp = getTwoButtonPanel(new ActionListener() { + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { public void actionPerformed(ActionEvent e) { int cidx = cbox.getSelectedIndex(); if (cidx == options.length) { @@ -4017,14 +3684,6 @@ public void actionPerformed(ActionEvent e) { showScreen(); return; } - /* - if (cidx == options.length) { - resetState(); - ps.currentScreen = ProgramState.SCREEN_CREATE_SKY_WALLET; - showScreen(); - return; - }*/ - if (cidx == 0) { ps.errText = "Wallet is not selected"; @@ -4108,11 +3767,7 @@ public void actionPerformed(ActionEvent e) { showScreen(); } - }); - - AppUI.hr(rightPanel, 20); - rightPanel.add(bp); - + }, y, gridbag); } public void showDepositScreen() { @@ -6054,144 +5709,47 @@ public void showSetDNSRecordScreen() { } public void showCreateSkyWalletScreen() { - boolean isError = !ps.errText.equals(""); + int y = 0; + JLabel fname; + MyTextField walletName = null; + JPanel subInnerCore = getPanel("Create Sky Wallet"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); final JFileChooser chooser = new JFileChooser(); - FileNameExtensionFilter filter = new FileNameExtensionFilter( - "CloudCoins", "jpg", "jpeg", "stack", "json", "txt"); + FileNameExtensionFilter filter = new FileNameExtensionFilter("CloudCoins", "jpg", "jpeg", "stack", "json", "txt"); chooser.setFileFilter(filter); - JPanel subInnerCore = getPanel("Create Sky Wallet"); - - AppUI.hr(subInnerCore, 4); - - // Outer Container - JPanel oct = new JPanel(); - AppUI.setBoxLayout(oct, true); - AppUI.noOpaque(oct); - subInnerCore.add(oct); - - // Container - JPanel ct = new JPanel(); - AppUI.noOpaque(ct); - oct.add(ct); - - int y = 0; - - GridBagLayout gridbag = new GridBagLayout(); - GridBagConstraints c = new GridBagConstraints(); - ct.setLayout(gridbag); - - - JLabel x; - - // Radio - ButtonGroup nwGroup = new ButtonGroup(); - final MyRadioButton rb0 = new MyRadioButton(); - - c.insets = new Insets(0, 0, 4, 0); - c.weightx = 0; - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = y; - gridbag.setConstraints(rb0.getRadioButton(), c); - ct.add(rb0.getRadioButton()); - rb0.attachToGroup(nwGroup); - if (isError && !ps.isCreatingNewSkyWallet) - rb0.select(); - - x = new JLabel("Add Existing"); - c.insets = new Insets(0, 14, 4, 0); - AppUI.setFont(x, 16); - gridbag.setConstraints(x, c); - ct.add(x); - - - final MyRadioButton rb1 = new MyRadioButton(); - c.insets = new Insets(0, 44, 4, 0); - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = y; - gridbag.setConstraints(rb1.getRadioButton(), c); - ct.add(rb1.getRadioButton()); - rb1.attachToGroup(nwGroup); - if (!isError || ps.isCreatingNewSkyWallet) - rb1.select(); - - x = new JLabel("Create New"); - c.insets = new Insets(0, 4, 4, 0); - AppUI.setFont(x, 16); - gridbag.setConstraints(x, c); - ct.add(x); - - y++; - - c.gridwidth = 4; - - - x = new JLabel("DNS Name or IP Address of Trusted Server"); - c.anchor = GridBagConstraints.WEST; - c.insets = new Insets(10, 0, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - AppUI.setFont(x, 16); - gridbag.setConstraints(x, c); - ct.add(x); + fname = new JLabel("Add Existing"); + final MyCheckBoxToggle cb1 = new MyCheckBoxToggle(); + if (ps.isCreatingNewSkyWallet) + cb1.setSelected(false); + else + cb1.setSelected(true); + AppUI.getGBRow(subInnerCore, fname, cb1.getCheckBox(), y, gridbag); + y++; - y++; String[] options = { Config.DDNS_DOMAIN, - // "Enter Custom Server" }; - - c.anchor = GridBagConstraints.WEST; - c.insets = new Insets(0, 0, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - - final RoundedCornerComboBox cbox = new RoundedCornerComboBox(AppUI.getColor2(), "Select Server", options); - gridbag.setConstraints(cbox.getComboBox(), c); - ct.add(cbox.getComboBox()); + + fname = new JLabel("DNS Name or IP Address of Trusted Server"); + final RoundedCornerComboBox cbox = new RoundedCornerComboBox(AppUI.getColor6(), "Select Server", options); cbox.setDefault(null); - - y++; - - // Name Label - x = new JLabel("Your Proposed Address"); - c.anchor = GridBagConstraints.WEST; - c.insets = new Insets(12, 0, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - AppUI.setFont(x, 16); - - gridbag.setConstraints(x, c); - ct.add(x); + AppUI.getGBRow(subInnerCore, fname, cbox.getComboBox(), y, gridbag); + y++; - y++; - - final MyTextField tf0 = new MyTextField("JohnDoe.SkyWallet.cc", false); - c.insets = new Insets(0, 0, 4, 0); - c.gridx = 0; - c.gridy = y; - gridbag.setConstraints(tf0.getTextField(), c); - ct.add(tf0.getTextField()); + fname = new JLabel("Your Proposed Address"); + final MyTextField tf0 = new MyTextField("JohnDoe.SkyWallet.cc", false); if (!ps.skyVaultDomain.isEmpty()) tf0.setData(ps.skyVaultDomain); + AppUI.getGBRow(subInnerCore, fname, tf0.getTextField(), y, gridbag); + y++; - y++; - // Text - JLabel txt = new JLabel("Select CloudCoin to be used as ID"); - AppUI.setCommonFont(txt); - AppUI.alignCenter(txt); - c.insets = new Insets(12, 0, 4, 0); - c.gridx = 0; - c.gridy = y; - AppUI.setFont(txt, 16); - gridbag.setConstraints(txt, c); - ct.add(txt); - - y++; + fname = new JLabel("Select CloudCoin to be used as ID"); final MyTextField tf1 = new MyTextField("", false, true); tf1.disable(); tf1.setFilepickerListener(new MouseAdapter() { @@ -6208,29 +5766,23 @@ public void mouseReleased(MouseEvent e) { if (!ps.chosenFile.isEmpty()) tf1.setData(new File(ps.chosenFile).getName()); - + AppUI.getGBRow(subInnerCore, fname, tf1.getTextField(), y, gridbag); + y++; + - c.insets = new Insets(0, 0, 0, 0); - c.gridx = 0; - c.gridy = y; - gridbag.setConstraints(tf1.getTextField(), c); - ct.add(tf1.getTextField()); + AppUI.GBPad(subInnerCore, y, gridbag); y++; - /* - final MyCheckBox cb = new MyCheckBox("Create New Wallet"); - //cb.setBoldFont(); - c.insets = new Insets(12, 0, 0, 0); - c.gridx = 0; - c.gridy = y; - gridbag.setConstraints(cb.getCheckBox(), c); - ct.add(cb.getCheckBox()); - */ - JPanel bp = getTwoButtonPanel(new ActionListener() { + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { public void actionPerformed(ActionEvent e) { - ps.isCreatingNewSkyWallet = rb1.isSelected(); + ps.isCreatingNewSkyWallet = !cb1.isChecked(); ps.skyVaultDomain = tf0.getText(); int srcIdx = cbox.getSelectedIndex(); @@ -6282,7 +5834,7 @@ public void actionPerformed(ActionEvent e) { int sn = d.getSN(); ps.domain = domain; - if (rb1.isSelected()) { + if (!cb1.isChecked()) { if (sn >= 0) { ps.errText = "DNS name already exists"; showScreen(); @@ -6338,10 +5890,9 @@ public void run(){ ps.currentScreen = ProgramState.SCREEN_SKY_WALLET_CREATED; showScreen(); } - }); + }, y, gridbag); + - AppUI.hr(subInnerCore, 20); - subInnerCore.add(bp); } public void showCreateWalletScreen() { @@ -6602,6 +6153,15 @@ public JPanel getWallet(Wallet wallet, int type) { if (wallet != null) isDisabled = !isActiveWallet(wallet); + if (isCreatingWallet() && type == TYPE_ADD_BUTTON) { + isDisabled = false; + } + + if (isCreatingSkyWallet() && type == TYPE_ADD_SKY) { + isDisabled = false; + } + + final Color color = isDisabled ? AppUI.getColor6() : AppUI.getColor3(); final JPanel wpanel = new JPanel(); @@ -6633,6 +6193,11 @@ else if (type == TYPE_ADD_SKY) wpanel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, AppUI.getColor0())); } + if (isCreatingWallet() && type == TYPE_ADD_BUTTON) { + isDisabled = false; + } + + final boolean fisDisabled = isDisabled; if (wallet != null) { String iconName = wallet.isSkyWallet() ? "walleticon.png" : "walleticonlight.png"; diff --git a/src/advclient/AppUI.java b/src/advclient/AppUI.java index d70cbf1..b2bb1d1 100644 --- a/src/advclient/AppUI.java +++ b/src/advclient/AppUI.java @@ -661,6 +661,7 @@ public static void getGBRow(JComponent parent, JComponent left, JComponent right if (right != null) { if (right instanceof JLabel) { + c.insets = new Insets(20, 0, 0, 0); AppUI.setCommonFont(right); } diff --git a/src/advclient/FancyProgressBar.java b/src/advclient/FancyProgressBar.java index 8a8c309..1b81242 100644 --- a/src/advclient/FancyProgressBar.java +++ b/src/advclient/FancyProgressBar.java @@ -60,7 +60,7 @@ protected void paintDeterminate(Graphics g, JComponent c) { width = (int) Math.round(width * dProgress); - g2d.setColor(AppUI.getColor6()); + g2d.setColor(AppUI.getColor2()); RoundRectangle2D fill = new RoundRectangle2D.Double(0, 0, width, height - 1, 20, 20); g2d.fill(fill); diff --git a/src/advclient/MyCheckBoxToggle.java b/src/advclient/MyCheckBoxToggle.java index e3a153d..a0a3ded 100644 --- a/src/advclient/MyCheckBoxToggle.java +++ b/src/advclient/MyCheckBoxToggle.java @@ -50,6 +50,10 @@ public boolean isChecked() { return cb.isSelected(); } + public void setSelected(boolean isSelected) { + cb.setSelected(isSelected); + } + public JPanel makeUI() { cb = new JCheckBox(); From 69db99905a1d1047fce191283ccb62745f4b3dba Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 8 Aug 2019 16:36:23 +0300 Subject: [PATCH 007/160] backup screen --- src/advclient/AdvancedClient.java | 217 ++++++++++-------------------- 1 file changed, 70 insertions(+), 147 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index fec56a0..31b522c 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -403,7 +403,8 @@ public boolean isFixing() { public boolean isBackupping() { if (ps.currentScreen == ProgramState.SCREEN_BACKUP || - ps.currentScreen == ProgramState.SCREEN_BACKUP_DONE) + ps.currentScreen == ProgramState.SCREEN_BACKUP_DONE || + ps.currentScreen == ProgramState.SCREEN_DOING_BACKUP) return true; return false; @@ -711,6 +712,7 @@ public void paintComponent(final Graphics g) { for (int i = 0; i < items.length; i++) { JMenuItem menuItem = new JMenuItem(items[i]); menuItem.setActionCommand("" + i); + AppUI.setHandCursor(menuItem); MouseAdapter ma = new MouseAdapter() { public void mouseEntered(MouseEvent evt) { @@ -865,8 +867,7 @@ public void resetState() { public void showScreen() { wl.debug(ltag, "SCREEN " + ps.currentScreen + ": " + ps.toString()); - clear(); - + clear(); switch (ps.currentScreen) { case ProgramState.SCREEN_AGREEMENT: resetState(); @@ -919,7 +920,7 @@ public void showScreen() { ps.isUpdatedWallets = false; showImportDoneScreen(); break; - case ProgramState.SCREEN_SUPPORT: + /**/ case ProgramState.SCREEN_SUPPORT: showSupportScreen(); break; case ProgramState.SCREEN_CONFIRM_TRANSFER: @@ -1897,19 +1898,17 @@ public void showTransferDoneScreen() { resetState(); return; } - - - - subInnerCore = getPanel("Transfer Complete"); - - JPanel ct = new JPanel(); - AppUI.noOpaque(ct); - subInnerCore.add(ct); - + + int y = 0; + JLabel fname, value; + MyTextField walletName = null; + + subInnerCore = getPanel("Transfer Complete"); GridBagLayout gridbag = new GridBagLayout(); - GridBagConstraints c = new GridBagConstraints(); - ct.setLayout(gridbag); + subInnerCore.setLayout(gridbag); + ps.dstWallet = wallets[0]; + ps.srcWallet = wallets[1]; String to; if (ps.sendType == ProgramState.SEND_TYPE_WALLET) { to = ps.dstWallet.getName(); @@ -1921,22 +1920,17 @@ public void showTransferDoneScreen() { to = "?"; } - String name = ps.srcWallet.getName(); - //if (ps.srcWallet.isSkyWallet()) - // name += "." + Config.DDNS_DOMAIN; - - JLabel x = new JLabel("
" - + "" + AppCore.formatNumber(ps.typedAmount) + " CC have been transferred to " + to + " from " - + name + "
"); - AppUI.setCommonFont(x); - - c.insets = new Insets(0, 0, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = 0; - gridbag.setConstraints(x, c); - ct.add(x); + String name = ps.srcWallet.getName(); + fname = AppUI.wrapDiv("" + AppCore.formatNumber(ps.typedAmount) + + " CC have been transferred to " + to + " from " + name + ""); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; - JPanel bp = getTwoButtonPanelCustom("Next Transfer", "Done", new ActionListener() { + + AppUI.getTwoButtonPanel(subInnerCore, "Next Transfer", "Continue", new ActionListener() { public void actionPerformed(ActionEvent e) { resetState(); ps.currentScreen = ProgramState.SCREEN_WITHDRAW; @@ -1954,15 +1948,10 @@ public void actionPerformed(ActionEvent e) { } showScreen(); } - }); - - //resetState(); - - subInnerCore.add(bp); + }, y, gridbag); } - public void showImportDoneScreen() { - + public void showImportDoneScreen() { boolean isError = !ps.errText.equals(""); JPanel subInnerCore; @@ -3565,14 +3554,14 @@ public void showPredepositScreen() { cnt++; } - System.out.println("sss=" + wallets.length + " cnt="+scnt); + final String[] options = new String[cnt + 1]; final String[] doptions = new String[wallets.length - scnt]; int j = 0, k = 0; final int fidxs[], tidxs[]; fidxs = new int[cnt + 1]; - tidxs = new int[wallets.length - cnt]; + tidxs = new int[wallets.length - scnt]; for (int i = 0; i < wallets.length; i++) { if (wallets[i].isSkyWallet()) { if (wallets[i].getTotal() > 0) { @@ -3594,7 +3583,7 @@ public void showPredepositScreen() { showScreen(); return; } - System.out.println("i=e="+doptions.length); + options[j++] = "- FileSystem"; final RoundedCornerComboBox cbox = new RoundedCornerComboBox(AppUI.getColor6(), "Select Source", options); @@ -3670,6 +3659,13 @@ public void actionPerformed(ActionEvent e) { } }); + if (ps.selectedFromIdx > 0) + cbox.setDefaultIdx(ps.selectedFromIdx); + + if (ps.selectedToIdx > 0) + cboxto.setDefaultIdx(ps.selectedToIdx); + + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { public void actionPerformed(ActionEvent e) { ps.currentScreen = ProgramState.SCREEN_DEFAULT; @@ -3691,6 +3687,7 @@ public void actionPerformed(ActionEvent e) { return; } + ps.selectedFromIdx = cidx; cidx = fidxs[cidx - 1]; Wallet w = wallets[cidx]; ps.srcWallet = w; @@ -3701,7 +3698,7 @@ public void actionPerformed(ActionEvent e) { showScreen(); return; } - + ps.selectedToIdx = cidx; cidx = tidxs[cidx - 1]; w = wallets[cidx]; @@ -4875,90 +4872,35 @@ public void actionPerformed(ActionEvent e) { } public void showBackupScreen() { - showLeftScreen(); - - JPanel rightPanel = getRightPanel(); - JPanel ct = new JPanel(); - AppUI.setBoxLayout(ct, true); - AppUI.noOpaque(ct); - rightPanel.add(ct); - - JLabel ltitle = AppUI.getTitle("Backup"); - ct.add(ltitle); - AppUI.hr(ct, 20); - - maybeShowError(ct); - + int y = 0; + JLabel fname; + MyTextField walletName = null; + + JPanel subInnerCore = getPanel("Backup"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + final optRv rv = setOptionsForWallets(false, false); if (rv.idxs.length == 0) { - JLabel nx = new JLabel("You have no coins to backup"); - AppUI.setSemiBoldFont(nx, 20); - AppUI.alignCenter(nx); - ct.add(nx); + fname = new JLabel("You have no coins to backup"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); return; } - - // GridHolder Container - JPanel gct = new JPanel(); - AppUI.noOpaque(gct); - - GridBagLayout gridbag = new GridBagLayout(); - gct.setLayout(gridbag); - GridBagConstraints c = new GridBagConstraints(); - - int y = 0; - // Text - c.anchor = GridBagConstraints.CENTER; - c.insets = new Insets(0, 0, 80, 0); - c.gridx = 0; - c.gridy = y; - c.gridwidth = 2; - - JLabel l = new JLabel("Backup will allow you to create Backup of your CloudCoins"); - AppUI.setCommonFont(l); - gridbag.setConstraints(l, c); - gct.add(l); + fname = new JLabel("Backup will allow you to create Backup of your CloudCoins"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; - y++; - c.gridwidth = 1; - c.insets = new Insets(0, 16, 10, 0); - c.anchor = GridBagConstraints.EAST; - // Transfer from - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - JLabel x = new JLabel(" Wallet"); - gridbag.setConstraints(x, c); - AppUI.setCommonFont(x); - gct.add(x); + fname = new JLabel("Wallet"); + final RoundedCornerComboBox cboxfrom = new RoundedCornerComboBox(AppUI.getColor6(), "Make Selection", rv.options); + AppUI.getGBRow(subInnerCore, fname, cboxfrom.getComboBox(), y, gridbag); + y++; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.WEST; - - final RoundedCornerComboBox cboxfrom = new RoundedCornerComboBox(AppUI.getColor2(), "Make Selection", rv.options); - gridbag.setConstraints(cboxfrom.getComboBox(), c); - gct.add(cboxfrom.getComboBox()); - - y++; - - // Password From - c.anchor = GridBagConstraints.EAST; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; final JLabel spText = new JLabel("Password"); - gridbag.setConstraints(spText, c); - AppUI.setCommonFont(spText); - gct.add(spText); - - c.anchor = GridBagConstraints.WEST; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; final MyTextField passwordSrc = new MyTextField("Wallet Password", true); - gridbag.setConstraints(passwordSrc.getTextField(), c); - gct.add(passwordSrc.getTextField()); - y++; - + AppUI.getGBRow(subInnerCore, spText, passwordSrc.getTextField(), y, gridbag); + y++; + passwordSrc.getTextField().setVisible(false); spText.setVisible(false); @@ -4984,20 +4926,7 @@ public void actionPerformed(ActionEvent e) { } }); - - - // Backup folder - JLabel txt = new JLabel("Backup Folder"); - AppUI.setCommonFont(txt); - AppUI.alignCenter(txt); - c.anchor = GridBagConstraints.EAST; - c.gridx = 0; - c.gridy = y; - - gridbag.setConstraints(txt, c); - gct.add(txt); - - + fname = new JLabel("Backup Folder"); final JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); chooser.setAcceptAllFileFilterUsed(false); @@ -5014,17 +4943,18 @@ public void mouseReleased(MouseEvent e) { } }); - c.anchor = GridBagConstraints.WEST; - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = y; - gridbag.setConstraints(tf1.getTextField(), c); - gct.add(tf1.getTextField()); - + AppUI.getGBRow(subInnerCore, fname, tf1.getTextField(), y, gridbag); + y++; - - rightPanel.add(gct); + AppUI.GBPad(subInnerCore, y, gridbag); + y++; - JPanel bp = getTwoButtonPanel(new ActionListener() { + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { public void actionPerformed(ActionEvent e) { int srcIdx = cboxfrom.getSelectedIndex() - 1; if (srcIdx < 0 || srcIdx >= rv.idxs.length) { @@ -5082,10 +5012,7 @@ public void actionPerformed(ActionEvent e) { ps.currentScreen = ProgramState.SCREEN_DOING_BACKUP; showScreen(); } - }); - - AppUI.hr(rightPanel, 20); - rightPanel.add(bp); + }, y, gridbag); } public void showListSerialsDone() { @@ -5693,16 +5620,12 @@ public void mouseExited(MouseEvent e) { } public void showDoingBackupScreen() { - boolean isError = !ps.errText.equals(""); - JPanel subInnerCore = getPanel("Doing Backup. Please wait..."); AppUI.hr(subInnerCore, 4); } public void showSetDNSRecordScreen() { - boolean isError = !ps.errText.equals(""); - JPanel subInnerCore = getPanel("Setting DNS Record. Please wait..."); AppUI.hr(subInnerCore, 4); From f18508c9314e514f4b25313dc163d23724596b2d Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 8 Aug 2019 18:00:58 +0300 Subject: [PATCH 008/160] gear screens --- src/advclient/AdvancedClient.java | 576 +++++++++++------------------- src/advclient/AppUI.java | 7 +- 2 files changed, 216 insertions(+), 367 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 31b522c..ce9b185 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -867,7 +867,8 @@ public void resetState() { public void showScreen() { wl.debug(ltag, "SCREEN " + ps.currentScreen + ": " + ps.toString()); - clear(); + clear(); + switch (ps.currentScreen) { case ProgramState.SCREEN_AGREEMENT: resetState(); @@ -920,7 +921,7 @@ public void showScreen() { ps.isUpdatedWallets = false; showImportDoneScreen(); break; - /**/ case ProgramState.SCREEN_SUPPORT: + case ProgramState.SCREEN_SUPPORT: showSupportScreen(); break; case ProgramState.SCREEN_CONFIRM_TRANSFER: @@ -1778,39 +1779,22 @@ public void showBackupDoneScreen() { if (isError) { subInnerCore = getPanel("Error"); - AppUI.hr(subInnerCore, 32); resetState(); return; } - - subInnerCore = getPanel("Backup Complete"); - maybeShowError(subInnerCore); - - JPanel ct = new JPanel(); - AppUI.noOpaque(ct); - subInnerCore.add(ct); - - GridBagLayout gridbag = new GridBagLayout(); - GridBagConstraints c = new GridBagConstraints(); - ct.setLayout(gridbag); - + int y = 0; - - JLabel x = new JLabel("
" + - "Your CloudCoins from " + ps.srcWallet.getName() + " have been backed up into" + - "
"); - - AppUI.setCommonFont(x); - - c.insets = new Insets(0, 0, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); - - y++; - - + JLabel fname, value; + MyTextField walletName = null; + + subInnerCore = getPanel("Backup Complete"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + fname = AppUI.wrapDiv("Your CloudCoins from " + ps.srcWallet.getName() + " have been backed up into:"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + final String fdir = ps.chosenFile; JLabel sl = AppUI.getHyperLink(fdir, "javascript:void(0); return false", 20); sl.addMouseListener(new MouseAdapter() { @@ -1824,68 +1808,46 @@ public void mouseReleased(MouseEvent e) { } } }); + + AppUI.getGBRow(subInnerCore, null, sl, y, gridbag); + AppUI.setColor(sl, AppUI.getColor2()); + AppUI.underLine(sl); + y++; - c.insets = new Insets(0, 0, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - gridbag.setConstraints(sl, c); - ct.add(sl); - - y++; - - x = new JLabel("
" + - "All backups are unencrypted. You should save them in a secure location. The CloudCoin Consortium " - + "recommends opening a free account at
" - + "to store backups and passwords."); - - AppUI.setFont(x, 18); - c.insets = new Insets(20, 0, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); - + fname = AppUI.wrapDiv("All backups are unencrypted. You should save them in a secure location. The CloudCoin Consortium " + + "recommends opening a free account at"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; - y++; + fname = AppUI.getHyperLink("https://SecureSafe.com", "https://securesafe.com", 18); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + AppUI.setColor(fname, AppUI.getColor2()); + AppUI.underLine(fname); + y++; - x = AppUI.getHyperLink("https://SecureSafe.com", "https://securesafe.com", 18); - c.insets = new Insets(0, 0, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); + fname = AppUI.wrapDiv("to store backups and passwords."); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + AppUI.GBPad(subInnerCore, y, gridbag); y++; - x = new JLabel("
to store backups and passwords.
"); - AppUI.setFont(x, 18); - c.insets = new Insets(0, 0, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - gridbag.setConstraints(x, c); - ct.add(x); - /* - JPanel bp = getTwoButtonPanelCustom("Show Folder", "Continue", new ActionListener() { - public void actionPerformed(ActionEvent e) { - File file = new File(ps.chosenFile); - Desktop desktop = Desktop.getDesktop(); - try { - desktop.open(file); - } catch (IOException ex){ } - - } - }, new ActionListener() { - public void actionPerformed(ActionEvent e) { - ps.currentScreen = ProgramState.SCREEN_DEFAULT; + AppUI.getTwoButtonPanel(subInnerCore, "", "Continue", null, new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (ps.srcWallet != null && !ps.srcWallet.isSkyWallet()) { + setActiveWallet(ps.srcWallet); + ps.sendType = 0; + ps.currentScreen = ProgramState.SCREEN_SHOW_TRANSACTIONS; + } else { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + } showScreen(); } - });*/ - - JPanel bp = this.getOneButtonPanel(); + }, y, gridbag); - resetState(); + - subInnerCore.add(bp); + resetState(); } public void showTransferDoneScreen() { @@ -1894,7 +1856,6 @@ public void showTransferDoneScreen() { if (isError) { subInnerCore = getPanel("Error"); - AppUI.hr(subInnerCore, 32); resetState(); return; } @@ -1907,8 +1868,6 @@ public void showTransferDoneScreen() { GridBagLayout gridbag = new GridBagLayout(); subInnerCore.setLayout(gridbag); - ps.dstWallet = wallets[0]; - ps.srcWallet = wallets[1]; String to; if (ps.sendType == ProgramState.SEND_TYPE_WALLET) { to = ps.dstWallet.getName(); @@ -1929,7 +1888,6 @@ public void showTransferDoneScreen() { AppUI.GBPad(subInnerCore, y, gridbag); y++; - AppUI.getTwoButtonPanel(subInnerCore, "Next Transfer", "Continue", new ActionListener() { public void actionPerformed(ActionEvent e) { resetState(); @@ -1957,7 +1915,6 @@ public void showImportDoneScreen() { if (isError) { subInnerCore = getPanel("Error"); - AppUI.hr(subInnerCore, 32); resetState(); return; } @@ -2073,120 +2030,97 @@ public void showDeleteWalletDoneScreen() { } public void showClearDoneScreen() { - boolean isError = !ps.errText.equals(""); + boolean isError = !ps.errText.equals(""); JPanel subInnerCore; if (isError) { subInnerCore = getPanel("Error"); - AppUI.hr(subInnerCore, 32); resetState(); return; } - - subInnerCore = getPanel("Confirmation"); - - // Container - JPanel ct = new JPanel(); - AppUI.noOpaque(ct); - subInnerCore.add(ct); - - GridBagLayout gridbag = new GridBagLayout(); - GridBagConstraints c = new GridBagConstraints(); - ct.setLayout(gridbag); - + int y = 0; + JLabel fname, value; + MyTextField walletName = null; - - String txt; + subInnerCore = getPanel("Erasing Complete"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); - if (ps.needBackup) + String txt; + if (!ps.needBackup) txt = "Your Log Files and Transaction History have been permanently deleted."; else - txt = "Your Log Files and Transaction History have been backed up to \\path\\LogTransactionBackup

They have been permanently deleted from Advanced Client."; + txt = "Your Log Files and Transaction History have been backed up.

They have been permanently deleted from Advanced Client."; + fname = AppUI.wrapDiv(txt); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + + AppUI.GBPad(subInnerCore, y, gridbag); y++; - // Q - JLabel x = new JLabel("
" + txt + "
"); - AppUI.setCommonBoldFont(x); - c.insets = new Insets(42, 0, 4, 0); - c.anchor = GridBagConstraints.CENTER; - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = y; - c.gridwidth = 2; - gridbag.setConstraints(x, c); - ct.add(x); - - y++; - resetState(); - - JPanel bp = getOneButtonPanel(); - subInnerCore.add(bp); + AppUI.getTwoButtonPanel(subInnerCore, "Next Transfer", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + resetState(); + ps.currentScreen = ProgramState.SCREEN_WITHDRAW; + showScreen(); + } + }, new ActionListener() { + public void actionPerformed(ActionEvent e) { + + if (ps.srcWallet != null && !ps.srcWallet.isSkyWallet()) { + setActiveWallet(ps.srcWallet); + ps.sendType = 0; + ps.currentScreen = ProgramState.SCREEN_SHOW_TRANSACTIONS; + } else { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + } + showScreen(); + } + }, y, gridbag); + + + resetState(); } public void showConfirmClearScreen() { - JPanel subInnerCore = getPanel("Confirmation"); - - // Container - JPanel ct = new JPanel(); - AppUI.noOpaque(ct); - subInnerCore.add(ct); - + int y = 0; + JLabel fname, value; + MyTextField walletName = null; - - + JPanel subInnerCore = getPanel("Clear History Confirmation"); GridBagLayout gridbag = new GridBagLayout(); - GridBagConstraints c = new GridBagConstraints(); - ct.setLayout(gridbag); + subInnerCore.setLayout(gridbag); + + fname = new JLabel("This is permanent and irreversible!"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + AppUI.setBoldFont(fname, 21); + y++; - int y = 0; - // From Label - JLabel x = new JLabel("
This is permanent and irreversible!
"); - AppUI.setCommonFont(x); - c.anchor = GridBagConstraints.EAST; - c.insets = new Insets(0, 0, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.gridwidth = 2; - gridbag.setConstraints(x, c); - ct.add(x); - String txt; - if (ps.needBackup) txt = "Are you sure you want to delete Log files and Transaction history?"; else txt = "Are you sure you want to delete Log files and Transaction history without backup?"; + fname = new JLabel(txt); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); y++; - // Q - x = new JLabel("
" + txt + "
"); - AppUI.setCommonBoldFont(x); - c.insets = new Insets(42, 0, 4, 0); - c.anchor = GridBagConstraints.CENTER; - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = y; - c.gridwidth = 2; - gridbag.setConstraints(x, c); - ct.add(x); - - y++; - - JPanel bp = getTwoButtonPanel(new ActionListener() { + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { public void actionPerformed(ActionEvent e) { - - // if (!AppCore.eraseSync) - launchErasers(); - - // ps.currentScreen = ProgramState.SCREEN_CLEAR_DONE; - // showScreen(); } - }); - - - subInnerCore.add(bp); - + }, y, gridbag); } public void showConfirmDeleteWalletScreen() { @@ -4316,107 +4250,61 @@ public void mouseReleased(MouseEvent e) { } public void showClearScreen() { - showLeftScreen(); - - JPanel rightPanel = getRightPanel(); - JPanel ct = new JPanel(); - AppUI.setBoxLayout(ct, true); - AppUI.noOpaque(ct); - rightPanel.add(ct); - - JLabel ltitle = AppUI.getTitle("Clear History"); - ct.add(ltitle); - AppUI.hr(ct, 12); - - maybeShowError(ct); - - JLabel ntext = new JLabel("Clearing history will ensure your privacy if somebody gains access to your computer"); - AppUI.setFont(ntext, 15); - AppUI.alignCenter(ntext); - ct.add(ntext); - - // Space - AppUI.hr(ct, 34); - - ntext = new JLabel("WARNING!"); - AppUI.setBoldFont(ntext, 21); - AppUI.alignCenter(ntext); - ct.add(ntext); - - // Space - AppUI.hr(ct, 4); - - ntext = new JLabel("Clearing the History is a permanent and irreversible process"); - AppUI.setBoldFont(ntext, 21); - AppUI.alignCenter(ntext); - ct.add(ntext); - - // Space - AppUI.hr(ct, 28); - - ntext = new JLabel("Do not proceed unless these files will never be needed again."); - AppUI.setFont(ntext, 20); - AppUI.alignCenter(ntext); - ct.add(ntext); - - ntext = new JLabel("Otherwise, copy the history and store it elsewhere before deleting."); - AppUI.setFont(ntext, 20); - AppUI.alignCenter(ntext); - ct.add(ntext); - - // Space - AppUI.hr(ct, 20); - - ntext = new JLabel("No coins will be deleted, only transaction history and log files."); - AppUI.setFont(ntext, 20); - AppUI.alignCenter(ntext); - ct.add(ntext); + int y = 0; + JLabel fname; + MyTextField tf0, tf1; + + JPanel subInnerCore = getPanel("Clear History"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + fname = AppUI.wrapDiv("Clearing history will ensure your privacy if somebody gains access to your computer"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; - // GridHolder Container - JPanel gct = new JPanel(); - AppUI.noOpaque(gct); - - GridBagLayout gridbag = new GridBagLayout(); - gct.setLayout(gridbag); - GridBagConstraints c = new GridBagConstraints(); + fname = new JLabel("Clearing the History is a permanent and irreversible process"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + AppUI.setBoldFont(fname, 21); + y++; - int y = 0; + fname = AppUI.wrapDiv("Do not proceed unless these files will never be needed again.
" + + "Otherwise, copy the history and store it elsewhere before deleting.
" + + "No coins will be deleted, only transaction history and log files."); + AppUI.setCommonFont(fname); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; - // Checkbox MyCheckBox cb0 = new MyCheckBox("I have read and understand the Warning"); - cb0.setBoldFontSize(21); - c.anchor = GridBagConstraints.WEST; - c.insets = new Insets(0, 0, 6, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = 0; - gridbag.setConstraints(cb0.getCheckBox(), c); - gct.add(cb0.getCheckBox()); + cb0.setFont(16, AppUI.getColor5()); + AppUI.getGBRow(subInnerCore, null, cb0.getCheckBox(), y, gridbag); + y++; - y++; - final MyCheckBox cb1 = new MyCheckBox("Create Backup of History and Log files"); - cb1.setBoldFontSize(21); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - gridbag.setConstraints(cb1.getCheckBox(), c); - gct.add(cb1.getCheckBox()); + MyCheckBox cb1 = new MyCheckBox("Create Backup of History and Log files"); + cb1.setFont(16, AppUI.getColor5()); + AppUI.getGBRow(subInnerCore, null, cb1.getCheckBox(), y, gridbag); + y++; - - ct.add(gct); - - // Space - AppUI.hr(ct, 20); - JPanel bp = getTwoButtonPanel(new ActionListener() { + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + // Buttons + continueButton = AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { public void actionPerformed(ActionEvent e) { - ps.needBackup = cb1.isChecked(); ps.currentScreen = ProgramState.SCREEN_CONFIRM_CLEAR; showScreen(); } - }); - + }, y, gridbag); + continueButton.disable(); @@ -4434,84 +4322,47 @@ public void itemStateChanged(ItemEvent e) { } } }); + + + - AppUI.hr(rightPanel, 20); - rightPanel.add(bp); } public void showListSerialsScreen() { - showLeftScreen(); - - JPanel rightPanel = getRightPanel(); - JPanel ct = new JPanel(); - AppUI.setBoxLayout(ct, true); - AppUI.noOpaque(ct); - rightPanel.add(ct); - - JLabel ltitle = AppUI.getTitle("List Serials"); - ct.add(ltitle); - AppUI.hr(ct, 20); - - maybeShowError(ct); - + int y = 0; + JLabel fname; + MyTextField walletName = null; + + JPanel subInnerCore = getPanel("List Serials"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + final optRv rv = setOptionsForWallets(false, false); if (rv.idxs.length == 0) { - JLabel nx = new JLabel("You have no coins to list serial numbers"); - AppUI.setSemiBoldFont(nx, 20); - AppUI.alignCenter(nx); - ct.add(nx); + fname = new JLabel("You have no coins to list serial numbers"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); return; } + fname = new JLabel("List Serials will show you Serial Numbers of your CloudCoins"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; - - // GridHolder Container - JPanel gct = new JPanel(); - AppUI.noOpaque(gct); - - GridBagLayout gridbag = new GridBagLayout(); - gct.setLayout(gridbag); - GridBagConstraints c = new GridBagConstraints(); - - int y = 0; - - // Text - c.anchor = GridBagConstraints.CENTER; - c.insets = new Insets(0, 0, 80, 0); - c.gridx = 0; - c.gridy = y; - c.gridwidth = 2; - - JLabel l = new JLabel("List Serials will show you Serial Numbers of your CloudCoins"); - AppUI.setCommonFont(l); - gridbag.setConstraints(l, c); - gct.add(l); - + fname = new JLabel("From Wallet"); + final RoundedCornerComboBox cboxfrom = new RoundedCornerComboBox(AppUI.getColor6(), "Make Selection", rv.options); + cboxfrom.setDefault(null); + AppUI.getGBRow(subInnerCore, fname, cboxfrom.getComboBox(), y, gridbag); y++; - c.gridwidth = 1; - c.insets = new Insets(0, 16, 10, 0); - c.anchor = GridBagConstraints.EAST; - // Transfer from - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - JLabel x = new JLabel(" From Wallet"); - gridbag.setConstraints(x, c); - AppUI.setCommonFont(x); - gct.add(x); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.WEST; - - final RoundedCornerComboBox cboxfrom = new RoundedCornerComboBox(AppUI.getColor2(), "Make Selection", rv.options); - gridbag.setConstraints(cboxfrom.getComboBox(), c); - gct.add(cboxfrom.getComboBox()); - + AppUI.GBPad(subInnerCore, y, gridbag); y++; - - rightPanel.add(gct); - - JPanel bp = getTwoButtonPanel(new ActionListener() { + + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { public void actionPerformed(ActionEvent e) { int srcIdx = cboxfrom.getSelectedIndex() - 1; if (srcIdx < 0 || srcIdx >= rv.idxs.length) { @@ -4528,10 +4379,9 @@ public void actionPerformed(ActionEvent e) { ps.currentScreen = ProgramState.SCREEN_LIST_SERIALS_DONE; showScreen(); } - }); + }, y, gridbag); + - AppUI.hr(rightPanel, 20); - rightPanel.add(bp); } @@ -5016,30 +4866,26 @@ public void actionPerformed(ActionEvent e) { } public void showListSerialsDone() { - showLeftScreen(); - - final Wallet w = ps.srcWallet; - - JPanel rightPanel = getRightPanel(AppUI.getColor4()); - JPanel ct = new JPanel(); - AppUI.setBoxLayout(ct, true); - AppUI.noOpaque(ct); - rightPanel.add(ct); - - JLabel ltitle = AppUI.getTitle("List Serials - " + w.getName() + " - " + w.getTotal() + " CC"); - ct.add(ltitle); - AppUI.hr(ct, 20); + JLabel fname; + int y = 0; + + JPanel subInnerCore = getPanel("List Serials"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + final Wallet w = ps.srcWallet; int[] sns = w.getSNs(); if (sns.length == 0) { - JLabel trLabel = new JLabel("No Serials"); - AppUI.setSemiBoldFont(trLabel, 20); - AppUI.alignCenter(trLabel); - ct.add(trLabel); + fname = new JLabel("No Serials"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); return; } + fname = AppUI.wrapDiv("Wallet " + w.getName() + " - " + w.getTotal() + " CC"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + // Scrollbar & Table DefaultTableCellRenderer r = new DefaultTableCellRenderer() { @@ -5049,19 +4895,16 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); lbl = (JLabel) this; - if (row % 2 == 0) { - AppUI.setBackground(lbl, AppUI.getColor3()); - } else { - AppUI.setBackground(lbl, AppUI.getColor4()); - } - - lbl.setHorizontalAlignment(JLabel.CENTER); + AppUI.setBackground(lbl, AppUI.getColor6()); + AppUI.setColor(lbl, AppUI.getColor5()); + lbl.setHorizontalAlignment(JLabel.LEFT); AppUI.setMargin(lbl, 8); return lbl; } }; + String[][] serials = new String[sns.length][]; for (int i = 0; i < sns.length; i++) { CloudCoin cc = new CloudCoin(Config.DEFAULT_NN, sns[i]); @@ -5075,11 +4918,17 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole //serial number table final JTable table = new JTable(); final JScrollPane scrollPane = AppUI.setupTable(table, new String[] {"Serial Number", "Denomination"}, serials, r); - AppUI.setSize(scrollPane, 260, 325); + AppUI.setSize(scrollPane, 460, 285); - ct.add(scrollPane); + AppUI.getGBRow(subInnerCore, null, scrollPane, y, gridbag); + y++; + - JPanel bp = getTwoButtonPanelCustom("Print", "Export List", new ActionListener() { + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + AppUI.getTwoButtonPanel(subInnerCore, "Print", "Export List", new ActionListener() { public void actionPerformed(ActionEvent e) { try { table.print(); @@ -5097,16 +4946,14 @@ public void actionPerformed(ActionEvent e) { w.saveSerials(c.getSelectedFile().getAbsolutePath()); } } - }); - - AppUI.hr(rightPanel, 20); - rightPanel.add(bp); + }, y, gridbag); + + resetState(); } public void showTransactionsScreen() { boolean isSky = sm.getActiveWallet().isSkyWallet() ? true : false; - - + showLeftScreen(); JPanel rightPanel = getRightPanel(); @@ -5421,10 +5268,7 @@ public void mouseMoved(MouseEvent e) { public void mouseExited(MouseEvent e) { }//end mouse exited };//end mouse Adapter - - - - + table.addMouseListener(ma); table.addMouseMotionListener(ma); @@ -6109,9 +5953,9 @@ else if (type == TYPE_ADD_SKY) JLabel labelName = new JLabel(name); if (isDisabled) { AppUI.setColor(labelName, AppUI.getDisabledColor2()); - AppUI.setFont(labelName, 16); + AppUI.setFont(labelName, 14); } else { - AppUI.setBoldFont(labelName, 16); + AppUI.setBoldFont(labelName, 14); AppUI.setColor(labelName, AppUI.getColor5()); wpanel.setBorder(BorderFactory.createMatteBorder(1, 1, 1, 1, AppUI.getColor0())); } @@ -6137,7 +5981,7 @@ else if (type == TYPE_ADD_SKY) GridBagConstraints c = new GridBagConstraints(); c.anchor = GridBagConstraints.CENTER; - c.insets = new Insets(0, 10, 0, 0); + c.insets = new Insets(0, 18, 0, 0); c.gridx = GridBagConstraints.RELATIVE; c.gridy = y; c.gridheight = 2; diff --git a/src/advclient/AppUI.java b/src/advclient/AppUI.java index b2bb1d1..137f499 100644 --- a/src/advclient/AppUI.java +++ b/src/advclient/AppUI.java @@ -661,10 +661,15 @@ public static void getGBRow(JComponent parent, JComponent left, JComponent right if (right != null) { if (right instanceof JLabel) { - c.insets = new Insets(20, 0, 0, 0); + if (left == null) + c.insets = new Insets(20, 0, 20, 0); + else + c.insets = new Insets(20, 0, 0, 0); AppUI.setCommonFont(right); } + + gridbag.setConstraints(right, c); parent.add(right); } From 189b936f8bdce13dc4ad582d9eb76dd5ee6079c6 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 8 Aug 2019 19:11:54 +0300 Subject: [PATCH 009/160] backup, delete, fix screens --- src/advclient/AdvancedClient.java | 654 +++++++++--------------------- 1 file changed, 201 insertions(+), 453 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index ce9b185..2249877 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -1128,17 +1128,7 @@ public void showFixingfrackedScreen() { c.gridy = y; gridbag.setConstraints(pbar, c); ct.add(pbar); - - JPanel bp = getOneButtonPanelCustom("Cancel", new ActionListener() { - public void actionPerformed(ActionEvent e) { - sm.cancel("FrackFixer"); - - showScreen(); - } - }); - - subInnerCore.add(bp); - + Thread t = new Thread(new Runnable() { public void run(){ if (!ps.isEchoFinished) { @@ -1219,6 +1209,7 @@ public void showEchoRAIDAFinishedScreen() { x = new JLabel("RAIDA" + i); AppUI.setCommonTableFontSize(x, fontSize); + AppUI.setColor(x, AppUI.getColor5()); c.gridwidth = 1; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(0, 0, 2, 0); @@ -1235,6 +1226,7 @@ public void showEchoRAIDAFinishedScreen() { x = new JLabel(status); AppUI.setCommonTableFontSize(x, fontSize); + AppUI.setColor(x, AppUI.getColor5()); c.anchor = GridBagConstraints.EAST; c.insets = new Insets(0, 40, 2, 0); c.gridx = GridBagConstraints.RELATIVE; @@ -1248,6 +1240,7 @@ public void showEchoRAIDAFinishedScreen() { x = new JLabel("RAIDA" + j); AppUI.setCommonTableFontSize(x, fontSize); + AppUI.setColor(x, AppUI.getColor5()); c.gridwidth = 1; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(0, 100, 2, 0); @@ -1264,6 +1257,7 @@ public void showEchoRAIDAFinishedScreen() { x = new JLabel(status); AppUI.setCommonTableFontSize(x, fontSize); + AppUI.setColor(x, AppUI.getColor5()); c.anchor = GridBagConstraints.EAST; c.insets = new Insets(0, 40, 2, 0); c.gridx = GridBagConstraints.RELATIVE; @@ -1685,92 +1679,57 @@ public void showFixDoneScreen() { if (isError) { subInnerCore = getPanel("Error"); - AppUI.hr(subInnerCore, 32); resetState(); return; } - - //String total = AppCore.formatNumber(ps.statTotalFracked); + + int y = 0; + JLabel fname, value; + MyTextField walletName = null; + + subInnerCore = getPanel("Fix Complete"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + String totalFixed = AppCore.formatNumber(ps.statTotalFixed); - //String totalFailedToFix = AppCore.formatNumber(ps.statFailedToFix); - - String total = AppCore.formatNumber(ps.statTotalFrackedValue); String totalFixedValue = AppCore.formatNumber(ps.statTotalFixedValue); - //String totalFailedToFixValue = AppCore.formatNumber(ps.statTotalFrackedValue - ps.statTotalFixedValue); - - subInnerCore = getPanel("Fix Complete"); - - JPanel ct = new JPanel(); - AppUI.noOpaque(ct); - subInnerCore.add(ct); - - GridBagLayout gridbag = new GridBagLayout(); - GridBagConstraints c = new GridBagConstraints(); - ct.setLayout(gridbag); - - + String txt; if (!totalFixed.equals("" + total)) { txt = "Not all CloudCoins from " + ps.srcWallet.getName() + " had been fixed. Try it again later"; } else { txt = "Your CloudCoins from " + ps.srcWallet.getName() + " have been fixed"; } + + //fname = AppUI.wrapDiv("Deposited " + total + " CloudCoins to " + ps.dstWallet.getName() + " "); + fname = AppUI.wrapDiv(txt); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; - JLabel x = new JLabel("
" + txt + "
"); - - AppUI.setCommonFont(x); - - c.insets = new Insets(0, 0, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = 0; - c.gridwidth = 2; - gridbag.setConstraints(x, c); - ct.add(x); - - x = new JLabel("Total Fracked Coins:"); - AppUI.setCommonFont(x); - - c.weightx = 1; - c.anchor = GridBagConstraints.EAST; - c.insets = new Insets(50, 0, 4, 10); - c.gridx = 0; - c.gridy = 1; - c.gridwidth = 1; - gridbag.setConstraints(x, c); - ct.add(x); - - x = new JLabel(total); - AppUI.setCommonBoldFont(x); - - c.anchor = GridBagConstraints.WEST; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = 1; - gridbag.setConstraints(x, c); - ct.add(x); - - x = new JLabel("Total Fixed Coins:"); - AppUI.setCommonFont(x); - c.anchor = GridBagConstraints.EAST; - c.insets = new Insets(10, 0, 4, 10); - c.gridx = 0; - c.gridy = 2; - gridbag.setConstraints(x, c); - ct.add(x); + fname = new JLabel("Total Fracked Coins:"); + value = new JLabel(total); + AppUI.getGBRow(subInnerCore, fname, value, y, gridbag); + y++; - x = new JLabel(totalFixedValue); - AppUI.setCommonBoldFont(x); - c.anchor = GridBagConstraints.WEST; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = 2; - gridbag.setConstraints(x, c); - ct.add(x); - - JPanel bp = getOneButtonPanel(); - - resetState(); + fname = new JLabel("Total Fixed Coins:"); + value = new JLabel(totalFixedValue); + AppUI.getGBRow(subInnerCore, fname, value, y, gridbag); + y++; + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; - subInnerCore.add(bp); + + AppUI.getTwoButtonPanel(subInnerCore, "", "Continue", null, new ActionListener() { + public void actionPerformed(ActionEvent e) { + setActiveWallet(ps.dstWallet); + ps.sendType = 0; + ps.currentScreen = ProgramState.SCREEN_SHOW_TRANSACTIONS; + showScreen(); + } + }, y, gridbag); + } public void showBackupDoneScreen() { @@ -1844,10 +1803,7 @@ public void actionPerformed(ActionEvent e) { showScreen(); } }, y, gridbag); - - - - resetState(); + } public void showTransferDoneScreen() { @@ -1982,51 +1938,41 @@ public void actionPerformed(ActionEvent e) { } public void showDeleteWalletDoneScreen() { - boolean isError = !ps.errText.equals(""); + boolean isError = !ps.errText.equals(""); JPanel subInnerCore; if (isError) { subInnerCore = getPanel("Error"); - AppUI.hr(subInnerCore, 32); resetState(); return; } - - subInnerCore = getPanel("Confirmation"); - - // Container - JPanel ct = new JPanel(); - AppUI.noOpaque(ct); - subInnerCore.add(ct); - - GridBagLayout gridbag = new GridBagLayout(); - GridBagConstraints c = new GridBagConstraints(); - ct.setLayout(gridbag); - + int y = 0; + JLabel fname, value; + MyTextField walletName = null; - + subInnerCore = getPanel("Delete Wallet Complete"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + String txt = "Your Wallet " + ps.srcWallet.getName() + " has been deleted."; - + + fname = AppUI.wrapDiv(txt); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + + AppUI.GBPad(subInnerCore, y, gridbag); y++; - // Q - JLabel x = new JLabel("
" + txt + "
"); - AppUI.setCommonBoldFont(x); - c.insets = new Insets(42, 0, 4, 0); - c.anchor = GridBagConstraints.CENTER; - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = y; - c.gridwidth = 2; - gridbag.setConstraints(x, c); - ct.add(x); - - y++; - - resetState(); - JPanel bp = getOneButtonPanel(); - subInnerCore.add(bp); + AppUI.getTwoButtonPanel(subInnerCore, "", "Continue", null, new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, y, gridbag); + + resetState(); } public void showClearDoneScreen() { @@ -2060,15 +2006,8 @@ public void showClearDoneScreen() { AppUI.GBPad(subInnerCore, y, gridbag); y++; - AppUI.getTwoButtonPanel(subInnerCore, "Next Transfer", "Continue", new ActionListener() { - public void actionPerformed(ActionEvent e) { - resetState(); - ps.currentScreen = ProgramState.SCREEN_WITHDRAW; - showScreen(); - } - }, new ActionListener() { - public void actionPerformed(ActionEvent e) { - + AppUI.getTwoButtonPanel(subInnerCore, "", "Continue", null, new ActionListener() { + public void actionPerformed(ActionEvent e) { if (ps.srcWallet != null && !ps.srcWallet.isSkyWallet()) { setActiveWallet(ps.srcWallet); ps.sendType = 0; @@ -2079,9 +2018,7 @@ public void actionPerformed(ActionEvent e) { showScreen(); } }, y, gridbag); - - - resetState(); + } public void showConfirmClearScreen() { @@ -2124,29 +2061,17 @@ public void actionPerformed(ActionEvent e) { } public void showConfirmDeleteWalletScreen() { - JPanel subInnerCore = getPanel("Confirmation"); - - // Container - JPanel ct = new JPanel(); - AppUI.noOpaque(ct); - subInnerCore.add(ct); - - GridBagLayout gridbag = new GridBagLayout(); - GridBagConstraints c = new GridBagConstraints(); - ct.setLayout(gridbag); - int y = 0; - // From Label - JLabel x = new JLabel("
This is permanent and irreversible!
"); - AppUI.setCommonFont(x); - c.anchor = GridBagConstraints.EAST; - c.insets = new Insets(0, 0, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.gridwidth = 2; - gridbag.setConstraints(x, c); - ct.add(x); + JLabel fname, value; + MyTextField walletName = null; + JPanel subInnerCore = getPanel("Delete Wallet Confirmation"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + fname = new JLabel("This is permanent and irreversible!"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + AppUI.setBoldFont(fname, 21); y++; String txt; @@ -2155,51 +2080,30 @@ public void showConfirmDeleteWalletScreen() { if (ps.srcWallet.isSkyWallet()) { txt += "

Your ID coin will be put back into your Bank. You will not be able to receive Coins at this address again"; } - - // Q - x = new JLabel("
" + txt + "
"); - AppUI.setCommonBoldFont(x); - c.insets = new Insets(32, 0, 4, 0); - c.anchor = GridBagConstraints.CENTER; - c.gridx = GridBagConstraints.RELATIVE;; - c.gridy = y; - c.gridwidth = 2; - gridbag.setConstraints(x, c); - ct.add(x); - - y++; + fname = AppUI.wrapDiv(txt); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + final Wallet dstWallet = sm.getWalletByName(AppCore.getDefaultWalletName()); MyTextField tf0 = null; if (dstWallet.isEncrypted() && ps.srcWallet.isSkyWallet()) { - // Password Label - JLabel n = new JLabel("Password"); - AppUI.setCommonFont(n); - c.anchor = GridBagConstraints.EAST; - c.insets = new Insets(24, 32, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.gridwidth = 1; - gridbag.setConstraints(n, c); - ct.add(n); - + fname = new JLabel("Password"); tf0 = new MyTextField("Dst Wallet Password"); - c.insets = new Insets(24, 10, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.anchor = GridBagConstraints.WEST; - c.gridy = y; - c.gridwidth = 1; - gridbag.setConstraints(tf0.getTextField(), c); - ct.add(tf0.getTextField()); - + AppUI.getGBRow(subInnerCore, fname, tf0.getTextField(), y, gridbag); y++; - - c.gridwidth = 2; } + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; final MyTextField mtf0 = tf0; - - JPanel bp = getTwoButtonPanel(new ActionListener() { + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { public void actionPerformed(ActionEvent e) { if (ps.srcWallet.getTotal() != 0) { ps.errText = "The Wallet is not empty"; @@ -2207,16 +2111,13 @@ public void actionPerformed(ActionEvent e) { return; } - wl.debug(ltag, "Deleting Wallet " + ps.srcWallet.getName()); - - + wl.debug(ltag, "Deleting Wallet " + ps.srcWallet.getName()); if (ps.srcWallet.isSkyWallet()) { String defWalletName = dstWallet.getName(); String origName = ps.srcWallet.getIDCoin().originalFile; String name = ps.srcWallet.getIDCoin().getFileName(); - wl.debug(ltag, "Moving id " + origName + " to " + defWalletName + " name"); - + wl.debug(ltag, "Moving id " + origName + " to " + defWalletName + " name"); if (dstWallet.isEncrypted()) { if (mtf0 == null) return; @@ -2241,8 +2142,7 @@ public void actionPerformed(ActionEvent e) { return; } - dstWallet.setPassword(mtf0.getText()); - + dstWallet.setPassword(mtf0.getText()); } if (!AppCore.moveToFolderNewName(origName, Config.DIR_BANK, defWalletName, name)) { @@ -2250,8 +2150,7 @@ public void actionPerformed(ActionEvent e) { showScreen(); return; } - - + if (dstWallet.isEncrypted()) { wl.debug(ltag, "Start Vaulter"); @@ -2284,8 +2183,7 @@ public void run() { }, dstWallet.getPassword()); return; - } - + } } else { if (!AppCore.moveFolderToTrash(ps.srcWallet.getName())) { ps.errText = "Failed to delete Wallet"; @@ -2298,10 +2196,7 @@ public void run() { ps.currentScreen = ProgramState.SCREEN_DELETE_WALLET_DONE; showScreen(); } - }); - - - subInnerCore.add(bp); + }, y, gridbag); } public void showConfirmTransferScreen() { @@ -3061,9 +2956,10 @@ public void showTransferScreen() { int nonSkyCnt = 0; - for (int i = 0; i < wallets.length; i++) + for (int i = 0; i < wallets.length; i++) { if (!wallets[i].isSkyWallet()) nonSkyCnt++; + } final int[] idxs = new int[nonSkyCnt]; final String[] options = new String[nonSkyCnt]; @@ -3769,17 +3665,7 @@ public void showDepositScreen() { AppUI.getGBRow(subInnerCore, null, ddPanel, y, gridbag); y++; - - - - - - - - - - - + AppUI.GBPad(subInnerCore, y, gridbag); y++; @@ -3812,8 +3698,7 @@ public void filesDropped( java.io.File[] files ) { for( int i = 0; i < files.length; i++ ) { ps.files.add(files[i].getAbsolutePath()); } - - + String totalCloudCoins = AppCore.calcCoinsFromFilenames(ps.files); String text = "Selected " + ps.files.size() + " files - " + totalCloudCoins + " CloudCoins"; @@ -3844,9 +3729,7 @@ public void mouseReleased(MouseEvent e) { } } }); - - - + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { public void actionPerformed(ActionEvent e) { ps.currentScreen = ProgramState.SCREEN_DEFAULT; @@ -3896,8 +3779,7 @@ public void actionPerformed(ActionEvent e) { return; } } - - + if (!w.isSkyWallet()) { int cnt; /* @@ -3929,8 +3811,7 @@ public void actionPerformed(ActionEvent e) { return; } } - - + ps.currentScreen = ProgramState.SCREEN_IMPORTING; showScreen(); @@ -3938,65 +3819,28 @@ public void actionPerformed(ActionEvent e) { }, y, gridbag); } - public void showFoldersScreen() { - showLeftScreen(); - - Wallet w = sm.getActiveWallet(); + public void showFoldersScreen() { + int y = 0; + JLabel fname, value; + MyTextField walletName = null; - JPanel rightPanel = getRightPanel(); - JPanel ct = new JPanel(); - AppUI.setBoxLayout(ct, true); - AppUI.noOpaque(ct); - rightPanel.add(ct); - - JLabel ltitle = AppUI.getTitle("Show Folders"); - ct.add(ltitle); - // AppUI.hr(ct, 20); - - // GridHolder Container - JPanel gct = new JPanel(); - AppUI.noOpaque(gct); - + JPanel subInnerCore = getPanel("Folders"); GridBagLayout gridbag = new GridBagLayout(); - gct.setLayout(gridbag); - GridBagConstraints c = new GridBagConstraints(); + subInnerCore.setLayout(gridbag); + + Wallet w = sm.getActiveWallet(); + - int y = 0; - - c.anchor = GridBagConstraints.NORTH; - c.insets = new Insets(0, 0, 24, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.gridwidth = 2; - - - JLabel sl = new JLabel("Folders:"); - AppUI.setCommonFont(sl); - gridbag.setConstraints(sl, c); - gct.add(sl); - y++; - - c.gridwidth = 1; for (int i = 0; i < wallets.length; i++) { if (wallets[i].isSkyWallet()) continue; - - sl = new JLabel(wallets[i].getName()); - AppUI.setBoldFont(sl, 18); - c.insets = new Insets(0, 0, 4, 0); - c.anchor = GridBagConstraints.EAST; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - // c.weightx = 2; - gridbag.setConstraints(sl, c); - gct.add(sl); - - sl = new JLabel(AppCore.getRootUserDir(wallets[i].getName())); - AppUI.setFont(sl, 18); - + + + + JLabel sl = new JLabel(wallets[i].getName()); final String fdir = AppCore.getRootUserDir(wallets[i].getName()); - sl = AppUI.getHyperLink(fdir, "javascript:void(0); return false", 20); - sl.addMouseListener(new MouseAdapter() { + JLabel link = AppUI.getHyperLink(fdir, "javascript:void(0); return false", 20); + link.addMouseListener(new MouseAdapter() { public void mouseReleased(MouseEvent e) { if (!Desktop.isDesktopSupported()) return; @@ -4007,35 +3851,24 @@ public void mouseReleased(MouseEvent e) { } } }); - - - - //only tested on windows -// Desktop desktop = Desktop.getDesktop(); -// File dirToOpen = null; -// try{ -// String path = AppCore.getRootUserDir(wallets[i].getName()); -// Runtime runtime = Runtime.getRuntime(); -// runtime.exec("explorer.exe " + path); -// } catch(Exception E) { -// -// } - - c.insets = new Insets(0, 10, 4, 0); - c.anchor = GridBagConstraints.WEST; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - // c.weightx = 3; - gridbag.setConstraints(sl, c); - gct.add(sl); + AppUI.getGBRow(subInnerCore, sl, link, y, gridbag); + AppUI.setColor(link, AppUI.getColor2()); + AppUI.underLine(link); y++; - - + } - - - ct.add(gct); + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + AppUI.getTwoButtonPanel(subInnerCore, "", "Continue", null, new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, y, gridbag); + } public void showSupportScreen() { @@ -4341,6 +4174,8 @@ public void showListSerialsScreen() { if (rv.idxs.length == 0) { fname = new JLabel("You have no coins to list serial numbers"); AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + AppUI.GBPad(subInnerCore, y, gridbag); return; } @@ -4387,105 +4222,46 @@ public void actionPerformed(ActionEvent e) { public void showFixfrackedScreen() { - showLeftScreen(); - - JPanel rightPanel = getRightPanel(); - JPanel ct = new JPanel(); - AppUI.setBoxLayout(ct, true); - AppUI.noOpaque(ct); - rightPanel.add(ct); - - JLabel ltitle = AppUI.getTitle("Fix Fracked"); - ct.add(ltitle); - AppUI.hr(ct, 20); - - maybeShowError(ct); - + int y = 0; + JLabel fname; + MyTextField tf0, tf1; + + JPanel subInnerCore = getPanel("Fix Fracked Coins"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + final optRv rv = setOptionsForWallets(true, false); if (rv.idxs.length == 0) { - JLabel nx = new JLabel("You have no fracked coins"); - AppUI.setSemiBoldFont(nx, 20); - AppUI.alignCenter(nx); - ct.add(nx); + fname = AppUI.wrapDiv("You have no fracked coins"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + AppUI.GBPad(subInnerCore, y, gridbag); return; } - - // GridHolder Container - JPanel gct = new JPanel(); - AppUI.noOpaque(gct); - - GridBagLayout gridbag = new GridBagLayout(); - gct.setLayout(gridbag); - GridBagConstraints c = new GridBagConstraints(); - - int y = 0; - // Text - c.anchor = GridBagConstraints.CENTER; - c.insets = new Insets(0, 0, 80, 0); - c.gridx = 0; - c.gridy = y; - c.gridwidth = 2; - - JLabel l = new JLabel("Fix Fracked CloudCoins"); - AppUI.setCommonFont(l); - gridbag.setConstraints(l, c); - gct.add(l); - - y++; - c.gridwidth = 1; - c.insets = new Insets(0, 16, 10, 0); - c.anchor = GridBagConstraints.EAST; - // Transfer from - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - JLabel x = new JLabel(" From Wallet"); - gridbag.setConstraints(x, c); - AppUI.setCommonFont(x); - gct.add(x); - - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.WEST; - - final RoundedCornerComboBox cboxfrom = new RoundedCornerComboBox(AppUI.getColor2(), "Make Selection", rv.options); - gridbag.setConstraints(cboxfrom.getComboBox(), c); - gct.add(cboxfrom.getComboBox()); - - y++; + fname = new JLabel("From Wallet"); + final RoundedCornerComboBox cboxfrom = new RoundedCornerComboBox(AppUI.getColor6(), "Make Selection", rv.options); + AppUI.getGBRow(subInnerCore, fname, cboxfrom.getComboBox(), y, gridbag); + y++; - // Password From - c.anchor = GridBagConstraints.EAST; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; final JLabel spText = new JLabel("Password"); - gridbag.setConstraints(spText, c); - AppUI.setCommonFont(spText); - gct.add(spText); - - c.anchor = GridBagConstraints.WEST; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; final MyTextField passwordSrc = new MyTextField("Wallet Password", true); - gridbag.setConstraints(passwordSrc.getTextField(), c); - gct.add(passwordSrc.getTextField()); + AppUI.getGBRow(subInnerCore, spText, passwordSrc.getTextField(), y, gridbag); y++; passwordSrc.getTextField().setVisible(false); spText.setVisible(false); - + cboxfrom.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { int srcIdx = cboxfrom.getSelectedIndex() - 1; if (srcIdx < 0 || srcIdx >= rv.idxs.length) return; - srcIdx = rv.idxs[srcIdx]; - + srcIdx = rv.idxs[srcIdx]; Wallet srcWallet = wallets[srcIdx]; - if (srcWallet.isEncrypted()) { passwordSrc.getTextField().setVisible(true); spText.setVisible(true); @@ -4495,10 +4271,17 @@ public void actionPerformed(ActionEvent e) { } } }); - - rightPanel.add(gct); - - JPanel bp = getTwoButtonPanel(new ActionListener() { + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + // Buttons + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { public void actionPerformed(ActionEvent e) { int srcIdx = cboxfrom.getSelectedIndex() - 1; if (srcIdx < 0 || srcIdx >= rv.idxs.length) { @@ -4541,10 +4324,7 @@ public void actionPerformed(ActionEvent e) { ps.currentScreen = ProgramState.SCREEN_FIXING_FRACKED; showScreen(); } - }); - - AppUI.hr(rightPanel, 20); - rightPanel.add(bp); + }, y, gridbag); } @@ -4627,76 +4407,47 @@ else if (wallets[i].isDefaultWallet()) } public void showDeleteWalletScreen() { - showLeftScreen(); - - JPanel rightPanel = getRightPanel(); - JPanel ct = new JPanel(); - AppUI.setBoxLayout(ct, true); - AppUI.noOpaque(ct); - rightPanel.add(ct); - - JLabel ltitle = AppUI.getTitle("Delete Wallet"); - ct.add(ltitle); - AppUI.hr(ct, 20); - - maybeShowError(ct); - + int y = 0; + JLabel fname; + MyTextField tf0, tf1; + + JPanel subInnerCore = getPanel("Delete Wallet"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + final optRv rv = setOptionsForWalletsCommon(false, true, true); if (rv.idxs.length == 0) { - JLabel nx = new JLabel("You have no empty wallets to delete"); - AppUI.setSemiBoldFont(nx, 20); - AppUI.alignCenter(nx); - ct.add(nx); + fname = AppUI.wrapDiv("You have no empty wallets to delete"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + AppUI.GBPad(subInnerCore, y, gridbag); return; } - // GridHolder Container - JPanel gct = new JPanel(); - AppUI.noOpaque(gct); - - GridBagLayout gridbag = new GridBagLayout(); - gct.setLayout(gridbag); - GridBagConstraints c = new GridBagConstraints(); - int y = 0; - - // Text - c.anchor = GridBagConstraints.CENTER; - c.insets = new Insets(0, 0, 80, 0); - c.gridx = 0; - c.gridy = y; - c.gridwidth = 2; - - JLabel l = new JLabel("You can only delete wallets that are empty"); - AppUI.setCommonFont(l); - gridbag.setConstraints(l, c); - gct.add(l); + fname = new JLabel("You can only delete wallets that are empty"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); y++; - c.gridwidth = 1; - c.insets = new Insets(0, 16, 10, 0); - c.anchor = GridBagConstraints.EAST; - // Transfer from - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - JLabel x = new JLabel(" Wallet"); - gridbag.setConstraints(x, c); - AppUI.setCommonFont(x); - gct.add(x); + + fname = new JLabel("Wallet"); + final RoundedCornerComboBox cboxfrom = new RoundedCornerComboBox(AppUI.getColor6(), "Make Selection", rv.options); + cboxfrom.setDefault(null); + AppUI.getGBRow(subInnerCore, fname, cboxfrom.getComboBox(), y, gridbag); + y++; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.WEST; - - final RoundedCornerComboBox cboxfrom = new RoundedCornerComboBox(AppUI.getColor2(), "Make Selection", rv.options); - gridbag.setConstraints(cboxfrom.getComboBox(), c); - gct.add(cboxfrom.getComboBox()); + + AppUI.GBPad(subInnerCore, y, gridbag); y++; - - rightPanel.add(gct); - - JPanel bp = getTwoButtonPanel(new ActionListener() { + + // Buttons + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { public void actionPerformed(ActionEvent e) { int srcIdx = cboxfrom.getSelectedIndex() - 1; if (srcIdx < 0 || srcIdx >= rv.idxs.length) { @@ -4712,13 +4463,8 @@ public void actionPerformed(ActionEvent e) { ps.srcWallet = srcWallet; ps.currentScreen = ProgramState.SCREEN_CONFIRM_DELETE_WALLET; showScreen(); - } - }); - - AppUI.hr(rightPanel, 20); - rightPanel.add(bp); - + }, y, gridbag); } public void showBackupScreen() { @@ -4734,6 +4480,8 @@ public void showBackupScreen() { if (rv.idxs.length == 0) { fname = new JLabel("You have no coins to backup"); AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + AppUI.GBPad(subInnerCore, y, gridbag); return; } @@ -6057,7 +5805,7 @@ public void mouseExited(MouseEvent e) { GridBagConstraints c = new GridBagConstraints(); c.anchor = GridBagConstraints.CENTER; - c.insets = new Insets(0, 8, 0, 0); + c.insets = new Insets(0, 18, 0, 0); c.gridx = GridBagConstraints.RELATIVE; c.gridy = y; c.gridheight = 1; From f255e4ba55eea75d7ea33b5a988732a9719dac66 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 8 Aug 2019 21:20:23 +0300 Subject: [PATCH 010/160] support --- src/advclient/AdvancedClient.java | 152 +++++++----------- src/advclient/AppUI.java | 4 +- src/advclient/common/core/ServantManager.java | 20 +++ src/advclient/common/core/Wallet.java | 2 +- src/resources/support0.png | Bin 0 -> 4739 bytes src/resources/support1.png | Bin 0 -> 4386 bytes src/resources/support2.png | Bin 0 -> 4814 bytes src/resources/support3.png | Bin 0 -> 3728 bytes 8 files changed, 80 insertions(+), 98 deletions(-) create mode 100644 src/resources/support0.png create mode 100644 src/resources/support1.png create mode 100644 src/resources/support2.png create mode 100644 src/resources/support3.png diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 2249877..f9cb8b6 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -2691,6 +2691,7 @@ public void eraserGoNext() { } else { ps.currentScreen = ProgramState.SCREEN_CLEAR_DONE; + sm.openTransactions(); if (ps.needBackup) { if (!wl.copyMe()) { @@ -3834,9 +3835,7 @@ public void showFoldersScreen() { for (int i = 0; i < wallets.length; i++) { if (wallets[i].isSkyWallet()) continue; - - JLabel sl = new JLabel(wallets[i].getName()); final String fdir = AppCore.getRootUserDir(wallets[i].getName()); JLabel link = AppUI.getHyperLink(fdir, "javascript:void(0); return false", 20); @@ -3872,106 +3871,73 @@ public void actionPerformed(ActionEvent e) { } public void showSupportScreen() { - showLeftScreen(); - - Wallet w = sm.getActiveWallet(); - - JPanel rightPanel = getRightPanel(); - JPanel ct = new JPanel(); - AppUI.setBoxLayout(ct, true); - AppUI.noOpaque(ct); - rightPanel.add(ct); - - JLabel ltitle = AppUI.getTitle("Help & Support"); - ct.add(ltitle); - // AppUI.hr(ct, 20); - - // GridHolder Container - JPanel gct = new JPanel(); - AppUI.noOpaque(gct); - - GridBagLayout gridbag = new GridBagLayout(); - gct.setLayout(gridbag); - GridBagConstraints c = new GridBagConstraints(); - int y = 0; - - c.anchor = GridBagConstraints.NORTH; - c.insets = new Insets(10, 0, 14, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - JLabel vl = new JLabel("Version: " + this.version); - AppUI.setFont(vl, 16); - gridbag.setConstraints(vl, c); - gct.add(vl); - y++; - - c.anchor = GridBagConstraints.NORTH; - c.insets = new Insets(0, 0, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; + JLabel fname, value; + MyTextField walletName = null; - /* - int tsw = 0; - for (int i = 0; i < wallets.length; i++) { - if (wallets[i].isSkyWallet()) { - tsw++; - } - } - - int topMargin = 0; - if (tsw != 0) { - JLabel sl = new JLabel("Your Sky Wallets:"); - AppUI.setFont(sl, 22); - gridbag.setConstraints(sl, c); - gct.add(sl); - y++; + JPanel subInnerCore = getPanel("Help and Support"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + Image img; + JLabel i0, i1, i2, i3; + try { + img = ImageIO.read(getClass().getClassLoader().getResource("resources/support0.png")); + i0 = new JLabel(new ImageIcon(img)); - for (int i = 0; i < wallets.length; i++) { - if (wallets[i].isSkyWallet()) { - sl = new JLabel(wallets[i].getName()); - AppUI.setFont(sl, 18); - c.insets = new Insets(0, 0, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - gridbag.setConstraints(sl, c); - gct.add(sl); - y++; - } - } - topMargin = 26; - } - */ - - int topMargin = 26; + + img = ImageIO.read(getClass().getClassLoader().getResource("resources/support1.png")); + i1 = new JLabel(new ImageIcon(img)); + + img = ImageIO.read(getClass().getClassLoader().getResource("resources/support2.png")); + i2 = new JLabel(new ImageIcon(img)); + + img = ImageIO.read(getClass().getClassLoader().getResource("resources/support3.png")); + i3 = new JLabel(new ImageIcon(img)); + + AppUI.setSize(i0, 10, 10); + AppUI.setSize(i1, 10, 10); + AppUI.setSize(i2, 10, 10); + } catch (Exception ex) { + return; + } - c.anchor = GridBagConstraints.CENTER; - c.insets = new Insets(topMargin, 0, 4, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - String urlName = "http://cloudcoinconsortium.com/use.html"; - JLabel l = AppUI.getHyperLink(urlName, urlName, 0); - gridbag.setConstraints(l, c); - gct.add(l); + JLabel link = AppUI.getHyperLink(urlName, urlName, 0); + AppUI.getGBRow(subInnerCore, i0, link, y, gridbag); + AppUI.setColor(link, AppUI.getColor2()); + AppUI.underLine(link); + y++; + fname = new JLabel("9AM to 3AM California time (PST)"); + AppUI.getGBRow(subInnerCore, i1, fname, y, gridbag); y++; - l = new JLabel("

" - + "Support: 9 AM to 3 AM California Time (PST)
" - + "Tel: +1(530)762-1361
" - + "Email: Support@cloudcoinmail.com
"); - c.insets = new Insets(0, 0, 0, 0); - AppUI.alignCenter(l); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - AppUI.setCommonFont(l); - gridbag.setConstraints(l, c); - gct.add(l); + fname = new JLabel("Tel: +1 (530) 762-1361"); + AppUI.getGBRow(subInnerCore, i2, fname, y, gridbag); + y++; + AppUI.GBPad(subInnerCore, y, gridbag); y++; + if (1==1) + return; + + /* + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + AppUI.getTwoButtonPanel(subInnerCore, "", "Continue", null, new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, y, gridbag); + + + l = new JLabel("
" + "(Secure if you get a free encrypted email account at ProtonMail.com)
"); @@ -4078,7 +4044,7 @@ public void mouseReleased(MouseEvent e) { //rightPanel - + */ } @@ -4114,13 +4080,11 @@ public void showClearScreen() { AppUI.getGBRow(subInnerCore, null, cb0.getCheckBox(), y, gridbag); y++; - MyCheckBox cb1 = new MyCheckBox("Create Backup of History and Log files"); + final MyCheckBox cb1 = new MyCheckBox("Create Backup of History and Log files"); cb1.setFont(16, AppUI.getColor5()); AppUI.getGBRow(subInnerCore, null, cb1.getCheckBox(), y, gridbag); y++; - - AppUI.GBPad(subInnerCore, y, gridbag); y++; diff --git a/src/advclient/AppUI.java b/src/advclient/AppUI.java index 137f499..0a538b1 100644 --- a/src/advclient/AppUI.java +++ b/src/advclient/AppUI.java @@ -667,9 +667,7 @@ public static void getGBRow(JComponent parent, JComponent left, JComponent right c.insets = new Insets(20, 0, 0, 0); AppUI.setCommonFont(right); } - - - + gridbag.setConstraints(right, c); parent.add(right); } diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index 996796f..b37d15e 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -1233,6 +1233,24 @@ public Wallet getWalletByName(String walletName) { return null; } + public void openTransactions() { + Collection c = wallets.values(); + + Iterator itr = c.iterator(); + while (itr.hasNext()) { + Wallet w = (Wallet) itr.next(); + + System.out.println("w=" + w.getName() + " total=" + w.getTotal()); + if (w.isSkyWallet()) + continue; + + + + if (w.getTotal() != 0) + w.appendTransaction("Opening Balance", w.getTotal(), "openingbalance"); + } + } + public String[] getRAIDAStatuses() { Servant e = sr.getServant("Echoer"); @@ -1270,5 +1288,7 @@ public class makeChangeResult { public int progress; } + + } diff --git a/src/advclient/common/core/Wallet.java b/src/advclient/common/core/Wallet.java index cde760d..f84169c 100644 --- a/src/advclient/common/core/Wallet.java +++ b/src/advclient/common/core/Wallet.java @@ -191,7 +191,7 @@ public void appendTransaction(String memo, int amount, String receiptId, String String rMemo = memo.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll(",", " "); //String sAmount = Integer.toString(amount); - int rest = getTotal(); + int rest = 0; String[][] tr = getTransactions(); if (tr != null) { diff --git a/src/resources/support0.png b/src/resources/support0.png new file mode 100644 index 0000000000000000000000000000000000000000..434d2db5b9e094bcd0abf8fa64e3054b24e5fdd9 GIT binary patch literal 4739 zcmV-}5`686P)KLZ*U+IBfRsybQWXdwQbLP>6pAqfylh#{fb6;Z(vMMVS~$e@S=j*ftg6;Uhf59&ghTmgWD0l;*T zI709Y^p6lP1rIRMx#05C~cW=H_Aw*bJ-5DT&Z2n+x)QHX^p z00esgV8|mQcmRZ%02D^@S3L16t`O%c004NIvOKvYIYoh62rY33S640`D9%Y2D-rV&neh&#Q1i z007~1e$oCcFS8neI|hJl{-P!B1ZZ9hpmq0)X0i`JwE&>$+E?>%_LC6RbVIkUx0b+_+BaR3cnT7Zv!AJxW zizFb)h!jyGOOZ85F;a?DAXP{m@;!0_IfqH8(HlgRxt7s3}k3K`kFu>>-2Q$QMFfPW!La{h336o>X zu_CMttHv6zR;&ZNiS=X8v3CR#fknUxHUxJ0uoBa_M6WNWeqIg~6QE69c9o#eyhGvpiOA@W-aonk<7r1(?fC{oI5N*U!4 zfg=2N-7=cNnjjOr{yriy6mMFgG#l znCF=fnQv8CDz++o6_Lscl}eQ+l^ZHARH>?_s@|##Rr6KLRFA1%Q+=*RRWnoLsR`7U zt5vFIcfW3@?wFpwUVxrVZ>QdQz32KIeJ}k~{cZZE^+ya? z2D1z#2HOnI7(B%_ac?{wFUQ;QQA1tBKtrWrm0_3Rgps+?Jfqb{jYbcQX~taRB;#$y zZN{S}1|}gUOHJxc?wV3fxuz+mJ4`!F$IZ;mqRrNsHJd##*D~ju=bP7?-?v~|cv>vB zsJ6IeNwVZxrdjT`yl#bBIa#GxRa#xMMy;K#CDyyGyQdMSxlWT#tDe?p!?5wT$+oGt z8L;Kp2HUQ-ZMJ=3XJQv;x5ci*?vuTfeY$;({XGW_huIFR9a(?@3)XSs8O^N5RyOM=TTmp(3=8^+zpz2r)C z^>JO{deZfso3oq3?Wo(Y?l$ge?uXo;%ru`Vo>?<<(8I_>;8Eq#KMS9gFl*neeosSB zfoHYnBQIkwkyowPu(zdms`p{<7e4kra-ZWq<2*OsGTvEV%s0Td$hXT+!*8Bnh2KMe zBmZRodjHV?r+_5^X9J0WL4jKW`}lf%A-|44I@@LTvf1rHjG(ze6+w@Jt%Bvjts!X0 z?2xS?_ve_-kiKB_KiJlZ$9G`c^=E@oNG)mWWaNo-3TIW8)$Hg0Ub-~8?KhvJ>$ z3*&nim@mj(aCxE5!t{lw7O5^0EIO7zOo&c6l<+|iDySBWCGrz@C5{St!X3hAA}`T4 z(TLbXTq+(;@<=L8dXnssyft|w#WSTW<++3>sgS%(4NTpeI-VAqb|7ssJvzNHgOZVu zaYCvgO_R1~>SyL=cFU|~g|hy|Zi}}s9+d~lYqOB71z9Z$wnC=pR9Yz4DhIM>Wmjgu z&56o6maCpC&F##y%G;1PobR9i?GnNg;gYtchD%p19a!eQtZF&3JaKv33gZ<8D~47E ztUS1iwkmDaPpj=$m#%)jCVEY4fnLGNg2A-`YwHVD3gv};>)hAvT~AmqS>Lr``i7kw zJ{5_It`yrBmlc25DBO7E8;5VoznR>Ww5hAaxn$2~(q`%A-YuS64wkBy=9dm`4cXeX z4c}I@?e+FW+b@^RDBHV(wnMq2zdX3SWv9u`%{xC-q*U}&`cyXV(%rRT*Z6MH?i+i& z_B8C(+grT%{XWUQ+f@NoP1R=AW&26{v-dx)iK^-Nmiuj8txj!m?Z*Ss1N{dh4z}01 z)YTo*JycSU)+_5r4#yw9{+;i4Ee$peRgIj+;v;ZGdF1K$3E%e~4LaI(jC-u%2h$&R z9cLXcYC@Xwnns&bn)_Q~Te?roKGD|d-g^8;+aC{{G(1^(O7m37Y1-+6)01cN&y1aw zoqc{T`P^XJqPBbIW6s}d4{z_f5Om?vMgNQEJG?v2T=KYd^0M3I6IZxbny)%vZR&LD zJpPl@Psh8QyPB@KTx+@RdcC!KX7}kEo;S|j^u2lU7XQ}Oo;f|;z4Ll+_r>@1-xl3| zawq-H%e&ckC+@AhPrP6BKT#_XdT7&;F71j}Joy zkC~6lh7E@6o;W@^IpRNZ{ptLtL(gQ-CY~4mqW;US7Zxvm_|@yz&e53Bp_lTPlfP|z zrTyx_>lv@x#=^!PzR7qqF<$gm`|ZJZ+;<)Cqu&ot2z=0000WV@Og>004R=004l4008;_004mL004C`008P>0026e000+nl3&F} z000NBNkl2`=0lG-shw2>62i*Kqk9`%P3vO+6s!1IW3z)oEoqs0^(Fe;`ut$X zcR_TWtyFw%P2=HFW0A6n`Li|7b(?8zT!L`>J_<{q3$$ZN+*bhJ)jhB4bLXVd1~3q>d}+ zXoD>cXoP6BIgW|X$sg_1g!lE`KQKR&2tnWAGbTPKUzIU$IhR(vC~$nkQpNASGxQt! zA;PEkp5YrR_c7L7r*gmfhtTO)R)@}ST^s&<$A-~J6<=EuD55aznZKhM^Zvf@m7SXn zi~oHb8Iv=H_lP+@T2kZEedom1+G+p*T4R}jOevWF0Ah2^Q5@)Sv9^L@T4%KZ01#P- zNG-M1ksI&-UGcWu8h#Rim%DFVR=mv(inryKzO>>!p|ScPD3UlVQ(e)fom7k|mIy%~ zt+U$X-iB|)_RD8u3f8`=%3ipV$O4bdX%hhegxjC}*Z0vg&cKNc%YYD~pSR-xr81a@ z@~S2-T4i2!{5BJxlh1$u$ve8DO*@BW$|mN|))fAJ8wCJtLhdvo1iVuFl^R+TYbCt* zUgYa{-y|~MkAt0Uj3px{aQvkuIMm%SP|9|f*j#fI6oDTEflv%ci@cW}7JL&EpE z6@R-+>1(Rzzx#0KV3|e+W6gEaYNLhLT5U}Hq5}5pGo- zppnV$V3P|=qMc<(N{e}N^&gNv(LQkM+4FU!+xD@E`Lo9xdM>(6QLH1ERvRri)YBo{IrR~( zjZc(3b+u!W;$WAXNywY7ajt!hiFHh76Q|AsiW)W{IDFSbv$ld_(f!5A=-ep+FL!@? z1sRjl0RRY=CDC=ZQgmNBJzl0b)ZLDQU2bH_$N?-%MCuO#01z=004z%Ygs`@PVurC~ z^%+XS51CT4D5O&V7($BE8FX_t?|$U_G{Y+1=34{Z+uKDe-j+tjk~s+nJKI7v zn_n=Lzx^StiL*+cx(jUT>;)93GmJ~h#%L){XB@k=Wr@Fe@SjSsvyGNKbr;y=X(a#v zV$1m|-zUE*Lgv(Lpb$fA;}aQcu5+ZWK18ZAS_Vd94EGV2ok#1eNs_1T0y3!4U5#`7 z7XJGq1NA2u%iTA>QaQ?gshhKTw|e5@)vC;S%L(uIDqhzQKnQ+lr$+AgDuIp`&OWOg z``mYw-iB|GKG8lXH~;{VYkRh{wu0iw*Zbe56<=Eu5duEeR#5x^1uL{RK5^)t)tCMC z15Lq;n}z}n4WY66VBfBvYQ2XR=lK7(<|!rUX&tImV$1m|AQ&sYwk8??p#SQwt=btI zw+{uxp}U@uz%fs*-e_J~)u5gE$G3(aYP68rE}e?bZ@|-{FaO)&{;RvTM)#@IdHtf| zbKi-{TN!l+e8aK#B+s?aM|7zXnNqW2rat#F6YIzw^FM3j5(e!I4)=KEt{Yztnzd+V zq1uY|>YSy|KiD{g1U_B2Kx)5yW+b54TysoxKgeX%HD_^51^^ITXDg98BPUc_vHl^u z0*WL`?k`X4%icPq^flGvU}q~}S)#R88<$*I8YOgJI@Mpd=M5a{=@^TYwdOjpzoQw& zWlss7*ti_`-|K#u6aa`2@JekLKhw?I{ytC$$vyRTOl;<4F0E)G03mYsw_gQ5{oO(w z=x7;N5>*BhYoGB{@WjUDiof0UNH;iWKl~rBoXJ{qoyKMR&r^tHfnX(g<}c6sj{JHC zks{$S%Nmz8#jxZ*C)p(D9Dn7rMI#9Zw0ATwD~5x?Gq0>3bofLO1zK&iAd}rO+O+{0 zY-w!DjCm?Y`3fKy_g~%p`eQr%G4C?^gk(Yp27)m~(TD&L9P05r&RypJ0{}okomo=U Rf$0DM002ovPDHLkV1j6D`{@7x literal 0 HcmV?d00001 diff --git a/src/resources/support1.png b/src/resources/support1.png new file mode 100644 index 0000000000000000000000000000000000000000..b199f39bcd6d73b4fc93dd8b5fadda6c79616fa1 GIT binary patch literal 4386 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 literal 0 HcmV?d00001 diff --git a/src/resources/support3.png b/src/resources/support3.png new file mode 100644 index 0000000000000000000000000000000000000000..0db92bfa80002ac649108866128e8e7c960df003 GIT binary patch literal 3728 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 Date: Thu, 8 Aug 2019 21:55:51 +0300 Subject: [PATCH 011/160] support screen --- src/advclient/AdvancedClient.java | 129 +++++++++++++++++++++++++++--- src/advclient/AppUI.java | 9 ++- 2 files changed, 124 insertions(+), 14 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index f9cb8b6..e9c4e4f 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -37,6 +37,8 @@ import java.awt.print.PrinterException; import java.io.File; import java.io.IOException; +import java.net.URI; +import java.net.URISyntaxException; import java.util.*; import javax.imageio.ImageIO; import javax.swing.event.PopupMenuEvent; @@ -3884,9 +3886,7 @@ public void showSupportScreen() { try { img = ImageIO.read(getClass().getClassLoader().getResource("resources/support0.png")); i0 = new JLabel(new ImageIcon(img)); - - - + img = ImageIO.read(getClass().getClassLoader().getResource("resources/support1.png")); i1 = new JLabel(new ImageIcon(img)); @@ -3896,31 +3896,138 @@ public void showSupportScreen() { img = ImageIO.read(getClass().getClassLoader().getResource("resources/support3.png")); i3 = new JLabel(new ImageIcon(img)); - AppUI.setSize(i0, 10, 10); - AppUI.setSize(i1, 10, 10); - AppUI.setSize(i2, 10, 10); } catch (Exception ex) { return; } + + JPanel wr; + String urlName = "http://cloudcoinconsortium.com/use.html"; JLabel link = AppUI.getHyperLink(urlName, urlName, 0); - AppUI.getGBRow(subInnerCore, i0, link, y, gridbag); - AppUI.setColor(link, AppUI.getColor2()); - AppUI.underLine(link); + + wr = new JPanel(); + AppUI.noOpaque(wr); + wr.add(i0); + wr.add(AppUI.vr(10)); + wr.add(link); + AppUI.getGBRow(subInnerCore, null, wr, y, gridbag); y++; + wr = new JPanel(); + AppUI.noOpaque(wr); + wr.add(i1); + wr.add(AppUI.vr(10)); fname = new JLabel("9AM to 3AM California time (PST)"); - AppUI.getGBRow(subInnerCore, i1, fname, y, gridbag); + AppUI.setCommonFont(fname); + wr.add(fname); + AppUI.getGBRow(subInnerCore, null, wr, y, gridbag); y++; + + wr = new JPanel(); + AppUI.noOpaque(wr); + wr.add(i2); + wr.add(AppUI.vr(10)); fname = new JLabel("Tel: +1 (530) 762-1361"); - AppUI.getGBRow(subInnerCore, i2, fname, y, gridbag); + AppUI.setCommonFont(fname); + wr.add(fname); + AppUI.getGBRow(subInnerCore, null, wr, y, gridbag); y++; + + wr = new JPanel(); + AppUI.noOpaque(wr); + wr.add(i3); + wr.add(AppUI.vr(10)); + + JPanel wr2 = new JPanel(); + AppUI.noOpaque(wr2); + AppUI.setBoxLayout(wr2, true); + fname = new JLabel("Email: support@protonmail.com"); + AppUI.setCommonFont(fname); + wr2.add(fname); + fname = new JLabel("(Secure if you get a free encrypted email account at ProtonMail.com)"); + AppUI.setFont(fname, 14); + AppUI.setColor(fname, AppUI.getColor14()); + wr2.add(fname); + wr.add(wr2); + + MyButton pb = new MyButton("Get ProtonMail"); + pb.addListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (Desktop.isDesktopSupported()) { + try { + URI uri = new URI("https://www.protonmail.com"); + Desktop.getDesktop().browse(uri); + } catch (IOException ex) { + + } catch (URISyntaxException ex) { + + } + } + } + }); + + + + + AppUI.getGBRow(subInnerCore, wr, pb.getButton(), y, gridbag); + y++; + + + + AppUI.GBPad(subInnerCore, y, gridbag); y++; + GridBagConstraints c = new GridBagConstraints(); + c.anchor = GridBagConstraints.CENTER; + c.insets = new Insets(20, 0, 0, 10); + c.gridy = y; + c.weightx = 1; + c.weighty = 0; + c.gridwidth = 2; + + JLabel l = AppUI.getHyperLink("Instructions, Terms and Conditions", "javascript:void(0); return false", 20); + l.addMouseListener(new MouseAdapter() { + public void mouseReleased(MouseEvent e) { + final JDialog f = new JDialog(mainFrame, "Instructions, Terms and Conditions", true); + f.setModalityType(Dialog.ModalityType.APPLICATION_MODAL); + AppUI.noOpaque((JComponent) f.getContentPane()); + AppUI.setSize(f, (int) (tw / 1.2), (int) (th / 1.2)); + + JTextPane tp = new JTextPane(); + + + AppUI.setFont(tp, 12); + String fontfamily = tp.getFont().getFamily(); + + tp.setContentType("text/html"); + tp.setText("
" + AppUI.getAgreementText() + "
"); + tp.setEditable(false); + tp.setBackground(null); + tp.setCaretPosition(0); + + JScrollPane scrollPane = new JScrollPane(tp); + + f.add(scrollPane); + f.pack(); + f.setLocationRelativeTo(mainFrame); + f.setVisible(true); + + scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMinimum()); + scrollPane.getViewport().setViewPosition(new java.awt.Point(0, 100)); + scrollPane.repaint(); + } + }); + + + gridbag.setConstraints(l, c); + subInnerCore.add(l); + + + if (1==1) return; diff --git a/src/advclient/AppUI.java b/src/advclient/AppUI.java index 0a538b1..8b2bc8b 100644 --- a/src/advclient/AppUI.java +++ b/src/advclient/AppUI.java @@ -193,6 +193,9 @@ public static Color getColor13() { return new Color(0x62A459); } + public static Color getColor14() { + return new Color(0x7E8084); + } public static Color getDisabledColor() { return new Color(0xCCCCCC); @@ -648,7 +651,7 @@ public static void getGBRow(JComponent parent, JComponent left, JComponent right if (left != null) { if (left instanceof JLabel) { AppUI.setCommonFont(left); - } + } gridbag.setConstraints(left, c); parent.add(left); @@ -656,8 +659,8 @@ public static void getGBRow(JComponent parent, JComponent left, JComponent right c.gridwidth = 2; } - c.insets = new Insets(10, 0, 0, 0); - c.weightx = 1; + c.insets = new Insets(8, 0, 0, 0); + c.weightx = 10; if (right != null) { if (right instanceof JLabel) { From 5b5d043afe0bc976f35234bee0defa2a15dedfd5 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 9 Aug 2019 07:44:27 +0300 Subject: [PATCH 012/160] wallet name --- src/advclient/AdvancedClient.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index e9c4e4f..de684d9 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -54,7 +54,7 @@ * */ public class AdvancedClient { - String version = "2.1.8"; + String version = "2.1.9"; JPanel headerPanel; JPanel mainPanel; @@ -1890,8 +1890,7 @@ public void showImportDoneScreen() { String totalFailedValue = AppCore.formatNumber(ps.statFailedValue); String totalLostValue = AppCore.formatNumber(ps.statLostValue); - //fname = AppUI.wrapDiv("Deposited " + total + " CloudCoins to " + ps.dstWallet.getName() + " "); - fname = AppUI.wrapDiv("Deposited " + total + " CloudCoins to xxx "); + fname = AppUI.wrapDiv("Deposited " + total + " CloudCoins to " + ps.dstWallet.getName() + " "); AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); y++; From 0c4bf4a73fe79258e8ebb17bed6c32300d77db5a Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Sun, 11 Aug 2019 10:35:05 +0300 Subject: [PATCH 013/160] optimize transactions --- src/advclient/AdvancedClient.java | 125 ++++++++++++++++++------------ 1 file changed, 75 insertions(+), 50 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index de684d9..3c4022a 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -90,6 +90,9 @@ public class AdvancedClient { final static int TYPE_ADD_BUTTON = 1; final static int TYPE_ADD_SKY = 2; + JLabel trTitle; + JPanel invPanel; + public AdvancedClient() { initSystem(); @@ -184,6 +187,12 @@ else if (total < 999999999) AppUI.setFont(cntLabel, fsize); } cntLabel.repaint(); + + if (ps.currentScreen == ProgramState.SCREEN_SHOW_TRANSACTIONS) { + if (w == sm.getActiveWallet()) { + updateTransactionWalletData(w); + } + } } public String getPickError(Wallet w) { @@ -4769,61 +4778,83 @@ public void actionPerformed(ActionEvent e) { resetState(); } - public void showTransactionsScreen() { + public void updateTransactionWalletData(Wallet w) { + if (trTitle != null) { + String rec = ""; + if (!w.getEmail().isEmpty()) { + String colstr = "#" + Integer.toHexString(AppUI.getColor5().getRGB()).substring(2); + rec = "
Recovery Email: " + w.getEmail() + ""; + } + + String titleText = "" + w.getName() + " - " + + AppCore.formatNumber(w.getTotal()) + "cc" + rec + ""; + trTitle.setText(titleText); + trTitle.validate(); + trTitle.repaint(); + } + + if (invPanel != null) { + int[][] counters = w.getCounters(); + if (counters != null && counters.length != 0) { + int t1, t5, t25, t100, t250; + + t1 = counters[Config.IDX_FOLDER_BANK][Config.IDX_1] + + counters[Config.IDX_FOLDER_FRACKED][Config.IDX_1] + + counters[Config.IDX_FOLDER_VAULT][Config.IDX_1]; + + t5 = counters[Config.IDX_FOLDER_BANK][Config.IDX_5] + + counters[Config.IDX_FOLDER_FRACKED][Config.IDX_5] + + counters[Config.IDX_FOLDER_VAULT][Config.IDX_5]; + + t25 = counters[Config.IDX_FOLDER_BANK][Config.IDX_25] + + counters[Config.IDX_FOLDER_FRACKED][Config.IDX_25] + + counters[Config.IDX_FOLDER_VAULT][Config.IDX_25]; + + t100 = counters[Config.IDX_FOLDER_BANK][Config.IDX_100] + + counters[Config.IDX_FOLDER_FRACKED][Config.IDX_100] + + counters[Config.IDX_FOLDER_VAULT][Config.IDX_100]; + + t250 = counters[Config.IDX_FOLDER_BANK][Config.IDX_250] + + counters[Config.IDX_FOLDER_FRACKED][Config.IDX_250] + + counters[Config.IDX_FOLDER_VAULT][Config.IDX_250]; + + AppUI.addInvItem(invPanel, "1", t1); + AppUI.addInvItem(invPanel, "5", t5); + AppUI.addInvItem(invPanel, "25", t25); + AppUI.addInvItem(invPanel, "100", t100); + AppUI.addInvItem(invPanel, "250", t250); + } + } + } + + + public void showTransactionsScreen() { + invPanel = null; + trTitle = null; + boolean isSky = sm.getActiveWallet().isSkyWallet() ? true : false; showLeftScreen(); JPanel rightPanel = getRightPanel(); Wallet w = sm.getActiveWallet(); - String rec = ""; - if (!w.getEmail().isEmpty()) { - String colstr = "#" + Integer.toHexString(AppUI.getColor5().getRGB()).substring(2); - rec = "
Recovery Email: " + w.getEmail() + ""; - } - - String titleText = "" + w.getName() + " - " - + AppCore.formatNumber(w.getTotal()) + "cc" + rec + ""; - + JPanel hwrapper = new JPanel(); AppUI.setBoxLayout(hwrapper, false); AppUI.alignLeft(hwrapper); AppUI.noOpaque(hwrapper); - JLabel title = new JLabel(titleText); - AppUI.alignLeft(title); - AppUI.alignTop(title); - AppUI.setFont(title, 30); - AppUI.setColor(title, AppUI.getColor1()); - hwrapper.add(title); + trTitle = new JLabel(""); + AppUI.alignLeft(trTitle); + AppUI.alignTop(trTitle); + AppUI.setFont(trTitle, 30); + AppUI.setColor(trTitle, AppUI.getColor1()); + hwrapper.add(trTitle); int[][] counters = w.getCounters(); if (!isSky && counters != null && counters.length != 0) { - int t1, t5, t25, t100, t250; - - t1 = counters[Config.IDX_FOLDER_BANK][Config.IDX_1] + - counters[Config.IDX_FOLDER_FRACKED][Config.IDX_1] + - counters[Config.IDX_FOLDER_VAULT][Config.IDX_1]; - - t5 = counters[Config.IDX_FOLDER_BANK][Config.IDX_5] + - counters[Config.IDX_FOLDER_FRACKED][Config.IDX_5] + - counters[Config.IDX_FOLDER_VAULT][Config.IDX_5]; - - t25 = counters[Config.IDX_FOLDER_BANK][Config.IDX_25] + - counters[Config.IDX_FOLDER_FRACKED][Config.IDX_25] + - counters[Config.IDX_FOLDER_VAULT][Config.IDX_25]; - - t100 = counters[Config.IDX_FOLDER_BANK][Config.IDX_100] + - counters[Config.IDX_FOLDER_FRACKED][Config.IDX_100] + - counters[Config.IDX_FOLDER_VAULT][Config.IDX_100]; - - t250 = counters[Config.IDX_FOLDER_BANK][Config.IDX_250] + - counters[Config.IDX_FOLDER_FRACKED][Config.IDX_250] + - counters[Config.IDX_FOLDER_VAULT][Config.IDX_250]; - - - JPanel invPanel = new JPanel(); + invPanel = new JPanel(); AppUI.setBackground(invPanel, AppUI.getColor7()); AppUI.alignTop(invPanel); AppUI.setSize(invPanel, 520, 62); @@ -4845,18 +4876,12 @@ public void showTransactionsScreen() { AppUI.setColor(invLabel, AppUI.getColor5()); AppUI.setMargin(invLabel, 0, 10, 0, 20); invPanel.add(invLabel); - - - // 5 times - AppUI.addInvItem(invPanel, "1", t1); - AppUI.addInvItem(invPanel, "5", t5); - AppUI.addInvItem(invPanel, "25", t25); - AppUI.addInvItem(invPanel, "100", t100); - AppUI.addInvItem(invPanel, "250", t250); - - + + } + updateTransactionWalletData(w); + rightPanel.add(hwrapper); rightPanel.add(AppUI.hr(22)); From 764ff4636decea2d0355b645d7aa939c9598d9f4 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Sun, 11 Aug 2019 10:40:53 +0300 Subject: [PATCH 014/160] email changed --- src/advclient/AdvancedClient.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 3c4022a..a1f5e98 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -200,7 +200,7 @@ public String getPickError(Wallet w) { + "Cannot make change

This version of software does not support making change
" + "You may only choose amounts that match your exact notes.
Please check to see if" + " there is a newer version of the software.
In the meantime, you may transfer amounts " - + "that match the CloudCoin notes.
There are people who make change and you can find their addresses by contacting CloudCoinSupport@Protonmail.com"; + + "that match the CloudCoin notes.
There are people who make change and you can find their addresses by contacting support@cloudcoinmail.com"; int[][] counters = w.getCounters(); @@ -3952,7 +3952,7 @@ public void showSupportScreen() { JPanel wr2 = new JPanel(); AppUI.noOpaque(wr2); AppUI.setBoxLayout(wr2, true); - fname = new JLabel("Email: support@protonmail.com"); + fname = new JLabel("Email: support@cloudcoinmail.com"); AppUI.setCommonFont(fname); wr2.add(fname); fname = new JLabel("(Secure if you get a free encrypted email account at ProtonMail.com)"); From bb2057dd7a33bbcee9268969ac589fa7aeabb2ce Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Sun, 11 Aug 2019 11:17:56 +0300 Subject: [PATCH 015/160] echo raida view --- src/advclient/AdvancedClient.java | 43 +++++++++------ src/advclient/AppUI.java | 7 ++- src/advclient/common/core/AppCore.java | 54 +++++++++++++++++++ src/advclient/common/core/ServantManager.java | 8 +-- 4 files changed, 89 insertions(+), 23 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index a1f5e98..b9b61dc 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -23,6 +23,7 @@ import global.cloudcoin.ccbank.core.CloudCoin; import global.cloudcoin.ccbank.core.Config; import global.cloudcoin.ccbank.core.DNSSn; +import global.cloudcoin.ccbank.core.RAIDA; import global.cloudcoin.ccbank.core.Wallet; import javax.swing.*; import java.awt.*; @@ -1211,16 +1212,16 @@ public void showEchoRAIDAFinishedScreen() { gridbag.setConstraints(x, c); ct.add(x);*/ - String[] statuses = sm.getRAIDAStatuses(); + int[] statuses = sm.getRAIDAStatuses(); int y = 1; int fontSize = 16; for (int i = 0; i < statuses.length / 2 + 1; i ++) { String status; - x = new JLabel("RAIDA" + i); + x = new JLabel(AppCore.getRAIDAString(i)); AppUI.setCommonTableFontSize(x, fontSize); - AppUI.setColor(x, AppUI.getColor5()); + AppUI.setColor(x, AppUI.getColor13()); c.gridwidth = 1; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(0, 0, 2, 0); @@ -1228,16 +1229,21 @@ public void showEchoRAIDAFinishedScreen() { c.gridy = y; gridbag.setConstraints(x, c); ct.add(x); - - if (statuses[i] == null) { + + x = new JLabel(""); + if (statuses[i] == -1) { status = "FAILED"; + AppUI.setColor(x, AppUI.getErrorColor()); } else { - status = "OK: " + statuses[i] + "ms"; + //status = "OK: " + statuses[i] + "ms"; + status = AppCore.getMS(statuses[i]); + AppUI.setColor(x, AppUI.getColor13()); } - x = new JLabel(status); + x.setText(status); + AppUI.setCommonTableFontSize(x, fontSize); - AppUI.setColor(x, AppUI.getColor5()); + c.anchor = GridBagConstraints.EAST; c.insets = new Insets(0, 40, 2, 0); c.gridx = GridBagConstraints.RELATIVE; @@ -1245,13 +1251,13 @@ public void showEchoRAIDAFinishedScreen() { gridbag.setConstraints(x, c); ct.add(x); - int j = i + 13; - if (j == 25) + int j = i + RAIDA.TOTAL_RAIDA_COUNT / 2 + 1; + if (j == RAIDA.TOTAL_RAIDA_COUNT) break; - x = new JLabel("RAIDA" + j); + x = new JLabel(AppCore.getRAIDAString(j)); AppUI.setCommonTableFontSize(x, fontSize); - AppUI.setColor(x, AppUI.getColor5()); + AppUI.setColor(x, AppUI.getColor13()); c.gridwidth = 1; c.anchor = GridBagConstraints.WEST; c.insets = new Insets(0, 100, 2, 0); @@ -1259,16 +1265,19 @@ public void showEchoRAIDAFinishedScreen() { c.gridy = y; gridbag.setConstraints(x, c); ct.add(x); - - if (statuses[j] == null) { + + x = new JLabel(""); + if (statuses[j] == -1) { status = "FAILED"; + AppUI.setColor(x, AppUI.getErrorColor()); } else { - status = "OK: " + statuses[j] + "ms"; + status = AppCore.getMS(statuses[j]); + AppUI.setColor(x, AppUI.getColor13()); } - x = new JLabel(status); + x.setText(status); + AppUI.setCommonTableFontSize(x, fontSize); - AppUI.setColor(x, AppUI.getColor5()); c.anchor = GridBagConstraints.EAST; c.insets = new Insets(0, 40, 2, 0); c.gridx = GridBagConstraints.RELATIVE; diff --git a/src/advclient/AppUI.java b/src/advclient/AppUI.java index 8b2bc8b..f3d8cca 100644 --- a/src/advclient/AppUI.java +++ b/src/advclient/AppUI.java @@ -103,8 +103,11 @@ public static void init(int tw, int th) { //GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(montLight); - osRegFont = Font.createFont(Font.TRUETYPE_FONT, cl.getResourceAsStream("resources/Montserrat-Medium.ttf")); - osSemiBoldFont = Font.createFont(Font.TRUETYPE_FONT, cl.getResourceAsStream("resources/Montserrat-Semibold.ttf")); + //osRegFont = Font.createFont(Font.TRUETYPE_FONT, cl.getResourceAsStream("resources/Montserrat-Medium.ttf")); + //osSemiBoldFont = Font.createFont(Font.TRUETYPE_FONT, cl.getResourceAsStream("resources/Montserrat-Semibold.ttf")); + + osRegFont = Font.createFont(Font.TRUETYPE_FONT, cl.getResourceAsStream("resources/OpenSans-Regular.ttf")); + osSemiBoldFont = Font.createFont(Font.TRUETYPE_FONT, cl.getResourceAsStream("resources/OpenSans-Semibold.ttf")); } catch(Exception e){ System.out.println("Failed to load font: " + e.getMessage()); diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index d0f62d2..9890a49 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -992,4 +992,58 @@ public static String calcCoinsFromFilenames(ArrayList files) { return totalCoins; } + public static String getMS(int ms) { + double dms = (double) ms / 1000; + String s = String.format(Locale.US, "%.2f", dms); + + if (s.charAt(0) == '0') + s = s.substring(1, s.length()); + + return s + " sec"; + } + + public static String getRAIDAString(int idx) { + String sidx; + + if (idx < 10) + sidx = "0" + idx; + else + sidx = "" + idx; + + String[] countries = { + "Australia", + "Macedonia", + "Philippines", + "Serbia", + "Switzerland", + "South Korea", + "Japan", + "UK", + "India", + "India", + "Germany", + "USA", + "India", + "Taiwan", + "Russia", + "Russia", + "UK", + "Singapore", + "USA", + "Argentina", + "France", + "India", + "USA", + "Germany", + "Canada" + }; + + if (idx > countries.length) { + return sidx + " RAIDA"; + } + + return sidx + " " + countries[idx]; + + } + } diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index b37d15e..4aa92aa 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -1251,20 +1251,20 @@ public void openTransactions() { } } - public String[] getRAIDAStatuses() { + public int[] getRAIDAStatuses() { Servant e = sr.getServant("Echoer"); e.updateRAIDAStatus(); String[] urls = e.getRAIDA().getRAIDAURLs(); int[] latencies = e.getRAIDA().getLatencies(); - String[] rv = new String[RAIDA.TOTAL_RAIDA_COUNT]; + int[] rv = new int[RAIDA.TOTAL_RAIDA_COUNT]; for (int i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { if (urls[i] == null) - rv[i] = null; + rv[i] = -1; else - rv[i] = "" + latencies[i]; + rv[i] = latencies[i]; } return rv; From 5af5b752dafbe10f56b5a356684a5ec07fe93599 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Sun, 11 Aug 2019 13:24:01 +0300 Subject: [PATCH 016/160] receiver --- src/advclient/AdvancedClient.java | 321 ++++---------------- src/advclient/common/Receiver/Receiver.java | 8 +- 2 files changed, 72 insertions(+), 257 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index b9b61dc..ec84d26 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -996,9 +996,6 @@ public void showScreen() { case ProgramState.SCREEN_PREDEPOSIT: showPredepositScreen(); break; - case ProgramState.SCREEN_DEPOSIT_SKY_WALLET: - showDepositSkyWalletScreen(); - break; case ProgramState.SCREEN_SHOW_FOLDERS: showFoldersScreen(); break; @@ -1813,7 +1810,7 @@ public void mouseReleased(MouseEvent e) { AppUI.getTwoButtonPanel(subInnerCore, "", "Continue", null, new ActionListener() { public void actionPerformed(ActionEvent e) { - if (ps.srcWallet != null && !ps.srcWallet.isSkyWallet()) { + if (ps.srcWallet != null) { setActiveWallet(ps.srcWallet); ps.sendType = 0; ps.currentScreen = ProgramState.SCREEN_SHOW_TRANSACTIONS; @@ -2291,15 +2288,21 @@ public void actionPerformed(ActionEvent e) { ps.srcWallet.setPassword(ps.typedSrcPassword); sm.setActiveWalletObj(ps.srcWallet); - if (ps.sendType == ProgramState.SEND_TYPE_FOLDER) { + if (ps.sendType == ProgramState.SEND_TYPE_FOLDER) { + ps.isSkyDeposit = false; if (ps.srcWallet.isEncrypted()) { sm.startSecureExporterService(Config.TYPE_STACK, ps.typedAmount, ps.typedMemo, ps.chosenFile, false, new ExporterCb()); } else { sm.startExporterService(Config.TYPE_STACK, ps.typedAmount, ps.typedMemo, ps.chosenFile, false, new ExporterCb()); - } + } } else if (ps.sendType == ProgramState.SEND_TYPE_WALLET) { ps.dstWallet.setPassword(ps.typedDstPassword); ps.currentScreen = ProgramState.SCREEN_SENDING; + if (ps.srcWallet.isSkyWallet()) { + ps.isSkyDeposit = true; + } else { + ps.isSkyDeposit = false; + } showScreen(); } else if (ps.sendType == ProgramState.SEND_TYPE_REMOTE) { DNSSn d = new DNSSn(ps.typedRemoteWallet, null, wl); @@ -2312,7 +2315,7 @@ public void actionPerformed(ActionEvent e) { } ps.foundSN = sn; - + ps.isSkyDeposit = false; ps.currentScreen = ProgramState.SCREEN_SENDING; showScreen(); } @@ -2752,219 +2755,6 @@ public String getNonEmptyFolderError(String folder) { + "Please click cancel below to reset. Then deposit them again.").getText(); } - public void showDepositSkyWalletScreen() { - - showLeftScreen(); - - JPanel rightPanel = getRightPanel(); - - JPanel ct = new JPanel(); - AppUI.setBoxLayout(ct, true); - AppUI.noOpaque(ct); - rightPanel.add(ct); - - JLabel ltitle = AppUI.getTitle("Deposit"); - ct.add(ltitle); - AppUI.alignTop(ct); - AppUI.alignTop(ltitle); - - AppUI.hr(ct, 10); - - maybeShowError(ct); - - // Outer Container - JPanel oct = new JPanel(); - AppUI.noOpaque(oct); - - int y = 0; - - GridBagLayout gridbag = new GridBagLayout(); - GridBagConstraints c = new GridBagConstraints(); - c.gridwidth = 1; - c.anchor = GridBagConstraints.EAST; - c.insets = new Insets(12, 18, 0, 0); - oct.setLayout(gridbag); - - String name = ps.dstWallet.getName(); - //if (ps.dstWallet.isSkyWallet()) - // name += "." + Config.DDNS_DOMAIN; - - // Deposit To - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.CENTER; - c.gridwidth = 2; - JLabel x = new JLabel("Deposit To " + name); - gridbag.setConstraints(x, c); - AppUI.setCommonFont(x); - oct.add(x); - - c.gridwidth = 1; - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.WEST; - - y++; - // Memo - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.EAST; - x = new JLabel("Memo (Note)"); - gridbag.setConstraints(x, c); - AppUI.setCommonFont(x); - oct.add(x); - - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.anchor = GridBagConstraints.WEST; - final MyTextField memo = new MyTextField("Memo", false); - gridbag.setConstraints(memo.getTextField(), c); - - if (!ps.typedMemo.isEmpty()) - memo.setData(ps.typedMemo); - - oct.add(memo.getTextField()); - - - - // Total files selected - final JLabel tl = new JLabel("Total files selected: " + ps.files.size()); - //final JLabel tl = new JLabel("Selected " + ps.files.size() + " files - CloudCoins"); - AppUI.setCommonFont(tl); - c.insets = new Insets(28, 18, 0, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridwidth = 2; - c.anchor = GridBagConstraints.CENTER; - c.gridy = y + 3; - gridbag.setConstraints(tl, c); - oct.add(tl); - - int ddWidth = 701; - - // Drag and Drop - JPanel ddPanel = new JPanel(); - ddPanel.setLayout(new GridBagLayout()); - - JLabel l = new JLabel("
Drop files here or click
to select files
"); - AppUI.setColor(l, AppUI.getColor13()); - AppUI.setBoldFont(l, 40); - AppUI.noOpaque(ddPanel); - AppUI.setHandCursor(ddPanel); - ddPanel.setBorder(new DashedBorder(40, AppUI.getColor13())); - ddPanel.add(l); - - c.insets = new Insets(8, 18, 0, 0); - c.gridx = GridBagConstraints.RELATIVE; - c.gridwidth = 2; - c.anchor = GridBagConstraints.CENTER; - c.gridy = y + 4; - - AppUI.setSize(ddPanel, (int) ddWidth, 179); - gridbag.setConstraints(ddPanel, c); - new FileDrop(null, ddPanel, new FileDrop.Listener() { - public void filesDropped( java.io.File[] files ) { - for( int i = 0; i < files.length; i++ ) { - ps.files.add(files[i].getAbsolutePath()); - } - - tl.setText("Total files selected: " + ps.files.size()); - } - }); - - final JFileChooser chooser = new JFileChooser(); - FileNameExtensionFilter filter = new FileNameExtensionFilter( - "CloudCoins", "jpg", "jpeg", "stack", "json", "txt"); - chooser.setFileFilter(filter); - chooser.setMultiSelectionEnabled(true); - - ddPanel.addMouseListener(new MouseAdapter() { - @Override - public void mouseReleased(MouseEvent e) { - int returnVal = chooser.showOpenDialog(null); - if (returnVal == JFileChooser.APPROVE_OPTION) { - File[] files = chooser.getSelectedFiles(); - for (int i = 0; i < files.length; i++) { - ps.files.add(files[i].getAbsolutePath()); - } - - tl.setText("Total files selected: " + ps.files.size()); - } - } - }); - - oct.add(ddPanel); - rightPanel.add(oct); - - // Space - AppUI.hr(oct, 22); - - JPanel bp = getTwoButtonPanel(new ActionListener() { - public void actionPerformed(ActionEvent e) { - Wallet w; - - ps.typedMemo = memo.getText(); - if (ps.typedMemo.isEmpty()) { - ps.errText = "Memo can not be empty"; - showScreen(); - return; - } - - w = ps.dstWallet; - - if (ps.files.size() == 0) { - ps.errText = "No files selected"; - showScreen(); - return; - } - - if (!Validator.memoLength(ps.typedMemo)) { - ps.errText = "Memo too long. Only 64 characters are allowed"; - showScreen(); - return; - } - - if (!Validator.memo(ps.typedMemo)) { - ps.errText = "Memo: Non alpha number characters are not allowed"; - showScreen(); - return; - } - - ps.typedMemo = ps.typedMemo.trim(); - - int cnt = AppCore.getFilesCount(Config.DIR_SUSPECT, w.getParent().getName()); - if (cnt != 0) { - ps.errText = getNonEmptyFolderError("Suspect"); - showScreen(); - return; - } - - cnt = AppCore.getFilesCount(Config.DIR_IMPORT, w.getParent().getName()); - if (cnt != 0) { - ps.errText = getNonEmptyFolderError("Import"); - showScreen(); - return; - } - - cnt = AppCore.getFilesCount(Config.DIR_DETECTED, w.getName()); - if (cnt != 0) { - ps.errText = getNonEmptyFolderError("Detected"); - showScreen(); - return; - } - - - ps.isSkyDeposit = true; - ps.currentScreen = ProgramState.SCREEN_IMPORTING; - - showScreen(); - } - }); - - AppUI.hr(rightPanel, 20); - rightPanel.add(bp); - - } - public void showTransferScreen() { int y = 0; JLabel fname; @@ -2975,28 +2765,16 @@ public void showTransferScreen() { subInnerCore.setLayout(gridbag); - int nonSkyCnt = 0; - for (int i = 0; i < wallets.length; i++) { - if (!wallets[i].isSkyWallet()) - nonSkyCnt++; + final optRv rvFrom = setOptionsForWalletsCommon(false, false, true); + if (rvFrom.idxs.length == 0) { + return; } - final int[] idxs = new int[nonSkyCnt]; - final String[] options = new String[nonSkyCnt]; - - int j = 0; - for (int i = 0; i < wallets.length; i++) { - if (wallets[i].isSkyWallet()) - continue; - - String name = wallets[i].getName(); - options[j] = name + " - " + AppCore.formatNumber(wallets[i].getTotal()) + " CC"; - idxs[j] = i; - j++; - } + final optRv rvTo = setOptionsForWalletsAll(); + fname = new JLabel("Transfer From"); - final RoundedCornerComboBox cboxfrom = new RoundedCornerComboBox(AppUI.getColor6(), "Make Selection", options); + final RoundedCornerComboBox cboxfrom = new RoundedCornerComboBox(AppUI.getColor6(), "Make Selection", rvFrom.options); AppUI.getGBRow(subInnerCore, fname, cboxfrom.getComboBox(), y, gridbag); y++; @@ -3009,7 +2787,7 @@ public void showTransferScreen() { spText.setVisible(false); fname = new JLabel("Transfer To"); - final RoundedCornerComboBox cboxto = new RoundedCornerComboBox(AppUI.getColor6(), "Make Selection", options); + final RoundedCornerComboBox cboxto = new RoundedCornerComboBox(AppUI.getColor6(), "Make Selection", rvTo.options); cboxto.addOption(AppUI.getRemoteUserOption()); cboxto.addOption(AppUI.getLocalFolderOption()); AppUI.getGBRow(subInnerCore, fname, cboxto.getComboBox(), y, gridbag); @@ -3081,7 +2859,7 @@ public void actionPerformed(ActionEvent e) { if (srcIdx < 0 || srcIdx >= wallets.length) return; - srcIdx = idxs[srcIdx]; + srcIdx = rvFrom.idxs[srcIdx]; Wallet srcWallet = wallets[srcIdx]; if (srcWallet == null) return; @@ -3105,7 +2883,7 @@ public void actionPerformed(ActionEvent e) { // Remote Wallet - if (dstIdx == idxs.length) { + if (dstIdx == rvTo.idxs.length) { remoteWalledId.getTextField().setVisible(true); rwText.setVisible(true); @@ -3126,7 +2904,7 @@ public void actionPerformed(ActionEvent e) { rwText.setVisible(false); // Local - if (dstIdx == idxs.length + 1) { + if (dstIdx == rvTo.idxs.length + 1) { passwordDst.getTextField().setVisible(false); dpText.setVisible(false); @@ -3136,11 +2914,11 @@ public void actionPerformed(ActionEvent e) { return; } - if (dstIdx < 0 || dstIdx >= idxs.length) + if (dstIdx < 0 || dstIdx >= rvTo.idxs.length) return; - dstIdx = idxs[dstIdx]; + dstIdx = rvTo.idxs[dstIdx]; Wallet dstWallet = wallets[dstIdx]; if (dstWallet == null) @@ -3183,17 +2961,17 @@ public void actionPerformed(ActionEvent e) { ps.selectedToIdx = cboxto.getSelectedIndex(); ps.typedRemoteWallet = remoteWalledId.getText(); - if (srcIdx < 0 || srcIdx >= idxs.length) { + if (srcIdx < 0 || srcIdx >= rvFrom.idxs.length) { ps.errText = "Please select From Wallet"; showScreen(); return; } - srcIdx = idxs[srcIdx]; + srcIdx = rvFrom.idxs[srcIdx]; Wallet srcWallet = wallets[srcIdx]; ps.srcWallet = srcWallet; - if (dstIdx < 0 || dstIdx >= idxs.length + 2) { + if (dstIdx < 0 || dstIdx >= rvTo.idxs.length + 2) { ps.errText = "Please select To Wallet"; showScreen(); return; @@ -3219,7 +2997,7 @@ public void actionPerformed(ActionEvent e) { return; } - if (dstIdx == idxs.length) { + if (dstIdx == rvTo.idxs.length) { if (ps.typedMemo.isEmpty()) { ps.errText = "Memo cannot be empty"; showScreen(); @@ -3266,7 +3044,7 @@ public void actionPerformed(ActionEvent e) { } - if (dstIdx == idxs.length) { + if (dstIdx == rvTo.idxs.length) { // Remote User if (remoteWalledId.getText().isEmpty()) { ps.errText = "Remote Wallet is empty"; @@ -3290,7 +3068,7 @@ public void actionPerformed(ActionEvent e) { showScreen(); return; } - } else if (dstIdx == idxs.length + 1) { + } else if (dstIdx == rvTo.idxs.length + 1) { if (!Validator.memo(ps.typedMemo)) { ps.errText = "Memo cannot contain dots or slashes"; showScreen(); @@ -3323,7 +3101,7 @@ public void actionPerformed(ActionEvent e) { return; } else { - dstIdx = idxs[dstIdx]; + dstIdx = rvTo.idxs[dstIdx]; if (srcIdx == dstIdx) { ps.errText = "You can not transfer to the same wallet"; showScreen(); @@ -4420,6 +4198,20 @@ public optRv setOptionsForWallets(boolean checkFracked, boolean needEmpty) { return setOptionsForWalletsCommon(checkFracked, needEmpty, false); } + public optRv setOptionsForWalletsAll() { + optRv rv = new optRv(); + + rv.options = new String[wallets.length]; + rv.idxs = new int[wallets.length]; + + for (int i = 0; i < wallets.length; i++) { + rv.options[i] = wallets[i].getName() + " - " + AppCore.formatNumber(wallets[i].getTotal()) + " CC"; + rv.idxs[i] = i; + } + + return rv; + } + public optRv setOptionsForWalletsCommon(boolean checkFracked, boolean needEmpty, boolean includeSky) { optRv rv = new optRv(); @@ -6396,7 +6188,11 @@ public void callback(Object result) { } - ps.dstWallet.appendTransaction(nsb.toString(), wholeTotal, ps.receiptId); + if (ps.typedMemo.isEmpty()) { + ps.dstWallet.appendTransaction(nsb.toString(), wholeTotal, ps.receiptId); + } else { + ps.dstWallet.appendTransaction(ps.typedMemo, ps.statToBankValue, ps.receiptId); + } } else { w.appendTransaction(ps.typedMemo, ps.statToBankValue, ps.receiptId); } @@ -6918,10 +6714,23 @@ public void run() { EventQueue.invokeLater(new Runnable() { public void run() { ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; - if (!rr.errText.isEmpty()) - //ps.errText = rr.errText; - ps.errText = "
" + rr.errText + "
"; - else + if (!rr.errText.isEmpty()) { + if (rr.errText.equals(Config.PICK_ERROR_MSG)) { + /* + if (ps.triedToChange) { + ps.errText = "Failed to change coins"; + } else { + ps.changeFromExport = false; + ps.triedToChange = true; + ps.currentScreen = ProgramState.SCREEN_MAKING_CHANGE; + showScreen(); + return; + }*/ + ps.errText = getPickError(ps.srcWallet); + } else { + ps.errText = rr.errText; + } + } else ps.errText = "Error occurred. Please check the logs"; showScreen(); diff --git a/src/advclient/common/Receiver/Receiver.java b/src/advclient/common/Receiver/Receiver.java index ade2348..dedc19d 100644 --- a/src/advclient/common/Receiver/Receiver.java +++ b/src/advclient/common/Receiver/Receiver.java @@ -73,6 +73,8 @@ public void doReceive(int sn, int[] sns, String fdstFolder, int amount, boolean logger.error(ltag, "Can't proceed. RAIDA is unavailable"); rr.status = ReceiverResult.STATUS_ERROR; rr.errText = AppCore.raidaErrText; + rr = new ReceiverResult(); + copyFromGlobalResult(rr); if (cb != null) cb.callback(rr); return; @@ -81,7 +83,9 @@ public void doReceive(int sn, int[] sns, String fdstFolder, int amount, boolean if (!pickCoinsAmountFromArray(sns, amount)) { logger.debug(ltag, "Not enough coins in the cloudfor amount " + amount); globalResult.status = ReceiverResult.STATUS_ERROR; - globalResult.errText = "Can't collect required amount"; + globalResult.errText = Config.PICK_ERROR_MSG; + rr = new ReceiverResult(); + copyFromGlobalResult(rr); if (cb != null) cb.callback(rr); return; @@ -93,6 +97,8 @@ public void doReceive(int sn, int[] sns, String fdstFolder, int amount, boolean logger.error(ltag, "NO ID Coin found for SN: " + sn); rr.status = ReceiverResult.STATUS_ERROR; rr.errText = "Failed to find coin ID"; + rr = new ReceiverResult(); + copyFromGlobalResult(rr); if (cb != null) cb.callback(rr); return; From 1e62d65f403e35846f0491892b2cb34ac9c36132 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Sun, 11 Aug 2019 16:18:48 +0300 Subject: [PATCH 017/160] Transfer Servant --- src/advclient/AdvancedClient.java | 147 +++++--- src/advclient/common/Transfer/Transfer.java | 324 ++++++++++++++++++ .../common/Transfer/TransferResponse.java | 16 + .../common/Transfer/TransferResult.java | 40 +++ src/advclient/common/core/ServantManager.java | 12 +- 5 files changed, 481 insertions(+), 58 deletions(-) create mode 100644 src/advclient/common/Transfer/Transfer.java create mode 100644 src/advclient/common/Transfer/TransferResponse.java create mode 100644 src/advclient/common/Transfer/TransferResult.java diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index ec84d26..07d0f7c 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -16,6 +16,7 @@ import global.cloudcoin.ccbank.ShowCoins.ShowCoinsResult; import global.cloudcoin.ccbank.ShowEnvelopeCoins.ShowEnvelopeCoins; import global.cloudcoin.ccbank.ShowEnvelopeCoins.ShowEnvelopeCoinsResult; +import global.cloudcoin.ccbank.Transfer.TransferResult; import global.cloudcoin.ccbank.Unpacker.UnpackerResult; import global.cloudcoin.ccbank.Vaulter.VaulterResult; import global.cloudcoin.ccbank.core.AppCore; @@ -197,7 +198,7 @@ else if (total < 999999999) } public String getPickError(Wallet w) { - String errText = "
" + String errText = "" + "Cannot make change

This version of software does not support making change
" + "You may only choose amounts that match your exact notes.
Please check to see if" + " there is a newer version of the software.
In the meantime, you may transfer amounts " @@ -239,13 +240,11 @@ public String getPickError(Wallet w) { counters[Config.IDX_FOLDER_VAULT][Config.IDX_250]; - errText += "1 CloudCoin Notes: " + t1 + "
"; - errText += "5 CloudCoin Notes: " + t5 + "
"; - errText += "25 CloudCoin Notes: " + t25 + "
"; - errText += "100 CloudCoin Notes: " + t100 + "
"; - errText += "250 CloudCoin Notes: " + t250 + "
"; - - errText += "
"; + errText += "1 CloudCoin Notes: " + t1 + "
"; + errText += "5 CloudCoin Notes: " + t5 + "
"; + errText += "25 CloudCoin Notes: " + t25 + "
"; + errText += "100 CloudCoin Notes: " + t100 + "
"; + errText += "250 CloudCoin Notes: " + t250 + "
"; return errText; } @@ -1559,6 +1558,25 @@ public void run(){ String dstName = (ps.foundSN == 0) ? ps.dstWallet.getName() : "" + ps.foundSN; + // Remote wallet + if (ps.srcWallet.isSkyWallet()) { + if ((ps.dstWallet == null && !ps.typedRemoteWallet.isEmpty()) || ps.dstWallet.isSkyWallet()) { + wl.debug(ltag, "Transfer requested"); + + int fromsn = ps.srcWallet.getIDCoin().sn; + int tosn; + if (ps.dstWallet != null) { + tosn = ps.dstWallet.getIDCoin().sn; + } else { + tosn = ps.foundSN; + } + + sm.startTransferService(fromsn, tosn, ps.srcWallet.getSNs(), ps.typedAmount, ps.typedMemo, new TransferCb()); + + return; + } + } + if (ps.isSkyDeposit) { wl.debug(ltag, "sky deposit"); if (ps.srcWallet.getIDCoin() == null) { @@ -3052,14 +3070,23 @@ public void actionPerformed(ActionEvent e) { return; } + /* if (ps.srcWallet.isSkyWallet()) { ps.errText = "Transfer from Sky Wallet to Remote Wallet is not supported"; showScreen(); return; } + */ + String dstName = remoteWalledId.getText().trim(); + if (ps.srcWallet.isSkyWallet() && ps.srcWallet.getName().equals(dstName)) { + ps.errText = "Src and Dst wallets cannot be the same"; + showScreen(); + return; + } + ps.dstWallet = null; - ps.typedRemoteWallet = remoteWalledId.getText(); + ps.typedRemoteWallet = dstName; ps.sendType = ProgramState.SEND_TYPE_REMOTE; DNSSn d = new DNSSn(ps.typedRemoteWallet, null, wl); @@ -3133,12 +3160,13 @@ public void actionPerformed(ActionEvent e) { ps.typedDstPassword = passwordDst.getText(); } - + /* if (srcWallet.isSkyWallet() && dstWallet.isSkyWallet()) { ps.errText = "Transfer from Sky Wallet to Sky Wallet is not supported"; showScreen(); return; } + */ if (dstWallet.isSkyWallet()) { if (ps.typedMemo.isEmpty()) { @@ -6746,69 +6774,74 @@ public void run() { showScreen(); return; } - - - - - + String name = null; if (ps.srcWallet != null) name = ps.srcWallet.getName(); wl.debug(ltag, "rramount " + rr.amount + " typed " + ps.typedAmount + " name=" + name); sm.startGraderService(new GraderCb(), null, name); - /* - if (ps.typedAmount != rr.amount) { - ps.typedAmount = rr.amount; - ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; - ps.errText = "Not all coins were received. Please check the logs"; - showScreen(); + } + } + + class TransferCb implements CallbackInterface { + public void callback(Object result) { + final TransferResult tr = (TransferResult) result; + + wl.debug(ltag, "Transfer finished: " + tr.status); + if (tr.status == TransferResult.STATUS_PROCESSING) { + setRAIDATransferProgressCoins(tr.totalRAIDAProcessed, tr.totalCoinsProcessed, tr.totalCoins); return; } - */ - - /* - ps.typedAmount = rr.amount; - - Wallet srcWallet = ps.srcWallet; - Wallet dstWallet = ps.dstWallet; + + if (tr.status == TransferResult.STATUS_CANCELLED) { + EventQueue.invokeLater(new Runnable() { + public void run() { + ps.errText = "Operation Cancelled"; + ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; + sm.resumeAll(); + showScreen(); + } + }); - srcWallet.appendTransaction(ps.typedMemo, rr.amount * -1, rr.receiptId); - if (dstWallet != null) { - if (srcWallet.isSkyWallet()) { - wl.debug(ltag, "Appending sky transactions"); - - Enumeration enumeration = ps.cenvelopes.keys(); - while (enumeration.hasMoreElements()) { - String key = enumeration.nextElement(); - String[] data = ps.cenvelopes.get(key); + return; + } - int total = 0; - try { - total = Integer.parseInt(data[1]); - } catch (NumberFormatException e) { + if (tr.status == ReceiverResult.STATUS_ERROR) { + EventQueue.invokeLater(new Runnable() { + public void run() { + ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; + if (!tr.errText.isEmpty()) { + if (tr.errText.equals(Config.PICK_ERROR_MSG)) { + /* + if (ps.triedToChange) { + ps.errText = "Failed to change coins"; + } else { + ps.changeFromExport = false; + ps.triedToChange = true; + ps.currentScreen = ProgramState.SCREEN_MAKING_CHANGE; + showScreen(); + return; + }*/ + ps.errText = getPickError(ps.srcWallet); + } else { + ps.errText = tr.errText; + } } - - ps.dstWallet.appendTransaction(data[0], total, rr.receiptId, data[2]); + else + ps.errText = "Error occurred. Please check the logs"; + + showScreen(); } - } else { - dstWallet.appendTransaction(ps.typedMemo, rr.amount, rr.receiptId); - } - - if (dstWallet.isEncrypted()) { - sm.changeServantUser("Vaulter", dstWallet.getName()); - sm.startVaulterService(new VaulterCb(), dstWallet.getPassword()); - } else { - ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; - showScreen(); - } + }); + return; } - + ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; showScreen(); - */ - } + } } + class optRv { int[] idxs; diff --git a/src/advclient/common/Transfer/Transfer.java b/src/advclient/common/Transfer/Transfer.java new file mode 100644 index 0000000..1978137 --- /dev/null +++ b/src/advclient/common/Transfer/Transfer.java @@ -0,0 +1,324 @@ +package global.cloudcoin.ccbank.Transfer; +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ + + +import global.cloudcoin.ccbank.core.AppCore; +import global.cloudcoin.ccbank.core.CallbackInterface; +import global.cloudcoin.ccbank.core.CloudCoin; +import global.cloudcoin.ccbank.core.CommonResponse; +import global.cloudcoin.ccbank.core.Config; +import global.cloudcoin.ccbank.core.GLogger; +import global.cloudcoin.ccbank.core.RAIDA; +import global.cloudcoin.ccbank.core.Servant; +import java.util.ArrayList; + +/** + * + * @author Александр + */ +public class Transfer extends Servant { + String ltag = "Transfer"; + TransferResult tr; + TransferResult globalResult; + + public Transfer(String rootDir, GLogger logger) { + super("Transfer", rootDir, logger); + } + + public void launch(int fromsn, int tosn, int[] sns, int amount, String tag, CallbackInterface icb) { + this.cb = icb; + + final int ffromsn = fromsn; + final int ftosn = tosn; + final int[] fsns = sns; + final int famount = amount; + final String ftag = tag; + + tr = new TransferResult(); + coinsPicked = new ArrayList(); + valuesPicked = new int[AppCore.getDenominations().length]; + globalResult = new TransferResult(); + + csb = new StringBuilder(); + launchThread(new Runnable() { + @Override + public void run() { + logger.info(ltag, "RUN Transfer"); + doTransfer(ffromsn, ftosn, fsns, ftag, famount); + } + }); + } + + private void copyFromGlobalResult(TransferResult trResult) { + trResult.totalFilesProcessed = globalResult.totalFilesProcessed; + trResult.totalRAIDAProcessed = globalResult.totalRAIDAProcessed; + trResult.totalCoins = globalResult.totalCoins; + trResult.totalCoinsProcessed = globalResult.totalCoinsProcessed; + trResult.totalFiles = globalResult.totalFiles; + trResult.status = globalResult.status; + trResult.amount = globalResult.amount; + trResult.errText = globalResult.errText; + } + + public void doTransfer(int fromsn, int tosn, int sns[], String tag, int amount) { + tr = new TransferResult(); + + if (!updateRAIDAStatus()) { + logger.error(ltag, "Can't proceed. RAIDA is unavailable"); + tr.status = TransferResult.STATUS_ERROR; + tr.errText = AppCore.raidaErrText; + copyFromGlobalResult(tr); + if (cb != null) + cb.callback(tr); + return; + } + + if (!pickCoinsAmountFromArray(sns, amount)) { + logger.debug(ltag, "Not enough coins in the cloudfor amount " + amount); + globalResult.status = TransferResult.STATUS_ERROR; + globalResult.errText = Config.PICK_ERROR_MSG; + copyFromGlobalResult(tr); + if (cb != null) + cb.callback(tr); + return; + } + + setSenderRAIDA(); + CloudCoin idcc = getIDcc(fromsn); + if (idcc == null) { + logger.error(ltag, "NO ID Coin found for SN: " + fromsn); + tr.status = TransferResult.STATUS_ERROR; + tr.errText = "Failed to find coin ID"; + copyFromGlobalResult(tr); + if (cb != null) + cb.callback(tr); + return; + } + + + ArrayList ccs; + ccs = new ArrayList(); + + int maxCoins = getIntConfigValue("max-coins-to-multi-detect"); + if (maxCoins == -1) + maxCoins = Config.DEFAULT_MAX_COINS_MULTIDETECT; + + logger.debug(ltag, "Maxcoins: " + maxCoins); + + globalResult.totalFiles = coinsPicked.size(); + globalResult.totalRAIDAProcessed = 0; + globalResult.totalFilesProcessed = 0; + globalResult.totalCoinsProcessed = 0; + + + copyFromGlobalResult(tr); + if (cb != null) + cb.callback(tr); + + + logger.info(ltag, "total files "+ globalResult.totalFiles); + + for (CloudCoin cc : coinsPicked) { + globalResult.totalCoins += cc.getDenomination(); + } + + int curValProcessed = 0; + for (CloudCoin cc : coinsPicked) { + logger.debug(ltag, "Transferring from SN " + fromsn + " to SN " + tosn); + if (isCancelled()) { + logger.info(ltag, "Cancelled"); + resume(); + tr = new TransferResult(); + globalResult.status = TransferResult.STATUS_CANCELLED; + copyFromGlobalResult(tr); + if (cb != null) + cb.callback(tr); + + return; + } + + ccs.add(cc); + curValProcessed += cc.getDenomination(); + if (ccs.size() == maxCoins) { + logger.info(ltag, "Processing"); + tr = new TransferResult(); + + if (!processTransfer(ccs, idcc, tag, tosn)) { + tr = new TransferResult(); + globalResult.status = TransferResult.STATUS_ERROR; + copyFromGlobalResult(tr); + if (cb != null) + cb.callback(tr); + + return; + } + + ccs.clear(); + + globalResult.totalRAIDAProcessed = 0; + globalResult.totalFilesProcessed += maxCoins; + globalResult.totalCoinsProcessed = curValProcessed; + + copyFromGlobalResult(tr); + if (cb != null) + cb.callback(tr); + } + } + + tr = new TransferResult(); + if (ccs.size() > 0) { + logger.info(ltag, "adding + " + ccs.size()); + if (!processTransfer(ccs, idcc, tag, tosn)) { + tr = new TransferResult(); + globalResult.status = TransferResult.STATUS_ERROR; + copyFromGlobalResult(tr); + if (cb != null) + cb.callback(tr); + } else { + globalResult.status = TransferResult.STATUS_FINISHED; + globalResult.totalFilesProcessed += ccs.size(); + } + } else { + globalResult.status = TransferResult.STATUS_FINISHED; + } + + copyFromGlobalResult(tr); + if (cb != null) + cb.callback(tr); + + } + + public boolean processTransfer(ArrayList ccs, CloudCoin cc, String tag, int tosn) { + String[] results; + Object[] o; + CommonResponse errorResponse; + TransferResponse[][] trs; + String[] requests; + StringBuilder[] sbs; + String[] posts; + int i; + CloudCoin[] sccs; + + sbs = new StringBuilder[RAIDA.TOTAL_RAIDA_COUNT]; + posts = new String[RAIDA.TOTAL_RAIDA_COUNT]; + requests = new String[RAIDA.TOTAL_RAIDA_COUNT]; + + for (i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { + requests[i] = "transfer"; + + sbs[i] = new StringBuilder(); + sbs[i].append("nn="); + sbs[i].append(cc.nn); + sbs[i].append("&sn="); + sbs[i].append(cc.sn); + sbs[i].append("&an="); + sbs[i].append(cc.ans[i]); + sbs[i].append("&pan="); + sbs[i].append(cc.ans[i]); + sbs[i].append("&denomination="); + sbs[i].append(cc.getDenomination()); + sbs[i].append("&to_sn="); + sbs[i].append(tosn); + sbs[i].append("&tag="); + sbs[i].append(tag); + + for (CloudCoin tcc : ccs) { + sbs[i].append("&sns[]="); + sbs[i].append(tcc.sn); + } + + posts[i] = sbs[i].toString(); + } + + results = raida.query(requests, posts, new CallbackInterface() { + final GLogger gl = logger; + final CallbackInterface myCb = cb; + + @Override + public void callback(Object result) { + globalResult.totalRAIDAProcessed++; + if (myCb != null) { + TransferResult trlocal = new TransferResult(); + copyFromGlobalResult(trlocal); + myCb.callback(trlocal); + } + } + }); + + if (results == null) { + logger.error(ltag, "Failed to query Transfer"); + return false; + } + + for (i = 0; i < results.length;i++) + System.out.println("i="+i+" r="+results[i]); + + sccs = new CloudCoin[ccs.size()]; + trs = new TransferResponse[RAIDA.TOTAL_RAIDA_COUNT][]; + for (i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { + logger.info(ltag, "i="+i+ " r="+results[i]); + if (results[i] != null) { + if (results[i].equals("")) { + logger.error(ltag, "Skipped raida" + i); + continue; + } + } + + o = parseArrayResponse(results[i], TransferResponse.class); + if (o == null) { + errorResponse = (CommonResponse) parseResponse(results[i], CommonResponse.class); + if (errorResponse == null) { + logger.error(ltag, "Failed to get error"); + continue; + } + + logger.error(ltag, "Failed to auth coin. Status: " + errorResponse.status); + continue; + } + + if (o.length != sccs.length) { + logger.error(ltag, "RAIDA " + i + " wrong number of coins: " + o.length); + continue; + } + + for (int j = 0; j < o.length; j++) { + String strStatus; + int rnn, rsn; + String ran; + boolean found; + + trs[i] = new TransferResponse[o.length]; + trs[i][j] = (TransferResponse) o[j]; + + strStatus = trs[i][j].status; + + found = false; + int cstatus; + if (strStatus.equals(Config.REQUEST_STATUS_PASS)) { + logger.info(ltag, "OK response from raida " + i); + cstatus = CloudCoin.STATUS_PASS; + } else if (strStatus.equals(Config.REQUEST_STATUS_FAIL)) { + logger.error(ltag, "Counterfeit response from raida " + i); + cstatus = CloudCoin.STATUS_FAIL; + } else { + logger.error(ltag, "Unknown coin status from RAIDA" + i + ": " + strStatus); + cstatus = CloudCoin.STATUS_ERROR; + } + + + } + } + + + + + logger.info(ltag, "Transferred"); + + return true; + } + +} diff --git a/src/advclient/common/Transfer/TransferResponse.java b/src/advclient/common/Transfer/TransferResponse.java new file mode 100644 index 0000000..4ce94cd --- /dev/null +++ b/src/advclient/common/Transfer/TransferResponse.java @@ -0,0 +1,16 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package global.cloudcoin.ccbank.Transfer; + +import global.cloudcoin.ccbank.core.CommonResponse; + +/** + * + * @author Александр + */ +public class TransferResponse extends CommonResponse { + +} diff --git a/src/advclient/common/Transfer/TransferResult.java b/src/advclient/common/Transfer/TransferResult.java new file mode 100644 index 0000000..c333f2e --- /dev/null +++ b/src/advclient/common/Transfer/TransferResult.java @@ -0,0 +1,40 @@ +/* + * To change this license header, choose License Headers in Project Properties. + * To change this template file, choose Tools | Templates + * and open the template in the editor. + */ +package global.cloudcoin.ccbank.Transfer; + +/** + * + * @author Александр + */ +public class TransferResult { + public int totalFilesProcessed; + public int totalFiles; + public int totalRAIDAProcessed; + + public int totalCoins; + public int totalCoinsProcessed; + + public static int STATUS_PROCESSING = 1; + public static int STATUS_FINISHED = 2; + public static int STATUS_ERROR = 3; + public static int STATUS_CANCELLED = 4; + + public int status; + + public int amount; + public String memo; + + public String errText; + + public TransferResult() { + memo = "Send"; + amount = 0; + totalFilesProcessed = totalRAIDAProcessed = 0; + totalFiles = 0; + status = STATUS_PROCESSING; + errText = ""; + } +} diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index 4aa92aa..63a0087 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -22,6 +22,8 @@ import global.cloudcoin.ccbank.Receiver.ReceiverResult; import global.cloudcoin.ccbank.Sender.Sender; import global.cloudcoin.ccbank.Sender.SenderResult; +import global.cloudcoin.ccbank.Transfer.Transfer; +import global.cloudcoin.ccbank.Transfer.TransferResult; import global.cloudcoin.ccbank.ShowCoins.ShowCoins; import global.cloudcoin.ccbank.ShowEnvelopeCoins.ShowEnvelopeCoins; import global.cloudcoin.ccbank.ShowEnvelopeCoins.ShowEnvelopeCoinsResult; @@ -143,7 +145,8 @@ public boolean initServants() { "Vaulter", "ShowEnvelopeCoins", "Eraser", - "Backupper" + "Backupper", + "Transfer" }, AppCore.getRootPath() + File.separator + user, logger); @@ -373,6 +376,13 @@ public void startSenderServiceForChange(int sn, int[] values, String memo, Callb s.launch(sn, null, values, 0, memo, Config.CHANGE_SKY_DOMAIN, cb); } + public void startTransferService(int fromsn, int tosn, int sns[], int amount, String tag, CallbackInterface cb) { + logger.debug(ltag, "Transfer from " + fromsn + " to " + tosn + " amount " + amount); + System.out.println("Transfer from " + fromsn + " to " + tosn + " amount " + amount); + Transfer tr = (Transfer) sr.getServant("Transfer"); + tr.launch(fromsn, tosn, sns, amount, tag, cb); + } + public int getRemoteSn(String dstWallet) { int sn; From 00f1758befbd6479378daf0d1dbd0bf2a2671d58 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 12 Aug 2019 07:38:34 +0300 Subject: [PATCH 018/160] export button --- src/advclient/AdvancedClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 07d0f7c..81443b9 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -4955,7 +4955,7 @@ public void mouseExited(MouseEvent e) { GridBagLayout gridbag = new GridBagLayout(); subInnerCore.setLayout(gridbag); - AppUI.getTwoButtonPanel(subInnerCore, "Print", "Export", new ActionListener() { + AppUI.getTwoButtonPanel(subInnerCore, "Print", "Export History", new ActionListener() { public void actionPerformed(ActionEvent e) { try { table.print(); From 6f34041e95007c8c8660aa4f093021cba3c36bbc Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 12 Aug 2019 12:54:21 +0300 Subject: [PATCH 019/160] disable double click --- src/advclient/AdvancedClient.java | 2 +- src/advclient/MyButton.java | 18 +++++++++++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 81443b9..a3b60d1 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -56,7 +56,7 @@ * */ public class AdvancedClient { - String version = "2.1.9"; + String version = "2.1.10"; JPanel headerPanel; JPanel mainPanel; diff --git a/src/advclient/MyButton.java b/src/advclient/MyButton.java index 638f911..993b089 100644 --- a/src/advclient/MyButton.java +++ b/src/advclient/MyButton.java @@ -9,6 +9,7 @@ import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; +import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemListener; import javax.swing.JButton; @@ -26,16 +27,23 @@ public class MyButton { JPanel core; JButton button; Color color; + boolean lastActionAdded; public MyButton(String text) { this.color = AppUI.getColor2(); core = makeUI(text); + this.lastActionAdded = false; + if (!text.toLowerCase().equals("continue")) + this.lastActionAdded = true; + } public MyButton(String text, Color color) { this.color = color; core = makeUI(text); - + this.lastActionAdded = false; + if (!text.toLowerCase().equals("continue")) + this.lastActionAdded = true; } public JPanel getButton() { @@ -44,6 +52,14 @@ public JPanel getButton() { public void addListener(ActionListener a) { button.addActionListener(a); + if (!this.lastActionAdded) { + this.lastActionAdded = true; + addListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + disable(); + } + }); + } } public void disable() { From cd8a26c95338b0d3a34be6fbce3c3d543c47df74 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 12 Aug 2019 12:57:02 +0300 Subject: [PATCH 020/160] html removal --- src/advclient/AdvancedClient.java | 141 ++---------------------------- 1 file changed, 6 insertions(+), 135 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index a3b60d1..500e883 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -1363,7 +1363,7 @@ public void actionPerformed(ActionEvent e) { final int skySN = getSkyWalletSN(); if (skySN == 0) { ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; - ps.errText = "
Transaction cannot be completed. You must have the exact denominations of CloudCoin notes or use the Change Maker. You must have at least one Sky Wallet created to access the Change Maker
"; + ps.errText = "Transaction cannot be completed. You must have the exact denominations of CloudCoin notes or use the Change Maker. You must have at least one Sky Wallet created to access the Change Maker"; showScreen(); return; } @@ -1546,9 +1546,9 @@ public void run(){ } if (!sm.isRAIDAOK()) { - ps.errText = "
RAIDA cannot be contacted. " + ps.errText = "RAIDA cannot be contacted. " + "This is usually caused by company routers blocking outgoing traffic. " - + "Please Echo RAIDA and try again.
"; + + "Please Echo RAIDA and try again."; ps.isEchoFinished = false; ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; showScreen(); @@ -1669,9 +1669,9 @@ public void run(){ } if (!sm.isRAIDAOK()) { - ps.errText = "
RAIDA cannot be contacted. " + ps.errText = "RAIDA cannot be contacted. " + "This is usually caused by company routers blocking outgoing traffic. " - + "Please Echo RAIDA and try again.
"; + + "Please Echo RAIDA and try again."; ps.isEchoFinished = false; ps.currentScreen = ProgramState.SCREEN_IMPORT_DONE; showScreen(); @@ -3843,139 +3843,10 @@ public void mouseReleased(MouseEvent e) { scrollPane.getViewport().setViewPosition(new java.awt.Point(0, 100)); scrollPane.repaint(); } - }); - + }); gridbag.setConstraints(l, c); subInnerCore.add(l); - - - - if (1==1) - return; - - /* - - AppUI.GBPad(subInnerCore, y, gridbag); - y++; - - AppUI.getTwoButtonPanel(subInnerCore, "", "Continue", null, new ActionListener() { - public void actionPerformed(ActionEvent e) { - ps.currentScreen = ProgramState.SCREEN_DEFAULT; - showScreen(); - } - }, y, gridbag); - - - - l = new JLabel("
" - + "(Secure if you get a free encrypted email account at ProtonMail.com)
"); - - AppUI.setMargin(l, 0); - AppUI.setFont(l, 12); - AppUI.alignCenter(l); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - AppUI.setCommonFont(l); - gridbag.setConstraints(l, c); - gct.add(l); - - y++; - - // Get proton - l = AppUI.getHyperLink("Get Protonmail", "https://www.protonmail.com", 14); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - gridbag.setConstraints(l, c); - gct.add(l); - - y++; - - // Get proton - l = AppUI.getHyperLink("Instructions, Terms and Conditions", "javascript:void(0); return false", 20); - l.addMouseListener(new MouseAdapter() { - public void mouseReleased(MouseEvent e) { - final JDialog f = new JDialog(mainFrame, "Instructions, Terms and Conditions", true); - f.setModalityType(Dialog.ModalityType.APPLICATION_MODAL); - AppUI.noOpaque((JComponent) f.getContentPane()); - AppUI.setSize(f, (int) (tw / 1.2), (int) (th / 1.2)); - - JTextPane tp = new JTextPane(); - - - AppUI.setFont(tp, 12); - String fontfamily = tp.getFont().getFamily(); - - tp.setContentType("text/html"); - tp.setText("
" + AppUI.getAgreementText() + "
"); - tp.setEditable(false); - tp.setBackground(null); - tp.setCaretPosition(0); - - JScrollPane scrollPane = new JScrollPane(tp); - - f.add(scrollPane); - f.pack(); - f.setLocationRelativeTo(mainFrame); - f.setVisible(true); - - scrollPane.getVerticalScrollBar().setValue(scrollPane.getVerticalScrollBar().getMinimum()); - scrollPane.getViewport().setViewPosition(new java.awt.Point(0, 100)); - scrollPane.repaint(); - } - }); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.insets = new Insets(40, 0, 4, 0); - gridbag.setConstraints(l, c); - gct.add(l); - - y++; - - // Support Portal - vl = new JLabel("Support Portal"); - AppUI.setCommonFont(vl); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.insets = new Insets(40, 0, 4, 0); - gridbag.setConstraints(vl, c); - gct.add(vl); - y++; - - - urlName = "https://cloudcoinsupport.atlassian.net/servicedesk/customer/portals"; - l = AppUI.getHyperLink(urlName, urlName, 14); - c.gridx = GridBagConstraints.RELATIVE; - c.gridy = y; - c.insets = new Insets(4, 0, 4, 0); - gridbag.setConstraints(l, c); - gct.add(l); - - y++; - - - - https://cloudcoinsupport.atlassian.net/servicedesk/customer/portals - - - - - - - - - - - - - ct.add(gct); - - - - //rightPanel - - */ - } public void showClearScreen() { From 569234158972428439f02ae2d94d35bc2475c0ff Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 12 Aug 2019 13:24:58 +0300 Subject: [PATCH 021/160] printing colors --- src/advclient/AdvancedClient.java | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 500e883..c6d1c42 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -4421,9 +4421,16 @@ public void showListSerialsDone() { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + Color c = AppUI.getColor6(); + Color fgc = AppUI.getColor5(); + if (table.isPaintingForPrint()) { + c = AppUI.getColor5(); + fgc = Color.BLACK; + } + lbl = (JLabel) this; - AppUI.setBackground(lbl, AppUI.getColor6()); - AppUI.setColor(lbl, AppUI.getColor5()); + AppUI.setBackground(lbl, c); + AppUI.setColor(lbl, fgc); lbl.setHorizontalAlignment(JLabel.LEFT); AppUI.setMargin(lbl, 8); @@ -4673,10 +4680,17 @@ public void showTransactionsScreen() { public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + Color c = AppUI.getColor6(); + Color fgc = AppUI.getColor5(); + if (table.isPaintingForPrint()) { + c = AppUI.getColor5(); + fgc = Color.BLACK; + } + JPanel cell = new JPanel(); AppUI.setBoxLayout(cell, false); //AppUI.noOpaque(cell); - AppUI.setBackground(cell, AppUI.getColor6()); + AppUI.setBackground(cell, c); AppUI.setMargin(cell, 0, 20, 0, 0); lbl = (JLabel) this; @@ -4685,7 +4699,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole String html = AppCore.getReceiptHtml(hash, sm.getActiveWallet().getName()); if (html != null) { - AppUI.setColor(lbl, AppUI.getColor5()); + AppUI.setColor(lbl, fgc); AppUI.underLine(lbl); } } if (column == 2) { @@ -4693,14 +4707,13 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole } else if (column == 3) { AppUI.setColor(lbl, AppUI.getColor12()); } else { - //AppUI.setColor(lbl, Color.BLACK); - AppUI.setColor(lbl, AppUI.getColor5()); + AppUI.setColor(lbl, fgc); } if (row % 2 == 0) { - AppUI.setBackground(lbl, AppUI.getColor6()); + AppUI.setBackground(lbl, c); } else { - AppUI.setBackground(lbl, AppUI.getColor6()); + AppUI.setBackground(lbl, c); } if (column == 0) { From f688e82683ab358e83730bc074fc0d868adc49f2 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Tue, 13 Aug 2019 10:44:13 +0300 Subject: [PATCH 022/160] memo --- src/advclient/AdvancedClient.java | 57 +++++++++++++------------------ 1 file changed, 24 insertions(+), 33 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index c6d1c42..4136956 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -2934,14 +2934,20 @@ public void actionPerformed(ActionEvent e) { if (dstIdx < 0 || dstIdx >= rvTo.idxs.length) return; - - - dstIdx = rvTo.idxs[dstIdx]; - + + dstIdx = rvTo.idxs[dstIdx]; Wallet dstWallet = wallets[dstIdx]; if (dstWallet == null) return; + if (dstWallet.isSkyWallet()) { + memo.setPlaceholder("From John Doe for May rent"); + } else { + memo.setPlaceholder("Optional"); + } + + + if (dstWallet.isEncrypted()) { passwordDst.getTextField().setVisible(true); dpText.setVisible(true); @@ -3015,21 +3021,14 @@ public void actionPerformed(ActionEvent e) { return; } - if (dstIdx == rvTo.idxs.length) { - if (ps.typedMemo.isEmpty()) { - ps.errText = "Memo cannot be empty"; + ps.typedMemo = ps.typedMemo.trim(); + if (!ps.typedMemo.isEmpty()) { + if (!Validator.memo(ps.typedMemo)) { + ps.errText = "Memo: Non alpha number characters are not allowed"; showScreen(); - return; + return; } } - - if (!Validator.memo(ps.typedMemo)) { - ps.errText = "Memo: Non alpha number characters are not allowed"; - showScreen(); - return; - } - - ps.typedMemo = ps.typedMemo.trim(); if (srcWallet.isEncrypted()) { if (passwordSrc.getText().isEmpty()) { @@ -3069,14 +3068,6 @@ public void actionPerformed(ActionEvent e) { showScreen(); return; } - - /* - if (ps.srcWallet.isSkyWallet()) { - ps.errText = "Transfer from Sky Wallet to Remote Wallet is not supported"; - showScreen(); - return; - } - */ String dstName = remoteWalledId.getText().trim(); if (ps.srcWallet.isSkyWallet() && ps.srcWallet.getName().equals(dstName)) { @@ -3084,7 +3075,14 @@ public void actionPerformed(ActionEvent e) { showScreen(); return; } - + + if (ps.typedMemo.isEmpty()) { + ps.errText = "Memo cannot be empty"; + showScreen(); + return; + } + + ps.dstWallet = null; ps.typedRemoteWallet = dstName; ps.sendType = ProgramState.SEND_TYPE_REMOTE; @@ -3160,14 +3158,7 @@ public void actionPerformed(ActionEvent e) { ps.typedDstPassword = passwordDst.getText(); } - /* - if (srcWallet.isSkyWallet() && dstWallet.isSkyWallet()) { - ps.errText = "Transfer from Sky Wallet to Sky Wallet is not supported"; - showScreen(); - return; - } - */ - + if (dstWallet.isSkyWallet()) { if (ps.typedMemo.isEmpty()) { ps.errText = "Memo must not be empty"; From 616e785bafc30078f3b3ecdcbdc68e7fbebdf32c Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Tue, 13 Aug 2019 12:59:07 +0300 Subject: [PATCH 023/160] default wallet --- src/advclient/AdvancedClient.java | 97 +++++++------------ src/advclient/ProgramState.java | 12 +-- src/advclient/common/Transfer/Transfer.java | 3 - src/advclient/common/core/AppCore.java | 76 ++++----------- src/advclient/common/core/Config.java | 2 +- src/advclient/common/core/Servant.java | 8 +- src/advclient/common/core/ServantManager.java | 59 ++++++----- src/advclient/common/core/Wallet.java | 31 ++---- 8 files changed, 95 insertions(+), 193 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 4136956..cd7734b 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -297,7 +297,7 @@ public synchronized void showCoinsGoNext() { sm.changeServantUser("ShowCoins", wallets[ps.currentWalletIdx].getName()); sm.startShowCoinsService(new ShowCoinsCb()); } else { - sm.changeServantUser("ShowEnvelopeCoins", wallets[ps.currentWalletIdx].getParent().getName()); + sm.changeServantUser("ShowEnvelopeCoins", Config.DIR_DEFAULT_USER); sm.startShowSkyCoinsService(new ShowEnvelopeCoinsCb(), wallets[ps.currentWalletIdx].getIDCoin().sn); } ps.currentWalletIdx++; @@ -321,11 +321,7 @@ public void initSystemUser() { ps.errText = "Failed to init Wallet"; return; } - - if (ps.isDefaultWalletBeingCreated) { - AppCore.setDefaultWallet(ps.typedWalletName); - } - + //AppCore.copyTemplatesFromJar(ps.typedWalletName); } @@ -620,17 +616,11 @@ public void fillHeaderPanel() { MouseAdapter ma0 = new MouseAdapter() { public void mouseReleased(MouseEvent e) { - if (!ps.defaultWalletCreated) - return; - resetState(); ps.currentScreen = ProgramState.SCREEN_PREDEPOSIT; showScreen(); } public void mouseEntered(MouseEvent e) { - if (!ps.defaultWalletCreated) - return; - JPanel p = (JPanel) e.getSource(); AppUI.opaque(p); depositIcon.setIcon(depositIiLight); @@ -638,10 +628,7 @@ public void mouseEntered(MouseEvent e) { p.repaint(); } - public void mouseExited(MouseEvent e) { - if (!ps.defaultWalletCreated) - return; - + public void mouseExited(MouseEvent e) { JPanel p = (JPanel) e.getSource(); if (!isDepositing()) { AppUI.noOpaque(p); @@ -654,28 +641,19 @@ public void mouseExited(MouseEvent e) { MouseAdapter ma1 = new MouseAdapter() { public void mouseReleased(MouseEvent e) { - if (!ps.defaultWalletCreated) - return; - resetState(); ps.currentScreen = ProgramState.SCREEN_WITHDRAW; showScreen(); } - public void mouseEntered(MouseEvent e) { - if (!ps.defaultWalletCreated) - return; - + public void mouseEntered(MouseEvent e) { JPanel p = (JPanel) e.getSource(); AppUI.opaque(p); transferIcon.setIcon(transferIiLight); p.revalidate(); p.repaint(); } - public void mouseExited(MouseEvent e) { - if (!ps.defaultWalletCreated) - return; - + public void mouseExited(MouseEvent e) { JPanel p = (JPanel) e.getSource(); if (!isWithdrawing()) { AppUI.noOpaque(p); @@ -696,8 +674,7 @@ public void mouseExited(MouseEvent e) { c.fill = GridBagConstraints.NORTH; // Icon Gear - if (ps.defaultWalletCreated) - AppUI.setHandCursor(icon0); + AppUI.setHandCursor(icon0); gridbag.setConstraints(icon0, c); AppUI.setSize(icon0, 52, 72); @@ -791,8 +768,7 @@ public void paint (final Graphics g, final JComponent c) { AppUI.setMargin(popupMenu, 0); AppUI.noOpaque(popupMenu); - if (!ps.defaultWalletCreated) - AppUI.setHandCursor(popupMenu); + AppUI.setHandCursor(popupMenu); popupMenu.addPopupMenuListener(new PopupMenuListener() { @Override @@ -816,8 +792,6 @@ public void popupMenuCanceled(final PopupMenuEvent e) { icon0.addMouseListener(new MouseAdapter() { public void mouseReleased(MouseEvent e) { - if (!ps.defaultWalletCreated) - return; ficon.setOpaque(true); AppUI.setBackground(ficon, AppUI.getColor1()); @@ -862,17 +836,8 @@ public void resetState() { return; if (sm.getWallets().length != 0) { - ps.defaultWalletCreated = true; - ps.defaultWalletName = AppCore.getDefaultWalletName(); ps.currentScreen = ProgramState.SCREEN_DEFAULT; - if (ps.defaultWalletName == null) { - wl.error(ltag, "Failed to determine default wallet"); - System.err.println("Failed to determine default wallet. The folders are corrupted"); - System.exit(1); - } - } else { - ps.defaultWalletCreated = false; - } + } } public void showScreen() { @@ -1683,11 +1648,7 @@ public void run(){ pbarText.setText("Moving coins ..."); for (String filename : ps.files) { - String name; - if (sm.getActiveWallet().isSkyWallet()) - name = sm.getActiveWallet().getParent().getName(); - else - name = sm.getActiveWallet().getName(); + String name = sm.getActiveWallet().getName(); AppCore.moveToFolder(filename, Config.DIR_IMPORT, name); } @@ -2111,6 +2072,7 @@ public void showConfirmDeleteWalletScreen() { String txt; txt = "Are you sure you want to delete Wallet " + ps.srcWallet.getName() + " ?"; + final Wallet dstWallet = sm.getFirstNonSkyWallet(); if (ps.srcWallet.isSkyWallet()) { txt += "

Your ID coin will be put back into your Bank. You will not be able to receive Coins at this address again"; } @@ -2119,7 +2081,6 @@ public void showConfirmDeleteWalletScreen() { AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); y++; - final Wallet dstWallet = sm.getWalletByName(AppCore.getDefaultWalletName()); MyTextField tf0 = null; if (dstWallet.isEncrypted() && ps.srcWallet.isSkyWallet()) { fname = new JLabel("Password"); @@ -2415,7 +2376,6 @@ public void actionPerformed(ActionEvent e) { ps.typedEmail = p0; ps.currentScreen = ProgramState.SCREEN_WALLET_CREATED; - ps.defaultWalletCreated = true; initSystemUser(); @@ -2785,6 +2745,7 @@ public void showTransferScreen() { final optRv rvFrom = setOptionsForWalletsCommon(false, false, true); if (rvFrom.idxs.length == 0) { + ps.errText = "No Wallets to Transfer From"; return; } @@ -3191,6 +3152,12 @@ public void showPredepositScreen() { GridBagLayout gridbag = new GridBagLayout(); subInnerCore.setLayout(gridbag); + if (sm.getFirstNonSkyWallet() == null) { + ps.errText = "You have no Local Wallets"; + return; + } + + fname = new JLabel("Deposit From"); int cnt = 0, scnt = 0; for (int i = 0; i < wallets.length; i++) { @@ -3573,6 +3540,12 @@ public void actionPerformed(ActionEvent e) { showScreen(); return; } + + if (w.isSkyWallet()) { + ps.errText = "The program cannot deposit to Sky Wallets. Use Transfer Screen"; + showScreen(); + return; + } if (w.isEncrypted()) { if (password.getText().isEmpty()) { @@ -4113,7 +4086,7 @@ public optRv setOptionsForWalletsCommon(boolean checkFracked, boolean needEmpty, continue; if (wallets[i].getTotal() == 0) { - if (needEmpty && !wallets[i].isDefaultWallet()) + if (needEmpty) cnt++; continue; @@ -4149,8 +4122,6 @@ public optRv setOptionsForWalletsCommon(boolean checkFracked, boolean needEmpty, if (wallets[i].getTotal() == 0) { if (!needEmpty) continue; - else if (wallets[i].isDefaultWallet()) - continue; } else { if (needEmpty) continue; @@ -4229,6 +4200,15 @@ public void actionPerformed(ActionEvent e) { srcIdx = rv.idxs[srcIdx]; Wallet srcWallet = wallets[srcIdx]; + if (srcWallet.isSkyWallet()) { + Wallet dstWallet = sm.getFirstNonSkyWallet(); + if (dstWallet == null) { + ps.errText = "You cannot delete a Sky Wallet because you do not have a Local Wallet"; + showScreen(); + return; + } + } + ps.srcWallet = srcWallet; ps.currentScreen = ProgramState.SCREEN_CONFIRM_DELETE_WALLET; @@ -4937,7 +4917,6 @@ public void showPrepareToAddWalletScreen() { MouseAdapter ma = new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { - ps.isDefaultWalletBeingCreated = false; ps.currentScreen = ProgramState.SCREEN_CREATE_WALLET; showScreen(); } @@ -4987,7 +4966,6 @@ public void mouseExited(MouseEvent e) { ma = new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { - ps.isDefaultWalletBeingCreated = false; ps.currentScreen = ProgramState.SCREEN_CREATE_SKY_WALLET; showScreen(); } @@ -5163,7 +5141,7 @@ public void run(){ return; } - if (!AppCore.moveToFolderNewName(ps.chosenFile, Config.DIR_ID, ps.defaultWalletName, newFileName)) { + if (!AppCore.moveToFolderNewName(ps.chosenFile, AppCore.getIDDir(), null, newFileName)) { ps.errText = "Failed to move ID Coin to the Default Wallet"; showScreen(); return; @@ -5194,7 +5172,7 @@ public void run(){ } } - if (!AppCore.moveToFolderNewName(ps.chosenFile, Config.DIR_ID, ps.defaultWalletName, newFileName)) { + if (!AppCore.moveToFolderNewName(ps.chosenFile, AppCore.getIDDir(), null, newFileName)) { ps.errText = "Failed to move coin"; showScreen(); return; @@ -5271,7 +5249,6 @@ public void actionPerformed(ActionEvent e) { initSystemUser(); ps.currentScreen = ProgramState.SCREEN_WALLET_CREATED; - ps.defaultWalletCreated = true; showScreen(); } }, y, gridbag); @@ -5433,8 +5410,7 @@ public void showLeftScreen() { wpanel.add(AppUI.hr(10)); // "Add Sky Wallet" Button - if (ps.defaultWalletCreated) - wpanel.add(getWallet(null, TYPE_ADD_SKY)); + wpanel.add(getWallet(null, TYPE_ADD_SKY)); // Padding from the bottom @@ -5752,7 +5728,6 @@ public void itemStateChanged(ItemEvent e) { button.addListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ps.currentScreen = ProgramState.SCREEN_CREATE_WALLET; - ps.isDefaultWalletBeingCreated = true; showScreen(); } }); diff --git a/src/advclient/ProgramState.java b/src/advclient/ProgramState.java index 4239526..189a7a6 100644 --- a/src/advclient/ProgramState.java +++ b/src/advclient/ProgramState.java @@ -82,7 +82,6 @@ public class ProgramState { int[][] counters; int cbState; - boolean isDefaultWalletBeingCreated; boolean isAddingWallet; ArrayList files; @@ -124,11 +123,7 @@ public class ProgramState { String trustedServer; boolean isSkyDeposit; - - boolean defaultWalletCreated; - - String defaultWalletName; - + boolean isCreatingNewSkyWallet; String skyVaultDomain; @@ -165,7 +160,6 @@ public ProgramState() { statToBankValue = statToBank = statFailed = 0; statFailedValue = statLostValue = 0; - isDefaultWalletBeingCreated = false; isAddingWallet = false; receiptId = ""; @@ -192,10 +186,6 @@ public ProgramState() { trustedServer = ""; isSkyDeposit = false; - - defaultWalletCreated = false; - - defaultWalletName = null; isCreatingNewSkyWallet = false; diff --git a/src/advclient/common/Transfer/Transfer.java b/src/advclient/common/Transfer/Transfer.java index 1978137..c9c0287 100644 --- a/src/advclient/common/Transfer/Transfer.java +++ b/src/advclient/common/Transfer/Transfer.java @@ -254,9 +254,6 @@ public void callback(Object result) { return false; } - for (i = 0; i < results.length;i++) - System.out.println("i="+i+" r="+results[i]); - sccs = new CloudCoin[ccs.size()]; trs = new TransferResponse[RAIDA.TOTAL_RAIDA_COUNT][]; for (i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index 9890a49..419ac81 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -91,6 +91,9 @@ static public boolean initFolders(File path, GLogger logger) throws Exception { if (!createDirectory(Config.DIR_ACCOUNTS)) return false; + if (!createDirectory(Config.DIR_ID)) + return false; + if (!createDirectory(Config.DIR_MAIN_LOGS)) return false; @@ -114,7 +117,6 @@ static public void initUserFolders(String user) throws Exception { Config.DIR_EMAILOUT, Config.DIR_FRACKED, Config.DIR_GALLERY, - Config.DIR_ID, Config.DIR_IMPORT, Config.DIR_IMPORTED, Config.DIR_LOGS, @@ -161,6 +163,12 @@ static public String getBackupDir() { return f.toString(); } + static public String getIDDir() { + File f = new File(rootPath, Config.DIR_ID); + + return f.toString(); + } + static public String getMainTrashDir() { File f = new File(rootPath, Config.DIR_MAIN_TRASH); @@ -241,7 +249,12 @@ static public boolean moveToFolderNewName(String fileName, String folder, String try { File fsource = new File(fileName); - String target = AppCore.getUserDir(folder, user) + File.separator + newFileName; + String target; + if (user != null) + target = AppCore.getUserDir(folder, user) + File.separator + newFileName; + else + target = folder + File.separator + newFileName; + File ftarget = new File(target); if (!fsource.renameTo(ftarget)) { logger.error(ltag, "Failed to rename file " + fileName + " to " + ftarget.getAbsolutePath()); @@ -581,7 +594,11 @@ public static int charCount(String pown, char character) { } public static String[] getFilesInDir(String dir, String user) { - String path = AppCore.getUserDir(dir, user); + String path; + if (user != null) + path = AppCore.getUserDir(dir, user); + else + path = dir; String[] rv; int c = 0; @@ -871,59 +888,6 @@ static public boolean moveFolderToTrash(String folder) { return true; } - public static String getDefaultWalletName() { - String wname, dname; - - wname = null; - - File dirObj = new File(rootPath + File.separator + Config.DIR_ACCOUNTS); - for (File file: dirObj.listFiles()) { - if (!file.isDirectory()) - continue; - - dname = file.getAbsolutePath() + File.separator + Config.DEFAULT_DIR_MARKER; - File f = new File(dname); - if (f.exists()) { - if (wname != null) { - logger.error(ltag, "Duplicated default wallets " + wname + " and " + f.getName()); - return null; - } - - wname = file.getName(); - } - } - - if (wname == null) { - logger.debug(ltag, "Falling back to the default dir"); - wname = Config.DIR_DEFAULT_USER; - } - - return wname; - } - - public static boolean setDefaultWallet(String walletName) { - File dirObj = new File(rootPath + File.separator + - Config.DIR_ACCOUNTS + File.separator + walletName); - - String fileMarker = dirObj.getAbsolutePath() + File.separator + Config.DEFAULT_DIR_MARKER; - - File f = new File(fileMarker); - - try { - if (!f.createNewFile()) { - logger.error(ltag, "Failed to create tag file: " + fileMarker); - return false; - } - } catch (IOException e) { - logger.error(ltag, "Failed to create tag file: " + fileMarker + " ex " + e.getMessage()); - return false; - } - - return true; - - } - - public static int maxCoinsWorkAround(int maxCoins) { String javaVersion = System.getProperty("java.version"); diff --git a/src/advclient/common/core/Config.java b/src/advclient/common/core/Config.java index 6f4606e..34a1294 100644 --- a/src/advclient/common/core/Config.java +++ b/src/advclient/common/core/Config.java @@ -35,7 +35,7 @@ public class Config { public static String DIR_ACCOUNTS = "Accounts"; - public static String DIR_DEFAULT_USER = "Default Wallet"; + public static String DIR_DEFAULT_USER = "Default_User_NonExist"; public static String DIR_MAIN_LOGS = "Logs"; public static String DIR_MAIN_TRASH = "Trash"; public static String DIR_BACKUPS = "Backups"; diff --git a/src/advclient/common/core/Servant.java b/src/advclient/common/core/Servant.java index ffb9a0e..da89fa5 100644 --- a/src/advclient/common/core/Servant.java +++ b/src/advclient/common/core/Servant.java @@ -494,13 +494,7 @@ protected void cleanPrivateLogDir() { } protected CloudCoin getIDcc(int sn) { - String defaultWalletName = AppCore.getDefaultWalletName(); - if (defaultWalletName == null) { - logger.error(ltag, "Can't find default wallet"); - return null; - } - - String fullDirIDPath = AppCore.getUserDir(Config.DIR_ID, defaultWalletName); + String fullDirIDPath = AppCore.getIDDir(); CloudCoin cc = null; File dirObj = new File(fullDirIDPath); diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index 63a0087..8b67458 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -89,7 +89,7 @@ public void setActiveWalletObj(Wallet wallet) { logger.debug(ltag, "Set active wallet obj " + wallet.getName() + " isky " + wallet.isSkyWallet()); this.user = wallet.getName(); if (wallet.isSkyWallet()) { - sr.changeUser(wallet.getParent().getName()); + sr.changeUser(Config.DIR_DEFAULT_USER); } else { sr.changeUser(this.user); } @@ -163,18 +163,20 @@ public void initWallets() { setActiveWallet(wallets[i]); initWallet(wallets[i], ""); - checkIDCoins(wallets[i]); + } + + checkIDCoins(); } - public void checkIDCoins(String root) { - String[] idCoins = AppCore.getFilesInDir(Config.DIR_ID, root); + public void checkIDCoins() { + String[] idCoins = AppCore.getFilesInDir(AppCore.getIDDir(), null); for (int i = 0; i < idCoins.length; i++) { CloudCoin cc; try { - cc = new CloudCoin(AppCore.getUserDir(Config.DIR_ID, root) + File.separator + idCoins[i]); + cc = new CloudCoin(AppCore.getIDDir() + File.separator + idCoins[i]); } catch (JSONException e) { logger.error(ltag, "Failed to parse ID coin: " + idCoins[i] + " error: " + e.getMessage()); continue; @@ -183,18 +185,13 @@ public void checkIDCoins(String root) { String wname = idCoins[i].substring(0, idCoins[i].lastIndexOf('.')); wname += "." + Config.DDNS_DOMAIN; - initCloudWallet(root, cc, wname); + initCloudWallet(cc, wname); } } - public void initCloudWallet(String wallet, CloudCoin cc, String name) { - Wallet parent = wallets.get(wallet); - - //String name = wallet + ":" + cc.sn; - - //Wallet wobj = new Wallet(name, parent.getEmail(), parent.isEncrypted(), parent.getPassword(), logger); + public void initCloudWallet(CloudCoin cc, String name) { Wallet wobj = new Wallet(name, "", false, "", logger); - wobj.setIDCoin(cc, parent); + wobj.setIDCoin(cc); wallets.put(name, wobj); } @@ -1196,28 +1193,10 @@ public Wallet[] getWallets() { Collection c = wallets.values(); Wallet[] ws = new Wallet[size]; - String defaultWalletName = AppCore.getDefaultWalletName(); - if (defaultWalletName == null) { - logger.info(ltag, "Can't find default wallet"); - defaultWalletName = Config.DIR_DEFAULT_USER; - } - int i = 0; Iterator itr = c.iterator(); while (itr.hasNext()) { Wallet tw = (Wallet) itr.next(); - if (tw.getName().equals(defaultWalletName)) { - ws[i++] = tw; - break; - } - } - - itr = c.iterator(); - while (itr.hasNext()) { - Wallet tw = (Wallet) itr.next(); - if (tw.getName().equals(defaultWalletName)) - continue; - ws[i++] = tw; } @@ -1298,7 +1277,23 @@ public class makeChangeResult { public int progress; } + - + public Wallet getFirstNonSkyWallet() { + Collection c = wallets.values(); + Iterator itr = c.iterator(); + while (itr.hasNext()) { + Wallet tw = (Wallet) itr.next(); + + if (tw.isSkyWallet()) { + continue; + } + + return tw; + } + + return null; + } + } diff --git a/src/advclient/common/core/Wallet.java b/src/advclient/common/core/Wallet.java index f84169c..2792d51 100644 --- a/src/advclient/common/core/Wallet.java +++ b/src/advclient/common/core/Wallet.java @@ -24,7 +24,6 @@ public class Wallet { CloudCoin cc; Object uiRef; int total; - Wallet parent; String passwordHash; int[] sns; int[][] counters; @@ -37,7 +36,6 @@ public Wallet(String name, String email, boolean isEncrypted, String password, G this.password = password; this.ltag += " " + name; this.logger = logger; - this.parent = null; this.sns = new int[0]; logger.debug(ltag, "wallet " + name + " e=" + email + " is="+isEncrypted+ " p="+password); @@ -52,11 +50,6 @@ public Hashtable getEnvelopes() { return this.envelopes; } - - public boolean isDefaultWallet() { - return name.equals(AppCore.getDefaultWalletName()); - } - public int[] getSNs() { return this.sns; } @@ -94,19 +87,14 @@ public boolean isSkyWallet() { return this.cc != null; } - public void setIDCoin(CloudCoin cc, Wallet parent) { + public void setIDCoin(CloudCoin cc) { this.cc = cc; - this.parent = parent; } public CloudCoin getIDCoin() { return this.cc; } - - public Wallet getParent() { - return this.parent; - } - + public boolean isEncrypted() { return this.isEncrypted; } @@ -139,14 +127,10 @@ public String getTransactionsFileName() { String tfFileName = Config.TRANSACTION_FILENAME; String rname; - if (isSkyWallet()) { - tfFileName += "-" + cc.sn; - rname = parent.getName(); - } else { - rname = name; - } - - String fileName = AppCore.getUserDir(tfFileName, rname); + if (isSkyWallet()) + return ""; + + String fileName = AppCore.getUserDir(tfFileName, name); return fileName; } @@ -187,6 +171,9 @@ public void appendTransaction(String memo, int amount, String receiptId) { public void appendTransaction(String memo, int amount, String receiptId, String date) { logger.debug(ltag, "Append transaction " + receiptId + " amount " + amount + " wallet " + getName()); + if (isSkyWallet()) + return; + String fileName = getTransactionsFileName(); String rMemo = memo.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll(",", " "); //String sAmount = Integer.toString(amount); From cf261bec8b72a62f2cc7ac722d756cec7bfa44dc Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 14 Aug 2019 13:46:04 +0300 Subject: [PATCH 024/160] same wallet dropdown --- src/advclient/AdvancedClient.java | 51 ++++++++++++++++++------ src/advclient/RoundedCornerComboBox.java | 18 ++++----- 2 files changed, 48 insertions(+), 21 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index cd7734b..e58692d 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -2743,13 +2743,13 @@ public void showTransferScreen() { subInnerCore.setLayout(gridbag); - final optRv rvFrom = setOptionsForWalletsCommon(false, false, true); + final optRv rvFrom = setOptionsForWalletsCommon(false, false, true, null); if (rvFrom.idxs.length == 0) { ps.errText = "No Wallets to Transfer From"; return; } - final optRv rvTo = setOptionsForWalletsAll(); + final optRv rvTo = setOptionsForWalletsAll(null); fname = new JLabel("Transfer From"); @@ -2850,6 +2850,15 @@ public void actionPerformed(ActionEvent e) { passwordSrc.getTextField().setVisible(false); spText.setVisible(false); } + + String value = cboxto.getSelectedValue(); + optRv lrvTo = setOptionsForWalletsAll(srcWallet.getName()); + rvTo.idxs = lrvTo.idxs; + rvTo.options = lrvTo.options; + cboxto.setOptions(rvTo.options); + cboxto.addOption(AppUI.getRemoteUserOption()); + cboxto.addOption(AppUI.getLocalFolderOption()); + cboxto.setDefault(value); } }); @@ -4058,25 +4067,39 @@ public void actionPerformed(ActionEvent e) { public optRv setOptionsForWallets(boolean checkFracked, boolean needEmpty) { - return setOptionsForWalletsCommon(checkFracked, needEmpty, false); + return setOptionsForWalletsCommon(checkFracked, needEmpty, false, null); } - public optRv setOptionsForWalletsAll() { + public optRv setOptionsForWalletsAll(String name) { optRv rv = new optRv(); - rv.options = new String[wallets.length]; - rv.idxs = new int[wallets.length]; + int len = wallets.length; + if (name != null) + len -= 1; - for (int i = 0; i < wallets.length; i++) { - rv.options[i] = wallets[i].getName() + " - " + AppCore.formatNumber(wallets[i].getTotal()) + " CC"; - rv.idxs[i] = i; + if (len < 0) + len = 0; + + rv.options = new String[len]; + rv.idxs = new int[len]; + + if (len == 0) + return rv; + + for (int i = 0, j = 0; i < wallets.length; i++) { + if (name != null && wallets[i].getName().equals(name)) + continue; + + rv.options[j] = wallets[i].getName() + " - " + AppCore.formatNumber(wallets[i].getTotal()) + " CC"; + rv.idxs[j] = i; + j++; } return rv; } - public optRv setOptionsForWalletsCommon(boolean checkFracked, boolean needEmpty, boolean includeSky) { + public optRv setOptionsForWalletsCommon(boolean checkFracked, boolean needEmpty, boolean includeSky, String name) { optRv rv = new optRv(); int cnt = 0; @@ -4104,7 +4127,9 @@ public optRv setOptionsForWalletsCommon(boolean checkFracked, boolean needEmpty, continue; } - + if (name != null && wallets[i].getName().equals(name)) + continue; + cnt++; } @@ -4138,6 +4163,8 @@ public optRv setOptionsForWalletsCommon(boolean checkFracked, boolean needEmpty, //wTotal = fc; } + if (name != null && wallets[i].getName().equals(name)) + continue; rv.options[j] = wallets[i].getName() + " - " + AppCore.formatNumber(wTotal) + " CC"; rv.idxs[j] = i; @@ -4156,7 +4183,7 @@ public void showDeleteWalletScreen() { GridBagLayout gridbag = new GridBagLayout(); subInnerCore.setLayout(gridbag); - final optRv rv = setOptionsForWalletsCommon(false, true, true); + final optRv rv = setOptionsForWalletsCommon(false, true, true, null); if (rv.idxs.length == 0) { fname = AppUI.wrapDiv("You have no empty wallets to delete"); AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); diff --git a/src/advclient/RoundedCornerComboBox.java b/src/advclient/RoundedCornerComboBox.java index 1d40231..8912248 100644 --- a/src/advclient/RoundedCornerComboBox.java +++ b/src/advclient/RoundedCornerComboBox.java @@ -29,7 +29,7 @@ public class RoundedCornerComboBox { JPanel core; JComboBox combo1; MyComboBoxModel cbm; - + ComboBoxRenderer renderer; public RoundedCornerComboBox(Color outerBgColor, String placeholder, String[] options) { this.outerBgColor = outerBgColor; @@ -50,7 +50,7 @@ public void setDefault(String value) { combo1.setSelectedItem(value); } - + public void setDefaultIdx(int idx) { combo1.setSelectedIndex(idx); return; @@ -83,6 +83,8 @@ public void setOptions(String[] options) { combo1.addItem(options[i]); cbm.drop(); + combo1.revalidate(); + combo1.repaint(); } public void addOption(String option) { @@ -137,7 +139,7 @@ public void focusGained(FocusEvent e) { cbm = new MyComboBoxModel(this.placeholder, combo1); combo1.addPopupMenuListener(new HeavyWeightContainerListener(this.outerBgColor, cbm)); - ComboBoxRenderer renderer = new ComboBoxRenderer(combo1, background); + renderer = new ComboBoxRenderer(combo1, background); combo1.setRenderer(renderer); combo1.setModel(cbm); setOptions(this.options); @@ -178,8 +180,8 @@ public void setSelectedItem(Object anObject) { super.setSelectedItem(anObject); } } - - + + } class HeavyWeightContainerListener implements PopupMenuListener { @@ -401,15 +403,13 @@ public ComboBoxRenderer(JComboBox combo, Color color) { this.color = color; textPanel = new JPanel(); textPanel.add(this); - - + text = new JLabel(); text.setOpaque(true); textPanel.add(text); AppUI.setMargin(text, 10, 10, 10, 10); } - @Override public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { @@ -434,7 +434,7 @@ public Component getListCellRendererComponent(JList list, Object value, } else { AppUI.setSize(text, (int) AppUI.getBoxWidth(), (int) AppUI.getBoxHeight()); } - + return text; } From e98fc99a1b0187631b1d33af8078afb710fc16f5 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 15 Aug 2019 16:32:51 +0300 Subject: [PATCH 025/160] terms --- src/advclient/AdvancedClient.java | 2 +- src/resources/TermsAndConditions.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index e58692d..5caefd7 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -56,7 +56,7 @@ * */ public class AdvancedClient { - String version = "2.1.10"; + String version = "2.1.11"; JPanel headerPanel; JPanel mainPanel; diff --git a/src/resources/TermsAndConditions.html b/src/resources/TermsAndConditions.html index b10fddc..400584f 100644 --- a/src/resources/TermsAndConditions.html +++ b/src/resources/TermsAndConditions.html @@ -105,7 +105,7 @@

CloudCoin Consortium

Indemnification


You hereby indemnify to the fullest extent the CloudCoin Consortium from and against any and all liabilities, costs, demands, causes of action, - damages, and expenses (including reasonable attorney’s fees) arising out of or in any + damages, and expenses (including reasonable attorney's fees) arising out of or in any way related to your breach of any of the provisions of these Terms.


Variation of Terms


The CloudCoin Consortium is permitted to revise these Terms at any time From 33886d2613c8dc7ad45a1b58965dfb2af006f431 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 15 Aug 2019 16:46:56 +0300 Subject: [PATCH 026/160] Support portal --- src/advclient/AdvancedClient.java | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 5caefd7..7c04223 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -3678,7 +3678,7 @@ public void showSupportScreen() { subInnerCore.setLayout(gridbag); Image img; - JLabel i0, i1, i2, i3; + JLabel i0, i1, i2, i3, i4; try { img = ImageIO.read(getClass().getClassLoader().getResource("resources/support0.png")); i0 = new JLabel(new ImageIcon(img)); @@ -3692,6 +3692,9 @@ public void showSupportScreen() { img = ImageIO.read(getClass().getClassLoader().getResource("resources/support3.png")); i3 = new JLabel(new ImageIcon(img)); + img = ImageIO.read(getClass().getClassLoader().getResource("resources/support0.png")); + i4 = new JLabel(new ImageIcon(img)); + } catch (Exception ex) { return; } @@ -3774,6 +3777,27 @@ public void actionPerformed(ActionEvent e) { + // Support Portal + JLabel sp = new JLabel("Support Portal"); + urlName = "https://cloudcoinsupport.atlassian.net/servicedesk/customer/portals"; + link = AppUI.getHyperLink(urlName, urlName, 14); + AppUI.setCommonFont(sp); + wr = new JPanel(); + AppUI.noOpaque(wr); + wr.add(i4); + wr.add(AppUI.vr(10)); + wr.add(sp); + wr.add(link); + + + + AppUI.getGBRow(subInnerCore, null, wr, y, gridbag); + // AppUI.setColor(vlink, AppUI.getColor2()); + // AppUI.underLine(vlink); + y++; + + + AppUI.GBPad(subInnerCore, y, gridbag); y++; From 0b4cc6a199cd518b32618ef1b157aa8a4823a24e Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 15 Aug 2019 16:55:59 +0300 Subject: [PATCH 027/160] delete wallet transaction --- src/advclient/AdvancedClient.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 7c04223..e09b558 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -2074,7 +2074,7 @@ public void showConfirmDeleteWalletScreen() { final Wallet dstWallet = sm.getFirstNonSkyWallet(); if (ps.srcWallet.isSkyWallet()) { - txt += "

Your ID coin will be put back into your Bank. You will not be able to receive Coins at this address again"; + txt += "

Your ID coin will be put back into your Bank (Wallet " + dstWallet.getName() + "). You will not be able to receive Coins at this address again"; } fname = AppUI.wrapDiv(txt); @@ -2146,6 +2146,8 @@ public void actionPerformed(ActionEvent e) { return; } + dstWallet.appendTransaction("Coin from Deleted Sky Wallet", ps.srcWallet.getIDCoin().getDenomination(), "skymove"); + if (dstWallet.isEncrypted()) { wl.debug(ltag, "Start Vaulter"); From 500d56e2ee46ac95e8566473276170eca537ae35 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 15 Aug 2019 18:12:04 +0300 Subject: [PATCH 028/160] Button rename --- src/advclient/AdvancedClient.java | 40 ++++++++++++++++--------------- src/advclient/MyButton.java | 2 +- 2 files changed, 22 insertions(+), 20 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index e09b558..2daee76 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -2043,7 +2043,7 @@ public void showConfirmClearScreen() { AppUI.GBPad(subInnerCore, y, gridbag); y++; - AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Confirm", new ActionListener() { public void actionPerformed(ActionEvent e) { ps.currentScreen = ProgramState.SCREEN_DEFAULT; showScreen(); @@ -2093,7 +2093,7 @@ public void showConfirmDeleteWalletScreen() { y++; final MyTextField mtf0 = tf0; - AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Confrim", new ActionListener() { public void actionPerformed(ActionEvent e) { ps.currentScreen = ProgramState.SCREEN_DEFAULT; showScreen(); @@ -2259,7 +2259,7 @@ public void showConfirmTransferScreen() { AppUI.GBPad(subInnerCore, y, gridbag); y++; - AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Confirm", new ActionListener() { public void actionPerformed(ActionEvent e) { ps.currentScreen = ProgramState.SCREEN_DEFAULT; showScreen(); @@ -4509,7 +4509,7 @@ public void actionPerformed(ActionEvent e) { resetState(); } - public void updateTransactionWalletData(Wallet w) { + public synchronized void updateTransactionWalletData(Wallet w) { if (trTitle != null) { String rec = ""; if (!w.getEmail().isEmpty()) { @@ -4526,6 +4526,22 @@ public void updateTransactionWalletData(Wallet w) { if (invPanel != null) { int[][] counters = w.getCounters(); + invPanel.removeAll(); + + try { + Image img = ImageIO.read(getClass().getClassLoader().getResource("resources/coinsinventory.png")); + JLabel icon = new JLabel(new ImageIcon(img)); + AppUI.setMargin(icon, 0, 0, 0, 0); + invPanel.add(icon); + } catch (Exception ex) { + } + + JLabel invLabel = new JLabel("Inventory:"); + AppUI.setSemiBoldFont(invLabel, 18); + AppUI.setColor(invLabel, AppUI.getColor5()); + AppUI.setMargin(invLabel, 0, 10, 0, 20); + invPanel.add(invLabel); + if (counters != null && counters.length != 0) { int t1, t5, t25, t100, t250; @@ -4594,19 +4610,7 @@ public void showTransactionsScreen() { hwrapper.add(invPanel); - try { - Image img = ImageIO.read(getClass().getClassLoader().getResource("resources/coinsinventory.png")); - JLabel icon = new JLabel(new ImageIcon(img)); - AppUI.setMargin(icon, 0, 0, 0, 0); - invPanel.add(icon); - } catch (Exception ex) { - } - JLabel invLabel = new JLabel("Inventory:"); - AppUI.setSemiBoldFont(invLabel, 18); - AppUI.setColor(invLabel, AppUI.getColor5()); - AppUI.setMargin(invLabel, 0, 10, 0, 20); - invPanel.add(invLabel); } @@ -4615,7 +4619,6 @@ public void showTransactionsScreen() { rightPanel.add(hwrapper); rightPanel.add(AppUI.hr(22)); - JLabel thlabel = new JLabel("Transaction History"); AppUI.alignLeft(thlabel); @@ -4685,8 +4688,7 @@ public void showTransactionsScreen() { "Total" }; } - - + final JLabel iconLeft, iconRight; try { Image img = ImageIO.read(getClass().getClassLoader().getResource("resources/arrowleft.png")); diff --git a/src/advclient/MyButton.java b/src/advclient/MyButton.java index 993b089..b593709 100644 --- a/src/advclient/MyButton.java +++ b/src/advclient/MyButton.java @@ -42,7 +42,7 @@ public MyButton(String text, Color color) { this.color = color; core = makeUI(text); this.lastActionAdded = false; - if (!text.toLowerCase().equals("continue")) + if (!text.toLowerCase().equals("continue") && !text.toLowerCase().equals("confirm")) this.lastActionAdded = true; } From 3e15e233f8a1d432795be96350bccac7a6941156 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 16 Aug 2019 10:30:50 +0300 Subject: [PATCH 029/160] Move from Imported --- src/advclient/AdvancedClient.java | 17 +++++++++++------ src/advclient/common/core/AppCore.java | 14 ++++++++++++++ 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 2daee76..19ab6dc 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -3344,9 +3344,11 @@ public void actionPerformed(ActionEvent e) { cnt = AppCore.getFilesCount(Config.DIR_IMPORT, w.getName()); if (cnt != 0) { - ps.errText = getNonEmptyFolderError("Import"); - showScreen(); - return; + wl.debug(ltag, "Import folder is not empty: " + cnt + " files. Cleaning"); + AppCore.moveFolderContentsToTrash(Config.DIR_IMPORT, w.getName()); +// ps.errText = getNonEmptyFolderError("Import"); + // showScreen(); + //return; } int total; @@ -3600,9 +3602,12 @@ public void actionPerformed(ActionEvent e) { cnt = AppCore.getFilesCount(Config.DIR_IMPORT, w.getName()); if (cnt != 0) { - ps.errText = getNonEmptyFolderError("Import"); - showScreen(); - return; + wl.debug(ltag, "Import folder is not empty: " + cnt + " files. Cleaning"); + AppCore.moveFolderContentsToTrash(Config.DIR_IMPORT, w.getName()); + + //ps.errText = getNonEmptyFolderError("Import"); + //showScreen(); + //return; } cnt = AppCore.getFilesCount(Config.DIR_DETECTED, w.getName()); diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index 419ac81..41d551d 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -888,6 +888,20 @@ static public boolean moveFolderToTrash(String folder) { return true; } + static public void moveFolderContentsToTrash(String folder, String user) { + String path = AppCore.getUserDir(folder, user); + + File dirObj = new File(path); + if (!dirObj.exists()) { + logger.error(ltag, "Path " + path + " doesn't exist"); + return; + } + + for (File file: dirObj.listFiles()) { + AppCore.moveToTrash(file.getAbsolutePath(), user); + } + } + public static int maxCoinsWorkAround(int maxCoins) { String javaVersion = System.getProperty("java.version"); From 5f3cd1e9dcc88de673eab886c09d6d5f91625f98 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 16 Aug 2019 10:51:43 +0300 Subject: [PATCH 030/160] wallet sort --- src/advclient/common/core/ServantManager.java | 10 +++++++--- src/advclient/common/core/Wallet.java | 7 ++++++- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index 8b67458..d72c8e5 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -48,6 +48,7 @@ import java.util.Enumeration; import java.util.Hashtable; import java.util.Iterator; +import java.util.TreeMap; import org.json.JSONException; /** @@ -1189,8 +1190,10 @@ public void callback(final Object result) { } public Wallet[] getWallets() { - int size = wallets.size(); - Collection c = wallets.values(); + TreeMap sorted = new TreeMap<>(wallets); + + int size = sorted.size(); + Collection c = sorted.values(); Wallet[] ws = new Wallet[size]; int i = 0; @@ -1199,7 +1202,8 @@ public Wallet[] getWallets() { Wallet tw = (Wallet) itr.next(); ws[i++] = tw; } - + + return ws; } diff --git a/src/advclient/common/core/Wallet.java b/src/advclient/common/core/Wallet.java index 2792d51..f101310 100644 --- a/src/advclient/common/core/Wallet.java +++ b/src/advclient/common/core/Wallet.java @@ -13,7 +13,7 @@ * * @author Alexander */ -public class Wallet { +public class Wallet implements Comparable { String ltag = "Wallet"; GLogger logger; String name; @@ -224,4 +224,9 @@ public void saveSerials(String fileName) { AppCore.saveFile(fileName, sb.toString()); } + + @Override + public int compareTo(Wallet w) { + return getName().compareTo(w.getName()); + } } From b2f6f4b1a6505e26afac2da2cd10993cb46f9046 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 16 Aug 2019 10:54:15 +0300 Subject: [PATCH 031/160] font size --- src/advclient/AdvancedClient.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 19ab6dc..4027856 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -686,7 +686,7 @@ public void mouseExited(MouseEvent e) { // Do stuff popup menu final int mWidth = 212; - final int mHeight = 60; + final int mHeight = 48; final JPopupMenu popupMenu = new JPopupMenu() { @Override public void paintComponent(final Graphics g) { @@ -742,7 +742,7 @@ public void mouseReleased(MouseEvent evt) { menuItem.addMouseListener(ma); AppUI.setSize(menuItem, mWidth, mHeight); - AppUI.setFont(menuItem, 28); + AppUI.setFont(menuItem, 20); menuItem.setOpaque(true); menuItem.setBackground(AppUI.getColor1()); From 1a61641f2a96710c1e4d1f08ca25f1bedd2a7139 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 19 Aug 2019 18:19:43 +0300 Subject: [PATCH 032/160] config value --- src/advclient/AdvancedClient.java | 5 ++++- src/advclient/common/Authenticator/Authenticator.java | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 4027856..84592f7 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -56,7 +56,7 @@ * */ public class AdvancedClient { - String version = "2.1.11"; + String version = "2.1.12"; JPanel headerPanel; JPanel mainPanel; @@ -4575,6 +4575,9 @@ public synchronized void updateTransactionWalletData(Wallet w) { AppUI.addInvItem(invPanel, "25", t25); AppUI.addInvItem(invPanel, "100", t100); AppUI.addInvItem(invPanel, "250", t250); + + invPanel.revalidate(); + invPanel.repaint(); } } } diff --git a/src/advclient/common/Authenticator/Authenticator.java b/src/advclient/common/Authenticator/Authenticator.java index eb8e0fc..6b35b60 100644 --- a/src/advclient/common/Authenticator/Authenticator.java +++ b/src/advclient/common/Authenticator/Authenticator.java @@ -46,7 +46,7 @@ public void run() { public void setConfig() { logger.debug(ltag, "Setting config"); - putConfigValue("max-coins-to-multi-detect", "" + Config.DEFAULT_MAX_COINS_MULTIDETECT); + //putConfigValue("max-coins-to-multi-detect", "" + Config.DEFAULT_MAX_COINS_MULTIDETECT); } private void copyFromGlobalResult(AuthenticatorResult aResult) { From e9dea408cde32570a21c15f2b313bb6fe992e84a Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 21 Aug 2019 12:21:06 +0300 Subject: [PATCH 033/160] errors and warnings --- src/advclient/AdvancedClient.java | 19 +++++++++++++++---- src/advclient/common/Exporter/Exporter.java | 2 +- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 84592f7..f507925 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -2982,7 +2982,7 @@ public void actionPerformed(ActionEvent e) { }; if (ps.typedAmount <= 0) { - ps.errText = "Invalid amount"; + ps.errText = "Transfer must be higher than zero"; showScreen(); return; } @@ -2996,7 +2996,7 @@ public void actionPerformed(ActionEvent e) { ps.typedMemo = ps.typedMemo.trim(); if (!ps.typedMemo.isEmpty()) { if (!Validator.memo(ps.typedMemo)) { - ps.errText = "Memo: Non alpha number characters are not allowed"; + ps.errText = "Memo: special characters not allowed! Use numbers and letters only"; showScreen(); return; } @@ -3049,7 +3049,7 @@ public void actionPerformed(ActionEvent e) { } if (ps.typedMemo.isEmpty()) { - ps.errText = "Memo cannot be empty"; + ps.errText = " nnot be empty"; showScreen(); return; } @@ -3067,7 +3067,7 @@ public void actionPerformed(ActionEvent e) { } } else if (dstIdx == rvTo.idxs.length + 1) { if (!Validator.memo(ps.typedMemo)) { - ps.errText = "Memo cannot contain dots or slashes"; + ps.errText = "Memo: special characters not allowed! Use numbers and letters only"; showScreen(); return; } @@ -3090,6 +3090,17 @@ public void actionPerformed(ActionEvent e) { if (ps.typedMemo.isEmpty()) ps.typedMemo = "Export"; + String filename = ps.chosenFile + File.separator + ps.typedAmount + ".CloudCoin." + ps.typedMemo + ".stack"; + File f = new File(filename); + if (f.exists()) { + ps.errText = "File with the same Memo already exists in " + + ps.chosenFile + " folder. Use different Memo or change folder for your transfer"; + showScreen(); + return; + } + + + ps.sendType = ProgramState.SEND_TYPE_FOLDER; setActiveWallet(ps.srcWallet); diff --git a/src/advclient/common/Exporter/Exporter.java b/src/advclient/common/Exporter/Exporter.java index 31a0112..a6fa6c5 100644 --- a/src/advclient/common/Exporter/Exporter.java +++ b/src/advclient/common/Exporter/Exporter.java @@ -296,7 +296,7 @@ private boolean exportStack(String dir, String tag) { if (f.exists()) { logger.error(ltag, "File exists: " + fileName); er.status = ExporterResult.STATUS_ERROR; - er.errText = "Exported file with the same tag already exist"; + er.errText = "Exported file with the same tag already exists"; return false; } From 6317d5fbc48db9becdfb30be4034093b144ed70d Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 21 Aug 2019 12:44:20 +0300 Subject: [PATCH 034/160] src --- src/advclient/AdvancedClient.java | 89 +++---------------------------- src/advclient/ProgramState.java | 2 - 2 files changed, 7 insertions(+), 84 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index f507925..222ba4d 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -248,39 +248,7 @@ public String getPickError(Wallet w) { return errText; } - - - public void showCoinsDone(int[][] counters) { - if (ps.currentWalletIdx <= 0) { - wl.error(ltag, "curIdx " + ps.currentWalletIdx); - return; - } - - Wallet w = wallets[ps.currentWalletIdx - 1]; - int totalCnt = AppCore.getTotal(counters[Config.IDX_FOLDER_BANK]) + - AppCore.getTotal(counters[Config.IDX_FOLDER_FRACKED]) + - AppCore.getTotal(counters[Config.IDX_FOLDER_VAULT]); - - wl.debug(ltag, "ShowCoins done"); - - ps.counters = counters; - walletSetTotal(w, totalCnt); - w.setCounters(counters); - - Thread t = new Thread(new Runnable() { - public void run(){ - try { - showCoinsGoNext(); - } catch (Exception e) { - wl.error(ltag, "ShowCoins failed: " + e.getMessage()); - } - } - }); - - t.start(); - } - - + public void setTotalCoins() { int total = 0; for (int i = 0; i < wallets.length; i++) { @@ -291,23 +259,6 @@ public void setTotalCoins() { totalText.repaint(); } - public synchronized void showCoinsGoNext() { - if (wallets.length > ps.currentWalletIdx) { - if (!wallets[ps.currentWalletIdx].isSkyWallet()) { - sm.changeServantUser("ShowCoins", wallets[ps.currentWalletIdx].getName()); - sm.startShowCoinsService(new ShowCoinsCb()); - } else { - sm.changeServantUser("ShowEnvelopeCoins", Config.DIR_DEFAULT_USER); - sm.startShowSkyCoinsService(new ShowEnvelopeCoinsCb(), wallets[ps.currentWalletIdx].getIDCoin().sn); - } - ps.currentWalletIdx++; - } else { - ps.isShowCoinsFinished = true; - } - - setTotalCoins(); - } - public void setCounters(int[][] counters) { ps.counters = counters; } @@ -1335,7 +1286,7 @@ public void actionPerformed(ActionEvent e) { Thread t = new Thread(new Runnable() { public void run() { - if (!ps.isEchoFinished || !ps.isShowCoinsFinished) { + if (!ps.isEchoFinished) { pbarText.setText("Checking RAIDA ..."); pbarText.repaint(); } @@ -1344,7 +1295,7 @@ public void run() { Thread.sleep(200); } catch (InterruptedException e) {} - while (!ps.isEchoFinished || !ps.isShowCoinsFinished) { + while (!ps.isEchoFinished) { try { Thread.sleep(300); } catch (InterruptedException e) {} @@ -1626,7 +1577,7 @@ public void run(){ } wl.debug(ltag, "Going here"); - while (!ps.isEchoFinished || !ps.isShowCoinsFinished) { + while (!ps.isEchoFinished) { try { Thread.sleep(500); } catch (InterruptedException e) {} @@ -2711,13 +2662,7 @@ public void eraserGoNext() { public void launchErasers() { if (wallets.length == 0) return; - - while (!ps.isShowCoinsFinished) { - try { - Thread.sleep(200); - } catch (InterruptedException e) {} - } - + ps.currentWalletIdx = 0; eraserGoNext(); } @@ -5981,17 +5926,7 @@ public void run() { } } } - - class ShowCoinsCb implements CallbackInterface { - public void callback(final Object result) { - final Object fresult = result; - ShowCoinsResult scresult = (ShowCoinsResult) fresult; - - setSNs(scresult.coins); - showCoinsDone(scresult.counters); - } - } - + class UnpackerSenderCb implements CallbackInterface { public void callback(Object result) { wl.debug(ltag, "Unpacker (Sender) finished"); @@ -6606,17 +6541,7 @@ public void run() { showScreen(); } } - - class ShowEnvelopeCoinsCb implements CallbackInterface { - public void callback(Object result) { - ShowEnvelopeCoinsResult er = (ShowEnvelopeCoinsResult) result; - - setEnvelopes(er.envelopes); - setSNs(er.coins); - showCoinsDone(er.counters); - } - } - + class ShowEnvelopeCoinsForReceiverCb implements CallbackInterface { public void callback(Object result) { ShowEnvelopeCoinsResult er = (ShowEnvelopeCoinsResult) result; diff --git a/src/advclient/ProgramState.java b/src/advclient/ProgramState.java index 189a7a6..17ec917 100644 --- a/src/advclient/ProgramState.java +++ b/src/advclient/ProgramState.java @@ -93,7 +93,6 @@ public class ProgramState { Wallet srcWallet; boolean isEchoFinished; - boolean isShowCoinsFinished; int statToBankValue, statToBank, statFailed, statLost; int statFailedValue, statLostValue; @@ -156,7 +155,6 @@ public ProgramState() { files = new ArrayList(); dstWallet = srcWallet = null; isEchoFinished = false; - isShowCoinsFinished = true; statToBankValue = statToBank = statFailed = 0; statFailedValue = statLostValue = 0; From e71d580648454c0b5a0128658538b584a8bc70d4 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 21 Aug 2019 12:48:46 +0300 Subject: [PATCH 035/160] blanks --- src/advclient/AdvancedClient.java | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 222ba4d..9757162 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -2587,7 +2587,7 @@ public void updateWalletAmount() { sc.launch(snID, "", new CallbackInterface() { public void callback(Object o) { ShowEnvelopeCoinsResult scresult = (ShowEnvelopeCoinsResult) o; - + wl.debug(ltag, "ShowEnvelopeCoins done"); w.setSNs(scresult.coins); w.setEnvelopes(scresult.envelopes); @@ -2604,8 +2604,7 @@ public void callback(Object o) { wl.debug(ltag, "ShowEnvelopeCoins return"); } }); - } else { - + } else { ShowCoins sc = new ShowCoins(rpath, wl); sc.launch(new CallbackInterface() { public void callback(Object o) { From fc97bd4aabbebf0c8db0ab16f352cbee13fa1f85 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 21 Aug 2019 13:43:47 +0300 Subject: [PATCH 036/160] use keyboard keys with scrollbar --- src/advclient/AdvancedClient.java | 33 +++++++++++++++++++++++++++---- 1 file changed, 29 insertions(+), 4 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 9757162..524551d 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -926,6 +926,17 @@ public void showScreen() { } + Component[] cs = lwrapperPanel.getComponents(); + if (cs != null && cs.length != 0) { + Container c = (Container) cs[0]; + if (c instanceof JScrollPane) { + JScrollPane sp = (JScrollPane) c; + Component[] spcs = sp.getComponents(); + spcs[0].requestFocus(); + } + } + + headerPanel.repaint(); headerPanel.revalidate(); @@ -5434,6 +5445,8 @@ public void showLeftScreen() { // Padding from the bottom AppUI.hr(wpanel, 120); + + JScrollPane scrollPane = new JScrollPane(wpanel); JScrollBar scrollBar = new JScrollBar(JScrollBar.VERTICAL) { @Override @@ -5450,7 +5463,21 @@ public boolean isVisible() { scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_NEVER); lwrapperPanel.add(scrollPane); - + + wpanel.addMouseListener(new MouseAdapter() { + public void mouseReleased(MouseEvent e) { + wpanel.requestFocus(); + } + }); + + corePanel.addMouseListener(new MouseAdapter() { + public void mouseReleased(MouseEvent e) { + wpanel.requestFocus(); + } + }); + + + corePanel.add(lwrapperPanel); } @@ -5561,7 +5588,7 @@ else if (type == TYPE_ADD_SKY) final Wallet fwallet = wallet; MouseAdapter ma = new MouseAdapter() { @Override - public void mouseReleased(MouseEvent e) { + public void mouseReleased(MouseEvent e) { setActiveWallet(fwallet); ps.sendType = 0; ps.currentScreen = ProgramState.SCREEN_SHOW_TRANSACTIONS; @@ -5647,8 +5674,6 @@ public void mouseExited(MouseEvent e) { wpanel.addMouseListener(ma); } - - AppUI.setHandCursor(wpanel); return wpanel; From dd256e8f508221ae6692db7b6e966fe1c5680d61 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 23 Aug 2019 10:58:11 +0300 Subject: [PATCH 037/160] updating wallets --- src/advclient/AdvancedClient.java | 24 ++++++++++++++++++++++++ src/advclient/common/core/Wallet.java | 14 ++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 524551d..a1cba55 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -170,6 +170,7 @@ public void walletSetTotal(Wallet w, int total) { wl.debug(ltag, "Set Total: " + w.getName() + " total = " + total); w.setTotal(total); + w.setUpdated(); String strCnt = AppCore.formatNumber(total); if (cntLabel == null) return; @@ -956,6 +957,11 @@ public void maybeShowError(JPanel p) { p.add(err); ps.errText = ""; + if (ps.srcWallet != null) + ps.srcWallet.setNotUpdated(); + + if (ps.dstWallet != null) + ps.dstWallet.setNotUpdated(); } } @@ -1773,6 +1779,10 @@ public void showTransferDoneScreen() { resetState(); return; } + + ps.srcWallet.setNotUpdated(); + if (ps.dstWallet != null) + ps.dstWallet.setNotUpdated(); int y = 0; JLabel fname, value; @@ -1837,6 +1847,8 @@ public void showImportDoneScreen() { JLabel fname, value; MyTextField walletName = null; + ps.dstWallet.setNotUpdated(); + subInnerCore = getPanel("Deposit Complete"); GridBagLayout gridbag = new GridBagLayout(); subInnerCore.setLayout(gridbag); @@ -2580,6 +2592,12 @@ public void updateWalletAmount() { if (cntLabel == null) continue; + if (wallets[i].isUpdated()) { + walletSetTotal(wallets[i], wallets[i].getTotal()); + continue; + } + + cntLabel.setText("Counting"); cntLabel.invalidate(); cntLabel.repaint(); @@ -2590,6 +2608,12 @@ public void updateWalletAmount() { for (int i = 0; i < wallets.length; i++) { final Wallet w = wallets[i]; + if (w.isUpdated()) + continue; + + System.out.println("updating wallet " + w.getName()); + + String rpath = AppCore.getRootPath() + File.separator + w.getName(); wl.debug(ltag, "Counting for " + w.getName()); if (w.isSkyWallet()) { diff --git a/src/advclient/common/core/Wallet.java b/src/advclient/common/core/Wallet.java index f101310..dbaa6d6 100644 --- a/src/advclient/common/core/Wallet.java +++ b/src/advclient/common/core/Wallet.java @@ -28,6 +28,7 @@ public class Wallet implements Comparable { int[] sns; int[][] counters; public Hashtable envelopes; + boolean isUpdated; public Wallet(String name, String email, boolean isEncrypted, String password, GLogger logger) { this.name = name; @@ -37,6 +38,7 @@ public Wallet(String name, String email, boolean isEncrypted, String password, G this.ltag += " " + name; this.logger = logger; this.sns = new int[0]; + this.isUpdated = false; logger.debug(ltag, "wallet " + name + " e=" + email + " is="+isEncrypted+ " p="+password); lsep = System.getProperty("line.separator"); @@ -123,6 +125,18 @@ public String getEmail() { return this.email; } + public boolean isUpdated() { + return this.isUpdated; + } + + public void setUpdated() { + this.isUpdated = true; + } + + public void setNotUpdated() { + this.isUpdated = false; + } + public String getTransactionsFileName() { String tfFileName = Config.TRANSACTION_FILENAME; String rname; From a7ffff58edc6c321ff1cd3504723194fd993deef Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 23 Aug 2019 11:38:00 +0300 Subject: [PATCH 038/160] skywallet default directory --- src/advclient/AdvancedClient.java | 12 +++++++++ src/advclient/common/core/ServantManager.java | 27 +++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index a1cba55..5ff36df 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -5100,6 +5100,18 @@ public void showCreateSkyWalletScreen() { tf1.setFilepickerListener(new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { + if (!cb1.isChecked()) { + Wallet w = sm.getFirstFullNonSkyWallet(); + if (w != null) { + String dir = AppCore.getUserDir(Config.DIR_BANK, w.getName()); + chooser.setCurrentDirectory(new File(dir)); + } else { + chooser.setCurrentDirectory(null); + } + } else { + chooser.setCurrentDirectory(null); + } + int returnVal = chooser.showOpenDialog(null); if (returnVal == JFileChooser.APPROVE_OPTION) { ps.chosenFile = chooser.getSelectedFile().getAbsolutePath(); diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index d72c8e5..e42d45f 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -107,6 +107,10 @@ public void changeServantUser(String servant, String wallet) { sr.changeServantUser(servant, wallet); } + public String getHomeDir() { + return this.home; + } + public boolean init() { boolean rv; @@ -1300,4 +1304,27 @@ public Wallet getFirstNonSkyWallet() { return null; } + public Wallet getFirstFullNonSkyWallet() { + Collection c = wallets.values(); + + Iterator itr = c.iterator(); + while (itr.hasNext()) { + Wallet tw = (Wallet) itr.next(); + + if (tw.isSkyWallet()) { + continue; + } + + if (tw.getTotal() == 0) + continue; + + if (tw.isEncrypted()) + continue; + + return tw; + } + + return null; + } + } From 909b6258ecd21ff9cfce9844388e91c3717855f8 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 26 Aug 2019 13:18:41 +0300 Subject: [PATCH 039/160] delete wallet --- src/advclient/AdvancedClient.java | 13 ++++ src/advclient/common/core/Config.java | 2 +- src/advclient/common/core/DNSSn.java | 88 +++++++++++++++++++-------- src/advclient/common/core/Wallet.java | 30 +++++++++ 4 files changed, 108 insertions(+), 25 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 5ff36df..8e8f283 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -2122,6 +2122,19 @@ public void actionPerformed(ActionEvent e) { dstWallet.appendTransaction("Coin from Deleted Sky Wallet", ps.srcWallet.getIDCoin().getDenomination(), "skymove"); + String wname = ps.srcWallet.getSkyName(); + String wdomain = ps.srcWallet.getDomain(); + final DNSSn d = new DNSSn(wname, wdomain, wl); + Thread t = new Thread(new Runnable() { + public void run(){ + if (!d.deleteRecord(wname, ps.srcWallet.getIDCoin(), sm.getSR())) { + wl.error(ltag, "Failed to delete coin. DNS error"); + return; + } + } + }); + t.start(); + if (dstWallet.isEncrypted()) { wl.debug(ltag, "Start Vaulter"); diff --git a/src/advclient/common/core/Config.java b/src/advclient/common/core/Config.java index 34a1294..eb0d68b 100644 --- a/src/advclient/common/core/Config.java +++ b/src/advclient/common/core/Config.java @@ -142,7 +142,7 @@ public class Config { final public static String DDNS_DOMAIN = "skywallet.cc"; - final public static String DDNSSN_SERVER = "https://cloudcoin.global"; + final public static String DDNSSN_SERVER = "https://ddns.cloudcoin.global"; final public static String MAIN_LOG_FILENAME = "main.log"; diff --git a/src/advclient/common/core/DNSSn.java b/src/advclient/common/core/DNSSn.java index f6e03cf..caa983d 100644 --- a/src/advclient/common/core/DNSSn.java +++ b/src/advclient/common/core/DNSSn.java @@ -106,6 +106,64 @@ public boolean setRecord(String path, ServantRegistry sr) { return false; } + int raidaNum = Config.RAIDANUM_TO_QUERY_BY_DEFAULT; + String message = getTicket(cc, sr); + if (message == null) { + logger.error(ltag, "Failed to get ticket"); + return false; + } + + String rq = "/ddns.php?sn=" + cc.sn + "&username=" + name + "&ticket=" + message + "&raidanumber=" + raidaNum; + + DetectionAgent daFake = new DetectionAgent(RAIDA.TOTAL_RAIDA_CNT * 10000, logger); + daFake.setExactFullUrl(Config.DDNSSN_SERVER + "/service/ddns"); + String result = daFake.doRequest(rq, null); + if (result == null) { + logger.error(ltag, "Failed to receive response from DDNSSN Server"); + return false; + } + + CommonResponse cr = (CommonResponse) sr.getServant("FrackFixer").parseResponse(result, CommonResponse.class); + if (!cr.status.equals("success")) { + logger.error(ltag, "Invalid response from DDNSSN Server"); + return false; + } + + return true; + } + + public boolean deleteRecord(String name, CloudCoin cc, ServantRegistry sr) { + logger.debug(ltag, "Delete record " + name + " SN: " + cc.sn); + String message = getTicket(cc, sr); + if (message == null) { + logger.error(ltag, "Failed to get ticket"); + return false; + } + + int raidaNum = Config.RAIDANUM_TO_QUERY_BY_DEFAULT; + String rq = "/ddns_delete.php?sn=" + cc.sn + "&username=" + name + "&ticket=" + message + "&raidanumber=" + raidaNum; + + DetectionAgent daFake = new DetectionAgent(RAIDA.TOTAL_RAIDA_CNT * 10000, logger); + daFake.setExactFullUrl(Config.DDNSSN_SERVER + "/service/ddns"); + String result = daFake.doRequest(rq, null); + if (result == null) { + logger.error(ltag, "Failed to receive response from DDNSSN Server"); + return false; + } + + logger.debug(ltag, result); + CommonResponse cr = (CommonResponse) sr.getServant("FrackFixer").parseResponse(result, CommonResponse.class); + if (!cr.status.equals("success")) { + logger.error(ltag, "Invalid response from DDNSSN Server"); + return false; + } + + return true; + } + + public String getTicket(CloudCoin cc, ServantRegistry sr) { + logger.debug(ltag, "Getting ticket for " + cc.sn); + int raidaNum = Config.RAIDANUM_TO_QUERY_BY_DEFAULT; StringBuilder sb = new StringBuilder(); @@ -125,18 +183,18 @@ public boolean setRecord(String path, ServantRegistry sr) { String result = da.doRequest("/service/multi_get_ticket", sb.toString()); if (result == null) { logger.error(ltag, "Failed to get tickets. Setting triad to failed"); - return false; + return null; } Object[] o = sr.getServant("FrackFixer").parseArrayResponse(result, GetTicketResponse.class); if (o == null) { logger.error(ltag, "Failed to parse result " + result); - return false; + return null; } if (o.length != 1) { logger.error(ltag, "Failed to parse result (length is wrong) " + result); - return false; + return null; } GetTicketResponse g = (GetTicketResponse) o[0]; @@ -145,32 +203,14 @@ public boolean setRecord(String path, ServantRegistry sr) { logger.debug(ltag, " message " + g.message); if (!g.status.equals("ticket")) { logger.error(ltag, "Failed to get ticket for coin id " + cc.sn); - return false; + return null; } if (message == null || message.length() != 44) { logger.error(ltag, "Invalid ticket from RAIDA"); - return false; + return null; } - String rq = "/ddns.php?sn=" + cc.sn + "&username=" + name + "&ticket=" + message + "&raidanumber=" + raidaNum; - - DetectionAgent daFake = new DetectionAgent(RAIDA.TOTAL_RAIDA_CNT * 10000, logger); - daFake.setExactFullUrl(Config.DDNSSN_SERVER); - result = daFake.doRequest(rq, null); - if (result == null) { - logger.error(ltag, "Failed to receive response from DDNSSN Server"); - return false; - } - - CommonResponse cr = (CommonResponse) sr.getServant("FrackFixer").parseResponse(result, CommonResponse.class); - if (!cr.status.equals("success")) { - logger.error(ltag, "Invalid response from DDNSSN Server"); - return false; - } - - return true; + return message; } - - } diff --git a/src/advclient/common/core/Wallet.java b/src/advclient/common/core/Wallet.java index dbaa6d6..6d18c39 100644 --- a/src/advclient/common/core/Wallet.java +++ b/src/advclient/common/core/Wallet.java @@ -243,4 +243,34 @@ public void saveSerials(String fileName) { public int compareTo(Wallet w) { return getName().compareTo(w.getName()); } + + + public String getDomain() { + if (!isSkyWallet()) + return ""; + + String wname = getName(); + String[] parts = wname.split("\\."); + String domain = ""; + for (int j = 1; j < parts.length; j++) { + if (j != 1) + domain += "."; + + domain += parts[j]; + } + + return domain; + } + + public String getSkyName() { + if (!isSkyWallet()) + return ""; + + String wname = getName(); + String[] parts = wname.split("\\."); + + return parts[0]; + } + + } From 4507f69ebe82b797dd72c63b984a1a65352116e6 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 26 Aug 2019 15:51:48 +0300 Subject: [PATCH 040/160] Unpacker will proceed if a file is failed --- src/advclient/common/Receiver/Receiver.java | 2 +- src/advclient/common/Unpacker/Unpacker.java | 21 ++++++++++----------- src/advclient/common/core/CloudCoin.java | 3 ++- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/advclient/common/Receiver/Receiver.java b/src/advclient/common/Receiver/Receiver.java index dedc19d..fd6b042 100644 --- a/src/advclient/common/Receiver/Receiver.java +++ b/src/advclient/common/Receiver/Receiver.java @@ -312,7 +312,7 @@ public void callback(Object result) { } rsn = rrs[i][j].sn; - ran = rrs[i][j].message; + ran = (cstatus == CloudCoin.STATUS_PASS) ? rrs[i][j].message : null; rnn = rrs[i][j].nn; for (int k = 0; k < sccs.length; k++) { if (sccs[k] == null) diff --git a/src/advclient/common/Unpacker/Unpacker.java b/src/advclient/common/Unpacker/Unpacker.java index 2d0fd47..b8de351 100644 --- a/src/advclient/common/Unpacker/Unpacker.java +++ b/src/advclient/common/Unpacker/Unpacker.java @@ -63,8 +63,7 @@ public int checkCoinsInFolder(String folder) { logger.error(ltag, "No such dir " + fullPath); return -1; } - - + for (File file: dirObj.listFiles()) { if (file.isDirectory()) continue; @@ -107,6 +106,7 @@ public void doUnpack() { logger.error(ltag, "Import Dir doesn't exist"); return; } + for (File file: dirObj.listFiles()) { if (file.isDirectory()) continue; @@ -115,9 +115,10 @@ public void doUnpack() { index = fileName.lastIndexOf('.'); if (index <= 0) { logger.error(ltag, "Skipping filename " + fileName + ". No extension found"); - AppCore.moveToTrash(file.toString(), user); - globalResult.status = UnpackerResult.STATUS_ERROR; - return; + //AppCore.moveToTrash(file.toString(), user); + //globalResult.status = UnpackerResult.STATUS_ERROR; + //return; + continue; } extension = fileName.substring(index + 1).toLowerCase(); @@ -135,17 +136,15 @@ public void doUnpack() { rv = doUnpackBinary(file.toString()); } else { rv = doUnpackStack(file.toString()); - // logger.error(ltag, "Unknown file: " + fileName); - // AppCore.moveToTrash(file.toString()); - // continue; } if (!rv) { logger.error(ltag, "Error processing file: " + fileName); AppCore.moveToTrash(file.toString(), user); - globalResult.status = UnpackerResult.STATUS_ERROR; - globalResult.errText = "Failed to parse: " + fileName; - return; + //globalResult.status = UnpackerResult.STATUS_ERROR; + //globalResult.errText = "Failed to parse: " + fileName; + //return; + continue; } } diff --git a/src/advclient/common/core/CloudCoin.java b/src/advclient/common/core/CloudCoin.java index e0ba2b7..7b1f9d1 100644 --- a/src/advclient/common/core/CloudCoin.java +++ b/src/advclient/common/core/CloudCoin.java @@ -166,7 +166,8 @@ public void setMissingANs() { for (int i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { if (ans[i] == null) { ans[i] = generatePan(); - detectStatus[i] = CloudCoin.STATUS_FAIL; + if (detectStatus[i] == CloudCoin.STATUS_PASS || detectStatus[i] == CloudCoin.STATUS_UNTRIED) + detectStatus[i] = CloudCoin.STATUS_ERROR; } } From d273203fa04dfbc93c7e720d563a3ccbc99bb450 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 26 Aug 2019 16:24:15 +0300 Subject: [PATCH 041/160] lastaction --- src/advclient/MyButton.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/advclient/MyButton.java b/src/advclient/MyButton.java index b593709..ab8e787 100644 --- a/src/advclient/MyButton.java +++ b/src/advclient/MyButton.java @@ -33,7 +33,7 @@ public MyButton(String text) { this.color = AppUI.getColor2(); core = makeUI(text); this.lastActionAdded = false; - if (!text.toLowerCase().equals("continue")) + if (!text.toLowerCase().equals("continue") && !text.toLowerCase().equals("confirm")) this.lastActionAdded = true; } From d47a44fed19e9075925c432a673f2f59a4a9496a Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 26 Aug 2019 16:57:19 +0300 Subject: [PATCH 042/160] rm debug --- src/advclient/AdvancedClient.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 8e8f283..60f1570 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -2624,9 +2624,6 @@ public void updateWalletAmount() { if (w.isUpdated()) continue; - System.out.println("updating wallet " + w.getName()); - - String rpath = AppCore.getRootPath() + File.separator + w.getName(); wl.debug(ltag, "Counting for " + w.getName()); if (w.isSkyWallet()) { From c72e0c5fdb204c1bafae19d1dd80167ef5d3e5a0 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 26 Aug 2019 19:00:13 +0300 Subject: [PATCH 043/160] LossFixer --- src/advclient/AdvancedClient.java | 7 +- .../common/Authenticator/Authenticator.java | 3 +- src/advclient/common/LossFixer/LossFixer.java | 281 ++++++++++++++++-- .../common/LossFixer/LossFixerResult.java | 3 + src/advclient/common/core/Wallet.java | 3 + 5 files changed, 267 insertions(+), 30 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 60f1570..c7580fd 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -1687,7 +1687,10 @@ public void showFixDoneScreen() { AppUI.getTwoButtonPanel(subInnerCore, "", "Continue", null, new ActionListener() { public void actionPerformed(ActionEvent e) { - setActiveWallet(ps.dstWallet); + if (ps.dstWallet != null) + setActiveWallet(ps.dstWallet); + else + setActiveWallet(ps.srcWallet); ps.sendType = 0; ps.currentScreen = ProgramState.SCREEN_SHOW_TRANSACTIONS; showScreen(); @@ -6227,7 +6230,7 @@ public void callback(Object result) { if (fr.status == FrackFixerResult.STATUS_ERROR) { EventQueue.invokeLater(new Runnable() { public void run() { - ps.errText = "

Failed to Fix Coins. Please see logs at
" + AppCore.getLogPath() + "
"; + ps.errText = "Failed to Fix Coins. Please see logs at
" + AppCore.getLogPath() + ""; ps.currentScreen = ProgramState.SCREEN_FIX_DONE; showScreen(); } diff --git a/src/advclient/common/Authenticator/Authenticator.java b/src/advclient/common/Authenticator/Authenticator.java index 6b35b60..b5e8bcd 100644 --- a/src/advclient/common/Authenticator/Authenticator.java +++ b/src/advclient/common/Authenticator/Authenticator.java @@ -242,7 +242,6 @@ public void doAuthencticate() { CloudCoin cc; ArrayList ccs; - ccs = new ArrayList(); int maxCoins = getIntConfigValue("max-coins-to-multi-detect"); @@ -257,7 +256,7 @@ public void doAuthencticate() { globalResult.totalFiles = AppCore.getFilesCount(Config.DIR_SUSPECT, user); if (globalResult.totalFiles == 0) { - logger.error(ltag, "The Suspect folder is empty"); + logger.info(ltag, "The Suspect folder is empty"); globalResult.status = AuthenticatorResult.STATUS_FINISHED; cb.callback(globalResult); return; diff --git a/src/advclient/common/LossFixer/LossFixer.java b/src/advclient/common/LossFixer/LossFixer.java index 87f0fbe..268bff1 100644 --- a/src/advclient/common/LossFixer/LossFixer.java +++ b/src/advclient/common/LossFixer/LossFixer.java @@ -7,10 +7,12 @@ import global.cloudcoin.ccbank.core.AppCore; import global.cloudcoin.ccbank.core.CallbackInterface; import global.cloudcoin.ccbank.core.CloudCoin; +import global.cloudcoin.ccbank.core.CommonResponse; import global.cloudcoin.ccbank.core.Config; import global.cloudcoin.ccbank.core.GLogger; import global.cloudcoin.ccbank.core.RAIDA; import global.cloudcoin.ccbank.core.Servant; +import java.util.ArrayList; public class LossFixer extends Servant { String ltag = "LossFixer"; @@ -49,13 +51,15 @@ public void run() { }); } - public void copyFromMainFr(LossFixerResult nlr) { + public void copyFromGlobalResult(LossFixerResult nlr) { nlr.failed = lr.failed; nlr.recovered = lr.recovered; nlr.status = lr.status; nlr.totalFiles = lr.totalFiles; nlr.totalFilesProcessed = lr.totalFilesProcessed; nlr.totalRAIDAProcessed = lr.totalRAIDAProcessed; + nlr.totalCoins = lr.totalCoins; + nlr.totalCoinsProcessed = lr.totalCoinsProcessed; } public void doLossFix() { @@ -64,14 +68,37 @@ public void doLossFix() { String fullLostPath = AppCore.getUserDir(Config.DIR_LOST, user); CloudCoin cc; + ArrayList ccs; + ccs = new ArrayList(); - int totalToFix = AppCore.getFilesCount(Config.DIR_LOST, user); - - logger.debug(ltag, "Need to check: " + totalToFix + " coins"); + int maxCoins = getIntConfigValue("max-coins-to-multi-detect"); + if (maxCoins == -1) + maxCoins = Config.DEFAULT_MAX_COINS_MULTIDETECT; + int totalToFix = AppCore.getFilesCount(Config.DIR_LOST, user); + logger.debug(ltag, "Need to check: " + totalToFix + " coins. Max coins: " + maxCoins); lr.totalFiles = totalToFix; - + raida.setReadTimeout(Config.MULTI_DETECT_TIMEOUT); + File dirObj = new File(fullLostPath); + for (File file: dirObj.listFiles()) { + if (file.isDirectory()) + continue; + + try { + cc = new CloudCoin(file.toString()); + } catch (JSONException e) { + logger.error(ltag, "Failed to parse coin: " + file.toString() + + " error: " + e.getMessage()); + + AppCore.moveToTrash(file.toString(), user); + continue; + } + + lr.totalCoins += cc.getDenomination(); + } + + int curValProcessed = 0; for (File file : dirObj.listFiles()) { if (file.isDirectory()) continue; @@ -91,34 +118,191 @@ public void doLossFix() { resume(); LossFixerResult lfr = new LossFixerResult(); - lfr.status = LossFixerResult.STATUS_CANCELLED; - copyFromMainFr(lfr); + lr.status = LossFixerResult.STATUS_CANCELLED; + copyFromGlobalResult(lfr); if (cb != null) cb.callback(lfr); return; } + ccs.add(cc); + curValProcessed += cc.getDenomination(); + if (ccs.size() == maxCoins) { + logger.info(ltag, "Processing"); - logger.info(ltag, "doing recovery " + cc.sn); - doRecoverCoin(cc); + LossFixerResult lfr = new LossFixerResult(); + if (!processLossfix(ccs)) { + lr.status = LossFixerResult.STATUS_ERROR; + copyFromGlobalResult(lfr); + if (cb != null) + cb.callback(lfr); - lr.totalFilesProcessed++; - lr.totalRAIDAProcessed = 0; - - LossFixerResult lfr = new LossFixerResult(); - copyFromMainFr(lfr); - if (cb != null) - cb.callback(lfr); + return; + } + + ccs.clear(); + + lr.totalRAIDAProcessed = 0; + lr.totalFilesProcessed += maxCoins; + lr.totalCoinsProcessed = curValProcessed; + + copyFromGlobalResult(lfr); + if (cb != null) + cb.callback(lfr); + } } LossFixerResult lfr = new LossFixerResult(); - lr.status = LossFixerResult.STATUS_FINISHED; - copyFromMainFr(lfr); + if (ccs.size() > 0) { + logger.info(ltag, "adding + " + ccs.size()); + if (!processLossfix(ccs)) { + lr.status = LossFixerResult.STATUS_ERROR; + } else { + lr.status = LossFixerResult.STATUS_FINISHED; + lr.totalFilesProcessed += ccs.size(); + lr.totalCoinsProcessed = curValProcessed; + } + } else { + lr.status = LossFixerResult.STATUS_FINISHED; + } + + copyFromGlobalResult(lfr); if (cb != null) cb.callback(lfr); } + public boolean processLossfix(ArrayList ccs) { + String[] results; + String[] requests; + StringBuilder[] sbs; + String[] posts; + + int i; + boolean first = true; + + posts = new String[RAIDA.TOTAL_RAIDA_COUNT]; + requests = new String[RAIDA.TOTAL_RAIDA_COUNT]; + sbs = new StringBuilder[RAIDA.TOTAL_RAIDA_COUNT]; + for (i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { + requests[i] = "fix_lost"; + sbs[i] = new StringBuilder(); + } + + for (CloudCoin cc : ccs) { + for (i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { + if (!first) + sbs[i].append("&"); + + sbs[i].append("nns[]="); + sbs[i].append(cc.nn); + + sbs[i].append("&sns[]="); + sbs[i].append(cc.sn); + + sbs[i].append("&denomination[]="); + sbs[i].append(cc.getDenomination()); + + sbs[i].append("&ans[]="); + sbs[i].append(cc.ans[i]); + + sbs[i].append("&pans[]="); + sbs[i].append(cc.pans[i]); + } + + first = false; + } + + for (i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { + posts[i] = sbs[i].toString(); + } + + results = raida.query(requests, posts, new CallbackInterface() { + final GLogger gl = logger; + final CallbackInterface myCb = cb; + + @Override + public void callback(Object result) { + lr.totalRAIDAProcessed++; + if (myCb != null) { + LossFixerResult lr = new LossFixerResult(); + copyFromGlobalResult(lr); + myCb.callback(lr); + } + } + }); + + if (results == null) { + logger.error(ltag, "Failed to query multi_detect"); + return false; + } + + CommonResponse errorResponse; + LossFixerResponse[][] lfrs; + Object[] o; + + lfrs = new LossFixerResponse[RAIDA.TOTAL_RAIDA_COUNT][]; + for (i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { + logger.info(ltag, "i="+i+ " r="+results[i]); + + if (results[i] != null) { + if (results[i].equals("")) { + logger.error(ltag, "Skipped raida" + i); + setCoinStatus(ccs, i, CloudCoin.STATUS_UNTRIED); + continue; + } + } + + o = parseArrayResponse(results[i], LossFixerResponse.class); + if (o == null) { + errorResponse = (CommonResponse) parseResponse(results[i], CommonResponse.class); + setCoinStatus(ccs, i, CloudCoin.STATUS_ERROR); + if (errorResponse == null) { + logger.error(ltag, "Failed to get error"); + continue; + } + + logger.error(ltag, "Failed to auth coin. Status: " + errorResponse.status); + continue; + } + + for (int j = 0; j < o.length; j++) { + String strStatus; + int status; + + lfrs[i] = new LossFixerResponse[o.length]; + lfrs[i][j] = (LossFixerResponse) o[j]; + + strStatus = lfrs[i][j].status; + + if (strStatus.equals("an")) { + status = CloudCoin.STATUS_PASS; + } else if (strStatus.equals("pan")) { + status = CloudCoin.STATUS_PASS; + ccs.get(j).ans[i] = ccs.get(j).pans[i]; + } else if (strStatus.equals("neither")) { + status = CloudCoin.STATUS_FAIL; + } else { + status = CloudCoin.STATUS_ERROR; + logger.error(ltag, "Unknown coin status from RAIDA" + i + ": " + strStatus); + } + + ccs.get(j).setDetectStatus(i, status); + logger.info(ltag, "raida" + i + " v=" + lfrs[i][j].status + " m="+lfrs[i][j].message + " j= " + j + " st=" + status); + } + } + + moveCoins(ccs); + + return true; + } + + private void setCoinStatus(ArrayList ccs, int idx, int status) { + for (CloudCoin cc : ccs) { + cc.setDetectStatus(idx, status); + } + } + /* public void doRecoverCoin(CloudCoin cc) { logger.debug(ltag, "Recovering " + cc.sn + " pown " + cc.getPownString()); @@ -321,29 +505,74 @@ public void callback(Object result) { lr.recoveredValue += cc.getDenomination(); addCoinToReceipt(cc, "bank", Config.DIR_BANK); } + */ - public void moveCoinToFracked(CloudCoin cc) { - String dir = AppCore.getUserDir(Config.DIR_FRACKED, user); - String file; + private void moveCoins(ArrayList ccs) { + for (CloudCoin cc : ccs) { + logger.debug(ltag, "pre cc " + cc.sn + " pown " + cc.getPownString()); + cc.setPownStringFromDetectStatus(); + logger.debug(ltag, "post cc " + cc.sn + " pown " + cc.getPownString()); + + int failed = 0; + for (int i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { + int status = cc.getDetectStatus(i); + + if (status == CloudCoin.STATUS_PASS) + continue; + + failed++; + } + + if (failed > RAIDA.TOTAL_RAIDA_COUNT - Config.PASS_THRESHOLD) { + logger.debug(ltag, "Coin " + cc.sn + " can't be restored: " + failed); + AppCore.moveToTrash(cc.originalFile, user); + addCoinToReceipt(cc, "counterfeit", Config.DIR_COUNTERFEIT); + lr.failed++; + continue; + } + + if (failed > 0) { + logger.debug(ltag, "Coin " + cc.sn + " move to fracked " + failed); + moveCoinToFracked(cc); + lr.recovered++; + lr.recoveredValue += cc.getDenomination(); + addCoinToReceipt(cc, "fracked", Config.DIR_FRACKED); + continue; + } + + moveCoin(cc); + logger.debug(ltag, "Moving to bank: " + cc.sn); + lr.recovered++; + lr.recoveredValue += cc.getDenomination(); + addCoinToReceipt(cc, "bank", Config.DIR_BANK); + + } + } + + public void moveCoin(CloudCoin cc) { + String dir = AppCore.getUserDir(Config.DIR_BANK, user); + String file; + file = dir + File.separator + cc.getFileName(); logger.info(ltag, "Saving coin " + file); + if (!AppCore.saveFile(file, cc.getJson(false))) { - logger.error(ltag, "Failed to move coin to Fracked: " + cc.getFileName()); + logger.error(ltag, "Failed to move coin to Bank: " + cc.getFileName()); return; } AppCore.moveToImported(cc.originalFile, user); } - - public void moveCoin(CloudCoin cc) { - String dir = AppCore.getUserDir(Config.DIR_BANK, user); + + public void moveCoinToFracked(CloudCoin cc) { + String dir = AppCore.getUserDir(Config.DIR_FRACKED, user); String file; file = dir + File.separator + cc.getFileName(); logger.info(ltag, "Saving coin " + file); if (!AppCore.saveFile(file, cc.getJson(false))) { - logger.error(ltag, "Failed to move coin to Bank: " + cc.getFileName()); + logger.error(ltag, "Failed to move coin to Fracked: " + cc.getFileName()); return; } diff --git a/src/advclient/common/LossFixer/LossFixerResult.java b/src/advclient/common/LossFixer/LossFixerResult.java index d451811..61efc59 100644 --- a/src/advclient/common/LossFixer/LossFixerResult.java +++ b/src/advclient/common/LossFixer/LossFixerResult.java @@ -10,6 +10,9 @@ public class LossFixerResult { public int totalFilesProcessed; public int totalFiles; public int totalRAIDAProcessed; + + public int totalCoins; + public int totalCoinsProcessed; public int recovered; diff --git a/src/advclient/common/core/Wallet.java b/src/advclient/common/core/Wallet.java index 6d18c39..82564bc 100644 --- a/src/advclient/common/core/Wallet.java +++ b/src/advclient/common/core/Wallet.java @@ -188,6 +188,9 @@ public void appendTransaction(String memo, int amount, String receiptId, String if (isSkyWallet()) return; + if (amount == 0) + return; + String fileName = getTransactionsFileName(); String rMemo = memo.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll(",", " "); //String sAmount = Integer.toString(amount); From c761dd40872698714216bcdf2a754da7945d2ad5 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 29 Aug 2019 10:55:11 +0300 Subject: [PATCH 044/160] config --- src/advclient/common/core/Config.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/advclient/common/core/Config.java b/src/advclient/common/core/Config.java index eb0d68b..f61e80c 100644 --- a/src/advclient/common/core/Config.java +++ b/src/advclient/common/core/Config.java @@ -40,16 +40,16 @@ public class Config { public static String DIR_MAIN_TRASH = "Trash"; public static String DIR_BACKUPS = "Backups"; - public static int THREAD_POOL_SIZE = 30; + public static int THREAD_POOL_SIZE = 60; - public static int READ_TIMEOUT = 30000; // ms + public static int READ_TIMEOUT = 40000; // ms public static int CONNECTION_TIMEOUT = 7000; // ms public static int REQUEST_CHANGE_READ_TIMEOUT = 50000; // ms - public static int FIX_FRACKED_TIMEOUT = 35000; // ms - public static int MULTI_FIX_TIMEOUT = 35000; // ms - public static int MULTI_DETECT_TIMEOUT = 35000; // ms + public static int FIX_FRACKED_TIMEOUT = 40000; // ms + public static int MULTI_FIX_TIMEOUT = 40000; // ms + public static int MULTI_DETECT_TIMEOUT = 40000; // ms public static int ECHO_TIMEOUT = 5000; From ad5501667523298c90b343607e89bf011b89df0a Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 29 Aug 2019 11:31:40 +0300 Subject: [PATCH 045/160] Exporting --- src/advclient/ProgramState.java | 1 + src/advclient/common/core/ServantManager.java | 4 +--- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/advclient/ProgramState.java b/src/advclient/ProgramState.java index 17ec917..43ddaea 100644 --- a/src/advclient/ProgramState.java +++ b/src/advclient/ProgramState.java @@ -57,6 +57,7 @@ public class ProgramState { final public static int SCREEN_MAKING_CHANGE = 39; final public static int SCREEN_SETTING_DNS_RECORD = 40; final public static int SCREEN_DOING_BACKUP = 41; + final public static int SCREEN_EXPORTING = 42; final static int CB_STATE_INIT = 1; diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index e42d45f..9b970fe 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -166,9 +166,7 @@ public void initWallets() { String[] wallets = AppCore.getDirs(); for (int i = 0; i < wallets.length; i++) { setActiveWallet(wallets[i]); - initWallet(wallets[i], ""); - - + initWallet(wallets[i], ""); } checkIDCoins(); From 8c2d18b3b0b51a903c23db5137073f4a3c33b665 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 29 Aug 2019 12:19:26 +0300 Subject: [PATCH 046/160] top menu behaviour --- src/advclient/AdvancedClient.java | 69 +++++++++++++++++++++++++++++-- src/advclient/ProgramState.java | 4 ++ 2 files changed, 69 insertions(+), 4 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index c7580fd..d84ca4e 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -56,7 +56,7 @@ * */ public class AdvancedClient { - String version = "2.1.12"; + String version = "2.1.13"; JPanel headerPanel; JPanel mainPanel; @@ -637,7 +637,7 @@ public void mouseExited(MouseEvent e) { final JLabel ficon = icon0; // Do stuff popup menu - final int mWidth = 212; + final int mWidth = 172; final int mHeight = 48; final JPopupMenu popupMenu = new JPopupMenu() { @Override @@ -656,6 +656,7 @@ public void paintComponent(final Graphics g) { MouseAdapter ma = new MouseAdapter() { public void mouseEntered(MouseEvent evt) { + ps.popupVisible = true; JMenuItem jMenuItem = (JMenuItem) evt.getSource(); jMenuItem.setBackground(AppUI.getColor2()); } @@ -663,6 +664,23 @@ public void mouseEntered(MouseEvent evt) { public void mouseExited(MouseEvent evt) { JMenuItem jMenuItem = (JMenuItem) evt.getSource(); jMenuItem.setBackground(AppUI.getColor1()); + + ps.popupVisible = false; + EventQueue.invokeLater(new Runnable() { + public void run(){ + try { + Thread.sleep(40); + } catch(InterruptedException ex) { + } + + if (ps.popupVisible) + return; + + ficon.setOpaque(false); + ficon.repaint(); + popupMenu.setVisible(false); + } + }); } public void mouseReleased(MouseEvent evt) { @@ -725,13 +743,14 @@ public void paint (final Graphics g, final JComponent c) { popupMenu.addPopupMenuListener(new PopupMenuListener() { @Override public void popupMenuWillBecomeVisible(final PopupMenuEvent e) { - + ps.popupVisible = true; } @Override public void popupMenuWillBecomeInvisible(final PopupMenuEvent e) { AppUI.setBackground(ficon, savedColor); ficon.setOpaque(false); ficon.repaint(); + ps.popupVisible = false; } @Override @@ -739,10 +758,12 @@ public void popupMenuCanceled(final PopupMenuEvent e) { AppUI.setBackground(ficon, savedColor); ficon.setOpaque(false); ficon.repaint(); + ps.popupVisible = false; } }); icon0.addMouseListener(new MouseAdapter() { + /* public void mouseReleased(MouseEvent e) { ficon.setOpaque(true); AppUI.setBackground(ficon, AppUI.getColor1()); @@ -750,6 +771,34 @@ public void mouseReleased(MouseEvent e) { ficon.repaint(); popupMenu.show(ficon, 0 - mWidth + ficon.getWidth(), ficon.getHeight()); } + */ + public void mouseEntered(MouseEvent e) { + ficon.setOpaque(true); + AppUI.setBackground(ficon, AppUI.getColor1()); + + ficon.repaint(); + popupMenu.show(ficon, 0 - mWidth + ficon.getWidth(), ficon.getHeight()); + + } + + public void mouseExited(MouseEvent e) { + ps.popupVisible = false; + EventQueue.invokeLater(new Runnable() { + public void run(){ + try { + Thread.sleep(40); + } catch(InterruptedException ex) { + } + + if (ps.popupVisible) + return; + + ficon.setOpaque(false); + ficon.repaint(); + popupMenu.setVisible(false); + } + }); + } }); @@ -924,7 +973,9 @@ public void showScreen() { case ProgramState.SCREEN_MAKING_CHANGE: showMakingChangeScreen(); break; - + case ProgramState.SCREEN_EXPORTING: + showExportingScreen(); + break; } Component[] cs = lwrapperPanel.getComponents(); @@ -2261,11 +2312,13 @@ public void actionPerformed(ActionEvent e) { sm.setActiveWalletObj(ps.srcWallet); if (ps.sendType == ProgramState.SEND_TYPE_FOLDER) { ps.isSkyDeposit = false; + ps.currentScreen = ProgramState.SCREEN_EXPORTING; if (ps.srcWallet.isEncrypted()) { sm.startSecureExporterService(Config.TYPE_STACK, ps.typedAmount, ps.typedMemo, ps.chosenFile, false, new ExporterCb()); } else { sm.startExporterService(Config.TYPE_STACK, ps.typedAmount, ps.typedMemo, ps.chosenFile, false, new ExporterCb()); } + showScreen(); } else if (ps.sendType == ProgramState.SEND_TYPE_WALLET) { ps.dstWallet.setPassword(ps.typedDstPassword); ps.currentScreen = ProgramState.SCREEN_SENDING; @@ -5054,6 +5107,13 @@ public void mouseExited(MouseEvent e) { rightPanel.add(gct); } + public void showExportingScreen() { + JPanel subInnerCore = getPanel("Exporting Coins. Please wait..."); + + AppUI.hr(subInnerCore, 4); + } + + public void showDoingBackupScreen() { JPanel subInnerCore = getPanel("Doing Backup. Please wait..."); @@ -6311,6 +6371,7 @@ public void run() { } sm.getActiveWallet().appendTransaction(ps.typedMemo, er.totalExported * -1, er.receiptId); + sm.getActiveWallet().setNotUpdated(); EventQueue.invokeLater(new Runnable() { public void run() { ps.isUpdatedWallets = false; diff --git a/src/advclient/ProgramState.java b/src/advclient/ProgramState.java index 43ddaea..a70ddab 100644 --- a/src/advclient/ProgramState.java +++ b/src/advclient/ProgramState.java @@ -140,6 +140,8 @@ public class ProgramState { boolean changeFromExport; + boolean popupVisible; + public ProgramState() { currentScreen = SCREEN_AGREEMENT; cwalletRecoveryRequested = cwalletPasswordRequested = false; @@ -202,6 +204,8 @@ public ProgramState() { changeFromExport = false; + popupVisible = false; + } public String toString() { From 245026ea5bf147d7832f4e95d8b1a4740af1c6e8 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 29 Aug 2019 12:41:21 +0300 Subject: [PATCH 047/160] text --- src/advclient/AdvancedClient.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index d84ca4e..a79a327 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -2112,7 +2112,7 @@ public void showConfirmDeleteWalletScreen() { MyTextField tf0 = null; if (dstWallet.isEncrypted() && ps.srcWallet.isSkyWallet()) { fname = new JLabel("Password"); - tf0 = new MyTextField("Dst Wallet Password"); + tf0 = new MyTextField("Wallet Password"); AppUI.getGBRow(subInnerCore, fname, tf0.getTextField(), y, gridbag); y++; } @@ -2154,7 +2154,7 @@ public void actionPerformed(ActionEvent e) { String wHash = dstWallet.getPasswordHash(); String providedHash = AppCore.getMD5(mtf0.getText()); if (wHash == null) { - ps.errText = "Dst Wallet is corrupted"; + ps.errText = "To Wallet is corrupted"; showScreen(); return; } @@ -3088,7 +3088,7 @@ public void actionPerformed(ActionEvent e) { String dstName = remoteWalledId.getText().trim(); if (ps.srcWallet.isSkyWallet() && ps.srcWallet.getName().equals(dstName)) { - ps.errText = "Src and Dst wallets cannot be the same"; + ps.errText = "Wallets cannot be the same"; showScreen(); return; } From 7f55966696af17af757db47bae0ed657e1edf360 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 29 Aug 2019 12:48:49 +0300 Subject: [PATCH 048/160] top color --- src/advclient/AdvancedClient.java | 2 +- src/advclient/AppUI.java | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index a79a327..17c5bc3 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -658,7 +658,7 @@ public void paintComponent(final Graphics g) { public void mouseEntered(MouseEvent evt) { ps.popupVisible = true; JMenuItem jMenuItem = (JMenuItem) evt.getSource(); - jMenuItem.setBackground(AppUI.getColor2()); + jMenuItem.setBackground(AppUI.getColor15()); } public void mouseExited(MouseEvent evt) { diff --git a/src/advclient/AppUI.java b/src/advclient/AppUI.java index f3d8cca..df44de4 100644 --- a/src/advclient/AppUI.java +++ b/src/advclient/AppUI.java @@ -200,6 +200,10 @@ public static Color getColor14() { return new Color(0x7E8084); } + public static Color getColor15() { + return new Color(0x224068); + } + public static Color getDisabledColor() { return new Color(0xCCCCCC); } From 37c42c4d23056ecc729dce3a5ed26bf2220ea3ce Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 29 Aug 2019 12:58:10 +0300 Subject: [PATCH 049/160] Error message --- src/advclient/AdvancedClient.java | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 17c5bc3..a0b2a5a 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -2792,7 +2792,10 @@ public void showTransferScreen() { final optRv rvFrom = setOptionsForWalletsCommon(false, false, true, null); if (rvFrom.idxs.length == 0) { - ps.errText = "No Wallets to Transfer From"; + fname = AppUI.wrapDiv("No Wallets to Transfer From"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + AppUI.GBPad(subInnerCore, y, gridbag); return; } @@ -3220,7 +3223,10 @@ public void showPredepositScreen() { subInnerCore.setLayout(gridbag); if (sm.getFirstNonSkyWallet() == null) { - ps.errText = "You have no Local Wallets"; + fname = AppUI.wrapDiv("You have no Local Wallets"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + AppUI.GBPad(subInnerCore, y, gridbag); return; } @@ -4670,13 +4676,8 @@ public void showTransactionsScreen() { AppUI.alignTop(invPanel); AppUI.setSize(invPanel, 520, 62); AppUI.setMargin(invPanel, 8, 8, 8, 20); - //AppUI.noOpaque(invPanel); hwrapper.add(invPanel); - - - - } updateTransactionWalletData(w); From 09e21b455f62991e1886031a43caa1aa060bed11 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Sat, 31 Aug 2019 13:22:04 +0300 Subject: [PATCH 050/160] verify SkyID coin --- src/advclient/AdvancedClient.java | 88 ++++++++++++++++++- src/advclient/ProgramState.java | 4 + .../common/Authenticator/Authenticator.java | 46 ++++++++-- src/advclient/common/core/AppCore.java | 15 +++- src/advclient/common/core/ServantManager.java | 8 ++ 5 files changed, 151 insertions(+), 10 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index a0b2a5a..4beecab 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -198,6 +198,12 @@ else if (total < 999999999) } } + public String getSkyIDError(Wallet w) { + return "Your Sky Coin ID " + w.getName() + " is not authentic. It is not safe to use it.

" + + "The Pown String is " + w.getIDCoin().getPownString() + "

Move the Coin to the Fracked folder of any Wallet and fix it"; + } + + public String getPickError(Wallet w) { String errText = "" + "Cannot make change

This version of software does not support making change
" @@ -1020,6 +1026,9 @@ private void setRAIDAProgressCoins(int raidaProcessed, int totalCoinsProcessed, pbar.setVisible(true); pbar.setValue(raidaProcessed); + if (totalCoins == 0) + return; + String stc = AppCore.formatNumber(totalCoinsProcessed); String tc = AppCore.formatNumber(totalCoins); @@ -1539,6 +1548,50 @@ public void run(){ return; } + CloudCoin skyCC = null; + if (ps.srcWallet.isSkyWallet()) { + ps.isCheckingSkyID = true; + skyCC = ps.srcWallet.getIDCoin(); + + pbarText.setText("Checking Your Source SkyWallet ID"); + pbarText.repaint(); + + sm.startAuthenticatorService(skyCC, new AuthenticatorForSkyCoinCb()); + while (ps.isCheckingSkyID) { + try { + Thread.sleep(300); + } catch (InterruptedException e) {} + } + + if (AppCore.getPassedCount(skyCC) != RAIDA.TOTAL_RAIDA_COUNT) { + ps.errText = getSkyIDError(ps.srcWallet); + showScreen(); + return; + } + } + + if (ps.dstWallet != null && ps.dstWallet.isSkyWallet()) { + ps.isCheckingSkyID = true; + skyCC = ps.dstWallet.getIDCoin(); + + pbarText.setText("Checking Your Destination SkyWallet ID"); + pbarText.repaint(); + + sm.startAuthenticatorService(skyCC, new AuthenticatorForSkyCoinCb()); + while (ps.isCheckingSkyID) { + try { + Thread.sleep(300); + } catch (InterruptedException e) {} + } + + if (AppCore.getPassedCount(skyCC) != RAIDA.TOTAL_RAIDA_COUNT) { + ps.errText = getSkyIDError(ps.dstWallet); + showScreen(); + return; + } + } + + String dstName = (ps.foundSN == 0) ? ps.dstWallet.getName() : "" + ps.foundSN; @@ -2176,7 +2229,7 @@ public void actionPerformed(ActionEvent e) { dstWallet.appendTransaction("Coin from Deleted Sky Wallet", ps.srcWallet.getIDCoin().getDenomination(), "skymove"); - String wname = ps.srcWallet.getSkyName(); + final String wname = ps.srcWallet.getSkyName(); String wdomain = ps.srcWallet.getDomain(); final DNSSn d = new DNSSn(wname, wdomain, wl); Thread t = new Thread(new Runnable() { @@ -6124,6 +6177,39 @@ public void run() { sm.startAuthenticatorService(new AuthenticatorCb()); } } + + class AuthenticatorForSkyCoinCb implements CallbackInterface { + public void callback(Object result) { + wl.debug(ltag, "AuthenticatorSkyCoin finished"); + + final Object fresult = result; + if (isWithdrawing()) + ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; + else + ps.currentScreen = ProgramState.SCREEN_IMPORT_DONE; + + final AuthenticatorResult ar = (AuthenticatorResult) fresult; + if (ar.status == AuthenticatorResult.STATUS_ERROR) { + EventQueue.invokeLater(new Runnable() { + public void run() { + ps.errText = "Failed to Authencticate SkyID Coin"; + showScreen(); + } + }); + ps.isCheckingSkyID = false; + return; + } else if (ar.status == AuthenticatorResult.STATUS_FINISHED) { + ps.isCheckingSkyID = false; + return; + } else if (ar.status == AuthenticatorResult.STATUS_CANCELLED) { + ps.isCheckingSkyID = false; + return; + } + + setRAIDAProgressCoins(ar.totalRAIDAProcessed, 0, 0); + } + } + class AuthenticatorCb implements CallbackInterface { public void callback(Object result) { diff --git a/src/advclient/ProgramState.java b/src/advclient/ProgramState.java index a70ddab..f46fe35 100644 --- a/src/advclient/ProgramState.java +++ b/src/advclient/ProgramState.java @@ -142,6 +142,8 @@ public class ProgramState { boolean popupVisible; + boolean isCheckingSkyID; + public ProgramState() { currentScreen = SCREEN_AGREEMENT; cwalletRecoveryRequested = cwalletPasswordRequested = false; @@ -206,6 +208,8 @@ public ProgramState() { popupVisible = false; + isCheckingSkyID = false; + } public String toString() { diff --git a/src/advclient/common/Authenticator/Authenticator.java b/src/advclient/common/Authenticator/Authenticator.java index b5e8bcd..6bf1b38 100644 --- a/src/advclient/common/Authenticator/Authenticator.java +++ b/src/advclient/common/Authenticator/Authenticator.java @@ -44,9 +44,36 @@ public void run() { }); } + public void launch(CloudCoin cc, CallbackInterface icb) { + this.cb = icb; + final CloudCoin fcc = cc; + + globalResult = new AuthenticatorResult(); + launchThread(new Runnable() { + @Override + public void run() { + logger.info(ltag, "RUN CloudCoin Authenticator for " + fcc.sn); + + ArrayList ccs = new ArrayList(); + ccs.add(fcc); + + AuthenticatorResult ar = new AuthenticatorResult(); + if (!processDetect(ccs, false)) { + logger.error(ltag, "Failed to detect"); + globalResult.status = AuthenticatorResult.STATUS_ERROR; + } else { + globalResult.status = AuthenticatorResult.STATUS_FINISHED; + } + + copyFromGlobalResult(ar); + if (cb != null) + cb.callback(ar); + } + }); + } + public void setConfig() { logger.debug(ltag, "Setting config"); - //putConfigValue("max-coins-to-multi-detect", "" + Config.DEFAULT_MAX_COINS_MULTIDETECT); } private void copyFromGlobalResult(AuthenticatorResult aResult) { @@ -65,7 +92,7 @@ private void setCoinStatus(ArrayList ccs, int idx, int status) { } } - public boolean processDetect(ArrayList ccs) { + public boolean processDetect(ArrayList ccs, boolean needGeneratePans) { String[] results; String[] requests; StringBuilder[] sbs; @@ -83,7 +110,10 @@ public boolean processDetect(ArrayList ccs) { } for (CloudCoin cc : ccs) { - cc.generatePans(this.email); + if (needGeneratePans) + cc.generatePans(this.email); + else + cc.setPansToAns(); for (i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { if (!first) @@ -143,7 +173,7 @@ public void callback(Object result) { if (results[i] != null) { if (results[i].equals("")) { logger.error(ltag, "Skipped raida" + i); - setCoinStatus(ccs, i, CloudCoin.STATUS_UNTRIED); + setCoinStatus(ccs, i, CloudCoin.STATUS_ERROR); continue; } } @@ -184,8 +214,6 @@ public void callback(Object result) { } } - moveCoins(ccs); - return true; } @@ -318,7 +346,7 @@ public void doAuthencticate() { logger.info(ltag, "Processing"); AuthenticatorResult ar = new AuthenticatorResult(); - if (!processDetect(ccs)) { + if (!processDetect(ccs, true)) { moveCoinsToLost(ccs); globalResult.status = AuthenticatorResult.STATUS_ERROR; copyFromGlobalResult(ar); @@ -328,6 +356,7 @@ public void doAuthencticate() { return; } + moveCoins(ccs); ccs.clear(); globalResult.totalRAIDAProcessed = 0; @@ -343,10 +372,11 @@ public void doAuthencticate() { AuthenticatorResult ar = new AuthenticatorResult(); if (ccs.size() > 0) { logger.info(ltag, "adding + " + ccs.size()); - if (!processDetect(ccs)) { + if (!processDetect(ccs, true)) { moveCoinsToLost(ccs); globalResult.status = AuthenticatorResult.STATUS_ERROR; } else { + moveCoins(ccs); globalResult.status = AuthenticatorResult.STATUS_FINISHED; globalResult.totalFilesProcessed += ccs.size(); globalResult.totalCoinsProcessed = curValProcessed; diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index 41d551d..ef2e036 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -1023,5 +1023,18 @@ public static String getRAIDAString(int idx) { return sidx + " " + countries[idx]; } - + + public static int getPassedCount(CloudCoin cc) { + int passed = 0; + + for (int i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { + if (cc.getDetectStatus(i) == CloudCoin.STATUS_PASS) + passed++; + } + + cc.setPownStringFromDetectStatus(); + logger.debug(ltag, "Passed count " + passed + " cc " + cc.sn + " pown=" + cc.getPownString()); + + return passed; + } } diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index 9b970fe..7a88339 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -308,6 +308,14 @@ public void startAuthenticatorService(CallbackInterface cb) { at.launch(cb); } + public void startAuthenticatorService(CloudCoin cc, CallbackInterface cb) { + if (sr.isRunning("Authenticator")) + return; + + Authenticator at = (Authenticator) sr.getServant("Authenticator"); + at.launch(cc, cb); + } + public void startGraderService(CallbackInterface cb, ArrayList duplicates, String source) { if (sr.isRunning("Grader")) return; From d0f54eb4886d090ad9b9bf19dc5cefc08b461c39 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 2 Sep 2019 09:37:49 +0300 Subject: [PATCH 051/160] first wallet by default --- src/advclient/AdvancedClient.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 4beecab..5d2ef0b 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -843,7 +843,8 @@ public void resetState() { return; if (sm.getWallets().length != 0) { - ps.currentScreen = ProgramState.SCREEN_DEFAULT; + setActiveWallet(sm.getWallets()[0]); + ps.currentScreen = ProgramState.SCREEN_SHOW_TRANSACTIONS; } } @@ -4762,7 +4763,7 @@ public void showTransactionsScreen() { if (isSky) { Hashtable envelopes = sm.getActiveWallet().getEnvelopes(); - thlabel.setText("Skywallet Contents. Click Deposit to Download"); + thlabel.setText("Skywallet Contents. Click Transfer to Download"); if (envelopes == null || envelopes.size() == 0) { thlabel.setText("No Coins"); return; From fb4d3729a13530e4394fa1ede4e0860e1a0bd84e Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 2 Sep 2019 12:34:40 +0300 Subject: [PATCH 052/160] existing skywallet check --- src/advclient/AdvancedClient.java | 123 +++++++++++++++--- src/advclient/ProgramState.java | 1 + src/advclient/common/core/ServantManager.java | 12 +- 3 files changed, 118 insertions(+), 18 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 5d2ef0b..629126a 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -198,9 +198,9 @@ else if (total < 999999999) } } - public String getSkyIDError(Wallet w) { - return "Your Sky Coin ID " + w.getName() + " is not authentic. It is not safe to use it.

" - + "The Pown String is " + w.getIDCoin().getPownString() + "

Move the Coin to the Fracked folder of any Wallet and fix it"; + public String getSkyIDError(String name, String pownString) { + return "Your Sky Coin ID " + name + " is not authentic. It is not safe to use it.

" + + "The Pown String is " + pownString + "

Move the Coin to the Fracked folder of any Wallet and fix it"; } @@ -982,7 +982,11 @@ public void showScreen() { break; case ProgramState.SCREEN_EXPORTING: showExportingScreen(); - break; + break; + case ProgramState.SCREEN_CHECKING_SKYID: + showCheckingSkyIDScreen(); + break; + } Component[] cs = lwrapperPanel.getComponents(); @@ -1020,6 +1024,9 @@ public void maybeShowError(JPanel p) { if (ps.dstWallet != null) ps.dstWallet.setNotUpdated(); + + p.revalidate(); + p.repaint(); } } @@ -1565,7 +1572,7 @@ public void run(){ } if (AppCore.getPassedCount(skyCC) != RAIDA.TOTAL_RAIDA_COUNT) { - ps.errText = getSkyIDError(ps.srcWallet); + ps.errText = getSkyIDError(ps.srcWallet.getName(), ps.srcWallet.getIDCoin().getPownString()); showScreen(); return; } @@ -1586,7 +1593,7 @@ public void run(){ } if (AppCore.getPassedCount(skyCC) != RAIDA.TOTAL_RAIDA_COUNT) { - ps.errText = getSkyIDError(ps.dstWallet); + ps.errText = getSkyIDError(ps.srcWallet.getName(), ps.srcWallet.getIDCoin().getPownString()); showScreen(); return; } @@ -5162,6 +5169,53 @@ public void mouseExited(MouseEvent e) { rightPanel.add(gct); } + public void showCheckingSkyIDScreen() { + JPanel subInnerCore = getPanel("Checking your Sky Wallet ID Coin..."); + + JPanel ct = new JPanel(); + AppUI.noOpaque(ct); + subInnerCore.add(ct); + + GridBagLayout gridbag = new GridBagLayout(); + GridBagConstraints c = new GridBagConstraints(); + ct.setLayout(gridbag); + + c.anchor = GridBagConstraints.CENTER; + c.insets = new Insets(10, 0, 4, 0); + c.gridx = GridBagConstraints.RELATIVE; + c.gridy = 0; + + pbarText = new JLabel(""); + AppUI.setCommonFont(pbarText); + c.insets = new Insets(40, 20, 4, 0); + c.gridx = GridBagConstraints.RELATIVE; + c.gridy = 1; + gridbag.setConstraints(pbarText, c); + ct.add(pbarText); + + // ProgressBar + pbar = new JProgressBar(); + pbar.setStringPainted(true); + AppUI.setMargin(pbar, 0); + AppUI.setSize(pbar, (int) (tw / 2.6f) , 50); + pbar.setMinimum(0); + pbar.setMaximum(24); + pbar.setValue(0); + pbar.setUI(new FancyProgressBar()); + AppUI.noOpaque(pbar); + + c.insets = new Insets(20, 20, 4, 0); + c.gridx = GridBagConstraints.RELATIVE; + c.gridy = 2; + gridbag.setConstraints(pbar, c); + ct.add(pbar); + + + AppUI.hr(subInnerCore, 4); + } + + + public void showExportingScreen() { JPanel subInnerCore = getPanel("Exporting Coins. Please wait..."); @@ -5314,7 +5368,7 @@ public void actionPerformed(ActionEvent e) { return; } - final String newFileName = domain + ".stack"; + final String newFileName = domain + "." + ps.trustedServer + ".stack"; final DNSSn d = new DNSSn(domain, ps.trustedServer, wl); int sn = d.getSN(); @@ -5363,17 +5417,54 @@ public void run(){ showScreen(); return; } - } - - if (!AppCore.moveToFolderNewName(ps.chosenFile, AppCore.getIDDir(), null, newFileName)) { - ps.errText = "Failed to move coin"; + + final CloudCoin fcc = cc; + final String wname = domain + "." + ps.trustedServer; + sm.startAuthenticatorService(fcc, new CallbackInterface() { + public void callback(Object result) { + wl.debug(ltag, "AuthenticatorSkyCoin finished"); + + final Object fresult = result; + final AuthenticatorResult ar = (AuthenticatorResult) fresult; + if (ar.status == AuthenticatorResult.STATUS_ERROR || ar.status == AuthenticatorResult.STATUS_CANCELLED) { + ps.errText = "Failed to check your Coin"; + showScreen(); + return; + } else if (ar.status == AuthenticatorResult.STATUS_FINISHED) { + ps.isCheckingSkyID = false; + } else { + setRAIDAProgressCoins(ar.totalRAIDAProcessed, 0, 0); + return; + } + + if (AppCore.getPassedCount(fcc) != RAIDA.TOTAL_RAIDA_COUNT) { + ps.currentScreen = ProgramState.SCREEN_SKY_WALLET_CREATED; + ps.errText = getSkyIDError(wname, fcc.getPownString()); + showScreen(); + return; + } + + if (!AppCore.moveToFolderNewName(ps.chosenFile, AppCore.getIDDir(), null, newFileName)) { + ps.errText = "Failed to move coin"; + showScreen(); + return; + } + + SwingUtilities.invokeLater(new Runnable() { + public void run() { + sm.initWallets(); + ps.currentScreen = ProgramState.SCREEN_SKY_WALLET_CREATED; + showScreen(); + } + }); + + } + }); + + ps.currentScreen = ProgramState.SCREEN_CHECKING_SKYID; showScreen(); - return; + } - - sm.initWallets(); - ps.currentScreen = ProgramState.SCREEN_SKY_WALLET_CREATED; - showScreen(); } }, y, gridbag); diff --git a/src/advclient/ProgramState.java b/src/advclient/ProgramState.java index f46fe35..1141755 100644 --- a/src/advclient/ProgramState.java +++ b/src/advclient/ProgramState.java @@ -58,6 +58,7 @@ public class ProgramState { final public static int SCREEN_SETTING_DNS_RECORD = 40; final public static int SCREEN_DOING_BACKUP = 41; final public static int SCREEN_EXPORTING = 42; + final public static int SCREEN_CHECKING_SKYID = 43; final static int CB_STATE_INIT = 1; diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index 7a88339..8ebf65d 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -185,8 +185,16 @@ public void checkIDCoins() { continue; } - String wname = idCoins[i].substring(0, idCoins[i].lastIndexOf('.')); - wname += "." + Config.DDNS_DOMAIN; + int dots = 0; + + String wname = idCoins[i].substring(0, idCoins[i].indexOf('.')); + for (int y = 0; y < wname.length(); y++) { + if (wname.charAt(y) == '.') + dots++; + } + + if (dots <= 2) + wname += "." + Config.DDNS_DOMAIN; initCloudWallet(cc, wname); } From 4fa810220a8dbeaac4d180654fdc545ed7d2f464 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 2 Sep 2019 18:17:45 +0300 Subject: [PATCH 053/160] rm revalidate --- src/advclient/AdvancedClient.java | 8 ++++---- src/advclient/RoundedBorder.java | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 629126a..2579155 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -1000,11 +1000,11 @@ public void showScreen() { } - headerPanel.repaint(); - headerPanel.revalidate(); + // headerPanel.repaint(); + // headerPanel.revalidate(); - corePanel.repaint(); - corePanel.revalidate(); + // corePanel.repaint(); + // corePanel.revalidate(); } public void maybeShowError(JPanel p) { diff --git a/src/advclient/RoundedBorder.java b/src/advclient/RoundedBorder.java index adafe67..9ef42f2 100644 --- a/src/advclient/RoundedBorder.java +++ b/src/advclient/RoundedBorder.java @@ -57,7 +57,7 @@ public void setColor(Color color) { public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { Graphics2D g2 = (Graphics2D) g.create(); - + g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); //g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, color.getAlpha())); g2.setColor(this.color); From e478613a7597f880aa4fd3bcb4fdaf136e5af43e Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Tue, 3 Sep 2019 16:20:36 +0300 Subject: [PATCH 054/160] placeholder --- src/advclient/AdvancedClient.java | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 2579155..8ac74a6 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -1963,6 +1963,8 @@ public void showImportDoneScreen() { MyTextField walletName = null; ps.dstWallet.setNotUpdated(); + if (ps.srcWallet != null) + ps.srcWallet.setNotUpdated(); subInnerCore = getPanel("Deposit Complete"); GridBagLayout gridbag = new GridBagLayout(); @@ -5270,7 +5272,7 @@ public void showCreateSkyWalletScreen() { y++; fname = new JLabel("Your Proposed Address"); - final MyTextField tf0 = new MyTextField("JohnDoe.SkyWallet.cc", false); + final MyTextField tf0 = new MyTextField("JohnDoe", false); if (!ps.skyVaultDomain.isEmpty()) tf0.setData(ps.skyVaultDomain); AppUI.getGBRow(subInnerCore, fname, tf0.getTextField(), y, gridbag); From 7cc22ca50d31ace9cb8c19609bc6fbb53ba0cdea Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 6 Sep 2019 11:30:02 +0300 Subject: [PATCH 055/160] Settings --- src/advclient/AdvancedClient.java | 209 ++++++++++++++++++++++- src/advclient/ProgramState.java | 2 + src/advclient/common/core/AppCore.java | 90 +++++++++- src/advclient/common/core/Config.java | 24 ++- src/advclient/common/core/DNSSn.java | 4 +- src/advclient/common/core/Validator.java | 16 +- 6 files changed, 331 insertions(+), 14 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 8ac74a6..7ea8e81 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -56,7 +56,7 @@ * */ public class AdvancedClient { - String version = "2.1.13"; + String version = "2.1.14"; JPanel headerPanel; JPanel mainPanel; @@ -135,9 +135,8 @@ public void initSystem() { ps.errText = "Failed to init program. Make sure you have correct folder permissions (" + home + ")"; return; } - - - + + AppCore.readConfig(); resetState(); } @@ -654,7 +653,7 @@ public void paintComponent(final Graphics g) { }; String[] items = {"Backup", "List serials", "Clear History", "Fix Fracked", - "Delete Wallet", "Show Folders", "Echo RAIDA"}; + "Delete Wallet", "Show Folders", "Echo RAIDA", "Settings"}; for (int i = 0; i < items.length; i++) { JMenuItem menuItem = new JMenuItem(items[i]); menuItem.setActionCommand("" + i); @@ -710,6 +709,8 @@ public void mouseReleased(MouseEvent evt) { ps.currentScreen = ProgramState.SCREEN_SHOW_FOLDERS; } else if (action.equals("6")) { ps.currentScreen = ProgramState.SCREEN_ECHO_RAIDA; + } else if (action.equals("7")) { + ps.currentScreen = ProgramState.SCREEN_SETTINGS; } showScreen(); } @@ -986,7 +987,12 @@ public void showScreen() { case ProgramState.SCREEN_CHECKING_SKYID: showCheckingSkyIDScreen(); break; - + case ProgramState.SCREEN_SETTINGS: + showSettingsScreen(); + break; + case ProgramState.SCREEN_SETTINGS_SAVED: + showSettingsDoneScreen(); + break; } Component[] cs = lwrapperPanel.getComponents(); @@ -2023,6 +2029,191 @@ public void actionPerformed(ActionEvent e) { } + + + public void showSettingsScreen() { + int y = 0; + JLabel fname; + MyTextField walletName = null; + + JPanel subInnerCore = getPanel("Settings"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + fname = new JLabel("Echo Timeout, s"); + final MyTextField echoTimeout = new MyTextField("Echo Timeout", false); + AppUI.getGBRow(subInnerCore, fname, echoTimeout.getTextField(), y, gridbag); + echoTimeout.setData(Integer.toString(Config.ECHO_TIMEOUT / 1000)); + y++; + + fname = new JLabel("Send/Receive Timeout, s "); + final MyTextField readTimeout = new MyTextField("Send/Receive Timeout", false); + AppUI.getGBRow(subInnerCore, fname, readTimeout.getTextField(), y, gridbag); + readTimeout.setData(Integer.toString(Config.READ_TIMEOUT / 1000)); + y++; + + fname = new JLabel("Detect Timeout, s"); + final MyTextField detectTimeout = new MyTextField("Detect Timeout", false); + AppUI.getGBRow(subInnerCore, fname, detectTimeout.getTextField(), y, gridbag); + detectTimeout.setData(Integer.toString(Config.MULTI_DETECT_TIMEOUT / 1000)); + y++; + + fname = new JLabel("Fix Timeout, s"); + final MyTextField fixTimeout = new MyTextField("Fix Timeout", false); + AppUI.getGBRow(subInnerCore, fname, fixTimeout.getTextField(), y, gridbag); + fixTimeout.setData(Integer.toString(Config.FIX_FRACKED_TIMEOUT / 1000)); + y++; + + fname = new JLabel("Max Notes"); + final MyTextField maxNotes = new MyTextField("Max Notes", false); + AppUI.getGBRow(subInnerCore, fname, maxNotes.getTextField(), y, gridbag); + maxNotes.setData(Integer.toString(Config.DEFAULT_MAX_COINS_MULTIDETECT)); + y++; + + fname = new JLabel("DDNS Server"); + final MyTextField ddnsServer = new MyTextField("DDNS Server", false); + AppUI.getGBRow(subInnerCore, fname, ddnsServer.getTextField(), y, gridbag); + ddnsServer.setData(Config.DDNSSN_SERVER); + y++; + + fname = new JLabel("Export Folder"); + final JFileChooser chooser = new JFileChooser(); + chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + chooser.setAcceptAllFileFilterUsed(false); + + final MyTextField localFolder = new MyTextField("Export Folder", false, true); + localFolder.setFilepickerListener(new MouseAdapter() { + @Override + public void mouseReleased(MouseEvent e) { + if (!Config.DEFAULT_EXPORT_DIR.isEmpty()) + chooser.setCurrentDirectory(new File(Config.DEFAULT_EXPORT_DIR)); + + int returnVal = chooser.showOpenDialog(null); + if (returnVal == JFileChooser.APPROVE_OPTION) { + ps.chosenFile = chooser.getSelectedFile().getAbsolutePath(); + localFolder.setData(chooser.getSelectedFile().getAbsolutePath()); + } + } + }); + + localFolder.setData(new File(Config.DEFAULT_EXPORT_DIR).getAbsolutePath()); + AppUI.getGBRow(subInnerCore, fname, localFolder.getTextField(), y, gridbag); + y++; + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Save", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { + public void actionPerformed(ActionEvent e) { + int echot = Validator.getIntFromString(echoTimeout.getText(), Config.MIN_ECHO_TIMEOUT / 1000, Config.MAX_ECHO_TIMEOUT / 1000); + if (echot < 0) { + ps.errText = "Echo timeout must be in the range (" + Config.MIN_ECHO_TIMEOUT/1000 + ", " + Config.MAX_ECHO_TIMEOUT + ")"; + showScreen(); + return; + } + + int detectt = Validator.getIntFromString(detectTimeout.getText(), Config.MIN_DETECT_TIMEOUT / 1000, Config.MAX_DETECT_TIMEOUT / 1000); + if (detectt < 0) { + ps.errText = "Detect timeout must be in the range (" + Config.MIN_DETECT_TIMEOUT/1000 + ", " + Config.MAX_DETECT_TIMEOUT + ")"; + showScreen(); + return; + } + + int fixt = Validator.getIntFromString(fixTimeout.getText(), Config.MIN_FIX_TIMEOUT / 1000, Config.MAX_FIX_TIMEOUT / 1000); + if (fixt < 0) { + ps.errText = "Fix timeout must be in the range (" + Config.MIN_FIX_TIMEOUT/1000 + ", " + Config.MAX_FIX_TIMEOUT + ")"; + showScreen(); + return; + } + + int readt = Validator.getIntFromString(readTimeout.getText(), Config.MIN_READ_TIMEOUT / 1000, Config.MAX_READ_TIMEOUT / 1000); + if (fixt < 0) { + ps.errText = "Send/Receive timeout must be in the range (" + Config.MIN_READ_TIMEOUT/1000 + ", " + Config.MAX_READ_TIMEOUT/1000 + ")"; + showScreen(); + return; + } + + int notes = Validator.getIntFromString(maxNotes.getText(), Config.MIN_MULTI_NOTES, Config.MAX_MULTI_NOTES); + if (notes < 0) { + ps.errText = "Send/Receive timeout must be in the range (" + Config.MIN_MULTI_NOTES + ", " + Config.MAX_MULTI_NOTES + ")"; + showScreen(); + return; + } + + String ddnssn = ddnsServer.getText(); + if (!Validator.domain(ddnssn)) { + ps.errText = "Invalid DDNS Server"; + showScreen(); + return; + } + + Config.DDNSSN_SERVER = ddnssn; + Config.DEFAULT_EXPORT_DIR = ps.chosenFile.replace("\"", "\\\"").replace("\\", "\\\\"); + Config.DEFAULT_MAX_COINS_MULTIDETECT = notes; + Config.FIX_FRACKED_TIMEOUT = fixt * 1000; + Config.MULTI_DETECT_TIMEOUT = detectt * 1000; + Config.READ_TIMEOUT = readt * 1000; + Config.ECHO_TIMEOUT = echot * 1000; + + if (AppCore.writeConfig() == false) { + ps.errText = "Failed to write config file"; + showScreen(); + return; + } + + ps.currentScreen = ProgramState.SCREEN_SETTINGS_SAVED; + showScreen(); + + } + }, y, gridbag); + + } + + + public void showSettingsDoneScreen() { + boolean isError = !ps.errText.equals(""); + JPanel subInnerCore; + + if (isError) { + subInnerCore = getPanel("Error"); + resetState(); + return; + } + + int y = 0; + JLabel fname, value; + + subInnerCore = getPanel("Settings"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + String txt = "Configuration Saved"; + + fname = AppUI.wrapDiv(txt); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + AppUI.getTwoButtonPanel(subInnerCore, "", "Continue", null, new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, y, gridbag); + + + resetState(); + } + + + public void showDeleteWalletDoneScreen() { boolean isError = !ps.errText.equals(""); JPanel subInnerCore; @@ -2913,6 +3104,9 @@ public void showTransferScreen() { localFolder.setFilepickerListener(new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { + if (!Config.DEFAULT_EXPORT_DIR.isEmpty()) + chooser.setCurrentDirectory(new File(Config.DEFAULT_EXPORT_DIR)); + int returnVal = chooser.showOpenDialog(null); if (returnVal == JFileChooser.APPROVE_OPTION) { ps.chosenFile = chooser.getSelectedFile().getAbsolutePath(); @@ -5469,8 +5663,7 @@ public void run() { } } }, y, gridbag); - - + } public void showCreateWalletScreen() { diff --git a/src/advclient/ProgramState.java b/src/advclient/ProgramState.java index 1141755..312de37 100644 --- a/src/advclient/ProgramState.java +++ b/src/advclient/ProgramState.java @@ -59,6 +59,8 @@ public class ProgramState { final public static int SCREEN_DOING_BACKUP = 41; final public static int SCREEN_EXPORTING = 42; final public static int SCREEN_CHECKING_SKYID = 43; + final public static int SCREEN_SETTINGS = 44; + final public static int SCREEN_SETTINGS_SAVED = 45; final static int CB_STATE_INIT = 1; diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index ef2e036..be1ce1b 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -1034,7 +1034,95 @@ public static int getPassedCount(CloudCoin cc) { cc.setPownStringFromDetectStatus(); logger.debug(ltag, "Passed count " + passed + " cc " + cc.sn + " pown=" + cc.getPownString()); - + return passed; } + + + public static void readConfig() { + String globalConfigFilename = rootPath + File.separator + Config.GLOBAL_CONFIG_FILENAME; + + logger.debug(ltag, "Reading config file " + globalConfigFilename); + + String data = AppCore.loadFile(globalConfigFilename); + if (data == null) { + logger.debug(ltag, "Failed to read config file. Maybe it doesn't exist yet"); + return; + } + + String os; + int oi; + try { + JSONObject o = new JSONObject(data); + + oi = o.optInt("echo_timeout", -1); + if (oi != -1) { + logger.debug(ltag, "Echo timeout: " + oi); + Config.ECHO_TIMEOUT = oi; + } + + oi = o.optInt("read_timeout", -1); + if (oi != -1) { + logger.debug(ltag, "Read timeout: " + oi); + Config.READ_TIMEOUT = oi; + } + + oi = o.optInt("detect_timeout", -1); + if (oi != -1) { + logger.debug(ltag, "Detect timeout: " + oi); + Config.MULTI_DETECT_TIMEOUT = oi; + } + + oi = o.optInt("fix_timeout", -1); + if (oi != -1) { + logger.debug(ltag, "Fix timeout: " + oi); + Config.FIX_FRACKED_TIMEOUT = oi; + } + + oi = o.optInt("max_coins", -1); + if (oi != -1) { + logger.debug(ltag, "Max coins: " + oi); + Config.DEFAULT_MAX_COINS_MULTIDETECT = oi; + } + + os = o.optString("export_dir"); + if (os != null) { + logger.debug(ltag, "Export dir: " + os); + Config.DEFAULT_EXPORT_DIR = os; + } + + os = o.optString("ddnssn_server"); + if (os != null) { + logger.debug(ltag, "DDNSSN Server: " + os); + Config.DDNSSN_SERVER = os; + } + } catch (JSONException e) { + logger.error(ltag, "Failed to parse config file: " + e.getMessage()); + return; + } + + } + + public static boolean writeConfig() { + String globalConfigFilename = rootPath + File.separator + Config.GLOBAL_CONFIG_FILENAME; + + logger.debug(ltag, "Saving config " + globalConfigFilename); + + String edir = Config.DEFAULT_EXPORT_DIR.replace("\"", "\\\""); + String data = "{\"echo_timeout\":" + Config.ECHO_TIMEOUT + ", " + + "\"detect_timeout\": " + Config.MULTI_DETECT_TIMEOUT + ", " + + "\"read_timeout\": " + Config.READ_TIMEOUT + ", " + + "\"fix_timeout\": " + Config.FIX_FRACKED_TIMEOUT + ", " + + "\"max_coins\": " + Config.DEFAULT_MAX_COINS_MULTIDETECT + ", " + + "\"export_dir\": \"" + edir + "\", " + + "\"ddnssn_server\": \"" + Config.DDNSSN_SERVER + "\"" + + "}"; + + File f = new File(globalConfigFilename); + f.delete(); + + return AppCore.saveFile(globalConfigFilename, data); + } + + } diff --git a/src/advclient/common/core/Config.java b/src/advclient/common/core/Config.java index f61e80c..590017c 100644 --- a/src/advclient/common/core/Config.java +++ b/src/advclient/common/core/Config.java @@ -40,6 +40,7 @@ public class Config { public static String DIR_MAIN_TRASH = "Trash"; public static String DIR_BACKUPS = "Backups"; + public static String GLOBAL_CONFIG_FILENAME = "global.config"; public static int THREAD_POOL_SIZE = 60; public static int READ_TIMEOUT = 40000; // ms @@ -48,7 +49,7 @@ public class Config { public static int REQUEST_CHANGE_READ_TIMEOUT = 50000; // ms public static int FIX_FRACKED_TIMEOUT = 40000; // ms - public static int MULTI_FIX_TIMEOUT = 40000; // ms + //public static int MULTI_FIX_TIMEOUT = 40000; // ms public static int MULTI_DETECT_TIMEOUT = 40000; // ms public static int ECHO_TIMEOUT = 5000; @@ -71,6 +72,7 @@ public class Config { public static String REQUEST_STATUS_FAIL = "fail"; + public static String DEFAULT_EXPORT_DIR = ""; public static int MAX_ALLOWED_LATENCY = 20000; @@ -142,7 +144,7 @@ public class Config { final public static String DDNS_DOMAIN = "skywallet.cc"; - final public static String DDNSSN_SERVER = "https://ddns.cloudcoin.global"; + public static String DDNSSN_SERVER = "ddns.cloudcoin.global"; final public static String MAIN_LOG_FILENAME = "main.log"; @@ -155,4 +157,22 @@ public class Config { final public static String AGREEMENT_FILE = "agreement.html"; final public static int LOG_BUFFER_SIZE = 1024000; + + + final public static int MIN_MULTI_NOTES = 10; + final public static int MAX_MULTI_NOTES = 4000; + + final public static int MIN_ECHO_TIMEOUT = 2000; + final public static int MAX_ECHO_TIMEOUT = 120000; + + final public static int MIN_DETECT_TIMEOUT = 2000; + final public static int MAX_DETECT_TIMEOUT = 120000; + + final public static int MIN_FIX_TIMEOUT = 2000; + final public static int MAX_FIX_TIMEOUT = 120000; + + final public static int MIN_READ_TIMEOUT = 4000; + final public static int MAX_READ_TIMEOUT = 120000; + + } diff --git a/src/advclient/common/core/DNSSn.java b/src/advclient/common/core/DNSSn.java index caa983d..ae28396 100644 --- a/src/advclient/common/core/DNSSn.java +++ b/src/advclient/common/core/DNSSn.java @@ -116,7 +116,7 @@ public boolean setRecord(String path, ServantRegistry sr) { String rq = "/ddns.php?sn=" + cc.sn + "&username=" + name + "&ticket=" + message + "&raidanumber=" + raidaNum; DetectionAgent daFake = new DetectionAgent(RAIDA.TOTAL_RAIDA_CNT * 10000, logger); - daFake.setExactFullUrl(Config.DDNSSN_SERVER + "/service/ddns"); + daFake.setExactFullUrl("https://" + Config.DDNSSN_SERVER + "/service/ddns"); String result = daFake.doRequest(rq, null); if (result == null) { logger.error(ltag, "Failed to receive response from DDNSSN Server"); @@ -144,7 +144,7 @@ public boolean deleteRecord(String name, CloudCoin cc, ServantRegistry sr) { String rq = "/ddns_delete.php?sn=" + cc.sn + "&username=" + name + "&ticket=" + message + "&raidanumber=" + raidaNum; DetectionAgent daFake = new DetectionAgent(RAIDA.TOTAL_RAIDA_CNT * 10000, logger); - daFake.setExactFullUrl(Config.DDNSSN_SERVER + "/service/ddns"); + daFake.setExactFullUrl("https://" + Config.DDNSSN_SERVER + "/service/ddns"); String result = daFake.doRequest(rq, null); if (result == null) { logger.error(ltag, "Failed to receive response from DDNSSN Server"); diff --git a/src/advclient/common/core/Validator.java b/src/advclient/common/core/Validator.java index 5c182c7..cc64020 100644 --- a/src/advclient/common/core/Validator.java +++ b/src/advclient/common/core/Validator.java @@ -51,5 +51,19 @@ public static boolean domain(String domain) { return m.matches(); } - + + public static int getIntFromString(String val, int min, int max) { + int rv; + + try { + rv = Integer.parseInt(val); + } catch (NumberFormatException e) { + return -1; + } + + if (rv < min || rv > max) + return -1; + + return rv; + } } From 447d4f1418961be0c66258e59dcc0ec6d0dc98d7 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 6 Sep 2019 11:54:15 +0300 Subject: [PATCH 056/160] Settings --- src/advclient/AdvancedClient.java | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 7ea8e81..43de4ff 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -2145,6 +2145,24 @@ public void actionPerformed(ActionEvent e) { return; } + if (fixt < echot) { + ps.errText = "Fix timeout can not be less than Echo timeout"; + showScreen(); + return; + } + + if (detectt < echot) { + ps.errText = "Detect timeout can not be less than Echo timeout"; + showScreen(); + return; + } + + if (readt < echot) { + ps.errText = "Send/Receive timeout can not be less than Echo timeout"; + showScreen(); + return; + } + String ddnssn = ddnsServer.getText(); if (!Validator.domain(ddnssn)) { ps.errText = "Invalid DDNS Server"; From e0e7fb42148b792f52900b279f01fc05772fd671 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 6 Sep 2019 12:10:09 +0300 Subject: [PATCH 057/160] Echo text --- src/advclient/AdvancedClient.java | 36 ++++++++++++++++++++----------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 43de4ff..adbf1c5 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -1204,21 +1204,12 @@ public void showEchoRAIDAFinishedScreen() { GridBagLayout gridbag = new GridBagLayout(); GridBagConstraints c = new GridBagConstraints(); ct.setLayout(gridbag); - /* - x = new JLabel(""); - AppUI.setFont(x, 15); - c.anchor = GridBagConstraints.CENTER; - c.insets = new Insets(0, 0, 4, 0); - c.gridx = 0; - c.gridy = 0; - c.gridwidth = 2; - gridbag.setConstraints(x, c); - ct.add(x);*/ - + int[] statuses = sm.getRAIDAStatuses(); int y = 1; int fontSize = 16; + boolean isfailed = false; for (int i = 0; i < statuses.length / 2 + 1; i ++) { String status; @@ -1235,7 +1226,8 @@ public void showEchoRAIDAFinishedScreen() { x = new JLabel(""); if (statuses[i] == -1) { - status = "FAILED"; + status = "TIMED OUT"; + isfailed = true; AppUI.setColor(x, AppUI.getErrorColor()); } else { //status = "OK: " + statuses[i] + "ms"; @@ -1271,7 +1263,8 @@ public void showEchoRAIDAFinishedScreen() { x = new JLabel(""); if (statuses[j] == -1) { - status = "FAILED"; + status = "TIMED OUT"; + isfailed = true; AppUI.setColor(x, AppUI.getErrorColor()); } else { status = AppCore.getMS(statuses[j]); @@ -1291,6 +1284,23 @@ public void showEchoRAIDAFinishedScreen() { y++; } + isfailed = true; + if (isfailed) { + y++; + String txt = "TIMED OUT means the response exceeded the " + Config.ECHO_TIMEOUT / 1000 + " seconds allowed. " + + "This could be caused by a slow network or because the RAIDA was blocked (usually by office routers). " + + "Try changing your settings to increase the Timeout."; + + x = AppUI.wrapDiv(txt); + AppUI.setCommonFont(x); + c.anchor = GridBagConstraints.WEST; + c.insets = new Insets(8, 0, 2, 0); + c.gridx = GridBagConstraints.RELATIVE; + c.gridy = y; + c.gridwidth = 4; + gridbag.setConstraints(x, c); + ct.add(x); + } } public int getSkyWalletSN() { From 32148f3e75d9e91f11bc368a42950a84aad5f21d Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 6 Sep 2019 12:11:25 +0300 Subject: [PATCH 058/160] Echo text --- src/advclient/AdvancedClient.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index adbf1c5..dbcf09f 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -1284,7 +1284,6 @@ public void showEchoRAIDAFinishedScreen() { y++; } - isfailed = true; if (isfailed) { y++; String txt = "TIMED OUT means the response exceeded the " + Config.ECHO_TIMEOUT / 1000 + " seconds allowed. " From 37ab8d5db8b59cc84d1aa948cfcb694ba7c896ea Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 6 Sep 2019 12:38:30 +0300 Subject: [PATCH 059/160] logfile --- src/advclient/AdvancedClient.java | 2 -- src/advclient/common/Authenticator/Authenticator.java | 4 ++-- src/advclient/common/ShowCoins/ShowCoins.java | 4 ---- src/advclient/common/core/GLogger.java | 5 +++-- src/advclient/common/core/Servant.java | 8 ++++---- src/advclient/common/core/Wallet.java | 2 +- 6 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index dbcf09f..a0abec8 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -2991,8 +2991,6 @@ public void callback(Object o) { sc.launch(new CallbackInterface() { public void callback(Object o) { ShowCoinsResult scresult = (ShowCoinsResult) o; - - wl.debug(ltag, "ShowCoins done"); w.setSNs(scresult.coins); int[][] counters = scresult.counters; diff --git a/src/advclient/common/Authenticator/Authenticator.java b/src/advclient/common/Authenticator/Authenticator.java index 6bf1b38..2d37d6b 100644 --- a/src/advclient/common/Authenticator/Authenticator.java +++ b/src/advclient/common/Authenticator/Authenticator.java @@ -71,9 +71,9 @@ public void run() { } }); } - + public void setConfig() { - logger.debug(ltag, "Setting config"); + } private void copyFromGlobalResult(AuthenticatorResult aResult) { diff --git a/src/advclient/common/ShowCoins/ShowCoins.java b/src/advclient/common/ShowCoins/ShowCoins.java index c62500e..8738012 100644 --- a/src/advclient/common/ShowCoins/ShowCoins.java +++ b/src/advclient/common/ShowCoins/ShowCoins.java @@ -45,8 +45,6 @@ public void doShowCoins() { cleanPrivateLogDir(); - logger.info(ltag, "Show Coins"); - showCoinsInFolder(Config.IDX_FOLDER_BANK, Config.DIR_BANK); showCoinsInFolder(Config.IDX_FOLDER_FRACKED, Config.DIR_FRACKED); //showCoinsInFolder(Config.IDX_FOLDER_LOST, Config.DIR_LOST); @@ -76,8 +74,6 @@ public void showCoinsInFolder(int idx, String folder) { if (file.isDirectory()) continue; - logger.debug(ltag, "Parsing " + file); - try { cc = new CloudCoin(file.toString()); } catch (JSONException e) { diff --git a/src/advclient/common/core/GLogger.java b/src/advclient/common/core/GLogger.java index 12b8cab..2505124 100644 --- a/src/advclient/common/core/GLogger.java +++ b/src/advclient/common/core/GLogger.java @@ -36,12 +36,13 @@ public boolean openCommonFile(String file) { BufferedWriter br; FileWriter fr; - /* if (f.exists()) { double bytes = f.length(); if (bytes > Config.MAX_COMMON_LOG_LENGTH_MB * 1024 * 1024) f.delete(); - }*/ + + f = new File(file); + } fileName = file; try { diff --git a/src/advclient/common/core/Servant.java b/src/advclient/common/core/Servant.java index da89fa5..3552234 100644 --- a/src/advclient/common/core/Servant.java +++ b/src/advclient/common/core/Servant.java @@ -110,7 +110,7 @@ public void launch() { } public void changeUser(String user) { - logger.debug(ltag, "Servant " + name + " changing user to " + user); + //logger.debug(ltag, "Servant " + name + " changing user to " + user); this.user = user; this.privateLogDir = AppCore.getPrivateLogDir(this.user) + File.separator + name; @@ -250,7 +250,7 @@ private boolean readConfig() { byte[] data; String xmlData; - logger.debug(ltag, "reading " + configFilename); + //logger.debug(ltag, "reading " + configFilename); File file = new File(configFilename); try { if (!file.exists()) { @@ -309,7 +309,7 @@ private boolean parseConfigData(String xmlData) { } public void setConfig() { - logger.debug(ltag, "Set parent config"); + } public String getConfigValue(String key) { @@ -473,7 +473,7 @@ protected void cleanDir(String dir) { File[] files = dirObj.listFiles(); if (files == null) { - logger.debug(ltag, "Skipping dir " + dir); + //logger.debug(ltag, "Skipping dir " + dir); return; } diff --git a/src/advclient/common/core/Wallet.java b/src/advclient/common/core/Wallet.java index 82564bc..84cca16 100644 --- a/src/advclient/common/core/Wallet.java +++ b/src/advclient/common/core/Wallet.java @@ -40,7 +40,7 @@ public Wallet(String name, String email, boolean isEncrypted, String password, G this.sns = new int[0]; this.isUpdated = false; - logger.debug(ltag, "wallet " + name + " e=" + email + " is="+isEncrypted+ " p="+password); + logger.debug(ltag, "wallet " + name + " EmailRecovery: " + email + " isEncrypted: " + isEncrypted); lsep = System.getProperty("line.separator"); } From bcf0d4436134a4dae0d46f75c082fb3156e42442 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 6 Sep 2019 13:09:56 +0300 Subject: [PATCH 060/160] error message --- src/advclient/AdvancedClient.java | 24 ++++++++++++++++++++++++ src/advclient/common/core/AppCore.java | 20 +++++++++++++++++--- 2 files changed, 41 insertions(+), 3 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index a0abec8..3e55678 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -202,6 +202,11 @@ public String getSkyIDError(String name, String pownString) { + "The Pown String is " + pownString + "

Move the Coin to the Fracked folder of any Wallet and fix it"; } + public String getSkyIDErrorIfRAIDAFailed() { + return "Creating a Skywallet requires that all RAIDA are available.
" + + "However, One or more could not be contaced. Please try again later."; + } + public String getPickError(Wallet w) { String errText = "" @@ -1585,6 +1590,12 @@ public void run(){ Thread.sleep(300); } catch (InterruptedException e) {} } + + if (AppCore.getErrorCount(skyCC) > 0) { + ps.errText = getSkyIDErrorIfRAIDAFailed(); + showScreen(); + return; + } if (AppCore.getPassedCount(skyCC) != RAIDA.TOTAL_RAIDA_COUNT) { ps.errText = getSkyIDError(ps.srcWallet.getName(), ps.srcWallet.getIDCoin().getPownString()); @@ -1606,6 +1617,12 @@ public void run(){ Thread.sleep(300); } catch (InterruptedException e) {} } + + if (AppCore.getErrorCount(skyCC) > 0) { + ps.errText = getSkyIDErrorIfRAIDAFailed(); + showScreen(); + return; + } if (AppCore.getPassedCount(skyCC) != RAIDA.TOTAL_RAIDA_COUNT) { ps.errText = getSkyIDError(ps.srcWallet.getName(), ps.srcWallet.getIDCoin().getPownString()); @@ -5657,6 +5674,13 @@ public void callback(Object result) { setRAIDAProgressCoins(ar.totalRAIDAProcessed, 0, 0); return; } + + if (AppCore.getErrorCount(fcc) > 0) { + ps.currentScreen = ProgramState.SCREEN_SKY_WALLET_CREATED; + ps.errText = getSkyIDErrorIfRAIDAFailed(); + showScreen(); + return; + } if (AppCore.getPassedCount(fcc) != RAIDA.TOTAL_RAIDA_COUNT) { ps.currentScreen = ProgramState.SCREEN_SKY_WALLET_CREATED; diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index be1ce1b..b5070bd 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -1019,11 +1019,25 @@ public static String getRAIDAString(int idx) { if (idx > countries.length) { return sidx + " RAIDA"; } - + return sidx + " " + countries[idx]; + + } + + public static int getErrorCount(CloudCoin cc) { + int error = 0; + + for (int i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { + if (cc.getDetectStatus(i) == CloudCoin.STATUS_ERROR || cc.getDetectStatus(i) == CloudCoin.STATUS_UNTRIED) + error++; + } + + cc.setPownStringFromDetectStatus(); + logger.debug(ltag, "Error count " + error + " cc " + cc.sn + " pown=" + cc.getPownString()); + return error; } - + public static int getPassedCount(CloudCoin cc) { int passed = 0; @@ -1031,7 +1045,7 @@ public static int getPassedCount(CloudCoin cc) { if (cc.getDetectStatus(i) == CloudCoin.STATUS_PASS) passed++; } - + cc.setPownStringFromDetectStatus(); logger.debug(ltag, "Passed count " + passed + " cc " + cc.sn + " pown=" + cc.getPownString()); From c49f23e9426c4495db967668b8bd7d15dc9ae0cd Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 6 Sep 2019 13:34:37 +0300 Subject: [PATCH 061/160] Deposit foleder --- src/advclient/AdvancedClient.java | 10 ++++++++-- src/advclient/common/core/AppCore.java | 11 ++++++++++- src/advclient/common/core/Config.java | 1 + 3 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 3e55678..38874b8 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -2197,7 +2197,7 @@ public void actionPerformed(ActionEvent e) { } Config.DDNSSN_SERVER = ddnssn; - Config.DEFAULT_EXPORT_DIR = ps.chosenFile.replace("\"", "\\\"").replace("\\", "\\\\"); + Config.DEFAULT_EXPORT_DIR = ps.chosenFile; Config.DEFAULT_MAX_COINS_MULTIDETECT = notes; Config.FIX_FRACKED_TIMEOUT = fixt * 1000; Config.MULTI_DETECT_TIMEOUT = detectt * 1000; @@ -3873,6 +3873,9 @@ public void filesDropped( java.io.File[] files ) { ddPanel.addMouseListener(new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { + if (!Config.DEFAULT_DEPOSIT_DIR.isEmpty()) + chooser.setCurrentDirectory(new File(Config.DEFAULT_DEPOSIT_DIR)); + int returnVal = chooser.showOpenDialog(null); if (returnVal == JFileChooser.APPROVE_OPTION) { File[] files = chooser.getSelectedFiles(); @@ -3883,7 +3886,10 @@ public void mouseReleased(MouseEvent e) { String totalCloudCoins = AppCore.calcCoinsFromFilenames(ps.files); String text = "Selected " + ps.files.size() + " files - " + totalCloudCoins + " CloudCoins"; - tl.setText(text); + tl.setText(text); + + Config.DEFAULT_DEPOSIT_DIR = chooser.getCurrentDirectory().getAbsolutePath(); + AppCore.writeConfig(); } } }); diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index b5070bd..ab62e60 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -1104,6 +1104,13 @@ public static void readConfig() { logger.debug(ltag, "Export dir: " + os); Config.DEFAULT_EXPORT_DIR = os; } + + os = o.optString("deposit_dir"); + if (os != null) { + logger.debug(ltag, "Deposit dir: " + os); + + Config.DEFAULT_DEPOSIT_DIR = os; + } os = o.optString("ddnssn_server"); if (os != null) { @@ -1122,13 +1129,15 @@ public static boolean writeConfig() { logger.debug(ltag, "Saving config " + globalConfigFilename); - String edir = Config.DEFAULT_EXPORT_DIR.replace("\"", "\\\""); + String edir = Config.DEFAULT_EXPORT_DIR.replace("\"", "\\\"").replace("\\", "\\\\"); + String ddir = Config.DEFAULT_DEPOSIT_DIR.replace("\"", "\\\"").replace("\\", "\\\\"); String data = "{\"echo_timeout\":" + Config.ECHO_TIMEOUT + ", " + "\"detect_timeout\": " + Config.MULTI_DETECT_TIMEOUT + ", " + "\"read_timeout\": " + Config.READ_TIMEOUT + ", " + "\"fix_timeout\": " + Config.FIX_FRACKED_TIMEOUT + ", " + "\"max_coins\": " + Config.DEFAULT_MAX_COINS_MULTIDETECT + ", " + "\"export_dir\": \"" + edir + "\", " + + "\"deposit_dir\": \"" + ddir + "\", " + "\"ddnssn_server\": \"" + Config.DDNSSN_SERVER + "\"" + "}"; diff --git a/src/advclient/common/core/Config.java b/src/advclient/common/core/Config.java index 590017c..d50f288 100644 --- a/src/advclient/common/core/Config.java +++ b/src/advclient/common/core/Config.java @@ -73,6 +73,7 @@ public class Config { public static String DEFAULT_EXPORT_DIR = ""; + public static String DEFAULT_DEPOSIT_DIR = ""; public static int MAX_ALLOWED_LATENCY = 20000; From 9426d57984e5afebdbaa7623c58e258d5205214f Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 9 Sep 2019 11:06:45 +0300 Subject: [PATCH 062/160] tls 1.2 --- src/advclient/common/core/DetectionAgent.java | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/src/advclient/common/core/DetectionAgent.java b/src/advclient/common/core/DetectionAgent.java index 7960670..af22ba6 100644 --- a/src/advclient/common/core/DetectionAgent.java +++ b/src/advclient/common/core/DetectionAgent.java @@ -62,7 +62,6 @@ public void setExactFullUrl(String url) { public void setDefaultFullUrl() { this.fullURL = "https://RAIDA" + this.RAIDANumber + ".cloudcoin.global"; - // this.fullURL = "https://RAIDA" + this.RAIDANumber + ".lab.shurafom.eu"; } public void setFullUrl(String ip, int basePortArg) { @@ -103,7 +102,6 @@ public String doRequest(String url, String post) { return ""; } - //String urlIn = fullURL + "/service/" + url; String urlIn = fullURL + url; String method = (post == null) ? "GET" : "POST"; @@ -112,15 +110,15 @@ public String doRequest(String url, String post) { tsBefore = System.currentTimeMillis(); disableSSLCheck(); - + URL cloudCoinGlobal; HttpURLConnection urlConnection = null; try { - cloudCoinGlobal = new URL(urlIn); + cloudCoinGlobal = new URL(urlIn); urlConnection = (HttpURLConnection) cloudCoinGlobal.openConnection(); urlConnection.setConnectTimeout(connectionTimeout); urlConnection.setReadTimeout(readTimeout); - urlConnection.setRequestProperty("User-Agent", "Android CloudCoin App"); + urlConnection.setRequestProperty("User-Agent", "CloudCoin Wallet Client"); if (post != null) { logger.debug(ltag, post); @@ -183,7 +181,8 @@ public void checkServerTrusted(X509Certificate[] certs, String authType) { } SSLContext sc; try { - sc = SSLContext.getInstance("SSL"); + sc = SSLContext.getInstance("TLSv1.2"); + //logger.debug(ltag, "Will use protocol: " + sc.getProtocol()); sc.init(null, trustAllCerts, new java.security.SecureRandom()); } catch (NoSuchAlgorithmException e) { logger.error(ltag, "Failed to get SSL context: " + e.getMessage()); @@ -193,8 +192,7 @@ public void checkServerTrusted(X509Certificate[] certs, String authType) { } return; } - HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); - + HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); HostnameVerifier allHostsValid = new HostnameVerifier() { public boolean verify(String hostname, SSLSession session) { return true; @@ -203,7 +201,6 @@ public boolean verify(String hostname, SSLSession session) { // Install the all-trusting host verifier HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); - } } From f2faa65d73c74551d9331623a699268cc65ccfc6 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 11 Sep 2019 18:43:56 +0300 Subject: [PATCH 063/160] Change --- .../common/ChangeMaker/ChangeMaker.java | 267 +++++++++---- .../common/ChangeMaker/ChangeMakerResult.java | 5 + .../common/ChangeMaker/ChangeResponse.java | 2 +- src/advclient/common/Transfer/Transfer.java | 182 ++++++++- src/advclient/common/core/Config.java | 12 +- src/advclient/common/core/Servant.java | 87 +++++ src/advclient/common/core/ServantManager.java | 360 +++++------------- 7 files changed, 568 insertions(+), 347 deletions(-) diff --git a/src/advclient/common/ChangeMaker/ChangeMaker.java b/src/advclient/common/ChangeMaker/ChangeMaker.java index 99a8de2..3788a85 100644 --- a/src/advclient/common/ChangeMaker/ChangeMaker.java +++ b/src/advclient/common/ChangeMaker/ChangeMaker.java @@ -27,21 +27,22 @@ public ChangeMaker(String rootDir, GLogger logger) { super("ChangeMaker", rootDir, logger); } - public void launch(String user, int method, CallbackInterface icb) { + public void launch(int method, CloudCoin cc, CallbackInterface icb) { this.cb = icb; - - final String fuser = user; final int fmethod = method; - - + final CloudCoin fcc = cc; + cr = new ChangeMakerResult(); - - + + csb = new StringBuilder(); + receiptId = AppCore.generateHex(); + cr.receiptId = receiptId; + launchThread(new Runnable() { @Override public void run() { logger.info(ltag, "RUN ChangeMaker"); - doChange(fuser, fmethod); + doChange(fmethod, fcc); if (cb != null) cb.callback(cr); @@ -49,23 +50,33 @@ public void run() { }); } - public void doChange(String user, int method) { + private void copyFromGlobalResult(ChangeMakerResult cmr) { + cmr.totalRAIDAProcessed = cr.totalRAIDAProcessed; + cmr.status = cr.status; + cmr.errText = cr.errText; + cmr.receiptId = cr.receiptId; + } + + + public void doChange(int method, CloudCoin cc) { logger.info(ltag, "Method " + method); - String resultMain; - CloudCoin cc; String[] results; Object[] o; CommonResponse cresponse; ShowEnvelopeCoinsResponse[] srs; - String[] requests; - setSenderRAIDA(); + + if (!updateRAIDAStatus()) { + logger.error(ltag, "Failed to query RAIDA"); + cr.status = ChangeMakerResult.STATUS_ERROR; + return; + } /* - results = raida.query(new String[] { "show_change" }, null, null, new int[] {Config.RAIDANUM_TO_QUERY_BY_DEFAULT}); + results = raida.query(new String[] { "show_change?sn=" + Config.PUBLIC_CHANGE_MAKER_ID }, null, null, new int[] {Config.RAIDANUM_TO_QUERY_BY_DEFAULT}); if (results == null) { logger.error(ltag, "Failed to query showchange"); cr.status = ChangeMakerResult.STATUS_ERROR; @@ -82,12 +93,12 @@ public void doChange(String user, int method) { resultMain = "{\n" + " \"server\":\"RAIDA1\",\n" + - " \"status\":\"shown\",\n" + - " \"d250\":[16230602,16675880,16192311,15169770],\n" + - " \"d100\":[13230602,13675880,16192311,15169770],\n" + - " \"d25\":[10230602,10675880,10192311,15169770,3,4,5,6,7,8],\n" + - " \"d5\":[8230602,8675880,6192311,15169770,1111,222,888,999,100,101,1,1,1,1,1,2,2,2,2,2,3,3,3,3,3,4,4,4,4,4,5,5,5,5,5,6,6,6,6,6,7,7,7,7,7],\n" + - " \"d1\":[230602,675880,192311,15169770,33,44,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,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],\n" + + " \"status\":\"pass\",\n" + + " \"d250\":[16777210, 16777211, 16777212, 16777213, 16777214],\n" + + " \"d100\":[14680000, 14680001, 14680002, 14680003, 14680004],\n" + + " \"d25\":[6291400, 6291401, 6291402, 6291403, 6291404],\n" + + " \"d5\":[4194200, 4194201, 4194202, 4194203, 4194204, 4194205, 4194206, 4194207],\n" + + " \"d1\":[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],\n" + " \"message\":\"Change:This report shows the serial numbers that are available to make change now.\",\n" + " \"version\":\"some version number here\",\n" + " \"time\":\"2016-44-19 7:44:PM\"\n" + @@ -100,7 +111,7 @@ public void doChange(String user, int method) { return; } - if (!cresponse.status.equals("shown")) { + if (!cresponse.status.equals(Config.REQUEST_STATUS_PASS)) { logger.error(ltag, "Failed to get response: " + cresponse.status); cr.status = ChangeMakerResult.STATUS_ERROR; return; @@ -147,6 +158,10 @@ public void doChange(String user, int method) { sns = get100D(scr.d1); rqDenom = 100; break; + case Config.CHANGE_METHOD_100E: + sns = get100E(scr.d25, scr.d5, scr.d1); + rqDenom = 100; + break; case Config.CHANGE_METHOD_250A: sns = get250A(scr.d100, scr.d25); rqDenom = 250; @@ -163,6 +178,10 @@ public void doChange(String user, int method) { sns = get250D(scr.d1); rqDenom = 250; break; + case Config.CHANGE_METHOD_250E: + sns = get250E(scr.d100, scr.d25, scr.d5, scr.d1); + rqDenom = 250; + break; default: logger.error(ltag, "Invalid method: " + method); cr.status = ChangeMakerResult.STATUS_ERROR; @@ -176,31 +195,34 @@ public void doChange(String user, int method) { } for (int i = 0; i < sns.length; i++) { - logger.info(ltag, "sn="+sns[i]); - } - - if (!updateRAIDAStatus()) { - logger.error(ltag, "Failed to query RAIDA"); - cr.status = ChangeMakerResult.STATUS_ERROR; - return; - } - - CloudCoin tcc = getTargetCoin(rqDenom); - if (tcc == null) { - logger.error(ltag, "Failed to get target coin"); - cr.status = ChangeMakerResult.STATUS_ERROR; - return; + CloudCoin ccx = new CloudCoin(1, sns[i]); + logger.info(ltag, "sn "+sns[i] + " d="+ccx.getDenomination()); } requests = new String[RAIDA.TOTAL_RAIDA_COUNT]; for (int i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { - requests[i] = "change?nn=" + tcc.nn + "&sn=" + tcc.sn + "&an=" + tcc.ans[i] + "&denomination=" + tcc.getDenomination(); + requests[i] = "change?nn=" + cc.nn + "&sn=" + cc.sn + "&an=" + cc.ans[i] + "&denomination=" + cc.getDenomination(); for (int j = 0; j < sns.length; j++) { - requests[i] += "&sns[]=" + sns[i]; + requests[i] += "&sns[]=" + sns[j]; } } - results = raida.query(requests); + results = raida.query(requests, null, new CallbackInterface() { + final GLogger gl = logger; + final CallbackInterface myCb = cb; + + @Override + public void callback(Object result) { + cr.totalRAIDAProcessed++; + cr.status = ChangeMakerResult.STATUS_PROCESSING; + if (myCb != null) { + ChangeMakerResult cmr = new ChangeMakerResult(); + copyFromGlobalResult(cmr); + myCb.callback(cmr); + } + } + }); + if (results == null) { logger.error(ltag, "Failed to query change"); cr.status = ChangeMakerResult.STATUS_ERROR; @@ -213,6 +235,36 @@ public void doChange(String user, int method) { return; } + + results = new String[] { + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", + + }; + int cntErr = 0; ChangeResponse[] crs = new ChangeResponse[RAIDA.TOTAL_RAIDA_COUNT]; CloudCoin[] ccs = new CloudCoin[sns.length]; @@ -240,8 +292,8 @@ public void doChange(String user, int method) { continue; } - if (ccs.length != crs[i].sns.length || ccs.length != crs[i].ans.length || ccs.length != crs[i].nns.length) { - logger.error(ltag, "RAIDA " + i + ": wrong response cnt: " + crs[i].sns.length + "/" + crs[i].ans.length + "/" +crs[i].nns.length + " need " + ccs.length); + if (ccs.length != crs[i].sns.length || ccs.length != crs[i].ans.length) { + logger.error(ltag, "RAIDA " + i + ": wrong response cnt: " + crs[i].sns.length + "/" + crs[i].ans.length + " need " + ccs.length); cntErr++; continue; } @@ -253,7 +305,7 @@ public void doChange(String user, int method) { rsn = crs[i].sns[j]; ran = crs[i].ans[j]; - rnn = crs[i].nns[j]; + rnn = crs[i].nn; logger.info(ltag, " sn="+ rsn + " nn="+rnn+ " an="+ran); found = false; @@ -287,7 +339,13 @@ public void doChange(String user, int method) { } } - String dir = AppCore.getUserDir(Config.DIR_IMPORT, user); + if (cntErr >= RAIDA.TOTAL_RAIDA_COUNT - Config.PASS_THRESHOLD) { + logger.error(ltag, "Too many errors: " + cntErr); + cr.status = ChangeMakerResult.STATUS_ERROR; + return; + } + + String dir = AppCore.getUserDir(Config.DIR_SUSPECT, user); String file; for (int i = 0; i < ccs.length; i++) { if (ccs[i] == null) @@ -299,39 +357,18 @@ public void doChange(String user, int method) { logger.error(ltag, "Failed to move coin to Import: " + ccs[i].getFileName()); continue; } - + logger.info(ltag, "cc="+ccs[i].sn + " v=" + ccs[i].getJson(false)); } - AppCore.moveToFolder(tcc.originalFile, Config.DIR_SENT, user); - cr.status = ChangeMakerResult.STATUS_FINISHED; - } - - private CloudCoin getTargetCoin(int denomination) { - String fullPath = AppCore.getUserDir(Config.DIR_BANK, user); - CloudCoin cc; - - File dirObj = new File(fullPath); - for (File file: dirObj.listFiles()) { - if (file.isDirectory()) - continue; + AppCore.moveToFolder(cc.originalFile, Config.DIR_SENT, user); - logger.debug(ltag, "Parsing " + file); - try { - cc = new CloudCoin(file.toString()); - } catch (JSONException e) { - logger.error(ltag, "Failed to parse JSON: " + e.getMessage()); - continue; - } + addCoinToReceipt(cc, "authentic", "Sent to Public Change"); + saveReceipt(user, 1, 0, 0, 0, 0, 0); - if (cc.getDenomination() == denomination) - return cc; - } - - return null; + cr.status = ChangeMakerResult.STATUS_FINISHED; } - private int[] getA(int[] a, int cnt) { int[] sns; int i, j; @@ -494,6 +531,36 @@ private int[] get100D(int[] sb) { return rsns; } + + private int[] get100E(int[] sb, int[] ss, int[] sss) { + int[] sns, rsns; + + rsns = new int[12]; + + sns = getA(sb, 3); + if (sns == null) + return null; + + for (int i = 0; i < 3; i++) + rsns[i] = sns[i]; + + sns = getA(ss, 4); + if (sns == null) + return null; + + for (int i = 0; i < 4; i++) + rsns[i + 3] = sns[i]; + + sns = getA(sss, 5); + if (sns == null) + return null; + + for (int i = 0; i < 5; i++) + rsns[i + 7] = sns[i]; + + return rsns; + } + private int[] get250A(int[] sb, int[] ss) { int[] sns, rsns; @@ -623,4 +690,68 @@ private int[] get250D(int[] sb) { return rsns; } + + private int[] get250E(int[] sb, int[] ss, int[] sss, int[] ssss) { + int[] sns, rsns; + + rsns = new int[12]; + sns = getA(sb, 2); + if (sns == null) + return null; + + for (int i = 0; i < 2; i++) + rsns[i] = sns[i]; + + sns = getA(ss, 1); + if (sns == null) + return null; + + rsns[2] = sns[0]; + + sns = getA(sss, 4); + if (sns == null) + return null; + + for (int i = 0; i < 4; i++) + rsns[i + 3] = sns[i]; + + sns = getA(ssss, 5); + if (sns == null) + return null; + + for (int i = 0; i < 5; i++) + rsns[i + 7] = sns[i]; + + return rsns; + } + + + + + + + + } +/* +Method 5A: 1,1,1,1,1 +Denomination 25 + +Method 25A: 5,5,5,5,5 (Min) +Method 25B: 5,5,5,5,5A +Method 25C: 5,5,5A,5A,5A +Method 25D: 5A,5A,5A,5A (Max) +Denomination 100 + +Method 100A: 25,25,25,25 (min) +Method 100B: 25,25,25,25A +Method 100C: 25,25,25A,25B +Method 100D: 25D,25D,25D,25D (Max) +Method 100E: 25,25,25,25B +Denomination 250 + +Method 250A: 100,100,25,25 (Min) +Method 250B: 100A,100A,25A,25B +Method 250C: 100B,100B,25B,25C +Method 250D: 100D,100D,25D,25D (Max) +*/ \ No newline at end of file diff --git a/src/advclient/common/ChangeMaker/ChangeMakerResult.java b/src/advclient/common/ChangeMaker/ChangeMakerResult.java index dc1bd94..d696abe 100644 --- a/src/advclient/common/ChangeMaker/ChangeMakerResult.java +++ b/src/advclient/common/ChangeMaker/ChangeMakerResult.java @@ -1,9 +1,14 @@ package global.cloudcoin.ccbank.ChangeMaker; + public class ChangeMakerResult { public static int STATUS_PROCESSING = 1; public static int STATUS_FINISHED = 2; public static int STATUS_ERROR = 3; + public String errText; + public int totalRAIDAProcessed; + + public String receiptId; public int status; } diff --git a/src/advclient/common/ChangeMaker/ChangeResponse.java b/src/advclient/common/ChangeMaker/ChangeResponse.java index 04587e8..9ff21f7 100644 --- a/src/advclient/common/ChangeMaker/ChangeResponse.java +++ b/src/advclient/common/ChangeMaker/ChangeResponse.java @@ -3,7 +3,7 @@ import global.cloudcoin.ccbank.core.CommonResponse; public class ChangeResponse extends CommonResponse { - int[] nns; + int nn; int[] sns; String[] ans; diff --git a/src/advclient/common/Transfer/Transfer.java b/src/advclient/common/Transfer/Transfer.java index c9c0287..b715eea 100644 --- a/src/advclient/common/Transfer/Transfer.java +++ b/src/advclient/common/Transfer/Transfer.java @@ -77,17 +77,27 @@ public void doTransfer(int fromsn, int tosn, int sns[], String tag, int amount) return; } + + CloudCoin extraCoin = null; if (!pickCoinsAmountFromArray(sns, amount)) { logger.debug(ltag, "Not enough coins in the cloudfor amount " + amount); - globalResult.status = TransferResult.STATUS_ERROR; - globalResult.errText = Config.PICK_ERROR_MSG; - copyFromGlobalResult(tr); - if (cb != null) - cb.callback(tr); - return; + + coinsPicked = new ArrayList(); + extraCoin = pickCoinsAmountFromArrayWithExtra(sns, amount); + if (extraCoin == null) { + globalResult.status = TransferResult.STATUS_ERROR; + globalResult.errText = "Failed to pick coins from the Sky Wallet"; + copyFromGlobalResult(tr); + if (cb != null) + cb.callback(tr); + + return; + } + + logger.debug(ltag, "Got extra coin " + extraCoin.sn + " denomination: " + extraCoin.getDenomination()); } - setSenderRAIDA(); + //setSenderRAIDA(); CloudCoin idcc = getIDcc(fromsn); if (idcc == null) { logger.error(ltag, "NO ID Coin found for SN: " + fromsn); @@ -178,14 +188,28 @@ public void doTransfer(int fromsn, int tosn, int sns[], String tag, int amount) copyFromGlobalResult(tr); if (cb != null) cb.callback(tr); + + return; } else { - globalResult.status = TransferResult.STATUS_FINISHED; globalResult.totalFilesProcessed += ccs.size(); } - } else { - globalResult.status = TransferResult.STATUS_FINISHED; - } + } + if (extraCoin != null) { + int remained = amount - curValProcessed; + logger.debug(ltag, "Changing coin " + extraCoin.sn + " alreadyProcessed=" + curValProcessed + " needed=" + amount); + if (!processTransferWithChange(extraCoin, idcc, tag, tosn, remained)) { + tr = new TransferResult(); + globalResult.status = TransferResult.STATUS_ERROR; + copyFromGlobalResult(tr); + if (cb != null) + cb.callback(tr); + + return; + } + } + + globalResult.status = TransferResult.STATUS_FINISHED; copyFromGlobalResult(tr); if (cb != null) cb.callback(tr); @@ -203,6 +227,8 @@ public boolean processTransfer(ArrayList ccs, CloudCoin cc, String ta int i; CloudCoin[] sccs; + logger.debug(ltag, "Transferring to " + tosn); + sbs = new StringBuilder[RAIDA.TOTAL_RAIDA_COUNT]; posts = new String[RAIDA.TOTAL_RAIDA_COUNT]; requests = new String[RAIDA.TOTAL_RAIDA_COUNT]; @@ -310,10 +336,140 @@ public void callback(Object result) { } } - + logger.info(ltag, "Transferred"); + + return true; + } + + + public boolean processTransferWithChange(CloudCoin tcc, CloudCoin cc, String tag, int tosn, int amount) { + String[] results; + Object[] o; + CommonResponse errorResponse; + TransferResponse[][] trs; + String[] requests; + StringBuilder[] sbs; + String[] posts; + int i; + CloudCoin[] sccs; + + logger.debug(ltag, "Transferring with change to " + tosn); + + System.out.println("sss"); + System.exit(1); + sbs = new StringBuilder[RAIDA.TOTAL_RAIDA_COUNT]; + posts = new String[RAIDA.TOTAL_RAIDA_COUNT]; + requests = new String[RAIDA.TOTAL_RAIDA_COUNT]; - logger.info(ltag, "Transferred"); + for (i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { + requests[i] = "transfer"; + + sbs[i] = new StringBuilder(); + sbs[i].append("nn="); + sbs[i].append(cc.nn); + sbs[i].append("&sn="); + sbs[i].append(cc.sn); + sbs[i].append("&an="); + sbs[i].append(cc.ans[i]); + sbs[i].append("&pan="); + sbs[i].append(cc.ans[i]); + sbs[i].append("&denomination="); + sbs[i].append(cc.getDenomination()); + sbs[i].append("&to_sn="); + sbs[i].append(tosn); + sbs[i].append("&payment_envelope="); + sbs[i].append(tag); + + sbs[i].append("&payment_required="); + sbs[i].append(amount); + + sbs[i].append("&sns[]="); + sbs[i].append(tcc.sn); + + sbs[i].append("&public_change_maker="); + sbs[i].append(Config.PUBLIC_CHANGE_MAKER_ID); + + posts[i] = sbs[i].toString(); + } + + results = raida.query(requests, posts, new CallbackInterface() { + final GLogger gl = logger; + final CallbackInterface myCb = cb; + + @Override + public void callback(Object result) { + globalResult.totalRAIDAProcessed++; + if (myCb != null) { + TransferResult trlocal = new TransferResult(); + copyFromGlobalResult(trlocal); + myCb.callback(trlocal); + } + } + }); + + if (results == null) { + logger.error(ltag, "Failed to query Transfer"); + return false; + } + + sccs = new CloudCoin[1]; + trs = new TransferResponse[RAIDA.TOTAL_RAIDA_COUNT][]; + for (i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { + logger.info(ltag, "i="+i+ " r="+results[i]); + if (results[i] != null) { + if (results[i].equals("")) { + logger.error(ltag, "Skipped raida" + i); + continue; + } + } + + o = parseArrayResponse(results[i], TransferResponse.class); + if (o == null) { + errorResponse = (CommonResponse) parseResponse(results[i], CommonResponse.class); + if (errorResponse == null) { + logger.error(ltag, "Failed to get error"); + continue; + } + + logger.error(ltag, "Failed to auth coin. Status: " + errorResponse.status); + continue; + } + + if (o.length != sccs.length) { + logger.error(ltag, "RAIDA " + i + " wrong number of coins: " + o.length); + continue; + } + + for (int j = 0; j < o.length; j++) { + String strStatus; + int rnn, rsn; + String ran; + boolean found; + + trs[i] = new TransferResponse[o.length]; + trs[i][j] = (TransferResponse) o[j]; + + strStatus = trs[i][j].status; + + found = false; + int cstatus; + if (strStatus.equals(Config.REQUEST_STATUS_PASS)) { + logger.info(ltag, "OK response from raida " + i); + cstatus = CloudCoin.STATUS_PASS; + } else if (strStatus.equals(Config.REQUEST_STATUS_FAIL)) { + logger.error(ltag, "Counterfeit response from raida " + i); + cstatus = CloudCoin.STATUS_FAIL; + } else { + logger.error(ltag, "Unknown coin status from RAIDA" + i + ": " + strStatus); + cstatus = CloudCoin.STATUS_ERROR; + } + + + } + } + + logger.info(ltag, "Change Transferred"); return true; } diff --git a/src/advclient/common/core/Config.java b/src/advclient/common/core/Config.java index d50f288..d39117e 100644 --- a/src/advclient/common/core/Config.java +++ b/src/advclient/common/core/Config.java @@ -128,11 +128,13 @@ public class Config { final public static int CHANGE_METHOD_100B = 7; final public static int CHANGE_METHOD_100C = 8; final public static int CHANGE_METHOD_100D = 9; + final public static int CHANGE_METHOD_100E = 10; - final public static int CHANGE_METHOD_250A = 10; - final public static int CHANGE_METHOD_250B = 11; - final public static int CHANGE_METHOD_250C = 12; - final public static int CHANGE_METHOD_250D = 13; + final public static int CHANGE_METHOD_250A = 11; + final public static int CHANGE_METHOD_250B = 12; + final public static int CHANGE_METHOD_250C = 13; + final public static int CHANGE_METHOD_250D = 14; + final public static int CHANGE_METHOD_250E = 15; final public static int VAULTER_OP_VAULT = 1; final public static int VAULTER_OP_UNVAULT = 2; @@ -176,4 +178,6 @@ public class Config { final public static int MAX_READ_TIMEOUT = 120000; + public static int PUBLIC_CHANGE_MAKER_ID = 2; + } diff --git a/src/advclient/common/core/Servant.java b/src/advclient/common/core/Servant.java index 3552234..1ca06ca 100644 --- a/src/advclient/common/core/Servant.java +++ b/src/advclient/common/core/Servant.java @@ -663,6 +663,10 @@ else if (denomination == 250) } public int[] getExpCoins(int amount, int[] totals) { + return getExpCoins(amount, totals, false); + } + + public int[] getExpCoins(int amount, int[] totals, boolean loose) { int savedAmount = amount; if (amount > totals[Config.IDX_TOTAL]) { @@ -673,6 +677,9 @@ public int[] getExpCoins(int amount, int[] totals) { if (amount < 0) return null; + if (loose) + logger.debug(ltag, "isLoose " + loose); + for (int i = 0; i < totals.length; i++) logger.debug(ltag, "v=" + totals[i]); @@ -712,6 +719,9 @@ public int[] getExpCoins(int amount, int[] totals) { break; if (i == 1 || exp_250 % 2 == 0) { + if (loose) + break; + logger.error(ltag, "Can't collect needed amount of coins. rest: " + amount); return null; } @@ -779,6 +789,83 @@ public void pickCoins(File[] files, int[] exps) { } } + public CloudCoin pickCoinsAmountFromArrayWithExtra(int[] coins, int amount) { + int[] totals, exps; + int denomination; + CloudCoin cc = null; + + totals = countCoinsFromArray(coins); + exps = getExpCoins(amount, totals, true); + + int collected, rest; + + collected = rest = 0; + for (int i = 0; i < coins.length; i++) { + cc = new CloudCoin(Config.DEFAULT_NN, coins[i]); + denomination = cc.getDenomination(); + if (denomination == 1) { + if (exps[Config.IDX_1]-- > 0) { + logger.info(ltag, "Adding 1: " + cc.sn); + coinsPicked.add(cc); + collected += cc.getDenomination(); + } + } else if (denomination == 5) { + if (exps[Config.IDX_5]-- > 0) { + logger.info(ltag, "Adding 5: " + cc.sn); + coinsPicked.add(cc); + collected += cc.getDenomination(); + } + } else if (denomination == 25) { + if (exps[Config.IDX_25]-- > 0) { + logger.info(ltag, "Adding 25: " + cc.sn); + coinsPicked.add(cc); + collected += cc.getDenomination(); + } + } else if (denomination == 100) { + if (exps[Config.IDX_100]-- > 0) { + logger.info(ltag, "Adding 100: " + cc.sn); + coinsPicked.add(cc); + collected += cc.getDenomination(); + } + } else if (denomination == 250) { + if (exps[Config.IDX_250]-- > 0) { + logger.info(ltag, "Adding 250: " + cc.sn); + coinsPicked.add(cc); + collected += cc.getDenomination(); + } + } + } + + boolean isAdded; + rest = amount - collected; + logger.debug(ltag, "rest = " + rest); + for (int i = 0; i < coins.length; i++) { + cc = new CloudCoin(Config.DEFAULT_NN, coins[i]); + denomination = cc.getDenomination(); + + if (rest > denomination) + continue; + + isAdded = false; + for (CloudCoin xcc : coinsPicked) { + if (xcc.sn == cc.sn) { + isAdded = true; + break; + } + } + + if (isAdded) { + logger.debug(ltag, "Adding change: skipp added sn " + cc.sn); + continue; + } + + logger.debug(ltag, "Chosen for change: " + cc.sn + " denomination " + cc.getDenomination()); + break; + } + + return cc; + } + public boolean pickCoinsAmountFromArray(int[] coins, int amount) { int[] totals, exps; CloudCoin cc; diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index 8ebf65d..3894c0a 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -8,7 +8,10 @@ import advclient.ProgramState; import advclient.common.core.RequestChange; import global.cloudcoin.ccbank.Authenticator.Authenticator; +import global.cloudcoin.ccbank.Authenticator.AuthenticatorResult; import global.cloudcoin.ccbank.Backupper.Backupper; +import global.cloudcoin.ccbank.ChangeMaker.ChangeMaker; +import global.cloudcoin.ccbank.ChangeMaker.ChangeMakerResult; import global.cloudcoin.ccbank.Echoer.Echoer; import global.cloudcoin.ccbank.Eraser.Eraser; import global.cloudcoin.ccbank.Exporter.Exporter; @@ -392,9 +395,13 @@ public void startSenderServiceForChange(int sn, int[] values, String memo, Callb s.launch(sn, null, values, 0, memo, Config.CHANGE_SKY_DOMAIN, cb); } + public void startChangeMakerService(int method, CloudCoin cc, CallbackInterface cb) { + ChangeMaker cm = (ChangeMaker) sr.getServant("ChangeMaker"); + cm.launch(method, cc, cb); + } + public void startTransferService(int fromsn, int tosn, int sns[], int amount, String tag, CallbackInterface cb) { logger.debug(ltag, "Transfer from " + fromsn + " to " + tosn + " amount " + amount); - System.out.println("Transfer from " + fromsn + " to " + tosn + " amount " + amount); Transfer tr = (Transfer) sr.getServant("Transfer"); tr.launch(fromsn, tosn, sns, amount, tag, cb); } @@ -661,174 +668,119 @@ else if (amount < 100) return true; } - + return sendToChange(cc, w, skySN, cb); } public boolean sendToChange(CloudCoin cc, Wallet w, int skySN, CallbackInterface cb) { makeChangeResult mcr = new makeChangeResult(); mcr.status = 1; - mcr.text = "Sending coin " + cc.sn + " to the SkyWallet"; + mcr.text = "Making change for coin " + cc.sn; mcr.progress = 0; if (cb != null) { cb.callback(mcr); } - logger.debug(ltag, "Sending to the Change.skywallet.cc " + cc.sn); - - DNSSn d = new DNSSn(Config.CHANGE_SKY_DOMAIN, null, logger); - int sn = d.getSN(); - if (sn < 0) { - logger.error(ltag, "Failed to query change service"); - mcr.errText = "Failed to query " + Config.CHANGE_SKY_DOMAIN; - if (cb != null) { - cb.callback(mcr); - } - - return false; - } - - String memoUUID = AppCore.generateHex(); + logger.debug(ltag, "Sending to the ChangeMaker " + cc.sn + " denomination " + cc.getDenomination()); + System.out.println("Sending to the ChangeMaker " + cc.sn); - logger.debug(ltag, "Generated hex " + memoUUID); - - int[] denominations = AppCore.getDenominations(); - int[] values = new int[denominations.length]; - for (int i = 0; i < denominations.length; i++) { - if (cc.getDenomination() == denominations[i]) { - values[i] = 1; + int method = 0; + switch (cc.getDenomination()) { + case 250: + method = Config.CHANGE_METHOD_250E; + break; + case 100: + method = Config.CHANGE_METHOD_100E; + break; + case 25: + method = Config.CHANGE_METHOD_25B; + break; + case 5: + method = Config.CHANGE_METHOD_5A; break; - } } - logger.debug(ltag, "values " + Arrays.toString(values)); - - //logger.debug(ltag, "send sn " + sn + " dstWallet " + dstFolder); - //startSenderService(sn, dstFolder, amount, memo, remoteWalletName, cb); - - startSenderServiceForChange(sn, values, memoUUID, new eSenderChangeCb(cb, w, memoUUID, cc.getDenomination(), skySN)); - - - return true; - - } - - public void requestChange(CallbackInterface cb, Wallet w, String memoUUID, int denomination, int skySN) { - makeChangeResult mcr = new makeChangeResult(); - mcr.status = 0; - mcr.text = "Requesting Change from the ChangeServer"; - if (cb != null) { - cb.callback(mcr); + if (method == 0) { + logger.error(ltag, "Can't find suitable method"); + return false; } - - logger.debug(ltag, "request change " + memoUUID + " d=" + denomination + " sky=" + skySN); - - RequestChange rc = new RequestChange(skySN, memoUUID, denomination, logger); - if (!rc.request(getSR())) { - mcr.errText = "Failed to query RequestChange service"; - if (cb != null) { - cb.callback(mcr); - } - - return; - } - - mcr.text = "Downloading Change"; - if (cb != null) { - cb.callback(mcr); - } - - startShowSkyCoinsService(new eShowSkyCoinsCb(memoUUID, w, denomination, skySN, cb), skySN); - - //startReceiverService(skySN, sns, 0, 0, "", rcb); - - } - - public void receiveFromSkyWallet(CallbackInterface cb, Wallet w, ArrayList coins, int total, int skySN) { - makeChangeResult mcr = new makeChangeResult(); - mcr.status = 0; - mcr.text = "Receiving change"; - if (cb != null) { - cb.callback(mcr); - } - - if (coins.size() == 0) { - logger.error(ltag, "Size is zero"); - mcr.errText = "No coins received from your wallet"; - if (cb != null) { - cb.callback(mcr); - } - return; - } - - logger.debug(ltag, "Receive from Skywallet: " + skySN + " to " + w.getName()); - - //sr.getServant("Receiver").changeUser(w.getName()); - - int[] sns = new int[coins.size()]; - int i = 0; - - for (int sn : coins) { - sns[i] = sn; - i++; - } - - startReceiverServiceForChange(skySN, sns, Config.CHANGE_SKY_DOMAIN, total, "Receive change", new eReceiverChangeCb(cb, w)); - //public void startReceiverService(int sn, int sns[], - // String dstFolder, int amount, String memo, CallbackInterface cb) { - } - - class eReceiverChangeCb implements CallbackInterface { - CallbackInterface cb; - makeChangeResult mcr; - Wallet w; + logger.debug(ltag, "Method chosen: " + method); + startChangeMakerService(method, cc, new CallbackInterface() { + public void callback(Object o) { + final ChangeMakerResult cmr = (ChangeMakerResult) o; - - public eReceiverChangeCb(CallbackInterface cb, Wallet w) { - this.cb = cb; - this.w = w; - mcr = new makeChangeResult(); - - } - public void callback(final Object result) { - ReceiverResult rr = (ReceiverResult) result; - - logger.debug(ltag, "Change Receiver finished: " + rr.status); - if (rr.status == ReceiverResult.STATUS_PROCESSING) { - mcr.status = 1; - mcr.progress = rr.totalRAIDAProcessed; - mcr.text = "Receiving change from the SkyWallet"; - if (this.cb != null) { - this.cb.callback(mcr); + logger.debug(ltag, "ChangeMaker finished: " + cmr.status); + + makeChangeResult mcr = new makeChangeResult(); + + if (cmr.status == ChangeMakerResult.STATUS_PROCESSING) { + mcr.text = "Making change for coin " + cc.sn; + mcr.progress = cmr.totalRAIDAProcessed; + mcr.status = 1; + if (cb != null) { + cb.callback(mcr); + } + + return; } - return; - } - - if (rr.status == ReceiverResult.STATUS_CANCELLED) { - mcr.errText = "Receiver Cancelled"; - if (this.cb != null) { - this.cb.callback(mcr); + + if (cmr.status == ChangeMakerResult.STATUS_ERROR) { + logger.debug(ltag, "Error in making Change"); + mcr.errText = "Failed to make Change. Please check the main.log file"; + mcr.status = 0; + if (cb != null) { + cb.callback(mcr); + } + return; } + + if (cmr.status == ChangeMakerResult.STATUS_FINISHED) { - return; - } + w.appendTransaction("Sent to Public Change", cc.getDenomination() * -1, cmr.receiptId); + mcr.text = "Authenticating Coins from Public Change"; + if (cb != null) + cb.callback(mcr); - if (rr.status == ReceiverResult.STATUS_ERROR) { - mcr.errText = "Receiver Error"; - if (this.cb != null) { - this.cb.callback(mcr); + startAuthenticatorService(new CallbackInterface() { + public void callback(Object result) { + logger.debug(ltag, "Authenticator for Change finished"); + + final Object fresult = result; + final AuthenticatorResult ar = (AuthenticatorResult) fresult; + if (ar.status == AuthenticatorResult.STATUS_ERROR) { + logger.debug(ltag, "Error in making Change"); + mcr.errText = "Failed to authenticate coins from Public Change"; + mcr.status = 0; + if (cb != null) { + cb.callback(mcr); + } + + return; + } else if (ar.status == AuthenticatorResult.STATUS_FINISHED) { + mcr.text = "Grading Coins from Public Change"; + if (cb != null) + cb.callback(mcr); + + startGraderService(new eGraderCb(cb, w), null, w.getName()); + return; + } + + mcr.text = "Authenticating Coins from Public Change"; + mcr.progress = ar.totalRAIDAProcessed; + mcr.status = 1; + if (cb != null) { + cb.callback(mcr); + } + } + }); } - return; } - - mcr.text = "Grading coins"; - if (cb != null) - cb.callback(mcr); - - startGraderService(new eGraderCb(cb, w, rr.receiptId), null, w.getName()); - } + }); + + return true; + } class eGraderCb implements CallbackInterface { @@ -838,10 +790,9 @@ class eGraderCb implements CallbackInterface { String receiptId; - public eGraderCb(CallbackInterface cb, Wallet w, String receiptId) { + public eGraderCb(CallbackInterface cb, Wallet w) { this.w = w; this.cb = cb; - this.receiptId = receiptId; mcr = new makeChangeResult(); } @@ -852,8 +803,9 @@ public void callback(Object result) { //receiverReceiptId = rr.receiptId; int total = gr.totalAuthenticValue + gr.totalFrackedValue; + String receiptId = gr.receiptId; - w.appendTransaction("Received from ChangeMaker", total, receiptId); + w.appendTransaction("Received from Public Change", total, receiptId); mcr.text = "Fixing coins"; if (cb != null) @@ -985,120 +937,6 @@ public void callback(Object result) { } } - - class eShowSkyCoinsCb implements CallbackInterface { - - String hash; - CallbackInterface cb; - int denomination; - makeChangeResult mcr; - int skySN; - Wallet w; - - public eShowSkyCoinsCb(String hash, Wallet w, int denomination, int skySN, CallbackInterface cb) { - this.hash = hash; - this.cb = cb; - this.denomination = denomination; - this.skySN = skySN; - this.w = w; - mcr = new makeChangeResult(); - } - - public void callback(final Object result) { - ShowEnvelopeCoinsResult sc = (ShowEnvelopeCoinsResult) result; - - - ArrayList coins = new ArrayList(); - - logger.debug(ltag, "ShowSky finished: " + sc.status + " coins: " + sc.coins.length); - for (int i = 0; i < sc.tags.length; i++) { - if (sc.tags[i].equals(hash)) { - logger.debug(ltag, "Our coin: " + sc.coins[i]); - coins.add(sc.coins[i]); - } - } - - int total = 0; - for (int sn : coins) { - CloudCoin cc = new CloudCoin(Config.DEFAULT_NN, sn); - - logger.debug(ltag, "sn: " + sn + " d: " + cc.getDenomination()); - - total += cc.getDenomination(); - } - - - if (total != denomination) { - logger.error(ltag, "Amount mismatch"); - mcr.errText = "Failed to find coins in your SkyWallet. We found only " + total; - if (this.cb != null) { - this.cb.callback(mcr); - } - - return; - } - - receiveFromSkyWallet(this.cb, w, coins, total, skySN); - } - } - - class eSenderChangeCb implements CallbackInterface { - CallbackInterface cb; - makeChangeResult mcr; - String memoUUID; - int denomination; - int skySN; - Wallet w; - - public eSenderChangeCb(CallbackInterface cb, Wallet w, String memoUUID, int denomination, int skySN) { - this.cb = cb; - this.memoUUID = memoUUID; - this.denomination = denomination; - this.skySN = skySN; - this.w = w; - mcr = new makeChangeResult(); - } - - public void callback(final Object result) { - final SenderResult sr = (SenderResult) result; - - logger.debug(ltag, "Sender (Change) finished: " + sr.status); - if (sr.status == SenderResult.STATUS_PROCESSING) { - mcr.status = 1; - mcr.progress = sr.totalRAIDAProcessed; - mcr.text = "Sending coin to SkyChange"; - if (this.cb != null) { - this.cb.callback(mcr); - } - return; - } - - - if (sr.status == SenderResult.STATUS_CANCELLED) { - mcr.errText = "Sender Cancelled"; - if (this.cb != null) { - this.cb.callback(mcr); - } - - return; - } - - if (sr.status == SenderResult.STATUS_ERROR || sr.amount != denomination) { - mcr.errText = "Failed to send coins to the Change Wallet. Check if they were valid"; - if (this.cb != null) { - this.cb.callback(mcr); - } - return; - } - - w.appendTransaction("Sent to ChangeMaker", sr.amount * -1, sr.receiptId); - - requestChange(this.cb, w, memoUUID, denomination, skySN); - - } - - } - class eVaulterChangeCb implements CallbackInterface { CallbackInterface mcb; CloudCoin cc; From 0e9994a1538a8dd98154a488d88da0beb84c25d6 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 12 Sep 2019 12:59:00 +0300 Subject: [PATCH 064/160] change --- src/advclient/AdvancedClient.java | 6 ++- .../common/ChangeMaker/ChangeMaker.java | 38 +++++++------------ .../ShowEnvelopeCoins/ShowEnvelopeCoins.java | 7 +++- src/advclient/common/Transfer/Transfer.java | 11 ++---- .../common/Transfer/TransferResponse.java | 6 +-- src/advclient/common/core/Config.java | 3 ++ src/advclient/common/core/ServantManager.java | 5 ++- 7 files changed, 34 insertions(+), 42 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 38874b8..325e4e5 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -5021,11 +5021,13 @@ public void showTransactionsScreen() { } Enumeration enumeration = envelopes.keys(); + ArrayList hlist = Collections.list(enumeration); + Collections.sort(hlist); + trs = new String[envelopes.size()][]; int i = 0; - while (enumeration.hasMoreElements()) { - String key = enumeration.nextElement(); + for (String key : hlist) { String[] data = envelopes.get(key); trs[i] = new String[4]; diff --git a/src/advclient/common/ChangeMaker/ChangeMaker.java b/src/advclient/common/ChangeMaker/ChangeMaker.java index 3788a85..e6dfdc0 100644 --- a/src/advclient/common/ChangeMaker/ChangeMaker.java +++ b/src/advclient/common/ChangeMaker/ChangeMaker.java @@ -37,6 +37,7 @@ public void launch(int method, CloudCoin cc, CallbackInterface icb) { csb = new StringBuilder(); receiptId = AppCore.generateHex(); cr.receiptId = receiptId; + cr.errText = ""; launchThread(new Runnable() { @Override @@ -57,7 +58,6 @@ private void copyFromGlobalResult(ChangeMakerResult cmr) { cmr.receiptId = cr.receiptId; } - public void doChange(int method, CloudCoin cc) { logger.info(ltag, "Method " + method); @@ -75,8 +75,10 @@ public void doChange(int method, CloudCoin cc) { return; } -/* - results = raida.query(new String[] { "show_change?sn=" + Config.PUBLIC_CHANGE_MAKER_ID }, null, null, new int[] {Config.RAIDANUM_TO_QUERY_BY_DEFAULT}); + String seed = AppCore.generateHex().substring(0, 8); + results = raida.query(new String[] { + "show_change?sn=" + Config.PUBLIC_CHANGE_MAKER_ID + "&seed=" + seed + }, null, null, new int[] { Config.RAIDANUM_TO_QUERY_REQUEST_CHANGE }); if (results == null) { logger.error(ltag, "Failed to query showchange"); cr.status = ChangeMakerResult.STATUS_ERROR; @@ -89,35 +91,20 @@ public void doChange(int method, CloudCoin cc) { cr.status = ChangeMakerResult.STATUS_ERROR; return; } - */ - - resultMain = "{\n" + - " \"server\":\"RAIDA1\",\n" + - " \"status\":\"pass\",\n" + - " \"d250\":[16777210, 16777211, 16777212, 16777213, 16777214],\n" + - " \"d100\":[14680000, 14680001, 14680002, 14680003, 14680004],\n" + - " \"d25\":[6291400, 6291401, 6291402, 6291403, 6291404],\n" + - " \"d5\":[4194200, 4194201, 4194202, 4194203, 4194204, 4194205, 4194206, 4194207],\n" + - " \"d1\":[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],\n" + - " \"message\":\"Change:This report shows the serial numbers that are available to make change now.\",\n" + - " \"version\":\"some version number here\",\n" + - " \"time\":\"2016-44-19 7:44:PM\"\n" + - "}\n"; - - cresponse = (CommonResponse) parseResponse(resultMain, CommonResponse.class); - if (cresponse == null) { + + ShowChangeResponse scr = (ShowChangeResponse) parseResponse(resultMain, ShowChangeResponse.class); + if (scr == null) { logger.error(ltag, "Failed to get response"); cr.status = ChangeMakerResult.STATUS_ERROR; return; } - - if (!cresponse.status.equals(Config.REQUEST_STATUS_PASS)) { - logger.error(ltag, "Failed to get response: " + cresponse.status); + + if (!scr.status.equals(Config.REQUEST_STATUS_PASS)) { + logger.error(ltag, "Failed to get response: " + scr.status); cr.status = ChangeMakerResult.STATUS_ERROR; return; } - - ShowChangeResponse scr = (ShowChangeResponse) parseResponse(resultMain, ShowChangeResponse.class); + int[] sns; int rqDenom = 0; @@ -190,6 +177,7 @@ public void doChange(int method, CloudCoin cc) { if (sns == null) { logger.info(ltag, "No coins"); + cr.errText = "Not enough coins at the Public Change Maker"; cr.status = ChangeMakerResult.STATUS_ERROR; return; } diff --git a/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java b/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java index 5620f59..727bc1e 100644 --- a/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java +++ b/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java @@ -129,6 +129,7 @@ public void doShowSkyCoins(int sn) { String tag; int rsn; int ts; + int ats; CloudCoin rcc; er[j] = (ShowEnvelopeCoinsResponse) o[j]; @@ -136,6 +137,10 @@ public void doShowSkyCoins(int sn) { rsn = er[j].sn; ts = er[j].created; + ats = ts / Config.SECONDS_TO_AGGREGATE_ENVELOPES; + + System.out.println("created="+ts + " ats="+ats); + rcc = new CloudCoin(cc.nn, rsn); int idx = Config.IDX_FOLDER_BANK; switch (rcc.getDenomination()) { @@ -158,7 +163,7 @@ public void doShowSkyCoins(int sn) { result.coins[j] = rsn; result.tags[j] = tag; - key = ts + "." + tag; + key = ats + "." + tag; String[] coinData = new String[3]; coinData[0] = tag; diff --git a/src/advclient/common/Transfer/Transfer.java b/src/advclient/common/Transfer/Transfer.java index b715eea..cfb86ef 100644 --- a/src/advclient/common/Transfer/Transfer.java +++ b/src/advclient/common/Transfer/Transfer.java @@ -354,16 +354,13 @@ public boolean processTransferWithChange(CloudCoin tcc, CloudCoin cc, String tag CloudCoin[] sccs; logger.debug(ltag, "Transferring with change to " + tosn); - - System.out.println("sss"); - System.exit(1); - + sbs = new StringBuilder[RAIDA.TOTAL_RAIDA_COUNT]; posts = new String[RAIDA.TOTAL_RAIDA_COUNT]; requests = new String[RAIDA.TOTAL_RAIDA_COUNT]; for (i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { - requests[i] = "transfer"; + requests[i] = "transfer_with_change"; sbs[i] = new StringBuilder(); sbs[i].append("nn="); @@ -463,9 +460,7 @@ public void callback(Object result) { } else { logger.error(ltag, "Unknown coin status from RAIDA" + i + ": " + strStatus); cstatus = CloudCoin.STATUS_ERROR; - } - - + } } } diff --git a/src/advclient/common/Transfer/TransferResponse.java b/src/advclient/common/Transfer/TransferResponse.java index 4ce94cd..c09d851 100644 --- a/src/advclient/common/Transfer/TransferResponse.java +++ b/src/advclient/common/Transfer/TransferResponse.java @@ -1,8 +1,4 @@ -/* - * To change this license header, choose License Headers in Project Properties. - * To change this template file, choose Tools | Templates - * and open the template in the editor. - */ + package global.cloudcoin.ccbank.Transfer; import global.cloudcoin.ccbank.core.CommonResponse; diff --git a/src/advclient/common/core/Config.java b/src/advclient/common/core/Config.java index d39117e..793b0ae 100644 --- a/src/advclient/common/core/Config.java +++ b/src/advclient/common/core/Config.java @@ -180,4 +180,7 @@ public class Config { public static int PUBLIC_CHANGE_MAKER_ID = 2; + + public static int SECONDS_TO_AGGREGATE_ENVELOPES = 30; + } diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index 3894c0a..5153538 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -727,7 +727,10 @@ public void callback(Object o) { if (cmr.status == ChangeMakerResult.STATUS_ERROR) { logger.debug(ltag, "Error in making Change"); - mcr.errText = "Failed to make Change. Please check the main.log file"; + if (!cmr.errText.isEmpty()) + mcr.errText = cmr.errText; + else + mcr.errText = "Failed to make Change. Please check the main.log file"; mcr.status = 0; if (cb != null) { cb.callback(mcr); From ada60d7f5428532d6cb34caf55e5e5cc98e85897 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 12 Sep 2019 13:00:26 +0300 Subject: [PATCH 065/160] change --- src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java b/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java index 727bc1e..6844159 100644 --- a/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java +++ b/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java @@ -138,9 +138,7 @@ public void doShowSkyCoins(int sn) { ts = er[j].created; ats = ts / Config.SECONDS_TO_AGGREGATE_ENVELOPES; - - System.out.println("created="+ts + " ats="+ats); - + rcc = new CloudCoin(cc.nn, rsn); int idx = Config.IDX_FOLDER_BANK; switch (rcc.getDenomination()) { From 250808846b2f2b1e5ee78a9aee30a847e5d8a11d Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 12 Sep 2019 17:29:55 +0300 Subject: [PATCH 066/160] change --- .../common/ChangeMaker/ChangeMaker.java | 48 ++++--------------- src/advclient/common/Transfer/Transfer.java | 36 ++------------ src/advclient/common/core/Config.java | 2 +- 3 files changed, 15 insertions(+), 71 deletions(-) diff --git a/src/advclient/common/ChangeMaker/ChangeMaker.java b/src/advclient/common/ChangeMaker/ChangeMaker.java index e6dfdc0..f101141 100644 --- a/src/advclient/common/ChangeMaker/ChangeMaker.java +++ b/src/advclient/common/ChangeMaker/ChangeMaker.java @@ -67,6 +67,7 @@ public void doChange(int method, CloudCoin cc) { CommonResponse cresponse; ShowEnvelopeCoinsResponse[] srs; String[] requests; + String[] posts; if (!updateRAIDAStatus()) { @@ -75,6 +76,7 @@ public void doChange(int method, CloudCoin cc) { return; } + Config.RAIDANUM_TO_QUERY_REQUEST_CHANGE = 7; String seed = AppCore.generateHex().substring(0, 8); results = raida.query(new String[] { "show_change?sn=" + Config.PUBLIC_CHANGE_MAKER_ID + "&seed=" + seed @@ -188,14 +190,16 @@ public void doChange(int method, CloudCoin cc) { } requests = new String[RAIDA.TOTAL_RAIDA_COUNT]; + posts = new String[RAIDA.TOTAL_RAIDA_COUNT]; for (int i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { - requests[i] = "change?nn=" + cc.nn + "&sn=" + cc.sn + "&an=" + cc.ans[i] + "&denomination=" + cc.getDenomination(); + requests[i] = "change"; + posts[i] = "nn=" + cc.nn + "&sn=" + cc.sn + "&an=" + cc.ans[i] + "&denomination=" + cc.getDenomination(); for (int j = 0; j < sns.length; j++) { - requests[i] += "&sns[]=" + sns[j]; + posts[i] += "&sns[]=" + sns[j]; } } - results = raida.query(requests, null, new CallbackInterface() { + results = raida.query(requests, posts, new CallbackInterface() { final GLogger gl = logger; final CallbackInterface myCb = cb; @@ -216,42 +220,6 @@ public void callback(Object result) { cr.status = ChangeMakerResult.STATUS_ERROR; return; } - - if (results == null) { - logger.error(ltag, "Failed to query change results"); - cr.status = ChangeMakerResult.STATUS_ERROR; - return; - } - - - results = new String[] { - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - "{\"server\":\"r\", \"status\":\"pass\", \"nn\":\"1\", \"sns\":[10,20,30,40,50,60,70,80,90,100,110,111], \"ans\":[02222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222, 22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,22222222222222222222222222222222,12222222222222222222222222222222], \"message\":\"xxx\", \"version\":\"1\", \"time\":\"232\"}", - - }; int cntErr = 0; ChangeResponse[] crs = new ChangeResponse[RAIDA.TOTAL_RAIDA_COUNT]; @@ -327,8 +295,10 @@ public void callback(Object result) { } } + logger.debug(ltag, "Error count: " + cntErr); if (cntErr >= RAIDA.TOTAL_RAIDA_COUNT - Config.PASS_THRESHOLD) { logger.error(ltag, "Too many errors: " + cntErr); + cr.errText = "Failed to get change. Too many errors from RAIDA: " + cntErr; cr.status = ChangeMakerResult.STATUS_ERROR; return; } diff --git a/src/advclient/common/Transfer/Transfer.java b/src/advclient/common/Transfer/Transfer.java index cfb86ef..ad97b0e 100644 --- a/src/advclient/common/Transfer/Transfer.java +++ b/src/advclient/common/Transfer/Transfer.java @@ -344,9 +344,7 @@ public void callback(Object result) { public boolean processTransferWithChange(CloudCoin tcc, CloudCoin cc, String tag, int tosn, int amount) { String[] results; - Object[] o; CommonResponse errorResponse; - TransferResponse[][] trs; String[] requests; StringBuilder[] sbs; String[] posts; @@ -411,7 +409,6 @@ public void callback(Object result) { } sccs = new CloudCoin[1]; - trs = new TransferResponse[RAIDA.TOTAL_RAIDA_COUNT][]; for (i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { logger.info(ltag, "i="+i+ " r="+results[i]); if (results[i] != null) { @@ -421,7 +418,7 @@ public void callback(Object result) { } } - o = parseArrayResponse(results[i], TransferResponse.class); + TransferResponse o = (TransferResponse) parseResponse(results[i], TransferResponse.class); if (o == null) { errorResponse = (CommonResponse) parseResponse(results[i], CommonResponse.class); if (errorResponse == null) { @@ -432,36 +429,13 @@ public void callback(Object result) { logger.error(ltag, "Failed to auth coin. Status: " + errorResponse.status); continue; } - - if (o.length != sccs.length) { - logger.error(ltag, "RAIDA " + i + " wrong number of coins: " + o.length); + + if (!o.status.equals(Config.REQUEST_STATUS_PASS)) { + logger.error(ltag, "Invalid status from raida " + i + " status: " + o.status); continue; } - for (int j = 0; j < o.length; j++) { - String strStatus; - int rnn, rsn; - String ran; - boolean found; - - trs[i] = new TransferResponse[o.length]; - trs[i][j] = (TransferResponse) o[j]; - - strStatus = trs[i][j].status; - - found = false; - int cstatus; - if (strStatus.equals(Config.REQUEST_STATUS_PASS)) { - logger.info(ltag, "OK response from raida " + i); - cstatus = CloudCoin.STATUS_PASS; - } else if (strStatus.equals(Config.REQUEST_STATUS_FAIL)) { - logger.error(ltag, "Counterfeit response from raida " + i); - cstatus = CloudCoin.STATUS_FAIL; - } else { - logger.error(ltag, "Unknown coin status from RAIDA" + i + ": " + strStatus); - cstatus = CloudCoin.STATUS_ERROR; - } - } + logger.debug(ltag, "Change from RAIDA " + i + " OK"); } logger.info(ltag, "Change Transferred"); diff --git a/src/advclient/common/core/Config.java b/src/advclient/common/core/Config.java index 793b0ae..4524300 100644 --- a/src/advclient/common/core/Config.java +++ b/src/advclient/common/core/Config.java @@ -112,7 +112,7 @@ public class Config { public static String SENDER_DOMAIN = "teleportnow.cc"; public static int RAIDANUM_TO_QUERY_BY_DEFAULT = 7; - public static int RAIDANUM_TO_QUERY_REQUEST_CHANGE = 18; + public static int RAIDANUM_TO_QUERY_REQUEST_CHANGE = 7; public static int MAX_COMMON_LOG_LENGTH_MB = 128; From 915e5fd3305fca3c2e6d59c0e8ac7660196b7b62 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 13 Sep 2019 17:19:28 +0300 Subject: [PATCH 067/160] icon --- src/advclient/AppUI.java | 8 ++++++ src/advclient/common/Transfer/Transfer.java | 31 ++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/src/advclient/AppUI.java b/src/advclient/AppUI.java index df44de4..480a6c0 100644 --- a/src/advclient/AppUI.java +++ b/src/advclient/AppUI.java @@ -413,6 +413,14 @@ public static JFrame getMainFrame(String version) { frame.setResizable(false); frame.setVisible(true); + ClassLoader cl; + cl = AppUI.class.getClassLoader(); + + /* + frame.setIconImage( + new ImageIcon(cl.getResource("resources/CloudCoinLogo.png")).getImage() + ); + */ return frame; } diff --git a/src/advclient/common/Transfer/Transfer.java b/src/advclient/common/Transfer/Transfer.java index ad97b0e..dbf5cf7 100644 --- a/src/advclient/common/Transfer/Transfer.java +++ b/src/advclient/common/Transfer/Transfer.java @@ -332,10 +332,30 @@ public void callback(Object result) { cstatus = CloudCoin.STATUS_ERROR; } - + ccs.get(j).setDetectStatus(i, cstatus); } } + boolean failed = false; + for (CloudCoin tcc : ccs) { + //tcc.setPownStringFromDetectStatus(); + + int cnt = AppCore.getPassedCount(tcc); + + logger.info(ltag, "cc " + tcc.sn + " " + tcc.getPownString()); + + if (cnt < Config.PASS_THRESHOLD) { + logger.error(ltag, "Coin " + tcc.sn + " was not transferred. PassCount: " + tcc.sn); + failed = true; + } + } + + if (failed) { + tr.errText = "Some coins were transferred with errors. Please check the main.log file"; + logger.error(ltag, "Transfer failed"); + return false; + } + logger.info(ltag, "Transferred"); return true; @@ -436,8 +456,17 @@ public void callback(Object result) { } logger.debug(ltag, "Change from RAIDA " + i + " OK"); + tcc.setDetectStatus(i, CloudCoin.STATUS_PASS); } + int cnt = AppCore.getPassedCount(tcc); + logger.info(ltag, "cc " + tcc.sn + " " + tcc.getPownString()); + + if (cnt < Config.PASS_THRESHOLD) { + logger.error(ltag, "Transfer Change Failed"); + return false; + } + logger.info(ltag, "Change Transferred"); return true; From 271ad9fe247a4022d7f3736298259bc53463dff7 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 13 Sep 2019 17:21:55 +0300 Subject: [PATCH 068/160] icon --- src/advclient/AppUI.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/advclient/AppUI.java b/src/advclient/AppUI.java index 480a6c0..58148d6 100644 --- a/src/advclient/AppUI.java +++ b/src/advclient/AppUI.java @@ -416,11 +416,10 @@ public static JFrame getMainFrame(String version) { ClassLoader cl; cl = AppUI.class.getClassLoader(); - /* frame.setIconImage( new ImageIcon(cl.getResource("resources/CloudCoinLogo.png")).getImage() ); - */ + return frame; } From bc313d6d422a89ffbdc9352f87795e08f879f215 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Tue, 17 Sep 2019 13:50:20 +0300 Subject: [PATCH 069/160] echoer --- src/advclient/common/Echoer/Echoer.java | 5 +++++ src/advclient/common/core/RAIDA.java | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/advclient/common/Echoer/Echoer.java b/src/advclient/common/Echoer/Echoer.java index 5fffba3..68f0ad2 100644 --- a/src/advclient/common/Echoer/Echoer.java +++ b/src/advclient/common/Echoer/Echoer.java @@ -47,6 +47,9 @@ private void setRAIDAUrl(String ip, int basePort) { } public void doEcho() { + cleanLogDir(); + raida.setDefaultUrls(); + if (!doEchoReal()) { logger.info(ltag, "Switching to the Backup0 RAIDA"); @@ -76,6 +79,8 @@ public boolean doEchoReal() { int cntErr = 0; int i; + + requests = new String[RAIDA.TOTAL_RAIDA_COUNT]; for (i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) requests[i] = "echo"; diff --git a/src/advclient/common/core/RAIDA.java b/src/advclient/common/core/RAIDA.java index 3af92c8..8d4a582 100644 --- a/src/advclient/common/core/RAIDA.java +++ b/src/advclient/common/core/RAIDA.java @@ -59,6 +59,11 @@ public void setReadTimeout(int timeout) { } } + public void setDefaultUrls() { + for (int i = 0; i < TOTAL_RAIDA_COUNT; i++) + agents[i].setDefaultFullUrl(); + } + public void setExactUrls(String[] urls) { for (int i = 0; i < TOTAL_RAIDA_COUNT; i++) { logger.info(ltag, "Set RAIDA url to " + urls[i]); From 0df11ca9512bd76acc521e5031cd8ec6bf642127 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Tue, 17 Sep 2019 13:50:56 +0300 Subject: [PATCH 070/160] version bump --- src/advclient/AdvancedClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 325e4e5..ee846b2 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -56,7 +56,7 @@ * */ public class AdvancedClient { - String version = "2.1.14"; + String version = "2.1.15"; JPanel headerPanel; JPanel mainPanel; From 67d00aee4de36de462f5f8aa453cd14e2a6c1204 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Tue, 17 Sep 2019 14:12:59 +0300 Subject: [PATCH 071/160] Sky wallet history --- src/advclient/AdvancedClient.java | 5 ++++- src/advclient/common/core/Wallet.java | 21 +++++++++++++++++++++ 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index ee846b2..5624839 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -5255,7 +5255,10 @@ public void actionPerformed(ActionEvent e) { int rVal = c.showSaveDialog(null); if (rVal == JFileChooser.APPROVE_OPTION) { - w.saveTransations(c.getSelectedFile().getAbsolutePath()); + if (w.isSkyWallet()) + w.saveEnvelopes(c.getSelectedFile().getAbsolutePath()); + else + w.saveTransations(c.getSelectedFile().getAbsolutePath()); if (!Desktop.isDesktopSupported()) return; try { diff --git a/src/advclient/common/core/Wallet.java b/src/advclient/common/core/Wallet.java index 84cca16..e386eb8 100644 --- a/src/advclient/common/core/Wallet.java +++ b/src/advclient/common/core/Wallet.java @@ -6,6 +6,9 @@ package global.cloudcoin.ccbank.core; import java.io.File; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Enumeration; import java.util.Hashtable; @@ -155,6 +158,24 @@ public void saveTransations(String dstPath) { AppCore.copyFile(fileName, dstPath); } + public void saveEnvelopes(String dstPath) { + StringBuilder sb = new StringBuilder(); + + Enumeration enumeration = envelopes.keys(); + ArrayList hlist = Collections.list(enumeration); + Collections.sort(hlist); + + for (String key : hlist) { + String[] data = envelopes.get(key); + + String value = data[0] + "," + data[2] + "," + data[1] + lsep; + sb.append(value); + } + + logger.debug(ltag, "Saving " + dstPath); + AppCore.saveFile(dstPath, sb.toString()); + } + public String[][] getTransactions() { String fileName = getTransactionsFileName(); From 8b5f55ccb51a519f68e37abbe8edf8194c9ae198 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Tue, 17 Sep 2019 15:50:39 +0300 Subject: [PATCH 072/160] select wallet after creation --- src/advclient/AdvancedClient.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 5624839..f48de74 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -2770,7 +2770,7 @@ public void showWalletCreatedScreen() { AppUI.getTwoButtonPanel(subInnerCore, "", "Continue", null, new ActionListener() { public void actionPerformed(ActionEvent e) { - sm.setActiveWallet(ps.typedWalletName); + setActiveWallet(sm.getWalletByName(ps.typedWalletName)); ps.currentScreen = ProgramState.SCREEN_SHOW_TRANSACTIONS; showScreen(); } @@ -2812,7 +2812,8 @@ public void showSkyWalletCreatedScreen() { AppUI.getTwoButtonPanel(subInnerCore, "", "Continue", null, new ActionListener() { public void actionPerformed(ActionEvent e) { - sm.setActiveWallet(ps.domain + "." + ps.trustedServer); + //sm.setActiveWallet(ps.domain + "." + ps.trustedServer); + setActiveWallet(sm.getWalletByName(ps.domain + "." + ps.trustedServer)); ps.currentScreen = ProgramState.SCREEN_SHOW_TRANSACTIONS; showScreen(); } From 7a33eff2766cb68780dac483a19865f8ca314df8 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Tue, 17 Sep 2019 16:01:18 +0300 Subject: [PATCH 073/160] frackfixer without echo --- src/advclient/AdvancedClient.java | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index f48de74..452988e 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -1151,21 +1151,6 @@ public void showFixingfrackedScreen() { Thread t = new Thread(new Runnable() { public void run(){ - if (!ps.isEchoFinished) { - pbarText.setText("Checking RAIDA ..."); - pbarText.repaint(); - } - - try { - Thread.sleep(200); - } catch (InterruptedException e) {} - - while (!ps.isEchoFinished) { - try { - Thread.sleep(300); - } catch (InterruptedException e) {} - } - wl.debug(ltag, "Fixing coins in " + ps.srcWallet.getName()); sm.setActiveWalletObj(ps.srcWallet); From 0e790b832bc1fc88aedcad87b769acb60cf71522 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 19 Sep 2019 14:15:09 +0300 Subject: [PATCH 074/160] Fracked SkyID workflow --- src/advclient/AdvancedClient.java | 137 +++++++++++++++++++++++--- src/advclient/ProgramState.java | 7 +- src/advclient/common/core/Config.java | 4 + 3 files changed, 136 insertions(+), 12 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 452988e..048ea81 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -198,8 +198,8 @@ else if (total < 999999999) } public String getSkyIDError(String name, String pownString) { - return "Your Sky Coin ID " + name + " is not authentic. It is not safe to use it.

" - + "The Pown String is " + pownString + "

Move the Coin to the Fracked folder of any Wallet and fix it"; + return "Your Sky Coin ID " + name + " is counterfeit. It is not safe to use it.

" + + "The Pown String is " + pownString + ""; } public String getSkyIDErrorIfRAIDAFailed() { @@ -998,6 +998,10 @@ public void showScreen() { case ProgramState.SCREEN_SETTINGS_SAVED: showSettingsDoneScreen(); break; + case ProgramState.SCREEN_WARN_FRACKED_TO_SEND: + showWarnFrackedToSend(); + break; + } Component[] cs = lwrapperPanel.getComponents(); @@ -1562,6 +1566,7 @@ public void run(){ } CloudCoin skyCC = null; + ps.coinIDinFix = null; if (ps.srcWallet.isSkyWallet()) { ps.isCheckingSkyID = true; skyCC = ps.srcWallet.getIDCoin(); @@ -1575,17 +1580,19 @@ public void run(){ Thread.sleep(300); } catch (InterruptedException e) {} } - - if (AppCore.getErrorCount(skyCC) > 0) { + + if (AppCore.getErrorCount(skyCC) > Config.MAX_FAILED_RAIDAS_TO_SEND) { ps.errText = getSkyIDErrorIfRAIDAFailed(); showScreen(); return; - } - - if (AppCore.getPassedCount(skyCC) != RAIDA.TOTAL_RAIDA_COUNT) { + } else if (AppCore.getPassedCount(skyCC) < Config.PASS_THRESHOLD) { ps.errText = getSkyIDError(ps.srcWallet.getName(), ps.srcWallet.getIDCoin().getPownString()); showScreen(); return; + } else if (AppCore.getPassedCount(skyCC) != RAIDA.TOTAL_RAIDA_COUNT) { + ps.currentScreen = ProgramState.SCREEN_WARN_FRACKED_TO_SEND; + showScreen(); + return; } } @@ -2327,6 +2334,72 @@ public void actionPerformed(ActionEvent e) { } + public void showWarnFrackedToSend() { + int y = 0; + JLabel fname, value; + MyTextField walletName = null; + + JPanel subInnerCore = getPanel("Fix Fracked Coin"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + fname = AppUI.wrapDiv("Your Address Coin for " + ps.srcWallet.getName() + " is fracked. This means that one or more of the " + + "RAIDA think that it is not authentic. Please fix it before sending"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + AppUI.setBoldFont(fname, 21); + y++; + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Fix Coin", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { + public void actionPerformed(ActionEvent e) { + Wallet w = sm.getFirstNonSkyWallet(); + if (w == null) { + ps.errText = "Address Coin can't be fixed bacuse you do not have any wallets"; + showScreen(); + return; + } + + wl.debug(ltag, "Chosen wallet for fixing: " + w.getName()); + + ps.coinIDinFix = ps.srcWallet; + ps.srcWallet = w; + + int cnt = AppCore.getFilesCount(Config.DIR_FRACKED, ps.srcWallet.getName()); + if (cnt != 0) { + ps.errText = "Coin can't be fixed. Fracked forder of the wallet " + ps.srcWallet.getName() + " is not empty"; + showScreen(); + return; + } + + String newFileName = AppCore.getUserDir(Config.DIR_FRACKED, ps.srcWallet.getName()) + File.separator + ps.coinIDinFix.getName() + ".stack"; + wl.debug(ltag, "New name: " + newFileName); + + if (!AppCore.saveFile(newFileName, ps.coinIDinFix.getIDCoin().getJson(false))) { + ps.errText = "Failed to move ID Coin. Please, check main.log file"; + showScreen(); + return; + } + + AppCore.moveToFolder(ps.coinIDinFix.getIDCoin().originalFile, Config.DIR_TRASH, ps.srcWallet.getName()); + + wl.debug(ltag, "Set fixing"); + ps.currentScreen = ProgramState.SCREEN_FIXING_FRACKED; + showScreen(); + + } + }, y, gridbag); + + subInnerCore.revalidate(); + subInnerCore.repaint(); + } + public void showConfirmClearScreen() { int y = 0; JLabel fname, value; @@ -5672,14 +5745,12 @@ public void callback(Object result) { return; } - if (AppCore.getErrorCount(fcc) > 0) { + if (AppCore.getErrorCount(fcc) > Config.MAX_FAILED_RAIDAS_TO_SEND) { ps.currentScreen = ProgramState.SCREEN_SKY_WALLET_CREATED; ps.errText = getSkyIDErrorIfRAIDAFailed(); showScreen(); return; - } - - if (AppCore.getPassedCount(fcc) != RAIDA.TOTAL_RAIDA_COUNT) { + } else if (AppCore.getPassedCount(fcc) < Config.PASS_THRESHOLD) { ps.currentScreen = ProgramState.SCREEN_SKY_WALLET_CREATED; ps.errText = getSkyIDError(wname, fcc.getPownString()); showScreen(); @@ -6888,6 +6959,50 @@ public void callback(final Object result) { wl.debug(ltag, "LossFixer finished"); + if (ps.coinIDinFix != null) { + wl.debug(ltag, "We are fixing coin id: " + ps.coinIDinFix.getName()); + ps.coinIDinFix.setNotUpdated(); + EventQueue.invokeLater(new Runnable() { + public void run() { + wl.debug(ltag, "Looking for: " + ps.srcWallet.getName() + " sn: " + ps.coinIDinFix.getIDCoin().sn); + + boolean fixed = true; + CloudCoin cc = AppCore.findCoinBySN(Config.DIR_BANK, ps.srcWallet.getName(), ps.coinIDinFix.getIDCoin().sn); + if (cc == null) { + wl.debug(ltag, "Failed to fix. Trying to move the coin back"); + cc = AppCore.findCoinBySN(Config.DIR_FRACKED, ps.srcWallet.getName(), ps.coinIDinFix.getIDCoin().sn); + if (cc == null) { + ps.currentScreen = ProgramState.SCREEN_WITHDRAW; + ps.errText = "Failed to find fixed coin. Please, check main.log file"; + showScreen(); + return; + } + + fixed = false; + } + + wl.debug(ltag, "Found cc: " + cc.originalFile); + + if (!AppCore.moveToFolderNewName(cc.originalFile, AppCore.getIDDir(), null, ps.coinIDinFix.getName() + ".stack")) { + ps.currentScreen = ProgramState.SCREEN_WITHDRAW; + ps.errText = "Failed to move ID Coin. Please, check main.log file"; + showScreen(); + return; + } + + ps.currentScreen = ProgramState.SCREEN_WITHDRAW; + if (fixed) + ps.errText = "ID Coin has been fixed. Please try again"; + else + ps.errText = "Failed to fix ID Coin. Please try again later"; + + ps.coinIDinFix.setIDCoin(cc); + showScreen(); + } + }); + return; + } + if (lr.recovered > 0) { sm.getActiveWallet().appendTransaction("LossFixer Recovered", lr.recoveredValue, lr.receiptId); diff --git a/src/advclient/ProgramState.java b/src/advclient/ProgramState.java index 312de37..566202e 100644 --- a/src/advclient/ProgramState.java +++ b/src/advclient/ProgramState.java @@ -61,6 +61,7 @@ public class ProgramState { final public static int SCREEN_CHECKING_SKYID = 43; final public static int SCREEN_SETTINGS = 44; final public static int SCREEN_SETTINGS_SAVED = 45; + final public static int SCREEN_WARN_FRACKED_TO_SEND = 46; final static int CB_STATE_INIT = 1; @@ -96,7 +97,10 @@ public class ProgramState { Wallet dstWallet; Wallet srcWallet; + Wallet coinIDinFix; + boolean isEchoFinished; + int statToBankValue, statToBank, statFailed, statLost; int statFailedValue, statLostValue; @@ -212,7 +216,8 @@ public ProgramState() { popupVisible = false; isCheckingSkyID = false; - + + coinIDinFix = null; } public String toString() { diff --git a/src/advclient/common/core/Config.java b/src/advclient/common/core/Config.java index 4524300..4312f02 100644 --- a/src/advclient/common/core/Config.java +++ b/src/advclient/common/core/Config.java @@ -183,4 +183,8 @@ public class Config { public static int SECONDS_TO_AGGREGATE_ENVELOPES = 30; + public static int MAX_COUNTERFEIT_RAIDAS_TO_SEND = 2; + public static int MAX_FAILED_RAIDAS_TO_SEND = 2; + + } From 821846848af4c62da7410918c25ee8d0add8e98f Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 19 Sep 2019 14:26:49 +0300 Subject: [PATCH 075/160] autoupdate sky wallets --- src/advclient/AdvancedClient.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 048ea81..089e0d2 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -881,7 +881,6 @@ public void showScreen() { showSetEmailScreen(); break; case ProgramState.SCREEN_WALLET_CREATED: - ps.isUpdatedWallets = false; showWalletCreatedScreen(); break; case ProgramState.SCREEN_PREPARE_TO_ADD_WALLET: @@ -908,7 +907,6 @@ public void showScreen() { showImportingScreen(); break; case ProgramState.SCREEN_IMPORT_DONE: - ps.isUpdatedWallets = false; showImportDoneScreen(); break; case ProgramState.SCREEN_SUPPORT: @@ -918,7 +916,6 @@ public void showScreen() { showConfirmTransferScreen(); break; case ProgramState.SCREEN_TRANSFER_DONE: - ps.isUpdatedWallets = false; showTransferDoneScreen(); break; case ProgramState.SCREEN_BACKUP: @@ -964,11 +961,9 @@ public void showScreen() { showConfirmDeleteWalletScreen(); break; case ProgramState.SCREEN_DELETE_WALLET_DONE: - ps.isUpdatedWallets = false; showDeleteWalletDoneScreen(); break; case ProgramState.SCREEN_SKY_WALLET_CREATED: - ps.isUpdatedWallets = false; showSkyWalletCreatedScreen(); break; case ProgramState.SCREEN_PREDEPOSIT: @@ -6159,6 +6154,7 @@ public void mouseReleased(MouseEvent e) { setActiveWallet(fwallet); ps.sendType = 0; ps.currentScreen = ProgramState.SCREEN_SHOW_TRANSACTIONS; + fwallet.setNotUpdated(); showScreen(); } @@ -6865,7 +6861,6 @@ public void run() { sm.getActiveWallet().setNotUpdated(); EventQueue.invokeLater(new Runnable() { public void run() { - ps.isUpdatedWallets = false; ps.currentScreen = ProgramState.SCREEN_SHOW_TRANSACTIONS; //ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; showScreen(); From 78dfe6f8380b940cd237b18e0fa522971c142a25 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 19 Sep 2019 14:29:33 +0300 Subject: [PATCH 076/160] ps --- src/advclient/ProgramState.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/advclient/ProgramState.java b/src/advclient/ProgramState.java index 566202e..c789b59 100644 --- a/src/advclient/ProgramState.java +++ b/src/advclient/ProgramState.java @@ -117,8 +117,6 @@ public class ProgramState { int sendType; - boolean isUpdatedWallets; - int foundSN; boolean needBackup; @@ -183,8 +181,6 @@ public ProgramState() { sendType = SEND_TYPE_WALLET; - isUpdatedWallets = false; - needBackup = false; cenvelopes = null; From 5a360e6459b1a71666b0095238b8dc0aa9736cb2 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 19 Sep 2019 17:41:59 +0300 Subject: [PATCH 077/160] change service improvements --- src/advclient/common/Transfer/Transfer.java | 8 +++++++- src/advclient/common/Vaulter/Vaulter.java | 3 +-- src/advclient/common/core/ServantManager.java | 10 ++++++++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/src/advclient/common/Transfer/Transfer.java b/src/advclient/common/Transfer/Transfer.java index dbf5cf7..19c792e 100644 --- a/src/advclient/common/Transfer/Transfer.java +++ b/src/advclient/common/Transfer/Transfer.java @@ -76,7 +76,6 @@ public void doTransfer(int fromsn, int tosn, int sns[], String tag, int amount) cb.callback(tr); return; } - CloudCoin extraCoin = null; if (!pickCoinsAmountFromArray(sns, amount)) { @@ -120,6 +119,9 @@ public void doTransfer(int fromsn, int tosn, int sns[], String tag, int amount) logger.debug(ltag, "Maxcoins: " + maxCoins); globalResult.totalFiles = coinsPicked.size(); + if (extraCoin != null) + globalResult.totalFiles++; + globalResult.totalRAIDAProcessed = 0; globalResult.totalFilesProcessed = 0; globalResult.totalCoinsProcessed = 0; @@ -136,6 +138,10 @@ public void doTransfer(int fromsn, int tosn, int sns[], String tag, int amount) globalResult.totalCoins += cc.getDenomination(); } + if (extraCoin != null) + globalResult.totalCoins += extraCoin.getDenomination(); + + int curValProcessed = 0; for (CloudCoin cc : coinsPicked) { logger.debug(ltag, "Transferring from SN " + fromsn + " to SN " + tosn); diff --git a/src/advclient/common/Vaulter/Vaulter.java b/src/advclient/common/Vaulter/Vaulter.java index 0d2e2b9..010a606 100644 --- a/src/advclient/common/Vaulter/Vaulter.java +++ b/src/advclient/common/Vaulter/Vaulter.java @@ -291,8 +291,7 @@ private boolean getCoins(String folder, int amount, CloudCoin cc, String addFold return true; } - if (amount != 0) { - + if (amount != 0) { if (addFolder != null) { logger.debug(ltag, "Checking with fracked. Dir " + addFolder); if (!pickCoinsAmountInDirs(folder, addFolder, amount)) { diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index 5153538..6eec4c8 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -682,7 +682,6 @@ public boolean sendToChange(CloudCoin cc, Wallet w, int skySN, CallbackInterface } logger.debug(ltag, "Sending to the ChangeMaker " + cc.sn + " denomination " + cc.getDenomination()); - System.out.println("Sending to the ChangeMaker " + cc.sn); int method = 0; switch (cc.getDenomination()) { @@ -971,7 +970,14 @@ public void callback(final Object result) { } if (vresult.status == VaulterResult.STATUS_FINISHED) { - sendToChange(cc, w, skySN, mcb); + CloudCoin ncc = AppCore.findCoinBySN(Config.DIR_BANK, w.getName(), cc.sn); + if (ncc == null) { + makeChangeResult mcr = new makeChangeResult(); + mcr.errText = "Failed to decrypt coin. The resulting coin is missing in the Bank"; + this.mcb.callback(mcr); + return; + } + sendToChange(ncc, w, skySN, mcb); } } } From c59a0e1dd2bc9b388e7102f52b4fb2bf842ca414 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 25 Sep 2019 17:31:26 +0300 Subject: [PATCH 078/160] add warnings --- src/advclient/AdvancedClient.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 089e0d2..aefd536 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -56,7 +56,7 @@ * */ public class AdvancedClient { - String version = "2.1.15"; + String version = "2.1.16"; JPanel headerPanel; JPanel mainPanel; @@ -3583,6 +3583,10 @@ public void showPredepositScreen() { return; } + JLabel tw = AppUI.wrapDiv("Deposit from Sky Wallet will deposit all coins from that Sky wallet!
" + + "You will be not able to select just part of the Sky Wallet coins."); + AppUI.getGBRow(subInnerCore, null, tw, y, gridbag); + y++; fname = new JLabel("Deposit From"); int cnt = 0, scnt = 0; @@ -3594,7 +3598,6 @@ public void showPredepositScreen() { cnt++; } - final String[] options = new String[cnt + 1]; final String[] doptions = new String[wallets.length - scnt]; int j = 0, k = 0; @@ -5552,6 +5555,11 @@ public void showCreateSkyWalletScreen() { chooser.setFileFilter(filter); + JLabel tw = AppUI.wrapDiv("The coin that you use for ID will be placed into your ID folder. " + + "It will not be available for spending until you close your SkyWallet"); + AppUI.getGBRow(subInnerCore, null, tw, y, gridbag); + y++; + fname = new JLabel("Add Existing"); final MyCheckBoxToggle cb1 = new MyCheckBoxToggle(); if (ps.isCreatingNewSkyWallet) From 5d3513c850f6d19655cd9664f16a511442563fd5 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 26 Sep 2019 14:26:18 +0300 Subject: [PATCH 079/160] showcoins & showchange multi queries --- src/advclient/AdvancedClient.java | 35 +- .../common/ChangeMaker/ChangeMaker.java | 476 +--------------- .../ChangeMaker/ShowChangeResponse.java | 10 +- .../ShowEnvelopeCoins/ShowEnvelopeCoins.java | 158 ++++-- src/advclient/common/core/AppCore.java | 65 ++- src/advclient/common/core/Config.java | 1 + src/advclient/common/core/Servant.java | 507 ++++++++++++++++++ 7 files changed, 701 insertions(+), 551 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index aefd536..dd63a91 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -71,10 +71,7 @@ public class AdvancedClient { //Sets the default screen width and height int tw = 1208; int th = 726; - - // int tw = 870; - // int th = 524; - + int headerHeight; ProgramState ps; @@ -1151,7 +1148,12 @@ public void showFixingfrackedScreen() { Thread t = new Thread(new Runnable() { public void run(){ wl.debug(ltag, "Fixing coins in " + ps.srcWallet.getName()); - + try { + while (!ps.isEchoFinished) { + Thread.sleep(100); + } + } catch (InterruptedException e) {} + sm.setActiveWalletObj(ps.srcWallet); sm.startFrackFixerService(new FrackFixerOnPurposeCb()); } @@ -1340,20 +1342,7 @@ public void showMakingChangeScreen() { c.gridy = 2; gridbag.setConstraints(pbar, c); ct.add(pbar); - - // Cancel button - /* - JPanel bp = getOneButtonPanelCustom("Cancel", new ActionListener() { - public void actionPerformed(ActionEvent e) { - sm.cancel("Sender"); - ps.currentScreen = ProgramState.SCREEN_DEFAULT; - showScreen(); - } - }); - - subInnerCore.add(bp); - */ subInnerCore.add(AppUI.hr(120)); pbar.setVisible(false); @@ -7158,9 +7147,13 @@ public void run() { ps.errText = "Coins were not sent. Please check the logs"; } - ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; - showScreen(); - + EventQueue.invokeLater(new Runnable() { + public void run() { + ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; + showScreen(); + } + }); + } } diff --git a/src/advclient/common/ChangeMaker/ChangeMaker.java b/src/advclient/common/ChangeMaker/ChangeMaker.java index f101141..580aad7 100644 --- a/src/advclient/common/ChangeMaker/ChangeMaker.java +++ b/src/advclient/common/ChangeMaker/ChangeMaker.java @@ -61,124 +61,18 @@ private void copyFromGlobalResult(ChangeMakerResult cmr) { public void doChange(int method, CloudCoin cc) { logger.info(ltag, "Method " + method); - String resultMain; String[] results; - Object[] o; - CommonResponse cresponse; - ShowEnvelopeCoinsResponse[] srs; String[] requests; String[] posts; - - + if (!updateRAIDAStatus()) { logger.error(ltag, "Failed to query RAIDA"); cr.status = ChangeMakerResult.STATUS_ERROR; return; } - Config.RAIDANUM_TO_QUERY_REQUEST_CHANGE = 7; - String seed = AppCore.generateHex().substring(0, 8); - results = raida.query(new String[] { - "show_change?sn=" + Config.PUBLIC_CHANGE_MAKER_ID + "&seed=" + seed - }, null, null, new int[] { Config.RAIDANUM_TO_QUERY_REQUEST_CHANGE }); - if (results == null) { - logger.error(ltag, "Failed to query showchange"); - cr.status = ChangeMakerResult.STATUS_ERROR; - return; - } - - resultMain = results[0]; - if (resultMain == null) { - logger.error(ltag, "Failed to query showchange"); - cr.status = ChangeMakerResult.STATUS_ERROR; - return; - } - - ShowChangeResponse scr = (ShowChangeResponse) parseResponse(resultMain, ShowChangeResponse.class); - if (scr == null) { - logger.error(ltag, "Failed to get response"); - cr.status = ChangeMakerResult.STATUS_ERROR; - return; - } - - if (!scr.status.equals(Config.REQUEST_STATUS_PASS)) { - logger.error(ltag, "Failed to get response: " + scr.status); - cr.status = ChangeMakerResult.STATUS_ERROR; - return; - } - - int[] sns; - int rqDenom = 0; - - switch (method) { - case Config.CHANGE_METHOD_5A: - sns = getA(scr.d1, 5); - rqDenom = 5; - break; - case Config.CHANGE_METHOD_25A: - sns = getA(scr.d5, 5); - rqDenom = 25; - break; - case Config.CHANGE_METHOD_25B: - sns = get25B(scr.d5, scr.d1); - rqDenom = 25; - break; - case Config.CHANGE_METHOD_25C: - sns = get25C(scr.d5, scr.d1); - rqDenom = 25; - break; - case Config.CHANGE_METHOD_25D: - sns = get25D(scr.d1); - rqDenom = 25; - break; - case Config.CHANGE_METHOD_100A: - sns = getA(scr.d25, 4); - rqDenom = 100; - break; - case Config.CHANGE_METHOD_100B: - sns = get100B(scr.d25, scr.d5); - rqDenom = 100; - break; - case Config.CHANGE_METHOD_100C: - sns = get100C(scr.d25, scr.d5, scr.d1); - rqDenom = 100; - break; - case Config.CHANGE_METHOD_100D: - sns = get100D(scr.d1); - rqDenom = 100; - break; - case Config.CHANGE_METHOD_100E: - sns = get100E(scr.d25, scr.d5, scr.d1); - rqDenom = 100; - break; - case Config.CHANGE_METHOD_250A: - sns = get250A(scr.d100, scr.d25); - rqDenom = 250; - break; - case Config.CHANGE_METHOD_250B: - sns = get250B(scr.d25, scr.d5, scr.d1); - rqDenom = 250; - break; - case Config.CHANGE_METHOD_250C: - sns = get250C(scr.d25, scr.d5, scr.d1); - rqDenom = 250; - break; - case Config.CHANGE_METHOD_250D: - sns = get250D(scr.d1); - rqDenom = 250; - break; - case Config.CHANGE_METHOD_250E: - sns = get250E(scr.d100, scr.d25, scr.d5, scr.d1); - rqDenom = 250; - break; - default: - logger.error(ltag, "Invalid method: " + method); - cr.status = ChangeMakerResult.STATUS_ERROR; - return; - } - + int sns[] = showChange(method, cc); if (sns == null) { - logger.info(ltag, "No coins"); cr.errText = "Not enough coins at the Public Change Maker"; cr.status = ChangeMakerResult.STATUS_ERROR; return; @@ -186,7 +80,7 @@ public void doChange(int method, CloudCoin cc) { for (int i = 0; i < sns.length; i++) { CloudCoin ccx = new CloudCoin(1, sns[i]); - logger.info(ltag, "sn "+sns[i] + " d="+ccx.getDenomination()); + logger.info(ltag, "sn "+ sns[i] + " d="+ccx.getDenomination()); } requests = new String[RAIDA.TOTAL_RAIDA_COUNT]; @@ -327,370 +221,8 @@ public void callback(Object result) { cr.status = ChangeMakerResult.STATUS_FINISHED; } - private int[] getA(int[] a, int cnt) { - int[] sns; - int i, j; - - sns = new int[cnt]; - for (i = 0, j = 0; i < a.length; i++) { - if (a[i] == 0) - continue; - - sns[j] = a[i]; - a[i] = 0; - j++; - - if (j == cnt) - break; - } - - if (j != cnt) - return null; - - return sns; - } - - private int[] get25B(int[] sb, int[] ss) { - int[] sns, rsns; - - rsns = new int[9]; - - sns = getA(ss, 5); - if (sns == null) - return null; - - for (int i = 0; i < 5; i++) - rsns[i] = sns[i]; - - sns = getA(sb, 4); - if (sns == null) - return null; - - for (int i = 0; i < 4; i++) - rsns[i + 5] = sns[i]; - - return rsns; - } - - private int[] get25C(int[] sb, int[] ss) { - int[] sns, rsns; - - rsns = new int[17]; - - sns = getA(ss, 5); - if (sns == null) - return null; - - for (int i = 0; i < 5; i++) - rsns[i] = sns[i]; - - sns = getA(ss, 5); - if (sns == null) - return null; - - for (int i = 0; i < 5; i++) - rsns[i + 5] = sns[i]; - - sns = getA(ss, 5); - if (sns == null) - return null; - - for (int i = 0; i < 5; i++) - rsns[i + 10] = sns[i]; - - sns = getA(sb, 2); - if (sns == null) - return null; - - for (int i = 0; i < 2; i++) - rsns[i + 15] = sns[i]; - - return rsns; - } - - private int[] get25D(int[] sb) { - int[] sns, rsns; - int j; - - rsns = new int[25]; - for (j = 0; j < 5; j++) { - sns = getA(sb, 5); - if (sns == null) - return null; - - for (int i = 0; i < 5; i++) - rsns[j * 5 + i] = sns[i]; - } - - return rsns; - } - - private int[] get100B(int[] sb, int[] ss) { - int[] sns, rsns; - - rsns = new int[8]; - - sns = getA(ss, 5); - if (sns == null) - return null; - - for (int i = 0; i < 5; i++) - rsns[i] = sns[i]; - - sns = getA(sb, 3); - if (sns == null) - return null; - - for (int i = 0; i < 3; i++) - rsns[i + 5] = sns[i]; - - return rsns; - } - - private int[] get100C(int[] sb, int[] ss, int[] sss) { - int[] sns, rsns; - - rsns = new int[16]; - - sns = get25B(ss, sss); - if (sns == null) - return null; - - for (int i = 0; i < 9; i++) - rsns[i] = sns[i]; - - sns = getA(ss, 5); - if (sns == null) - return null; - - for (int i = 0; i < 5; i++) - rsns[i + 9] = sns[i]; - - sns = getA(sb, 2); - for (int i = 0; i < 2; i++) - rsns[i + 14] = sns[i]; - - return rsns; - } - - private int[] get100D(int[] sb) { - int[] sns, rsns; - int j; - - rsns = new int[100]; - for (j = 0; j < 4; j++) { - sns = get25D(sb); - if (sns == null) - return null; - - for (int i = 0; i < 25; i++) - rsns[j * 25 + i] = sns[i]; - } - - return rsns; - } - - private int[] get100E(int[] sb, int[] ss, int[] sss) { - int[] sns, rsns; - - rsns = new int[12]; - - sns = getA(sb, 3); - if (sns == null) - return null; - - for (int i = 0; i < 3; i++) - rsns[i] = sns[i]; - - sns = getA(ss, 4); - if (sns == null) - return null; - - for (int i = 0; i < 4; i++) - rsns[i + 3] = sns[i]; - - sns = getA(sss, 5); - if (sns == null) - return null; - - for (int i = 0; i < 5; i++) - rsns[i + 7] = sns[i]; - - return rsns; - } - - - private int[] get250A(int[] sb, int[] ss) { - int[] sns, rsns; - - rsns = new int[4]; - - sns = getA(ss, 2); - if (sns == null) - return null; - - for (int i = 0; i < 2; i++) - rsns[i] = sns[i]; - - sns = getA(sb, 2); - if (sns == null) - return null; - - for (int i = 0; i < 2; i++) - rsns[i + 2] = sns[i]; - - return rsns; - } - - private int[] get250B(int[] sb, int[] ss, int[] sss) { - int[] sns, rsns; - - rsns = new int[22]; - sns = get25B(ss, sss); - if (sns == null) - return null; - - for (int i = 0; i < 9; i++) - rsns[i] = sns[i]; - - sns = getA(ss, 5); - if (sns == null) - return null; - - for (int i = 0; i < 5; i++) - rsns[i + 9] = sns[i]; - - sns = getA(sb, 4); - if (sns == null) - return null; - - for (int i = 0; i < 4; i++) - rsns[i + 14] = sns[i]; - - sns = getA(sb, 4); - if (sns == null) - return null; - - for (int i = 0; i < 4; i++) - rsns[i + 18] = sns[i]; - - return rsns; - } - - private int[] get250C(int[] sb, int[] ss, int[] sss) { - int[] sns, rsns; - - rsns = new int[42]; - sns = get25C(ss, sss); - if (sns == null) - return null; - - for (int i = 0; i < 17; i++) - rsns[i] = sns[i]; - - sns = get25B(ss, sss); - if (sns == null) - return null; - - for (int i = 0; i < 9; i++) - rsns[i + 17] = sns[i]; - - sns = get100B(sb, ss); - if (sns == null) - return null; - - for (int i = 0; i < 8; i++) - rsns[i + 26] = sns[i]; - - sns = get100B(sb, ss); - if (sns == null) - return null; - - for (int i = 0; i < 8; i++) - rsns[i + 34] = sns[i]; - - return rsns; - } - - private int[] get250D(int[] sb) { - int[] sns, rsns; - - rsns = new int[250]; - - sns = get25D(sb); - if (sns == null) - return null; - - for (int i = 0; i < 25; i++) - rsns[i] = sns[i]; - - sns = get25D(sb); - if (sns == null) - return null; - - for (int i = 0; i < 25; i++) - rsns[i + 25] = sns[i]; - - - sns = get100D(sb); - if (sns == null) - return null; - - for (int i = 0; i < 100; i++) - rsns[i + 50] = sns[i]; - - sns = get100D(sb); - if (sns == null) - return null; - - for (int i = 0; i < 100; i++) - rsns[i + 150] = sns[i]; - - return rsns; - } - - private int[] get250E(int[] sb, int[] ss, int[] sss, int[] ssss) { - int[] sns, rsns; - - rsns = new int[12]; - sns = getA(sb, 2); - if (sns == null) - return null; - - for (int i = 0; i < 2; i++) - rsns[i] = sns[i]; - - sns = getA(ss, 1); - if (sns == null) - return null; - - rsns[2] = sns[0]; - - sns = getA(sss, 4); - if (sns == null) - return null; - - for (int i = 0; i < 4; i++) - rsns[i + 3] = sns[i]; - - sns = getA(ssss, 5); - if (sns == null) - return null; - - for (int i = 0; i < 5; i++) - rsns[i + 7] = sns[i]; - - return rsns; - } - - - - - - - - } + /* Method 5A: 1,1,1,1,1 Denomination 25 diff --git a/src/advclient/common/ChangeMaker/ShowChangeResponse.java b/src/advclient/common/ChangeMaker/ShowChangeResponse.java index 2966331..c565ae3 100644 --- a/src/advclient/common/ChangeMaker/ShowChangeResponse.java +++ b/src/advclient/common/ChangeMaker/ShowChangeResponse.java @@ -3,9 +3,9 @@ import global.cloudcoin.ccbank.core.CommonResponse; public class ShowChangeResponse extends CommonResponse { - int[] d250; - int[] d100; - int[] d25; - int[] d5; - int[] d1; + public int[] d250; + public int[] d100; + public int[] d25; + public int[] d5; + public int[] d1; } diff --git a/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java b/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java index 6844159..0ae5ca0 100644 --- a/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java +++ b/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java @@ -16,14 +16,13 @@ import global.cloudcoin.ccbank.core.GLogger; import global.cloudcoin.ccbank.core.RAIDA; import global.cloudcoin.ccbank.core.Servant; +import java.util.HashMap; import java.util.Hashtable; +import java.util.Map; public class ShowEnvelopeCoins extends Servant { String ltag = "ShowEnvelopeCoins"; - ShowEnvelopeCoinsResult result; - - public ShowEnvelopeCoins(String rootDir, GLogger logger) { super("ShowEnvelopeCoins", rootDir, logger); @@ -59,10 +58,9 @@ public void doShowSkyCoins(int sn) { CloudCoin cc; String[] results; Object[] o; - CommonResponse errorResponse; - ShowEnvelopeCoinsResponse srs; + StringBuilder[] sbs; + String[] requests; - setSenderRAIDA(); cc = getIDcc(sn); if (cc == null) { logger.error(ltag, "NO ID Coin found for SN: " + sn); @@ -70,72 +68,127 @@ public void doShowSkyCoins(int sn) { return; } - StringBuilder sb = new StringBuilder(); - sb.append("show?nn="); - sb.append(cc.nn); - sb.append("&sn="); - sb.append(cc.sn); - sb.append("&an="); - sb.append(cc.ans[Config.RAIDANUM_TO_QUERY_BY_DEFAULT]); - sb.append("&pan="); - sb.append(cc.ans[Config.RAIDANUM_TO_QUERY_BY_DEFAULT]); - sb.append("&denomination="); - sb.append(cc.getDenomination()); - - results = raida.query(new String[] { sb.toString() }, null, null, new int[] {Config.RAIDANUM_TO_QUERY_BY_DEFAULT}); + sbs = new StringBuilder[RAIDA.TOTAL_RAIDA_COUNT]; + requests = new String[RAIDA.TOTAL_RAIDA_COUNT]; + for (int i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { + sbs[i] = new StringBuilder(); + sbs[i].append("show?nn="); + sbs[i].append(cc.nn); + sbs[i].append("&sn="); + sbs[i].append(cc.sn); + sbs[i].append("&an="); + sbs[i].append(cc.ans[i]); + sbs[i].append("&pan="); + sbs[i].append(cc.ans[i]); + sbs[i].append("&denomination="); + sbs[i].append(cc.getDenomination()); + + requests[i] = sbs[i].toString(); + } + + results = raida.query(requests, null, null); if (results == null) { logger.error(ltag, "Failed to query showcoinsinenvelope"); result.status = ShowEnvelopeCoinsResult.STATUS_ERROR; return; } - String resultMain = results[0]; - if (resultMain == null) { - logger.error(ltag, "Failed to query showcoinsinenvelope"); - result.status = ShowEnvelopeCoinsResult.STATUS_ERROR; - return; + HashMap[] hashmaps = new HashMap[RAIDA.TOTAL_RAIDA_COUNT]; + int[][] sns = new int[RAIDA.TOTAL_RAIDA_COUNT][]; + for (int i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { + hashmaps[i] = new HashMap(); } + + for (int i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { + sns[i] = new int[0]; + if (results[i] != null) { + if (results[i].equals("")) { + logger.error(ltag, "Skipped raida" + i); + continue; + } + } - CommonResponse cr; - cr = (CommonResponse) parseResponse(resultMain, CommonResponse.class); - if (cr == null) { - result.status = ShowEnvelopeCoinsResult.STATUS_ERROR; - logger.error(ltag, "Failed to show env coins. Invalid response"); - return; - } - - if (!cr.status.equals(Config.REQUEST_STATUS_PASS)) { - result.status = ShowEnvelopeCoinsResult.STATUS_ERROR; - logger.error(ltag, "Failed to show env coins. Result: " + cr.message); - return; + CommonResponse cr = (CommonResponse) parseResponse(results[i], CommonResponse.class); + if (cr == null) { + logger.error(ltag, "Failed to get response coin. RAIDA: " + i); + continue; + } + + if (!cr.status.equals(Config.REQUEST_STATUS_PASS)) { + logger.error(ltag, "Failed to show env coins. RAIDA: " + i + " Result: " + cr.message); + continue; + } + + o = parseArrayResponse(cr.message, ShowEnvelopeCoinsResponse.class); + if (o == null) { + logger.error(ltag, "Failed to parse message: " + cr.message); + continue; + } + + logger.debug(ltag, "Returned length " + o.length); + + //System.out.println("r="+i+ " st="+cr.status + " length " + o.length); + + ShowEnvelopeCoinsResponse[] er = new ShowEnvelopeCoinsResponse[o.length]; + sns[i] = new int[o.length]; + for (int j = 0; j < o.length; j++) { + String tag; + int rsn; + int ts; + + er[j] = (ShowEnvelopeCoinsResponse) o[j]; + tag = er[j].tag; + rsn = er[j].sn; + ts = er[j].created; + + + hashmaps[i].put("" + rsn, er[j]); + sns[i][j] = rsn; + + logger.debug(ltag, "Wallet " + sn + " raida" + i + " coin#" + j + " sn=" +rsn + " t=" + tag + " ts="+ts); + } } - - o = parseArrayResponse(cr.message, ShowEnvelopeCoinsResponse.class); - if (o == null) { + + int vsns[] = AppCore.getSNSOverlap(sns); + if (vsns == null) { result.status = ShowEnvelopeCoinsResult.STATUS_ERROR; - logger.error(ltag, "Failed to parse message: " + cr.message); + logger.error(ltag, "Failed to get coins"); return; } - - logger.debug(ltag, "Returned length " + o.length); - - result.coins = new int[o.length]; - result.tags = new String[o.length]; + + result.coins = new int[vsns.length]; + result.tags = new String[vsns.length]; String key; - ShowEnvelopeCoinsResponse[] er; - er = new ShowEnvelopeCoinsResponse[o.length]; - for (int j = 0; j < o.length; j++) { + ShowEnvelopeCoinsResponse er; + for (int j = 0; j < vsns.length; j++) { String tag; int rsn; int ts; int ats; CloudCoin rcc; - er[j] = (ShowEnvelopeCoinsResponse) o[j]; - tag = er[j].tag; - rsn = er[j].sn; - ts = er[j].created; + rsn = vsns[j]; + String rsnKey = "" + rsn; + boolean found = false; + int ex; + for (ex = 0; ex < RAIDA.TOTAL_RAIDA_COUNT; ex++) { + if (hashmaps[ex].containsKey(rsnKey)) { + found = true; + break; + } + } + + if (!found) { + logger.error(ltag, "Can't find hash for key " + rsnKey); + continue; + } + + er = (ShowEnvelopeCoinsResponse) hashmaps[ex].get(rsnKey); + + tag = er.tag; + rsn = er.sn; + ts = er.created; ats = ts / Config.SECONDS_TO_AGGREGATE_ENVELOPES; @@ -192,6 +245,7 @@ public void doShowSkyCoins(int sn) { result.status = ShowEnvelopeCoinsResult.STATUS_FINISHED; logger.info(ltag, "us=" + user + " sn=" +sn + " r="+results[0]); + } } diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index ab62e60..cd325bd 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -30,7 +30,10 @@ import java.util.ArrayList; import java.util.Date; import java.util.Enumeration; +import java.util.HashMap; +import java.util.Iterator; import java.util.Locale; +import java.util.Map; import java.util.jar.JarEntry; import java.util.jar.JarFile; import org.json.JSONArray; @@ -1147,5 +1150,65 @@ public static boolean writeConfig() { return AppCore.saveFile(globalConfigFilename, data); } - + public static int[] getSNSOverlap(int[][] sns) { + int[] vsns; + + logger.debug(ltag, "Getting overlapped sns"); + HashMap hm = new HashMap(); + + for (int i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { + for (int j = 0; j < sns[i].length; j++) { + int sn = sns[i][j]; + + if (!hm.containsKey(sn)) { + hm.put(sn, 1); + continue; + } + + int cnt = hm.get(sn); + cnt++; + + hm.put(sn, cnt); + } + } + + int valid = 0; + Iterator it = hm.entrySet().iterator(); + while (it.hasNext()) { + Map.Entry pair = (Map.Entry) it.next(); + + int sn = (int) pair.getKey(); + int cnt = (int) pair.getValue(); + + if (cnt < RAIDA.TOTAL_RAIDA_COUNT - Config.MAX_FAILED_RAIDAS_TO_SEND) { + logger.debug(ltag, "Skipping coin " + sn + ". Only " + cnt + " RAIDAs think it is ok"); + continue; + } + + valid++; + } + + logger.debug(ltag, "Number of valid coins: " + valid); + + int rsns[] = new int[valid]; + + it = hm.entrySet().iterator(); + int idx = 0; + while (it.hasNext()) { + Map.Entry pair = (Map.Entry) it.next(); + + int sn = (int) pair.getKey(); + int cnt = (int) pair.getValue(); + + if (cnt < RAIDA.TOTAL_RAIDA_COUNT - Config.MAX_FAILED_RAIDAS_TO_SEND) { + logger.debug(ltag, "Skipping coin " + sn + ". Only " + cnt + " RAIDAs think it is ok"); + continue; + } + + rsns[idx] = sn; + idx++; + } + + return rsns; + } } diff --git a/src/advclient/common/core/Config.java b/src/advclient/common/core/Config.java index 4312f02..d4e0afe 100644 --- a/src/advclient/common/core/Config.java +++ b/src/advclient/common/core/Config.java @@ -185,6 +185,7 @@ public class Config { public static int MAX_COUNTERFEIT_RAIDAS_TO_SEND = 2; public static int MAX_FAILED_RAIDAS_TO_SEND = 2; + } diff --git a/src/advclient/common/core/Servant.java b/src/advclient/common/core/Servant.java index 1ca06ca..9aecdc0 100644 --- a/src/advclient/common/core/Servant.java +++ b/src/advclient/common/core/Servant.java @@ -1,6 +1,8 @@ package global.cloudcoin.ccbank.core; +import global.cloudcoin.ccbank.ChangeMaker.ChangeMakerResult; +import global.cloudcoin.ccbank.ChangeMaker.ShowChangeResponse; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -1050,4 +1052,509 @@ public void saveReceipt(String duser, int a, int c, int f, int l, int u, int dup logger.error(ltag, "Failed to save file " + fileName); } } + + + protected int[] getA(int[] a, int cnt) { + int[] sns; + int i, j; + + sns = new int[cnt]; + for (i = 0, j = 0; i < a.length; i++) { + if (a[i] == 0) + continue; + + sns[j] = a[i]; + a[i] = 0; + j++; + + if (j == cnt) + break; + } + + if (j != cnt) + return null; + + return sns; + } + + protected int[] get25B(int[] sb, int[] ss) { + int[] sns, rsns; + + rsns = new int[9]; + + sns = getA(ss, 5); + if (sns == null) + return null; + + for (int i = 0; i < 5; i++) + rsns[i] = sns[i]; + + sns = getA(sb, 4); + if (sns == null) + return null; + + for (int i = 0; i < 4; i++) + rsns[i + 5] = sns[i]; + + return rsns; + } + + protected int[] get25C(int[] sb, int[] ss) { + int[] sns, rsns; + + rsns = new int[17]; + + sns = getA(ss, 5); + if (sns == null) + return null; + + for (int i = 0; i < 5; i++) + rsns[i] = sns[i]; + + sns = getA(ss, 5); + if (sns == null) + return null; + + for (int i = 0; i < 5; i++) + rsns[i + 5] = sns[i]; + + sns = getA(ss, 5); + if (sns == null) + return null; + + for (int i = 0; i < 5; i++) + rsns[i + 10] = sns[i]; + + sns = getA(sb, 2); + if (sns == null) + return null; + + for (int i = 0; i < 2; i++) + rsns[i + 15] = sns[i]; + + return rsns; + } + + protected int[] get25D(int[] sb) { + int[] sns, rsns; + int j; + + rsns = new int[25]; + for (j = 0; j < 5; j++) { + sns = getA(sb, 5); + if (sns == null) + return null; + + for (int i = 0; i < 5; i++) + rsns[j * 5 + i] = sns[i]; + } + + return rsns; + } + + protected int[] get100B(int[] sb, int[] ss) { + int[] sns, rsns; + + rsns = new int[8]; + + sns = getA(ss, 5); + if (sns == null) + return null; + + for (int i = 0; i < 5; i++) + rsns[i] = sns[i]; + + sns = getA(sb, 3); + if (sns == null) + return null; + + for (int i = 0; i < 3; i++) + rsns[i + 5] = sns[i]; + + return rsns; + } + + protected int[] get100C(int[] sb, int[] ss, int[] sss) { + int[] sns, rsns; + + rsns = new int[16]; + + sns = get25B(ss, sss); + if (sns == null) + return null; + + for (int i = 0; i < 9; i++) + rsns[i] = sns[i]; + + sns = getA(ss, 5); + if (sns == null) + return null; + + for (int i = 0; i < 5; i++) + rsns[i + 9] = sns[i]; + + sns = getA(sb, 2); + for (int i = 0; i < 2; i++) + rsns[i + 14] = sns[i]; + + return rsns; + } + + protected int[] get100D(int[] sb) { + int[] sns, rsns; + int j; + + rsns = new int[100]; + for (j = 0; j < 4; j++) { + sns = get25D(sb); + if (sns == null) + return null; + + for (int i = 0; i < 25; i++) + rsns[j * 25 + i] = sns[i]; + } + + return rsns; + } + + protected int[] get100E(int[] sb, int[] ss, int[] sss) { + int[] sns, rsns; + + rsns = new int[12]; + + sns = getA(sb, 3); + if (sns == null) + return null; + + for (int i = 0; i < 3; i++) + rsns[i] = sns[i]; + + sns = getA(ss, 4); + if (sns == null) + return null; + + for (int i = 0; i < 4; i++) + rsns[i + 3] = sns[i]; + + sns = getA(sss, 5); + if (sns == null) + return null; + + for (int i = 0; i < 5; i++) + rsns[i + 7] = sns[i]; + + return rsns; + } + + + protected int[] get250A(int[] sb, int[] ss) { + int[] sns, rsns; + + rsns = new int[4]; + + sns = getA(ss, 2); + if (sns == null) + return null; + + for (int i = 0; i < 2; i++) + rsns[i] = sns[i]; + + sns = getA(sb, 2); + if (sns == null) + return null; + + for (int i = 0; i < 2; i++) + rsns[i + 2] = sns[i]; + + return rsns; + } + + protected int[] get250B(int[] sb, int[] ss, int[] sss) { + int[] sns, rsns; + + rsns = new int[22]; + sns = get25B(ss, sss); + if (sns == null) + return null; + + for (int i = 0; i < 9; i++) + rsns[i] = sns[i]; + + sns = getA(ss, 5); + if (sns == null) + return null; + + for (int i = 0; i < 5; i++) + rsns[i + 9] = sns[i]; + + sns = getA(sb, 4); + if (sns == null) + return null; + + for (int i = 0; i < 4; i++) + rsns[i + 14] = sns[i]; + + sns = getA(sb, 4); + if (sns == null) + return null; + + for (int i = 0; i < 4; i++) + rsns[i + 18] = sns[i]; + + return rsns; + } + + protected int[] get250C(int[] sb, int[] ss, int[] sss) { + int[] sns, rsns; + + rsns = new int[42]; + sns = get25C(ss, sss); + if (sns == null) + return null; + + for (int i = 0; i < 17; i++) + rsns[i] = sns[i]; + + sns = get25B(ss, sss); + if (sns == null) + return null; + + for (int i = 0; i < 9; i++) + rsns[i + 17] = sns[i]; + + sns = get100B(sb, ss); + if (sns == null) + return null; + + for (int i = 0; i < 8; i++) + rsns[i + 26] = sns[i]; + + sns = get100B(sb, ss); + if (sns == null) + return null; + + for (int i = 0; i < 8; i++) + rsns[i + 34] = sns[i]; + + return rsns; + } + + protected int[] get250D(int[] sb) { + int[] sns, rsns; + + rsns = new int[250]; + + sns = get25D(sb); + if (sns == null) + return null; + + for (int i = 0; i < 25; i++) + rsns[i] = sns[i]; + + sns = get25D(sb); + if (sns == null) + return null; + + for (int i = 0; i < 25; i++) + rsns[i + 25] = sns[i]; + + + sns = get100D(sb); + if (sns == null) + return null; + + for (int i = 0; i < 100; i++) + rsns[i + 50] = sns[i]; + + sns = get100D(sb); + if (sns == null) + return null; + + for (int i = 0; i < 100; i++) + rsns[i + 150] = sns[i]; + + return rsns; + } + + protected int[] get250E(int[] sb, int[] ss, int[] sss, int[] ssss) { + int[] sns, rsns; + + rsns = new int[12]; + sns = getA(sb, 2); + if (sns == null) + return null; + + for (int i = 0; i < 2; i++) + rsns[i] = sns[i]; + + sns = getA(ss, 1); + if (sns == null) + return null; + + rsns[2] = sns[0]; + + sns = getA(sss, 4); + if (sns == null) + return null; + + for (int i = 0; i < 4; i++) + rsns[i + 3] = sns[i]; + + sns = getA(ssss, 5); + if (sns == null) + return null; + + for (int i = 0; i < 5; i++) + rsns[i + 7] = sns[i]; + + return rsns; + } + + protected int[] showChange(int method, CloudCoin cc) { + String resultMain; + String[] results; + String[] requests; + StringBuilder[] sbs; + + String seed = AppCore.generateHex().substring(0, 8); + + sbs = new StringBuilder[RAIDA.TOTAL_RAIDA_COUNT]; + requests = new String[RAIDA.TOTAL_RAIDA_COUNT]; + for (int i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { + sbs[i] = new StringBuilder(); + sbs[i].append("show_change?nn="); + sbs[i].append(cc.nn); + sbs[i].append("&sn="); + sbs[i].append(Config.PUBLIC_CHANGE_MAKER_ID); + sbs[i].append("&seed="); + sbs[i].append(seed); + sbs[i].append("&denomination="); + sbs[i].append(cc.getDenomination()); + + requests[i] = sbs[i].toString(); + } + + results = raida.query(requests, null, null); + if (results == null) { + logger.error(ltag, "Failed to query showchange"); + return null; + } + + int[][] rsns1 = new int[RAIDA.TOTAL_RAIDA_COUNT][]; + int[][] rsns5 = new int[RAIDA.TOTAL_RAIDA_COUNT][]; + int[][] rsns25 = new int[RAIDA.TOTAL_RAIDA_COUNT][]; + int[][] rsns100 = new int[RAIDA.TOTAL_RAIDA_COUNT][]; + for (int i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { + rsns1[i] = new int[0]; + rsns5[i] = new int[0]; + rsns25[i] = new int[0]; + rsns100[i] = new int[0]; + if (results[i] != null) { + if (results[i].equals("")) { + logger.error(ltag, "Skipped raida" + i); + continue; + } + } + + ShowChangeResponse scr = (ShowChangeResponse) parseResponse(results[i], ShowChangeResponse.class); + if (scr == null) { + logger.error(ltag, "Failed to get response coin. RAIDA: " + i); + continue; + } + + if (!scr.status.equals(Config.REQUEST_STATUS_PASS)) { + logger.error(ltag, "Failed to show env coins. RAIDA: " + i + " Result: " + scr.status); + continue; + } + + rsns1[i] = scr.d1; + rsns5[i] = scr.d5; + rsns25[i] = scr.d25; + rsns100[i] = scr.d100; + } + + int[] vsns1, vsns5, vsns25, vsns100; + vsns1 = AppCore.getSNSOverlap(rsns1); + if (vsns1 == null) { + logger.error(ltag, "Failed to get coins for denomination #1"); + return null; + } + + vsns5 = AppCore.getSNSOverlap(rsns5); + if (vsns5 == null) { + logger.error(ltag, "Failed to get coins for denomination #5"); + return null; + } + + vsns25 = AppCore.getSNSOverlap(rsns25); + if (vsns25 == null) { + logger.error(ltag, "Failed to get coins for denomination #25"); + return null; + } + + vsns100 = AppCore.getSNSOverlap(rsns100); + if (vsns100 == null) { + logger.error(ltag, "Failed to get coins for denomination #100"); + return null; + } + + int[] sns; + switch (method) { + case Config.CHANGE_METHOD_5A: + sns = getA(vsns1, 5); + break; + case Config.CHANGE_METHOD_25A: + sns = getA(vsns5, 5); + break; + case Config.CHANGE_METHOD_25B: + sns = get25B(vsns5, vsns1); + break; + case Config.CHANGE_METHOD_25C: + sns = get25C(vsns5, vsns1); + break; + case Config.CHANGE_METHOD_25D: + sns = get25D(vsns1); + break; + case Config.CHANGE_METHOD_100A: + sns = getA(vsns25, 4); + break; + case Config.CHANGE_METHOD_100B: + sns = get100B(vsns25, vsns5); + break; + case Config.CHANGE_METHOD_100C: + sns = get100C(vsns25, vsns5, vsns1); + break; + case Config.CHANGE_METHOD_100D: + sns = get100D(vsns1); + break; + case Config.CHANGE_METHOD_100E: + sns = get100E(vsns25, vsns5, vsns1); + break; + case Config.CHANGE_METHOD_250A: + sns = get250A(vsns100, vsns25); + break; + case Config.CHANGE_METHOD_250B: + sns = get250B(vsns25, vsns5, vsns1); + break; + case Config.CHANGE_METHOD_250C: + sns = get250C(vsns25, vsns5, vsns1); + break; + case Config.CHANGE_METHOD_250D: + sns = get250D(vsns1); + break; + case Config.CHANGE_METHOD_250E: + sns = get250E(vsns100, vsns25, vsns5, vsns1); + break; + default: + logger.error(ltag, "Invalid method: " + method); + return null; + } + + if (sns == null) { + logger.error(ltag, "Failed to break coin"); + return null; + } + + return sns; + } } From 49805cccdcd4ed9b2f7cd0c21c5b6cb60b99a39c Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 27 Sep 2019 16:02:09 +0300 Subject: [PATCH 080/160] Transfer with change --- src/advclient/common/Transfer/Transfer.java | 81 ++++++++++++++++++- src/advclient/common/core/AppCore.java | 21 +++++ src/advclient/common/core/ServantManager.java | 18 +---- 3 files changed, 102 insertions(+), 18 deletions(-) diff --git a/src/advclient/common/Transfer/Transfer.java b/src/advclient/common/Transfer/Transfer.java index 19c792e..f1144ef 100644 --- a/src/advclient/common/Transfer/Transfer.java +++ b/src/advclient/common/Transfer/Transfer.java @@ -6,6 +6,7 @@ */ +import global.cloudcoin.ccbank.ChangeMaker.ChangeMakerResult; import global.cloudcoin.ccbank.core.AppCore; import global.cloudcoin.ccbank.core.CallbackInterface; import global.cloudcoin.ccbank.core.CloudCoin; @@ -207,6 +208,7 @@ public void doTransfer(int fromsn, int tosn, int sns[], String tag, int amount) if (!processTransferWithChange(extraCoin, idcc, tag, tosn, remained)) { tr = new TransferResult(); globalResult.status = TransferResult.STATUS_ERROR; + globalResult.errText = "Failed to make change"; copyFromGlobalResult(tr); if (cb != null) cb.callback(tr); @@ -377,7 +379,74 @@ public boolean processTransferWithChange(CloudCoin tcc, CloudCoin cc, String tag int i; CloudCoin[] sccs; - logger.debug(ltag, "Transferring with change to " + tosn); + System.out.println("change " + tosn + " amount=" + amount + " d=" + tcc.getDenomination()); + + + logger.debug(ltag, "Transferring with change to " + tosn + ". Target coin " + tcc.sn); + + int method = AppCore.getChangeMethod(tcc.getDenomination()); + if (method == 0) { + logger.error(ltag, "Can't find suitable method"); + return false; + } + + logger.debug(ltag, "Method chosen: " + method); + + int sns[] = showChange(method, tcc); + if (sns == null) { + logger.error(tag, "Not enough coins to make change"); + return false; + } + + for (i = 0; i < sns.length; i++) { + CloudCoin ccx = new CloudCoin(1, sns[i]); + logger.info(ltag, "sn "+ sns[i] + " d="+ccx.getDenomination()); + } + + coinsPicked = new ArrayList(); + ArrayList coinsToChange = new ArrayList(); + valuesPicked = new int[sns.length]; + if (!pickCoinsAmountFromArray(sns, amount)) { + logger.error(ltag, "Failed to pick amount: " + amount + " from the resulting coins from all RAIDAs"); + return false; + } + + boolean present; + int totalToSend = 0; + int totalChange = 0; + for (i = 0; i < sns.length; i++) { + present = false; + for (CloudCoin vcc : coinsPicked) { + if (vcc.sn == sns[i]) { + present = true; + break; + } + } + if (!present) { + CloudCoin changeCC = new CloudCoin(Config.DEFAULT_NN, sns[i]); + coinsToChange.add(changeCC); + totalChange += changeCC.getDenomination(); + + logger.debug(ltag, "to change: " + changeCC.sn + " d=" + changeCC.getDenomination()); + } + } + + for (CloudCoin vcc : coinsPicked) { + totalToSend += vcc.getDenomination(); + logger.debug(ltag, "to send: " + vcc.sn + " d=" + vcc.getDenomination()); + } + + logger.debug(ltag, "Total to send: " + totalToSend + " change: " + totalChange); + if (totalToSend != amount) { + logger.error(ltag, "Wrong amount: " + amount + " collected=" + totalToSend); + return false; + } + + if (totalToSend + totalChange != tcc.getDenomination()) { + logger.error(ltag, "Incorrectly broken: toSend=" + totalToSend + " change=" + + totalChange + " Coin: " + tcc.getDenomination()); + return false; + } sbs = new StringBuilder[RAIDA.TOTAL_RAIDA_COUNT]; posts = new String[RAIDA.TOTAL_RAIDA_COUNT]; @@ -411,6 +480,16 @@ public boolean processTransferWithChange(CloudCoin tcc, CloudCoin cc, String tag sbs[i].append("&public_change_maker="); sbs[i].append(Config.PUBLIC_CHANGE_MAKER_ID); + for (CloudCoin vcc : coinsPicked) { + sbs[i].append("&paysns[]="); + sbs[i].append(vcc.sn); + } + + for (CloudCoin vcc : coinsToChange) { + sbs[i].append("&chsns[]="); + sbs[i].append(vcc.sn); + } + posts[i] = sbs[i].toString(); } diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index cd325bd..bfa8da1 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -1211,4 +1211,25 @@ public static int[] getSNSOverlap(int[][] sns) { return rsns; } + + public static int getChangeMethod(int denomination) { + int method = 0; + + switch (denomination) { + case 250: + method = Config.CHANGE_METHOD_250E; + break; + case 100: + method = Config.CHANGE_METHOD_100E; + break; + case 25: + method = Config.CHANGE_METHOD_25B; + break; + case 5: + method = Config.CHANGE_METHOD_5A; + break; + } + + return method; + } } diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index 6eec4c8..923e39d 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -682,23 +682,7 @@ public boolean sendToChange(CloudCoin cc, Wallet w, int skySN, CallbackInterface } logger.debug(ltag, "Sending to the ChangeMaker " + cc.sn + " denomination " + cc.getDenomination()); - - int method = 0; - switch (cc.getDenomination()) { - case 250: - method = Config.CHANGE_METHOD_250E; - break; - case 100: - method = Config.CHANGE_METHOD_100E; - break; - case 25: - method = Config.CHANGE_METHOD_25B; - break; - case 5: - method = Config.CHANGE_METHOD_5A; - break; - } - + int method = AppCore.getChangeMethod(cc.getDenomination()); if (method == 0) { logger.error(ltag, "Can't find suitable method"); return false; From d749da1e9938d2dbd8cc2935693bbcf3fc3df0fa Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 27 Sep 2019 16:10:38 +0300 Subject: [PATCH 081/160] locale --- src/advclient/AdvancedClient.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index dd63a91..961a9f5 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -6458,6 +6458,8 @@ public static void main(String[] args) { } catch (Exception e) { e.printStackTrace(); }*/ + Locale.setDefault(new Locale("EN")); + System.setProperty("user.language","EN"); try { From 8dea11771e3a6cce376644941ff23d7be7d8f752 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 27 Sep 2019 16:35:54 +0300 Subject: [PATCH 082/160] locale --- src/advclient/AdvancedClient.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 961a9f5..42c8d5a 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -6458,8 +6458,8 @@ public static void main(String[] args) { } catch (Exception e) { e.printStackTrace(); }*/ - Locale.setDefault(new Locale("EN")); - System.setProperty("user.language","EN"); + Locale.setDefault(new Locale("en", "US")); + System.setProperty("user.language","en-US"); try { From 566f030219ee5df3e418adc9e6c855f8bbe0c9dd Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 3 Oct 2019 11:43:20 +0300 Subject: [PATCH 083/160] dup coins will not stop Unpacker --- src/advclient/AdvancedClient.java | 2 +- src/advclient/common/Unpacker/Unpacker.java | 19 ++++++++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 42c8d5a..9156223 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -56,7 +56,7 @@ * */ public class AdvancedClient { - String version = "2.1.16"; + String version = "2.1.17"; JPanel headerPanel; JPanel mainPanel; diff --git a/src/advclient/common/Unpacker/Unpacker.java b/src/advclient/common/Unpacker/Unpacker.java index b8de351..818da17 100644 --- a/src/advclient/common/Unpacker/Unpacker.java +++ b/src/advclient/common/Unpacker/Unpacker.java @@ -226,8 +226,22 @@ public boolean saveCoin(CloudCoin cc) { String path; path = AppCore.getUserDir(Config.DIR_SUSPECT, user) + File.separator + fileName; + logger.info(ltag, "Saving " + path + ": " + json); + File f = new File(path); + if (f.exists()) { + logger.info(ltag, "File " + path + " already exists. Moving to Trash. Continue"); + path = AppCore.getUserDir(Config.DIR_TRASH, user) + File.separator + System.currentTimeMillis() + + "-" + fileName; + + if (!AppCore.saveFile(path, json)) { + logger.error(ltag, "Failed to save file in Trash: " + path); + return false; + } + + return true; + } if (!AppCore.saveFile(path, json)) { logger.error(ltag, "Failed to save file: " + fileName); @@ -263,12 +277,7 @@ public boolean doUnpackJpeg(String fileName) { } addCoinToRccs(cc, fileName); - /* - if (!saveCoin(cc)) - return false; - AppCore.moveToImported(fileName, user); -*/ return true; } From b2b6e66520c7b7d2125a9746b3abea490cfb2e27 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 3 Oct 2019 12:24:53 +0300 Subject: [PATCH 084/160] Remove and mask sensetive data in logs --- src/advclient/common/Vaulter/Vaulter.java | 4 ++-- src/advclient/common/core/AppCore.java | 6 ++++++ src/advclient/common/core/DetectionAgent.java | 2 +- src/advclient/common/core/ServantManager.java | 6 +++--- 4 files changed, 12 insertions(+), 6 deletions(-) diff --git a/src/advclient/common/Vaulter/Vaulter.java b/src/advclient/common/Vaulter/Vaulter.java index 010a606..3e6f845 100644 --- a/src/advclient/common/Vaulter/Vaulter.java +++ b/src/advclient/common/Vaulter/Vaulter.java @@ -141,7 +141,7 @@ public void doVault(String password, int amount, CloudCoin cc) { - logger.info(ltag, "cc=" + tcc.sn + " was AN" + i + ":" + tcc.ans[i]); + //logger.info(ltag, "cc=" + tcc.sn + " was AN" + i + ":" + tcc.ans[i]); tcc.ans[i] = builder.toString().toLowerCase(); logger.info(ltag, "cc=" + tcc.sn + " is AN" + i + ":" + tcc.ans[i]); } @@ -265,7 +265,7 @@ public void doUnvault(String password, int amount, CloudCoin cc) { return; } - logger.info(ltag, "cc=" + tcc.sn + " was AN" + i + ":" + tcc.ans[i]); + //logger.info(ltag, "cc=" + tcc.sn + " was AN" + i + ":" + tcc.ans[i]); tcc.ans[i] = builder.toString().replace(")", ""); logger.info(ltag, "cc=" + tcc.sn + " is AN" + i + ":" + tcc.ans[i] + " move " + tcc.originalFile + " d=" + Config.DIR_VAULT); } diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index bfa8da1..bfd23b4 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -1232,4 +1232,10 @@ public static int getChangeMethod(int denomination) { return method; } + + public static String maskStr(String key, String data) { + String result = data.replaceAll(key + "([A-Fa-f0-9]{28})", key + "***"); + return result; + } + } diff --git a/src/advclient/common/core/DetectionAgent.java b/src/advclient/common/core/DetectionAgent.java index af22ba6..384c261 100644 --- a/src/advclient/common/core/DetectionAgent.java +++ b/src/advclient/common/core/DetectionAgent.java @@ -121,7 +121,7 @@ public String doRequest(String url, String post) { urlConnection.setRequestProperty("User-Agent", "CloudCoin Wallet Client"); if (post != null) { - logger.debug(ltag, post); + logger.debug(ltag, AppCore.maskStr("pans\\[\\]=", post)); byte[] postDataBytes = post.getBytes("UTF-8"); diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index 923e39d..776baf0 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -502,13 +502,13 @@ public void startVaulterService(CallbackInterface cb) { return; } - logger.debug(ltag, "Vaulter password " + password); + //logger.debug(ltag, "Vaulter password " + password); Vaulter v = (Vaulter) sr.getServant("Vaulter"); v.vault(password, 0, null, cb); } public void startVaulterService(CallbackInterface cb, String password) { - logger.debug(ltag, "Vaulter password " + password); + //logger.debug(ltag, "Vaulter password " + password); if (password.isEmpty()) { logger.error(ltag, "Empty password"); return; @@ -535,7 +535,7 @@ public void startSecureExporterService(int exportType, int amount, String tag, S return; } - logger.debug(ltag, "Vaulter password " + password); + //logger.debug(ltag, "Vaulter password " + password); Vaulter v = (Vaulter) sr.getServant("Vaulter"); v.unvault(password, amount, null, new eVaulterCb(exportType, amount, tag, dir, keepSrc, cb)); } From a7825b2b08d921d1d11f3db49da5ff54b09365b6 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 4 Oct 2019 12:22:42 +0300 Subject: [PATCH 085/160] transfer from sky-sky - show requested amount --- src/advclient/common/Transfer/Transfer.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/advclient/common/Transfer/Transfer.java b/src/advclient/common/Transfer/Transfer.java index f1144ef..dc26c62 100644 --- a/src/advclient/common/Transfer/Transfer.java +++ b/src/advclient/common/Transfer/Transfer.java @@ -135,13 +135,16 @@ public void doTransfer(int fromsn, int tosn, int sns[], String tag, int amount) logger.info(ltag, "total files "+ globalResult.totalFiles); + /* for (CloudCoin cc : coinsPicked) { globalResult.totalCoins += cc.getDenomination(); } if (extraCoin != null) globalResult.totalCoins += extraCoin.getDenomination(); + */ + globalResult.totalCoins = amount; int curValProcessed = 0; for (CloudCoin cc : coinsPicked) { From 992b1c6ee5664703418a4e069842d303652fe911 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 4 Oct 2019 12:34:12 +0300 Subject: [PATCH 086/160] error handling wrap --- src/advclient/AdvancedClient.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 9156223..aaeb5f6 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -1429,10 +1429,14 @@ public void run() { } if (!mcr.errText.isEmpty()) { - ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; - ps.errText = mcr.errText; - showScreen(); - return; + EventQueue.invokeLater(new Runnable() { + public void run() { + ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; + ps.errText = mcr.errText; + showScreen(); + return; + } + }); } } }); From 3c9568dfefe1697b3a25d4c19516e83f49d4d9da Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 4 Oct 2019 15:29:25 +0300 Subject: [PATCH 087/160] transaction auto-adjust, show coins interrupt --- src/advclient/AdvancedClient.java | 16 ++++++----- .../ShowEnvelopeCoins/ShowEnvelopeCoins.java | 10 +++++-- .../ShowEnvelopeCoinsResult.java | 1 + src/advclient/common/Transfer/Transfer.java | 3 -- src/advclient/common/core/AppCore.java | 4 +-- src/advclient/common/core/DetectionAgent.java | 13 +++++++-- src/advclient/common/core/RAIDA.java | 5 ++++ src/advclient/common/core/Servant.java | 10 ++++++- src/advclient/common/core/ServantManager.java | 25 ++++++++++++++--- .../common/core/ServantRegistry.java | 3 +- src/advclient/common/core/Wallet.java | 28 +++++++++++++++---- 11 files changed, 88 insertions(+), 30 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index aaeb5f6..09b25c9 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -291,9 +291,10 @@ public boolean isActiveWallet(Wallet wallet) { return ps.currentWallet.getName().equals(wallet.getName()); } - public void setActiveWallet(Wallet wallet) { + public void setActiveWallet(Wallet wallet) { ps.currentWallet = wallet; + sm.cancelSecs(); sm.setActiveWalletObj(wallet); } @@ -3000,7 +3001,7 @@ public void actionPerformed(ActionEvent e) { public void updateWalletAmount() { if (wallets == null) wallets = sm.getWallets(); - + for (int i = 0; i < wallets.length; i++) { JLabel cntLabel = (JLabel) wallets[i].getuiRef(); if (cntLabel == null) @@ -3019,6 +3020,7 @@ public void updateWalletAmount() { setTotalCoins(); + sm.initIsolatedSec(); for (int i = 0; i < wallets.length; i++) { final Wallet w = wallets[i]; @@ -3029,11 +3031,15 @@ public void updateWalletAmount() { wl.debug(ltag, "Counting for " + w.getName()); if (w.isSkyWallet()) { ShowEnvelopeCoins sc = new ShowEnvelopeCoins(rpath, wl); + sm.addSec(sc); int snID = w.getIDCoin().sn; sc.launch(snID, "", new CallbackInterface() { public void callback(Object o) { ShowEnvelopeCoinsResult scresult = (ShowEnvelopeCoinsResult) o; + if (scresult.status != ShowEnvelopeCoinsResult.STATUS_FINISHED) + return; + wl.debug(ltag, "ShowEnvelopeCoins done"); w.setSNs(scresult.coins); w.setEnvelopes(scresult.envelopes); @@ -3066,12 +3072,9 @@ public void callback(Object o) { w.setCounters(counters); setTotalCoins(); } - }); - - + }); } } - } public void eraserGoNext() { @@ -3132,7 +3135,6 @@ public void showTransferScreen() { GridBagLayout gridbag = new GridBagLayout(); subInnerCore.setLayout(gridbag); - final optRv rvFrom = setOptionsForWalletsCommon(false, false, true, null); if (rvFrom.idxs.length == 0) { fname = AppUI.wrapDiv("No Wallets to Transfer From"); diff --git a/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java b/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java index 0ae5ca0..43691aa 100644 --- a/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java +++ b/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java @@ -93,6 +93,12 @@ public void doShowSkyCoins(int sn) { return; } + if (isCancelled()) { + result.status = ShowEnvelopeCoinsResult.STATUS_CANCELLED; + logger.error(ltag, "ShowCoins cancelled"); + return; + } + HashMap[] hashmaps = new HashMap[RAIDA.TOTAL_RAIDA_COUNT]; int[][] sns = new int[RAIDA.TOTAL_RAIDA_COUNT][]; for (int i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { @@ -126,9 +132,7 @@ public void doShowSkyCoins(int sn) { } logger.debug(ltag, "Returned length " + o.length); - - //System.out.println("r="+i+ " st="+cr.status + " length " + o.length); - + ShowEnvelopeCoinsResponse[] er = new ShowEnvelopeCoinsResponse[o.length]; sns[i] = new int[o.length]; for (int j = 0; j < o.length; j++) { diff --git a/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoinsResult.java b/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoinsResult.java index e6fb7c3..e45498a 100644 --- a/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoinsResult.java +++ b/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoinsResult.java @@ -8,6 +8,7 @@ public class ShowEnvelopeCoinsResult { public static int STATUS_PROCESSING = 1; public static int STATUS_FINISHED = 2; public static int STATUS_ERROR = 3; + public static int STATUS_CANCELLED = 4; public int status; public int[][] counters; diff --git a/src/advclient/common/Transfer/Transfer.java b/src/advclient/common/Transfer/Transfer.java index dc26c62..0746e42 100644 --- a/src/advclient/common/Transfer/Transfer.java +++ b/src/advclient/common/Transfer/Transfer.java @@ -382,9 +382,6 @@ public boolean processTransferWithChange(CloudCoin tcc, CloudCoin cc, String tag int i; CloudCoin[] sccs; - System.out.println("change " + tosn + " amount=" + amount + " d=" + tcc.getDenomination()); - - logger.debug(ltag, "Transferring with change to " + tosn + ". Target coin " + tcc.sn); int method = AppCore.getChangeMethod(tcc.getDenomination()); diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index bfd23b4..8a41f20 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -960,11 +960,9 @@ public static String calcCoinsFromFilenames(ArrayList files) { } String identifier = parts[1].toLowerCase(); - System.out.println(identifier); if (!identifier.equals("cloudcoin") && !identifier.equals("cloudcoins")) return "?"; - - + total += ltotal; } diff --git a/src/advclient/common/core/DetectionAgent.java b/src/advclient/common/core/DetectionAgent.java index 384c261..25678da 100644 --- a/src/advclient/common/core/DetectionAgent.java +++ b/src/advclient/common/core/DetectionAgent.java @@ -29,6 +29,9 @@ public class DetectionAgent { private int RAIDANumber; private int lastStatus; + + HttpURLConnection urlConnection; + public DetectionAgent(int RAIDANumber, GLogger logger) { @@ -46,6 +49,12 @@ public DetectionAgent(int RAIDANumber, GLogger logger) { setDefaultFullUrl(); } + public void stopConnection() { + if (urlConnection == null) + return; + + urlConnection.disconnect(); + } public void setReadTimeout(int timeout) { this.readTimeout = timeout; @@ -96,6 +105,7 @@ public String doRequest(String url, String post) { String data; StringBuilder sb = new StringBuilder(); + urlConnection = null; if (fullURL == null) { logger.error(ltag, "Skipping raida: " + RAIDANumber); lastStatus = RAIDA.STATUS_FAILED; @@ -111,8 +121,7 @@ public String doRequest(String url, String post) { disableSSLCheck(); - URL cloudCoinGlobal; - HttpURLConnection urlConnection = null; + URL cloudCoinGlobal; try { cloudCoinGlobal = new URL(urlIn); urlConnection = (HttpURLConnection) cloudCoinGlobal.openConnection(); diff --git a/src/advclient/common/core/RAIDA.java b/src/advclient/common/core/RAIDA.java index 8d4a582..5c18486 100644 --- a/src/advclient/common/core/RAIDA.java +++ b/src/advclient/common/core/RAIDA.java @@ -64,6 +64,11 @@ public void setDefaultUrls() { agents[i].setDefaultFullUrl(); } + public void cancel() { + for (int i = 0; i < TOTAL_RAIDA_COUNT; i++) + agents[i].stopConnection(); + } + public void setExactUrls(String[] urls) { for (int i = 0; i < TOTAL_RAIDA_COUNT; i++) { logger.info(ltag, "Set RAIDA url to " + urls[i]); diff --git a/src/advclient/common/core/Servant.java b/src/advclient/common/core/Servant.java index 9aecdc0..099488e 100644 --- a/src/advclient/common/core/Servant.java +++ b/src/advclient/common/core/Servant.java @@ -63,7 +63,7 @@ public Servant(String name, String rootDir, GLogger logger) { configHT = new Hashtable(); this.raida = new RAIDA(logger); - + File f = new File(rootDir); this.user = f.getName(); setLtag(); @@ -95,6 +95,14 @@ public boolean isUserBound() { return isUserBound; } + public void cancelForce() { + if (raida == null) + return; + + cancel(); + raida.cancel(); + } + public void cancel() { this.cancelRequest = true; } diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index 776baf0..1657ca7 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -66,12 +66,16 @@ public class ServantManager { String user; private Hashtable wallets; + ArrayList secs; + public ServantManager(GLogger logger, String home) { this.logger = logger; this.home = home; this.sr = new ServantRegistry(); this.user = Config.DIR_DEFAULT_USER; this.wallets = new Hashtable(); + + initIsolatedSec(); } public Wallet getActiveWallet() { @@ -1082,12 +1086,9 @@ public void openTransactions() { while (itr.hasNext()) { Wallet w = (Wallet) itr.next(); - System.out.println("w=" + w.getName() + " total=" + w.getTotal()); if (w.isSkyWallet()) continue; - - - + if (w.getTotal() != 0) w.appendTransaction("Opening Balance", w.getTotal(), "openingbalance"); } @@ -1172,4 +1173,20 @@ public Wallet getFirstFullNonSkyWallet() { return null; } + + public void initIsolatedSec() { + secs = new ArrayList(); + } + + public void addSec(ShowEnvelopeCoins sec) { + secs.add(sec); + } + + public void cancelSecs() { + for (ShowEnvelopeCoins sec : secs) + sec.cancelForce(); + + initIsolatedSec(); + } + } diff --git a/src/advclient/common/core/ServantRegistry.java b/src/advclient/common/core/ServantRegistry.java index a9bfc53..71bf051 100644 --- a/src/advclient/common/core/ServantRegistry.java +++ b/src/advclient/common/core/ServantRegistry.java @@ -76,7 +76,7 @@ public void changeUser(String user) { Servant s = servants.get(k); if (!s.isUserBound()) continue; - + if (isRunning(k)) s.cancel(); @@ -122,7 +122,6 @@ public boolean isRunning(String name) { for (int i = 0; i < es.length; i++) { className = es[i].getClassName(); - if (className.startsWith(targetClass)) return true; } diff --git a/src/advclient/common/core/Wallet.java b/src/advclient/common/core/Wallet.java index e386eb8..5d6f0ac 100644 --- a/src/advclient/common/core/Wallet.java +++ b/src/advclient/common/core/Wallet.java @@ -218,8 +218,7 @@ public void appendTransaction(String memo, int amount, String receiptId, String int rest = 0; String[][] tr = getTransactions(); - if (tr != null) { - + if (tr != null) { String[] last = tr[tr.length - 1]; String rRest = last[4]; @@ -229,18 +228,37 @@ public void appendTransaction(String memo, int amount, String receiptId, String rest = 0; } } + + int expectedRest = getTotal() + amount; + String result = ""; + if (rest != getTotal()) { + int adjusted = getTotal() - rest; + + logger.debug(ltag, "Appending correcting transaction. Rest was: " + + rest + " total=" + getTotal() + " adjusted: " + adjusted); + + result = "Balance Auto Adjustment," + date + ","; + if (adjusted > 0) { + result += adjusted + ",,"; + } else { + result += "," + adjusted + ","; + } + + result += getTotal() + ",dummy" + lsep; + rest = getTotal(); + } - String result = rMemo + "," + date + ","; + rest += amount; + result += rMemo + "," + date + ","; if (amount > 0) { result += amount + ",,"; } else { result += "," + amount + ","; } - rest += amount; result += rest; result += "," + receiptId + lsep; - + logger.debug(ltag, "Saving " + result); AppCore.saveFileAppend(fileName, result, true); } From 775078b7edac61cfb89aef1c0eeea9a965d76287 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Sat, 5 Oct 2019 12:28:43 +0300 Subject: [PATCH 088/160] showcoin log --- src/advclient/common/ShowCoins/ShowCoins.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/advclient/common/ShowCoins/ShowCoins.java b/src/advclient/common/ShowCoins/ShowCoins.java index 8738012..7f3b4f0 100644 --- a/src/advclient/common/ShowCoins/ShowCoins.java +++ b/src/advclient/common/ShowCoins/ShowCoins.java @@ -69,7 +69,7 @@ public void showCoinsInFolder(int idx, String folder) { return; } - + int cnt = 0; for (File file: dirObj.listFiles()) { if (file.isDirectory()) continue; @@ -99,10 +99,11 @@ public void showCoinsInFolder(int idx, String folder) { break; } + cnt += cc.getDenomination(); ccs.add(cc); } - logger.debug(ltag, "Total coins in " + folder + ": " + ccs.size()); + logger.debug(ltag, user + ": Total coins in " + folder + ": " + cnt); //createStatFile(folder, result.counters[idx]); } From 8d60f3552997e2bf42d4ce213b51c5e2f9b6a63a Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Sun, 6 Oct 2019 10:56:35 +0300 Subject: [PATCH 089/160] av --- src/advclient/AdvancedClient.java | 10 +- src/advclient/common/LossFixer/LossFixer.java | 205 ------------------ src/advclient/common/core/Wallet.java | 10 +- 3 files changed, 16 insertions(+), 209 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 09b25c9..c567512 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -339,6 +339,14 @@ public void initHeaderPanel() { fillHeaderPanel(); } + public boolean isMakingChange() { + if (ps.currentScreen == ProgramState.SCREEN_MAKING_CHANGE) + return true; + + return false; + } + + public boolean isDepositing() { if (ps.currentScreen == ProgramState.SCREEN_PREDEPOSIT || ps.currentScreen == ProgramState.SCREEN_DEPOSIT || @@ -6929,7 +6937,7 @@ public void callback(final Object result) { public void run() { if (isDepositing()) { ps.currentScreen = ProgramState.SCREEN_IMPORT_DONE; - } else if (isWithdrawing()) { + } else if (isWithdrawing() || isMakingChange()) { ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; } else if (isFixing()) { ps.currentScreen = ProgramState.SCREEN_FIX_DONE; diff --git a/src/advclient/common/LossFixer/LossFixer.java b/src/advclient/common/LossFixer/LossFixer.java index 268bff1..7c6c450 100644 --- a/src/advclient/common/LossFixer/LossFixer.java +++ b/src/advclient/common/LossFixer/LossFixer.java @@ -302,211 +302,6 @@ private void setCoinStatus(ArrayList ccs, int idx, int status) { cc.setDetectStatus(idx, status); } } - /* - public void doRecoverCoin(CloudCoin cc) { - logger.debug(ltag, "Recovering " + cc.sn + " pown " + cc.getPownString()); - - String[] results; - String[] requests; - int[] rlist, trlist; - int failed = 0, rcnt = 0; - boolean[] brlist; - int i, j; - - brlist = new boolean[RAIDA.TOTAL_RAIDA_COUNT]; - for (i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) - brlist[i] = false; - - for (i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { - int status = cc.getDetectStatus(i); - - logger.debug(ltag, " i " + i + " status=" + status); - - if (status == CloudCoin.STATUS_PASS) - continue; - - if (status == CloudCoin.STATUS_FAIL) { - failed++; - continue; - } - - if (status == CloudCoin.STATUS_UNTRIED || status == CloudCoin.STATUS_ERROR) { - brlist[i] = true; - rcnt++; - continue; - } - } - - if (failed > RAIDA.TOTAL_RAIDA_COUNT - Config.PASS_THRESHOLD) { - logger.error(ltag, "Too many counterfeit responses"); - AppCore.moveToTrash(cc.originalFile, user); - addCoinToReceipt(cc, "counterfeit", Config.DIR_COUNTERFEIT); - lr.failed++; - return; - } - - if (rcnt == 0) { - logger.error(ltag, "Coin can not be recovered: " + cc.sn); - AppCore.moveToTrash(cc.originalFile, user); - addCoinToReceipt(cc, "counterfeit", Config.DIR_COUNTERFEIT); - lr.failed++; - return; - } - - rlist = new int[rcnt]; - requests = new String[rcnt]; - for (i = 0, j = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { - if (brlist[i]) { - rlist[j] = i; - requests[j] = "detect?nn="+ cc.nn + "&sn=" + cc.sn + "&an=" + cc.ans[i] + "&pan=" + cc.ans[i] + "&denomination=" + cc.getDenomination(); - j++; - } - } - - CallbackInterface lcb = new CallbackInterface() { - final GLogger gl = logger; - final CallbackInterface myCb = cb; - - @Override - public void callback(Object result) { - lr.totalRAIDAProcessed++; - if (myCb != null) { - LossFixerResult lfr = new LossFixerResult(); - copyFromMainFr(lfr); - myCb.callback(lfr); - } - } - }; - - results = raida.query(requests, null, lcb, rlist); - if (results == null) { - logger.error(ltag, "Failed to query raida"); - lr.failed++; - return; - } - - if (results.length != rcnt) { - logger.error(ltag, "Invalid response length: " + results.length + " vs " + rcnt); - lr.failed++; - return; - } - - LossFixerResponse lfr; - boolean changed = false; - int ridx; - - for (i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) - brlist[i] = false; - - rcnt = 0; - for (i = 0; i < results.length; i++) { - ridx = rlist[i]; - - logger.info(ltag, "res=" + results[i] + " from raida " + ridx); - lfr = (LossFixerResponse) parseResponse(results[i], LossFixerResponse.class); - if (lfr == null) { - logger.error(ltag, "Failed to parse response from: " + i + " raida " + ridx); - cc.setDetectStatus(ridx, CloudCoin.STATUS_ERROR); - changed = true; - continue; - } - - if (lfr.status.equals(Config.REQUEST_STATUS_PASS)) { - logger.debug(ltag, "RAIDA " + ridx + " returned OK"); - cc.setDetectStatus(ridx, CloudCoin.STATUS_PASS); - changed = true; - continue; - } - - if (lfr.status.equals(Config.REQUEST_STATUS_FAIL)) { - logger.debug(ltag, "RAIDA " + ridx + " returned Counterfeit"); - cc.setDetectStatus(ridx, CloudCoin.STATUS_FAIL); - changed = true; - brlist[ridx] = true; - rcnt++; - continue; - } - } - - if (!changed) { - logger.error(ltag, "No changes from RAIDA"); - lr.failed++; - return; - } - - logger.info(ltag, "Doing the next round. Failed raidas: " + rcnt); - - rlist = new int[rcnt]; - requests = new String[rcnt]; - for (i = 0, j = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { - if (brlist[i]) { - rlist[j] = i; - requests[j] = "detect?nn="+ cc.nn + "&sn=" + cc.sn + "&an=" + cc.pans[i] + "&pan=" + cc.pans[i] + "&denomination=" + cc.getDenomination(); - j++; - } - } - - lr.totalRAIDAProcessed = 0; - - results = raida.query(requests, null, lcb, rlist); - if (results == null) { - logger.error(ltag, "Failed to query raida"); - lr.failed++; - return; - } - - for (i = 0; i < results.length; i++) { - ridx = rlist[i]; - - logger.info(ltag, "res=" + results[i] + " from raida " + ridx); - - lfr = (LossFixerResponse) parseResponse(results[i], LossFixerResponse.class); - if (lfr == null) { - logger.error(ltag, "Failed to parse response from: " + i + " raida " + ridx); - cc.setDetectStatus(ridx, CloudCoin.STATUS_ERROR); - continue; - } - - if (lfr.status.equals(Config.REQUEST_STATUS_PASS)) { - logger.debug(ltag, "Round2. RAIDA " + i + " returned OK"); - cc.setDetectStatus(ridx, CloudCoin.STATUS_PASS); - cc.ans[ridx] = cc.pans[ridx]; - continue; - } - } - - cc.setPownStringFromDetectStatus(); - logger.debug(ltag, "Coin Pown after " + cc.getPownString()); - - - for (i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { - int status = cc.getDetectStatus(i); - - if (status == CloudCoin.STATUS_FAIL) { - logger.debug(ltag, "Counterfeit on RAIDA " + i + " Moving to Fracked"); - moveCoinToFracked(cc); - lr.recoveredValue += cc.getDenomination(); - addCoinToReceipt(cc, "fracked", Config.DIR_FRACKED); - return; - } - } - - for (i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { - int status = cc.getDetectStatus(i); - - if (status == CloudCoin.STATUS_UNTRIED || status == CloudCoin.STATUS_ERROR) { - logger.debug(ltag, "We still have a error on RAIDA " + i); - return; - } - } - - moveCoin(cc); - lr.recovered++; - lr.recoveredValue += cc.getDenomination(); - addCoinToReceipt(cc, "bank", Config.DIR_BANK); - } - */ - private void moveCoins(ArrayList ccs) { for (CloudCoin cc : ccs) { diff --git a/src/advclient/common/core/Wallet.java b/src/advclient/common/core/Wallet.java index 5d6f0ac..82f2743 100644 --- a/src/advclient/common/core/Wallet.java +++ b/src/advclient/common/core/Wallet.java @@ -32,6 +32,7 @@ public class Wallet implements Comparable { int[][] counters; public Hashtable envelopes; boolean isUpdated; + boolean correctionAdded; public Wallet(String name, String email, boolean isEncrypted, String password, GLogger logger) { this.name = name; @@ -42,6 +43,7 @@ public Wallet(String name, String email, boolean isEncrypted, String password, G this.logger = logger; this.sns = new int[0]; this.isUpdated = false; + this.correctionAdded = false; logger.debug(ltag, "wallet " + name + " EmailRecovery: " + email + " isEncrypted: " + isEncrypted); lsep = System.getProperty("line.separator"); @@ -231,7 +233,7 @@ public void appendTransaction(String memo, int amount, String receiptId, String int expectedRest = getTotal() + amount; String result = ""; - if (rest != getTotal()) { + if (rest != getTotal() && !correctionAdded) { int adjusted = getTotal() - rest; logger.debug(ltag, "Appending correcting transaction. Rest was: " + @@ -245,9 +247,11 @@ public void appendTransaction(String memo, int amount, String receiptId, String } result += getTotal() + ",dummy" + lsep; - rest = getTotal(); + rest = getTotal(); } - + + correctionAdded = true; + rest += amount; result += rMemo + "," + date + ","; if (amount > 0) { From 83d611dde608c1bb4a21940f7ccd0ef6bea45b02 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Sun, 6 Oct 2019 11:17:02 +0300 Subject: [PATCH 090/160] no trash for encrypted wallets --- src/advclient/common/Vaulter/Vaulter.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/advclient/common/Vaulter/Vaulter.java b/src/advclient/common/Vaulter/Vaulter.java index 3e6f845..423c2ac 100644 --- a/src/advclient/common/Vaulter/Vaulter.java +++ b/src/advclient/common/Vaulter/Vaulter.java @@ -154,8 +154,9 @@ public void doVault(String password, int amount, CloudCoin cc) { return; } - logger.debug(ltag, "File has been successfully encrypted. Moving the original file to Trash"); - AppCore.moveToFolder(tcc.originalFile, Config.DIR_TRASH, user); + logger.debug(ltag, "File has been successfully encrypted. Deleting the original file"); + AppCore.deleteFile(tcc.originalFile); + //AppCore.moveToFolder(tcc.originalFile, Config.DIR_TRASH, user); } vr.status = VaulterResult.STATUS_FINISHED; From 897397900493c7f5a45b4e90cbcf87f4300d6820 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Sun, 6 Oct 2019 13:02:56 +0300 Subject: [PATCH 091/160] predeposit --- src/advclient/AdvancedClient.java | 109 ++++++++++++++----------- src/advclient/ProgramState.java | 1 + src/advclient/common/core/AppCore.java | 18 ++++ 3 files changed, 82 insertions(+), 46 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index c567512..52c0ee5 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -351,7 +351,8 @@ public boolean isDepositing() { if (ps.currentScreen == ProgramState.SCREEN_PREDEPOSIT || ps.currentScreen == ProgramState.SCREEN_DEPOSIT || ps.currentScreen == ProgramState.SCREEN_IMPORTING || - ps.currentScreen == ProgramState.SCREEN_IMPORT_DONE) + ps.currentScreen == ProgramState.SCREEN_IMPORT_DONE || + ps.currentScreen == ProgramState.SCREEN_DEPOSIT_LEFTOVER) return true; return false; @@ -1002,6 +1003,10 @@ public void showScreen() { case ProgramState.SCREEN_WARN_FRACKED_TO_SEND: showWarnFrackedToSend(); break; + case ProgramState.SCREEN_DEPOSIT_LEFTOVER: + showDepositLeftover(); + break; + } @@ -2331,6 +2336,51 @@ public void actionPerformed(ActionEvent e) { } + public void showDepositLeftover() { + int y = 0; + JLabel fname, value; + MyTextField walletName = null; + + JPanel subInnerCore = getPanel("Fix Fracked Coin"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + fname = AppUI.wrapDiv("Left over coins found from last time. Click to import them"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + AppUI.setBoldFont(fname, 21); + y++; + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { + public void actionPerformed(ActionEvent e) { + wl.debug(ltag, "Leftover deposit"); + + ps.srcWallet = null; + ps.currentScreen = ProgramState.SCREEN_IMPORTING; + ps.files = new ArrayList(); + ps.typedMemo = "Recovered from Last time"; + + if (!ps.typedDstPassword.isEmpty()) { + if (ps.typedPassword.isEmpty()) { + ps.typedPassword = ps.typedDstPassword; + } + } + + showScreen(); + } + }, y, gridbag); + + subInnerCore.revalidate(); + subInnerCore.repaint(); + } + public void showWarnFrackedToSend() { int y = 0; JLabel fname, value; @@ -3756,22 +3806,6 @@ public void actionPerformed(ActionEvent e) { ps.dstWallet = w; - int cnt = AppCore.getFilesCount(Config.DIR_SUSPECT, w.getName()); - if (cnt != 0) { - ps.errText = getNonEmptyFolderError("Suspect"); - showScreen(); - return; - } - - cnt = AppCore.getFilesCount(Config.DIR_IMPORT, w.getName()); - if (cnt != 0) { - wl.debug(ltag, "Import folder is not empty: " + cnt + " files. Cleaning"); - AppCore.moveFolderContentsToTrash(Config.DIR_IMPORT, w.getName()); -// ps.errText = getNonEmptyFolderError("Import"); - // showScreen(); - //return; - } - int total; total = ps.srcWallet.getTotal(); if (total == 0) { @@ -3805,6 +3839,14 @@ public void actionPerformed(ActionEvent e) { ps.dstWallet.setPassword(ps.typedDstPassword); } + int cnt = AppCore.staleFiles(w.getName()); + wl.debug(ltag, "Stale files: " + cnt); + if (cnt > 0) { + ps.currentScreen = ProgramState.SCREEN_DEPOSIT_LEFTOVER; + showScreen(); + return; + } + ps.typedAmount = total; ps.isSkyDeposit = true; ps.sendType = ProgramState.SEND_TYPE_WALLET; @@ -4011,35 +4053,10 @@ public void actionPerformed(ActionEvent e) { } if (!w.isSkyWallet()) { - int cnt; - /* - cnt = AppCore.getFilesCount(Config.DIR_FRACKED, w.getName()); - if (cnt != 0) { - ps.errText = "Fracked folder is not empty. Please fix your coins first"; - showScreen(); - return; - }*/ - - cnt = AppCore.getFilesCount(Config.DIR_SUSPECT, w.getName()); - if (cnt != 0) { - ps.errText = getNonEmptyFolderError("Suspect"); - showScreen(); - return; - } - - cnt = AppCore.getFilesCount(Config.DIR_IMPORT, w.getName()); - if (cnt != 0) { - wl.debug(ltag, "Import folder is not empty: " + cnt + " files. Cleaning"); - AppCore.moveFolderContentsToTrash(Config.DIR_IMPORT, w.getName()); - - //ps.errText = getNonEmptyFolderError("Import"); - //showScreen(); - //return; - } - - cnt = AppCore.getFilesCount(Config.DIR_DETECTED, w.getName()); - if (cnt != 0) { - ps.errText = getNonEmptyFolderError("Detected"); + int cnt = AppCore.staleFiles(w.getName()); + wl.debug(ltag, "Stale files: " + cnt); + if (cnt > 0) { + ps.currentScreen = ProgramState.SCREEN_DEPOSIT_LEFTOVER; showScreen(); return; } diff --git a/src/advclient/ProgramState.java b/src/advclient/ProgramState.java index c789b59..2078072 100644 --- a/src/advclient/ProgramState.java +++ b/src/advclient/ProgramState.java @@ -62,6 +62,7 @@ public class ProgramState { final public static int SCREEN_SETTINGS = 44; final public static int SCREEN_SETTINGS_SAVED = 45; final public static int SCREEN_WARN_FRACKED_TO_SEND = 46; + final public static int SCREEN_DEPOSIT_LEFTOVER = 47; final static int CB_STATE_INIT = 1; diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index 8a41f20..108202d 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -1236,4 +1236,22 @@ public static String maskStr(String key, String data) { return result; } + public static int staleFiles(String user) { + int cnt; + + cnt = AppCore.getFilesCount(Config.DIR_IMPORT, user); + if (cnt != 0) + return 1; + + cnt = AppCore.getFilesCount(Config.DIR_SUSPECT, user); + if (cnt != 0) + return 2; + + cnt = AppCore.getFilesCount(Config.DIR_DETECTED, user); + if (cnt != 0) + return 3; + + return 0; + } + } From 6058c9205efad2c2c35ecfacffb1c949afc1a721 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 7 Oct 2019 11:31:00 +0300 Subject: [PATCH 092/160] frack deletion --- .../common/FrackFixer/FrackFixer.java | 18 +++++++++++---- src/advclient/common/core/AppCore.java | 23 ++++++++++++++++++- 2 files changed, 35 insertions(+), 6 deletions(-) diff --git a/src/advclient/common/FrackFixer/FrackFixer.java b/src/advclient/common/FrackFixer/FrackFixer.java index b5978c4..e1793e0 100644 --- a/src/advclient/common/FrackFixer/FrackFixer.java +++ b/src/advclient/common/FrackFixer/FrackFixer.java @@ -628,16 +628,24 @@ private void syncCoin(int raidaIdx, CloudCoin cc) { cc.setPownStringFromDetectStatus(); cc.calcExpirationDate(); - - AppCore.moveToFolder(cc.originalFile, Config.DIR_TRASH, user); - logger.debug(ltag, "Saving file: " + cc.originalFile + " pown " + cc.getPownString()); - if (!AppCore.saveFile(cc.originalFile, cc.getJson(false))) { + String tmpFile = cc.originalFile + ".tmp"; + //AppCore.moveToFolder(cc.originalFile, Config.DIR_TRASH, user); + logger.debug(ltag, "Saving file: " + tmpFile + " pown " + cc.getPownString()); + if (!AppCore.saveFile(tmpFile, cc.getJson(false))) { logger.error(ltag, "Failed to save file: " + cc.originalFile); logger.debug(ltag, "Coin details: " + cc.getJson()); return; } - logger.info(ltag, "saved"); + AppCore.deleteFile(cc.originalFile); + + if (!AppCore.renameFile(tmpFile, cc.originalFile)) { + logger.error(ltag, "Failed to rename file"); + logger.debug(ltag, "Coin details: " + cc.getJson()); + return; + } + + logger.info(ltag, "Coin saved"); } } diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index 108202d..c641733 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -317,7 +317,28 @@ static public boolean moveToFolderNoTs(String fileName, String folder, String us return true; } - + + static public boolean renameFile(String oldFile, String newFile) { + logger.info(ltag, "Renaming " + oldFile + " -> " + newFile); + try { + File fsource = new File(oldFile); + File ftarget = new File(newFile); + if (ftarget.exists()) { + logger.error(ltag, "Target File exists. Leaving"); + return false; + } + + if (!fsource.renameTo(ftarget)) { + logger.error(ltag, "Failed to rename file"); + return false; + } + } catch (Exception e) { + logger.error(ltag, "Failed to move file: " + e.getMessage()); + return false; + } + + return true; + } static public void moveToTrash(String fileName, String user) { moveToFolder(fileName, Config.DIR_TRASH, user); From c9092a0c8598a364109281dd2cdd122b4085a0a6 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 7 Oct 2019 11:40:11 +0300 Subject: [PATCH 093/160] date --- src/advclient/common/core/AppCore.java | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index c641733..3c897d0 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -732,10 +732,13 @@ public static void copyTemplatesFromJar(String user) { } public static String getCurrentDate() { - DateFormat dateFormat = new SimpleDateFormat("yyyy-MMM-d h-mma"); + DateFormat dateFormat = new SimpleDateFormat("yyyy-MMM-dd hh:mma"); Date date = new Date(); - return dateFormat.format(date); + String strDate = dateFormat.format(date).replaceAll("AM$", "am"); + strDate = strDate.replaceAll("PM$", "pm"); + + return strDate; } From 4cc5bb8c93ee1d05bddd15e983307b0c41c60ba0 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 7 Oct 2019 12:04:10 +0300 Subject: [PATCH 094/160] deleting --- src/advclient/common/Authenticator/Authenticator.java | 5 +++-- src/advclient/common/Vaulter/Vaulter.java | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/advclient/common/Authenticator/Authenticator.java b/src/advclient/common/Authenticator/Authenticator.java index 2d37d6b..e64db25 100644 --- a/src/advclient/common/Authenticator/Authenticator.java +++ b/src/advclient/common/Authenticator/Authenticator.java @@ -228,10 +228,11 @@ private void moveCoinsToLost(ArrayList ccs) { logger.info(ltag, "Saving coin to Lost " + file); if (!AppCore.saveFile(file, cc.getJson())) { logger.error(ltag, "Failed to move coin to move to Lost: " + cc.getFileName()); + continue; } - logger.debug(ltag, "Moving to Trash " + cc.sn); - AppCore.moveToTrash(cc.originalFile, user); + logger.debug(ltag, "Deleting " + cc.sn); + AppCore.deleteFile(cc.originalFile); } } } diff --git a/src/advclient/common/Vaulter/Vaulter.java b/src/advclient/common/Vaulter/Vaulter.java index 423c2ac..ec397a8 100644 --- a/src/advclient/common/Vaulter/Vaulter.java +++ b/src/advclient/common/Vaulter/Vaulter.java @@ -279,8 +279,8 @@ public void doUnvault(String password, int amount, CloudCoin cc) { return; } - logger.debug(ltag, "File has been successfully decrypted. Moving the original file to Trash"); - AppCore.moveToFolder(tcc.originalFile, Config.DIR_TRASH, user); + logger.debug(ltag, "File has been successfully decrypted. Deleting the original file"); + AppCore.deleteFile(tcc.originalFile); } vr.status = VaulterResult.STATUS_FINISHED; From 4d62db603f531431183934ceebe7bd4ab37d9ae0 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 7 Oct 2019 12:17:38 +0300 Subject: [PATCH 095/160] deletion --- src/advclient/common/FrackFixer/FrackFixer.java | 1 - src/advclient/common/LossFixer/LossFixer.java | 4 ++-- src/advclient/common/Sender/Sender.java | 5 ----- src/advclient/common/Unpacker/Unpacker.java | 10 +--------- src/advclient/common/Vaulter/Vaulter.java | 1 - 5 files changed, 3 insertions(+), 18 deletions(-) diff --git a/src/advclient/common/FrackFixer/FrackFixer.java b/src/advclient/common/FrackFixer/FrackFixer.java index e1793e0..b69621f 100644 --- a/src/advclient/common/FrackFixer/FrackFixer.java +++ b/src/advclient/common/FrackFixer/FrackFixer.java @@ -629,7 +629,6 @@ private void syncCoin(int raidaIdx, CloudCoin cc) { cc.calcExpirationDate(); String tmpFile = cc.originalFile + ".tmp"; - //AppCore.moveToFolder(cc.originalFile, Config.DIR_TRASH, user); logger.debug(ltag, "Saving file: " + tmpFile + " pown " + cc.getPownString()); if (!AppCore.saveFile(tmpFile, cc.getJson(false))) { logger.error(ltag, "Failed to save file: " + cc.originalFile); diff --git a/src/advclient/common/LossFixer/LossFixer.java b/src/advclient/common/LossFixer/LossFixer.java index 7c6c450..833653e 100644 --- a/src/advclient/common/LossFixer/LossFixer.java +++ b/src/advclient/common/LossFixer/LossFixer.java @@ -357,7 +357,7 @@ public void moveCoin(CloudCoin cc) { return; } - AppCore.moveToImported(cc.originalFile, user); + AppCore.deleteFile(cc.originalFile); } public void moveCoinToFracked(CloudCoin cc) { @@ -371,6 +371,6 @@ public void moveCoinToFracked(CloudCoin cc) { return; } - AppCore.moveToImported(cc.originalFile, user); + AppCore.deleteFile(cc.originalFile); } } diff --git a/src/advclient/common/Sender/Sender.java b/src/advclient/common/Sender/Sender.java index 958f658..2b801d6 100644 --- a/src/advclient/common/Sender/Sender.java +++ b/src/advclient/common/Sender/Sender.java @@ -390,20 +390,15 @@ else if (cc.getDetectStatus(i) == CloudCoin.STATUS_FAIL) logger.info(ltag, "Moving to Counterfeit: " + cc.sn); addCoinToReceipt(cc, "counterfeit", Config.DIR_COUNTERFEIT); c++; - - //AppCore.moveToFolder(cc.originalFile, Config.DIR_COUNTERFEIT, user); } else { logger.info(ltag, "Moving to Lost: " + cc.sn); addCoinToReceipt(cc, "error", Config.DIR_LOST); e++; - //fv += cc.getDenomination(); - //AppCore.moveToFolder(cc.originalFile, Config.DIR_LOST, user); } } } } - public boolean processSend(ArrayList ccs, int tosn, String envelope) { String[] results; String[] requests; diff --git a/src/advclient/common/Unpacker/Unpacker.java b/src/advclient/common/Unpacker/Unpacker.java index 818da17..69538ef 100644 --- a/src/advclient/common/Unpacker/Unpacker.java +++ b/src/advclient/common/Unpacker/Unpacker.java @@ -141,9 +141,6 @@ public void doUnpack() { if (!rv) { logger.error(ltag, "Error processing file: " + fileName); AppCore.moveToTrash(file.toString(), user); - //globalResult.status = UnpackerResult.STATUS_ERROR; - //globalResult.errText = "Failed to parse: " + fileName; - //return; continue; } } @@ -214,8 +211,7 @@ public void doUnpack() { AppCore.moveToImported(cc.originalFile, user); } - //privateLogDir - + globalResult.status = UnpackerResult.STATUS_FINISHED; } @@ -300,8 +296,6 @@ public boolean doUnpackStack(String fileName) { addCoinToRccs(ccs[i], fileName); } - //AppCore.moveToImported(fileName, user); - return true; } @@ -325,8 +319,6 @@ public boolean doUnpackCsv(String fileName) { addCoinToRccs(ccs[i], fileName); } - //AppCore.moveToImported(fileName, user); - return true; } diff --git a/src/advclient/common/Vaulter/Vaulter.java b/src/advclient/common/Vaulter/Vaulter.java index ec397a8..b861019 100644 --- a/src/advclient/common/Vaulter/Vaulter.java +++ b/src/advclient/common/Vaulter/Vaulter.java @@ -156,7 +156,6 @@ public void doVault(String password, int amount, CloudCoin cc) { logger.debug(ltag, "File has been successfully encrypted. Deleting the original file"); AppCore.deleteFile(tcc.originalFile); - //AppCore.moveToFolder(tcc.originalFile, Config.DIR_TRASH, user); } vr.status = VaulterResult.STATUS_FINISHED; From b58c6d19de081af8f70ef25d32d96f7cc14610a3 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 7 Oct 2019 17:18:41 +0300 Subject: [PATCH 096/160] Import ts --- src/advclient/AdvancedClient.java | 2 +- src/advclient/common/core/AppCore.java | 15 ++++++++++++--- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 52c0ee5..bcd2c74 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -1756,7 +1756,7 @@ public void run(){ for (String filename : ps.files) { String name = sm.getActiveWallet().getName(); - AppCore.moveToFolder(filename, Config.DIR_IMPORT, name); + AppCore.moveToFolderNoTs(filename, Config.DIR_IMPORT, name); } pbarText.setText("Unpacking coins ..."); diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index 3c897d0..c8aa3d9 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -294,6 +294,10 @@ static public boolean moveToFolder(String fileName, String folder, String user) } static public boolean moveToFolderNoTs(String fileName, String folder, String user) { + return moveToFolderNoTs(fileName, folder, user, false); + } + + static public boolean moveToFolderNoTs(String fileName, String folder, String user, boolean isOverwrite) { logger.info(ltag, "Moving no Ts to " + folder + " -> " + fileName); try { @@ -302,8 +306,13 @@ static public boolean moveToFolderNoTs(String fileName, String folder, String us File ftarget = new File(target); if (ftarget.exists()) { - logger.error(ltag, "File exists. Leaving " + fileName); - return false; + if (isOverwrite) { + logger.info(ltag, "Overwriting file: " + target); + ftarget.delete(); + } else { + logger.error(ltag, "File exists. Leaving " + fileName); + return false; + } } if (!fsource.renameTo(ftarget)) { @@ -353,7 +362,7 @@ static public void moveToBank(String fileName, String user) { } static public void moveToImported(String fileName, String user) { - moveToFolder(fileName, Config.DIR_IMPORTED, user); + moveToFolderNoTs(fileName, Config.DIR_IMPORTED, user, true); } static public boolean copyFile(InputStream is, String fdst) { From 2bd05cd2fdace2ad197c411147ba01cd893def95 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 7 Oct 2019 18:17:43 +0300 Subject: [PATCH 097/160] skywallet workflow --- src/advclient/AdvancedClient.java | 83 ++++++++++++++++++++++++++----- src/advclient/ProgramState.java | 2 +- 2 files changed, 71 insertions(+), 14 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index bcd2c74..b9f5181 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -5563,7 +5563,7 @@ public void showSetDNSRecordScreen() { public void showCreateSkyWalletScreen() { int y = 0; - JLabel fname; + JLabel fname0, fname1, fname2, fname3, fname4; MyTextField walletName = null; JPanel subInnerCore = getPanel("Create Sky Wallet"); @@ -5580,34 +5580,33 @@ public void showCreateSkyWalletScreen() { AppUI.getGBRow(subInnerCore, null, tw, y, gridbag); y++; - fname = new JLabel("Add Existing"); + fname0 = new JLabel("Add Existing"); final MyCheckBoxToggle cb1 = new MyCheckBoxToggle(); if (ps.isCreatingNewSkyWallet) cb1.setSelected(false); else cb1.setSelected(true); - AppUI.getGBRow(subInnerCore, fname, cb1.getCheckBox(), y, gridbag); + AppUI.getGBRow(subInnerCore, fname0, cb1.getCheckBox(), y, gridbag); y++; - String[] options = { Config.DDNS_DOMAIN, }; - fname = new JLabel("DNS Name or IP Address of Trusted Server"); + fname1 = new JLabel("DNS Name or IP Address of Trusted Server"); final RoundedCornerComboBox cbox = new RoundedCornerComboBox(AppUI.getColor6(), "Select Server", options); cbox.setDefault(null); - AppUI.getGBRow(subInnerCore, fname, cbox.getComboBox(), y, gridbag); + AppUI.getGBRow(subInnerCore, fname1, cbox.getComboBox(), y, gridbag); y++; - fname = new JLabel("Your Proposed Address"); + fname2 = new JLabel("Your Proposed Address"); final MyTextField tf0 = new MyTextField("JohnDoe", false); if (!ps.skyVaultDomain.isEmpty()) tf0.setData(ps.skyVaultDomain); - AppUI.getGBRow(subInnerCore, fname, tf0.getTextField(), y, gridbag); + AppUI.getGBRow(subInnerCore, fname2, tf0.getTextField(), y, gridbag); y++; - fname = new JLabel("Select CloudCoin to be used as ID"); + fname3 = new JLabel("Select CloudCoin to be used as ID"); final MyTextField tf1 = new MyTextField("", false, true); tf1.disable(); tf1.setFilepickerListener(new MouseAdapter() { @@ -5636,15 +5635,45 @@ public void mouseReleased(MouseEvent e) { if (!ps.chosenFile.isEmpty()) tf1.setData(new File(ps.chosenFile).getName()); - AppUI.getGBRow(subInnerCore, fname, tf1.getTextField(), y, gridbag); + AppUI.getGBRow(subInnerCore, fname3, tf1.getTextField(), y, gridbag); y++; - - + + + fname4 = new JLabel("Please put your ID coin here: "); + JLabel sl = AppUI.getHyperLink(AppCore.getIDDir(), "javascript:void(0); return false", 20); + sl.addMouseListener(new MouseAdapter() { + public void mouseReleased(MouseEvent e) { + if (!Desktop.isDesktopSupported()) + return; + try { + Desktop.getDesktop().open(new File(AppCore.getIDDir())); + } catch (IOException ie) { + wl.error(ltag, "Failed to open browser: " + ie.getMessage()); + } + } + }); + + AppUI.getGBRow(subInnerCore, fname4, sl, y, gridbag); + AppUI.setColor(sl, AppUI.getColor2()); + AppUI.underLine(sl); + y++; + + if (ps.isCreatingNewSkyWallet) { + fname4.setVisible(false); + sl.setVisible(false); + } else { + fname4.setVisible(true); + sl.setVisible(true); + } + AppUI.GBPad(subInnerCore, y, gridbag); y++; - AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + + + + MyButton cb = AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { public void actionPerformed(ActionEvent e) { ps.currentScreen = ProgramState.SCREEN_DEFAULT; showScreen(); @@ -5804,6 +5833,34 @@ public void run() { } }, y, gridbag); + cb1.addListener(new ItemListener() { + public void itemStateChanged(ItemEvent e) { + boolean isChecked = e.getStateChange() == ItemEvent.SELECTED; + + if (isChecked) { + fname1.setVisible(false); + fname2.setVisible(false); + fname3.setVisible(false); + tf0.getTextField().setVisible(false); + tf1.getTextField().setVisible(false); + cbox.getComboBox().setVisible(false); + fname4.setVisible(true); + sl.setVisible(true); + cb.disable(); + } else { + fname1.setVisible(true); + fname2.setVisible(true); + fname3.setVisible(true); + tf0.getTextField().setVisible(true); + tf1.getTextField().setVisible(true); + cbox.getComboBox().setVisible(true); + fname4.setVisible(false); + sl.setVisible(false); + cb.enable(); + } + System.out.println("changed " + isChecked); + } + }); } public void showCreateWalletScreen() { diff --git a/src/advclient/ProgramState.java b/src/advclient/ProgramState.java index 2078072..69c918c 100644 --- a/src/advclient/ProgramState.java +++ b/src/advclient/ProgramState.java @@ -194,7 +194,7 @@ public ProgramState() { isSkyDeposit = false; - isCreatingNewSkyWallet = false; + isCreatingNewSkyWallet = true; skyVaultDomain = ""; From aa04e4c7aeb5200d3e33a2f88d5ab67decaad360 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 7 Oct 2019 18:42:04 +0300 Subject: [PATCH 098/160] skywallet workflow --- src/advclient/AdvancedClient.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index b9f5181..19843c9 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -5858,7 +5858,6 @@ public void itemStateChanged(ItemEvent e) { sl.setVisible(false); cb.enable(); } - System.out.println("changed " + isChecked); } }); } From 4f90e0102b0b091e2633b853e3d2dea9b295396d Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 7 Oct 2019 18:58:04 +0300 Subject: [PATCH 099/160] ts remove --- src/advclient/AdvancedClient.java | 3 ++- .../common/ChangeMaker/ChangeMaker.java | 2 +- src/advclient/common/Grader/Grader.java | 8 ++++-- src/advclient/common/Sender/Sender.java | 2 +- src/advclient/common/Unpacker/Unpacker.java | 7 +++-- src/advclient/common/core/AppCore.java | 27 +------------------ 6 files changed, 16 insertions(+), 33 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 19843c9..511462e 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -2434,7 +2434,8 @@ public void actionPerformed(ActionEvent e) { return; } - AppCore.moveToFolder(ps.coinIDinFix.getIDCoin().originalFile, Config.DIR_TRASH, ps.srcWallet.getName()); + AppCore.deleteFile(ps.coinIDinFix.getIDCoin().originalFile); + //AppCore.moveToFolder(ps.coinIDinFix.getIDCoin().originalFile, Config.DIR_TRASH, ps.srcWallet.getName()); wl.debug(ltag, "Set fixing"); ps.currentScreen = ProgramState.SCREEN_FIXING_FRACKED; diff --git a/src/advclient/common/ChangeMaker/ChangeMaker.java b/src/advclient/common/ChangeMaker/ChangeMaker.java index 580aad7..36d5f18 100644 --- a/src/advclient/common/ChangeMaker/ChangeMaker.java +++ b/src/advclient/common/ChangeMaker/ChangeMaker.java @@ -213,7 +213,7 @@ public void callback(Object result) { logger.info(ltag, "cc="+ccs[i].sn + " v=" + ccs[i].getJson(false)); } - AppCore.moveToFolder(cc.originalFile, Config.DIR_SENT, user); + AppCore.moveToFolderNoTs(cc.originalFile, Config.DIR_SENT, user, true); addCoinToReceipt(cc, "authentic", "Sent to Public Change"); saveReceipt(user, 1, 0, 0, 0, 0, 0); diff --git a/src/advclient/common/Grader/Grader.java b/src/advclient/common/Grader/Grader.java index c560bbe..26c47de 100644 --- a/src/advclient/common/Grader/Grader.java +++ b/src/advclient/common/Grader/Grader.java @@ -179,8 +179,12 @@ public void gradeCC(CloudCoin cc, String fsource) { includePans = true; } - ccFile = AppCore.getUserDir(dstFolder, user) + File.separator + - + System.currentTimeMillis() + "-" + cc.getFileName(); + ccFile = AppCore.getUserDir(dstFolder, user) + File.separator + cc.getFileName(); + File f = new File(ccFile); + if (f.exists()) { + logger.debug(ltag, "This coin already exists. Overwriting it"); + AppCore.deleteFile(ccFile); + } } cc.setAnsToPansIfPassed(); diff --git a/src/advclient/common/Sender/Sender.java b/src/advclient/common/Sender/Sender.java index 2b801d6..4d2c391 100644 --- a/src/advclient/common/Sender/Sender.java +++ b/src/advclient/common/Sender/Sender.java @@ -384,7 +384,7 @@ else if (cc.getDetectStatus(i) == CloudCoin.STATUS_FAIL) addCoinToReceipt(cc, "authentic", "Remote Wallet " + remoteWalletName); a++; av += cc.getDenomination(); - AppCore.moveToFolder(cc.originalFile, Config.DIR_SENT, user); + AppCore.moveToFolderNoTs(cc.originalFile, Config.DIR_SENT, user, true); } else if (failed > 0) { if (failed >= RAIDA.TOTAL_RAIDA_COUNT - Config.PASS_THRESHOLD) { logger.info(ltag, "Moving to Counterfeit: " + cc.sn); diff --git a/src/advclient/common/Unpacker/Unpacker.java b/src/advclient/common/Unpacker/Unpacker.java index 69538ef..298f1a9 100644 --- a/src/advclient/common/Unpacker/Unpacker.java +++ b/src/advclient/common/Unpacker/Unpacker.java @@ -227,7 +227,9 @@ public boolean saveCoin(CloudCoin cc) { logger.info(ltag, "Saving " + path + ": " + json); File f = new File(path); if (f.exists()) { - logger.info(ltag, "File " + path + " already exists. Moving to Trash. Continue"); + logger.info(ltag, "File " + path + " already exists. Deleting the old version"); + AppCore.deleteFile(path); + /* path = AppCore.getUserDir(Config.DIR_TRASH, user) + File.separator + System.currentTimeMillis() + "-" + fileName; @@ -235,8 +237,9 @@ public boolean saveCoin(CloudCoin cc) { logger.error(ltag, "Failed to save file in Trash: " + path); return false; } - + return true; + */ } if (!AppCore.saveFile(path, json)) { diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index c8aa3d9..82ecc96 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -272,27 +272,6 @@ static public boolean moveToFolderNewName(String fileName, String folder, String } - static public boolean moveToFolder(String fileName, String folder, String user) { - logger.info(ltag, "Moving to " + folder + " -> " + fileName); - - try { - File fsource = new File(fileName); - String target = AppCore.getUserDir(folder, user) + File.separator + - System.currentTimeMillis() + "-" + fsource.getName(); - - File ftarget = new File(target); - if (!fsource.renameTo(ftarget)) { - logger.error(ltag, "Failed to rename file " + fileName); - return false; - } - } catch (Exception e) { - logger.error(ltag, "Failed to move file: " + e.getMessage()); - return false; - } - - return true; - } - static public boolean moveToFolderNoTs(String fileName, String folder, String user) { return moveToFolderNoTs(fileName, folder, user, false); } @@ -350,11 +329,7 @@ static public boolean renameFile(String oldFile, String newFile) { } static public void moveToTrash(String fileName, String user) { - moveToFolder(fileName, Config.DIR_TRASH, user); - } - - static public void moveToLost(String fileName, String user) { - moveToFolder(fileName, Config.DIR_LOST, user); + moveToFolderNoTs(fileName, Config.DIR_TRASH, user, true); } static public void moveToBank(String fileName, String user) { From 2f286a1c77dac6a63a6964491f8f00bad0300efc Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 9 Oct 2019 16:50:46 +0300 Subject: [PATCH 100/160] sky wallet --- src/advclient/AdvancedClient.java | 19 +++++++++++++++---- src/advclient/ProgramState.java | 6 +++++- 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 511462e..6159dab 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -56,7 +56,7 @@ * */ public class AdvancedClient { - String version = "2.1.17"; + String version = "2.1.18"; JPanel headerPanel; JPanel mainPanel; @@ -865,6 +865,11 @@ public void showScreen() { wl.debug(ltag, "SCREEN " + ps.currentScreen + ": " + ps.toString()); clear(); + if (ps.needInitWallets) { + sm.initWallets(); + ps.needInitWallets = false; + } + switch (ps.currentScreen) { case ProgramState.SCREEN_AGREEMENT: @@ -5648,6 +5653,7 @@ public void mouseReleased(MouseEvent e) { return; try { Desktop.getDesktop().open(new File(AppCore.getIDDir())); + ps.needInitWallets = true; } catch (IOException ie) { wl.error(ltag, "Failed to open browser: " + ie.getMessage()); } @@ -5763,9 +5769,14 @@ public void run(){ t.start(); - ps.currentScreen = ProgramState.SCREEN_SETTING_DNS_RECORD; - showScreen(); - return; + EventQueue.invokeLater(new Runnable() { + public void run() { + ps.currentScreen = ProgramState.SCREEN_SETTING_DNS_RECORD; + showScreen(); + return; + } + }); + } else { if (sn <= 0) { ps.errText = "Wallet does not exist or network error occured"; diff --git a/src/advclient/ProgramState.java b/src/advclient/ProgramState.java index 69c918c..83d9b7b 100644 --- a/src/advclient/ProgramState.java +++ b/src/advclient/ProgramState.java @@ -149,7 +149,9 @@ public class ProgramState { boolean popupVisible; boolean isCheckingSkyID; - + + boolean needInitWallets; + public ProgramState() { currentScreen = SCREEN_AGREEMENT; cwalletRecoveryRequested = cwalletPasswordRequested = false; @@ -215,6 +217,8 @@ public ProgramState() { isCheckingSkyID = false; coinIDinFix = null; + + needInitWallets = false; } public String toString() { From 45811621780e80c1ff7977884ea0f88fbc866c8f Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Tue, 15 Oct 2019 19:24:42 +0300 Subject: [PATCH 101/160] updates; colons; segv --- src/advclient/AdvancedClient.java | 54 ++++++------------------------- 1 file changed, 10 insertions(+), 44 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 6159dab..0086ea2 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -1015,22 +1015,17 @@ public void showScreen() { } - Component[] cs = lwrapperPanel.getComponents(); - if (cs != null && cs.length != 0) { - Container c = (Container) cs[0]; - if (c instanceof JScrollPane) { - JScrollPane sp = (JScrollPane) c; - Component[] spcs = sp.getComponents(); - spcs[0].requestFocus(); + if (lwrapperPanel != null) { + Component[] cs = lwrapperPanel.getComponents(); + if (cs != null && cs.length != 0) { + Container c = (Container) cs[0]; + if (c instanceof JScrollPane) { + JScrollPane sp = (JScrollPane) c; + Component[] spcs = sp.getComponents(); + spcs[0].requestFocus(); + } } } - - - // headerPanel.repaint(); - // headerPanel.revalidate(); - - // corePanel.repaint(); - // corePanel.revalidate(); } public void maybeShowError(JPanel p) { @@ -4972,7 +4967,7 @@ public synchronized void updateTransactionWalletData(Wallet w) { rec = "
Recovery Email: " + w.getEmail() + ""; } - String titleText = "" + w.getName() + " - " + String titleText = "" + w.getName() + " : " + AppCore.formatNumber(w.getTotal()) + "cc" + rec + ""; trTitle.setText(titleText); trTitle.validate(); @@ -5352,35 +5347,6 @@ public void actionPerformed(ActionEvent e) { } } }, 0, gridbag); - - - /* - if (ps.sendType == ProgramState.SEND_TYPE_FOLDER) { - Thread t = new Thread(new Runnable() { - public void run(){ - //UIManager.put("FileChooser.readOnly", Boolean.TRUE); - JFileChooser c = new JFileChooser(ps.chosenFile); - // UIManager.put("FileChooser.readOnly", Boolean.FALSE); - c.setSelectedFile(new File(ps.typedAmount + ".CloudCoin." + ps.typedMemo + ".stack")); - - int rVal = c.showSaveDialog(null); - if (rVal == JFileChooser.APPROVE_OPTION) { - String file = c.getSelectedFile().getAbsolutePath(); - sm.setActiveWalletObj(ps.srcWallet); - ps.srcWallet.setPassword(ps.typedSrcPassword); - if (ps.srcWallet.isEncrypted()) { - sm.startSecureExporterService(Config.TYPE_STACK, ps.typedAmount, ps.typedMemo, file, false, new ExporterCb()); - } else { - sm.startExporterService(Config.TYPE_STACK, ps.typedAmount, ps.typedMemo, file, false, new ExporterCb()); - } - } - } - }); - - t.start(); - } - */ - } From 938974214339bad3187353fb858a92a43d01178d Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 17 Oct 2019 11:10:28 +0300 Subject: [PATCH 102/160] dst --- src/advclient/AdvancedClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 0086ea2..855c8e3 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -1619,7 +1619,7 @@ public void run(){ } if (AppCore.getPassedCount(skyCC) != RAIDA.TOTAL_RAIDA_COUNT) { - ps.errText = getSkyIDError(ps.srcWallet.getName(), ps.srcWallet.getIDCoin().getPownString()); + ps.errText = getSkyIDError(ps.dstWallet.getName(), ps.dstWallet.getIDCoin().getPownString()); showScreen(); return; } From 0ff77807c5a3ac6974423f7b478d5d4f53851301 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 24 Oct 2019 11:42:03 +0300 Subject: [PATCH 103/160] race condition --- src/advclient/AdvancedClient.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 0086ea2..fa7105e 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -192,6 +192,7 @@ else if (total < 999999999) updateTransactionWalletData(w); } } + } public String getSkyIDError(String name, String pownString) { @@ -5063,7 +5064,7 @@ public void showTransactionsScreen() { hwrapper.add(invPanel); } - updateTransactionWalletData(w); + //updateTransactionWalletData(w); rightPanel.add(hwrapper); rightPanel.add(AppUI.hr(22)); From 4ccb24486d08c53d93f39415cab4e4e5f2884284 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 24 Oct 2019 11:43:02 +0300 Subject: [PATCH 104/160] race condition --- src/advclient/AdvancedClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 6758ffb..5d70475 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -56,7 +56,7 @@ * */ public class AdvancedClient { - String version = "2.1.18"; + String version = "2.1.19"; JPanel headerPanel; JPanel mainPanel; From 646cb2c4ed8b6882c5d8256b96bcac87addca8a2 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 24 Oct 2019 11:53:53 +0300 Subject: [PATCH 105/160] race condition --- src/advclient/AdvancedClient.java | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 5d70475..debdba8 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -5030,23 +5030,21 @@ public synchronized void updateTransactionWalletData(Wallet w) { public void showTransactionsScreen() { - invPanel = null; - trTitle = null; - - boolean isSky = sm.getActiveWallet().isSkyWallet() ? true : false; + invPanel = new JPanel(); + trTitle = new JLabel(""); + Wallet w = sm.getActiveWallet(); + updateTransactionWalletData(w); + + boolean isSky = w.isSkyWallet() ? true : false; showLeftScreen(); JPanel rightPanel = getRightPanel(); - - Wallet w = sm.getActiveWallet(); - + JPanel hwrapper = new JPanel(); AppUI.setBoxLayout(hwrapper, false); AppUI.alignLeft(hwrapper); AppUI.noOpaque(hwrapper); - - - trTitle = new JLabel(""); + AppUI.alignLeft(trTitle); AppUI.alignTop(trTitle); AppUI.setFont(trTitle, 30); @@ -5055,7 +5053,6 @@ public void showTransactionsScreen() { int[][] counters = w.getCounters(); if (!isSky && counters != null && counters.length != 0) { - invPanel = new JPanel(); AppUI.setBackground(invPanel, AppUI.getColor7()); AppUI.alignTop(invPanel); AppUI.setSize(invPanel, 520, 62); @@ -5064,7 +5061,6 @@ public void showTransactionsScreen() { hwrapper.add(invPanel); } - //updateTransactionWalletData(w); rightPanel.add(hwrapper); rightPanel.add(AppUI.hr(22)); From 9e5306f19a0f101247b2d3403d45058043c33a57 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 28 Oct 2019 14:13:32 +0300 Subject: [PATCH 106/160] receive round up --- src/advclient/AdvancedClient.java | 12 ++++++-- src/advclient/ProgramState.java | 8 +++++ src/advclient/common/Receiver/Receiver.java | 29 ++++++++++++++----- .../common/Receiver/ReceiverResult.java | 3 ++ 4 files changed, 42 insertions(+), 10 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index debdba8..857d069 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -2001,8 +2001,13 @@ public void showImportDoneScreen() { String totalBankValue = AppCore.formatNumber(ps.statToBankValue); String totalFailedValue = AppCore.formatNumber(ps.statFailedValue); String totalLostValue = AppCore.formatNumber(ps.statLostValue); - - fname = AppUI.wrapDiv("Deposited " + total + " CloudCoins to " + ps.dstWallet.getName() + " "); + + if (ps.needExtra) { + fname = AppUI.wrapDiv("You wanted " + AppCore.formatNumber(ps.typedAmount) + " CC but you got " + total + " CC" + + " because you did not have perfect change. The coins have been transferred to " + ps.dstWallet.getName() + ""); + } else { + fname = AppUI.wrapDiv("Deposited " + total + " CloudCoins to " + ps.dstWallet.getName() + " "); + } AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); y++; @@ -7357,6 +7362,9 @@ public void run() { if (ps.srcWallet != null) name = ps.srcWallet.getName(); + ps.needExtra = rr.needExtra; + ps.rrAmount = rr.amount; + wl.debug(ltag, "rramount " + rr.amount + " typed " + ps.typedAmount + " name=" + name); sm.startGraderService(new GraderCb(), null, name); } diff --git a/src/advclient/ProgramState.java b/src/advclient/ProgramState.java index 83d9b7b..2b55f27 100644 --- a/src/advclient/ProgramState.java +++ b/src/advclient/ProgramState.java @@ -152,6 +152,10 @@ public class ProgramState { boolean needInitWallets; + boolean needExtra; + + int rrAmount; + public ProgramState() { currentScreen = SCREEN_AGREEMENT; cwalletRecoveryRequested = cwalletPasswordRequested = false; @@ -219,6 +223,10 @@ public ProgramState() { coinIDinFix = null; needInitWallets = false; + + needExtra = false; + + rrAmount = 0; } public String toString() { diff --git a/src/advclient/common/Receiver/Receiver.java b/src/advclient/common/Receiver/Receiver.java index fd6b042..84bfe6f 100644 --- a/src/advclient/common/Receiver/Receiver.java +++ b/src/advclient/common/Receiver/Receiver.java @@ -64,11 +64,14 @@ private void copyFromGlobalResult(ReceiverResult rResult) { rResult.amount = globalResult.amount; rResult.errText = globalResult.errText; rResult.receiptId = globalResult.receiptId; + rResult.needExtra = globalResult.needExtra; } public void doReceive(int sn, int[] sns, String fdstFolder, int amount, boolean needReceipt) { int i; + globalResult.needExtra = false; + if (!updateRAIDAStatus()) { logger.error(ltag, "Can't proceed. RAIDA is unavailable"); rr.status = ReceiverResult.STATUS_ERROR; @@ -80,15 +83,25 @@ public void doReceive(int sn, int[] sns, String fdstFolder, int amount, boolean return; } + CloudCoin extraCoin = null; if (!pickCoinsAmountFromArray(sns, amount)) { - logger.debug(ltag, "Not enough coins in the cloudfor amount " + amount); - globalResult.status = ReceiverResult.STATUS_ERROR; - globalResult.errText = Config.PICK_ERROR_MSG; - rr = new ReceiverResult(); - copyFromGlobalResult(rr); - if (cb != null) - cb.callback(rr); - return; + logger.debug(ltag, "Not enough coins in the cloudfor amount " + amount + ". Picking extra"); + + coinsPicked = new ArrayList(); + extraCoin = pickCoinsAmountFromArrayWithExtra(sns, amount); + if (extraCoin == null) { + globalResult.status = ReceiverResult.STATUS_ERROR; + globalResult.errText = "Failed to find coins in the Sky Wallet"; + //globalResult.errText = Config.PICK_ERROR_MSG; + rr = new ReceiverResult(); + copyFromGlobalResult(rr); + if (cb != null) + cb.callback(rr); + return; + } + + globalResult.needExtra = true; + coinsPicked.add(extraCoin); } setSenderRAIDA(); diff --git a/src/advclient/common/Receiver/ReceiverResult.java b/src/advclient/common/Receiver/ReceiverResult.java index f010b8b..90ad7e2 100644 --- a/src/advclient/common/Receiver/ReceiverResult.java +++ b/src/advclient/common/Receiver/ReceiverResult.java @@ -9,6 +9,8 @@ public class ReceiverResult { public int totalCoins; public int totalCoinsProcessed; + public boolean needExtra; + public static int STATUS_PROCESSING = 1; public static int STATUS_FINISHED = 2; public static int STATUS_ERROR = 3; @@ -28,5 +30,6 @@ public ReceiverResult() { amount = 0; memo = "Receive"; status = STATUS_PROCESSING; + needExtra = false; } } From 385a3ea5ee59d81154cc6a68838b4931e3a25929 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 31 Oct 2019 22:58:36 +0300 Subject: [PATCH 107/160] picking algoritm --- src/advclient/AdvancedClient.java | 2 +- src/advclient/common/core/Servant.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 857d069..9c7b73b 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -56,7 +56,7 @@ * */ public class AdvancedClient { - String version = "2.1.19"; + String version = "2.1.20"; JPanel headerPanel; JPanel mainPanel; diff --git a/src/advclient/common/core/Servant.java b/src/advclient/common/core/Servant.java index 099488e..ecb0dde 100644 --- a/src/advclient/common/core/Servant.java +++ b/src/advclient/common/core/Servant.java @@ -728,7 +728,7 @@ public int[] getExpCoins(int amount, int[] totals, boolean loose) { if (amount == 0) break; - if (i == 1 || exp_250 % 2 == 0) { + if (i == 1 || exp_250 == 0) { if (loose) break; From b6bcbe3ce2ad64e620b026bb063a90169310ac5b Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 31 Oct 2019 23:12:15 +0300 Subject: [PATCH 108/160] merge --- src/advclient/common/Exporter/Exporter.java | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/advclient/common/Exporter/Exporter.java b/src/advclient/common/Exporter/Exporter.java index a6fa6c5..29af337 100644 --- a/src/advclient/common/Exporter/Exporter.java +++ b/src/advclient/common/Exporter/Exporter.java @@ -207,9 +207,6 @@ private boolean exportJpeg(String dir, String user, String tag) { logger.info(ltag, "Loaded: " + bytes.length); - // Header - sb.append(Config.JPEG_MARKER); - // Ans for (int i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { sb.append(cc.ans[i]); @@ -219,19 +216,13 @@ private boolean exportJpeg(String dir, String user, String tag) { sb.append("00000000000000000000000000000000"); // PownString - for (int i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { - sb.append("0"); - } - - // Append trailing zero - if (RAIDA.TOTAL_RAIDA_COUNT % 2 != 0) - sb.append("0"); - + sb.append("11111111111111111111111111"); + // Append HC sb.append("00"); // Append ED - sb.append("97E2"); + sb.append("AC");//AC means nothing // NN sb.append("0" + cc.nn); From d9eab9336b36bc7238c4106e9769c3e789c1dd36 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Sat, 2 Nov 2019 13:32:25 +0300 Subject: [PATCH 109/160] change algorithm --- src/advclient/AdvancedClient.java | 6 +- src/advclient/common/core/ServantManager.java | 87 +++++++++++++++++++ 2 files changed, 92 insertions(+), 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 9c7b73b..5656be0 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -56,7 +56,7 @@ * */ public class AdvancedClient { - String version = "2.1.20"; + String version = "2.1.21"; JPanel headerPanel; JPanel mainPanel; @@ -1027,6 +1027,10 @@ public void showScreen() { } } } + + corePanel.repaint(); + corePanel.revalidate(); + } public void maybeShowError(JPanel p) { diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index 1657ca7..18df41c 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -544,9 +544,67 @@ public void startSecureExporterService(int exportType, int amount, String tag, S v.unvault(password, amount, null, new eVaulterCb(exportType, amount, tag, dir, keepSrc, cb)); } + public int findNoteToChange(int needed, int b250, int b100, int b25, int b5, int b1) { + int totalReturn = 0; + int totalNeeded = needed; + int bankTotal = b250 * 250 + b100 * 100 + b25 * 25 + b5 * 5 + b1; + + logger.debug(ltag, "Finding note to change: " + needed + " 250s:" + b250 + + ", 100s: " + b100 + ", 25s: " + b25 + ", 5s: " + b5 + ", 1s: " + b1); + + if (bankTotal < totalNeeded) { + logger.error(ltag, "Not enough bank total: " + bankTotal + " Wanted to send " + totalNeeded); + return -1; + } + + while (totalNeeded != totalReturn) { + if (b250 > 0 && totalNeeded >= 250) { + b250--; + totalNeeded -= 250; + totalReturn += 250; + } else if (b100 > 0 && totalNeeded >= 100) { + b100--; + totalNeeded -= 100; + totalReturn += 100; + } else if (b25 > 0 && totalNeeded >= 25) { + b25--; + totalNeeded -= 25; + totalReturn += 25; + } else if (b5 > 0 && totalNeeded >= 5) { + b5--; + totalNeeded -= 5; + totalReturn += 5; + } else if (b1 > 0 && totalNeeded >= 1) { + b1--; + totalNeeded -= 1; + totalReturn += 1; + } else { + if (b5 > 0) + return 5; + + if (b25 > 0) + return 25; + + if (b100 > 0) + return 100; + + if (b250 > 0) + return 250; + + logger.error(ltag, "Unable to find change"); + return -1; + } + } + + logger.error(ltag, "No change required. Why did you call me?"); + + return 0; + } public boolean makeChange(Wallet w, int amount, int skySN, CallbackInterface cb) { int min5sn, min25sn, min100sn, min250sn; + int b250, b100, b25, b5, b1; + makeChangeResult mcr = new makeChangeResult(); logger.debug(ltag, "Make Change"); @@ -564,6 +622,7 @@ public boolean makeChange(Wallet w, int amount, int skySN, CallbackInterface cb) } min5sn = min25sn = min100sn = min250sn = 0; + b250 = b100 = b25 = b5 = b1 = 0; for (int i = 0; i < sns.length; i++) { CloudCoin cc = new CloudCoin(Config.DEFAULT_NN, sns[i]); int denomination = cc.getDenomination(); @@ -573,24 +632,51 @@ public boolean makeChange(Wallet w, int amount, int skySN, CallbackInterface cb) switch (denomination) { case 5: + b5++; if (min5sn == 0 || min5sn < denomination) min5sn = sns[i]; break; case 25: + b25++; if (min25sn == 0 || min25sn < denomination) min25sn = sns[i]; break; case 100: + b100++; if (min100sn == 0 || min100sn < denomination) min100sn = sns[i]; break; case 250: + b250++; if (min250sn == 0 || min250sn < denomination) min250sn = sns[i]; break; } } + int rqDenom = findNoteToChange(amount, b250, b100, b25, b5, b1); + logger.debug(ltag, "rqDenom = " + rqDenom); + if (rqDenom <= 0) { + mcr.errText = "Failed to find a coin (SN) to make change"; + if (cb != null) + cb.callback(mcr); + logger.error(ltag, "Failed to find a coin (SN) to change"); + return false; + } + + int sn = 0; + for (int i = 0; i < sns.length; i++) { + CloudCoin cc = new CloudCoin(Config.DEFAULT_NN, sns[i]); + int denomination = cc.getDenomination(); + + if (rqDenom == denomination) { + logger.debug(ltag, "Found denomination"); + sn = cc.sn; + break; + } + } + + /* int[] ds = { min5sn, min25sn, min100sn, min250sn }; int idx; if (amount < 5) @@ -619,6 +705,7 @@ else if (amount < 100) idx--; } + */ if (sn == 0) { mcr.errText = "Failed to find a coin to make change"; From 2df7ed209acd88f8ee56cc19589db96bd7b2453f Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 18 Dec 2019 10:46:13 +0300 Subject: [PATCH 110/160] dots --- src/advclient/AdvancedClient.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 5656be0..f16b226 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -56,7 +56,7 @@ * */ public class AdvancedClient { - String version = "2.1.21"; + String version = "2.1.22"; JPanel headerPanel; JPanel mainPanel; @@ -5707,6 +5707,13 @@ public void actionPerformed(ActionEvent e) { return; } + if (domain.indexOf(".") != -1) { + ps.errText = "Dots are not allowed in Sky Wallet names"; + showScreen(); + return; + } + + final String newFileName = domain + "." + ps.trustedServer + ".stack"; final DNSSn d = new DNSSn(domain, ps.trustedServer, wl); int sn = d.getSN(); From 75c38ec3748e01537ee9c4d83fa1000b424a17a1 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 18 Dec 2019 10:57:30 +0300 Subject: [PATCH 111/160] export limit --- src/advclient/common/Exporter/Exporter.java | 15 +++++++++++++++ src/advclient/common/core/Config.java | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/src/advclient/common/Exporter/Exporter.java b/src/advclient/common/Exporter/Exporter.java index 29af337..9fb3694 100644 --- a/src/advclient/common/Exporter/Exporter.java +++ b/src/advclient/common/Exporter/Exporter.java @@ -140,6 +140,21 @@ public void doExport(int type, int[] values, int amount, String dir, boolean kee logger.debug(ltag, "Export isbackup " + keepSrc + " type " + type + " amount " + amount); if (type == Config.TYPE_STACK) { + if (!keepSrc) { + int totalNotes = coinsPicked.size(); + if (totalNotes > Config.MAX_EXPORTED_NOTES) { + er.status = ExporterResult.STATUS_ERROR; + er.errText = "Exporting more than " + Config.MAX_EXPORTED_NOTES + + " notes is not allowed. Try to export fewer coins"; + if (cb != null) + cb.callback(er); + + return; + } + } + + System.out.println("cp="+coinsPicked.size()); + System.exit(1); if (!exportStack(fullExportPath, tag)) { er.status = ExporterResult.STATUS_ERROR; if (cb != null) diff --git a/src/advclient/common/core/Config.java b/src/advclient/common/core/Config.java index d4e0afe..0a7ba65 100644 --- a/src/advclient/common/core/Config.java +++ b/src/advclient/common/core/Config.java @@ -186,6 +186,6 @@ public class Config { public static int MAX_COUNTERFEIT_RAIDAS_TO_SEND = 2; public static int MAX_FAILED_RAIDAS_TO_SEND = 2; - + public static int MAX_EXPORTED_NOTES = 3000; } From 90cb3543cc235bb9b381b61486f6e51d07831a30 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 18 Dec 2019 11:37:37 +0300 Subject: [PATCH 112/160] deposit --- src/advclient/AdvancedClient.java | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index f16b226..7884214 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -1949,9 +1949,16 @@ public void showTransferDoneScreen() { to = "?"; } - String name = ps.srcWallet.getName(); - fname = AppUI.wrapDiv("" + AppCore.formatNumber(ps.typedAmount) + String name = ps.srcWallet.getName(); + if (ps.needExtra) { + String total = AppCore.formatNumber(ps.statToBankValue + ps.statFailedValue + ps.statLostValue); + fname = AppUI.wrapDiv("You wanted " + AppCore.formatNumber(ps.typedAmount) + " CC but you got " + total + " CC" + + " because you did not have perfect change. " + + "The coins have been transferred to " + to + " from " + name + ""); + } else { + fname = AppUI.wrapDiv("" + AppCore.formatNumber(ps.typedAmount) + " CC have been transferred to " + to + " from " + name + ""); + } AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); y++; @@ -2006,12 +2013,8 @@ public void showImportDoneScreen() { String totalFailedValue = AppCore.formatNumber(ps.statFailedValue); String totalLostValue = AppCore.formatNumber(ps.statLostValue); - if (ps.needExtra) { - fname = AppUI.wrapDiv("You wanted " + AppCore.formatNumber(ps.typedAmount) + " CC but you got " + total + " CC" - + " because you did not have perfect change. The coins have been transferred to " + ps.dstWallet.getName() + ""); - } else { - fname = AppUI.wrapDiv("Deposited " + total + " CloudCoins to " + ps.dstWallet.getName() + " "); - } + + fname = AppUI.wrapDiv("Deposited " + total + " CloudCoins to " + ps.dstWallet.getName() + " "); AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); y++; @@ -6815,7 +6818,10 @@ public void callback(Object result) { EventQueue.invokeLater(new Runnable() { public void run() { ps.errText = "Operation Cancelled"; - ps.currentScreen = ProgramState.SCREEN_IMPORT_DONE; + if (isWithdrawing()) + ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; + else + ps.currentScreen = ProgramState.SCREEN_IMPORT_DONE; showScreen(); } }); @@ -7096,6 +7102,9 @@ public void run() { if (isFixing()) { ps.currentScreen = ProgramState.SCREEN_FIX_DONE; } else { + if (isWithdrawing()) + ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; + else ps.currentScreen = ProgramState.SCREEN_IMPORT_DONE; } showScreen(); From 833ca9fdedb7f3e3eb9f01ddf45069192afae068 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 18 Dec 2019 11:51:11 +0300 Subject: [PATCH 113/160] skip non-stack from ID --- src/advclient/common/core/ServantManager.java | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index 18df41c..73b236c 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -184,6 +184,13 @@ public void checkIDCoins() { String[] idCoins = AppCore.getFilesInDir(AppCore.getIDDir(), null); for (int i = 0; i < idCoins.length; i++) { + System.out.println("f=" + idCoins[i]); + if (idCoins[i].endsWith(".stack")) { + logger.info(ltag, "Skipping non-stack file in the ID folder: " + idCoins[i]); + System.out.println("Skipping non-stack file in the ID folder: " + idCoins[i]); + continue; + } + CloudCoin cc; try { cc = new CloudCoin(AppCore.getIDDir() + File.separator + idCoins[i]); From 9dc9a1c88e921702dc9dccacfe127996fda523da Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 18 Dec 2019 11:51:56 +0300 Subject: [PATCH 114/160] skip non-stack from ID --- src/advclient/common/core/ServantManager.java | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index 73b236c..66979b5 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -184,10 +184,8 @@ public void checkIDCoins() { String[] idCoins = AppCore.getFilesInDir(AppCore.getIDDir(), null); for (int i = 0; i < idCoins.length; i++) { - System.out.println("f=" + idCoins[i]); if (idCoins[i].endsWith(".stack")) { logger.info(ltag, "Skipping non-stack file in the ID folder: " + idCoins[i]); - System.out.println("Skipping non-stack file in the ID folder: " + idCoins[i]); continue; } From fac3388d7d7ba5e6ccceb7b9904d6dd4a21b85cd Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Sun, 22 Dec 2019 11:17:03 +0300 Subject: [PATCH 115/160] fix --- src/advclient/common/core/ServantManager.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index 66979b5..e513167 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -184,7 +184,7 @@ public void checkIDCoins() { String[] idCoins = AppCore.getFilesInDir(AppCore.getIDDir(), null); for (int i = 0; i < idCoins.length; i++) { - if (idCoins[i].endsWith(".stack")) { + if (!idCoins[i].endsWith(".stack")) { logger.info(ltag, "Skipping non-stack file in the ID folder: " + idCoins[i]); continue; } From 3098151e0456f5facf7336ad3521bf4a3cf251e3 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Sun, 22 Dec 2019 11:17:46 +0300 Subject: [PATCH 116/160] version bump --- src/advclient/AdvancedClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 7884214..97d6de9 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -56,7 +56,7 @@ * */ public class AdvancedClient { - String version = "2.1.22"; + String version = "2.1.23"; JPanel headerPanel; JPanel mainPanel; From a5ac3905fd1f25941e99c414feaf8b959b730a2a Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 23 Dec 2019 22:46:06 +0300 Subject: [PATCH 117/160] rm debug --- src/advclient/common/Exporter/Exporter.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/advclient/common/Exporter/Exporter.java b/src/advclient/common/Exporter/Exporter.java index 9fb3694..6ca6f2d 100644 --- a/src/advclient/common/Exporter/Exporter.java +++ b/src/advclient/common/Exporter/Exporter.java @@ -152,9 +152,7 @@ public void doExport(int type, int[] values, int amount, String dir, boolean kee return; } } - - System.out.println("cp="+coinsPicked.size()); - System.exit(1); + if (!exportStack(fullExportPath, tag)) { er.status = ExporterResult.STATUS_ERROR; if (cb != null) From a1f6f3bda23ee7bd281a7f793659bdeb4fa8e3ca Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 23 Dec 2019 23:28:06 +0300 Subject: [PATCH 118/160] skip stack extension --- src/advclient/AdvancedClient.java | 2 +- .../common/Authenticator/Authenticator.java | 7 +++ .../common/FrackFixer/FrackFixer.java | 3 ++ src/advclient/common/Grader/Grader.java | 3 ++ src/advclient/common/LossFixer/LossFixer.java | 3 ++ src/advclient/common/Sender/Sender.java | 3 ++ src/advclient/common/ShowCoins/ShowCoins.java | 3 ++ src/advclient/common/Unpacker/Unpacker.java | 6 +++ src/advclient/common/Vaulter/Vaulter.java | 3 ++ src/advclient/common/core/AppCore.java | 44 +++++++++++++++---- src/advclient/common/core/Servant.java | 9 ++++ 11 files changed, 76 insertions(+), 10 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 97d6de9..47e5ee7 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -56,7 +56,7 @@ * */ public class AdvancedClient { - String version = "2.1.23"; + String version = "2.1.24"; JPanel headerPanel; JPanel mainPanel; diff --git a/src/advclient/common/Authenticator/Authenticator.java b/src/advclient/common/Authenticator/Authenticator.java index e64db25..5677fef 100644 --- a/src/advclient/common/Authenticator/Authenticator.java +++ b/src/advclient/common/Authenticator/Authenticator.java @@ -299,6 +299,9 @@ public void doAuthencticate() { if (file.isDirectory()) continue; + if (!AppCore.hasCoinExtension(file)) + continue; + try { cc = new CloudCoin(file.toString()); } catch (JSONException e) { @@ -317,6 +320,9 @@ public void doAuthencticate() { if (file.isDirectory()) continue; + if (!AppCore.hasCoinExtension(file)) + continue; + try { cc = new CloudCoin(file.toString()); } catch (JSONException e) { @@ -391,4 +397,5 @@ public void doAuthencticate() { cb.callback(ar); } + } diff --git a/src/advclient/common/FrackFixer/FrackFixer.java b/src/advclient/common/FrackFixer/FrackFixer.java index b69621f..3296798 100644 --- a/src/advclient/common/FrackFixer/FrackFixer.java +++ b/src/advclient/common/FrackFixer/FrackFixer.java @@ -187,6 +187,9 @@ public void doFrackFix() { if (file.isDirectory()) continue; + if (!AppCore.hasCoinExtension(file)) + continue; + try { cc = new CloudCoin(file.toString()); } catch (JSONException e) { diff --git a/src/advclient/common/Grader/Grader.java b/src/advclient/common/Grader/Grader.java index 26c47de..6365a27 100644 --- a/src/advclient/common/Grader/Grader.java +++ b/src/advclient/common/Grader/Grader.java @@ -60,6 +60,9 @@ public void doGrade(ArrayList duplicates, String source) { if (file.isDirectory()) continue; + if (!AppCore.hasCoinExtension(file)) + continue; + graded = true; try { cc = new CloudCoin(file.toString()); diff --git a/src/advclient/common/LossFixer/LossFixer.java b/src/advclient/common/LossFixer/LossFixer.java index 833653e..d8b2bad 100644 --- a/src/advclient/common/LossFixer/LossFixer.java +++ b/src/advclient/common/LossFixer/LossFixer.java @@ -85,6 +85,9 @@ public void doLossFix() { if (file.isDirectory()) continue; + if (!AppCore.hasCoinExtension(file)) + continue; + try { cc = new CloudCoin(file.toString()); } catch (JSONException e) { diff --git a/src/advclient/common/Sender/Sender.java b/src/advclient/common/Sender/Sender.java index 4d2c391..a92400a 100644 --- a/src/advclient/common/Sender/Sender.java +++ b/src/advclient/common/Sender/Sender.java @@ -172,6 +172,9 @@ public void pickCoinsFromSuspect() { if (file.isDirectory()) continue; + if (!AppCore.hasCoinExtension(file)) + continue; + try { cc = new CloudCoin(file.toString()); } catch (JSONException e) { diff --git a/src/advclient/common/ShowCoins/ShowCoins.java b/src/advclient/common/ShowCoins/ShowCoins.java index 7f3b4f0..6ec4a12 100644 --- a/src/advclient/common/ShowCoins/ShowCoins.java +++ b/src/advclient/common/ShowCoins/ShowCoins.java @@ -74,6 +74,9 @@ public void showCoinsInFolder(int idx, String folder) { if (file.isDirectory()) continue; + if (!AppCore.hasCoinExtension(file)) + continue; + try { cc = new CloudCoin(file.toString()); } catch (JSONException e) { diff --git a/src/advclient/common/Unpacker/Unpacker.java b/src/advclient/common/Unpacker/Unpacker.java index 298f1a9..980c585 100644 --- a/src/advclient/common/Unpacker/Unpacker.java +++ b/src/advclient/common/Unpacker/Unpacker.java @@ -68,6 +68,9 @@ public int checkCoinsInFolder(String folder) { if (file.isDirectory()) continue; + if (!AppCore.hasCoinExtension(file)) + continue; + logger.debug(ltag, "Parsing " + file); try { @@ -111,6 +114,9 @@ public void doUnpack() { if (file.isDirectory()) continue; + if (!AppCore.hasCoinExtension(file)) + continue; + fileName = file.getName(); index = fileName.lastIndexOf('.'); if (index <= 0) { diff --git a/src/advclient/common/Vaulter/Vaulter.java b/src/advclient/common/Vaulter/Vaulter.java index b861019..7d9c6af 100644 --- a/src/advclient/common/Vaulter/Vaulter.java +++ b/src/advclient/common/Vaulter/Vaulter.java @@ -322,6 +322,9 @@ public void pickAll(String folder) { if (file.isDirectory()) continue; + if (!AppCore.hasCoinExtension(file)) + continue; + try { cc = new CloudCoin(file.toString()); } catch (JSONException e) { diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index 82ecc96..4e2eb59 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -522,19 +522,30 @@ static public void deleteFile(String path) { } static public int getFilesCount(String dir, String user) { - String path = getUserDir(dir, user); - File rFile; - int rv; + String path = getUserDir(dir, user); + File rFile; + int rv; - try { - rFile = new File(path); - rv = rFile.listFiles().length; - } catch (Exception e) { + try { + rFile = new File(path); + //rv = rFile.listFiles().length; + + rv = 0; + for (File file: rFile.listFiles()) { + if (file.isDirectory()) + continue; + + if (!AppCore.hasCoinExtension(file)) + continue; + + rv++; + } + } catch (Exception e) { logger.error(ltag, "Failed to read directory: " + e.getMessage()); return 0; - } + } - return rv; + return rv; } static public String getMD5(String data) { @@ -782,6 +793,9 @@ public static CloudCoin findCoinBySN(String dir, String user, int sn) { if (file.isDirectory()) continue; + if (!AppCore.hasCoinExtension(file)) + continue; + try { cc = new CloudCoin(file.toString()); } catch (JSONException e) { @@ -1262,4 +1276,16 @@ public static int staleFiles(String user) { return 0; } + + public static boolean hasCoinExtension(File file) { + String f = file.toString().toLowerCase(); + if (f.endsWith(".stack") || f.endsWith(".jpg") || f.endsWith(".jpeg")) + return true; + + logger.debug(ltag, "Ignoring invalid extension " + file.toString()); + + return false; + } + + } diff --git a/src/advclient/common/core/Servant.java b/src/advclient/common/core/Servant.java index ecb0dde..8735239 100644 --- a/src/advclient/common/core/Servant.java +++ b/src/advclient/common/core/Servant.java @@ -512,6 +512,9 @@ protected CloudCoin getIDcc(int sn) { if (file.isDirectory()) continue; + if (!AppCore.hasCoinExtension(file)) + continue; + logger.debug(ltag, "Parsing " + file); try { @@ -573,6 +576,9 @@ public boolean pickCoinsInDir(String dir, int[] values) { if (file.isDirectory()) continue; + if (!AppCore.hasCoinExtension(file)) + continue; + try { cc = new CloudCoin(file.toString()); } catch (JSONException e) { @@ -643,6 +649,9 @@ public int[] countCoins(String dir) { if (file.isDirectory()) continue; + if (!AppCore.hasCoinExtension(file)) + continue; + try { cc = new CloudCoin(file.toString()); } catch (JSONException e) { From 5f11f0f6fb82f877a82807e3a6c1b05e58bdf024 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 30 Dec 2019 13:51:40 +0300 Subject: [PATCH 119/160] sent --- src/advclient/AdvancedClient.java | 100 ++++++++++++++++++++++++- src/advclient/common/core/AppCore.java | 27 ++++++- src/advclient/common/core/Config.java | 2 + 3 files changed, 121 insertions(+), 8 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 47e5ee7..16f15aa 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -56,7 +56,7 @@ * */ public class AdvancedClient { - String version = "2.1.24"; + String version = "2.1.25"; JPanel headerPanel; JPanel mainPanel; @@ -666,7 +666,7 @@ public void paintComponent(final Graphics g) { }; String[] items = {"Backup", "List serials", "Clear History", "Fix Fracked", - "Delete Wallet", "Show Folders", "Echo RAIDA", "Settings"}; + "Delete Wallet", "Show Folders", "Echo RAIDA", "Settings", "Sent Coins"}; for (int i = 0; i < items.length; i++) { JMenuItem menuItem = new JMenuItem(items[i]); menuItem.setActionCommand("" + i); @@ -724,7 +724,10 @@ public void mouseReleased(MouseEvent evt) { ps.currentScreen = ProgramState.SCREEN_ECHO_RAIDA; } else if (action.equals("7")) { ps.currentScreen = ProgramState.SCREEN_SETTINGS; + } else if (action.equals("8")) { + ps.currentScreen = ProgramState.SCREEN_SHOW_SENT_COINS; } + showScreen(); } }; @@ -1012,8 +1015,9 @@ public void showScreen() { case ProgramState.SCREEN_DEPOSIT_LEFTOVER: showDepositLeftover(); break; - - + case ProgramState.SCREEN_SHOW_SENT_COINS: + showSentCoins(); + break; } if (lwrapperPanel != null) { @@ -3173,6 +3177,7 @@ public void eraserGoNext() { } wl.killMe(); + AppCore.rmSentCoins(); showScreen(); } } @@ -4879,6 +4884,80 @@ public void actionPerformed(ActionEvent e) { }, y, gridbag); } + public void showSentCoins() { + + JLabel fname; + int y = 0; + + JPanel subInnerCore = getPanel("Sent Coins"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + fname = AppUI.wrapDiv("Sent Coins"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + + + // Scrollbar & Table + DefaultTableCellRenderer r = new DefaultTableCellRenderer() { + JLabel lbl; + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column); + + Color c = AppUI.getColor6(); + Color fgc = AppUI.getColor5(); + if (table.isPaintingForPrint()) { + c = AppUI.getColor5(); + fgc = Color.BLACK; + } + + lbl = (JLabel) this; + AppUI.setBackground(lbl, c); + AppUI.setColor(lbl, fgc); + lbl.setHorizontalAlignment(JLabel.LEFT); + AppUI.setMargin(lbl, 8); + + return lbl; + } + }; + + + String[][] serials = AppCore.getSentCoins(); + if (serials == null) { + return; + } + + //serial number table + final JTable table = new JTable(); + final JScrollPane scrollPane = AppUI.setupTable(table, new String[] {"Date", "From", "To", "SN", "Amount", "Memo"}, serials, r); + AppUI.setSize(scrollPane, 830, 285); + + AppUI.getGBRow(subInnerCore, null, scrollPane, y, gridbag); + y++; + + table.getColumnModel().getColumn(0).setPreferredWidth(120); + table.getColumnModel().getColumn(3).setPreferredWidth(10); + table.getColumnModel().getColumn(4).setPreferredWidth(10); + + + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + AppUI.getTwoButtonPanel(subInnerCore, "Print", "", new ActionListener() { + public void actionPerformed(ActionEvent e) { + try { + table.print(); + } catch (PrinterException pe) { + System.out.println("Failed to print"); + } + } + }, null, y, gridbag); + + resetState(); + } + public void showListSerialsDone() { JLabel fname; @@ -7443,6 +7522,19 @@ public void run() { return; } + String dstName; + int sn; + + if (ps.dstWallet != null) { + sn = ps.dstWallet.getIDCoin().sn; + dstName = ps.dstWallet.getName(); + } else { + sn = ps.foundSN; + dstName = ps.typedRemoteWallet; + } + + AppCore.appendSkySentCoinTransaction(ps.srcWallet.getName(), dstName, sn, ps.typedAmount, ps.typedMemo); + ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; showScreen(); } diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index 4e2eb59..98950b5 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -1276,7 +1276,28 @@ public static int staleFiles(String user) { return 0; } - + public static void appendSkySentCoinTransaction(String from, String to, int tosn, int amount, String memo) { + String rMemo = memo.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll(",", " "); + String fstr, result; + String date = AppCore.getCurrentDate(); + + fstr = date + "," + from + "," + to + "," + tosn + "," + amount + "," +memo; + + String fileName = AppCore.getLogDir() + File.separator + Config.SENT_SKYCOINS_FILENAME; + result = AppCore.loadFile(fileName); + if (result == null) { + logger.debug(ltag, "Failed to open transactions file for SentCoins"); + return; + } + + System.out.println("str=" +fstr); + logger.debug(ltag, "Append transaction: " + fstr + " s="+fileName); + + result += "\r\n" + fstr; + + AppCore.saveFileAppend(fileName, result, true); + } + public static boolean hasCoinExtension(File file) { String f = file.toString().toLowerCase(); if (f.endsWith(".stack") || f.endsWith(".jpg") || f.endsWith(".jpeg")) @@ -1285,7 +1306,5 @@ public static boolean hasCoinExtension(File file) { logger.debug(ltag, "Ignoring invalid extension " + file.toString()); return false; - } - - + } } diff --git a/src/advclient/common/core/Config.java b/src/advclient/common/core/Config.java index 0a7ba65..1a0ddc1 100644 --- a/src/advclient/common/core/Config.java +++ b/src/advclient/common/core/Config.java @@ -188,4 +188,6 @@ public class Config { public static int MAX_EXPORTED_NOTES = 3000; + final public static String SENT_SKYCOINS_FILENAME = "sentcoins.csv"; + } From beaeadf8a62849ac6b44e4a11b66158552dae036 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 30 Dec 2019 14:47:30 +0300 Subject: [PATCH 120/160] add sent coins --- src/advclient/AdvancedClient.java | 109 ++++++++++++++++++++----- src/advclient/AppUI.java | 38 +++++---- src/advclient/ProgramState.java | 1 + src/advclient/common/core/AppCore.java | 77 ++++++++++++----- 4 files changed, 167 insertions(+), 58 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 16f15aa..261f3a7 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -50,6 +50,7 @@ import javax.swing.plaf.MenuItemUI; import javax.swing.plaf.basic.BasicScrollBarUI; import javax.swing.table.DefaultTableCellRenderer; +import javax.swing.table.TableCellRenderer; /** @@ -4889,15 +4890,29 @@ public void showSentCoins() { JLabel fname; int y = 0; - JPanel subInnerCore = getPanel("Sent Coins"); - GridBagLayout gridbag = new GridBagLayout(); - subInnerCore.setLayout(gridbag); - - fname = AppUI.wrapDiv("Sent Coins"); - AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); - y++; + showLeftScreen(); + //JPanel subInnerCore = getPanel("Sent Coins"); + JPanel rightPanel = getRightPanel(); + JLabel xtrTitle = new JLabel("Sent Coins"); + + + + AppUI.alignCenter(xtrTitle); + AppUI.alignTop(xtrTitle); + AppUI.setFont(xtrTitle, 30); + AppUI.setColor(xtrTitle, AppUI.getColor1()); + + + rightPanel.add(xtrTitle); + + rightPanel.add(AppUI.hr(22)); + + + //GridBagLayout gridbag = new GridBagLayout(); + //subInnerCore.setLayout(gridbag); + // Scrollbar & Table DefaultTableCellRenderer r = new DefaultTableCellRenderer() { JLabel lbl; @@ -4915,7 +4930,19 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole lbl = (JLabel) this; AppUI.setBackground(lbl, c); AppUI.setColor(lbl, fgc); - lbl.setHorizontalAlignment(JLabel.LEFT); + if (column == 0) + lbl.setHorizontalAlignment(JLabel.LEFT); + else if (column == 4) { + lbl.setHorizontalAlignment(JLabel.RIGHT); + String d = (String) value; + try { + String total = AppCore.formatNumber(Integer.parseInt(d)); + lbl.setText(total); + } catch (NumberFormatException e) { + + } + } else + lbl.setHorizontalAlignment(JLabel.CENTER); AppUI.setMargin(lbl, 8); return lbl; @@ -4927,25 +4954,65 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole if (serials == null) { return; } - - //serial number table + final JTable table = new JTable(); - final JScrollPane scrollPane = AppUI.setupTable(table, new String[] {"Date", "From", "To", "SN", "Amount", "Memo"}, serials, r); - AppUI.setSize(scrollPane, 830, 285); + final TableCellRenderer hr = table.getTableHeader().getDefaultRenderer(); + TableCellRenderer hrx = new TableCellRenderer() { + private JLabel lbl; + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + lbl = (JLabel) hr.getTableCellRendererComponent(table, value, true, true, row, column); + //lbl.setHorizontalAlignment(SwingConstants.LEFT); + + if (column == 0) + lbl.setHorizontalAlignment(SwingConstants.LEFT); + else + lbl.setHorizontalAlignment(SwingConstants.CENTER); + + lbl.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, AppUI.getColor10())); + lbl.setBorder(BorderFactory.createCompoundBorder(lbl.getBorder(), BorderFactory.createEmptyBorder(0, 6, 10, 0))); + + AppUI.setBackground(lbl, AppUI.getColor6()); + + return lbl; + } + }; + + //serial number table + + final JScrollPane scrollPane = AppUI.setupTable(table, new String[] {"Date", "From", "To", "SN", "Amount", "Memo"}, serials, r, hrx); + AppUI.setSize(scrollPane, 920, 325); - AppUI.getGBRow(subInnerCore, null, scrollPane, y, gridbag); - y++; + + // AppUI.getGBRow(subInnerCore, null, scrollPane, y, gridbag); + //y++; table.getColumnModel().getColumn(0).setPreferredWidth(120); - table.getColumnModel().getColumn(3).setPreferredWidth(10); - table.getColumnModel().getColumn(4).setPreferredWidth(10); - + table.getColumnModel().getColumn(5).setPreferredWidth(120); + // table.getColumnModel().getColumn(4).setPreferredWidth(10); + + rightPanel.add(scrollPane); + + JPanel subInnerCore = new JPanel(); + AppUI.alignLeft(subInnerCore); + AppUI.noOpaque(subInnerCore); + rightPanel.add(subInnerCore); + + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + + + + + + AppUI.GBPad(subInnerCore, y, gridbag); y++; - AppUI.getTwoButtonPanel(subInnerCore, "Print", "", new ActionListener() { + AppUI.getTwoButtonPanel(subInnerCore, "", "Print", null, new ActionListener() { public void actionPerformed(ActionEvent e) { try { table.print(); @@ -4953,7 +5020,7 @@ public void actionPerformed(ActionEvent e) { System.out.println("Failed to print"); } } - }, null, y, gridbag); + }, y, gridbag); resetState(); } @@ -5017,7 +5084,7 @@ public Component getTableCellRendererComponent(JTable table, Object value, boole //serial number table final JTable table = new JTable(); - final JScrollPane scrollPane = AppUI.setupTable(table, new String[] {"Serial Number", "Denomination"}, serials, r); + final JScrollPane scrollPane = AppUI.setupTable(table, new String[] {"Serial Number", "Denomination"}, serials, r, null); AppUI.setSize(scrollPane, 460, 285); AppUI.getGBRow(subInnerCore, null, scrollPane, y, gridbag); @@ -5321,7 +5388,7 @@ else if (column == 3) final JTable table = new JTable(); - final JScrollPane scrollPane = AppUI.setupTable(table, headers, trs, r); + final JScrollPane scrollPane = AppUI.setupTable(table, headers, trs, r, null); AppUI.alignLeft(scrollPane); diff --git a/src/advclient/AppUI.java b/src/advclient/AppUI.java index 58148d6..246cd8f 100644 --- a/src/advclient/AppUI.java +++ b/src/advclient/AppUI.java @@ -510,7 +510,8 @@ public static String getLocalFolderOption() { return "- Local Folder"; } - public static JScrollPane setupTable(JTable table, String[] columnNames, String[][] data, DefaultTableCellRenderer r) { + public static JScrollPane setupTable(JTable table, String[] columnNames, String[][] data, + DefaultTableCellRenderer r, TableCellRenderer hrr) { final String[] fcolumnNames = columnNames; DefaultTableModel model = new DefaultTableModel(data.length, data[0].length - 1) { @Override @@ -551,26 +552,29 @@ public boolean isCellEditable(int row, int column){ final TableCellRenderer hr = table.getTableHeader().getDefaultRenderer(); - header.setDefaultRenderer(new TableCellRenderer() { - private JLabel lbl; - @Override - public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { - lbl = (JLabel) hr.getTableCellRendererComponent(table, value, true, true, row, column); - //lbl.setHorizontalAlignment(SwingConstants.LEFT); + if (hrr != null) + header.setDefaultRenderer(hrr); + else + header.setDefaultRenderer(new TableCellRenderer() { + private JLabel lbl; + @Override + public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { + lbl = (JLabel) hr.getTableCellRendererComponent(table, value, true, true, row, column); + //lbl.setHorizontalAlignment(SwingConstants.LEFT); - if (column == 0 || column == 1) - lbl.setHorizontalAlignment(SwingConstants.LEFT); - else - lbl.setHorizontalAlignment(SwingConstants.RIGHT); + if (column == 0 || column == 1) + lbl.setHorizontalAlignment(SwingConstants.LEFT); + else + lbl.setHorizontalAlignment(SwingConstants.RIGHT); - lbl.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, AppUI.getColor10())); - lbl.setBorder(BorderFactory.createCompoundBorder(lbl.getBorder(), BorderFactory.createEmptyBorder(0, 6, 10, 0))); + lbl.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, AppUI.getColor10())); + lbl.setBorder(BorderFactory.createCompoundBorder(lbl.getBorder(), BorderFactory.createEmptyBorder(0, 6, 10, 0))); - AppUI.setBackground(lbl, AppUI.getColor6()); + AppUI.setBackground(lbl, AppUI.getColor6()); - return lbl; - } - }); + return lbl; + } + }); //This is the wallet table size diff --git a/src/advclient/ProgramState.java b/src/advclient/ProgramState.java index 2b55f27..383c644 100644 --- a/src/advclient/ProgramState.java +++ b/src/advclient/ProgramState.java @@ -63,6 +63,7 @@ public class ProgramState { final public static int SCREEN_SETTINGS_SAVED = 45; final public static int SCREEN_WARN_FRACKED_TO_SEND = 46; final public static int SCREEN_DEPOSIT_LEFTOVER = 47; + final public static int SCREEN_SHOW_SENT_COINS = 48; final static int CB_STATE_INIT = 1; diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index 98950b5..412d3a7 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -996,21 +996,21 @@ public static String calcCoinsFromFilenames(ArrayList files) { public static String getMS(int ms) { double dms = (double) ms / 1000; String s = String.format(Locale.US, "%.2f", dms); - + if (s.charAt(0) == '0') s = s.substring(1, s.length()); return s + " sec"; } - + public static String getRAIDAString(int idx) { String sidx; - + if (idx < 10) sidx = "0" + idx; else sidx = "" + idx; - + String[] countries = { "Australia", "Macedonia", @@ -1038,7 +1038,7 @@ public static String getRAIDAString(int idx) { "Germany", "Canada" }; - + if (idx > countries.length) { return sidx + " RAIDA"; } @@ -1068,7 +1068,7 @@ public static int getPassedCount(CloudCoin cc) { if (cc.getDetectStatus(i) == CloudCoin.STATUS_PASS) passed++; } - + cc.setPownStringFromDetectStatus(); logger.debug(ltag, "Passed count " + passed + " cc " + cc.sn + " pown=" + cc.getPownString()); @@ -1276,28 +1276,65 @@ public static int staleFiles(String user) { return 0; } - public static void appendSkySentCoinTransaction(String from, String to, int tosn, int amount, String memo) { + public static void appendSkySentCoinTransaction(String from, String to, int tosn, int amount, String memo) { String rMemo = memo.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll(",", " "); String fstr, result; String date = AppCore.getCurrentDate(); - - fstr = date + "," + from + "," + to + "," + tosn + "," + amount + "," +memo; - - String fileName = AppCore.getLogDir() + File.separator + Config.SENT_SKYCOINS_FILENAME; - result = AppCore.loadFile(fileName); - if (result == null) { - logger.debug(ltag, "Failed to open transactions file for SentCoins"); + + fstr = date + "," + from + "," + to + "," + tosn + "," + amount + "," +memo + ", closed"; + + String fileName = AppCore.getLogDir() + File.separator + Config.SENT_SKYCOINS_FILENAME; + logger.debug(ltag, "Append transaction: " + fstr + " s="+fileName); + + result = "\r\n" + fstr; + + if (!AppCore.saveFileAppend(fileName, result, true)) { + logger.debug(ltag, "Failed to write to the SkySent log. Maybe this file is open"); return; } + } - System.out.println("str=" +fstr); - logger.debug(ltag, "Append transaction: " + fstr + " s="+fileName); + public static void rmSentCoins() { + String fileName = AppCore.getLogDir() + File.separator + Config.SENT_SKYCOINS_FILENAME; + File f = new File(fileName); + f.delete(); + } + + public static String[][] getSentCoins() { + String fileName = AppCore.getLogDir() + File.separator + Config.SENT_SKYCOINS_FILENAME; + + String data = AppCore.loadFile(fileName); + if (data == null) + return null; + + String[] parts = data.split("\\r?\\n"); + + String[] tmp; + + int j = 0; + for (int i = 0; i < parts.length; i++) { + tmp = parts[i].split(","); + if (tmp.length != 7) { + continue; + } + j++; + } - result += "\r\n" + fstr; + int r = 0; + String[][] rv = new String[j][]; + for (int i = 0; i < parts.length; i++) { + tmp = parts[i].split(","); + if (tmp.length != 7) { + continue; + } - AppCore.saveFileAppend(fileName, result, true); + rv[r++] = tmp; + } + + return rv; } - + + public static boolean hasCoinExtension(File file) { String f = file.toString().toLowerCase(); if (f.endsWith(".stack") || f.endsWith(".jpg") || f.endsWith(".jpeg")) @@ -1306,5 +1343,5 @@ public static boolean hasCoinExtension(File file) { logger.debug(ltag, "Ignoring invalid extension " + file.toString()); return false; - } + } } From 6f76f5f95c5aa317158751fdb7ef3106917f8930 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Tue, 31 Dec 2019 11:58:11 +0300 Subject: [PATCH 121/160] stack --- src/advclient/AdvancedClient.java | 15 +++++++++++++++ src/advclient/ProgramState.java | 2 ++ src/advclient/common/Unpacker/Unpacker.java | 1 + src/advclient/common/Unpacker/UnpackerResult.java | 2 ++ 4 files changed, 20 insertions(+) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 261f3a7..445cdb7 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -2017,6 +2017,7 @@ public void showImportDoneScreen() { String totalBankValue = AppCore.formatNumber(ps.statToBankValue); String totalFailedValue = AppCore.formatNumber(ps.statFailedValue); String totalLostValue = AppCore.formatNumber(ps.statLostValue); + String totalFailedFiles = AppCore.formatNumber(ps.failedFiles); fname = AppUI.wrapDiv("Deposited " + total + " CloudCoins to " + ps.dstWallet.getName() + " "); @@ -2045,6 +2046,13 @@ public void showImportDoneScreen() { y++; } + if (ps.failedFiles > 0) { + fname = new JLabel("Corrupted files:"); + value = new JLabel(totalFailedFiles); + AppUI.getGBRow(subInnerCore, fname, value, y, gridbag); + y++; + } + AppUI.GBPad(subInnerCore, y, gridbag); y++; @@ -3976,6 +3984,12 @@ public void actionPerformed(ActionEvent e) { new FileDrop(null, ddPanel, new FileDrop.Listener() { public void filesDropped( java.io.File[] files ) { for( int i = 0; i < files.length; i++ ) { + if (!AppCore.hasCoinExtension(files[i])) { + ps.errText = "File must have .jpeg or .stack extension"; + showScreen(); + return; + } + ps.files.add(files[i].getAbsolutePath()); } @@ -6797,6 +6811,7 @@ public void run() { } ps.duplicates = ur.duplicates; + ps.failedFiles = ur.failedFiles; //setRAIDAProgress(0, 0, AppCore.getFilesCount(Config.DIR_SUSPECT, sm.getActiveWallet().getName())); setRAIDAProgressCoins(0, 0, 0); diff --git a/src/advclient/ProgramState.java b/src/advclient/ProgramState.java index 383c644..af45788 100644 --- a/src/advclient/ProgramState.java +++ b/src/advclient/ProgramState.java @@ -157,6 +157,8 @@ public class ProgramState { int rrAmount; + int failedFiles; + public ProgramState() { currentScreen = SCREEN_AGREEMENT; cwalletRecoveryRequested = cwalletPasswordRequested = false; diff --git a/src/advclient/common/Unpacker/Unpacker.java b/src/advclient/common/Unpacker/Unpacker.java index 980c585..5580c80 100644 --- a/src/advclient/common/Unpacker/Unpacker.java +++ b/src/advclient/common/Unpacker/Unpacker.java @@ -147,6 +147,7 @@ public void doUnpack() { if (!rv) { logger.error(ltag, "Error processing file: " + fileName); AppCore.moveToTrash(file.toString(), user); + globalResult.failedFiles++; continue; } } diff --git a/src/advclient/common/Unpacker/UnpackerResult.java b/src/advclient/common/Unpacker/UnpackerResult.java index aa22971..07544d4 100644 --- a/src/advclient/common/Unpacker/UnpackerResult.java +++ b/src/advclient/common/Unpacker/UnpackerResult.java @@ -24,10 +24,12 @@ public class UnpackerResult { public ArrayList duplicates; public int status; + public int failedFiles; public UnpackerResult() { status = STATUS_PROCESSING; duplicates = new ArrayList(); + failedFiles = 0; } } From c22fee8a2628e67fe9df06c02c72da2646980c16 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 1 Jan 2020 11:06:54 +0300 Subject: [PATCH 122/160] sent --- src/advclient/AdvancedClient.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 445cdb7..1a3e5c6 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -7363,6 +7363,10 @@ public void run() { if (sr.amount > 0) { wl.debug(ltag, "sramount " + sr.amount + " typed " + ps.typedAmount); + + AppCore.appendSkySentCoinTransaction(ps.srcWallet.getName(), + ps.dstWallet.getName(), ps.dstWallet.getIDCoin().sn, sr.amount, ps.typedMemo); + if (ps.typedAmount != sr.amount) { ps.typedAmount = sr.amount; ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; From 415d89a1a75ddcfc705e85449984e2a6d4598221 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 9 Jan 2020 11:15:33 +0300 Subject: [PATCH 123/160] errmsg --- src/advclient/AdvancedClient.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 445cdb7..d9438a8 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -57,7 +57,7 @@ * */ public class AdvancedClient { - String version = "2.1.25"; + String version = "2.1.26"; JPanel headerPanel; JPanel mainPanel; @@ -1303,7 +1303,8 @@ public void showEchoRAIDAFinishedScreen() { y++; String txt = "TIMED OUT means the response exceeded the " + Config.ECHO_TIMEOUT / 1000 + " seconds allowed. " + "This could be caused by a slow network or because the RAIDA was blocked (usually by office routers). " - + "Try changing your settings to increase the Timeout."; + + "It could also be caused by your computer being old and unable to handle 25 threads at once. " + + "Try changing your settings to increase the Timeout. Or try using a more powerful computer."; x = AppUI.wrapDiv(txt); AppUI.setCommonFont(x); From f7289cfafcbd899adeadcd212b347d299c1d6660 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 9 Jan 2020 11:38:13 +0300 Subject: [PATCH 124/160] Record counterfeit and failed coins --- src/advclient/AdvancedClient.java | 13 +++++++++++-- src/advclient/common/core/Config.java | 3 ++- src/advclient/common/core/Wallet.java | 3 +++ 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 4745c09..8bb5745 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -6905,9 +6905,9 @@ public void callback(Object result) { ps.statFailed = gr.totalCounterfeit; ps.statLost = gr.totalLost + gr.totalUnchecked; ps.receiptId = gr.receiptId; - + + Wallet w = sm.getActiveWallet(); if (ps.statToBankValue != 0) { - Wallet w = sm.getActiveWallet(); Wallet wsrc = ps.srcWallet; if (wsrc != null && wsrc.isSkyWallet()) { wl.debug(ltag, "Appending sky transactions"); @@ -6945,6 +6945,15 @@ public void callback(Object result) { } else { w.appendTransaction(ps.typedMemo, ps.statToBankValue, ps.receiptId); } + } else { + // StatToBank == 0 + String memo = ""; + if (ps.statFailedValue > 0) { + memo = AppCore.formatNumber(ps.statFailedValue) + " Counterfeit"; + } else { + memo = "Failed to Import"; + } + w.appendTransaction(memo, Config.NEGATIVE_AMOUNT_FOR_COUNTERFEIT, "dummy"); } EventQueue.invokeLater(new Runnable() { diff --git a/src/advclient/common/core/Config.java b/src/advclient/common/core/Config.java index 1a0ddc1..e1d8ed1 100644 --- a/src/advclient/common/core/Config.java +++ b/src/advclient/common/core/Config.java @@ -189,5 +189,6 @@ public class Config { public static int MAX_EXPORTED_NOTES = 3000; final public static String SENT_SKYCOINS_FILENAME = "sentcoins.csv"; - + + final public static int NEGATIVE_AMOUNT_FOR_COUNTERFEIT = -1; } diff --git a/src/advclient/common/core/Wallet.java b/src/advclient/common/core/Wallet.java index 82f2743..7332735 100644 --- a/src/advclient/common/core/Wallet.java +++ b/src/advclient/common/core/Wallet.java @@ -214,6 +214,9 @@ public void appendTransaction(String memo, int amount, String receiptId, String if (amount == 0) return; + if (amount == Config.NEGATIVE_AMOUNT_FOR_COUNTERFEIT) + amount = 0; + String fileName = getTransactionsFileName(); String rMemo = memo.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll(",", " "); //String sAmount = Integer.toString(amount); From 0cedb88fb96c04839ff191e5fbc72542fce201b2 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 9 Jan 2020 11:51:28 +0300 Subject: [PATCH 125/160] validate memo loosely --- src/advclient/common/core/Validator.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/advclient/common/core/Validator.java b/src/advclient/common/core/Validator.java index cc64020..5591c02 100644 --- a/src/advclient/common/core/Validator.java +++ b/src/advclient/common/core/Validator.java @@ -39,7 +39,7 @@ public static boolean memoLength(String tag) { } public static boolean memo(String tag) { - Pattern p = Pattern.compile("[\\w ]+", Pattern.UNICODE_CHARACTER_CLASS); + Pattern p = Pattern.compile("[-_=\\.\\w ]+", Pattern.UNICODE_CHARACTER_CLASS); Matcher m = p.matcher(tag); return m.matches(); From 2bdd4fe5f7a8f91a397036c0e690ce9544a7b352 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 9 Jan 2020 13:33:14 +0300 Subject: [PATCH 126/160] List serials in dir --- src/advclient/AdvancedClient.java | 89 +++++++++++++++++++++++--- src/advclient/common/core/AppCore.java | 48 ++++++++++++++ 2 files changed, 128 insertions(+), 9 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 8bb5745..bacd6e7 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -4435,8 +4435,53 @@ public void showListSerialsScreen() { final RoundedCornerComboBox cboxfrom = new RoundedCornerComboBox(AppUI.getColor6(), "Make Selection", rv.options); cboxfrom.setDefault(null); AppUI.getGBRow(subInnerCore, fname, cboxfrom.getComboBox(), y, gridbag); + cboxfrom.addOption(AppUI.getLocalFolderOption()); y++; + final JLabel lfText = new JLabel("Local folder"); + final JFileChooser chooser = new JFileChooser(); + chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + chooser.setAcceptAllFileFilterUsed(false); + + final MyTextField localFolder = new MyTextField("Select Folder", false, true); + localFolder.setFilepickerListener(new MouseAdapter() { + @Override + public void mouseReleased(MouseEvent e) { + if (!Config.DEFAULT_EXPORT_DIR.isEmpty()) + chooser.setCurrentDirectory(new File(Config.DEFAULT_EXPORT_DIR)); + + int returnVal = chooser.showOpenDialog(null); + if (returnVal == JFileChooser.APPROVE_OPTION) { + ps.chosenFile = chooser.getSelectedFile().getAbsolutePath(); + localFolder.setData(chooser.getSelectedFile().getName()); + } + } + }); + AppUI.getGBRow(subInnerCore, lfText, localFolder.getTextField(), y, gridbag); + y++; + + + localFolder.getTextField().setVisible(false); + lfText.setVisible(false); + + + cboxfrom.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + int dstIdx = cboxfrom.getSelectedIndex() - 1; + + localFolder.getTextField().setVisible(false); + lfText.setVisible(false); + + // Remote Wallet + if (dstIdx == rv.idxs.length) { + localFolder.getTextField().setVisible(true); + lfText.setVisible(true); + return; + } + + } + }); + AppUI.GBPad(subInnerCore, y, gridbag); y++; @@ -4447,7 +4492,13 @@ public void actionPerformed(ActionEvent e) { } }, new ActionListener() { public void actionPerformed(ActionEvent e) { - int srcIdx = cboxfrom.getSelectedIndex() - 1; + int srcIdx = cboxfrom.getSelectedIndex() - 1; + if (srcIdx == rv.idxs.length) { + ps.currentScreen = ProgramState.SCREEN_LIST_SERIALS_DONE; + showScreen(); + return; + } + if (srcIdx < 0 || srcIdx >= rv.idxs.length) { ps.errText = "Please select Wallet"; showScreen(); @@ -5049,18 +5100,38 @@ public void showListSerialsDone() { GridBagLayout gridbag = new GridBagLayout(); subInnerCore.setLayout(gridbag); - final Wallet w = ps.srcWallet; - int[] sns = w.getSNs(); - if (sns.length == 0) { - fname = new JLabel("No Serials"); + final Wallet w = ps.srcWallet; + int[] sns; + + if (w != null) { + sns = w.getSNs(); + if (sns.length == 0) { + fname = new JLabel("No Serials"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + return; + } + + fname = AppUI.wrapDiv("Wallet " + w.getName() + " - " + w.getTotal() + " CC"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + } else if (ps.chosenFile == null) { + fname = new JLabel("No Folder or Wallet chosen"); AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); return; + } else { + CloudCoin[] ccs = AppCore.getCoinsInDir(ps.chosenFile); + if (ccs == null) { + fname = new JLabel("Failed to read folder " + ps.chosenFile); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + return; + } + + sns = new int[ccs.length]; + for (int i = 0; i < ccs.length; i++) { + sns[i] = ccs[i].sn; + } } - fname = AppUI.wrapDiv("Wallet " + w.getName() + " - " + w.getTotal() + " CC"); - AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); - y++; - // Scrollbar & Table DefaultTableCellRenderer r = new DefaultTableCellRenderer() { diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index 412d3a7..9d75bac 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -1344,4 +1344,52 @@ public static boolean hasCoinExtension(File file) { return false; } + + public static CloudCoin[] getCoinsInDir(String dir) { + File dirObj = new File(dir); + if (!dirObj.exists()) { + return null; + } + + int c = 0; + for (File file: dirObj.listFiles()) { + if (file.isDirectory()) + continue; + + if (!AppCore.hasCoinExtension(file)) + continue; + + CloudCoin cc; + try { + cc = new CloudCoin(file.getAbsolutePath()); + } catch (JSONException e) { + continue; + } + + c++; + } + + int i = 0; + CloudCoin[] ccs = new CloudCoin[c]; + for (File file: dirObj.listFiles()) { + if (file.isDirectory()) + continue; + + if (!AppCore.hasCoinExtension(file)) + continue; + + CloudCoin cc; + try { + cc = new CloudCoin(file.getAbsolutePath()); + } catch (JSONException e) { + continue; + } + + ccs[i] = cc; + i++; + } + + return ccs; + } + } From b1131c3fbed2fcd2c3a937f271cf4141df9aa616 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 10 Jan 2020 12:55:17 +0300 Subject: [PATCH 127/160] export save default dir --- src/advclient/AdvancedClient.java | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index bacd6e7..f9eb789 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -2123,6 +2123,7 @@ public void showSettingsScreen() { ddnsServer.setData(Config.DDNSSN_SERVER); y++; + /* fname = new JLabel("Export Folder"); final JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); @@ -2146,6 +2147,7 @@ public void mouseReleased(MouseEvent e) { localFolder.setData(new File(Config.DEFAULT_EXPORT_DIR).getAbsolutePath()); AppUI.getGBRow(subInnerCore, fname, localFolder.getTextField(), y, gridbag); y++; + */ AppUI.GBPad(subInnerCore, y, gridbag); y++; @@ -2218,7 +2220,7 @@ public void actionPerformed(ActionEvent e) { } Config.DDNSSN_SERVER = ddnssn; - Config.DEFAULT_EXPORT_DIR = ps.chosenFile; + //Config.DEFAULT_EXPORT_DIR = ps.chosenFile; Config.DEFAULT_MAX_COINS_MULTIDETECT = notes; Config.FIX_FRACKED_TIMEOUT = fixt * 1000; Config.MULTI_DETECT_TIMEOUT = detectt * 1000; @@ -3272,13 +3274,17 @@ public void showTransferScreen() { remoteWalledId.getTextField().setVisible(false); rwText.setVisible(false); + if (ps.chosenFile.isEmpty()) + ps.chosenFile = Config.DEFAULT_EXPORT_DIR; final JLabel lfText = new JLabel("Local folder"); final JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); chooser.setAcceptAllFileFilterUsed(false); + final MyTextField localFolder = new MyTextField("Select Folder", false, true); + localFolder.setData(new File(ps.chosenFile).getName()); localFolder.setFilepickerListener(new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { @@ -3289,6 +3295,8 @@ public void mouseReleased(MouseEvent e) { if (returnVal == JFileChooser.APPROVE_OPTION) { ps.chosenFile = chooser.getSelectedFile().getAbsolutePath(); localFolder.setData(chooser.getSelectedFile().getName()); + Config.DEFAULT_EXPORT_DIR = ps.chosenFile; + AppCore.writeConfig(); } } }); @@ -3549,6 +3557,11 @@ public void actionPerformed(ActionEvent e) { return; } } else if (dstIdx == rvTo.idxs.length + 1) { + if (ps.typedMemo.isEmpty()) { + ps.errText = "Memo cannot be empty"; + showScreen(); + return; + } if (!Validator.memo(ps.typedMemo)) { ps.errText = "Memo: special characters not allowed! Use numbers and letters only"; showScreen(); From cf23a9ccd357e968fd7569f95cde5b60161cf293 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 13 Jan 2020 10:42:27 +0300 Subject: [PATCH 128/160] icon color --- src/advclient/AdvancedClient.java | 2 +- src/advclient/AppUI.java | 13 +++++++++++++ src/advclient/MyTextField.java | 10 ++++++---- src/advclient/RoundedCornerComboBox.java | 4 +++- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index f9eb789..ad07a01 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -57,7 +57,7 @@ * */ public class AdvancedClient { - String version = "2.1.26"; + String version = "2.1.27"; JPanel headerPanel; JPanel mainPanel; diff --git a/src/advclient/AppUI.java b/src/advclient/AppUI.java index 246cd8f..a1b52be 100644 --- a/src/advclient/AppUI.java +++ b/src/advclient/AppUI.java @@ -24,6 +24,7 @@ import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.font.TextAttribute; +import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.io.InputStream; @@ -778,4 +779,16 @@ public static void addInvItem(JComponent parent, String denomination, int count) parent.add(invItem); } + public static void invertImage(BufferedImage img) { + for (int x = 0; x < img.getWidth(); x++) { + for (int y = 0; y < img.getHeight(); y++) { + int rgba = img.getRGB(x, y); + Color col = new Color(rgba, true); + col = new Color(255 - col.getRed(), + 255 - col.getGreen(), + 255 - col.getBlue(), col.getAlpha()); + img.setRGB(x, y, col.getRGB()); + } + } + } } diff --git a/src/advclient/MyTextField.java b/src/advclient/MyTextField.java index 4dc0d3f..c7ac421 100644 --- a/src/advclient/MyTextField.java +++ b/src/advclient/MyTextField.java @@ -109,9 +109,10 @@ public void focusLost(FocusEvent e) { if (isPassword) { tf.hide(); try { - Image img; + BufferedImage img; - img = ImageIO.read(getClass().getClassLoader().getResource("resources/eye.png")); + img = ImageIO.read(getClass().getClassLoader().getResource("resources/eye.png")); + AppUI.invertImage(img); imgEye = new ImageIcon(img); } catch (Exception ex) { @@ -130,9 +131,10 @@ public void mouseReleased(MouseEvent e) { AppUI.setHandCursor(label); } else if (isFilepicker) { try { - Image img; + BufferedImage img; - img = ImageIO.read(getClass().getClassLoader().getResource("resources/lg0.png")); + img = ImageIO.read(getClass().getClassLoader().getResource("resources/lg0.png")); + AppUI.invertImage(img); imgEye = new ImageIcon(img); } catch (Exception ex) { diff --git a/src/advclient/RoundedCornerComboBox.java b/src/advclient/RoundedCornerComboBox.java index 8912248..977d3bd 100644 --- a/src/advclient/RoundedCornerComboBox.java +++ b/src/advclient/RoundedCornerComboBox.java @@ -7,6 +7,7 @@ import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.geom.*; +import java.awt.image.BufferedImage; import java.util.*; import javax.accessibility.*; import javax.imageio.ImageIO; @@ -382,7 +383,8 @@ protected JButton createArrowButton() { //button.setBounds(100,100,100,100); try { - Image img = ImageIO.read(getClass().getClassLoader().getResource("resources/arrow.png")); + BufferedImage img = ImageIO.read(getClass().getClassLoader().getResource("resources/arrow.png")); + AppUI.invertImage(img); button.setIcon(new ImageIcon(img)); button.setForeground(background); button.setText(" "); From 17e2aa99d9c636dee8d2f7f359a8667bac0d489e Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 13 Jan 2020 13:13:49 +0300 Subject: [PATCH 129/160] export keys --- src/advclient/AdvancedClient.java | 140 +++++++++++++++++++++++++++++- src/advclient/ProgramState.java | 2 + 2 files changed, 141 insertions(+), 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index ad07a01..5932708 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -667,7 +667,7 @@ public void paintComponent(final Graphics g) { }; String[] items = {"Backup", "List serials", "Clear History", "Fix Fracked", - "Delete Wallet", "Show Folders", "Echo RAIDA", "Settings", "Sent Coins"}; + "Delete Wallet", "Show Folders", "Echo RAIDA", "Settings", "Sent Coins", "Export Keys"}; for (int i = 0; i < items.length; i++) { JMenuItem menuItem = new JMenuItem(items[i]); menuItem.setActionCommand("" + i); @@ -727,6 +727,8 @@ public void mouseReleased(MouseEvent evt) { ps.currentScreen = ProgramState.SCREEN_SETTINGS; } else if (action.equals("8")) { ps.currentScreen = ProgramState.SCREEN_SHOW_SENT_COINS; + } else if (action.equals("9")) { + ps.currentScreen = ProgramState.SCREEN_SHOW_BACKUP_KEYS; } showScreen(); @@ -1019,6 +1021,13 @@ public void showScreen() { case ProgramState.SCREEN_SHOW_SENT_COINS: showSentCoins(); break; + case ProgramState.SCREEN_SHOW_BACKUP_KEYS: + showBackupKeys(); + break; + case ProgramState.SCREEN_SHOW_BACKUP_KEYS_DONE: + showBackupKeysDone(); + break; + } if (lwrapperPanel != null) { @@ -1848,6 +1857,60 @@ public void actionPerformed(ActionEvent e) { } + public void showBackupKeysDone() { + boolean isError = !ps.errText.equals(""); + JPanel subInnerCore; + + if (isError) { + subInnerCore = getPanel("Error"); + resetState(); + return; + } + + int y = 0; + JLabel fname, value; + MyTextField walletName = null; + + subInnerCore = getPanel("Export Complete"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + fname = AppUI.wrapDiv("Your ID keys have been backed up into:"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + + final String fdir = ps.chosenFile; + JLabel sl = AppUI.getHyperLink(fdir, "javascript:void(0); return false", 20); + sl.addMouseListener(new MouseAdapter() { + public void mouseReleased(MouseEvent e) { + if (!Desktop.isDesktopSupported()) + return; + try { + Desktop.getDesktop().open(new File(fdir)); + } catch (IOException ie) { + wl.error(ltag, "Failed to open browser: " + ie.getMessage()); + } + } + }); + + AppUI.getGBRow(subInnerCore, null, sl, y, gridbag); + AppUI.setColor(sl, AppUI.getColor2()); + AppUI.underLine(sl); + y++; + + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + AppUI.getTwoButtonPanel(subInnerCore, "", "Continue", null, new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, y, gridbag); + + } + public void showBackupDoneScreen() { boolean isError = !ps.errText.equals(""); JPanel subInnerCore; @@ -4818,6 +4881,81 @@ public void actionPerformed(ActionEvent e) { }, y, gridbag); } + public void showBackupKeys() { + int y = 0; + JLabel fname; + MyTextField walletName = null; + + JPanel subInnerCore = getPanel("Export Keys"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + String[] idCoins = AppCore.getFilesInDir(AppCore.getIDDir(), null); + if (idCoins.length == 0) { + fname = new JLabel("You have no keys to backup"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + AppUI.GBPad(subInnerCore, y, gridbag); + return; + } + + fname = new JLabel("Keys will not be encrypted. You should put them in a secure location"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + + fname = new JLabel("Backup Folder"); + final JFileChooser chooser = new JFileChooser(); + chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + chooser.setAcceptAllFileFilterUsed(false); + final MyTextField tf1 = new MyTextField("", false, true); + tf1.disable(); + tf1.setFilepickerListener(new MouseAdapter() { + @Override + public void mouseReleased(MouseEvent e) { + int returnVal = chooser.showOpenDialog(null); + if (returnVal == JFileChooser.APPROVE_OPTION) { + ps.chosenFile = chooser.getSelectedFile().getAbsolutePath(); + tf1.setData(chooser.getSelectedFile().getName()); + } + } + }); + + AppUI.getGBRow(subInnerCore, fname, tf1.getTextField(), y, gridbag); + y++; + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { + public void actionPerformed(ActionEvent e) { + if (ps.chosenFile.isEmpty()) { + ps.errText = "Folder is not chosen"; + showScreen(); + return; + } + + for (int i = 0; i < idCoins.length; i++) { + String src = AppCore.getIDDir() + File.separator + idCoins[i]; + String dst = ps.chosenFile + File.separator + idCoins[i]; + + if (!AppCore.copyFile(src, dst)) { + ps.errText = "Failed to copy file: " + idCoins[i]; + showScreen(); + return; + } + } + + ps.currentScreen = ProgramState.SCREEN_SHOW_BACKUP_KEYS_DONE; + showScreen(); + } + }, y, gridbag); + } + public void showBackupScreen() { int y = 0; JLabel fname; diff --git a/src/advclient/ProgramState.java b/src/advclient/ProgramState.java index af45788..16b76de 100644 --- a/src/advclient/ProgramState.java +++ b/src/advclient/ProgramState.java @@ -64,6 +64,8 @@ public class ProgramState { final public static int SCREEN_WARN_FRACKED_TO_SEND = 46; final public static int SCREEN_DEPOSIT_LEFTOVER = 47; final public static int SCREEN_SHOW_SENT_COINS = 48; + final public static int SCREEN_SHOW_BACKUP_KEYS = 49; + final public static int SCREEN_SHOW_BACKUP_KEYS_DONE = 50; final static int CB_STATE_INIT = 1; From d089d14fed4bd235f4c5f48e5690b456ae5d85a4 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Tue, 14 Jan 2020 11:26:19 +0300 Subject: [PATCH 130/160] cloudcoin domain bugfix --- src/advclient/common/core/ServantManager.java | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index e513167..c08e768 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -182,9 +182,10 @@ public void initWallets() { public void checkIDCoins() { String[] idCoins = AppCore.getFilesInDir(AppCore.getIDDir(), null); + String coinExt = ".stack"; for (int i = 0; i < idCoins.length; i++) { - if (!idCoins[i].endsWith(".stack")) { + if (!idCoins[i].endsWith(coinExt)) { logger.info(ltag, "Skipping non-stack file in the ID folder: " + idCoins[i]); continue; } @@ -199,13 +200,13 @@ public void checkIDCoins() { int dots = 0; - String wname = idCoins[i].substring(0, idCoins[i].indexOf('.')); + String wname = idCoins[i].substring(0, idCoins[i].length() - coinExt.length()); for (int y = 0; y < wname.length(); y++) { if (wname.charAt(y) == '.') dots++; } - if (dots <= 2) + if (dots < 2) wname += "." + Config.DDNS_DOMAIN; initCloudWallet(cc, wname); @@ -1156,16 +1157,10 @@ public Wallet getWalletByName(String walletName) { Collection c = wallets.values(); Iterator itr = c.iterator(); - while (itr.hasNext()) { + while (itr.hasNext()) { Wallet tw = (Wallet) itr.next(); if (tw.getName().equals(walletName)) - return tw; - - if (tw.isSkyWallet()) { - String name = tw.getName() + "." + Config.DDNS_DOMAIN; - if (name.equals(walletName)) - return tw; - } + return tw; } return null; From 0fc6037f8b582c434cee5ae1701dc447b151dc4c Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Tue, 14 Jan 2020 13:26:40 +0300 Subject: [PATCH 131/160] setcounters reordering --- src/advclient/AdvancedClient.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 5932708..2c0a5bd 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -3200,8 +3200,8 @@ public void callback(Object o) { AppCore.getTotal(counters[Config.IDX_FOLDER_FRACKED]) + AppCore.getTotal(counters[Config.IDX_FOLDER_VAULT]); - walletSetTotal(w, totalCnt); w.setCounters(counters); + walletSetTotal(w, totalCnt); setTotalCoins(); wl.debug(ltag, "ShowEnvelopeCoins return"); @@ -3219,8 +3219,8 @@ public void callback(Object o) { AppCore.getTotal(counters[Config.IDX_FOLDER_FRACKED]) + AppCore.getTotal(counters[Config.IDX_FOLDER_VAULT]); - walletSetTotal(w, totalCnt); w.setCounters(counters); + walletSetTotal(w, totalCnt); setTotalCoins(); } }); From 718de9801f15c3ec670cfe6882932484b8687526 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Tue, 14 Jan 2020 13:48:31 +0300 Subject: [PATCH 132/160] prevent hanging if send error --- src/advclient/AdvancedClient.java | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 2c0a5bd..8d34910 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -7600,10 +7600,15 @@ public void run() { ps.dstWallet.getName(), ps.dstWallet.getIDCoin().sn, sr.amount, ps.typedMemo); if (ps.typedAmount != sr.amount) { - ps.typedAmount = sr.amount; - ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; - ps.errText = "Not all coins were sent. Please check the logs"; - showScreen(); + EventQueue.invokeLater(new Runnable() { + public void run() { + ps.typedAmount = sr.amount; + ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; + ps.errText = "Not all coins were sent. Please check the logs"; + showScreen(); + return; + } + }); return; } From d6e8ac9d0d7cae69ef354b26e4e7e187e93d51c6 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Tue, 14 Jan 2020 15:48:19 +0300 Subject: [PATCH 133/160] show_envs add cancel point --- .../common/ShowEnvelopeCoins/ShowEnvelopeCoins.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java b/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java index 43691aa..f03b15d 100644 --- a/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java +++ b/src/advclient/common/ShowEnvelopeCoins/ShowEnvelopeCoins.java @@ -152,6 +152,12 @@ public void doShowSkyCoins(int sn) { logger.debug(ltag, "Wallet " + sn + " raida" + i + " coin#" + j + " sn=" +rsn + " t=" + tag + " ts="+ts); } } + + if (isCancelled()) { + result.status = ShowEnvelopeCoinsResult.STATUS_CANCELLED; + logger.error(ltag, "ShowCoins cancelled p. 2"); + return; + } int vsns[] = AppCore.getSNSOverlap(sns); if (vsns == null) { From 1289cfb909ecfcf9912b9984a7242ba5ae6ae8c8 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Sat, 18 Jan 2020 14:47:50 +0300 Subject: [PATCH 134/160] bill pay dark --- src/advclient/AdvancedClient.java | 274 ++++++++++++++++++++++++- src/advclient/ProgramState.java | 8 + src/advclient/common/core/AppCore.java | 32 +++ 3 files changed, 311 insertions(+), 3 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 8d34910..08a1409 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -57,7 +57,7 @@ * */ public class AdvancedClient { - String version = "2.1.27"; + String version = "2.1.28"; JPanel headerPanel; JPanel mainPanel; @@ -667,7 +667,7 @@ public void paintComponent(final Graphics g) { }; String[] items = {"Backup", "List serials", "Clear History", "Fix Fracked", - "Delete Wallet", "Show Folders", "Echo RAIDA", "Settings", "Sent Coins", "Export Keys"}; + "Delete Wallet", "Show Folders", "Echo RAIDA", "Settings", "Sent Coins", "Export Keys", "Bill Pay"}; for (int i = 0; i < items.length; i++) { JMenuItem menuItem = new JMenuItem(items[i]); menuItem.setActionCommand("" + i); @@ -729,7 +729,9 @@ public void mouseReleased(MouseEvent evt) { ps.currentScreen = ProgramState.SCREEN_SHOW_SENT_COINS; } else if (action.equals("9")) { ps.currentScreen = ProgramState.SCREEN_SHOW_BACKUP_KEYS; - } + } else if (action.equals("10")) { + ps.currentScreen = ProgramState.SCREEN_SHOW_BILL_PAY; + } showScreen(); } @@ -1027,6 +1029,13 @@ public void showScreen() { case ProgramState.SCREEN_SHOW_BACKUP_KEYS_DONE: showBackupKeysDone(); break; + case ProgramState.SCREEN_SHOW_BILL_PAY: + showBillPayScreen(); + break; + case ProgramState.SCREEN_SHOW_CONFIRM_BILL_PAY: + showConfirmBillPay(); + break; + } @@ -2733,6 +2742,104 @@ public void run() { }, y, gridbag); } + public void showConfirmBillPay() { + int y = 0; + JLabel fname, value; + MyTextField walletName = null; + + JPanel subInnerCore = getPanel("Bill Pay Confirmation"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + //fname = AppUI.wrapDiv("Deposited " + total + " CloudCoins to " + ps.dstWallet.getName() + " "); + JLabel fromLabel = new JLabel("From: "); + JLabel fromValue = new JLabel(ps.srcWallet.getName()); + AppUI.getGBRow(subInnerCore, fromLabel, fromValue, y, gridbag); + y++; + + + String v = ""; + for (int i = 0; i < ps.billpays.length; i++) { + v += "

" + ps.billpays[i][0] + ": " + ps.billpays[i][1] + ": " + ps.billpays[i][1] + ": " + ps.billpays[i][2] + " : " + ps.billpays[i][3] + " : " + ps.billpays[i][4] + + ps.billpays[i][5] + ": " + ps.billpays[i][6] + ": " + ps.billpays[i][7] + " : " + ps.billpays[i][8] + "


"; + } + v+=""; + JLabel x = new JLabel(v); + AppUI.noOpaque(x); + + JPanel jp = new JPanel(); + jp.add(x); + AppUI.noOpaque(jp); + JScrollBar scrollBar = new JScrollBar(JScrollBar.VERTICAL) { + @Override + public boolean isVisible() { + return true; + } + }; + + JScrollPane scrollPane = new JScrollPane(jp); + scrollPane.setVerticalScrollBar(scrollBar); + scrollPane.getVerticalScrollBar().setUnitIncrement(42); + scrollPane.getViewport().setOpaque(false); + scrollPane.setOpaque(false); + scrollPane.setBorder(BorderFactory.createEmptyBorder()); + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + AppUI.setSize(scrollPane, 800, 280); + + AppUI.getGBRow(subInnerCore, null, scrollPane, y, gridbag); + y++; + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Confirm", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.srcWallet.setPassword(ps.typedSrcPassword); + + sm.setActiveWalletObj(ps.srcWallet); + if (ps.sendType == ProgramState.SEND_TYPE_FOLDER) { + ps.isSkyDeposit = false; + ps.currentScreen = ProgramState.SCREEN_EXPORTING; + if (ps.srcWallet.isEncrypted()) { + sm.startSecureExporterService(Config.TYPE_STACK, ps.typedAmount, ps.typedMemo, ps.chosenFile, false, new ExporterCb()); + } else { + sm.startExporterService(Config.TYPE_STACK, ps.typedAmount, ps.typedMemo, ps.chosenFile, false, new ExporterCb()); + } + showScreen(); + } else if (ps.sendType == ProgramState.SEND_TYPE_WALLET) { + ps.dstWallet.setPassword(ps.typedDstPassword); + ps.currentScreen = ProgramState.SCREEN_SENDING; + if (ps.srcWallet.isSkyWallet()) { + ps.isSkyDeposit = true; + } else { + ps.isSkyDeposit = false; + } + showScreen(); + } else if (ps.sendType == ProgramState.SEND_TYPE_REMOTE) { + DNSSn d = new DNSSn(ps.typedRemoteWallet, null, wl); + int sn = d.getSN(); + if (sn < 0) { + ps.errText = "Failed to query receiver. Check that the name is valid"; + ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; + showScreen(); + return; + } + + ps.foundSN = sn; + ps.isSkyDeposit = false; + ps.currentScreen = ProgramState.SCREEN_SENDING; + showScreen(); + } + } + }, y, gridbag); + + } + public void showConfirmTransferScreen() { int y = 0; JLabel fname, value; @@ -3278,6 +3385,167 @@ public String getNonEmptyFolderError(String folder) { + "Please click cancel below to reset. Then deposit them again.").getText(); } + public void showBillPayScreen() { + int y = 0; + JLabel fname; + MyTextField walletName = null; + + JPanel subInnerCore = getPanel("Bill Pay"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + final optRv rvFrom = setOptionsForWalletsCommon(false, false, true, null); + if (rvFrom.idxs.length == 0) { + fname = AppUI.wrapDiv("No Wallets"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + AppUI.GBPad(subInnerCore, y, gridbag); + return; + } + + fname = new JLabel("From"); + final RoundedCornerComboBox cboxfrom = new RoundedCornerComboBox(AppUI.getColor6(), "Make Selection", rvFrom.options); + AppUI.getGBRow(subInnerCore, fname, cboxfrom.getComboBox(), y, gridbag); + y++; + + final JLabel spText = new JLabel("Password"); + final MyTextField passwordSrc = new MyTextField("Wallet Password", true); + AppUI.getGBRow(subInnerCore, spText, passwordSrc.getTextField(), y, gridbag); + y++; + + passwordSrc.getTextField().setVisible(false); + spText.setVisible(false); + + final JLabel lfText = new JLabel("CSV File"); + final JFileChooser chooser = new JFileChooser(); + chooser.setAcceptAllFileFilterUsed(false); + + + final MyTextField localFolder = new MyTextField("CSV File", false, true); + chooser.setFileSelectionMode(JFileChooser.FILES_ONLY); + localFolder.setData(new File(ps.chosenFile).getName()); + FileNameExtensionFilter filter = new FileNameExtensionFilter("CloudCoins", "csv"); + chooser.setFileFilter(filter); + + localFolder.setFilepickerListener(new MouseAdapter() { + @Override + public void mouseReleased(MouseEvent e) { + int returnVal = chooser.showOpenDialog(null); + if (returnVal == JFileChooser.APPROVE_OPTION) { + ps.chosenFile = chooser.getSelectedFile().getAbsolutePath(); + localFolder.setData(chooser.getSelectedFile().getName()); + } + } + }); + AppUI.getGBRow(subInnerCore, lfText, localFolder.getTextField(), y, gridbag); + y++; + + cboxfrom.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + int srcIdx = cboxfrom.getSelectedIndex() - 1; + if (srcIdx < 0 || srcIdx >= wallets.length) + return; + + srcIdx = rvFrom.idxs[srcIdx]; + Wallet srcWallet = wallets[srcIdx]; + if (srcWallet == null) + return; + + if (srcWallet.isEncrypted()) { + passwordSrc.getTextField().setVisible(true); + spText.setVisible(true); + } else { + passwordSrc.getTextField().setVisible(false); + spText.setVisible(false); + } + } + }); + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + + if (ps.srcWallet != null && ps.selectedFromIdx > 0) { + cboxfrom.setDefaultIdx(ps.selectedFromIdx); + } + + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { + public void actionPerformed(ActionEvent e) { + int srcIdx = cboxfrom.getSelectedIndex() - 1; + + + ps.selectedFromIdx = cboxfrom.getSelectedIndex(); + if (srcIdx < 0 || srcIdx >= rvFrom.idxs.length) { + ps.errText = "Please select Wallet"; + showScreen(); + return; + } + + srcIdx = rvFrom.idxs[srcIdx]; + Wallet srcWallet = wallets[srcIdx]; + ps.srcWallet = srcWallet; + + + if (srcWallet.isEncrypted()) { + if (passwordSrc.getText().isEmpty()) { + ps.errText = "Password is empty"; + showScreen(); + return; + } + + String wHash = srcWallet.getPasswordHash(); + String providedHash = AppCore.getMD5(passwordSrc.getText()); + if (wHash == null) { + ps.errText = "Wallet is corrupted"; + showScreen(); + return; + } + + if (!wHash.equals(providedHash)) { + ps.errText = "Password is incorrect"; + showScreen(); + return; + } + + ps.typedSrcPassword = passwordSrc.getText(); + } + + if (ps.chosenFile.isEmpty()) { + ps.errText = "File is not chosen"; + showScreen(); + return; + } + + if (ps.srcWallet.isSkyWallet()) { + ps.errText = "Remote transfer is not supported yet"; + showScreen(); + return; + } + + String[][] s = AppCore.parseBillPayCsv(ps.chosenFile); + if (s == null) { + ps.errText = "Failed to parse file. Make sure it is formatted corretly"; + showScreen(); + return; + } + + ps.billpays = s; + + setActiveWallet(ps.srcWallet); + ps.currentScreen = ProgramState.SCREEN_SHOW_CONFIRM_BILL_PAY; + showScreen(); + + return; + } + }, y, gridbag); + + } + public void showTransferScreen() { int y = 0; JLabel fname; diff --git a/src/advclient/ProgramState.java b/src/advclient/ProgramState.java index 16b76de..c46486f 100644 --- a/src/advclient/ProgramState.java +++ b/src/advclient/ProgramState.java @@ -66,6 +66,10 @@ public class ProgramState { final public static int SCREEN_SHOW_SENT_COINS = 48; final public static int SCREEN_SHOW_BACKUP_KEYS = 49; final public static int SCREEN_SHOW_BACKUP_KEYS_DONE = 50; + final public static int SCREEN_SHOW_BILL_PAY = 51; + final public static int SCREEN_SHOW_CONFIRM_BILL_PAY = 52; + + final static int CB_STATE_INIT = 1; @@ -161,6 +165,8 @@ public class ProgramState { int failedFiles; + String[][] billpays; + public ProgramState() { currentScreen = SCREEN_AGREEMENT; cwalletRecoveryRequested = cwalletPasswordRequested = false; @@ -232,6 +238,8 @@ public ProgramState() { needExtra = false; rrAmount = 0; + + billpays = null; } public String toString() { diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index 9d75bac..616f57f 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -1392,4 +1392,36 @@ public static CloudCoin[] getCoinsInDir(String dir) { return ccs; } + public static String[][] parseBillPayCsv(String filename) { + String [][] rvs; + BufferedReader reader; + ArrayList as = new ArrayList(); + try { + reader = new BufferedReader(new FileReader(filename)); + String line = reader.readLine(); + while (line != null) { + as.add(line); + line = reader.readLine(); + } + reader.close(); + + int i = 0; + rvs = new String[as.size()][]; + for (String s : as) { + String[] parts = s.split(","); + if (parts.length != 9) { + logger.debug(ltag, "Failed to parse string: " + s); + return null; + } + + rvs[i++] = parts; + } + + } catch (IOException e) { + logger.debug(ltag, "Failed to read file: " + filename + ": " +e.getMessage()); + return null; + } + + return rvs; + } } From 3be8b109ea766c2ccea74768c6acc595df9e39db Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 22 Jan 2020 16:06:32 +0300 Subject: [PATCH 135/160] send mails --- src/advclient/AdvancedClient.java | 396 ++++++++++++++++-- src/advclient/ProgramState.java | 12 + src/advclient/common/core/AppCore.java | 124 ++++++ src/advclient/common/core/Config.java | 8 +- src/advclient/common/core/ServantManager.java | 9 +- src/advclient/common/core/Wallet.java | 2 +- 6 files changed, 509 insertions(+), 42 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 08a1409..d814ff7 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -4,6 +4,7 @@ import global.cloudcoin.ccbank.Authenticator.AuthenticatorResult; import global.cloudcoin.ccbank.Backupper.BackupperResult; import global.cloudcoin.ccbank.Eraser.EraserResult; +import global.cloudcoin.ccbank.Emailer.EmailerResult; import global.cloudcoin.ccbank.Exporter.ExporterResult; import global.cloudcoin.ccbank.FrackFixer.FrackFixerResult; import global.cloudcoin.ccbank.Grader.GraderResult; @@ -1033,8 +1034,15 @@ public void showScreen() { showBillPayScreen(); break; case ProgramState.SCREEN_SHOW_CONFIRM_BILL_PAY: - showConfirmBillPay(); + showConfirmBillPayScreen(); break; + case ProgramState.SCREEN_BILL_PAY_DONE: + showBillPayDoneScreen(); + break; + case ProgramState.SCREEN_DOING_BILL_PAY: + showSendingBillPayScreen(); + break; + } @@ -1079,6 +1087,17 @@ public void maybeShowError(JPanel p) { } } + private void setEmailerStatus(int emailsSent, int totalEmails) { + pbar.setVisible(false); + + String sent = AppCore.formatNumber(emailsSent); + String total = AppCore.formatNumber(totalEmails); + + pbarText.setText("Emails sent: " + sent + " / " + total + ""); + pbarText.repaint(); + } + + private void setRAIDAProgressCoins(int raidaProcessed, int totalCoinsProcessed, int totalCoins) { pbar.setVisible(true); pbar.setValue(raidaProcessed); @@ -1391,16 +1410,28 @@ public void showMakingChangeScreen() { pbar.setVisible(false); int cnt = AppCore.getFilesCount(Config.DIR_DETECTED, ps.srcWallet.getName()); if (cnt != 0) { - ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; ps.errText = getNonEmptyFolderError("Detected"); + if (ps.frombillpay) { + ps.finishedMc = true; + ps.currentScreen = ProgramState.SCREEN_BILL_PAY_DONE; + return; + } + + ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; showScreen(); return; } final int skySN = getSkyWalletSN(); if (skySN == 0) { - ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; ps.errText = "Transaction cannot be completed. You must have the exact denominations of CloudCoin notes or use the Change Maker. You must have at least one Sky Wallet created to access the Change Maker"; + if (ps.frombillpay) { + ps.finishedMc = true; + ps.currentScreen = ProgramState.SCREEN_BILL_PAY_DONE; + return; + } + + ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; showScreen(); return; } @@ -1447,7 +1478,10 @@ public void callback(Object o) { pbar.setValue(mcr.progress); } else if (mcr.status == 2) { wl.debug(ltag, "Change done successfully. Retrying"); - if (ps.changeFromExport) { + if (ps.frombillpay) { + ps.currentScreen = ProgramState.SCREEN_BILL_PAY_DONE; + ps.finishedMc = true; + } else if (ps.changeFromExport) { EventQueue.invokeLater(new Runnable() { public void run() { if (ps.srcWallet.isEncrypted()) { @@ -1474,8 +1508,13 @@ public void run() { if (!mcr.errText.isEmpty()) { EventQueue.invokeLater(new Runnable() { public void run() { - ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; ps.errText = mcr.errText; + if (ps.frombillpay) { + ps.currentScreen = ProgramState.SCREEN_BILL_PAY_DONE; + return; + } + + ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; showScreen(); return; } @@ -1703,6 +1742,219 @@ public void run(){ t.start(); } + public void showSendingBillPayScreen() { + JPanel subInnerCore = getPanel("Bill Pay in Progress"); + + JPanel ct = new JPanel(); + AppUI.noOpaque(ct); + subInnerCore.add(ct); + + GridBagLayout gridbag = new GridBagLayout(); + GridBagConstraints c = new GridBagConstraints(); + ct.setLayout(gridbag); + + String fwallet = ps.srcWallet.getName(); + int y = 0; + + // Info + JLabel x = new JLabel("From Wallet " + fwallet + " "); + AppUI.setCommonFont(x); + c.anchor = GridBagConstraints.CENTER; + c.insets = new Insets(4, 0, 4, 0); + c.gridx = GridBagConstraints.RELATIVE; + c.gridy = y; + gridbag.setConstraints(x, c); + ct.add(x); + + y++; + + // Warning Label + x = new JLabel("Do not close the application until all emails are sentd!"); + AppUI.setCommonFont(x); + AppUI.setColor(x, AppUI.getErrorColor()); + c.anchor = GridBagConstraints.CENTER; + c.insets = new Insets(20, 0, 4, 0); + c.gridx = GridBagConstraints.RELATIVE; + c.gridy = y; + gridbag.setConstraints(x, c); + ct.add(x); + + y++; + + pbarText = new JLabel(""); + AppUI.setCommonFont(pbarText); + c.insets = new Insets(40, 20, 4, 0); + c.gridx = GridBagConstraints.RELATIVE; + c.gridy = y; + gridbag.setConstraints(pbarText, c); + ct.add(pbarText); + + y++; + + // ProgressBar + pbar = new JProgressBar(); + pbar.setStringPainted(true); + AppUI.setMargin(pbar, 0); + AppUI.setSize(pbar, (int) (tw / 2.6f) , 50); + pbar.setMinimum(0); + pbar.setMaximum(24); + pbar.setValue(0); + pbar.setUI(new FancyProgressBar()); + AppUI.noOpaque(pbar); + + c.insets = new Insets(20, 20, 4, 0); + c.gridx = GridBagConstraints.RELATIVE; + c.gridy = y; + gridbag.setConstraints(pbar, c); + ct.add(pbar); + + y++; + + subInnerCore.add(AppUI.hr(120)); + + Thread t = new Thread(new Runnable() { + public void run(){ + pbar.setVisible(false); + + CloudCoin skyCC = null; + ps.coinIDinFix = null; + if (ps.srcWallet.isSkyWallet()) { + ps.isCheckingSkyID = true; + skyCC = ps.srcWallet.getIDCoin(); + + pbarText.setText("Checking Your Source SkyWallet ID"); + pbarText.repaint(); + + sm.startAuthenticatorService(skyCC, new AuthenticatorForSkyCoinCb()); + while (ps.isCheckingSkyID) { + try { + Thread.sleep(300); + } catch (InterruptedException e) {} + } + + if (AppCore.getErrorCount(skyCC) > Config.MAX_FAILED_RAIDAS_TO_SEND) { + ps.errText = getSkyIDErrorIfRAIDAFailed(); + showScreen(); + return; + } else if (AppCore.getPassedCount(skyCC) < Config.PASS_THRESHOLD) { + ps.errText = getSkyIDError(ps.srcWallet.getName(), ps.srcWallet.getIDCoin().getPownString()); + showScreen(); + return; + } else if (AppCore.getPassedCount(skyCC) != RAIDA.TOTAL_RAIDA_COUNT) { + ps.currentScreen = ProgramState.SCREEN_WARN_FRACKED_TO_SEND; + showScreen(); + return; + } + } + + ps.finishedMc = false; + String[][] attachments = new String[ps.billpays.length][1]; + for (int i = 0; i < ps.billpays.length; i++) { + String email = ps.billpays[i][7]; + pbarText.setText("Exporting coins for " + email); + pbarText.repaint(); + + ps.typedAmount = AppCore.getTotalToSend(ps.billpays[i]); + ps.finishedMc = false; + ps.triedToChange = false; + + final int fi = i; + CallbackInterface cb = new CallbackInterface() { + public void callback(Object result) { + final Object eresult = result; + final ExporterResult er = (ExporterResult) eresult; + + if (er.status == ExporterResult.STATUS_ERROR) { + EventQueue.invokeLater(new Runnable() { + public void run() { + if (!er.errText.isEmpty()) { + if (er.errText.equals(Config.PICK_ERROR_MSG)) { + ps.errText = "Failed to find enough denominations"; + ps.finishedMc = true; + + /* + if (ps.triedToChange) { + ps.errText = "Failed to change coins"; + ps.finishedMc = true; + } else { + ps.finishedMc = false; + ps.frombillpay = true; + ps.changeFromExport = true; + ps.triedToChange = true; + ps.currentScreen = ProgramState.SCREEN_MAKING_CHANGE; + showScreen(); + return; + }*/ + } else { + ps.errText = er.errText; + ps.finishedMc = true; + } + } else { + ps.errText = "Failed to export coins"; + ps.finishedMc = true; + } + } + }); + + return; + } + + if (er.status == ExporterResult.STATUS_FINISHED) { + if (er.totalExported != ps.typedAmount) { + ps.errText = "Some of the coins were not exported"; + } + } + + sm.getActiveWallet().appendTransaction("Sent to " + email, er.totalExported * -1, er.receiptId); + ps.finishedMc = true; + + attachments[fi][0] = er.exportedFileNames.get(0); + } + }; + + String tag = i + "_" + email.replaceAll("\\.", "_"); + if (ps.srcWallet.isEncrypted()) { + sm.startSecureExporterService(Config.TYPE_STACK, ps.typedAmount, tag, null, false, cb); + } else { + sm.startExporterService(Config.TYPE_STACK, ps.typedAmount, tag, null, false, cb); + } + + while (!ps.finishedMc) { + try { + Thread.sleep(200); + } catch(InterruptedException e) {} + } + + if (!ps.errText.isEmpty()) { + ps.errText = ps.errText + " for " + email; + ps.currentScreen = ProgramState.SCREEN_BILL_PAY_DONE; + showScreen(); + return; + } + } + + sm.getActiveWallet().setNotUpdated(); + + setEmailerStatus(0, ps.billpays.length); + String[] bodies = new String[ps.billpays.length]; + String[] subjects = new String[ps.billpays.length]; + String[] emails = new String[ps.billpays.length]; + + for (int i = 0; i < ps.billpays.length; i++) { + int total = AppCore.getTotalToSend(ps.billpays[i]); + bodies[i] = AppCore.getEmailTemplate(ps.billpays[i][8], total); + subjects[i] = total + " CloudCoins"; + emails[i] = ps.billpays[i][7]; + } + + sm.startEmailerService(emails, subjects, bodies, attachments, new EmailerCb()); + + + } + }); + + t.start(); + } public void showImportingScreen() { JPanel subInnerCore = getPanel("Deposit in Progress"); @@ -1994,6 +2246,49 @@ public void actionPerformed(ActionEvent e) { } + public void showBillPayDoneScreen() { + boolean isError = !ps.errText.equals(""); + JPanel subInnerCore; + + if (isError) { + subInnerCore = getPanel("Error"); + resetState(); + return; + } + + ps.srcWallet.setNotUpdated(); + + int y = 0; + JLabel fname, value; + MyTextField walletName = null; + + subInnerCore = getPanel("Bill Pay Complete"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + String name = ps.srcWallet.getName(); + fname = new JLabel("Coins have been sent successfully from " +name); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + AppUI.getTwoButtonPanel(subInnerCore, "Next Pay", "Done", new ActionListener() { + public void actionPerformed(ActionEvent e) { + resetState(); + ps.currentScreen = ProgramState.SCREEN_SHOW_BILL_PAY; + showScreen(); + } + }, new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, y, gridbag); + } + + public void showTransferDoneScreen() { boolean isError = !ps.errText.equals(""); JPanel subInnerCore; @@ -2742,7 +3037,7 @@ public void run() { }, y, gridbag); } - public void showConfirmBillPay() { + public void showConfirmBillPayScreen() { int y = 0; JLabel fname, value; MyTextField walletName = null; @@ -2802,39 +3097,8 @@ public void actionPerformed(ActionEvent e) { ps.srcWallet.setPassword(ps.typedSrcPassword); sm.setActiveWalletObj(ps.srcWallet); - if (ps.sendType == ProgramState.SEND_TYPE_FOLDER) { - ps.isSkyDeposit = false; - ps.currentScreen = ProgramState.SCREEN_EXPORTING; - if (ps.srcWallet.isEncrypted()) { - sm.startSecureExporterService(Config.TYPE_STACK, ps.typedAmount, ps.typedMemo, ps.chosenFile, false, new ExporterCb()); - } else { - sm.startExporterService(Config.TYPE_STACK, ps.typedAmount, ps.typedMemo, ps.chosenFile, false, new ExporterCb()); - } - showScreen(); - } else if (ps.sendType == ProgramState.SEND_TYPE_WALLET) { - ps.dstWallet.setPassword(ps.typedDstPassword); - ps.currentScreen = ProgramState.SCREEN_SENDING; - if (ps.srcWallet.isSkyWallet()) { - ps.isSkyDeposit = true; - } else { - ps.isSkyDeposit = false; - } - showScreen(); - } else if (ps.sendType == ProgramState.SEND_TYPE_REMOTE) { - DNSSn d = new DNSSn(ps.typedRemoteWallet, null, wl); - int sn = d.getSN(); - if (sn < 0) { - ps.errText = "Failed to query receiver. Check that the name is valid"; - ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; - showScreen(); - return; - } - - ps.foundSN = sn; - ps.isSkyDeposit = false; - ps.currentScreen = ProgramState.SCREEN_SENDING; - showScreen(); - } + ps.currentScreen = ProgramState.SCREEN_DOING_BILL_PAY; + showScreen(); } }, y, gridbag); @@ -3533,6 +3797,14 @@ public void actionPerformed(ActionEvent e) { showScreen(); return; } + + String err = AppCore.checkBillPays(ps.srcWallet, s); + if (err != null) { + ps.errText = "Parse error: " + err; + showScreen(); + return; + } + ps.billpays = s; @@ -7569,6 +7841,7 @@ public void run() { //ps.errText = getPickError(ps.srcWallet); ps.errText = "Failed to change coins"; } else { + ps.frombillpay = false; ps.changeFromExport = true; ps.triedToChange = true; ps.currentScreen = ProgramState.SCREEN_MAKING_CHANGE; @@ -7840,6 +8113,7 @@ public void run() { if (ps.triedToChange) { ps.errText = "Failed to change coins"; } else { + ps.frombillpay = false; ps.changeFromExport = false; ps.triedToChange = true; ps.currentScreen = ProgramState.SCREEN_MAKING_CHANGE; @@ -8131,6 +8405,50 @@ public void run() { } } + class EmailerCb implements CallbackInterface { + public void callback(Object result) { + final EmailerResult er = (EmailerResult) result; + + wl.debug(ltag, "Emailer finished: " + er.status); + if (er.status == EmailerResult.STATUS_PROCESSING) { + //setRAIDATransferProgressCoins(tr.totalRAIDAProcessed, tr.totalCoinsProcessed, tr.totalCoins); + setEmailerStatus(er.sentEmails, er.totalEmails); + return; + } + + if (er.status == TransferResult.STATUS_CANCELLED) { + EventQueue.invokeLater(new Runnable() { + public void run() { + ps.errText = "Operation Cancelled"; + ps.currentScreen = ProgramState.SCREEN_BILL_PAY_DONE; + sm.resumeAll(); + showScreen(); + } + }); + return; + } + + if (er.status == ReceiverResult.STATUS_ERROR) { + EventQueue.invokeLater(new Runnable() { + public void run() { + ps.currentScreen = ProgramState.SCREEN_BILL_PAY_DONE; + if (!er.errText.isEmpty()) { + ps.errText = er.errText; + } + else + ps.errText = "Error occurred. Please check the logs"; + + showScreen(); + } + }); + return; + } + + ps.currentScreen = ProgramState.SCREEN_BILL_PAY_DONE; + showScreen(); + } + } + class optRv { int[] idxs; diff --git a/src/advclient/ProgramState.java b/src/advclient/ProgramState.java index c46486f..b9fba50 100644 --- a/src/advclient/ProgramState.java +++ b/src/advclient/ProgramState.java @@ -68,6 +68,8 @@ public class ProgramState { final public static int SCREEN_SHOW_BACKUP_KEYS_DONE = 50; final public static int SCREEN_SHOW_BILL_PAY = 51; final public static int SCREEN_SHOW_CONFIRM_BILL_PAY = 52; + final public static int SCREEN_DOING_BILL_PAY = 53; + final public static int SCREEN_BILL_PAY_DONE = 54; @@ -167,6 +169,11 @@ public class ProgramState { String[][] billpays; + boolean frombillpay; + + boolean finishedMc; + + public ProgramState() { currentScreen = SCREEN_AGREEMENT; cwalletRecoveryRequested = cwalletPasswordRequested = false; @@ -240,6 +247,11 @@ public ProgramState() { rrAmount = 0; billpays = null; + + frombillpay = false; + + finishedMc = false; + } public String toString() { diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index 616f57f..cffa276 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -12,6 +12,7 @@ import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStream; +import java.io.Reader; import java.io.UnsupportedEncodingException; import java.net.URL; import java.net.URLDecoder; @@ -34,6 +35,7 @@ import java.util.Iterator; import java.util.Locale; import java.util.Map; +import java.util.Properties; import java.util.jar.JarEntry; import java.util.jar.JarFile; import org.json.JSONArray; @@ -91,6 +93,9 @@ static public boolean initFolders(File path, GLogger logger) throws Exception { rootPath = new File(path, Config.DIR_ROOT); + if (!createDirectory(Config.DIR_EMAIL_TEMPLATES)) + return false; + if (!createDirectory(Config.DIR_ACCOUNTS)) return false; @@ -106,6 +111,9 @@ static public boolean initFolders(File path, GLogger logger) throws Exception { if (!createDirectory(Config.DIR_BACKUPS)) return false; + if (!createDirectory(Config.DIR_EMAIL_TEMPLATES)) + return false; + return true; } @@ -748,6 +756,7 @@ public static String getCurrentBackupDir(String broot, String user) { return bdir; } + public static String getDate(String ts) { int lts; @@ -1075,6 +1084,9 @@ public static int getPassedCount(CloudCoin cc) { return passed; } + public static String getMailConfigFilename() { + return rootPath + File.separator + Config.MAIL_CONFIG_FILENAME; + } public static void readConfig() { String globalConfigFilename = rootPath + File.separator + Config.GLOBAL_CONFIG_FILENAME; @@ -1424,4 +1436,116 @@ public static String[][] parseBillPayCsv(String filename) { return rvs; } + + public static Map parseINI(Reader reader) throws IOException { + Map result = new HashMap(); + new Properties() { + private Properties section; + + @Override + public Object put(Object key, Object value) { + String header = (((String) key) + " " + value).trim(); + if (header.startsWith("[") && header.endsWith("]")) { + return result.put(header.substring(1, header.length() - 1), + section = new Properties()); + } + else { + return section.put(key, value); + } + } + }.load(reader); + return result; + } + + public static String getEmailTemplate(String template, int amount) { + String fname = AppCore.rootPath + File.separator + Config.DIR_EMAIL_TEMPLATES + File.separator + template; + File f = new File(fname); + + String fdata = AppCore.loadFile(fname); + if (fdata == null) { + logger.debug(ltag, "Failed to load email template: " + fname); + return null; + } + + fdata = fdata.replaceAll("%amountToSend%", "" + amount); + + return fdata; + } + + public static boolean checkEmailTemplate(String template) { + String fname = AppCore.rootPath + File.separator + Config.DIR_EMAIL_TEMPLATES + File.separator + template; + File f = new File(fname); + if (!f.exists()) { + logger.debug(ltag, "FileTemplate " + fname + " doesn't exist"); + return false; + } + + return true; + } + + public static String checkBillPays(Wallet w, String[][] s) { + for (int i = 0; i < s.length; i++) { + String[] line = s[i]; + + int total, s1, s5, s25, s100, s250; + total = s1 = s5 = s25 = s100 = s250 = 0; + + try { + total = Integer.parseInt(line[1]); + s1 = Integer.parseInt(line[2]); + s5 = Integer.parseInt(line[3]); + s25 = Integer.parseInt(line[4]); + s100 = Integer.parseInt(line[5]); + s250 = Integer.parseInt(line[6]); + } catch (NumberFormatException e) { + return "Failed to numbers. Line: " + (i + 1); + } + + if (total < 0 || s1 < 0 || s5 < 0 || s25 < 0 || s100 < 0 || s250 < 0) { + return "Invalid amount value. Line " + (i + 1); + } + + if (total != 0 && (s1 > 0 || s5 > 0 || s25 > 0 || s100 > 0 || s250 > 0)) { + return "Both total and denominations are set"; + } + + if (total == 0) + total = s1 + s5 + s25 + s100 + s250; + + if (w.getTotal() < total) { + return "Not enough funds. Required: " + total; + } + + if (!AppCore.checkEmailTemplate(line[8])) { + return "Template " + line[8] + " doesn't exist. Line " + (i + 1); + } + // if (total != 0 && (s1 )) + + } + + return null; + } + + public static int getTotalToSend(String[] line) { + int total, s1, s5, s25, s100, s250; + total = s1 = s5 = s25 = s100 = s250 = 0; + + try { + total = Integer.parseInt(line[1]); + s1 = Integer.parseInt(line[2]); + s5 = Integer.parseInt(line[3]); + s25 = Integer.parseInt(line[4]); + s100 = Integer.parseInt(line[5]); + s250 = Integer.parseInt(line[6]); + } catch (NumberFormatException e) { + return -1; + } + + if (total == 0) + total = s1 + s5 + s25 + s100 + s250; + + return total; + } + + } diff --git a/src/advclient/common/core/Config.java b/src/advclient/common/core/Config.java index e1d8ed1..348df9a 100644 --- a/src/advclient/common/core/Config.java +++ b/src/advclient/common/core/Config.java @@ -33,7 +33,7 @@ public class Config { public static String DIR_VAULT = "Vault"; - + public static String DIR_EMAIL_TEMPLATES = "EmailTemplates"; public static String DIR_ACCOUNTS = "Accounts"; public static String DIR_DEFAULT_USER = "Default_User_NonExist"; public static String DIR_MAIN_LOGS = "Logs"; @@ -41,6 +41,12 @@ public class Config { public static String DIR_BACKUPS = "Backups"; public static String GLOBAL_CONFIG_FILENAME = "global.config"; + public static String MAIL_CONFIG_FILENAME = "mailsettings.ini"; + + public static int DEFAULT_MAX_EMAILS_PER_RUN = 10; + public static String DEFAULT_EMAIL_HOST = "localhost"; + public static int DEFAULT_EMAIL_PORT = 1025; + public static int THREAD_POOL_SIZE = 60; public static int READ_TIMEOUT = 40000; // ms diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index c08e768..544d86b 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -27,6 +27,8 @@ import global.cloudcoin.ccbank.Sender.SenderResult; import global.cloudcoin.ccbank.Transfer.Transfer; import global.cloudcoin.ccbank.Transfer.TransferResult; +import global.cloudcoin.ccbank.Emailer.Emailer; +import global.cloudcoin.ccbank.Emailer.EmailerResult; import global.cloudcoin.ccbank.ShowCoins.ShowCoins; import global.cloudcoin.ccbank.ShowEnvelopeCoins.ShowEnvelopeCoins; import global.cloudcoin.ccbank.ShowEnvelopeCoins.ShowEnvelopeCoinsResult; @@ -158,7 +160,8 @@ public boolean initServants() { "ShowEnvelopeCoins", "Eraser", "Backupper", - "Transfer" + "Transfer", + "Emailer" }, AppCore.getRootPath() + File.separator + user, logger); @@ -528,6 +531,10 @@ public void startVaulterService(CallbackInterface cb, String password) { v.vault(password, 0, null, cb); } + public void startEmailerService(String[] emails, String[] subjects, String[] bodies, String[][] attachments, CallbackInterface icb) { + Emailer el = (Emailer) sr.getServant("Emailer"); + el.launch(emails, subjects, bodies, attachments, icb); + } public void startExporterService(int exportType, int amount, String tag, String dir, boolean keepSrc, CallbackInterface cb) { if (sr.isRunning("Exporter")) diff --git a/src/advclient/common/core/Wallet.java b/src/advclient/common/core/Wallet.java index 7332735..7df2a3c 100644 --- a/src/advclient/common/core/Wallet.java +++ b/src/advclient/common/core/Wallet.java @@ -180,7 +180,7 @@ public void saveEnvelopes(String dstPath) { public String[][] getTransactions() { String fileName = getTransactionsFileName(); - + String data = AppCore.loadFile(fileName); if (data == null) return null; From a641a76cf1ef12509e6ce3886d2ce9173ca8b165 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 22 Jan 2020 16:12:18 +0300 Subject: [PATCH 136/160] send mails --- src/advclient/common/Emailer/Emailer.java | 425 ++++++++++++++++++ .../common/Emailer/EmailerResult.java | 22 + 2 files changed, 447 insertions(+) create mode 100644 src/advclient/common/Emailer/Emailer.java create mode 100644 src/advclient/common/Emailer/EmailerResult.java diff --git a/src/advclient/common/Emailer/Emailer.java b/src/advclient/common/Emailer/Emailer.java new file mode 100644 index 0000000..e0dd377 --- /dev/null +++ b/src/advclient/common/Emailer/Emailer.java @@ -0,0 +1,425 @@ +package global.cloudcoin.ccbank.Emailer; + +import global.cloudcoin.ccbank.Emailer.EmailerResult; +import java.io.File; + +import global.cloudcoin.ccbank.core.AppCore; +import global.cloudcoin.ccbank.core.CallbackInterface; +import global.cloudcoin.ccbank.core.CloudCoin; +import global.cloudcoin.ccbank.core.Config; +import global.cloudcoin.ccbank.core.RAIDA; +import global.cloudcoin.ccbank.core.Servant; +import global.cloudcoin.ccbank.core.GLogger; +import java.io.BufferedReader; +import java.io.FileInputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.io.PrintWriter; +import java.net.Socket; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Base64; +import java.util.Map; +import java.util.Properties; +import java.util.Random; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.TimeUnit; + +public class Emailer extends Servant { + EmailerResult ger; + String ltag = "Emailer"; + + String host; + int port; + String username, password, from, mail_from; + int maxConcurrent; + + public Emailer(String rootDir, GLogger logger) { + super("Emailer", rootDir, logger); + } + + public void launch(String[] emails, String[] subjects, String[] bodies, String[][] attachments, CallbackInterface icb) { + this.cb = icb; + + final String[] femails = emails; + final String[] fsubjects = subjects; + final String[] fbodies = bodies; + final String[][] fattachments = attachments; + + this.maxConcurrent = Config.DEFAULT_MAX_EMAILS_PER_RUN; + this.host = Config.DEFAULT_EMAIL_HOST; + this.port = Config.DEFAULT_EMAIL_PORT; + + ger = new EmailerResult(); + launchThread(new Runnable() { + @Override + public void run() { + logger.info(ltag, "RUN Emailer"); + + doEmail(femails, fsubjects, fbodies, fattachments, cb); + if (cb != null) + cb.callback(ger); + } + }); + } + + public void copyFromMainResult(EmailerResult er) { + er.sentEmails = ger.sentEmails; + er.errText = ger.errText; + er.totalEmails = ger.totalEmails; + } + + public void setError(String errText) { + EmailerResult er = new EmailerResult(); + ger.errText = errText; + ger.status = EmailerResult.STATUS_ERROR; + } + + public boolean readConfig() { + String filename = AppCore.getMailConfigFilename(); + File f = new File(filename); + if (!f.exists()) { + try { + f.createNewFile(); + } catch (IOException e) {} + logger.error(ltag, "Failed to read config file. It doesn't exist"); + setError("Failed to read mail config: " + AppCore.getMailConfigFilename()); + return false; + } + + FileReader fr; + try { + fr = new FileReader(f); + } catch (Exception e) { + setError("Failed to read mail config: " + AppCore.getMailConfigFilename()); + return false; + } + Map data; + try { + data = AppCore.parseINI(fr); + } catch (IOException e) { + setError("Failed to parse mail config: " + AppCore.getMailConfigFilename()); + return false; + } + + Properties smtp = data.get("smtp"); + if (smtp == null) { + setError("Failed to parse mail config: smtp section not defined"); + return false; + } + + String port = smtp.getProperty("port"); + if (port != null) { + try { + this.port = Integer.parseInt(port); + } catch (NumberFormatException e) { + setError("Failed to parse mail config: invalid port"); + return false; + } + } + + if (this.port < 1 || this.port > 65535) { + setError("Failed to parse mail config: invalid port"); + return false; + } + + String rr = smtp.getProperty("maxEmailsPerRun"); + if (rr != null) { + try { + this.maxConcurrent = Integer.parseInt(rr); + } catch (NumberFormatException e) { + setError("Failed to parse mail config: maxEmailsPerRun"); + return false; + } + } + + String host = smtp.getProperty("smptServerAddress"); + if (host != null) + this.host = host; + + String from = smtp.getProperty("from"); + if (smtp.get("from") == null) { + setError("Failed to parse mail config: from address not defined"); + return false; + } + this.from = from; + + String mail_from = smtp.getProperty("mail_from"); + if (smtp.get("mail_from") == null) { + setError("Failed to parse mail config: mail_from address not defined"); + return false; + } + this.mail_from = mail_from; + + String username = smtp.getProperty("username"); + if (smtp.get("username") == null) { + setError("Failed to parse mail config: username not defined"); + return false; + } + this.username = username; + + String password = smtp.getProperty("password"); + if (smtp.get("password") == null) { + setError("Failed to parse mail config: password not defined"); + return false; + } + this.password = password; + + return true; + } + + + + public void doEmail(String[] emails, String[] subjects, String[] bodies, String[][] attachments, CallbackInterface cb) { + if (!this.readConfig()) { + logger.error(ltag, "Failed to read config"); + return; + } + + ger.totalEmails = emails.length; + ger.sentEmails = 0; + + ExecutorService executor = Executors.newFixedThreadPool(this.maxConcurrent); + for (int i = 0; i < emails.length; i++) { + final String femail = emails[i]; + final String fsubject = subjects[i]; + final String fbody = bodies[i]; + final String[] fattachments = attachments[i]; + final CallbackInterface fcb = cb; + final int fi = i; + Thread t = new Thread() { + public void run() { + sendEmail(femail, fsubject, fbody, fattachments); + if (!ger.errText.isEmpty()) { + logger.error(ltag, "Terminating sending to " + femail); + return; + } + + AppCore.moveToFolderNoTs(fattachments[0], Config.DIR_SENT, user, true); + ger.sentEmails++; + EmailerResult er = new EmailerResult(); + copyFromMainResult(er); + if (cb != null) + cb.callback(er); + } + }; + executor.execute(t); + } + + try { + executor.shutdown(); + executor.awaitTermination(1000, TimeUnit.SECONDS); + } catch (InterruptedException e) { + logger.debug(ltag, "Interrupted"); + } finally { + if (!executor.isTerminated()) { + logger.debug(ltag, "Cancel non-finished"); + } + executor.shutdownNow(); + } + + if (!ger.errText.isEmpty()) + ger.status = EmailerResult.STATUS_ERROR; + else + ger.status = EmailerResult.STATUS_FINISHED; + } + + public void sendEmail(String email, String subject, String body, String[] attachments) { + logger.debug(ltag, "Sedning " + email + " s=" + subject + " a=" + attachments[0] + " total="+attachments.length); + String fileData = AppCore.loadFile(attachments[0]); + if (fileData == null) { + setError("Failed to load file: " + attachments[0]); + return; + } + + try { + logger.debug(ltag, "Connecting to " + this.host + ":" + this.port); + Socket socket = new Socket(this.host, this.port); + + InputStream input = socket.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(input)); + + OutputStream output = socket.getOutputStream(); + PrintWriter writer = new PrintWriter(output, true); + + String line; + + line = reader.readLine(); + logger.debug(ltag, line); + if (!isResponseOk(line, 220)) { + setError("Invalid response from Protonmail. Please check the logs"); + return; + } + + writer.println("EHLO localhost"); + logger.debug(ltag, "EHLO localhost"); + while ((line = reader.readLine()) != null) { + logger.debug(ltag, line); + if (isInterimResponse(line)) + continue; + + if (!isResponseOk(line, 250)) { + setError("Invalid response from Protonmail (EHLO). Please check the logs"); + return; + } + + break; + } + + String login = Base64.getEncoder().encodeToString((this.username).getBytes()); + String password = Base64.getEncoder().encodeToString((this.password).getBytes()); + + writer.println("AUTH LOGIN"); + logger.debug(ltag, "AUTH LOGIN"); + + line = reader.readLine(); + logger.debug(ltag, line); + if (!isResponseOk(line, 334)) { + setError("Invalid response from Protonmail (Login). Please check the logs"); + return; + } + + writer.println(login); + logger.debug(ltag, login); + + line = reader.readLine(); + if (!isResponseOk(line, 334)) { + setError("Invalid response from Protonmail (Login). Please check the logs"); + return; + } + + writer.println(password); + logger.debug(ltag, password); + + line = reader.readLine(); + logger.debug(ltag, line); + if (!isResponseOk(line, 235)) { + setError("Proton auth failed. Please check your credentials"); + return; + } + + writer.println("MAIL FROM: " + this.mail_from); + logger.debug(ltag, "MAIL FROM: " + this.mail_from); + + line = reader.readLine(); + logger.debug(ltag, line); + if (!isResponseOk(line, 250)) { + setError("Invalid response from Protonmail (MAIL FROM). Please check the logs"); + return; + } + + writer.println("RCPT TO: " + email); + logger.debug(ltag, "RCPT TO: " + email); + + line = reader.readLine(); + logger.debug(ltag, line); + if (!isResponseOk(line, 250)) { + setError("Invalid response from Protonmail (RCPT TO). Please check the logs"); + return; + } + + writer.println("DATA"); + logger.debug(ltag, "DATA"); + + line = reader.readLine(); + logger.debug(ltag, line); + if (!isResponseOk(line, 354)) { + setError("Invalid response from Protonmail (DATA). Please check the logs"); + return; + } + + String fname = new File(attachments[0]).getName().replaceAll("@", "_"); + String attachment = Base64.getEncoder().encodeToString((fileData).getBytes()); + String boundary = this.generateBoundary(); + String msg = "Subject: " + subject + "\r\n" + + "Date: " + AppCore.getDate("" + (System.currentTimeMillis() /1000)) +"\r\n"+ + "To: " + email + "\r\n" + + "From: " + this.from + "\r\n" + + "MIME-Version: 1.0\r\n" + + "Content-type: multipart/mixed; boundary=\"" + boundary + "\"\r\n" + + "\r\n" + + "This is a multipart message in MIME format.\r\n\r\n" + + "--" + boundary + "\r\n" + + "Content-Type: text/plain; charset=\"UTF-8\"\r\n\r\n" + + "" + body + "\r\n" + + "--" + boundary + "\r\n" + + "Content-Type: text/plain\r\n" + + "Content-Disposition: attachment; filename=" + fname + "\r\n" + + "Content-Transfer-Encoding: Base64\r\n\r\n" + + "" + attachment + "\r\n" + + "--" + boundary + "--"; + + + writer.println(msg); + logger.debug(ltag, msg); + writer.println("."); + logger.debug(ltag, "."); + + + line = reader.readLine(); + logger.debug(ltag, line); + if (!isResponseOk(line, 250)) { + setError("Proton rejected the message. Please check the logs"); + return; + } + + writer.println("QUIT"); + logger.debug(ltag, "QUIT"); + + } catch (UnknownHostException ex) { + logger.error(ltag, "Unknown network error: " + ex.getMessage()); + ger.status = EmailerResult.STATUS_ERROR; + setError("Unknown network error. Please check the logs"); + return; + } catch (IOException ex) { + setError("Failed to connect to the ProtonMail bridge. Make sure it is running"); + logger.error(ltag, "Failed to connect to the ProtonMail bridge: " + ex.getMessage()); + return; + } + } + + protected String generateBoundary() { + StringBuilder buffer = new StringBuilder(); + Random rand = new Random(); + int count = rand.nextInt(11) + 30; + for (int i = 0; i < count; i++) { + buffer.append(MULTIPART_CHARS[rand.nextInt(MULTIPART_CHARS.length)]); + } + + return buffer.toString(); + } + + private final static char[] MULTIPART_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); + + public boolean isInterimResponse(String response) { + if (response.length() > 3 && response.charAt(3) == '-') + return true; + + return false; + } + + public boolean isResponseOk(String response, int dcode) { + String[] v = response.split(" "); + + logger.debug(ltag, response); + try { + int rcode = Integer.parseInt(v[0]); + if (rcode != dcode) { + logger.error(ltag, "Invalid code returned from Protonmail: " + rcode); + return false; + } + } catch (NumberFormatException e) { + logger.error(ltag, "Failed to parse response: " + response); + return false; + } + + return true; + + } + + +} diff --git a/src/advclient/common/Emailer/EmailerResult.java b/src/advclient/common/Emailer/EmailerResult.java new file mode 100644 index 0000000..9ae5f7e --- /dev/null +++ b/src/advclient/common/Emailer/EmailerResult.java @@ -0,0 +1,22 @@ +package global.cloudcoin.ccbank.Emailer; + +import java.util.ArrayList; + +public class EmailerResult { + public int status; + + public static int STATUS_PROCESSING = 1; + public static int STATUS_FINISHED = 2; + public static int STATUS_ERROR = 3; + + public int totalEmails; + public int sentEmails; + + public String errText; + + public EmailerResult() { + status = STATUS_PROCESSING; + errText = ""; + totalEmails = sentEmails = 0; + } +} \ No newline at end of file From 8f88dd9ba7bb5bc6d59b30529c7c1a53a6c156f2 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 23 Jan 2020 13:13:33 +0300 Subject: [PATCH 137/160] log message --- src/advclient/common/core/Servant.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/advclient/common/core/Servant.java b/src/advclient/common/core/Servant.java index 8735239..75b111e 100644 --- a/src/advclient/common/core/Servant.java +++ b/src/advclient/common/core/Servant.java @@ -264,7 +264,7 @@ private boolean readConfig() { File file = new File(configFilename); try { if (!file.exists()) { - logger.error(ltag, "No config found for user " + user); + // No probleam, actually. Will use default values return false; } From 0727d9336e89be460353f1083fecac50eb461814 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 23 Jan 2020 13:16:19 +0300 Subject: [PATCH 138/160] msg --- src/advclient/AdvancedClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index d814ff7..69f8c24 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -198,7 +198,7 @@ else if (total < 999999999) } public String getSkyIDError(String name, String pownString) { - return "Your Sky Coin ID " + name + " is counterfeit. It is not safe to use it.

" + return "Your Sky Coin ID " + name + " is not 100% authentic. It is not safe to use it.

" + "The Pown String is " + pownString + ""; } From c0f531f647ce53866c67f67cf6d89163bc7d408f Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 31 Jan 2020 10:52:54 +0300 Subject: [PATCH 139/160] Transfer done screen fix --- src/advclient/AdvancedClient.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 69f8c24..ac8218b 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -8166,12 +8166,20 @@ public void run() { sm.changeServantUser("Vaulter", dstWallet.getName()); sm.startVaulterService(new VaulterCb(), dstWallet.getPassword()); } else { - ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; - showScreen(); + EventQueue.invokeLater(new Runnable() { + public void run() { + ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; + showScreen(); + } + }); } } else { - ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; - showScreen(); + EventQueue.invokeLater(new Runnable() { + public void run() { + ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; + showScreen(); + } + }); } return; From bccd74d0b2c2831626c0f338ab86bb0a6608a193 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Sat, 1 Feb 2020 11:56:18 +0300 Subject: [PATCH 140/160] Move socket checks before export --- src/advclient/AdvancedClient.java | 37 ++++++-- src/advclient/common/Emailer/Emailer.java | 92 ++++++++++++------- src/advclient/common/core/ServantManager.java | 15 +++ 3 files changed, 101 insertions(+), 43 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index ac8218b..c14977e 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -1769,7 +1769,7 @@ public void showSendingBillPayScreen() { y++; // Warning Label - x = new JLabel("Do not close the application until all emails are sentd!"); + x = new JLabel("Do not close the application until all emails are sent!"); AppUI.setCommonFont(x); AppUI.setColor(x, AppUI.getErrorColor()); c.anchor = GridBagConstraints.CENTER; @@ -3055,8 +3055,8 @@ public void showConfirmBillPayScreen() { String v = ""; for (int i = 0; i < ps.billpays.length; i++) { - v += "

" + ps.billpays[i][0] + ": " + ps.billpays[i][1] + ": " + ps.billpays[i][1] + ": " + ps.billpays[i][2] + " : " + ps.billpays[i][3] + " : " + ps.billpays[i][4] + - ps.billpays[i][5] + ": " + ps.billpays[i][6] + ": " + ps.billpays[i][7] + " : " + ps.billpays[i][8] + "


"; + v += "

" + ps.billpays[i][0] + ": " + ps.billpays[i][1] + ": " + ps.billpays[i][2] + ": " + ps.billpays[i][3] + " : " + ps.billpays[i][4] + " : " + ps.billpays[i][5] + + ": " + ps.billpays[i][6] + ": " + ps.billpays[i][7] + ": " + ps.billpays[i][8] + "


"; } v+=""; JLabel x = new JLabel(v); @@ -3666,6 +3666,11 @@ public void showBillPayScreen() { AppUI.GBPad(subInnerCore, y, gridbag); return; } + + JLabel infox = AppUI.wrapDiv(""); + AppUI.getGBRow(subInnerCore, null, infox, y, gridbag); + y++; + fname = new JLabel("From"); final RoundedCornerComboBox cboxfrom = new RoundedCornerComboBox(AppUI.getColor6(), "Make Selection", rvFrom.options); @@ -3804,15 +3809,29 @@ public void actionPerformed(ActionEvent e) { showScreen(); return; } + + infox.setText("Checking Email Gateway..."); + Thread t = new Thread(new Runnable() { + public void run() { + String err = sm.getEmailerError(); + infox.setText(""); + if (err != null) { + ps.errText = err; + showScreen(); + return; + } + ps.billpays = s; + setActiveWallet(ps.srcWallet); - ps.billpays = s; + ps.currentScreen = ProgramState.SCREEN_SHOW_CONFIRM_BILL_PAY; + showScreen(); + return; + } + }); - setActiveWallet(ps.srcWallet); - ps.currentScreen = ProgramState.SCREEN_SHOW_CONFIRM_BILL_PAY; - showScreen(); - - return; + t.start(); + } }, y, gridbag); diff --git a/src/advclient/common/Emailer/Emailer.java b/src/advclient/common/Emailer/Emailer.java index e0dd377..573ce78 100644 --- a/src/advclient/common/Emailer/Emailer.java +++ b/src/advclient/common/Emailer/Emailer.java @@ -30,7 +30,7 @@ import java.util.concurrent.TimeUnit; public class Emailer extends Servant { - EmailerResult ger; + public EmailerResult ger; String ltag = "Emailer"; String host; @@ -40,6 +40,7 @@ public class Emailer extends Servant { public Emailer(String rootDir, GLogger logger) { super("Emailer", rootDir, logger); + ger = new EmailerResult(); } public void launch(String[] emails, String[] subjects, String[] bodies, String[][] attachments, CallbackInterface icb) { @@ -53,7 +54,7 @@ public void launch(String[] emails, String[] subjects, String[] bodies, String[] this.maxConcurrent = Config.DEFAULT_MAX_EMAILS_PER_RUN; this.host = Config.DEFAULT_EMAIL_HOST; this.port = Config.DEFAULT_EMAIL_PORT; - + ger = new EmailerResult(); launchThread(new Runnable() { @Override @@ -172,7 +173,16 @@ public boolean readConfig() { return true; } - + public boolean doChecks() { + logger.debug(ltag, "Doing Email checks"); + if (!this.readConfig()) + return false; + + if (!sendEmail(null, null, null, null, true)) + return false; + + return true; + } public void doEmail(String[] emails, String[] subjects, String[] bodies, String[][] attachments, CallbackInterface cb) { if (!this.readConfig()) { @@ -193,7 +203,7 @@ public void doEmail(String[] emails, String[] subjects, String[] bodies, String[ final int fi = i; Thread t = new Thread() { public void run() { - sendEmail(femail, fsubject, fbody, fattachments); + sendEmail(femail, fsubject, fbody, fattachments, false); if (!ger.errText.isEmpty()) { logger.error(ltag, "Terminating sending to " + femail); return; @@ -228,13 +238,16 @@ public void run() { ger.status = EmailerResult.STATUS_FINISHED; } - public void sendEmail(String email, String subject, String body, String[] attachments) { - logger.debug(ltag, "Sedning " + email + " s=" + subject + " a=" + attachments[0] + " total="+attachments.length); - String fileData = AppCore.loadFile(attachments[0]); - if (fileData == null) { - setError("Failed to load file: " + attachments[0]); - return; - } + public boolean sendEmail(String email, String subject, String body, String[] attachments, boolean checkOnly) { + String fileData = null; + if (!checkOnly) { + logger.debug(ltag, "Sedning " + email + " s=" + subject + " a=" + attachments[0] + " total="+attachments.length); + fileData = AppCore.loadFile(attachments[0]); + if (fileData == null) { + setError("Failed to load file: " + attachments[0]); + return false; + } + } try { logger.debug(ltag, "Connecting to " + this.host + ":" + this.port); @@ -247,24 +260,23 @@ public void sendEmail(String email, String subject, String body, String[] attach PrintWriter writer = new PrintWriter(output, true); String line; - line = reader.readLine(); - logger.debug(ltag, line); if (!isResponseOk(line, 220)) { setError("Invalid response from Protonmail. Please check the logs"); - return; + socket.close(); + return false; } writer.println("EHLO localhost"); logger.debug(ltag, "EHLO localhost"); while ((line = reader.readLine()) != null) { - logger.debug(ltag, line); if (isInterimResponse(line)) continue; if (!isResponseOk(line, 250)) { setError("Invalid response from Protonmail (EHLO). Please check the logs"); - return; + socket.close(); + return false; } break; @@ -277,10 +289,10 @@ public void sendEmail(String email, String subject, String body, String[] attach logger.debug(ltag, "AUTH LOGIN"); line = reader.readLine(); - logger.debug(ltag, line); if (!isResponseOk(line, 334)) { setError("Invalid response from Protonmail (Login). Please check the logs"); - return; + socket.close(); + return false; } writer.println(login); @@ -289,47 +301,57 @@ public void sendEmail(String email, String subject, String body, String[] attach line = reader.readLine(); if (!isResponseOk(line, 334)) { setError("Invalid response from Protonmail (Login). Please check the logs"); - return; + socket.close(); + return false; } writer.println(password); logger.debug(ltag, password); line = reader.readLine(); - logger.debug(ltag, line); if (!isResponseOk(line, 235)) { setError("Proton auth failed. Please check your credentials"); - return; + socket.close(); + return false; } - + writer.println("MAIL FROM: " + this.mail_from); logger.debug(ltag, "MAIL FROM: " + this.mail_from); line = reader.readLine(); - logger.debug(ltag, line); if (!isResponseOk(line, 250)) { setError("Invalid response from Protonmail (MAIL FROM). Please check the logs"); - return; + socket.close(); + return false; } + + if (checkOnly) { + writer.println("QUIT"); + logger.debug(ltag, "QUIT"); + socket.close(); + return true; + } + + writer.println("RCPT TO: " + email); logger.debug(ltag, "RCPT TO: " + email); line = reader.readLine(); - logger.debug(ltag, line); if (!isResponseOk(line, 250)) { setError("Invalid response from Protonmail (RCPT TO). Please check the logs"); - return; + socket.close(); + return false; } writer.println("DATA"); logger.debug(ltag, "DATA"); line = reader.readLine(); - logger.debug(ltag, line); if (!isResponseOk(line, 354)) { setError("Invalid response from Protonmail (DATA). Please check the logs"); - return; + socket.close(); + return false; } String fname = new File(attachments[0]).getName().replaceAll("@", "_"); @@ -359,27 +381,28 @@ public void sendEmail(String email, String subject, String body, String[] attach writer.println("."); logger.debug(ltag, "."); - line = reader.readLine(); - logger.debug(ltag, line); if (!isResponseOk(line, 250)) { setError("Proton rejected the message. Please check the logs"); - return; + socket.close(); + return false; } writer.println("QUIT"); logger.debug(ltag, "QUIT"); - + socket.close(); } catch (UnknownHostException ex) { logger.error(ltag, "Unknown network error: " + ex.getMessage()); ger.status = EmailerResult.STATUS_ERROR; setError("Unknown network error. Please check the logs"); - return; + return false; } catch (IOException ex) { setError("Failed to connect to the ProtonMail bridge. Make sure it is running"); logger.error(ltag, "Failed to connect to the ProtonMail bridge: " + ex.getMessage()); - return; + return false; } + + return true; } protected String generateBoundary() { @@ -396,6 +419,7 @@ protected String generateBoundary() { private final static char[] MULTIPART_CHARS = "-_1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray(); public boolean isInterimResponse(String response) { + logger.debug(ltag, response); if (response.length() > 3 && response.charAt(3) == '-') return true; diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index 544d86b..3d2228e 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -531,6 +531,8 @@ public void startVaulterService(CallbackInterface cb, String password) { v.vault(password, 0, null, cb); } + + public void startEmailerService(String[] emails, String[] subjects, String[] bodies, String[][] attachments, CallbackInterface icb) { Emailer el = (Emailer) sr.getServant("Emailer"); el.launch(emails, subjects, bodies, attachments, icb); @@ -557,6 +559,19 @@ public void startSecureExporterService(int exportType, int amount, String tag, S v.unvault(password, amount, null, new eVaulterCb(exportType, amount, tag, dir, keepSrc, cb)); } + public String getEmailerError() { + String error = null; + + Emailer el = (Emailer) sr.getServant("Emailer"); + + if (!el.doChecks()) { + error = el.ger.errText; + return error; + } + + return error; + } + public int findNoteToChange(int needed, int b250, int b100, int b25, int b5, int b1) { int totalReturn = 0; int totalNeeded = needed; From 0939bb7968b640c0fed39d6f2ffb325a69e50c04 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Sat, 1 Feb 2020 12:05:43 +0300 Subject: [PATCH 141/160] txt --- src/advclient/AdvancedClient.java | 4 ++-- src/advclient/common/core/AppCore.java | 3 +++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index c14977e..fa06917 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -3055,8 +3055,8 @@ public void showConfirmBillPayScreen() { String v = ""; for (int i = 0; i < ps.billpays.length; i++) { - v += "

" + ps.billpays[i][0] + ": " + ps.billpays[i][1] + ": " + ps.billpays[i][2] + ": " + ps.billpays[i][3] + " : " + ps.billpays[i][4] + " : " + ps.billpays[i][5] + - ": " + ps.billpays[i][6] + ": " + ps.billpays[i][7] + ": " + ps.billpays[i][8] + "


"; + v += "

" + ps.billpays[i][0] + "," + ps.billpays[i][1] + "," + ps.billpays[i][2] + "," + ps.billpays[i][3] + "," + ps.billpays[i][4] + " : " + ps.billpays[i][5] + + "," + ps.billpays[i][6] + "," + ps.billpays[i][7] + "," + ps.billpays[i][8] + "


"; } v+=""; JLabel x = new JLabel(v); diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index cffa276..ab93981 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -822,6 +822,9 @@ public static CloudCoin findCoinBySN(String dir, String user, int sn) { } public static String getReceiptHtml(String hash, String user) { + if (hash == "dummy") + return null; + String receiptsFile = AppCore.getUserDir(Config.DIR_RECEIPTS, user); receiptsFile += File.separator + hash + ".txt"; From 785b18f02d128307f2c275c7639fc4abfe4b7f3c Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Sat, 1 Feb 2020 12:58:37 +0300 Subject: [PATCH 142/160] checks --- src/advclient/AdvancedClient.java | 21 ++++++++++--------- src/advclient/common/Exporter/Exporter.java | 18 ++++++++++++++++ src/advclient/common/core/AppCore.java | 19 +++++++++++------ src/advclient/common/core/ServantManager.java | 8 +++++-- 4 files changed, 48 insertions(+), 18 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index fa06917..cf7d583 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -3803,17 +3803,20 @@ public void actionPerformed(ActionEvent e) { return; } - String err = AppCore.checkBillPays(ps.srcWallet, s); - if (err != null) { - ps.errText = "Parse error: " + err; - showScreen(); - return; - } + setActiveWallet(ps.srcWallet); - infox.setText("Checking Email Gateway..."); + infox.setText("Checking Denominations..."); Thread t = new Thread(new Runnable() { public void run() { - String err = sm.getEmailerError(); + String err = AppCore.checkBillPays(sm, ps.srcWallet, s); + if (err != null) { + ps.errText = "Parse error: " + err; + showScreen(); + return; + } + + infox.setText("Checking Email Gateway..."); + err = sm.getEmailerError(); infox.setText(""); if (err != null) { ps.errText = err; @@ -3822,8 +3825,6 @@ public void run() { } ps.billpays = s; - setActiveWallet(ps.srcWallet); - ps.currentScreen = ProgramState.SCREEN_SHOW_CONFIRM_BILL_PAY; showScreen(); return; diff --git a/src/advclient/common/Exporter/Exporter.java b/src/advclient/common/Exporter/Exporter.java index 6ca6f2d..8b849f2 100644 --- a/src/advclient/common/Exporter/Exporter.java +++ b/src/advclient/common/Exporter/Exporter.java @@ -22,6 +22,8 @@ public class Exporter extends Servant { public Exporter(String rootDir, GLogger logger) { super("Exporter", rootDir, logger); + coinsPicked = new ArrayList(); + valuesPicked = new int[AppCore.getDenominations().length]; } public void launch(CallbackInterface icb) { @@ -80,6 +82,22 @@ public void run() { }); } + public boolean checkCoins(int amount) { + String fullFrackedPath = AppCore.getUserDir(Config.DIR_FRACKED, user); + String fullBankPath = AppCore.getUserDir(Config.DIR_BANK, user); + + boolean rv = pickCoinsAmountInDirs(fullBankPath, fullFrackedPath, amount); + if (rv) + return rv; + + String fullVaultPath = AppCore.getUserDir(Config.DIR_VAULT, user); + rv = pickCoinsAmountInDirs(fullVaultPath, fullFrackedPath, amount); + + + return rv; + + } + public void doExport(int type, int[] values, int amount, String dir, boolean keepSrc, String tag) { if (tag.equals("")) tag = Config.DEFAULT_TAG; diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index ab93981..3245fb8 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -1,5 +1,6 @@ package global.cloudcoin.ccbank.core; +import global.cloudcoin.ccbank.ServantManager.ServantManager; import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.File; @@ -1486,7 +1487,8 @@ public static boolean checkEmailTemplate(String template) { return true; } - public static String checkBillPays(Wallet w, String[][] s) { + public static String checkBillPays(ServantManager sm, Wallet w, String[][] s) { + int globalTotal = 0; for (int i = 0; i < s.length; i++) { String[] line = s[i]; @@ -1514,11 +1516,8 @@ public static String checkBillPays(Wallet w, String[][] s) { if (total == 0) total = s1 + s5 + s25 + s100 + s250; - - if (w.getTotal() < total) { - return "Not enough funds. Required: " + total; - } - + + globalTotal += total; if (!AppCore.checkEmailTemplate(line[8])) { return "Template " + line[8] + " doesn't exist. Line " + (i + 1); } @@ -1526,6 +1525,14 @@ public static String checkBillPays(Wallet w, String[][] s) { } + if (w.getTotal() < globalTotal) { + return "Not enough funds. Required: " + globalTotal; + } + + if (!sm.checkCoins(globalTotal)) { + return "Failed to collect denominations"; + } + return null; } diff --git a/src/advclient/common/core/ServantManager.java b/src/advclient/common/core/ServantManager.java index 3d2228e..1922fe7 100644 --- a/src/advclient/common/core/ServantManager.java +++ b/src/advclient/common/core/ServantManager.java @@ -559,11 +559,15 @@ public void startSecureExporterService(int exportType, int amount, String tag, S v.unvault(password, amount, null, new eVaulterCb(exportType, amount, tag, dir, keepSrc, cb)); } + public boolean checkCoins(int amount) { + Exporter er = (Exporter) sr.getServant("Exporter"); + return er.checkCoins(amount); + } + public String getEmailerError() { String error = null; - Emailer el = (Emailer) sr.getServant("Emailer"); - + Emailer el = (Emailer) sr.getServant("Emailer"); if (!el.doChecks()) { error = el.ger.errText; return error; From e1e82d8581daf26fb1401fcedb279eda1782977b Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Sat, 1 Feb 2020 13:17:29 +0300 Subject: [PATCH 143/160] version --- src/advclient/AdvancedClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index cf7d583..c7a04ac 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -58,7 +58,7 @@ * */ public class AdvancedClient { - String version = "2.1.28"; + String version = "2.1.29"; JPanel headerPanel; JPanel mainPanel; From 46b645a2c699a815dab904aa2bc7d42d30fed071 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 3 Feb 2020 16:56:25 +0300 Subject: [PATCH 144/160] png --- src/advclient/common/Exporter/Exporter.java | 149 ++++++++++++++++++-- src/advclient/common/core/Config.java | 1 + 2 files changed, 138 insertions(+), 12 deletions(-) diff --git a/src/advclient/common/Exporter/Exporter.java b/src/advclient/common/Exporter/Exporter.java index 8b849f2..46eeb83 100644 --- a/src/advclient/common/Exporter/Exporter.java +++ b/src/advclient/common/Exporter/Exporter.java @@ -157,20 +157,21 @@ public void doExport(int type, int[] values, int amount, String dir, boolean kee logger.debug(ltag, "Export isbackup " + keepSrc + " type " + type + " amount " + amount); - if (type == Config.TYPE_STACK) { - if (!keepSrc) { - int totalNotes = coinsPicked.size(); - if (totalNotes > Config.MAX_EXPORTED_NOTES) { - er.status = ExporterResult.STATUS_ERROR; - er.errText = "Exporting more than " + Config.MAX_EXPORTED_NOTES - + " notes is not allowed. Try to export fewer coins"; - if (cb != null) - cb.callback(er); + if (!keepSrc) { + int totalNotes = coinsPicked.size(); + if (totalNotes > Config.MAX_EXPORTED_NOTES) { + er.status = ExporterResult.STATUS_ERROR; + er.errText = "Exporting more than " + Config.MAX_EXPORTED_NOTES + + " notes is not allowed. Try to export fewer coins"; + if (cb != null) + cb.callback(er); - return; - } + return; } - + } + + //type = Config.TYPE_PNG; + if (type == Config.TYPE_STACK) { if (!exportStack(fullExportPath, tag)) { er.status = ExporterResult.STATUS_ERROR; if (cb != null) @@ -186,6 +187,14 @@ public void doExport(int type, int[] values, int amount, String dir, boolean kee return; } + } else if (type == Config.TYPE_PNG) { + if (!exportPng(fullExportPath, tag)) { + er.status = ExporterResult.STATUS_ERROR; + if (cb != null) + cb.callback(er); + + return; + } } else { logger.error(ltag, "Unsupported format"); er.status = ExporterResult.STATUS_ERROR; @@ -286,6 +295,122 @@ private boolean exportJpeg(String dir, String user, String tag) { return true; } + + private boolean exportPng(String dir, String tag) { + StringBuilder sb = new StringBuilder(); + boolean first = true; + int total = 0; + String fileName; + String data; + + sb.append("{" + ls + "\t\"cloudcoin\": ["); + for (CloudCoin cc : coinsPicked) { + if (!first) + sb.append(", "); + + sb.append(cc.getSimpleJson()); + first = false; + + total += cc.getDenomination(); + } + + sb.append("]" + ls + "}"); + data = sb.toString(); + + File sdir = new File(dir); + if (sdir.isDirectory()) { + fileName = total + ".CloudCoin." + tag + ".png"; + fileName = dir + File.separator + fileName; + } else { + fileName = dir; + } + + String tdir = AppCore.getUserDir(Config.DIR_TEMPLATES, user); + File dirObj = new File(tdir); + if (!dirObj.exists()) { + logger.error(ltag, "Template dir doesn't exist: " + tdir); + er.status = ExporterResult.STATUS_ERROR; + er.errText = "Template dir doesn't exist"; + return false; + } + + String templateFileName = null; + for (File file: dirObj.listFiles()) { + if (file.isDirectory()) + continue; + + templateFileName = file.getAbsolutePath(); + if (!templateFileName.endsWith(".png")) { + templateFileName = null; + continue; + } + + break; + } + + logger.debug(ltag, "Picked png template: " + templateFileName); + if (templateFileName == null) { + logger.error(ltag, "Failed to find any png in " + tdir); + er.status = ExporterResult.STATUS_ERROR; + er.errText = "Failed to find any PNG templates"; + return false; + } + + byte[] bytes = AppCore.loadFileToBytes(templateFileName); + if (bytes == null) { + logger.error(ltag, "Failed to load template"); + return false; + } + + logger.info(ltag, "Loaded: " + bytes.length); + int dl = data.length(); + logger.debug(ltag, "data length " + dl); + + byte[] nbytes = new byte[bytes.length + dl + 12]; + for (int i = 0; i < 33; i++) { + nbytes[i] = bytes[i]; + } + + int totalLength = dl + 8; + + nbytes[33] = (byte)(totalLength >> 24); + nbytes[34] = (byte)(totalLength >> 16); + nbytes[35] = (byte)(totalLength >> 8); + nbytes[36] = (byte)(totalLength); + + nbytes[37] = nbytes[38] = nbytes[39] = nbytes[40] = 0x20; + + + + for (int i = 0; i < dl; i++) { + nbytes[i + 41] = (byte) data.charAt(i); + } + + nbytes[41 + dl] = nbytes[41 + dl + 1] = nbytes[41 + dl + 2] = nbytes[41 + dl + 3] = 0x20; + + for (int i = 0; i < bytes.length - 33; i++) { + nbytes[i + 41 + dl + 4] = bytes[i + 33]; + } + + File f = new File(fileName); + if (f.exists()) { + logger.error(ltag, "File exists: " + fileName); + er.status = ExporterResult.STATUS_ERROR; + er.errText = "Exported file with the same tag already exists"; + return false; + } + + if (!AppCore.saveFileFromBytes(fileName, nbytes)) { + logger.error(ltag, "Failed to write file"); + return false; + } + + er.exportedFileNames.add(fileName); + er.totalExported = total; + + return true; + + } private boolean exportStack(String dir, String tag) { StringBuilder sb = new StringBuilder(); diff --git a/src/advclient/common/core/Config.java b/src/advclient/common/core/Config.java index 348df9a..3a04be4 100644 --- a/src/advclient/common/core/Config.java +++ b/src/advclient/common/core/Config.java @@ -111,6 +111,7 @@ public class Config { public static int TYPE_STACK = 1; public static int TYPE_JPEG = 2; public static int TYPE_CSV = 3; + public static int TYPE_PNG = 4; public static String JPEG_MARKER = "01C34A46494600010101006000601D05"; From 730ee454556bbb40c94c3584f98b120455fbe5ce Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 17 Feb 2020 21:10:49 +0300 Subject: [PATCH 145/160] fix --- src/advclient/AdvancedClient.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index c7a04ac..8101bde 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -8158,8 +8158,9 @@ public void run() { if (sr.amount > 0) { wl.debug(ltag, "sramount " + sr.amount + " typed " + ps.typedAmount); - AppCore.appendSkySentCoinTransaction(ps.srcWallet.getName(), - ps.dstWallet.getName(), ps.dstWallet.getIDCoin().sn, sr.amount, ps.typedMemo); + if (ps.dstWallet.getIDCoin() != null) + AppCore.appendSkySentCoinTransaction(ps.srcWallet.getName(), + ps.dstWallet.getName(), ps.dstWallet.getIDCoin().sn, sr.amount, ps.typedMemo); if (ps.typedAmount != sr.amount) { EventQueue.invokeLater(new Runnable() { From 45319e88e2eddaef8ecb938e6bb6ac599b1b134a Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 17 Feb 2020 21:11:31 +0300 Subject: [PATCH 146/160] fix --- src/advclient/AdvancedClient.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 8101bde..3456981 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -58,7 +58,7 @@ * */ public class AdvancedClient { - String version = "2.1.29"; + String version = "2.1.30"; JPanel headerPanel; JPanel mainPanel; From 81989435ef32840b24428a11b730b559387e9aa5 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 17 Feb 2020 22:00:42 +0300 Subject: [PATCH 147/160] negative transactions --- src/advclient/AdvancedClient.java | 2 +- src/advclient/common/core/Config.java | 3 +-- src/advclient/common/core/Wallet.java | 9 ++++----- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 3456981..c959be6 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -7735,7 +7735,7 @@ public void callback(Object result) { } else { memo = "Failed to Import"; } - w.appendTransaction(memo, Config.NEGATIVE_AMOUNT_FOR_COUNTERFEIT, "dummy"); + w.appendTransaction(memo, 0, "COUNTERFEIT"); } EventQueue.invokeLater(new Runnable() { diff --git a/src/advclient/common/core/Config.java b/src/advclient/common/core/Config.java index 3a04be4..9458856 100644 --- a/src/advclient/common/core/Config.java +++ b/src/advclient/common/core/Config.java @@ -196,6 +196,5 @@ public class Config { public static int MAX_EXPORTED_NOTES = 3000; final public static String SENT_SKYCOINS_FILENAME = "sentcoins.csv"; - - final public static int NEGATIVE_AMOUNT_FOR_COUNTERFEIT = -1; + } diff --git a/src/advclient/common/core/Wallet.java b/src/advclient/common/core/Wallet.java index 7df2a3c..b6c8f35 100644 --- a/src/advclient/common/core/Wallet.java +++ b/src/advclient/common/core/Wallet.java @@ -211,11 +211,10 @@ public void appendTransaction(String memo, int amount, String receiptId, String if (isSkyWallet()) return; - if (amount == 0) - return; - - if (amount == Config.NEGATIVE_AMOUNT_FOR_COUNTERFEIT) - amount = 0; + if (!receiptId.equals("COUNTERFEIT")) { + if (amount == 0) + return; + } String fileName = getTransactionsFileName(); String rMemo = memo.replaceAll("\r\n", " ").replaceAll("\n", " ").replaceAll(",", " "); From aa9b4f5572a3a2de30141e90a5996a78862a58dc Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 19 Feb 2020 11:22:24 +0300 Subject: [PATCH 148/160] ui and bugs --- src/advclient/AdvancedClient.java | 27 ++++++++++++++++++++------- src/advclient/AppUI.java | 2 +- 2 files changed, 21 insertions(+), 8 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index c959be6..044b227 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -58,7 +58,7 @@ * */ public class AdvancedClient { - String version = "2.1.30"; + String version = "2.1.31"; JPanel headerPanel; JPanel mainPanel; @@ -658,7 +658,7 @@ public void mouseExited(MouseEvent e) { // Do stuff popup menu final int mWidth = 172; - final int mHeight = 48; + final int mHeight = 42; final JPopupMenu popupMenu = new JPopupMenu() { @Override public void paintComponent(final Graphics g) { @@ -6044,7 +6044,7 @@ public void showTransactionsScreen() { if (isSky) { Hashtable envelopes = sm.getActiveWallet().getEnvelopes(); - thlabel.setText("Skywallet Contents. Click Transfer to Download"); + thlabel.setText("Skywallet Contents "); if (envelopes == null || envelopes.size() == 0) { thlabel.setText("No Coins"); return; @@ -6267,6 +6267,10 @@ public void mouseExited(MouseEvent e) { GridBagLayout gridbag = new GridBagLayout(); subInnerCore.setLayout(gridbag); + int y = 0; + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + AppUI.getTwoButtonPanel(subInnerCore, "Print", "Export History", new ActionListener() { public void actionPerformed(ActionEvent e) { try { @@ -6298,7 +6302,7 @@ public void actionPerformed(ActionEvent e) { } } } - }, 0, gridbag); + }, y, gridbag); } @@ -8158,9 +8162,18 @@ public void run() { if (sr.amount > 0) { wl.debug(ltag, "sramount " + sr.amount + " typed " + ps.typedAmount); - if (ps.dstWallet.getIDCoin() != null) - AppCore.appendSkySentCoinTransaction(ps.srcWallet.getName(), - ps.dstWallet.getName(), ps.dstWallet.getIDCoin().sn, sr.amount, ps.typedMemo); + int sn = 0; + String name; + if (ps.dstWallet == null) { + sn = ps.foundSN; + name = ps.typedRemoteWallet; + } else { + sn = ps.dstWallet.getIDCoin().sn; + name = ps.dstWallet.getName(); + } + AppCore.appendSkySentCoinTransaction(ps.srcWallet.getName(), + name, sn, sr.amount, ps.typedMemo); + if (ps.typedAmount != sr.amount) { EventQueue.invokeLater(new Runnable() { diff --git a/src/advclient/AppUI.java b/src/advclient/AppUI.java index a1b52be..3aa2a61 100644 --- a/src/advclient/AppUI.java +++ b/src/advclient/AppUI.java @@ -150,7 +150,7 @@ public static Color getColor1() { } public static Color getColor2() { - return new Color(0x2492E7); + return new Color(0x338FFF); } public static Color getColor3() { From d293129a909fc8267348995c3238059797f9b029 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Wed, 19 Feb 2020 18:52:58 +0300 Subject: [PATCH 149/160] fx --- src/advclient/AdvancedClient.java | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 044b227..c965a59 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -58,7 +58,7 @@ * */ public class AdvancedClient { - String version = "2.1.31"; + String version = "2.1.32"; JPanel headerPanel; JPanel mainPanel; @@ -8168,11 +8168,14 @@ public void run() { sn = ps.foundSN; name = ps.typedRemoteWallet; } else { - sn = ps.dstWallet.getIDCoin().sn; + if (ps.dstWallet.getIDCoin() != null) + sn = ps.dstWallet.getIDCoin().sn; name = ps.dstWallet.getName(); } - AppCore.appendSkySentCoinTransaction(ps.srcWallet.getName(), - name, sn, sr.amount, ps.typedMemo); + + if (sn != 0) + AppCore.appendSkySentCoinTransaction(ps.srcWallet.getName(), + name, sn, sr.amount, ps.typedMemo); if (ps.typedAmount != sr.amount) { From f542db56e0895bf264089d53157b16854429b174 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Fri, 28 Feb 2020 16:21:32 +0300 Subject: [PATCH 150/160] dark export --- src/advclient/AdvancedClient.java | 472 ++++++++++++++++++-- src/advclient/ProgramState.java | 8 +- src/advclient/common/Exporter/Exporter.java | 62 +-- src/advclient/common/Unpacker/Unpacker.java | 90 +++- src/advclient/common/core/AppCore.java | 183 ++++++-- src/advclient/common/core/Config.java | 5 +- src/resources/withdrawicon.png | Bin 0 -> 4245 bytes src/resources/withdrawiconlight.png | Bin 0 -> 4267 bytes 8 files changed, 695 insertions(+), 125 deletions(-) create mode 100644 src/resources/withdrawicon.png create mode 100644 src/resources/withdrawiconlight.png diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index c965a59..e984bf1 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -58,7 +58,7 @@ * */ public class AdvancedClient { - String version = "2.1.32"; + String version = "2.1.33"; JPanel headerPanel; JPanel mainPanel; @@ -136,6 +136,7 @@ public void initSystem() { } AppCore.readConfig(); + AppCore.copyTemplatesFromJar(); resetState(); } @@ -283,8 +284,6 @@ public void initSystemUser() { ps.errText = "Failed to init Wallet"; return; } - - //AppCore.copyTemplatesFromJar(ps.typedWalletName); } public boolean isActiveWallet(Wallet wallet) { @@ -361,8 +360,8 @@ public boolean isDepositing() { return false; } - public boolean isWithdrawing() { - if (ps.currentScreen == ProgramState.SCREEN_WITHDRAW || + public boolean isTransferring() { + if (ps.currentScreen == ProgramState.SCREEN_TRANSFER || ps.currentScreen == ProgramState.SCREEN_CONFIRM_TRANSFER || ps.currentScreen == ProgramState.SCREEN_SENDING || ps.currentScreen == ProgramState.SCREEN_TRANSFER_DONE) @@ -371,6 +370,14 @@ public boolean isWithdrawing() { return false; } + public boolean isWithdrawing() { + if (ps.currentScreen == ProgramState.SCREEN_WITHDRAW || + ps.currentScreen == ProgramState.SCREEN_CONFIRM_WITHDRAW) + return true; + + return false; + } + public boolean isFixing() { if (ps.currentScreen == ProgramState.SCREEN_FIX_FRACKED || ps.currentScreen == ProgramState.SCREEN_FIXING_FRACKED || @@ -425,8 +432,8 @@ public void fillHeaderPanel() { JLabel icon0, icon1, icon2, icon3; - final JLabel depositIcon, transferIcon, coinsIcon; - final ImageIcon depositIi, transferIi, depositIiLight, transferIiLight; + final JLabel depositIcon, transferIcon, withdrawIcon, coinsIcon; + final ImageIcon depositIi, transferIi, withdrawIi, depositIiLight, transferIiLight, withdrawIiLight; ImageIcon ii; try { Image img; @@ -448,6 +455,11 @@ public void fillHeaderPanel() { depositIi = new ImageIcon(img); depositIcon = new JLabel(new ImageIcon(img)); + img = ImageIO.read(getClass().getClassLoader().getResource("resources/withdrawicon.png")); + withdrawIi = new ImageIcon(img); + withdrawIcon = new JLabel(new ImageIcon(img)); + + img = ImageIO.read(getClass().getClassLoader().getResource("resources/transfericon.png")); transferIi = new ImageIcon(img); transferIcon = new JLabel(new ImageIcon(img)); @@ -461,6 +473,9 @@ public void fillHeaderPanel() { img = ImageIO.read(getClass().getClassLoader().getResource("resources/transfericonlight.png")); transferIiLight = new ImageIcon(img); + img = ImageIO.read(getClass().getClassLoader().getResource("resources/withdrawiconlight.png")); + withdrawIiLight = new ImageIcon(img); + } catch (Exception ex) { wl.error(ltag, "Failed to open file: " + ex.getMessage()); return; @@ -502,7 +517,7 @@ public void fillHeaderPanel() { return; } else { - int bwidth = 168; + int bwidth = 158; // Coins wrp.add(coinsIcon); wrp.add(AppUI.vr(16)); @@ -521,7 +536,7 @@ public void fillHeaderPanel() { AppUI.setMargin(titleText, 0, 6, 16, 0); wrp.add(titleText); - c.insets = new Insets(0, 32, 0, 0); + c.insets = new Insets(0, 2, 0, 0); c.anchor = GridBagConstraints.NORTH; gridbag.setConstraints(wrp, c); p.add(wrp); @@ -539,11 +554,9 @@ public void fillHeaderPanel() { if (isDepositing()) { depositIcon.setIcon(depositIiLight); AppUI.opaque(wrpDeposit); - } else { AppUI.setHandCursor(wrpDeposit); depositIcon.setIcon(depositIi); - } wrpDeposit.add(AppUI.vr(6)); @@ -552,11 +565,45 @@ public void fillHeaderPanel() { AppUI.setTitleFont(titleText, 20); wrpDeposit.add(titleText); - c.insets = new Insets(0, 32, 0, 0); + c.insets = new Insets(0, 2, 0, 0); c.anchor = GridBagConstraints.NORTH; gridbag.setConstraints(wrpDeposit, c); p.add(wrpDeposit); - + + + + // Withdraw + JPanel wrpWithdraw = new JPanel(); + AppUI.setBoxLayout(wrpWithdraw, false); + AppUI.setSize(wrpWithdraw, bwidth, headerHeight); + AppUI.setBackground(wrpWithdraw, AppUI.getColor1()); + AppUI.noOpaque(wrpWithdraw); + + wrpWithdraw.add(AppUI.vr(12)); + + wrpWithdraw.add(withdrawIcon); + if (isWithdrawing()) { + depositIcon.setIcon(withdrawIiLight); + AppUI.opaque(wrpWithdraw); + } else { + AppUI.setHandCursor(wrpWithdraw); + depositIcon.setIcon(withdrawIi); + } + + wrpWithdraw.add(AppUI.vr(6)); + + titleText = new JLabel("Withdraw"); + AppUI.setTitleFont(titleText, 20); + wrpWithdraw.add(titleText); + + c.insets = new Insets(0, 2, 0, 0); + c.anchor = GridBagConstraints.NORTH; + gridbag.setConstraints(wrpWithdraw, c); + p.add(wrpWithdraw); + + + + // Transfer JPanel wrpTransfer = new JPanel(); AppUI.setBoxLayout(wrpTransfer, false); @@ -566,7 +613,7 @@ public void fillHeaderPanel() { wrpTransfer.add(AppUI.vr(12)); - if (isWithdrawing()) { + if (isTransferring()) { transferIcon.setIcon(transferIiLight); AppUI.opaque(wrpTransfer); } else { @@ -581,7 +628,7 @@ public void fillHeaderPanel() { AppUI.setTitleFont(titleText, 20); wrpTransfer.add(titleText); - c.insets = new Insets(0, 32, 0, 0); + c.insets = new Insets(0, 2, 0, 0); c.anchor = GridBagConstraints.NORTH; gridbag.setConstraints(wrpTransfer, c); p.add(wrpTransfer); @@ -589,7 +636,9 @@ public void fillHeaderPanel() { MouseAdapter ma0 = new MouseAdapter() { public void mouseReleased(MouseEvent e) { resetState(); - ps.currentScreen = ProgramState.SCREEN_PREDEPOSIT; + //ps.currentScreen = ProgramState.SCREEN_PREDEPOSIT; + ps.isSkyDeposit = false; + ps.currentScreen = ProgramState.SCREEN_DEPOSIT; showScreen(); } public void mouseEntered(MouseEvent e) { @@ -614,7 +663,7 @@ public void mouseExited(MouseEvent e) { MouseAdapter ma1 = new MouseAdapter() { public void mouseReleased(MouseEvent e) { resetState(); - ps.currentScreen = ProgramState.SCREEN_WITHDRAW; + ps.currentScreen = ProgramState.SCREEN_TRANSFER; showScreen(); } @@ -627,7 +676,7 @@ public void mouseEntered(MouseEvent e) { } public void mouseExited(MouseEvent e) { JPanel p = (JPanel) e.getSource(); - if (!isWithdrawing()) { + if (!isTransferring()) { AppUI.noOpaque(p); transferIcon.setIcon(transferIi); p.revalidate(); @@ -635,12 +684,38 @@ public void mouseExited(MouseEvent e) { } } }; + + MouseAdapter ma2 = new MouseAdapter() { + public void mouseReleased(MouseEvent e) { + resetState(); + ps.currentScreen = ProgramState.SCREEN_WITHDRAW; + showScreen(); + } + + public void mouseEntered(MouseEvent e) { + JPanel p = (JPanel) e.getSource(); + AppUI.opaque(p); + withdrawIcon.setIcon(withdrawIiLight); + p.revalidate(); + p.repaint(); + } + public void mouseExited(MouseEvent e) { + JPanel p = (JPanel) e.getSource(); + if (!isWithdrawing()) { + AppUI.noOpaque(p); + withdrawIcon.setIcon(withdrawIi); + p.revalidate(); + p.repaint(); + } + } + }; wrpDeposit.addMouseListener(ma0); wrpTransfer.addMouseListener(ma1); + wrpWithdraw.addMouseListener(ma2); } - c.insets = new Insets(0, 42, 0, 0); + c.insets = new Insets(0, 32, 0, 0); c.gridwidth = 1; c.weightx = 0; c.fill = GridBagConstraints.NORTH; @@ -921,7 +996,7 @@ public void showScreen() { ps.currentWallet = null; showDepositScreen(); break; - case ProgramState.SCREEN_WITHDRAW: + case ProgramState.SCREEN_TRANSFER: ps.currentWallet = null; showTransferScreen(); break; @@ -1042,6 +1117,13 @@ public void showScreen() { case ProgramState.SCREEN_DOING_BILL_PAY: showSendingBillPayScreen(); break; + case ProgramState.SCREEN_WITHDRAW: + showWithdrawScreen(); + break; + case ProgramState.SCREEN_CONFIRM_WITHDRAW: + showConfirmWithdrawScreen(); + break; + @@ -2341,7 +2423,7 @@ public void showTransferDoneScreen() { AppUI.getTwoButtonPanel(subInnerCore, "Next Transfer", "Continue", new ActionListener() { public void actionPerformed(ActionEvent e) { resetState(); - ps.currentScreen = ProgramState.SCREEN_WITHDRAW; + ps.currentScreen = ProgramState.SCREEN_TRANSFER; showScreen(); } }, new ActionListener() { @@ -3215,6 +3297,83 @@ public void actionPerformed(ActionEvent e) { } + public void showConfirmWithdrawScreen() { + int y = 0; + JLabel fname, value; + MyTextField walletName = null; + + JPanel subInnerCore = getPanel("Withdraw Confirmation"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + String total = AppCore.formatNumber(ps.statToBankValue + ps.statFailedValue + ps.statLostValue); + String totalBankValue = AppCore.formatNumber(ps.statToBankValue); + String totalFailedValue = AppCore.formatNumber(ps.statFailedValue); + String totalLostValue = AppCore.formatNumber(ps.statLostValue); + + fname = new JLabel("Do you wish to continue?"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + + //fname = AppUI.wrapDiv("Deposited " + total + " CloudCoins to " + ps.dstWallet.getName() + " "); + JLabel fromLabel = new JLabel("From: "); + JLabel fromValue = new JLabel(ps.srcWallet.getName()); + AppUI.getGBRow(subInnerCore, fromLabel, fromValue, y, gridbag); + y++; + + + JLabel toLabel = new JLabel("To: "); + String to = ps.chosenFile; + if (to.length() > 24) { + to = to.substring(0, 24) + "..."; + } + JLabel toValue = new JLabel(to); + AppUI.getGBRow(subInnerCore, toLabel, toValue, y, gridbag); + y++; + + + fname = new JLabel("Amount: "); + JLabel amountValue = new JLabel(ps.typedAmount + " CC"); + AppUI.getGBRow(subInnerCore, fname, amountValue, y, gridbag); + y++; + + String memo = ps.typedMemo; + if (memo.length() > 24) { + memo = memo.substring(0, 24) + "..."; + } + + fname = new JLabel("Memo: "); + JLabel memoValue = new JLabel(memo); + AppUI.getGBRow(subInnerCore, fname, memoValue, y, gridbag); + y++; + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Confirm", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.srcWallet.setPassword(ps.typedSrcPassword); + + sm.setActiveWalletObj(ps.srcWallet); + ps.isSkyDeposit = false; + ps.currentScreen = ProgramState.SCREEN_EXPORTING; + if (ps.srcWallet.isEncrypted()) { + sm.startSecureExporterService(Config.TYPE_STACK, ps.typedAmount, ps.typedMemo, ps.chosenFile, false, new ExporterCb()); + } else { + sm.startExporterService(Config.TYPE_STACK, ps.typedAmount, ps.typedMemo, ps.chosenFile, false, new ExporterCb()); + } + + showScreen(); + } + }, y, gridbag); + + } + public void showSetEmailScreen() { int y = 0; @@ -3838,6 +3997,255 @@ public void run() { } + public void showWithdrawScreen() { + int y = 0; + JLabel fname; + MyTextField walletName = null; + + JPanel subInnerCore = getPanel("Transfer"); + GridBagLayout gridbag = new GridBagLayout(); + subInnerCore.setLayout(gridbag); + + final optRv rvFrom = setOptionsForWalletsCommon(false, false, false, null); + if (rvFrom.idxs.length == 0) { + fname = AppUI.wrapDiv("No Wallets to Withdraw From"); + AppUI.getGBRow(subInnerCore, null, fname, y, gridbag); + y++; + AppUI.GBPad(subInnerCore, y, gridbag); + return; + } + + final optRv rvTo = setOptionsForWalletsAll(null); + + + fname = new JLabel("Withdraw From"); + final RoundedCornerComboBox cboxfrom = new RoundedCornerComboBox(AppUI.getColor6(), "Make Selection", rvFrom.options); + AppUI.getGBRow(subInnerCore, fname, cboxfrom.getComboBox(), y, gridbag); + y++; + + final JLabel spText = new JLabel("Password");; + final MyTextField passwordSrc = new MyTextField("Wallet Password", true); + AppUI.getGBRow(subInnerCore, spText, passwordSrc.getTextField(), y, gridbag); + y++; + + passwordSrc.getTextField().setVisible(false); + spText.setVisible(false); + + if (ps.chosenFile.isEmpty()) + ps.chosenFile = Config.DEFAULT_EXPORT_DIR; + + final JLabel lfText = new JLabel("Local folder"); + final JFileChooser chooser = new JFileChooser(); + chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + chooser.setAcceptAllFileFilterUsed(false); + + final MyTextField localFolder = new MyTextField("Select Folder", false, true); + localFolder.setData(new File(ps.chosenFile).getName()); + localFolder.setFilepickerListener(new MouseAdapter() { + @Override + public void mouseReleased(MouseEvent e) { + if (!Config.DEFAULT_EXPORT_DIR.isEmpty()) + chooser.setCurrentDirectory(new File(Config.DEFAULT_EXPORT_DIR)); + + int returnVal = chooser.showOpenDialog(null); + if (returnVal == JFileChooser.APPROVE_OPTION) { + ps.chosenFile = chooser.getSelectedFile().getAbsolutePath(); + localFolder.setData(chooser.getSelectedFile().getName()); + Config.DEFAULT_EXPORT_DIR = ps.chosenFile; + AppCore.writeConfig(); + } + } + }); + AppUI.getGBRow(subInnerCore, lfText, localFolder.getTextField(), y, gridbag); + y++; + + fname = new JLabel("Amount"); + final MyTextField amount = new MyTextField("0 CC", false); + if (ps.typedAmount > 0) + amount.setData("" + ps.typedAmount); + AppUI.getGBRow(subInnerCore, fname, amount.getTextField(), y, gridbag); + y++; + + + fname = new JLabel("Memo (Note)"); + final MyTextField memo = new MyTextField("Optional", false); + if (!ps.typedMemo.isEmpty()) + memo.setData(ps.typedMemo); + AppUI.getGBRow(subInnerCore, fname, memo.getTextField(), y, gridbag); + y++; + + fname = new JLabel("Format"); + final RoundedCornerComboBox boxformat = new RoundedCornerComboBox(AppUI.getColor6(), "Make Selection", new String[]{"Stack", "PNG", "JPEG"} ); + AppUI.getGBRow(subInnerCore, fname, boxformat.getComboBox(), y, gridbag); + boxformat.setDefaultIdx(1); + y++; + + + AppUI.GBPad(subInnerCore, y, gridbag); + y++; + + cboxfrom.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent e) { + int srcIdx = cboxfrom.getSelectedIndex() - 1; + if (srcIdx < 0 || srcIdx >= wallets.length) + return; + + srcIdx = rvFrom.idxs[srcIdx]; + Wallet srcWallet = wallets[srcIdx]; + if (srcWallet == null) + return; + + if (srcWallet.isEncrypted()) { + passwordSrc.getTextField().setVisible(true); + spText.setVisible(true); + } else { + passwordSrc.getTextField().setVisible(false); + spText.setVisible(false); + } + } + }); + + if (ps.srcWallet != null && ps.selectedFromIdx > 0) { + cboxfrom.setDefaultIdx(ps.selectedFromIdx); + } + + AppUI.getTwoButtonPanel(subInnerCore, "Cancel", "Continue", new ActionListener() { + public void actionPerformed(ActionEvent e) { + ps.currentScreen = ProgramState.SCREEN_DEFAULT; + showScreen(); + } + }, new ActionListener() { + public void actionPerformed(ActionEvent e) { + + ps.typedMemo = memo.getText().trim(); + + int srcIdx = cboxfrom.getSelectedIndex() - 1; + ps.selectedFromIdx = cboxfrom.getSelectedIndex(); + if (srcIdx < 0 || srcIdx >= rvFrom.idxs.length) { + ps.errText = "Please select From Wallet"; + showScreen(); + return; + } + + srcIdx = rvFrom.idxs[srcIdx]; + Wallet srcWallet = wallets[srcIdx]; + ps.srcWallet = srcWallet; + + + try { + ps.typedAmount = Integer.parseInt(amount.getText()); + } catch (NumberFormatException ex) { + ps.errText = "Invalid amount"; + showScreen(); + return; + }; + + if (ps.typedAmount <= 0) { + ps.errText = "Transfer must be higher than zero"; + showScreen(); + return; + } + + if (!Validator.memoLength(ps.typedMemo)) { + ps.errText = "Memo too long. Only 64 characters are allowed"; + showScreen(); + return; + } + + ps.typedMemo = ps.typedMemo.trim(); + if (!ps.typedMemo.isEmpty()) { + if (!Validator.memo(ps.typedMemo)) { + ps.errText = "Memo: special characters not allowed! Use numbers and letters only"; + showScreen(); + return; + } + } + + if (srcWallet.isEncrypted()) { + if (passwordSrc.getText().isEmpty()) { + ps.errText = "From Password is empty"; + showScreen(); + return; + } + + String wHash = srcWallet.getPasswordHash(); + String providedHash = AppCore.getMD5(passwordSrc.getText()); + if (wHash == null) { + ps.errText = "From Wallet is corrupted"; + showScreen(); + return; + } + + if (!wHash.equals(providedHash)) { + ps.errText = "From Password is incorrect"; + showScreen(); + return; + } + + ps.typedSrcPassword = passwordSrc.getText(); + } + + if (ps.typedAmount > srcWallet.getTotal()) { + ps.errText = "Insufficient funds"; + showScreen(); + return; + } + + if (ps.typedMemo.isEmpty()) + ps.typedMemo = "Export"; + + if (!Validator.memo(ps.typedMemo)) { + ps.errText = "Memo: special characters not allowed! Use numbers and letters only"; + showScreen(); + return; + } + + ps.typedMemo = ps.typedMemo.trim(); + + // Local folder + if (ps.chosenFile.isEmpty()) { + ps.errText = "Folder is not chosen"; + showScreen(); + return; + } + + if (ps.srcWallet.isSkyWallet()) { + ps.errText = "Withdraw from Sky Wallet to Local Folder is not supported"; + showScreen(); + return; + } + + + + String filename = ps.chosenFile + File.separator + ps.typedAmount + ".CloudCoin." + ps.typedMemo + ".stack"; + File f = new File(filename); + if (f.exists()) { + ps.errText = "File with the same Memo already exists in " + + ps.chosenFile + " folder. Use different Memo or change folder for your transfer"; + showScreen(); + return; + } + + int ftype = boxformat.getSelectedIndex(); + if (ftype == 1) + ps.exportType = Config.TYPE_STACK; + else if (ftype == 2) + ps.exportType = Config.TYPE_PNG; + else if (ftype == 3) + ps.exportType = Config.TYPE_JPEG; + + ps.sendType = ProgramState.SEND_TYPE_FOLDER; + + setActiveWallet(ps.srcWallet); + ps.currentScreen = ProgramState.SCREEN_CONFIRM_WITHDRAW; + showScreen(); + + return; + } + }, y, gridbag); + + } + public void showTransferScreen() { int y = 0; JLabel fname; @@ -3875,7 +4283,7 @@ public void showTransferScreen() { fname = new JLabel("Transfer To"); final RoundedCornerComboBox cboxto = new RoundedCornerComboBox(AppUI.getColor6(), "Make Selection", rvTo.options); cboxto.addOption(AppUI.getRemoteUserOption()); - cboxto.addOption(AppUI.getLocalFolderOption()); + //cboxto.addOption(AppUI.getLocalFolderOption()); AppUI.getGBRow(subInnerCore, fname, cboxto.getComboBox(), y, gridbag); y++; @@ -3973,7 +4381,7 @@ public void actionPerformed(ActionEvent e) { rvTo.options = lrvTo.options; cboxto.setOptions(rvTo.options); cboxto.addOption(AppUI.getRemoteUserOption()); - cboxto.addOption(AppUI.getLocalFolderOption()); + //cboxto.addOption(AppUI.getLocalFolderOption()); cboxto.setDefault(value); } }); @@ -4622,7 +5030,7 @@ public void actionPerformed(ActionEvent e) { public void filesDropped( java.io.File[] files ) { for( int i = 0; i < files.length; i++ ) { if (!AppCore.hasCoinExtension(files[i])) { - ps.errText = "File must have .jpeg or .stack extension"; + ps.errText = "File must have .png .jpeg or .stack extension"; showScreen(); return; } @@ -6471,7 +6879,7 @@ public void showCheckingSkyIDScreen() { public void showExportingScreen() { - JPanel subInnerCore = getPanel("Exporting Coins. Please wait..."); + JPanel subInnerCore = getPanel("Withdrawing Coins. Please wait..."); AppUI.hr(subInnerCore, 4); } @@ -7611,7 +8019,7 @@ public void callback(Object result) { wl.debug(ltag, "AuthenticatorSkyCoin finished"); final Object fresult = result; - if (isWithdrawing()) + if (isTransferring()) ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; else ps.currentScreen = ProgramState.SCREEN_IMPORT_DONE; @@ -7775,7 +8183,7 @@ public void callback(Object result) { EventQueue.invokeLater(new Runnable() { public void run() { ps.errText = "Operation Cancelled"; - if (isWithdrawing()) + if (isTransferring()) ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; else ps.currentScreen = ProgramState.SCREEN_IMPORT_DONE; @@ -7965,7 +8373,7 @@ public void callback(final Object result) { public void run() { if (isDepositing()) { ps.currentScreen = ProgramState.SCREEN_IMPORT_DONE; - } else if (isWithdrawing() || isMakingChange()) { + } else if (isTransferring() || isMakingChange()) { ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; } else if (isFixing()) { ps.currentScreen = ProgramState.SCREEN_FIX_DONE; @@ -8008,7 +8416,7 @@ public void run() { wl.debug(ltag, "Failed to fix. Trying to move the coin back"); cc = AppCore.findCoinBySN(Config.DIR_FRACKED, ps.srcWallet.getName(), ps.coinIDinFix.getIDCoin().sn); if (cc == null) { - ps.currentScreen = ProgramState.SCREEN_WITHDRAW; + ps.currentScreen = ProgramState.SCREEN_TRANSFER; ps.errText = "Failed to find fixed coin. Please, check main.log file"; showScreen(); return; @@ -8020,13 +8428,13 @@ public void run() { wl.debug(ltag, "Found cc: " + cc.originalFile); if (!AppCore.moveToFolderNewName(cc.originalFile, AppCore.getIDDir(), null, ps.coinIDinFix.getName() + ".stack")) { - ps.currentScreen = ProgramState.SCREEN_WITHDRAW; + ps.currentScreen = ProgramState.SCREEN_TRANSFER; ps.errText = "Failed to move ID Coin. Please, check main.log file"; showScreen(); return; } - ps.currentScreen = ProgramState.SCREEN_WITHDRAW; + ps.currentScreen = ProgramState.SCREEN_TRANSFER; if (fixed) ps.errText = "ID Coin has been fixed. Please try again"; else @@ -8060,7 +8468,7 @@ public void run() { if (isFixing()) { ps.currentScreen = ProgramState.SCREEN_FIX_DONE; } else { - if (isWithdrawing()) + if (isTransferring()) ps.currentScreen = ProgramState.SCREEN_TRANSFER_DONE; else ps.currentScreen = ProgramState.SCREEN_IMPORT_DONE; diff --git a/src/advclient/ProgramState.java b/src/advclient/ProgramState.java index b9fba50..dfa05b3 100644 --- a/src/advclient/ProgramState.java +++ b/src/advclient/ProgramState.java @@ -27,7 +27,7 @@ public class ProgramState { final public static int SCREEN_CREATE_SKY_WALLET = 9; final public static int SCREEN_SHOW_TRANSACTIONS = 10; final public static int SCREEN_DEPOSIT = 11; - final public static int SCREEN_WITHDRAW = 12; + final public static int SCREEN_TRANSFER = 12; final public static int SCREEN_IMPORTING = 13; final public static int SCREEN_IMPORT_DONE = 14; final public static int SCREEN_SUPPORT = 15; @@ -70,8 +70,8 @@ public class ProgramState { final public static int SCREEN_SHOW_CONFIRM_BILL_PAY = 52; final public static int SCREEN_DOING_BILL_PAY = 53; final public static int SCREEN_BILL_PAY_DONE = 54; - - + final public static int SCREEN_WITHDRAW = 55; + final public static int SCREEN_CONFIRM_WITHDRAW = 56; final static int CB_STATE_INIT = 1; @@ -173,6 +173,7 @@ public class ProgramState { boolean finishedMc; + int exportType; public ProgramState() { currentScreen = SCREEN_AGREEMENT; @@ -252,6 +253,7 @@ public ProgramState() { finishedMc = false; + exportType = 0; } public String toString() { diff --git a/src/advclient/common/Exporter/Exporter.java b/src/advclient/common/Exporter/Exporter.java index 46eeb83..0c37328 100644 --- a/src/advclient/common/Exporter/Exporter.java +++ b/src/advclient/common/Exporter/Exporter.java @@ -228,11 +228,11 @@ private void deletePickedCoins() { } private boolean exportJpeg(String dir, String user, String tag) { - String templateDir = AppCore.getUserDir(Config.DIR_TEMPLATES, user); + String templateDir = AppCore.getTemplateDir(); String fileName; StringBuilder sb; - sb = new StringBuilder(); + byte[] bytes; for (CloudCoin cc : coinsPicked) { @@ -247,6 +247,7 @@ private boolean exportJpeg(String dir, String user, String tag) { logger.info(ltag, "Loaded: " + bytes.length); + sb = new StringBuilder(); // Ans for (int i = 0; i < RAIDA.TOTAL_RAIDA_COUNT; i++) { sb.append(cc.ans[i]); @@ -270,14 +271,13 @@ private boolean exportJpeg(String dir, String user, String tag) { // SN sb.append(AppCore.padString(Integer.toHexString(cc.sn).toUpperCase(), 6, '0')); - byte[] ccArray = AppCore.hexStringToByteArray(sb.toString()); int offset = 20; for (int j =0; j < ccArray.length; j++) { bytes[offset + j] = ccArray[j]; } - fileName = cc.getDenomination() + ".CloudCoin." + tag + ".jpeg"; + fileName = cc.getDenomination() + "." + cc.sn + ".CloudCoin." + tag + ".jpeg"; fileName = dir + File.separator + fileName; logger.info(ltag, "saving bytes " + bytes.length); @@ -290,8 +290,6 @@ private boolean exportJpeg(String dir, String user, String tag) { er.exportedFileNames.add(fileName); } - - return true; } @@ -325,7 +323,7 @@ private boolean exportPng(String dir, String tag) { fileName = dir; } - String tdir = AppCore.getUserDir(Config.DIR_TEMPLATES, user); + String tdir = AppCore.getTemplateDir(); File dirObj = new File(tdir); if (!dirObj.exists()) { logger.error(ltag, "Template dir doesn't exist: " + tdir); @@ -362,34 +360,43 @@ private boolean exportPng(String dir, String tag) { return false; } - logger.info(ltag, "Loaded: " + bytes.length); + int idx = AppCore.basicPngChecks(bytes); + if (idx == -1) { + logger.error(ltag, "PNG checks failed"); + return false; + } + + logger.info(ltag, "Loaded, bytes: " + bytes.length); int dl = data.length(); + int chunkLength = dl + 12; logger.debug(ltag, "data length " + dl); - - byte[] nbytes = new byte[bytes.length + dl + 12]; - for (int i = 0; i < 33; i++) { + byte[] nbytes = new byte[bytes.length + chunkLength]; + for (int i = 0; i < idx + 4; i++) { nbytes[i] = bytes[i]; } - int totalLength = dl + 8; - - nbytes[33] = (byte)(totalLength >> 24); - nbytes[34] = (byte)(totalLength >> 16); - nbytes[35] = (byte)(totalLength >> 8); - nbytes[36] = (byte)(totalLength); - - nbytes[37] = nbytes[38] = nbytes[39] = nbytes[40] = 0x20; - - + // Setting up the chunk + // Set length + AppCore.setUint32(nbytes, idx + 4, dl); + // Header cLDc + nbytes[idx + 4 + 4] = 0x63; + nbytes[idx + 4 + 5] = 0x4c; + nbytes[idx + 4 + 6] = 0x44; + nbytes[idx + 4 + 7] = 0x63; + for (int i = 0; i < dl; i++) { - nbytes[i + 41] = (byte) data.charAt(i); + nbytes[i + idx + 4 + 8] = (byte) data.charAt(i); } + + // crc + long crc32 = AppCore.crc32(nbytes, idx + 8, dl + 4); + AppCore.setUint32(nbytes, idx + 8 + dl + 4, crc32); + logger.debug(ltag, "crc32 " + crc32); - nbytes[41 + dl] = nbytes[41 + dl + 1] = nbytes[41 + dl + 2] = nbytes[41 + dl + 3] = 0x20; - - for (int i = 0; i < bytes.length - 33; i++) { - nbytes[i + 41 + dl + 4] = bytes[i + 33]; + // Rest data + for (int i = 0; i < bytes.length - idx - 4; i++) { + nbytes[i + idx + 8 + dl + 4 + 4] = bytes[i + idx + 4]; } File f = new File(fileName); @@ -408,8 +415,7 @@ private boolean exportPng(String dir, String tag) { er.exportedFileNames.add(fileName); er.totalExported = total; - return true; - + return true; } private boolean exportStack(String dir, String tag) { diff --git a/src/advclient/common/Unpacker/Unpacker.java b/src/advclient/common/Unpacker/Unpacker.java index 5580c80..3709b0c 100644 --- a/src/advclient/common/Unpacker/Unpacker.java +++ b/src/advclient/common/Unpacker/Unpacker.java @@ -22,6 +22,7 @@ import global.cloudcoin.ccbank.core.RAIDA; import global.cloudcoin.ccbank.core.Servant; import java.util.ArrayList; +import java.util.Arrays; public class Unpacker extends Servant { String ltag = "Unpacker"; @@ -139,7 +140,9 @@ public void doUnpack() { } else if (extension.equals("stack")) { rv = doUnpackStack(file.toString()); } else if (extension.equals("coin")) { - rv = doUnpackBinary(file.toString()); + rv = doUnpackBinary(file.toString()); + } else if (extension.equals("png")) { + rv = doUnpackPng(file.toString()); } else { rv = doUnpackStack(file.toString()); } @@ -236,17 +239,6 @@ public boolean saveCoin(CloudCoin cc) { if (f.exists()) { logger.info(ltag, "File " + path + " already exists. Deleting the old version"); AppCore.deleteFile(path); - /* - path = AppCore.getUserDir(Config.DIR_TRASH, user) + File.separator + System.currentTimeMillis() + - "-" + fileName; - - if (!AppCore.saveFile(path, json)) { - logger.error(ltag, "Failed to save file in Trash: " + path); - return false; - } - - return true; - */ } if (!AppCore.saveFile(path, json)) { @@ -286,6 +278,80 @@ public boolean doUnpackJpeg(String fileName) { return true; } + + + public boolean doUnpackPng(String fileName) { + logger.info(ltag, "Unpacking png"); + + CloudCoin[] ccs; + + byte[] bytes = AppCore.loadFileToBytes(fileName); + if (bytes == null) { + logger.error(ltag, "Failed to load file " + fileName); + return false; + } + + int idx = AppCore.basicPngChecks(bytes); + if (idx == -1) { + logger.error(ltag, "PNG is corrupted"); + return false; + } + + int i = 0; + long length; + + while (true) { + length = AppCore.getUint32(bytes, idx + 4 + i); + if (length == 0) { + i += 12; + if (i > bytes.length) { + logger.error(ltag, "CloudCoin was not found"); + return false; + } + } + + StringBuilder sb = new StringBuilder(); + sb.append(Character.toChars(bytes[idx + 4 + i + 4])); + sb.append(Character.toChars(bytes[idx + 4 + i + 5])); + sb.append(Character.toChars(bytes[idx + 4 + i + 6])); + sb.append(Character.toChars(bytes[idx + 4 + i + 7])); + String signature = sb.toString(); + + logger.debug(ltag, "sig " + signature); + if (signature.equals("cLDc")) { + long crcSig = AppCore.getUint32(bytes, idx + 4 + i + 8 + (int) length); + long calcCrc = AppCore.crc32(bytes, idx + 4 + i + 4, (int)(length + 4)); + + if (crcSig != calcCrc) { + logger.error(ltag, "Invalid CRC32"); + return false; + } + + break; + } + + i += length + 12; + if (i > bytes.length) { + logger.error(ltag, "CloudCoin was not found"); + return false; + } + } + + byte[] nbytes = Arrays.copyOfRange(bytes, idx + 4 + i + 8, idx + 4 + i + 8 + (int)length); + String sdata = new String(nbytes); + + logger.debug(ltag, "Extracted coin. Length: " + sdata.length()); + ccs = parseStack(sdata); + if (ccs == null) + return false; + + for (i = 0; i < ccs.length; i++) { + addCoinToRccs(ccs[i], fileName); + } + + return true; + } + public boolean doUnpackStack(String fileName) { logger.info(ltag, "Unpacking stack"); diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index 3245fb8..43df722 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -17,6 +17,7 @@ import java.io.UnsupportedEncodingException; import java.net.URL; import java.net.URLDecoder; +import java.nio.ByteBuffer; import java.nio.file.Files; import java.nio.file.Paths; import java.nio.file.StandardCopyOption; @@ -30,6 +31,7 @@ import java.text.NumberFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; +import java.util.Arrays; import java.util.Date; import java.util.Enumeration; import java.util.HashMap; @@ -39,6 +41,8 @@ import java.util.Properties; import java.util.jar.JarEntry; import java.util.jar.JarFile; +import java.util.zip.CRC32; +import java.util.zip.Checksum; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; @@ -94,7 +98,7 @@ static public boolean initFolders(File path, GLogger logger) throws Exception { rootPath = new File(path, Config.DIR_ROOT); - if (!createDirectory(Config.DIR_EMAIL_TEMPLATES)) + if (!createDirectory(Config.DIR_TEMPLATES)) return false; if (!createDirectory(Config.DIR_ACCOUNTS)) @@ -142,7 +146,6 @@ static public void initUserFolders(String user) throws Exception { Config.DIR_REQUESTRESPONSE, Config.DIR_SENT, Config.DIR_SUSPECT, - Config.DIR_TEMPLATES, Config.DIR_TRASH, Config.DIR_TRUSTEDTRANSFER, Config.DIR_VAULT @@ -175,6 +178,12 @@ static public String getBackupDir() { return f.toString(); } + static public String getTemplateDir() { + File f = new File(rootPath, Config.DIR_TEMPLATES); + + return f.toString(); + } + static public String getIDDir() { File f = new File(rootPath, Config.DIR_ID); @@ -680,58 +689,80 @@ public static String[] getDirs() { } - public static void copyTemplatesFromJar(String user) { + public static void copyTemplatesFromJar() { int d; - String templateDir, fileName; - - templateDir = AppCore.getUserDir(Config.DIR_TEMPLATES, user); - fileName = templateDir + File.separator + "jpeg1.jpg"; - File f = new File(fileName); - if (!f.exists()) { - for (int i = 0; i < AppCore.getDenominations().length; i++) { - d = AppCore.getDenominations()[i]; - fileName = "jpeg" + d + ".jpg"; - - URL u = AppCore.class.getClassLoader().getResource("resources/" + fileName); - if (u == null) - continue; + String templateDir; + + String[] templates = new String[] { + "jpeg1.jpg", + "jpeg5.jpg", + "jpeg25.jpg", + "jpeg100.jpg", + "jpeg250.jpg", + Config.PNG_TEMPLATE_NAME + }; + + templateDir = AppCore.rootPath + File.separator + Config.DIR_TEMPLATES; + + for (int i = 0; i < templates.length; i++) { + String fileName = templates[i]; + + URL u = AppCore.class.getClassLoader().getResource("resources/" + fileName); + if (u == null) { + logger.debug(ltag, "Failed to find resource " + fileName); + continue; + } + + String url; + try { + url = URLDecoder.decode(u.toString(), "UTF-8"); + } catch (UnsupportedEncodingException e) { + logger.error(ltag, "Failed to decode url"); + return; + } + + int bang = url.indexOf("!"); + String JAR_URI_PREFIX = "jar:file:"; + JarFile jf; - String url; - try { - url = URLDecoder.decode(u.toString(), "UTF-8"); - } catch (UnsupportedEncodingException e) { - logger.error(ltag, "Failed to decode url"); + logger.debug(ltag, "jurl " + url); + try { + if (url.startsWith(JAR_URI_PREFIX) && bang != -1) { + jf = new JarFile(url.substring(JAR_URI_PREFIX.length(), bang)) ; + } else if (url.startsWith("file:/")) { + String file = url.substring(6, url.length()); + logger.debug(ltag, "template file " + file); + String dst = templateDir + File.separator + fileName; + + File f = new File(dst); + if (f.exists()) + continue; + + AppCore.copyFile(file, dst); + continue; + } else { + logger.error(ltag, "Invalid jar"); return; } - - int bang = url.indexOf("!"); - String JAR_URI_PREFIX = "jar:file:"; - JarFile jf; - try { - if (url.startsWith(JAR_URI_PREFIX) && bang != -1) { - jf = new JarFile(url.substring(JAR_URI_PREFIX.length(), bang)) ; - } else { - logger.error(ltag, "Invalid jar"); - return; - } - - for (Enumeration entries = jf.entries(); entries.hasMoreElements();) { - JarEntry entry = entries.nextElement(); - - if (entry.getName().equals("resources/" + fileName)) { - InputStream in = jf.getInputStream(entry); - String dst = AppCore.getUserDir(Config.DIR_TEMPLATES, user); - dst += File.separator + fileName; - - AppCore.copyFile(in, dst); - } + for (Enumeration entries = jf.entries(); entries.hasMoreElements();) { + JarEntry entry = entries.nextElement(); + + if (entry.getName().equals("resources/" + fileName)) { + InputStream in = jf.getInputStream(entry); + String dst = templateDir + File.separator + fileName; + + File f = new File(dst); + if (f.exists()) + continue; + + AppCore.copyFile(in, dst); } - } catch (IOException e) { - logger.error(ltag, "Failed to copy templates: " + e.getMessage()); - return ; - } - } + } + } catch (IOException e) { + logger.error(ltag, "Failed to copy templates: " + e.getMessage()); + return ; + } } } @@ -1353,7 +1384,7 @@ public static String[][] getSentCoins() { public static boolean hasCoinExtension(File file) { String f = file.toString().toLowerCase(); - if (f.endsWith(".stack") || f.endsWith(".jpg") || f.endsWith(".jpeg")) + if (f.endsWith(".stack") || f.endsWith(".jpg") || f.endsWith(".jpeg") || f.endsWith(".png")) return true; logger.debug(ltag, "Ignoring invalid extension " + file.toString()); @@ -1557,5 +1588,59 @@ public static int getTotalToSend(String[] line) { return total; } + public static int basicPngChecks(byte[] bytes) { + if (bytes[0] != 0x89 && bytes[1] != 0x50 && bytes[2] != 0x4e && bytes[3] != 0x45 + && bytes[4] != 0x0d && bytes[5] != 0x0a && bytes[6] != 0x1a && bytes[7] != 0x0a) { + logger.error(ltag, "Invalid PNG signature"); + return -1; + } + + long chunkLength = AppCore.getUint32(bytes, 8); + long headerSig = AppCore.getUint32(bytes, 12); + if (headerSig != 0x49484452) { + logger.error(ltag, "Invalid PNG header"); + return -1; + } + + int idx = (int)(16 + chunkLength); + long crcSig = AppCore.getUint32(bytes, idx); + long calcCrc = AppCore.crc32(bytes, 12, (int)(chunkLength + 4)); + if (crcSig != calcCrc) { + logger.error(ltag, "Invalid PNG Crc32 checksum"); + return -1; + } + + + return idx; + } + + public static long getUint32(byte[] bytes, int offset) { + byte[] nbytes = Arrays.copyOfRange(bytes, offset, offset + 4); + ByteBuffer buffer = ByteBuffer.allocate(8).put(new byte[]{0, 0, 0, 0}).put(nbytes); + buffer.position(0); + + return buffer.getLong(); + } + public static void setUint32(byte[] data, int offset, long value) { + byte[] bytes = new byte[8]; + ByteBuffer.wrap(bytes).putLong(value); + + data[offset] = bytes[4]; + data[offset + 1] = bytes[5]; + data[offset + 2] = bytes[6]; + data[offset + 3] = bytes[7]; + + return; + } + + public static long crc32(byte[] data, int offset, int length) { + byte[] nbytes = Arrays.copyOfRange(data, offset, offset + length); + Checksum checksum = new CRC32(); + checksum.update(nbytes, 0, nbytes.length); + long checksumValue = checksum.getValue(); + + return checksumValue; + } + } diff --git a/src/advclient/common/core/Config.java b/src/advclient/common/core/Config.java index 9458856..bf266e8 100644 --- a/src/advclient/common/core/Config.java +++ b/src/advclient/common/core/Config.java @@ -25,7 +25,7 @@ public class Config { public static String DIR_REQUESTS = "Requests"; public static String DIR_REQUESTRESPONSE = "RequestsResponse"; public static String DIR_SUSPECT = "Suspect"; - public static String DIR_TEMPLATES = "Templates"; + public static String DIR_TRASH = "Trash"; public static String DIR_TRUSTEDTRANSFER = "TrustedTransfer"; public static String DIR_CONFIG = "Config"; @@ -33,6 +33,7 @@ public class Config { public static String DIR_VAULT = "Vault"; + public static String DIR_TEMPLATES = "Templates"; public static String DIR_EMAIL_TEMPLATES = "EmailTemplates"; public static String DIR_ACCOUNTS = "Accounts"; public static String DIR_DEFAULT_USER = "Default_User_NonExist"; @@ -196,5 +197,7 @@ public class Config { public static int MAX_EXPORTED_NOTES = 3000; final public static String SENT_SKYCOINS_FILENAME = "sentcoins.csv"; + + final public static String PNG_TEMPLATE_NAME = "template.png"; } diff --git a/src/resources/withdrawicon.png b/src/resources/withdrawicon.png new file mode 100644 index 0000000000000000000000000000000000000000..da898b6ff6d38be17dbcfc2aaf44d24be868cd3c GIT binary patch literal 4245 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 literal 0 HcmV?d00001 diff --git a/src/resources/withdrawiconlight.png b/src/resources/withdrawiconlight.png new file mode 100644 index 0000000000000000000000000000000000000000..9f22005e2b02ae2547a23c8f59168d9bf403c2e7 GIT binary patch literal 4267 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 Date: Sun, 1 Mar 2020 15:24:44 +0300 Subject: [PATCH 151/160] jpegs --- src/resources/jpeg1.jpg | Bin 0 -> 136742 bytes src/resources/jpeg100.jpg | Bin 0 -> 163544 bytes src/resources/jpeg25.jpg | Bin 0 -> 164527 bytes src/resources/jpeg250.jpg | Bin 0 -> 164603 bytes src/resources/jpeg5.jpg | Bin 0 -> 176344 bytes 5 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/resources/jpeg1.jpg create mode 100644 src/resources/jpeg100.jpg create mode 100644 src/resources/jpeg25.jpg create mode 100644 src/resources/jpeg250.jpg create mode 100644 src/resources/jpeg5.jpg diff --git a/src/resources/jpeg1.jpg b/src/resources/jpeg1.jpg new file mode 100644 index 0000000000000000000000000000000000000000..1366637d6e38f06afee8f8468de273082db1321b GIT binary patch literal 136742 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 I66JR;)088k3r7lTTe>`QOg2WTO>`6cu| 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

`_Rq!%(vlUd<@WvC*UQ~3UKi0t4)(!;d* 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%0DvtaHCnU4jeMBN_4|I%Y6CEQ47|fyGp5tmt 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�dvMXj3) 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�nZ;7QvNgeKZ+hD?qu#P)=GJjpE{FGzbt5Qo;ph$1ateHtZ^ z_A#rmDmbhhzAZfRCY5ZxG3&j`oxOP7$h@&_i76om=lbu4mgZP2qe=}=uuVjkT`84u zu;6Gkg~X)MdPJ0WWzvIV8d#X}lhV+h6-NF*28q>(I{&hXsV7n^^$Rt7e#gOO&Ru1v z#Ov+POi%Mb7tdod#4rmbT=iTo?@{;P zRld`5Iwwo$w+vPoR@7gA9nox3<;ldZoe%WTck5v<<%GU2JgCU-h9Hp#k+{hsV@?w_O~4{YTatEkeKb%$UuF<8 zk#d}tn?;qf-}?4z2aU2HH9V-OhHK^Zrtb^c4)}{N+XUhtGt;b6?b{_P10-1cjQ3XN z|AF?D$L1@;hDI9_yaV=g*mnhW3w5p*B`-v~7FKaqi*EX|_t^ajs@pn5TNPxO;BfbU zpb2Jd*v{e&-$5nK<3tfP_3v-Yk`L2=dmDljeVmyeYZ%WzrZc<1r^U9G2$%*NV)u3Z zJLI6Af1;WlR+cEwZVOgW3ChmjifumT0Zy1jN&P2I{;R*mbtb!zlgbyz9w{B`&O>;_ zjbCt^(wn%``)c@SKT>v8VaB9XchB?-GO|Ul)Xwe2vDWy>JW9lT)NspoQ`%`%@)h~Y zoEjNIe#B)syuHY3{h|=k?a1Dz;{R~#=^8T{S@TZM(IwOI?{J8mm7g&o9M!?GqFi=m=JyfZ9j48Ff2-q#QRw(v>2X%yx9^=dh-> zGi3|osO3OpR_OJmC&^BJIM4dGuKAkf=S;ty2DH3)GWSv znNKF-5w`vu99!S8b;mS;u)ZEytNZBCN^g6Az`W7@Cp;P(V&^xkLz@4VrZw%jDBS;m@4cN{?L$@ zE}swJ2bzHpceb&Wh+0y0S{<+Bc=Rr>FJ?yV#SvTuK|^ti1U^hFEhDS*f6szNB~0*O zAZKTv7L#NUkYItAw)#J!{D0{Lt;RgzUd_O^=17Ww3k48?Z z5_F)Qm{_ks6;5dlwzY%$3=7SczK>MjR+lLEVw-$7qvy0$3Md^PD^yya3m#B!lr=t{vuVso>7SO-cgL9=J!Xf5Bu3>e3K)Kzf{ibUi8r>eh1dj_|7lmN(ABC$eUNvj4{t4Euzwa-qZ1A z@0QVE{{xk42-Q3LY`Z87;}=-$3Kst45qhiTg(#_EltJ31#5CdtL9ah;=^@Se*K^5W ze*>&>I-A6M->53Mc*B47hgP*ZU5I}#QGZ9txtpe+fg6!Bi>z|MvjqrEueNdu4Ze|B zIlRa2-8%n62hUMOOT37w+h-m4v_|eq0Y{ud8B5p-QxMv9p-k;meh{^1D*)_*`^$Pj zxn&dPxS$IljVJCU;i7X@9%j`KUhsme@c)^yNg$nz1d3^-_R~Oz3(uW1vDN$Jm)n^a z;|6hx%}cT5p$)F>Duhsi&|`1`iUPk(6V#S4YSpaY<)IO|y@BN`&{O!v;k~f=@1@Vf z)&WZRfTx4L^$%9?!)qBtDV&p9j84I^K;GpcA}QOXeNBIh@;zbvpidD3w99vGm6gF7 zUlXXHh^<>>txDGM0$P z^@Rlz(d60MdwOjmNBX_h5c5+8_eX!`hA;A4@Z5B3&R=IQrIz0Fj5d0G8$Qm2JjV;6 z<2uleETDIzG*CRFyGdY}o_LGT=Felfq?t0NvXLYzM!~rrbnQYKeL2@(F5y628pYn6 zT39QyUdFMCi<8q@8o0Ikozv}vL!-6ON_lmVvT9&M!%aDsJltdX_p2H7eANWnJtPcV z!iJP){}fHvb+Xg(!OX29z%^vV5IL+wd2Q7Vb5nbskb>%wpROV}sww+ZyHiG=4av!_ zTg`#HO@mQz&|CqRrx0`-tXax-!w`De_V_@WnR8f`Mr%2qXWpW8oB((HIG4D>JaX*48%) zm@`>crZON-=*}AA{#dT+{!M0Byw~fAD(_&1{iwtxhO{XKP+dG>!qWic-kKO}T@1eU zRn`9On3B6r{vtYIyvNC6^Zm7!C!~^!EJXGqS6{X^a!L7W0{?T~2A z&^Ycupwkh~WwiEV zwP0{-5OENpSPYJqskJL9b3@d{KjpOLOdTlCUcAjab%Op_+J-Tss=Y|*%(l|D`~!2c zdy;MgCR!z{0Ps10+ZJP##xF2<=8QF9ASZKpsYr3XhNFr(w1Ym?5^g`+WCBlrw~<0I zBQgVJ{l)F5D6S}R*RmDd+)LeM)g(C-kZK_&PwoBsx6*L)=yhk5BNI-K%Ci)Eb*QvH zn+ABb;}e+4gp%-G^EMhz=eE17)WF39r6ikt^c04()0@q*xKf+BFr64ODAf4&+jEJ$ z4YR9@R#Kq}#T^N)H}Hv!{2dFo>F&I9ABWAaZhvb%)e*Ty(&P{s>qiAk zu_(`)`uIrXTh@ixd=*HOjAf>1r?(Lg%K)PhH8OJP|K2Dp&a!DG;E(YWpu6nlWso>$ zep;MbYw1kwzbhr`_nDnGUi|2OVz?Od2Y0BARV`O%Z&si_dn~-3Hqh(VB$ui2id1h@ zH;|Qyp5YIY={hRJw#Dv>?NHHGX7iVXn(BNN%b9qgkniCp%+$ni;mzap0Pas?Ugl>q zrM5Ovdl6a2GdFTz!7;6lF%8e?jBon0{W3eoq(i&44XV^v_jb`F)!(86DcZ$eq;tG~ zt2DF(C@&j4hi_X4OID4E@9A^Vteb9lm~#f0bE9_IN0*8e)*Yf%?l*lR>P1)usSG76 zJ^XP}ewfGy%E=_1vHGs{chwMK4ZOPsLosY z6HdOR?ZurG#B@8yA&f9~Q$q1aAE;*FR#g>mK00Lv;qcEX?rY78Nva4Q;l_Q)!KFWD zDU>Shn0tw#Xe_I!&?@>e%`!t)wpY(ts$n4u7@&=TU!Mg8u@wCwe%&iB&dkcr6TOj?I9csRKT4C4E{c*s=5vqy^Bq(HQ!FT%hAV-G%f5fb3{<-~8lw0K&B|eW{&ba)ewX~F zJCLnng5Tc7&NQ-3YtH@K9J}6ps~lQNd>Z^RbnEn(&@`KFmzL44#cXbd7V)Ov^F@L- zvPydtab?}XIcFrgEe_SLNfXdg#uvJt8<6!g3);F!9JDXu=C~|xCve;(#zO+52uYP( zy~~iKHuV4~0W@Hw*r=M;&w;-&3^ zfPRt{7SuFJQ%XQa4(#i*xWZ?H=_DHCS%Mj@cf+rNwz;QgG-_%-&G#J%>F5Tn#R@k+ z3Uth<_4I8^%Qg@+uYHwwZ#@%C=Xd;l;d-$ZVfrn?-{B`}{qoP7WE4k2bTjRgQw&Ky z?6~bE)7Sf{0NCt7aX^C$@$~S&);lNBChf^MrDkR^d~_u>U|m;qHOKIiL1EB-+)!=O zY6o1A&U-Wk-mXDD#pPBf9MAAWnHqo+TYlrGWHM&%#*rd{ewbiOs|4~TqA9WPWNd0< zQb%$LPRh!46c`z_WDFd z6oiY(%ZT<3?AZO4aZ@6F6^B@Kc$W2sfT{^OLsa5ZF2G4xoDxSiX%!Sb8MJ+_sySSj z)dk>}IdZ|<2;0f4(CgQu1B=)7iFAnRTkYl#9;#6;y7zcel9NDZ%dB`L8KhC%c2N+3 zjO_Ep?ynz330h)gLmb~=$>S!kiP(jR5kZk!oX zyd>aPkH`1Dn;=z~MCI0;(4LZ+VGD*K51JXElSO3V8>ty(JjvUaxqi(A_DSX=psO zh%GEyX)~AQhPbLVG^uNdhzhShwf3j`3uOIXY8{Sl*?Bter@Qb99{sE>Fa#$ zkPFgsxyN3L$vRps|NA;IiigW(u74GiFQax~Hq@x5Zj9>S#`gLbn#t2i&_??|(7tjT zCh)xt1SAeQf7#i@G$&XPT(0+s>Z)w7+njs-BvfLItNW<&bTKW>-!8p_{kP2YSc1&( zVPjG^8xfNl{gA?b=@R=7q)71>A7KADb>&Fo{K?W3cbiDBZufx?Ccbj`@@+7Qx@nCU z+=dQi`x>cL=>^lS+Nqb5EpCwx9fZg=QPvm~Xm4vZ?{E9Q6)N3+v6x7dj$Qftvb8%Y zl=nDqRFO~fugS6ctJ}$7d(yO#9>P+{zff}zx3S_ z$P?bsxHw;Ts9($7=b^Q+{luqZrD<;v8sz5;Pp&AUzz{y9Tx%xtV z$|zr^ipK79kEOD9bg~ z^e2B4g54z)wv;G(`N&wOj=oq&D>pHJ4GR&)WKx_)cp8>m`Zn`?<_kJq}XGPVZx@A;) zd=&6L%hxmihrj9Z3=RhS!JwqDc4@5tY#7&7s{{?{+X7|j9rh@{5hsqp4RQJ%rcgvR3YXb4O_tIizO?XsN zDS`*8NrzSIJgHy-_tJA3pb64CsJ@1X3tctEt#N6hO=O2JS=JZ!?Ims&)AL(F0*)cm zAt3av9+lya_Mm73d06JY(Ni1rmXHtajhsvBX_~t8OD)V7dgT5f(3d=$;6-OoAq`OM zMy)>8xHAGw8gXa44AK%6%$R?HW+vlFfkIJo5=@_7f4uVTHMU+!tTnrU$T-GKDy7>x z&PJ_*rZM|323-17m%l-2ZmP00dOYcX5xggT;<7yLeIxs_+XPV?JC#tyaXV91^2WQ9 zSORha8av_8L3zm6Um&_;I`poGR1k6l5VfEtkp4POqJ2v;Wb@*WPwnCLPgK%j2M?6a z{SU!PcRx|uxFR)}e(SME(QGj}Q?otzCEMFnp(fZ6yvd60;a@#}Z^k#85#xGM>tg^f5a zwf}hu!SDVo&^7!x=YgPYbhfQo204#BnSo+PVtVR)R`&LI-pGqmL{DcepMjtUCpDP? z-aknZ;Ac|xfGWK6!xGhxU;zouCYd3zWD7X3`YXwFdE_h&1WsMQ(`+(#ie#Zsz%0hR7;)SnMqZ(UJ-C;?B{v5mb@|T71@)S)b>ObpmA7!;H zE4KN$UUx74sQ0Y%TdbVo(e33+7nbXxwr~Zb*!H1!i?%4uM!>*eSG85Lay)DG35O}{ zraPA7_@M@NZlO(i>qxa~hK=U=ih&TW0^=>?3W0L)Zqpe#{}GRyp|(Mtkw^EybkoZ_ zKDF~qpjG2jXyfgUOrV^aydD?|vo|+w1D{mtA7r_1is($qi{j$xEAe)$3 zb6Gx=fZVF@80{O0Jdp#ko7w+jeMN@U*;|T^}YQz$Cg)TnCr4EZkah ztSg)zaujf@XEmPp1kl|B?!eRmEGvl*n^$Ujqshw6)t?k6wi5ytDS=g_0;w4+zrWzN z9GGo45%57f2?Ra_Ox&40B6od1c6aQ{G3z$G9oX2e(JXIii^M;0eqC5zi&-9~B4A|0 zdT;Vw9K%{J_a6v<;bj)1i`w;sn~GsmWr$U29w}!L+OS@YkZGfrQ9}Pble9Zd7o@5C zaFnVjN+Lol!!u|K7qs9iBg0lsBL0ZQe!QxXzjE|CL!g-nS?Zr=kSMQZ*W{%A5drVP z)!WU_NOf!&1!ThO`lxVDP2(#W2(qxM$%w!Ln>-iRT@+<@ZF$#tq-)t_Ku)|i|9sA1p&b-6@O5-m(*Z=rIOLH5RDj4- zf4UauSWtsY1$*-wbZL#YA3PT(Ald6-r5R_u0C|i+7gOw5_=J>%_*Ai&GAAw5#nF3Nazc?QmA{v1A4wZB9<;{0&n|OS5|F-Xqev_c{ zQLDQ*=P_wDUo!F%1I$!=0Z6-8)56fOf-x-Q3`lGPbUO$(ZHYLUeXFrTb-(s$Yg8#;aJ4v4#{lH+Z+8ON#m<)wU zftGQ>^tC^aBC5>y_rPqG5WXqw=BBDf z-lfZ`>14NV=Vavhu8qBhju9#Y=zEde8hv3X7u@R3_Jaa5{Lr$a z9|RNcZlk`tFv=jbG^1=UUr_PP`%6d9T<7upVMrNqJBW@_aZX$<=pj`T#FhK2=-Y)k zI=s80Rm8C5jrZwp-&RjAG(FwTmFT_4kkfPkXL|cE z66wD{00s8Ym}kRlb}n$Kz%wFEfXmJX?rAs#tn8C_DwAS;%teGVni%1!^>z+L!cEE! zOpGy*6fdh5WF+!T5l3C!r>}Vai7nUDxU!bKX^1s1flz^ez-4(uW<2Ig(mzm=L?CQ5 zu_-e}Z{T@;My8dmo|7XJ6O$3uPXC-#6%_d7StJAm0x?DgoN+q52%OTH%M)|s{VqRGuUK`yEFrHd(FI?Q!W(Q(I1yV2(NZx(c9 z6f=Z0Wgqak(|0+JAY04?3SUB!G$Et*$ekur{aN@Qj&q%?H)2=J8P;f6bWZ*b7hm4i zEmXCZC^C|GKSh)pBjpMUJwn3d=l|q&WqH~OUM3oG-dKa1ziOr^ho|!eGO}qD(O#wx z5^?8^v5>z`M}jq#)Flh}W5mDI*(^$+t@mXeiY5l}Gwh_zcQLlXc$eVG#eDmQ{Ez~b zO*#~IP9CUgf!g-#MLt_T>nRiY$fbar@TfcG#9-asSxuXBGNTrtA#xf--ch|HjXB1}og3Y*XV3zjNKV31 zMcaH=ua)_~OsOsvb|wN%I!e`P$V7XUwPx4d0pfRLH748he_csK1{pB>Wfup*m=xgo z2;99zkg?Ju5Z=#CEVGuF9aMDM3#z<+{D8LchZwYeHW5r2C<44_2eyg-z5QGm_{S6G zUSDizyUHs&Sy!0EI*fMr@1jiH$cb+KfZjUYJ2+0A;T$+@S^ms%1fRgrU+u*=#bPGr z&>IKIg-0Hcetg>JKfptQOrl{nm@UoUVtX9pgLj{I-NXe1#Qsjc{}^RI!)fvICw`mf zVr#$~^b)b58*ELEMz?MIh{a!!dGFUui1r>t_d&-P&ZEF7I%oBe4*wMG?>G?E1Whh2 z#+ZlP(+`xSG>uW=GqC{7r|E2CUf%|5X9N{B@NEm;N5>Pr;m@w8HphYvRNoSlv< z{g>Zg>`;;!wo3m-O^<)$8^pK`FX0gv2wrbpUV2vnL`vUi2BZ7YX1#+k7?84Wd;)SA zz6g_`MxcObpMiqe7dSvGE5U3Ik%)GXaO?K9f!7rVC||K3r9f;P{Xb+YQMJl-$i`8( zl;H1}p;uLnsJVVNU(c%JpNXBVQnH2cx}DRXK|ZS~{iI*e0Pv24l^V?YKWX?SbWB+2 zwv&>{1DB|xRn;V8Cq`0&$*K-4K(JTZVoH? zk@^_S;U}cahDJIWXbG`B)ajqahT&!@hNjvd6P-3ORc{ti#D9q~ARYASDNhb((fl?n zs9iYvA@<||@NL;cXGAv3u`+O(&owH9ieg0{hjY@Y6-IUj+(*@oeWPWOLOux#4QybY zkV>q|`l=U~_hJGmarWPml-p(5GMdC{xaNuj-GWG$YxP|ZL!&#*y$X~%jOdM~`!*7t z?kvk@eaJ<|n8gy;!DVAR8L5{2@`jgU#eQ>`WGVu6WZlgVgkpgU`^26y;gAk?IaAn~ z(SWPDu0J;0HeA{s(}Bkp)OlJzbm<_dRmSd@(xb}O_UV)Q8C9-IIPTl|Wt+#9hN5T6 z31Ts+nVaAtjkTplddC+FAo}@h2H!dFKYhFqZe?BANia@tzOB8-hGKj7J$SZ(n^VV) zR>CHr;jjKw#vD=hmQtcZ#^+z;L9h*7c+-MzbY3n$cBj6~Jz3N~ByOT(e)nBQ)$ftg zI&z^Cg}TyEeuD|;n{5CFN)Agf%jSl`Q%q%{B}uHg4hHE`{7pA@Pz$mr9+hoIB-;#` zqTH;CCe~)0=o{6Hi#(qQ!29g^>yOODGZ_!9$sf;R%`{cl^XRzFs+~pD#1KJ3{0P9$ z@O>`?2Db0hMV-lr40PI5Rz6yo$M!l|c3h@eU@WR5GA>3d3dp?E=90fN{&k_==0qg) z{_DnY!}yL9J|d?!_=w+x?WQkhU%Th8aP_L(%~b8ksB%XMQ*?J-MU6z6)8)_WV1s`1 z2|8n}?4C`UjFGCKdJs|Qr$&&@J3_}7^S||Wn!ztN-XRZr zt{FyD5fLl`X5};s7c{(h*mMOaq`8|(=20Kw#GX)pX^n%T6X+12NGh4^4INZ|AWCXY+#jByLxs14X9%!KC}vlsx3j_ekcY1 zC6``d2>PQlcN^JeBm`OY&yV0gi`3Mgu!(|e!?4szv{E_4$g+J;F$8rm;pyOoA?13U zv%2yPMtyYxTj>Mr? z|2s`+B~>zqkUd}S=`}eU;^~>f1Ila_uJ4_139qo1;gv)I5K}FA?}KR=YPc2LFI?E6>n7Dw z>}nAY_9{wI6_F4GWFW;*uI4ZHqQ7B-d;@O8jJpP3mHp{e{&Q; z-$ET5$s4Y}zi__p{tW!V@zIY~@4PlR(JRduFfqny2q01)8vM-<0&7t`xh_omBY|aM zFD+($OvH-Zl_^#Q4fVc<&goA)?)i0q83OP^(6@tW{7Yz`FQ2`m+)+L8<=$9$+j7~b zzWggGpG;}U`_*$|J<9 zX|5Uj)a(|IA<+)syB_*(1p!@oqOY1qXXW5-Nr|DNtXmNE!bcz>r=2ETzQ0JQH>b8C zT}Fe)lm%HqKwC~?7Yw_ks+lK<3&+W-Z5wr4#^HC%PcQ_;^7-5Tse5yLDrNO?AF@CO{;ed2R}@GiRFrZbMHw${``l)tU#8sB~_}2Xpwt%+b&b&t)`n-nm~W2 z`8TWFUY9u@E9wkul!YTbHytncSDuOyOC4b~oYVZ%iOAF_!}@o*SKjkWRjztB9}C$k zX4JV;G2J+3*NiP%aZS(?(o?uhg=#Mz5An^E$Lp=~Yy=}RXM+)_1dPxRX^|Z2wXEVF zuhXU>Nl)Mr^*_^S-qM=}MoJ8*^0+5ZjJpDig#mmiN=Expzzlz{Z!}}(l z05acc_bC(o$}}#!mIRSDV)uK4&UlfTqs@Rx&7MifIoUiD5iD~r30#UMX#f9}s2vV+ z-hB?p%Xc$UY@FDS!GBqb2@(|J6LbSVMh2@YhPCJ4$a#V4z(inLY_oR=pn3r}60GiW z78KW?!~lYQc$F(wkC~V2y>$}2@vJ6#7h`Ex6DO;H^J{FZ^EGtx%61MSVlRKseC_>1 zua32&o0Y7Z6f?2S1@M=1Z-OIEt|VNB1sBWer^u32{(O+0n5ux=l@#cx?mgs|365f1 zrJ;o|6w58FyH%o_nAxhn!B`#;d~=!YpTy-{&m4^~d^UBruT{q%A!}JCj5hyDGVe?( z-AmdPE=fR|Ie+5RDCRxk101BQm>* zkJV7BB2Op42eA=SQuDDjdiSM;%tY@SHyfj6T(8tdcE!08;!n*kNI51+g*~kx*Nar% zE(LoYt-X2ct*fvvTp0G-7}8qgb?fGMD}e`lip|<^{zD^HYOAa%mYJlIi4<#(FwM={r$sb-Z}3?{h^jUQR_7O&xDi3cjyx(okq28BchK*c5Ui_&Tz~;S}&@fLt(g zAaXvBv@gsg!W?Uw-XZ~gydJCMuc73flD}d$4GX{>M z>zgCTMz|@=pl=LXpx~e2QTYP3JR%cJ7CcOXD7#i{MN`dJWk)Q7KFQuOp69X;n$Qag zwMgKZ3p?g^o(cBfbZ5R6w1eA7DRS#0ie5b)PsKz%#nr76QZQn1J2tDhIujdgBXXNC zm%r5LYp>47(drs0RC7g|5V$CYbRcQSfKuvK z2Bs3($8!p8^P5D%CoXQ6eBep_S#xP+_ghngqDOMH;}Q!JnbV{qX(}=cq}Zw98}e&x zz5yE$(0yv}`X&9I`yot5;%kzTf*Jdm*f2r$R{KbcaP}c#k4n-qv4$3KIYK=%x;T(e zG4{Q^rDa|A@M`@{(O^THmf(?E3N>ac?M{QZEI zK~Nw;%?bY~2zZ=hzF1s5FZoZp|6f65c0F8lEEVCw*I+dF3VJC|C~V{8Yerk-c+hPM zT>CJc-;pUdst!8_Vt}#No0m6Rn#@2x9nnK4!PGSC7yfGiU`!VPjAeF#+%tfc-(RYh zpkedk|24`$wq3_pVap!zgwyLFAvBtZfSZ|>$Xe3P$(Alc^i5}?%7C-+=v)HyovRh+ z^?F(y>sOtwOjWyl{1xm>i|8!8#YBk*mYlYP8TB@1A>l?_TKdI>wUckx<-*NpHh5gK zhFHg*X(f(oH0!U6cINIJ&9kSUW)xXe1$Ui)ef_uZRgXeq2cajwg76!C`Usg^*h!@n zduz$u_i>Z=--cvW<1aJGMPWHHhXMI%bvz@MuBenqp`zP(SE;1bF2nhkz3c)J&MmCr zY<~3w+7a`O#ZgFuK~{rz95VG8n#lQ;$Ml#c%Ex6`6X9j^epz9uo>YyQnu@s)E)P4m zgu{BxHwosbG0>0cyl2Z~77-Cn-wU8G%2kmS3B#eY>YLS!3T-5!IBkYoCce(H$aRJs zkZqHdKXnfi#V=fUxXMS4mo4_}T!|k;2ab9ONRjf>o%Lzti3$7*5eU`<%_`+E)Yu{A z*H^F+d-i3~IYxK=1_1&B$}JtX0sPM~JR{!h+)OVH1b zk`*B{JGqCh5eqd{r8f2nLZ&5lZ|``UlxuFR#0j6iRyLlkP1@nohWiO{TlES7b)_G- zn=Q!ljhOro2Y0+4m}pD``Y((_XX>~~I03EvbrEx8T7H4T9VYjMG`*B)R+T42-~fP+ zK2wxSUHEY{!$}qPP}HJVR3ex;CI$m$Y<0ozg>Yw=elBV%bm%@KFwGZYWG$c{o9AV& zJ88+BQciqSNK{HSg86o)`}F$RMAq=ueuDWEX+ezaRe8c0nJAb>H=XZRJD?kw3~r+) z3ywn+8ICb+-&>bNYGpPH$V%J%H+XEP%h(vUkr#o@v`8mijtZ5g0lML&klEusUY0OF z7e%(IIFe084wrp()(&4Y;A5rgFD0$Pl0;Hfx`o+(-IbOrZ0K%HnY)MzC>e0Q!1|(P zQUE1t(LH-m#GT96Q5^X?Gtg96j8v(^EgSB&9X=WgO)gd(q|;BG`A%@{UBF&+5=Xl; ze(j%Sv)?ijB*V!EdBtVaMV-~XdpD$O;G`lJ>K_wapjF%oCE)*~yZhj00SU)U1Z{<=6IiItnp*XA6rn* zwilk(O>(Ty^rEz!gdOrnzlb!WMAo}bli1C)xPwY#n_*5bN4YxN~t?S{%L z?-(w-4OzY51iv;ivPGzqm9Q13%(A(o#FK@?aVi5_A&%K6)~*C3;s@Ynrb7EpaE0&P z9W9;ZdR@-syU?$i|3H)wL1bDrGO9x{JjFTZ$+Q`moMQ%G7ZP++m3J zz-qs7>%xWH*LS`r?6#S&<}c`|`~zKKD{i4&tCJ8N)WhwRaD8{|T0SdxPbe;Y^d%s& zK;^S|Z}t{3p^1p9BQSz`$2K!4l<&f?E}wCZ;*QkEIjq$SF3GtX{V}O${($STTyWss zqR#fc6wdcI^3vN36mLa=a+h==Ylli69-2vq{V1(YE4}&UH+JA93OUJB4fjGMDhqI5 z`>*JMnEL%bI{Y^^V)UtGi2z5UR@H;_C4^852m4X)p&MR*@MAlYwNDMXt&bizLCp5Y zkKZw_R-7vFZh|RN?}DO0ySzcWjE@GgH|+_rc`aeg@>~f%PV1D_8#%iR+{7s65dmv| zhgH7UE#Svg(Q2(s9*<1^31;oClKy3RebMj-zkX3A?4*6)1*1~{Y@Dy=H$kAyhxJ_d z+U2(F1On-Sxq$^Or%SJ^CV9eOCsIswn zvy5lRmCVc=vp#Q6`aD$7_&27eCx9M`>%)LO4IxBEMv@tKOC@__hPv%rcK&9m|b_XRymkm z7VzwJFVm-Y&CN}3wrygmv-rl<3DAKZQ8YFD{{7M3QSt*T*X0k0f@x;rmBA7cX*%aB z#}ljRl5u3s&3hU9atLzyB~Cs3Y|8Nkj88*NlZClGN{g9<0E#bkNvnJ0GaN48c9E38 zEid07OsLzf)nw`JqR@g;zNscGka8N(6dJli6tF1u&Tuv_kUtoe60#1S_UKsaE3r1D*c^ZF(-I>VUxl4PfN&*@RdZcvh!% zP2<1@;^?N-A;VJf<5%vwNMTd06_`ijrmMFBk`4KrCGmhGoIF`%-}6x52s!BFpYq0B zW6REXUxDyS6TL!b(0AcIzUx%Hl^g~9W4n7a35_|n>4~v5Qxviyoq1HmwtXE6)!;1D zELJC9g)>uzpj;K%)~Hr3e{mR5eq>n6>lr2=u&M z2so@;c1lLk&k{jRh^9JSt0@yFIU``0ZYux(2z%?WwzhX&6biHj3N4{Hr4Ss7yHiN; zpa~MBxVu|hoCGcI6jC&}JH=g!JH;tQiWf@Dx>;-O-`V?|bMJHiN#>JejxlC3^Nmm5 z?|tom!fU&0JC@MK=yax@TcO;K>1kuWXQQeUPA4|_?o~DHOlfSY87NfqZDwed1WcZ( zPD`bn@z`7bPKwTc$>j2=Wun^%$(*Fc5~G&jU~Zk?{ydIZ=>9z=A7E=X3%GDr(f>o` zu9Vh6LH@4M@9TlPKY$-_giLbsRQyDJf_FN!Xc!On>edqi(70f}S%QtSOyuR~6@m>9 z;gjE*l~^N98^0Kgo+oEnO&{Hu84;V0_q=br2zMobWL3%(kDr9Q$_sI?JP`IqLGa3z z9{;BrgGu84ZS6?aL|M4*$G~|J|DD?<>mro;@VD_pNSpqyFV4=q)z}NRx9ne)${;sn z;A^N;HbrxJLNF;xomLsJCwAl8m!Ta-?ExzGpu66X#_e(8y@k0oHv+QtYCR3_92Fz~ zM5$mc>uslzW6Jc@HCOO}nvc^3rpRB2NwR*$!Q18*o~K*HSs=A?U7IEWf4dW%N5bbH zYUsLKuhY-dM1KDDlR1mR=Xe>r&=!%^*129OX^~cM&&f=B4gDIsv+V6hmERv_l;um6 z*|>(346SBTIVg03EMBlLZ;M$BvKP@67W4~6#+?3AB(S#i?rc%cdRNQA z!Aur#(9d2)Jx{BWJAU4J_=ila`*pIjBCrkdRJ^BnCBc0Giz<^Z|m9pL>b1!%|s2RyE`t^+`TAVdtWslNC@#sLmC*7elXEwiTYU- z%{37>bV4rP=f}as zXRF2^KpRoW(ka{I_=QKJrD@E|j^Raqb5*H>z3<61LF;b1nMSF_wbi&WTWX;b5b*h)&yDDe#+JrHqW5K9^b)9^uQo~3F* zEcq!3cUq2bYO8Qm@=Q3rsp`m>(65)meoaQMXc1(}LBHNO1klP#S3<@8h|n3T1WEN# z$`V6HR*;;~LuaGgOG?V1Doog#F*%<+BgSY*0D8=`6^C%23L!8Ijk=>J+;ppck%TQ! z4Wx;&lJ@W|!LTwwRk)F8EnitW)UC{U&>nM8lQomCGh^DGUwPwzxhhdh5=0p?Ftn<5 z*ow-%Ie)>B$Ip0|vP8mi@ae0+DI(S#=$xEtRUrjV^)u?j&ay6G;=`fKXo@%cY0#cV zogbyAL0npyqIBydf%@WbCsHmoN(?MGX(7?l)jRaYJ9f+My;U0(&=BE4v{M@X@WdN# zd}G^y@}G|hDFc5gsTnA^bk4$AmcNcwvy8JZzC;7p&}u0b_NQruqE4P#-1$)w5_y0`<`qfr8=ME2{H!qnBy>T@~SUGr1<5QRPi%tMD+sdTOQ!<>(int$=ZPtdJc`7>rKMA6|JPluXF~@99%KU|uXEEfrNzQ2Z?9YE9@qGRI@35go9^L2qW}C z=Gq#eDykYy(9(ae55wb;lpwJs#tK737yldAkRhL4(&LA3NeycF)REx2I9}(La8Z5$ zV#-nfCWR<&Tn?oxFhukF-F_%6-}jNDSkgb>fAT&_suF%tH7$#+>-CEd zL=k|SF%?zf!w2SBVR@NcDJ`5R?snUnhtn3lRV&9*Ol8?=&vV%&DWGjwmXapGtr}TI zx5lrIndz3acHQ;eUCl~?9MP!aTK)wbitOrDd76=%2%?B|r+pgoZ;GbP6me5+cOoH_ zz*7}eWkTKSs1Ygl1fY-hAIn;US9OWQR@sR5I1BvDG2+J-(_70a)~8_fgU=|ZIK zP(f(mr`N4$L_rw{lw?sGe{b^hUZ_=P0Bs&;H0Pqa%RZKnOOwOB#N%lfqH4|E+S}Go zf+s=od0O;APFBCuhAWmK4|ZR$`uNw&4gA8s;JuS?eMW@CA)Iet2c<0gnPWAz+8^(S ztbZ0%BO`$rxA4>HKgcTPy50Db{s6VF=d2caEK6u3^43-M!G6}fTIBt=2g+}&DXM&> za`l54a~W6$hO%Cp0sh`!{u9{-e88#O3!?deQ-ekSaOa=996cK(V@@wizL?4!v9TC9 zz!ft&sx+iruc0MY;)G)O@KFz|d=6mbwG#fcel%z8?Mg7gjy~f^o(O zZRl5y^$VUogQB-~Uhg8NPb)lKr@z}HvMmlf=pp9Wbor3ERZMbxaa& z__9nw_HBO&{QbK41^rW~yHq@}K*;cr_|W^6Me^~J4~sY^l~FSw5c=vY&iYHZ^(e%B zy~#I~_lKxjd0TCHn>hajsR(|%AnBZaFhmpvC^HU7QabZYuTn(IXKLW~3&L*hcZ>AB z`^A1e9}@F`MCS`m9MAqRo|}#;LmirYo5^~0=U<*uHi8L?@`Tl%K1~*B&SuSDVtQHmcMtph58LXEx^Pt2A~ePYCVotVq31PU-+r_)9xkba#g(JH#a(T z*1QLgT~4My)No}?4aZd8YbRjVxRMRz1fvex_w#jXjJ+ zu~@-znzJad@bduxi2dViJngJOG)k7VQTtfAj<2C*A)7PIxdEe$(|Wn8&H+bp2^Ktg zE>Qo@G(CkkJum%2fpR^b8cH zF20~d#Zxdm95DbvJ~b5OYE;-DtP8h?4w2c_;t^h6vy@@!Uqr~N*ycVkJKjxW4+Yj@ zWN+*RLB=qlX{=6n*RaB6dqX1EYb&=F;e*FfXSj!QusNtNx`LkQ?!)RWU*d&)WT?85 z>c!r08m(KU>v5UW24ah?kc6YmzCsXQZhK6POZ4f%1k=183WzpISJ!?6WmfH^Ce5ltMCSBb#xu&GHKhddRO>yx}qBJg+L|AgMgh zvo9t$2tf+hw9~zF+i#5d%*8QJV;jX)T1Wy0I~woKk@)qzsE&pd(llP8?ouaWN{yeaXet`wlVXqNKyV;oDD*2kr_PAi zD>=>XkyKKbIeI*s?i|d^ujaJ8Kun8`Hs$;$rrjRSk66>scWyMy>UuqRhmS4P?-R`Sr!1jjD^}5@ zCD#9}RbW69fQErJx+F`coQj=|Hy~^VsQ~jYwWH>YbyudLE%22S@S8#}csaNnL%RE) zG~a&=-hbOZp3`+qc@wx{;(CM8NWN+6$CBng?IOTHQ2Mbv{4g2#J4~6#CE(znNLhtD z!TIgWC`=AshQc?GKsj}^hz`>ohHW9bcirWW^IJP^0ikp-91sE^fHvkO?&YF0)eUY364Ro)lrBQDWwM+8&}K8P3|>vEg-; zvzN&qL7kb15=l}x`ab;IXHZE8O{m@10v^9#&dx~m)(Hi5944W)8WtA$ZialI|9~uc z>m!-cl@(aKfEB6QHeUHC+8Sus?|#RT0fwpQL&K>J%=r*e!qz%alt~mF+s9 zU-VDq-5-UuaE7Oxk2SkIOBj8|?p*9-2O^tCCpfx#)!)4y3?PAOj5~u`)KIPj#>5JcFP({x7UQ z#qH(lmT}6boyw=dNxf?mPm>mto_ws>gRq^TuU0)Vp>a>m)ytz#7PT3W*hV1aS{a6J z*7fEB83|y2l@QVcgqc>VgN$VY)3HZG*3cAgb3oYf4ny1}W^le#7`qSx-`m?y}nW zw+qQM9eSqbv;gQ2ypE2;O*|ZzmH1=0sy0S)wp{6sKc*)NTU!x86cL&KhFXJFu-$=Q z**@;$Y&!Q9IUQn3p7Lk7b0CLOEkHE1sG44}J~u6;Ppl(^m>0Os^nFnwx;e_BEDp#4 zAh69nrnijoyC&Db(Rh~$WNH(8J2f4}?xT{j4WWp9jKj9mzODT!R83tirp1T{hl^hh zBwQJhV>i$M`gw>2JHS6;eV&$0b!W}I>TKcEXp4blYX1@O1XW0-zz0l5wG~a4MI<{XSQNopGaxrWmHLm$Pd9%W>j zmA|A+OYsF2e~^PK_0Kv+?X(sIgVvryVb3ePlp5meuhTS`I~LUSFf1XD^WquL8%7kF zZ)SLQRs*c>LKeqIAmUFO#0h{ECd)6%pwM*{fGcduLdV`wDyNCwV1`P}wA3T3+wHW2 zLUzF*H+N@pw>$ZQ&}rm6At={4v(09b`TG%up>~zh%Nnh0+FLzH)?kR(>n6?X&GsJysml`WHO%v1E(b)O?}0*BGnwY zqgG4%35U1x{=bbd#_azuU-W-F`~!Rj;9nzIXATl-DL-SG=>ybSpNdRN{4$Tvh9_M@d{E`PzF2tz{?z`DuF*@Y`|k)+azq*5Qkf@wy2iZZOBz+pa> zwheko;cJQ)_)&2y=wI3Fy;>iSgZF>DFMlbB$DKUS;cW$Pw#B%QM!kC+$cwWnxqgE~ zA#`!_ZWfXk!t^*dH^JQAM8(`Kb&sWTkzXOi*>Iq5tNyU~F%0|QfSjdp=WDiA3lc+3 z&1BB9D`ZF-g~``5KmlF&>Xj{^H2A(oMd~}cZ zP(|He1CT;BChnF|>LdP?-_{hm4Tb=Vg~tE`|M&KSjRodGC{1+madL`|P7bF|SQU*a zrAu#vHah#mHC6wudHv_tz`ogzsa{DUeTw<_Fl|?g+R}dk!jxg2AkZAIH0}+PFk2k7B@2z=6v@Vl--2AhlB!bTM>KyIbAK!h`0R4p( z+iowTEum4d!H_@_wh-@&wDemc1jiSq@y| z`U4=eQE#lBO+s20#tKIOq zYU}q1wpK1XsETV8a4bju)zD|@SAStGxh{n|M*LLK-m=w$ zU32{51VNR~J#Wf`Wo&n*Sfe(wcF&-%%w}EvhKI#M?0o=9Nw2ShR`|b7{ooP;&6gFw zC1V_#HsfbxC5k#KDidsbhxEhrEk7GudjE(tv!9RN1I1EseY`4q1@mw2e`YI~sZkd; zsqr$x@{szW>F!dC8Ps|x&!~V4y zJ$tKhp1LbRxf_|%E|1ZZzMah_UQ!xfv4i6ev}-A=G(f9rWk8qjEnhEsl51@k|KRzZ zcHquX^b=0&L+GZUZf~S8;~M#1?pH~UWyc{3=rd@Gbk>2?bJdG{_+ga8gSqy?g*lvu z7KFWh(GC*)02EMISk{>An1lEVH*}+@t%88r0k%$7RHpQRg4ycYeK)*=i}$E3wHfkz?z{0roM;S6G8ciUFZzHd zpkoN6u({?TAxsUOa3m(#{z zYXAIF0{SUHNj4y=J{B(ZBH5;sR*c1msnYm{W5OZ#w^}AmZ0!ltXvISso^dC?FWDka z{^DVW}~Icv7C4Yu6Bh`kTmsK4BM z!B_8X;;3Zj-`HC0wFy?SbGM^~v`meEoPLPeBbU|a(!?Y^AftkRS3Y02(CpqZoXeKG?4LAV<9;frI9P}+4lYF_3EA7@IBbO$bri(fzj{ki8qS*kXM&a?9;KZ;VCPIBE z|7kFT=|5ZFa|lFbNTo$ghJUQRjnSh@)H^61`L_XW$SY0Dc$@mwY{RYi;Rc^XSa^U^ zI~gNZgyOT_GX)h3;*Y7Bwn|xymS6fHqJ=sY;?pd9os_JIe-k*s?A)Z@LKP1{wzaNt zXVxS&7Llh4`e0CL)X)}p=Q1X&RAX{NfQNgnz(vxQ9@x%NR#ffage{`vLWgvXc~F9Z zgR&MESnU<=?6Fcgo7-=uS;m0A7L}R1!CA`GpP}(haj~uVFxqw=p$uZN7;GxVL!)$T znbk7=oNQT>zP|zNTy9Tvhr{??6ebbXukBzbtA%v{Q~1`|JS7hMww|Otm&ix;l5@-@pJI^D$2k2A-F({ znTLM;{39MwVvV83mC2e857V~~jM=Md^j1jGzfyC*hnym0ojto0+haiQ{rj+Q|Jl1< z31E$pKjj7Fol!lGFI|^#p3hy(mT3oGJW4$!AIy=68KSWqI$;ITkU?ObtyOOtxuSkt z4>c5ta3cNv^(?V%kHw`(2;Nn->#26suyu6xC=W7gh>A^W%n{}`*)0+Jf4*~=?>KdF zea}0g)RDAT^w2~(!>J^0yb9*jJLu8=Zm6o!rrO3l(X#ya#rt~Rhlc&XP4r8iK0Uq7 z`yVJTga1Z(oj+3JYz*JJr`%0qKZ=j6yY0d~e)~BYJ390Br;I(zm)C%YIXM_rfz1>* zDoMfpk114b%qxNb4n#58l*Bz^Ie0Ztk`>6qWu4p4=XjN3U8B~1O))lNJ^m>#Ks6Mu z6E0J(+`!QN&Lbf>+FH%r;dx(#sz3zsJhdT}E`eswzI7(LxgJhX`5ma`zx66?BxiV% zwyuLFN@qFp73XB+(8vVX+j%B7jqvy=VC~Da)+| zpU(Cn@dH<|p`gk^DNE+SD12hjA}VD;TrflOsJ#V(MR+2(BpNzJsx_ZGGLRKbqyQV+ z%%sijb8YXTR4Z>EO*}960QuNiM^&N^!6x|yPTmZ6Neh?s5UF%NHAa4QA;F)bX6;-d z*0Ac=6gH0!icQY1IM6_l{yfMgP9kQ3arCCh+=pdr=4NbnF}bYH{2_gAdAJB3TQZbv z6TVPc!&YJCZSd2X*I@THW{D@>>beFaj3C8>G^4tA$gkDcZ&ps<_^iu^R+$9xi`>iRq=%Y>8HkpCODe&9Y;y}e3lH7@X*3ytkY#R{^56ZBamI-SZ(nxtv zPTy*YfhF8N6sGb$)9308DPADs!T3tVd4A)q{@mXLiqwPD9?$x!9as1_MiNNXh)F$j ze|(Q!7rLGUh%g9!9J8so2YZcg6J@ghmezIcwbpqeycHSo$YViofGGcJC4V`Myfd_C> z<3$SW8yu{DL|O+=cyN8@xT|R58mDTUa-W?~+4yYf5X_?r5IkIy`1vWuHvhl<)R6Dtl7+BBSx?3K$EUa9n|i5Y%YM&WH=&-4-O&>&*hn^p^y$_3#SUWd!}of^Wy0-{pE_^D)*tOuc5Y?sES#*7^e^0r2yZ zuK*bNB|u;y7|a;c@r!w&fBN`$WhYGkozt?r;qWSkK&CrKBz|P0REqlib+mfH^Nq6N zTIpm>7%$4gjQ@IgQqMIit>W-H6DHc#?NUSPYwRg(x__8U82L#>OY{&Du<>}6W_7)D zUmR0R`vDO&`BhZS?;pAYOXgGl-JLF=BMZ2RFzz|&U3Xl5v?%ff-cHiDPNO!Zg~I?F)g<|@236-rG`n$ zMBis06LH@dn4|4W`?WaB0~MX8>8B4=0Zgp?wR3vRL%Sn(k`(ymv5hp|WKm}4KZIv= zs{DnT*4;{{(+smY>u{9vgb9-)e#A# zax`0P^;N_#)n2b)|AplTa9?01i+(a5F?t>w8dm;0q4v&)lskdGM<&29BkzyhkD?DQhMO?cv z6O{=Wd}Y~&AHj5Yl*eJpb4;UL=LxY*5o3bbEWY(i%0UU2Ai{a^Qj8XlAU7vOP(N18 z+nB^;;wn@3qMO9aXomf3aKr*rub<3isvS$+bIh${mgo<=&L|}f!>#8+eNTbF*x}O& zly~Mmk>UbOWvswTr50trHNVV==+RWm(e`+E9L5}GgGYQVfz&>adiIRg-!AMCM_HrO z$Ud2f7kb7mC~jys?ybivykFCERBYe{*&88{?hvcK(2lI9DTY)*X{@r>E-i<&{8eDD z?c?vzLeiMGH#2;-j^lisf{p^N?Q+W}p6z8vRX%W*dIS#pnB{5X?*3j33+rQqi|ete zT~{}$-zcU=4AjFgjXw}8?eR9=_nt|54u`IXEsTkMkC6OlyKNtm;kjuCdNWz zME_JWu9r}WJczP=!C%j22)Zt+e)xLA)iLe`r?fN9yJ8paX(6Vu=6nv_k^&e!le-KI zRe6Q2R{pWnYE=}g@TcGK7&f6CTNoOR+u&!L8IYKx`H%+yXlSxBS}wm2ODR4opLGBVbM)Orm;nF zOAZtw+IVh0MTJ>!N$Ejalmg_yyNL?F7_UxJrRr!{9Z?c{=#FN~Q4AN~$m?_)HVLfN zK6f9hn|LeFU-y&{%0!~Nx?zi_y$OfWBb3I8h4@%`gu;h#$J%>ilLGe?v|8K(M=F}L z6z#nYtaOpkB19>y^h<@?uMxe%MRn7j?ZwM^_Hi2xf%^}qt%m%4Pp)yL1S^nEdk8Od zA<#8*=-o~SiRXD2rIEY2D+_{^FV6E@v$}{7r{ryPTq*Y-m8jARsgjh?fK2Bv*jCfNz|NFoe!v(HN|15!(!s*1b`ViJc-qHiI;VEt@*ZDGH_9M7E2yh)BvyG z2$NoXK+E$ox694U<8g+h6w^?6aaKD~n)BS@g0B{5zo-|;XdYyht%~W(<@#2NLamx! zEik<2v0?VBG}tYITOAlSGQ>4fNDr-n_OU*SBQi@12{O^I0^17SFO9O39nie2KGLP$ z_|NTqBNAYj z)HHP0e&4{(ZO(BMFpWm883TWcCA^%M+UXZEiW-2qTd?l5luA;4V2|W$D%e#%LCl6} zPGs96-`Mx?EHef`Sn?(%_Z&wq76Y1#Bq{rnFNa1t@wj7Y9vYD~&=r`lHT>*p`zv6E?Q?3Xl6Ch>dJXuf%gsx6Gtoscz9*f^z!`H$B3+FQ@zb ze#Dix=`2EcM!=9v+7V}uQGo4&o2@tcP{?Zd$B&Hyn)ollhi z+M~t)N26(}YEruv(97UW?DUiur@;8uO!|avLR!zBx32@gglXw~Ak_>rWy+}FD|)N4sJT=(S*r3m??tTaW&c<`AM`LhyQ(50sA zC$4U}kU5*2H3&ko{88*YZ|xrT{OCK^Ku7HkXbiFz+Z0!4j4AQSrjW0vex&lU&BmJo zO(W6>euB)KZquEK+=L}H-pACI5M=?q{*;o+fxmo*sl;I zC&_j14G9ZP1Ztn~8Nc$09m%n;uYxL%TWMGi|H!$QU97X*xr{LEXXX8T0U0Hq95Ld& zWcduz!tbbc=56swT21xyhDDw#JIWSQQn0X?5UvFd*%!Wl4nHk^+{wiu^;X0(%$|}; z?8pOW=q9<60x9K85!1xV$gi96yfrt!LQ6~ZJzK*ZP~keGU;$~+tgdbju{nB4Xm7nL zZmwcAxK!=LNVW<;n^~+u57hQ!2*o~jn!7vByY?65X7<$tU3z98je3(RH)PP1AfbgQ zYMlzb7(==OnOkK^8IM=AB`Qrq;hPc$&aOmTW1>z=-e0u8$BKW?)TylgB++<}y~pD4 zvU#r-)HXBp1ARMRaCE4rR zP}!`V6n-#-BmsItr?{cl92KPDKp`i}38t}kyw~q~YfJW?p6PH)2-Uh~P|1>5LKGF! z;4>j>#+)h~pezfLYcClS`m8D6*&l4_XQqoKX2pDw!-RFXUt0ZH5RY5!+hGpHk9Do0 zxp+DhJ1sm&)8{RAz5-JEi?NEB+=yLxA@#!Ji1g{wIrM@GOq-RUK=gi6@SN{=U7qQ= z$24Vt`%Nl`Z_*!b*Nw+yW!-Fo5K+AtyOy;MLc-?1;YF2La~G+vOJxh4?(vVn>M36KU&SgC0Hxe4Kjxj%vKS@tIq}9J{ZiVTbB|&64YdCak*# zfxpy+nRG9`)Jx{v%v`@tJUxDbooX_8B^7Y`?n4+Wd9CrO`jMo+!p^Et>V?sQ;*Fvup$!Dvva5W zj#7rf<($t*DIEm#!*YSv=I#=zxcCLG|cBTn#*J!=6F!e97^6Z@4{Iy3Tai_Jw#k6L- zXH4d!ubLdU<)bEq`!2$EdNFKofV1yawX6=`6!KHktXgyp)6xiECy?Nt7sw{W(l)VB zz8b)3lnUz>-O4>)>3`z`RbObbRmdl12ua=(0{(?n>Bww_U-P!EK5QoPdh=mhwP{9s zQ{;u;KvC?$r@n^^>mEgN*^d^H1nUv@&r^*l{HnzJZCJ#zLbidsTr|GSGF6niWY`#5 zP-9W;oAPZ2gs8goiYa*lcaEJ2wOmtPiJXB`Z?4mP@p_6mIM`axMvmd^?A}ehC!Z#Hgrfq)w}@R!jFdNaS+>2+>rVK1F0^+}Hm=|u_Q=`jN1{+} z=AB_AvNR;y@5EJ)UTn%`k!~m$==)zVslSUM4_?VX>phK;wjl2>-Yu{!SYiE`k?#At zs9Ur&^BeLsK~(dj(%WodjuvN-Dn=|$*7xZy_%60!SMo+VgiBu zmV(hYzD8YXOGjuzS9_fZW7Vjd^`5sl9y2^Uctp$zFLXGX$4W=;zlD~z({BfuHhEZs z;8UVg`0NnQeiC{@zhbIC^tTP2RkmCo7})06$_9{C#GFbv)3iC8Ev%e7YRs!T>}LA2 z6GChPPt_2d#ZFfs0yLvFvQ@cTI~sku(;u!7E>;c(UgP?ZVh z)Ok<4Iby?>cT$6}Bcf3}{^fpuVQt>=Sd<-*n8T%a zvH-W0MCDCym~;7A;S7snoJl>Wt5w_rW}^CaNfs>Ezzxp!qd}PNvPRZ(G;jgJmaygh zTYu`nSyyEOmQd;iHDdYU=ZgV=9cZ6#9e6D1r1~2V(mDZPDUM->WdYJ`?VdlUCChS{ z>X3roQiVB7uTD*vVm{{&*c!e(uYI5=>9gV`8lY1_M)56Hs9@>GJEQ%IzM*QL-0X1; z)tF}G&E|J>o2tC5od=?gWh2=_g{Ar_%;n*7iW7CKJDEF(l_`?9&|qRRcHViXk(kyY zMt=Szt5*NS3R^T1rSnrS%s@G6@JlJb;cCUXnw7NW6G-{UxOviUK;$pgSw_e-^vzD| z9SJ*)ho^#kWTcnq`A5ybn_EZs^!30oeHqqtqkYj{{_KVsZh^Oz5P*>#7)t#x1&u;g zro^{jJ~hXP$e=ni0Q&<5BL|GSU?#(CR+uWy!1mrR|(XxI0I(S?Cg(hy_;s_#AGW8FAw(A6x*!E}(Z|*g0N+&J_ z8XO{~YxOmkVqe3&n|$f4Lv4se&{kMz8Y=lSaiW+qLh@P^-Gf1;1}r!5U0%w5(iWlGJY@&?rzj+ZM?-w!%Fnxqen-7 zp{8vKs&gFomJz4N#S)6`!`iI(&S5pW?;4EHea zla^RXLz~Ag+36YNeQ0!a-T_pr*vlSC+9K9PvPD^c&OeqsGXPPom(X2LH!Er>sc3Z0 z=b%0zu&+m<4&ZWmd>6!Ge_^>MrmQ@cyovsO?)Mq`<%h6+C|nBybA+jA0W$l7V>7Ld zr#y1hA4$Eak=7x#w*)c2f!S;Cst}RsRYiONLihw%Lj|-e7q1!HH>DowH+>H+Y)>KLB88rpcmZ&1Ei&^(<;`Dwuk5Mi!`IcnsEmxOwkP3v3R_iB(4*rGZ z$(eIL>oju_?($kQ{PqSu_XTa z`myqCa@ni2z4hOG(`3s*GQ5icXR-%s?(bO_F)y=#a``yJ-=|1r`)}+Mgbz@J*M+Gz z_qAZWjuSPmb>LR+H?jG!sG3(?*_u|}GkkkLV!BqgD24h6Y^ob=SPRb}HFZLqUN7jr z@H~T`DG7BIPdPS7Ng*OD#rE)$EK99WnXEGl`nnJCj%o#-#AH!I$C_7#^on@wf?Lb# zG+Z91JK~I(=J3zgh@0h*=5;Oe`(ZGJlEcI=PqF9*aOjsgF3dp>XAl&$c_Flo< z#Ns(sx#on0E$IA6?zrV?Xb*Dv$0iLohD3Y>vhs8+-Gm(@x>e-U%(Ov*hmy;-JK3b3 z2)8yc!pPYi96aeerI`sM>J%VYJ8Y+LBQC(*D4nkfFtqLAVH`_O5?!aC{8Z&CY|iBj zcZRmUn?FPq8!-q^<~kF*b*MH~r&${{H!dO#r@mM~tD9~1v;O1<@vmc)vca_dAF~fJ`zayn-CD=Dz1Oj|C{IlrOP4O?alv&@fQBnQnHHPPU6(z{~FYRp-zf%AsnCc ze+f;&c@#G8*+$p>e>Jp<%()p8DT;sDd=!E&ZC$6Pc zIl^&fJQE&WnYR^1AHjil;`5C9WTehPja^vya5-gvL*G*&_;kB%&g>8518e0$tK0JS zhBmpD#BV8`;+6Gs>J5duANUPgJnobuO&S&+BfFk){Vm0}16^3b3Mk{;bPrI=N*CKB z;|APXtJqt0C`a^bBW%~R`sYq!PPl-&{X=^1zWSJduUtbYW4yL$l3 z)}-~5N0J?^5`2zrlLEX&8r3#BRnG7ZXaF4SqEh+Uzm=C|2s|W7kION_ z6fZ+1t*6W^m3x-X zih4rQ2TXUM{?3^rs+}fgmB(2oi@O(}fKx#=oJ=c%b)L%HCO=&0?whw^ibq#-MrD}I z#}6R3&rNmlXlImZduismEgeass{zpz;O#q?xM&y{_R~)PQi^IRp>bT8h=6)TC93T0 zxY|1ebl>13Lrv*0aw>OBH04AhT6(7^yH~m%-NX?-3xc1_;n{&f@v}!340ob$XItSw zQ`^j33YP8iaq~V>uKEjSVVW1m9iFb5E|4b zOPlbV-JA&q1l9HIXy-bNh<36Z;P!!0Aqeb?e^przTL?kB%|BH8`}gAy+{oZFlFcGX za*yRbVEbqh9h8+?F@!MEuEy(R7+0{%!1w#W^=UhRpI%N6^!B z4V|vVW_j@YqVh3)I%%tO<(I41#cn`bbOT5qhh892fOKA^HV^{}7WriDjL9~|l@w)T zX_3Jmm695BV#&t{L!`JBx$4>XSJT0c1Dni{*S!!I)Ernh6LqHl;6+S(7PrRljmw0_ zo~=3C2b+~4C7(YV(?7{q-RkGq*3l8*R+$Lg@(3aXcL4G*P|FUssM6wE+-NEas(z-` zUN=Y$p~#ckaR`EUY1V}i&QZ9mjVKA9MV3F#P}a<)5*xlX(skSNcXToEdrn?OkHQk& zLIJs+u&Xn|dpgdUAgsI_&wFd{6SJ*`Pn<8u_JFG`q$O=2uog^<>DiQnN`>eYQ1bf| zI}ygZ%#TkvUJr{!;-?-bx8xH{Y0nlv7ml>s0f73G=Co&xXLRo5NY@w9vLb~> zU`H(&nH^|4+1L(CVcTg7GFtE3^_YL9jo3}9mf^6WV}t`;)Ue%}62#$a!eF&BKAOIa zeNo5hTn{62#56Ib#YG{?paobAe)+V*7Jz0GPFQDP&;wjxNdvT^L$$C0A}UKRJQ^0) z)9Y)J0nnI!4(^uaTBk0dpypyP6bhnIj7=m7uzg?Y6WADpuX+W_yCm)Wv|5ep6ko|6 zk?U_ff6Tylr8@&f6>=?vpyun9aK2yO5| zxj1Ma4!3y1rdI5_>*D(SJ4y_&$G3@_otwa9vG@zIhM&@KAbK~|!&!cy7tou%COuj^ zIKNVH2GCe-*Mc!_8ERPRcuT&kQnOOD%H*)0>(<%Kj$S^Lw}^9N_}{^h|8INDe-J(- z>dK>&qbZxo?%n=`rM=D7c9HKBIgTa&?e@J?heM!sGhKYz#r^nc z<)cr#zprnq4&?rMWo`NEx1N8FZhd}f{`=-t#UDyNoT>Bs_e-5*U6+BMbH9@Pd)`m) zreD1OeCXczKAAHZGq_CF`%eTL{?czIcU3oyo+^&s9{>1^>6-rg=;Y+{f8P80U-RAm zuL1f#7yfhJfcH&RxU1Alp8dAoz<-96>bPh7cYX{Dp~62a__&yMng7q2e|}#6*WjmL z|DD$*>gNCa^yug5e~0|}b?V=PDld$@#{V(jb>V-m6XQgw{5#M1=l?pPt;FS@Gq=Tk zzW)CAn*YM8`*(pdY487C`{dr=-yTjxttAl465P#$xkzch-<>Ui-5$D9jKkcJzTC{7 z^WVc#(Q5qfP}Xk&LCYM08}%vZOJ`W2Q+&&N8!6g%lOcaf)hs`fF!dQ}HKQw|euy#O zWKJ3RVo;X;_U3l`#xAz^Uvl%QSAjW&*ADOsfOLXUNrT*yh(pu5L|#XJQAw*#tS_dJ zxKb+M_Ixv1PK2F8rRPgGObB|2a#QLe!ij6TP>YH$qYxxvRfM97A7~YdE-X=@3H}%& z-PqoJ0Lf~&9QCV2Lm?!Z4eFKk5DVPLxh|P$Lf+l=6@sKX#%oU_t@Hv^iZW$0zP|(e z$&R#qOgehRybS>^Y%6dLGgO4l)ON=5FKNoI3oUNl~2>3w9PtnX{J~* z8iw65DEUN~L6Z2_o3mkEljPxB=8Ww=yc%~!9kY-ZcJ&7Y+~^W1>D>>Vd#lKjI_6oX&gI0CXi%l>+P}R!GltrEWuZw*@9P8oVX=COR z6{=X(+$55>4`cM=I_#r+vMG!ilj^-^#bs!d-W1&?I;c;jtxdN0hH~xF+dS{FTxBn+ zK2kmm9u6n;9-YFpyX*FY(7?fn!X_IX=>@eTkdKv7Uk7!xcuV0=6`zrs=%Iw6k*OJVl%Wt9q-OV#1NlxWC2_!0x&YQqA&g z+C5c1)xORW9f!P+s!O%`tphMLnxbWB};JsPw!=zceg{NZib&1XW;1Vm*{t@_#sXyB_0 zgbG^Ad(F^@1*lr)T)~((!eP*2xZ)f{hmNb!N997;YOPs`+m7fqlhsT+PY66k##WM2 zp^X(&uvb)QWLBI@<3vO2N!={c4E&xv<0YP;TULNietr``Sug`sTV;~4D@}!fX!7FH zQbS$HjJ-Asuv1B>#7g}PN`H$us|#MmMv9ZaR)VSgLbG#WD&om-)O5A^7}9qoDP*j@ z#pBj3Ju8F!OQX9J=>r<+4rq#&R(C}^i4Y=SV_;m;Xl{Th7uz=7CHv?#I9imQCLE^C z4}#4{!+9R3^H8xe@AOqS#Tggv;u&C*WwA=xYEfMzPD9!ptQ(5)jLda`+D7L ze}9W7a4P0@(~SA*84l8InB!*3J5b@^G9{E`abF;K*PG%EeJfYTUGy!zLJOuFYEl3L z7YZriyxN+S;9+HzVR3O(v>j2SZgX{F%Oh%P4goc3UTMQnQ)XJv5|}>CC~^-+>m=sM zkC~WerrH{$8UH_pop)3dTiEV{QUnAcbO8mVNC~}zQcMs62{n{ZgwQ*LUQ|Rt2uKgT zXrzW_=v_g2l}_kgKvbG2ik_QOzH`>P-@5DmJ(E3U&CKuF+3)*2Y!21F2m~y^1mq$u7xF^BCm@OE6Hf{HYYDf*K@7uUW~n0AkW1A*e5v@)NS_O>NDer7Kr7j4BAUtuP2 zYBea=KTUt{961!;vNbU>&na|EMMQHk7qJMliXe`=LXBJ6*B`;VTahTDI@_VCyL;^Du9 zYwG=nNe6%9ua_=mksfAe-cDCYlv8Jo(%f8qT*eaGD2a%6GiAARsQWB*hy|0*QT zvdknyosbaAob+2kUPq}99`0t8owYXq1PC8zT4v_=YP^@Xv*TP z@Xz|;ReXWmjrZo5SoG$ES}K@FrkL)_7Oz7vzzTH)l|q!M%JXb`{^i=@Llf+2>M z&YwkmDLO+(i4|AI*dJMuPL@B{m>oREznPWBuMVDI#o~>&phDazgN31t6gli-S9EWS zdB57ba|I4;7){qbY1)gU3r(w4H{`HOIYhI;>>1093eNM%>KM{VBwNh=uG7_9X*Z9; zs}&+qQ;8@#-3A%a+xDWh3ZMt3(0HGZh?)ro2YE}2HHT8V?aNYrBZE<6<7-)jweM1> z)cFin+R=es6OTzerqxVyEhSUa*`Ap+F^-Fb!%rG*N3B-e8An@C?w-$DWY0KniEAi{ zneILMQA`nBth~u+S9_x!Ep30Uu+1s$EOw6;(%$-=c<5dOnQ+du<)|)!-q#k)hl&#}Rp1=4iz}h(<|5Ezq zN)Ta2PH<4$NyzU^9WS#u7A`^aoqw(-Yn+K5`OMAorF)Wh$m_IFA(IRil1Qk zNGjan+)9O|OLB6A-90VM*!-!2Br%o@nY-sEg2xHA;x%4pFZO*R^S(0_Lt4!#Zng=) zW+bQd2obanPwruE> zgtR4syxs(U$1wJF<=1|ew}Tby7wz^;En3#Z7>Df>4)`F=6Wxq%FW4rob>0l)vr!gb z^AHrk*>wKMNhG&XD!Z=nRxY8kA$jZY<<(BmNk2h!*ya4WVa9~Aa$sh)uses*q+n>c z#trm%c0BK>U31Bum|>--a43_vf(W@&AKw!LSg8xCD*_`1iEo9tU?1|Xc_&p5~P7uN(X8t)=*o_?Xr z+saJa`<6R0HS&1bSJ+SYbtCOpo;UkBF8G{?n$Y6A`R~PJA2Wo>lZt5x@J+K-blC8@ zVfY-Hxfc_@9CG$qRK6Q*`Q+iEG$}qEiNhOLg>HUkd5&J#bp4e^4iB6l7jHIRB^d@Y zTQjw3KU2LJVEHkcEmgnh?a@^|Gu?{M_n&^8krMH!R;-i%qed+mCE(s<+;nRV z1$a{WEp)3zXNmk#6K;*c(v{{jU1)k5M#vOfX`9W^eArB+RnaP`7NAdFLW-26L)M{g z`JsL0>X=EFy!Oj8*an8>7wL4N#*`LJ6nwyVjjF?JsdXyJ#POg( zS0YH$xm}WDFX6hApTt%rp1o0CO!-VeA@;^rohBBH!pMSIjEs@^-Pn}1Js+aByReF; zT%Isasc?@kX$Wj2?~=3yCGBrM?HbUCYyD8DKVIdrmNP)4=qYIK=hwe#uC zlBcapi@$bTKasKKZ?xVohKl>+U=rVFiXQpH@*QN?h+d_JG9n8?H~927OCmVFO!z9`(~OUuuyXYVnrb z(NmDou{+Omj>`Q&n@I6$q?g*#@^lf1FQzbxjXUkX=H*F)pvU~+T&6ERuDj3`UjAHE zDhJ6SrTD-<9$TPvUO7soxN}SKv z5qSwI_R>cck%gOwziVu@Ne$*~c)R3f7NQqT=RS#;VQ$5;uqBYW3(1M7u9-WBTP_Jn z7<0YC%B(a30F)l3q4&QF*DAIt^?_p@&7V;^UAAM&N6T7N!wt6~HAk&aa6nwWhJz z;-ovVC()o-%tK@2+ZA%3KHE9ZBP#kh7tA+>;lX+1T*{Fy29lcdO#*y7L&t@|(HV%= zMQ4wS4QobWr21eo7RwQzs0sIZcw>Tjl+<*Mk~4vR#^8MM_!?$-*`--~kJ*XkhTaBJ zp14o|?#1mFrISb#(Jm3JHktU@QZ*$k<4UeiM5uywi>(AR0)kAfVS$iZETw-cMf$#I ze{8;H5!fs7el%Qef~qra4iK1>vMQpFelRS^6bFN|uVqJcu*JQkXrdju{S5lvfa|4@ zwJ6U0hGj|Et?zvU;fg^W`Hk+fy{eY7$DpXs#ILqdQB~r}pG$MpMoU}L1aY~buBiIjt^6ZB1(FTqHGSpz15UXQuzF{8xx2KVi^Q^R##c^Rv`^S> z&!1h|L3Qh7J4@+UG*Z#fr63R5;*fZ=5JSdb5t32>mX_g3W)%K;qvmJb_i{t!AJDqF z*;cL!m#VPrgJ;X3J*e(F=bgeAa#ji%VyGb6OgFo1d6H+QmcZN$C{ZUnxm+ImKH3P= zVDkf#`0DYZgi!#zDi)@@UVCC(ci$aYrFgWw#%zmHeBx_snC&yo6gRYE9`8(&9juJ)p~Brud zU?;Va)RiEI#l|-h*6+n;fIvcFJS7v7&JbCO;-U^@6(7u=Pwg#7!l$f~+O787V5=+` zO0j5nV4(hJf!uvT?lbt;5j(7YJyt5%#%UzAd27~e)Q-ovAc@o%os&}bG?LAPnau?E z`+FKmODBK7)Te*PK8?d!V3QvhzA1^iEUL&iwv7R2%43(UnUIz6LF{T9nMqV#U}(?< z45J--19eY)tV7&rOxE_}rzQ7GK6*x>V)k?`>gZ=#?<1X#Xx&nZ`Mcl z49(FoNiVL%^&{llX!U7kW1n>xWw$DzicVzV{e7#iP}s-Ytyr9RWqQ;Mf)tSb z?HeOkI9XuZkU2`kz(&HzM#Kg}NzSRdz|3rHo9&@Nxq-D&G_E*6+oJCL;Y>5h!woBD zPw6d8s;DF}CEhOlCy>%Y^jRpz^COPNt*oIY9QGO{`q_d9Z}oV3a0AL z#o%ji{VE833LNtqo42rSE^$fj?qEy2yT}7<^4yN=stCgGZinu5gKC|Re-7?n^^zNE z6n=`zZo87@WUf!QNDn+4s9K1mImnv}Aua6*!x;tN)|bCwG-)5@dSRa>lcjj=mCqUB zs$9#vg1k(hd7&AKKppSVZ!_-DB8_C?kMLe&P@+?%Ym)lfJgqbnd!y=vszgc(wDA&F z23`x_`l$U5IliYaX`bOfV#My{mfX9w)z39tdrOf@!YDJG_C=t0`6p=iV180})1|yu z`7*3B@vKyGGEc`i=N}YtWT#QoTFk61mLu>p0Z`l?FrF^?V!H<+E?q5EK+v1O*v{Ag zrZ;Nl8b+UhM_xW@2}a1fhc3cfaXowuSjDF|qdy#UDMfFG%xUVoC)j^k_kPjfasa3& zh`tP}?%d6NDLwHs6;+|0-OZ0r* zvMz;~l=DL?_#Up7r;a_4b@t#3qflMsjrO}5(v|7S|1q49V?zG%rCF76l+$40@bGk3 zT-LTbu=~iPH%fota<8cLRy9Lqy$xYP#3OIU9rw}<2F&+$d}ddGD{pqNLWfCjTX1;; z=TFLC`niZjKY5vI6;~w-|BkyQwsQ5`+e{1(IGl|n(68kH9{DyN`nHNu|xTcW;b;05CP2{Wc(b-1Om3ng3>iq?0aF<<%y126Pjt(>Z#+|ESrRfVhMF^M zvV@%KqJE1_NQ%`-NZlURTn4>F)I$(BqxhK`_V_~A&)N)|O9g96xiZ>2R=x${vo~*V z6-tJr$X|)wPXq;&)zG+7_Jqq@{D{mWCR>b5nTt(V%b(Hwri3%s$Ypx;hmZ%e#(_z< z($&yO?X%>|)jCgqqe9emZt@tcR*<_69CKGRPC#J%h?H~@4 z1XsCBh!6QBvUvfm>!7>T*4}&SDR^HEQ5q)=bU<~ZJC%MV) z&OSRnd2HmAE4=6roijO`q)T#Mk6AbG9I?t>Q_2aW4r2TRAR0BO#y5?Pg(=cgl;JDz z42CQ$%9C`7-ybPNuK1;eSm_F^hlo7Bk(WhkdzsIoPR*oUV%1LPklbB_G?-zEKtBU> zE=E$J$3eGvGfyZ@(s~M<>H4WRC@GQ~)ou3Tbr<0En(N)H9c_A3)4g_?Xs)wMs|rCX z`Wry2!9mvTf^-LRaO5-+V}%#)VsYv43D?#43zqV;!fX>On=%jCe1-EnE$b}`S?_tR z@qQAMU56m{*LxLvehg1spji@19JW3`;OZBY+PgZ4S(C|nYA>N`9`Yh#QKyT(otjBE z&HO2fSZ6JiTxsp(ktURlZm%|b%#!CAr?6eX@tiw6E)q{u?%P%s{0(f$I(nA3LYEx- zyjxTuJ~TfcMGg%jl?T~UVG1qOHUPol)`eq$;PyK;LjZ5<_bb0SAMgD2)~>7^1wQ-D zbLs5S_}KqtbKW>rw@R|JT(zv1Bnwk>{s8c)!6pr9Bx)Q7uM;2c1=UrnP8B?N99>U! zl|}nZRZ&IIoW{?K-XN7>vpm)oHcgK&JN!BPJ(JnZx7Un+r3}FeD!fR-8rRj$kMYLZ z%bXyN87%H-YI%dIx{nF%lw*jzRL#oT96JI0k#j^-ovBc_Hwm+nd-r5H~*>uN1; z13QcDaDv6%GbM4|d{?S{BRz66mzs3~?K(AE50QJlcRG9%Lo^*tKiLqbK2R#iKbhb( zaHBQZ1Wy)>?G~!Zo>F+EsjhmRcJ!QyJ{gnq%5_x?%9-flK1wH8US>@9kfI?!FN67%R)uho#FoD`0Ljk(cFc@*o*2FSg#Zy zZPZ+G$W9S{Q!q?80ckCckVXFJzYoP#nYe;0L+Hxy|GvgqZIUN67k*#)j4%g1FsukK zj@&3Be!2!b_KsPfx6utIaNVRz8$PbH59_(#fOdgbn0__$f<{vA3ldH~HQkWAZ0X!L#y_St7JP(Bp*ONh+U&k?R5~mKFa<|LYJf}BhP6e?U+q!ylF-m zA5KKToqP0|?nma^6MRyJwgf}OepOEKoJyd~8?MWvT`eKP!d%A8y>Mr0`|IHj+bQe! zt%=k#lgktJEMQ!!TaJJ$m)TwZ`?bu}U~^XsM>Nd1Hgi+9&m2`N?SJ)EDjH6eseLGU z8dc%vAno_Xpyks5v@H*EAFj-2OuXUe^2z$8Zt=rcwcGG1ytC9H&{DuQ4-0e$kCbQkN@F)rW zc8_ilETivjhVCh6u*p^Vks2-yp(?nG~ zI#r}PlD0^oX%2#g2iz%aiuB21s}hn&4I7g+sOTtGxOT@aliZmvxjxpG-Atm{8N2?hxA~0hYs$FlhjhkRG zw52WO_r2r;dy&03#)KNz)FV$_Fl1ZAW*B40T!5!EVZI$txMyy*xAiu>XSp_-fcs6Qd!kx6}S=JCCO;J}L zQqf=Q0clEvr7!^R?b@^lA0k06`34j!I%ZDMlr$5cc`SQ~6eH8&2k!uruo?c{+3?F>r_t#)| z*PMIk<`A1_ibZGxK|V{GZf49r#rokTmfUX??g0gqXS|AM@OVC)*)qUJ@$ev!l2Y%^ zNjbqmul!|oe0S9^uFy4bDk{{PXyZQSMFnEbVXI!U-Y3~PkfM9zi+Qe)zCa+QhRp12 zrp$T^`DG2_&*yHDn1*t}iWz`4ODVy&pb?f^NmljLhOmmwx>(#r&&fm5;HitYO)U-xde=Vl(yvaWFQ@(f4m zU2Pv(8GsNAj?wwQ{3rQ$YvRVp6ZGB)G`rL54z(qr>e%&iFV+(T`qOe7wGpsjJl`Qp zoaOnxD2L8LZuEvl+qE%c%CHdD!4#)1LiY+T=LmAWO1STq`+VJ>W`=5l!{fRGswYqH zNb4(B1LCfHy=07`^S2SbLh!uW(s%QB+FECP*Wpx8iO$6hkCNh@MvbsYxF<^;oOLep zNWVnD>koho%kwl@Tl*ZzkOU6mx1#wR-bGHHD6kwprbBnOW5Uwf=_;IUaD^&@7my|8w^YzXs*-tk zVo}HvJQUD=ub|_;^+IAf*m?r`5gaEk;XSEIke$^zEdidfWsy2~F^qSY-pPOgQ^$!( z6kf}BzQ&Ryd6Q2iEMlwC$3xSewXoM&s?x|c(aTt7_A_CPq-Z-H9{TIT-uADDXRila zo#yqI90`|Sl{?N#epetx)K%_qg&}~gLE!wG-&kUulq9^|+?f}4D(zatkRBza4jiwq z`()NVhUObIo{pGGoA=#M>v7`$KuX&5yPThvvE%XPmS<0Y#Du>Iym%vpwfAU4l=>hk zW_%5;DASxF(9k{X3Q}umb!`fpFiUECM!!qCs6-2zUd2cEuxXjSk?!n;JyKk5=EXZg zJ5{#`T7QagY?aE|Zf7=4w?6NBt+6@Rgnox4`wiAJ;PdA9i_%m*No`9xnsYPGZ&}f* z*zI#MA?CNed)=8mf{S_dv3V~sULK>0Q;VPDEbsblL+k~jx6ZbZ=uX{z*rJp@a%YJg>>wmCK1*1|?;=1;?^fNvIjA$YQS}z~mg;)z0Gd*h*@LsGZy{ZBs zcQW1due$|t7WN1o4SKoDs7bl9H+V8KGQkulSqrjhdd)M1zQY9~hSrw0h=Ne)dEWx8 z;$m^<{ZzDCrU@ro(-?{nf^jtU9fwJg++NdCg9-9FBBrrA42Oa&a`@^Bo91|w#rM!7 ziq4xUizc#LHstW>K(-aG}H_^Um&Luba={sI-{yqlW;BrEWsZc z{Pkam*LFV096EobPlnA4wJTSNvhiWi!xy#UT<5fvW|QhEje9pfJuj_JTr%8&OI26H#S*ZS21d)9s|eZN@8#0U{lDo5`l*mH{g57q(Q7)1m+$)%Qs! zUEw-65y7pU|DFQooov0h2?)2}K1omL9|{st{Or;HKqCm4>)S}=)m(4Fa2va0KWbE{c#goRLFZn@b zq7|;d>yz>C^quLIdmbD$_Z$la?wOji4jQ&ZQJEOSGe{9}EE9Kfs_f~UP%|rmBOByOjFG(z6J>m^8VYM0TtJ=Ew6^L(;=ca-qZ%Zcc;` zu-F|(`ML9p7qiS{meXW1Tf(t0tsHRfkB6#p>8;fK!xA(r`b>izM1t$tYz0Tv__fNe ziF20W!|E8jI+mL@=h!nt&`CA1BrII(Sg#4~<#iE$5J9-(280L@Iep#uqOmzm-ZUJslsw960S~Irj=p z(s~`g2hQJ}Ra)o7S%?O*45x4V*QK(FULDlab<}B>5%CLhvd$iTyxtis;en+b#%^B+ z4Yl%Ns&41mYmNTYAPD8$8r-m8mnwGt)vGVeS zs#w$!K?dyYcvrqqENu6CAYmjUuS8 zhzAs@Lge?5LMu1i`;6`4{DN4^MzT7KCU1ekx*hnS!&$-sG{GcyI3C_2StY-aToD~G zCTyimYlOg8H)w9;@m)pEXGs)5UnQM};PU|r;297eD`(mI^_!8P!%)r-87jR&(fvR; zd70$c{>$6R6}gb|852eqOkA&`dP;%LY>QZLyFmYrdd{V87V~LtIa6$ z{WqIL#u2OIgHR`*A&9d)?wH`pXsMwwq0HAXgD@h09#Cmxto#>jIqRJ%L{O!=q@f-(9W$z9yP_$73kR-9{Na9)94~t|fIJb}h=+$xUBdHKxOLDO znnmtc0E~IZEVFYnJ=gA};t+=mFRz~(qM=yG!k*u02c%Ec&>2uSY>BqnI`98A6f!3 zjg9KfUi!Key;?0cBh6t1T)!11^BZb(XJ)_lA}9LiA`iZce32kU5U22fTSA&{j#RHD z-PJ-5oxoMgGMf2lp$Zc$xXIQU(nJq1`RO{^qT7KBXn2GFcHC@-Lx)3o4O%^}6Mb_i z5w%sLWXJJEq{5@~-8%^xkvDQmBBn2EKah$lDE5&e0!B)?-VSdUO%&djvx9b9Ue%(# z^-Y@d6inX!yfSfXq<%N@O6z=nyC>chdv<>t0nPGJ&|f(Fv8PQor%g6XT9f@3bo<61 z=@~B9IL}N*aJzLJ{tL&yskKP_YWn&z{&zFkqQO1|{%^dkZmpAW7&iO&1~8t=$o)TB zeLgvg;0_8C1_;mp$xb9&QUc&lVsfuMlDu3_+X^ry%pl*=7v23|wB-)FTb&L#@Kh$9 Y<)4T67l0*gcZ(yqE#aLBWPcF<59#q>1^@s6 literal 0 HcmV?d00001 diff --git a/src/resources/jpeg250.jpg b/src/resources/jpeg250.jpg new file mode 100644 index 0000000000000000000000000000000000000000..36378f8cf21a14fe67b98d1c3477c9c6e146a21f GIT binary patch literal 164603 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 l1-b7e;o}Rjn+`#Rk))7z+f;y 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

o1Ec?k=pcUrZ}a`H^{&r9 zHoqK4qz$ZC}FYk!Ooco#m zMP~Z1neFwQd+K#ERX_MkAN`}8@`#k6kg|`dEoV=TOHDgp!iuwLPzm`n%LIL4KPw~U zWOSUKx6^X0b$3KKO1y74YLA^Vy0zs8^((uIYx(AWUPAc3~;LD%$$D+}CSkjNKu5wXcVxc=S$t7#iNZa(G6dzeA^M zD{gyo)2%APA#1+RLb+>%)mbz-A|xqB|3eIee9nCkiyO6^lgm5_F9CY4g!1w0Xjio( zXdd58jqz0Ob%?xAA$`UiR;}K8MW+P|%#aGjC#9%f?Mc=;eOdkxa6j^bp>I1YzbyEps$cG;eD7l1 z!Vd4}y!MFPYS?HD)I+P)iS^s$v00Znr=G7;%k7yIM+spMTt^pQA_7nIScO~GP>eGM z>J;AS02_`1t=x9mo!)=?(!|rGC1BR#6~jzTs1&wVdO;SX(v}u4elx_KlaR}qk>R>x zuu~xLOTp9cVM_gzgou_!>IBaN%Y|)59SzF2TJcRzz`2r|5i=DK3#_v!u%y$9RPZ6R zFW=-f7zO-@mo6y}abZd2QM(fvu)PxEHl}FnfhYqpc_kDIHwib^;eI46Qu%Z~u;9Ng z0mSR$O1gD(I4LTVQJ2LmGTypqpQlUo3i9CSHRAxUYfpmGm%k>DgrCWAOGNsXdh)&< zm#0~`WDv9aXte67Tt575@;>(cqgsxNi~28HEtj?wZ7yxW4K8i5&%Sx2GZrACcYz7pWPfBjq!vKd*TIs2%uvWxDR`RX>zunto0f7_j5et0 z_=tQq@*KsVTa%HIWy-YsMH-SLr(uO26b|SoT%XtCHYwD$V0rY3%aS^MbOO@l8e1A>4S+5QUx2f_Ei~u&EmkySDS>4)Haucftmq_G8aBW_AcNnswKnCz z&j4!1V%u0lPvcuDIUa?M(7?Wiy7?{Y^)8Du;3O#g#LurKKkkfH@9rs$FrubDo(F4?c4n30o{I8z#og$r8a6? z;`qVFJ>+}6R5%C1)mW#C2@Z$sSV_LQ;;RDH)mNsDmO3^qo$Q|+#24B0yQL4nz_Im6 zCqu3RCx^o7lywFj0ZDs?>2MiE*U-gXg~(j@QT0Tz(oMP0#VUNpylNx4BZ98XSwCgc z#$nuY63++F(@p4gL>CXf3KKi<}$uT zV;>B3sWXhp8v^NRnkqvCew8}xbA2hugwEkO{bj%f_beyZ={!p@8~6p-3zP2gty;bl+#Cip~<2(@>(Sl(P1GZ!=xez-Y{Yggq~e zA=V2YX8cI%T4=_^`YxGT?Iv1&k`W&d*D+S$3Cqsq@ynnbrPl|g@-#o($(fqgFsp?P zwe+KX5dM7Qe03wM?O(9%)f^M4V7oYafR+%_T14Nh*;C4WbA9lM`jn- z!wPpN=b9yp5Du=+v4Nwm4Rso_yt*!n3YTe^Z4a!}5rLWzKGBa3rLtSHl2$o_fiwEA2#Whh_Ql0m)#`Qx$d*Y`((=`-o27S z#xT3=xt6BPH=+xcqkX*+#L)09A>VDEqo4(n6mHnjk>^zI!1r7e?gim<xfx&;~K_EDuxERx{bLsLJ6NSwC& zPND*VpVQ9b{7ktj7W`a~Wf*+VIny5?J!PDJCZf>EmelUi`x*YKp+U^5lum9T>%3AS zj)$o-F1C3!Zt=05(H6H_mF)YJ>FdyG0WkJ-k<=av@*K@^?K)tJ7_l=~Qu^oWvEf z8crYvbeo3ftxIPc8)QA&2Vnj^6WOhM!A-&}7)@fKkjkd1uc(5gP8t<`z95muiks2_ z$D?;!BB|G`UwEx4W6@J$pF{bbQVn3LBNl5qo>m4Y5Dd8yTSK47TRRNPh9X95&Z8#K zK2r(&97Nw3cU$h@@Fk^J$>PTsUC5?-luo-=VU=UXLFg?$Zq;WGtjId%xOSG4CPq+>_NCspEtsCm3{s&DiI&52Hn z1UOpAh|72Q@S(g^hlPo83HbQXjOtRqJgSW%2^Zc45}Owo%FbD^;#|bG75+t*mos40 zxf9iZ!A)zi(G((}eKK0!dXuMhisTH~d$rN-?;E0JTepokafn+ukjM+4=%9LFR%N_- zM@-Cv{P!hGnPaYuzRjb8T7pU|K=v>Cg|eSPiA-g6b%TPQ z=xu0qP9`W>Lg%^xZ+J7e)jZ9FZtppp$!46E^02|sp?f13bL(DfxFqI2pDMgKaI}yQ zu7WD3!1LV!>0|9_Xy5DPbV_j@N_l}?w}3xWs4%~~I{}a7c>~i;VTT4iAbJd?=i?!+ ziBfRHT&Vm6cXH$r+|csb%R_nd9_4n0G8Bp?=d<3b088?_Ie*`_M17i5-uQmI5!7I1 z@CRxJkv8E|0)~5P^BIl{bHADsHM@f}YU@$zhF6O`5uOw8O-oBmM86hZrz+tVTY#O& zt2bL}M&w4==ns*2us8HV$(Q5NtBrEw?e7YHTu-?n?)#xp;NbA;2X7#RW+fslffWib zkDC51ync)H2y$*)Cle|Yb(McAzcZDLM(@Wy&b{#~TpCcvZq(3QoA%@v=ehAb@>0BU z5JvBLYDY(?)j;|5c^1eN^K_F0KZp;nbt4R#+w zauowpf1ylUpIZ@5xUbIyvcMloeO{dUn1C%6KeqhEn2l%x`!+1O zlib2BL9lSf_}UN$?$ zfd1%58@KTdM?-JJX0|}$Er}IyEUP$;$H~{Si3J%GTQ_%aSxR$%RLvUh2VQJ2hw}CM ztS;Z>VUZ7hZt3e*R&n6C(aJ0nC-{pu?ahKG0)x~F@pUQ&N@J9{Aw3T}tF6Ij zf^Is><)C!$EgZ;N%yN1>9b*6P-AcUK96e9-wVgD%%eOGHh1%vR_Y6Haj@usR-pZf7 zX`Do_HQ#rdmtpT2Ir*IB>}^)Dm#p_L8przEJ4<+Nw{L-ePW5)fPwemz+t_b~WqdO! z2}|VX5<$6DgOOP;aki3^iP%b5kj0n840+bl8f>JB*2?F}=K0CDdM`+81FFsxJ>43mB789H?#gG;UaJQV*;9Fzbc4Fin~@*y zJVKV-*Lbuo>Vvia)KMz%0=DW1{$1@(CM`(bYXWb$DE#g8gs(WbfvFA99B0&O%-pGG zVu$`A?MMjxVLKIZv#Hban;EkzzcB8J_t86Sis?rjLIrOTPN|=<`l+J*YN2C(v9y%4 zY+KwcvL>yLDs z0R~GhzFR&!w-m^J+Da z|CEo!`-8V8pI4s=u?GLRF~_fBm`6`zXZ1(m71o~cvv%0b!vshA9-(@K5+N-#I)@XK-Kj5kjcdVvhf__0av zsD{6PyKjATl-owaTu`?y3I{5sMO>?Wt=e}YqtPSO`Z&2ca-L1DXRv*DMsq&}qtcHE z97wCZ(-F-}D}z00;o;ZcGGVK}iJvTe<-YCd%?BO!y|1r<(qmAx;DvcsLKI;%FG zZ{G(sUmoTz7Nn0U7^sk6u`wCD$@*DbRJ$ELuDlsV&sv)p6S&1W8^#fEFP<#m4r!%L zVd^ikTV$tj(l)>4YZKJg`uORqf7qf=OC4{vj)A)VmM{AhT6*;T>U!YoU^27qqwlwS z;>j}G3_xZ~eWO`Goq8_*?qYeac2;Uy6%U|C$^QPKN?%^>S%hezxgpa5N5-rn4oOtu z?x=SBoTvz*Lft;2md1WzbegGMr1X{%%B~IFR%O}C?{u)RolOa7O@HXTy=+&tr@AtF3n)revJd*K)xepCR_H?|!fcbG>0HoLxK z{W`6MEep`tI!!_+&P^v#zCHP>vbUOk;cT5i7CYEuruIxn+tuolH4RbM3TyAIYxV{C zftQFF7h!2<|6ZoWW)r{q0Z{u*4#Q-Zl7@1=9#2D}njAOsE-uL|YgGttJhXIXGjLnB z-yQ-;c)L#pkr8x|Xj1`_hi+1HOl(UOt#i9%y94&)(@>kf?Ru2ApYYU?eAO;_Hgi*1 zikM1FCP^?Ul$*D!&pr8#;?Y7mQCG-wwx&hXxVbNsV#i)0m?g&UIm;mYbBs$^R)ngF zO6Ot~F2lM6|4Zd0V`X?M;Cfxfbr^rs{Y<41x@)=sI2js`fw{F-TrAR9ipMRreLy%TWS4X@K| zv2S5P^{)RexqPT?1n=`^b(x{s zeC@j})N+4j;=01K2k)!KurFd4LF$$Kdzp{fI2d)Ec#|M{?*OBIGqTA&@4M*TO(JGS z^QA(63l3y^9Xa!qD)NU+et$k@DL#XMuFSMbx1MSbkX9{KvN`5A;PobnMd}us1=rlt zM>@MtC z98$Ho3KtQ{tHtc*_uT#*_OVHfYIds9+TfjbP>&UvPr)AYJpJ-PP*EG1msa!G+2d;m zP9cXo3xARMT&mrBdC6*O+w;@uQ}VyL-+y!ksn*8!YU+fqcnc-8l1Vir*u4C6Ik)}l z-&Z?JSvT)~r@ZN@sjHO>3<=-n62GOwKR=pB6L@M2Clr@AGdHG|B?KoD?L(U7hVT zO0GM|(b}R+a`Abmran!nPi(yH`CfMG+_n>$-O3;9p^1yFm58KZAlP;+;{XQ$-`-BG z)U+6JZ8Nb7YuBV|z6E@HhzgwtzjC~BdUhQlKIeTk(6}L!^8zl7$hWrd&E3G<^S~s$ zDtaNAmdV>vkLA}C`n{;#24yd@0LXh5&Bqr$w;stg`~n90og=<~#aXoClS{*Y>RNg2pn^VYUg%HT?c1jSdF) zyrN9T%A8?wScl{wfV4-He>L*x;?Ch?qJ>C4VGut9|BOMRGbJbX)vol*)V*J=V7|tI z1jo$2;q#pYYjcpdfx})rtS~L^A@i5Sf`G=)z)W?&BQDjz6O_N*?QJT z-($4nn2$uMv1FU8E=9R?9*_O2;vxO=HUC?E~{{}pxKQBAB{8xNw`X@W@6s~89!5rWdh0%!;cBoJC? z3IReV1VT{`Do7C&LJyG|0!b)G2)zl?s}PC=K|y*EX(FKb<=ngO{r-N}erLaH)|&av zp1q&Pk2ESpVWDw$INuL>=C1k*PFZ=HF|or>nH;SQI`Kp<(IUhG98VkJl9;T{ci1u&#l+ufB<%TL&srw{Q9DvH0Y->d^=q#gj{-_egrO zCk|DQ$$9M(E<3#I`(5V#6f0<+Ww_Bs5WhjRmglVz!mV}palB$6W^~i>tVhAP^0JTT z2#EgVQ@EvTY*$0rspUe_R9B4x{<|p+lNj@=YVKLk!^ev9m?a$4U|g)nvjUDuVUrn} z+sW#1$Fzrg<@|%)_;EQ6c{LzoIi*E^^}=Wyr-Lo1<)p@~9TXw|K|WT$L|(15e{N^i zcg|Q)+Kp%$TkVnPk=d^Q;1gLD=$qc^hj%`yoHXV;ES{S??#SR&72s4Ge<-jbuH4tk z)?Ix5PMP~)x!Fdt#IrpWMI~CLMxdy903Xc1&AYEg}DR=+xOyO3evmCe@^$8w$17Wc&^B`($( zcu=BdvU8`TwIc8RYMqF&+^BHrf-p-8E=uK9Ocq(WZg}MHg%>|qf%SYKC+0$jW%^J5 ze3f(`8{=4mLP=8$XW3Fk#U+~t8_1@(yFhoZ)>3~`;R5kE0K(VCv$LP z%dI3it?I5hk^C~q*!r?X6=+H0#hiE|bwHem_F(QkbC5sl+$}5@!tKqnh8dl2rG@0L zi=!t;tE@I4)4|nn`0w`ZVEGkyevAp-$hfBlY*xI+Lpf05-V#az6o!}0c~RcqqZ=KO z?sqUo2}_}i)Pwm8Zp|t_)d3Mi6h1k9ZdnhU0FE6!#ePtQJRek=?etj$UDt2yL2~;1 zm}n)@xEV&2hf8A1@JfZzfgej1KW{VvOV}~%)}QPceOmUnZPe916!gM)FHu(|LcMZ& z#~Dgk1F0%EA&x;fLcmP=f}Rb{$qZRW!4h^e>b-$^gtIo~;bWj8%wMEeM*NFw!x3*& zJ2!My)O%m@_MsxOMLRlF!aMB)?0h5cNH)G8Bk-{YdO3dpZgBXAIwlUT+jr7A6_hQd zA-Vm2XzSkn;wounjwW!OzmrD$+$`~1H_7fG2)Pq0Db>Za({>bcYa!nV99b>-Zml=~ z2{wk@65PL(A!WzFB&VkpnUCxIZJtGzHJBF@tJ@=Hsh=Q=ri-gD@t3U*oG|zUfmK$G;8Lh3_~B9bdkR@C zE^1)!U<^W-Kz4s)>KNp?+|y$gZnQTKcHcBf^Xo7%dg$?V3ffC;=?Xl$F9D<;s2OsT}L~ z3!by7JK3Kax5E12=||k$Ak6`;wLrI#l=XfDj4_v)>Mcdc-E4U33w6%uT^8ndQFzy5 zv}#fntN;EZ^m@h&y0EelWrEVT=_AqIEyx=!S)`_8lk1ShvF^R1WJ+?|a*)Bkyn!CUVYv9t;U2j zd+7FDt)~rS>|>XhE}f8l*%zwi@J6u(E=AAH-+Ay0{RbdeX^1~C5XWdeA~91+<*lly z*u@%gGrq@Deex$XLsZ+C#6!AsLIS{X6-Abg0G<7z1Ej{o#pYko9IzfJDEKH zit5((QojHmfoA+Cab@k+=L0uYS-`EBFPGzAn@Ck>?Yjr8ycOTaV?gO}|p zzQy9_>W;yb6KgLX=ZB0HDjRi?8Sv|~jX3eXza)3xIFldu))es09>dZt&-z@_dL%Hnd0{-jV7Qr{rIpx*AeK&|`HeI#*5 znSaJG*(AovS(J2{Co2gbC?AC1odSh$DtlL=Chs)kw%x+ptV0)~{7?Wgw8+5S{$X5wEge_7fo_c@g-#(^x1!txIyySTQrMGo}`aM7|An>O1} zL!;-^#W2oxqNv@tfIH+cR(ONezWMTtgYPpc=TWhIAVgYXR{n^Kj9(eMUp-lRQHZa?N>0SS zvWmY2d@?mVB>uVW)1xb$n--C?OJKvxz5PNBcRg#`f1d2VK%MVp#Wgf8(#+qivo5@p zv*YuE+vO-*l$tS~n|VLly`}RhO1(RbBzX{6WJLc}+$p?01#@x&0qx(EqTGl~V&7FM zwMQ_h2r|Dy-rqjljB%(LYk-0qVZi~uN9$K-yDnYM5S`YJCLsnT>fY@8_H~4Zh#m4N zG#E(gn;zXau(LxI8KV*(rk|g+@vMKr7nWZx?-UaSoq?G$!u8w^v%5n8L(Vj{TAQTa zIUV+es7^REtJsmyfS2Dev#T~J{aV=So;rJ&IdZ-N9>CBAgQLX8`^+-m-m--_eTjMl zX^{{4y!}N*{O@lk6IynT7hwHfpEebY?dk3D2)py%!{fCiwGcWQolEDOZ(Z{j*Y($t zR(Tfks7k6`5Sz8uEA9n|s=O`gkuu`lVQGjSh?kw19Zk7_A!{sI4SZOzDTKnS9G*mW zmgY0de15cf9~=zCw|XSc9@^40S*8^=`{BQFXj1R6^!0?7RvuANBy9VKsZa@?t8$T` zZBjCid0an?=tL>+SMOZ2pZ_fVf~@#kGe@l9usT++n=0&F4W`P2WxKjGbJXw2S?K|z zLX70x{cX*E`>Ld@&;8tgrlZSU`Chfx-1n?`weU$Vw>vk#ePNQ138?jEDqTx9j&Hr6 zzexaH(E(}cM!8iO&~yt`)EtSH)mSfL0kZT&jm4h5y-L&@XftykKZnE*ywNf#)Ic5! zJihICS(-EDzsR7k2*_n+OFew7s~q9;>&>y~4yssUugq51GYn2@6e-{N?{n}*x%<%ach09{Q2`SU_WX_OZlUaK;os`JS%TM%cweI6rsYKs(@fV|u;BWxn3%3=nD^pd}8k z<{HfzmiSN9`le6V#R_kl!*NIKnEP!}%x8mrBB0}+IKtk|+q~<#7XUhEeg`lCD_tW1 z&4kB~9ghE%7!LThwGk$Q&LP}B9iUkn$n`}1jr;$nvW)u9*)`-=NfMy9l5KCvHJtZl z8lYAG>p!u}cQ!cbq2Z0OfMq72F`9FVn+yNsG38(T?sTbf31F{kv$Hr@;aatp%sJvv zao=!FdE4?E6?L)lXtq&FRzRg);qQB#655j7Aqzop`rf``MoKDsd~qfgJaCMGq*|9$ zJZ~?Y7VAb8*pYp+eW=d)cRMPN=--$6>?$r|DTOdSs)n%rc<^&9CTHy<&WnVA70DUP zb6lw>e2Eascjk_YMC0Y+8rbaa8C(hS;IIB`C*?e7Mw+UY0qs^A;md-WA5Z0$^p;EJ zj+=Kzi%)=0aMb@i#JpB#SBsHL_7aNDzeZ{j+l;fO7xCKE-l{N{#j=~P5V2-`I0R|m zEc23!O^RZPzN_1rk8#3W0zyv_=k)Y!9WBaeC4(rs$J!8nq9B4m)2_fzL2b`j%&;5VqWs@53f*?S`D-&(OE3SCo`Q*Um18);wpt zGx3m&ipE>+%LaH2LNw`>AW^%maHrKoi1gnTq`IKWi9YTz22r?nOtKd@iEfRIlA_Rg z&)p>OclHc)FRp`+-QeeXe}$`7t~eo3((3BG>quVNkEWmC6J8TB4Thd=OL61QM9=*# zk0#Cw-hur-@HOuv(QgiClg~eiX6E&Z^*`Jdboe2|Hl6A#zkLkNUq@OADL663rqP9S z_`Zhc#Sz?g&&#i0b)Ui7-kj)4_&#&_YxSi(eM7{$ypjb;QN?0LQwV{?mvyWwolWg{$hd?f zI8sF?)TuovXH0XnJsyr1EB|mhmG$UK2SlLzQPP zN%OM3(eV`|+Yz%T5wHiQDyQTYqg@M>UDoc8f9NinCZMb!6VtjA^FnXWYz>QS;EI7^!fFLqH1O8)#74Khp@qwV%`Lq zFNtIYay1ypdTFdRt{5~QY;HzdeH$I5-SVxsA5K-ACo+S{pPDb;=R469k4TM_(>!5t zKR!b62Xy>OW9R^LO&!W}L#8MXG2Or>U>8fW($vPJc`_|K=|jDvAfHJm$^y~>*EvE$ z_?{pqiJvyMV(R&q2||f0f$Z_CYi5hJPdfY0GF)UToQpy9ftyTL*>r-S#xED}^|Pkd zq{q}tG{oGz)aONUqmz=rx;>9XNtwd1`;UZ#pe6LWkc&5~hm*k=QLSQAZ}X-X`^+-W z@}ZcZ$(L$t*?G~oydZ$@2KUt6329RYR7OXvSG-G98bA~hhDphw^^iN6orQU)c=_cd z>2#uE%6PKJOHYKLba)f%P@;4o8WSQcB9)e=k12Q(jK-$p;7HI<2-7hJ82MoQuzY zbtVlm7DA|l`tzXNL+>%FtNit3Sq*$XGM^Zf<1rs^!a1_+a zdi+z&V9W)Tiu`@cZhF~lHJz=8K>J3QBE`>Crpth8pFvT9x-YC2+_iL2hq=k!b+}D% z??dxEQ!0WzgUEb@$WOeM*{PQ-OSof}KZ%^WEYxY+C5}#gB`&2=5%CB%UT}V>88{Y% z22Ruhe-#{UoxfOMMp?L+?7trYla5byQyO^iwqn6C!+c~A?DeZRSg{OgJ$tz9zRtRv54|y(cEnWb_EB{zZ_nmywfU|# zIL8*S|?RF$)+?Rb)PO$w+%60biNt#+#=s38m1DqFBVtjAtZ;lNYV09}n z6!PNiQ__5~c;QFp#wzUT)Cc_m8wuR`sF;L=AtGGKv!X-3%6)Q8$FrPV=V5?59_U?!emgYta#Tb|nL6KkdGmQ(y-Z zJW^Md5v-orj`<1yAv|ix4cjCAgoWKmItC@>Cwfq2-K9GH@3QWqbo;(Fi15O_BgL&2 zx|Yj@{8S%wtEwY=d*4dCeK0iQbuOzMfD+^uP-xoJa_*@rMD4oiGcx%+Y{Pna@3R7v zrOsFU2XIvr$x1zcy)-WZ)F;)tiLp@S@mC%3YOsa0c@~Aj{s5wPY#(@x{d}tn#U#Ad z+ea637yj&+r8;hDps{0vVY@cWq1U(>|6Wi?VR9V|M~-snN#eg; z=7RRrd>;;28Q;NYA4jG>{$I?IePs?|RXNgk!!BCwe>rX)Y4Q&oaW-q}Y618&o)}hz zU5qQR0hHNt)4>0~LJ0c#?(~oSHCJwV@7d*sFK2>3)c^N_FN}3BaE-p41Sq6$`rCcy zX6RbK Date: Sun, 1 Mar 2020 15:52:51 +0300 Subject: [PATCH 152/160] top icon --- src/advclient/AdvancedClient.java | 6 +++--- src/resources/withdrawicon.png | Bin 4245 -> 4966 bytes src/resources/withdrawiconlight.png | Bin 4267 -> 4397 bytes 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index e984bf1..b4540a7 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -58,7 +58,7 @@ * */ public class AdvancedClient { - String version = "2.1.33"; + String version = "2.1.34"; JPanel headerPanel; JPanel mainPanel; @@ -583,11 +583,11 @@ public void fillHeaderPanel() { wrpWithdraw.add(withdrawIcon); if (isWithdrawing()) { - depositIcon.setIcon(withdrawIiLight); + withdrawIcon.setIcon(withdrawIiLight); AppUI.opaque(wrpWithdraw); } else { AppUI.setHandCursor(wrpWithdraw); - depositIcon.setIcon(withdrawIi); + withdrawIcon.setIcon(withdrawIi); } wrpWithdraw.add(AppUI.vr(6)); diff --git a/src/resources/withdrawicon.png b/src/resources/withdrawicon.png index da898b6ff6d38be17dbcfc2aaf44d24be868cd3c..d905472e0f1c43b559e22a341b1baa563d62777c 100644 GIT binary patch delta 2296 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 T*yf>~00000NkvXXu0mjf3ftO& diff --git a/src/resources/withdrawiconlight.png b/src/resources/withdrawiconlight.png index 9f22005e2b02ae2547a23c8f59168d9bf403c2e7..6cd8e0b528ca9312310c61b0673eaff2d458bb1b 100644 GIT binary patch delta 1722 zcmV;r21WU+A*~`diBL{Q4GJ0x0000DNk~Le0000j0000a2nGNE038*xQUCw|32;bR za{vHTy#N4Iy#b+hjWV$|i3)!PSV=@dRCwC#nQy3NRT;*A&%4&%=iWPa?uhtjnEsdP zl!_##7BxXeN}B%yKQtA6un(4BM52NulF&*KBkM~_9|{GL{vZ@WQ86RIP?(dAO{paf zshKm0-nr+Tz1MpBa7M>*?u=)y-Oy;kfz4vG*0bODS?}|_>&P~*wh@243dgGwbbj%~ z{eSxVm7<&gypnh$leV6A;)c7H1s(Js56YRZwCGm60NiybdMv&|S+VrL#p$UCwhDAN zS{=~BbhJP2X>Nz-cd0-DMhColC~T840Gb!9yRK#U4dIzpiF75lceHl~ejb7F+Mv8c z&;qR|AK(K&n0DV>UxYmrTM zRk)p&)KT3+k=CKeG4$N!R{DMR(rv(4FqePTpEmUDHI>-in;n6EBkEd7 z3&_&M?o@07j)iiz&^%B>%%u>eYF864PZ68tL}lc`H+!|WwcdM&@Vtp#S>1;U@sCdJ z4U~Q()Pbcf;A6Y0`6j8@rLB$z*RFFs+-c@!#H053S&8GNIHpJUnDJH9Vm%1-h}lnr z*S$E*MR|W~cx9TIdUwlC)kg8rR}{=-I(S7Ljj-(+A^;*M5JpGnCx zz2lF?dL%-_Qi~Nalxtrs=M+O+Psyt9nPK?Z&gp-rjrvWQ{=&}94~o)Op{Xk0vWKZ5G+xrJ}wDVrMmbg1P~q)VQzKQi=4d#X2}O(;Z*!bu*cEvCp$} zG0K0PW{#qa7v|f_QlI)U?E_Y`Go+bH`dgyBF4Jx97~CZ4RBE25k(5TGFZRyAZ0IiR zobOC3XHBT2M{IB{&%OLawVp80dm_-qG4X*wwJ<_qPz-xF-%l!EXc%4H(|i}SXA*6# zT*eI~_vePoDb@Nz$Qz3FVBj}Q{I4I)s#t$Pqzp=+eZUUKH3hASNX;yrW@(#-KFt#;6YUxny_TBi zNV!2kwVSA;&A?s*jYd}m<-`>kCfoad6e+47tLJ}X z@6Q^KuJHlU6edj~r=ULfyl;m2kS&{aYvX?+JAB@SdK&J4N;2gYQA2o|HWPM4`FuP<4BmNNZmT>&Z!V{kZ1u zgvzNPvV3+`bMKgD+bY~ZsS?{vdI-7bFy1X6N>Gyeizb?uwhid6GV!lA%Efw6E?EV@ zA>4H2pA0>FzE&nKRzrWGfh51R)8JeE>Rs%}Xm=%c2(qRyAbI&Z=r@IY3WynvZd(0& zy4bzM+(uiEP1C$A%W2`hqFW)VaJ%BJ{RrC6sNGDprs}x#|9=AhOXJ@I01fpQ+XTi5 Q;{X5v07*qoM6N<$f{t}={{R30 delta 1591 zcmV-72FUrXBC8=biBL{Q4GJ0x0000DNk~Le0000Z0000b2nGNE0LXw)L;wH)32;bR za{vGf6951U69E94oEWh-i3)!O)=5M`RCwC#SM5)eR}??@d8I(#K+xG?22}>4fq^e5 z6&ccow@h>yy2&(4jP4~a^MgzL4~*Fd}H>proqlV9hnIproqlAOJvyD(3Lzn#KdmWQ=TEX3o9Bl4{jl z&p>l|O~n-rpQ%$-KTo(ZU#Hh;a<{AN003@qwmS(*X|z{BKoWl#Zg94)1f_H}06@_t z-PWzC>S})mQ98YG|IUo0U*>%?<@L9ZXKPevhU^}@?us^Ql1NEa)4>F#G+Nif6_5l* zx)!b=K`D)%yrJCf>N?#OZPbw6W6##8&Xm{RK0YrpwQUc|GPbNa()Dnx*H~2?mbW{{ zJc)^eLRGwgK)ruKxfcLHy+OH`7Z8YpLZ`x#w>!sdtSS!cdN|gbv1QGX+O`K}|C&sG z!3E|zXX{Lf3(Gck4CvboWvlk(<&OETaaf0&C;~&Zspm8RK((poG(})=ScjW@*X_&8 z9cwd`tul5D=u_gtvafTt&isN4%$#!OT%lI6J|(M78Nz=o(V4nVrEiY+3(=nW;Jt0Dyk4X}>QH zVCCTqr{_fGj9v z9Yv8MUwnLg+~OQ}^ddyi!6BiE&mUyB*}B~>=MYV^K~lLq#upnMd2~(i@=wB}F#Ekmp>XRxuM^ z-!Y)?9&``Q=D*{?M1Ot9fPSvMi3;+^6iI*4Gm0dVq9sB8m;wN5CY)hed7y}%RbU19 zF%pJl<*!TwziN9!<_(!QWd4_Aro>f4=a4Z*xinGCV$#JUi~vAHV`Q;mr_1ei0RSlE zw3HwKdAxwhXT8Qe; zkhhcj%aj!JRK!nJPq|E@#28@EhMm5xaL79Tr`zLpJf$v;U@3y0rbDcbey<>SNrE65 zQo7Q2uZtHv!&ZAA002WXV!#2*eQ|#lF>;wiIaTs~9rq17`rZo6oMA{v%j9t#t%D@P&~Vn3$`_~xFGo0B<% zMrZHx7X-Uga7~5Dbp6(MizPc55}>TKJWd+AVi)2#4mWlUo2>Fodj From a7df8dbf850af31c989277ae0608e364cc5d1842 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Sun, 1 Mar 2020 15:55:13 +0300 Subject: [PATCH 153/160] icons --- src/resources/arrow.png | Bin 0 -> 259 bytes src/resources/eye.png | Bin 0 -> 5476 bytes src/resources/lg.png | Bin 0 -> 7964 bytes src/resources/lg0.png | Bin 0 -> 684 bytes 4 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/resources/arrow.png create mode 100644 src/resources/eye.png create mode 100644 src/resources/lg.png create mode 100644 src/resources/lg0.png diff --git a/src/resources/arrow.png b/src/resources/arrow.png new file mode 100644 index 0000000000000000000000000000000000000000..fa0bebb24e59fcd3a262fe91a1db29824195def8 GIT binary patch literal 259 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC&H|6fVg`ms6F``8hqNUxP;jfK zi(^Q}y|>d1`I-U*SYLi%5D~d|=+L24Etj}wR0w;YThV&&(2d913JV1U@AB4{s#U%< z5_WQ&#t78Q!0<<~I`?fs`BK?EPy3@5-`%?Q;oaV{?ELF-pF)2(9J5%Ye?RxRU_eIt z=XXx69AInCK7OtRPGGpJWa?R(E7q)h#^`*VEO{Wt~$(695oa BX~_Tp literal 0 HcmV?d00001 diff --git a/src/resources/eye.png b/src/resources/eye.png new file mode 100644 index 0000000000000000000000000000000000000000..80291a9881c8b464180d7b6b4845a0610d102cfc GIT binary patch literal 5476 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 literal 0 HcmV?d00001 diff --git a/src/resources/lg0.png b/src/resources/lg0.png new file mode 100644 index 0000000000000000000000000000000000000000..81dfc7aff29d92640eaeaf61c783889cba8bf2d0 GIT binary patch literal 684 zcmV;d0#p5oP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!vFvd!vV){sAK>D0zpYcK~zXft<}v- z6;T++anm#{%P=b=dNYlzs7(4vSIL0HftXdMV4LAIzx_y@RjDM2M|f-q#Men3N}Q$s}*<-c7)hi zV%>NTTk#QC+b%^wIFvv3;z=Fgtv0eAU{R##dOse;^@nyD(2k@|Ng(dp}3my;QO|Z#D^?v|(gmj{c SKen6z0000 Date: Sun, 1 Mar 2020 15:58:28 +0300 Subject: [PATCH 154/160] icons --- src/resources/template.png | Bin 0 -> 85114 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 src/resources/template.png diff --git a/src/resources/template.png b/src/resources/template.png new file mode 100644 index 0000000000000000000000000000000000000000..00dd234d8d0b858b01ab7bbade3a6a1b688c2e64 GIT binary patch literal 85114 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 m48X-wNTsDqA*Nt4 zHZ-rHOSFjpzbHEIa5n!gjQ^@Z?3lGj#HRKvT061#rX}{?Vzd;s1);G*Z8d9ajjCNM zRz-`NwVK*h)fR8w|8iaVC)bnb`DonB-3;GmWO;2#VES76}X-F1Gt$h(l zDEu>Ov1|1P#3woa?r%z>o%uO&KKUX`g73*Qm1W(Zk(s#`L@$AIa$R3mzicgr`{(>Y zL%r-*f-c`ZB`lx8?z5(-Z)EBeF77~Vwg}8qw7%0BH1_sCC1eW^C|v`32iPDalmX{n zGN?6kc%q^pGf0*T^x!ZlN;FraB@5|%_TeK5Z@FL}T9co3S91q>m>&Gm@sh388wQVr*nc5hPcOGQEJz@VXcaHU{8Y8ieC6WJWiN!7~)LZ^PL=k=gADZTEn*4Ze*i2wku9|wnrijLPl~qdRDF@LFYK7(qC=MxCL&00ntT9#-i_eScO?DeYbd>|$sml~zEDOm1 zad^3)HpuB~ck&}5b#-=6%q3I^mm~yh#&K)?R~yhdL>j;|+s-l6%RTO_T_Khg*X>|6 zW7Bp-{F*l-oepzenc{LgRqSzS0#^4h3Md&`U}4L-Q)I_Bl_!#$9H`o?SP*+6v$pU_ zEbaeo2M>yKrIRqTdW;Ml(j#|emzua*gxUPolsA5D@&wu&iy^b2+S^2BqA5rgY8^^a zjj&%~%tkfCy5J1%)bfk!WkH^~)M+O*&9SvnlC`MLuy942#fCy;ll`W;o-O70oUzl+~9Rd2?Nz_lRQ3I)>*;n5BcjbH3gBO*umLnCCvYu#lbB7O({$g@) z7s?CPzKS);=HZ1cJ#RxgWzVu|VEBPO_j_$-42LTN)xUO{8)z(qLb6ByeBd^+=|H;r z8qb$?fD=N?^jAWmjPx+Ag-{>A44~j{8fvaYYY* z!H++3MNZc%_J)4Uz>Bx^bxnS0+d~}IbCs5GoUXz%w|ZS9ipz@%Erk**;xZZu5c)_@ zVuVG`2-&vt)aefXSP3fBD$iP$sw%fx!`_CmD(hdZ!6K^^He5hg3>5YI#GGgz9(L)wyS+ zLRf=uRwGE_@3gclY#T@R9cz0_sG(d~JelBeV+cJwyNAIZPAnpUCV7J!n$Z3+@3LXU zG+PK}nJ(Cxemcq&KM<={KAxb{wEOl8RrmH?7c;sv>X!&}IuDIu*p9Va^T}O|aDcEt zs*JGVBR*!xnquXJi%lG=5E@xYmoV#0g+~J2zLLsi0I(g11yG#5(Sn~Jtq_d+IWHVtxDrqTZK!dtqKogR8<4p+G~XV80R!I8+;T&%B1uU9M&|&@C;fV=d?9 zj-n}l2yUyF&nURNdNhn_53m?C^6RQ?RY?I%$Hep4QJgw4BtP)rU5yY)PS4s|XV<@# zF|MeeoN4-e zU5NSa{^oH%b`6_A^YmnB7&eFt$r;~Gu1$ySUfoGQ3y zX+b>I9bPhf=NDt7kRR~5-b;RT>1DxGZ7VhQJ%RKq7M~2X*oDAV#wpc}99R-SNhy&U z)P65(;)&Q4lgNDUBf-!4`dOxPI1W#S97Yx!bW2Cab6IME53G6^7Z0&~eg6EWGQ8v3 zPfwLVhMXFq2;ml-8N=Pg?c6A=!z1ArL|ae^W?y57P#|gp5HjjiEC77IL`0@Z=gecW zESYXreHA=HcCw=b{G2p1Moc-Ty6?fBQ8jIU>P}9s4xN zr!ywt5`pz`mGIRlq#{#|O}7zq6ZIZC+%`i`q8GlTuZ#)wf0~@37}>?$9|%h)A0SLJ z;~p~3#*p+eUTrq|?&Vn=RUX03+Zif4nW(S#y_+XRcG7EvJEH{~9OfSWwIDuyz#~1G zSC|)Cx%<;&{NMmn*90op-lK&{mQqlMBpLE{hRGM`*HB80aF4(Kp7`}37FNx|sDa+W zDBp*6XpfQ=ZPSJ>Wb@G)cxS6iiX|fODILxdAG2*~eM%d=P}cGCg2h=+vZ2-SxuXF4 z0LoDH>^(e75_Y~l(b~HgSZRVqWCfi6%x&su5MUbk9cx0Xps}~~ys3?-crF5@(z zXQp`MQ;lW{5!>qrdf7S&py!^m&MJR!w$F{OH~P`BkID(f}lKp3?MBL+tMp6CJv z!=tOg^{bWJ@xSZWM>8N{H+OHgGTAoQ@eaKi;~8XHUES?|i2LPr#oX_!%-8>E{N!z1 z6EI!7xw-uJxBpVU|9a(S!bQq0G`dJn++hz%5gz1rOBpDNIJaAyILMe>MVu;zSU#yL z7bMAVRdE-Es!-S$w5_qU=XWn*u&WPgPyy(^5y7%qh-Yp)D zEv2CI?g^DPt-?i>4M(PmD5w=`D~JbRx$Pg#wlpkpA-p*pR!k|$ZMT!llbgJjCJj`% zLlZ!8(*uOKnDPU59J7-5>7BwRHK3Z=(py|hUmFairLV16;T$_!0fwQqfB5^O7>FON z(6hP+@~CS|s=bL?^DNGxl>gXj5c18_twy2E#k}%c4jC-F6r6E^cC`t*4#76gw=|O% z8!-DF=IpQxZ34DAMgmgX#MHI$XpMu|&RQEW8bWW2qbLvgPi;#*o{m=aZRiLKNeUnv zOtx$<@Fy0iRq)2p^gB^xzyzejIK2dDf(%?=;B= z5Z&=eI+FPG{KU4suy@Tp1KgR4!Mpcc)v!Y}4}(P7>z~&@2nqO+PM)g3KQSNruFtlA zjV*_EjhMe8&RQoui6yOddo9>KOC5wFvhXpJi>o{T)WL%!GC@hRR1KRX7#D8Xo&mZrkiiTEgV#-Yjl(EX)|7mOUJYi_PP7@=gfW%&tzB@nn}|b@9na{056V zN$hTb*6@C>t};$Nc=EvmROWaj_3$HwQd>EmUDsWvS{(|rv4rSufe@57C373h3@lCf zEMc%Ikq95_+p~XduS0&byt;hx>Neg;`OkY&4dCyM&+88<)Pm1hV?q$Bn6v&iPl`Ztdi^KOd5|9zaf-MDS{SAqEe|Y13Mrc{7^9<-weI zqRy7w3%V)_R&PZ`<#JDswFi~=LVPt!8eW}cZzyRb)kq^vB<+nJYO(V1q7>B047`;p z^$+y*FkXcgFS3a4DXRiP*v-Bv*4I@v>NQZf4ACk98ZIHQ^e+4vjFC*=JzqZ&0!x?` zvPEEj6x-apOG*0USl@aoFS%3_`s0sUc8CO+m0@3oH<`6~#APTMf@WT9t;-|aXlL_{ zW`69`ic%ogqEY}%PF?Fj>7PYH*7MC~>vhV7gePpN;K#S=;~)+J!1jT@0cvMhX+Y`j z0BtX1`tET+$Fo~ z;Om*rV<sXRGqh7fqFva15~c05n2G*i8zEmYpbOkcb2ryav!m^5upFaiexCP*R*|;dlMBCmWz<@)#icJtBxYye1ftK*-3+gfk z+UE;e&OnzBi9(jix=Z2$dn9XvanTM?1ZfXwVv!)9LOq;~@ zfAXPP%y>a7igLuGTqfwd_gBxyQZ7dKxMgq(4f57Yje1jGyA!y$2ry1zWk|7&k+{%{ z7BNq`4>n0Tw2n|ie=Z*2XRK)$N#&58$Kd3cqq*#4-2h33FKc;uX%p*m^*}-5Rh_d% z7lxhFOrELOKj7j!UtOzB-tm4yrL|Q`waGAon|TjKu@^SJo!oZssIX|+DEee>YvYlY z$;7Xt0#m>}y{csAl-%b~erA@omOcYhedePhGar599N*Cu_^923VVhBh@S~ux@S+~9 zZ_pk#cN{^#Xbu_8=2uLr(Gm3jAg8J1Y=X@njyoI&ymU)Hi#r6DA5t1DN)%Jti0u*j zOOgZT7rX{CwmRHPJQckFV0Tv(|WYM!Fw*nDHjKF18P6S2yXB4Bff+ zDw1Tc;_v&PBJcnC$84xPyhU%YM-{PA%F7)n=`=sDV6#$CQvEk=fK0onx97;2Kh@Gw%ZwbDk zoD6bs2v-m%tJd0>)dllrpjr1m{ASuIYkZ*8@23^Ay-OQGn@uPK-htRgyIUV0v-^9w z9c4Z^`4@FwYE5h}$+@7Y{A#<*xOC4)UhU~A?anP2X-+Cwjz`}w2$Ao?mcGssarMxh zQxBrGR(oug`iA3u(n~*;k|w>+mRI@G97yg;J{0H2DdRm-Be8m3N+2-Mbv|0b$*ciJGN_m7w^^R*K+t zZsXh>62(XpU4l4i!r*cRs+G}lob42YK?L!9FPI>#`W+BM1_y^N4UL6dz(&8vk zIDJoH&$EyfPGwp%HHrE%PMZi6gN!OM)#%6=P-sqB$%Zb>$xwxMl-61P1|?T82*_fI z&t$fyj;OcQbNFaiR@lC!xWR7+Ew)Yl?E59ZH~d#1{fcW0hrp0lN!jNvgmOe$8yBFF z30MDI`quAHfanr}-}-6EK5p%ocCzWjV6EB>^va3L@cCSvK}+@P&;~IBo7RH8Z#Gzu z?zDNy<;8FFn^n~mM2wz>d(xF?P2KW%I7-VJ4h3uB0WeIf4;uj0Dms^4?WH@>%A4vu zyRm|lNyYso6vc&V^}inq8p*CE&0dbOvg41Kx1of92PJk>7qa3^!9?N#wUyj_T#E;~ z9lJ2j%p+@q&aTT3tP`52B-$4oje_~A2&W!=XDZ{1K$(Sd@BbQ zhGf{QnNZ>`GZkEASe?2T3ye*&qTfl1D-*)TcSiwmmHlL>Zi6&H9EhD& z>R4ZBufa^H5NUqJbXEEBdi=K1gTKN&dm|#C0b}*wR+j> z2}YCNCc~-ubkWK2GoE-8wd@`JG5D6C^Ly*LCUkB+ZTo+V_%)xtZLUPLasDIDz zNV#XkrP5@8jzZ0@1G>4-0Oi9`C5&|ct~gTa#?6HyTMu48n5?T)D0n&LCIDq@l&9-K zD!|6K7_8rjP@ko5dT6?c@aGsLR`3u=RYcd(S@T*NAC6ai>G|V4Ydbthjpx5c-gMuk z$Mnjf4x2t{k|m2ii8@cZFA7Y#h3XmO=SVt*ZSJF);WmVIWQR+~YoNNx{XF~ruopuM zy!uO~@`*V;8?f!Fz5L^6XfCM6iUW!4vC zvRfk!Os1?*7x|J-Wm*Sc*yrq)A@qyxd zwT9k{4yuSk?s8^4z!BKp>1tl-0@EyX_1KgIcH@E+>`)LP6LzPk8v!P~4KMx^CM-_w z(rv!OPs!!L)WjHIs$gdj>I9EB()b za#nSt!D-PZq<8JN?-ZR`7iDT3E~4;?EGm3`=rF#>B^#U~JK{0yEXj*v#d8eJ<%-;U z{Go#LW=s6<{O#UB&8w%y1l?gQ>Bn(#l{eLdq92F--mk+VnmU=t>v!kj|6ZGRA8Ozi zu#;64TRSI2P4@49_pF}|J^Uwq{HNg6*4Ftm>F>Kf+je! z6{1VOjGJAQwI$XpMCnd*FSO&h+pC4V%dMN1g121yZWxr;B9#`LGj>AWIZI7hqp9~) z47`nX>9ts+xeXvg$~9hW6Wwrc@1#~a!q61T5m>_0>;A5;AWyGc5Ijw%9r0ZDSDxHP z7*1W{H+QnLmd%pF9@IIb?b%mrbK&mJDnB;Ja~XqEEN?D17p3R-)D4Cag}td8RbMOT zzU}>!ty96s$0g`{;I`|xSr_0|_VBGmv*sm{NOQb~Ehsrmo-bCfg_wPE%k&lJA zCy9zc+lh}s)jTP1eSzjMm6r=F1d$kX|6YS7V_Iv4pPk`70yNKOu^1H9=`1HwyNuqp zcoF`5XhlHOyR9TBjXvNGoU-Hs4+bi1n+Q90-Jz4j+D){od8E*R;szD>SO5I0!YX!m zyFH84cer0$m>49fLp~7HQQnw`Ux+c#v3s*`Nj28SQeWpLS2Wilt2PGM#_e!3b&nc{ zQxiHo!Big9g{?b-R=ckTyH>gmi>GM*Oy=k1&l@FHeP{(1NyVsRBge?27fU1@+rC3S zVT0ud9=;mB>}%%iGfeH1#IA6HgKg&@!-5jYP%Z&`ExX@hFvOi{-C%3k#@Dux6Y4El z#!O|p>^gpgW8fpIkH7a>HCR4=ocX(A&jOVT#uP_YzZj=h*s92B+JUZX2MEn64f0wq zGMWnY(payc1hrNcH3yzED6j`Mq*Npqd+KKInOkUB;LJ0KcUUsC1y{0lP@<;8Fr@Kw zESa_zw(s%>yulf#Shp;}(I6tD;Zcj0E$;9joAXFFB$+bu3v}|&lp)t|ORx5(H8ttr zpw>gXt-cM_WmNK6vM^ykNIbhog;TxCsSqeh@mFuFRKC+1TwH&;My?txm zP5ad2X=I`mP)+4@bL@6C^A;a-O%rok^Nhf_vFyz}e&X%U#-Z%G(5xtg*zfS)m4}sj;m|AWwl#7ZE>t!=9U$-&CGPrNou2in3I-C?%iWp> zz|)DxM7eQ-^AM8>+>uRO8~$2f{YiF0Gj%go5qxzvIsug~Xo}kR^)dLkl@K3aB-8l# zO^ndEhk}c>3kJg;i2ub?E&Jo}heWZyV0~hD-Rtj6RnFM;P?~s`j~O*9QFb$ney$CWqLkhz%c*~>nzddLh zB}|=F#B@jTeJIq1;LoEbNCt}a9>v^ZBp*T6oSaeyaJjB(&C}e5!{}BmE4|0@^;fup0n?%q_w&&HqrDLqH;SMB^;8>=@vp`ot2>qC3*U- z$tIGIK(p%HE}FTF8?vMVNgw~aL)t*2DvOg$2D3j00Wv!9W>uu{xHkjdj@{4huD|?b zp@ps%bsLjWH4eXs{FXcVsc}eT%06m6}y?Gm?wsIglsfK zkSd!flMi+tN>yf)Ic$W?RES!ye;0aA5>d_#oMntYXnx`{+WL&JiZomgQR%aklXZ-<7oD&;nQKKxY7Jg z@tf6|o3>ZcdzrUQHC!>2j8)%;$a2Pkv`Te#&b^8|&;N36ouwJgi{68HV(Xeb*z|zN z?po-XtVru;}kFC&ISRDuX!rAPz9o-!mb zxy(gA^;G7hA3-&FzYWEMY8fJ0R0RXFb};?NYQsTT3a&q(@sQ!4KO!c&2Y)9+N%`Z` zPeTR|24@@5(8gKQmO7QR9ZID6vN%8g`y|v(l!D*xe;S^4IWB5>|>N>ne+HY;sFt7DnLda35AS- zPBjq>vl**^9MG-n90a~N6ovL5bqM0V3gM1NLT7rx(;kgwN8EFgEeUmPkcd=M)@{lN zcFAHF%*sQZYydyo10R2*0z>&Z%dB0vQgHy{6r5H!(w*q_9+E+!RJ&hCJOqX-vj>KR z#L;jp93(7yjYNm3i!uxovcT|1=Qa%6J&E(o)!SsAQr}!mP+l5wV~NZ>L^dVhLd7ou z_Y?~P@XM})UWuvT<<5~ldoNB9a65pGX_8K?^rN%Stoa4%@RS)&32iAEI6*q0n|j7c z)$S2>N>|$Qyr>Q&w2&;i(2lK2xe$l3U)pMgJD)5%N_59IGpa7=8sX{^`Ttq0fYiBR zbi26iglc8g-KJ^U?ac%yp0|OYr1W`PMR~`a4XtEha@@(W+91qG`S@0BtsYYcPc|n< zRY;Qtp4r4_;K}gey;rX09`hlZ4Uk4FgxNx*7Slj$T`j(FDH?n4tZ)W#{qUba%<=JU zHi)P~bVwnSju1as=fIQ0(|_)LyOBvqKYF^hQXy#jO!(Ea^8TPWZaw1qR$e3CTpV6C#57xrH36b) znphz@5S4)P@jG@d3cVMw@afZHbl+QlzKXg3`1njJnRgXUa_Lqhono%3PY6qHNoJ>X zo69JT?JAe1zJ)A4`w4?2`>r5gZ9QY?SMCIz@5wO7*=6(>=Ye0pu#-DyHSJ%! zDF%Wh1q_2ayQ(pYZAPqA%rrqqedmVXN5t;;BVJg#f8vqg_?9jJx70MnrD8kk+@eEtp;D({K8_kn<)0)UA`v`9GJ&lbaQP@7JsXE z)tXI}K|UgxaMi+7t%X}}pC~8^2#I~_sA^%Ng*fbaWM~K)h^mzZh`$+6c!H}i=E$yM zxerjE#ShUwKKjN53<>=kv`0s_)~MsFPFI@`aSX2knwD9pvwJgHWPnhD<5@}@wi=a0 zIgK1gNwk5uB+e z7;OMU3t}ifEvEJ|(~XclC}KnK(1HiTI5JvXzAz^U%#bu#N;jM{laBUWaMo<>YfgHpn+T`A1^%CqDJF+1Ouizb*sJPT*rW!1eIkfXLF+0Jt;xrZR#3J5-jyz)aQ zT2s$nsnQ->APAHEC^(-GSZ=7&*|rFJgpuQe%`37t@WI~1ndyw zri>^5l(Ry*dQsRF5RG_C9p&v|XT<(SCru5YZafUrEgZIgwyQzO|KQc>i^qQmK~R_d z_^J4;U#VH*Nt-!3L5 z)6o%7c$4pwzF(LqXqcr=3(y>tEGjl$61$Vh@I4P_*XlIzYnRFMUyz_Stw}DCIB6~N zwVei#DTNzV0s@SNAjDte6FdE^Lz$|;NF!=8$L6-Sk;5U4!sP%r|5pvnL3rGBUeZNe zo!IGUIXz-udMz>tzkB}0$5W_!Wgjw@_CbO(izW#QfH^kXHf7So(rCxVNZ&T?{6@fR zUP*D(_RMF(-<=lkFvE25|lZ)@Ly08{EMh8 z7uWmrxh zO8(wlH|gobn)`H86-`qwg#KJJW#VlT$J#WB$RG`tcpIud28Sp*Sy@1Y!6|gP4DH1u zkx3VR&3;j8J?{qPsG=@aM}tB$q&YbE|1f!f^-q#Q_i(1@j01W2)G5m-S4bx`xpRkk zvux*op|ObQB@pJrCd*5{)c@A#4-z1TCKEjI&S-bSRI4S4Q!rId{2-`DwqItPIZzLz zN$#z5d>rg*vE{9ej<%1^+3x%94 zA0n(BU!705Kg&;Z=aMj#s?JFl93LpSv&^o1U%_WdN=PUATBM&R_3G=)HO;f5%zs>} zk;n1tZz>^{Pb@USd`P9tUqXv9hqKqzr{WNi(mh} z81pauWe4{*QLRj11MKCut?z}`6?fksZ*%RPK3M-i9Dfuu&0NKz!-c-gw3<#uYqQ7(q3S)lRK3bLyjQIORV;1K3FPQ4c_N`U<6z89adGwTg~N8%vK?&?cR;tl4xH$%eXvOtVL5JuSfv zPPZFb+Yc`DvAemRNXt9!D)o_Rx!S^ z>blN&0)){@ zAfbHvI&c)&DMqzMP)BsBsLbBZut5J(P-mMb3(QwEow&1=+T?%Glek8uMhq9dPr2>F zu?KZ}ZTL{#%}i6VMiyxe^jk(ZN&l!5)9lLU^*7;}UFH-5)N*>Tc)U0u>O0?;5y+;4 ztJsJNp>jEs%xOKr**LRZNniJ5aK`Z`C_$3j{Py)Qxn9?o ztP#n-IkYcKhqFt)yd%YD2~HRA_s+d17*ji)a#et7`lc%KIM05sJg!-md#x}?u9p2xka5#NXZ?aulWibSmc&5Y z2HKlnRCCm|%Fi{u4VGjP$9GaBN%$DF*x^spD2Uvn$}2zE=&{zchiVkwBRnmo#y|UX z0mT)R*Y=*oy!z@lc@d--?U7J(962vK6qy!I07wK4Ru&ulm|iP5%N0xApWNgQMUDie zpty!`%xh1Zbi6V^ocD;TR~8@7$v=%&UG+$C zvb$)Idr;S1Q6KivFUeD7{OyxmO`kBa9)kzNpQ{GbN`|(19it99>fhI=uKmLDHLc~UcsDH&TO>*{f-aYSo{~O z8hW3?z+YP|ll9(_-T_kldJAPD`@}7j2>;X0F+ErveXhB+{A>ThCZ6PERYXW-%TpaN zqboaA9Sb~pOOn|rTd31F>A&|qq-Q)JU?ps{+ZLt80{!e`*K7LCQ=hXYUtuI4ZBxh_ zxA%JLAb#lU_wbNHY0l|`LJrzE$B{}U*3mS%(qUr&HjR0SMH`kn%Zg{O==~6Bl)ba6 z95om}^AB>dC=|g?_3#*?R+p?`*fMI&AT&UVp_pCk;`-(z46SvG7pe}N(;%}y4(6n2dCWVT`X=SDS-F_+|f-bOh$)AfPxTDH}R+Ps-C`^AuQ1`eG0q?9duR0l6QLWj|`Ifpmm!6Oc(5OktV>nTn!>| zsJ6|3bBE^Zgg%>r5UI@_c}HG9O0MYZE)Vc@cikglbef1}RTs;C;mnR(K)LZ?&cyU2UOumh~Ud*P*H;{p-haqdvp8ygt7GnO<4t^Fcq zrDe;YX*259;oMVitjpWZoyr>*?qjK^bzv~#+&9`15D(5C!GYhABdd#h$nVe;t zXD60op+#X>#>Ug!d5G{RZPf6h(C70qj|%c+N<%7vwl(p9nGh{0tAhU5w9 z%}u=ffR(Nv-#PjMhduS91E!9)a+g1E${nh-RrKUX>Hw)5Wi8C+qVm%z-d`*}p1w5X z?E6RGe|veI@h0Y?OVvzXOvw}oP(p$Le+~=R|4rmQ`*&24cd>a|9K)jt8hW#Kd{ea4 zFPDVt@8+kuRf#(LO>@0D%N~54{jUt4M(cOXgyokSPx0q_# zyT_smm1qw>6G6hoTBeQt(*8kCOijV(I1y{cIu{}~VHd(a*RHZgTxp32_O>E!mElx= z=q&NG(?MEv-{FbO_(6sa^aUM}5D_+5MDWMwAHv@|`Cx=4u+D_j>GKC$b|pazD}iO78}p!50l3yxzmFC9G8Q3Wg3t%v zq#as?E#6+HVm8O<^i;C*FUf>|dthkkvuf1T!46BGA&V>Vh>t#96`{L|mV?WcNE98n zJuHOVf3Qu;0BdFe7@{iZYL)(Yjjf%M^;{sqlQ3Qwp4ir_yLv0=ol{{|ZUwDD&j?9! z4yN`bq?7N})W^wmg>h?9CJ&ArO(7dqb)Z%QFJ+vA72Ke-OC`lvP%N>%(iGtgKBS#1 z9Y5)^bW13o(qpIe|1ij-EGYZodH(}Tz1%_a}He9$mmVVFo=FhEue30p2Y|=>S8h)qU7G?uzmVziDI6RH`vLH zFPJ(y`Eg1b5;_^wQQg$_(_n0RhtWo~_V0h{JRw+wGCVTm<3I>k8H2-~=XZ`nH!9QS zn4niuBCwnU@c74afPgZ1BIP`8DCe*B0w|h$9##D%yOITKIcyy%B9tasOo-oxn;k1K z?^W8UtweS|OJXPyg$bdU-Ni~`si^q|jdQ8*a?MXVH4yGnzBQoFi3gFC0;;moi?uf% zoJqpuv9t}40Tzx>qN0IVs5#bF7x zC)9Mz{1Pq`_vYW9Hw=F-x!&KvAD&j+9?19q*^w{4C%9Q#bY}`*OuTYF{pNPpXf@_) z(d+i)_fpK8X7bw(Hk!oP=-a;IfB)8hi`-`R|2bM&Pb?+5eome~i5eyGW3p0?4oF&h z9Fy_pdimiX3Cz+EyZC{`TNvR1NHGnli9s^H4F0%MOHj^L1 zI6(LPdN}W#^p#38Mks9{eHN%GADWe&(ON8mMpCyc;22pbPjVXuO0rzNwYy8Q=V!sl zS?JxHX)eHww@ZX-m@=$75pr0^x}e|v!2g)>50Au z+D*S&dOk>fv3=FPT*eVt)H|jJCi^P9BFbgwn{G(pu|V z!f_w{;SrUTXpUjObS;hyy*15-Xs# z-PFL}H~pPT3JQM){c~d8hkIQ6U7ej3A4mUh64H;h(0Fhn-tq9q+&XMWE{w>%2U_i)|lZ`r_~A0tp6GFjtFwG5yHU z^MKG$#oo;Se13ozc0+Rx8@&VL6Pq>Fm&4kV*u`JG1Yj~$`o+?it zdN{}BT8o>I$0aAjQ)EF^EE1~<=j8yE-h|$NC!Fe9gj1WPNk*DOMRGwl9uYmCDdlDkC(|7sM`JLlz!xF;(OH&sCysV{Mh`(F-6*SSXwQbH)N#OQ-OK)u$r9mdn+Z$z*`wPE1eJ z9Px_|&h5MVxf{0Z5@G_@3r=;i!faHFxq>`~NkLETD|1t{g)^x%#zt2*-QK@{xBG3e z>+@kJq)98~Q7%%F0D)(uCe~?~S$X(9PN&sWKYRK3wj=4)wfxP8{@=eZ`!BYN9^ZWT zCQ7kP#S*tOFu;c0y0%yPuc}@>yZWnoijaHwyYcvI`?GsLTHlN4J$QQaWBo>i5TShi za>3mw`Nd$!wQ)kaGv?rn&(e=q?C007Zk*mU>_4E}=aA(&Tsg zzGv~1-ozX?s2#hOcn1)XZR+2}><&G57L-ej1rdo6*{HJ4Dg?bQzZl&ZYM!I$dRm~s zdebB-{_g$z-Lo@PUEThlM}3W-*IxxR$7pugw5|9)(k(~CzR+#-{L9qH5K#~u5S`SM zq!VH>5@tuQIMlf;Rd}4^#97}=mmy@v>D1*5QsSSZH667+PO18ky2)+k%)J@UJ56{Y z3C~OZi7lRDx9eF~`sbaJ2+7qcB8^`*W0GJ50CeE-Ih0rrgocv0o0h^`qc!asf!N@^ zH5I0N_Yg}oA<=yA-o7jIj!Z~pHmLdJpjGlA`Z%^P9)7f{SSfX9nmmI&AU z*0H(Qrp>=Qlu_&`eK^Tk@d_6JASP*tjjBF-oueClPp+;(f`~@wKPd37mGq& z?2@d=1I2%@9^bO?|0VTsGSQ9Ag?s@zvFZD#R1UIDM(1wR%2ba=!u-7wn73|CVg*wU zvOQQ9evzz%?hCT&9x8!NX(P~-QQE{C%wwzz9s3IIJ@z1{+QP51X=iA2FBeR!RV85s z)#*Fav6MfJlF44>aOakVnP$20Z6BzbRDLn1^0ajBL6-{-L_~hL5Ieu(ob=V=;(m3s z(7=>S=ygriQBT4dZO87$a;MS`ZYH=#giTZ!{bR=8GfHwdgtXk3P*E5yV2u-iN%vA& zD}xaz$Q{xCD}o;NiRSty<}&YST}9yv`K&% zI2*X6Zd~8&5xt{)wej`gseH_-`0W^1^xg`zv`gcWS~W}dC($l8HvygK^|6Q3OZ_KC z`-LSw_Rigf)|w6S6#UyPx+Cod8V(je9pVEdiUe)FN%v3}?bnAq-}uIThgC9omp59p zK?!B@DmDydx#j+L_Um+7&W}{z#pd2|QD15&_#^5Irf59BvvR<|wfpIC{}|QJ-Y>xb zEfhb)NHPTGi6`eFm__(Og6F6WVuvMov{4ocDlkQZ1o|Pozpg*rcoH-C8Z*CKScGS^ zO5@XY*LR0Q;_8~zVrdFZ6w3wmehEmQ1Ox^e5-5lZa`P#lXPTA}OkN6sPKVVvzuB^vPIhGjdZ`_2X2n>vL&sxAFqCiRA0J8!n_@0| z-y)vrJ>7?eq%NTPPLpkDTkINZnRmO=iuj6r^*{vo839u_r%m&Um*tcN0b%Eu>FQmA zJ(VSm9&KGSbObg?t_W$?5iwX|NfjkvaVF@k29`laLDq%&pJJ>=pi|?-mqT8%sm>TG z#1s46_NPX5-vWyAQXw#)qeS7c$zd2oX?HhrBy0&pJhK+f#aI>MC^c?&v>x-w=9}`< zu!+cyC+27%&)nOxi{ zlEK(%511=8pjzIPo^)oTl7cUQ)OeMZFdZH0Md=a06ns4i*2j@ycDcx?Y{U2xt7bG$f1jxY81~H&g_z~w@BME zDT!#S=m~~D=|1LvyyFhLbA0&u=x1D#AAGYKm!26$3&u^r6{%^3di}aR3_IdR-;6pw zyv?I2f8;}6{QsKuXMQ(hD13+J;ZOd3X~1%DoR<-MsY9~_H!E($-?6C0kRLhAm(E?s zrQzxzrWa`~sTYoC7`iRsIty?O$FxoLP+MLw_Yg9_n^l|AjwyYM*NXxyEh^yRrwo7A zSXNeJIW54Jf+GO`kG@2`!gjH&5oe!F4oIG=Dj|1x`NJbacwa*mDjZakBdM zwz`)gx$Z19`q_(IeI5-dYm{v@gZdlowI>zqi6JpVM(!=u5)8k~-p@2kf{)Q6^m^G7 z+sW#@=N=>e4ZUqWtw_TxuwkNr&JHST=9H$dPiiL?&VT{Vz6ezuQD zJWayp#vST7|I3fZ3B4>f`Q7{jTZL}BCD=HUEUN2p;lRc20JxD!L#IK7j45?WFDrE0V6N|2h0Zc6d`!>jqlm`MGv|B<$z6wAe+s|+wii72c4mLBBT%;3oxx79 zBE|8|7EeXIs^U%7Y%_=P6qzp^!9L>Lq632+o?M+JOTvU-l5vxdYlE_Q_<T@5pkjgP)lC)GHz?w=+IVlN*RO&B^)PKpO<8?(uja37Es-;OGzj0q;Tr#{E~I} zZe`>Sj|MM<{j`7b36Fmn1Wv*@idewBEqW=zwi|$biMN(GHQ-+P+{ z8r7G=grZyQH|?QP!hL=6Q&GntT+W1y_|sEYeS>_GTz-~?e7&7L>Rjw?K}h#wcB=eU zT2hiuTab#8Lp9{hj^wIClOm2}n@>+m*Xc`xynNz%J*uj6L<5b`)lT#wkpm{D*WB^W z$J^2EU;&Tk-{lpCaQpUH9;p`X2Ytnq{$?Me*>as*L%h`I8#PxAf2?;X4O8t2mOGXM z3K5HZu>O3DZi8@OIvd&kZ+b07XU+N$PgDE}9)8}2Dn-IMslg9s? zsPVd3q`f3xqHq#QvPXdiR=*c~cE9Yekf}qIFZB#)-tT)n4}8I2$5uSbeuFOfSf%VPiN&{;cNPen)d{_|77^^R}6j_ke3lT-w|bX|Y^de@tO&GLX7 z-ccnK{;zn*AYoQ9*b5^jE%_vy6dle|F~AbM35MK%UruQ)U!IAZTf5m34d0!3%v?`G7M`Y;N(JBICTn1$D!H%>X6QRe zeP?l)IFZOdt9NH~PFiJPEE`>&*8y%V3?+<%enwO?GD&`U01e45XDE_v3pY3#oNPG& z0#!vj7__srd6kdO9Ckv_a>QqfpZ;~%skSrZ9h81k#jpm_P$O?fMbiJrIe2CzNVBnc zBkaZ!j*`V`B8bz3yM{T zh2Od&j0QFUY5^mVkv3V!kS|l9wDN#dUFL>)>;ZkqH?w}5&}Ug4tdu1xL< zJIB+SWPhG4z9tH771P4+C7C6~r_s}SFW}a~n5oKotVJqC|7e|%FlbG%_Ew(k#z}<27 zIscFQME=0Je?l7K7#g!DQyq~*BcwSKg*N})%r0b7k`zBpRYMipv@Y>5@b&&r_htD* zv4Wjxl0wk+8c_{(uXOc+p>f&(`SL@}GX2N(PL`mfUsd6u*<>XCglw@SRafZ3^JRzW zwQd3TyMOZ@rV3ZC;l~r*_ZRbFl!D?vq+*hfXglim{l$x~nU^oGS=Jf4Px5CZERlOZ z6UozGwR9*LEcs>5&>6}1${3iMN^UR6ATl_4N5*0WbmB88I@AdC7`aEwI1-Ozo`}sY zYon!=)9?;8lklxAfykRdKNWgj=vD)qM;o{1QwtB^qg~JK{jF$3rF&6MOA`xi+Xc$U z&A6{tG#g^NoEMvji;c7@#Y`pUX>rY8Dm&{f`>Bk|;c>m!o~MILD)C0@+uf9@Rj>_Y zaY;F6MUa(vMUt*WDH52uy*zWD7;_n3?ZqgT-Tu2pKwGqWy2#9i#TBRyoVw8Vo=NR!Djor4 zK8jppm`-CdS&(KqLCG$wU zW}5kV#(ll-=5BNo4tSp@#bnl;py}Uwy+i#5yxX^KZs3bfKaTs_lSicHq)1W?vXd_t z-pKrYn1e4h1NDxENH!w1B`!=im&Fmb`Za&bo(?bP- zyl|vB$4$B}_`6Ru9`7GFA8+DlJ_&_A4D9+KFYzks${1Eq=KY_#kM@L?!q3G+eYYPJ zZiM{J2QED<9^JVGAF9IblldRUh3;p!yKf90Be^1;Ma@}O6Yhu=LWo6DuFpvCsg|#r z!Xv2C-gCaTHaeICnd>u-SSqW9!CacBVAoeZB za{Pq4NRYu%CmWAa5!hZf(=$5$3nB=5`X9l%B}EO+V>(sz=LJI8A-WXe(%jB8FJY=l zouS8tln?D~aGa0~_8Jee_VNkUH*q)AP9MaN)6mf6Hu)tm^j~!U)WWlbk0@z zo%Q=H-yA@G4~JWi1;9$743e%7oxsK;#DpN#96QB>^v2tx#qO2X zQC^wH6n*A2&u5~0{_Wl0^vbN$_(t&imsE2}id3aeoIj_@y+A$Z$?DjflJBK+i&a;K zPep&!5O7UU7)G*B1n$koG3Ng%L|6YzO2+-#5#!Fk2HGZkcSnD|g)~Y(E?vG78E;0u zdz-#(^41DD^%CaZv~qNm{e*EzVb$i9h(gzpFXHrONWM2?=#X+5jhuO9{BJCcZ*6~{ zU{9{S?R{O%cMHMA>X&Xb^H$bftSQvy^hOYgeSXtd#x(c)_Yt7CjQx2fTz?L$QQaUJ8nBung9CW;FeE_wpi4tvGDUJ!Bzs+gjNuTL=No@z|KHw$+Y z>$TLVq{j-zn% zZ|Z`AZ^AZG*tDsB<4W^q!$jDvDaz?BYle&Qgg_1VDt}!xq(7TL=BwxCWy3D-^B?;Z z9?Qf2p7pgnZg_MK+`eG68W$a>j7kexcYXJGY;e~@dOuUoD0hv99(8Bv(EKpZdF*@l zfO>bg`M9AVpKeiD(gQU#rqqC+JLtUpb-kK@b9kH*etkKm4KJrd>s*kK0`H7|m!D~z z&WZmC8>^Q%D>qo$VIvurORFTzFcOS)xo>@~`&^oU$HOyh=be3v90MD5=dRWaErcP; zP!h%V{v{|ss{EfodS-RYo)UNk*S0|Tsm$bsVCUhkOrM)Pc;0RJGzui>oI@}pZnn*P zl6>xt z%-#t}$^?%u?$SvlxmH@oUG}Ls7~41Mja_yg`{w9Kp^|XC;(w%Q`^D`UWT?@^nv`6n3{3&PnyujEbW% z$oKTRpam26$^@|kcRE3;;09j5cP3oC#$O6Ks0VmB&0alq6*Vxq*b=2*H^e}+al$Br zz}XwTNtMdzo4<`Qza^`M7bc18Cnd{;1ry*-zx&$!GpB{eOa{$kgfS>VZ(SPa z#5x(Gga^|(cWr!lMC^~g*zBe`ft;UZz|>otODkLY7qL*5Q31(G_{z|i0Lf8~Cm1)? zOqT2@I$flQ2{aA={#O+JNnvnppM$+nGb2V*LqLK7xu-Q098)kgmFB-x8=$I{aNysH zCgbmI7&<&&TfEM{yL{|>oF(nN+Ud++7KFqXX9HP$X_@AO-accq4GoXSmigEFLj7L# zH^2b+SpMTEfC1fmyOV#n{kW)bX8`O~XWs#d3_nvF&)CSGvuY`J%ISw=*vin=@2~g3 z-O$cmr374k;8aCC{)QE+*4ZmGl?;xif0m?!bpEV+@fjuxFtTLE1#~+z=JIxsu$bMk zBS?^rr70*-2{o^(y^iD<(e}?lEczza+1h;5^0YPE*;D1%(E_IsV^niP>>frjW-rYN&#M*X!Nk=djrV2Mqhx3M z(gFl!M(vG=>QB5g3^+Jq`;^$XuJSf~PY`{xvE2uirOt>B&3x79Za~GI8Tf0=VMK#P zeyg~A!mNgW{Q2|iontUM@KOa}gUe2NM`jVVyXFvAeONir7-QbY@U?4Hhm_@H{PwUI z;H#mj19rpBzt@8M;tb?5*?v-vIhYn_&~jq&jaMLCXp<1DQ&d%W+&Cyt&%0(44m}Q= z9jo*EBOjpR9>Z^w7zp{UIbS)aAYf8^${_?T;!*mkC?MxtlAWS+;;s6bA4Wn7Jvze3 z8H1e%>6JZoC)MV8YgO~bpMQ;gJDN1#)BDBx>XJ%Oc}4YRA1RtU1-vyQb$Smh$fC@h zXVO4VBe|nvx!F8$schJdhjiaEvxIo6Th8y)7tn6TclF{7Ke&zZOgJa6uJ+wh1xDe) z&x5crqsaQ$rip@b8ySfu`7r5I&JCYodm(H>ZJI2O*Mf%62Sn=|75~7%O^Fx=jO9O7 zdux>1fBG=ysgmgaEZfyAikL)HdeDC4G}dfGQ|L@iJt>|ekp8M!inaQpOoN;ADpnu` zZ_vk`(b~F>hQI7XnFJ0$D1iiPdy1C+Yl3|bu0)5KJvLLKCZW}2%$J^XOI_E5L`Dda z*Be$&9*Kpay=E>Z78{gpTy=5GfrAnmW`K;EXIc57Fzmd@h@gL`Mr*OxM(@>jttlk_A4hoNWxr{2OJCBjyP9#e0E@bo3| zn_1TO&OK5RMZ;Fg!(zYQ|5Z?4M6_SNWBwIq6y*u4*4znJ$xA(EO9Nq2gF5%<-t!t! zH7MjZSXr%pP^MEc-iTf7@_xcdLw*)JoI*8}_1EJ*d^_nOcG~!(TL6HSljp#J0JU_mV3YpglexGEp1> z!-RlPtc06@7g8i|%(*?btEI$91oRKnUb?I)*8Ka>oz38bed_l1_I_m+jpKI5Y0WZ~ z#5|2}J5$+L-V-WbPA#PI1~zw`&k1lxv^R6i2C9O}DFIhQvwPs?gY}vXzJ*s<*M?2A z0i4>+-%>qr@WD-Ac*zktn0f1?K0JB8xQxAYsWfN!Zq? z<8h5cBX^fqR2fbKxiX~L{|?j3@HZR#p#Vv~_V;hpX_XE_FPaKJw@DK}<2ZXII8Q!M zefFiQ`Eaepnr?wRE^&t+1}DewE{AsO=`*H=>zE;fyt<{@of>XI0{QFj6F%N25w}8} zKLCG;5}(qyDC-uE6w2wMf*QV;DC*GVC1x@5+FdWDNm>mG9SS*3F>uWjJwtdcB;iAW zE(ITWr>49PHrb*&_2SsjD7HUC6_c*~k1yG|jDwnPmV+5#@OsoZT}SksFwdL*$qK@^ ztQ;TohyK&ka}-EOqndfjzG+?~&6PoJjj}-k#REllq_(cLU!U_1av(E-JQ{cj&;MiU zabDDx#}^9A&3cp{cAnEcGf)5-!&ic%PUFprqks4lv(KpKtg-9t0KJ#yC$g*i z$L+K%kADmv>l7Xu4#U@7!$+G1EwrqTV$f-+Tp>pn62sgXEFo8a_qwl^mgWxsQye@@ zIJS9mywR8Xu(NzO@a{^q>+q+q?sCA{{iIw)fU7Un@zd_Z<+aYQ_c-T&i6$G}`_6W- z)Cy=F0T&(PwyFiWau1!xwtxt<870oAO{b^Pr_Tx_Ggp5%uUUaH=HIDK!<&!@Vavss z39!G;bZKB8i){^};KyX1kr{m7TkC@JY}FkxN*9-COh&OsWbtMBd0r4}3XVxtT4ERE z1)7o*yHf%Sg69zt@1Ug&q5E>IN6KEnG3F*RAk*v6!WHwRms~57vM-F6S45xWP&7yX zXuRHPiHPKzWZ_Rypr>v8nD$2*90l$oaiq7J!fU-GB z+@jA{WUaV7^|S7vY};eJ>AUcrC7FQFj7Zi}^&vWINQJ+p|Ln7EMu~aCUv{H$6M4r+ zy`lR0Fsa}9^}x@270s42fLShEzD@W`VEybQc7{eMO}e;dj&*f>RX#9}BXnY>f&b-e zHGwA;WLW>0S-gV+Q(C@NG_SO+vYz-Cn8rsGs9+KHQijAe$x$dd3d}_kCaRLAyUK#< zSVur;(fyKX;c3fhS&nhzD6&j7?YFQrW7b9us05D|86)F(>*ETWDUGQn=a))^BrHCr zn8%pp!lzlL?|cn0|1LO1lG!KhB9rBAqa1p={?+)vrExs)?k@QiVcC!mN$R1GpTCl| zX~;=RoF+M`WF6Y8L3;b|NfbMOtIzgxATAz(fOKAFCpG9Gtj7Rni3o#UtGQJM7s4w& zqm+DR5t(sIx{yz0@2ts zAp1T#x=^0gIL-D2sUx{YaPTW@70*a_R0elqS%BoBmY26}TgSDd>t;4hKgUCKQX`|vs|>&$p^QIS!ljPvzU!3iVh zx@DLh>wIFZvlh3gvO-7y%@e=nB5NB6yxywzvz|KeI7M@?W+N9UiqhqsOyd@&z&F!HabVe-kMH6h+Ns?%gddSU{(0QEZvhNB z?z0sAN6P=K4TR}WQ@(~A11HvCpOygMJ69E}l>n~tqs#t6zre5ylkPLZ@Z(SU;b+g? ztw|@1*YPo$QB3`bEVsM)n=`b zCh9zB0PU8~Zeae$YQ3hI@l)d*G5tw%86=oFzpKF6vc8(tK;x(6w_ShP*5J4{3C5-G zzz=2PZVg_xhtH=jIbv70vACYPll)#RPnemyLoyh49%8($Bic}n3(Twd;I zW&KWMDMxroW@WcQRP~#0=jPTHydjD3xAf7~H81+o>Q6QFX4M3)>+R_|>ifptXHB69?7%y6Ml%iuWdj&3K<1U-F*#RE~cIRQ5X0jjFN5g($y!emB0@}Yo>y1z6|6|O=e=h)` zY^AGm*Flu-Xj16tWr0-K|C986$z{yjUgnrd^T*2C=h8EEYz}5ZRv~-+z_NDI2U$%QsholMyw zZbAhao~u@Ue9Q8~ILlrCcKFeuy?NM!40ZKw`@^J#AVmI}5D%RsoD*V7nqsHEl(aB+C}BxtdzAL0daElrA~i@rPu6#k z95CZ*KiU~v6~*D~VK-O3*i z07+C_9Dg1(_OKrzV33{3G5-AR3qkF-VVm!{GI|^AYc_1ce|gML&NGed@i*7lLS$D5 zPJQyiuClo&@;!t66N$5e0}LdkyN3K*)@($!KH{dPNtc~wrM~T0`TG~1n%B9Kd#SK- z^A}i0GPs4ckVn%aUp+6cNCHwXCI6tnV#^#lHg#`p5hQkcAnd)_tSP7d*#X`vcK|Hm z+RPp&hHP0w3iduH>r9LNXlI5<|8B;iA!8qu(V@q6!*i-hiQ?0YJ(k=lAy{*0z zd04`FysDZeCvQVM2xe&Uf{(y6>o!1NQXVP7$IdJl@_qK#Zr7oi;C%GZuVyobg;zM# zYENIwCtTkFwqqKhJTKqF?0~M*=SdCQ=8W4V@3od+hV1IRQ*#*@+ogQgo>*=G1hfo0 ziP-ve+Jr+M{WqRX`B7V7!}LjvDp`dz{sZn$m;22!@(;rXz}Oqd&HdjV@!nEw^!;KF z?3I*s>USTgav9($BIp2%;OJ!*Wsd*nyg4f&09KlZfzM3}IxQO@`koJ_+5!8+i&*O?&29ri`r>khxCX4fn z=9Cyt1@4{sXQwv+bMrU1;4*f$442cnQgD4ZbGKyWc-LnzgO>zod~j)TfIC8&rkVr; zU$WupAm0n*D{PLj-1DLzetimDACm~Y*r!u7pFYc)g6cz_DoZOL#dJA(KZ<8o?7nej zB`cRQwy0c!wKCQ%R?|5m#1inExivlCvVJV8w7BWw#46 z13tX&bY3+Gt@@GCudSfov9S|_&hyU`56-2pZe_f5uiDQhPvERhh^3|O%YcVDiNEJ5 zXw-5atpL9Gw;GaeDjhbvc zF|NYr4Gi=oN^7RD5u4g2{iIJL0Zb` z+)kX6^jmQON8`eD)Qrsf37M-l(ssVvt8wiEn{V5fg!9IsUdNb%*cL(33{bCG_NGz+ zLb1HKOO_~SXxR77;|7!F^C*C{-@=XSc5DD)P6B6DKPlKV?rCNOlF_I!XtL(tbNXa0C>F3KVSIKYNaC z9cxdZB5IEGzG58bZ|x9nBxxi%;HqGfh#;+vCPL+JB;jXAUga}49y9l5UG||~Newju zHVXfm_i)$WWoiSwBFv(Q(ZyNu8k6Kp65s+9)8q?;Qg4-L{b+Nk8-(-dWvN%A@|?{L zO{tYg2|!@kfOlaDsptosuOa*3j>lYxu(ae4;#HlFJv?hU-)1cP3cDsV&!a8J#k^3- z9#UF?MRO^2oJjY|!VX5Y7?f5r8UCz)0zo1fXubGph@+;-SWDMksl?mIt8Mi40_puv zpeOU7C0t}W%I2VFc9b0*d?~ZP6bRi$N5^&FS^MvWYdN1RPo~`eUzIjwXSP61%N$O3 zUyg*|j&z@-KJ+Rz)tJ4t7M7AMSe(UMW-D2lQMkEXaJP7#-vP|_Z%YpZ%bXL|usAWh zSTeVai4gnEHB(+9X#{7iRASBGu5ekN$=u$Tg2l(QN+M2D^+el@Z;8$bz(GJXU89^9 z1=yN(SVy;^)HF(9JdMxr^*xz8P1Fjed&9tDgdLQyWjO`wGRurqHE2)HJd5p>GLp*| z;KN5~Q`D>9@SpG$?ph>MQmMiGR&v$o;>hzf34%mloc(fBg>#9u2lYr}sTq~Tv$l3X z$7eUi=?#`&R!g8F9lsd=u5^%JR&iFco;72ELPL^ac59%b8iwW^0=oD8((F0}&uho) z<}k>#zV$|vGLCLxi6?h6FNMY&M^^1&qn6+zDO#_7xE)4J2FM0KWHvMS`_J!Xq0emu zN&hjPZUI+(XNwTDW zGI^84Nkc>Pr#(Clhy`nh_1#P5?gGnni6KBT916f^Y`X2mKFN_1OwC42BI8VHg|f9 zY35B$<1mK3!8<9%U-_p6u-n&ri$4LwZld*aI*m!0*U;3laKp7cY6<3!Iz3;$lb-b$ zNPXzJ1lOnn?V{nNA2xfVK7c)$L4<23J z2S|3e{aDQE+?6*M*1#SbIKd8`ud_M;ZWSeBuN|FlNyua6Ag)YolpD-y7yRVvehtsW zG$hfCj*uHisS)Kb*(Vz(YLaM8wpIL`POhxX9(Qn?S|S0Q z%LdhcL8Upzz*(ONt&Yyh2KWbL-aV{sFW>w}8n*esEq`1J*hwx(%e<0*MEyVCCZOv& zg}rY?co2Rd9i(~l;9ItS z5gvbkjr#&?BeS8f1qHu26mU7L*M&`%a63n87$4BHS0psxtus1P7-gBPsjf$tSMog@ z!FEOfq(b3Z{D4E;DXezy_$}E01xnn_Uyf!ZN9ifETJkS)t?FG=7D(_*6;neeZ*h@* zN5JUqVJIcFYyiyQ>R91u=B&xFv%~KD($R5?{P6IxaMC%VuXwePITL(%#9V9?14mTt zaXLCWegSQ+9?PT3wjMfhVuHiu7P;{d>r<_~ zXfiXIKd?*EORbE|SqHUr`)r%zE)9x!c8xrkWN=VW>z`LEOf)pxw17dKO>^cltJWQQ z4`$&uMwA=mgF8SUnZ9;kNDo{+K?UmzeT8n$rXHW@Kt%H2YnEo~>oA93Ww&&n`<)!e ze`5YKKs#jGeQfzhPJZ>{C+4HS3||fPHSPw#KG2WT>%R?)kq|V7b(ldoc)8W8t3PZGPFUxXSUKJ^=$ zfP{e$Ezj^zy99lT(IYZNXT3^MzM0iy$(iC9t^}-3rXRv@KPjd*z%=pL@txC!wHdjb z#uYg|&>xDfuWf$E4u|A7JM*3aNg~d{_f{_v{OwAJgTFQrU zp`V@=P<*NKZ(aJJhytGR0htMOue^Dlv8i}YW$X(wkzd|1{|ReV51%4Ce)66mhe3`= zntta*DvXZzvT_@npIFjMgPyfEt!-_qXJ-Ifpf=-=+-EtN?&KgM z2i~2Kx(bW1{kU+Of_)jCJ@HF@{e}HGflrnI0?$TN68eGm?4O7OauZL`v)85usE=n> zV|30W(cH~W6~)33!g?+_&BK*=W-|g4O|Ef5Ac8Cb)nI&Fr~=51W%BSlchGw+&I;OW z-MCr9Uf;!-$jc|`c}wGzJU~x4?iuPQ9&*SH_D3addXG7Yt)Yuehl_e>y6>nfXQ>xr zGXPLhf~*{WLg?+JxS)^%G+{4?&F~x0w}m1W>O2u1R2z1aT^-ISmkm8ZPK0dv0F>nl zplz9ZGs53vH@T$I}WsdjT9@I1CRBr{Z*P>LX8+W>K$FVm(%Q&8h!woS2G2Y}&Fq z4x}TAFgTJge1@MZzE2%QJB**8ZrgYC9f;8c$$hHg)DkKBNs(2B{T@#7-;=S2+V(Mi zy%MbFW~vdjdtN%IQP|ph86rUTK(lZPqBa=$m%LuKjrJUs?l#xhi7$ zGkY(6pf<;&mX1XZY0higUVtW^N#=RY!&pm7l|iSivES_aYKOO;Tso0VnS6jANTNK? z8nF97idi9h7_!N)aQgIdF8uMamGIh9?U#Maq75Q~?Au!_^77qnmX4c2$k57TJ2UY^ ztyE(SYsh7ezfb7(QvgeT`21+!+1iV(R6?Edp=%cyq9o++qx+BJzuw;{Y#kj%2xuLl zi%XRUrXc0n$i0M8kYqGW1m4<#L-0x*JR#sNBYXch3>G$NM zwO`Cdcx`Orp_ijf5U(F)QX?A>y%|s z%^!RlBySE6D*#e3ZZC0m_%b%JVe=+wMKv6ca^?#cyoh?UjS>)f#=6MG; zZ1i^Cx>aSBPZ&s{^F{R8%YsEa5-S3LZk^#Hc2-&C9)}h?i2VA$B^kyE$B_Mx8r7B~ z65ZE=`uZ1Aft%#ZH*@W;Li;pWa@X1rV-7>EssDVS&>ok-fg$u2Z9fIC?Dn>)o4-t6 z_?i4mUjWTfHm3rd{&gMS*Zv((9ZhF!X|CcoZ;R&NQzae5Uf)IRZbSeuJZWSpB-p>5 zY382erma*WcFZ9`oN2DHRuQ=OyV0cE=S}?3w3ZH|B%pd6+~mqzALTb& zfV5@i|2qeFpli2QL6n@0Qw~T~P*@3?;uQ{`#59XiZN`i_r0hu~tBd{}klJ)3P5qHw zc-3M3$MfU}W8SeGNUabb&zE<2bjlyF)1n&M7{FS`be3l)Pt0i$We(jMnwXndW(g#f z=Jy&*SLHO%`-Ymex3KGUl>N2n_6*7$52r1}3bkfC1zN#@W*mL0q}jys!;tNAh4b66 zzZ0ot>oip(r!Bw7Y)s;P``3Y~by^3~aco~7aFw&%?tK3^IUq8Z{Qn_!I*uhQxS+ZH ziS_ok=VT#6m*J1)*}1YCmfgpxwD0N6WmoQ0s3K{8k~#fmGB>7B6V5q647;h$`trz~ zNd(Qzv^+ia@b=Vg=^6}9jW@0@QdK7}`}a+mTtJh~(7P2jaNDG5+-VL>`d10{#uu9&FKq>Bbzf zY_(qX@9vt&lFVHE=ib+up>pA9a*=94_Cu5*#L2 zr|0dOLePsdeC~k5<7wBg#~+14$sGlAiKA7t2s(~fIrUXv`K5lsJY>`!Mn#8y$VAj< z7g40V5gwN*;^ETsE>NjTZeAoCA}`w|Q;s5XdnvxIn^BIilij)jB9I|JrqGOE*~Vg* z%$POK02ff?nE%jueW?U&?;Pf0Ue|4!R?cZIwHnPm@m*GK(HLJ=7+5DA=EhFVmj&bn`NxXG z?SJ=_&nMn_1_ccccLrmDujc}~#`f}|A3a)_{ENA4e&g_hzIL8#0oRS30zLrVKl*zNE_sMK2pbW9L(9bcd8d#+}xkIr%9m!vQ!=UxyxAl9+Xi8TtJ5?)kg8RJKRDjcTrg)-%!A@nMKs3R}8RMG(P+oaXBVeW#~ zStedY8JjjvdmG;%2emU|cFblxix94wD9#Kn7uIeKBVa>hz~0UGjiKu ziFGX|sbT2qyn!W`QK2J`Q2`p}b9|=MX~B*O_$y8w4IXk+fjs8B{Fv$c!x*a7L%7O_ z4(3Vz<9hewuqZu0aU!eJnU+NEB02CkGO89Py2L zbeGdKr2J5Joor*?Z>l&6FxU-E1%F(#dFN3B{+-Q%2GS|MA|O&l8(%3sMO*pE3@A*9 z(p10dAF&&SpGG0B@xz7EW^_uhbBCC~A`e$8R82tC3=5;x}B zisVktoga)%6xl1rN9+byws9nY|GMZ{w`kVTZc4G?y+KjW;b%rPoSNVzE`Hg_ZRzfv zJ*TMP)S?pp3>%(KUcV*H*4@%g6dpOpUJptBFL4;E9Mmq_{=H+PNkSo(!}DSdQ9mjv zC10rN^PFZL2pAHnsS6#6z9p4ZP+(|#VQtVGu!1MHw>%MiR9)z_k^Sr8r&6t*IX>Yq{LGl*;eJ8 zqTv!bM_#);bq*Wb!ud$8%Ox6vr^!~=rBRv9qd#dBlSqNr!p17MkP4RDe_1aH&LR=M z8ZwYyyYgh&CJGL|-7r^Lp8xOs8F^6kUiJh@pud;i>tHd%`PexE{dWT2!>v4h#Wq)U zAV(jB!V-pCSGKkg>(Ly|O{;e&@J}pqtXRWwz}FWd4StDQ?+oZtLE3j*-{(hlaVJsd zoFn`@--mei@Ta~lg;-n|z`kEjy9x-62X4-O3cT6iWeGhZx%{Vqb!aB=MivSvdqEmh z{4o@6&j`o$6^efP0AI^i>g;Fhe5u=NXsI~=b#8pMO62z<(&hAt*>jIJnEz-c1g24&4j5@ls56p!jh=r7y~cYj27!zuIN7cig8e-z-0jb)S5Cc)BX+&OMn9 z`kCEq;d9tD4?X%_ezm4>Kk+jOc^#79R$CE39caF$s|YM~-+PJpdka0!VI2ay?aZa; zJ-n{|0JX)mZ0mO)ReP{|^Y6lD(uwv5gBJ;gE+oEG`91!eS;>*TbJPh&Dp$J7NN;0a zXM4cHfxkUq91HfPS`X1{ai7%Em7;Gz{rfo*qPWKDRja`l=SeTbDr7P^!x0325%D5R zQcrj`7TO%Q7c9b5=lU08$sY54I%S8V&X9Mf>JYCoP7qkLAyYtS_jl}hkm!DGHJfIn z@gz!-o|Nz($iTUBD=SPe_RJnx*bra5NX5imJr6*Wm!I`Cb|isMCDT#g<$fP`>i4d; zt+jpZveS)q^57ZX;^X)!x747P_wqRud&xl!MYRmlDB)!VkmSVfOgVJk>+(Ux!{d2E zDHq;IE6=1whCM!-M3oQ{j28t2iK=+{dPY!1j9XG*fhYTP3$Xh>4(9Nq zOi1W9Q$0upYob^}UVY{tK+FRuFtA!j8Oq9p!pP`LMM_@8G#3WIHocYPrPzeLJKVkG zSxbLpE5b|r)48-nIs#a!jKsbXWPsFuMYsoVWrUKD7$f(-ytejp z>X78__h8>o0rFSz4X4z5dP#W9hfhy;Cv}1^cj>-%dFRiaQw`Iy_ujH}tvvKH`HEm^ zV+zhJVgxXEBq!Q2%eQLGpLg6|$n3wgBq7~y%!vh!NQE9p-FH4!FAjBxqwKn=dbhE2 z6*G1cWj%AcGsWTmI{E^}a$Ui)dK_2YZvo%rjML!0s^wnkHHRH`#ZW}Lv~cq4csv&} zM_Vr(`MT~rOS^&wS zo`6R_09~H69CBz{EpF-l;9>eT?1uDiUuZ68fLmpmq_H4m5ce=-&nN%tF7@tQQV;U~ zTaM|4Df`{UA2Fi1`OWKr)W;7Bx8>ne;;xwZW(Jv@t!QCs=?zhZ6G+$PX87Gma3pLg z$j3D-h35ow=8|@Xjl5(4kMjxB%$&^s04_n%zLG2gKYY*!N<>7GDB>(*|L{H+&mW_d zLTHWmjzr4;H+z2`u3LJZ^?|>4TGKb~dG9lyng^9irP4fFvavkJ25f^dV|Rj~I}Hwj zTur0wIBr?qCxz7>EIz;0Z9cXI?JJa*a}^+o^jCN}?hV0?TrVZR_r} zW_bs}bv0Q!KqVPXvp{><`96X}=L1&8Lu}JUx-Y7RBFnMC)9H?H1fWoL~v&G`7sFLLS9Io3ui9339u$|Yr8 z;wAKpK0+vF^BHw(naoS13>cHKy|o4itPkw%9V1jAO%kRjbJ8qjUX?^4xO)8>n`@gi zP0Pi*?`<%{PzymN=dr1VxdxP50IkO&7VSZq_#2AIuj zvXu>@5X5$YL!(6?F`7g{nkFP!idLHFYlPHDJX)uWh66_9F~pX#3aqS-D3Xi|XV>WU zdW?GoNnxlfi>s#$R#sSBTW2}h<@SlEX(WdyORCl}FD*r8cJ=RB?XtUni_7;t%KoiuwDT#6Nx18t`?-4U zh0cRlRrHGnBjEb2>wNszYJ~jun|Cq-jcAS!X$$GLjAlpfV~4!qo&?Qj<_xi;|KUJay}c0!%t2NmCY; z?`CVZ#=FjhTvshREpTl~@E)TC);qK`7_E^yp{z@!lt|x@^>XT}qD4~_Ig8m6=W2%I z4eDh{zn6d$1m9qUqO}dy1zbDF2gl;%gzZP)dG+M#Gvi3aN4nXsk4U8;1f)z+O5&Vl zkZPQ-@xl%b`ucZ1^-KTm z2ObO(a+7lI@;%ItkIB;kK?$-XA;yUH4iP-wdz$$itueOdY~1~d7N+vF9`&Se1MM*B@$w^#3)e;ri%q@ z<1y3e6py8!XPw$8Mgo>3%~&pGXsKxGiotk<5D8HTv^13Uf~M-|^HPGuFz6SEL{pxe zkPkPg7jqDF=%;i*be5CJgyW43py% zT=1um-H7#`(P$Nw_rW_ZT)fQ6c!jzuIXONew3fA%6{gD)BO>Q6UScsRao)1Jx<;Dk zXep?hh8M1UoJ2~_o!w%7GG{uS5<|^hm+vJT_SwC$$MNI@>pkap&agTva6a&>Pd)`g zQ#B34(F*-MXW5pludlIO)aa~7qF{S#ld4`~Lm_8iaMxJii1fdWy z((C2eC|OhuS)xc&Nv~HRbxK*41Roi1tm4`k=gwbbGCd?ikO;%tTAyLxkQo6YU|nE( ze9XhIdWhk8%(WZWdEw=K?%X*DHWrBkGmeapA5%fRPf$ zjwsQIp(rvi1LXP{za}`&feCE;Dz31!x?eW3Ey_3UzMxzy;d-|h;`yP7r3!}C5 zkN(G^^_g0PLc|b!^7B9UbN}okzx)e#8=WG9IGxiN#@pLmc<2pRe*TC5$^A-#7MiR- zB>IN&>JH^{LEA3r4+c0Ju&!k>@6<@qx1@QGev#v2K%36bWLr;?6>P6=v%7bbU@gXU z^D3RDr}!8{SyfbJ#c(|Al7p2&B2XA=+cF-FXk5j3yv}TTK!}1~p5sG6Ny&V1LZSr2 z!5C{>nyN%v;^U0a*@!f@lxKKrwhrtt()w4W24Lm5pJ>U4pXI2)0%3oPkp zSr>{}mH6QB4xDY++*qZqOGK#o@;5z(unyhNuwlu-2$~RB%q#l2W@CGu`Q(6Wwvv$95OLEAW%O~Zrd&v5p_Wj^+?kCNp%AA9mi)&_mXo147$Esruip7G#4 z_i_F9E(g1}LA7kG?NFqK^>gQ$9`AMY!*a@CFrt@0j5X0MdF|tmGaj!pnH(_M+~R2O z4!bvQvVGxh#^V8tX~~tBU*f)d?`1kUX0dEJd*(dzlM|9uqP1dvGDRl}A1vMlOrmML zqg*bjs)~M^fb#VFqpmgRyY`@`GZVLMNnYf%ZHx5{(RT)aExYbSh>GE0gwkD$E#x{Ie$#Mb9u3MB5T#Kp`kwkJ5$^JxyJK4A`JB zA`(tfOF}5>d49B!wknZIlA0cEU81Gw z#sE@d+ZOK~!(3xf)FE(u?drX6{OWJ~zN3@FN2|$pwbF4+TgLbefj&J_^E&Mh?a&T8!($sXcot` zb;WFQj1*n?;;dYvjV87psUgvd#28xZDa$23bk6#=T;QYS-uoV8cCt@XEfGRNjNQ&I zM!a*FG(#JO5E}0zqhdfLQq?Uc%gJ&{wXhhiI6j#mgnj8Hk50Jz@>$NEJI4HPwbC+dPap}xi5@Wdc(ph%SZFBzv5A*!<&oUZ~ z$nz1$Cx^7o(d+fOc>lw!^v9UVg!AV%IjELA`SL9m^O~lylvRsxH3~?wgb)KEN>Y;` zguwf5anlH*4@4oU>K44f7{ho_pp7F@kztXtICusW^u`0K=@AdzeSv3QxQdX0$KUV> z&Q|R1PI>0zy96&uvz*tw>H!KDI9Qe}%9a=ci?ZeN*%6Q2b&)109(dKGeDsN@x%krlDHa)CkU=yNGLR7K;V_Isp^WIopV%8&4r6+m>kd0Mp3sFAw-HiLrG0mWGt(aW?9lSEjmx}O#@2c z8jseen}ZmzuEAO8@WkOXf}}J3YpD@3PrXeV0*^)JLsF@+&XOnvcotQQ77?utCehfo zLRd$pI}%TprFbQ1YlkUvya~g2{YAn)SL_wN~8;GBmvO+>4LC;~T!^ z@87)o(&MQ~*}Hj-;p*nb*^8Hc_;<^*C1U&{1Noj#v=;OE<$v}4|McanFFuPhDKbQ+ z^JBIyJ;?co-|%x!y!S`mIoZ8RF&v#TwXzQQxR`cciMGYtj%MzfhPBN#jt-7H6;AAw zfJ&*(TO~9xbOyuA_ubD+ANvT#n9jee6m=UgQgu<)K%OSVNEeeXHEEill zQ_W(rU}Z35|L}mFwN;RYgX2Alybn@PS4;9dXSt{tj|MCj3tH>x6$v6nVsy;sB~r8q z40)vz?S8?;!9^>H(Q3Ot=hnTd-+AyQPwoQ99W9v+xm#^O8*3puU zwKaa?r+<;-qXkXVB6Wh%fiz9Kh!Uw$MfZCI-%#{2L~YTjAgXTOy1BlFk0oz=%{?Tl zbG(I&V-k4yomD^&D_!(_gLw#Fr6H6;lc$5{fsNu zuCiL>+0(bG9P{FV?6Z0eMlnLZro%xE%CO+qzOh# zCX)$yHpJQ%Ar(q_(j;d-J;8S|TFB64yA@fFdA$JFk}HLeV2mJDl48)OXAG*Baqhm0 zOb(|cwjm=@mlZY&avjh*0q-!0I=$Bw%gVAg&N!JYD2hH&3W9Ygr3gvNe7>Zgr9=@C zK@p_Fn2gG{NLP|4DU}mwAqgsy3V{zT;#9N|ZG|VtdPgx>#f3yN(U;QIUj?M4;?N`m#0C{*Xo5`wy}K__HHyr3)gKCtwj zJS`~81%uI$8#j*_42F1Hp33OE4VN$(H5qUF+Hd@+kNm>VenmAsp%{+%_W$Cqym@_N z>jS^k|}&5Q!m>r~(p=M&R0(AOua-G8&F4%LPgbthJaVp)SjA*3(+1iy20B z(B2RngWixBp=}!0R{A(wcQ>$-l(wO%D)N4hBJWe#79&B*gg`)vfKigNnp2lc5Q@Ct z>(WfihHS7(T`#Dbx^wS0ElL<fX4ubh)=~6xTIb6p{z;y$5spy@izAf8TvHP0KUSzlcgR)>ei*aMxW#sd(aJ&oG%BbK}+>`bExD z&pyL+IzComJyr>ArJ(N?odx6L}CnxB&V*HFg?M#gtknjbjczw_|? zMYK9PHC$jF7ZVLz-n&WsOjg;2o(+X_^M_T5^+v zfYvn-EXt&8?VRQI&5skEqpd5NW=TYy?yd~ZJBIxMWnGhLNp0CGMo*R<$^rdXw!vHN(pt_$#<3R(nq5R*vcV9L`g~OJ&BMsZG$!$Dos(w;9HN> z0_P({NR7gIhruC~#5)*lUO+_{6a~ww##&2|qT?_IOWRu1smai!2_go((6p|jUo2(| zq!a`?`K&~BQ5so~s#?$=P7J_}DWqu(7?yqH0K!jQzu7#={}QUPiwdP%f5aX~O=&K515P z=FASp2$EE>v%N#z1a{7z#n0#T&4PoY+Z^oeFf9>1;A4!@YcSY*c^OQb? z^esMH){=-q5S2D%k`{;K&2ztW?`t0a?t313_ydWN58iz7SGQt_WJ$)gtJm?(oZeu} zc+{tyOlfR|i=I?x_-F|hvQ!gYOWm|&y@KhY1|Ml%K#DGrC`k-a&>89p7$r_$jf5yk zM`JSY=nuR2pAaS1fe?n;I*POtW)UF>feQ|GN@kb3z@4I?jLKM+74@C%*2ojwrq6)Zd`(cZ0lPi|jL2IGxl`~3MI|NU9C z#3vt$wyD>C(IC6yhfGGg8>uDJDPC%V4M>^L`0nrOrlx5c zOsWucM${MrN+l>E$c*YDzS|ZhB-QEf7?lPIsZ3~`LqylbC@78UxL3q1V|H{vk!2th zLMWEy0)hh~Wz&%5Lt=SbIL2qzWEV1*`B7%A!XR%m_8_SsD` zW9Sbu-uTGAXK$f9Cw% z_y4o|9(vWsjEawphl7=^Gv~z1FTKd&?k%>@oTIf3#&r2pP18{1DN1X~)70t^K%p>3 zP_?c@omq=WB+gn=nG!|7`xd2BiY%dYT^l*idq`i?)E4g|o`8=EA1ywB^Bu}55OA)` zmx@B;mBI!|a=Ib$%0Ltd<&hx}oTaRmDA@&eY9Fb6gGf4Go}?3RLe%6_tg9jlyt3ZpwxdxMF$RH4|q_Lq((2j;o$FA5By7$RB5~XPBDf6nm z_o2sL`{CWagEMnxW`Y*V5n2&rl666j73 zt!pTXjQd{wI3IuNDWp1On}ygN&86xhOk~&N&5{&jQX(x;NtTP6&D9MivlE06s6>-U z(a|*sSl^N*J({M%Bsp1@vaCw-JY_yF84L=1+fdbxEKiU`T3eHugy1~ZwxmX|Y#c^+ zH)@e6);2fT+dIGok5(P1)+8CJk_hRsHH`0n4ZANrOLU&eh3ZssN|LW zCMQP}`H<1d7((Rs?kzUAb})I5!FWWT>T-IxTNHVZ%?o$^!lip3{NC+zm;OzfWrwds zA)G2n{by2`I@=7Z<>b=I?yYy+zViIH-n@R}%^!H*&!LPa&xTyPd4t|yh0!QwJY40* z)f)`P>p15*fA$<#ZePdRhTFGyxpe*lt7}7SIpf^0afd(Ulfw5*sMACl^v z)u5OqihuSaKf#?lCuCai)nE1)FJC+4?QeSvAARzddE}w{`IV1e;jRm3NmSs`2hQ{7m^BqC7KqcG@HqXjG$C0a#95I752KS7Fw*vwOs(C zOh}8o+laPHjF9x#H)&_b*v56IB&l#!LsVVLvB^_xWyyOP+T=J3s$URWM^jEI@)Yj` z!7d;QiaenVf!@VOIdk_zPwzkR-iKW|qpnMWbzR|+k|a@hC#hVEG8&^ZY_-Iwgt`f2 zgBr57tyQLTS<@!3KvAbg)kmi810`OJXzu zK_)dJSn!g@cJU(4Su&jylt3tf6rCC^I!~UZR82#YCiI3WlfyYtNJOY<+7{ckNTo1I zLWqJ?OY)Vo93Adsn;Fqtb~d+IG#1}>hU?lkWO+u_I9A5%RApzr#Rbq^Qma&;w81Dt z-L@22O50kpETs(!r6p2$nkFD+WY8~Y>zdV#ZJK6*8LhK_=N6B=`can4B}zKZUpVvh zs~&sf|Le7H{{w&du{XTqzq)k)tN#9Yb>j)G&GJ)s^y0I$p@a}oDP5;|e|Nlb=7Z<% zdDTC<=hct@-PgVGEg#%oU%lAOch40?k3o@v(99Pl7q+%Y2SaY`AMvYCe3;qsNjKxV z_aa3qQBjd5T?Sf_8gAY>B8@F=<4JTvTa{QRx$pc%UVG17_}-Yq$t}*D-QaBfB3m49=P$UU!Tbm@>aP8JH(G(mUPC1;GYzINUv5G))>-HTMi;{C^ z*D*$8y=635;qFWKQdTqWz55c{Reaqa`%nMe*2Vk&wfIC~`IHvm=e3LS$xBMrAMv8Afc;)V)7Xx~34|DM z&LdG6C9$q0F|y0D%lj0g720x&i(Rm*t17ImvDRU&!_^f8PxKLI>rRnaFR7cBqR5HC zQMMi}J#ACrq(`mv`LWqrAt9d*I7CPiu0 z!52kG1CmA|Vn87=X^yuIK}tl@(SV%uxOT~KZ37j-HA`Fw_~_6wvTPm7I?Ba_VzjZj zeeUf3^UplHx^w32-sjo^ItgqfV2q}%Is6$NEk zG3c-2Y+zZ<$+V_%-S6f+WVs=coi}BicT#f?WOWqjbP9#NQ~zE zeVlo(}QoA93K!G zk5-bl@wB#~myfAjLkO`m_Dh2{lBTNgJ`y8nKxsjcf;27ANb(}V6a%8|LOtCpEk!8_ zQ6dl>xyB^qgDyX<35rAsBCjY4EkR0L5D)||N@R%ivaIWJ2#qI#?Kq=l>kvXC5M)Jy zq${Wnjf?@U4LXq+ouO2M4=sv7+tw(lF-D=1l-c5lEJ+aF5k!lZl056ykIbaBb;*1_ zVOiG9mnWoYysV6-JlMmxZ71j&4hg~HtA?WJ;aW!~yPZUqW#Da>yGNuh8$#@I`kEGc zgJHJ@B`Iy=Fj7!E-?ciUV7|Z0c>99PSBK`x3om{3eUH56yS35F-w6f$7fsPR*uVYu zU;3G!{1c1Wf+S5TRyXioaB|}YGSL)+0n@{MJPH{-y`n(MZjRM7HLh(?S}`bwXsKAt zj!4rXf=E*@7>rh^mka8)B25aiTp^`meftvi;)tdVD5(etM&k{1mLXJ%l!7G5aJD8j zrgOrVB}tx>Ck7EEjcv)&uC?d8z$~11cvp9FdL!wjJ*u_=9|_iX516yKwjy{(h@F4K zoQf8RiWpi1k*Z!ILW^xciwLTN%SvQN#!wR5Mv}yUZE4#EA3RASh|Lj;>5S#FK`2lH z+SYbHl_(HGkfa$>YMN$=F&d#dm7ui|lWLG1d(gKHiB=smF$R*<;7-$fwd_=eCe4vC zvT^nj);iJHmN&fP9Y1*fo(F&6u{XW*FP*!5@4xI1S6&cGS@EeSDt>dR2cL5h{X|fx z3?|Kw$J>{F=Gn+~Iit4z_ie z-jMy>J2b5)m4Y+pFS2{*CPHVJWyxzFdCPN2Q;+uAQhPTeNYB6+@;qa4GU05J()5Q^ z<)i~B)6(mY7!3`x!$az(B1X-0K0)dPS1s9I8xuod)_T@g3Yuy`W>RkN?r}0(k|h$E zW^A0f$mD3w;mw;227T6hilQhOudLEGEq<|Jw{}!@$<3R46luomAAOYRq6Oi|MI`C> z5$%F+_%q-6l_u*Qhz^+cANF2L?4R~?{m$JRAK!9OP?d{Mpr87u z8Cpn)LgVNPSPZV~Qe-Jbrg1G4dD=<4qeCVM&HNaxG+K8_4Hk`33DTHu@pc`Wscajv zv>=F<`J(AMA`!~Qp|v5=8kwe@mrK!Y5@U;?^FJ!lMFn{oyBshnQ9^cDDXq{lo(99p zF1rti&H(}45m&LkVm_ZS?2QOQBa9%+$9N1nDz?t;aOd_-`u#CVE40?MO+$5XzIc= zB1N~!K0LT%&fWds?Yf!`Y-`V-yL9?;*LS{5VDAw0kacxUg)i@bh zPUmcFZV~Y`%>vhUDa7mBI~?!rVRXXInG3YRQ!f`p0SCML42K0}wWOaHI01Flpy)hQ zwe_e(AR{zQ-4&WBFxrqMDI4pXR8>ukK#U}rCe8cZgBLA04>5Mqc>zV5l4Uuzt&vJ0 zW49112S|ZIp0+hhgtJ)JK#T-yyO;_jRlOwQkV;WjH7Cc%=yb%LyDzIM<@J zW>MSIpvi__uTNDkNz)XFC?n7+XIah>QIML95F^rP(xgWSj$x70*cPJ%>l+)Cwx#F| zY1i_D#M;`khcFtb>cX_XW>l56v7!`0D?Af)XK0iDAU)$c2TGzet#?zM` ze%=3g>F&Fq)qe3!(Us!(=#V$Q^~+h#jwzQ5vaI0bWXjzSJjDL~A;UpVY9h975L!^= zId^s!Jg_q2!rc#DY0G-+*6fy!qCqrJ3^EcU7z@YZ;DlREg_W9H2ZtomFq@oEFDrWa z3geXwZ@YH0uS;U%NP7dE023WYM^jew6sZMm)37=)^ol;`FKknlHLaH@Z)vUN)}3Q& z7qLx6UrKB#IrN^WGVa{E!F;jc>%ROgyziq=a@U13%x1@2K7WCCe*GW*hZpXB_qJ+oWipm8{^jHUZo)Nt0>@+bV zwI;^c<;v0G0w^Q!5v=W!SiO%3C5f-#meQ0wOYs3(Z;9Svf~B z1R*7@bx56Joue2IP)gyNCAP5)R@T_xJEYeiqeY-?muw9Bq#8nNiM>%rvnXdsosft~ zFE1#UQ-t?j{+>**O&7(aq^5BW?;VNIwBC`WeX?A0Je{yQ=%Zsx9c;(*43boJtV5$a z5b^GfD}(zUd);%_UVQP(w$5LEUw_cQ_Jt0N{9P|vF-G;#55E6zz4zb$_`AJ@v=~#( z=JNKH=a|ioi8fF-H6cXu-Uw&wZtxjBSuvul=CtjSix=*pSLDnl$0S)w)pRqL{&+}e zJGQcFkeitwxTYVl*^K}Gds+tQwDiXl4VrO5+5SUXo7EP zs|MRvU27=K5mMsX8t)xdRpMMr-PDwAg^~ghHO@PP2o(7Uou#z4!_zn)AO?g^5)`p3&}qub&JH+1S|n_&uXF#S zkNx1=zvi3%@R_rh{%xA1lUGz}-GUV)LdH)j)w-Mfw^FcT*Fpc3hvV0Oj|f6aWs8-q zkDY(u(eEB7;oN9AeAUY@eT zefdS+e9wJs?3{h^WU;*ausIZ_$O*oNBw1@vNd_j`*xV?LuVttL{ z!#$igoZVSvJj_{^OH7iocQnVA3#wC`*vhC+Mqo7TQC5!exR3Ra^~N-_L-y|+p|VxV zx~6oN#bn9G<`%0#GEX4y<-GjyD}<)y&2M-;i*m`%)(Sgkc6ikT4?gqSFZ;T0m0C68 zv(BKta64x4xrw6-gxsR(!L&HM!4lt`)Yt|mctDHbNB zwT=)y2=Geb8cUI7G_KnWm{jB278wI=Oeu1W)=9@z^ns!`plxf29-}gPnc>d0>+27_ z_3i)u#iyS63wJ;8;P+^)tIsyi{5?^$_I7W-`=5R9-}|4Ns%C9_8>tj8J^KU^L0vbL zO+_!ysmm!b3Y3xPEW-pza1N7Xgw}C%ypM>H;mRtl>!hgD=?U}6gpIWg@_fj$oP+Fk z%_>b;-?@aJPnb-m>>uy3ESH4f5H?^#>>{*ngNuT?Y>=w+K-jjzT8oYyDyeNtk~AaH znx?E#S|O!Ih)(cPoN@tMAG-mk4Tw{Gluk2}tmx?9gbt|`x_Mh{yJX(hM~sjJ7qP*0 zYNrrMO@XuRX-_gU+}d8iddUJVo9^Nr7u?(ln>_o?b5}$$ALsdE?vO^^YHa_t$*;UH3oyJy}-l zeWEb^8ZVxR;Q zW2B!LvZB{<+;cP=oihAbhgH}mMkeq_NKHeeS8)% z(V?~G?Ai)#s7a)tT~=(KJx^4T!^1jM2o9kf{hV5Tj;ueMFMw zOlK9d`I6hWXWZOBCd*Pbx5ivv>v3j%%+MI7*Y6NF*GbY8>jTrnDQ|u3K3=-M%j(7^ ziPpUF%fITcu5OE#9Tv~VetG8zntNkYHq zkr#c^Bx8H$98q=|S$ThqmZlR}WjXzR(b++SM#`>$b!QL@AtWN{ zgb@8K1JQ*}swlg8H6D{CU7SrKFhbMT6#+$E%^>SB8uVxu3(_QIb$yHJ$uY%XNW^wy z2iLN4=5DYH@Rk?_-ggB3qF>-#O<68T(gGVHl^qFazN`^Sl4#Q@rzK>0&TP6M>kaS$ zWb8H$Qfb-{sGHEOMNwji9Pb|8bLOE3-#?o!@7XzX=BK}qZNlIAqV*{Yj0a)s>>BZ zbrBJ`7UtLwJ5EKNQ~<8 zk75WUNrI9QlccnbrL{HrpofSG9~y)Jb=qDa3Zw)d+EZ_r>k1?gaQI+RDkCvDI!!<- zj8Y5+1B_Al5J-z0qY|<-N2MttK+zu{wIT2INs*2@#cAockg^=zyQjvXr6ltH~;SiteX9g*R^u5)Mr&hPl{=)M1^*??6>Q%HhpbbYS z3(lNbXK(+2uS>5u*5Pku|?I&73^BdKfGZC;HgG%ce+AE`9PXiS!|vV9&S zJx8~0(bSeKOGxrQ>l^C~1|v+GvA()Nk{6`;kfyCrTG1>!1#eST%%(Hy5$NM)#(Q-toI;c0J(loD^t&VN}qNGY)av~XYsXenr%MT#yNgV=4X8gG#_RMYaZ zEb`uXb^W8gqIdI?8^_OYtN9CFw0>O+KzuUj@yU;T=)d{tANoJulJ)wmu5NSv`HxaA z=QMRoZ5w)7AM3jzW!FQt7y^w8=p^kHV%sUKRMNGzgj56xiB#YmiPB_gkJhyu9UL$i z4ADB{!ozQHt~rsTJSRyN&N>bbCmc@?&?ZB8Ph&fXW}fFHCdGSCq70F)V4=EZn)MD5 zA%-r!SQ$y0_rS$2%~*6KdFvoe60|aGY;WOg#7EyzsU0ZEsRZ8Qn+EGcC!^JdsP^$CD$ZkZf*kFrClo_XfCX(vdUTiqY0x zrJl~xtIFV;33=AXXc${TTpdvQl(wn3dhI&Jc#W)A;C;*f;fy>@AyKTaud_DHyB%)Z zQb$FvXILK($+e+rN>snkxy@b|3^-aPCK~So$1~6BFvV31?i?zH(m^PX}!>Buv-rM0$$^fsMc#Ar`h zxAck>hXK*a><5EBt!q1px_9K6rm9=KkKJrdNxY2c(=lxbEmhS$x55Vk5v4TB7_z+c zm)73Xv=$o#5rGz()<=8@B#I7fd;0xl+R4_vgXlvS7)h6WZM33omh^Q>ur)#(rY9$i z&YZ_Crw}5EHmDHs(P6!(ih^F=C$=q(@2opgiY_lt1p0Z(e7-;>Dbgqw%N9ro?E(Gs6B(0!$V2_fQQ zIlKI$KluIsVp-L!Y+Ypc#!D>c^Umqrw20{O(SZi()t!3=@NpqBJcMZjYgD>^XlN9~w-iuG=(~}dfUcbh{;XakEIlr|- zSuOEiAb~XN79rt1iB_a}*7d1{!nxBvw2+^WoGTr=(8L(gNrFx^N@+rf)J@fe9ukmg zpSE5gd`pO+q{KM~!XriJ^zT{_orzHhXsQZuWNCp=3VEt%il+nNsAOl!m7tUXB5h+y z(}Z$4MI{-^WK>N{nj5Nei8302BQXh0<1tAmz4nnVPfMuI>JcT;2l8Hu6kYpZYkQlw z{eiFh=Wlq|SN@T_7~XtkQzH0MxVrl?9jsg#t!+H9xcSnz@10ChiRAF`nCgS}QrLJcbT2b`+-6kO#8X=kPA98#&=eUIN z+7>Z37zrXc<|Uk88&kC|H_ zff$i05`;pDh_!*dP$Z_nJB#p<7(GU3_+Sy*pp_zq&Tf+!1JUD!I&G(`Ztmw{zy)PkkXy z>%Rl-!B48f#HTpofBfJ4@CROg=Bd?<^LMj*{bkDe6lX0$pQi1q*u`nP4r+^#q^Utm zP1}@6lM;NS-^(yMIdw*Q@+3!z&VNCO^zs}PVP2Ie8PRy|e&9lV{n-x>Zrr@XY`Hky z$waceV7i>6q{JkK)dPX=b1%N| z+-papF+Ms*gEjW|4w%k%dBbB5aI`mLr$551oT=;GtNI3!a#^y|OX%x@xq-#x7Q;c# zpD1wb69wA!Oii z|A5w6qW44zd6Hp$N3jsGBg~}50P6#dwa7$6P~^P==Uc365z0{34O%ODz4TOA5m72V z1>>47E=ht`1{b^8u#}qMT4MAdx{NO&BZMyg#0P=!oi#;Z@!oa#H5Kq)ptYuHE3E4_ zCBxndCnv|OZ*5?kE?IfDoRB45=&Vv1A%c(sWJa(xMrlf06KsdIn#>oNEFqPOrgfkK zQfZPTBayHu>r(-l>QvD#5Mu1OqDc-~(Hk0qw*&#g2ROxGDIuxb2CWpguD+y0F@D{~ z+WLow!_kXhk~6JOueQ%W{nTIl@gMqE-@3Vdp51HDQ!N(+8wfIhFtpW@v^ON6@ga7w z$q)zv9FftWPu;Y*&?1DuhJXzo?>tA730amRr0Ha-Q(YFxVqwMQj}6;dC|#O>p4;h zlr*GSg3=jDl2X?tXc6nGrW73p{DiMTeV= zG|g!1nn971CW`)G$T$D-Kl@)?dhp@zmO}bpH?aR*%Gvo%%unPeW%j47>eJK4aO>>* zcdxwkSDt%t9FiqNY*Vwkx=x}6Qfu6D3MOT|w#D(CTO^|)!(l;|2o}ql+LpMepqaD1 zxq{467G>mU7CD|Q5K^N2@>%ZlX zy*WwJ=@;kc^tm@4gVl{EUwq~x-*vQiNL5#O1o(#Kd`^)k3|4aL#ge9JsmfUgzKwy_ zdeT9LmMLkGGaj#yB?-Opn9*>BUVlKpmor{jVZ5@++WIELL4hzSgUld=BH%GvBcz~p z4yiRtxQ<4{>6|NeCl+EL#)u%07>N)HDZ2j}rAg9)C?wW)6#hi1PJ|`Ex`xac5Z&5i zbb&;Yq&bVll;L=Vax%l7c5$S%q&h_;DOFvel_3UC)z%a%>%?+~r0bG|07_W2NeOg5 ztIQZe)M%qvlok?2k>;nOvJS{lWPQ9)Eb9iML$(2xq#cnYdR$05u&x(4*HHPErfis; z?5nIlxc}~Z?)%5$Gp!N74WW!%Y* zk_7K+oO6V#!G%sm=1*nq!?aJ9DrVCuMQ_l}$&4a;uwFs5U2YWt=UPZ4(RHe+;9N(d zmIf(Y2mEX;o`7pxdRdQUJtwr0)^5B)vyNvXR3w4U%6-K^xZF$}x91xcD8 ze#Ia9wy&BTAN=@7KKfCjDUdf_Vo;1xB(%#JOeOXS5{tSE*yktcu9C zMoP)iWXjIjO_oW9jgitzWNkS(+GlNL#Omrgwpws>`$dMm4fb!{#E4C78yF5VX0sL> zI%qfrlM zOL~JLYpd%FR#!QH`7YMBwx8^e)}I-T1~2CQ(UmOA4pfrNwJ~!kr4>S1De*!GAEOX4 zdgFsj>$2Le7xN3pySLwdvVZ$6x365edwO`t;n8jC#hk7+BvD2Xy+evF*wG75k{Fb; z9ev(=yi91Cj)Z~+r7|klB5aK@1`#8*4QLSnfpabCFsE%=oRlQq(XX6yAB+-&_Z-94-vRN?jxev|tj=%c-5dvhCaYZ#3gyE5T$rHzv>VDz29sh|6;u! zef^vM$^)-{&7Zmc%#*mfB_FJ^wcdhj*gSVHXYaYl1NXn`>D6=R-n)6`{7(%BE6?kq z*f&Nke_eoOL`0(eT)%$=F2B4 z%Xn>_*~yYNN<=L{G_-9*YSZ~!kvNm!g@h1M-qAWh2^RAbVKn{WDlP>2Aut}Va`XBP z7SqZ7dC|Z1`MeLl;6(YybG-#C)qNS>qI2XvW zg0`)@n@4rNs#m1pGH6zMX?K&=OF%Lj3>o(OG}ZEzW;@Pyu|p!t?(I~eiw=lg%P#>c z+jb%g)ghmx7Oal8XxkQfIvCY5AV`Qfs?+Zuh@@#ky@=?n%hD=xL$wgpiy4h`s2Fh0 zG4~EFB;Hz_(#YT`lAK;|Kq3tDy6g}xSw<>7&2pdh3->Vl*a@3ks~qm_BZOiwOz~RM zR7d1VpWtE_l4lIXaKPK&^Y!o1CY}A7BK2vfmRAbam)fET@Zf9T{9V8LDl8um1yIpI5WR#eXDaP5Sutxq=_k}T

o7MY|- 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 P$^ZnOu6{1-oD!M Date: Mon, 2 Mar 2020 15:41:49 +0300 Subject: [PATCH 155/160] withdraw --- src/advclient/AdvancedClient.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index b4540a7..257939e 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -58,7 +58,7 @@ * */ public class AdvancedClient { - String version = "2.1.34"; + String version = "2.1.35"; JPanel headerPanel; JPanel mainPanel; @@ -4002,7 +4002,7 @@ public void showWithdrawScreen() { JLabel fname; MyTextField walletName = null; - JPanel subInnerCore = getPanel("Transfer"); + JPanel subInnerCore = getPanel("Withdraw"); GridBagLayout gridbag = new GridBagLayout(); subInnerCore.setLayout(gridbag); From e26301135265369222d9c78577993ddec6754bf1 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 2 Mar 2020 15:47:00 +0300 Subject: [PATCH 156/160] sign --- src/advclient/common/core/Wallet.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/advclient/common/core/Wallet.java b/src/advclient/common/core/Wallet.java index b6c8f35..accc42c 100644 --- a/src/advclient/common/core/Wallet.java +++ b/src/advclient/common/core/Wallet.java @@ -256,7 +256,7 @@ public void appendTransaction(String memo, int amount, String receiptId, String rest += amount; result += rMemo + "," + date + ","; - if (amount > 0) { + if (amount >= 0) { result += amount + ",,"; } else { result += "," + amount + ","; From 1eebe5b09e97eedb6925bf575c9f1bcc0a4071b7 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Mon, 2 Mar 2020 16:00:39 +0300 Subject: [PATCH 157/160] keys and backup --- src/advclient/AdvancedClient.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 257939e..90891c7 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -5875,8 +5875,8 @@ public void showBackupKeys() { final JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); chooser.setAcceptAllFileFilterUsed(false); - final MyTextField tf1 = new MyTextField("", false, true); - tf1.disable(); + final MyTextField tf1 = new MyTextField("Click here to select folder", false, true); + //tf1.disable(); tf1.setFilepickerListener(new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { @@ -5985,8 +5985,8 @@ public void actionPerformed(ActionEvent e) { final JFileChooser chooser = new JFileChooser(); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); chooser.setAcceptAllFileFilterUsed(false); - final MyTextField tf1 = new MyTextField("", false, true); - tf1.disable(); + final MyTextField tf1 = new MyTextField("Click here to select folder", false, true); + //tf1.disable(); tf1.setFilepickerListener(new MouseAdapter() { @Override public void mouseReleased(MouseEvent e) { From bc3e0cfe87ed6792dc6ce0eabb88dabae48c16ef Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Tue, 3 Mar 2020 11:10:36 +0300 Subject: [PATCH 158/160] exporter --- src/advclient/AdvancedClient.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index 90891c7..fe6c329 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -3363,9 +3363,9 @@ public void actionPerformed(ActionEvent e) { ps.isSkyDeposit = false; ps.currentScreen = ProgramState.SCREEN_EXPORTING; if (ps.srcWallet.isEncrypted()) { - sm.startSecureExporterService(Config.TYPE_STACK, ps.typedAmount, ps.typedMemo, ps.chosenFile, false, new ExporterCb()); + sm.startSecureExporterService(ps.exportType, ps.typedAmount, ps.typedMemo, ps.chosenFile, false, new ExporterCb()); } else { - sm.startExporterService(Config.TYPE_STACK, ps.typedAmount, ps.typedMemo, ps.chosenFile, false, new ExporterCb()); + sm.startExporterService(ps.exportType, ps.typedAmount, ps.typedMemo, ps.chosenFile, false, new ExporterCb()); } showScreen(); From a422f0fd6b8cd9a01906f1e1c477db5b08c9f82e Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Tue, 3 Mar 2020 11:14:34 +0300 Subject: [PATCH 159/160] randomizer --- src/advclient/common/Exporter/Exporter.java | 8 ++++++-- src/advclient/common/core/AppCore.java | 1 + src/advclient/common/core/Config.java | 1 + 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/advclient/common/Exporter/Exporter.java b/src/advclient/common/Exporter/Exporter.java index 0c37328..9f50298 100644 --- a/src/advclient/common/Exporter/Exporter.java +++ b/src/advclient/common/Exporter/Exporter.java @@ -94,8 +94,7 @@ public boolean checkCoins(int amount) { rv = pickCoinsAmountInDirs(fullVaultPath, fullFrackedPath, amount); - return rv; - + return rv; } public void doExport(int type, int[] values, int amount, String dir, boolean keepSrc, String tag) { @@ -113,6 +112,11 @@ public void doExport(int type, int[] values, int amount, String dir, boolean kee return; } + if (tag.toLowerCase().equals(Config.TAG_RANDOM)) { + tag = AppCore.generateHex(); + logger.debug(ltag, "Generated random tag: " + tag); + } + String fullExportPath = AppCore.getUserDir(Config.DIR_EXPORT, user); if (dir != null) diff --git a/src/advclient/common/core/AppCore.java b/src/advclient/common/core/AppCore.java index 43df722..7b954c9 100644 --- a/src/advclient/common/core/AppCore.java +++ b/src/advclient/common/core/AppCore.java @@ -1643,4 +1643,5 @@ public static long crc32(byte[] data, int offset, int length) { return checksumValue; } + } diff --git a/src/advclient/common/core/Config.java b/src/advclient/common/core/Config.java index bf266e8..35181ea 100644 --- a/src/advclient/common/core/Config.java +++ b/src/advclient/common/core/Config.java @@ -200,4 +200,5 @@ public class Config { final public static String PNG_TEMPLATE_NAME = "template.png"; + final public static String TAG_RANDOM = "random"; } From 5a33e538f74835acb94149d06d817bedf784f903 Mon Sep 17 00:00:00 2001 From: Alexander Miroch Date: Thu, 12 Mar 2020 12:59:56 +0300 Subject: [PATCH 160/160] cocacola --- src/advclient/AdvancedClient.java | 52 ++++++++++++++++++------------ src/advclient/AppUI.java | 47 +++++++++++++++++++++------ src/resources/cocacola.png | Bin 0 -> 60960 bytes src/resources/coke-logo.png | Bin 0 -> 28755 bytes 4 files changed, 69 insertions(+), 30 deletions(-) create mode 100644 src/resources/cocacola.png create mode 100644 src/resources/coke-logo.png diff --git a/src/advclient/AdvancedClient.java b/src/advclient/AdvancedClient.java index fe6c329..2723dc1 100644 --- a/src/advclient/AdvancedClient.java +++ b/src/advclient/AdvancedClient.java @@ -37,6 +37,7 @@ import java.awt.event.KeyListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; +import java.awt.image.BufferedImage; import java.awt.print.PrinterException; import java.io.File; import java.io.IOException; @@ -62,7 +63,8 @@ public class AdvancedClient { JPanel headerPanel; JPanel mainPanel; - ImageJPanel corePanel; + //ImageJPanel corePanel; + JPanel corePanel; JPanel wpanel; JPanel lwrapperPanel; @@ -445,27 +447,34 @@ public void fillHeaderPanel() { img = ImageIO.read(getClass().getClassLoader().getResource("resources/supporticon.png")); icon1 = new JLabel(new ImageIcon(img)); - img = ImageIO.read(getClass().getClassLoader().getResource("resources/CloudCoinText.png")); - icon2 = new JLabel(new ImageIcon(img)); + //img = ImageIO.read(getClass().getClassLoader().getResource("resources/CloudCoinText.png")); + //icon2 = new JLabel(new ImageIcon(img)); - img = ImageIO.read(getClass().getClassLoader().getResource("resources/CloudCoinLogo.png")); + //img = ImageIO.read(getClass().getClassLoader().getResource("resources/CloudCoinLogo.png")); + img = ImageIO.read(getClass().getClassLoader().getResource("resources/cocacola.png")); + img = img.getScaledInstance(178, 58, Image.SCALE_SMOOTH); icon3 = new JLabel(new ImageIcon(img)); - img = ImageIO.read(getClass().getClassLoader().getResource("resources/depositicon.png")); - depositIi = new ImageIcon(img); + BufferedImage bi; + bi = ImageIO.read(getClass().getClassLoader().getResource("resources/depositicon.png")); + AppUI.repaintImage(bi, Color.white); + depositIi = new ImageIcon(bi); depositIcon = new JLabel(new ImageIcon(img)); - img = ImageIO.read(getClass().getClassLoader().getResource("resources/withdrawicon.png")); - withdrawIi = new ImageIcon(img); + bi = ImageIO.read(getClass().getClassLoader().getResource("resources/withdrawicon.png")); + AppUI.repaintImage(bi, Color.white); + withdrawIi = new ImageIcon(bi); withdrawIcon = new JLabel(new ImageIcon(img)); - img = ImageIO.read(getClass().getClassLoader().getResource("resources/transfericon.png")); - transferIi = new ImageIcon(img); + bi = ImageIO.read(getClass().getClassLoader().getResource("resources/transfericon.png")); + AppUI.repaintImage(bi, Color.white); + transferIi = new ImageIcon(bi); transferIcon = new JLabel(new ImageIcon(img)); - img = ImageIO.read(getClass().getClassLoader().getResource("resources/coinsicon.png")); - coinsIcon = new JLabel(new ImageIcon(img)); + bi = ImageIO.read(getClass().getClassLoader().getResource("resources/coinsicon.png")); + AppUI.repaintImage(bi, Color.white); + coinsIcon = new JLabel(new ImageIcon(bi)); img = ImageIO.read(getClass().getClassLoader().getResource("resources/depositiconlight.png")); depositIiLight = new ImageIcon(img); @@ -488,8 +497,8 @@ public void fillHeaderPanel() { p.add(icon3); c.insets = new Insets(0, 20, 0, 0); - gridbag.setConstraints(icon2, c); - p.add(icon2); + //gridbag.setConstraints(icon2, c); + //p.add(icon2); JLabel wlabel = new JLabel("wallet"); AppUI.setTitleFont(wlabel, 20); @@ -545,7 +554,7 @@ public void fillHeaderPanel() { JPanel wrpDeposit = new JPanel(); AppUI.setBoxLayout(wrpDeposit, false); AppUI.setSize(wrpDeposit, bwidth, headerHeight); - AppUI.setBackground(wrpDeposit, AppUI.getColor1()); + AppUI.setBackground(wrpDeposit, AppUI.getColor3()); AppUI.noOpaque(wrpDeposit); wrpDeposit.add(AppUI.vr(12)); @@ -576,7 +585,7 @@ public void fillHeaderPanel() { JPanel wrpWithdraw = new JPanel(); AppUI.setBoxLayout(wrpWithdraw, false); AppUI.setSize(wrpWithdraw, bwidth, headerHeight); - AppUI.setBackground(wrpWithdraw, AppUI.getColor1()); + AppUI.setBackground(wrpWithdraw, AppUI.getColor3()); AppUI.noOpaque(wrpWithdraw); wrpWithdraw.add(AppUI.vr(12)); @@ -608,7 +617,7 @@ public void fillHeaderPanel() { JPanel wrpTransfer = new JPanel(); AppUI.setBoxLayout(wrpTransfer, false); AppUI.setSize(wrpTransfer, bwidth, headerHeight); - AppUI.setBackground(wrpTransfer, AppUI.getColor1()); + AppUI.setBackground(wrpTransfer, AppUI.getColor3()); AppUI.noOpaque(wrpTransfer); wrpTransfer.add(AppUI.vr(12)); @@ -758,7 +767,7 @@ public void mouseEntered(MouseEvent evt) { public void mouseExited(MouseEvent evt) { JMenuItem jMenuItem = (JMenuItem) evt.getSource(); - jMenuItem.setBackground(AppUI.getColor1()); + jMenuItem.setBackground(AppUI.getColor3()); ps.popupVisible = false; EventQueue.invokeLater(new Runnable() { @@ -819,7 +828,7 @@ public void mouseReleased(MouseEvent evt) { AppUI.setFont(menuItem, 20); menuItem.setOpaque(true); - menuItem.setBackground(AppUI.getColor1()); + menuItem.setBackground(AppUI.getColor3()); menuItem.setBorder(BorderFactory.createEmptyBorder(0,0,0,0)); menuItem.setUI(new MenuItemUI() { public void paint (final Graphics g, final JComponent c) { @@ -878,7 +887,7 @@ public void mouseReleased(MouseEvent e) { */ public void mouseEntered(MouseEvent e) { ficon.setOpaque(true); - AppUI.setBackground(ficon, AppUI.getColor1()); + AppUI.setBackground(ficon, AppUI.getColor3()); ficon.repaint(); popupMenu.show(ficon, 0 - mWidth + ficon.getWidth(), ficon.getHeight()); @@ -926,7 +935,8 @@ public void mouseReleased(MouseEvent e) { public void initCorePanel() { - corePanel = new ImageJPanel("bglogo.png"); + //corePanel = new ImageJPanel("bglogo.png"); + corePanel = new JPanel(); AppUI.setBoxLayout(corePanel, false); AppUI.setSize(corePanel, tw, th - headerHeight); AppUI.setBackground(corePanel, AppUI.getColor4()); diff --git a/src/advclient/AppUI.java b/src/advclient/AppUI.java index 3aa2a61..02b377f 100644 --- a/src/advclient/AppUI.java +++ b/src/advclient/AppUI.java @@ -142,24 +142,32 @@ public static void setSize(Component c, int w, int h) { } public static Color getColor0() { - return new Color(0x1C1F28); + // return new Color(0x1C1F28); + return new Color(0xE61D2B); } public static Color getColor1() { - return new Color(0x338FFF); + //return new Color(0x338FFF); + return new Color(0xeeeeee); } public static Color getColor2() { - return new Color(0x338FFF); + return new Color(0xE61D2B); + //return new Color(0x338FFF); } public static Color getColor3() { //return new Color(0xBFFFFFFF, true); - return new Color(0x303441); + return new Color(0xE3434F); + //return new Color(0xE61D2B); + //return new Color(0xE61D2B); + //return new Color(0x303441); } public static Color getColor4() { - return new Color(0x2C303D); + //return new Color(0xE3434F); + return new Color(0xE61D2B); + //return new Color(0x2C303D); } public static Color getColor5() { @@ -167,10 +175,13 @@ public static Color getColor5() { //return Color.WHITE; } public static Color getColor6() { + //return new Color(0xE3434F); return new Color(0x1F222B); + //return new Color(0xFFFFFF); } public static Color getColor7() { - return new Color(0x14161E); + return new Color(0xE3434F); + //return new Color(0x14161E); } public static Color getColor8() { @@ -202,7 +213,9 @@ public static Color getColor14() { } public static Color getColor15() { - return new Color(0x224068); + return new Color(0xE61D2B); + //return new Color(0xE3434F); + //return new Color(0x224068); } public static Color getDisabledColor() { @@ -406,7 +419,7 @@ public static void setColor(Component c, Color color) { public static JFrame getMainFrame(String version) { JFrame frame = new JFrame(); - frame.setTitle("CloudCoin Wallet " + version); + frame.setTitle("CocaCola Wallet " + version); frame.setLayout(new BorderLayout()); frame.setSize(new Dimension(tw, th)); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); @@ -418,7 +431,8 @@ public static JFrame getMainFrame(String version) { cl = AppUI.class.getClassLoader(); frame.setIconImage( - new ImageIcon(cl.getResource("resources/CloudCoinLogo.png")).getImage() + //new ImageIcon(cl.getResource("resources/CloudCoinLogo.png")).getImage() + new ImageIcon(cl.getResource("resources/coke-logo.png")).getImage() ); return frame; @@ -791,4 +805,19 @@ public static void invertImage(BufferedImage img) { } } } + + public static void repaintImage(BufferedImage img, Color color) { + for (int x = 0; x < img.getWidth(); x++) { + for (int y = 0; y < img.getHeight(); y++) { + int rgba = img.getRGB(x, y); + Color col = new Color(rgba, true); + col = new Color(color.getRed(), + color.getBlue(), + color.getGreen(), col.getAlpha()); + //Color col = new Color(rgba, true); + //col = new Color(color); + img.setRGB(x, y, col.getRGB()); + } + } + } } diff --git a/src/resources/cocacola.png b/src/resources/cocacola.png new file mode 100644 index 0000000000000000000000000000000000000000..6c8a1ea45b69b99e2d71f8838c08ed4108abe40f GIT binary patch literal 60960 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 literal 0 HcmV?d00001 diff --git a/src/resources/coke-logo.png b/src/resources/coke-logo.png new file mode 100644 index 0000000000000000000000000000000000000000..0d87648662283697572905cef0f8403de5d7c0b5 GIT binary patch literal 28755 zcmX_HQ(&Cm)85!Y;4NAc7h;0H>);7tVbz2Ng7H+(KTLyoEMe#Rb`tl&B9QcR4O zKeB*6d@jbv7;U|*zBMLl&1N6A#<4XujdxsvocSNuvWQyu66IO`|Enr=sUSGmSaT1% z%CH1GRzDwypv1}nrarmgT#>r2y7*XTV0@lp_+ONNPUW$7kzEO7G||%TJ=X3thScVw zpNM%|F}7mwVc^W+OJ@?NJ2yz&ZIoJjY>5dn?nrO2+faH-D?!i}7^0t3%icp%jxPwg zrm(;l8hC^(zrgyl{Kd1l`~!Jh?JiZ3n`24i9)`Vsenk21l3*l@%b~dPB-*Dd=L2Qs z)?4JIeVBQng*X>VIzYHYWA4+De#q(W&{6L8ZbJU{-t%vAUw7&O4&%aZ$(vYCje%S2 z&1rB}R&IZYK8Mp9=~?ioy`H&;W0>6^^#Z)X60HVHjTtmblh$9Nmo(~g#uS+{fz4cs z=!6axG_OB9hU1PnHx=`|zXUy8L(dE9gQQIng7O=`nHqt*KAQLSW^(0z+1ihfjedz! zWoeb}4@2oTn4{cNJeL4?K>&UNb{TIn#*VGwAf(}fj7t@z11^Gb57Idmm>xjwOpk&+ zSJ@fIg3KkK{tL4)ga|}vrI&5J7&nM8fc-@KP(y4?nzzYC3V{`phM6gDeuH_DP_NLM zUmp%LpVcsI-elV`Ci-7Dn`8YKzg#6JFxT^C@pR>V`e*nXncF5%GB>)^*VPW`p@K&0 zg7*^b@eC&Kjw?PTGjTFgftgTp2xm-E-IySb7ybyI545{Y&AWQP&=3Owt$vf=N5-=O z-C_^F%LugRa?zp>PBJN(Yq$blsx6bjtI88-IC-~l-i`fdG{?}$LNL@7+5xw95a7qN zf;d%(=_0@0*73G&4IQXFGi84)$`1j9tsm*2QxG#{n32nBLYHa~l3K04D9XLKc=w|i z#}W1=qD-o)PIFgiH4ht756adf-sT0^w)7Y@q+UXxFSB4~9wuNK!)-O@Or?+_UlsG+ zi(dpP0L4i9IpgIsdH*Cyf%=B@=E5is#TJPSrA#xP_o<{(T1k3)fQ3#6GXirK&D*K& z`+i~tDeg%7vQES3WCQj)^Qud<5L&e>78YIIYKI-)EMjs=dFt#Gn!`<>;tl-aoES9# zJk>JLcM+MerkK&et1F5}GxeDRJ?Org=51)-y19&zlqA0$&A2I8^a6NlMtzpnM1#dN z_HHo}G()VrTXFSRVB}k3Btuc)ml`|`YD7)QFX!S~zYkApmCOY5)n~d&RtW|n2EQ*8-x(#HTP&%;b@s`3<9bL9WN- z7lF{HmQ%g@{iVX7H%``s%|>W#o%tTY!;-Jzr{!_W*Ijw;T>xZ1L(_NFlOTBUEs4QnJ&pKVT7iA7IV`f8HG9JyQ!q}BbJv_q}_|sw~qnehUrn3 zB*xPYp=qr@Zv~Madbv`xj~wzhAhUFbLUlSKt=M~VE7zba=>4&j3NwXkXnpp{!>rhX z)O58@?7x3J>-vyeg6;Oc#TU;UG7BnK*e>Q6Fe*Nbtl7z19Alfc% zlbv2t&>h>~#MSIwu41uAF#ngx{I^z4ZDz5Q)7CRi)kvU&Qf+V1=vIwij}|4IgqFPC z!5+bM2MJ9e_{C1e=Vur1yeu%IEX6*re2@4GEK%1fCV$a)$FDPJ4~bs7>#0yjeSD6w zb80OZH)s@U@#N_6ME=RJ+cU2V`Kw`0EF*5(%HbMR-)xXsgn6{Sqv@(<!KsHg~eh zqz!STIVt<*`{GGr#lcMX9Ht=TNJ!yCze{U|4xq0v=V{O@nPY&a>?rUA-jR%bdHg4a{Qu!Zyk@Bj9= z<$v{^GfQ}1l=34PeR$7tj=u9hurHR2BcfX ze(Z8$J-2X5_H89(ZuVatsd2j{78B(D?Zd^?--j_97jMO&e_ErKlIQj=GN^ZR)6&&SgWMN@(hpsX-H3^jj; z`}c<8bz!giRYok%)K_e0Sc9@%M{dvbD$8N}Dl!rV6x0YE=$t9H$9G05sTfSve3OGiLM;091yO7Q`(cZphX6Z0JgQ}1{bq0Qk$ns+a z_N^r{3e;|0xF=&~*qDUqfS5N6`UJv4(91#ee=a=2*)SNJn+y)aB_+l-^e>NfqJsml zYfuh!n)ljr?)UirMK&cBn;(JIlB$bjTVNL_O&+AD;qiWmD#Lc72lkM+0OR6Bg9uh1j7qTpEdD2Ib9|96q6+AcC!i(#W(Zqy|GWUd|Fln7E6H`8SGz&4#TBXC@3@ zC{P}q(}LAsWb+)8tZx(y5yi<$(@AOUOW@9k@^9moUV?7qn5l#H#Q85B0td(m$3!U_ znv?~eO%2LYroW5^`qLGp+Jna6m_3w7t{Je76Q``;&@y7`hp`ZYS#Bx%{W~t#z?lIu z#?mFOkT84gHf&%*YZFd7e}LlqCp194rH6o3l?F#Q!#@>}o3?yKB{uhwZJ1#UDkj)m&G2yk5s6~nKb|F^ z9&LcF85IS+?#p67{?y&#&U>e<%9A=sNy9_o78tFdD6+2C&Zexwf{=yK~b%I z172*(zgGHD{!ea|N6Nw9IuVKXK?$Sia=)Y~z~d^Dfjvv`fM(AUWn)8zo(;`{qtB^X z3TwIFj5It2l^F$X*4n?5hJA%C$5^4C<4@HoX>|#rvH$#n0gp~ZB9o?n@6ZwuHK=yh zZ^N(F<8V||aNyD*TyfK%Lt~m+`s85{bMC78?yDevDzn_gyP2y|}c@y{AmyOXX2`m)!mI%OCs>s+n5Robkz^UrCM zj&5I6D-81e>bkSO*%}-e00Io8H#Vg-Df!>HZ)0K+_N_ttPM{+*GqV~TeeN!9Zu1Ii zaKdRiFsdPzyrLFEcoba~AHhsRvp5%Hb@M?|n0p%c`vNVZ&rqNKh1RcjYM(qhGLo8m zkk53$BY-Tjl`CM~SANDgfg&O;O$YG452YS^#zE0j9jubI^IYht*$n?Cun+dq$Y(sF zqEko3IONxps!F`MA_f>Ng3L6tselR88FeY8N9~CgcK8Ok5>736>1`_^nTp4Rm z?4{f<+1?tY07og235}Sr8+5QSW*h9}qt|M=0?a;Y$hks(+c3Pyr@;S;ii|9_-8foJ zRGV04Kh@s^_~yo?-w;A}|7GI7Ndk(3ANdiI=c=A=hGotDM9y!!j~{jy)Lkc4s;r>E zB+&=Q6IHsWW69oVsm8*eBWi(3cP*|QDdC&0GH zulo3~s2HNxWl+=Onw*WAyb4s7Rsqk$a`x7q+6Q>*7Le9sRDk8EeDu}@qytX?q7IzH z@Nrl4pkXe{YwkKAVW#gvM1l{K81975sL?p3$?=7{;0?2KsrIxBQ3{YKSPPVGbYYag zj@H#jmr=!2b5n`&sDlHD?LUcqY?GO<#ZUHmro3jnIcCKG-S6ID1HtyPT{QKn-8n|A zy;4?Riq91{kA!@|#3YOvW2LHgBH`#&r?q}LSuppQ(1_(_^OYotN=sWN`yL=7enDbr z8G`CBKNR~KQY`(G0@{cPO+rDzVOmI3N@VKeA39wZ)9wn<3({Wj;z$TO_?d54OWsLW z)`wy+T{qnKpNta=)@i_BvWUds2}+oGS{(kOn_I*iKy)t3(}*>&i!{mw>zc+9A!)pc zS|ThGA0A(DxOt)5d)MjsZ`H|RL=&)PE9gDd!rj-Gs1! z^s9CVQV)xL>?)ZauZlHqu#gF&hu<=z3*pEMO3_YuS}WFhzXZHnEhCxpryt)ir0`q% zWIQT&y1_?j*nW72+Z@ioPp^vQ z>ph_zc6%1`;znRKXHX(s`UYmP%;SXd_{1f4YlmNu_QU^El+>8$7nQz^ySMiSObRX* z;T={;6Lr1U7k365{;xO`i|4YQMO;jH*M9*@^CSw-mzGx-yzipV6QgPeF*%0M2|4$9 z$uP!%|LOU|GvS@&@07&8E^HrDr5hzY^$XMiHmI&cQ;AF^@V&;1Q_R~aqx*t%g8fD5 zuJ3`4pP$HQt?g%}vS-2R`y72{Q?mNU6mix~<>$VJL%ZM#NtI)Lrn;~>ZK=ci@z3|i z`=>{X>sXAxjBaPwr-Cy(idl6iR(zJ34!ggc+p^WWR=z2%h%|YQl{g(s(mG3jS|NV^ zDk>ggb@yw)V*^w7axJZs z?4up$$K@WtCd>H0YzZGv-u91qdBQ(wsbt)q=E*i_Z+*c9nYX2~?gOjR=atl~hw5(6 zwi804(u%*4hK%}pSwBfr`C^+lb~PM2Gu!E4@TA{f0;MPk`IFl(PUmy{yXL$Pp_Kj- zUh+AT`t3AKywBVEIXBI{%_Awj7cU853!V*THp1zEsv%71{(0M%p7a!Eug*<+5ma>! z+J5&=nR_{Ce-mK02i*#l9)HMWw?$XGmB$H;mMuput_mb+cPgc@#I=N zr)wr)xR0%*?MMt|2)t@NYM#|ySv~O3)Z#zC#TD>8G`{$yn9c%V$5?_3LIJjCU{1PZ z~YU&YF&7|HDrlitCv3favu%(w@9Dc zm85>V$(daOM`CGms?#uVY@mA5r35OT(=n#YMQa~I%n3pE_Q zaAswEP6zvMv6tS5#CfyVMacA|j5XF3CXsRhRDeARn5)v!Jg((vLL0Un@4^owtKAqOKp{2xQ4;H^qrqvsDRx za+Lc1HC$71uMw>_;owL1;rGNfI_BzrVhE_NijuRo^m#3xl0${c3Mm=R`NrV2!h8P6 zK)F@X{$yABoQ|9Q^0&&e=l-4syOXK>B=rvIjg2tL=xiWie_t^l(_5zWAWi-0&f#?r z$=cG;@2D|Cy~TV~t<-IogfNTc~omrsv^2h#?(lA=IR%Pr1YEw|l7V$UV&ycyh5hldksX`T>DSsbb zv1i~O_ezN08U6Q5((GhMMyoX>4Gc-K~a)7#AL-~7`0(6gz2 z{|&MyV*2zS>EJ=^QP>6Pm)4HjL4%IptDo?t+a-e857k{r%`Hb_6jWk1(H*Ett1lJK zZYL})X4u|+`b8Dyqa3B%8JRGW;kGu>JL32G!~C&cB0Zu9@iMt@SZ6!&4elTWkV!7T zqO$Pmys!eWGEO5-m z6*`A4$Zmh~_3Gs^uRnKAtn&e}OZ_y0)Rn4nHo8FIAmCDi6l69Qp#sB?fzrIuPtMg- zeUO&a|Jha04Tc6C)4L8!j|EpUu4ihDmY=153b{f}Vsfpy2>LkYv*vSKYkO)RHc8$1SS=rbfL{OPM@cD#y}MlUK|-XR2{l_ejf8kqAoWnU{XEuPJ{>viZ4Ka$asMW z&6d~Zi}ezcHJZIp(#So~$4AM9TwX2{-s6M3M@!u6K5l=nN$XaBw)!WS{JEM-6yxko zN={WJyc7D1;W(KS%}vkfd-7&QQs42aJImLFLPHaVm*eA*Tr(m$RyCn4T;7h()mxTb zDkh8>(_3z0qyUeT>W-PRWhXTMtFOwcdUqrE6uq%hfor*eV{F$CbfHkOW!pplKz=ok z*k*nW3EJxJXJtw&()x7~W~v%rr~y)RKkQh$m4Z9i7iD*uyx@ zckgNwa9z?`HXEp%2&IyH;Dyqz0zvU%jeUw{_l;xL8q2`r_z%^%GRiT{hq+X=D|s&znPb9NF>j( zFi0>u;r;n7*NaN$WrqUH)!h>$+A2z@ssJ}_&qJdFjf*x?XSD}48$UAE1((;(w?_b^ zx1;PwbH@{+^Ij8wZVO2|u_r-QTO`PDv_s{O{$5c+PFW!v0XaA6>M@q|>c3XD*_Q(! zrE^`}TFUrYzk+*|F}dCMxVqt0!Ewv1djQUw_Rknmn1ahdL|$A^o4?$%o%EY#sXYx) zU7Q^zd-B&t@R|BX-eE|LWjO8%d+!?W{r|zwo@&?vfd-vr(iiyOkO%`MOZm$s@}SAO zG0Njrbq7HNzvjM-ak%nFHV4AR4$iy0`XN_kmrNj$5JFdzZzT@48bel;L;Z9kxNMoS z{oG+>!GjJ@@E{8|Q}vsVRA{XMX25h1P4mS+!C8jg_Cssr)q=fJD8dO_|NXD6|3|=f zPqmk65RgS9b347SaPNpBy8s@f0xv{(=`&FFJaw$l)8zY`qBcu^-wBRyqCRK$&7y#f zXam21@+|dfQ)&h#YY>n4&qGoDdOyY21w0dDuZv;>)k~%d7c{iCxXMf4Esb+f{NH4S z%XC(@TZ*JqFdQMkeWe}~FvHp{+`-^UcwM&UGDlp|(aEOThoQHo3_R5!^%qy0j@FD~ zd;~7rc07K0K!0^e+^1H83gd?4($$+Ln<_n6Rv-E269KF*-$G;ok(?X*o`2`*EPq-a z2hacrBdqT(zZ^7nJTcrt@V`;kz_0}#^quzC@%!#|%Tq_Kn80ew6JGkIF^(cH)6dp^ z_paW<)4=#GS^CClDvbU~x>9{%UBlQ#qN&Y}Oi;&#@ z*^b5kWS?8T(*6CV=LQ69oau@1B`xJrcBR}rNr%C2oY^=xXWvsF%&V6kj&VC|pdIRvpN5o8 zNesaHIq3Oo(g0H-6yb|rA|B;v!cAy8t~Z|}nAs`K8}4H8{5+8AftcbABu3L!uWiZ3 z9ZaBzBgE~=2oH7sJCKUaF|Kwz3)TVpgZcV!0LdF~OSNOJf4cWnU~|irOlbz{mp%Gd z-=Wb=x78p0i{a9x$Gx;!HvtaKf!tu&ZZU29tR z`V2RSOG-1h(QC5ZYg|k>K1PWR=A+7fjH<#&M6|B=LBk%ovtl_Ce?N`9+U)F-5_QGA zL{F0dO5b$%N#Fz~raI5QD-Tay#r=E5y(&$KRey(HknMe` z?8rI&{jgX6UwHDQjFFP3!xEl8e^z94ctrhw#w9o+?4j*q%4e+g z?3`v*hJ}rJN6sm?NodOMNW~^oXvr`71`$yo?E+Q*9D$GzTkvw1OXMSFuGS+gQ{wC% zD4_jo+N*s&62~bmh%3U#xjcdQ{4Mf%JIML%sar>HZ~M>XNnU20O38H<+>sTF@>v4) z_X|%?gCbF-kiUlz8h|~K_sh5YdW6u#8JMf^}qQ;_P_T86Q2n1lsYa(}#N!rnoASpi4w($aJf!rg}&;sD2T zw0u6!03^U_#1qC!j4o6%Et(}#Qd3pqW7{#m8OIh|Lv6)g;F*ZmO%?zPf30Wa7u_%7 z@ujijO>d}O6~J^QnQpe5aNci(e1~hek8`CY@DHXdJUmn~0E;v}#C#(!W$$*{G^7Lc zj?K%5!n-l5^mSJVjdKBpE4`|GU{Gd_Fus6)FwjiFUz+%blHk&^>C7kNlizZ@SHMfL zavjgOl)v*QCEu^F`$14tnIrqKv0=&VeX|riYgu2*{1}EwvH>0l{u8dJh)>AeS7NS~ zseakv`WFv$Oy|9=n<-k5WxTDN!O?)uB|;Ea)&QLClKfL)HBOG&ECWp?Yl9j2^(D?i ziktO7;9k3`FaMdy89bXYyX0i1&kVv7`g4hf3OyW!2nUyZj@d{p&*;(5>Ht6sIf+kxPF0R|>oSIDdG3 znwbvk?8wBK#0XQH3R8t4jlg}x)qwm0_UC25)|w8-Rx~y(y0H5vFTmnq_)i~4{3a6X*PBV%Q>71}~AoiscDq;M^R1iw;7hXbyI~ zK%bNe6M_u6OMf=nU0IR!a@z<}w`-W5O{k-NyCC79{I;&E_`_dkH3}b!pjZRw8;)Zf z4VQ9ubKez1ykDl@ z+KTEn_m^jVazgco?|b}VfGZuv9|dWN6L+$L;fJ5EEjlK&{OB_V#^6#BuZ0iDQoV%?2G#P#@WI>=k|~Ee^&=4x0m(!vKW-R>Rlr?JcUI4s>*>?VuFruA~a4 zzJ4=~qaccLV`omUeg}~x?zQQ{G5$H%q`EzotXhUo!tmX2ClbN28w;Dd$0V@`FSwt2 z$Yi1jK}&l}FU#vQVvmT=oy%d;ejc!v5_h5VfIwE=r>M*5Ec%0`z!(&xjj@A+dA0A3 z=R~W)NRiK!_e*PiLX)O1>2O$YzeZpdSHnPGd!4TZ1_O$pp2Wq!G7@5?rW;)iYL~71 z-oZ@1&zG$^eufs!HMr41=Zz$}c*ZEX9yOAu&VKA`J8Yqd_vOGXTGaH1^y1{nm>_*% z?agQA`mNZ8=T?n3ixzOBysyJHdR4T-Av#q2wvk#fh{qKI7fZ!1Pu5EqmLcyWm>aJ^Aaq$b-e`I5 zA2=sUPM}xj!f^W-NutbvRjy5G*W7_9WG>Dj;i!m70NXh@P1wphRmiXh-Rk z(zbIWEyJO(DM(hjahfXOo9?yZp5)n80o3Z&ea9cSeSan)l^p6&>3og88y(3Xa?O<; zy17y*^aI=qCRjWAf>AVINiM#%p)b1+B&RCQ?cbFa=w0KCR&?MgRUNbbD_0f#m8kJ& z=jBA7{y2?&H%B}#qfnXV(%!CHnaG=VO&EO4u?P~c6GLR8h=$fc<}K*o^B3bI5ISvh z8F(Rip#zp7373!EA!@cfi^}nWUqi3(7wk3ebkx>M715tr*U*|5su^2lrsoGV`)q(@ zg~0;0>K8#nTpVn#nD}nqnm)v{+WeV3SVv526VrHAS7AQG^`uQ})W58eHweXflyaxV zhKY&9$O(tImHw@2diQ$eNg!+n-A3(}B5#L#MSGAv(C)w2t}4uH${7W~qQUiXO5{Vo zqJxyYS3GeICd2Jq@5P2|_~?szMO~yVf}aOfGzmga95YO-KeQsv&JK9%3j?`pG&(&; zRug&tDXPJj`EYb^gdsR5nx2nM*$GnF!o*C95XpIJr(%1sXe$ zr%i|?WxXuWiWtLe?P^iL zIO#i4-JL!fdZjAw<{%+g!tkKG5YER4fujuroMkZn{f6~HRh%;}+mF(LNtv8jAa%_? zW|`p~DmP$UR+f?!SAKk#b7>9&y@VPu_7&cF`YspQfs?42&YFx+IJAmdWRG2LbK@C8fBx40xk zeItpIxmtZ{54dNJi22$nye3ogW#lzzX&j`An51v?J=Wb=g84f9t2MEFD)pr!?DI=> z^%DRYGa)~fL@%A_dYS}`S><2Z0~wiS#YI?^;QdtuVI~F%g42md&dI8$YaKvii9kSh zO~2}!8>Q?H)bblJBjvO6SYrbCd&&UK_oKvUp;iT{|CA^Qxvg5Vl@}MsfF4!3V`^MF zvmT$nA!SzS100|mplzD8d`*~EUPx&btR$Cf%9c0H$Wv6@j0-S1iGiviyE4aj-s3g? zo-EW>w8nUp6%-8EHwab3OZd?Wr+?O$iAFBKJJru=&=hQo@1Hal|7O*QNm_-ARhFJxHp1V~xyyX;!N-kcPT2+rkt|*zN<_z{`n0;Ecj8MpR$18N zviHAEg~6}IM`4e_dstKHQd3Q6?D*@X08{{SweE|<(?ug~cCyO4x5^{NkbKv*lSu;d ztqbUPys^~cKhlxw{Qj^xG7%<%7jdQ4d@zJHyA~O6QL&v0ZclferH8D~MJp}1(j1tMAmyz%)0M5=z7nQ4`cV$b)WX99^ubUi17 zI$!fE3d7eh%ZrnEceO-DY{(xYCP)OidVHX+c~yU+l@E-h*B+)oKee5l@*isXP0w`n znv=!7ksZw42+7eXOXfC4=1{(5`>2KS>=hs~G{8$G;fqh!1vo72K5w%q+8uqwqlfNt6uohaG+Mq&(rv|4J?=<75R%2W@BD8o z7!ld(x{wv^1=&>H2%_d&f**HI>3*T6M_i)b$u{#8ZXA3HFM!QEV$hdYyNVfUt1ZgB zC|a6+%>Kjk?76eu)_lcZh;D0H*!{^3JW$iHD1WI8(L4^536wJs zr0P{yiS7yM84XihtzM)<#Al!5`XPzJikfWk$Vd<1t}2qO&rY4UdswPuOw zXfBVo(cAB&Hjt0O_1dl|Y7pi+tG5u!(&i#3DZLxULG^4QrJ@)?y#*zNC)@i#j{emSR}wA}doy|k~kryL}3BN;{2 zwJ$Na(C0fsuPlMYS<$0BXZ+JHp-a*lhim#y5Dw<8hMspb-Cf@FpyVNCRg8qr5raMZ zfO|L#qm3Jp|7YG;HF)wiT90HsC2l&5p$1_@!sJhZz@UGrl52}Y8ecS!cl#Ye$?)D1 zUG^v(WgQH>X@m$@*K5LT@r1X+Ab{}2g{Mx7GL+R1f1;lQZ>V+5*_4BoetKBfk-=rk zUEq>2YQ|L`x2yU;vfJBVucd_`}`sZlyTGRdln4S35VT`)=S9mWQ|Y_?yyu zW3xBrx;kM;A1ykGNd_%5;}T?`IF7bXKum{#aTGMoF!NJ>`z#)5-{8n!o6!>*j8|W4 z73Oj)k~1xW&dZU(gbA;msvn{1jnj%^WDD(A>R#KLRWWU(QjmD{(eG!&GoM+K=w-H|e6O%sWiU>LP0ubsChN+L-NI3HzAmgB>_#CEKEw6wmdn*LmcV){~z(-PMLI z+gEU14ge9SoPe8^d0Xa&nRu`5+Hc1VFAjCFb8ma@AHD()76e%(x>MJI1SAL}pbi2j zh>Eqx8j@|MDX-;AmmK5i^+k{Cg>{sh-&$tu&k(X5%jUbpkF*ZBJCHr&Q0r18htJzN zT-|pW6-fuo)5}CizWyTH+9MUs{%pgQFZTr=F8&EPLeaxbjj!L!=teApA5^*)s{T;o zYQulxAqh{(twC_ALciyi9E(kCOhW2azLXY(qa!#=NX?~t;^ zjKxCx`={v>ZFW`v93q2sa!p?+$2pZ0sSLYg!4xl4swZ+LbK$j{#CePIqtFN$m*}OpySO`*(ulJG5t?Czvg_K*mjX-M^DfARm_pLiGkh`*bFwq90a%;f^d=>VO z*0ec-@T_PejBpF{9{1T3t{`C>WO!qh*wCNEP#ix-HXx;vaq9FG(>AvryJ{haZ4aqi zjA4D?m*M^27YtlWC4w_QUZI5ZG)xQ)K!wgz&big1aELEjuUIM4k@<&d{f6ECXI05- zIU_MaR8UO@3k7~UUg-4DS{KiENTm;1(K1g zCaFxGydVM&&1Idmhl78HTcFe{ixbw?aAi$zPH?MfC;X@DHVt3E)d9Mb=zc+cM_+Pd zfz%JSAR!^rS+@eD!033^ga<=30jSlopTa9;g0C1Kk4OGTy_%F$&^rnFe2G|n)Hlm5 zmOpdUX>X!O`;=ck`S7N{#z%$PxM1X5a291q6JLS;1cAE`*Ku_5UF2jE z)xIDDMk~@mJ4j)Tz;?lsF2gOvW>g6b_th<2&3ivsfjvjxD|Q;lQb{Z6!Y4}Q;&-;Z zqh6xMz&DDBcyQ+>ys>ufC!o|VE`T$D$zPTI2PEDOt@+@mVN~llTSvu33XivL9{rZJ zFA{za!E-Kp;%@9CaAd990>R@4-cwk+ER>156lXkA@ZqAsfcrZ0*A<;|7!?i&`4 zeldF13Zn37j4sq3*HvB~6{ifJoakY!*GPUfNn3oE87k$MHwEgt%Rq+F9gheG_bAM~ zX=nY~-3?ns*?wuKj>m14d|CzrmHQ*&zFthoC6pW-jbE)h8Trwg-0(V}mWkz$<2-WS z!SW>tN0Umt8dL&BNLI`oOJ?we2H~yx+KgOK&~427L}Sn*WR8KunC=ydd$cM5bWwum zXhfP+Y28vU1&PXkA@_2LFNAh$G>EdODardIb+N4diC{^7Turgd6v2P3BhE}h%8tO# zsruxcB$Des9Y)0%AxTEOC5k14WUXUkoi2>f^%O?~I1NQ$tN;juF(q4FKo=K0Ful(F*k-abu z!0l>_Ui`zm>F)DqxKi+>CvI3)O?GT1Y09)0rtR=^__K>Qo;}jHv=by!*8=mskKR{$ zveCDmSQ@sNTE7Qv)O*iLKxidbV}M_*Usk(3>RHaY6E{t!Z19&Xu7mm6#@f`J;prXpo`K&Ek} zc{l^e8Ysw6pMG>4PG*%S=egz{>>Y@-Q5Io&^k$+uiDFfguad-K$&o*+ui`pOuM}!ro>k={Xnmxz54KFK@TB!hrlcbDdwc`H zo9{u8)Z31gnTZWOb5yTu!bxdYLOJxwEt^Rdt(x^b=+MSq{Bxf_6?#k|-y}rX6crn@ z?0(iZjsmd_`mG0!1aeB|YmaM44>T97*oTyGLau&d77@>vrM-V1OHYD$ z1yP@5d?R^0;)&`xD7DUss{COD&K-@XgOa)4mPEF1H@@d+J_B>gq6q?4W&0gM0YE-^ z8xDNBBF@7hrjhw6QPq4WoQ2Nf1iVU<{~;X|M}+aaol1e+gcPFXI1j=Rsr3?!&g}RM zKVCk~jX-Tq-LkB|ac*Enu&1FT!~%Hs*^$zlmtf)E&=V7Q2QoQ}s8q-Md!T=Nl!LO2 zi(rQPOCkO9ojM@=x^;3`S2O>(sY5cW!etjV9&#dfzdkHndMMZUh-&2G*0j~KZIbxE6@3HJn z)U#P30+lre7{6@@KE>Z~q1LWI^w}te4w+CCW8Mk!ZhYcJFbptrsuV zT@XM0LU3Qn^*^43Lx4KC^CPQW_~N0HH}Pd`{FQX(@G-yk$3rK{OZ?JCA|FQ2W6yhG z2*kSJk30;147#>JpJ*Pri%D|PKiw}@r3t`MN!Sei1@hro)T`*(g5XD-?*~q2y<9x4 zV2;pUUk(3ET)M-|{qOMi8ort(cK;d-60YW2h^HP-iNQH}y24{ZQ-ie2F|~6zlJ#ya zCRS)f0gV>=Z1DvPkQCD@4XbjxhAHe?H9u*4HcBT@#^~-S*-B`DMq4hI2OC%8yN^Gg zDBYd-7l!1%FN{&5v}`l>G-RQaywUwILapP562?virt(-66mMWUS$51wtvU08p?|jE zV&G;ocWV^tO)9DXFE*ee*C5(_PF};89M5xn+&fe00V@Pf%fJ7O`LJ4A5&(B%>3y5c ztOk2y4f*nPy=_*FsktexRfJT&<1^b|QW`xGDjg?jvzqX*w+@?MQzauNn!Vp!3s>-8^^nmyddM#ET>9#7lJnz`#0aa}8;w06 zHS}gG6CH4*;}{;mB#Uj&L?8wZvv4zMV_2(kY3}7g=*}@W(_&5TKgHQ)S)`5>pP(6* zRQRH+*DZq=lu0EI+59n7J!un?gpKBlI{W7ZM1s3xvB=l_vQCA5ANoN?thWqA zuq*~9^0Z;JD6;<1zy@KaJ>hUY5n?;bMzY7#GP*$=9d)X%M;ww=&j&BI-C$X(4V0iz z>_yI=B~ea83VblWR6gJdfaV-J-YB$WfDq!FNP!^cp9QaB(|$Kws^VG%(ksSB&M} zhwpn6R%UWb^s{9XW$Kz?2NLdkL@lV_U}CDfFY+XGGa3~)^!lv$$>qgG_6|WaUP8R_ zp$g8hCvG1bp(rt-F@dD#_E^;3T*nS6te9zaT0f7w3LCBL3jn&KswkhUC+MTf^TFWe zC&@uS_RZ(nXmcBb;55{L&A7%Q;VRK-b$jd}+KX?g5^vFvH!P4dkkh+#WEdjU3;=&& z4^xn}k*u}1K0+CzS{e-hqKGE4O`?MLLuxAJ)t{Xn4G#0b$@c|Dk;LHx8X329A&5cMlxn<$PU(o&f4Z4YY`gh)YzFo2%4if^M%w0j8tXh=pN* zJ)dV9+To4w8ry0>8tZK3y9^S+IvU;102G9VXfQOULEBgUzlEg>pNPG33W)MNuFMel zX$wCvJxs421zs$0Dv(dgtfpp`TS^Z$U^%nG?VU}9@w;(BKjT|3&xwaZuo!kKtGhA% z(P!kE-4M1E7a!oZB#KF}UyCwvdSr}9zH93~4^>pTS0!FpGi8NZhq`8(Mk}VtLz>7P zol~a%m@FF3buF&mDU7ZiB>D7+WPM_9apIlRPUn9x8mZq21pI}VD*0J}air1~6RLHf z=C)d(%@QxPgfGbNnQGKeby!qZprpNpy}`IiIVC^Xb93-?QA%~%b$^aFtG-N9wY3E1 z=zLIQfI%H0$-U6D`K&sef2zJ?;Wt05gh)@Y#6{R?GX&Rpc$jQ*_P?C6!|wWrF!LQ^ z&(DTWAdm;+G1D}H`Ur2v(I)#FU>>{sGR0a#7E2^ssl3TYpkP2IOlFZ$K5O=QCPCz1 z*R;ndS@hQ~!``ep(gQ})W=ewctd15%R=FnPga&VJzUJ}=qPbi6b-{Jifhn2ioY2_; zxjd|NqP0*^VVTqRCEvhaJW@tO?7@$Onzn`y@&OxPtr%F(#*R?+6V?Y5kU>ESzGnJFl3a*QgLsm?cQJK{#xLH~A)laJ${`spw!zcNA@;e{CmLr&}n}jna zw$&Diz@i4_Z%X9r<{sdX{;~NzMiTcXAJh=57^t4q8B-HQn|B3vT=eQ;pP&Z0ZI+Qi zytdtn3k5<#KqL$)66SM#mdinTnI$?#wood>*rnihe2|Monw_ODDiUOE8eb~Bs0+Xp zXqg(f!`XvRh{hFX@ocU!A*Oa1fL0^)25pRp&1c6F%K!?3-(^w-eEr@s`xrDF)j?Wn za&&J7RlXy{F%kxIk&aFMb{Su7585S8jfT6qQU0s5P5>vFD}gYBNE~GYJi1Csk!S|fM$P#qoI0Qx zS8b&a3CSG_H?6iH=y9-u4B@Vh&QX}BRvU6S;cC;}DoA!%4|4j6M9hFyl~0<{F67(d zwZ`N17()N(u{6zj(yurVWGjAj{Cv^>bi(=`3nmL*6?3>cUu$o+Q8_`zSo|XMR?>tc z?dPv1nmA+K6KisU4 zmmE1L%UsPGf`qj1*oXAnLhf!`{8fjT1QPfjSZ}DACQoEOs;@I^>t%~Ay{dtLK&v~2 zAu77IzQ{YpynZd}`u6A7G;In0=%nSG)IrTUWnnLCQmR#~1~!157>ExQ?breqQ&>Y2 zmmn05xSt%Qn9HJx=_6y5u`iIlrjF;Xip%s&Qb=RwiO*dWkjRyRCgTv6G~*46n$b5+Azd^b@}Qy)Q8$$l$ND=71sj+KJpX zx>$$Vtk&3av4{i_M89?-TNzw95arq`{tu)M$Go-kjTTZ8;ERhF>2y66>mI{RXRXG~ zxZD+)s>tDZue;`KY{S`s^;29JLsCFe93{lUqg?ck!?>n#`n!r>(bDz8JLp#L+YNky zK;*hNQU)leufzwtlSa8)Fh=K5!QoA4Cq7H(z35UlXgXh7Wh`397QjTlTTKv z1ydugpDhSSh0&!Gq3NtFNb*yBXmGDoU! z^MR_aa@U@S1wE>(Is$An?J6@s@xD>lRg;bXo06JaT5d71*JY?SGxD zSJlwT<`t5#7o|Pgc^2dZ;>X=f)i~?guuAHWj&jiT^}UwfgKT(HI1A`2FwsB`8lnBr zF|aYRM-HkD4k$A0p9A`*gWx>_*P+Hv(dj}}7lS>Y$@lv5s|`z?2mOs)m#AHlyT}snEP5Xb2zwB4;Hz{a6T-utGnI z23gT!9p`)2b zRRev`^*v_kjr0FGF6QSwkVR)HYu$6$2TlU?>Q%xQ{{(XKyTwFYMfOXTW z75Cb+8Rp z0Z5g7b^30ggI8Mb;BH1ppyzi`?~6r`Y|a*;0Kr!kR}=*IFcY}xfnVHH)D!ETYIFPg zFl^5D0;R%|SfPt@Hd_p~u^9%On-#g|(jO9DAMBZQyr_g1P3%RqMw*tsPBvgmL)TC7 z7<$aQrzu6zrW{EXV8$D~lByE3(s*ec(n(|_pUU7V`T3>yGA-VH@pLxxr*I`d;y%G; z`qrd9L@pqDeVxzH6y6rzC2lj3?d8yQ4WBYtAIqF7;&&&flX=EAfa6qMizYoyubVld zz31HfG0_533smys?CFgW`}-pys-6%iA{+?84g+t%(Bks7hl+w>hYWR9^+6&7@i@+q zD__esZHMed;`N>rJ9o^T0G_wx6k5_;S0_q=SJzz6V^;@l(;Giy&NnLK-iUnk?KU@o zCXxT!K7534KM-kBBp%)9tlA0H%^J$SKFAHi5LJbbt3Ib(#x6+dhT}ac3?!>mvSq52 zEI!zogOB_h>E6O38GwzE{HNLj_cKjE`Q+7(0F&+d2B##9WSM(yjmrODaU}M0mbk9 z)eIfdW=mqoJ;n_SHW=FV>0%8GS$T~o>~e<2%=7sY^;AenI#D)P(C4)z8?N0?a*;LmPYcA&eGbStN=PbA?88WOYFh_n5`F@{5oakXA^YLSLaXm zeTJrgH@T=%S3ClWS`Re_{A-VhlmCCs8ZyS9gMyFj22eBt0hv+UKpp}@^ z_Dpnwt~-h&d*eWLAXtZXe5!j^0vER+t15w{dUraDBMOU!Gd_PkK%j8 zb~=wIVBL@$^S$~r{Z6{x+mX+#J>zM}sP8ayo2^rR$D!kv&R^+dpK0Fqfgrl46ZZ3O zCQ!Fc*!8mf8~x2X5ZK6E(kE~lCa6}UvY^8by`-xi7!?~u=Cmwd)3|KelobQcqZ7*l zRYAK=b%=w?R4cOU188!QXt8c;l%GBvc(>ybR8r7?WJm}{@Tm2p^4tk{~h)GafbwXzI>I7tTW!RK|BSu7W<2A5CN*Who>O;EJ01(mGlYu13y!n z1RA0TM~DvPFZ1Ml+}LWcCr(T_;!b|JyzzXeviHL`LRx9XPt)mC?ugo?Yk%R@*j@?6 z2~fb4Z^ZUn_}VX+HOYobPRFaFyj$>IGw0^p3JKy3Sg6QXSe+PFbR)_k!dK1KuUWj4 zz&q|M{Ft{D?ClCSv<*kIq9JD&IyiN)vV>qc-w1o$GXIGf&MYWN8QfByjvRJ6?r|z3 zMuQ|wt2ZgZNEeVgg6(^{>?I#wUUhxAavJvSR9R8>iyZ4;lo6i7XYzt--!A{AwTkrM z-*>&b?DpulTh*<{2z@}phy42Wp7?sb5zAe25mB>#H_?NR$|8h)J|`pHYvh6{bjH>W&;U(;c{yXTMP!Sm{TXg2YKz5!Dd59PAIO>fpit6@eLh zhAV?FhS7%c=nLliWWwQ_tUVAYJhU2sSeq;$-Pl#;lQ3e3`?f=zAXa3zqQQOO)OC6J zN*rqLX-sLJcZZH792m?t>!m#TF|vixBfc$5y#F|{-~H$q46L!N4P1Z2@BP;B`L_f@ zGq*(|!JVhGYHc+CzASwEq8m$_KG+XPwcnRFOW90lt!Dj)7{n(0(JPQb+RQ-;5&1j@ zUFP%3#UL@{Gc^{WbO~D0!+@iUR5(9dmuvtoLT*)(bIR0BM`1oc=a{DWI-|h5xB1-C z$^rJLMjuDj8Jyh}^4#T+5y~I^8s+NkPckI^*s!1&;RM#h=g;V(d|sl< zbE}&^F`)hdPTB?w63_hdRiYf{n2aF`EMot3Red^JYVhr0aB9QPRUoxHeL?7+HFsEHcNQPEXDgDHXSBlh0#6M<{USkCaw z_R;tSPaD9D2~P6%17Hc07iso0r7Axr-$bKv?{QI$t3A+-924C!otVpj{qR#nPinE| zV#L~M1Y=b3Z}jS17iX1ePcEi&)SY|#J}4q-P@{~gibynwAX~6e_%cuHDLH61Z+a0< zx8THAgpgHLl{DfzN1WarN^;BONB+1N>_E#QadF7XMQ7xsB18JkaP@evQ!L;-lkq6% zyNsrLaJAWA-(_||cl_8VaTz9s#noRu2L@8>H}AF(D?gh#a@N#F)d zWrkQ9(8xb{_{`r&)|5e^O@Ww0QxyJvwI?;zjXr&G`SL%c`_S`Et0PWnOMo1~rk#UE z?~pEu;@*qYn(IDYq(JIn5C5=tL!cl;J_}r-;tpNKTUz35jNSDK^=Fq)&buBkhReTbcWUe!ZwuLnHy($+n zS$e7rM_{$v1NvgouCFasM7i-o_G|2>J1HI?G4_^seQ?QOe;-HepV2(xw4cQnvy+uJ z*iojj3&F@W@8%E!X}2eX7B8W$0xfZOH3;CAGdUY*NcTU|XG&5UL|#?h%C zznP9krp=I@>J%pA;8Wg%@cJ0LwoIM8x8AP?C`ilTMtXXiK603JzPpO-YUR)3q-LZ0w_ZzVYSD={jHoW#AFikwBIevAB zKHM0-fB$pdjKg1?;sb8Gz|xFF%%zrzN0E}^3H}5~F!O^LVW|&dCzh6`_n7$s(y7He z=S~sCT-*(To1{o#QxCn#Jj5Kj4F`cy zxkw|^%J=DMcn>dxswP(5T-j$2zePvc6V7;fjD zueF{Z94ow5n#B^HFrJv|Tfi6jTer?NdG5N1`$8AbaNK4yA(W7=vLf;D-Z=JtE|McL zYWo0B*0Wlx(msLqn{q?8YYp_Qc5)X3rGi=hM}hDj=jcHk`%VFHBi2{L~{v2xM;32dTEQ zR6@56IHzcPz`lwJ-(T<4|1Y)no~mB>Fwp+IVy{slQE$(QJJ^lr_-)P=vRJ<$6@n_u z#N*CE&;)FJjG{MXwGa-vNU2}wF7S2FV|c}3Mrh2Qvg4mrAUSAcOJi^;jMm64qFFF0 zwxSMpvEtfgbP;cTUD8iD=#dpxR(fL|+$G||Ag?l1AY0Z+8e?rf9vQ|=2+LHMEPVee zM|&yFq=@&swL%~^>DMlEk08C$3exn>Zu*_8KSTpYuE{KsUx!?YB|=;EuZ+zbIpX!A zXIrC=ua!|sMb+8!*0I;#PZZh&j>b#D+~)a`ukjJYuS`w6vaz1N-v@P>+VF&_3nO!7 zUS670(eH)3)1F?^!a^`prJXT-{|q?y#b3%! zLWD{cJ$&AZzNJ0x_7HVwxV|l)WgYux+i>?GwcF*~$RXMo*oSYP{3K5M$xYh{UlTt3>JkBy-ASXF!GAB!)%dp3+O>a_V|N_#!iJ*+IJ7JlIDrh5Y=p$K71m}`@_3> z8?eNYn~g)-lab3Y%9cqmdCv2fAK%xkT{Hlb-#vL~q89IqB(f$&!W+SG4Oos4gQeg!ECFe1gxjS(A4NJxBahn|o&+q* z<7`8ZpAuUCMjgz^GVjEQ+v_b=(FAK3Xy^`dwR+2Mv2}bMs*@qlj+KLjm+`Gd-go=b zoEk+B%f@%>l0PWSW z^7e^r6`eAsdpH_jz(bsyxmjPZjO}le4f%3|G#hVMU@q=UghBEX0Z45Fae|j$PpA$# z0{bRK;5Gya(~?q4Pm)aT8y4)dQC6NB<^~+mVZ~7GIx^vr7hQ49JlEfvU{PcRwNfX|T>29Q|`haWxM`q!4cMolS{SXmnH- z!K|g@83Ng~(TeDPx*GGk6H4AN(Z^*bn9cU1nXmKH{5`qHpM;ss+h#Kfi7d1`-#EQY z4PC_k>yUcF+(ol>Z>Y1ocr9U$j5eyh54OtsCP|4_m{B*@LG$a04jir!H8i!l#MZ#T+*A>rV)rd%+>3PQuc_M9yY^f)gsR> zIw)}S8`~#F#)r&neXH$_p%lVX3T+RW+CqBK$2sARc)W8y=3ywNDIbjxuD*gj5f;64K_yuYSE@mjWJ>>MQF?*9x zwL{k~YjTlT2Ns6NaO2+jfjM?hVEkjx1Uy>6KZicB5}83lcaS!PONDM7@g$jFNw(b) zh{Qy2?EfcrKPfC;=OG+5)DH)D4JK}u1tZy_IBn+B>;)$I&a{P}BZW4v^zZjb`5{1P zT0qcz0E&`j=)SH(jk9`>xR;#W!tn{ER9%t)C6}l*;Ei-!s0`5-kQu zEhUTR^61#}SlRr?xs&@?UpQ5!Nq9yhv-VDJWPfbfm5eq@;GDHf(H!H*+ns{(Yk9B0 zVr6xiA%V3}N00HF&T%Yw8BOu0ig>B7NyDdunJs6lP|17&WO?Bal9C&@J99?nP;~}? zi110ol2)a~aiMrgLgjvGjh zE&byhevr|M2wxzS&@FG?Zlk%REXHWXe zx7IapP_7VQSI{TWeB`tVQdv>u>NK_E;_d5mO$3Ra!Kf$SzJ2P7^ky2k5w<{=jg7$; zHeXDy58{wl%f1Ti`S4+1YKK;^*2h82eTX6*(-wfm9Kn zm!pPgc#=ODYT4JY>orB?h!x~%c{Ge{$?%TbIhv|am3OVvmzMI}h+X4O1%m#_Ao-OW zJN&p~!}koeE7`v#el7r@AB7Z1ixzk}9nI1n$k@tOn+8KS3OTP}vg5LLE&u!=qQS_x zO5Y3Ja&2=A>Dh!mHUBaNP7i_R(Z_|{H8qCF!DN|*^@MAYk(*Cra9{Br3_%jiDMTKK zDX+DpspLX@7_bJ5ryz1H5>E!>%JD-P$XqInZEO5H)`P~wWI5{aSP{r5MM9j&-31A! znBTl*HsB7Y)3qn6$Ov4Iik&^?@yC;g$5N$TL*n;wPS_qm8LS?Lop~!mnGrVi!Tp5j z+8I9x-9R3_{XlNFwW*T4DN^1hsCO0q8b6$TQaRnO+qE>cI<0H)xX z84yG0%U-%OQ9VA`bA=IO!I7AiB@}q;q9$HAJbQ_^13}_8cI5!O=Sypiz9bCs4a*XP zG98(5U4Njma#)uFhN#Eg(wp2`andO*ZchG$T=eYCfi;k2!gzQ+f+{J)^|P;=0gbrO zsZwsu(-7&Pj7RVkMqoZv(Vd%UN_pRt-^d$XDc6cQ@GpeP{v!k>CFBd3oh<4z=oRm? zH7)*TSrdp7SNl`qPpK1P)1U&fF=tgu+g?i-H=CXhh}VAPusV@lj_u%Icj?J1x5KU9 zAJuJ?6mq2;s%xW`xTMPE&AQ)x4rf@KXbs6Ck4olrLRBZ~NhpS4<31o*qK~u;STaaF z&oKq&KGp~E0ieVxiEM}&i|Gt9#nu-k(KC$Z!GzJyg1y-5ZgY2R9Ad1M+YjQ;|DJ|z9s93Vr||#C=HS%Mk(9?!aTB8QVze*u}~T(w4iDJ?oQ++T?J-5 zdHJx>Ynq(r6+LM6khO&|2I(>1ZonqbYXm?)zm3COfBbV9LJ;MHpvZ+gUX$Fz?ARIe z7@A!6e0dn^@d=;cL1&MW1M;VA8W?(~1Bo?rZtD}B-r)tM1^{4A{4ONgQc%lD&CD?% zsC&Kf;OZ?g3Upv&BFF)M$zmYX<(=RPVNNe;P*<>lh4nyv^X@mUhT9sbUv)BtrtNn;q!??efSu%cZNh0ds_q_ z$oXaQ&JpAzUr`cJ8BAjLAzawS0Rh_OAP zwr081d08>|tE^BZnoq}jGh?|7r*}iB;{dx2ndi%HHwFG=xj)5VS%lVY9X4(yeV#Pr z>lB3`t8_WTdBSCP-07+XiuTl|*QV*x)|zVfWj&A6tch183nQ0XqE2Jc0oLw!?~Kg0 z3~jwe*2|`w;AG5#Lh09w zy6yI#zqXoR3-uFA%ylkv)~p_%Y3fwgI0x7LF~0`ck#yAws!a-wSadh_HRnncwRX0P zc+NnA)6#bz_wE(Kk-q;T@(E8}tMAadn3_UrFU4JmFy4ksv>t=VB+_R}rrD3LQiM2b zCH>NDl~HD;H+=q*0YL2Ua@L4stcIeOm1~UiXPsEcB4Z0K%MOnb{jgGE`DPVK9~AMd zVkd!QtbH)4*k{DXMu29xU>{{npna+2a_6mYFo6evOp6HZlSx_V>G?54+ux~G91Gl3 zs>Oa*=5rx!waH%A1IUPGrtzt^cl3`)?M1i$o+ii&Pp3JYHMxKzotrndePCb-_j%b7 z>grNl^|yNj-#3RTzY0K_>S%UdaI?IVz&MX^;da)yD1PYEh@=zrX1{2@WZ2B08&kXG4iVA1p+FdoK9t>c(-OqpZKr9EGuj(^ZNoXWaq zslBz7p&4V}2tcYCFmz46ljQQ3ZzM2aStxl)(MnB_%A1TP5n6B&^8X)Ql3}jokS~>_ zahk+1J&gxj*Y>A)w-(LV;3xrbRc`1n#oq%2`N;T1tZvmhXD0S??Ok^6$=}$4a$?R} zGTo6~!2S*m>a$tr{nXHwh*&)mY20{WLz*jn>J_9gKommo)NX)X)emA40@uT(3KmK& ze(oN`s}WiVHKQa#GmoB(eqnGTm>`gFGCy%|xT~uE9YexZ@ zr>7?v|I0t76|?1v^p9DW8f>Jab4lO{dO>^I#7lp1gmyRr>|mqCXotva2HZ=8Zm1KdG^JkG8;fE}f90e}~4y4j+A8nM3)y5DZRP*B&W z4F?990Zee1>aPlrg!SFUj1nyBPYKplpeW_bbzygHzwo!FvpzMa+R1IPR_h`mb>a>*f>x%clMcWBVj=g=}hf|22hJdbYDr> z1N)1&0=5nu<{qDLb_Ld&_AKvrU{5iZDsujVxUCYvm$}KjS8-%mXNmpT7pLF-58YKi z)0y5kkYb1GKZfoM9&FWi@7>54v1*zSJ$Humnm6mgEl?Vz#tt*LpgG+FSv0cu&pXxd z?Y9?!Dts=SRM+sH>A*cQk+?~7$m4wOKz@yhaajaCEhcDGgM0^C1KO;-@me&UqWVNN zqBy%B9^S*yUxDIp<>H1BW59`2Wo+lHqk?8Q8*lzPwds_;?!&$zmoXXo!x)zq4)h1R z7Qa(*8_fnn6?vRrTm_dvFL(PTwoWy-_=D7Uc!E4z6-9O z{yWRoOAK!9+{$1=5buqv{GFW14aFZ3XsHrGK>B8{+>C@~x1vZ2yMJs-Yr zC{vTaxp`rozpj9aiiG2Y0+zeCw!eQIsxsbP&ZoDRx&WQp;8&TP1M^t4@?TI$X~EsePE~`O#$2)mDD@3l%1n*n{OgiKG?f9tee~fJN%0-RXJsp6d9W%fl zSBFOFMl(KZ&eRuME7{W{|NVC#%;!bpfn}K87T7Q}H~n0t75&M~?#>V~WVBWf_{i5$ z`gIYXMx6@=sb<;Uc&@Ey>5Wryo0-xR08G~dQ9M3;ZE1T>LO6c|*XCzrWfA+k zK+)0!VjWHv#LCH4^XcaiJK*oAvzqKo6nd3cDR-6k?LO8c0O*1b&hq(wPfSx2rtYee zag?TXqE)|GLkbMGm76-xt!e;JaG|NxwuXy_n>8;ZH`bLE(9Rgr0NKa{y5-B!@QiW? zVBbeui;efC8%5E;91kV^#N2nATHw!t4is;|9(CbzJ}vI&vj+CZJTXa?cn@YyB{?J$ z;E-sWqGs%}U7S4MZhlL-OEiAN;yx)J2=6tin_ZpuBNzzqLW~W|LkW6-_YBnSLipOt zNY7vTg1onXd+)?2RY(Od=^B&og2E~!$yFnDb_4SH@>ASGOXdCWAsJ;9r3RSbHK~H3 zneAP+I$Lch$Rt%e(0;U`L+4WNB0<nJP;bwjm5sigoH`eCrcZYP3e0r`wfgJ8Q!0t4 z2|;zbonWf(lg8AvUxAUg6EK384I>}2T=uFy$IJBi&WE@Tb*7w*NBz&4XEhgC1z zB-PWCWDr_*z@cwo`JDOi`I&K_3!Xj8m?+B9wvQYS>DjXOA&&J67uQ%5t6UX>cRBC7 zHKVTOL|v3yVpss8A45j@StzRqSB+r&yVzx&0=%ckb0$qcs>yR2T#)rooqSb@%z8ax zXy@2q0U_zm?8hH>)_=^i(Bh6>tVgJdG0@>BKq6sZWaI5}ep(Q2;($(}_6g6+8xJf- zs!bFA)mCl`&`3;x^&cjUeBT=&&SjQArGyF<)>8Gzw|#Da|K2C2K005+>%N%_#+0{( zU?ZfkjS2=5AfQal)C%>;GrCs|Yg%T!!x`Hd{v9E15;5%J%$QX&#tC>vHsGUT)$Hg& z57kD|M^uesjb29QFD)BbuD4|FE6WiqA2;ifkKzopElXT_(fS-ZZ#_}Y7&YD*tqaJV zNA=6Ee1x*T8-)`9Y*11vx4+nrg zr||WqoUp!~Rd=M7X1Y?|bxoQ4E2)yOi`}6VXY2}yzz)_9rMwK2!OU8U3Il)7tbF*H zk72ZtcB=KKhbcV^wvCfPzC6M{D+A9y2S5~)7~qui29h$$$e;e*3ggggTniI+6%}P! znqU;XhdPOB2av&eQU;uJbk@y>N0Eni@klw}VTB49POS0cZw0;l<4fzM+9`0@DNo3< z${S?mCNk*l(&ZL0Qm0C_pIuOrN}Dz{`Uciav-gN~&$PffQv` zEmN5EYR;Q+dZlA(39!TbJZe(2`k_U?!#;Q6Z@Nsuw(LlYN1)^$fgRpZ?uY)kyztjV zfI?BWc6fWpfg_88ZY8~Jq0&#CZP;~UDbC_qNzbgmKbqHDTxx^RA#j$F}m;-X1SdgRB|J*%1fotOX z_21QYU*DZ-5PzrThT&0tt?A482$ViXhN^-}ME)m^H`UjCuzzIPzQp(#eU-JI^yWlS z@v^z?-L<8=VN}gGHJxn|d_n@@#hnJ>iv95BUm6Pt*rr6cGM!R}p4qS3ruH+QX_{2e zOr#8PV#ONeXD(m1Thag;JSJK&&>8dUODjF&t>!U^um^DAV(>Wg`R1T00{m;VkBb{@@-A1dvuIn|Ua#KA2M7S}BH9{9XTxtd1wqshduk;nhf>80t zPi*D|E`uq?e$Z=_XaM)mdf~R{faP3NKY@r6F6h5kM!)6xbu$5`LAdnwUs8Xv(oetl z^O6IY1>Tk$fX3t1uP~L~oA|+|pe8m--k$Qo%rpAH^+6O{^%h3;;>wNRd8kmphDBe6 zE2objhdc8AcS?ajE;i)Qi&WITK^kN$>HW#D!72an`kTSF1Qc4JsICrptS}75Xww(~ z2i7jWs>#ZeVP__P0B4nrw-&CgjInb5*;eY3N^KYVFk*{FJ-cJXqxGKx31Csd0%u9o zq8@lO)g!sZb@7sSl2{BooPZH<{%-Vbh0%MhOV=0ujbEFj#9rQ=f{s;lk|Dg4SY=p; zJ@HBj$3gpA2P=lK;7>TLU%Udfy=XIf$eNFqfX-`kZDwt&<9oEdJO5n-Ow!08rQ?c3ENMnG?2dx= zm`-RafE=alfN*lxKLfM@%tGuPTFr%3(yUpwJ_!ac56!zn_ocFzHHt};_V<1ie^{1X zyLZx>OpEyjLspBiv>KqBLuqHHj7MVoLNpM9Mz?*#b@_u=H&+YbP7mhid^AD|fEt|c zCbE&!cZ7?sxEGUTC>fuK4Ft-k44hr;y$9XAgb;1r7uab1z<)$V4g}@C7~t%50I$Qi z3)qyiAMag6d2d*T^(Tx1_P}-3W#0m#a06iY9YQ?t^Ln6V4BIs6nkYl*xs`JDZXzFk z%>HfF+