Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
H
holo-web
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
xinkong
holo-web
Commits
795327b1
Commit
795327b1
authored
Jun 28, 2023
by
ninglx
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
引入pako解压处理数据,部分接口替换固定时间参数
parent
bbe19e64
Changes
12
Show whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
182 additions
and
130 deletions
+182
-130
package.json
wj-manage-web/package.json
+1
-0
pathMap.vue
wj-manage-web/src/components/Standard/map/pathMap.vue
+19
-11
crossCompare.vue
wj-manage-web/src/views/efficiency/crossCompare.vue
+65
-45
index.vue
wj-manage-web/src/views/efficiency/index.vue
+34
-28
pathMapCtrl.vue
wj-manage-web/src/views/efficiency/pathMapCtrl.vue
+26
-4
index.vue
wj-manage-web/src/views/organization/index.vue
+5
-5
mapConflict.vue
wj-manage-web/src/views/organization/mapConflict.vue
+3
-3
mapFlow.vue
wj-manage-web/src/views/organization/mapFlow.vue
+3
-3
mapTrack.vue
wj-manage-web/src/views/organization/mapTrack.vue
+13
-9
analysisTypes.vue
wj-manage-web/src/views/safety/analysisTypes.vue
+1
-0
index.vue
wj-manage-web/src/views/safety/index.vue
+8
-6
index.vue
wj-manage-web/src/views/situation/index.vue
+4
-16
No files found.
wj-manage-web/package.json
View file @
795327b1
...
...
@@ -31,6 +31,7 @@
"highcharts-vue"
:
"^1.4.0"
,
"js-cookie"
:
"^3.0.0"
,
"js-export-excel"
:
"^1.1.4"
,
"pako"
:
"^2.1.0"
,
"protobufjs"
:
"^7.2.3"
,
"sortablejs"
:
"^1.13.0"
,
"vue-clipboard2"
:
"^0.3.1"
,
...
...
wj-manage-web/src/components/Standard/map/pathMap.vue
View file @
795327b1
...
...
@@ -32,6 +32,7 @@ export default {
// 取到数据 fullTrack 开始渲染
render
()
{
this
.
dillPath
=
JSON
.
parse
(
JSON
.
stringify
(
this
.
fullTrack
));
if
(
this
.
dillPath
[
0
]?.
carInfo
?.
length
)
{
this
.
playStatus
=
true
;
console
.
log
(
"
this.dill
"
,
this
.
fullTrack
);
map
.
flyTo
({
...
...
@@ -42,6 +43,9 @@ export default {
zoom
:
19
,
});
this
.
renderPath
(
true
);
}
else
{
this
.
$message
(
"
暂无历史轨迹数据
"
);
}
},
initMap
()
{
map
=
new
mapboxgl
.
Map
({
...
...
@@ -107,7 +111,11 @@ export default {
this
.
dillPath
=
[];
},
renderPath
(
begin
)
{
if
(
this
.
dillPath
.
length
&&
this
.
playStatus
)
{
if
(
this
.
dillPath
.
length
&&
this
.
dillPath
[
0
].
carInfo
?.
length
&&
this
.
playStatus
)
{
let
allData
=
this
.
diff
(
lastFrame
.
carInfo
,
this
.
dillPath
[
0
].
carInfo
);
// console.log(this.dillPath[0].frameTime);
this
.
$emit
(
...
...
wj-manage-web/src/views/efficiency/crossCompare.vue
View file @
795327b1
...
...
@@ -102,22 +102,22 @@ export default {
fontSize
:
getFontSize
(
12
),
},
confine
:
true
,
formatter
:
(
params
)
=>
{
// console.log("p", params);
let
str
=
`
${
params
[
0
].
axisValue
}
<br/>`
;
for
(
let
i
=
0
;
i
<
params
.
length
;
i
++
)
{
if
(
i
<=
1
)
{
str
+=
`
${
this
.
nameMap
[
params
[
i
].
seriesName
]}
(当前值)
${
params
[
i
].
value
}
%<br/>`
;
}
else
{
str
+=
`
${
this
.
nameMap
[
params
[
i
].
seriesName
]}
(对比值)
${
params
[
i
].
value
}
%<br/>`
;
}
}
return
str
;
},
//
formatter: (params) => {
//
// console.log("p", params);
//
let str = `${params[0].axisValue}
<
br
/>
`;
//
for (let i = 0; i < params.length; i++) {
//
if (i <= 1) {
//
str += `
$
{
this
.
nameMap
[
params
[
i
].
seriesName
]}(
当前值
)
$
{
//
params[i].value
//
}%
<
br
/>
`;
//
} else {
//
str += `
$
{
this
.
nameMap
[
params
[
i
].
seriesName
]}(
对比值
)
$
{
//
params[i].value
//
}%
<
br
/>
`;
//
}
//
}
//
return str;
//
},
},
legend: {
formatter: (item) => {
...
...
@@ -262,13 +262,17 @@ export default {
passingRateOptionData: {
current: {
xAxis: [],
onceStopRate
:
[],
noStopRate
:
[],
// onceStopRate: [],
// noStopRate: [],
一次停车通过率: [],
不停车通过率: [],
},
compare: {
xAxis: [],
onceStopRate
:
[],
noStopRate
:
[],
// onceStopRate: [],
// noStopRate: [],
一次停车通过率: [],
不停车通过率: [],
},
},
nameMap: {
...
...
@@ -411,10 +415,10 @@ export default {
this
.
turnMap
[
indexValue
.
turnDirNo
]
}
`
);
this
.
passingRateOptionData
.
current
.
noStopRate
.
push
(
this.passingRateOptionData.current
["不停车通过率"]
.push(
indexValue.noStopRate
);
this
.
passingRateOptionData
.
current
.
onceStopRate
.
push
(
this.passingRateOptionData.current
["一次停车通过率"]
.push(
indexValue.onceStopRate
);
}
...
...
@@ -433,10 +437,10 @@ export default {
);
}
this
.
passingRateOptionData
.
compare
.
noStopRate
.
push
(
this.passingRateOptionData.compare
["不停车通过率"]
.push(
indexValue.noStopRate
);
this
.
passingRateOptionData
.
compare
.
onceStopRate
.
push
(
this.passingRateOptionData.compare
["一次停车通过率"]
.push(
indexValue.onceStopRate
);
}
...
...
@@ -447,7 +451,23 @@ export default {
);
// debugger;
// this.passingRateChart.setOption(this.passingRateOption);
let chartTitle = { show: false };
if (
!this.passingRateOptionData.current.xAxis.length &&
!this.passingRateOptionData.compare.xAxis.length
) {
chartTitle = {
show: true,
text: "暂无数据",
left: "center",
top: "center",
textStyle: {
color: "#abb9be",
},
};
}
this.passingRateChart.setOption({
title: chartTitle,
color: ["#4082f2", "#ffa600", "#d9f4ff"],
tooltip: {
trigger: "axis",
...
...
@@ -459,27 +479,27 @@ export default {
fontSize: getFontSize(12),
},
confine: true,
formatter
:
(
params
)
=>
{
// console.log("p", params);
let
str
=
`
${
params
[
0
].
axisValue
}
<br/>`
;
for
(
let
i
=
0
;
i
<
params
.
length
;
i
++
)
{
if
(
i
<=
1
)
{
str
+=
`
${
this
.
nameMap
[
params
[
i
].
seriesName
]}
(当前值)
${
params
[
i
].
value
}
%<br/>`
;
}
else
{
str
+=
`
${
this
.
nameMap
[
params
[
i
].
seriesName
]}
(对比值)
${
params
[
i
].
value
}
%<br/>`
;
}
}
return
str
;
},
//
formatter: (params) => {
//
// console.log("p", params);
//
let str = `
$
{
params
[
0
].
axisValue
}
<
br
/>
`;
//
for (let i = 0; i < params.length; i++) {
//
if (i <= 1) {
//
str += `
$
{
this
.
nameMap
[
params
[
i
].
seriesName
]}(
当前值
)
$
{
//
params[i].value
//
}%
<
br
/>
`;
//
} else {
//
str += `
$
{
this
.
nameMap
[
params
[
i
].
seriesName
]}(
对比值
)
$
{
//
params[i].value
//
}%
<
br
/>
`;
//
}
//
}
//
return str;
//
},
},
legend: {
formatter
:
(
item
)
=>
{
return
this
.
nameMap
[
item
];
},
//
formatter: (item) => {
//
return this.nameMap[item];
//
},
right: 0,
itemGap: getFontSize(16),
itemWidth: getFontSize(12),
...
...
@@ -568,7 +588,7 @@ export default {
},
stack: 1,
label: {
show
:
key
===
"
onceStopRate
"
,
show: key === "
一次停车通过率
",
position: "bottom",
formatter: "当前值",
color: "rgba(217, 231, 255, 1)",
...
...
@@ -590,7 +610,7 @@ export default {
},
stack: 2,
label: {
show
:
key
===
"
onceStopRate
"
,
show: key === "
一次停车通过率
",
position: "bottom",
formatter: "对比值",
color: "rgba(217, 231, 255, 1)",
...
...
wj-manage-web/src/views/efficiency/index.vue
View file @
795327b1
...
...
@@ -140,14 +140,17 @@
v-model=
"noVehicleCheckList"
>
<el-checkbox
style=
"width: 100%"
label=
"机动车道"
v-show=
"scope.$index === 0"
></el-checkbox>
<el-checkbox
style=
"width: 100%"
label=
"非机动车道"
v-show=
"scope.$index === 1"
></el-checkbox>
<el-checkbox
style=
"width: 100%"
label=
"非机动车闯红灯"
v-show=
"scope.$index === 2"
></el-checkbox>
...
...
@@ -184,9 +187,9 @@
</el-table-column>
</el-table>
</div>
<div
class=
"noDataChart"
v-show=
"!tableData.length"
>
<
!-- <
div class="noDataChart" v-show="!tableData.length">
暂无数据
</div>
</div>
-->
<div
class=
"form_chart"
>
<div
class=
"ef_chart"
id=
"chart_no_vehicle"
></div>
</div>
...
...
@@ -662,12 +665,12 @@ export default {
switchTab1
()
{
if
(
this
.
tableCurrentData
)
{
this
.
pathParam
=
{
//
startTime: this.tableCurrentData.windowStartTime,
//
endTime: this.tableCurrentData.windowEndTime,
//
crossId: this.currentCrossId,
startTime
:
"
2023-05-21 18:00:25
"
,
endTime
:
"
2023-05-21 18:00:30
"
,
crossId
:
"
12F6S08J8T0
"
,
startTime
:
this
.
tableCurrentData
.
windowStartTime
,
endTime
:
this
.
tableCurrentData
.
windowEndTime
,
crossId
:
this
.
currentCrossId
,
//
startTime: "2023-05-21 18:00:25",
//
endTime: "2023-05-21 18:00:30",
//
crossId: "12F6S08J8T0",
};
this
.
pathApiName
=
"
passerbyTrack
"
;
this
.
$nextTick
(()
=>
{
...
...
@@ -702,12 +705,12 @@ export default {
switchTab2
()
{
if
(
this
.
tableCurrentData
)
{
this
.
pathParam
=
{
//
startTime: this.tableCurrentData.windowStartTime,
//
endTime: this.tableCurrentData.windowEndTime,
//
crossId: this.currentCrossId,
startTime
:
"
2023-05-21 18:00:25
"
,
endTime
:
"
2023-05-21 18:00:30
"
,
crossId
:
"
12F6S08J8T0
"
,
startTime
:
this
.
tableCurrentData
.
windowStartTime
,
endTime
:
this
.
tableCurrentData
.
windowEndTime
,
crossId
:
this
.
currentCrossId
,
//
startTime: "2023-05-21 18:00:25",
//
endTime: "2023-05-21 18:00:30",
//
crossId: "12F6S08J8T0",
};
this
.
pathApiName
=
"
noVehicleTrack
"
;
this
.
$nextTick
(()
=>
{
...
...
@@ -746,12 +749,12 @@ export default {
switchTab3
()
{
if
(
this
.
tableCurrentData
)
{
this
.
pathParam
=
{
//
startTime: this.tableCurrentData.windowStartTime,
//
endTime: this.tableCurrentData.windowEndTime,
//
crossId: this.currentCrossId,
startTime
:
"
2023-05-21 18:00:25
"
,
endTime
:
"
2023-05-21 18:00:30
"
,
crossId
:
"
12F6S08J8T0
"
,
startTime
:
this
.
tableCurrentData
.
windowStartTime
,
endTime
:
this
.
tableCurrentData
.
windowEndTime
,
crossId
:
this
.
currentCrossId
,
//
startTime: "2023-05-21 18:00:25",
//
endTime: "2023-05-21 18:00:30",
//
crossId: "12F6S08J8T0",
};
this
.
pathApiName
=
"
vehicleTrack
"
;
this
.
$nextTick
(()
=>
{
...
...
@@ -778,14 +781,14 @@ export default {
</
script
>
<
style
lang=
"less"
scoped
>
.noDataChart {
height: 40%;
display: flex;
justify-content: center;
align-items: center;
font-size: 16px;
font-weight: 700;
}
//
.noDataChart {
//
height: 40%;
//
display: flex;
//
justify-content: center;
//
align-items: center;
//
font-size: 16px;
//
font-weight: 700;
//
}
::v-deep .el-table::before {
height: 0;
...
...
@@ -881,6 +884,9 @@ export default {
font-size: 16px;
cursor: pointer;
}
::v-deep .el-checkbox {
width: 100%;
}
}
/*滚动条样式:谷歌浏览器下*/
...
...
wj-manage-web/src/views/efficiency/pathMapCtrl.vue
View file @
795327b1
...
...
@@ -29,8 +29,13 @@
>
{{
formatTime
(
Math
.
round
(
currentTime
/
1000
))
}}
/
{{
formatTime
(
Math
.
round
(
duration
/
1000
))
}}
</span
>
<el-select
class=
"ctrl-select"
>
<el-option
v-for=
"item of 4"
:key=
"item"
></el-option>
<el-select
v-model=
"speedValue"
class=
"ctrl-select"
>
<el-option
v-for=
"item of speeds"
:key=
"item.value"
:label=
"item.label"
:value=
"item.value"
></el-option>
</el-select>
</div>
</div>
...
...
@@ -39,6 +44,7 @@
<
script
>
let
protobuf
=
require
(
"
protobufjs
"
);
let
pako
=
require
(
"
pako
"
);
let
FrameList
;
protobuf
.
load
(
"
../wj-manage-web/RealtimeCarInfo.proto
"
,
(
event
,
root
)
=>
{
FrameList
=
root
.
lookupType
(
"
com.wanji.holo.proto.FrameList
"
);
...
...
@@ -51,6 +57,12 @@ export default {
components
:
{
pathMap
},
data
()
{
return
{
speeds
:
[
{
value
:
1
,
label
:
"
正常速度
"
},
// {value:'',label:''},
// {value:'',label:''},
],
speedValue
:
1
,
currentTime
:
0
,
fullTrack
:
[],
playFlag
:
true
,
...
...
@@ -98,18 +110,27 @@ export default {
// ref调用此方法请求并播放轨迹
getTracksAndPlay
()
{
console
.
log
(
"
this.params
"
,
this
.
params
);
let
customParam
=
{
startTime
:
"
2023-05-21 18:00:25
"
,
endTime
:
"
2023-05-21 18:00:30
"
,
crossId
:
"
12F6S08J8T0
"
,
};
this
.
$refs
.
pathMap
.
clearAll
();
this
.
playFlag
=
true
;
// 计算轨迹总时长
let
diff
=
new
Date
(
this
.
params
.
endTime
).
getTime
()
-
new
Date
(
this
.
params
.
startTime
).
getTime
();
// let diff =
// new Date(customParam.endTime).getTime() -
// new Date(customParam.startTime).getTime();
this
.
duration
=
diff
;
this
.
fullTrack
=
[];
this
.
loading
=
true
;
trackApi
[
this
.
apiName
](
this
.
params
).
then
((
res
)
=>
{
let
buf
=
new
Uint8Array
(
res
);
let
realData
=
FrameList
.
decode
(
buf
);
// trackApi[this.apiName](customParam).then((res) => {
let
data
=
pako
.
inflate
(
res
);
// pako解压为protobuf
let
realData
=
FrameList
.
decode
(
data
);
// protobuf根据定义类型转json
this
.
fullTrack
=
realData
.
frameInfo
;
this
.
$nextTick
(()
=>
{
this
.
loading
=
false
;
...
...
@@ -186,6 +207,7 @@ export default {
::v-deep .el-input__inner {
height: 24px;
line-height: 24px;
padding: 0 8px;
}
::v-deep .el-input__icon {
height: 24px;
...
...
wj-manage-web/src/views/organization/index.vue
View file @
795327b1
...
...
@@ -405,7 +405,7 @@ export default {
type
:
1
,
crossId
:
e
.
crossId
,
rid
:
rid
.
rid
,
//
...timeParam,
...
timeParam
,
})
);
jinchukouList
.
push
(
rid
.
type
);
...
...
@@ -423,7 +423,7 @@ export default {
crossId
:
e
.
crossId
,
type
:
1
,
rid
:
chukouRid
,
//
...timeParam,
...
timeParam
,
}).
then
((
res
)
=>
{
console
.
log
(
"
转向流量趋势图
"
,
res
);
this
.
loadFlowChart1
(
res
.
content
);
...
...
@@ -496,7 +496,7 @@ export default {
show
:
true
,
text
:
"
暂无数据
"
,
left
:
"
center
"
,
top
:
'
center
'
,
top
:
"
center
"
,
textStyle
:
{
color
:
"
#abb9be
"
,
},
...
...
@@ -646,7 +646,7 @@ export default {
let
timeParam
=
this
.
getStartAndEndDate
();
orgPasserby
({
crossId
:
this
.
currentCrossData
.
id
,
//
...timeParam,
...
timeParam
,
}).
then
((
res
)
=>
{
console
.
log
(
"
orgpasserby
"
,
res
);
this
.
passerbyFormCheck
=
res
.
content
.
filter
((
item
)
=>
{
...
...
@@ -670,7 +670,7 @@ export default {
let
timeParam
=
this
.
getStartAndEndDate
();
orgNoVehicle
({
crossId
:
this
.
currentCrossData
.
id
,
// ...timeParam
...
timeParam
,
}).
then
((
res
)
=>
{
console
.
log
(
"
orgnovehicle
"
,
res
);
this
.
noVehicleFormCheck
=
res
.
content
.
filter
((
item
)
=>
{
...
...
wj-manage-web/src/views/organization/mapConflict.vue
View file @
795327b1
...
...
@@ -117,9 +117,9 @@ export default {
let
timeParam
=
this
.
timeData
;
orgConflict
({
crossId
:
this
.
rowData
.
id
,
startDate
:
""
,
endDate
:
""
,
//
...timeParam,
//
startDate: "",
//
endDate: "",
...
timeParam
,
}).
then
((
res
)
=>
{
console
.
log
(
"
conflict...
"
,
res
);
this
.
allConflicts
=
res
.
content
;
...
...
wj-manage-web/src/views/organization/mapFlow.vue
View file @
795327b1
...
...
@@ -61,9 +61,9 @@ export default {
orgCrossPolygon
(
params
),
orgFlowByLane
({
crossId
:
this
.
rowData
.
id
,
startDate
:
""
,
endDate
:
""
,
//
...timeParam,
//
startDate: "",
//
endDate: "",
...
timeParam
,
}),
orgLaneLine
({
crossId
:
this
.
rowData
.
id
}),
]).
then
(([
res
,
flow
,
line
])
=>
{
...
...
wj-manage-web/src/views/organization/mapTrack.vue
View file @
795327b1
...
...
@@ -56,12 +56,16 @@ export default {
// millPoints.push({lng:Math.random()*100,lat:Math.random()*160})
// }
// let param = {startTime:this.timeData.startDate,endTime:this.timeData.endDate, crossId:this.rowData.id}
let
param
=
{
startTime
:
"
2023-05-21 18:00:25
"
,
endTime
:
"
2023-05-21 18:00:30
"
,
crossId
:
"
12F6S08J8T0
"
,
startTime
:
this
.
timeData
.
startDate
,
endTime
:
this
.
timeData
.
endDate
,
crossId
:
this
.
rowData
.
id
,
};
// let param = {
// startTime: "2023-05-21 18:00:25",
// endTime: "2023-05-21 18:00:30",
// crossId: "12F6S08J8T0",
// };
allTrack
(
param
).
then
((
res
)
=>
{
let
buf
=
new
Uint8Array
(
res
);
let
realData
=
FrameList
.
decode
(
buf
);
...
...
@@ -74,11 +78,11 @@ export default {
}
console
.
log
(
"
before render
"
,
millPoints
);
//---
map
.
flyTo
({
center
:
[
millPoints
[
0
].
longitude
,
millPoints
[
0
].
latitude
],
maxDuration
:
1000
,
zoom
:
17.2
,
});
//
map.flyTo({
//
center: [millPoints[0].longitude, millPoints[0].latitude],
//
maxDuration: 1000,
//
zoom: 17.2,
//
});
//---
l7Tools
.
addTrackEasyPoint
(
scene
,
millPoints
);
this
.
loading
=
false
;
...
...
wj-manage-web/src/views/safety/analysisTypes.vue
View file @
795327b1
...
...
@@ -232,6 +232,7 @@ export default {
}
,
series
:
{
markLine
:
{
silent
:
true
,
data
:
[
{
symbol
:
"
none
"
,
...
...
wj-manage-web/src/views/safety/index.vue
View file @
795327b1
...
...
@@ -50,14 +50,13 @@
</div>
<el-divider></el-divider>
<div
class=
"tabs_bottom"
>
<
!--
<
path-map-ctrl
<path-map-ctrl
:params=
"pathParam"
:apiName=
"pathApiName"
ref=
"pathMap"
class=
"commonPathMap"
style=
"position: absolute"
/>
-->
<path-map-ctrl
ref=
"pathMap"
class=
"commonPathMap"
/>
/>
<!--
<path-map-ctrl
ref=
"pathMap"
class=
"commonPathMap"
/>
-->
<el-tabs
:before-leave=
"beforeLeaveTab"
v-model=
"tabsActiveName"
...
...
@@ -173,8 +172,11 @@ export default {
startTime
:
row
.
startTime
,
endTime
:
row
.
endTime
,
};
this
.
pathParam
=
{};
this
.
pathApiName
=
""
;
this
.
pathParam
=
{
...
this
.
cameraTimeBetween
,
crossId
:
row
.
crossId
,
};
this
.
pathApiName
=
"
allTrack
"
;
this
.
$nextTick
(()
=>
{
this
.
$refs
.
pathMap
.
getTracksAndPlay
();
});
...
...
wj-manage-web/src/views/situation/index.vue
View file @
795327b1
...
...
@@ -977,23 +977,11 @@ export default {
layers
.
first
.
license
=
l7Tools
.
addLicenseLayer
(
scene
,
msg
);
layers
.
first
.
licenseBack
=
l7Tools
.
addLicenseBackLayer
(
scene
,
msg
);
}
else
{
// for (let i = 0; i
<
msg
.
length
;
i
++
)
{
// for (let old of layers.first.license.encodedData) {
// if (
// msg[i].picLicense === old.shape &&
// turf.distance(
// [msg[i].longitude, msg[i].latitude],
// old.coordinates,
// { units: "kilometers" }
// )
<
0.0005
// ) {
// msg[i].longitude = old.coordinates[0];
// msg[i].latitude = old.coordinates[1];
// }
// }
// }
layers
.
first
.
license
.
setData
(
msg
);
layers
.
first
.
licenseBack
.
setData
(
msg
);
let
backData
=
msg
.
filter
((
item
)
=>
{
return
item
.
picLicense
!==
""
;
});
layers
.
first
.
licenseBack
.
setData
(
backData
);
show
(
layers
.
first
.
license
);
show
(
layers
.
first
.
licenseBack
);
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment