diff --git a/FA/writingPad/build-profile.json5 b/FA/writingPad/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..af956a732be8bd3e68aa9fcab3eb389c965043ad
--- /dev/null
+++ b/FA/writingPad/build-profile.json5
@@ -0,0 +1,26 @@
+{
+ "app": {
+ "compileSdkVersion": 8,
+ "compatibleSdkVersion": 8,
+ "products": [
+ {
+ "name": "default",
+ "signingConfig": "default",
+ }
+ ]
+ },
+ "modules": [
+ {
+ "name": "entry",
+ "srcPath": "./entry",
+ "targets": [
+ {
+ "name": "default",
+ "applyToProducts": [
+ "default"
+ ]
+ }
+ ]
+ }
+ ]
+}
\ No newline at end of file
diff --git a/FA/writingPad/entry/.gitignore b/FA/writingPad/entry/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..5a6ba80fa3d9498a23ae8ae7d9518f8743fa8a96
--- /dev/null
+++ b/FA/writingPad/entry/.gitignore
@@ -0,0 +1,4 @@
+/node_modules
+/.preview
+/build
+/.cxx
\ No newline at end of file
diff --git a/FA/writingPad/entry/build-profile.json5 b/FA/writingPad/entry/build-profile.json5
new file mode 100644
index 0000000000000000000000000000000000000000..813a6f0c7eec270313be21a88fe9a189ce2a8dc9
--- /dev/null
+++ b/FA/writingPad/entry/build-profile.json5
@@ -0,0 +1,14 @@
+{
+ "apiType": 'faMode',
+ "buildOption": {
+ },
+ "targets": [
+ {
+ "name": "default",
+ "runtimeOS": "OpenHarmony"
+ },
+ {
+ "name": "ohosTest",
+ }
+ ]
+}
\ No newline at end of file
diff --git a/FA/writingPad/entry/hvigorfile.js b/FA/writingPad/entry/hvigorfile.js
new file mode 100644
index 0000000000000000000000000000000000000000..bcec4c99653062cbf17702c40a2dd2a7b809b81a
--- /dev/null
+++ b/FA/writingPad/entry/hvigorfile.js
@@ -0,0 +1,2 @@
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+module.exports = require('@ohos/hvigor-ohos-plugin').legacyHapTasks
diff --git a/FA/writingPad/entry/package-lock.json b/FA/writingPad/entry/package-lock.json
new file mode 100644
index 0000000000000000000000000000000000000000..15bc7145be1490029883067847743ea7134cf545
--- /dev/null
+++ b/FA/writingPad/entry/package-lock.json
@@ -0,0 +1,5 @@
+{
+ "name": "entry",
+ "version": "1.0.0",
+ "lockfileVersion": 1
+}
diff --git a/FA/writingPad/entry/package.json b/FA/writingPad/entry/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..c7685ac4e7c0d79df04c96744f0d8f22cb4a9025
--- /dev/null
+++ b/FA/writingPad/entry/package.json
@@ -0,0 +1,14 @@
+{
+ "license": "ISC",
+ "devDependencies": {},
+ "name": "entry",
+ "ohos": {
+ "org": "huawei",
+ "directoryLevel": "module",
+ "buildTool": "hvigor"
+ },
+ "description": "example description",
+ "repository": {},
+ "version": "1.0.0",
+ "dependencies": {}
+}
diff --git a/FA/writingPad/entry/project.txt b/FA/writingPad/entry/project.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e26dc2dd81ee66db0dfad5596154d2c838c13b38
Binary files /dev/null and b/FA/writingPad/entry/project.txt differ
diff --git a/FA/writingPad/entry/src/main/config.json b/FA/writingPad/entry/src/main/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..5cf8c0e215e3bf586695e903055372c13b52040d
--- /dev/null
+++ b/FA/writingPad/entry/src/main/config.json
@@ -0,0 +1,65 @@
+{
+ "app": {
+ "vendor": "example",
+ "bundleName": "com.example.myapplication",
+ "version": {
+ "code": 1000000,
+ "name": "1.0.0"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "mainAbility": ".MainAbility",
+ "deviceType": [
+ "phone"
+ ],
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "visible": true,
+ "srcPath": "MainAbility",
+ "name": ".MainAbility",
+ "srcLanguage": "js",
+ "icon": "$media:icon",
+ "description": "$string:MainAbility_desc",
+ "formsEnabled": false,
+ "label": "$string:MainAbility_label",
+ "type": "page",
+ "launchType": "standard"
+ }
+ ],
+ "distro": {
+ "moduleType": "entry",
+ "installationFree": false,
+ "deliveryWithInstall": true,
+ "moduleName": "entry"
+ },
+ "package": "com.example.entry",
+ "name": ".entry",
+ "js": [
+ {
+ "pages": [
+ "pages/index/index"
+ ],
+ "name": ".MainAbility",
+ "window": {
+ "designWidth": 720,
+ "autoDesignWidth": false
+ }
+ }
+ ],
+ "reqPermissions": [{
+ "name": "ohos.permission.INTERNET"
+ }]
+ }
+}
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/app.js b/FA/writingPad/entry/src/main/js/MainAbility/app.js
new file mode 100644
index 0000000000000000000000000000000000000000..6d060ffe5682c19fc83e2274a9e62cbc40a655f8
--- /dev/null
+++ b/FA/writingPad/entry/src/main/js/MainAbility/app.js
@@ -0,0 +1,8 @@
+export default {
+ onCreate() {
+ console.info("Application onCreate");
+ },
+ onDestroy() {
+ console.info("Application onDestroy");
+ }
+};
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/components/Draw/index.css b/FA/writingPad/entry/src/main/js/MainAbility/common/components/Draw/index.css
new file mode 100644
index 0000000000000000000000000000000000000000..9af0d19789a389ea042dffc2f18dfd98756fb24a
--- /dev/null
+++ b/FA/writingPad/entry/src/main/js/MainAbility/common/components/Draw/index.css
@@ -0,0 +1,164 @@
+.canvas {
+ height: 800px;
+ width: 700px;
+}
+
+.editor text {
+ margin: 10px;
+}
+
+.one {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.nav {
+ width: 100%;
+ height: 100px;
+ border: 3px solid black;
+ border-bottom-left-radius: 20px;
+ border-bottom-right-radius: 20px;
+ margin-bottom: 10px;
+}
+
+.nav text {
+ width: 100%;
+ height: 100%;
+ text-align: center;
+ line-height: 50px;
+}
+
+.PracticeWords {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.tow {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.canvasDraw {
+ height: 360px;
+ width: 360px;
+}
+
+.drawing {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.editorBoxOn {
+ position: absolute;
+ left: 0;
+ bottom: 0;
+}
+
+.editorBoxOff {
+ position: absolute;
+ left: -430px;
+ bottom: 0;
+}
+
+.editorDraw text {
+ margin: 30px;
+}
+
+.editorOff {
+ position: absolute;
+ bottom: 100px;
+ left: -500px;
+}
+
+.editorOn {
+ position: absolute;
+ bottom: 100px;
+ left: 0px;
+}
+
+.editorOff div {
+ width: 80px;
+ height: 80px;
+ margin: 25px;
+}
+
+.editorOn div {
+ width: 80px;
+ height: 80px;
+ margin: 25px;
+}
+
+.red {
+ width: 80px;
+ height: 80px;
+ border-radius: 40px;
+ background-color: red;
+}
+
+.blue {
+ width: 80px;
+ height: 80px;
+ border-radius: 40px;
+ background-color: blue;
+}
+
+.white {
+ width: 80px;
+ height: 80px;
+ border-radius: 40px;
+ background-color: white;
+}
+
+.black {
+ width: 80px;
+ height: 80px;
+ border-radius: 40px;
+ background-color: black;
+}
+
+.pop-box {
+ width: 120px;
+ height: 120px;
+ border: 1px solid pink;
+ display: flex;
+ flex-direction: column-reverse;
+ justify-content: space-between;
+ overflow: hidden;
+ position: fixed;
+ bottom: 100px;
+ right: 50px;
+}
+
+.right {
+ margin-top: 20px;
+ width: 50px;
+ height: 100px;
+}
+
+.txt {
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ position: fixed;
+ top: 65%;
+}
+
+text {
+ margin-top: 30px;
+}
+
+.slider {
+ position: absolute;
+ bottom: 200px;
+}
+
+.canvasFont {
+ width: 300px;
+ height: 100px;
+}
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/components/Draw/index.hml b/FA/writingPad/entry/src/main/js/MainAbility/common/components/Draw/index.hml
new file mode 100644
index 0000000000000000000000000000000000000000..1b653cd2bd6ad57115d4da0c322297de3981b234
--- /dev/null
+++ b/FA/writingPad/entry/src/main/js/MainAbility/common/components/Draw/index.hml
@@ -0,0 +1,53 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/components/Draw/index.js b/FA/writingPad/entry/src/main/js/MainAbility/common/components/Draw/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..64eee49d7abec338cf6cd9c9ab9921eecac9f464
--- /dev/null
+++ b/FA/writingPad/entry/src/main/js/MainAbility/common/components/Draw/index.js
@@ -0,0 +1,241 @@
+// @ts-nocheck
+import animator from '@ohos.animator';
+
+export default {
+ data: {
+ ctx: '',
+ width: 0,
+ height: 0,
+ ArrX: [],
+ ArrY: [],
+ lineWidth: 14,
+ isEraser: false, //是否开启橡皮擦功能
+ eraserValue: 30, //橡皮擦大小
+ strokeStyle: 'black',
+ canvasHistory: [],
+ step: -1,
+ showClear: true,
+ showEraser: true,
+ showSave: true,
+ showUndo: true,
+ showRedo: true,
+ foldB: true,
+ foldT: true,
+ value: 0,
+ WidthVal: 5,
+ HeightVal: 250,
+ divWidth: 200, // 动画
+ animator: null
+ },
+ onLayoutReady() {
+ const el = this.$refs.canvas;
+ this.ctx = el.getContext('2d')
+ this.width = el.getBoundingClientRect().width;
+ this.height = el.getBoundingClientRect().height;
+ this.getFontSize()
+ // 动画
+ var options = {
+ duration: 1500,
+ easing: 'friction',
+ fill: 'forwards',
+ iterations: 2,
+ begin: 200.0,
+ end: 400.0
+ };
+ this.animator = animator.createAnimator(options);
+ },
+ // 偏移很多
+ touchstart(e) {
+ this.ArrX.push(e.touches[0].localX)
+ this.ArrY.push(e.touches[0].localY)
+ if (this.isEraser) {
+ this.ctx.clearRect(e.touches[0].localX - this.eraserValue, e.touches[0].localY - this.eraserValue, this.eraserValue, this.eraserValue)
+ }
+ },
+ touchmove(e) {
+ if (this.isEraser) {
+ this.ctx.clearRect(this.ArrX[this.ArrX.length-1] - this.eraserValue, this.ArrY[this.ArrY.length-1] - this.eraserValue, this.eraserValue, this.eraserValue)
+ } else {
+ this.lineDraw(e)
+ }
+ this.ArrX.push(e.touches[0].localX)
+ this.ArrY.push(e.touches[0].localY)
+ },
+ lineDraw(e) {
+ this.ctx.lineWidth = this.lineWidth
+ this.ctx.strokeStyle = this.strokeStyle
+ this.ctx.beginPath()
+ // 向线条的每个末端添加圆形线帽。
+ this.ctx.lineCap = 'round'
+ // 每次将数组中最后一个值取出,作为起始点
+ this.ctx.moveTo(this.ArrX[this.ArrX.length-1], this.ArrY[this.ArrY.length-1])
+ this.ctx.lineTo(e.touches[0].localX, e.touches[0].localY)
+ this.ctx.stroke()
+ },
+ touchend(e) {
+ const el = this.$refs.canvas;
+ this.step++;
+ this.canvasHistory.push(el.toDataURL()); // 添加新的绘制到历史记录
+ // console.log(this.step)
+ },
+ saveBtn() {
+ const el = this.$refs.canvas;
+ const dataURL = el.toDataURL();
+ // console.log(dataURL);
+ },
+ withdraw() {
+ this.ArrX.pop()
+ this.ArrY.pop()
+ },
+ clearBtn(e) {
+ this.ctx.clearRect(0, 0, this.width, this.height);
+ this.showClear = false
+ this.showEraser = true
+ this.showSave = true
+ this.showUndo = true
+ this.showRedo = true
+ },
+ clearBtnEnd() {
+ this.canvasHistory = []
+ this.step = -1
+ this.showClear = true
+ },
+ EraserBtn() {
+ this.isEraser = !this.isEraser
+ this.showClear = true
+ this.showEraser = !this.showEraser
+ this.showSave = true
+ this.showUndo = true
+ this.showRedo = true
+ },
+ saveBtn() {
+ this.showClear = true
+ this.showEraser = true
+ this.showSave = false
+ this.showUndo = true
+ this.showRedo = true
+ },
+ saveBtnEnd() {
+ this.showClear = true
+ this.showEraser = true
+ this.showSave = true
+ this.showUndo = true
+ this.showRedo = true
+ },
+ red() {
+ this.strokeStyle = 'red'
+ this.getFontSize()
+ },
+ blue() {
+ this.strokeStyle = 'blue'
+ this.getFontSize()
+ },
+ white() {
+ this.strokeStyle = 'white'
+ this.getFontSize()
+ },
+ black() {
+ this.strokeStyle = 'black'
+ this.getFontSize()
+ },
+ undo() {
+ if (this.step >= 0) {
+ this.step--;
+ this.ctx.clearRect(0, 0, this.width, this.height);
+ let img = new Image();
+ img.src = this.canvasHistory[this.step];
+ let that = this
+ img.onload = function () {
+ // 画上图片
+ that.ctx.drawImage(img, 0, 0);
+ };
+ } else {
+ console.log('不能再继续撤销了');
+ }
+
+ this.showClear = true
+ this.showEraser = true
+ this.showSave = true
+ this.showUndo = false
+ this.showRedo = true
+ },
+ undoEnd() {
+ this.showClear = true
+ this.showEraser = true
+ this.showSave = true
+ this.showUndo = true
+ this.showRedo = true
+ },
+ redo() {
+ if (this.step < this.canvasHistory.length - 1) {
+ this.step++;
+ let img = new Image();
+ img.src = this.canvasHistory[this.step];
+ let that = this
+ img.onload = function () {
+ that.ctx.clearRect(0, 0, this.width, this.height);
+ that.ctx.drawImage(img, 0, 0);
+ };
+ } else {
+ console.log('已经是最新的记录了');
+ }
+
+ this.showClear = true
+ this.showEraser = true
+ this.showSave = true
+ this.showUndo = true
+ this.showRedo = false
+ },
+ redoEnd() {
+ this.showClear = true
+ this.showEraser = true
+ this.showSave = true
+ this.showUndo = true
+ this.showRedo = true
+ },
+ foldBottom() {
+ this.foldB = !this.foldB
+ },
+ foldTop() {
+ this.foldT = !this.foldT
+ },
+ setvalue(e) {
+ this.lineWidth = e.value;
+ this.getFontSize()
+ },
+ getFontSize() {
+ const el = this.$refs.canvasFont;
+ const ctxFont = el.getContext('2d')
+ ctxFont.beginPath();
+ ctxFont.clearRect(0, 0, 300, 100);
+ ctxFont.lineWidth = this.lineWidth
+ ctxFont.strokeStyle = this.strokeStyle
+ // console.log(this.lineWidth)
+ ctxFont.moveTo(50, 50);
+ // 三次贝赛尔曲线的路径
+ ctxFont.lineTo(300, 50);
+ ctxFont.stroke();
+ },
+ // 动画
+ Show() {
+ this.isAnimator = !this.isAnimator
+ var options1 = {
+ duration: 2000,
+ easing: 'friction',
+ fill: 'both',
+ iterations: 1,
+ begin: 200.0,
+ end: 800.0
+ };
+ this.animator.update(options1);
+ var _this = this;
+ this.animator.onframe = function (value) {
+ _this.divWidth = value;
+ };
+ if (this.isAnimator) {
+ this.animator.play();
+ } else {
+ this.animator.reverse();
+ }
+ }
+}
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/components/Note/index.css b/FA/writingPad/entry/src/main/js/MainAbility/common/components/Note/index.css
new file mode 100644
index 0000000000000000000000000000000000000000..a650f43c385bca033e7004b282a761e4a89a1e24
--- /dev/null
+++ b/FA/writingPad/entry/src/main/js/MainAbility/common/components/Note/index.css
@@ -0,0 +1,175 @@
+.canvas {
+ height: 800px;
+ width: 350px;
+}
+
+.editor text {
+ margin: 10px;
+}
+
+.one {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.nav {
+ width: 100%;
+ height: 100px;
+ border: 3px solid black;
+ border-bottom-left-radius: 20px;
+ border-bottom-right-radius: 20px;
+ margin-bottom: 10px;
+}
+
+.nav text {
+ width: 100%;
+ height: 100%;
+ text-align: center;
+ line-height: 50px;
+}
+
+.PracticeWords {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.tow {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.canvasDraw {
+ height: 360px;
+ width: 360px;
+}
+
+.drawing {
+ width: 100%;
+ height: 100%;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.editorBoxOn {
+ position: absolute;
+ left: 0;
+ bottom: 0;
+}
+
+.editorBoxOff {
+ position: absolute;
+ left: -215px;
+ bottom: 0;
+}
+
+.editorDraw text {
+ margin: 20px;
+}
+
+.editorOff {
+ position: absolute;
+ bottom: 100px;
+ left: -250px;
+}
+
+.editorOn {
+ position: absolute;
+ bottom: 100px;
+ left: 0px;
+}
+
+.editorOff div {
+ width: 30px;
+ height: 30px;
+ margin: 15px;
+}
+
+.editorOn div {
+ width: 30px;
+ height: 30px;
+ margin: 15px;
+}
+
+.red {
+ width: 30px;
+ height: 30px;
+ border-radius: 15px;
+ background-color: red;
+}
+
+.blue {
+ width: 30px;
+ height: 30px;
+ border-radius: 15px;
+ background-color: blue;
+}
+
+.white {
+ width: 30px;
+ height: 30px;
+ border-radius: 15px;
+ background-color: white;
+}
+
+.black {
+ width: 30px;
+ height: 30px;
+ border-radius: 15px;
+ background-color: black;
+}
+
+.pop-box {
+ width: 120px;
+ height: 120px;
+ border: 1px solid pink;
+ display: flex;
+ flex-direction: column-reverse;
+ justify-content: space-between;
+ overflow: hidden;
+ position: fixed;
+ bottom: 100px;
+ right: 50px;
+}
+
+.right {
+ margin-top: 10px;
+ width: 25px;
+ height: 50px;
+}
+
+.txt {
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ position: fixed;
+ top: 65%;
+}
+
+text {
+ margin-top: 30px;
+}
+
+.slider {
+ position: absolute;
+ bottom: 200px;
+}
+
+.canvasFont {
+ width: 300px;
+ height: 100px;
+}
+
+.node {
+ position: absolute;
+ right: 10px;
+ top: 500px;
+}
+
+.node image {
+ width: 80px;
+ height: 80px;
+}
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/components/Note/index.hml b/FA/writingPad/entry/src/main/js/MainAbility/common/components/Note/index.hml
new file mode 100644
index 0000000000000000000000000000000000000000..96a115cbea3c95dfaf3bd559b92243f6551f5ba0
--- /dev/null
+++ b/FA/writingPad/entry/src/main/js/MainAbility/common/components/Note/index.hml
@@ -0,0 +1,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ content }}
+
+
+
+
+
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/components/Note/index.js b/FA/writingPad/entry/src/main/js/MainAbility/common/components/Note/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..16bb7812363be8e979f7673a1b49b53d8982fa7d
--- /dev/null
+++ b/FA/writingPad/entry/src/main/js/MainAbility/common/components/Note/index.js
@@ -0,0 +1,356 @@
+// @ts-nocheck
+import animator from '@ohos.animator';
+
+export default {
+ data: {
+ ctx: '',
+ width: 0,
+ height: 0,
+ ArrX: [],
+ ArrY: [],
+ lineWidth: 14,
+ isEraser: false, //是否开启橡皮擦功能
+ eraserValue: 30, //橡皮擦大小
+ strokeStyle: 'black',
+ canvasHistory: [],
+ step: -1,
+ showClear: true,
+ showEraser: true,
+ showSave: true,
+ showUndo: true,
+ showRedo: true,
+ foldB: true,
+ foldT: true,
+ value: 0,
+ WidthVal: 5,
+ HeightVal: 250,
+ divWidth: 200, // 动画
+ animator: null,
+ isShowNote: true,
+ showCanvas: [],
+ showStep: 0,
+ content: `
+前言
+
+本篇还是canvas内容,实现的是一个绘画板,本次绘画板的功能比较多一些,包括画笔颜色切换、清空、橡皮擦、保存、撤回、反撤回。可以用该绘画板来完成一些基础的绘画功能。
+
+介绍
+
+这是一个绘画板,我们可以实现简单的绘画,功能包括:画笔颜色切换、清空、橡皮擦、保存、撤回、反撤回
+
+效果展示
+
+
+
+原理分析
+
+1.线条生成
+
+这是最基础的功能,具体实现方法,前面的文章也介绍过。
+
+首先,我们需要将canvas上下文对象,需要在触摸移动事件中绑定,因为我们是通过触摸来生成对应线条的。
+
+然后,定义两个数组,分别存储鼠标经过的x与y坐标,在鼠标按下时开始记录,在鼠标移动时,也将坐标push到数组中
+
+最后,将获取的坐标通过绘画方法,通过moveTo和lineTo进行绘画,即可得到线条。
+
+2.清空画板
+
+清空画布的功能最简单,调用canvasAPI的ctx.clearRect即可
+
+API介绍:clearRect(x: number, y: number, w: number, h: number): void
+
+- x:指定矩形上的左上角x坐标;
- y:指定矩形上的左上角y坐标;
- width:指定矩形的宽度;
- height:指定矩形的高度;
+
+这里因为是清空,所以只需要将在坐标设置为左上角,然后宽高设置为和当前canvs画布宽高一致即可清空画板
+
+3.橡皮擦
+
+这里的实现实际和清空画板一样,只是橡皮擦清空的面积小很多
+
+首先,定义一个标识,来判断是否需要橡皮擦功能,用户通过点击下面的橡皮擦图片进行控制
+
+然后,我们需要在触摸移动事件,提前判断是否需要橡皮擦功能,如果需要,我们将画线功能替换为橡皮擦功能,功能实现的API和清空画板一样
+
+最后,就是橡皮擦大小的问题,我们可以提前定义一个属性,用来控制大小,在橡皮擦功能中,将该属性添加即可
+
+4.保存绘画
+
+这里还没实现出来
+
+这里利用了canvas的一个API:toDataURL(type?: string, quality?:number)
+
+可以生成一个包含图片展示的URL
+
+参数:
+
+
+
+返回值:
+
+
+
+我们可以通过toDataURL将获取到的图像的URL地址进行存储,在需要的地方生成canvas图像即可
+
+5.撤回
+
+撤回功能用到的API比较多,需要耐心的阅读文档
+
+在实现撤回功能之前,我们需要将每次绘画出来的线条进行存储,在鼠标抬起事件中,通过toDataURL()将获取到当前的图像,push到数组中,存储起来
+
+实现撤回功能:
+
+首先,需要一个属性:步频,我们每次绘画一条线段,step就自增,撤回功能中,只需要将当前步频-1,就能拿到上一次绘画的图像
+
+然后,将当前的图像清空,通过clearRect
+
+最后,拿到上一次的图像,通过onload函数,将图像进行绘画,通过drawImage实现绘画功能
+
+6.反撤回
+
+反撤回的实现基本上和撤回一样,只不过获取的图像不同
+
+和撤回一样,需要拿到每次的图像,这里可以直接利用撤回中获取的图像
+
+实现反撤回功能:
+
+首先,每次反撤回,需要将步频++,我们就可以拿到当前显示画像的前一张画画像
+
+然后,将当前的图像清空,通过clearRect
+
+最后,拿到上一次的图像,通过onload函数,将图像进行绘画,通过drawImage实现绘画功能
+
+7.线条样式
+
+线条颜色实现比较简单,当用户点击需要的颜色样式时,修改画布的ctx.strokeStyle即可。
+ `,
+ },
+ onLayoutReady() {
+ const el = this.$refs.canvas;
+ this.ctx = el.getContext('2d')
+ this.width = el.getBoundingClientRect().width;
+ this.height = el.getBoundingClientRect().height;
+ this.getFontSize()
+ // 动画
+ var options = {
+ duration: 1500,
+ easing: 'friction',
+ fill: 'forwards',
+ iterations: 2,
+ begin: 200.0,
+ end: 400.0
+ };
+ this.animator = animator.createAnimator(options);
+ },
+ // 偏移很多
+ touchstart(e) {
+ this.ArrX.push(e.touches[0].localX)
+ this.ArrY.push(e.touches[0].localY)
+ if (this.isEraser) {
+ this.ctx.clearRect(e.touches[0].localX - this.eraserValue, e.touches[0].localY - this.eraserValue, this.eraserValue, this.eraserValue)
+ }
+ },
+ touchmove(e) {
+ if (this.isEraser) {
+ this.ctx.clearRect(this.ArrX[this.ArrX.length-1] - this.eraserValue, this.ArrY[this.ArrY.length-1] - this.eraserValue, this.eraserValue, this.eraserValue)
+ } else {
+ this.lineDraw(e)
+ }
+ this.ArrX.push(e.touches[0].localX)
+ this.ArrY.push(e.touches[0].localY)
+ },
+ lineDraw(e) {
+ this.ctx.lineWidth = this.lineWidth
+ this.ctx.strokeStyle = this.strokeStyle
+ this.ctx.beginPath()
+ // 向线条的每个末端添加圆形线帽。
+ this.ctx.lineCap = 'round'
+ // 每次将数组中最后一个值取出,作为起始点
+ this.ctx.moveTo(this.ArrX[this.ArrX.length-1], this.ArrY[this.ArrY.length-1])
+ this.ctx.lineTo(e.touches[0].localX, e.touches[0].localY)
+ this.ctx.stroke()
+ },
+ touchend(e) {
+ const el = this.$refs.canvas;
+ this.step++;
+ this.canvasHistory.push(el.toDataURL()); // 添加新的绘制到历史记录
+ // console.log(this.step)
+ },
+ saveBtn() {
+ const el = this.$refs.canvas;
+ const dataURL = el.toDataURL();
+ // console.log(dataURL);
+ },
+ withdraw() {
+ this.ArrX.pop()
+ this.ArrY.pop()
+ },
+ clearBtn(e) {
+ this.ctx.clearRect(0, 0, this.width, this.height);
+ this.showClear = false
+ this.showEraser = true
+ this.showSave = true
+ this.showUndo = true
+ this.showRedo = true
+ },
+ clearBtnEnd() {
+ this.canvasHistory = []
+ this.step = -1
+ this.showClear = true
+ },
+ EraserBtn() {
+ this.isEraser = !this.isEraser
+ this.showClear = true
+ this.showEraser = !this.showEraser
+ this.showSave = true
+ this.showUndo = true
+ this.showRedo = true
+ },
+ saveBtn() {
+ this.showClear = true
+ this.showEraser = true
+ this.showSave = false
+ this.showUndo = true
+ this.showRedo = true
+ },
+ saveBtnEnd() {
+ this.showClear = true
+ this.showEraser = true
+ this.showSave = true
+ this.showUndo = true
+ this.showRedo = true
+ },
+ red() {
+ this.strokeStyle = 'red'
+ this.getFontSize()
+ },
+ blue() {
+ this.strokeStyle = 'blue'
+ this.getFontSize()
+ },
+ white() {
+ this.strokeStyle = 'white'
+ this.getFontSize()
+ },
+ black() {
+ this.strokeStyle = 'black'
+ this.getFontSize()
+ },
+ undo() {
+ if (this.step >= 0) {
+ this.step--;
+ this.ctx.clearRect(0, 0, this.width, this.height);
+ let img = new Image();
+ img.src = this.canvasHistory[this.step];
+ let that = this
+ img.onload = function () {
+ // 画上图片
+ that.ctx.drawImage(img, 0, 0);
+ };
+ } else {
+ console.log('不能再继续撤销了');
+ }
+
+ this.showClear = true
+ this.showEraser = true
+ this.showSave = true
+ this.showUndo = false
+ this.showRedo = true
+ },
+ undoEnd() {
+ this.showClear = true
+ this.showEraser = true
+ this.showSave = true
+ this.showUndo = true
+ this.showRedo = true
+ },
+ redo() {
+ if (this.step < this.canvasHistory.length - 1) {
+ this.step++;
+ let img = new Image();
+ img.src = this.canvasHistory[this.step];
+ let that = this
+ img.onload = function () {
+ that.ctx.clearRect(0, 0, this.width, this.height);
+ that.ctx.drawImage(img, 0, 0);
+ };
+ } else {
+ console.log('已经是最新的记录了');
+ }
+
+ this.showClear = true
+ this.showEraser = true
+ this.showSave = true
+ this.showUndo = true
+ this.showRedo = false
+ },
+ redoEnd() {
+ this.showClear = true
+ this.showEraser = true
+ this.showSave = true
+ this.showUndo = true
+ this.showRedo = true
+ },
+ foldBottom() {
+ this.foldB = !this.foldB
+ },
+ foldTop() {
+ this.foldT = !this.foldT
+ },
+ setvalue(e) {
+ this.lineWidth = e.value;
+ this.getFontSize()
+ },
+ getFontSize() {
+ const el = this.$refs.canvasFont;
+ const ctxFont = el.getContext('2d')
+ ctxFont.beginPath();
+ ctxFont.clearRect(0, 0, 300, 100);
+ ctxFont.lineWidth = this.lineWidth
+ ctxFont.strokeStyle = this.strokeStyle
+ // console.log(this.lineWidth)
+ ctxFont.moveTo(50, 50);
+ // 三次贝赛尔曲线的路径
+ ctxFont.lineTo(300, 50);
+ ctxFont.stroke();
+ },
+ // 动画
+ Show() {
+ this.isAnimator = !this.isAnimator
+ var options1 = {
+ duration: 2000,
+ easing: 'friction',
+ fill: 'both',
+ iterations: 1,
+ begin: 200.0,
+ end: 800.0
+ };
+ this.animator.update(options1);
+ var _this = this;
+ this.animator.onframe = function (value) {
+ _this.divWidth = value;
+ };
+ if (this.isAnimator) {
+ this.animator.play();
+ } else {
+ this.animator.reverse();
+ }
+ },
+ isShowNoteBtn() {
+ this.isShowNote = !this.isShowNote
+ if (this.isShowNote) {
+ let img = new Image();
+ img.src = this.showCanvas[this.showStep];
+ let that = this
+ img.onload = function () {
+ that.ctx.drawImage(img, 0, 0);
+ };
+ console.log('打开')
+ console.log(this.showCanvas[this.showStep])
+ } else {
+ this.showCanvas[this.step] = this.canvasHistory[this.step]
+ this.showStep = this.step
+ console.log(this.showCanvas)
+ }
+ }
+}
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/components/Write/index.css b/FA/writingPad/entry/src/main/js/MainAbility/common/components/Write/index.css
new file mode 100644
index 0000000000000000000000000000000000000000..8586c2e5887383ea81e9dbb2310ed9d55d496eb4
--- /dev/null
+++ b/FA/writingPad/entry/src/main/js/MainAbility/common/components/Write/index.css
@@ -0,0 +1,217 @@
+.canvas {
+ height: 500px;
+ width: 500px;
+}
+
+.canvasBox {
+ margin-top: 140px;
+}
+
+.canvas2 {
+ height: 250px;
+ width: 250px;
+ border: 3px solid black;
+}
+
+.canvas2Box {
+ margin-top: 40px;
+}
+
+.editor text {
+ margin: 10px;
+}
+
+.one {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.PracticeWords {
+ width: 100%;
+ height: 100%;
+ position: relative;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+.tow {
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+}
+
+/* dialog */
+
+.doc-page {
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+}
+
+.editorOff {
+ position: absolute;
+ bottom: 0px;
+ left: -500px;
+}
+
+.editorOn {
+ position: absolute;
+ bottom: 0px;
+ left: 0px;
+}
+
+.editorOff div {
+ width: 80px;
+ height: 80px;
+ margin: 25px;
+}
+
+.editorOn div {
+ width: 80px;
+ height: 80px;
+ margin: 25px;
+}
+
+.help {
+ position: absolute;
+ top: 110px;
+ right: 0px;
+}
+
+.help image {
+ width: 100px;
+ height: 100px;
+}
+
+.dialog-div {
+ flex-direction: column;
+ align-items: center;
+}
+
+.inner-txt {
+ width: 80%;
+ height: 100px;
+ align-items: center;
+ flex-direction: column;
+ justify-content: space-around;
+}
+
+.txt {
+ font-size: 45px;
+ color: #000000;
+ font-weight: bold;
+}
+
+.containerText {
+ margin: 0% 20px;
+ height: 250px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+}
+
+.containerText text {
+ font-size: 45px;
+}
+
+.inner-btn {
+ width: 80%;
+ height: 100px;
+ align-items: center;
+ justify-content: space-around;
+}
+
+.inner-btn button {
+ font-size: 55px;
+ color: #ffc200;
+}
+
+.nest-div {
+ background-color: #FFFFFF;
+}
+
+.read {
+ position: absolute;
+ top: 110px;
+ left: 0px;
+}
+
+.read image {
+ width: 90px;
+ height: 90px;
+}
+
+.popup {
+ mask-color: gray;
+}
+
+.text {
+ color: white;
+}
+
+.Animation {
+ position: absolute;
+ bottom: 0;
+ left: 0;
+}
+
+/*使用教程*/
+
+.container {
+ position: absolute;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ background-color: #F1F3F5;
+}
+
+.stepperContent {
+ width: 1080px;
+ height: 1920px;
+}
+
+.stepperClass {
+ border: 1px solid silver;
+ background-color: white;
+ font-size: 55px;
+}
+
+.stepperClass text {
+ font-size: 80px;
+}
+
+text {
+ width: 100%;
+ height: 100%;
+ text-align: center;
+}
+
+.searchContainer {
+ position: absolute;
+ top: 20px;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ background-color: #F1F3F5;
+}
+
+text {
+ width: 100%;
+ font-size: 25px;
+ text-align: center;
+ margin-bottom: 100px;
+}
+
+/*评分*/
+
+.ratingContainer {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+
+rating {
+ width: 200px;
+}
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/components/Write/index.hml b/FA/writingPad/entry/src/main/js/MainAbility/common/components/Write/index.hml
new file mode 100644
index 0000000000000000000000000000000000000000..91699579f5e209133c075e86232057f1c4b9a993
--- /dev/null
+++ b/FA/writingPad/entry/src/main/js/MainAbility/common/components/Write/index.hml
@@ -0,0 +1,102 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 本软件可以进行练字,练习笔顺,并且模拟真实的写字,让你有如纸上写字一般的体验!
+
+ 点击下一步,让我为你介绍一下吧!
+
+
+
+ 提示当你忘记该字体的笔顺时,可以点击左上角的喇叭,会有笔顺提示
+
+
+ 用户和在练字时,每写一步,都会进行判断,如果笔顺正确,那么可以继续写,如果错误,则需要重写
+
+
+ 用户如果发现写错或者写的不好看时,可以进行撤回或清空
+
+
+ 当你写完时,可以进行存储,并且在下方进行展示
+
+
+ 点击开始,让我们愉快的练字吧!
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/components/Write/index.js b/FA/writingPad/entry/src/main/js/MainAbility/common/components/Write/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..33c8940e35f1d80e921366b17c1e51eb6476c004
--- /dev/null
+++ b/FA/writingPad/entry/src/main/js/MainAbility/common/components/Write/index.js
@@ -0,0 +1,409 @@
+// @ts-nocheck
+import animator from '@ohos.animator';
+import prompt from '@system.prompt';
+import router from '@system.router';
+
+export default {
+ data: {
+ ctx: '',
+ width: 0,
+ height: 0,
+ ArrX: [],
+ ArrY: [],
+ startTime: 0, // 开始时间
+ lineWidth: 14,
+ oldLineWidth: 3,
+ oldoldLineWidth: 3,
+ isEraser: false, //是否开启橡皮擦功能
+ saveImg: '', //保存的图片
+ canvasHistory: [],
+ step: -1,
+ pathX: [120, 40, 208, 85, 310, 390], // 文字的书写顺序
+ pathIndex: 0,
+ isRedo: false, //判断是否需要回退
+ foldT: true,
+ divWidth: 200, //动画
+ animator: null,
+ isAnimator: 'translateR', // 动画开始与结束
+ isStepper: false, // 帮助
+ rating: 5, // 评分等级
+ lastRating: null, // 旧评分
+ showRatingTip: '', // 评分提示语
+ isRating: false, // 评分显示与隐藏
+ saveScale: 0.5, //存储缩放
+ color: 'color',
+ showClear: true,
+ showEraser: true,
+ showSave: true,
+ showUndo: true,
+ showRedo: true,
+ showRead: true,
+ },
+ onLayoutReady() {
+ this.getBgcImage()
+ this.formLine()
+ const el = this.$refs.canvas;
+ this.ctx = el.getContext('2d')
+ this.width = el.getBoundingClientRect().width;
+ this.height = el.getBoundingClientRect().height;
+ // 获取完文字后先获取最初状态
+ this.step++;
+ this.canvasHistory.push(el.toDataURL()); // 添加新的绘制到历史记录
+ // 动画
+ var options = {
+ duration: 1500,
+ easing: 'friction',
+ fill: 'forwards',
+ iterations: 2,
+ begin: 200.0,
+ end: 400.0
+ };
+ this.animator = animator.createAnimator(options);
+ },
+ // 偏移很多
+ touchstart(e) {
+ // 开始时间清空
+ this.startTime = Date.now() - 1
+ this.ArrX.push(e.touches[0].localX)
+ this.ArrY.push(e.touches[0].localY)
+ if (e.touches[0].localX > this.pathX[this.pathIndex] + 30 || e.touches[0].localX < this.pathX[this.pathIndex] - 30) {
+ this.isRedo = true
+ this.rating-- // 如果写错一步,星星减一
+ } else {
+ this.pathIndex++
+ }
+ },
+ // 计算最后两点的速度
+ speed(x1, y1, x2, y2, s) {
+ const x = Math.abs(x1 - x2) * Math.abs(x1 - x2)
+ const y = Math.abs(y1 - y2) * Math.abs(y1 - y2)
+ return Math.sqrt(x + y) / s
+ },
+ touchmove(e) {
+ // 计算线条粗细
+ const currTime = Date.now()
+ if (this.startTime !== 0) {
+ const duration = currTime - this.startTime
+ // 传入倒数第二个点和最后一个点,和持续时间,会返回加速度
+ const v = this.speed(this.ArrX[this.ArrX.length-2], this.ArrY[this.ArrY.length-2], this.ArrX[this.ArrX.length-1], this.ArrY[this.ArrY.length-1], duration)
+ if (v > 30 || v != v) {
+ this.lineWidth = 3
+ }
+ else if (v < 1) {
+ this.lineWidth = 30
+ } else {
+ this.lineWidth = 30 - v * 15
+ }
+ this.lineWidth = this.oldLineWidth / 3 + this.oldoldLineWidth / 3 + (this.lineWidth) / 3
+ }
+ this.startTime = currTime
+
+ const el = this.$refs.canvas;
+ this.ctx = el.getContext('2d')
+ this.ctx.lineWidth = this.lineWidth
+ this.ctx.beginPath()
+ // 向线条的每个末端添加圆形线帽。
+ this.ctx.lineCap = 'round'
+ // 每次将数组中最后一个值取出,作为起始点
+ this.ctx.moveTo(this.ArrX[this.ArrX.length-1], this.ArrY[this.ArrY.length-1])
+ this.ctx.lineTo(e.touches[0].localX, e.touches[0].localY)
+ this.ctx.stroke()
+ this.ArrX.push(e.touches[0].localX)
+ this.ArrY.push(e.touches[0].localY)
+ this.oldoldLineWidth = this.oldLineWidth
+ this.oldLineWidth = this.lineWidth
+ },
+ touchend(e) {
+ this.startTime = 0,
+ this.lineWidth = 14,
+ this.oldLineWidth = 1,
+ this.oldoldLineWidth = 1
+ if (this.isRedo) {
+ this.openDialog()
+ this.ctx.clearRect(0, 0, this.width, this.height);
+ let canvasPic = new Image();
+ canvasPic.src = this.canvasHistory[this.step];
+ let that = this
+ canvasPic.onload = function () {
+ // 画上图片
+ that.ctx.drawImage(canvasPic, 0, 0);
+ };
+ this.isRedo = false
+ } else {
+ const el = this.$refs.canvas;
+ this.step++;
+ this.canvasHistory.push(el.toDataURL()); // 添加新的绘制到历史记录
+ }
+ },
+ formLine() {
+ this.ctx.strokeStyle = "red";
+
+ //画外层边框
+ this.ctx.beginPath();
+ this.ctx.moveTo(0, 0);
+ this.ctx.lineTo(this.width - 0, 0);
+ this.ctx.lineTo(this.width - 0, this.height - 0);
+ this.ctx.lineTo(3, this.height - 0);
+ this.ctx.closePath();
+ this.ctx.lineWidth = 6;
+ this.ctx.stroke();
+
+ //画米字格
+ this.ctx.beginPath();
+ this.ctx.moveTo(0, 0);
+ this.ctx.lineTo(this.width, this.height);
+
+ this.ctx.moveTo(this.width, 0);
+ this.ctx.lineTo(0, this.height);
+
+ this.ctx.moveTo(this.width / 2, 0);
+ this.ctx.lineTo(this.width / 2, this.height);
+
+ this.ctx.moveTo(0, this.height / 2);
+ this.ctx.lineTo(this.width, this.height / 2);
+
+ this.ctx.lineWidth = 1;
+ this.ctx.stroke();
+ this.ctx.restore();
+
+ },
+ saveBtn() {
+ const el = this.$refs.canvas2;
+ const ctx = el.getContext('2d')
+ let width = el.getBoundingClientRect().width;
+ let height = el.getBoundingClientRect().height;
+ ctx.clearRect(0, 0, width, height);
+ let index = this.canvasHistory.length - 1
+ this.saveImg = el.toDataURL();
+ let canvasPic = new Image();
+ canvasPic.src = this.canvasHistory[index];
+ ctx.scale(this.saveScale, this.saveScale);
+ this.saveScale = 1
+ canvasPic.onload = function () {
+ ctx.drawImage(canvasPic, 0, 0);
+ };
+ this.showRating()
+ this.showClear = true
+ this.showEraser = true
+ this.showSave = false
+ this.showUndo = true
+ this.showRedo = true
+ },
+ withdraw() {
+ this.ArrX.pop()
+ this.ArrY.pop()
+ },
+ clearBtn(e) {
+ this.ctx.clearRect(0, 0, this.width, this.height);
+ this.formLine()
+ this.getBgcImage()
+
+ // 情况小画板
+
+ const el = this.$refs.canvas2;
+ const ctx = el.getContext('2d')
+ let width = el.getBoundingClientRect().width;
+ let height = el.getBoundingClientRect().height;
+ ctx.clearRect(0, 0, width * 2, height * 2);
+ this.pathIndex = 0
+ this.isRating = false
+ this.rating = 5 // 评分等级
+ this.showClear = false
+ this.showEraser = true
+ this.showSave = true
+ this.showUndo = true
+ this.showRedo = true
+ },
+ getBgcImage() {
+ const el = this.$refs.canvas;
+ this.ctx = el.getContext('2d')
+ this.width = el.getBoundingClientRect().width;
+ this.height = el.getBoundingClientRect().height;
+ // 创建图片对象
+ let img = new Image();
+ // 设置图片路径
+ img.src = 'common/images/liu5.png';
+ let that = this
+ img.onload = function () {
+ // 画上图片
+ that.ctx.drawImage(img, 0, 0, this.width, this.height);
+ };
+ },
+ showEditor() {
+ },
+ undo() {
+ if (this.step >= 1) {
+ this.step--;
+ this.ctx.clearRect(0, 0, this.width, this.height);
+ let canvasPic = new Image();
+ canvasPic.src = this.canvasHistory[this.step];
+ let that = this
+ canvasPic.onload = function () {
+ that.ctx.drawImage(canvasPic, 0, 0);
+ };
+ this.pathIndex--
+ } else {
+ this.$element('dialogId').show()
+ prompt.showToast({
+ message: '不能再继续撤销了'
+ })
+ }
+
+ this.showClear = true
+ this.showEraser = true
+ this.showSave = true
+ this.showUndo = false
+ this.showRedo = true
+ },
+ redo() {
+ if (this.step < this.canvasHistory.length - 1) {
+ this.step++;
+ let canvasPic = new Image();
+ canvasPic.src = this.canvasHistory[this.step];
+ let that = this
+ canvasPic.onload = function () {
+ that.ctx.clearRect(0, 0, this.width, this.height);
+ that.ctx.drawImage(canvasPic, 0, 0);
+ };
+ this.pathIndex++
+ } else {
+ this.$element('dialogId').show()
+ prompt.showToast({
+ message: '已经是最新的记录了'
+ })
+ }
+
+ this.showClear = true
+ this.showEraser = true
+ this.showSave = true
+ this.showUndo = true
+ this.showRedo = false
+ },
+
+ openDialog() {
+ this.$element('dialogId').show()
+ prompt.showToast({
+ message: '笔画不对,再来一次!'
+ })
+ },
+ foldTop() {
+ this.foldT = !this.foldT
+ },
+ showhintDialog(e) {
+ this.$element('hintDialog').show()
+ this.showRead = false
+ },
+ sethintDialog(e) {
+ this.$element('hintDialog').close()
+ this.showRead = true
+ },
+ // 动画
+ Show() {
+ if (this.isAnimator == 'translate') {
+ this.isAnimator = 'translateR'
+ } else {
+ this.isAnimator = 'translate'
+ }
+ var options1 = {
+ duration: 1000,
+ fill: 'forwards',
+ iterations: 2,
+ begin: 200.0,
+ end: 500.0
+ };
+ this.animator.update(options1);
+ var _this = this;
+ this.animator.onframe = function (value) {
+ _this.divWidth = value;
+ };
+ if (this.isAnimator) {
+ this.animator.reverse();
+ } else {
+ this.animator.play();
+ }
+ },
+ stepperFinish() {
+ this.isStepper = false
+ },
+ showStepper() {
+ this.isStepper = true
+ },
+ // 搜索功能
+ search(e) {
+ prompt.showToast({
+ message: e.value,
+ duration: 3000,
+ });
+ },
+ translate(e) {
+ prompt.showToast({
+ message: e.value,
+ duration: 3000,
+ });
+ },
+ share(e) {
+ prompt.showToast({
+ message: e.value,
+ duration: 3000,
+ });
+ },
+ change(e) {
+ prompt.showToast({
+ message: e.value,
+ duration: 3000,
+ });
+ },
+ submit(e) {
+ router.push({
+ uri: 'pages/serch/serch',
+ });
+ },
+ showRating() {
+ this.isRating = true
+ if (this.lastRating !== null) {
+ if (this.rating >= lastRating) {
+ this.showRatingTip = '太棒了!再接再厉!'
+ } else {
+ this.showRatingTip = '加油你能做的更好!'
+ }
+ }
+ },
+ colorBtn() {
+ this.color = 'colorR'
+ },
+
+ clearBtnEnd() {
+ this.canvasHistory = []
+ this.step = -1
+ this.showClear = true
+ },
+ EraserBtn() {
+ this.isEraser = !this.isEraser
+ this.showClear = true
+ this.showEraser = !this.showEraser
+ this.showSave = true
+ this.showUndo = true
+ this.showRedo = true
+ },
+ saveBtnEnd() {
+ this.showClear = true
+ this.showEraser = true
+ this.showSave = true
+ this.showUndo = true
+ this.showRedo = true
+ },
+ undoEnd() {
+ this.showClear = true
+ this.showEraser = true
+ this.showSave = true
+ this.showUndo = true
+ this.showRedo = true
+ },
+ redoEnd() {
+ this.showClear = true
+ this.showEraser = true
+ this.showSave = true
+ this.showUndo = true
+ this.showRedo = true
+ },
+}
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/components/layout/layout.css b/FA/writingPad/entry/src/main/js/MainAbility/common/components/layout/layout.css
new file mode 100644
index 0000000000000000000000000000000000000000..4ea5e1da725f1b738880307c7f5802e872c11082
--- /dev/null
+++ b/FA/writingPad/entry/src/main/js/MainAbility/common/components/layout/layout.css
@@ -0,0 +1,60 @@
+.container {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+}
+
+
+tab-content {
+ width: 100%;
+ height: 100%;
+}
+
+tab-bar {
+ height: 100px;
+ width: 100%;
+ padding: 0;
+ padding-top: 4px;
+}
+
+.b-item-cont {
+ height: 150px;
+ width: 150px;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ position: relative;
+
+}
+
+.b-item-cont div {
+ width: 100%;
+ height: 48px;
+ display: flex;
+ justify-content: center;
+
+}
+
+.b-item-cont div image {
+ width: 42px;
+}
+
+.b-item-cont .b-item-tite {
+ padding-top: 9px;
+ text-align: center;
+
+}
+
+
+@media screen and (device-type: phone) and (orientation: landscape) {
+
+}
+
+@media screen and (device-type: tablet) and (orientation: landscape) {
+
+}
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/components/layout/layout.hml b/FA/writingPad/entry/src/main/js/MainAbility/common/components/layout/layout.hml
new file mode 100644
index 0000000000000000000000000000000000000000..2916d30c81faa3c9bc42578d10c2df00d58e7134
--- /dev/null
+++ b/FA/writingPad/entry/src/main/js/MainAbility/common/components/layout/layout.hml
@@ -0,0 +1,24 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ $item.title }}
+
+
+
+
+
+
+
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/components/layout/layout.js b/FA/writingPad/entry/src/main/js/MainAbility/common/components/layout/layout.js
new file mode 100644
index 0000000000000000000000000000000000000000..6abda8c824f5fdfc95ca71b0f5d1ed6b6dc2c72a
--- /dev/null
+++ b/FA/writingPad/entry/src/main/js/MainAbility/common/components/layout/layout.js
@@ -0,0 +1,70 @@
+export default {
+ props: {
+ iconBaseUrl: {
+ default: "common/images/icon/"
+ },
+ activeBaseUrl: {
+ default: "common/images/icon_active/"
+ },
+ menu: {
+ default: [
+ {
+ icon: "brush.png",
+ active: "brush_active.png",
+ title: "练字"
+ },
+ {
+ icon: "palette.png",
+ active: "palette_active.png",
+ title: "绘画"
+ },
+ {
+ icon: "book.png",
+ active: "book_active.png",
+ title: "笔记"
+ }
+ ]
+ },
+ menuCustomStyle: {
+ default: {
+ activeColor: "#ffC300",
+ backgroundColor: "#fff",
+ fontSize: "25px",
+ color: "#343434"
+ }
+ },
+ backgroundColor: {
+ default: "#f7f5fb"
+ }
+ },
+ data() {
+ return {
+ imgUrl: []
+ }
+ },
+ changePage(e) { //发生change事件时,根据当前页数来激活
+
+ for (let i = 0; i < this.imgUrl.length; i++) {
+ if (!this.imgUrl[i].show) continue;
+ this.imgUrl[i].show = false;
+ }
+ this.imgUrl[e.index].show = true;
+
+ this.$emit("childLayoutChange", this.imgUrl[e.index].title);
+ },
+ onInit() {
+ for (let index = 0; index < 3; index++) { //初始化导航
+ let show = index === 0 ? true : false;
+ let temp = {
+ ...this.menu[index],
+ show
+ }
+ this.imgUrl.push(temp)
+
+ }
+ },
+ onReady() {
+
+ // console.log(this.$refs["tes"]);
+ }
+}
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/Wallpaper.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/Wallpaper.png
new file mode 100644
index 0000000000000000000000000000000000000000..60d4841a80eb20c63de74306cb7f8350d6a85c48
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/Wallpaper.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/book.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/book.png
new file mode 100644
index 0000000000000000000000000000000000000000..fa93373815d8f77dda36a5f2d18ab3b499a93323
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/book.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/brush.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/brush.png
new file mode 100644
index 0000000000000000000000000000000000000000..17a93a4b5f18c5d1d75fe4cb02af0dfa6046dfa2
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/brush.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/clear.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/clear.png
new file mode 100644
index 0000000000000000000000000000000000000000..ed38b1574416efb583ec8edae86b5f0d03b4aaad
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/clear.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/eraser.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/eraser.png
new file mode 100644
index 0000000000000000000000000000000000000000..2167bf74052be9aa3ae20e0c1f36033745cb7600
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/eraser.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/fontSize.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/fontSize.png
new file mode 100644
index 0000000000000000000000000000000000000000..df30e3755826a23beac6244331dc57d868963356
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/fontSize.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/gerenwenzhangxiao.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/gerenwenzhangxiao.png
new file mode 100644
index 0000000000000000000000000000000000000000..e6dc5f651ed94ff9510f2d89b5c8751a02a18744
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/gerenwenzhangxiao.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/help.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/help.png
new file mode 100644
index 0000000000000000000000000000000000000000..b935235a830201fde8e83a7d903bb67a92d0d3bd
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/help.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/liuyan.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/liuyan.png
new file mode 100644
index 0000000000000000000000000000000000000000..e671cfc584fa524097f401fb545ecaa73e9d7011
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/liuyan.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/node.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/node.png
new file mode 100644
index 0000000000000000000000000000000000000000..e2996421dcac81e9b7649a1dc7a7179721be5fdf
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/node.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/palette.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/palette.png
new file mode 100644
index 0000000000000000000000000000000000000000..c93bd63f42ab2f8945a54b6188a9b017521bd255
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/palette.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/read.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/read.png
new file mode 100644
index 0000000000000000000000000000000000000000..1dc8bf1e13b91194b5c9aea1f6aa72914fba5283
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/read.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/redo.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/redo.png
new file mode 100644
index 0000000000000000000000000000000000000000..c7570db385f05353be04436234870d8de26bbf25
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/redo.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/right.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/right.png
new file mode 100644
index 0000000000000000000000000000000000000000..60a9ee02b398067304ebaa815859260c8556f3ef
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/right.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/save.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/save.png
new file mode 100644
index 0000000000000000000000000000000000000000..3f49eabc1a4e270a60020479e2eb84bf4a1a7695
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/save.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/shangyiye.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/shangyiye.png
new file mode 100644
index 0000000000000000000000000000000000000000..ffaea5dd84f4ba6ba7be4a5a70bf64c241ef4b57
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/shangyiye.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/undo.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/undo.png
new file mode 100644
index 0000000000000000000000000000000000000000..0bfdca0af72890e0eb4cf7a715cd6f70fca60a23
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/undo.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/xiayiye.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/xiayiye.png
new file mode 100644
index 0000000000000000000000000000000000000000..434756bb36cf1a5bcbd9ffc0d44e4f731dc0fd2b
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon/xiayiye.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/active_gerenwenzhangxiao.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/active_gerenwenzhangxiao.png
new file mode 100644
index 0000000000000000000000000000000000000000..dac2ccb682f9535c6c4234847baa0530791e0b97
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/active_gerenwenzhangxiao.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/active_help.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/active_help.png
new file mode 100644
index 0000000000000000000000000000000000000000..3cafe79cb0744089de4863262eff38c8b4fb374d
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/active_help.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/active_shangyiye.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/active_shangyiye.png
new file mode 100644
index 0000000000000000000000000000000000000000..bed393a5b0fdf1c6fc6bd6919af61b7a1176321f
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/active_shangyiye.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/active_tiaozhuan.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/active_tiaozhuan.png
new file mode 100644
index 0000000000000000000000000000000000000000..3a933de2bc4418692d95fbed3c540d659bbd80a6
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/active_tiaozhuan.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/active_xiayiye.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/active_xiayiye.png
new file mode 100644
index 0000000000000000000000000000000000000000..c88a639b6c0e861d3026774fc3eaf6089d5e9541
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/active_xiayiye.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/book_active.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/book_active.png
new file mode 100644
index 0000000000000000000000000000000000000000..46fa9cb6c5d99943342e22b2b9e2fb78a84a58c6
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/book_active.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/brush_active.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/brush_active.png
new file mode 100644
index 0000000000000000000000000000000000000000..e031cc1680490d084e9a90528247108a15e7551c
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/brush_active.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/clear_active.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/clear_active.png
new file mode 100644
index 0000000000000000000000000000000000000000..5986142e6bba174b3b296e0f7aad9f32be8e4316
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/clear_active.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/eraser_active.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/eraser_active.png
new file mode 100644
index 0000000000000000000000000000000000000000..a7b1bbed0bd128f71eb91c72f31170bc7ca90e26
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/eraser_active.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/palette_active.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/palette_active.png
new file mode 100644
index 0000000000000000000000000000000000000000..b4a82f4bb172d93e8e3d41d74d8e0882f072b325
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/palette_active.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/read_active.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/read_active.png
new file mode 100644
index 0000000000000000000000000000000000000000..5294a281b0cba8d26a00c480d90e44b81b78154b
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/read_active.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/redo_active.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/redo_active.png
new file mode 100644
index 0000000000000000000000000000000000000000..00d6abca2a031ad6c4e579db34f96a21ffd30fba
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/redo_active.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/save_active.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/save_active.png
new file mode 100644
index 0000000000000000000000000000000000000000..26572768ad4f7dd7f080f8524d5a077ed2788b63
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/save_active.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/undo_active.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/undo_active.png
new file mode 100644
index 0000000000000000000000000000000000000000..2506f8622ffe316115b34135a1148e3f339c3a29
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/icon_active/undo_active.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/liu.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/liu.png
new file mode 100644
index 0000000000000000000000000000000000000000..7af01acd13501b7d20b43baca9f9b96b466dcace
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/liu.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/liu2.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/liu2.png
new file mode 100644
index 0000000000000000000000000000000000000000..dae32b5ee6a975a73c97fc4d3e190650eb99ff9d
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/liu2.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/liu3.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/liu3.png
new file mode 100644
index 0000000000000000000000000000000000000000..b6e2e569dfda4f5d4701934d9fac480e43d08a80
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/liu3.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/liu4.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/liu4.png
new file mode 100644
index 0000000000000000000000000000000000000000..c598e9c02cdf0a5577c1a02b9e196c2c96ca71af
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/liu4.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/common/images/liu5.png b/FA/writingPad/entry/src/main/js/MainAbility/common/images/liu5.png
new file mode 100644
index 0000000000000000000000000000000000000000..b561f35986439da750b123f56380e3efdffbe5d2
Binary files /dev/null and b/FA/writingPad/entry/src/main/js/MainAbility/common/images/liu5.png differ
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/i18n/en-US.json b/FA/writingPad/entry/src/main/js/MainAbility/i18n/en-US.json
new file mode 100644
index 0000000000000000000000000000000000000000..55561b83737c3c31d082fbfa11e5fc987a351104
--- /dev/null
+++ b/FA/writingPad/entry/src/main/js/MainAbility/i18n/en-US.json
@@ -0,0 +1,8 @@
+{
+ "strings": {
+ "hello": "Hello",
+ "world": "World"
+ },
+ "Files": {
+ }
+}
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/i18n/zh-CN.json b/FA/writingPad/entry/src/main/js/MainAbility/i18n/zh-CN.json
new file mode 100644
index 0000000000000000000000000000000000000000..cce1af06761a42add0cac1a0567aa3237eda8cb4
--- /dev/null
+++ b/FA/writingPad/entry/src/main/js/MainAbility/i18n/zh-CN.json
@@ -0,0 +1,8 @@
+{
+ "strings": {
+ "hello": "您好",
+ "world": "世界"
+ },
+ "Files": {
+ }
+}
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/pages/index/index.css b/FA/writingPad/entry/src/main/js/MainAbility/pages/index/index.css
new file mode 100644
index 0000000000000000000000000000000000000000..098977ad3640c3e3e37db7e8553be45ecca7fec9
--- /dev/null
+++ b/FA/writingPad/entry/src/main/js/MainAbility/pages/index/index.css
@@ -0,0 +1,4 @@
+.container {
+ height: 1920px;
+ width: 1080px;
+}
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/pages/index/index.hml b/FA/writingPad/entry/src/main/js/MainAbility/pages/index/index.hml
new file mode 100644
index 0000000000000000000000000000000000000000..7784fc01f5df733ab91509d7e9d9ec9821937f16
--- /dev/null
+++ b/FA/writingPad/entry/src/main/js/MainAbility/pages/index/index.hml
@@ -0,0 +1,18 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/main/js/MainAbility/pages/index/index.js b/FA/writingPad/entry/src/main/js/MainAbility/pages/index/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/FA/writingPad/entry/src/main/resources/base/element/color.json b/FA/writingPad/entry/src/main/resources/base/element/color.json
new file mode 100644
index 0000000000000000000000000000000000000000..1bbc9aa9617e97c45440e1d3d66afc1154837012
--- /dev/null
+++ b/FA/writingPad/entry/src/main/resources/base/element/color.json
@@ -0,0 +1,8 @@
+{
+ "color": [
+ {
+ "name": "white",
+ "value": "#FFFFFF"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/main/resources/base/element/string.json b/FA/writingPad/entry/src/main/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..490210a3908f47722dc942d49dacc98b97669a5f
--- /dev/null
+++ b/FA/writingPad/entry/src/main/resources/base/element/string.json
@@ -0,0 +1,16 @@
+{
+ "string": [
+ {
+ "name": "entry_desc",
+ "value": "description"
+ },
+ {
+ "name": "MainAbility_desc",
+ "value": "description"
+ },
+ {
+ "name": "MainAbility_label",
+ "value": "label"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/main/resources/base/media/icon.png b/FA/writingPad/entry/src/main/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/FA/writingPad/entry/src/main/resources/base/media/icon.png differ
diff --git a/FA/writingPad/entry/src/ohosTest/config.json b/FA/writingPad/entry/src/ohosTest/config.json
new file mode 100644
index 0000000000000000000000000000000000000000..1e1abb094a673c711966bb6aa8846a2968867e25
--- /dev/null
+++ b/FA/writingPad/entry/src/ohosTest/config.json
@@ -0,0 +1,67 @@
+{
+ "app": {
+ "bundleName": "com.example.myapplication",
+ "vendor": "example",
+ "version": {
+ "code": 1000000,
+ "name": "1.0.0"
+ }
+ },
+ "deviceConfig": {},
+ "module": {
+ "package": "com.example.entry_test",
+ "name": ".entry_test",
+ "mainAbility": ".TestAbility",
+ "srcPath": "",
+ "deviceType": [
+ "phone"
+ ],
+ "distro": {
+ "deliveryWithInstall": true,
+ "moduleName": "entry_test",
+ "moduleType": "feature",
+ "installationFree": false
+ },
+ "abilities": [
+ {
+ "skills": [
+ {
+ "entities": [
+ "entity.system.home"
+ ],
+ "actions": [
+ "action.system.home"
+ ]
+ }
+ ],
+ "orientation": "unspecified",
+ "formsEnabled": false,
+ "name": ".TestAbility",
+ "srcLanguage": "js",
+ "srcPath": "TestAbility",
+ "icon": "$media:icon",
+ "description": "$string:TestAbility_desc",
+ "label": "$string:TestAbility_label",
+ "type": "page",
+ "visible": true,
+ "launchType": "standard"
+ }
+ ],
+ "js": [
+ {
+ "pages": [
+ "pages/index/index"
+ ],
+ "name": ".TestAbility",
+ "window": {
+ "designWidth": 720,
+ "autoDesignWidth": false
+ }
+ }
+ ],
+ "testRunner": {
+ "name": "OpenHarmonyTestRunner",
+ "srcPath": "TestRunner"
+ }
+ }
+}
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/ohosTest/js/TestAbility/app.js b/FA/writingPad/entry/src/ohosTest/js/TestAbility/app.js
new file mode 100644
index 0000000000000000000000000000000000000000..9cb81cd2ff3e24ddb0a75d43932c880ac33d3223
--- /dev/null
+++ b/FA/writingPad/entry/src/ohosTest/js/TestAbility/app.js
@@ -0,0 +1,16 @@
+import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry'
+import { Hypium } from '@ohos/hypium'
+import testsuite from '../test/List.test'
+
+export default {
+ onCreate() {
+ console.info("TestApplication onCreate")
+ var abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
+ var abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
+ console.info('start run testcase!!!')
+ Hypium.hypiumTest(abilityDelegator, abilityDelegatorArguments, testsuite)
+ },
+ onDestroy() {
+ console.info("TestApplication onDestroy");
+ }
+};
diff --git a/FA/writingPad/entry/src/ohosTest/js/TestAbility/i18n/en-US.json b/FA/writingPad/entry/src/ohosTest/js/TestAbility/i18n/en-US.json
new file mode 100644
index 0000000000000000000000000000000000000000..55561b83737c3c31d082fbfa11e5fc987a351104
--- /dev/null
+++ b/FA/writingPad/entry/src/ohosTest/js/TestAbility/i18n/en-US.json
@@ -0,0 +1,8 @@
+{
+ "strings": {
+ "hello": "Hello",
+ "world": "World"
+ },
+ "Files": {
+ }
+}
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/ohosTest/js/TestAbility/i18n/zh-CN.json b/FA/writingPad/entry/src/ohosTest/js/TestAbility/i18n/zh-CN.json
new file mode 100644
index 0000000000000000000000000000000000000000..cce1af06761a42add0cac1a0567aa3237eda8cb4
--- /dev/null
+++ b/FA/writingPad/entry/src/ohosTest/js/TestAbility/i18n/zh-CN.json
@@ -0,0 +1,8 @@
+{
+ "strings": {
+ "hello": "您好",
+ "world": "世界"
+ },
+ "Files": {
+ }
+}
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/ohosTest/js/TestAbility/pages/index/index.css b/FA/writingPad/entry/src/ohosTest/js/TestAbility/pages/index/index.css
new file mode 100644
index 0000000000000000000000000000000000000000..502568f0751f5e40d9c6504b07f7ccd4f28c1767
--- /dev/null
+++ b/FA/writingPad/entry/src/ohosTest/js/TestAbility/pages/index/index.css
@@ -0,0 +1,30 @@
+.container {
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ align-items: center;
+ left: 0px;
+ top: 0px;
+ width: 100%;
+ height: 100%;
+}
+
+.title {
+ font-size: 60px;
+ text-align: center;
+ width: 100%;
+ height: 40%;
+ margin: 10px;
+}
+
+@media screen and (orientation: landscape) {
+ .title {
+ font-size: 60px;
+ }
+}
+
+@media screen and (device-type: tablet) and (orientation: landscape) {
+ .title {
+ font-size: 100px;
+ }
+}
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/ohosTest/js/TestAbility/pages/index/index.hml b/FA/writingPad/entry/src/ohosTest/js/TestAbility/pages/index/index.hml
new file mode 100644
index 0000000000000000000000000000000000000000..f64b040a5ae394dbaa5e185e1ecd4f4556b92184
--- /dev/null
+++ b/FA/writingPad/entry/src/ohosTest/js/TestAbility/pages/index/index.hml
@@ -0,0 +1,5 @@
+
+
+ {{ $t('strings.hello') }} {{ title }}
+
+
diff --git a/FA/writingPad/entry/src/ohosTest/js/TestAbility/pages/index/index.js b/FA/writingPad/entry/src/ohosTest/js/TestAbility/pages/index/index.js
new file mode 100644
index 0000000000000000000000000000000000000000..5cf79d7ab0d03baad69d333929f809451140ae3c
--- /dev/null
+++ b/FA/writingPad/entry/src/ohosTest/js/TestAbility/pages/index/index.js
@@ -0,0 +1,11 @@
+export default {
+ data: {
+ title: ""
+ },
+ onInit() {
+ this.title = this.$t('strings.world');
+ }
+}
+
+
+
diff --git a/FA/writingPad/entry/src/ohosTest/js/TestRunner/OpenHarmonyTestRunner.js b/FA/writingPad/entry/src/ohosTest/js/TestRunner/OpenHarmonyTestRunner.js
new file mode 100644
index 0000000000000000000000000000000000000000..6f6f10d017a742a2918b5bcfbf1e0b91c1465773
--- /dev/null
+++ b/FA/writingPad/entry/src/ohosTest/js/TestRunner/OpenHarmonyTestRunner.js
@@ -0,0 +1,43 @@
+import AbilityDelegatorRegistry from '@ohos.application.abilityDelegatorRegistry'
+
+function translateParamsToString(parameters) {
+ const keySet = new Set([
+ '-s class', '-s notClass', '-s suite', '-s itName',
+ '-s level', '-s testType', '-s size', '-s timeout',
+ '-s package', '-s dryRun'
+ ])
+ let targetParams = '';
+ for (const key in parameters) {
+ if (keySet.has(key)) {
+ targetParams += ' ' + key + ' ' + parameters[key]
+ }
+ }
+ return targetParams.trim()
+}
+
+ export default {
+ onPrepare() {
+ console.info('OpenHarmonyTestRunner OnPrepare')
+ },
+ onRun() {
+ console.log('OpenHarmonyTestRunner onRun run')
+ var abilityDelegatorArguments = AbilityDelegatorRegistry.getArguments()
+ var abilityDelegator = AbilityDelegatorRegistry.getAbilityDelegator()
+
+ var testAbilityName = abilityDelegatorArguments.parameters['-p'] + '.TestAbility'
+ var cmd = 'aa start -d 0 -a ' + testAbilityName + ' -b ' + abilityDelegatorArguments.bundleName
+ cmd += ' ' + translateParamsToString(abilityDelegatorArguments.parameters)
+ var debug = abilityDelegatorArguments.parameters["-D"]
+ console.info('debug value : '+debug)
+ if (debug == 'true')
+ {
+ cmd += ' -D'
+ }
+ console.info('cmd : '+cmd)
+ abilityDelegator.executeShellCommand(cmd, (err, data) => {
+ console.info('executeShellCommand : err : ' + JSON.stringify(err));
+ console.info('executeShellCommand : data : ' + data.stdResult);
+ console.info('executeShellCommand : data : ' + data.exitCode);
+ })
+ }
+};
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/ohosTest/js/test/Ability.test.js b/FA/writingPad/entry/src/ohosTest/js/test/Ability.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..5b993c8c472009088b4f3e188f72c4c8052761aa
--- /dev/null
+++ b/FA/writingPad/entry/src/ohosTest/js/test/Ability.test.js
@@ -0,0 +1,12 @@
+import {describe, beforeAll, beforeEach, afterEach, afterAll, it, expect, Assert} from '@ohos/hypium';
+
+export default function abilityTest() {
+ describe('ActsAbilityTest', function () {
+ it('assertContain',0, function () {
+ console.info("it begin")
+ let a = 'abc'
+ let b = 'b'
+ expect(a).assertContain(b)
+ })
+ })
+}
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/ohosTest/js/test/List.test.js b/FA/writingPad/entry/src/ohosTest/js/test/List.test.js
new file mode 100644
index 0000000000000000000000000000000000000000..63473a372ff63ec0e1130d7384b52b20c4321e9e
--- /dev/null
+++ b/FA/writingPad/entry/src/ohosTest/js/test/List.test.js
@@ -0,0 +1,5 @@
+import abilityTest from './ability.test'
+
+export default function testsuite() {
+ abilityTest()
+}
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/ohosTest/resources/base/element/string.json b/FA/writingPad/entry/src/ohosTest/resources/base/element/string.json
new file mode 100644
index 0000000000000000000000000000000000000000..3ddc84b17681377c0656b3b5f306ff4c5e0c3e44
--- /dev/null
+++ b/FA/writingPad/entry/src/ohosTest/resources/base/element/string.json
@@ -0,0 +1,12 @@
+{
+ "string": [
+ {
+ "name": "TestAbility_desc",
+ "value": "the test ability"
+ },
+ {
+ "name": "TestAbility_label",
+ "value": "test label"
+ }
+ ]
+}
\ No newline at end of file
diff --git a/FA/writingPad/entry/src/ohosTest/resources/base/media/icon.png b/FA/writingPad/entry/src/ohosTest/resources/base/media/icon.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce307a8827bd75456441ceb57d530e4c8d45d36c
Binary files /dev/null and b/FA/writingPad/entry/src/ohosTest/resources/base/media/icon.png differ
diff --git a/FA/writingPad/entry/src/ohosTest/resources/base/profile/test_pages.json b/FA/writingPad/entry/src/ohosTest/resources/base/profile/test_pages.json
new file mode 100644
index 0000000000000000000000000000000000000000..fcef82b4dfc18e28106ff9ecd1c8b48ec74d18a4
--- /dev/null
+++ b/FA/writingPad/entry/src/ohosTest/resources/base/profile/test_pages.json
@@ -0,0 +1,5 @@
+{
+ "src": [
+ "TestAbility/pages/index"
+ ]
+}
diff --git a/FA/writingPad/hvigorfile.js b/FA/writingPad/hvigorfile.js
new file mode 100644
index 0000000000000000000000000000000000000000..cff9f0dfcf8cb00cca34e7f50d61380cf5496868
--- /dev/null
+++ b/FA/writingPad/hvigorfile.js
@@ -0,0 +1,2 @@
+// Script for compiling build behavior. It is built in the build plug-in and cannot be modified currently.
+module.exports = require('@ohos/hvigor-ohos-plugin').legacyAppTasks
\ No newline at end of file
diff --git a/FA/writingPad/local.properties b/FA/writingPad/local.properties
new file mode 100644
index 0000000000000000000000000000000000000000..f91966fc95e9d08ce2f520e1bb2bc1216086a65f
--- /dev/null
+++ b/FA/writingPad/local.properties
@@ -0,0 +1,10 @@
+# This file is automatically generated by DevEco Studio.
+# Do not modify this file -- YOUR CHANGES WILL BE ERASED!
+#
+# This file should *NOT* be checked into Version Control Systems,
+# as it contains information specific to your local configuration.
+#
+# For customization when using a Version Control System, please read the header note.
+sdk.dir=C:/Users/Shinelon/AppData/Local/OpenHarmony/Sdk
+nodejs.dir=C:/Users/Shinelon/nodejs
+hwsdk.dir=C:/Users/Shinelon/AppData/Local/Huawei/Sdk
\ No newline at end of file
diff --git a/FA/writingPad/package-lock.json b/FA/writingPad/package-lock.json
new file mode 100644
index 0000000000000000000000000000000000000000..15ddbb5772c74bcca0aa5a3db9475843c1f73423
--- /dev/null
+++ b/FA/writingPad/package-lock.json
@@ -0,0 +1,1227 @@
+{
+ "name": "myapplication",
+ "version": "1.0.0",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "@ohos/hos-sdkmanager-common": {
+ "version": "1.0.4",
+ "resolved": "https://repo.harmonyos.com/npm/@ohos/hos-sdkmanager-common/-/@ohos/hos-sdkmanager-common-1.0.4.tgz",
+ "integrity": "sha512-LWrfF8Js+u54BcEAdyjzsA81iGBA4LPvQdQ1ig/pX6mvTieUPSvtjtAzdI8nnGVmJRLrHwAMHEO/syd9d8UAFw==",
+ "requires": {
+ "@ohos/sdkmanager-common": "^1.1.8"
+ }
+ },
+ "@ohos/hvigor": {
+ "version": "1.1.6",
+ "resolved": "https://repo.harmonyos.com/npm/@ohos/hvigor/-/@ohos/hvigor-1.1.6.tgz",
+ "integrity": "sha512-/n7cSH3Tc1p5CEgELeJof2MLBYbu96Enmkga8PA1BFoBZnPF+SirHwJyynhtUtOJQOyFkBFQOXmwzq5o2Pdvug==",
+ "requires": {
+ "@ohos/hvigor-base": "1.1.6",
+ "fs-extra": "10.0.0",
+ "interpret": "1.4.0",
+ "liftoff": "4.0.0",
+ "mute-stdout": "1.0.0",
+ "pretty-hrtime": "1.0.0",
+ "v8flags": "3.2.0",
+ "yargs": "7.1.2"
+ }
+ },
+ "@ohos/hvigor-base": {
+ "version": "1.1.6",
+ "resolved": "https://repo.harmonyos.com/npm/@ohos/hvigor-base/-/@ohos/hvigor-base-1.1.6.tgz",
+ "integrity": "sha512-VU1jdgb+86RZ6fsea1kKP3Dx77DAQmSwGQoFEpjRVPP6aLXpRfM8aLS8DNlpMVEw1dFVQhOOsZ22thcbxinSOA==",
+ "requires": {
+ "json5": "2.2.0",
+ "log4js": "6.4.1",
+ "once": "1.4.0",
+ "pretty-hrtime": "1.0.0"
+ }
+ },
+ "@ohos/hvigor-ohos-plugin": {
+ "version": "1.1.6",
+ "resolved": "https://repo.harmonyos.com/npm/@ohos/hvigor-ohos-plugin/-/@ohos/hvigor-ohos-plugin-1.1.6.tgz",
+ "integrity": "sha512-Bnm1932VypATJf/Cp+sTzsX/oHFojAW7dAbEgfQpwQsyXmQbwXEf0zGnbrjVD0WKtxVVpO+znhpZvrDhOiUXlg==",
+ "requires": {
+ "@ohos/hos-sdkmanager-common": "1.0.4",
+ "@ohos/hvigor-base": "1.1.6",
+ "@ohos/sdkmanager-common": "1.1.8",
+ "adm-zip": "0.5.9",
+ "ajv": "8.10.0",
+ "execa": "5.1.1",
+ "fast-xml-parser": "4.0.3",
+ "fs-extra": "10.0.0",
+ "glob": "7.2.0",
+ "iconv-lite": "0.6.3",
+ "json5": "2.2.0",
+ "lodash": "4.17.21",
+ "pretty-hrtime": "1.0.3",
+ "resolve-package-path": "4.0.3"
+ },
+ "dependencies": {
+ "pretty-hrtime": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
+ "integrity": "sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A=="
+ }
+ }
+ },
+ "@ohos/hypium": {
+ "version": "1.0.1",
+ "resolved": "https://repo.harmonyos.com/npm/@ohos/hypium/-/@ohos/hypium-1.0.1.tgz",
+ "integrity": "sha512-HaztFbgwYZCdVlayXirBlmJaNTXUO65qRgYnUmrhWGEzG7wFU2fyFbeXgQeYMVWFXgeezFOoHAPoS96TEE7TIQ=="
+ },
+ "@ohos/sdkmanager-common": {
+ "version": "1.1.8",
+ "resolved": "https://repo.harmonyos.com/npm/@ohos/sdkmanager-common/-/@ohos/sdkmanager-common-1.1.8.tgz",
+ "integrity": "sha512-mxq69+6Zg/ybeQGnOtkBzOTbNBkEdiYehRKWsAD/je53v1W+ahauLqe90pNZEiBuVYugzb6z2EaJtAXYZtE8gQ=="
+ },
+ "adm-zip": {
+ "version": "0.5.9",
+ "resolved": "https://registry.npmmirror.com/adm-zip/-/adm-zip-0.5.9.tgz",
+ "integrity": "sha512-s+3fXLkeeLjZ2kLjCBwQufpI5fuN+kIGBxu6530nVQZGVol0d7Y/M88/xw9HGGUcJjKf8LutN3VPRUBq6N7Ajg=="
+ },
+ "ajv": {
+ "version": "8.10.0",
+ "resolved": "https://registry.npmmirror.com/ajv/-/ajv-8.10.0.tgz",
+ "integrity": "sha512-bzqAEZOjkrUMl2afH8dknrq5KEk2SrwdBROR+vH1EKVQTqaUbJVPdc/gEdggTMM0Se+s+Ja4ju4TlNcStKl2Hw==",
+ "requires": {
+ "fast-deep-equal": "^3.1.1",
+ "json-schema-traverse": "^1.0.0",
+ "require-from-string": "^2.0.2",
+ "uri-js": "^4.2.2"
+ }
+ },
+ "ansi-regex": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmmirror.com/ansi-regex/-/ansi-regex-2.1.1.tgz",
+ "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA=="
+ },
+ "array-each": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/array-each/-/array-each-1.0.1.tgz",
+ "integrity": "sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA=="
+ },
+ "array-slice": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/array-slice/-/array-slice-1.1.0.tgz",
+ "integrity": "sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w=="
+ },
+ "balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
+ },
+ "brace-expansion": {
+ "version": "1.1.11",
+ "resolved": "https://registry.npmmirror.com/brace-expansion/-/brace-expansion-1.1.11.tgz",
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
+ "requires": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "braces": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmmirror.com/braces/-/braces-3.0.2.tgz",
+ "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
+ "requires": {
+ "fill-range": "^7.0.1"
+ }
+ },
+ "call-bind": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/call-bind/-/call-bind-1.0.2.tgz",
+ "integrity": "sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==",
+ "requires": {
+ "function-bind": "^1.1.1",
+ "get-intrinsic": "^1.0.2"
+ }
+ },
+ "camelcase": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/camelcase/-/camelcase-3.0.0.tgz",
+ "integrity": "sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg=="
+ },
+ "cliui": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmmirror.com/cliui/-/cliui-3.2.0.tgz",
+ "integrity": "sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==",
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1",
+ "wrap-ansi": "^2.0.0"
+ }
+ },
+ "code-point-at": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/code-point-at/-/code-point-at-1.1.0.tgz",
+ "integrity": "sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA=="
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmmirror.com/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
+ },
+ "cross-spawn": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmmirror.com/cross-spawn/-/cross-spawn-7.0.3.tgz",
+ "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==",
+ "requires": {
+ "path-key": "^3.1.0",
+ "shebang-command": "^2.0.0",
+ "which": "^2.0.1"
+ },
+ "dependencies": {
+ "which": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/which/-/which-2.0.2.tgz",
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ }
+ }
+ },
+ "date-format": {
+ "version": "4.0.13",
+ "resolved": "https://registry.npmmirror.com/date-format/-/date-format-4.0.13.tgz",
+ "integrity": "sha512-bnYCwf8Emc3pTD8pXnre+wfnjGtfi5ncMDKy7+cWZXbmRAsdWkOQHrfC1yz/KiwP5thDp2kCHWYWKBX4HP1hoQ=="
+ },
+ "debug": {
+ "version": "4.3.4",
+ "resolved": "https://registry.npmmirror.com/debug/-/debug-4.3.4.tgz",
+ "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==",
+ "requires": {
+ "ms": "2.1.2"
+ }
+ },
+ "decamelize": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmmirror.com/decamelize/-/decamelize-1.2.0.tgz",
+ "integrity": "sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA=="
+ },
+ "define-properties": {
+ "version": "1.1.4",
+ "resolved": "https://registry.npmmirror.com/define-properties/-/define-properties-1.1.4.tgz",
+ "integrity": "sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==",
+ "requires": {
+ "has-property-descriptors": "^1.0.0",
+ "object-keys": "^1.1.1"
+ }
+ },
+ "detect-file": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/detect-file/-/detect-file-1.0.0.tgz",
+ "integrity": "sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q=="
+ },
+ "error-ex": {
+ "version": "1.3.2",
+ "resolved": "https://registry.npmmirror.com/error-ex/-/error-ex-1.3.2.tgz",
+ "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
+ "requires": {
+ "is-arrayish": "^0.2.1"
+ }
+ },
+ "execa": {
+ "version": "5.1.1",
+ "resolved": "https://registry.npmmirror.com/execa/-/execa-5.1.1.tgz",
+ "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
+ "requires": {
+ "cross-spawn": "^7.0.3",
+ "get-stream": "^6.0.0",
+ "human-signals": "^2.1.0",
+ "is-stream": "^2.0.0",
+ "merge-stream": "^2.0.0",
+ "npm-run-path": "^4.0.1",
+ "onetime": "^5.1.2",
+ "signal-exit": "^3.0.3",
+ "strip-final-newline": "^2.0.0"
+ }
+ },
+ "expand-tilde": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/expand-tilde/-/expand-tilde-2.0.2.tgz",
+ "integrity": "sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==",
+ "requires": {
+ "homedir-polyfill": "^1.0.1"
+ }
+ },
+ "extend": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmmirror.com/extend/-/extend-3.0.2.tgz",
+ "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g=="
+ },
+ "fast-deep-equal": {
+ "version": "3.1.3",
+ "resolved": "https://registry.npmmirror.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
+ "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="
+ },
+ "fast-xml-parser": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmmirror.com/fast-xml-parser/-/fast-xml-parser-4.0.3.tgz",
+ "integrity": "sha512-xhQbg3a/EYNHwK0cxIG1nZmVkHX/0tWihamn5pU4Mhd9KEVE2ga8ZJiqEUgB2sApElvAATOdMTLjgqIpvYDUkQ==",
+ "requires": {
+ "strnum": "^1.0.5"
+ }
+ },
+ "fill-range": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmmirror.com/fill-range/-/fill-range-7.0.1.tgz",
+ "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
+ "requires": {
+ "to-regex-range": "^5.0.1"
+ }
+ },
+ "find-up": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/find-up/-/find-up-1.1.2.tgz",
+ "integrity": "sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==",
+ "requires": {
+ "path-exists": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "findup-sync": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/findup-sync/-/findup-sync-5.0.0.tgz",
+ "integrity": "sha512-MzwXju70AuyflbgeOhzvQWAvvQdo1XL0A9bVvlXsYcFEBM87WR4OakL4OfZq+QRmr+duJubio+UtNQCPsVESzQ==",
+ "requires": {
+ "detect-file": "^1.0.0",
+ "is-glob": "^4.0.3",
+ "micromatch": "^4.0.4",
+ "resolve-dir": "^1.0.1"
+ }
+ },
+ "fined": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/fined/-/fined-2.0.0.tgz",
+ "integrity": "sha512-OFRzsL6ZMHz5s0JrsEr+TpdGNCtrVtnuG3x1yzGNiQHT0yaDnXAj8V/lWcpJVrnoDpcwXcASxAZYbuXda2Y82A==",
+ "requires": {
+ "expand-tilde": "^2.0.2",
+ "is-plain-object": "^5.0.0",
+ "object.defaults": "^1.1.0",
+ "object.pick": "^1.3.0",
+ "parse-filepath": "^1.0.2"
+ }
+ },
+ "flagged-respawn": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/flagged-respawn/-/flagged-respawn-2.0.0.tgz",
+ "integrity": "sha512-Gq/a6YCi8zexmGHMuJwahTGzXlAZAOsbCVKduWXC6TlLCjjFRlExMJc4GC2NYPYZ0r/brw9P7CpRgQmlPVeOoA=="
+ },
+ "flatted": {
+ "version": "3.2.6",
+ "resolved": "https://registry.npmmirror.com/flatted/-/flatted-3.2.6.tgz",
+ "integrity": "sha512-0sQoMh9s0BYsm+12Huy/rkKxVu4R1+r96YX5cG44rHV0pQ6iC3Q+mkoMFaGWObMFYQxCVT+ssG1ksneA2MI9KQ=="
+ },
+ "for-in": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/for-in/-/for-in-1.0.2.tgz",
+ "integrity": "sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ=="
+ },
+ "for-own": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/for-own/-/for-own-1.0.0.tgz",
+ "integrity": "sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==",
+ "requires": {
+ "for-in": "^1.0.1"
+ }
+ },
+ "fs-extra": {
+ "version": "10.0.0",
+ "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-10.0.0.tgz",
+ "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==",
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^6.0.1",
+ "universalify": "^2.0.0"
+ },
+ "dependencies": {
+ "jsonfile": {
+ "version": "6.1.0",
+ "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-6.1.0.tgz",
+ "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
+ "requires": {
+ "graceful-fs": "^4.1.6",
+ "universalify": "^2.0.0"
+ }
+ },
+ "universalify": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/universalify/-/universalify-2.0.0.tgz",
+ "integrity": "sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ=="
+ }
+ }
+ },
+ "fs.realpath": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/fs.realpath/-/fs.realpath-1.0.0.tgz",
+ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
+ },
+ "function-bind": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/function-bind/-/function-bind-1.1.1.tgz",
+ "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A=="
+ },
+ "get-caller-file": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/get-caller-file/-/get-caller-file-1.0.3.tgz",
+ "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w=="
+ },
+ "get-intrinsic": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmmirror.com/get-intrinsic/-/get-intrinsic-1.1.2.tgz",
+ "integrity": "sha512-Jfm3OyCxHh9DJyc28qGk+JmfkpO41A4XkneDSujN9MDXrm4oDKdHvndhZ2dN94+ERNfkYJWDclW6k2L/ZGHjXA==",
+ "requires": {
+ "function-bind": "^1.1.1",
+ "has": "^1.0.3",
+ "has-symbols": "^1.0.3"
+ }
+ },
+ "get-stream": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmmirror.com/get-stream/-/get-stream-6.0.1.tgz",
+ "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg=="
+ },
+ "glob": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmmirror.com/glob/-/glob-7.2.0.tgz",
+ "integrity": "sha512-lmLf6gtyrPq8tTjSmrO94wBeQbFR3HbLHbuyD69wuyQkImp2hWqMGB47OX65FBkPffO641IP9jWa1z4ivqG26Q==",
+ "requires": {
+ "fs.realpath": "^1.0.0",
+ "inflight": "^1.0.4",
+ "inherits": "2",
+ "minimatch": "^3.0.4",
+ "once": "^1.3.0",
+ "path-is-absolute": "^1.0.0"
+ }
+ },
+ "global-modules": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/global-modules/-/global-modules-1.0.0.tgz",
+ "integrity": "sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==",
+ "requires": {
+ "global-prefix": "^1.0.1",
+ "is-windows": "^1.0.1",
+ "resolve-dir": "^1.0.0"
+ }
+ },
+ "global-prefix": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/global-prefix/-/global-prefix-1.0.2.tgz",
+ "integrity": "sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==",
+ "requires": {
+ "expand-tilde": "^2.0.2",
+ "homedir-polyfill": "^1.0.1",
+ "ini": "^1.3.4",
+ "is-windows": "^1.0.1",
+ "which": "^1.2.14"
+ }
+ },
+ "graceful-fs": {
+ "version": "4.2.10",
+ "resolved": "https://registry.npmmirror.com/graceful-fs/-/graceful-fs-4.2.10.tgz",
+ "integrity": "sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA=="
+ },
+ "has": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/has/-/has-1.0.3.tgz",
+ "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==",
+ "requires": {
+ "function-bind": "^1.1.1"
+ }
+ },
+ "has-property-descriptors": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/has-property-descriptors/-/has-property-descriptors-1.0.0.tgz",
+ "integrity": "sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==",
+ "requires": {
+ "get-intrinsic": "^1.1.1"
+ }
+ },
+ "has-symbols": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/has-symbols/-/has-symbols-1.0.3.tgz",
+ "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A=="
+ },
+ "homedir-polyfill": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmmirror.com/homedir-polyfill/-/homedir-polyfill-1.0.3.tgz",
+ "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==",
+ "requires": {
+ "parse-passwd": "^1.0.0"
+ }
+ },
+ "hosted-git-info": {
+ "version": "2.8.9",
+ "resolved": "https://registry.npmmirror.com/hosted-git-info/-/hosted-git-info-2.8.9.tgz",
+ "integrity": "sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw=="
+ },
+ "human-signals": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/human-signals/-/human-signals-2.1.0.tgz",
+ "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw=="
+ },
+ "iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmmirror.com/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "requires": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ }
+ },
+ "inflight": {
+ "version": "1.0.6",
+ "resolved": "https://registry.npmmirror.com/inflight/-/inflight-1.0.6.tgz",
+ "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
+ "requires": {
+ "once": "^1.3.0",
+ "wrappy": "1"
+ }
+ },
+ "inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmmirror.com/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="
+ },
+ "ini": {
+ "version": "1.3.8",
+ "resolved": "https://registry.npmmirror.com/ini/-/ini-1.3.8.tgz",
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew=="
+ },
+ "interpret": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/interpret/-/interpret-1.4.0.tgz",
+ "integrity": "sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA=="
+ },
+ "invert-kv": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/invert-kv/-/invert-kv-1.0.0.tgz",
+ "integrity": "sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ=="
+ },
+ "is-absolute": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/is-absolute/-/is-absolute-1.0.0.tgz",
+ "integrity": "sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==",
+ "requires": {
+ "is-relative": "^1.0.0",
+ "is-windows": "^1.0.1"
+ }
+ },
+ "is-arrayish": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmmirror.com/is-arrayish/-/is-arrayish-0.2.1.tgz",
+ "integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg=="
+ },
+ "is-core-module": {
+ "version": "2.9.0",
+ "resolved": "https://registry.npmmirror.com/is-core-module/-/is-core-module-2.9.0.tgz",
+ "integrity": "sha512-+5FPy5PnwmO3lvfMb0AsoPaBG+5KHUI0wYFXOtYPnVVVspTFUuMZNfNaNVRt3FZadstu2c8x23vykRW/NBoU6A==",
+ "requires": {
+ "has": "^1.0.3"
+ }
+ },
+ "is-extglob": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmmirror.com/is-extglob/-/is-extglob-2.1.1.tgz",
+ "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="
+ },
+ "is-fullwidth-code-point": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz",
+ "integrity": "sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==",
+ "requires": {
+ "number-is-nan": "^1.0.0"
+ }
+ },
+ "is-glob": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmmirror.com/is-glob/-/is-glob-4.0.3.tgz",
+ "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
+ "requires": {
+ "is-extglob": "^2.1.1"
+ }
+ },
+ "is-number": {
+ "version": "7.0.0",
+ "resolved": "https://registry.npmmirror.com/is-number/-/is-number-7.0.0.tgz",
+ "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
+ },
+ "is-plain-object": {
+ "version": "5.0.0",
+ "resolved": "https://registry.npmmirror.com/is-plain-object/-/is-plain-object-5.0.0.tgz",
+ "integrity": "sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q=="
+ },
+ "is-relative": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/is-relative/-/is-relative-1.0.0.tgz",
+ "integrity": "sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==",
+ "requires": {
+ "is-unc-path": "^1.0.0"
+ }
+ },
+ "is-stream": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/is-stream/-/is-stream-2.0.1.tgz",
+ "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg=="
+ },
+ "is-unc-path": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/is-unc-path/-/is-unc-path-1.0.0.tgz",
+ "integrity": "sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==",
+ "requires": {
+ "unc-path-regex": "^0.1.2"
+ }
+ },
+ "is-utf8": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmmirror.com/is-utf8/-/is-utf8-0.2.1.tgz",
+ "integrity": "sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q=="
+ },
+ "is-windows": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/is-windows/-/is-windows-1.0.2.tgz",
+ "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA=="
+ },
+ "isexe": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/isexe/-/isexe-2.0.0.tgz",
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
+ },
+ "isobject": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmmirror.com/isobject/-/isobject-3.0.1.tgz",
+ "integrity": "sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg=="
+ },
+ "json-schema-traverse": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
+ "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug=="
+ },
+ "json5": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmmirror.com/json5/-/json5-2.2.0.tgz",
+ "integrity": "sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA==",
+ "requires": {
+ "minimist": "^1.2.5"
+ }
+ },
+ "jsonfile": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/jsonfile/-/jsonfile-4.0.0.tgz",
+ "integrity": "sha512-m6F1R3z8jjlf2imQHS2Qez5sjKWQzbuuhuJ/FKYFRZvPE3PuHcSMVZzfsLhGVOkfd20obL5SWEBew5ShlquNxg==",
+ "requires": {
+ "graceful-fs": "^4.1.6"
+ }
+ },
+ "kind-of": {
+ "version": "6.0.3",
+ "resolved": "https://registry.npmmirror.com/kind-of/-/kind-of-6.0.3.tgz",
+ "integrity": "sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw=="
+ },
+ "lcid": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/lcid/-/lcid-1.0.0.tgz",
+ "integrity": "sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==",
+ "requires": {
+ "invert-kv": "^1.0.0"
+ }
+ },
+ "liftoff": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmmirror.com/liftoff/-/liftoff-4.0.0.tgz",
+ "integrity": "sha512-rMGwYF8q7g2XhG2ulBmmJgWv25qBsqRbDn5gH0+wnuyeFt7QBJlHJmtg5qEdn4pN6WVAUMgXnIxytMFRX9c1aA==",
+ "requires": {
+ "extend": "^3.0.2",
+ "findup-sync": "^5.0.0",
+ "fined": "^2.0.0",
+ "flagged-respawn": "^2.0.0",
+ "is-plain-object": "^5.0.0",
+ "object.map": "^1.0.1",
+ "rechoir": "^0.8.0",
+ "resolve": "^1.20.0"
+ }
+ },
+ "load-json-file": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/load-json-file/-/load-json-file-1.1.0.tgz",
+ "integrity": "sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==",
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "parse-json": "^2.2.0",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0",
+ "strip-bom": "^2.0.0"
+ }
+ },
+ "lodash": {
+ "version": "4.17.21",
+ "resolved": "https://registry.npmmirror.com/lodash/-/lodash-4.17.21.tgz",
+ "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg=="
+ },
+ "log4js": {
+ "version": "6.4.1",
+ "resolved": "https://registry.npmmirror.com/log4js/-/log4js-6.4.1.tgz",
+ "integrity": "sha512-iUiYnXqAmNKiIZ1XSAitQ4TmNs8CdZYTAWINARF3LjnsLN8tY5m0vRwd6uuWj/yNY0YHxeZodnbmxKFUOM2rMg==",
+ "requires": {
+ "date-format": "^4.0.3",
+ "debug": "^4.3.3",
+ "flatted": "^3.2.4",
+ "rfdc": "^1.3.0",
+ "streamroller": "^3.0.2"
+ }
+ },
+ "make-iterator": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/make-iterator/-/make-iterator-1.0.1.tgz",
+ "integrity": "sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==",
+ "requires": {
+ "kind-of": "^6.0.2"
+ }
+ },
+ "map-cache": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmmirror.com/map-cache/-/map-cache-0.2.2.tgz",
+ "integrity": "sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg=="
+ },
+ "merge-stream": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/merge-stream/-/merge-stream-2.0.0.tgz",
+ "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
+ },
+ "micromatch": {
+ "version": "4.0.5",
+ "resolved": "https://registry.npmmirror.com/micromatch/-/micromatch-4.0.5.tgz",
+ "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
+ "requires": {
+ "braces": "^3.0.2",
+ "picomatch": "^2.3.1"
+ }
+ },
+ "mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg=="
+ },
+ "minimatch": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmmirror.com/minimatch/-/minimatch-3.1.2.tgz",
+ "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
+ "requires": {
+ "brace-expansion": "^1.1.7"
+ }
+ },
+ "minimist": {
+ "version": "1.2.6",
+ "resolved": "https://registry.npmmirror.com/minimist/-/minimist-1.2.6.tgz",
+ "integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q=="
+ },
+ "ms": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmmirror.com/ms/-/ms-2.1.2.tgz",
+ "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w=="
+ },
+ "mute-stdout": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/mute-stdout/-/mute-stdout-1.0.0.tgz",
+ "integrity": "sha512-MaSQenn0f9oxIjtCufclpV00MuYTiHaXPbdcfPIM+quMqoa8cXywjHHx4LhhIAZlXqPWMdcUpYviajfmHtHRJw=="
+ },
+ "normalize-package-data": {
+ "version": "2.5.0",
+ "resolved": "https://registry.npmmirror.com/normalize-package-data/-/normalize-package-data-2.5.0.tgz",
+ "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==",
+ "requires": {
+ "hosted-git-info": "^2.1.4",
+ "resolve": "^1.10.0",
+ "semver": "2 || 3 || 4 || 5",
+ "validate-npm-package-license": "^3.0.1"
+ }
+ },
+ "npm-run-path": {
+ "version": "4.0.1",
+ "resolved": "https://registry.npmmirror.com/npm-run-path/-/npm-run-path-4.0.1.tgz",
+ "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
+ "requires": {
+ "path-key": "^3.0.0"
+ }
+ },
+ "number-is-nan": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/number-is-nan/-/number-is-nan-1.0.1.tgz",
+ "integrity": "sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ=="
+ },
+ "object-keys": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmmirror.com/object-keys/-/object-keys-1.1.1.tgz",
+ "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA=="
+ },
+ "object.assign": {
+ "version": "4.1.2",
+ "resolved": "https://registry.npmmirror.com/object.assign/-/object.assign-4.1.2.tgz",
+ "integrity": "sha512-ixT2L5THXsApyiUPYKmW+2EHpXXe5Ii3M+f4e+aJFAHao5amFRW6J0OO6c/LU8Be47utCx2GL89hxGB6XSmKuQ==",
+ "requires": {
+ "call-bind": "^1.0.0",
+ "define-properties": "^1.1.3",
+ "has-symbols": "^1.0.1",
+ "object-keys": "^1.1.1"
+ }
+ },
+ "object.defaults": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/object.defaults/-/object.defaults-1.1.0.tgz",
+ "integrity": "sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==",
+ "requires": {
+ "array-each": "^1.0.1",
+ "array-slice": "^1.0.0",
+ "for-own": "^1.0.0",
+ "isobject": "^3.0.0"
+ }
+ },
+ "object.map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/object.map/-/object.map-1.0.1.tgz",
+ "integrity": "sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w==",
+ "requires": {
+ "for-own": "^1.0.0",
+ "make-iterator": "^1.0.0"
+ }
+ },
+ "object.pick": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/object.pick/-/object.pick-1.3.0.tgz",
+ "integrity": "sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==",
+ "requires": {
+ "isobject": "^3.0.1"
+ }
+ },
+ "once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "requires": {
+ "wrappy": "1"
+ }
+ },
+ "onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmmirror.com/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "requires": {
+ "mimic-fn": "^2.1.0"
+ }
+ },
+ "os-locale": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmmirror.com/os-locale/-/os-locale-1.4.0.tgz",
+ "integrity": "sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==",
+ "requires": {
+ "lcid": "^1.0.0"
+ }
+ },
+ "parse-filepath": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/parse-filepath/-/parse-filepath-1.0.2.tgz",
+ "integrity": "sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==",
+ "requires": {
+ "is-absolute": "^1.0.0",
+ "map-cache": "^0.2.0",
+ "path-root": "^0.1.1"
+ }
+ },
+ "parse-json": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmmirror.com/parse-json/-/parse-json-2.2.0.tgz",
+ "integrity": "sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==",
+ "requires": {
+ "error-ex": "^1.2.0"
+ }
+ },
+ "parse-passwd": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/parse-passwd/-/parse-passwd-1.0.0.tgz",
+ "integrity": "sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q=="
+ },
+ "path-exists": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/path-exists/-/path-exists-2.1.0.tgz",
+ "integrity": "sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==",
+ "requires": {
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "path-is-absolute": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
+ "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg=="
+ },
+ "path-key": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/path-key/-/path-key-3.1.1.tgz",
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q=="
+ },
+ "path-parse": {
+ "version": "1.0.7",
+ "resolved": "https://registry.npmmirror.com/path-parse/-/path-parse-1.0.7.tgz",
+ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw=="
+ },
+ "path-root": {
+ "version": "0.1.1",
+ "resolved": "https://registry.npmmirror.com/path-root/-/path-root-0.1.1.tgz",
+ "integrity": "sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==",
+ "requires": {
+ "path-root-regex": "^0.1.0"
+ }
+ },
+ "path-root-regex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmmirror.com/path-root-regex/-/path-root-regex-0.1.2.tgz",
+ "integrity": "sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ=="
+ },
+ "path-type": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/path-type/-/path-type-1.1.0.tgz",
+ "integrity": "sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==",
+ "requires": {
+ "graceful-fs": "^4.1.2",
+ "pify": "^2.0.0",
+ "pinkie-promise": "^2.0.0"
+ }
+ },
+ "picomatch": {
+ "version": "2.3.1",
+ "resolved": "https://registry.npmmirror.com/picomatch/-/picomatch-2.3.1.tgz",
+ "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
+ },
+ "pify": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmmirror.com/pify/-/pify-2.3.0.tgz",
+ "integrity": "sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog=="
+ },
+ "pinkie": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmmirror.com/pinkie/-/pinkie-2.0.4.tgz",
+ "integrity": "sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg=="
+ },
+ "pinkie-promise": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmmirror.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz",
+ "integrity": "sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==",
+ "requires": {
+ "pinkie": "^2.0.0"
+ }
+ },
+ "pretty-hrtime": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/pretty-hrtime/-/pretty-hrtime-1.0.0.tgz",
+ "integrity": "sha512-CU2l5CYUAptUYq/671ajexQfXuxJFwwg0n243Kdkx8bTjeenedsWgu8TGHPm03vLfNtk3aTXgySKPp3Usykudw=="
+ },
+ "punycode": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmmirror.com/punycode/-/punycode-2.1.1.tgz",
+ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A=="
+ },
+ "read-pkg": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmmirror.com/read-pkg/-/read-pkg-1.1.0.tgz",
+ "integrity": "sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==",
+ "requires": {
+ "load-json-file": "^1.0.0",
+ "normalize-package-data": "^2.3.2",
+ "path-type": "^1.0.0"
+ }
+ },
+ "read-pkg-up": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz",
+ "integrity": "sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==",
+ "requires": {
+ "find-up": "^1.0.0",
+ "read-pkg": "^1.0.0"
+ }
+ },
+ "rechoir": {
+ "version": "0.8.0",
+ "resolved": "https://registry.npmmirror.com/rechoir/-/rechoir-0.8.0.tgz",
+ "integrity": "sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ==",
+ "requires": {
+ "resolve": "^1.20.0"
+ }
+ },
+ "require-directory": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmmirror.com/require-directory/-/require-directory-2.1.1.tgz",
+ "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="
+ },
+ "require-from-string": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmmirror.com/require-from-string/-/require-from-string-2.0.2.tgz",
+ "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw=="
+ },
+ "require-main-filename": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/require-main-filename/-/require-main-filename-1.0.1.tgz",
+ "integrity": "sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug=="
+ },
+ "resolve": {
+ "version": "1.22.1",
+ "resolved": "https://registry.npmmirror.com/resolve/-/resolve-1.22.1.tgz",
+ "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==",
+ "requires": {
+ "is-core-module": "^2.9.0",
+ "path-parse": "^1.0.7",
+ "supports-preserve-symlinks-flag": "^1.0.0"
+ }
+ },
+ "resolve-dir": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmmirror.com/resolve-dir/-/resolve-dir-1.0.1.tgz",
+ "integrity": "sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==",
+ "requires": {
+ "expand-tilde": "^2.0.0",
+ "global-modules": "^1.0.0"
+ }
+ },
+ "resolve-package-path": {
+ "version": "4.0.3",
+ "resolved": "https://registry.npmmirror.com/resolve-package-path/-/resolve-package-path-4.0.3.tgz",
+ "integrity": "sha512-SRpNAPW4kewOaNUt8VPqhJ0UMxawMwzJD8V7m1cJfdSTK9ieZwS6K7Dabsm4bmLFM96Z5Y/UznrpG5kt1im8yA==",
+ "requires": {
+ "path-root": "^0.1.1"
+ }
+ },
+ "rfdc": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmmirror.com/rfdc/-/rfdc-1.3.0.tgz",
+ "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA=="
+ },
+ "safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmmirror.com/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg=="
+ },
+ "semver": {
+ "version": "5.7.1",
+ "resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.1.tgz",
+ "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ=="
+ },
+ "set-blocking": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/set-blocking/-/set-blocking-2.0.0.tgz",
+ "integrity": "sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw=="
+ },
+ "shebang-command": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/shebang-command/-/shebang-command-2.0.0.tgz",
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
+ "requires": {
+ "shebang-regex": "^3.0.0"
+ }
+ },
+ "shebang-regex": {
+ "version": "3.0.0",
+ "resolved": "https://registry.npmmirror.com/shebang-regex/-/shebang-regex-3.0.0.tgz",
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="
+ },
+ "signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmmirror.com/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ=="
+ },
+ "spdx-correct": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmmirror.com/spdx-correct/-/spdx-correct-3.1.1.tgz",
+ "integrity": "sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==",
+ "requires": {
+ "spdx-expression-parse": "^3.0.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-exceptions": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmmirror.com/spdx-exceptions/-/spdx-exceptions-2.3.0.tgz",
+ "integrity": "sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A=="
+ },
+ "spdx-expression-parse": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmmirror.com/spdx-expression-parse/-/spdx-expression-parse-3.0.1.tgz",
+ "integrity": "sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==",
+ "requires": {
+ "spdx-exceptions": "^2.1.0",
+ "spdx-license-ids": "^3.0.0"
+ }
+ },
+ "spdx-license-ids": {
+ "version": "3.0.11",
+ "resolved": "https://registry.npmmirror.com/spdx-license-ids/-/spdx-license-ids-3.0.11.tgz",
+ "integrity": "sha512-Ctl2BrFiM0X3MANYgj3CkygxhRmr9mi6xhejbdO960nF6EDJApTYpn0BQnDKlnNBULKiCN1n3w9EBkHK8ZWg+g=="
+ },
+ "streamroller": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmmirror.com/streamroller/-/streamroller-3.1.2.tgz",
+ "integrity": "sha512-wZswqzbgGGsXYIrBYhOE0yP+nQ6XRk7xDcYwuQAGTYXdyAUmvgVFE0YU1g5pvQT0m7GBaQfYcSnlHbapuK0H0A==",
+ "requires": {
+ "date-format": "^4.0.13",
+ "debug": "^4.3.4",
+ "fs-extra": "^8.1.0"
+ },
+ "dependencies": {
+ "fs-extra": {
+ "version": "8.1.0",
+ "resolved": "https://registry.npmmirror.com/fs-extra/-/fs-extra-8.1.0.tgz",
+ "integrity": "sha512-yhlQgA6mnOJUKOsRUFsgJdQCvkKhcz8tlZG5HBQfReYZy46OwLcY+Zia0mtdHsOo9y/hP+CxMN0TU9QxoOtG4g==",
+ "requires": {
+ "graceful-fs": "^4.2.0",
+ "jsonfile": "^4.0.0",
+ "universalify": "^0.1.0"
+ }
+ }
+ }
+ },
+ "string-width": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/string-width/-/string-width-1.0.2.tgz",
+ "integrity": "sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==",
+ "requires": {
+ "code-point-at": "^1.0.0",
+ "is-fullwidth-code-point": "^1.0.0",
+ "strip-ansi": "^3.0.0"
+ }
+ },
+ "strip-ansi": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmmirror.com/strip-ansi/-/strip-ansi-3.0.1.tgz",
+ "integrity": "sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==",
+ "requires": {
+ "ansi-regex": "^2.0.0"
+ }
+ },
+ "strip-bom": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/strip-bom/-/strip-bom-2.0.0.tgz",
+ "integrity": "sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==",
+ "requires": {
+ "is-utf8": "^0.2.0"
+ }
+ },
+ "strip-final-newline": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmmirror.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
+ "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA=="
+ },
+ "strnum": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmmirror.com/strnum/-/strnum-1.0.5.tgz",
+ "integrity": "sha512-J8bbNyKKXl5qYcR36TIO8W3mVGVHrmmxsd5PAItGkmyzwJvybiw2IVq5nqd0i4LSNSkB/sx9VHllbfFdr9k1JA=="
+ },
+ "supports-preserve-symlinks-flag": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz",
+ "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w=="
+ },
+ "to-regex-range": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmmirror.com/to-regex-range/-/to-regex-range-5.0.1.tgz",
+ "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
+ "requires": {
+ "is-number": "^7.0.0"
+ }
+ },
+ "unc-path-regex": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmmirror.com/unc-path-regex/-/unc-path-regex-0.1.2.tgz",
+ "integrity": "sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg=="
+ },
+ "universalify": {
+ "version": "0.1.2",
+ "resolved": "https://registry.npmmirror.com/universalify/-/universalify-0.1.2.tgz",
+ "integrity": "sha512-rBJeI5CXAlmy1pV+617WB9J63U6XcazHHF2f2dbJix4XzpUF0RS3Zbj0FGIOCAva5P/d/GBOYaACQ1w+0azUkg=="
+ },
+ "uri-js": {
+ "version": "4.4.1",
+ "resolved": "https://registry.npmmirror.com/uri-js/-/uri-js-4.4.1.tgz",
+ "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==",
+ "requires": {
+ "punycode": "^2.1.0"
+ }
+ },
+ "v8flags": {
+ "version": "3.2.0",
+ "resolved": "https://registry.npmmirror.com/v8flags/-/v8flags-3.2.0.tgz",
+ "integrity": "sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==",
+ "requires": {
+ "homedir-polyfill": "^1.0.1"
+ }
+ },
+ "validate-npm-package-license": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmmirror.com/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz",
+ "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==",
+ "requires": {
+ "spdx-correct": "^3.0.0",
+ "spdx-expression-parse": "^3.0.0"
+ }
+ },
+ "which": {
+ "version": "1.3.1",
+ "resolved": "https://registry.npmmirror.com/which/-/which-1.3.1.tgz",
+ "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==",
+ "requires": {
+ "isexe": "^2.0.0"
+ }
+ },
+ "which-module": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmmirror.com/which-module/-/which-module-1.0.0.tgz",
+ "integrity": "sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ=="
+ },
+ "wrap-ansi": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmmirror.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz",
+ "integrity": "sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==",
+ "requires": {
+ "string-width": "^1.0.1",
+ "strip-ansi": "^3.0.1"
+ }
+ },
+ "wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmmirror.com/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ=="
+ },
+ "y18n": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmmirror.com/y18n/-/y18n-3.2.2.tgz",
+ "integrity": "sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ=="
+ },
+ "yargs": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmmirror.com/yargs/-/yargs-7.1.2.tgz",
+ "integrity": "sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==",
+ "requires": {
+ "camelcase": "^3.0.0",
+ "cliui": "^3.2.0",
+ "decamelize": "^1.1.1",
+ "get-caller-file": "^1.0.1",
+ "os-locale": "^1.4.0",
+ "read-pkg-up": "^1.0.1",
+ "require-directory": "^2.1.1",
+ "require-main-filename": "^1.0.1",
+ "set-blocking": "^2.0.0",
+ "string-width": "^1.0.2",
+ "which-module": "^1.0.0",
+ "y18n": "^3.2.1",
+ "yargs-parser": "^5.0.1"
+ }
+ },
+ "yargs-parser": {
+ "version": "5.0.1",
+ "resolved": "https://registry.npmmirror.com/yargs-parser/-/yargs-parser-5.0.1.tgz",
+ "integrity": "sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==",
+ "requires": {
+ "camelcase": "^3.0.0",
+ "object.assign": "^4.1.0"
+ }
+ }
+ }
+}
diff --git a/FA/writingPad/package.json b/FA/writingPad/package.json
new file mode 100644
index 0000000000000000000000000000000000000000..54a4583849cb42743df9ba6114f8bcaa12cbbbc8
--- /dev/null
+++ b/FA/writingPad/package.json
@@ -0,0 +1,18 @@
+{
+ "license": "ISC",
+ "devDependencies": {},
+ "name": "myapplication",
+ "ohos": {
+ "org": "huawei",
+ "directoryLevel": "project",
+ "buildTool": "hvigor"
+ },
+ "description": "example description",
+ "repository": {},
+ "version": "1.0.0",
+ "dependencies": {
+ "@ohos/hypium": "1.0.1",
+ "@ohos/hvigor-ohos-plugin": "1.1.6",
+ "@ohos/hvigor": "1.1.6"
+ }
+}
diff --git a/README.md b/README.md
index 9d5cb5a68c1102f0442c4c37c22b2ae539030810..2eb28d142702d1e4d07281c3b13747857546e581 100644
--- a/README.md
+++ b/README.md
@@ -29,7 +29,7 @@
### 样例汇总
--
+- [基于OpenHarmony的多功能手写板](./docs/writingPad/README.md)
## 学习资源
diff --git a/docs/writingPad/README.md b/docs/writingPad/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..ae0005393fe4199d4fa9899797624085e74ffeb1
--- /dev/null
+++ b/docs/writingPad/README.md
@@ -0,0 +1,148 @@
+# OpenHarmony 多功能手写板
+
+## 一、简介
+
+[本Demo](../../FA/writingPad)是基于OpenHarmony3.2 Beta1,使用js语言编写的应用。用户可以使用该应用能在设备上临摹、绘画、做笔记。
+
+#### 1.效果展示
+
+视频地址:[基于OpenHarmony的多功能手写板_哔哩哔哩_bilibili](https://www.bilibili.com/video/BV1da411R76G/?spm_id_from=333.999.0.0&vd_source=d9be34bb05ccdbfa6d92285af7480048)
+
+#### 2.涉及OpenHarmony技术特性
+
+- JS UI
+- Canvas 组件
+
+#### 3.支持OpenHarmony版本
+
+OpenHarmony 3.0 LTS
+
+## 二、快速上手
+
+#### 1、标准设备环境准备
+
+以润和大禹系列HH-SCDAYU200开发板套件为例
+
+- [开发板上新 | RK3568开发板上丝滑体验OpenHarmony标准系统](https://gitee.com/openharmony-sig/knowledge_demo_smart_home/tree/master/dev/docs/rk3568_quick_start)
+
+#### 2、应用编译环境准备
+
+- 下载DevEco Studio [下载地址](https://gitee.com/link?target=https%3A%2F%2Fdeveloper.harmonyos.com%2Fcn%2Fdevelop%2Fdeveco-studio%23download_beta);
+- SDK 版本 :OpenHarmony SDK API 8,请参考[配置OpenHarmony SDK](https://gitee.com/openharmony/docs/blob/update_master_0323/zh-cn/application-dev/quick-start/configuring-openharmony-sdk.md),完成**DevEco Studio**的安装和开发环境配置。
+
+#### 3、项目下载和导入
+
+- 项目下载
+
+ `git clone git@gitee.com:openharmony-sig/knowledge_demo_temp.git --depth=1`
+
+- 项目导入
+
+ 打开DevEco Studio,点击File->Open->下载路径/FA/writingPad
+
+```
+└─src
+ ├─main
+ │ │ config.json // 应用配置文件
+ │ │
+ │ ├─js
+ │ │ └─MainAbility
+ │ │ │ app.js // 应用程序主入口
+ │ │ │
+ │ │ ├─common
+ │ │ │ ├─components
+ │ │ │ │ ├─Draw // 绘画模块
+ │ │ │ │ │ index.css
+ │ │ │ │ │ index.hml
+ │ │ │ │ │ index.js
+ │ │ │ │ │
+ │ │ │ │ ├─layout // tab栏
+ │ │ │ │ │ layout.css
+ │ │ │ │ │ layout.hml
+ │ │ │ │ │ layout.js
+ │ │ │ │ │
+ │ │ │ │ ├─Note // 笔记模块
+ │ │ │ │ │ index.css
+ │ │ │ │ │ index.hml
+ │ │ │ │ │ index.js
+ │ │ │ │ │
+ │ │ │ │ └─Write // 练字模块
+ │ │ │ │ index.css
+ │ │ │ │ index.hml
+ │ │ │ │ index.js
+ │ │ │ │
+ │ │ │ └─images
+ │ │ └─pages
+ │ │ └─index // 首页
+ │ │ index.css
+ │ │ index.hml
+ │ │ index.js
+ │ │
+ │ └─resources
+ │ ├─base
+ │ │ ├─element
+ │ │ │ color.json
+ │ │ │ string.json
+ │ │ │
+ │ │ └─media
+ │ │ icon.png
+ │ │
+ │ └─rawfile
+```
+
+
+
+## 三、关键代码解读
+
+#### 1.绘制原理
+
+>使用前,需要线了解canvas组件,可以参考[OpenHarmony开发者文档](https://gitee.com/openharmony/docs/tree/master/zh-cn/application-dev/reference#/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/Readme-CN.md)
+
+首先,我们需要将canvas上下文对象,需要在触摸移动事件中绑定,因为我们是通过触摸来生成对应线条的。
+
+绘制直线,通常使用moveTo ()与lineTo ()两个方法。. moveTo ()方法用于将画笔移至指定点并以改点为直线的开始点,lineTo ()则为结束点。
+
+```
+ const el = this.$refs.canvas;
+ this.ctx = el.getContext('2d')
+ this.ctx.lineWidth =this.lineWidth/2
+ this.ctx.beginPath()
+ // 向线条的每个末端添加圆形线帽。
+ this.ctx.lineCap = 'square'
+ // 每次将数组中最后一个值取出,作为起始点
+ this.ctx.moveTo(this.ArrX[this.ArrX.length-1],this.ArrY[this.ArrY.length-1])
+ this.ctx.lineTo(e.touches[0].localX,e.touches[0].localY)
+ this.ctx.stroke()
+ this.ArrX.push(e.touches[0].localX)
+ this.ArrY.push(e.touches[0].localY)
+```
+
+将数组中的最后一个值取出,作为moveTo的坐标,将鼠标移动后的点作为lineTo的坐标,然后再通过stroke就能绘制出图像。
+
+#### 2.线条粗细
+
+> 想要通过速度来计算线条粗细,那么可以是需要获取两点之间的时间,通过时间和距离得到速度
+
+当触发touchmove事件,将当前时间戳存储起来,通过上一次触发事件获得的时间-当前触发事件获得的时间,就可以得到两次触发事件的事件间隔,此时我们就获得了两点之间的时间
+
+再计算两点之间的距离(平方和再开根号),通过 `路程/时间 = 速度`计算出两点之间的速度,从而可以动态生成线条粗细
+
+```
+ // 计算线条粗细
+ const currTime = Date.now()
+ if(this.startTime !== 0){
+ const duration = currTime - this.startTime
+ // 传入倒数第二个点和最后一个点,和持续时间,会返回加速度
+ const v = this.speed(this.ArrX[this.ArrX.length-2],this.ArrY[this.ArrY.length-2],this.ArrX[this.ArrX.length-1],this.ArrY[this.ArrY.length-1],duration)
+ this.lineWidth = this.lineWidth/v
+ if(this.lineWidth>25){
+ this.lineWidth = 25
+ }
+ if(this.lineWidth<1){
+ this.lineWidth = 1
+ }
+ }
+ this.startTime = currTime
+
+```
+