Commit 254fb48a authored by Sky's avatar Sky

update

parent 550bfe87
Pipeline #148 canceled with stages
{
"profile": {
"package": "com.company.fit",
"version-code": 1,
"version-name": "1.0.0",
"uses-sdk": {
"min-version": "zsdk 1.0.0"
},
"distro": {
"delivery-with-install": true,
"module-name": "entry",
"module-type": "entry"
},
"application": {
"label": "Fit",
"icon": "res/drawable",
"abilities": [
{
"name": "default",
"label": "Fit"
}
],
"js": [
{
"name": "default",
"pages": [
"pages/index/index"
]
}
]
}
}
}
\ No newline at end of file
apply plugin: 'com.huawei.harmony.hap'
harmonyos {
signingConfigs {
debug {
certpath file('C:/Users/Administrator/Desktop/huawei_watch/com.company.fit.cer')
profile file('C:/Users/Administrator/Desktop/huawei_watch/com.company.fit_HarmonyAppProvision_debug.p7b')
signAlg 'SHA256withECDSA'
keyPassword '0000001BA5B4F455E634DAD3600D1EAA4433CA0169925774EC115323BD0EA2CE289094694DF8C9DA73F9C2'
keyAlias 'huawei_watch Release'
storePassword '0000001BEC1AEE04E0D331CC47AC56B11FFCF80694C5C7E5AC3CDB84EB3548B95BD2E8DD7DF65945E733ED'
storeFile file('C:/Users/Administrator/Desktop/huawei_watch/huawei_watch.jks')
}
}
compileSdkVersion 1
defaultConfig {
compatibleSdkVersion 1
}
}
sourceSets{
main{
java{
srcDir 'build\\generated\\source\\r\\debug'
}
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
testCompile'junit:junit:4.12'
}
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":entry" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":entry" />
</configuration>
</facet>
<facet type="java-gradle" name="Java-Gradle">
<configuration>
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
<option name="BUILDABLE" value="true" />
</configuration>
</facet>
<facet type="harmony" name="Harmony">
<configuration>
<option name="configurationProperty" value="This is option under configuration" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
<output url="file://$MODULE_DIR$/build/classes/java/main" />
<output-test url="file://$MODULE_DIR$/build/classes/java/test" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
<excludeFolder url="file://$MODULE_DIR$/build" />
</content>
<orderEntry type="jdk" jdkName="HarmonyOS SDK 1" jdkType="HarmonyOS SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="Gradle: rt_java" level="project" />
<orderEntry type="library" exported="" name="Gradle: harmonyos" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="Gradle: junit-4.12" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="Gradle: hamcrest-core-1.3" level="project" />
</component>
</module>
\ No newline at end of file
{
"app": {
"bundleName": "com.company.fit",
"version": {
"code": 1,
"name": "1.0.0"
}
},
"deviceConfig": {
"default": {
"reqSdk": {
"compatible": "zsdk 1.0.0",
"target": "zsdk 1.0.0"
}
}
},
"module": {
"deviceType": [
"fitnessWatch"
],
"abilities": [
{
"name": "default",
"icon": "$media:icon",
"label": "Fit",
"type": "page"
}
],
"distro": {
"moduleType": "entry",
"deliveryWithInstall": true,
"moduleName": "entry"
},
"description": "",
"js": [
{
"pages": [
"pages/index/index"
],
"name": "default"
}
],
"reqPermissions": []
}
}
\ No newline at end of file
import app from "@system.app";
export default {
onCreate() {
console.log(JSON.stringify(app.getInfo(),321));
console.info("Application onCreate");
//发送一个手表应用已启动的事件给手机
this.sendMsg({
"eventFlg": "6",
});
},
onDestroy() {
console.info("Application onDestroy");
//页面销毁,发送时间到手机,用于弹出断开连接弹窗
this.sendMsg({
"eventFlg": "7",
});
FeatureAbility.unsubscribeMsg();
},
//发送短消息给客户端
sendMsg(obj) {
FeatureAbility.sendMsg({
deviceId: 'remote',
bundleName: 'com.sportq.fit',
abilityName: 'com.sportq.fit',
message: JSON.stringify(obj),
success: function () {
console.log("发送成功")
},
fail: function (data, code) {
console.log("发送失败")
}
});
},
}
.container {
justify-content: center;
align-items: center;
left: 0px;
top: 0px;
width: 454px;
height: 454px;
color: #FFFFFF;
flex-direction: column;
}
/*准备开始*/
.logo{
width: 230px;
height: 129px;
}
.start{
width: 454px;
height: 454px;
justify-content: center;
align-items: center;
}
.start-text{
font-size: 38px;
text-align: center;
}
/* 标题 */
.title{
width: 262px;
height: 90px;
}
.text{
color: #ffffff;
font-size: 38px;
width: 262px;
text-align: center;
justify-content: center;
}
/*倒计时*/
.count-down{
width: 350px;
text-align: center;
font-size: 38px;
justify-content: center;
color:#FFD208;
}
.count-down-num{
width: 60px;
height: 170px;
}
/* 动作预览 */
.train-view{
width: 454px;
height: 454px;
flex-direction: column;
align-items: center;
}
.train-page-title,.train-pape-num-box{
font-size: 38px;
height: 130px;
margin-top:60px;
width: 350px;
color:#FFFFFF;
text-align: center;
justify-content: center;
}
.train-pape-num{
font-size: 38px;
}
.train-pape-num-f{
font-size: 30px;
margin-top: 8px;
}
.train-pape-num-o{
color:#FFD208;
font-size: 38px;
}
.train-view-title{
width: 350px;
color:#A8A8A8;
text-align: center;
text-overflow: ellipsis;
}
.train-view-progress-line{
width: 350px;
height: 10px;
border-radius: 10px;
background-color:rgba(255,255,255,0.15);
margin-top:60px;
}
.train-view-progress-new{
width: 100px;
height: 10px;
border-radius: 10px;
background-color:#FFD208;
}
.train-num{
width: 350px;
height: 54px;
margin-top:26px;
}
.train-heartbeat,.train-calorie{
width: 175px;
height: 54px;
justify-content: center;
align-items: center;
}
.train-num-icon{
width: 54px;
height: 54px;
margin-right: 16px;
}
.train-num-text{
width: 105px;
height: 42px;
justify-content: center;
align-items: center;
font-size: 38px;
}
.train-num-text-no{
color: #C8C8C8;
}
.select{
width: 454px;
height:36px;
justify-content: center;
}
.select-item{
width: 12px;
height: 12px;
border-radius: 12px;
margin-left:6px;
margin-right:6px;
background-color: #3B3B3B;
}
.select-item-active{
background-color: #FFFFFF;
}
/**已训练**/
.train-new-title{
font-size: 38px;
height: 38px;
margin-top:60px;
width: 350px;
color:#FFFFFF;
text-align: center;
}
.train-time{
justify-content: center;
align-items: center;
height: 130px;
margin-top:26px;
font-size: 38px;
}
.train-time-icon{
width: 46px;
height: 130px;
}
.train-time-icon-d{
width: 26px;
height: 130px;
}
.train-tool{
width: 454px;
height: 120px;
justify-content: center;
align-items: center;
}
.train-tool-icon{
width: 80px;
height: 80px;
}
.train-play-icon{
width: 120px;
height: 120px;
margin-left: 35px;
margin-right: 35px;
}
/**切出**/
.train-quit{
width: 454px;
height: 454px;
flex-direction:column;
align-items: center;
justify-content:center;
}
.train-quit-icon{
width: 90px;
height: 160px;
}
.train-quit-logo-icon{
width: 120px;
height: 68px;
}
.train-quit-text-box{
width: 350px;
height: 84px;
margin-top: 32px;
}
.train-quit-text{
width: 350px;
text-align: center;
}
/*暂停倒计时*/
.train-down{
width: 454px;
height: 454px;
flex-direction:column;
align-items: center;
justify-content:center;
}
.train-down-text{
color:#FFFFFF;
width: 59px;
height: 152px;
font-size: 152px;
text-align: center;
font-size: 38px;
}
.todo-wraper {
width: 454px;
height: 418px;
flex-direction: row;
}
.todo-item {
width: 454px;
height: 418px;
}
/*完成训练*/
.train-end{
width: 454px;
height: 454px;
flex-direction: column;
}
.train-end-tt{
height: 103px;
width: 454px;
justify-content: center;
align-items: center;
flex-direction: column;
margin-top: 40px;
}
.train-end-tt-text{
font-size: 38px;
margin-bottom: 10px;
}
.train-end-time{
font-size: 30px;
color: #A8A8A8;
}
.train-end-list{
align-items: flex-end;
width: 454px;
height:200px;
flex-direction: column;
margin-top: 20px;
}
.train-end-list-item{
width: 450px;
height: 38px;
justify-content: center;
margin-bottom: 30px;
}
.train-end-label{
height: 38px;
width: 147px;
color: #A8A8A8;
font-size: 30px;
margin-top: 6px;
}
.train-end-num{
width: 104px;
margin-right: 16px;
font-size: 38px;
text-align: right;
}
.train-end-unit{
width: 83px;
color: #A8A8A8;
font-size: 30px;
margin-top: 6px;
}
.train-end-btn-box{
width: 454px;
height: 91px;
justify-content: center;
}
.train-end-btn{
width: 327px;
height: 91px;
}
/**退出**/
.train-out{
width: 454px;
height: 454px;
flex-direction:column;
align-items: center;
justify-content:center;
}
.train-out-icon{
width: 120px;
height: 68px;
}
.train-out-text-box{
width: 350px;
height: 84px;
margin-top: 32px;
flex-direction: column;
}
.train-out-text{
width: 350px;
text-align: center;
height: 42px;
}
\ No newline at end of file
<div class="container">
<!--启动页面-->
<image class="logo" if="!page" src="../../common/default_img.png"></image>
<!--启动页面-->
<!--训练切出-->
<div class="train-quit" if="page == '12'">
<image class="train-quit-icon" src="../../common/oppo_img_fit.png"></image>
<div class="train-quit-text-box">
<text class="train-quit-text">
请在手机上打开Fit,并登录账户
</text>
</div>
</div>
<!--训练切出end-->
<!--准备开始-->
<div class="start" if="page == '0'">
<text class="start-text">{{title}}
</text>
</div>
<!--准备开始end-->
<!--训练准备倒计时-->
<text if="page == '1'" class="count-down">{{countdownT}}
</text>
<!--训练准备倒计时end-->
<!-- 标题 -->
<div class="title" if="page == '2'">
<text class="text">{{acName}}
</text>
</div>
<!-- 标题end -->
<list class="todo-wraper" ref="listDom" if="page == '3' || page == '4' || page == '5'|| page == '6'">
<list-item class="todo-item">
<!-- 动作预览 -->
<div class="train-view">
<text if="page == '3'" class="train-page-title">
动作预览
</text>
<div if="page == '4' " class="train-pape-num-box">
<text class="train-pape-num-o">{{countdownT}}
</text>
</div>
<div if="(page == '5'|| page == '6') && acType == '1' " class="train-pape-num-box">
<text class="train-pape-num">{{countdownT}}
</text>
</div>
<div if="page == '5'&& acType == '0' " class="train-pape-num-box">
<text class="train-pape-num">{{acCnt}}/{{acTotalCnt}}
</text>
</div>
<text class="train-view-title">{{acName}}
</text>
<div class="train-view-progress-line">
<div class="train-view-progress-new" style="width: {{progress}}"></div>
</div>
<div class="train-num">
<div class="train-heartbeat">
<image class="train-num-icon" src="../../common/oppo_icon_heart.png"></image>
<text if="newHeartRate != '--'" class="train-num-text">{{newHeartRate}}
</text>
<text else class="train-num-text train-num-text-no">{{newHeartRate}}
</text>
</div>
<div class="train-calorie">
<image class="train-num-icon" src="../../common/oppo_icon_calorie.png"></image>
<text if="acCalorie != '--'" class="train-num-text">{{acCalorie}}
</text>
<text else class="train-num-text train-num-text-no">{{acCalorie}}
</text>
</div>
</div>
</div>
<!-- 动作预览end -->
</list-item>
<list-item class="todo-item">
<!-- 已训练 -->
<div class="train-view">
<text class="train-new-title">
已训练
</text>
<text class="train-time">{{fitDuration}}
</text>
<div class="train-tool" if="{{stopFlg}}">
<image class="train-play-icon" @click="play" src="../../common/oppo_btn_play.png"></image>
<image class="train-play-icon" @click="close" src="../../common/oppo_btn_close.png"></image>
</div>
<div class="train-tool" else>
<image class="train-tool-icon" if="{{isFirst == '0'}}"
src="../../common/oppo_btn_previous_disabled.png"></image>
<image class="train-tool-icon" @click="previous"
else src="../../common/oppo_btn_previous.png"></image>
<image class="train-play-icon" @click="stop" src="../../common/oppo_bun_pause.png"></image>
<image class="train-tool-icon" if="{{isLast == '0'}}"
src="../../common/oppo_btn_next_disabled.png"></image>
<image class="train-tool-icon" @click="next" else src="../../common/oppo_btn_next.png"></image>
</div>
</div>
<!-- 已训练end -->
</list-item>
</list>
<!--切换圆点-->
<div class="select" if="page == '3' || page == '4' || page == '5' || page == '7' || page == '8'">
<div class="select-item select-item-active"></div>
<div class="select-item"></div>
</div>
<!--切换圆点end-->
<!--训练切出-->
<div class="train-quit" if="page == '15'">
<image class="train-quit-icon" src="../../common/oppo_img_fit.png"></image>
<div class="train-quit-text-box">
<text class="train-quit-text">
请在手机上返回训练视频,继续您的训练
</text>
</div>
</div>
<!--训练切出end-->
<!--暂停播放倒计时-->
<div class="train-down" if="page == '8'">
<text class="train-down-text">
{{countdownT}}
</text>
</div>
<!---暂停播放倒计时end-->
<!--完成训练-->
<div class="train-end" if="page == '9'">
<div class="train-end-tt">
<text class="train-end-tt-text">
运动数据
</text>
<text class="train-end-time">{{fitTotalDuration}}分钟
</text>
</div>
<div class="train-end-list">
<div class="train-end-list-item">
<text class="train-end-label">
平均心率
</text>
<text class="train-end-num">{{averHeartRate}}
</text>
<text class="train-end-unit">
Bpm
</text>
</div>
<div class="train-end-list-item">
<text class="train-end-label">
最高心率
</text>
<text class="train-end-num">{{maxHeartRate}}
</text>
<text class="train-end-unit">
Bpm
</text>
</div>
<div class="train-end-list-item">
<text class="train-end-label">
我的消耗
</text>
<text class="train-end-num">{{acCalorie}}
</text>
<text class="train-end-unit">
千卡
</text>
</div>
</div>
<div class="train-end-btn-box" @click="end">
<image class="train-end-btn" src="../../common/hm_btn_finish.png"></image>
</div>
</div>
<!--完成训练end-->
<!--退出训练-->
<div class="train-out" if="page == '10' || page == '11'">
<image class="train-out-icon" src="../../common/hm_img_logo.png"></image>
<div class="train-out-text-box">
<text class="train-out-text">
在手机上开启你
</text>
<text class="train-out-text">
今天的训练
</text>
</div>
</div>
<!--退出训练end-->
</div>
\ No newline at end of file
import sensor from '@system.sensor'; //传感器
import vibrator from '@system.vibrator'
export default {
data: {
page : "", //显示页面
title: "训练准备", //页面标题
acName: " ",//动作名称
progress: "",//进度条
acType: "",//次/秒 (0:次,1:秒)
acCnt: "00",//动作次数
acTotalCnt: "00",// 动作总次数
acCalorie: "",//卡路里
countdownT: "",// 倒计时
restHint: "",//休息文案
isLast: "",//是否第一个动作 "0":真 "1":假
isFirst: "",// 是否最后一个动作 "0":真 "1":假
fitDuration: "",//训练持续时长
fitTotalDuration: "",//训练时长-用于训练完成界面
heartRateList : [], //心率数组
averHeartRate: "",//平均心率
maxHeartRate: "",//最高心率
rollbackStop: "",//切出回来时候,是否需要暂停 "0":暂停 "0以外":切出训练
newHeartRate:"--", //当前心率
isStop : false, //是否暂停
sendFlg : false, // 是否在发送消息
stopFlg : false, //是否暂停
tabIndex : 0, //滑动index
isPhoneLeave : false, //手机端离开状态
isEnd : false, //是否完成
lastPage:"",//上个页面标识
isReceiveStartMessage: false,//启动时收到手机端给的回复消息
},
onReady(){
let _this = this;
/**
*获取客户端信息
*/
_this.getMsg();
/**
* 关闭启动页
*/
setTimeout(function(){
if(!_this.isReceiveStartMessage){
_this.page = "12";
}
},1500)
},
start(msg){
let _this = this;
let model = msg.acModel;
if(msg.eventFlg != ""){
_this.isReceiveStartMessage=true;
}
if(_this.sendFlg){
return false;
}
if(_this.isStop && msg.eventFlg != "7"){
return false;
}
_this.isStop = false;
//手机端主动离开时间,等待0.5秒后再处理其他时间
if(_this.isPhoneLeave){
return
}
if( msg.eventFlg == "15" && model.rollbackStop != '0'){
_this.isPhoneLeave = true;
setTimeout(function(){
_this.isPhoneLeave = false;
},500)
}
//完成训练停止接受10、15事件
if(_this.isEnd){
if(msg.eventFlg == "10" || msg.eventFlg == "15"){
return false;
}
}
switch(msg.eventFlg){
case "0": //训练准备
_this.page ="0";
_this.title = "训练准备";
break;
case "1": //训练准备后的倒计时
_this.page = "1";
_this.countdownT = model.countdownT;
_this.isEnd = false;
_this.stopFlg = false;
/**
*获取心率
*/
_this.getHeartRate();
break;
case "2": //动作名称
_this.vibrate();
_this.page ="2";
_this.acName = model.acName;
_this.isLast = model.isLast;
_this.isFirst = model.isFirst;
break;
case "3": //动作预览
_this.page ="3";
_this.acName = model.acName;
break;
case "4": //动作预览倒计时
_this.page ="4";
_this.acName = model.acName;
_this.countdownT = model.countdownT;
break;
case "5": //训练动作倒计时
_this.page ="5";
_this.acName = model.acName;
_this.countdownT = model.countdownT == "-1" ? "0" : model.countdownT;
_this.acType = model.acType;
_this.acCnt = model.acCnt;
_this.acTotalCnt = model.acTotalCnt;
break;
case "6": //休息中
_this.page ="6";
_this.acName = model.acName;
_this.countdownT =model.countdownT;
_this.acType = 1;
break;
case "7": //暂停
_this.$refs.listDom.scrollTo({index:1});
_this.tabIndex = 1;
_this.stopFlg = true;
break;
case "8": //继续
_this.$refs.listDom.scrollTo({index:0});
_this.tabIndex = 0;
_this.countdownT = model.countdownT;
_this.stopFlg = false;
break;
case "9": //完成训练
_this.vibrate();
_this.isEnd = true;
_this.page ="9";
_this.fitTotalDuration = model.fitTotalDuration;
_this.averHeartRate =_this.getAverHeartRate(_this.heartRateList);//平均心率
_this.maxHeartRate = _this.getMaxHeartRatet(_this.heartRateList); //最高心率
_this.acCalorie = model.acCalorie;
this.quit();
break;
case "10": //退出训练
_this.page ="10";
this.quit();
break;
case "11": //登录中
_this.page ="11"
break;
case "12": //退出登录
_this.page ="12";
this.quit();
break;
case "13": //进度条
_this.progress = ((model.acProgress / model.maxProgress) * 350);
break;
case "14": //训练总时长
_this.acCalorie = model.acCalorie ? model.acCalorie : '--';
_this.fitDuration = model.fitDuration;
break;
case "15": //离开或者返回训练
if(model.rollbackStop == '0'){
_this.page =_this.lastPage;
}else{
_this.lastPage=_this.page;
_this.page ="15"
}
this.quit();
break;
case "16": //杀掉进程
_this.page ="12";
this.quit();
break;
case "17": //播放初始化、注册心率
/**
*获取心率
*/
_this.getHeartRate();
break;
}
},
/**
发送短消息给客户端
*/
sendMsg(obj){
let _this = this;
_this.sendFlg = true;
FeatureAbility.sendMsg({
deviceId: 'remote',
bundleName: 'com.sportq.fit',
abilityName: 'com.sportq.fit',
message: JSON.stringify(obj),
success: function() {
_this.sendFlg = false;
console.log("发送成功")
},
fail: function(data, code) {
_this.sendFlg = false;
console.log("发送失败")
}
});
},
/**
*获取客户端短消息
*/
getMsg(){
let _this = this;
FeatureAbility.subscribeMsg({
success: function(data) {
_this.start(JSON.parse(data.message));
},
fail: function(data, code) {
_this.sendErrMsg(data,code)
}
});
},
/**
把错误信息发送至客户端
*/
sendErrMsg(data,code) {
let _this = this;
_this.sendMsg({
"errData" : data,
"errCode" : code,
"text" : "手表错误信息"
})
},
/**
*获取心率
*/
getHeartRate() {
let _this = this;
sensor.subscribeHeartRate({
success :function(data){
_this.newHeartRate = data.heartRate;
_this.heartRateList.push(data.heartRate);
_this.sendMsg({
"eventFlg" : "0",
"reatCnt" : data.heartRate
})
},
fail : function(data, code){
_this.sendErrMsg(data,code)
}
})
},
/**
*计算平均心率
*/
getAverHeartRate(arr) {
//将array的长度赋给len
let len = arr.length;
let sum = 0;
//利用for循环遍历数组的内容,利用sum累加求和
for(let i = 0; i < len ; i++){
sum += arr[i];
}
//返回数组的和与长度求平均值
return parseInt(sum/len);
},
/**
*获取最大心率
*/
getMaxHeartRatet(arr){
let max = arr[0];
for (let i = 0; i < arr.length - 1; i++) {
max = max < arr[i+1] ? arr[i+1] : arr
}
return parseInt(max)
},
/**
*暂停
*/
stop(){
this.isStop = true;
this.stopFlg = true;
this.$refs.listDom.scrollTo({index:1});
this.tabIndex = 1;
this.sendMsg({
"eventFlg" : "3",
})
},
/**
*播放
*/
play(){
this.isStop = false;
this.stopFlg = false;
this.sendMsg({
"eventFlg" : "4",
})
},
/**
*关闭
*/
close(){
this.sendMsg({
"eventFlg" : "5",
});
this.quit();
},
/**
*上一个动作
*/
previous(){
this.sendMsg({
"eventFlg" : "1",
})
},
/**
*下一个动作
*/
next(){
this.sendMsg({
"eventFlg" : "2",
})
},
/**
*震动
*/
vibrate(){
vibrator.vibrate({
mode: "short",
})
},
/**
*退出训练
*/
quit(){
this.isStop = false;
this.sendFlg = false;
this.stopFlg = false;
this.heartRateList = [];
sensor.unsubscribeHeartRate() //取消监听心率
},
/**
*完成
*/
end(){
this.page = '10';
}
}
{
"appID": "com.company.fit",
"appName": "Fit",
"versionName": "1.0.0",
"versionCode": 1,
"minPlatformVersion": "zsdk 1.0.0",
"pages": [
"pages/index/index"
]
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment