Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
E
evm-store
Project overview
Project overview
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
wanli
evm-store
Commits
497be17d
Commit
497be17d
authored
Jul 22, 2021
by
wanli
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
🐞
fix(): 更新资源监视器前端
parent
6ddc5256
Changes
9
Show whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
132 additions
and
60 deletions
+132
-60
tools/build_out/controllers/workbench.py
tools/build_out/controllers/workbench.py
+7
-6
tools/build_out/tests/http_interval.py
tools/build_out/tests/http_interval.py
+61
-0
tools/build_out/views/menu.py
tools/build_out/views/menu.py
+11
-11
tools/build_out/views/monitor.py
tools/build_out/views/monitor.py
+3
-1
tools/frontend/src/api/menu.js
tools/frontend/src/api/menu.js
+0
-8
tools/frontend/src/api/openapi.js
tools/frontend/src/api/openapi.js
+8
-1
tools/frontend/src/defaultSettings.js
tools/frontend/src/defaultSettings.js
+4
-4
tools/frontend/src/store/modules/global-nav.js
tools/frontend/src/store/modules/global-nav.js
+1
-1
tools/frontend/src/views/Application/Monitor.vue
tools/frontend/src/views/Application/Monitor.vue
+37
-28
No files found.
tools/build_out/controllers/workbench.py
View file @
497be17d
'''
'''
Author: your name
Author: your name
Date: 2021-07-22 04:03:24
Date: 2021-07-22 04:03:24
LastEditTime: 2021-07-22
04:03:2
4
LastEditTime: 2021-07-22
18:58:3
4
LastEditors: Please set LastEditors
LastEditors: Please set LastEditors
Description: In User Settings Edit
Description: In User Settings Edit
FilePath:
\
evm-store
\t
ools
\b
uild_out
\
controllers
\
workbench.py
FilePath:
\
evm-store
\t
ools
\b
uild_out
\
controllers
\
workbench.py
'''
'''
from
models.user
import
UserModel
from
datetime
import
datetime
,
timedelta
from
datetime
import
datetime
,
timedelta
time_now
=
datetime
.
now
()
time_now
=
datetime
.
now
()
#最近30天数据
#最近30天数据
model_user
=
User
.
query
.
filter
(
User
.
create_time
>=
time_now
-
timedelta
(
days
=
30
))
.
all
()
result
=
UserModel
.
query
.
filter
(
UserModel
.
create_time
>=
time_now
-
timedelta
(
days
=
30
))
.
all
()
#最近一周数据
#最近一周数据
model_user
=
User
.
query
.
filter
(
User
.
create_time
>=
time_now
-
timedelta
(
days
=
7
))
.
all
()
result
=
UserModel
.
query
.
filter
(
UserModel
.
create_time
>=
time_now
-
timedelta
(
days
=
7
))
.
all
()
#最近1天数据
#最近1天数据
model_user
=
User
.
query
.
filter
(
User
.
create_time
>=
time_now
-
timedelta
(
days
=
1
))
.
all
()
result
=
UserModel
.
query
.
filter
(
UserModel
.
create_time
>=
time_now
-
timedelta
(
days
=
1
))
.
all
()
#最近12小时
#最近12小时
model_user
=
User
.
query
.
filter
(
User
.
create_time
>=
time_now
-
timedelta
(
hours
=
12
))
.
all
()
result
=
UserModel
.
query
.
filter
(
UserModel
.
create_time
>=
time_now
-
timedelta
(
hours
=
12
))
.
all
()
#最近半小时
#最近半小时
model_user
=
User
.
query
.
filter
(
User
.
create_time
>=
time_now
-
timedelta
(
seconds
=
30
))
.
all
()
result
=
UserModel
.
query
.
filter
(
UserModel
.
create_time
>=
time_now
-
timedelta
(
seconds
=
30
))
.
all
()
tools/build_out/tests/http_interval.py
0 → 100644
View file @
497be17d
'''
Author: your name
Date: 2021-07-22 19:01:41
LastEditTime: 2021-07-22 21:46:18
LastEditors: Please set LastEditors
Description: In User Settings Edit
FilePath:
\
evm-store
\t
ools
\b
uild_out
\t
ests
\
http_interval.py
'''
import
json
import
random
import
requests
from
threading
import
Timer
def
send_request
():
payload
=
{
"system"
:{
"free_size"
:
1769792
,
"free_space_size"
:
5156864
,
"used_space_size"
:
1134592
},
"lvgl"
:{
"total_size"
:
0
,
"free_cnt"
:
0
,
"free_size"
:
0
,
"free_biggest_size"
:
0
,
"used_cnt"
:
0
,
"used_pct"
:
0
,
"frag_pct"
:
0
},
"evm"
:{
"heap_total_size"
:
2097152
,
"heap_used_size"
:
575072
,
"heap_map_size"
:
8192
,
"stack_total_size"
:
102400
,
"stack_used_size"
:
1312
},
"image"
:[
{
"uri"
:
"evue_launcher"
,
"length"
:
13515
,
"png_total_count"
:
0
,
"png_uncompressed_size"
:
0
,
"png_file_size"
:
0
},
{
"uri"
:
"kdgs_1_startup"
,
"length"
:
3666
,
"png_total_count"
:
0
,
"png_uncompressed_size"
:
0
,
"png_file_size"
:
0
},
{
"uri"
:
"kdgs_1_index"
,
"length"
:
5482
,
"png_total_count"
:
0
,
"png_uncompressed_size"
:
0
,
"png_file_size"
:
0
},
{
"uri"
:
"kdgs_1_story"
,
"length"
:
5509
,
"png_total_count"
:
0
,
"png_uncompressed_size"
:
0
,
"png_file_size"
:
0
},
{
"uri"
:
"kdgs_1_storyList"
,
"length"
:
9196
,
"png_total_count"
:
0
,
"png_uncompressed_size"
:
0
,
"png_file_size"
:
0
},
{
"uri"
:
"kdgs_1_storyPlay"
,
"length"
:
25791
,
"png_total_count"
:
6
,
"png_uncompressed_size"
:
319376
,
"png_file_size"
:
10770
}
],
"imei"
:
"352099001761481"
,
"datetime"
:{
"second"
:
55
,
"minute"
:
48
,
"hour"
:
15
,
"day"
:
21
,
"month"
:
7
,
"year"
:
2021
,
"weekday"
:
3
}
}
for
item
in
payload
.
get
(
"image"
):
item
.
update
({
'length'
:
0
,
'png_total_count'
:
0
,
'png_uncompressed_size'
:
0
,
'png_file_size'
:
0
})
rand_index
=
random
.
randint
(
0
,
len
(
payload
.
get
(
"image"
)))
if
rand_index
<
len
(
payload
.
get
(
"image"
)):
print
(
"------------------------------>"
)
else
:
rand_index
=
rand_index
-
1
print
(
"rand_index ==>"
,
rand_index
)
payload
.
get
(
"image"
)[
rand_index
]
.
update
({
'length'
:
random
.
randint
(
0
,
10000
),
'png_total_count'
:
random
.
randint
(
0
,
10000
),
'png_uncompressed_size'
:
random
.
randint
(
100
,
100000
),
'png_file_size'
:
random
.
randint
(
0
,
10000
)
})
r
=
requests
.
post
(
"http://localhost:3000/api/v1/evm_store/monitor"
,
data
=
json
.
dumps
(
payload
))
print
(
r
.
status_code
)
print
(
r
.
json
())
t
=
Timer
(
3
,
send_request
)
t
.
run
()
if
__name__
==
"__main__"
:
send_request
()
tools/build_out/views/menu.py
View file @
497be17d
'''
'''
Author: your name
Author: your name
Date: 2021-07-15 09:33:39
Date: 2021-07-15 09:33:39
LastEditTime: 2021-07-22 18:
49:47
LastEditTime: 2021-07-22 18:
54:43
LastEditors: Please set LastEditors
LastEditors: Please set LastEditors
Description: In User Settings Edit
Description: In User Settings Edit
FilePath:
\
evm-store
\t
ools
\b
uild_out
\v
iews
\
package.20210715165358.py
FilePath:
\
evm-store
\t
ools
\b
uild_out
\v
iews
\
package.20210715165358.py
...
@@ -26,16 +26,6 @@ class MenuResourceList(Resource):
...
@@ -26,16 +26,6 @@ class MenuResourceList(Resource):
# self.parser.add_argument("page", type=int, location="args", default=1)
# self.parser.add_argument("page", type=int, location="args", default=1)
# self.parser.add_argument("pageSize", type=int, location="args", default=15)
# self.parser.add_argument("pageSize", type=int, location="args", default=15)
# args = self.parser.parse_args()
# args = self.parser.parse_args()
try
:
json_payload
=
request
.
json
logger
.
warn
(
json_payload
)
return
response_result
(
ResponseCode
.
HTTP_INVAILD_REQUEST
)
except
Exception
as
e
:
current_app
.
logger
.
error
(
e
)
return
response_result
(
ResponseCode
.
HTTP_SERVER_ERROR
)
def
post
(
self
):
result
=
[
result
=
[
{
{
"id"
:
"1044886626813353984"
,
"id"
:
"1044886626813353984"
,
...
@@ -193,6 +183,16 @@ class MenuResourceList(Resource):
...
@@ -193,6 +183,16 @@ class MenuResourceList(Resource):
]
]
return
response_result
(
ResponseCode
.
HTTP_SUCCESS
,
data
=
result
)
return
response_result
(
ResponseCode
.
HTTP_SUCCESS
,
data
=
result
)
def
post
(
self
):
try
:
json_payload
=
request
.
json
logger
.
warn
(
json_payload
)
return
response_result
(
ResponseCode
.
HTTP_INVAILD_REQUEST
)
except
Exception
as
e
:
current_app
.
logger
.
error
(
e
)
return
response_result
(
ResponseCode
.
HTTP_SERVER_ERROR
)
class
MenuResource
(
Resource
):
class
MenuResource
(
Resource
):
def
__init__
(
self
):
def
__init__
(
self
):
pass
pass
...
...
tools/build_out/views/monitor.py
View file @
497be17d
'''
'''
Author: your name
Author: your name
Date: 2021-06-29 19:33:41
Date: 2021-06-29 19:33:41
LastEditTime: 2021-07-2
1 19:30:55
LastEditTime: 2021-07-2
2 19:30:38
LastEditors: Please set LastEditors
LastEditors: Please set LastEditors
Description: In User Settings Edit
Description: In User Settings Edit
FilePath:
\
evm-store
\b
ackend
\v
iew
\
monitor.py
FilePath:
\
evm-store
\b
ackend
\v
iew
\
monitor.py
...
@@ -172,6 +172,8 @@ class NotifyHandler(BaseWebsocket):
...
@@ -172,6 +172,8 @@ class NotifyHandler(BaseWebsocket):
# self.close()
# self.close()
return
return
logger
.
info
(
user
.
to_dict
())
# 查询该用户可查看设备
# 查询该用户可查看设备
devices
=
DeviceModel
.
query
.
filter
(
DeviceModel
.
create_by
==
user
.
id
)
.
all
()
devices
=
DeviceModel
.
query
.
filter
(
DeviceModel
.
create_by
==
user
.
id
)
.
all
()
if
len
(
devices
):
if
len
(
devices
):
...
...
tools/frontend/src/api/menu.js
deleted
100644 → 0
View file @
6ddc5256
import
request
from
'
@/utils/request
'
export
function
menuNav
()
{
return
request
({
url
:
'
https://randomuser.me/api
'
,
method
:
'
get
'
})
}
tools/frontend/src/api/openapi.js
View file @
497be17d
/*
/*
* @Author: your name
* @Author: your name
* @Date: 2021-07-15 09:33:39
* @Date: 2021-07-15 09:33:39
* @LastEditTime: 2021-07-2
0 14:53:11
* @LastEditTime: 2021-07-2
2 18:53:32
* @LastEditors: Please set LastEditors
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @Description: In User Settings Edit
* @FilePath: \evm-store\tools\frontend\src\api\openapi.js
* @FilePath: \evm-store\tools\frontend\src\api\openapi.js
*/
*/
import
request
from
"
@/utils/request
"
;
import
request
from
"
@/utils/request
"
;
export
function
menuNav
()
{
return
request
({
url
:
"
/api/v1/menu
"
,
method
:
'
get
'
})
}
export
function
getWatchList
()
{
export
function
getWatchList
()
{
return
request
({
return
request
({
url
:
"
/api/v1/monitor/watch
"
,
url
:
"
/api/v1/monitor/watch
"
,
...
...
tools/frontend/src/defaultSettings.js
View file @
497be17d
/*
/*
* @Author: your name
* @Author: your name
* @Date: 2021-07-15 09:33:39
* @Date: 2021-07-15 09:33:39
* @LastEditTime: 2021-07-22
09:50:53
* @LastEditTime: 2021-07-22
19:26:59
* @LastEditors: Please set LastEditors
* @LastEditors: Please set LastEditors
* @Description: In User Settings Edit
* @Description: In User Settings Edit
* @FilePath: \evm-store\tools\frontend\src\defaultSettings.js
* @FilePath: \evm-store\tools\frontend\src\defaultSettings.js
...
@@ -11,9 +11,9 @@ export default {
...
@@ -11,9 +11,9 @@ export default {
primaryColor
:
'
#1890FF
'
,
// primary color of ant design
primaryColor
:
'
#1890FF
'
,
// primary color of ant design
layout
:
'
sidemenu
'
,
// nav menu position: sidemenu or topmenu
layout
:
'
sidemenu
'
,
// nav menu position: sidemenu or topmenu
contentWidth
:
'
Fixed
'
,
// layout of content: Fluid or Fixed, only works when layout is topmenu
contentWidth
:
'
Fixed
'
,
// layout of content: Fluid or Fixed, only works when layout is topmenu
fixedHeader
:
fals
e
,
// sticky header
fixedHeader
:
tru
e
,
// sticky header
autoHideHeader
:
fals
e
,
// auto hide header
autoHideHeader
:
tru
e
,
// auto hide header
fixSiderbar
:
fals
e
,
// sticky siderbar
fixSiderbar
:
tru
e
,
// sticky siderbar
leftMenuTitle
:
"
EVM 应用商店
"
,
// 左侧边栏顶部名称
leftMenuTitle
:
"
EVM 应用商店
"
,
// 左侧边栏顶部名称
leftMenuIcon
:
""
,
// 左侧边栏顶部Logo
leftMenuIcon
:
""
,
// 左侧边栏顶部Logo
appSlogan
:
"
EVM,致力于为互联网行业提供物联网解决方案
"
,
// 应用宣传文案
appSlogan
:
"
EVM,致力于为互联网行业提供物联网解决方案
"
,
// 应用宣传文案
...
...
tools/frontend/src/store/modules/global-nav.js
View file @
497be17d
import
{
menuNav
}
from
"
@/api/
menu
"
;
import
{
menuNav
}
from
"
@/api/
openapi
"
;
//从服务端获取
//从服务端获取
const
mock
=
[
const
mock
=
[
...
...
tools/frontend/src/views/Application/Monitor.vue
View file @
497be17d
...
@@ -58,19 +58,19 @@
...
@@ -58,19 +58,19 @@
>
>
<p
class=
"item-title"
>
SYSTEM
</p>
<p
class=
"item-title"
>
SYSTEM
</p>
<div
class=
"grid-container"
>
<div
class=
"grid-container"
>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
host
</h3>
<h3>
host
</h3>
<p>
{{
system
.
host
}}
</p>
<p>
{{
system
.
host
}}
</p>
</div>
</div>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
timestamp
</h3>
<h3>
timestamp
</h3>
<p>
{{
system
.
timestamp
}}
</p>
<p>
{{
system
.
timestamp
}}
</p>
</div>
</div>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
imei
</h3>
<h3>
imei
</h3>
<p>
{{
system
.
imei
}}
</p>
<p>
{{
system
.
imei
}}
</p>
</div>
</div>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
free_size
</h3>
<h3>
free_size
</h3>
<p>
{{
system
.
free_size
}}
</p>
<p>
{{
system
.
free_size
}}
</p>
</div>
</div>
...
@@ -90,23 +90,23 @@
...
@@ -90,23 +90,23 @@
>
>
<p
class=
"item-title"
>
EVM
</p>
<p
class=
"item-title"
>
EVM
</p>
<div
class=
"grid-container"
>
<div
class=
"grid-container"
>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
heap_map_size
</h3>
<h3>
heap_map_size
</h3>
<p>
{{
evm
.
heap_map_size
}}
</p>
<p>
{{
evm
.
heap_map_size
}}
</p>
</div>
</div>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
heap_total_size
</h3>
<h3>
heap_total_size
</h3>
<p>
{{
evm
.
heap_total_size
}}
</p>
<p>
{{
evm
.
heap_total_size
}}
</p>
</div>
</div>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
heap_used_size
</h3>
<h3>
heap_used_size
</h3>
<p>
{{
evm
.
heap_used_size
}}
</p>
<p>
{{
evm
.
heap_used_size
}}
</p>
</div>
</div>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
stack_total_size
</h3>
<h3>
stack_total_size
</h3>
<p>
{{
evm
.
stack_total_size
}}
</p>
<p>
{{
evm
.
stack_total_size
}}
</p>
</div>
</div>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
stack_used_size
</h3>
<h3>
stack_used_size
</h3>
<p>
{{
evm
.
stack_used_size
}}
</p>
<p>
{{
evm
.
stack_used_size
}}
</p>
</div>
</div>
...
@@ -126,31 +126,31 @@
...
@@ -126,31 +126,31 @@
>
>
<p
class=
"item-title"
>
LVGL
</p>
<p
class=
"item-title"
>
LVGL
</p>
<div
class=
"grid-container"
>
<div
class=
"grid-container"
>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
total_size
</h3>
<h3>
total_size
</h3>
<p>
{{
lvgl
.
total_size
}}
</p>
<p>
{{
lvgl
.
total_size
}}
</p>
</div>
</div>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
free_cnt
</h3>
<h3>
free_cnt
</h3>
<p>
{{
lvgl
.
free_cnt
}}
</p>
<p>
{{
lvgl
.
free_cnt
}}
</p>
</div>
</div>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
free_size
</h3>
<h3>
free_size
</h3>
<p>
{{
lvgl
.
free_size
}}
</p>
<p>
{{
lvgl
.
free_size
}}
</p>
</div>
</div>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
free_biggest_size
</h3>
<h3>
free_biggest_size
</h3>
<p>
{{
lvgl
.
free_biggest_size
}}
</p>
<p>
{{
lvgl
.
free_biggest_size
}}
</p>
</div>
</div>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
used_cnt
</h3>
<h3>
used_cnt
</h3>
<p>
{{
lvgl
.
used_cnt
}}
</p>
<p>
{{
lvgl
.
used_cnt
}}
</p>
</div>
</div>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
used_pct
</h3>
<h3>
used_pct
</h3>
<p>
{{
lvgl
.
used_pct
}}
</p>
<p>
{{
lvgl
.
used_pct
}}
</p>
</div>
</div>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
frag_pct
</h3>
<h3>
frag_pct
</h3>
<p>
{{
lvgl
.
frag_pct
}}
</p>
<p>
{{
lvgl
.
frag_pct
}}
</p>
</div>
</div>
...
@@ -171,28 +171,28 @@
...
@@ -171,28 +171,28 @@
<div
style=
"width: 100%; height: 100%; overflow-y: auto"
>
<div
style=
"width: 100%; height: 100%; overflow-y: auto"
>
<p
class=
"item-title"
>
APP
</p>
<p
class=
"item-title"
>
APP
</p>
<div
class=
"grid-container"
>
<div
class=
"grid-container"
>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
uri
</h3>
<h3>
uri
</h3>
</div>
</div>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
length
</h3>
<h3>
length
</h3>
</div>
</div>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
png_file_size
</h3>
<h3>
png_file_size
</h3>
</div>
</div>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
png_total_count
</h3>
<h3>
png_total_count
</h3>
</div>
</div>
<div
class=
"grid-
item
"
>
<div
class=
"grid-
node
"
>
<h3>
png_uncompressed_size
</h3>
<h3>
png_uncompressed_size
</h3>
</div>
</div>
</div>
</div>
<div
class=
"grid-container
"
v-for=
"(item, index) in imageList"
:key=
"index"
>
<div
:class=
"['grid-container', item.highlight ? 'active' : '']
"
v-for=
"(item, index) in imageList"
:key=
"index"
>
<div
class=
"grid-
item
"
><p>
{{
item
.
uri
}}
</p></div>
<div
class=
"grid-
node
"
><p>
{{
item
.
uri
}}
</p></div>
<div
class=
"grid-
item
"
><p>
{{
item
.
length
}}
</p></div>
<div
class=
"grid-
node
"
><p>
{{
item
.
length
}}
</p></div>
<div
class=
"grid-
item
"
><p>
{{
item
.
png_file_size
}}
</p></div>
<div
class=
"grid-
node
"
><p>
{{
item
.
png_file_size
}}
</p></div>
<div
class=
"grid-
item
"
><p>
{{
item
.
png_total_count
}}
</p></div>
<div
class=
"grid-
node
"
><p>
{{
item
.
png_total_count
}}
</p></div>
<div
class=
"grid-
item
"
><p>
{{
item
.
png_uncompressed_size
}}
</p></div>
<div
class=
"grid-
node
"
><p>
{{
item
.
png_uncompressed_size
}}
</p></div>
</div>
</div>
</div>
</div>
</grid-item>
</grid-item>
...
@@ -627,11 +627,20 @@ export default {
...
@@ -627,11 +627,20 @@ export default {
.grid-container
{
.grid-container
{
display
:
flex
;
display
:
flex
;
flex-direction
:
row
;
flex-direction
:
row
;
&
>
.grid-
item
{
&
>
.grid-
node
{
flex
:
1
;
flex
:
1
;
&
>
h3
,
p
{
&
>
h3
,
p
{
display
:
flex
;
justify-content
:
center
;
flex-direction
:
row
;
align-items
:
center
;
text-align
:
center
;
text-align
:
center
;
height
:
100%
;
}
}
}
&
.active
{
color
:
#fff
;
background-color
:
#2ECCCD
;
}
}
}
}
...
...
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