From cf6b07988fc0106fac1b10c898dcc715ffa78050 Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Wed, 6 May 2020 15:20:02 +0800 Subject: [PATCH 01/30] =?UTF-8?q?DSJ=20=E6=A0=B7=E5=BC=8F=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/QrRendererDSJ.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/components/QrRendererDSJ.js b/src/components/QrRendererDSJ.js index d64dcc2..3de682c 100644 --- a/src/components/QrRendererDSJ.js +++ b/src/components/QrRendererDSJ.js @@ -18,7 +18,8 @@ function listPoint(props) { let posType = props.params[2]; let id = 0; - if (width2 <= 0) width2 = 80; + if (width2 <= 0) width2 = 70; + if (width1 <= 0) width1 = 70; let available = []; let ava2 = []; From b3b68fa8e1d6093069b07953c98bd99f6f6655d9 Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Wed, 6 May 2020 18:42:14 +0800 Subject: [PATCH 02/30] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E8=83=8C=E6=99=AF=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/QrRendererImage.js | 136 ++++++++++++++++++++++++++++++ src/components/Qrcode.js | 3 +- src/utils/qrcodeHandler.js | 9 +- 3 files changed, 143 insertions(+), 5 deletions(-) create mode 100644 src/components/QrRendererImage.js diff --git a/src/components/QrRendererImage.js b/src/components/QrRendererImage.js new file mode 100644 index 0000000..2a6c599 --- /dev/null +++ b/src/components/QrRendererImage.js @@ -0,0 +1,136 @@ +import React from "react"; +import './Qrcode.css' +import {getTypeTable, QRPointType} from "../utils/qrcodeHandler"; +import {defaultRenderer, rand} from "../utils/util"; + +function listPoint(props) { + if (!props.qrcode) return [] + + const qrcode = props.qrcode; + const nCount = qrcode.getModuleCount(); + const typeTable = getTypeTable(qrcode); + const pointList = new Array(nCount); + + let type = props.params[0]; + let size = props.params[1] / 100 / 3; + let opacity = props.params[2] / 100; + let posType = props.params[3]; + let id = 0; + + const vw = [3, -3]; + const vh = [3, -3]; + + if (size <= 0) size = 1.0 + + pointList.push(<image key={id++} x="0" y="0" width={nCount} height={nCount} href="http://blog.ciaochaos.com/images/Avatar.jpg"/>); + + for (let x = 0; x < nCount; x++) { + for (let y = 0; y < nCount; y++) { + + if (typeTable[x][y] == QRPointType.ALIGN_CENTER || typeTable[x][y] == QRPointType.ALIGN_OTHER || typeTable[x][y] == QRPointType.TIMING) { + if (qrcode.isDark(x, y)) { + if (type == 0) + pointList.push(<rect opacity={opacity} width={size} height={size} key={id++} fill="black" x={x + (1 - size)/2} y={y + (1 - size)/2}/>) + else if (type == 1) + pointList.push(<circle opacity={opacity} r={size / 2} key={id++} fill="black" cx={x + 0.5} cy={y + 0.5}/>) + } else { + if (type == 0) + pointList.push(<rect opacity={opacity} width={size} height={size} key={id++} fill="white" x={x + (1 - size)/2} y={y + (1 - size)/2}/>) + else if (type == 1) + pointList.push(<circle opacity={opacity} r={size / 2} key={id++} fill="white" cx={x + 0.5} cy={y + 0.5}/>) + } + } + else if (typeTable[x][y] == QRPointType.POS_CENTER) { + if (qrcode.isDark(x, y)) { + if (posType == 0) { + pointList.push(<rect width={1} height={1} key={id++} fill="black" x={x} y={y}/>); + } else if (posType == 1) { + pointList.push(<circle key={id++} fill="white" cx={x + 0.5} cy={y + 0.5} r={5} />) + pointList.push(<circle key={id++} fill="black" cx={x + 0.5} cy={y + 0.5} r={1.5} />) + pointList.push(<circle key={id++} fill="none" strokeWidth="1" stroke="black" cx={x + 0.5} cy={y + 0.5} r={3} />) + } else if (posType == 2) { + pointList.push(<circle key={id++} fill="white" cx={x + 0.5} cy={y + 0.5} r={5} />) + pointList.push(<circle key={id++} fill="black" cx={x + 0.5} cy={y + 0.5} r={1.5} />) + pointList.push(<circle key={id++} fill="none" strokeWidth="0.15" strokeDasharray="0.5,0.5" stroke="black" cx={x + 0.5} cy={y + 0.5} r={3} />) + for (let w = 0; w < vw.length; w++) { + pointList.push(<circle key={id++} fill="black" cx={x + vw[w] + 0.5} cy={y + 0.5} r={0.5} />) + } + for (let h = 0; h < vh.length; h++) { + pointList.push(<circle key={id++} fill="black" cx={x + 0.5} cy={y + vh[h] + 0.5} r={0.5} />) + } + } + } + + } + else if (typeTable[x][y] == QRPointType.POS_OTHER) { + if (qrcode.isDark(x, y)) { + if (posType == 0) { + pointList.push(<rect width={1} height={1} key={id++} fill="black" x={x} y={y}/>); + } + } else { + if (posType == 0) { + pointList.push(<rect width={1} height={1} key={id++} fill="white" x={x} y={y}/>); + } + } + + } + else { + if (qrcode.isDark(x, y)) { + if (type == 0) + pointList.push(<rect opacity={opacity} width={size} height={size} key={id++} fill="black" x={x + (1 - size)/2} y={y + (1 - size)/2}/>) + else if (type == 1) + pointList.push(<circle opacity={opacity} r={size / 2} key={id++} fill="black" cx={x + 0.5} cy={y + 0.5}/>) + } else { + if (type == 0) + pointList.push(<rect opacity={opacity} width={size} height={size} key={id++} fill="white" x={x + (1 - size)/2} y={y + (1 - size)/2}/>) + else if (type == 1) + pointList.push(<circle opacity={opacity} r={size / 2} key={id++} fill="white" cx={x + 0.5} cy={y + 0.5}/>) + } + + } + } + } + + return pointList; +} + +export default class QrRendererImage extends React.Component { + constructor(props) { + super(props); + if (this.props.setParamInfo) { + this.props.setParamInfo([ + { + key: '信息点样式', + default: 0, + choices: [ + "矩形", + "圆形", + ] + }, + { + key: '信息点缩放', + default: 100 + }, + { + key: '信息点不透明度', + default: 100, + }, + { + key: '定位点样式', + default: 2, + choices: [ + "矩形", + "圆形", + "行星", + ] + }, + ] + ); + } + } + + render() { + return defaultRenderer(this.props.qrcode, listPoint(this.props)); + } +} + diff --git a/src/components/Qrcode.js b/src/components/Qrcode.js index 37b263c..f6b8e0a 100644 --- a/src/components/Qrcode.js +++ b/src/components/Qrcode.js @@ -16,6 +16,7 @@ import QrRendererRandRound from "./QrRendererRandRound"; import QrRendererBlank from "./QrRendererBlank"; import QrRendererRandRect from "./QrRendererRandRect"; import QrRendererDSJ from "./QrRendererDSJ"; +import QrRendererImage from "./QrRendererImage"; const logoStyle = { background: `url(${logo})`, @@ -29,7 +30,7 @@ const styleList = [ {value: "A3", renderer: QrRendererRandRound}, {value: "SP — 1", renderer: QrRendererDSJ}, {value: "SP — 2", renderer: QrRendererRandRect}, - {value: "C2", renderer: QrRendererBlank}, + {value: "C1", renderer: QrRendererImage}, {value: "D1", renderer: QrRendererBlank}, {value: "D2", renderer: QrRendererBlank}, ]; diff --git a/src/utils/qrcodeHandler.js b/src/utils/qrcodeHandler.js index 724924e..3a947b7 100644 --- a/src/utils/qrcodeHandler.js +++ b/src/utils/qrcodeHandler.js @@ -62,10 +62,11 @@ export function getTypeTable(qrcode) { for (let i = 0; i < PD.length; i++) { typeTable[PD[i][0]][PD[i][1]] = QRPointType.POS_CENTER - for (let r = -3; r <= 3; r++) { - for (let c = -3; c <= 3; c++) { - if (!(r == 0 && c == 0)) - typeTable[PD[i][0] + r][PD[i][1] + c] = QRPointType.POS_OTHER; + for (let r = -4; r <= 4; r++) { + for (let c = -4; c <= 4; c++) { + if (PD[i][0] + r >= 0 && PD[i][0] + r < nCount && PD[i][1] + c >=0 && PD[i][1] + c < nCount) + if (!(r == 0 && c == 0)) + typeTable[PD[i][0] + r][PD[i][1] + c] = QRPointType.POS_OTHER; } } } From 616b1cd5471ef8db217b5915fa43488a59ff21b9 Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Wed, 6 May 2020 21:46:50 +0800 Subject: [PATCH 03/30] =?UTF-8?q?=E6=96=B0=E5=A2=9E=E5=9B=BE=E7=89=87?= =?UTF-8?q?=E8=83=8C=E6=99=AF=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/QrRendererImage.js | 5 +++-- src/components/QrRendererRandRect.js | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/components/QrRendererImage.js b/src/components/QrRendererImage.js index 2a6c599..4338876 100644 --- a/src/components/QrRendererImage.js +++ b/src/components/QrRendererImage.js @@ -1,7 +1,7 @@ import React from "react"; import './Qrcode.css' import {getTypeTable, QRPointType} from "../utils/qrcodeHandler"; -import {defaultRenderer, rand} from "../utils/util"; +import {defaultRenderer} from "../utils/util"; function listPoint(props) { if (!props.qrcode) return [] @@ -22,7 +22,7 @@ function listPoint(props) { if (size <= 0) size = 1.0 - pointList.push(<image key={id++} x="0" y="0" width={nCount} height={nCount} href="http://blog.ciaochaos.com/images/Avatar.jpg"/>); + pointList.push(<image key={id++} x="0" y="0" width={nCount} height={nCount} xlinkHref={data}/>); for (let x = 0; x < nCount; x++) { for (let y = 0; y < nCount; y++) { @@ -134,3 +134,4 @@ export default class QrRendererImage extends React.Component { } } +let data = "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQAASABIAAD/4QBMRXhpZgAATU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAEOKADAAQAAAABAAAEOAAAAAD/wAARCAQ4BDgDASIAAhEBAxEB/8QAHwAAAQUBAQEBAQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBAQAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAkM2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKjpKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAAAAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAxEEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmqsrO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8vP09fb3+Pn6/9sAQwACAgICAgIDAgIDBQMDAwUGBQUFBQYIBgYGBgYICggICAgICAoKCgoKCgoKDAwMDAwMDg4ODg4PDw8PDw8PDw8P/9sAQwECAgIEBAQHBAQHEAsJCxAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ/90ABABE/9oADAMBAAIRAxEAPwD9IKESiigAooooAKKKKACiiigAoRKKKACiiigAooooAKKKKAChEoooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKESiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Q/SCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//R/SCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//S/SCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//T/SCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//U/SCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//V/SCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//W/SCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//X/SCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//Q/SCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//R/SCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//S/SCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKK0rPSrm8f5E+T+/XVJ4YtvJ2O/7+gDg6K1b/R7mzf503p/frKoAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/0/0gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAop6I8z7E+d66fTfDE03768+RP7lAHNw21zcvstk3122m+G4Yf31587/3K6G2tobZNlsmyrdAESQpCmxE2VLRRQBE6JMmx031yupeG4Zv31t8j/3K6+igDyC5s5rZ9kybKrV7BNbW1ynkzJvrjNS8MPD++s/nT+5QByVFPmheF9kybHplABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf//U/SCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoorSs9Nubx9lsn/A6AM2tuw0G5vPnf5IK6rTfD1tbfPc/PPXR0AZdno9nYJ+5T9//frUoooAKKKKACiiigAooooAKKKKAMi80q2v02TJ8/8AfrjNS0G5s/nT50r0qovv0AeOUV6Lf6DbXnzw/uHrjLzSrmwf98nyf36AM2iiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/1f0gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiijY7/IlABU1tbTTP5Nsm963tN8NzXP765/cJ/wCP13NtYW1mnkwpsoA5XTfDGz99f/P/ALFdbDbJCmyFNiVYooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACmvDDMmyZN6U9Emd9iJvd67DTfDDzfvr/wCRP7n8dAHktz4MfUpv+JUnz/3K4y/sLnTrh7O/TyZk++lfXSfYNNh8m2RE/wBhK+cviFM83iR3f+4lAHDUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB//9b9IKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACirNtYXN4+yFN9dzpvhu2tv31z+/f/AMcoA5Kw0e8v33omxP7713lho9nYfcTfP/fetJPkTYlS0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAN/2KdRRQAUUVdsNNvNSfZbJ8n8b/wUAUq29N8P31987/JD/feuo07w9Y6b++uf38399/uVtTX/APBD/wB90AV7PTdO0pMp9/8Avv8Afpk15NN8kP7tKrO7v87/AH6SgArwbx//AMjFN/uJXvNeEePv+Q8/+4lAHDUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB//1/0gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqOpKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoorodN8N3Nz++m/cQ/8Aj9AGDDDNcv5MKb3rsNN8Kv8A66//AO+K6ez022sE2Qp/wP8Ajq9QBFDbQ20Pk2ybEqWiigAooooAKKKKACiiigAooooAKKKKACiiigAoopvzv9ygB1SQwzTTeTCju7/wV0Om+GLm52PefuE/8feuwtobPTYfJtk/+L/4HQBgab4YRP32ov8A8AX/ANnrpBNDCnk2yJ8n937lUZrmab7/ANz+5UdACu7u++Z99JRRQAUUUUAFeDeP/wDkYpv9xK95rwLx5/yHX/3EoA4yiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/9D9IKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKmhtrm8fybZN9AENaVho95fv+5TYn9966rTfDFtD++vP37/3P4K6dERE2J8lAGVpuiWdh8+zz5/771tUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRVqzsLm/m2Wyb/8A2Su1sPDdnZp51+/nv/44lAHJ6bot/qT70Ty4P7713dtpWnaUnnfff++/3/8AgFXZr/5P9GrKd3d97vvoAuTXk03yQ/u0qt89JRQAUUUUAFFL/uUlABRRRQAV4R4+/wCQ8/8AuJXvH+/Xgnjz/kPf8AoA4miiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/R/SCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKeiPM+xPnd629N0G8vPnf8AcQf33rubDSrawT/Rk+f++/36AOV03wrNN++v/kg/ufx12cMMNtD5MKIif7FWKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoore07w/eXJ82b9zB/t/ff/AIBQBz8MM0zpDEju7/wJXa6b4Yd/32ovsT/nin/s9dFDbabpSbIU+f8A8fpk00033/kT+5QBMJrazg8mzjTYn937lU5neb53eo6KACiil+SgBKKKKACiiigAooooAKKX+CkoAK8C+IH/ACHX/wByvfa8F8ef8h7/AIBQBxNFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/0v0gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAoqaGG5uZvJtk3vXbab4YhT99fvvf+4n3KAOSsNKvNSf/AEZPk/v/AMFdzpvh62s/3037+f8AvvW2iJCiQomxEqWgAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKnhtprybZbI7v/sUAQVd03Sr/Un/ANGT5P77/crrdN8Kww/vtSfe/wDc/grb+2IibLNNiJQBn2Gg2Glfvpv38/8Aff8A9kSrs15NN8kP7tKrO7zPvf56SgAopfuUlABRRRQAUUUUAFFFFABRRRQAUv8Av0lFABRRRQAV4L48/wCQ9/wCveq8F8ef8h7/AIBQBxNFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/0/0gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAGO6Im966rTfDc1zsmvH8iB/n2J996868Q/JpUm9N+x0/8AQ6oeHvGepaO/k2z+fB/z7zfc/wCAUAfRVtZ21nD5NsmxKt1zOieLdK1vZDC/kXX/ADyf/wBk/v101ABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUqI7vsT53ra03Qb6/wBjbPIh/vv/AOyV2lnpum6Un7lN7/33+/QBzGm+FXuf32o/In9z+P8A+wrrIXsLBPJsESoZruab/YT+5UNAEjzO/wA8z1HRRQAUUUUAFFFFAColJRRQAvyUlFFABS/JSUUAFFFFABRRRQAUUUUAFeC+PP8AkPf8Ar3qvAvHn/IbkoA4yiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP//U/SCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA5/xJ/yB5v8AgH/odeZ16Z4k/wCQPN/wD/0OvL6ANC2v5ofv/P8A+h16j4e+It5Z7Ib/AP0qD+//AMtk/wDi68ipiO6fOlAH2BpWsabrFt51hMk399P40/30rXr5DsNYubOaC5hneCdP40r2PQfiQk2y21tP+3iH/wBnSgD1miq9tcw3MKXNs6TwP9x0qxQAUUUUAFFFFABRRRQAUVJDDLM/k2yO7v8AwJXYWHhjZ++1V/8AgCf+zvQBzFhpt5qL7LdN/wDt/wAFdrYeHrCwTzrx/Pf/AMc/74rWeZLZPJs0RESqG93fe776ALk1+7/InyJVKiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKX5KP46SgAooooAX56SiigArwLxz/yHH/3K99rwLxz/wAhx/8AcoA4yiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP//V/SCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA5/xJ/yB5v8AgH/odeX16h4k/wCQPN/wD/0OvL6ACiiigAqSGZ4fnSio6AOr0HxVf6PNvs5vI/vo/wA6PXuWg+PNN1XZbXn+i3X+39x/9x6+ZqmhvHh/20oA+zqK+cPD3jzUtK2Qo/2q1/54zfwf7j17Zo/ifStbT/Rn2T/xwv8AfoA6OiitbTdHvNS+dE2J/ff7lAGTXRab4bvLzY95+4g/8feums9K03Sk3/fm/vv9/wD+wqea8mm/2EoAlhS20qH7NZx/P/n771Xmlmm++9R0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUqUlABRS/7FJQAUUUUAFFFFABRRRQAUUUUAFFFFABXgXjz/kNyV77XgXjz/kNyUAcZRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH/9b9IKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACo6kooAKKKKACiiigAooooAKKKKACiiigAooooA57xL/yB5/8AgFeYV6f4l/5A8/8AwCvMKACipKjoAKKKKAJKjqSo6AJKuW1/NC6P/c/jT76VTooA+tvhNqtvqtt/xPbpJ7p/9Sj/AH9iff3/AN+vdprx/uQ/IlfJfwl/5Cul/wDbb/0B6+pKAF/36SiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKbs9qAHUUUUAFFFFABRRRQAUuykooAKKKKACvAvHn/Ibkr32vAvHn/IYegDjKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//X/SCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA57xL/yB5/8AgFeYV6h4k/5A83/AP/Q68voAKKKKACiiigAqSo6KAJKKjooA98+Ev/IV0v8A7bf+gPX1JXy58Iv+Qrpf+5N/6A9fUdABRRRQAUUUr0AJRS/JSUAFFFFABRRRQAUUUUAFFFFABRS/JSUAFFFK9ACUUUUAFFFFABRRRQAUUUUAFFFL8lACV4F48/5DD177XgXjz/kMPQBxlFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf//Q/SCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA5/xJ/yB5v8AgH/odeX16f4l/wCQPP8A8ArzCgAooooAKKKKACipKKAI6KkqOgD334Rf8hXS/wDcm/8AQHr6jr5f+EX/ACEtL/3Jv/QHr6goAKKKKACiiigAooooAX/cpKKKACiiigApfno+/SUAFFFFABRRRQAUUUUAFFKlJQAUUUUAFFFFABRRRQAUUUUAFeBePP8AkMPXvteC+PP+QxQBxNFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/R/SCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACo6kooAKKKKACiiigAooqOgCSiiigAooooAKKKKACio6koAKKKKACiiigAooooA57xL/yB5/8AgFeYV6f4l/5A8/8AwCvMKACpKjooAKkqOigAqSiigCOpKKKAPePhF/yEtL/7bf8AoD19SV8t/CX/AJCul/8Abb/0B6+pKACil/3KSgAooooAKKKX/boASiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKX/YpKKAF30lFFABRRRQAV4N45/5Cte814F45/wCQwKAOMooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD//S/SCiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiio6AJKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACo6kooAKKKKACiiigDnvEv/IHn/wCAV5hXp/iX/kDz/wDAK8woAKKkooAKKjooAkqOpKjoAKkoooA94+Ev/IV0v/tt/wCgPX1JXy38Jf8AkK6X/wBtv/QHr6koAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigApfuUlFABRRRQAUUUUAFFFFABRRRQAUUUUAFeDeOf+QrXvNeDeOf+QrQBxFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/T/SCiiigAooooAKKjqSgAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACo6kooAKKKKACiiigAooooAKKKKACiiigCOpKKKACiiigAooooAjqSiigAqOpKKACiiigDnvEv/IHn/wCAV5hXp/iX/kDz/wDAK8woAKKKKACpKKKACiiigAooooA94+Ev/IV0v/tt/wCgPX1JXy38Iv8AkJaX/wBtv/QHr6koAKKKKACiiigAooooAKKKKAF/gpKKKAClekooAKKKKACiiigBfv0fwUlL89ACUUUUAL/t0bKSigAooooAKKKKAF/3KSiigArwbxz/AMhWvZb/AFK2sEd7l68E8T6rDqt+80P3KAOeooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/9T9HKKKKACiiigAooooAKKKKACiiigAooooAKKKKAJKjoooAkoqOigCSio6KAJKKKKACiiigAooqOgCSiiigAooooAjqSiigAooooAKKjqSgCOpKKKACiiigAooooAjoqSigAooqOgCSiio6AJKjqSigAqOiigDC8S/8gef/gFeYV6f4l/5A8//AACvMKACpKKKACiiigAooooAKKKKAPefhF/yFdL/ANyb/wBAevqOvmH4Rf8AIV0v/cm/9Aevp6gBd9JRRQAUUUUAFFFFABRRRQAUvyUlFABRRS/7FACUv+5SUUAFFFFABRRRQAUUUUAFFFFABRRRQAv+xSUruiJveuM1jxhYaajoj73oA6qaaG2h3zPsrz3W/HkNt+5sPnnrzrWPE+paq/zvsSueoA0r/VbzUn3zPWbRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB//9X9HKKjqOgCxRVeigCSio6KAJKKjooAkoqOjfQBJRUe+jfQBZ30lV6N9AFiiq9SUASUVHRQBLvpKjooAkopd9JQBJRUdFAElFR0UAFSVHUlABRRRQBHUlFFABRRUdAElFFFABRUdSUAFFFR0ASVHUlFAEdFFFABRRUlABUdSVHQAUVJUdAElFR0UAYvif8A5BU//AK8tr0/xJ/yCp68woAkooooAKKKKACiiigAooooA9++EX/IV07/ALbf+gPX09Xy98JP+Qpp/wDuTf8AoD19Q0AFFL/t0lABRSpSUAFFFFABRRRQAUUUUAFFL/BSUAFFFFABRRRQAUUUUAFFFFABRRVS81K2sE33L7KALdc/qviGw0pP3z/P/crgNe8eO++203/vuvNJrm5uX86Z98lAHYa342vNSfybb5IK4x3eZ97/ADvTKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooA//1v0Uoopm+gB9FR0UASUVHRQBJTN9Rb6N9AFimb6i30b6ALFFV99G+gCXfT6r76N9AFiiq++jfQBYoqvvp2/3oAmo31Dv96N/vQBNRvpm+jfQBPRUG+n0AWd9G+q1G+gCxRUdFAElFFLvoAfRTN9JQAVJRRQAUVHRQAVJRRQBHUlFR0ASVHRUlAEdFSVHQAUVJRQAUVHRQAUUVJQBHRRRQBheIf8AkDzV5hXp/iT/AJBU9eYUASUUUUAFFFSUAR0VJRQBHRUlFAHu/wAJP+Qpp/8AuTf+gPX1DXyz8KP+Qrp//bb/ANAevqagAooooAKKKKACiiigAooooAKKKKACiiigBfkpKKKACiiigAoopX+SgBKrzTJCm+b5Erm9Y8W6bpSbN/nz/wByvH9Y8T6lqr/PJsg/uJQB6Rrfjy2tt8Nh8715RqWq3+qvvuX/AOAVlUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//1/0Mo31V3+9TUASb6g30zf70b/egB++jfTN/vTd9ADt/vRv96bvo30AO3+9G/wB6hooAm3+9G/3qGigCbf70b/eoaKAJt/vRv96hooAm3+9G/wB6hooAm3+9P31WooAs76N9Vqk30AXN9G+qe+nb/egC5v8Aejf71T3+9G/3oAv76fVDfRvoAv76N9V99O3+9AFqpKqb6fQBZ30lV99SUASUUu+jfQAlFFFABRRRQAUUUUAFFFFABRRRQBJUdFFABUlR0UAFFFFAGF4h/wCQPNXllep+Jv8AkDz15QlAFipKjqSgAqSo6koAKKkqSgCOipKKAPb/AIU/8hXTv+23/oD19Q18w/Cj5NV07/cm/wDQHr6eoAKKKKACil/2KSgAooooAKVKSigAooooAKKKKACiiigAoqjc3ltZw+dcvsRK80174hffttK/77oA9C1XW7DTYd9y/wDwCvH9b8c3l/vhs/3EFcZc3lzeTedcvveqtAE7u8z73fe9MoooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD/9D9AN9R0UzfQA+imb6N9AD6KZvpm/3oAfvo30zf70b/AHoAfvo30zf703fQBLvo31FvqDfQBc30zf71W30b6ALO/wB6N/vVbfRvoAs7/ejf71W31FvoAvb/AHp++qe+jfQBc30b6zt9S76ALm+jfVPfRvoAub6fVffTt/vQBNUm+qu/3o3+9AFrfTt/vVbfRvoAub6n31n1JvoAvb/en76ob/ejf70AaVG+qG+p99AFypd9U99G+gC5vo31W31JQBJRS76N9ACUUUUAFFFSUAR0UUUAFSVHRQAUUUUAc/4q/wCQPNXkqPXq/i35NEnrx9HoAubKspWaj1ZR6AL9SVVR6mR6ALKU+mI9PoAKKkooA9u+Ff8AyGNO/wByb/0B6+nq+XvhX/yGNO/7ea+oaAJKjoooAKX/AG6SigAopXpKACiiigAooooAKKK5nWPFWlaOjo775/7iUAdI7pCm+Z9iJXB6345s7DfDZ/v56831vxhqWqvs3+RB/cSuVoA1dV1u/wBVm865n/4BWVUdSUAFFR0UAFSVHRQAUVJRQBHUlFR0ASUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB//0fvbf70b/em76g30AWd/vTd9U99G+gC5vqDfUW+o99AEzvTd9V6KALG+jfVeo99AFjfRvqvvo30ASUVHvo30ASUVU30b6ALdFVN9G+gC3RVHf70b/egC9RVHf70b/egC9RVHf70/fQBbqTzXqhvo84UAX/NepPONU/ONG+gC55xqXfVBJqPOoA1t9O86smpPNegDV30b6zvONS76AL9Sb6p+cadv96ALm/3o3+9U/tPvT0moA099O3+9Ud9O86gC/vp9Zu/3p/nCgC/vqSqe+pd9AFzfSVXo30AWKKjqXfQAlFFFABRRRQBzPjN9mgz14ak1e8eKrO5v9EntrNN718zX9zc2Ez21yjwOn9+gDp0uU61ZS5rjEv8AfV+G830AdbDNVyF65uG5rYhmoA3EqxWbC9X0egCdKkqNKkoA9n+FH/IVsv8Acmr6hr5i+F//ACGNO/4HX07QAUUUUAFFL9ykoAKKKKACiiq800NtC80zokaf36ALFZ2parZ6bC815Mif7Fee698QoYd9tpSb3/v15XeX9zfzfabl3d6AO517x/c3m+2039xB/f8A464CaZ5n3zPveoKKACiiigAooooAkqOiigAooqSgAoqOpKACo6KkoAKjqSo6AJKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigD//S+6N9R76jqPfQBJRUe+jfQBJUe+oN9M3+9AFrfRvqnvqDfQBc30zf71W30b6ALO/3pu+oN9RUAS76N9Vt9M30AXN9G+qe+jfQBc30b6ob/ej7T70AWvtElFU99G+gC59oko+0SVT31B5woA0/tElH2iSszzhR5woA0/tElO86srzhU++gC951P31nb6d9p96AL/nCp/ONZnnCjfQBq/afen+cKx99T/aJKANjzjTvOrH86n76ANPfVjzXrL84077T70Aa3nGpd9Z3nGnedQBqpNT/ADqykekoA1vtPvU2+svzjUqTUAavnUb/AHqgk1CTUAaW+pkes3fU++gDR30+s3zqfvoA06l31nb6ydV8Q2elQ75n3v8A3EoA6R3RE3vXnXif4kaVo++2s/8ASrr/AGPuV5X4n8Ya9rO+FP8ARbX+4ledOj/x0Adt/wALI8Tpf/b/AD/k/wCeP8Fd/Z+JPB/jyH7BrCJa3X9+vAnqq6UAeqeJPh7rGib7yw/02y/2Pv1wcN5sfY/yPXT+GPiRreg7La8/02y/uP8Afr0t9N8E/EK2+06a6Wt7/wCP0AeXW15W9bXlc3rfhXXvDE3+mQeZB/BMn3KrWepUAekW1zWwj1xNneb66S2moA3kqxVGF6tJQB7d8Kv+QxZf8Dr6er5h+FX/ACGLL/gdfT1ABRRRQAUUUUAFLv8Ak3v9yue1XxJpWlJ++fe/9xPv14/rfjbVdV3wwv5Fr/cSgD0vXvG2m6Vvhtv391/sfcrxzVfEOpaxNvuZ/k/ufwVh0UAFFFFABRRRQAUUUUAFFFFABRRRQAUVJUdABUlR0UASVHRRQBJUdSUUAR0UUUASUUVHQBJRUdSUAFFFFABRRRQAVHUlFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/T+3N9Qb6Zv96rb6ALO/3pu+oN9Qu9AE2+h3qtvooAkqPfTN9Rb6AJd9G+qe+mb/egC5v96bvqrv8Aem76AJd9M86oaZ5rUAWd/vR51U9/vRv96ALW+o99V/ONQb6AL++mecKp76N9AFzzhR5rVnecaPONAGj5rUea1Z3nGjzjQBo+a1HmtWd5xo840AaPnCjzhWd5xqXfQBf31JvrM30b6ANXzqPOqnv96N/vQBrb6d9p96x9/vT/ADhQBsecKN9ZW+npNQBs/aJKck1Y/nU/zhQBsecKs/afesdJqmR6ANhJqmSasRJqek1AG2j09JqxPOFWUmoA1vONXPONZKTVNbJNczJDbJvd/wCBKAL6TVch3zfcrpNK8GXLp52pfJ/sV1qaJDCmyFKAPK7m2vHTZD8lclc+Hnmd3f79e6vo+/8AgqnNon+xQB85XPht/wC5XN3nhj/Yr6im0H/YrKufDe/76UAfJ154bmT7iVg3Om3MP8FfWlz4V3/wVzdz4M37/koA+V5rZ0+/UMM1zZzJc2cjwOn8aV79f+Bt+/YlcTf+CblPuJQBseG/i1MkP2DxVB59r9zzf/i66TUvAGieJLb+1fB90iO/z+T/AAV4zeeHr+2/gqtpupax4euftNhM8D/+OUAdJc22paDc/Y9SgeB/9v7lbdhfo+yuq0f4kaD4ntk0rxhaojv8nnfwVW1j4e3lmn2/wxN9qtX+fZ/H/wAAoAv2cyPWqj1wFhfvDN5Nymx0/geu2tpt6UAe9/Cv/kK2P+49fT1fL3wr/wCQrZP/ALD19Q0AFFRTTQ20LzTPsRP79eda98QobbfDpSee/wDz2/goA7y/1Kz02HzrydIEryXXviFNc77bR4/IT/nt/HXB3+pXmpTedeTvO9Z9AE8001y7zTPvd/43qCiigAooooAKKKKACiiigAooooAKKKKACiiigCSo6KKACiiigAqSo6KACpKjqSgCOiipKAI6koooAKKKKACiiigAqOpKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/1PsnfUVR76KADfTN9M3+9Vt9AFnf71W3093qs70AP3+9G/3qGmO9AD6Zvqs71JvoAdv96hd6ZvqF3oAsu9M31W31X30AXPONHnGqe+o3egC5vpm+qDvTfONAF7zqPOqjvqDzhQBp+caPONZm+medQBf84UecKoedT99AFzzhR5wqh51P30AafnGnedWVvo84UAavnUedWV5wqffQBo76N9Z2+jzjQBqb6k841k7/AHp/nCgDVSan76x/OFT+caANdJqej1j+dT99AGx5rU9Jqx99SecaANpJqek1Y++no9AG8k1TI+6sRJq7bwZqtnpVz9pvIUuv/Q0oA6Tw94G1XWNlzc/6La/33++9e06V4e03RIdltB8/99/v1No+t6brEO+wn3/7H8da1AEdM2JT6KAH+UtVnhSpqKAK32aKoXsIXq/RQBlSabbPVabRIXreooA5Kbw3C/8ABWVc+D4X/gr0KmbKAPIrz4ewzfwVxOpfChJv+WFfSVFAHxLqvwcufne2Ssqw03x/4Jm32G+e1/jhf7lfdrwwv9+Oq01hZzffgR6APlGG/wDDfjNPs2q2r6dqP+38j/8AAHpk3h7UtEf/AJ+rX++lfTlz4S0G8/4+bKF/+AVfsPhr9oh8nTd8EP8Afl+5QBxXwo/5Ctj/ALj17LrfjPStH3wo/wBqn/uJXiF/pVz4c1Wazd/JmT5Pk/26of7b0Ab2seJ9V1t/9JfZB/zxT7lYFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBJUdSUUAFFFR0ASUUVHQAVJRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB/9X663+9Md6h30zf70ATO9Q7/eoXemb6AH0x3pjvULvQBJUbvTHemO9AD3eoXemO9VnegCWonel31BvoAn31V3+9NqDfQBM71Dvod6ioAl31FUe+mb6AH76ZvqKigB2/3o3+9Q0UATb/AHo3+9Q0UATb/ejf71DRQBNv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FSUVHQAUUVJQAUVHRQBJRUdFAElFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/0foF6iepXqJ6AIHeoqleqz0AM30b6So6ACio6KACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooqSgCOpNlGynbPagB1Lsp+ypKAI9lPRKm2VPsoAgRKmRKeiVMiUAQ7ParWykRKsolADESpkSpkSnolADEhq/D/AKmmIlPoAKkqOpKACiiigAqSo6koAKKKKANnw9/yFYP+B19veCf+RZsv9x//AEOviHw9/wAhWD/gdfb3gn/kWbL/AHH/APQ6AOpooooAKKKKACiiigAooooA+efHH/IyT1yNdd44/wCRknrkaACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAkooqOgCSiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP//S+h3SqzpWk6VWdKAKDpVZ0q+6Ux0oAobKZsq5so2UAUNntTdlXKj2UAU6Ks7KZs9qAIaKk2VHQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFSU7Z7UANp2z2p+yp6AINlT1Lsp6JQAzZT0SnolTIlAEVSolTIlTIlAEKJVlEp6JVlEoAhRKmRKESrKJQAxEqZIamRKmRKABEqu/360USs2X/X0AMooooAkoqOpKACiiigCSio6KAOg8Pf8AIVT/AIHX2x4JT/imLL/cf/0Ovifw9/yFU/4HX234J/5Fux/3H/8AQ6AOpooooAKXfSUUAFFFFABS/wC3R8lJQB88+OP+Rknrka67xr/yMU9cjQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRUlAEdFFFABRRRQAUUUUAFFSVHQAVJUdSUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFSUAR0UUUAFFSVHQAUVJRQB/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R1JRUdABUlR1JQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQB//9f722e1VnSr9MdKAM10qF0rVdKhdKAKDpVPZWk6VC6UAZTpTHStJ0qs6UAZrpVZ0rSdKrOlAGU6VC6VqulU3SgDNdKpularpVZ0oAx3SqzpWq6VQdKAKb1WerLpVN6AEqOio6ACiiigAooooAKKKKAJN9O3+9Q0UATb/epkeqdM30AaqTUJNWVvqffQBrpNVlLmsH7T70/7TQB0iXNWUua5hLmpkuaAOwS5q+l/XBpeVZS8oA9ChvK0ob+vN0v6spqVAHp0N+laUN/XlaaxVyHWKAPV0vExXlfiF9+pO9XIdY/26568ufOuXkoAKkoShKACpKjqSgCSiiigAqSo6koA3fDf/ISSvt7wT/yLVr/uV8Q+G/8AkJJX294J/wCRatf9ygDqaKKKACiiigAooooAKKKKAPnzxt/yHp65Kut8bf8AIenrkqACiiigAooooAKKKKACiiigCOpKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACipKKAI6KkooAjqSiigAqOpKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP/Q/QXZTNntWlULpQBm0x0q+6VDs9qAKbpVZ0rSdKhdKAM10qF0rVdKrOlAGU6VWdK1XSmOlAGO6VTdK1XSqzpQBlOlUHhrbdKoPDQBlOlUHSth4apvDQBiOlUHSt54apvDQBiOlQ1sPDVN4aAKdFTOlQ0AFFFFABUdSUUAR0UUUAFFFFABRRRQAUUUUAFFFFADd/vT970lFAEnmvR5r1HRQBP5z0/7Y/rVWigDQS/et62m3w7642umsH/cpQBrJVxKz0qRKALlFCUUAWKKjqSgAqSo6koA3fDf/ISSvuLwZ/yKtr/uV8O+G/8AkJJX294Mf/im7X/coA6miiigAopfnpKACm/cp1FABRRRQB8+eNv+Q9PXJV1vjn/kOT1yVABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUVJQBHRUlFABUdSUUAR0VJRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRUlR0AFFSVHQAUUUUAFFFFABRRRQAUUUUAFFFFABRRUlAEdFFFABRRRQAUUVJQBHRRRQAUUUUAFFFFABRRRQAUUUUAFFFFAH//R/Rio9lWKKAK7pULpVqo3SgCm6VC6VfdKi2UAUnSqzpWk6VWdKAKDpULpWk6VC6UAZTpVZ4a1XSqzw0AY7w1TdK3nhqs8NAGC8NU3hrbeGoXSgDBdKrPDW88NU3tqAMF4apvDXSPDVN7agDnnhqs8NdC9tVN7agDBeGq2yt50qs8NAGbRVx4ar7KAK9FLspKACiiigAooooAKKKKACiiigAooooAKKKKACiio6ACugtn/AHNc/W7bP+5oA0kerKPVBHqZHoA0kqeqqPUyPQBMlOqOpKAFSn0xKfQB0Phv/kJJX294M/5Fu1T/AG6+HPD3/ISjr7j8GJ/xTdr/ALlAHU0UUUAFFL9+koAKKKKACiiigD588Y/8hqeuSrrfHP8AyHJ65KgAooooAKKkqOgAooooAKKKKACiipKAI6koooAKKKKACiiigAqSiigCOipKKACiiigAooooAKKKKAI6koooAKKKKACiiigCOpKKKACiiigAooooAKKKKACiiigAooooAjoqSo6AJKKKKACiiigAqOipKAI6KkqOgCSo6kqOgAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKAP//S/SCo6kooAjpdlJRQBHUdWKXZQBQ2e1MdKs7KKAKbpVfZWjsqF0oAzXSoXhrVdKheGgDKeGoXhrVdKheGgDKdKrPDW28NVnhoAwXhqs8NdC8NQvDQBzzw1Te2rpHtqrPbUAc29tVZ4a6R4arPbUAcw9tUL21dI9tVZ7agDm3tqpvDXVPbVTe2oA557aqzw10j21QvbUAc28NVtldC8NVntqAMaitB7aoXhoAq0UuykoAKKKKACiiigAooooAKjqSo6ACtG2f5KynqZHoA3kerKPWOk1XEegDYR6so9ZSPVxHoA00pyVWR6ej0AXKKjqSgDc8Pf8hKOvubwR/yLdl/uV8M+Hv+QlHX3H4J/wCRatf9ygDrajpf46P4KAEooooAKb81OooAbv8AenUUUAfPnjb/AJDD1yVdV42f/idvXK0AFFFSUAR0VJRQAUUUUAFFFSUAR0VJRQBHUlFFABRRRQAUUUUAFFFFABRRRQAUVJUdABRRRQAUVJUdABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFR1JRQAUUUUAFFFFAEdFFFABRRRQAUUUUAFFFFABRRRQAUUUUAf/0/0gooqOgAoqSo6ACipKjoAKXZSUUAR1HsqxRQBU2UzZ7VaooAzNlPdKuUzZQBQ8modlaWz2puygDJeGmPDV/wAmjyaAMd4aheGtt4aheGgDE8mqz21bzw0PDQBzb21QvbV0P2b2qHZQBzbw1We2rp3hqF7agDmHs6rPbV1T2dQvZ0Ack9tVZ7aute2qF7agDj3s6pvbV2D2dQvYUAcS9tUL21dg9nVN7CgDkntn6VW2PXVPYVTezoAwKK2Xs6oPbP0oAq0Uux6SgAqOpKjoAjSqE1z9m+er71z2pI7psSgC/Z63ZzPs37HroYZq+ctYs7+F/Ohd0eptH+It5pT/AGbVU3p/foA+mYZquQzVxOieIbDVYfOs5t9dJDNQB0KPWglYEM1aSPQBfSpqr1KlAG/4e/5CUdfc3gz/AJFu1/3K+GfD3/ISjr7j8E/8i1a/7lAHW0UUUAR0UUUAFFFc/rfifStBhea8nTf/AHKAN53T771yWseLdK0eF037568W1v4l6rrcz22lR+Ra/wB+sG2s7m5+ebe70Aausaq+sX73P9+s3ZVl7N4X2PT9lAEWypKXZRsoASiil2UAJRRRQAUUuykoAKKKKACiipKAI6KkooAjqSiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKjqSigCOipKKAI6KkooAjooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACio6KAJKjqSigCOipKKACo6kqOgAoqSo6ACiiigAooooA//9T9IKKKKACo6KkoAKKKKAI6KkqOgAooooAKKKKAF2UbKSigCOo9lWKKAK9M8kVc2UbKAKH2b2puytHZRsoAx/JFM8mtao9lAGb5NN2VqbKZsoAx/JFMe2rb8kUeSKAOe+y+9Me2rofs3tUP2X3oA557aofs1dP9l96PsvvQByr21Vns66r7NTPsvvQBx72dVns67B7ah7OgDhns6pvZ13j2dVns6AOAewqg9hXor2FU3sKAPN5rCqE1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+5QB2CPV9Kx4Xq/voAsUUqUlAC76SionegAd6zZnq471QuX+TmgDnryuem+/XQ3lYT0AYc1V3q86VTegCrUdS7KSgCOiiigAooooAKKKKACipKbs9qAG1JRRQAUUuyn0AR0uyn1JsoAjoqSpKAK9SbKds9qfsoAip2z2qambKAGbPajZ7U/ZRsoAZs9qhqzspmz2oAbsqN0qxTdntQBVoqxsqB6AIqKkooAr0VJRQBXqOrFR0AR0UUUAFR1JRQBHRRRQAUUUUAFFFFAEdFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVHUlFAEdSUVHQAUUVJQBHRRRQB//Q/SCiiigAooqOgCSiiigAooooAKKKKACiiigAqOipKACiiigCOipKKAI6koooAKjqSigAooooAKKKKAI6KkooAjqSio6ACiipKAI6kqOigAooqSgCOiiigAqSo6koAKKKKACpKKKACpKKKACiiigAooooAKkoqaFKANWzQ767/TfuVwtn9+u0saAOqheriPWVbPWkj0AWakqDfT99AElFR0x6AGO9UZutW3es25oAx7msKbrW7c1iT0AZTpVB6vzdKrPQBTpjpU9QbKAEpuz2qao6ACiiigAooqSgCOipKKAGbKfUlFABsop2z2p+ygCKnbPapqKAGbKfUmynbPagCGirFFAEeyjZUlFAEeynbPajZ7UbPagBuyjZUlFAFembKs7Pam7KAK9R7KlekoAr1HUlMegBKjqSo6ACo6kqOgCOo6sVHQBHRRRQAVHUlR0AFFFFABRRRQAVHUlFAEdFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVHUlFABRUdFAElFR0UAf//R/SCiiigAooooAKKKKACiiigAooooAKKKKAI6koooAKKKKACiiigAooooAKKKKACo6kooAKKKKACiiigAoqOpKACiiigCOpKKjoAKkoooAKKjqSgAooooAKKKKAJKKKkoAKKKKACiiigAqSimJQA+rMPSoqsQ0AattXW2dcra966qzoA6S2er8L1m2z1fgoAtVJVRKnoAsVDv96dTXoArO9U3q49Ztz92gDNuax5ulbFzWVMlAGW9UnSr9z3qm9AFZ6iqw9Q7PagCGipKKAI6KkooAjoqSigCOptntTqXZQAzZ7VNRRQAzZT6m2e1OoAj2U7Z7UbPajZ7UAOpuz2p+yp9lAEGyjZVnZ7U/ZQBFRsqXZT6AK+yirGymbKAItlQbKubKSgCi9PdKm/gqs9ADXqOrFRvQBXqN6c9D0AVaKkqOgCOh6kqOgCOo6sVHQBHUdSVHQAUUUUAR0VJUdABRRRQAUUUUAFR0UUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUVHQAUUUUAf/0v0gooooAKKKKACiiigAooooAKKKKACiiigAooooAKjqSigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigCOpKKKACiiigAooooAKkqOpKACpKjqSgAooooAKkqOpKACiiigCRKtxfdqFKspQBsW3auhtq56Ct62egDoUq+lZtt2q+j0AXEqeqqPU1AElQPU9R0AV3qrc96tPVV6AMq5rHm6VsTdKx5ulAFN6pulab1mOlAET1HVio6AINlJUlFAEOz2o2e1TUUAQ7PapqKkoAjqTZTtntRs9qAG07Z7U6l2UAJRVjZUlAEeynbPan7KfsoAjqSpKKACipdlGygCKk2f3Km2UbKAItiUVLspKAI6jqzsqF0oArPTHSpaa9AFWilekoAr1C9WXSmUAU6Y9WXqGgCOo6kooAjqOpKKAK9FSVHQBHRRRQAVHUlFAEdFFFABRRRQAUUUUAR0UUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABUdSUUAR0VJRQB/9P9IKKKKACiiigAooooAKKKKACiiigAooooAjqSiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKkoooAKkqOpKACiiigCSiiigAqSo6koAlSriVWStBKAL0FbcPSsSCtuHpQBvpV5KyoelX0egDQSpKro9SUAS76Y9OqOgAeqb1K71E9AGZN0rNl+7WlN0rNl+7QBUqq9WX/26hegCg9OpXpKAG7Pam1JRQBHTtntTqKAG7PanU3Z7U/ZQAlN2e1P2VboAiRKfs9qfsp+ygBmyn7KkqXZQBFRUuyjZQAbKNlGypkSgCHZU+ykRKloAj2UbKds9qdQBHsqDZVuo6AI3SmbKneoNlAELpUL1PUb0AV3qq9XqqPQBE9R1M9Q0AQ7PamvUlV6AI6KkqOgCOiiigCOo6kooAr0UUUAFFFFAEdFFFABRRRQAUUUUAR0VJUdABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBHUlR1JQBHRUlFAH//1P0gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKkoAKKKKAJKKKKACiipKACiiigCShKKEoAuJVxKppVxKAL0FbdtWIlbdtQBq23atZKyUq4lAF9KfUdSUASb6joooAY9U3qy9U3oArTdKoPVp6qvQBWeqz1ZeonoApvUdWKKAKmykqxsooAg2U+pKds9qAG7KkpdlPRKAGbKeiVJRQAUiJU2yjZQAIlPRKeiUqUAGyjZTkSnUANRKdRS7KAEpdlPooAjqSj/booAjoqSo6AI6jdKsVHQBA9RPUlR0AVXptSvUT0AV6jenPTXoAr016e9MegCs9JVh6r0AR0VJUdAEdFFFAEdR1JUdABRRRQAVHUlR0AFFFFABRRRQAVHUlR0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQBHRRRQB/9X9IKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACpKjqSgAooooAkooooAKkqOpKACiiigCSpUqJKkoAsJV5KopV5KALkFbaViJWtD1oA2Eq5VNKsJQBcR6sVUSrO/wB6AH76N9M3+9OoAa9UaleoqAKb1Xqw9V6AKj1E9SvUVAEdR1Yeo9lAEdFSbKKAGbKfUlFABRUuyjZQAbKNlGyp9lABsop2z2p1ADUp1Ls/gp9ABUmyo6k2UAGyipKj2UAFSVJRQBXoqSigCPZUdSbKjoAjqOpKjoAgf5KiqV6ioAjeq71YeoXoApvTXpz0PQBWeoqsPUL0AQ1HVh6r0AFRvUlR0AFR1JUdAEdR1JUdABRRRQAVHUlR0AFFFFABRRRQBHUlFR0AFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABUdSUUAR0VJRQB//9b9IKKKKACiiigAooooAKjqSigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqSo6koAKKKkoAKKKKAJKKKKACpKjqSgAqwlV0qxQBMlXEqmlXEoAuQVrQ9ayYK0kegDVR6uJWclW0egC+j09KiqSgCxvqN3pm+jfQAx6a9FQPQBE9V6sPVV6AKz0PU71A9AEVFFFABUuyoql2UAGyjZT6ZsoAfUlGypKAIkSpaKXZQAlKiU+pKAI0SpNlSUUAR7KNlSVJQAUUUUAFFFFABUdSfJRQBHUb0UPQBXopXpj/PQBWeh6HoegCJ6pvVx6qvQBVopr0PQBC9R1I9QvQA16r1JUdABUdSVHQAVHUlR0AR1HUlR0AFFFFABUdSVHQAUUUUAFFFFABUdSVHQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAR0VJUdABRUlFAH/1/0gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooqSgAooooAKkoooAKKKKAJKKjqSgAqRKjqSgAqxVerCUATJVxKppVxKALkFayVkwVfSgC5D0q+j1QSrdAF1HqffUCPT99AElFR76N9AElQPT6rvQAPVV6e9MegBr1A9T1HQBHRUlFABRUmyigA2UVJTUoAdSolPqTZQBHUlFSUAR7KkqSigCOpNlFSUAR1JRRQAUUUUAFR1JRQBHRRRQBHVerFRvQBHUM/3Ke9JQBUeoqsUx6AInqq9Wnqm9AFV6dTXp1AFd6hepqjoAr0UUUAR1HUlR0AFR1JUdAEdR1JUdABRRRQAVHUlR0AFFFFABRRRQAUUUUAR0UUUAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFR1JRQBHRUlFAH/0P0gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAqSiigAooooAKkqOpKACiiigAqSo6koAKkqOpKACrCVXSrCUATJVxKppVxKALiVfSqCVcSgC+j1ZR6o1cSgCwj1JvqBHp9AFiio99G+gA31G/9+pHqvQAUU16bQAUUUUAGyiiigAqSmpTqACpKKKACpKEqSgAqSihKAD/AGKKKkoAKKKKACiiigAooooAKjqSigCOmPT6KAI6jeh6HoAjqu9SVG9AED0PQ9RUAR1XerFV3oAqvQ9D06gCu9V6leoqAB6r1JUdABUdSVG9ABUdSVHQBHUdSVHQAUUUUAFR1JUdABRRRQAUUUUAFFR0UAFFFFABRRRQAUUUUAFFFFABRRRQAUUUUAFFFFABRRUdABRRRQB//9H9IKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKkoooAKKKKAJKKjqSgAooooAKkqOpKACpKjqSgCSpEqvVhKAJkq4lU0q0lAFxKlSqyVMlAGslSpVNHq4lAEyPT9/vUKPUm+gCSio6N9AElFR76KACiiigAooooAKkpqU6gAoqSigCRKEqOpKAJKkqOpKACiipKACiiigAooooAKKKKACiiigAqOpKjegAqOpKrvQAVHUj1A9ACVG9SVG9AED1FUr1E9AEb1XepXqm9ACVG9SVG9AEdR0r0x6AIajpXpKACo6kqOgCOipKjoAjqOpKjoAKKKKAI6KKKACiiigAooooAjooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiio6ACipKKAP/0v0gooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACiiigAooooAKKKKACpKjqSgAooooAKKKKAJKKKKACiiigAqSo6koAKkqOpKAJUp6UxKelAEyVaSqqVaSgCVKt1USrdAE6PVlHqmlWEoAsVLvqKigCxRRRQBJUdSVHQBJRRRQAUUUUAFSVHUlACpT6YlPoAKsVXqxQBJRRRQAVJUdSUAFFFFABRRRQAUUUUAFFFFAEdFFFAEdR1JUdAEdR1JUdAEb0PQ9D0AU6HooegCq9Vnqy9VnoASo3qSo3oAgeoqleoqAIHpKV6SgCOh6KHoAjpj0+mPQAlR1JUdABRRRQBHRRRQAUUUUAFFFFABUdSVHQAUUUUAFFFFABRRRQAUUUUAFFFFABRRRQAVHUlR0AFFFFABRRRQB//2Q==" diff --git a/src/components/QrRendererRandRect.js b/src/components/QrRendererRandRect.js index 75dfb1d..fcf78fd 100644 --- a/src/components/QrRendererRandRect.js +++ b/src/components/QrRendererRandRect.js @@ -1,6 +1,6 @@ import React from "react"; import './Qrcode.css' -import {defaultRenderer, rand, randRGB} from "../utils/util"; +import {defaultRenderer, rand} from "../utils/util"; function listPoint(props) { if (!props.qrcode) return [] From f9f5ceb28b1b02a9908ec9ba380a1c4915f87b90 Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Fri, 8 May 2020 00:45:24 +0800 Subject: [PATCH 04/30] download data record --- .idea/jsLibraryMappings.xml | 7 +++ package-lock.json | 119 ++++++++++++++++++++++++++++++++++++ package.json | 3 +- src/api/db.js | 37 +++++++++++ src/utils/downloader.js | 13 ++-- 5 files changed, 174 insertions(+), 5 deletions(-) create mode 100644 .idea/jsLibraryMappings.xml create mode 100644 src/api/db.js diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml new file mode 100644 index 0000000..68023dc --- /dev/null +++ b/.idea/jsLibraryMappings.xml @@ -0,0 +1,7 @@ +<?xml version="1.0" encoding="UTF-8"?> +<project version="4"> + <component name="JavaScriptLibraryMappings"> + <file url="file://$PROJECT_DIR$" libraries="{qrbtf/node_modules}" /> + <file url="PROJECT" libraries="{qrbtf/node_modules}" /> + </component> +</project> \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index 0247657..59ad16a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1071,6 +1071,22 @@ "to-fast-properties": "^2.0.0" } }, + "@cloudbase/adapter-interface": { + "version": "0.4.0", + "resolved": "https://registry.npm.taobao.org/@cloudbase/adapter-interface/download/@cloudbase/adapter-interface-0.4.0.tgz", + "integrity": "sha1-xXk1tQPnv6zksVHfY6h9xWSumQc=" + }, + "@cloudbase/database": { + "version": "0.9.11-rc.0", + "resolved": "https://registry.npm.taobao.org/@cloudbase/database/download/@cloudbase/database-0.9.11-rc.0.tgz", + "integrity": "sha1-ev1zOIzpzmct1bbZTm5XCNmRQ70=", + "requires": { + "bson": "^4.0.2", + "lodash.clonedeep": "4.5.0", + "lodash.set": "4.3.2", + "lodash.unset": "4.5.2" + } + }, "@cnakazawa/watch": { "version": "1.0.4", "resolved": "https://registry.npm.taobao.org/@cnakazawa/watch/download/@cnakazawa/watch-1.0.4.tgz", @@ -2384,6 +2400,37 @@ "resolved": "https://registry.npm.taobao.org/aws4/download/aws4-1.9.1.tgz?cache=0&sync_timestamp=1578959055063&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faws4%2Fdownload%2Faws4-1.9.1.tgz", "integrity": "sha1-fjPY99RJs/ZzzXLeuavcVS2+Uo4=" }, + "axios": { + "version": "0.19.2", + "resolved": "https://registry.npm.taobao.org/axios/download/axios-0.19.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Faxios%2Fdownload%2Faxios-0.19.2.tgz", + "integrity": "sha1-PqNsXYgY0NX4qKl6bTa4bNwAyyc=", + "requires": { + "follow-redirects": "1.5.10" + }, + "dependencies": { + "debug": { + "version": "3.1.0", + "resolved": "https://registry.npm.taobao.org/debug/download/debug-3.1.0.tgz", + "integrity": "sha1-W7WgZyYotkFJVmuhaBnmFRjGcmE=", + "requires": { + "ms": "2.0.0" + } + }, + "follow-redirects": { + "version": "1.5.10", + "resolved": "https://registry.npm.taobao.org/follow-redirects/download/follow-redirects-1.5.10.tgz?cache=0&sync_timestamp=1585479417937&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Ffollow-redirects%2Fdownload%2Ffollow-redirects-1.5.10.tgz", + "integrity": "sha1-e3qfmuov3/NnhqlP9kPtB/T/Xio=", + "requires": { + "debug": "=3.1.0" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npm.taobao.org/ms/download/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" + } + } + }, "axobject-query": { "version": "2.1.2", "resolved": "https://registry.npm.taobao.org/axobject-query/download/axobject-query-2.1.2.tgz", @@ -3099,6 +3146,26 @@ "node-int64": "^0.4.0" } }, + "bson": { + "version": "4.0.4", + "resolved": "https://registry.npm.taobao.org/bson/download/bson-4.0.4.tgz", + "integrity": "sha1-S9os7fKuehjRXLJO4e3ox5f47s8=", + "requires": { + "buffer": "^5.1.0", + "long": "^4.0.0" + }, + "dependencies": { + "buffer": { + "version": "5.6.0", + "resolved": "https://registry.npm.taobao.org/buffer/download/buffer-5.6.0.tgz?cache=0&sync_timestamp=1588706716358&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbuffer%2Fdownload%2Fbuffer-5.6.0.tgz", + "integrity": "sha1-oxdJ3H2B2E2wir+Te2uMQDP2J4Y=", + "requires": { + "base64-js": "^1.0.2", + "ieee754": "^1.1.4" + } + } + } + }, "buffer": { "version": "4.9.2", "resolved": "https://registry.npm.taobao.org/buffer/download/buffer-4.9.2.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fbuffer%2Fdownload%2Fbuffer-4.9.2.tgz", @@ -3452,6 +3519,14 @@ "shallow-clone": "^0.1.2" } }, + "cloudbase-adapter-wx_mp": { + "version": "0.1.1", + "resolved": "https://registry.npm.taobao.org/cloudbase-adapter-wx_mp/download/cloudbase-adapter-wx_mp-0.1.1.tgz", + "integrity": "sha1-J1DtgUX4IWhB0lu7XWubSiFLhDg=", + "requires": { + "@cloudbase/adapter-interface": "^0.4.0" + } + }, "co": { "version": "4.6.0", "resolved": "https://registry.npm.taobao.org/co/download/co-4.6.0.tgz", @@ -3812,6 +3887,11 @@ "randomfill": "^1.0.3" } }, + "crypto-js": { + "version": "3.3.0", + "resolved": "https://registry.npm.taobao.org/crypto-js/download/crypto-js-3.3.0.tgz?cache=0&sync_timestamp=1581508591511&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fcrypto-js%2Fdownload%2Fcrypto-js-3.3.0.tgz", + "integrity": "sha1-hG3RzOL2iqz6FWyFePkmpgm3l2s=" + }, "css": { "version": "2.2.4", "resolved": "https://registry.npm.taobao.org/css/download/css-2.2.4.tgz", @@ -5565,6 +5645,11 @@ "locate-path": "^2.0.0" } }, + "fingerprintjs2": { + "version": "2.1.0", + "resolved": "https://registry.npm.taobao.org/fingerprintjs2/download/fingerprintjs2-2.1.0.tgz", + "integrity": "sha1-Idw/7ifTsZkFbvjrhz3rzNjgYyM=" + }, "flat-cache": { "version": "2.0.1", "resolved": "https://registry.npm.taobao.org/flat-cache/download/flat-cache-2.0.1.tgz", @@ -8164,11 +8249,21 @@ "resolved": "https://registry.npm.taobao.org/lodash._reinterpolate/download/lodash._reinterpolate-3.0.0.tgz", "integrity": "sha1-DM8tiRZq8Ds2Y8eWU4t1rG4RTZ0=" }, + "lodash.clonedeep": { + "version": "4.5.0", + "resolved": "https://registry.npm.taobao.org/lodash.clonedeep/download/lodash.clonedeep-4.5.0.tgz", + "integrity": "sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8=" + }, "lodash.memoize": { "version": "4.1.2", "resolved": "https://registry.npm.taobao.org/lodash.memoize/download/lodash.memoize-4.1.2.tgz", "integrity": "sha1-vMbEmkKihA7Zl/Mj6tpezRguC/4=" }, + "lodash.set": { + "version": "4.3.2", + "resolved": "https://registry.npm.taobao.org/lodash.set/download/lodash.set-4.3.2.tgz", + "integrity": "sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM=" + }, "lodash.sortby": { "version": "4.7.0", "resolved": "https://registry.npm.taobao.org/lodash.sortby/download/lodash.sortby-4.7.0.tgz", @@ -8196,11 +8291,21 @@ "resolved": "https://registry.npm.taobao.org/lodash.uniq/download/lodash.uniq-4.5.0.tgz", "integrity": "sha1-0CJTc662Uq3BvILklFM5qEJ1R3M=" }, + "lodash.unset": { + "version": "4.5.2", + "resolved": "https://registry.npm.taobao.org/lodash.unset/download/lodash.unset-4.5.2.tgz", + "integrity": "sha1-Nw0dPoW3Kn4bDN8tJyEhMG8j5O0=" + }, "loglevel": { "version": "1.6.8", "resolved": "https://registry.npm.taobao.org/loglevel/download/loglevel-1.6.8.tgz?cache=0&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Floglevel%2Fdownload%2Floglevel-1.6.8.tgz", "integrity": "sha1-iiX7ddCSIw7NRFcnDYC1TigBEXE=" }, + "long": { + "version": "4.0.0", + "resolved": "https://registry.npm.taobao.org/long/download/long-4.0.0.tgz", + "integrity": "sha1-mntxz7fTYaGU6lVSQckvdGjVvyg=" + }, "loose-envify": { "version": "1.4.0", "resolved": "https://registry.npm.taobao.org/loose-envify/download/loose-envify-1.4.0.tgz", @@ -12569,6 +12674,20 @@ "resolved": "https://registry.npm.taobao.org/tapable/download/tapable-1.1.3.tgz", "integrity": "sha1-ofzMBrWNth/XpF2i2kT186Pme6I=" }, + "tcb-js-sdk": { + "version": "1.6.1", + "resolved": "https://registry.npm.taobao.org/tcb-js-sdk/download/tcb-js-sdk-1.6.1.tgz", + "integrity": "sha1-jaLnrtwR+iNYqtrr2YcSg4shFUM=", + "requires": { + "@cloudbase/adapter-interface": "^0.4.0", + "@cloudbase/database": "0.9.11-rc.0", + "axios": "^0.19.1", + "cloudbase-adapter-wx_mp": "^0.1.0", + "crypto-js": "^3.1.9-1", + "fingerprintjs2": "^2.1.0", + "url": "^0.11.0" + } + }, "terser": { "version": "4.6.12", "resolved": "https://registry.npm.taobao.org/terser/download/terser-4.6.12.tgz?cache=0&sync_timestamp=1587902079221&other_urls=https%3A%2F%2Fregistry.npm.taobao.org%2Fterser%2Fdownload%2Fterser-4.6.12.tgz", diff --git a/package.json b/package.json index 750cab4..2b23484 100644 --- a/package.json +++ b/package.json @@ -8,7 +8,8 @@ "@testing-library/user-event": "^7.1.2", "react": "^16.13.1", "react-dom": "^16.13.1", - "react-scripts": "3.4.1" + "react-scripts": "3.4.1", + "tcb-js-sdk": "^1.6.1" }, "scripts": { "start": "react-scripts start", diff --git a/src/api/db.js b/src/api/db.js new file mode 100644 index 0000000..765d9ee --- /dev/null +++ b/src/api/db.js @@ -0,0 +1,37 @@ +import * as tcb from 'tcb-js-sdk'; + +const app = tcb.init({ + env: 'qrbtf-1d845d' +}); +const auth = app.auth(); + +async function login() { + await auth.signInAnonymously(); + const loginState = await auth.getLoginState() + console.log(loginState.isAnonymous); +} + +login(); + +const db = app.database(); +const _ = db.command +const counter = db.collection('QRCounter'); + +export function insert(value) { + counter.add({ + value: value, + count: 1 + }).then(res => { + console.log(res); + }) +} + +export function update(value) { + counter.where({ + value: _.eq(value) + }).update({ + count: _.inc(1) + }).then(res => { + console.log(res) + }) +} diff --git a/src/utils/downloader.js b/src/utils/downloader.js index b93b078..78af1d1 100644 --- a/src/utils/downloader.js +++ b/src/utils/downloader.js @@ -1,3 +1,5 @@ +import {insert, update} from "../api/db"; + const svgHead = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n " + "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n" @@ -5,21 +7,23 @@ export function isChrome() { return navigator.userAgent.toLowerCase().indexOf('chrome') > -1; } -export function saveSvg(filename, content) { +export function saveSvg(value, content) { let htmlContent = [svgHead + content] let bl = new Blob(htmlContent, {type: "image/svg+xml"}) let a = document.createElement("a") - filename = "QRcode_" + filename + ".svg" + let filename = "QRcode_" + value + ".svg" a.href = URL.createObjectURL(bl) a.download = filename a.hidden = true a.click() + + update(value) } -export function saveImg(filename, content, width, height) { +export function saveImg(value, content, width, height) { // Finish creating downloadable data - filename = "QRcode_" + filename + ".jpg"; + let filename = "QRcode_" + value + ".jpg"; const wrap = document.createElement('div'); wrap.innerHTML = content; @@ -56,6 +60,7 @@ export function saveImg(filename, content, width, height) { a.setAttribute('target', 'download') a.setAttribute('download', filename); a.click(); + update(value) }; img.setAttribute('src', 'data:image/svg+xml;base64,' + btoa(svgData)); From ad43a039aa633679d90602c160b2d7756be0a8b1 Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Fri, 8 May 2020 10:27:49 +0800 Subject: [PATCH 05/30] =?UTF-8?q?=E6=96=B0=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/QrRenderer25D.js | 102 ++++++++++++++++++++++++++++++ src/components/QrRendererImage.js | 2 +- src/components/Qrcode.js | 3 +- 3 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 src/components/QrRenderer25D.js diff --git a/src/components/QrRenderer25D.js b/src/components/QrRenderer25D.js new file mode 100644 index 0000000..ff56816 --- /dev/null +++ b/src/components/QrRenderer25D.js @@ -0,0 +1,102 @@ +import React from "react"; +import './Qrcode.css' +import {getTypeTable, QRPointType} from "../utils/qrcodeHandler"; +import {defaultRenderer, rand} from "../utils/util"; + +function listPoint(props) { + if (!props.qrcode) return [] + + const qrcode = props.qrcode; + const nCount = qrcode.getModuleCount(); + const typeTable = getTypeTable(qrcode); + const pointList = new Array(nCount); + + let type = props.params[0]; + let size = props.params[1] / 100; + let opacity = props.params[2] / 100; + let posType = props.params[3]; + let id = 0; + + const vw = [3, -3]; + const vh = [3, -3]; + + const X = [-Math.sqrt(3)/2, 1/2]; + const Y = [ Math.sqrt(3)/2, 1/2]; + const Z = [0, 0]; + + const matrixString = 'matrix(' + String(X[0]) + ', ' + String(X[1]) + ', ' + String(Y[0]) + ', ' + String(Y[1]) + ', ' + String(Z[0]) + ', ' + String(Z[1]) + ')' + + + if (size <= 0) size = 1.0 + + for (let x = 0; x < nCount; x++) { + for (let y = 0; y < nCount; y++) { + if (qrcode.isDark(x, y) == false) continue; + else if (typeTable[x][y] == QRPointType.POS_CENTER) { + if (posType == 0) { + pointList.push(<rect width={1} height={1} key={id++} fill="rgb(0,0,0)" x={x} y={y} transform={matrixString}/>); + pointList.push(<rect opacity={opacity} width={size/2} height={size} key={id++} fill="rgb(225,225,225)" x={0} y={0} transform={matrixString+'translate('+String(x+1)+','+String(y)+') '+'skewY(45) '}/>); + pointList.push(<rect opacity={opacity} width={size} height={size/2} key={id++} fill="rgb(240,240,240)" x={0} y={0} transform={matrixString+'translate('+String(x)+','+String(y+1)+') '+'skewX(45) '}/>); + } + } + else if (typeTable[x][y] == QRPointType.POS_OTHER) { + if (posType == 0) { + pointList.push(<rect width={1} height={1} key={id++} fill="rgb(0,0,0)" x={x} y={y} transform={matrixString}/>); + pointList.push(<rect opacity={opacity} width={size/2} height={size} key={id++} fill="rgb(225,225,225)" x={0} y={0} transform={matrixString+'translate('+String(x+1)+','+String(y)+') '+'skewY(45) '}/>); + pointList.push(<rect opacity={opacity} width={size} height={size/2} key={id++} fill="rgb(240,240,240)" x={0} y={0} transform={matrixString+'translate('+String(x)+','+String(y+1)+') '+'skewX(45) '}/>); + } + } + else { + if (type == 0) { + pointList.push(<rect opacity={opacity} width={size} height={size} key={id++} fill="rgb(0,0,0)" x={x + (1 - size)/2} y={y + (1 - size)/2} transform={matrixString}/>); + pointList.push(<rect opacity={opacity} width={size/2} height={size} key={id++} fill="rgb(210,210,210)" x={0} y={0} transform={matrixString+'translate('+String(x+1)+','+String(y)+') '+'skewY(45) '}/>); + pointList.push(<rect opacity={opacity} width={size} height={size/2} key={id++} fill="rgb(235,235,235)" x={0} y={0} transform={matrixString+'translate('+String(x)+','+String(y+1)+') '+'skewX(45) '}/>); + } + } + } + } + + return pointList; +} + +export default class QrRenderer25D extends React.Component { + constructor(props) { + super(props); + if (this.props.setParamInfo) { + this.props.setParamInfo([ + { + key: '信息点样式', + default: 0, + choices: [ + "矩形", + "圆形", + "随机" + ] + }, + { + key: '信息点缩放', + default: 100 + }, + { + key: '信息点不透明度', + default: 100, + }, + { + key: '定位点样式', + default: 0, + choices: [ + "矩形", + "圆形", + "行星", + ] + }, + ] + ); + } + } + + render() { + return defaultRenderer(this.props.qrcode, listPoint(this.props)); + } +} + diff --git a/src/components/QrRendererImage.js b/src/components/QrRendererImage.js index 4338876..c841282 100644 --- a/src/components/QrRendererImage.js +++ b/src/components/QrRendererImage.js @@ -117,7 +117,7 @@ export default class QrRendererImage extends React.Component { }, { key: '定位点样式', - default: 2, + default: 0, choices: [ "矩形", "圆形", diff --git a/src/components/Qrcode.js b/src/components/Qrcode.js index f6b8e0a..77e0d9b 100644 --- a/src/components/Qrcode.js +++ b/src/components/Qrcode.js @@ -16,6 +16,7 @@ import QrRendererRandRound from "./QrRendererRandRound"; import QrRendererBlank from "./QrRendererBlank"; import QrRendererRandRect from "./QrRendererRandRect"; import QrRendererDSJ from "./QrRendererDSJ"; +import QrRenderer25D from "./QrRenderer25D"; import QrRendererImage from "./QrRendererImage"; const logoStyle = { @@ -30,8 +31,8 @@ const styleList = [ {value: "A3", renderer: QrRendererRandRound}, {value: "SP — 1", renderer: QrRendererDSJ}, {value: "SP — 2", renderer: QrRendererRandRect}, + {value: "D1", renderer: QrRenderer25D}, {value: "C1", renderer: QrRendererImage}, - {value: "D1", renderer: QrRendererBlank}, {value: "D2", renderer: QrRendererBlank}, ]; From f235315bc3af2d15d0538290909ea407c8271ed5 Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Fri, 8 May 2020 12:47:23 +0800 Subject: [PATCH 06/30] =?UTF-8?q?=E6=96=B0=E6=A0=B7=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/QrRenderer25D.js | 9 +++++++-- src/components/QrRendererBase.js | 9 +++++++-- src/components/QrRendererBlank.js | 8 ++++++-- src/components/QrRendererDSJ.js | 9 +++++++-- src/components/QrRendererImage.js | 9 +++++++-- src/components/QrRendererRandRect.js | 9 +++++++-- src/components/QrRendererRandRound.js | 9 +++++++-- src/components/QrRendererRound.js | 9 +++++++-- src/utils/util.js | 8 -------- 9 files changed, 55 insertions(+), 24 deletions(-) diff --git a/src/components/QrRenderer25D.js b/src/components/QrRenderer25D.js index ff56816..fd8bfdb 100644 --- a/src/components/QrRenderer25D.js +++ b/src/components/QrRenderer25D.js @@ -1,7 +1,7 @@ import React from "react"; import './Qrcode.css' import {getTypeTable, QRPointType} from "../utils/qrcodeHandler"; -import {defaultRenderer, rand} from "../utils/util"; +import {defaultRenderer, defaultViewBox, rand} from "../utils/util"; function listPoint(props) { if (!props.qrcode) return [] @@ -96,7 +96,12 @@ export default class QrRenderer25D extends React.Component { } render() { - return defaultRenderer(this.props.qrcode, listPoint(this.props)); + return ( + <svg className="Qr-item-svg" width="100%" height="100%" viewBox={defaultViewBox(this.props.qrcode)} fill="white" + xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink"> + {listPoint(this.props)} + </svg> + ); } } diff --git a/src/components/QrRendererBase.js b/src/components/QrRendererBase.js index 34ab950..3c3e103 100644 --- a/src/components/QrRendererBase.js +++ b/src/components/QrRendererBase.js @@ -1,7 +1,7 @@ import React from "react"; import './Qrcode.css' import {getTypeTable, QRPointType} from "../utils/qrcodeHandler"; -import {defaultRenderer, rand} from "../utils/util"; +import {defaultRenderer, defaultViewBox, rand} from "../utils/util"; function listPoint(props) { if (!props.qrcode) return [] @@ -107,7 +107,12 @@ export default class QrRendererBase extends React.Component { } render() { - return defaultRenderer(this.props.qrcode, listPoint(this.props)); + return ( + <svg className="Qr-item-svg" width="100%" height="100%" viewBox={defaultViewBox(this.props.qrcode)} fill="white" + xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink"> + {listPoint(this.props)} + </svg> + ); } } diff --git a/src/components/QrRendererBlank.js b/src/components/QrRendererBlank.js index be3c819..77fce98 100644 --- a/src/components/QrRendererBlank.js +++ b/src/components/QrRendererBlank.js @@ -1,10 +1,14 @@ import React from "react"; import './Qrcode.css' -import {defaultRenderer} from "../utils/util"; +import {defaultViewBox} from "../utils/util"; export default class QrRendererBlank extends React.Component { render() { - return defaultRenderer(this.props.qrcode); + return ( + <svg className="Qr-item-svg" width="100%" height="100%" viewBox={defaultViewBox(this.props.qrcode)} fill="white" + xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink"> + </svg> + ); } } diff --git a/src/components/QrRendererDSJ.js b/src/components/QrRendererDSJ.js index c3f2259..337566f 100644 --- a/src/components/QrRendererDSJ.js +++ b/src/components/QrRendererDSJ.js @@ -1,7 +1,7 @@ import React from "react"; import './Qrcode.css' import {getTypeTable, QRPointType} from "../utils/qrcodeHandler"; -import {defaultRenderer, rand} from "../utils/util"; +import {defaultRenderer, defaultViewBox, rand} from "../utils/util"; function listPoint(props) { if (!props.qrcode) return [] @@ -186,7 +186,12 @@ export default class QrRendererDSJ extends React.Component { } render() { - return defaultRenderer(this.props.qrcode, listPoint(this.props)); + return ( + <svg className="Qr-item-svg" width="100%" height="100%" viewBox={defaultViewBox(this.props.qrcode)} fill="white" + xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink"> + {listPoint(this.props)} + </svg> + ); } } diff --git a/src/components/QrRendererImage.js b/src/components/QrRendererImage.js index c841282..f00195b 100644 --- a/src/components/QrRendererImage.js +++ b/src/components/QrRendererImage.js @@ -1,7 +1,7 @@ import React from "react"; import './Qrcode.css' import {getTypeTable, QRPointType} from "../utils/qrcodeHandler"; -import {defaultRenderer} from "../utils/util"; +import {defaultRenderer, defaultViewBox} from "../utils/util"; function listPoint(props) { if (!props.qrcode) return [] @@ -130,7 +130,12 @@ export default class QrRendererImage extends React.Component { } render() { - return defaultRenderer(this.props.qrcode, listPoint(this.props)); + return ( + <svg className="Qr-item-svg" width="100%" height="100%" viewBox={defaultViewBox(this.props.qrcode)} fill="white" + xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink"> + {listPoint(this.props)} + </svg> + ); } } diff --git a/src/components/QrRendererRandRect.js b/src/components/QrRendererRandRect.js index fcf78fd..a6cd774 100644 --- a/src/components/QrRendererRandRect.js +++ b/src/components/QrRendererRandRect.js @@ -1,6 +1,6 @@ import React from "react"; import './Qrcode.css' -import {defaultRenderer, rand} from "../utils/util"; +import {defaultRenderer, defaultViewBox, rand} from "../utils/util"; function listPoint(props) { if (!props.qrcode) return [] @@ -40,7 +40,12 @@ function listPoint(props) { export default class QrRendererRandRect extends React.Component { render() { - return defaultRenderer(this.props.qrcode, listPoint(this.props)); + return ( + <svg className="Qr-item-svg" width="100%" height="100%" viewBox={defaultViewBox(this.props.qrcode)} fill="white" + xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink"> + {listPoint(this.props)} + </svg> + ); } } diff --git a/src/components/QrRendererRandRound.js b/src/components/QrRendererRandRound.js index 109122f..b581b6b 100644 --- a/src/components/QrRendererRandRound.js +++ b/src/components/QrRendererRandRound.js @@ -1,7 +1,7 @@ import React from "react"; import './Qrcode.css' import {getTypeTable, QRPointType} from "../utils/qrcodeHandler"; -import {rand, defaultRenderer} from "../utils/util"; +import {rand, defaultRenderer, defaultViewBox} from "../utils/util"; function listPoint(props) { if (!props.qrcode) return [] @@ -107,7 +107,12 @@ export default class QrRendererRandRound extends React.Component { } render() { - return defaultRenderer(this.props.qrcode, listPoint(this.props)); + return ( + <svg className="Qr-item-svg" width="100%" height="100%" viewBox={defaultViewBox(this.props.qrcode)} fill="white" + xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink"> + {listPoint(this.props)} + </svg> + ); } } diff --git a/src/components/QrRendererRound.js b/src/components/QrRendererRound.js index cf1762b..d23f7f1 100644 --- a/src/components/QrRendererRound.js +++ b/src/components/QrRendererRound.js @@ -1,7 +1,7 @@ import React from "react"; import './Qrcode.css' import {getTypeTable, QRPointType} from "../utils/qrcodeHandler"; -import {defaultRenderer, rand} from "../utils/util"; +import {defaultRenderer, defaultViewBox, rand} from "../utils/util"; function listPoint(props) { if (!props.qrcode) return [] @@ -107,7 +107,12 @@ export default class QrRendererRound extends React.Component { } render() { - return defaultRenderer(this.props.qrcode, listPoint(this.props)); + return ( + <svg className="Qr-item-svg" width="100%" height="100%" viewBox={defaultViewBox(this.props.qrcode)} fill="white" + xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink"> + {listPoint(this.props)} + </svg> + ); } } diff --git a/src/utils/util.js b/src/utils/util.js index 5c6ab47..a79d532 100644 --- a/src/utils/util.js +++ b/src/utils/util.js @@ -22,14 +22,6 @@ export function defaultViewBox(qrcode) { return String(-nCount / 5) + ' ' + String(-nCount / 5) + ' ' + String(nCount + nCount / 5 * 2) + ' ' + String(nCount + nCount / 5 * 2); } -export function defaultRenderer(qrcode, points) { - return ( - <svg className="Qr-item-svg" width="100%" height="100%" viewBox={defaultViewBox(qrcode)} fill="white" - xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink"> - {points} - </svg> - ); -} export function isWeiXin(){ const ua = window.navigator.userAgent.toLowerCase(); From f9a58fb4aa07006fb0fc2618d8d46fe350ee2f33 Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Fri, 8 May 2020 14:52:53 +0800 Subject: [PATCH 07/30] =?UTF-8?q?=E6=9B=B4=E6=96=B0=E6=96=B0=E6=A0=B7?= =?UTF-8?q?=E5=BC=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/QrRenderer25D.js | 72 ++++++++++++--------------------- src/components/Qrcode.css | 3 ++ 2 files changed, 28 insertions(+), 47 deletions(-) diff --git a/src/components/QrRenderer25D.js b/src/components/QrRenderer25D.js index fd8bfdb..d8057a2 100644 --- a/src/components/QrRenderer25D.js +++ b/src/components/QrRenderer25D.js @@ -11,10 +11,10 @@ function listPoint(props) { const typeTable = getTypeTable(qrcode); const pointList = new Array(nCount); - let type = props.params[0]; - let size = props.params[1] / 100; - let opacity = props.params[2] / 100; - let posType = props.params[3]; + let size = 1.03; + let size2 = 1.03; + let height = props.params[0]; + let height2 = props.params[1]; let id = 0; const vw = [3, -3]; @@ -26,32 +26,21 @@ function listPoint(props) { const matrixString = 'matrix(' + String(X[0]) + ', ' + String(X[1]) + ', ' + String(Y[0]) + ', ' + String(Y[1]) + ', ' + String(Z[0]) + ', ' + String(Z[1]) + ')' - - if (size <= 0) size = 1.0 + if (height <= 0) height = 1.0; + if (height2 <= 0) height2 = 1.0; for (let x = 0; x < nCount; x++) { for (let y = 0; y < nCount; y++) { if (qrcode.isDark(x, y) == false) continue; - else if (typeTable[x][y] == QRPointType.POS_CENTER) { - if (posType == 0) { - pointList.push(<rect width={1} height={1} key={id++} fill="rgb(0,0,0)" x={x} y={y} transform={matrixString}/>); - pointList.push(<rect opacity={opacity} width={size/2} height={size} key={id++} fill="rgb(225,225,225)" x={0} y={0} transform={matrixString+'translate('+String(x+1)+','+String(y)+') '+'skewY(45) '}/>); - pointList.push(<rect opacity={opacity} width={size} height={size/2} key={id++} fill="rgb(240,240,240)" x={0} y={0} transform={matrixString+'translate('+String(x)+','+String(y+1)+') '+'skewX(45) '}/>); - } - } - else if (typeTable[x][y] == QRPointType.POS_OTHER) { - if (posType == 0) { - pointList.push(<rect width={1} height={1} key={id++} fill="rgb(0,0,0)" x={x} y={y} transform={matrixString}/>); - pointList.push(<rect opacity={opacity} width={size/2} height={size} key={id++} fill="rgb(225,225,225)" x={0} y={0} transform={matrixString+'translate('+String(x+1)+','+String(y)+') '+'skewY(45) '}/>); - pointList.push(<rect opacity={opacity} width={size} height={size/2} key={id++} fill="rgb(240,240,240)" x={0} y={0} transform={matrixString+'translate('+String(x)+','+String(y+1)+') '+'skewX(45) '}/>); - } + else if (typeTable[x][y] == QRPointType.POS_OTHER || typeTable[x][y] == QRPointType.POS_CENTER) { + pointList.push(<rect width={size2} height={size2} key={id++} fill="#FF7F89" x={x + (1 - size2)/2} y={y + (1 - size2)/2} transform={matrixString}/>); + pointList.push(<rect width={height2} height={size2} key={id++} fill="#FFEBF3" x={0} y={0} transform={matrixString+'translate('+String(x + (1 - size2)/2 + size2)+','+String(y + (1 - size2)/2)+') '+'skewY(45) '}/>); + pointList.push(<rect width={size2} height={height2} key={id++} fill="#FFD7D9" x={0} y={0} transform={matrixString+'translate('+String(x + (1 - size2)/2)+','+String(y + size2 + (1 - size2)/2)+') '+'skewX(45) '}/>); } else { - if (type == 0) { - pointList.push(<rect opacity={opacity} width={size} height={size} key={id++} fill="rgb(0,0,0)" x={x + (1 - size)/2} y={y + (1 - size)/2} transform={matrixString}/>); - pointList.push(<rect opacity={opacity} width={size/2} height={size} key={id++} fill="rgb(210,210,210)" x={0} y={0} transform={matrixString+'translate('+String(x+1)+','+String(y)+') '+'skewY(45) '}/>); - pointList.push(<rect opacity={opacity} width={size} height={size/2} key={id++} fill="rgb(235,235,235)" x={0} y={0} transform={matrixString+'translate('+String(x)+','+String(y+1)+') '+'skewX(45) '}/>); - } + pointList.push(<rect width={size} height={size} key={id++} fill="#FF7F89" x={x + (1 - size)/2} y={y + (1 - size)/2} transform={matrixString}/>); + pointList.push(<rect width={height} height={size} key={id++} fill="#FFEBF3" x={0} y={0} transform={matrixString+'translate('+String(x + (1 - size)/2 + size)+','+String(y + (1 - size)/2)+') '+'skewY(45) '}/>); + pointList.push(<rect width={size} height={height} key={id++} fill="#FFD7D9" x={0} y={0} transform={matrixString+'translate('+String(x + (1 - size)/2)+','+String(y + size + (1 - size)/2)+') '+'skewX(45) '}/>); } } } @@ -59,36 +48,25 @@ function listPoint(props) { return pointList; } +function viewBox(qrcode) { + if (!qrcode) return '0 0 0 0'; + + const nCount = qrcode.getModuleCount(); + return String(-nCount) + ' ' + String(-nCount / 2) + ' ' + String(nCount * 2) + ' ' + String(nCount * 2); +} + export default class QrRenderer25D extends React.Component { constructor(props) { super(props); if (this.props.setParamInfo) { this.props.setParamInfo([ { - key: '信息点样式', - default: 0, - choices: [ - "矩形", - "圆形", - "随机" - ] + key: '柱体高度', + default: 1 }, { - key: '信息点缩放', - default: 100 - }, - { - key: '信息点不透明度', - default: 100, - }, - { - key: '定位点样式', - default: 0, - choices: [ - "矩形", - "圆形", - "行星", - ] + key: '定位点柱体高度', + default: 1, }, ] ); @@ -97,7 +75,7 @@ export default class QrRenderer25D extends React.Component { render() { return ( - <svg className="Qr-item-svg" width="100%" height="100%" viewBox={defaultViewBox(this.props.qrcode)} fill="white" + <svg className="Qr-item-svg" width="100%" height="100%" viewBox={viewBox(this.props.qrcode)} fill="white" xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink"> {listPoint(this.props)} </svg> diff --git a/src/components/Qrcode.css b/src/components/Qrcode.css index c726719..17bb110 100644 --- a/src/components/Qrcode.css +++ b/src/components/Qrcode.css @@ -84,6 +84,8 @@ .Qr-item-image { /*padding: 23px;*/ + overflow: auto; + display: flex; background-color: white; width: calc((100vw - 56px) / 2); height: calc((100vw - 56px) / 2); @@ -105,6 +107,7 @@ } .Qr-item-image-inner { + justify-content: center; -webkit-transition-timing-function: ease-in-out; -moz-transition-timing-function: ease-in-out; transition-timing-function: ease-in-out; From a9c76d5972c0e90e51e03dc6adcaa5b838d08c7b Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Fri, 8 May 2020 15:35:08 +0800 Subject: [PATCH 08/30] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E4=B8=8A=E4=B8=8B?= =?UTF-8?q?=E6=BB=91=E5=8A=A8=20bug?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Qrcode.css | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Qrcode.css b/src/components/Qrcode.css index 17bb110..7e5c9c5 100644 --- a/src/components/Qrcode.css +++ b/src/components/Qrcode.css @@ -84,7 +84,7 @@ .Qr-item-image { /*padding: 23px;*/ - overflow: auto; + overflow: hidden; display: flex; background-color: white; width: calc((100vw - 56px) / 2); From 5b9a0fb55e630416f9464af6637b1d8ed841452f Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Fri, 8 May 2020 15:48:23 +0800 Subject: [PATCH 09/30] =?UTF-8?q?=E8=81=94=E7=B3=BB=E6=96=B9=E5=BC=8F?= =?UTF-8?q?=E6=9B=B4=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Footer.js | 2 +- src/components/Qrcode.js | 10 ++++++---- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/components/Footer.js b/src/components/Footer.js index 69e2ed8..c761d50 100644 --- a/src/components/Footer.js +++ b/src/components/Footer.js @@ -8,7 +8,7 @@ class Footer extends React.Component { return ( <div className="Qr-titled"> <div className="Qr-Centered Qr-footer note-font"> - <div><strong>作者</strong> <a href="https://blog.ciaochaos.com/" rel="noopener noreferrer" target="_blank">ciaochaos</a> <a href="https://github.com/CPunisher/" rel="noopener noreferrer" target="_blank">CPunisher</a></div> + <div><strong>作者</strong> <a href="https://blog.ciaochaos.com/" rel="noopener noreferrer" target="_blank">ciaochaos</a> <a href="https://github.com/CPunisher/" rel="noopener noreferrer" target="_blank">CPunisher</a> 丨 <a href="https://www.yuque.com/qrbtf/docs/contact" rel="noopener noreferrer" target="_blank">联系我们</a></div> <div className="Gray">Copyright © {currentYear} QRBTF. 保留所有权利。</div> <div className="Gray"><a href="http://www.beian.miit.gov.cn/" rel="noopener noreferrer" target="_blank">浙 ICP 备 19005869 号 </a></div> </div> diff --git a/src/components/Qrcode.js b/src/components/Qrcode.js index 77e0d9b..1b6357b 100644 --- a/src/components/Qrcode.js +++ b/src/components/Qrcode.js @@ -246,15 +246,17 @@ class Qrcode extends React.Component { </div> <div className="Qr-Centered btn-row"> <div className="div-btn"> - <a href="https://www.yuque.com/qrbtf/docs" rel="noopener noreferrer" target="_blank"> - <button className="dl-btn">使用手册</button> - </a> <a href="https://www.yuque.com/qrbtf/topics" rel="noopener noreferrer" target="_blank"> <button className="dl-btn">问题反馈</button> </a> + <a href="https://www.yuque.com/qrbtf/docs/dev" rel="noopener noreferrer" target="_blank"> + <button className="dl-btn">开发与设计</button> + </a> </div> <div className="div-btn"> - <button disabled className="dl-btn">提交样式</button> + <a href="https://www.yuque.com/qrbtf/docs/coop" rel="noopener noreferrer" target="_blank"> + <button className="dl-btn">商业合作</button> + </a> </div> </div> </div> From 5dc5c80460513fa61ed2a293d464ece60da4c763 Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Fri, 8 May 2020 16:08:17 +0800 Subject: [PATCH 10/30] download data record --- src/api/db.js | 31 ++++++++++++++++++------------- 1 file changed, 18 insertions(+), 13 deletions(-) diff --git a/src/api/db.js b/src/api/db.js index 765d9ee..d617d55 100644 --- a/src/api/db.js +++ b/src/api/db.js @@ -17,21 +17,26 @@ const db = app.database(); const _ = db.command const counter = db.collection('QRCounter'); -export function insert(value) { - counter.add({ - value: value, - count: 1 - }).then(res => { - console.log(res); - }) -} - export function update(value) { counter.where({ value: _.eq(value) - }).update({ - count: _.inc(1) - }).then(res => { - console.log(res) + }).get().then(res => { + if (res.data.length > 0) { + counter.where({ + value: _.eq(value) + }).update({ + count: _.inc(1) + }).then(res => { + console.log(res) + }) + } + else { + counter.add({ + value: value, + count: 1 + }).then(res => { + console.log(res) + }) + } }) } From e1c472961fc3a7674aea20b035025c623d2be1cb Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Fri, 8 May 2020 16:40:56 +0800 Subject: [PATCH 11/30] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=89=88=E7=9B=B8?= =?UTF-8?q?=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Qrcode.js | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/components/Qrcode.js b/src/components/Qrcode.js index 1b6357b..c451fc7 100644 --- a/src/components/Qrcode.js +++ b/src/components/Qrcode.js @@ -157,7 +157,7 @@ class Qrcode extends React.Component { <div style={logoStyle}> <h1 className="Qr-title"> </h1> </div> - <p className="Qr-subtitle">参数化二维码生成器</p> + <p className="Qr-subtitle">参数化二维码生成器 <sup>测试版</sup></p> <input className="Qr-input big-input" placeholder="Input your URL here" @@ -214,7 +214,7 @@ class Qrcode extends React.Component { }}> <option value={1}>7%</option> <option value={0}>15%</option> - <option value={3}>20%</option> + <option value={3}>25%</option> <option value={2}>30%</option> </select> </td> @@ -246,14 +246,17 @@ class Qrcode extends React.Component { </div> <div className="Qr-Centered btn-row"> <div className="div-btn"> + <a href="https://www.yuque.com/qrbtf/docs/donate" rel="noopener noreferrer" target="_blank"> + <button className="dl-btn">打赏 & 赞助</button> + </a> <a href="https://www.yuque.com/qrbtf/topics" rel="noopener noreferrer" target="_blank"> <button className="dl-btn">问题反馈</button> </a> - <a href="https://www.yuque.com/qrbtf/docs/dev" rel="noopener noreferrer" target="_blank"> - <button className="dl-btn">开发与设计</button> - </a> </div> <div className="div-btn"> + <a href="https://www.yuque.com/qrbtf/docs/dev" rel="noopener noreferrer" target="_blank"> + <button className="dl-btn">开发与设计</button> + </a> <a href="https://www.yuque.com/qrbtf/docs/coop" rel="noopener noreferrer" target="_blank"> <button className="dl-btn">商业合作</button> </a> From e01bbb79fb5d66e69846c20cfdc3d69d4306340e Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Fri, 8 May 2020 16:42:46 +0800 Subject: [PATCH 12/30] =?UTF-8?q?=E6=B5=8B=E8=AF=95=E7=89=88=E7=9B=B8?= =?UTF-8?q?=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/QrRenderer25D.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/QrRenderer25D.js b/src/components/QrRenderer25D.js index d8057a2..dd29d11 100644 --- a/src/components/QrRenderer25D.js +++ b/src/components/QrRenderer25D.js @@ -62,11 +62,11 @@ export default class QrRenderer25D extends React.Component { this.props.setParamInfo([ { key: '柱体高度', - default: 1 + default: 0.5, }, { key: '定位点柱体高度', - default: 1, + default: 0.5, }, ] ); From e3bd0d3190de8160dc2cc45c41b417e41aba45c5 Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Fri, 8 May 2020 16:44:52 +0800 Subject: [PATCH 13/30] =?UTF-8?q?=E6=A0=B7=E5=BC=8F=E5=90=8D=E8=B0=83?= =?UTF-8?q?=E6=95=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Qrcode.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Qrcode.js b/src/components/Qrcode.js index c451fc7..5d08744 100644 --- a/src/components/Qrcode.js +++ b/src/components/Qrcode.js @@ -31,9 +31,9 @@ const styleList = [ {value: "A3", renderer: QrRendererRandRound}, {value: "SP — 1", renderer: QrRendererDSJ}, {value: "SP — 2", renderer: QrRendererRandRect}, - {value: "D1", renderer: QrRenderer25D}, + {value: "B1", renderer: QrRenderer25D}, {value: "C1", renderer: QrRendererImage}, - {value: "D2", renderer: QrRendererBlank}, + {value: "D1", renderer: QrRendererBlank}, ]; From 417ccd08c83ec16df12cc27a4ef98ac4da785736 Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Fri, 8 May 2020 16:46:40 +0800 Subject: [PATCH 14/30] =?UTF-8?q?=E6=96=87=E5=AD=97=E5=BE=AE=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Qrcode.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Qrcode.js b/src/components/Qrcode.js index 5d08744..1334722 100644 --- a/src/components/Qrcode.js +++ b/src/components/Qrcode.js @@ -255,7 +255,7 @@ class Qrcode extends React.Component { </div> <div className="div-btn"> <a href="https://www.yuque.com/qrbtf/docs/dev" rel="noopener noreferrer" target="_blank"> - <button className="dl-btn">开发与设计</button> + <button className="dl-btn">开发 & 设计</button> </a> <a href="https://www.yuque.com/qrbtf/docs/coop" rel="noopener noreferrer" target="_blank"> <button className="dl-btn">商业合作</button> From 2ac7b63ba11207e35d1b3738431681cad645013e Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Fri, 8 May 2020 16:54:21 +0800 Subject: [PATCH 15/30] =?UTF-8?q?=E6=96=87=E5=AD=97=E5=BE=AE=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Qrcode.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/Qrcode.js b/src/components/Qrcode.js index 1334722..8ca9d28 100644 --- a/src/components/Qrcode.js +++ b/src/components/Qrcode.js @@ -157,7 +157,7 @@ class Qrcode extends React.Component { <div style={logoStyle}> <h1 className="Qr-title"> </h1> </div> - <p className="Qr-subtitle">参数化二维码生成器 <sup>测试版</sup></p> + <p className="Qr-subtitle">参数化二维码生成器 <sup className="note-font">测试版</sup></p> <input className="Qr-input big-input" placeholder="Input your URL here" From 1cee37fb9fbc45e13333fce2f5b39ccf1d68f529 Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Fri, 8 May 2020 17:00:44 +0800 Subject: [PATCH 16/30] =?UTF-8?q?=E6=96=87=E5=AD=97=E5=BE=AE=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/Qrcode.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/Qrcode.js b/src/components/Qrcode.js index 8ca9d28..9804cdf 100644 --- a/src/components/Qrcode.js +++ b/src/components/Qrcode.js @@ -157,7 +157,7 @@ class Qrcode extends React.Component { <div style={logoStyle}> <h1 className="Qr-title"> </h1> </div> - <p className="Qr-subtitle">参数化二维码生成器 <sup className="note-font">测试版</sup></p> + <p className="Qr-subtitle">参数化二维码生成器 <sup className="Gray">测试版</sup></p> <input className="Qr-input big-input" placeholder="Input your URL here" @@ -255,7 +255,7 @@ class Qrcode extends React.Component { </div> <div className="div-btn"> <a href="https://www.yuque.com/qrbtf/docs/dev" rel="noopener noreferrer" target="_blank"> - <button className="dl-btn">开发 & 设计</button> + <button className="dl-btn">开发与设计</button> </a> <a href="https://www.yuque.com/qrbtf/docs/coop" rel="noopener noreferrer" target="_blank"> <button className="dl-btn">商业合作</button> From 425aabde1e79064924079cc7f62e6fe57ff827c2 Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Fri, 8 May 2020 17:33:38 +0800 Subject: [PATCH 17/30] =?UTF-8?q?Google=20Analyst=20=E6=94=AF=E6=8C=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/index.html | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/public/index.html b/public/index.html index 6b5bd12..351abc4 100644 --- a/public/index.html +++ b/public/index.html @@ -1,6 +1,16 @@ <!DOCTYPE html> <html lang="zh"> <head> + <!-- Global site tag (gtag.js) - Google Analytics --> + <script async src="https://www.googletagmanager.com/gtag/js?id=UA-165845289-1"></script> + <script> + window.dataLayer = window.dataLayer || []; + function gtag(){dataLayer.push(arguments);} + gtag('js', new Date()); + + gtag('config', 'UA-165845289-1'); + </script> + <meta charset="utf-8" /> <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> <!--<meta name="viewport" content="width=device-width, initial-scale=1" />--> From 7f578a749eb2693b35528d4853bee7b8b7c3134a Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Fri, 8 May 2020 17:36:18 +0800 Subject: [PATCH 18/30] =?UTF-8?q?Baidu=20=E6=8F=90=E4=BA=A4=E9=93=BE?= =?UTF-8?q?=E6=8E=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/index.html | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/public/index.html b/public/index.html index 351abc4..7d53dfc 100644 --- a/public/index.html +++ b/public/index.html @@ -10,6 +10,20 @@ gtag('config', 'UA-165845289-1'); </script> + <script> + (function(){ + var bp = document.createElement('script'); + var curProtocol = window.location.protocol.split(':')[0]; + if (curProtocol === 'https') { + bp.src = 'https://zz.bdstatic.com/linksubmit/push.js'; + } + else { + bp.src = 'http://push.zhanzhang.baidu.com/push.js'; + } + var s = document.getElementsByTagName("script")[0]; + s.parentNode.insertBefore(bp, s); + })(); + </script> <meta charset="utf-8" /> <link rel="icon" href="%PUBLIC_URL%/favicon.ico" /> From 10e2968312afc55efb38e6068e0002171942e549 Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Fri, 8 May 2020 17:42:43 +0800 Subject: [PATCH 19/30] =?UTF-8?q?meta=20=E4=BF=A1=E6=81=AF=E6=9B=B4?= =?UTF-8?q?=E6=94=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- public/index.html | 25 +------------------------ 1 file changed, 1 insertion(+), 24 deletions(-) diff --git a/public/index.html b/public/index.html index 7d53dfc..8b9691d 100644 --- a/public/index.html +++ b/public/index.html @@ -32,37 +32,14 @@ <meta name="viewport" content="width=device-width, height=device-height, initial-scale=1.0, maximum-scale=1.0, user-scalable=no"> <meta name="theme-color" content="#000000" /> <meta name="description" - content="Web site created using create-react-app" + content="QRBTF 参数化二维码生成器 Parametric QR Code Generator" /> <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" /> - <!-- - manifest.json provides metadata used when your web app is installed on a - user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/ - --> <link rel="manifest" href="%PUBLIC_URL%/manifest.json" /> - <!-- - Notice the use of %PUBLIC_URL% in the tags above. - It will be replaced with the URL of the `public` folder during the build. - Only files inside the `public` folder can be referenced from the HTML. - - Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will - work correctly both with client-side routing and a non-root public URL. - Learn how to configure a non-root public URL by running `npm run build`. - --> <title>QRBTF 参数化二维码生成器</title> </head> <body> <noscript>You need to enable JavaScript to run this app.</noscript> <div id="root"></div> - <!-- - This HTML file is a template. - If you open it directly in the browser, you will see an empty page. - - You can add webfonts, meta tags, or analytics to this file. - The build step will place the bundled scripts into the <body> tag. - - To begin the development, run `npm start` or `yarn start`. - To create a production bundle, use `npm run build` or `yarn build`. - --> </body> </html> From 1764949de4e9295a7d03250a4d3b96cc40b1e70c Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Fri, 8 May 2020 18:15:14 +0800 Subject: [PATCH 20/30] =?UTF-8?q?25D=20=E6=A0=B7=E5=BC=8F=E5=BE=AE?= =?UTF-8?q?=E8=B0=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/components/QrRenderer25D.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/QrRenderer25D.js b/src/components/QrRenderer25D.js index dd29d11..ee19afb 100644 --- a/src/components/QrRenderer25D.js +++ b/src/components/QrRenderer25D.js @@ -11,8 +11,8 @@ function listPoint(props) { const typeTable = getTypeTable(qrcode); const pointList = new Array(nCount); - let size = 1.03; - let size2 = 1.03; + let size = 1.001; + let size2 = 1.001; let height = props.params[0]; let height2 = props.params[1]; let id = 0; From f584e4795295aa083b81c5d1e9116ad389cacd0f Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Sat, 9 May 2020 00:34:31 +0800 Subject: [PATCH 21/30] [Record more data] --- src/api/db.js | 28 ++++++++++++++++++------ src/components/Qrcode.js | 46 ++++++++++++++++++++++++++++++++++------ src/utils/downloader.js | 7 +++--- 3 files changed, 65 insertions(+), 16 deletions(-) diff --git a/src/api/db.js b/src/api/db.js index d617d55..5479d09 100644 --- a/src/api/db.js +++ b/src/api/db.js @@ -15,28 +15,42 @@ login(); const db = app.database(); const _ = db.command -const counter = db.collection('QRCounter'); -export function update(value) { - counter.where({ +export function increaseDownloadData(value, date) { + db.collection('QRCounter').where({ value: _.eq(value) }).get().then(res => { if (res.data.length > 0) { - counter.where({ + db.collection('QRCounter').where({ value: _.eq(value) }).update({ - count: _.inc(1) + count: _.inc(1), + date: date }).then(res => { console.log(res) }) } else { - counter.add({ + db.collection('QRCounter').add({ value: value, - count: 1 + count: 1, + date: date }).then(res => { console.log(res) }) } }) } + +export function recordDownloadDetail({text, value, type, params, history}) { + db.collection('QRDownloadData').add({ + date: new Date().toString(), + text: text, + value: value, + type: type, + params: params, + history: history + }).then(res => { + console.log(res) + }) +} diff --git a/src/components/Qrcode.js b/src/components/Qrcode.js index 9804cdf..0795dd5 100644 --- a/src/components/Qrcode.js +++ b/src/components/Qrcode.js @@ -18,6 +18,7 @@ import QrRendererRandRect from "./QrRendererRandRect"; import QrRendererDSJ from "./QrRendererDSJ"; import QrRenderer25D from "./QrRenderer25D"; import QrRendererImage from "./QrRendererImage"; +import {recordDownloadDetail} from "../api/db"; const logoStyle = { background: `url(${logo})`, @@ -49,7 +50,8 @@ class Qrcode extends React.Component { qrcode: null, paramInfo: [], paramValue: [], - correctLevel: 0 + correctLevel: 0, + history: [] }; this.paramInfoBuffer = new Array(16).fill(new Array(16)); this.paramValueBuffer = new Array(16).fill(new Array(16)); @@ -90,15 +92,41 @@ class Qrcode extends React.Component { } downloadSvg = (e) => { - const style = styleList[this.state.selectedIndex] - const el = React.createElement(style.renderer, {qrcode: this.state.qrcode, params: this.state.paramValue[this.state.selectedIndex]}) + const selected = this.state.selectedIndex + const style = styleList[selected] + const el = React.createElement(style.renderer, {qrcode: this.state.qrcode, params: this.state.paramValue[selected]}) saveSvg(style.value, ReactDOMServer.renderToString(el)) + recordDownloadDetail({ + text: this.state.text, + value: styleList[selected], + type: 'svg', + params: this.state.paramInfo[selected].map((item, index) => { + return { + key: item.key, + value: item.choices ? item.choices[this.state.paramValue[selected][index]] : this.state.paramValue[selected][index] + } + }), + history: this.state.history + }); } downloadImg = (e) => { - const style = styleList[this.state.selectedIndex] - const el = React.createElement(style.renderer, {qrcode: this.state.qrcode, params: this.state.paramValue[this.state.selectedIndex]}) + const selected = this.state.selectedIndex + const style = styleList[selected] + const el = React.createElement(style.renderer, {qrcode: this.state.qrcode, params: this.state.paramValue[selected]}) saveImg(style.value, ReactDOMServer.renderToString(el), 1500, 1500) + recordDownloadDetail({ + text: this.state.text, + value: styleList[selected], + type: 'jpg', + params: this.state.paramInfo[selected].map((item, index) => { + return { + key: item.key, + value: item.choices ? item.choices[this.state.paramValue[selected][index]] : this.state.paramValue[selected][index] + } + }), + history: this.state.history + }); } renderParamEditor = (info, index) => { @@ -150,6 +178,12 @@ class Qrcode extends React.Component { } } + changeStyle = (index) => { + const newHistory = this.state.history.slice(); + newHistory.push(styleList[index].value); + this.setState({selectedIndex: index, history: newHistory}) + } + render() { return ( <div className="Qr-outer"> @@ -187,7 +221,7 @@ class Qrcode extends React.Component { })} text={this.state.text} selected={index == this.state.selectedIndex} - onSelected={() => this.setState({selectedIndex: index})} + onSelected={this.changeStyle} /> }) } diff --git a/src/utils/downloader.js b/src/utils/downloader.js index 78af1d1..75a0548 100644 --- a/src/utils/downloader.js +++ b/src/utils/downloader.js @@ -1,4 +1,4 @@ -import {insert, update} from "../api/db"; +import {increaseDownloadData} from "../api/db"; const svgHead = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n " + "<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 20010904//EN\" \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n" @@ -18,7 +18,7 @@ export function saveSvg(value, content) { a.hidden = true a.click() - update(value) + increaseDownloadData(value, new Date().toString()) } export function saveImg(value, content, width, height) { @@ -60,8 +60,9 @@ export function saveImg(value, content, width, height) { a.setAttribute('target', 'download') a.setAttribute('download', filename); a.click(); - update(value) }; img.setAttribute('src', 'data:image/svg+xml;base64,' + btoa(svgData)); + + increaseDownloadData(value, new Date().toString()) } From ce7b38218997e3c0ea060c989b4f153ceff7e93a Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Sat, 9 May 2020 13:09:15 +0800 Subject: [PATCH 22/30] Remove console log --- src/api/db.js | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/api/db.js b/src/api/db.js index 5479d09..e8722a0 100644 --- a/src/api/db.js +++ b/src/api/db.js @@ -8,7 +8,6 @@ const auth = app.auth(); async function login() { await auth.signInAnonymously(); const loginState = await auth.getLoginState() - console.log(loginState.isAnonymous); } login(); @@ -27,7 +26,6 @@ export function increaseDownloadData(value, date) { count: _.inc(1), date: date }).then(res => { - console.log(res) }) } else { @@ -36,7 +34,6 @@ export function increaseDownloadData(value, date) { count: 1, date: date }).then(res => { - console.log(res) }) } }) @@ -51,6 +48,5 @@ export function recordDownloadDetail({text, value, type, params, history}) { params: params, history: history }).then(res => { - console.log(res) }) } From 47b5922ea20e1169b708c47a7b2994d9c1e9bc2d Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Wed, 13 May 2020 16:50:17 +0800 Subject: [PATCH 23/30] dev-redux Action --- .github/workflows/nodejs-dev.yml | 37 ++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 .github/workflows/nodejs-dev.yml diff --git a/.github/workflows/nodejs-dev.yml b/.github/workflows/nodejs-dev.yml new file mode 100644 index 0000000..d50c2ee --- /dev/null +++ b/.github/workflows/nodejs-dev.yml @@ -0,0 +1,37 @@ +name: Continuous Integration #action名称 +on: + push: + branches: + - dev-redux + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - name: Checkout master + uses: actions/checkout@v2 + with: + ref: master + + - name: Setup node + uses: actions/setup-node@v1 + with: + node-version: "12.x" + + - name: Build project + run: yarn && yarn build + env: + CI: false + + - name: Authenticate + run: sudo chmod 775 ./build/ + + - name: Upload COS + uses: ciaochaos/tencent-cos-action@master + with: + args: delete -r -f / && upload -r build/ / + secret_id: ${{ secrets.SECRET_ID }} + secret_key: ${{ secrets.SECRET_KEY }} + bucket: ${{ secrets.BUCKET_DEV }} + region: ap-shanghai From 1b5ee71fcfc92f0a9263b51d67f86e34d0578019 Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Wed, 13 May 2020 16:53:52 +0800 Subject: [PATCH 24/30] dev-redux Action 2 --- .github/workflows/nodejs-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nodejs-dev.yml b/.github/workflows/nodejs-dev.yml index d50c2ee..6959fe6 100644 --- a/.github/workflows/nodejs-dev.yml +++ b/.github/workflows/nodejs-dev.yml @@ -30,7 +30,7 @@ jobs: - name: Upload COS uses: ciaochaos/tencent-cos-action@master with: - args: delete -r -f / && upload -r build/ / + args: delete -r -f / && upload -r ./build/ / secret_id: ${{ secrets.SECRET_ID }} secret_key: ${{ secrets.SECRET_KEY }} bucket: ${{ secrets.BUCKET_DEV }} From 0acb23eca79b48cb5f76311da361011588d819cb Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Wed, 13 May 2020 16:58:55 +0800 Subject: [PATCH 25/30] dev-redux Action 3 --- .github/workflows/nodejs-dev.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nodejs-dev.yml b/.github/workflows/nodejs-dev.yml index 6959fe6..8c21525 100644 --- a/.github/workflows/nodejs-dev.yml +++ b/.github/workflows/nodejs-dev.yml @@ -25,12 +25,12 @@ jobs: CI: false - name: Authenticate - run: sudo chmod 775 ./build/ + run: sudo chmod 775 ./build/ && ls - name: Upload COS uses: ciaochaos/tencent-cos-action@master with: - args: delete -r -f / && upload -r ./build/ / + args: delete -r -f / && upload -r build/ / secret_id: ${{ secrets.SECRET_ID }} secret_key: ${{ secrets.SECRET_KEY }} bucket: ${{ secrets.BUCKET_DEV }} From 3ec208d417717886b721ff9e27910af437f63698 Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Wed, 13 May 2020 17:04:18 +0800 Subject: [PATCH 26/30] dev-redux Action 4 --- .github/workflows/nodejs-dev.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nodejs-dev.yml b/.github/workflows/nodejs-dev.yml index 8c21525..b408b9c 100644 --- a/.github/workflows/nodejs-dev.yml +++ b/.github/workflows/nodejs-dev.yml @@ -1,4 +1,4 @@ -name: Continuous Integration #action名称 +name: Continuous Integration Dev #action名称 on: push: branches: @@ -25,7 +25,7 @@ jobs: CI: false - name: Authenticate - run: sudo chmod 775 ./build/ && ls + run: sudo chmod 775 build/ && ls - name: Upload COS uses: ciaochaos/tencent-cos-action@master From 971c5b039adb2b300c5261fa301607226f46af01 Mon Sep 17 00:00:00 2001 From: ciaochaos <1272777550@qq.com> Date: Wed, 13 May 2020 17:07:40 +0800 Subject: [PATCH 27/30] dev-redux Action 5 --- .github/workflows/nodejs-dev.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nodejs-dev.yml b/.github/workflows/nodejs-dev.yml index b408b9c..c1971d8 100644 --- a/.github/workflows/nodejs-dev.yml +++ b/.github/workflows/nodejs-dev.yml @@ -25,12 +25,12 @@ jobs: CI: false - name: Authenticate - run: sudo chmod 775 build/ && ls + run: sudo chmod 775 ./build/ && ls - name: Upload COS uses: ciaochaos/tencent-cos-action@master with: - args: delete -r -f / && upload -r build/ / + args: delete -r -f / && upload -r /build/ / secret_id: ${{ secrets.SECRET_ID }} secret_key: ${{ secrets.SECRET_KEY }} bucket: ${{ secrets.BUCKET_DEV }} From 99156f9cadebe07ce780637c8f01e922a5a48f05 Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Wed, 13 May 2020 17:26:31 +0800 Subject: [PATCH 28/30] Update nodejs-dev.yml --- .github/workflows/nodejs-dev.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/nodejs-dev.yml b/.github/workflows/nodejs-dev.yml index c1971d8..e674c4b 100644 --- a/.github/workflows/nodejs-dev.yml +++ b/.github/workflows/nodejs-dev.yml @@ -30,7 +30,7 @@ jobs: - name: Upload COS uses: ciaochaos/tencent-cos-action@master with: - args: delete -r -f / && upload -r /build/ / + args: delete -r -f / && upload -r ./build/ / secret_id: ${{ secrets.SECRET_ID }} secret_key: ${{ secrets.SECRET_KEY }} bucket: ${{ secrets.BUCKET_DEV }} From 61352e3e15fc491a5336be43c814f3ba22c6c939 Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Wed, 13 May 2020 17:32:28 +0800 Subject: [PATCH 29/30] Update nodejs-dev.yml --- .github/workflows/nodejs-dev.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/nodejs-dev.yml b/.github/workflows/nodejs-dev.yml index e674c4b..55ca648 100644 --- a/.github/workflows/nodejs-dev.yml +++ b/.github/workflows/nodejs-dev.yml @@ -9,10 +9,10 @@ jobs: runs-on: ubuntu-latest steps: - - name: Checkout master + - name: Checkout dev-redux uses: actions/checkout@v2 with: - ref: master + ref: dev-redux - name: Setup node uses: actions/setup-node@v1 From 028b25c992d8078e54e5cb3d5e205b58ff3af7be Mon Sep 17 00:00:00 2001 From: CPunisher <1343316114@qq.com> Date: Wed, 13 May 2020 17:32:56 +0800 Subject: [PATCH 30/30] Update db.js --- src/api/db.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/api/db.js b/src/api/db.js index d82a585..4eed67a 100644 --- a/src/api/db.js +++ b/src/api/db.js @@ -6,7 +6,7 @@ const app = tcb.init({ const auth = app.auth(); async function login() { - // await auth.signInAnonymously(); + await auth.signInAnonymously(); // const loginState = await auth.getLoginState(); }