Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
Cláudio Gomes
URInterface
Commits
9c4ef4c0
Commit
9c4ef4c0
authored
Sep 09, 2020
by
Claudio Gomes
Browse files
change thread comm mechanism and more documentation
parent
b05b3575
Changes
10
Hide whitespace changes
Inline
Side-by-side
.gitignore
View file @
9c4ef4c0
*.egg-info
.tox
.idea
__pycache__
.coverage
.coverage.*
htmlcov
*.pyc
docs/_build
venv
dist
.pytest_cache
.mypy_cache
build
\ No newline at end of file
README.md
View file @
9c4ef4c0
...
...
@@ -44,3 +44,25 @@ Signed image's hash is not allowed (DB).

The solution is to follow this guide: https://www.thomasmaurer.ch/2018/06/how-to-install-ubuntu-in-a-hyper-v-generation-2-virtual-machine/
## Error when running the unit tests from PyCharm
Similar error:
```
Testing started at 08:54 ...
H:\srcctrl\gitlab\urinterface\venv\Scripts\python.exe "C:\Program Files\JetBrains\PyCharm Community Edition 2020.1.1\plugins\python-ce\helpers\pycharm\_jb_pytest_runner.py" --target robot_connection_tests.py::MyTestCase.test_dummy_start_stop_record
Traceback (most recent call last):
File "C:\Program Files\JetBrains\PyCharm Community Edition 2020.1.1\plugins\python-ce\helpers\pycharm\_jb_pytest_runner.py", line 4, in <module>
import pytest
ModuleNotFoundError: No module named 'pytest'
Process finished with exit code 1
```
Solution:
1.
Clear all run configurations, and create a new one using unittest.
robot_live_tests/robot_connection_live_tests.py
View file @
9c4ef4c0
import
logging
import
math
import
time
import
unittest
...
...
test
s/__init__.py
→
src/example
s/__init__.py
View file @
9c4ef4c0
File moved
src/urinterface/__init__.py
View file @
9c4ef4c0
from
urinterface.robot_connection
import
RobotConnection
# if somebody does "from somepackage import *", this is what they will
# be able to access:
__all__
=
[
'RobotConnection'
,
]
src/urinterface/recording.py
0 → 100644
View file @
9c4ef4c0
import
logging
import
os
import
sys
from
queue
import
Queue
from
third_party.rtde
import
rtde_config
,
csv_writer
,
rtde
STOP_REQUEST
=
1
def
_start_recording
(
rtde_con
,
config_file
,
frequency
,
log
):
# Connect to RTDE
rtde_con
.
connect
()
# get controller version
rtde_con
.
get_controller_version
()
# check existence of config file
if
not
os
.
path
.
isfile
(
config_file
):
log
.
error
(
f
"Config file does not exists. Expected to find it in
{
config_file
}
. Exiting..."
)
sys
.
exit
(
1
)
conf
=
rtde_config
.
ConfigFile
(
config_file
)
output_names
,
output_types
=
conf
.
get_recipe
(
'out'
)
# setup recipes
if
not
rtde_con
.
send_output_setup
(
output_names
,
output_types
,
frequency
=
frequency
):
log
.
error
(
'Unable to configure output'
)
sys
.
exit
(
1
)
# start data synchronization
if
not
rtde_con
.
send_start
():
log
.
error
(
'Unable to start synchronization'
)
sys
.
exit
(
1
)
return
rtde_con
,
output_names
,
output_types
def
_read_csv_stream
(
filename
,
samples
,
output_names
,
output_types
,
read_row_function
,
_thread_log
):
write_mode
=
'w'
with
open
(
filename
,
write_mode
)
as
csvfile
:
writer
=
csv_writer
.
CSVWriter
(
csvfile
,
output_names
,
output_types
)
writer
.
writeheader
()
i
=
1
keep_running
=
True
while
keep_running
:
if
samples
>
0
:
_thread_log
.
debug
(
"{:.2%} done."
.
format
(
float
(
i
)
/
float
(
samples
)))
else
:
_thread_log
.
debug
(
"{:3d} samples."
.
format
(
i
))
state
,
should_continue
=
read_row_function
()
_thread_log
.
debug
(
f
"Sample received:
{
state
}
"
)
if
samples
>
0
:
keep_running
=
i
<
samples
else
:
keep_running
=
should_continue
writer
.
writerow
(
state
)
i
+=
1
def
_recording_thread
(
rtde_con
,
config_file
,
filename
,
frequency
,
samples
,
communication_queue
:
Queue
):
_thread_log
=
logging
.
getLogger
(
"Recording"
)
rtde_con
,
output_names
,
output_types
=
_start_recording
(
rtde_con
,
config_file
,
frequency
,
_thread_log
)
def
read_row_function
():
try
:
state
=
rtde_con
.
receive
(
binary
=
False
)
assert
state
is
not
None
,
state
except
rtde
.
RTDEException
:
_thread_log
.
error
(
"Disconnected"
)
rtde_con
.
disconnect
()
sys
.
exit
(
1
)
# Check if logging should be stopped.
# This does not lead to race conditions because of Python's GIL
keep_running
=
communication_queue
.
qsize
()
==
0
if
not
keep_running
:
signal
=
communication_queue
.
get_nowait
()
assert
signal
==
STOP_REQUEST
,
f
"Strange signal received:
{
signal
}
."
_thread_log
.
info
(
"Stop record signal received."
)
return
state
,
keep_running
_read_csv_stream
(
filename
,
samples
,
output_names
,
output_types
,
read_row_function
,
_thread_log
)
rtde_con
.
send_pause
()
rtde_con
.
disconnect
()
src/urinterface/robot_connection.py
View file @
9c4ef4c0
import
logging
import
socket
import
sys
import
threading
import
time
import
os
from
queue
import
Queue
import
numpy
as
np
import
logging
from
third_party.rtde
import
rtde_config
,
rtde
,
csv_writer
from
third_party.rtde
import
rtde
from
urinterface.recording
import
_recording_thread
,
STOP_REQUEST
_log
=
logging
.
getLogger
(
"RobotConnection"
)
_stop_recording
=
False
def
_start_recording
(
rtde_con
,
config_file
,
frequency
,
log
):
# Connect to RTDE
rtde_con
.
connect
()
# get controller version
rtde_con
.
get_controller_version
()
# check existence of config file
if
not
os
.
path
.
isfile
(
config_file
):
log
.
error
(
'Config file does not exists. Exiting...'
)
sys
.
exit
(
1
)
conf
=
rtde_config
.
ConfigFile
(
config_file
)
output_names
,
output_types
=
conf
.
get_recipe
(
'out'
)
# setup recipes
if
not
rtde_con
.
send_output_setup
(
output_names
,
output_types
,
frequency
=
frequency
):
log
.
error
(
'Unable to configure output'
)
sys
.
exit
(
1
)
# start data synchronization
if
not
rtde_con
.
send_start
():
log
.
error
(
'Unable to start synchronization'
)
sys
.
exit
(
1
)
return
rtde_con
,
output_names
,
output_types
def
_read_csv_stream
(
filename
,
samples
,
output_names
,
output_types
,
read_row_function
,
_thread_log
):
write_mode
=
'w'
with
open
(
filename
,
write_mode
)
as
csvfile
:
writer
=
csv_writer
.
CSVWriter
(
csvfile
,
output_names
,
output_types
)
writer
.
writeheader
()
i
=
1
keep_running
=
True
while
keep_running
:
if
samples
>
0
:
_thread_log
.
debug
(
"{:.2%} done."
.
format
(
float
(
i
)
/
float
(
samples
)))
else
:
_thread_log
.
debug
(
"{:3d} samples."
.
format
(
i
))
state
,
should_continue
=
read_row_function
()
_thread_log
.
debug
(
f
"Sample received:
{
state
}
"
)
if
samples
>
0
:
keep_running
=
i
<
samples
else
:
keep_running
=
should_continue
writer
.
writerow
(
state
)
i
+=
1
def
_recording_thread
(
rtde_con
,
config_file
,
filename
,
frequency
,
samples
):
_thread_log
=
logging
.
getLogger
(
"Recording"
)
rtde_con
,
output_names
,
output_types
=
_start_recording
(
rtde_con
,
config_file
,
frequency
,
_thread_log
)
def
read_row_function
():
state
=
None
keep_running
=
True
try
:
state
=
rtde_con
.
receive
(
binary
=
False
)
assert
state
is
not
None
,
state
except
rtde
.
RTDEException
:
_thread_log
.
error
(
"Disconnected"
)
rtde_con
.
disconnect
()
sys
.
exit
(
1
)
# Check if logging should be stopped.
# This does not lead to race conditions because of Python's GIL
global
_stop_recording
keep_running
=
not
_stop_recording
if
not
keep_running
:
_thread_log
.
info
(
"Stop record signal received."
)
return
state
,
keep_running
_read_csv_stream
(
filename
,
samples
,
output_names
,
output_types
,
read_row_function
,
_thread_log
)
rtde_con
.
send_pause
()
rtde_con
.
disconnect
()
class
RobotConnection
:
# ip_adr: <string>
# controller_socket, dashboard_socket: <socket>
...
...
@@ -109,6 +21,7 @@ class RobotConnection:
dashboard_socket
=
socket
.
socket
(
socket
.
AF_INET
,
socket
.
SOCK_STREAM
)):
self
.
ip_adr
=
ip_adr
self
.
recording_thread
=
None
self
.
recording_thread_queue
=
Queue
()
self
.
logging_process
=
None
controller_port
=
30002
dashboard_port
=
29999
...
...
@@ -190,8 +103,6 @@ class RobotConnection:
connection
=
RtdeConstructor
(
self
.
ip_adr
,
rtde_port
)
_stop_recording
=
False
self
.
recording_thread
=
threading
.
Thread
(
target
=
_recording_thread
,
args
=
[
...
...
@@ -199,7 +110,8 @@ class RobotConnection:
config_file
,
filename
,
frequency
,
samples
samples
,
self
.
recording_thread_queue
]
)
self
.
recording_thread
.
start
()
...
...
@@ -209,9 +121,8 @@ class RobotConnection:
_log
.
debug
(
f
"Stop recording requested."
)
global
_stop_recording
_stop_recording
=
True
assert
self
.
recording_thread_queue
.
empty
(),
"Expected this queue to be empty"
self
.
recording_thread_queue
.
put
(
STOP_REQUEST
)
_log
.
debug
(
f
"Waiting for thread to finish."
)
self
.
recording_thread
.
join
()
...
...
tests/resources/record_configuration.xml
0 → 100644
View file @
9c4ef4c0
<?xml version="1.0"?>
<rtde_config>
<recipe
key=
"out"
>
<field
name=
"timestamp"
type=
"DOUBLE"
/>
<field
name=
"target_q"
type=
"VECTOR6D"
/>
<field
name=
"target_qd"
type=
"VECTOR6D"
/>
<field
name=
"target_qdd"
type=
"VECTOR6D"
/>
<field
name=
"target_current"
type=
"VECTOR6D"
/>
<field
name=
"target_moment"
type=
"VECTOR6D"
/>
<field
name=
"actual_q"
type=
"VECTOR6D"
/>
<field
name=
"actual_qd"
type=
"VECTOR6D"
/>
<field
name=
"actual_current"
type=
"VECTOR6D"
/>
<field
name=
"joint_control_output"
type=
"VECTOR6D"
/>
<field
name=
"actual_TCP_pose"
type=
"VECTOR6D"
/>
<field
name=
"actual_TCP_speed"
type=
"VECTOR6D"
/>
<field
name=
"actual_TCP_force"
type=
"VECTOR6D"
/>
<field
name=
"target_TCP_pose"
type=
"VECTOR6D"
/>
<field
name=
"target_TCP_speed"
type=
"VECTOR6D"
/>
<field
name=
"actual_digital_input_bits"
type=
"UINT64"
/>
<field
name=
"joint_temperatures"
type=
"VECTOR6D"
/>
<field
name=
"actual_execution_time"
type=
"DOUBLE"
/>
<field
name=
"robot_mode"
type=
"INT32"
/>
<field
name=
"joint_mode"
type=
"VECTOR6INT32"
/>
<field
name=
"safety_mode"
type=
"INT32"
/>
<field
name=
"actual_tool_accelerometer"
type=
"VECTOR3D"
/>
<field
name=
"speed_scaling"
type=
"DOUBLE"
/>
<field
name=
"target_speed_fraction"
type=
"DOUBLE"
/>
<field
name=
"actual_momentum"
type=
"DOUBLE"
/>
<field
name=
"actual_main_voltage"
type=
"DOUBLE"
/>
<field
name=
"actual_robot_voltage"
type=
"DOUBLE"
/>
<field
name=
"actual_robot_current"
type=
"DOUBLE"
/>
<field
name=
"actual_joint_voltage"
type=
"VECTOR6D"
/>
<field
name=
"actual_digital_output_bits"
type=
"UINT64"
/>
<field
name=
"runtime_state"
type=
"UINT32"
/>
<!--
<field name="script_control_line" type="UINT32"/>
<field name="output_bit_registers0_to_31" type="UINT32"/>
<field name="output_bit_registers32_to_63" type="UINT32"/>
<field name="output_int_register_0" type="INT32"/>
<field name="output_int_register_1" type="INT32"/>
<field name="output_int_register_2" type="INT32"/>
<field name="output_int_register_3" type="INT32"/>
<field name="output_int_register_4" type="INT32"/>
<field name="output_int_register_5" type="INT32"/>
<field name="output_int_register_6" type="INT32"/>
<field name="output_int_register_7" type="INT32"/>
<field name="output_int_register_8" type="INT32"/>
<field name="output_int_register_9" type="INT32"/>
<field name="output_int_register_10" type="INT32"/>
<field name="output_int_register_11" type="INT32"/>
<field name="output_int_register_12" type="INT32"/>
<field name="output_int_register_13" type="INT32"/>
<field name="output_int_register_14" type="INT32"/>
<field name="output_int_register_15" type="INT32"/>
<field name="output_int_register_16" type="INT32"/>
<field name="output_int_register_17" type="INT32"/>
<field name="output_int_register_18" type="INT32"/>
<field name="output_int_register_19" type="INT32"/>
<field name="output_int_register_20" type="INT32"/>
<field name="output_int_register_21" type="INT32"/>
<field name="output_int_register_22" type="INT32"/>
<field name="output_int_register_23" type="INT32"/>
<field name="output_double_register_0" type="DOUBLE"/>
<field name="output_double_register_1" type="DOUBLE"/>
<field name="output_double_register_2" type="DOUBLE"/>
<field name="output_double_register_3" type="DOUBLE"/>
<field name="output_double_register_4" type="DOUBLE"/>
<field name="output_double_register_5" type="DOUBLE"/>
<field name="output_double_register_6" type="DOUBLE"/>
<field name="output_double_register_7" type="DOUBLE"/>
<field name="output_double_register_8" type="DOUBLE"/>
<field name="output_double_register_9" type="DOUBLE"/>
<field name="output_double_register_10" type="DOUBLE"/>
<field name="output_double_register_11" type="DOUBLE"/>
<field name="output_double_register_12" type="DOUBLE"/>
<field name="output_double_register_13" type="DOUBLE"/>
<field name="output_double_register_14" type="DOUBLE"/>
<field name="output_double_register_15" type="DOUBLE"/>
<field name="output_double_register_16" type="DOUBLE"/>
<field name="output_double_register_17" type="DOUBLE"/>
<field name="output_double_register_18" type="DOUBLE"/>
<field name="output_double_register_19" type="DOUBLE"/>
<field name="output_double_register_20" type="DOUBLE"/>
<field name="output_double_register_21" type="DOUBLE"/>
<field name="output_double_register_22" type="DOUBLE"/>
<field name="output_double_register_23" type="DOUBLE"/>
-->
</recipe>
</rtde_config>
tests/robot_connection_tests.py
View file @
9c4ef4c0
...
...
@@ -6,7 +6,7 @@ from urinterface.robot_connection import RobotConnection
from
utils.robot_connection_mockup
import
DummySocket
,
DummyDashboardSocket
,
DummyRTDE
class
MyTestCase
(
unittest
.
TestCase
):
class
RobotConnectionTests
(
unittest
.
TestCase
):
def
test_dummy_record
(
self
):
logging
.
basicConfig
(
level
=
logging
.
DEBUG
)
ur5e
=
RobotConnection
(
"192.168.56.101"
,
...
...
tests/robotdata.csv
0 → 100644
View file @
9c4ef4c0
timestamp target_q_0 target_q_1 target_q_2 target_q_3 target_q_4 target_q_5 target_qd_0 target_qd_1 target_qd_2 target_qd_3 target_qd_4 target_qd_5 target_qdd_0 target_qdd_1 target_qdd_2 target_qdd_3 target_qdd_4 target_qdd_5 target_current_0 target_current_1 target_current_2 target_current_3 target_current_4 target_current_5 target_moment_0 target_moment_1 target_moment_2 target_moment_3 target_moment_4 target_moment_5 actual_q_0 actual_q_1 actual_q_2 actual_q_3 actual_q_4 actual_q_5 actual_qd_0 actual_qd_1 actual_qd_2 actual_qd_3 actual_qd_4 actual_qd_5 actual_current_0 actual_current_1 actual_current_2 actual_current_3 actual_current_4 actual_current_5 joint_control_output_0 joint_control_output_1 joint_control_output_2 joint_control_output_3 joint_control_output_4 joint_control_output_5 actual_TCP_pose_0 actual_TCP_pose_1 actual_TCP_pose_2 actual_TCP_pose_3 actual_TCP_pose_4 actual_TCP_pose_5 actual_TCP_speed_0 actual_TCP_speed_1 actual_TCP_speed_2 actual_TCP_speed_3 actual_TCP_speed_4 actual_TCP_speed_5 actual_TCP_force_0 actual_TCP_force_1 actual_TCP_force_2 actual_TCP_force_3 actual_TCP_force_4 actual_TCP_force_5 target_TCP_pose_0 target_TCP_pose_1 target_TCP_pose_2 target_TCP_pose_3 target_TCP_pose_4 target_TCP_pose_5 target_TCP_speed_0 target_TCP_speed_1 target_TCP_speed_2 target_TCP_speed_3 target_TCP_speed_4 target_TCP_speed_5 actual_digital_input_bits joint_temperatures_0 joint_temperatures_1 joint_temperatures_2 joint_temperatures_3 joint_temperatures_4 joint_temperatures_5 actual_execution_time robot_mode joint_mode_0 joint_mode_1 joint_mode_2 joint_mode_3 joint_mode_4 joint_mode_5 safety_mode actual_tool_accelerometer_0 actual_tool_accelerometer_1 actual_tool_accelerometer_2 speed_scaling target_speed_fraction actual_momentum actual_main_voltage actual_robot_voltage actual_robot_current actual_joint_voltage_0 actual_joint_voltage_1 actual_joint_voltage_2 actual_joint_voltage_3 actual_joint_voltage_4 actual_joint_voltage_5 actual_digital_output_bits runtime_state
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
Write
Preview
Supports
Markdown
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