Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
SRCT
schedules
Commits
9d104142
Commit
9d104142
authored
Oct 11, 2018
by
Zac Wood
Browse files
fixed course card header
parent
6c8d6b74
Changes
22
Hide whitespace changes
Inline
Side-by-side
schedules/app/assets/javascripts/application.js
View file @
9d104142
...
...
@@ -24,7 +24,7 @@ const elementFromString = string => {
};
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
this
.
schedule
=
new
Schedule
();
this
.
cart
=
new
Cart
();
});
const
setSemester
=
async
select
=>
{
...
...
schedules/app/assets/javascripts/
schedule
.js
→
schedules/app/assets/javascripts/
cart
.js
View file @
9d104142
class
Schedule
{
class
Cart
{
constructor
()
{
this
.
isOpen
=
false
;
this
.
_courses
=
{};
// {title, id, sections: {id, crn}}
...
...
@@ -12,7 +12,7 @@ class Schedule {
}
document
.
getElementById
(
'
course-counter
'
).
innerText
=
Object
.
keys
(
this
.
_courses
).
length
;
this
.
_ids
=
Array
.
from
(
document
.
getElementById
(
'
schedule
'
).
children
).
map
(
e
=>
e
.
dataset
.
crn
);
this
.
_ids
=
Array
.
from
(
document
.
getElementById
(
'
cart-courses
'
).
children
).
map
(
e
=>
e
.
dataset
.
crn
);
}
get
crns
()
{
...
...
@@ -45,12 +45,12 @@ class Schedule {
addCourse
(
course
)
{
this
.
_courses
[
course
.
id
]
=
course
;
const
paren
t
=
document
.
querySelector
(
'
#schedule
'
);
const
cur
rent
=
paren
t
.
querySelector
(
`#schedule-
${
course
.
id
}
`
);
const
courseLis
t
=
document
.
getElementById
(
'
cart-courses
'
);
const
c
o
ur
seNode
=
courseLis
t
.
querySelector
(
`#schedule-
${
course
.
id
}
`
);
const
newNode
=
this
.
_constructCourseNode
(
course
);
if
(
cur
rent
!==
null
)
paren
t
.
replaceChild
(
newNode
,
cur
rent
);
else
paren
t
.
appendChild
(
newNode
);
if
(
c
o
ur
seNode
!==
null
)
courseLis
t
.
replaceChild
(
newNode
,
c
o
ur
seNode
);
else
courseLis
t
.
appendChild
(
newNode
);
document
.
getElementById
(
'
course-counter
'
).
innerText
=
Object
.
keys
(
this
.
_courses
).
length
;
fetch
(
`/sessions/update?section_ids=
${
this
.
ids
.
join
(
'
,
'
)}
`
,
{
cache
:
'
no-store
'
});
...
...
@@ -65,9 +65,9 @@ class Schedule {
delete
this
.
_courses
[
id
];
const
paren
t
=
document
.
querySelector
(
'
#schedule
'
);
const
current
=
paren
t
.
querySelector
(
`#schedule-
${
id
}
`
);
paren
t
.
removeChild
(
current
);
const
courseLis
t
=
document
.
getElementById
(
'
cart-courses
'
);
const
current
=
courseLis
t
.
querySelector
(
`#schedule-
${
id
}
`
);
courseLis
t
.
removeChild
(
current
);
document
.
getElementById
(
'
course-counter
'
).
innerText
=
Object
.
keys
(
this
.
_courses
).
length
;
fetch
(
`/sessions/update?section_ids=
${
this
.
ids
.
join
(
'
,
'
)}
`
,
{
cache
:
'
no-store
'
});
...
...
@@ -93,7 +93,7 @@ class Schedule {
if
(
course
)
{
course
.
sections
.
push
(
section
);
const
courseNode
=
document
.
querySelector
(
'
#schedule
'
).
querySelector
(
`#schedule-
${
course
.
id
}
`
);
const
courseNode
=
document
.
getElementById
(
`#schedule-
${
course
.
id
}
`
);
const
crnList
=
courseNode
.
querySelector
(
'
.crns
'
);
crnList
.
innerText
=
course
.
sections
.
map
(
s
=>
`#
${
s
.
crn
}
`
);
...
...
@@ -109,7 +109,7 @@ class Schedule {
removeSection
(
section
)
{
const
course
=
this
.
courseContainingSection
(
section
.
id
);
course
.
sections
=
course
.
sections
.
filter
(
s
=>
s
.
id
!==
section
.
id
);
const
schedule
=
document
.
querySelector
(
'
#
schedule
'
);
const
schedule
=
document
.
querySelector
(
'
#
cart-courses
'
);
const
courseNode
=
schedule
.
querySelector
(
`#schedule-
${
course
.
id
}
`
);
const
crnList
=
courseNode
.
querySelector
(
'
.crns
'
);
if
(
course
.
sections
.
length
===
0
)
{
...
...
@@ -148,5 +148,5 @@ class Schedule {
}
const
removeCourse
=
id
=>
{
this
.
schedule
.
removeCourse
(
id
);
this
.
cart
.
removeCourse
(
id
);
};
schedules/app/assets/javascripts/schedules.js
0 → 100644
View file @
9d104142
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
const
eventsTemplate
=
document
.
querySelector
(
'
#events
'
);
if
(
eventsTemplate
)
{
const
eventsJSON
=
eventsTemplate
.
dataset
.
events
;
const
events
=
JSON
.
parse
(
eventsJSON
);
console
.
log
(
events
);
$
(
'
#calendar
'
).
fullCalendar
({
defaultDate
:
new
Date
(
2019
,
0
,
14
),
defaultView
:
'
agendaWeek
'
,
header
:
false
,
events
:
events
,
});
}
});
schedules/app/assets/javascripts/search.js
View file @
9d104142
...
...
@@ -9,23 +9,23 @@ const addCourse = (event, id) => {
const
sectionsItems
=
Array
.
from
(
courseCard
.
querySelectorAll
(
'
li
'
));
const
sections
=
sectionsItems
.
map
(
li
=>
({
...
li
.
dataset
}));
this
.
schedule
.
addCourse
({
title
,
id
,
sections
});
this
.
cart
.
addCourse
({
title
,
id
,
sections
});
sectionsItems
.
forEach
(
s
=>
s
.
classList
.
add
(
'
selected
'
));
event
.
stopPropagation
();
};
/**
* Either adds or removes a section from the
schedule
depending on
* if it is currently in the
schedule
.
* Either adds or removes a section from the
cart
depending on
* if it is currently in the
cart
.
*/
const
addOrRemoveFrom
Schedule
=
(
event
,
sectionNode
)
=>
{
const
addOrRemoveFrom
Cart
=
(
event
,
sectionNode
)
=>
{
const
section
=
{
...
sectionNode
.
dataset
};
if
(
this
.
schedule
.
includesSection
(
section
.
id
))
{
this
.
schedule
.
removeSection
(
section
);
if
(
this
.
cart
.
includesSection
(
section
.
id
))
{
this
.
cart
.
removeSection
(
section
);
sectionNode
.
classList
.
remove
(
'
selected
'
);
}
else
{
this
.
schedule
.
addSection
(
section
);
this
.
cart
.
addSection
(
section
);
sectionNode
.
classList
.
add
(
'
selected
'
);
}
...
...
@@ -33,15 +33,15 @@ const addOrRemoveFromSchedule = (event, sectionNode) => {
};
/**
* Removes a given section from the
schedule
* @param {Node} DOM Node of the Section in the
schedule
* Removes a given section from the
cart
* @param {Node} DOM Node of the Section in the
cart
*/
const
removeFrom
Schedule
=
section
=>
{
const
removeFrom
Cart
=
section
=>
{
const
sectionInSearch
=
sectionWithCrn
(
section
.
dataset
.
crn
);
if
(
sectionInSearch
)
{
sectionInSearch
.
classList
.
remove
(
'
selected
'
);
}
this
.
schedule
.
removeFromSchedule
(
section
.
dataset
.
crn
);
this
.
cart
.
removeFromSchedule
(
section
.
dataset
.
crn
);
};
/**
...
...
@@ -62,5 +62,5 @@ const toggleSections = course => {
* and sets the link in the modal to it.
*/
const
setUrlInModal
=
()
=>
{
document
.
getElementById
(
'
calendar-link
'
).
innerText
=
`https://
${
window
.
location
.
hostname
}
/api/schedule?crns=
${
this
.
schedule
.
ids
.
join
(
'
,
'
)}
`
;
document
.
getElementById
(
'
calendar-link
'
).
innerText
=
`https://
${
window
.
location
.
hostname
}
/api/schedule?crns=
${
this
.
cart
.
ids
.
join
(
'
,
'
)}
`
;
};
schedules/app/assets/stylesheets/application.scss
View file @
9d104142
...
...
@@ -27,23 +27,26 @@ body {
box-shadow
:
0
0
5px
rgba
(
0
,
0
,
0
,
0
.2
);
transition
:
0
.3s
;
.card-header
{
display
:
flex
;
flex-direction
:
column
;
display
:
flex
;
flex-direction
:
column
;
}
.card-body
{
.attr-list
{
display
:
flex
;
flex-direction
:
row
;
justify-content
:
flex-start
;
padding-bottom
:
10px
;
.attr
{
margin-right
:
13px
;
}
}
.attr-list
{
display
:
flex
;
flex-direction
:
row
;
.attr
{
.icon
{
padding-right
:
4px
;
}
align-items
:
center
;
display
:
inline-flex
;
white-space
:
nowrap
;
}
}
}
}
...
...
@@ -98,35 +101,8 @@ body {
align-items
:
center
;
}
#navbar
{
margin-top
:
8px
;
margin-bottom
:
48px
;
}
#logo
{
font-size
:
24pt
;
color
:
black
;
}
.form-control
:focus
{
border-color
:
transparent
;
box-shadow
:
0px
0px
0px
rgba
(
0
,
0
,
0
,
0
.075
)
inset
,
0px
0px
0px
rgba
(
0
,
0
,
255
,
0
.5
);
}
#cart
{
display
:
none
;
}
.card
.small
{
margin-bottom
:
16px
;
padding
:
12px
;
}
#add-course-btn
:hover
{
background-color
:
rgba
(
0
,
0
,
0
,
0
.2
);
}
#calendar
{
background-color
:
white
;
padding
:
16px
;
}
schedules/app/assets/stylesheets/cart.scss
0 → 100644
View file @
9d104142
.cart-course
{
display
:
flex
;
justify-content
:
space-between
;
.title
{
min-width
:
15%
;
}
.crns
{
color
:
gray
;
font-size
:
10pt
;
}
}
#cart
{
display
:
none
;
}
schedules/app/assets/stylesheets/courses.scss
View file @
9d104142
// Place all the styles related to the Courses controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
#add-course-btn
:hover
{
background-color
:
rgba
(
0
,
0
,
0
,
0
.2
);
}
schedules/app/assets/stylesheets/navbar.scss
0 → 100644
View file @
9d104142
.center-vert
{
display
:
flex
;
justify-content
:
center
;
align-items
:
center
;
}
#navbar
{
margin-top
:
8px
;
margin-bottom
:
48px
;
}
#logo
{
font-size
:
24pt
;
color
:
black
;
}
schedules/app/assets/stylesheets/schedule.scss
0 → 100644
View file @
9d104142
#calendar
{
background-color
:
white
;
padding
:
16px
;
}
schedules/app/assets/stylesheets/sessions.scss
deleted
100644 → 0
View file @
6c8d6b74
// Place all the styles related to the sessions controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/
schedules/app/controllers/schedules_controller.rb
View file @
9d104142
...
...
@@ -25,11 +25,15 @@ class SchedulesController < ApplicationController
"S"
:
Date
.
new
(
2019
,
1
,
19
),
"U"
:
Date
.
new
(
2019
,
1
,
20
)
}.
freeze
def
show
all_sections
=
@cart
.
values
# schedules = []
all_sections
.
each_with_index
do
|
sections
,
i
|
end
@events
=
@cart
.
map
do
|
_cid
,
sections
|
s
=
sections
.
first
s
.
days
.
split
(
''
).
map
do
|
day
|
formatted_date
=
DAYS
[
day
.
to_sym
].
to_s
.
tr
(
'-'
,
''
)
time
=
Time
.
parse
(
s
.
start_time
).
strftime
(
"%H%M%S"
)
...
...
@@ -41,7 +45,6 @@ class SchedulesController < ApplicationController
end:
"
#{
formatted_date
}
T
#{
endtime
}
"
}
end
end
.
flatten
end
end
schedules/app/controllers/search_controller.rb
View file @
9d104142
class
SearchController
<
ApplicationController
def
index
@results
=
SearchHelper
::
GenericItem
.
fetchall
(
params
[
:query
],
semester:
@semester
)
results
=
SearchHelper
::
GenericItem
.
fetchall
(
params
[
:query
],
semester:
@semester
).
group_by
(
&
:type
)
@instructors
=
results
[
:instructor
]
@courses
=
results
[
:course
]
end
end
schedules/app/helpers/search_helper.rb
View file @
9d104142
...
...
@@ -29,9 +29,10 @@ module SearchHelper
end
def
self
.
fetch_instructors
(
query_data
)
Instructor
.
from_name
(
Instructor
.
select
(
"instructors.*, COUNT(course_sections.id) AS section_count"
),
query_data
.
search_string
)
.
left_outer_joins
(
:course_sections
)
.
group
(
"instructors.id"
)
Instructor
.
from_name
(
Instructor
.
select
(
"instructors.*, COUNT(course_sections.id) AS section_count"
),
query_data
.
search_string
)
.
left_outer_joins
(
:course_sections
)
.
group
(
"instructors.id"
)
end
def
self
.
fetch_courses
(
query_data
)
...
...
schedules/app/models/course_section.rb
View file @
9d104142
...
...
@@ -13,9 +13,9 @@ class CourseSection < ApplicationRecord
def
labs
return
nil
unless
section_type
==
"Lecture"
lecture_number
=
name
.
split
[
name
.
split
.
length
-
1
]
lecture_number
=
name
.
split
[
name
.
split
.
length
-
1
]
course
.
course_sections
.
select
do
|
s
|
s
.
title
.
split
[
s
.
title
.
split
.
length
-
1
]
==
lecture_number
s
.
title
.
split
[
s
.
title
.
split
.
length
-
1
]
==
lecture_number
end
end
...
...
schedules/app/views/schedules/show.html.erb
View file @
9d104142
...
...
@@ -7,16 +7,6 @@
* var calendar = new Calendar(cal, {
* defaultView: 'agendaWeek'
* }); */
document
.
addEventListener
(
'
DOMContentLoaded
'
,
()
=>
{
const
eventsJSON
=
document
.
querySelector
(
'
#events
'
).
dataset
.
events
;
const
events
=
JSON
.
parse
(
eventsJSON
);
console
.
log
(
events
);
$
(
'
#calendar
'
).
fullCalendar
({
defaultDate
:
new
Date
(
2019
,
0
,
14
),
defaultView
:
'
agendaWeek
'
,
header
:
{
right
:
'
next
'
},
events
:
events
});
});
</script>
schedules/app/views/search/index.html.erb
View file @
9d104142
<%
if
@results
.
any?
%>
<%
@results
.
each
do
|
result
|
%>
<%
if
result
.
type
==
:course
%>
<%=
render
partial:
'shared/course'
,
object:
result
.
data
%>
<%
elsif
result
.
type
==
:instructor
%>
<%=
render
partial:
'shared/instructor'
,
object:
result
.
data
%>
<%
unless
@instructors
.
nil?
%>
<h2>
Instructors
</h2>
<div
class=
"row"
>
<%
@instructors
.
map
(
&
:data
).
each
do
|
instructor
|
%>
<div
class=
"col"
>
<%=
render
partial:
'shared/instructor'
,
object:
instructor
%>
</div>
<%
end
%>
</div>
<hr
/>
<%
end
%>
<%
unless
@courses
.
nil?
%>
<h2>
Courses
</h2>
<%
@courses
.
map
(
&
:data
).
each
do
|
course
|
%>
<div
class=
"col"
>
<%=
render
partial:
'shared/course'
,
object:
course
%>
</div>
<%
end
%>
<%
end
%>
<%
else
%>
<h1>
Sorry, we couldn't find anything matching your search.
</h1>
<p>
Please try again!
</p>
<%
end
%>
<%
if
@courses
.
nil?
&&
@instructors
.
nil?
%>
<h1>
Sorry, we couldn't find anything matching your search.
</h1>
<p>
Please try again!
</p>
<%
end
%>
schedules/app/views/shared/_cart.html.erb
View file @
9d104142
...
...
@@ -4,26 +4,21 @@
<div
class=
"col order-1 order-lg-1"
id=
"cart"
>
<div
class=
"card"
>
<div
class=
"card-body"
>
<h3
class=
"card-title"
>
<%=
link_to
'Your
Schedule
'
,
schedule_path
%>
</h3>
<h3
class=
"card-title"
>
<%=
link_to
'Your
Cart
'
,
schedule_path
%>
</h3>
</div>
<ul
class=
"list-group list-group-flush"
id=
"
schedule
"
>
<ul
class=
"list-group list-group-flush"
id=
"
cart-courses
"
>
<%
@cart
.
each
do
|
cid
,
sections
|
%>
<%
course
=
Course
.
find_by_id
(
cid
)
%>
<li
id=
"schedule-
<%=
cid
%>
"
class=
"list-group-item
schedule-section-card
"
onclick=
"removeCourse(
<%=
cid
%>
)"
>
<div
style=
"display: flex; justify-content: space-between;
"
>
<b
style=
"min-width: 15%
"
>
<%=
"
#{
course
.
subject
}
#{
course
.
course_number
}
"
%>
</b>
<span
class=
"crns"
style=
"color: gray; font-size: 10pt;"
>
<li
id=
"schedule-
<%=
cid
%>
"
class=
"list-group-item"
onclick=
"removeCourse(
<%=
cid
%>
)"
>
<div
class=
"cart-course
"
>
<b
class=
"title
"
>
<%=
"
#{
course
.
subject
}
#{
course
.
course_number
}
"
%>
</b>
<span
class=
"crns"
>
<%=
sections
.
map
{
|
s
|
"#
#{
s
.
crn
}
"
}.
join
(
', '
)
%>
</span>
</div>
</li>
<%
end
%>
</ul>
<div
class=
"card-body"
>
<button
type=
"button"
class=
"btn btn-primary"
data-toggle=
"modal"
data-target=
"#exportModal"
onclick=
"setUrlInModal()"
>
Export schedule
</button>
</div>
</div>
</div>
...
...
schedules/app/views/shared/_course.html.erb
View file @
9d104142
...
...
@@ -2,16 +2,34 @@
<div
class=
"card"
id=
"course-
<%=
course
.
id
%>
"
onclick=
"toggleSections(this)"
>
<div
class=
"card-header"
>
<h4
class=
"title"
>
<%=
"
#{
course
.
subject
}
#{
course
.
course_number
}
"
%>
</h4>
<h5><em>
<%=
course
.
title
%>
</em>
.
<%=
course
.
credits
%>
credits.
</h5>
<h4
id=
"add-course-btn"
onclick=
"addCourse(event, '
<%=
course
.
id
%>
');"
>
<i
class=
"fas fa-plus"
style=
"color: green"
></i>
</h4>
<div
class=
"row"
>
<div
class=
"col"
>
<h4
class=
"title"
>
<%=
"
#{
course
.
subject
}
#{
course
.
course_number
}
"
%>
</h4>
</div>
<div
class=
"col"
>
<h4
id=
"add-course-btn"
class=
"text-right"
onclick=
"addCourse(event, '
<%=
course
.
id
%>
');"
>
<i
class=
"fas fa-plus"
style=
"color: green"
></i>
</h4>
</div>
</div>
<h5><em>
<%=
course
.
title
%>
</em></h5>
</div>
<div
class=
"card-body"
>
<div
class=
"attr-list"
>
<div
class=
"attr"
><i
class=
"fa fa-book"
></i>
3 credits
</div>
<div
class=
"attr"
><i
class=
"fa fa-bars"
></i>
3 sections
</div>
<div
class=
"attr-list justify-content-start"
>
<div
class=
"attr"
>
<div
class=
"icon"
>
<i
class=
"fa fa-book"
></i>
</div>
3 credits
</div>
<div
class=
"attr"
>
<div
class=
"icon"
>
<i
class=
"fa fa-bars"
></i>
</div>
3 sections
</div>
</div>
<p
class=
"description"
>
<%=
course
.
description
%>
</p>
...
...
schedules/app/views/shared/_instructor.html.erb
View file @
9d104142
<div
class=
"card"
>
<div
class=
"card-header"
>
<h4>
<%=
"
#{
instructor
.
name
}
"
%>
</h4>
</div>
<div
class=
"card-body"
>
<div
class=
"attr-list"
>
<div
class=
"attr"
><i
class=
"fa fa-user"
></i>
Instructor
</div>
<div
class=
"attr"
><i
class=
"fa fa-bars"
></i>
<%=
"
#{
instructor
.
section_count
}
"
%>
sections
</div>
<div
class=
"card-body"
>
<div
class=
"attr-list justify-content-between"
>
<div
class=
"attr"
>
<div
class=
"icon"
>
<i
class=
"fa fa-user"
></i>
</div>
<%=
link_to
instructor
.
name
,
instructor_path
(
instructor
)
%>
</div>
<div
class=
"attr"
>
<div
class=
"icon"
>
<i
class=
"fa fa-bars"
></i>
</div>
<%=
"
#{
instructor
.
section_count
}
"
%>
sections
</div>
</div>
</div>
</div>
</div>
\ No newline at end of file
</div>
schedules/app/views/shared/_navbar.html.erb
View file @
9d104142
<div
class=
"container-fluid"
>
<div
class=
"row align-left align-sm-center align-md-right"
id=
"navbar"
>
<div
class=
"col align-center"
>
<div>
<div
class=
"center-vert"
>
<a
href=
"/"
id=
"logo"
>
<i
class=
"fas fa-calendar-alt"
></i>
Schedules
</a>
<select
onchange=
"setSemester(this)"
>
<%
Semester
.
all
.
each
do
|
semester
|
%>
<option
value=
"
<%=
semester
.
id
%>
"
<%
if
@semester
==
semester
%>
selected
<%
end
%>
>
<%=
"
#{
semester
.
season
}
#{
semester
.
year
}
"
%>
</option>
<%
end
%>
</select>
</select>
</div>
</div>
<div
class=
"col-sm align-center order-0 order-sm-1"
onclick=
"window.
schedule
.toggle()"
>
<div
class=
"col-sm align-center order-0 order-sm-1"
onclick=
"window.
cart
.toggle()"
>
<h1
style=
"margin-top:24px"
>
<span
class=
"fa-layers fa-fw"
id=
"schedule-icon"
>
<i
class=
"fas fa-shopping-cart"
></i>
...
...
@@ -29,17 +30,15 @@
</span>
</h1>
</div>
<div
class=
"col order-1 order-sm-0"
>
<form
action=
"/search"
class=
"form"
>
<div
class=
"form-group"
>
<div
class=
"input-group"
style=
"width:100%;"
>
<input
name=
"query"
type=
"text"
class=
"form-control"
placeholder=
"Search by CRN, course, professor..."
aria-describedby=
"basic-addon2"
>
<div
class=
"input-group-append"
>
<button
class=
"btn btn-secondary"
type=
"button"
>
<i
class=
"fas fa-search"
></i>
</button>
</div>
<div
class=
"input-group"
style=
"width:100%;"
>
<input
name=
"query"
type=
"text"
class=
"form-control"
placeholder=
"Search by CRN, course, professor..."
aria-describedby=
"basic-addon2"
>
<div
class=
"input-group-append"
>
<button
class=
"btn btn-secondary"
type=
"button"
>
<i
class=
"fas fa-search"
></i>
</button>
</div>
</div>
</form>
...
...
@@ -50,6 +49,6 @@
<div
class=
"container-fluid"
>
<!-- The main screen consists of a row with two columns: the search results, and the cart -->
<div
class=
"row"
>
<!-- Search result, List of Courses -->
<div
class=
"col-lg-7 col-md-10 mx-auto order-2 order-lg-0"
id=
"search-list"
>
Prev
1
2
Next
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