This commit is contained in:
zyy 2020-04-10 16:19:54 +08:00
commit f058795597
17 changed files with 268 additions and 99 deletions

View File

@ -341,21 +341,11 @@ export function Jl3dDrivingNew(mixers,updatemmi,sound,translation,routegroup,sta
}
function trainhmi(data){
for(let i=0,leni=data.length;i<leni;i++){
if(trainmodel.code == data[i].code){
// console.log(data[i]);
//更新车组号
updatemmi.updatetrainnum(data[i].groupNumber);
// updatemmi.updatestoptime(data[i].atoOn);
updatemmi.updatenowspeed(data[i].v);
updatemmi.updateatpspeed(data[i].pv);
updatemmi.updateatospeed(data[i].tv);
updatemmi.updatenowlen(data[i].maLen);
updatestatus(data[i]);
return;
}

View File

@ -180,39 +180,39 @@ export function RailListN(){
scope.sectionrail[section[i].code].standTrack = false;
}
//
// for(let n=0,nm=scope.sectionrail[section[i].code].lineleft.points.length;n<nm;n++){
// var geometry = new THREE.CircleGeometry( 0.05, 16 );
// var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
// var circle = new THREE.Mesh( geometry, material );
// // console.log(n);
// // console.log(scope.sectionrail[section[i].code].lineleft.points[n]);
// circle.position.x = scope.sectionrail[section[i].code].lineleft.points[n].x;
// circle.position.y = scope.sectionrail[section[i].code].lineleft.points[n].y;
// circle.position.z = scope.sectionrail[section[i].code].lineleft.points[n].z;
// circle.rotation.x = -Math.PI/2;
// scene.add( circle );
// }
// // scope.sectionrail[section[i].code].lineright.tension = 0.11;
// var points = scope.sectionrail[section[i].code].lineleft.getPoints( 50 );
// var geometry = new THREE.BufferGeometry().setFromPoints( points );
// var material;
// if(scope.sectionrail[section[i].code].type == "a"){
// material = new THREE.LineBasicMaterial( { color : 0xff0000 } );
// }
// if(scope.sectionrail[section[i].code].type == "b"){
// material = new THREE.LineBasicMaterial( { color : 0x00ff00 } );
// }
// if(scope.sectionrail[section[i].code].type == "c"){
// material = new THREE.LineBasicMaterial( { color : 0x0000ff } );
// }
//
//
// // Create the final object to add to the scene
// var curveObject = new THREE.Line( geometry, material );
//
// curveObject.position.y = Math.random();
// scene.add(curveObject);
for(let n=0,nm=scope.sectionrail[section[i].code].lineleft.points.length;n<nm;n++){
var geometry = new THREE.CircleGeometry( 0.05, 16 );
var material = new THREE.MeshBasicMaterial( { color: 0xffff00 } );
var circle = new THREE.Mesh( geometry, material );
// console.log(n);
// console.log(scope.sectionrail[section[i].code].lineleft.points[n]);
circle.position.x = scope.sectionrail[section[i].code].lineleft.points[n].x;
circle.position.y = scope.sectionrail[section[i].code].lineleft.points[n].y;
circle.position.z = scope.sectionrail[section[i].code].lineleft.points[n].z;
circle.rotation.x = -Math.PI/2;
scene.add( circle );
}
// scope.sectionrail[section[i].code].lineright.tension = 0.11;
var points = scope.sectionrail[section[i].code].lineleft.getPoints( 50 );
var geometry = new THREE.BufferGeometry().setFromPoints( points );
var material;
if(scope.sectionrail[section[i].code].type == "a"){
material = new THREE.LineBasicMaterial( { color : 0xff0000 } );
}
if(scope.sectionrail[section[i].code].type == "b"){
material = new THREE.LineBasicMaterial( { color : 0x00ff00 } );
}
if(scope.sectionrail[section[i].code].type == "c"){
material = new THREE.LineBasicMaterial( { color : 0x0000ff } );
}
// Create the final object to add to the scene
var curveObject = new THREE.Line( geometry, material );
curveObject.position.y = Math.random();
scene.add(curveObject);
}
}

View File

@ -19,6 +19,12 @@ export function SectionListN() {
var autorail;
this.loadpromise = function(sectionList,sectiondata,scene,assetloader){
// console.log(sectiondata);
var texture = new THREE.TextureLoader().load( '../../static/test/z025.png' );
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set( 1,1);
var selectmaterial = new THREE.MeshPhongMaterial( { map: texture,transparent:true } );
for(let i=0;i<assetloader.modellist.length;i++){
if(assetloader.modellist[i].deviceType == "autorail"){
autorail = assetloader.modellist[i].mesh.children[0];
@ -74,9 +80,6 @@ this.loadpromise = function(sectionList,sectiondata,scene,assetloader){
}
let newrail = new THREE.BufferGeometry();
newrail.copy(testmesh2.geometry);
// console.log(sectiondata[i]);
// console.log(testmesh2);
testmesh2.geometry = newrail;
testmesh2.geometry.attributes.position.needsUpdate = true;
testmesh2.geometry.attributes.uv.needsUpdate = true;
@ -85,19 +88,127 @@ this.loadpromise = function(sectionList,sectiondata,scene,assetloader){
testmesh2.position.set(sectiondata[i].position.x,sectiondata[i].position.y,sectiondata[i].position.z);
testmesh2.rotation.set(sectiondata[i].rotation._x,sectiondata[i].rotation._y,sectiondata[i].rotation._z);
testmesh2.matrixAutoUpdate = false;
// scope.sectiongroup.add(testmesh2);
// newsection.mesh = testmesh2;
scope.sections.datalist[newsection.code] = newsection;
// console.log(newsection);
testmesh2.updateMatrix();
mergegeometry.merge(new THREE.Geometry().fromBufferGeometry(testmesh2.geometry),testmesh2.matrix);
// console.log(testmesh2);
testmesh2.geometry.dispose();
for(let j in testmesh2.material){
testmesh2.material[j].map.dispose();
testmesh2.material[j].dispose();
}
testmesh2 = null;
// if(newsection.rp.z != newsection.lp.z){
// // console.log(newsection);
// let height = Math.random()/1000;
// var closedSpline = new THREE.CatmullRomCurve3( [
// new THREE.Vector3(newsection.lp.x, height, newsection.lp.z),
// new THREE.Vector3(newsection.lp.x+2, height,newsection.lp.z),
// new THREE.Vector3((newsection.lp.x+newsection.rp.x)/2, height,(newsection.lp.z+newsection.rp.z)/2),
// new THREE.Vector3(newsection.rp.x-2, height,newsection.rp.z),
// new THREE.Vector3(newsection.rp.x, height, newsection.rp.z)
// ] );
//
// closedSpline.type = 'catmullrom';
// closedSpline.closed = false;
// // Set up settings for later extrusion
// var extrudeSettings = {
// steps : 12,
// curveSegments : 1,
// bevelSegments : 1,
// bevelEnabled : false,
// extrudePath : closedSpline,
// };
// var shape = new THREE.Shape();
// shape.moveTo( 0,-2 );
// shape.lineTo( 0, 2 );
// // Extrude the triangle along the CatmullRom curve
// var geometry = new THREE.ExtrudeBufferGeometry( shape, extrudeSettings );
// var material = new THREE.MeshLambertMaterial( { color: 0xb00000, wireframe: true } );
// // newnormal = new Float32Array(newnormal);
// // console.log(newnormal);
// // geometry.attributes.normal = new THREE.BufferAttribute(newnormal, 3);
// // geometry.attributes.needsUpdate = true;
// // Create mesh with the resulting geometry
// var mesh = new THREE.Mesh( geometry, selectmaterial );
// let count = mesh.geometry.attributes.position.count/3;
//
// for(let i=0;i<count;i++){
// let ui=i*6;
// if(i%2 != 0){
// mesh.geometry.attributes.uv.array[ui] = 0;
// mesh.geometry.attributes.uv.array[ui+1] = 1;
// mesh.geometry.attributes.uv.array[ui+2] = len/10;
// mesh.geometry.attributes.uv.array[ui+3] = 1;
// mesh.geometry.attributes.uv.array[ui+4] = len/10;
// mesh.geometry.attributes.uv.array[ui+5] = 0;
// }else{
// mesh.geometry.attributes.uv.array[ui] = 0;
// mesh.geometry.attributes.uv.array[ui+1] = 0;
// mesh.geometry.attributes.uv.array[ui+2] = 0;
// mesh.geometry.attributes.uv.array[ui+3] = 1;
// mesh.geometry.attributes.uv.array[ui+4] = len/10;
// mesh.geometry.attributes.uv.array[ui+5] = 0;
// }
// }
//
// // mergegeometry.merge(new THREE.Geometry().fromBufferGeometry(mesh.geometry),mesh.matrix);
// console.log(mesh);
// scene.add(mesh);
// }else{
// let height = Math.random()/1000;
// var closedSpline = new THREE.CatmullRomCurve3( [
// new THREE.Vector3(newsection.lp.x, height, newsection.lp.z),
// new THREE.Vector3(newsection.rp.x, height, newsection.rp.z)
// ] );
//
// closedSpline.type = 'catmullrom';
// closedSpline.closed = false;
// // Set up settings for later extrusion
// var extrudeSettings = {
// steps : 12,
// curveSegments : 1,
// bevelSegments : 1,
// bevelEnabled : false,
// extrudePath : closedSpline,
// };
// var shape = new THREE.Shape();
// shape.moveTo( -2,0 );
// shape.lineTo( 2,0 );
// // Extrude the triangle along the CatmullRom curve
// var geometry = new THREE.ExtrudeBufferGeometry( shape, extrudeSettings );
// var material = new THREE.MeshLambertMaterial( { color: 0xb00000, wireframe: true } );
// // newnormal = new Float32Array(newnormal);
// // console.log(newnormal);
// // geometry.attributes.normal = new THREE.BufferAttribute(newnormal, 3);
// // geometry.attributes.needsUpdate = true;
// // Create mesh with the resulting geometry
// var mesh = new THREE.Mesh( geometry, selectmaterial );
// let count = mesh.geometry.attributes.position.count/3;
//
// for(let i=0;i<count;i++){
// let ui=i*6;
// if(i%2 != 0){
// mesh.geometry.attributes.uv.array[ui] = 0;
// mesh.geometry.attributes.uv.array[ui+1] = 1;
// mesh.geometry.attributes.uv.array[ui+2] = len/10;
// mesh.geometry.attributes.uv.array[ui+3] = 1;
// mesh.geometry.attributes.uv.array[ui+4] = len/10;
// mesh.geometry.attributes.uv.array[ui+5] = 0;
// }else{
// mesh.geometry.attributes.uv.array[ui] = 0;
// mesh.geometry.attributes.uv.array[ui+1] = 0;
// mesh.geometry.attributes.uv.array[ui+2] = 0;
// mesh.geometry.attributes.uv.array[ui+3] = 1;
// mesh.geometry.attributes.uv.array[ui+4] = len/10;
// mesh.geometry.attributes.uv.array[ui+5] = 0;
// }
// }
//
// // mergegeometry.merge(new THREE.Geometry().fromBufferGeometry(mesh.geometry),mesh.matrix);
// console.log(mesh);
// scene.add(mesh);
//
// }
}
let mergemesh = new THREE.Mesh( mergegeometry, autorail.material );
mergemesh.matrixAutoUpdate = false;

View File

@ -250,7 +250,7 @@ export default {
this.param = {
switchCode: this.selected.code,
sectionCode: section.code,
speedLimitValue: 5
speedLimitValue: '5'
};
},
handleSingalMenu() {

View File

@ -86,7 +86,7 @@ export default {
productTypes: ['01'],
stepVOList: [
{ deviceType: '03', orderNum: 1, operateCode: 'click', tip: '鼠标左键点击选择该区段' },
{ deviceType: '03', orderNum: 2, operateCode: '404', tip: '鼠标左键点击【区段解封】按钮' },
{ deviceType: '03', orderNum: 2, operateCode: '404', tip: '鼠标左键点击【解封区段】按钮' },
{ deviceType: '03', orderNum: 3, operateCode: '008', tip: '鼠标左键点击【执行】按钮' }
]
},
@ -132,8 +132,8 @@ export default {
minDuration: 8,
operateType: 'Section_Fault_Unlock',
skinCode: '02',
trainingName: '区段故障解锁({8}{9})',
trainingRemark: '故障解锁功能',
trainingName: '强解区段({8}{9})',
trainingRemark: '强解区段功能',
trainingType: 'Section',
productTypes: ['01'],
stepVOList: [
@ -162,8 +162,8 @@ export default {
minDuration: 8,
operateType: 'Switch_Normal_Position',
skinCode: '07',
trainingName: '单操到定位({7})',
trainingRemark: '单操到定位({15})',
trainingName: '转换定位({7})',
trainingRemark: '转换定位({15})',
trainingType: 'Switch',
productTypes: ['01'],
stepVOList: [
@ -191,8 +191,8 @@ export default {
minDuration: 8,
operateType: 'Switch_Reverse_Position', // 0313 新增定位字典
skinCode: '07',
trainingName: '单操到反位({7})',
trainingRemark: '单操到反位({7})',
trainingName: '转换反位({7})',
trainingRemark: '转换反位({7})',
trainingType: 'Switch',
productTypes: ['01'],
stepVOList: [
@ -339,7 +339,7 @@ export default {
skinCode: '07',
trainingName: '道岔区段解封({7})',
trainingRemark: '区段解封功能',
trainingType: '03',
trainingType: 'Switch',
productTypes: ['01'],
stepVOList: [
{ deviceType: '03', orderNum: 1, operateCode: 'click', tip: '鼠标左键点击选择该道岔' },
@ -352,8 +352,8 @@ export default {
minDuration: 8,
operateType: 'Switch_Fault_Unlock',
skinCode: '02',
trainingName: '道岔区段故障解锁({7})',
trainingRemark: '故障解锁功能',
trainingName: '强解区段({7})',
trainingRemark: '强解区段',
trainingType: 'Switch',
productTypes: ['01'],
stepVOList: [
@ -367,7 +367,7 @@ export default {
minDuration: 8,
operateType: 'Switch_Set_Limit_Speed',
skinCode: '02',
trainingName: '道岔置临时({7})',
trainingName: '道岔区设限({7})',
trainingRemark: '轨区设限功能',
trainingType: 'Switch',
productTypes: ['01'],
@ -382,7 +382,7 @@ export default {
minDuration: 8,
operateType: 'Switch_Cancel_Limit_Speed',
skinCode: '02',
trainingName: '道岔段取临时({7})',
trainingName: '道岔区消限({7})',
trainingRemark: '轨区消限功能',
trainingType: 'Switch',
productTypes: ['01'],
@ -479,7 +479,7 @@ export default {
productTypes: ['01'],
stepVOList: [
{ deviceType: '04', orderNum: 1, operateCode: 'click', tip: '鼠标左键点击选择该信号机' },
{ deviceType: '04', orderNum: 2, operateCode: '306', tip: '鼠标左键点击【封信号】按钮' },
{ deviceType: '04', orderNum: 2, operateCode: '306', tip: '鼠标左键点击【封信号】按钮' },
{ deviceType: '04', orderNum: 3, operateCode: '008', tip: '鼠标左键点击【执行】按钮' }
]
},

View File

@ -106,14 +106,18 @@ export default {
},
//
handlerTurnBack() {
commitOperate(menuOperate.Signal.setAutoTurnBack, {code:this.selected.code, cycleCode:this.selected.cycleCode}, 0).then((data)=>{
this.$refs.turnBackControl.doShow(data.operate, this.selected);
commitOperate(menuOperate.Signal.setAutoTurnBack, {cycleCode:this.selected.cycleCode}, 0).then(({valid, operate})=>{
if (valid) {
this.$refs.turnBackControl.doShow(operate, this.selected);
}
});
},
//
cancelTurnBack() {
commitOperate(menuOperate.Signal.cancelAutoTurnBack, {code:this.selected.code, cycleCode:this.selected.cycleCode, cancelRoute:false}, 0).then((data)=>{
this.$refs.turnBackControl.doShow(data.operate, this.selected);
commitOperate(menuOperate.Signal.cancelAutoTurnBack, {cycleCode:this.selected.cycleCode, cancelRoute:false}, 0).then(({valid, operate})=>{
if (valid) {
this.$refs.turnBackControl.doShow(operate, this.selected);
}
});
}
}

View File

@ -151,8 +151,8 @@ export default {
minDuration: 8,
operateType: 'Stand_Set_Run_Time',
skinCode: '06',
trainingName: '运行时间控制({10}-{12} 站台)',
trainingRemark: '运行时间控制(设置区间 运行等级1运行时间为115一直有效)',
trainingName: '设置运行等级({10}-{12} 站台)',
trainingRemark: '设置运行等级(设置区间 运行等级1运行时间为115一直有效)',
trainingType: 'Stand',
productTypes: ['02'],
stepVOList: [
@ -168,8 +168,8 @@ export default {
minDuration: 8,
operateType: 'Stand_Set_Run_Time',
skinCode: '06',
trainingName: '运行时间控制({10}-{12} 站台)',
trainingRemark: '运行时间控制(设置区间 运行等级自动,一直有效)',
trainingName: '设置运行等级({10}-{12} 站台)',
trainingRemark: '设置运行等级(设置区间 运行等级自动,一直有效)',
trainingType: 'Stand',
productTypes: ['02'],
stepVOList: [
@ -212,7 +212,7 @@ export default {
minDuration: 5,
operateType: 'Stand_View_Status',
skinCode: '06',
trainingName: '查看站台信息({10}-{12}站台)',
trainingName: '站台详细信息({10}-{12}站台)',
trainingRemark: '站台详细信息功能',
trainingType: 'Stand',
productTypes: ['01', '02'],

View File

@ -40,8 +40,8 @@ export default {
CMD_SWITCH_TURN_RP_CHAIN: {value: 'Switch_Turn_RP_Chain', label: '道岔反操(联动)'},
/** 道岔区段封锁 */
CMD_SWITCH_SECTION_BLOCK: {value: 'Switch_Section_Block', label: '道岔区段封锁'},
/** 道岔区段 */
CMD_SWITCH_SECTION_UNBLOCK: {value: 'Switch_Section_Unblock', label: '道岔区段'}
/** 道岔区段封 */
CMD_SWITCH_SECTION_UNBLOCK: {value: 'Switch_Section_Unblock', label: '道岔区段封'}
},
// 控制模式操作

View File

@ -98,7 +98,6 @@ class Handler {
const valid = ValidateHandler.vaildate(this.getTrainingMode(), operation);
this.afterValid(operation, valid);
rtn.valid = valid;
if (operation.cmdType && valid) {
const command = this.getCommand(operation);
if (command) {

View File

@ -157,6 +157,7 @@ export default {
mounted() {
this.mmishow = true;
window.datanew = this.datanew;
window.updatestatus = this.updatestatus;
// this.$refs.mmiui.init();
},
methods: {
@ -252,7 +253,11 @@ export default {
this.jlmap3d.cctvon();
}
}
},
updatestatus(newdata){
this.trainnum = newdata.groupNumber;
this.$refs.mmiui.updatetrainstatus(newdata);
},
}
};

View File

@ -10,11 +10,11 @@
</div>
<div class="toptext" style="left:16%;top:15px;">
{{$t('jlmap3d.terminal')}}
{{$t('jlmap3d.terminal')}}{{endstation}}
</div>
<div class="toptext" style="left:46%;top:15px;">
{{$t('jlmap3d.nextStation')}}
{{$t('jlmap3d.nextStation')}}{{nextstation}}
</div>
<div class="toptext" style="left:76%;top:15px;">
@ -111,6 +111,8 @@ export default {
nowspeed:0,
nowatpspeed:0,
nowatospeed:0,
endstation:'',
nextstation:'',
mmimodel:null,
nstate:"tiaoting",
nimage:null,
@ -198,6 +200,23 @@ export default {
document.getElementById("time").innerHTML = year + "/" + month + "/" + day + "/" + "\t" + vWeek[vWeek_s];
},
updatetrainstatus(newdata){
//
this.updatespeed(newdata.v);
this.updateatpspeed(newdata.pv);
this.updateatospeed(newdata.tv);
this.updatelen(newdata.maLen);
this.updatarunlevel(newdata.runLevel);
this.updatedrivemode(newdata.driveMode);
this.updatestation(newdata.endStation,newdata.nextStation);
},
updatemmistate(aaa){
},
@ -289,6 +308,37 @@ export default {
}
},
updatarunlevel(drivedata){
if(drivedata == "cbtc"){
if(this.m2state == "start"){
this.m2state = 'il';
this.m2image = this.images.m2[this.m2state];
}else if(this.m2state == "il"){
this.m2state = 'itc';
this.m2image = this.images.m2[this.m2state];
}else if(this.m2state == "itc"){
this.m2state = 'cbtc';
this.m2image = this.images.m2[this.m2state];
}else if(this.m2state == "cbtc"){
this.m2state = 'start';
this.m2image = this.images.m2[this.m2state];
}
}
},
updatedrivemode(drivedata){
if(drivedata == "AA"){
this.m7state = 'aoac';
this.m7image = this.images.m7[this.m7state];
}
if(drivedata == "AM"){
this.m7state = 'aomc';
this.m7image = this.images.m7[this.m7state];
}
if(drivedata == "MM"){
this.m7state = 'momc';
this.m7image = this.images.m7[this.m7state];
}
},
updatelen(len) {
//this.malen = 150+"px";
if(len>=750){
@ -322,6 +372,10 @@ export default {
this.malen = +parseInt(len)/2*10+"px";
}
},
updatestation(end,next){
this.endstation = end;
this.nextstation = next;
},
},
mounted() {
this.init();

View File

@ -264,6 +264,7 @@ export default {
this.placeholderMap = {};
getPlaceholderList({ trainingType: '' }).then(res => {
debugger;
res.data.forEach(item => {
if (!this.placeholderMap[item.trainingType]) {
this.placeholderMap[item.trainingType] = [];
@ -277,7 +278,7 @@ export default {
repliceName(fieldValue, enumList) {
if (enumList && enumList.length > 0) {
for (let i = 0; i < enumList.length; i++) {
if (fieldValue.includes(`{${enumList[i].id}}`)) {
if (fieldValue.includes(`{${enumList[i].code}}`)) {
fieldValue = fieldValue.replace(
`{${enumList[i].code}}`,
`{${enumList[i].name}}`

View File

@ -230,13 +230,13 @@ export default {
if (!this.isLeaving) {
this.interCheckGenerateStatus(this.$route.query.mapId, false);
}
}, 30000);
}, 15000);
}).catch(()=>{
setTimeout(() => {
if (!this.isLeaving) {
this.interCheckGenerateStatus(this.$route.query.mapId, false);
}
}, 30000);
}, 15000);
});
},
async prdChoose(queryData) {

View File

@ -25,8 +25,8 @@
<span class="list-elem">{{ courseModel.maxDuration }} {{ $t('display.seconds') }} </span>
</p>
<p class="list-item">
<span class="list-label"> {{ $t('display.training.trainingInstructions') }}</span>
<span class="list-elem">{{ courseModel.remarks }}</span>
<span class="list-label" style="vertical-align: top;"> {{ $t('display.training.trainingInstructions') }}</span>
<span class="list-elem elem-span">{{ courseModel.remarks }}</span>
</p>
</el-scrollbar>
</div>
@ -159,6 +159,10 @@ export default {
position: relative;
}
.elem-span{
display:inline-block;width:77%;line-height:26px;margin-top:-4px;
}
.reminder-box {
position: absolute;
float: left;

View File

@ -57,17 +57,6 @@ export default {
this.popTipShow();
}
} else if (step.code) {
//
if (step.code.includes('TurnedAround')) {
const buttonList = this.$store.state.map.map.cycleButtonList;
if (buttonList && buttonList.length > 0) {
buttonList.forEach(element => {
if (element.cycleCode == step.code) {
step.code = element.code;
}
});
}
}
/** 默认是shape类型如果找不到坐标则可以认为是存在code的dailog*/
const position = this.getShapeTipPoint(step);
if (position) {
@ -115,9 +104,21 @@ export default {
//
getShapeTipPoint(step) {
var position = null;
//
const newStep = Object.assign({}, step);
if (newStep.code.includes('TurnedAround')) {
const buttonList = this.$store.state.map.map.cycleButtonList;
if (buttonList && buttonList.length > 0) {
buttonList.forEach(element => {
if (element.cycleCode == newStep.code) {
newStep.code = element.code;
}
});
}
}
position = this.$jlmap.getShapeTipPoint({
code: step.code,
subDeviceType: step.type
code: newStep.code,
subDeviceType: newStep.type
});
if (position) {

BIN
static/test/z025.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

BIN
static/test/z025.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 27 KiB