Merge remote-tracking branch 'systemed/master' into graph-perf2

This commit is contained in:
Ansis Brammanis
2013-01-30 16:58:44 -05:00
60 changed files with 3536 additions and 761 deletions

View File

@@ -38,6 +38,8 @@ all: \
js/id/behavior/*.js \
js/id/modes.js \
js/id/modes/*.js \
js/id/operations.js \
js/id/operations/*.js \
js/id/controller/*.js \
js/id/graph/*.js \
js/id/renderer/*.js \
@@ -45,7 +47,9 @@ all: \
js/id/svg/*.js \
js/id/ui.js \
js/id/ui/*.js \
js/id/end.js
js/id/end.js \
locale/locale.js \
locale/en.js
iD.js: Makefile
@rm -f $@

View File

@@ -89,7 +89,7 @@ a:visited, a {
}
a:hover {
color:#154dff;
color:#597be7;
}
@@ -220,9 +220,10 @@ ul.link-list li:last-child {
.fillD {
background:rgba(0,0,0,.8);
color: white;
color: #a9a9a9;
}
.fl { float: left;}
.fr { float: right;}
@@ -255,6 +256,9 @@ button {
height:40px;
cursor:url(../img/cursor-pointer.png) 6 1, auto;
border-radius:4px;
-webkit-transition: background 100ms;
-moz-transition: background 100ms;
transition: background 100ms;
}
button:hover {
@@ -279,11 +283,11 @@ button.minor {
width: 20px;
border: 0;
box-shadow: none;
background-color: transparent;
background: rgba(0,0,0,.5);
}
button.minor:hover {
background: white;
background: #222;
}
button.centered {
@@ -315,6 +319,8 @@ button.centered {
border-radius:0 4px 4px 0;
}
button.Browse .label { display: none;}
button.action {
background: #7092ff;
}
@@ -399,17 +405,25 @@ button[disabled] .label {
height: 40px;
}
.icon.icon-pre-text {
.icon-pre-text {
margin-right: 3px;
}
.user-icon {
max-height: 20px;
max-width: 20px;
height: auto;
width: auto;
border-radius: 3px;
}
/* Definitions for every icon */
.icon.browse { background-position: 0px -20px;}
.icon.add-point { background-position: -20px -20px;}
.icon.add-line { background-position: -40px -20px;}
.icon.add-area { background-position: -60px -20px;}
.icon.undo { background-position: -80px -20px;}
.icon.redo { background-position: -100px -20px;}
.icon.browse { background-position: 0px 0px;}
.icon.add-point { background-position: -20px 0px;}
.icon.add-line { background-position: -40px 0px;}
.icon.add-area { background-position: -60px 0px;}
.icon.undo { background-position: -80px 0px;}
.icon.redo { background-position: -100px 0px;}
.icon.apply { background-position: -120px 0px;}
.icon.save { background-position: -140px 0px;}
@@ -419,20 +433,15 @@ button[disabled] .label {
.icon.inspect { background-position: -220px 0px;}
.icon.zoom-in { background-position: -240px 0px;}
.icon.zoom-out { background-position: -260px 0px;}
.icon.plus { background-position: -240px 0px;}
.icon.geocode { background-position: -280px 0px;}
.icon.layers { background-position: -300px 0px;}
.icon.avatar { background-position: -320px 0px;}
.icon.nearby { background-position: -340px 0px;}
.icon.geolocate { background-position: -360px 0px;}
.icon.warning { background-position: -380px 0px;}
.icon.invert.zoom-in { background-position: -240px -40px;}
.icon.browse { background-position: 0px 0px;}
.icon.add-point { background-position: -20px 0px;}
.icon.add-line { background-position: -40px 0px;}
.icon.add-area { background-position: -60px 0px;}
.icon.undo { background-position: -80px 0px;}
.icon.redo { background-position: -100px 0px;}
.icon.close-modal { background-position: -200px -40px;}
.fillD .icon.avatar { background-position: -320px -20px;}
.fillD .icon.nearby { background-position: -340px -20px;}
@@ -456,11 +465,23 @@ button[disabled] .icon.layers { background-position: -300px -40px;}
button[disabled] .icon.avatar { background-position: -320px -40px;}
button[disabled] .icon.nearby { background-position: -340px -40px;}
.icon.big-line { background-position: 0px -80px;}
.icon.big-point { background-position: -40px -80px;}
.icon.big-area { background-position: -80px -80px;}
.icon.big-vertex { background-position: -120px -80px;}
.icon.big-inspect { background-position: -160px -80px;}
.icon.big-line { background-position: 0px -80px;}
.icon.big-point { background-position: -40px -80px;}
.icon.big-area { background-position: -80px -80px;}
.icon.big-vertex { background-position: -120px -80px;}
.icon.big-inspect { background-position: -160px -80px;}
.icon.big-relation { background-position: -200px -80px;}
.icon-operation-delete { background-position: 0px -140px;}
.icon-operation-circularize { background-position: -20px -140px;}
.icon-operation-straighten { background-position: -40px -140px;}
.icon-operation-split { background-position: -60px -140px;}
.icon-operation-unjoin { background-position: -80px -140px;}
.icon-operation-reverse { background-position: -100px -140px;}
.icon-operation-move { background-position: -120px -140px;}
.icon-operation-merge { background-position: -140px -140px;}
.icon-operation-orthogonalize { background-position: -160px -140px;}
/* Toggle icon is special */
.toggle.icon { background-position: 0px -180px;}
@@ -593,19 +614,19 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;}
width: 60%;
}
.inspector-inner .add-tag-row {
width: 100%;
}
.inspector-inner .add-tag-row button {
.inspector-inner .add-tag {
width: 20%;
height: 30px;
border-top: 0;
background: rgba(0,0,0,.5);
border-radius: 0 0 4px 4px;
}
.inspector-inner .add-tag:hover {
background: rgba(0,0,0,.8);
}
.inspector-inner .add-tag {
width: 40%;
height: 30px;
border: 1px solid #ccc;
border-top: 0;
.inspector-inner .add-tag .label {
display: none;
}
/* Map Controls */
@@ -617,12 +638,13 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;}
.map-control button {
width: 40px;
background: rgba(0,0,0,.8);
border-radius: 0 4px 4px 0;
background: rgba(0,0,0,.5);
border-radius: 0;
border-bottom: 1px solid rgba(0, 0, 0, 1);
}
.map-control button:hover {
background: rgba(0, 0, 0, .9);
background: rgba(0, 0, 0, .8);
}
.map-control button.active:hover {
@@ -647,18 +669,16 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;}
.zoombuttons button.zoom-in {
border-radius:0 4px 0 0;
border-bottom: 1px solid rgba(0, 0, 0, .5);
}
.zoombuttons button.zoom-out {
border-top:0;
border-radius:0 0 4px 0;
}
/* Layer Switcher */
.layerswitcher-control {
top:210px;
top:190px;
}
.layerswitcher-control .adjustments button {
@@ -729,7 +749,7 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;}
/* Geocoder */
.geocode-control {
top:160px;
top:150px;
}
.geocode-control input {
@@ -738,8 +758,15 @@ a.selected:hover .toggle.icon { background-position: -40px -180px;}
margin: 4px;
}
/* Geolocator */
.geolocate-control {
top:260px;
top:230px;
}
.geolocate-control button {
border-radius: 0 0 4px 0;
border-bottom: 0;
}
/* Map
@@ -862,9 +889,11 @@ div.typeahead a:first-child {
display: inline-block;
position:absolute;
width: 50%;
left: 25%;
left: 0;
right: 0;
margin: auto;
max-width: 600px;
top:80px;
top: 80px;
z-index: 3;
}
@@ -900,6 +929,59 @@ div.typeahead a:first-child {
left:0px; right:0px; top:0px; bottom:0px;
}
.modal-section {
padding: 20px;
}
.modal-section.header {
border-radius: 4px 4px 0 0;
}
.modal-section:last-child {
border-radius: 0 0 4px 4px;
}
.modal-section .buttons {
padding-top: 10px;
width: 100%;
}
.modal-section img.wiki-image {
max-width: 100%;
max-height: 300px;
display: block;
}
.modal-flash .content {
box-shadow: none;
border-radius: 4px;
background: #111;
color: #eee;
}
.modal-flash .close-modal {
display:none;
}
.loading-modal {
text-align: center;
}
/* Commit Modal
------------------------------------------------------- */
.commit-modal .user-info {
display: inline-block;
}
.commit-modal .commit-info {
margin-top: 10px;
}
.commit-modal .user-info img {
float: left;
}
.commit-modal h3 small.count {
margin-right: 10px;
text-align: center;
@@ -921,49 +1003,15 @@ div.typeahead a:first-child {
max-height: 160px;
}
.commit-modal .user-details {
.commit-modal .warning-section .changeset-list button {
float: right;
}
.user-icon {
max-width: 50px;
max-height: 50px;
.commit-section.modal-section {
padding-bottom: 0;
}
.modal-section {
padding: 20px;
}
.modal-section.header {
border-radius: 4px 4px 0 0;
}
.modal-section:last-child {
border-radius: 0 0 4px 4px;
}
.modal-section .buttons {
padding-top: 10px;
width: 100%;
}
.modal-section img.wiki-image {
max-width: 400px;
max-height: 300px;
padding: 10px;
display: block;
}
.modal-flash .content {
box-shadow: none;
border-radius: 4px;
background: #111;
color: #eee;
}
.modal-flash .close-modal {
display:none;
}
.commit-section.modal-section:last-child { padding-bottom: 20px;}
.changeset-list li {
border-top:1px solid #ccc;
@@ -987,8 +1035,12 @@ div.typeahead a:first-child {
font:normal 12px/20px 'Helvetica Neue', Arial, sans-serif;
}
.loading-modal {
text-align: center;
/* Success
------------------------------------------------------- */
a.success-action {
display:inline-block;
padding:10px;
margin:10px;
}
/* Notices
@@ -1053,17 +1105,17 @@ div.typeahead a:first-child {
}
.tooltip-inner {
text-align: left;
width: 200px;
font-size: 11px;
font-weight: bold;
line-height: 20px;
padding: 5px 10px;
color: #333;
background-color: white;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
text-align: left;
width: 200px;
font-size: 11px;
font-weight: bold;
line-height: 20px;
padding: 5px 10px;
color: #333;
background-color: white;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
.tooltip-arrow {
@@ -1110,6 +1162,17 @@ div.typeahead a:first-child {
left: 30px;
}
.tooltip .keyhint {
float: right;
background: #eee;
font-size: 10px;
padding: 0 4px;
background:#aaa;
color:#fff;
border-radius: 2px;
margin-left: 4px;
}
.tail {
pointer-events:none;
position: absolute;
@@ -1122,10 +1185,13 @@ div.typeahead a:first-child {
border-radius: 4px;
}
.radial-menu-background {
stroke: #aaa;
stroke-opacity: 0.4;
}
.radial-menu-item {
fill: white;
stroke: black;
stroke-width: 1;
fill: black;
cursor:url(../img/cursor-pointer.png) 6 1, auto;
}
@@ -1143,6 +1209,17 @@ div.typeahead a:first-child {
fill: rgba(255,255,255,.5);
}
.radial-menu .icon {
pointer-events: none;
}
.radial-menu-tooltip {
background: rgba(255, 255, 255, 0.8);
padding: 5px;
-webkit-border-radius: 4px;
-moz-border-radius: 4px;
border-radius: 4px;
}
/* Media Queries
------------------------------------------------------- */
@@ -1151,5 +1228,5 @@ div.typeahead a:first-child {
span.label {display: none;}
/* override hide for save button */
.icon.icon-pre-text { margin-right: 0px;}
.save .label { display: block;}
.save .label, .apply .label { display: block;}
}

View File

@@ -16,7 +16,7 @@ g.point .shadow {
transition: transform 100ms linear;
-moz-transition: fill 100ms linear;
}
g.point.hover .shadow {
.behavior-hover g.point.hover .shadow {
fill: #E96666;
fill-opacity: 0.3;
}
@@ -106,7 +106,7 @@ g.vertex .shadow {
transition: transform 100ms linear;
-moz-transition: fill 100ms linear;
}
g.vertex.hover .shadow {
.behavior-hover g.vertex.hover .shadow {
fill: #E96666;
fill-opacity: 0.3;
}
@@ -120,7 +120,7 @@ g.vertex.selected .shadow {
g.midpoint .fill {
fill:#aaa;
}
g.midpoint .fill.hover {
.behavior-hover g.midpoint .fill.hover {
fill:#fff;
stroke:#000;
}
@@ -133,7 +133,7 @@ g.midpoint .shadow {
transition: transform 100ms linear;
-moz-transition: fill 100ms linear;
}
g.midpoint .shadow.hover {
.behavior-hover g.midpoint .shadow.hover {
fill:#E96666;
fill-opacity: 0.3;
}
@@ -161,7 +161,7 @@ path.shadow {
-webkit-transition: stroke 100ms linear;
}
path.shadow.hover {
.behavior-hover path.shadow.hover {
stroke: #E96666;
stroke-opacity: 0.3;
}
@@ -691,17 +691,17 @@ text.point.tag-amenity {
cursor:url(../img/cursor-draw.png) 9 9, auto;
}
.mode-draw-line .way,
.mode-draw-area .way,
.mode-add-line .way,
.mode-add-area .way {
.mode-draw-line .behavior-hover .way,
.mode-draw-area .behavior-hover .way,
.mode-add-line .behavior-hover .way,
.mode-add-area .behavior-hover .way {
cursor:url(../img/cursor-draw-connect-line.png) 9 9, auto;
}
.mode-draw-line .vertex,
.mode-draw-area .vertex,
.mode-add-line .vertex,
.mode-add-area .vertex {
.mode-draw-line .behavior-hover .vertex,
.mode-draw-area .behavior-hover .vertex,
.mode-add-line .behavior-hover .vertex,
.mode-add-area .behavior-hover .vertex {
cursor:url(../img/cursor-draw-connect-vertex.png) 9 9, auto;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 278 B

After

Width:  |  Height:  |  Size: 1.4 KiB

1835
img/source/radial-menu.svg Normal file

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 1021 KiB

View File

@@ -9,11 +9,11 @@
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="380"
width="420"
height="200"
id="svg12393"
version="1.1"
inkscape:version="0.48.1 r9760"
inkscape:version="0.48.2 r9819"
sodipodi:docname="sprite.svg"
inkscape:export-filename="/Users/saman/work_repos/iD/img/sprite.png"
inkscape:export-xdpi="90"
@@ -38,25 +38,25 @@
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="2.8284271"
inkscape:cx="173.1037"
inkscape:cy="123.12989"
inkscape:zoom="4"
inkscape:cx="332.2911"
inkscape:cy="175.13176"
inkscape:document-units="px"
inkscape:current-layer="layer12"
showgrid="false"
inkscape:window-width="1560"
inkscape:window-height="922"
inkscape:window-x="223"
inkscape:window-width="1280"
inkscape:window-height="700"
inkscape:window-x="0"
inkscape:window-y="0"
inkscape:window-maximized="0"
fit-margin-top="0"
fit-margin-left="0"
fit-margin-right="0"
fit-margin-bottom="0"
showguides="false"
showguides="true"
inkscape:guide-bbox="true"
inkscape:snap-bbox="true"
inkscape:snap-nodes="false">
inkscape:snap-nodes="true">
<inkscape:grid
type="xygrid"
id="grid12420"
@@ -164,6 +164,18 @@
orientation="1,0"
position="380,185"
id="guide3408" />
<sodipodi:guide
orientation="1,0"
position="240,196"
id="guide15954" />
<sodipodi:guide
orientation="1,0"
position="400,210"
id="guide15997" />
<sodipodi:guide
orientation="1,0"
position="420,191"
id="guide10219" />
</sodipodi:namedview>
<metadata
id="metadata12398">
@@ -173,7 +185,7 @@
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
<dc:title></dc:title>
</cc:Work>
</rdf:RDF>
</metadata>
@@ -183,15 +195,6 @@
id="layer1"
transform="translate(-25,-62.362183)"
style="display:inline">
<rect
style="opacity:0.5;color:#000000;fill:none;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect3410"
width="380"
height="200"
x="25"
y="62.362183"
rx="0"
ry="0" />
<g
id="g9591"
style="fill:#1a1a1a;fill-opacity:1;display:inline"
@@ -275,7 +278,12 @@
inkscape:groupmode="layer"
id="layer12"
inkscape:label="sprite"
transform="translate(-25,3.0625e-6)">
transform="translate(-25,3.0625001e-6)">
<path
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 255,3.9999969 -1,1 0,1 1,1 1,0 1,-1 0,-1 -1,-1 -1,0 z m 0,4 -1,1 0,5.0000001 1,1 1,0 1,-1 0,-5.0000001 -1,-1 -1,0 z"
id="path10936"
inkscape:connector-curvature="0" />
<g
transform="translate(105.03464,-25.104239)"
id="g58869"
@@ -299,7 +307,7 @@
id="path5387" />
<path
style="color:#000000;fill:#222222;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter8013-4);enable-background:accumulate"
d="m 55,3.9999981 c -2.76142,0 -5,2.23858 -5,5 0,2.7614299 5,6.9999999 5,6.9999999 0,0 5,-4.23857 5,-6.9999999 0,-2.76142 -2.23858,-5 -5,-5 z m 0.15625,3 c 1.10457,0 2,0.89543 2,2 0,1.1045699 -0.89543,1.9999999 -2,1.9999999 -1.104569,0 -2,-0.89543 -2,-1.9999999 0,-1.10457 0.895431,-2 2,-2 z"
d="m 57,3.9999981 c -2.76142,0 -5,2.23858 -5,5 0,2.7614299 5,6.9999999 5,6.9999999 0,0 5,-4.23857 5,-6.9999999 0,-2.76142 -2.23858,-5 -5,-5 z m 0.15625,3 c 1.10457,0 2,0.89543 2,2 0,1.1045699 -0.89543,1.9999999 -2,1.9999999 -1.104569,0 -2,-0.89543 -2,-1.9999999 0,-1.10457 0.895431,-2 2,-2 z"
id="path8139"
inkscape:connector-curvature="0" />
<g
@@ -358,12 +366,6 @@
id="path22362"
d="M 159.5,4 154.5625,12.5625 151,9 l -1,0 -1,1 0,1 5,5 1,0 1,0 6,-10 0,-1 -1,-1 -1.5,0 z"
style="color:#000000;fill:#222222;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
inkscape:connector-curvature="0"
style="color:#000000;fill:#222222;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 210,2.999999 -1,1 0,1 1,1 9,0 1,-1 0,-1 -1,-1 z m 0,4 0,9 1,1 7,0 1,-1 0,-9 z m 2,2 1,0 0,6 -1,0 0,-1 z m 2,0 1,0 0,5 0,1 -1,0 z m 2,0 1,0 0,5 0,1 -1,0 z"
id="path22366"
sodipodi:nodetypes="cccccccccccccccccccccccccccccccccc" />
<g
transform="translate(-55,-130)"
style="display:inline"
@@ -500,44 +502,23 @@
inkscape:export-ydpi="90" />
</g>
<g
transform="translate(-355,-155)"
style="display:inline"
id="g45432">
<g
transform="matrix(0.70710678,0.70710679,-0.70710679,0.70710678,-113.14357,-447.56033)"
id="g9588-1-5"
style="fill:#ff7070;fill-opacity:1;display:inline">
<path
inkscape:connector-curvature="0"
style="color:#000000;fill:#ff7070;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 586,160 -1,1 0,1 3,3 -3,3 0,1 1,1 1,0 3,-3 3,3 1,0 1,-1 0,-1 -3,-3 3,-3 0,-1 -1,-1 -1,0 -3,3 -3,-3 -1,0 z"
transform="matrix(0.70710677,-0.70710678,0.70710678,0.70710677,396.47753,236.46835)"
id="path9584-1-7" />
</g>
<g
style="fill:#ff7070;fill-opacity:1;display:inline"
id="g16306-51"
transform="matrix(-0.70710678,0.70710679,0.70710679,0.70710678,1293.1436,-447.56033)" />
</g>
<g
style="fill:#7092ff;fill-opacity:1;display:inline"
transform="translate(-671.00001,-114)"
style="opacity:0.5;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
transform="translate(-511.00001,-44)"
id="g44379">
<g
style="fill:#7092ff;fill-opacity:1"
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.55555558;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="g44381"
transform="matrix(0.64285714,0,0,0.64285714,332.85714,42.142857)">
<path
style="color:#000000;fill:#7092ff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 231.5,4 c -2.48528,0 -4.5,2.0147199 -4.5,4.5 0,0.7234859 0.19662,1.3943625 0.5,2 l -3.5,3.5 0,2 2,0 3.5,-3.5 c 0.60564,0.303377 1.27651,0.5 2,0.5 2.48528,0 4.5,-2.01472 4.5,-4.5 C 236,6.0147199 233.98528,4 231.5,4 z m 0,2 c 1.38071,0 2.5,1.11929 2.5,2.5 0,1.38071 -1.11929,2.5 -2.5,2.5 C 230.11929,11 229,9.88071 229,8.5 229,7.11929 230.11929,6 231.5,6 z"
transform="matrix(1.5555556,0,0,1.5555556,564.88891,111.77778)"
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.55555558;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 925.00003,71.333338 c -3.86599,0 -7,3.13401 -7,7 0,1.12542 0.30585,2.16901 0.77778,3.11111 l -5.44445,5.444436 0,3.11111 3.11112,0 5.44444,-5.44444 c 0.94211,0.47192 1.98568,0.77778 3.11111,0.77778 3.86599,0 7,-3.134006 7,-6.999996 0,-3.86599 -3.13401,-7 -7,-7 z m 0,3.11111 c 2.14777,0 3.88889,1.74112 3.88889,3.88889 0,2.14777 -1.74112,3.88889 -3.88889,3.88889 -2.14777,0 -3.88889,-1.74112 -3.88889,-3.88889 0,-2.14777 1.74112,-3.88889 3.88889,-3.88889 z"
id="path44383"
inkscape:connector-curvature="0" />
</g>
<g
transform="matrix(0.35714364,0,0,0.35714364,597.14212,77.857044)"
id="g44387"
style="fill:#7092ff;fill-opacity:1" />
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<g
transform="translate(-656,73.637817)"
@@ -589,20 +570,6 @@
id="path55334"
d="m 35,4 c 0,1 0,4 0,4 0,0 0,0.5 -0.5,0.5 C 34,8.5 34.070717,8.22484 34,8 33.695312,7.03125 33.132813,5.63541 33,5 32.795405,4.02115 32.333333,4 32,4 31,4 31,5 31,5 l 1,4 0,3 C 32,12 31.5,11.5 30.5,10.5 29.945312,9.94531 29.257659,9.7508 28.8125,10.00781 28.377049,10.25922 28.150942,10.89541 28.5,11.5 28.853553,12.11237 32,16 32,16 c 1,1 2,1 4,1 2.666667,0 1,0 3,0 2,0 2.288488,-2.86546 3,-5 C 43,9 43.5,7 43.5,7 43.613427,6.57668 43.45711,6.154 43,6 42.119539,5.70338 41.63994,6.35278 41.5,7 41.25,8.15625 41,9 41,9 40.90625,9.31383 41.0013,9.5 40.5,9.5 39.99086,9.5 40,9 40,9 40,9 40,6.33333 40,5 40,4 39,4 39,4 c 0,0 -1,0 -1,1 0,1 0,1.66667 0,3 0,0 0.01305,0.5 -0.5,0.5 C 36.998673,8.5 37,8 37,8 37,8 37,5 37,4 37,3 36,3 36,3 36,3 35,3 35,4 z"
style="color:#000000;fill:#222222;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter8013-4);enable-background:accumulate" />
<rect
y="80"
x="65"
height="40"
width="40"
id="rect44456"
style="color:#000000;fill:none;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<rect
style="color:#000000;fill:none;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect44458"
width="40"
height="40"
x="105"
y="80" />
<path
style="color:#000000;fill:#c1c1c1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 85,88 c -5.5228,0 -10,4.47716 -10,10 0,5.52286 10,14 10,14 0,0 10,-8.47714 10,-14 0,-5.52284 -4.4772,-10 -10,-10 z m 0.3124,6 c 2.2092,0 4,1.79086 4,4 0,2.20914 -1.7908,4 -4,4 -2.209,0 -4,-1.79086 -4,-4 0,-2.20914 1.791,-4 4,-4 z"
@@ -612,13 +579,6 @@
transform="translate(-1015,19.999998)"
style="display:inline"
id="g44643">
<rect
y="60"
x="1040"
height="40"
width="40"
id="rect43311-5"
style="color:#000000;fill:none;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<g
transform="matrix(2,0,0,2,529,-143.72437)"
id="g5401-6"
@@ -732,7 +692,7 @@
id="path16227" />
<path
style="opacity:0.5;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter8013-4);enable-background:accumulate"
d="m 55,43.999998 c -2.76142,0 -5,2.23858 -5,5 0,2.76143 5,7 5,7 0,0 5,-4.23857 5,-7 0,-2.76142 -2.23858,-5 -5,-5 z m 0.15625,3 c 1.10457,0 2,0.89543 2,2 0,1.10457 -0.89543,2 -2,2 -1.104569,0 -2,-0.89543 -2,-2 0,-1.10457 0.895431,-2 2,-2 z"
d="m 57,43.999998 c -2.76142,0 -5,2.23858 -5,5 0,2.76143 5,7 5,7 0,0 5,-4.23857 5,-7 0,-2.76142 -2.23858,-5 -5,-5 z m 0.15625,3 c 1.10457,0 2,0.89543 2,2 0,1.10457 -0.89543,2 -2,2 -1.104569,0 -2,-0.89543 -2,-2 0,-1.10457 0.895431,-2 2,-2 z"
id="path16231"
inkscape:connector-curvature="0" />
<path
@@ -773,36 +733,10 @@
inkscape:export-xdpi="90"
inkscape:export-ydpi="90" />
<path
inkscape:connector-curvature="0"
style="opacity:0.5;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 210,42.999999 -1,1 0,1 1,1 9,0 1,-1 0,-1 -1,-1 z m 0,4 0,9 1,1 7,0 1,-1 0,-9 z m 2,2 1,0 0,6 -1,0 0,-1 z m 2,0 1,0 0,5 0,1 -1,0 z m 2,0 1,0 0,5 0,1 -1,0 z"
id="path16769"
sodipodi:nodetypes="cccccccccccccccccccccccccccccccccc" />
<path
inkscape:connector-curvature="0"
style="opacity:0.5;color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 231,45 -1,1 0,1 3,3 -3,3 0,1 1,1 1,0 3,-3 3,3 1,0 1,-1 0,-1 -3,-3 3,-3 0,-1 -1,-1 -1,0 -3,3 -3,-3 -1,0 z"
id="path47520" />
<g
style="opacity:0.5;fill:#000000;fill-opacity:1;display:inline"
transform="translate(-671.00001,-74)"
id="g47524">
<g
style="fill:#000000;fill-opacity:1"
id="g47526"
transform="matrix(0.64285714,0,0,0.64285714,332.85714,42.142857)">
<path
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 231.5,44 c -2.48528,0 -4.5,2.01472 -4.5,4.5 0,0.723486 0.19662,1.394362 0.5,2 l -3.5,3.5 0,2 2,0 3.5,-3.5 c 0.60564,0.303377 1.27651,0.5 2,0.5 2.48528,0 4.5,-2.01472 4.5,-4.5 0,-2.48528 -2.01472,-4.5 -4.5,-4.5 z m 0,2 c 1.38071,0 2.5,1.11929 2.5,2.5 0,1.38071 -1.11929,2.5 -2.5,2.5 -1.38071,0 -2.5,-1.11929 -2.5,-2.5 0,-1.38071 1.11929,-2.5 2.5,-2.5 z"
transform="matrix(1.5555556,0,0,1.5555556,564.88891,49.555553)"
id="path47528"
inkscape:connector-curvature="0" />
</g>
<g
transform="matrix(0.35714364,0,0,0.35714364,597.14212,77.857044)"
id="g47532"
style="fill:#000000;fill-opacity:1" />
</g>
style="opacity:1;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375000000006;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 416.5,3.9999947 c -2.48528,0 -4.5,2.0147207 -4.5,4.5 0,0.7234907 0.19662,1.3943635 0.50001,2.0000053 L 409,13.999995 l 0,1.999999 2.00001,0 3.49999,-3.499997 c 0.60565,0.303377 1.27651,0.499995 2,0.499995 2.48528,0 4.5,-2.014712 4.5,-4.4999973 0,-2.4852793 -2.01472,-4.5 -4.5,-4.5 z m 0,1.9999993 c 1.38071,0 2.5,1.1192914 2.5,2.5000007 0,1.3807157 -1.11929,2.5000003 -2.5,2.5000003 -1.38071,0 -2.5,-1.1192846 -2.5,-2.5000003 0,-1.3807093 1.11929,-2.5000007 2.5,-2.5000007 z"
id="path47528"
inkscape:connector-curvature="0" />
<g
transform="translate(-656,113.63782)"
id="g47761"
@@ -853,33 +787,19 @@
<path
id="path46639"
d="m 208,87.999997 c -4.97056,0 -9,4.02944 -9,9 0,1.45311 0.35716,2.816163 0.96875,4.031253 L 193,108 l 0,2 c 0,1 1,2 2,2 l 2,0 6.96875,-6.96875 C 205.18384,105.64284 206.54689,106 208,106 c 4.97056,0 9,-4.02944 9,-9.000003 0,-4.97056 -4.02944,-9 -9,-9 z m 0,4 c 2.76142,0 5,2.23858 5,5 C 213,99.76142 210.76142,102 208,102 c -2.76142,0 -5,-2.23858 -5,-5.000003 0,-2.76142 2.23858,-5 5,-5 z"
style="color:#000000;fill:#cccccc;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
style="color:#000000;fill:#c1c1c1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
inkscape:connector-curvature="0" />
<g
id="g4437"
transform="matrix(2,0,0,2,-1601,221.27564)"
style="display:inline">
<path
sodipodi:nodetypes="cccccccccsssss"
inkscape:connector-curvature="0"
style="color:#000000;fill:#c1c1c1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 136,92 -4,4 -7,0 0,8 7,0 4,4 8,0 4,-4 7,0 0,-8 -7,0 -4,-4 -8,0 z m 4,4 c 2.20912,0 4,1.79086 4,4 0,2.20914 -1.79088,4 -4,4 -2.20912,0 -4,-1.79086 -4,-4 0,-2.20914 1.79088,-4 4,-4 z"
transform="matrix(0.5,0,0,0.5,813,-110.63782)"
id="path4439"
d="m 879,-58.63782 2,2 4,0 2,-2 0,-4 -2,-2 -4,-2e-6 -2,2 z m 4,-4 c 1.10456,0 2,0.89543 2,2 0,1.10457 -0.89544,2 -2,2 -1.10456,0 -2,-0.89543 -2,-2 0,-1.10457 0.89544,-2 2,-2 z"
style="color:#000000;fill:#c1c1c1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
inkscape:connector-curvature="0" />
</g>
<rect
style="color:#000000;fill:#c1c1c1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect4444"
width="9"
height="8"
x="150"
y="96" />
<rect
y="96"
x="171"
height="8"
width="9"
id="rect4446"
style="color:#000000;fill:#c1c1c1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
sodipodi:type="arc"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:5;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
@@ -963,7 +883,7 @@
<path
inkscape:connector-curvature="0"
id="path33321"
d="m 55,23.999998 c -2.76142,0 -5,2.23858 -5,5 0,2.76143 5,7 5,7 0,0 5,-4.23857 5,-7 0,-2.76142 -2.23858,-5 -5,-5 z m 0.15625,3 c 1.10457,0 2,0.89543 2,2 0,1.10457 -0.89543,2 -2,2 -1.104569,0 -2,-0.89543 -2,-2 0,-1.10457 0.895431,-2 2,-2 z"
d="m 57,23.999998 c -2.76142,0 -5,2.23858 -5,5 0,2.76143 5,7 5,7 0,0 5,-4.23857 5,-7 0,-2.76142 -2.23858,-5 -5,-5 z m 0.15625,3 c 1.10457,0 2,0.89543 2,2 0,1.10457 -0.89543,2 -2,2 -1.104569,0 -2,-0.89543 -2,-2 0,-1.10457 0.895431,-2 2,-2 z"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter8013-4);enable-background:accumulate" />
<path
inkscape:connector-curvature="0"
@@ -1002,34 +922,22 @@
id="path33331"
d="m 169.00002,29.999999 5.99998,-7 6.00002,7.00002 -4,-1e-5 -1e-5,6 -1.00001,0.99999 -2,0 -1,-0.99998 1e-5,-6.00002 z"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
sodipodi:nodetypes="cccccccccccccccccccccccccccccccccc"
id="path33333"
d="m 210,22.999999 -1,1 0,1 1,1 9,0 1,-1 0,-1 -1,-1 z m 0,4 0,9 1,1 7,0 1,-1 0,-9 z m 2,2 1,0 0,6 -1,0 0,-1 z m 2,0 1,0 0,5 0,1 -1,0 z m 2,0 1,0 0,5 0,1 -1,0 z"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
inkscape:connector-curvature="0" />
<path
id="path33335"
d="m 231,25 -1,1 0,1 3,3 -3,3 0,1 1,1 1,0 3,-3 3,3 1,0 1,-1 0,-1 -3,-3 3,-3 0,-1 -1,-1 -1,0 -3,3 -3,-3 -1,0 z"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
inkscape:connector-curvature="0" />
<g
id="g33337"
transform="translate(-671.00001,-94)"
style="fill:#ffffff;fill-opacity:1;display:inline">
transform="translate(-511.00001,-14)"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
<g
transform="matrix(0.64285714,0,0,0.64285714,332.85714,42.142857)"
id="g33339"
style="fill:#ffffff;fill-opacity:1">
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.55555558;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate">
<path
inkscape:connector-curvature="0"
id="path33341"
transform="matrix(1.5555556,0,0,1.5555556,564.88891,49.555553)"
d="m 231.5,44 c -2.48528,0 -4.5,2.01472 -4.5,4.5 0,0.723486 0.19662,1.394362 0.5,2 l -3.5,3.5 0,2 2,0 3.5,-3.5 c 0.60564,0.303377 1.27651,0.5 2,0.5 2.48528,0 4.5,-2.01472 4.5,-4.5 0,-2.48528 -2.01472,-4.5 -4.5,-4.5 z m 0,2 c 1.38071,0 2.5,1.11929 2.5,2.5 0,1.38071 -1.11929,2.5 -2.5,2.5 -1.38071,0 -2.5,-1.11929 -2.5,-2.5 0,-1.38071 1.11929,-2.5 2.5,-2.5 z"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
d="m 925.00003,-6.4444512 c -3.86599,0 -7,3.1340096 -7,6.99999958 0,1.12543002 0.30585,2.16901002 0.77778,3.11112002 l -5.44445,5.444436 0,3.1111096 3.11112,0 5.44444,-5.4444396 c 0.94211,0.47192 1.98568,0.77777 3.11111,0.77777 3.86599,0 7,-3.133996 7,-6.99999602 0,-3.86598998 -3.13401,-6.99999958 -7,-6.99999958 z m 0,3.1111096 c 2.14777,0 3.88889,1.74112 3.88889,3.88888998 0,2.14778002 -1.74112,3.88889002 -3.88889,3.88889002 -2.14777,0 -3.88889,-1.74111 -3.88889,-3.88889002 0,-2.14776998 1.74112,-3.88888998 3.88889,-3.88888998 z"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1.55555558;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<g
style="fill:#ffffff;fill-opacity:1"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="g33343"
transform="matrix(0.35714364,0,0,0.35714364,597.14212,77.857044)" />
</g>
@@ -1080,5 +988,366 @@
id="path33359"
d="m 354.5,22.999997 c -1.5,0 -2.5,2 -2.5,3 0,0.666667 0,1.333333 0,2 0,1 1,2.153847 1,2.153847 l 0,0.846153 -1.69231,0.384617 c -1.45419,0.330499 -2.02608,1.236079 -2.15384,2.76923 L 349,35.999998 l 12,0 -0.15385,-1.846154 c -0.12776,-1.533151 -0.69965,-2.438731 -2.15384,-2.76923 L 357,30.999997 l 0,-0.846153 c 0,0 1,-1.153847 1,-2.153847 0,-0.666667 0,-1.333333 0,-2 0,-1 -1,-3 -2.5,-3 z"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
inkscape:connector-curvature="0"
style="color:#000000;fill:#c1c1c1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 235,88 -2,2 0,4 2,2 4,0 2,-2 0,-4 -2,-2 -4,0 z m 2,2 c 1.10456,0 2,0.89543 2,2 0,1.10457 -0.89544,2 -2,2 -1.10456,0 -2,-0.89543 -2,-2 0,-1.10457 0.89544,-2 2,-2 z"
id="path16163" />
<path
inkscape:connector-curvature="0"
style="color:#000000;fill:#c1c1c1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 251,104 -2,2 0,4 2,2 4,0 2,-2 0,-4 -2,-2 -4,0 z m 2,2 c 1.10456,0 2,0.89543 2,2 0,1.10457 -0.89544,2 -2,2 -1.10456,0 -2,-0.89543 -2,-2 0,-1.10457 0.89544,-2 2,-2 z"
id="path16191" />
<path
sodipodi:type="arc"
style="color:#000000;fill:#c1c1c1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path16208"
sodipodi:cx="215"
sodipodi:cy="95"
sodipodi:rx="1"
sodipodi:ry="1"
d="m 216,95 c 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 0.55228,0 1,0.447715 1,1 z"
transform="translate(27,1.9999969)" />
<path
transform="translate(33,7.9999969)"
d="m 216,95 c 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 0.55228,0 1,0.447715 1,1 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="95"
sodipodi:cx="215"
id="path16210"
style="color:#000000;fill:#c1c1c1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
sodipodi:type="arc" />
<path
id="path16212"
d="m 255,88 2,2 0,4 -2,2 -4,0 -2,-2 0,-4 2,-2 4,0 z m -2,2 c -1.10456,0 -2,0.89543 -2,2 0,1.10457 0.89544,2 2,2 1.10456,0 2,-0.89543 2,-2 0,-1.10457 -0.89544,-2 -2,-2 z"
style="color:#000000;fill:#c1c1c1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
inkscape:connector-curvature="0" />
<path
id="path16214"
d="m 239,104 2,2 0,4 -2,2 -4,0 -2,-2 0,-4 2,-2 4,0 z m -2,2 c -1.10456,0 -2,0.89543 -2,2 0,1.10457 0.89544,2 2,2 1.10456,0 2,-0.89543 2,-2 0,-1.10457 -0.89544,-2 -2,-2 z"
style="color:#000000;fill:#c1c1c1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
inkscape:connector-curvature="0" />
<path
transform="matrix(-1,0,0,1,463,1.9999969)"
d="m 216,95 c 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 0.55228,0 1,0.447715 1,1 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="95"
sodipodi:cx="215"
id="path16216"
style="color:#000000;fill:#c1c1c1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
sodipodi:type="arc" />
<path
sodipodi:type="arc"
style="color:#000000;fill:#c1c1c1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path16218"
sodipodi:cx="215"
sodipodi:cy="95"
sodipodi:rx="1"
sodipodi:ry="1"
d="m 216,95 c 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 0.55228,0 1,0.447715 1,1 z"
transform="matrix(-1,0,0,1,457,7.9999969)" />
<path
transform="matrix(-1,0,0,1,460,4.9999969)"
d="m 216,95 c 0,0.552285 -0.44772,1 -1,1 -0.55228,0 -1,-0.447715 -1,-1 0,-0.552285 0.44772,-1 1,-1 0.55228,0 1,0.447715 1,1 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="95"
sodipodi:cx="215"
id="path16220"
style="color:#000000;fill:#c1c1c1;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
sodipodi:type="arc" />
<path
inkscape:connector-curvature="0"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 31,144 -1,1 0,1 1,1 8,0 1,-1 0,-1 -1,-1 z m 0,4 0,7 1,1 6,0 1,-1 0,-7 z m 2,2 1,0 0,4 -1,0 0,-1 z m 3,0 1,0 0,3 0,1 -1,0 z"
id="path9820"
sodipodi:nodetypes="cccccccccccccccccccccccccccc" />
<g
transform="translate(-26,-582.36218)"
id="g9824">
<path
sodipodi:nodetypes="sscccccsssscccccssccccsccccccccccsc"
inkscape:connector-curvature="0"
id="path9826"
transform="translate(0.9999996,1.4591601e-6)"
d="m 114,727.375 c -1,0 -2,1 -2,2 l 0,2 3,0 2,1 -2,1 -3,0 0,2 c 0,1 1,2 2,2 l 1,0 c 2,0 2.48722,-0.97443 3,-2 l 1,-2 9,-5 c 0,0 0,-1 -2,-1 l -7.03125,3.90625 L 118,729.375 c -0.49406,-0.98812 -1,-2 -3,-2 z m 0,1 2,0 1,2 -4,0 c 0,0 0,-0.66667 0,-1 0,-1.01282 1,-1 1,-1 z m 8.09375,4.71875 -2,1 L 126,737.375 c 2,0 2,-1 2,-1 z M 113,734.375 l 4,0 -1,2 -2,0 c 0,0 -1,0 -1,-1 z"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<g
transform="translate(-50,-762.36218)"
id="g9961">
<path
inkscape:connector-curvature="0"
id="rect9822"
d="m 119.8125,911.375 c 0.11352,0.31647 0.1875,0.64447 0.1875,1 0,0.35553 -0.074,0.68353 -0.1875,1 l 2.375,0 c -0.11352,-0.31647 -0.1875,-0.64447 -0.1875,-1 0,-0.35553 0.074,-0.68353 0.1875,-1 l -2.375,0 z m 8,0 c 0.11352,0.31647 0.1875,0.64447 0.1875,1 0,0.35553 -0.074,0.68353 -0.1875,1 l 2.375,0 c -0.11352,-0.31647 -0.1875,-0.64447 -0.1875,-1 0,-0.35553 0.074,-0.68353 0.1875,-1 l -2.375,0 z"
style="color:#000000;fill:#6bc641;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
transform="translate(67,173)"
sodipodi:type="arc"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path9830"
sodipodi:cx="50"
sodipodi:cy="739.36218"
sodipodi:rx="2"
sodipodi:ry="2"
d="m 52,739.36218 c 0,1.10457 -0.895431,2 -2,2 -1.104569,0 -2,-0.89543 -2,-2 0,-1.10457 0.895431,-2 2,-2 1.104569,0 2,0.89543 2,2 z" />
<path
d="m 52,739.36218 c 0,1.10457 -0.895431,2 -2,2 -1.104569,0 -2,-0.89543 -2,-2 0,-1.10457 0.895431,-2 2,-2 1.104569,0 2,0.89543 2,2 z"
sodipodi:ry="2"
sodipodi:rx="2"
sodipodi:cy="739.36218"
sodipodi:cx="50"
id="path9834"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
sodipodi:type="arc"
transform="translate(75,173)" />
<path
transform="translate(83,173)"
sodipodi:type="arc"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path9838"
sodipodi:cx="50"
sodipodi:cy="739.36218"
sodipodi:rx="2"
sodipodi:ry="2"
d="m 52,739.36218 c 0,1.10457 -0.895431,2 -2,2 -1.104569,0 -2,-0.89543 -2,-2 0,-1.10457 0.895431,-2 2,-2 1.104569,0 2,0.89543 2,2 z" />
</g>
<g
transform="translate(-110,-762.36218)"
id="g9967">
<path
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter8013-4);enable-background:accumulate"
d="m 268,906.36218 -3,-3 -3,3 1,1 4,0 z"
id="path9844"
inkscape:connector-curvature="0"
sodipodi:nodetypes="cccccc" />
<path
inkscape:connector-curvature="0"
id="path9846"
d="m 268,918.36218 -3,3 -3,-3 1,-1 4,0 z"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter8013-4);enable-background:accumulate"
sodipodi:nodetypes="cccccc" />
<path
sodipodi:nodetypes="cccccc"
inkscape:connector-curvature="0"
id="path9848"
d="m 271,915.36219 3,-3.00001 -3,-2.99999 -1,0.99999 0,4 z"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter8013-4);enable-background:accumulate" />
<path
sodipodi:nodetypes="cccccc"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter8013-4);enable-background:accumulate"
d="m 259,915.36217 -3,-2.99999 3,-3.00001 1,1.00001 0,4 z"
id="path9850"
inkscape:connector-curvature="0" />
<path
sodipodi:type="arc"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path9852"
sodipodi:cx="225"
sodipodi:cy="732.36218"
sodipodi:rx="1"
sodipodi:ry="1"
d="m 226,732.36218 c 0,0.55229 -0.44772,1 -1,1 -0.55228,0 -1,-0.44771 -1,-1 0,-0.55228 0.44772,-1 1,-1 0.55228,0 1,0.44772 1,1 z"
transform="matrix(2,0,0,2,-185,-552.36218)" />
</g>
<g
transform="translate(-35,-762.36218)"
id="g9952">
<path
inkscape:connector-curvature="0"
id="path9840"
d="m 87.03125,904.96875 c -1.32908,0.53118 -2.444369,1.41916 -3.3125,2.53125 0.07092,0.0184 0.149734,0.009 0.21875,0.0312 0.520689,0.16918 0.941853,0.48986 1.28125,0.875 0.583365,-0.69731 1.320919,-1.23792 2.15625,-1.625 C 87.146997,906.35926 87,905.88411 87,905.375 c 0,-0.14028 0.0122,-0.27085 0.03125,-0.40625 z m 5.9375,0 C 92.987796,905.10415 93,905.23472 93,905.375 c 0,0.50911 -0.146997,0.98426 -0.375,1.40625 0.835331,0.38708 1.572885,0.92769 2.15625,1.625 0.339397,-0.38514 0.760561,-0.70582 1.28125,-0.875 0.06748,-0.0219 0.146303,-0.0395 0.21875,-0.0625 -0.866395,-1.10291 -1.991152,-1.97191 -3.3125,-2.5 z m -10.9375,8.21875 c 0.132811,1.35398 0.618313,2.61506 1.34375,3.6875 0.05422,-0.0956 0.121594,-0.19054 0.1875,-0.28125 0.298579,-0.41096 0.689964,-0.72255 1.125,-0.9375 -0.439267,-0.72096 -0.728373,-1.5606 -0.84375,-2.4375 -0.563589,0.16464 -1.184566,0.16262 -1.78125,-0.0312 -0.009,-0.003 -0.02228,0.003 -0.03125,0 z m 15.90625,0 c -0.596684,0.19387 -1.217661,0.19589 -1.78125,0.0312 -0.115377,0.8769 -0.404483,1.71654 -0.84375,2.4375 0.438042,0.20421 0.821177,0.51932 1.125,0.9375 0.06591,0.0907 0.133279,0.18566 0.1875,0.28125 0.725438,-1.07244 1.210939,-2.33352 1.34375,-3.6875 -0.009,0.003 -0.02224,-0.003 -0.03125,0 z M 89,918.53125 c -0.03014,0.55835 -0.21394,1.114 -0.5625,1.59375 -0.027,0.0372 -0.06534,0.0582 -0.09375,0.0937 0.540476,0.11583 1.081942,0.1875 1.65625,0.1875 0.574308,0 1.115774,-0.0717 1.65625,-0.1875 -0.02841,-0.0355 -0.06675,-0.0566 -0.09375,-0.0937 -0.34856,-0.47975 -0.532362,-1.0354 -0.5625,-1.59375 -0.329444,0.0535 -0.654988,0.0937 -1,0.0937 -0.345012,0 -0.670556,-0.0403 -1,-0.0937 z"
style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#6bc641;fill-opacity:1;stroke:none;stroke-width:0.50000125;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" />
<g
id="g9894"
transform="translate(40,180)">
<path
d="m 52,725.36218 c 0,1.10457 -0.895431,2 -2,2 -1.104569,0 -2,-0.89543 -2,-2 0,-1.10457 0.895431,-2 2,-2 1.104569,0 2,0.89543 2,2 z"
sodipodi:ry="2"
sodipodi:rx="2"
sodipodi:cy="725.36218"
sodipodi:cx="50"
id="path9896"
style="color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
sodipodi:type="arc" />
<path
transform="matrix(0.30901699,-0.95105652,0.95105652,0.30901699,-662.31182,553.76523)"
sodipodi:type="arc"
style="color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path9898"
sodipodi:cx="50"
sodipodi:cy="725.36218"
sodipodi:rx="2"
sodipodi:ry="2"
d="m 52,725.36218 c 0,1.10457 -0.895431,2 -2,2 -1.104569,0 -2,-0.89543 -2,-2 0,-1.10457 0.895431,-2 2,-2 1.104569,0 2,0.89543 2,2 z" />
<path
d="m 52,725.36218 c 0,1.10457 -0.895431,2 -2,2 -1.104569,0 -2,-0.89543 -2,-2 0,-1.10457 0.895431,-2 2,-2 1.104569,0 2,0.89543 2,2 z"
sodipodi:ry="2"
sodipodi:rx="2"
sodipodi:cy="725.36218"
sodipodi:cx="50"
id="path9900"
style="color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
sodipodi:type="arc"
transform="matrix(-0.809017,-0.58778525,0.58778525,-0.809017,-339.90648,1354.5819)" />
<path
transform="matrix(-0.80901699,0.58778526,-0.58778526,-0.80901699,520.80791,1295.8034)"
sodipodi:type="arc"
style="color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path9902"
sodipodi:cx="50"
sodipodi:cy="725.36218"
sodipodi:rx="2"
sodipodi:ry="2"
d="m 52,725.36218 c 0,1.10457 -0.895431,2 -2,2 -1.104569,0 -2,-0.89543 -2,-2 0,-1.10457 0.895431,-2 2,-2 1.104569,0 2,0.89543 2,2 z" />
<path
d="m 52,725.36218 c 0,1.10457 -0.895431,2 -2,2 -1.104569,0 -2,-0.89543 -2,-2 0,-1.10457 0.895431,-2 2,-2 1.104569,0 2,0.89543 2,2 z"
sodipodi:ry="2"
sodipodi:rx="2"
sodipodi:cy="725.36218"
sodipodi:cx="50"
id="path9904"
style="color:#000000;fill:#ffffff;fill-opacity:1;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
sodipodi:type="arc"
transform="matrix(0.309017,0.95105651,-0.95105651,0.309017,731.41012,458.66065)" />
</g>
</g>
<g
transform="translate(-80,-762.36218)"
id="g9978">
<path
inkscape:connector-curvature="0"
id="path9854"
d="m 189,908.375 -4,4 4,4 1,-1 0,-2 2.1875,0 c -0.11352,-0.31647 -0.1875,-0.64447 -0.1875,-1 0,-0.34518 0.0802,-0.69136 0.1875,-1 l -2.1875,0 0,-2 -1,-1 z m 12,0 -1,1 0,2 -2.1875,0 c 0.10728,0.30864 0.1875,0.65482 0.1875,1 0,0.35553 -0.074,0.68353 -0.1875,1 l 2.1875,0 0,2 1,1 4,-4 -4,-4 z"
style="color:#000000;fill:#6bc641;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
<path
transform="matrix(2.0000003,0,0,2.0000003,-255.00007,-552.36238)"
d="m 226,732.36218 c 0,0.55229 -0.44772,1 -1,1 -0.55228,0 -1,-0.44771 -1,-1 0,-0.55228 0.44772,-1 1,-1 0.55228,0 1,0.44772 1,1 z"
sodipodi:ry="1"
sodipodi:rx="1"
sodipodi:cy="732.36218"
sodipodi:cx="225"
id="path9908"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
sodipodi:type="arc" />
</g>
<g
transform="translate(-94,-762.36218)"
id="g9974">
<path
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 227,917.36218 -4,-5 4,-5 2,0 0,1 -3.5,4 3.5,4 0,1 z"
id="path9842"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccc" />
<path
sodipodi:nodetypes="ccccccccc"
inkscape:connector-curvature="0"
id="path9910"
d="m 233,917.36218 -4,-5 4,-5 2,0 0,1 -3.5,4 3.5,4 0,1 z"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate" />
</g>
<g
id="g9683"
transform="translate(-109.40337,-628.51757)"
style="fill:#6bc641;fill-opacity:1">
<path
style="color:#000000;fill:#6bc641;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 283.40337,771.51757 -1,1 0,4 -4,0 -1,1 0,2 1,1 4,0 0,4 1,1 2,0 1,-1 0,-4 4,0 1,-1 0,-2 -1,-1 -4,0 0,-4 -1,-1 z"
id="path5624-8"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccccccccccccc" />
</g>
<g
transform="translate(-100,-582.36218)"
id="g9864-9">
<path
inkscape:connector-curvature="0"
style="color:#000000;fill:#6bc641;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 331,910.1875 0,2.375 c 0.31647,-0.11352 0.64447,-0.1875 1,-0.1875 0.35553,0 0.68353,0.074 1,0.1875 l 0,-2.375 c -0.31647,0.11352 -0.64447,0.1875 -1,0.1875 -0.35553,0 -0.68353,-0.074 -1,-0.1875 z m 3.8125,4.1875 c 0.11352,0.31647 0.1875,0.64447 0.1875,1 0,0.35553 -0.074,0.68353 -0.1875,1 l 2.375,0 c -0.11352,-0.31647 -0.1875,-0.64447 -0.1875,-1 0,-0.35553 0.074,-0.68353 0.1875,-1 l -2.375,0 z"
transform="translate(-41,-179.00001)"
id="rect9866-2" />
<path
d="m 52,739.36218 c 0,1.10457 -0.895431,2 -2,2 -1.104569,0 -2,-0.89543 -2,-2 0,-1.10457 0.895431,-2 2,-2 1.104569,0 2,0.89543 2,2 z"
sodipodi:ry="2"
sodipodi:rx="2"
sodipodi:cy="739.36218"
sodipodi:cx="50"
id="path9870-1"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
sodipodi:type="arc"
transform="translate(249,-3)" />
<path
transform="translate(241,-3)"
sodipodi:type="arc"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path9878-4"
sodipodi:cx="50"
sodipodi:cy="739.36218"
sodipodi:rx="2"
sodipodi:ry="2"
d="m 52,739.36218 c 0,1.10457 -0.895431,2 -2,2 -1.104569,0 -2,-0.89543 -2,-2 0,-1.10457 0.895431,-2 2,-2 1.104569,0 2,0.89543 2,2 z" />
<path
transform="translate(241,-11)"
sodipodi:type="arc"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="path9880-9"
sodipodi:cx="50"
sodipodi:cy="739.36218"
sodipodi:rx="2"
sodipodi:ry="2"
d="m 52,739.36218 c 0,1.10457 -0.895431,2 -2,2 -1.104569,0 -2,-0.89543 -2,-2 0,-1.10457 0.895431,-2 2,-2 1.104569,0 2,0.89543 2,2 z" />
</g>
<rect
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
id="rect10175"
width="40"
height="140"
x="-15"
y="-3.0624999e-06" />
<path
id="path10245"
d="m 436,22.999997 -1,1 0,4 -4,0 -1,1 0,1 1,1 4,0 0,4 1,1 1,0 1,-1 0,-4 4,0 1,-1 0,-1 -1,-1 -4,0 0,-4 -1,-1 -1,0 z"
style="opacity:0.5;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.79999375;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 211,3.9999969 -1,1 0,1 1,1 8,0 1,-1 0,-1 -1,-1 z m 0,4 0,7.0000001 1,1 6,0 1,-1 0,-7.0000001 z m 2,2 1,0 0,4.0000001 -1,0 0,-1 z m 3,0 1,0 0,3.0000001 0,1 -1,0 z"
id="path9820-4"
sodipodi:nodetypes="cccccccccccccccccccccccccccc" />
<path
sodipodi:nodetypes="cccccccccccccccccccccccccccc"
id="path10997"
d="m 211,23.999997 -1,1 0,1 1,1 8,0 1,-1 0,-1 -1,-1 z m 0,4 0,7 1,1 6,0 1,-1 0,-7 z m 2,2 1,0 0,4 -1,0 0,-1 z m 3,0 1,0 0,3 0,1 -1,0 z"
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
inkscape:connector-curvature="0" />
<path
inkscape:connector-curvature="0"
style="color:#000000;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;opacity:0.50000000000000000"
d="m 211,43.999997 -1,1 0,1 1,1 8,0 1,-1 0,-1 -1,-1 z m 0,4 0,7 1,1 6,0 1,-1 0,-7 z m 2,2 1,0 0,4 -1,0 0,-1 z m 3,0 1,0 0,3 0,1 -1,0 z"
id="path11016"
sodipodi:nodetypes="cccccccccccccccccccccccccccc" />
<g
id="g11035"
style="fill:#ffffff;fill-opacity:1;display:inline"
transform="translate(-354,-135)">
<g
style="fill:#ffffff;fill-opacity:1;display:inline"
id="g11037"
transform="matrix(0.70710678,0.70710679,-0.70710679,0.70710678,-113.14357,-447.56033)" />
<g
transform="matrix(-0.70710678,0.70710679,0.70710679,0.70710678,1293.1436,-447.56033)"
id="g11041"
style="fill:#ffffff;fill-opacity:1;display:inline" />
</g>
<path
style="color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:0;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate"
d="m 231,4.9999992 -1,1 0,1 3,3 -3,2.9999998 0,1 1,1 1,0 3,-3 3,3 1,0 1,-1 0,-1 -3,-2.9999998 3,-3 0,-1 -1,-1 -1,0 -3,3 -3,-3 z"
id="path11047"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccccccccccccc" />
</g>
</svg>

Before

Width:  |  Height:  |  Size: 66 KiB

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -73,6 +73,7 @@
<script src='js/id/ui/key_reference.js'></script>
<script src='js/id/actions.js'></script>
<script src="js/id/actions/add_midpoint.js"></script>
<script src='js/id/actions/add_node.js'></script>
<script src='js/id/actions/add_way.js'></script>
<script src='js/id/actions/add_way_node.js'></script>
@@ -81,7 +82,7 @@
<script src="js/id/actions/delete_way.js"></script>
<script src='js/id/actions/move_node.js'></script>
<script src='js/id/actions/move_way.js'></script>
<script src='js/id/actions/circular.js'></script>
<script src='js/id/actions/circularize.js'></script>
<script src='js/id/actions/noop.js'></script>
<script src='js/id/actions/reverse_way.js'></script>
<script src='js/id/actions/split_way.js'></script>
@@ -92,7 +93,6 @@
<script src='js/id/behavior/drag.js'></script>
<script src='js/id/behavior/drag_midpoint.js'></script>
<script src='js/id/behavior/drag_node.js'></script>
<script src='js/id/behavior/drag_way.js'></script>
<script src='js/id/behavior/draw.js'></script>
<script src='js/id/behavior/draw_way.js'></script>
<script src='js/id/behavior/hover.js'></script>
@@ -104,8 +104,17 @@
<script src='js/id/modes/browse.js'></script>
<script src='js/id/modes/draw_area.js'></script>
<script src='js/id/modes/draw_line.js'></script>
<script src='js/id/modes/move_way.js'></script>
<script src='js/id/modes/select.js'></script>
<script src='js/id/operations.js'></script>
<script src='js/id/operations/circularize.js'></script>
<script src='js/id/operations/delete.js'></script>
<script src='js/id/operations/move.js'></script>
<script src='js/id/operations/reverse.js'></script>
<script src='js/id/operations/split.js'></script>
<script src='js/id/operations/unjoin.js'></script>
<script src='js/id/controller/controller.js'></script>
<script src='js/id/graph/entity.js'></script>
@@ -117,9 +126,13 @@
<script src='js/id/graph/validate.js'></script>
<script src='js/id/connection.js'></script>
<script src='locale/locale.js'></script>
<script src='locale/en.js'></script>
</head>
<body>
<div id="iD"></div><script>
locale.current = 'en';
d3.json('keys.json', function(err, keys) {
var id = iD();
id.connection().keys(keys)

View File

@@ -0,0 +1,11 @@
iD.actions.AddMidpoint = function(midpoint, node) {
return function(graph) {
graph = graph.replace(node.move(midpoint.loc));
midpoint.ways.forEach(function(way) {
graph = graph.replace(graph.entity(way.id).addNode(node.id, way.index));
});
return graph;
};
};

View File

@@ -1,4 +1,4 @@
iD.actions.Circular = function(wayId, map) {
iD.actions.Circularize = function(wayId, map) {
var action = function(graph) {
var way = graph.entity(wayId),
@@ -51,7 +51,7 @@ iD.actions.Circular = function(wayId, map) {
};
action.enabled = function(graph) {
return true;
return graph.entity(wayId).isClosed();
};
return action;

View File

@@ -1,6 +1,6 @@
// https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteNodeAction.as
iD.actions.DeleteNode = function(nodeId) {
var action = function(graph) {
return function(graph) {
var node = graph.entity(nodeId);
graph.parentWays(node)
@@ -20,10 +20,4 @@ iD.actions.DeleteNode = function(nodeId) {
return graph.remove(node);
};
action.enabled = function(graph) {
return true;
};
return action;
};

View File

@@ -1,6 +1,6 @@
// https://github.com/openstreetmap/potlatch2/blob/master/net/systemeD/halcyon/connection/actions/DeleteWayAction.as
iD.actions.DeleteWay = function(wayId) {
var action = function(graph) {
return function(graph) {
var way = graph.entity(wayId);
graph.parentRelations(way)
@@ -27,10 +27,4 @@ iD.actions.DeleteWay = function(wayId) {
return graph.remove(way);
};
action.enabled = function(graph) {
return true;
};
return action;
};

View File

@@ -53,7 +53,7 @@ iD.actions.ReverseWay = function(wayId) {
}
}
var action = function(graph) {
return function(graph) {
var way = graph.entity(wayId),
nodes = way.nodes.slice().reverse(),
tags = {}, key, role;
@@ -73,10 +73,4 @@ iD.actions.ReverseWay = function(wayId) {
return graph.replace(way.update({nodes: nodes, tags: tags}));
};
action.enabled = function(graph) {
return true;
};
return action;
};

View File

@@ -1,33 +1,22 @@
iD.behavior.AddWay = function(mode) {
var map = mode.map,
history = mode.history,
controller = mode.controller,
event = d3.dispatch('startFromNode', 'startFromWay', 'start'),
hover, draw;
function add() {
var datum = d3.select(d3.event.target).datum() || {};
if (datum.type === 'node') {
event.startFromNode(datum);
} else if (datum.type === 'way') {
var choice = iD.geo.chooseIndex(datum, d3.mouse(map.surface.node()), map);
event.startFromWay(datum, choice.loc, choice.index);
} else if (datum.midpoint) {
var way = history.graph().entity(datum.way);
event.startFromWay(way, datum.loc, datum.index);
} else {
event.start(map.mouseCoordinates());
}
}
event = d3.dispatch('start', 'startFromWay', 'startFromNode', 'startFromMidpoint'),
draw = iD.behavior.Draw(map);
var addWay = function(surface) {
draw.on('click', event.start)
.on('clickWay', event.startFromWay)
.on('clickNode', event.startFromNode)
.on('clickMidpoint', event.startFromMidpoint)
.on('cancel', addWay.cancel)
.on('finish', addWay.cancel);
map.fastEnable(false)
.minzoom(16)
.dblclickEnable(false);
surface.call(hover)
.call(draw);
surface.call(draw);
};
addWay.off = function(surface) {
@@ -39,20 +28,12 @@ iD.behavior.AddWay = function(mode) {
map.dblclickEnable(true);
}, 1000);
surface.call(hover.off)
.call(draw.off);
surface.call(draw.off);
};
addWay.cancel = function() {
controller.exit();
};
hover = iD.behavior.Hover();
draw = iD.behavior.Draw()
.on('add', add)
.on('cancel', addWay.cancel)
.on('finish', addWay.cancel);
return d3.rebind(addWay, event, 'on');
};

View File

@@ -24,7 +24,8 @@ iD.behavior.drag = function () {
origin = null,
selector = '',
filter = null,
keybinding = d3.keybinding('drag');
keybinding = d3.keybinding('drag'),
event_, target;
event.of = function(thiz, argumentz) {
return function(e1) {
@@ -40,9 +41,9 @@ iD.behavior.drag = function () {
};
function mousedown() {
var target = this,
event_ = event.of(target, arguments),
eventTarget = d3.event.target,
target = this,
event_ = event.of(target, arguments);
var eventTarget = d3.event.target,
touchId = d3.event.touches ? d3.event.changedTouches[0].identifier : null,
offset,
origin_ = point(),
@@ -166,6 +167,13 @@ iD.behavior.drag = function () {
return drag;
};
drag.target = function() {
if (!arguments.length) return target;
target = arguments[0];
event_ = event.of(target, Array.prototype.slice.call(arguments, 1));
return drag;
};
keybinding
.on('⌘+Z', drag.cancel)
.on('⌃+Z', drag.cancel);

View File

@@ -2,34 +2,31 @@ iD.behavior.DragMidpoint = function(mode) {
var history = mode.history,
projection = mode.map.projection;
return iD.behavior.drag()
var behavior = iD.behavior.drag()
.delegate(".midpoint")
.origin(function(d) {
return projection(d.loc);
})
.on('start', function(d) {
var w, nds;
d.node = iD.Node({loc: d.loc});
var args = [iD.actions.AddNode(d.node)];
for (var i = 0; i < d.ways.length; i++) {
w = d.ways[i], nds = w.nodes;
for (var j = 0; j < nds.length; j++) {
if ((nds[j] === d.nodes[0] && nds[j + 1] === d.nodes[1]) ||
(nds[j] === d.nodes[1] && nds[j + 1] === d.nodes[0])) {
args.push(iD.actions.AddWayNode(w.id, d.node.id, j + 1));
}
}
}
history.perform.apply(history, args);
var node = iD.Node();
history.perform(iD.actions.AddMidpoint(d, node));
var vertex = d3.selectAll('.vertex')
.filter(function(data) { return data.id === node.id; });
behavior.target(vertex.node(), vertex.datum());
})
.on('move', function(d) {
d3.event.sourceEvent.stopPropagation();
history.replace(
iD.actions.MoveNode(d.node.id, projection.invert(d3.event.point)));
iD.actions.MoveNode(d.id, projection.invert(d3.event.point)));
})
.on('end', function() {
history.replace(
iD.actions.Noop(),
'added a node to a way');
});
return behavior;
};

View File

@@ -1,7 +1,30 @@
iD.behavior.DragNode = function(mode) {
var history = mode.history,
size = mode.map.size(),
nudgeInterval,
projection = mode.map.projection;
function edge(point) {
var pad = [30, 100, 30, 100];
if (point[0] > size[0] - pad[0]) return [-10, 0];
else if (point[0] < pad[2]) return [10, 0];
else if (point[1] > size[1] - pad[1]) return [0, -10];
else if (point[1] < pad[3]) return [0, 10];
return null;
}
function startNudge(nudge) {
if (nudgeInterval) window.clearInterval(nudgeInterval);
nudgeInterval = window.setInterval(function() {
mode.map.pan(nudge).redraw();
}, 50);
}
function stopNudge(nudge) {
if (nudgeInterval) window.clearInterval(nudgeInterval);
nudgeInterval = null;
}
return iD.behavior.drag()
.delegate(".node")
.origin(function(entity) {
@@ -13,11 +36,17 @@ iD.behavior.DragNode = function(mode) {
})
.on('move', function(entity) {
d3.event.sourceEvent.stopPropagation();
var nudge = edge(d3.event.point);
if (nudge) startNudge(nudge);
else stopNudge();
history.replace(
iD.actions.MoveNode(entity.id, projection.invert(d3.event.point)),
'moved a node');
})
.on('end', function() {
stopNudge();
history.replace(
iD.actions.Noop(),
'moved a node');

View File

@@ -1,28 +0,0 @@
iD.behavior.DragWay = function(mode) {
var history = mode.history,
projection = mode.map.projection;
return iD.behavior.drag()
.delegate('.casing, .stroke, .area')
.filter(function(d) {
return d && d.id === mode.entity.id;
})
.origin(function(entity) {
return projection(history.graph().entity(entity.nodes[0]).loc);
})
.on('start', function() {
history.perform(
iD.actions.Noop());
})
.on('move', function(entity) {
d3.event.sourceEvent.stopPropagation();
history.replace(
iD.actions.MoveWay(entity.id, d3.event.delta, projection),
'moved a way');
})
.on('end', function() {
history.replace(
iD.actions.Noop(),
'moved a way');
});
};

View File

@@ -1,45 +1,77 @@
iD.behavior.Draw = function () {
var event = d3.dispatch('move', 'add', 'undo', 'cancel', 'finish'),
iD.behavior.Draw = function(map) {
var event = d3.dispatch('move', 'click', 'clickWay', 'clickNode', 'clickMidpoint', 'undo', 'cancel', 'finish'),
keybinding = d3.keybinding('draw'),
down;
down, surface, hover;
function datum() {
if (d3.event.altKey) {
return {};
} else {
return d3.event.target.__data__ || {};
}
}
function mousedown() {
down = true;
}
function mouseup() {
down = false;
}
function mousemove() {
if (!down) {
event.move(datum());
}
}
function click() {
var d = datum();
if (d.type === 'way') {
var choice = iD.geo.chooseIndex(d, d3.mouse(map.surface.node()), map);
event.clickWay(d, choice.loc, choice.index);
} else if (d.type === 'node') {
event.clickNode(d);
} else if (d.type === 'midpoint') {
event.clickMidpoint(d);
} else {
event.click(map.mouseCoordinates());
}
}
function keydown() {
if (d3.event.keyCode === d3.keybinding.modifierCodes.alt) {
surface.call(hover.off);
}
}
function keyup() {
if (d3.event.keyCode === d3.keybinding.modifierCodes.alt) {
surface.call(hover);
}
}
function backspace() {
d3.event.preventDefault();
event.undo();
}
function del() {
d3.event.preventDefault();
event.cancel();
}
function ret() {
d3.event.preventDefault();
event.finish();
}
function draw(selection) {
function mousemove() {
if (!down) event.move();
}
function click() {
event.add();
}
function mousedown() {
down = true;
}
function mouseup() {
down = false;
}
function backspace() {
d3.event.preventDefault();
event.undo();
}
function del() {
d3.event.preventDefault();
event.cancel();
}
function ret() {
d3.event.preventDefault();
event.finish();
}
selection
.on('mousedown.draw', mousedown)
.on('mouseup.draw', mouseup)
.on('mousemove.draw', mousemove)
.on('click.draw', click);
surface = selection;
hover = iD.behavior.Hover();
keybinding
.on('⌫', backspace)
@@ -47,18 +79,33 @@ iD.behavior.Draw = function () {
.on('⎋', ret)
.on('↩', ret);
selection
.on('mousedown.draw', mousedown)
.on('mouseup.draw', mouseup)
.on('mousemove.draw', mousemove)
.on('click.draw', click)
.call(hover);
d3.select(document)
.call(keybinding);
.call(keybinding)
.on('keydown.draw', keydown)
.on('keyup.draw', keyup);
return draw;
}
draw.off = function(selection) {
selection
.on('mousedown.draw', null)
.on('mouseup.draw', null)
.on('mousemove.draw', null)
.on('click.draw', null);
.on('click.draw', null)
.call(hover.off);
keybinding.off();
d3.select(document)
.call(keybinding.off)
.on('keydown.draw', null)
.on('keyup.draw', null);
};
return d3.rebind(draw, event, 'on');

View File

@@ -1,10 +1,11 @@
iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode) {
iD.behavior.DrawWay = function(wayId, index, mode, baseGraph) {
var map = mode.map,
history = mode.history,
controller = mode.controller,
event = d3.dispatch('add', 'addHead', 'addTail', 'addNode', 'addWay'),
way = mode.history.graph().entity(wayId),
hover, draw;
finished = false,
annotation = 'added to a way',
draw = iD.behavior.Draw(map);
var node = iD.Node({loc: map.mouseCoordinates()}),
nodeId = node.id;
@@ -13,28 +14,16 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode) {
iD.actions.AddNode(node),
iD.actions.AddWayNode(wayId, node.id, index));
function move() {
history.replace(iD.actions.MoveNode(nodeId, map.mouseCoordinates()));
}
function move(datum) {
var loc = map.mouseCoordinates();
function add() {
var datum = d3.select(d3.event.target).datum() || {};
if (datum.id === headId) {
event.addHead(datum);
} else if (datum.id === tailId) {
event.addTail(datum);
} else if (datum.type === 'node' && datum.id !== nodeId) {
event.addNode(datum);
if (datum.type === 'node' || datum.type === 'midpoint') {
loc = datum.loc;
} else if (datum.type === 'way') {
var choice = iD.geo.chooseIndex(datum, d3.mouse(map.surface.node()), map);
event.addWay(datum, choice.loc, choice.index);
} else if (datum.midpoint) {
var way = history.graph().entity(datum.way);
event.addWay(way, datum.loc, datum.index);
} else {
event.add(map.mouseCoordinates());
loc = iD.geo.chooseIndex(datum, d3.mouse(map.surface.node()), map).loc;
}
history.replace(iD.actions.MoveNode(nodeId, loc));
}
function undone() {
@@ -42,12 +31,20 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode) {
}
var drawWay = function(surface) {
draw.on('move', move)
.on('click', drawWay.add)
.on('clickWay', drawWay.addWay)
.on('clickNode', drawWay.addNode)
.on('clickMidpoint', drawWay.addMidpoint)
.on('undo', history.undo)
.on('cancel', drawWay.cancel)
.on('finish', drawWay.finish);
map.fastEnable(false)
.minzoom(16)
.dblclickEnable(false);
surface.call(hover)
.call(draw)
surface.call(draw)
.selectAll('.way, .node')
.filter(function (d) { return d.id === wayId || d.id === nodeId; })
.classed('active', true);
@@ -56,6 +53,9 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode) {
};
drawWay.off = function(surface) {
if (!finished)
history.pop();
map.fastEnable(true)
.minzoom(0)
.tail(false);
@@ -64,14 +64,19 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode) {
map.dblclickEnable(true);
}, 1000);
surface.call(hover.off)
.call(draw.off)
surface.call(draw.off)
.selectAll('.way, .node')
.classed('active', false);
history.on('undone.draw', null);
};
drawWay.annotation = function(_) {
if (!arguments.length) return annotation;
annotation = _;
return drawWay;
};
function ReplaceTemporaryNode(newNode) {
return function(graph) {
return graph
@@ -80,17 +85,21 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode) {
}
}
// Connect the way to an existing node and continue drawing.
drawWay.addNode = function(node, annotation) {
history.perform(
ReplaceTemporaryNode(node),
// Accept the current position of the temporary node and continue drawing.
drawWay.add = function(loc) {
var newNode = iD.Node({loc: loc});
history.replace(
iD.actions.AddNode(newNode),
ReplaceTemporaryNode(newNode),
annotation);
finished = true;
controller.enter(mode);
};
// Connect the way to an existing way.
drawWay.addWay = function(way, loc, wayIndex, annotation) {
drawWay.addWay = function(way, loc, wayIndex) {
var newNode = iD.Node({loc: loc});
history.perform(
@@ -99,18 +108,30 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode) {
ReplaceTemporaryNode(newNode),
annotation);
finished = true;
controller.enter(mode);
};
// Accept the current position of the temporary node and continue drawing.
drawWay.add = function(loc, annotation) {
var newNode = iD.Node({loc: loc});
history.replace(
iD.actions.AddNode(newNode),
ReplaceTemporaryNode(newNode),
// Connect the way to an existing node and continue drawing.
drawWay.addNode = function(node) {
history.perform(
ReplaceTemporaryNode(node),
annotation);
finished = true;
controller.enter(mode);
};
// Add a midpoint, connect the way to it, and continue drawing.
drawWay.addMidpoint = function(midpoint) {
var node = iD.Node();
history.perform(
iD.actions.AddMidpoint(midpoint, node),
ReplaceTemporaryNode(node),
annotation);
finished = true;
controller.enter(mode);
};
@@ -118,6 +139,7 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode) {
// nodes to be valid, it's selected. Otherwise, return to browse mode.
drawWay.finish = function() {
history.pop();
finished = true;
var way = history.graph().entity(wayId);
if (way) {
@@ -129,18 +151,13 @@ iD.behavior.DrawWay = function(wayId, headId, tailId, index, mode) {
// Cancel the draw operation and return to browse, deleting everything drawn.
drawWay.cancel = function() {
history.perform(iD.actions.DeleteWay(wayId), 'cancelled drawing');
history.perform(
d3.functor(baseGraph),
'cancelled drawing');
finished = true;
controller.enter(iD.modes.Browse());
};
hover = iD.behavior.Hover();
draw = iD.behavior.Draw()
.on('move', move)
.on('add', add)
.on('undo', history.undo)
.on('cancel', drawWay.cancel)
.on('finish', drawWay.finish);
return d3.rebind(drawWay, event, 'on');
};

View File

@@ -9,6 +9,8 @@
*/
iD.behavior.Hover = function () {
var hover = function(selection) {
selection.classed('behavior-hover', true);
selection.on('mouseover.hover', function () {
var datum = d3.event.target.__data__;
if (datum) {
@@ -25,7 +27,8 @@ iD.behavior.Hover = function () {
};
hover.off = function(selection) {
selection.on('mouseover.hover', null)
selection.classed('behavior-hover', false)
.on('mouseover.hover', null)
.on('mouseout.hover', null);
};

View File

@@ -10,6 +10,10 @@ iD.Connection = function() {
loadedTiles = {},
oauth = iD.OAuth().url(url);
function changesetUrl(changesetId) {
return url + '/browse/changeset/' + changesetId;
}
function bboxUrl(b) {
return url + '/api/0.6/map?bbox=' + [b[0][0],b[1][1],b[1][0],b[0][1]];
}
@@ -325,6 +329,7 @@ iD.Connection = function() {
};
connection.bboxFromAPI = bboxFromAPI;
connection.changesetUrl = changesetUrl;
connection.loadFromURL = loadFromURL;
connection.loadTiles = _.debounce(loadTiles, 100);
connection.userDetails = userDetails;

View File

@@ -21,6 +21,10 @@ window.iD = function(container) {
return;
}
function hintprefix(x, y) {
return '<span class="keyhint">' + x + '</span> ' + y;
}
var m = container.append('div')
.attr('id', 'map')
.call(map);
@@ -40,8 +44,10 @@ window.iD = function(container) {
.enter().append('button')
.attr('tabindex', -1)
.attr('class', function (mode) { return mode.title + ' add-button col3'; })
.attr('data-original-title', function (mode) { return mode.description; })
.call(bootstrap.tooltip().placement('bottom'))
.attr('data-original-title', function (mode) {
return hintprefix(mode.key, mode.description);
})
.call(bootstrap.tooltip().placement('bottom').html(true))
.on('click.editor', function (mode) { controller.enter(mode); });
function disableTooHigh() {
@@ -82,7 +88,7 @@ window.iD = function(container) {
var undo_buttons = limiter.append('div')
.attr('class', 'button-wrap joined col1'),
undo_tooltip = bootstrap.tooltip().placement('bottom');
undo_tooltip = bootstrap.tooltip().placement('bottom').html(true);
undo_buttons.append('button')
.attr({ id: 'undo', 'class': 'col6' })
@@ -201,12 +207,12 @@ window.iD = function(container) {
limiter.select('#undo')
.property('disabled', !undo)
.attr('data-original-title', undo)
.attr('data-original-title', hintprefix('⌘Z', undo))
.call(refreshTooltip);
limiter.select('#redo')
.property('disabled', !redo)
.attr('data-original-title', redo)
.attr('data-original-title', hintprefix('⌘⇧Z', redo))
.call(refreshTooltip);
});
@@ -215,16 +221,16 @@ window.iD = function(container) {
});
var keybinding = d3.keybinding('main')
.on('M', function() { if (map.editable()) controller.enter(iD.modes.Browse()); })
.on('P', function() { if (map.editable()) controller.enter(iD.modes.AddPoint()); })
.on('L', function() { if (map.editable()) controller.enter(iD.modes.AddLine()); })
.on('A', function() { if (map.editable()) controller.enter(iD.modes.AddArea()); })
.on('⌘+Z', function() { history.undo(); })
.on('⌃+Z', function() { history.undo(); })
.on('⌘+⇧+Z', function() { history.redo(); })
.on('⌃+⇧+Z', function() { history.redo(); })
.on('⌫', function() { d3.event.preventDefault(); });
[iD.modes.Browse(), iD.modes.AddPoint(), iD.modes.AddLine(), iD.modes.AddArea()].forEach(function(m) {
keybinding.on(m.key, function() { if (map.editable()) controller.enter(m); });
});
d3.select(document)
.call(keybinding);

View File

@@ -3,7 +3,8 @@ iD.modes.AddArea = function() {
id: 'add-area',
button: 'area',
title: 'Area',
description: 'Add parks, buildings, lakes, or other areas to the map.'
description: 'Add parks, buildings, lakes, or other areas to the map.',
key: 'a'
};
var behavior,
@@ -14,19 +15,23 @@ iD.modes.AddArea = function() {
history = mode.history,
controller = mode.controller;
function startFromNode(node) {
var way = iD.Way({tags: defaultTags});
function start(loc) {
var graph = history.graph(),
node = iD.Node({loc: loc}),
way = iD.Way({tags: defaultTags});
history.perform(
iD.actions.AddNode(node),
iD.actions.AddWay(way),
iD.actions.AddWayNode(way.id, node.id),
iD.actions.AddWayNode(way.id, node.id));
controller.enter(iD.modes.DrawArea(way.id));
controller.enter(iD.modes.DrawArea(way.id, graph));
}
function startFromWay(other, loc, index) {
var node = iD.Node({loc: loc}),
var graph = history.graph(),
node = iD.Node({loc: loc}),
way = iD.Way({tags: defaultTags});
history.perform(
@@ -36,26 +41,40 @@ iD.modes.AddArea = function() {
iD.actions.AddWayNode(way.id, node.id),
iD.actions.AddWayNode(other.id, node.id, index));
controller.enter(iD.modes.DrawArea(way.id));
controller.enter(iD.modes.DrawArea(way.id, graph));
}
function start(loc) {
var node = iD.Node({loc: loc}),
function startFromNode(node) {
var graph = history.graph(),
way = iD.Way({tags: defaultTags});
history.perform(
iD.actions.AddNode(node),
iD.actions.AddWay(way),
iD.actions.AddWayNode(way.id, node.id),
iD.actions.AddWayNode(way.id, node.id));
controller.enter(iD.modes.DrawArea(way.id));
controller.enter(iD.modes.DrawArea(way.id, graph));
}
function startFromMidpoint(midpoint) {
var graph = history.graph(),
node = iD.Node(),
way = iD.Way({tags: defaultTags});
history.perform(
iD.actions.AddMidpoint(midpoint, node),
iD.actions.AddWay(way),
iD.actions.AddWayNode(way.id, node.id),
iD.actions.AddWayNode(way.id, node.id));
controller.enter(iD.modes.DrawArea(way.id, graph));
}
behavior = iD.behavior.AddWay(mode)
.on('startFromNode', startFromNode)
.on('start', start)
.on('startFromWay', startFromWay)
.on('start', start);
.on('startFromNode', startFromNode)
.on('startFromMidpoint', startFromMidpoint);
mode.map.surface.call(behavior);
mode.map.tail('Click on the map to start drawing an area, like a park, lake, or building.', true);

View File

@@ -3,7 +3,8 @@ iD.modes.AddLine = function() {
id: 'add-line',
button: 'line',
title: 'Line',
description: 'Lines can be highways, streets, pedestrian paths, or even canals.'
description: 'Lines can be highways, streets, pedestrian paths, or even canals.',
key: 'l'
};
var behavior,
@@ -14,30 +15,22 @@ iD.modes.AddLine = function() {
history = mode.history,
controller = mode.controller;
function startFromNode(node) {
function start(loc) {
var graph = history.graph(),
parent = graph.parentWays(node)[0],
isLine = parent && parent.geometry(graph) === 'line';
node = iD.Node({loc: loc}),
way = iD.Way({tags: defaultTags});
if (isLine && parent.first() === node.id) {
controller.enter(iD.modes.DrawLine(parent.id, 'backward'));
history.perform(
iD.actions.AddNode(node),
iD.actions.AddWay(way),
iD.actions.AddWayNode(way.id, node.id));
} else if (isLine && parent.last() === node.id) {
controller.enter(iD.modes.DrawLine(parent.id, 'forward'));
} else {
var way = iD.Way({tags: defaultTags});
history.perform(
iD.actions.AddWay(way),
iD.actions.AddWayNode(way.id, node.id));
controller.enter(iD.modes.DrawLine(way.id, 'forward'));
}
controller.enter(iD.modes.DrawLine(way.id, 'forward', graph));
}
function startFromWay(other, loc, index) {
var node = iD.Node({loc: loc}),
var graph = history.graph(),
node = iD.Node({loc: loc}),
way = iD.Way({tags: defaultTags});
history.perform(
@@ -46,25 +39,49 @@ iD.modes.AddLine = function() {
iD.actions.AddWayNode(way.id, node.id),
iD.actions.AddWayNode(other.id, node.id, index));
controller.enter(iD.modes.DrawLine(way.id, 'forward'));
controller.enter(iD.modes.DrawLine(way.id, 'forward', graph));
}
function start(loc) {
var node = iD.Node({loc: loc}),
function startFromNode(node) {
var graph = history.graph(),
parent = graph.parentWays(node)[0],
isLine = parent && parent.geometry(graph) === 'line';
if (isLine && parent.first() === node.id) {
controller.enter(iD.modes.DrawLine(parent.id, 'backward', graph));
} else if (isLine && parent.last() === node.id) {
controller.enter(iD.modes.DrawLine(parent.id, 'forward', graph));
} else {
var way = iD.Way({tags: defaultTags});
history.perform(
iD.actions.AddWay(way),
iD.actions.AddWayNode(way.id, node.id));
controller.enter(iD.modes.DrawLine(way.id, 'forward', graph));
}
}
function startFromMidpoint(midpoint) {
var graph = history.graph(),
node = iD.Node(),
way = iD.Way({tags: defaultTags});
history.perform(
iD.actions.AddNode(node),
iD.actions.AddMidpoint(midpoint, node),
iD.actions.AddWay(way),
iD.actions.AddWayNode(way.id, node.id));
controller.enter(iD.modes.DrawLine(way.id, 'forward'));
controller.enter(iD.modes.DrawLine(way.id, 'forward', graph));
}
behavior = iD.behavior.AddWay(mode)
.on('startFromNode', startFromNode)
.on('start', start)
.on('startFromWay', startFromWay)
.on('start', start);
.on('startFromNode', startFromNode)
.on('startFromMidpoint', startFromMidpoint);
mode.map.surface.call(behavior);
mode.map.tail('Click on the map to start drawing an road, path, or route.', true);

View File

@@ -2,7 +2,8 @@ iD.modes.AddPoint = function() {
var mode = {
id: 'add-point',
title: 'Point',
description: 'Restaurants, monuments, and postal boxes are points.'
description: 'Restaurants, monuments, and postal boxes are points.',
key: 'p'
};
var behavior;
@@ -15,8 +16,8 @@ iD.modes.AddPoint = function() {
map.tail('Click on the map to add a point.', true);
function add() {
var node = iD.Node({loc: map.mouseCoordinates()});
function add(loc) {
var node = iD.Node({loc: loc});
history.perform(
iD.actions.AddNode(node),
@@ -25,12 +26,23 @@ iD.modes.AddPoint = function() {
controller.enter(iD.modes.Select(node, true));
}
function addWay(way, loc, index) {
add(loc);
}
function addNode(node) {
add(node.loc);
}
function cancel() {
controller.exit();
}
behavior = iD.behavior.Draw()
.on('add', add)
behavior = iD.behavior.Draw(map)
.on('click', add)
.on('clickWay', addWay)
.on('clickNode', addNode)
.on('clickMidpoint', addNode)
.on('cancel', cancel)
.on('finish', cancel)
(surface);

View File

@@ -2,8 +2,9 @@ iD.modes.Browse = function() {
var mode = {
button: 'browse',
id: 'browse',
title: 'Move',
description: 'Pan and zoom the map'
title: 'Browse',
description: 'Pan and zoom the map',
key: 'b'
};
var behaviors;

View File

@@ -1,4 +1,4 @@
iD.modes.DrawArea = function(wayId) {
iD.modes.DrawArea = function(wayId, baseGraph) {
var mode = {
button: 'area',
id: 'draw-area'
@@ -8,33 +8,21 @@ iD.modes.DrawArea = function(wayId) {
mode.enter = function() {
var way = mode.history.graph().entity(wayId),
index = -1,
headId = way.nodes[way.nodes.length - 2],
tailId = way.first(),
annotation = way.isDegenerate() ? 'started an area' : 'continued an area';
tailId = way.first();
function addHeadTail() {
behavior.finish();
}
behavior = iD.behavior.DrawWay(wayId, -1, mode, baseGraph)
.annotation(way.isDegenerate() ? 'started an area' : 'continued an area');
function addNode(node) {
behavior.addNode(node, annotation);
}
var addNode = behavior.addNode;
function addWay(way, loc, index) {
behavior.addWay(way, loc, index, annotation);
}
function add(loc) {
behavior.add(loc, annotation);
}
behavior = iD.behavior.DrawWay(wayId, headId, tailId, index, mode)
.on('addHead', addHeadTail)
.on('addTail', addHeadTail)
.on('addNode', addNode)
.on('addWay', addWay)
.on('add', add);
behavior.addNode = function(node) {
if (node.id === headId || node.id === tailId) {
behavior.finish();
} else {
addNode(node);
}
};
mode.map.surface.call(behavior);
mode.map.tail('Click to add points to your area. Click the first point to finish the area.', true);

View File

@@ -1,4 +1,4 @@
iD.modes.DrawLine = function(wayId, direction) {
iD.modes.DrawLine = function(wayId, direction, baseGraph) {
var mode = {
button: 'line',
id: 'draw-line'
@@ -9,41 +9,20 @@ iD.modes.DrawLine = function(wayId, direction) {
mode.enter = function() {
var way = mode.history.graph().entity(wayId),
index = (direction === 'forward') ? undefined : 0,
headId = (direction === 'forward') ? way.last() : way.first(),
tailId = (direction === 'forward') ? way.first() : way.last(),
annotation = way.isDegenerate() ? 'started a line' : 'continued a line';
headId = (direction === 'forward') ? way.last() : way.first();
function addHead() {
behavior.finish();
}
behavior = iD.behavior.DrawWay(wayId, index, mode, baseGraph)
.annotation(way.isDegenerate() ? 'started a line' : 'continued a line');
function addTail(node) {
// connect the way in a loop
if (way.nodes.length > 2) {
behavior.addNode(node, annotation);
var addNode = behavior.addNode;
behavior.addNode = function(node) {
if (node.id === headId) {
behavior.finish();
} else {
behavior.cancel();
addNode(node);
}
}
function addNode(node) {
behavior.addNode(node, annotation);
}
function addWay(way, loc, index) {
behavior.addWay(way, loc, index, annotation);
}
function add(loc) {
behavior.add(loc, annotation);
}
behavior = iD.behavior.DrawWay(wayId, headId, tailId, index, mode)
.on('addHead', addHead)
.on('addTail', addTail)
.on('addNode', addNode)
.on('addWay', addWay)
.on('add', add);
};
mode.map.surface.call(behavior);
mode.map.tail('Click to add more points to the line. ' +

78
js/id/modes/move_way.js Normal file
View File

@@ -0,0 +1,78 @@
iD.modes.MoveWay = function(wayId) {
var mode = {
id: 'move-way'
};
var keybinding = d3.keybinding('move-way');
mode.enter = function() {
var map = mode.map,
history = mode.history,
graph = history.graph(),
selection = map.surface,
controller = mode.controller,
projection = map.projection;
var way = graph.entity(wayId),
origin = d3.mouse(selection.node());
history.perform(
iD.actions.Noop(),
'moved a way');
function move() {
var p = d3.mouse(selection.node()),
delta = [p[0] - origin[0],
p[1] - origin[1]];
origin = p;
history.replace(
iD.actions.MoveWay(wayId, delta, projection),
'moved a way');
}
function finish() {
d3.event.stopPropagation();
controller.enter(iD.modes.Select(way, true));
}
function cancel() {
history.pop();
controller.enter(iD.modes.Select(way, true));
}
function undone() {
controller.enter(iD.modes.Browse());
}
selection
.on('mousemove.move-way', move)
.on('click.move-way', finish);
history.on('undone.move-way', undone);
keybinding
.on('⎋', cancel)
.on('↩', finish);
d3.select(document)
.call(keybinding);
};
mode.exit = function() {
var map = mode.map,
history = mode.history,
selection = map.surface;
selection
.on('mousemove.move-way', null)
.on('click.move-way', null);
history.on('undone.move-way', null);
keybinding.off();
};
return mode;
};

View File

@@ -10,20 +10,6 @@ iD.modes.Select = function(entity, initial) {
behaviors,
radialMenu;
function remove() {
if (entity.type === 'way') {
mode.history.perform(
iD.actions.DeleteWay(entity.id),
'deleted a way');
} else if (entity.type === 'node') {
mode.history.perform(
iD.actions.DeleteNode(entity.id),
'deleted a node');
}
mode.controller.exit();
}
function changeTags(d, tags) {
if (!_.isEqual(entity.tags, tags)) {
mode.history.perform(
@@ -43,13 +29,24 @@ iD.modes.Select = function(entity, initial) {
behaviors = [
iD.behavior.Hover(),
iD.behavior.DragNode(mode),
iD.behavior.DragWay(mode),
iD.behavior.DragMidpoint(mode)];
behaviors.forEach(function(behavior) {
behavior(surface);
});
var operations = d3.values(iD.operations)
.map(function (o) { return o(entity.id, mode); })
.filter(function (o) { return o.available(); });
operations.forEach(function(operation) {
keybinding.on(operation.key, function () {
if (operation.enabled()) {
operation();
}
});
});
var q = iD.util.stringQs(location.hash.substring(1));
location.replace('#' + iD.util.qsString(_.assign(q, {
id: entity.id
@@ -127,8 +124,6 @@ iD.modes.Select = function(entity, initial) {
surface.on('click.select', click)
.on('dblclick.select', dblclick);
keybinding.on('⌫', remove);
d3.select(document)
.call(keybinding);
@@ -138,7 +133,7 @@ iD.modes.Select = function(entity, initial) {
})
.classed('selected', true);
radialMenu = iD.ui.RadialMenu(entity, history, mode.map);
radialMenu = iD.ui.RadialMenu(operations);
if (d3.event && !initial) {
var loc = map.mouseCoordinates();

1
js/id/operations.js Normal file
View File

@@ -0,0 +1 @@
iD.operations = {}

View File

@@ -0,0 +1,39 @@
iD.operations.Circularize = function(entityId, mode) {
var history = mode.map.history(),
action = iD.actions.Circularize(entityId, mode.map);
var operation = function() {
var graph = history.graph(),
entity = graph.entity(entityId),
geometry = entity.geometry(graph);
if (geometry === 'line') {
history.perform(
action,
'made a line circular');
} else if (geometry === 'area') {
history.perform(
action,
'made an area circular');
}
};
operation.available = function() {
var graph = history.graph(),
entity = graph.entity(entityId);
return entity.geometry(graph) === 'area' || entity.geometry(graph) === 'line';
};
operation.enabled = function() {
var graph = history.graph();
return action.enabled(graph);
};
operation.id = "circularize";
operation.key = "O";
operation.title = "Circularize";
operation.description = "Make this round";
return operation;
};

View File

@@ -0,0 +1,47 @@
iD.operations.Delete = function(entityId, mode) {
var history = mode.map.history();
var operation = function() {
var graph = history.graph(),
entity = graph.entity(entityId),
geometry = entity.geometry(graph);
if (geometry === 'vertex') {
history.perform(
iD.actions.DeleteNode(entityId),
'deleted a vertex');
} else if (geometry === 'point') {
history.perform(
iD.actions.DeleteNode(entityId),
'deleted a point');
} else if (geometry === 'line') {
history.perform(
iD.actions.DeleteWay(entityId),
'deleted a line');
} else if (geometry === 'area') {
history.perform(
iD.actions.DeleteWay(entityId),
'deleted an area');
}
};
operation.available = function() {
var graph = history.graph(),
entity = graph.entity(entityId);
return _.contains(['vertex', 'point', 'line', 'area'], entity.geometry(graph));
};
operation.enabled = function() {
return true;
};
operation.id = "delete";
operation.key = "⌫";
operation.title = "Delete";
operation.description = "Remove this from the map";
return operation;
};

23
js/id/operations/move.js Normal file
View File

@@ -0,0 +1,23 @@
iD.operations.Move = function(entityId, mode) {
var history = mode.map.history();
var operation = function() {
mode.controller.enter(iD.modes.MoveWay(entityId));
};
operation.available = function() {
var graph = history.graph();
return graph.entity(entityId).type === 'way';
};
operation.enabled = function() {
return true;
};
operation.id = "move";
operation.key = "M";
operation.title = "Move";
operation.description = "Move this to a different location";
return operation;
};

View File

@@ -0,0 +1,26 @@
iD.operations.Reverse = function(entityId, mode) {
var history = mode.map.history();
var operation = function() {
history.perform(
iD.actions.ReverseWay(entityId),
'reversed a line');
};
operation.available = function() {
var graph = history.graph(),
entity = graph.entity(entityId);
return entity.geometry(graph) === 'line';
};
operation.enabled = function() {
return true;
};
operation.id = "reverse";
operation.key = "V";
operation.title = "Reverse";
operation.description = "Make this way go in the opposite direction";
return operation;
};

26
js/id/operations/split.js Normal file
View File

@@ -0,0 +1,26 @@
iD.operations.Split = function(entityId, mode) {
var history = mode.map.history(),
action = iD.actions.SplitWay(entityId);
var operation = function() {
history.perform(action, 'split a way');
};
operation.available = function() {
var graph = history.graph(),
entity = graph.entity(entityId);
return entity.geometry(graph) === 'vertex';
};
operation.enabled = function() {
var graph = history.graph();
return action.enabled(graph);
};
operation.id = "split";
operation.key = "X";
operation.title = "Split";
operation.description = "Split this into two ways at this point";
return operation;
};

View File

@@ -0,0 +1,26 @@
iD.operations.Unjoin = function(entityId, mode) {
var history = mode.map.history(),
action = iD.actions.UnjoinNode(entityId);
var operation = function() {
history.perform(action, 'unjoined lines');
};
operation.available = function() {
var graph = history.graph(),
entity = graph.entity(entityId);
return entity.geometry(graph) === 'vertex';
};
operation.enabled = function() {
var graph = history.graph();
return action.enabled(graph);
};
operation.id = "unjoin";
operation.key = "⇧-J";
operation.title = "Unjoin";
operation.description = "Disconnect these ways from each other";
return operation;
};

View File

@@ -92,7 +92,7 @@ iD.Map = function() {
all = _.compact(_.values(only));
filter = function(d) {
if (d.midpoint) {
if (d.type === 'midpoint') {
for (var i = 0; i < d.ways.length; i++) {
if (d.ways[i].id in only) return true;
}
@@ -165,24 +165,33 @@ iD.Map = function() {
}
function resetTransform() {
if (!surface.style(transformProp)) return;
if (!surface.style(transformProp)) return false;
surface.style(transformProp, '');
tilegroup.style(transformProp, '');
return true;
}
function redraw(difference) {
resetTransform();
// If we are in the middle of a zoom/pan, we can't do differenced redraws.
// It would result in artifacts where differenced entities are redrawn with
// one transform and unchanged entities with another.
if (resetTransform())
difference = undefined;
surface.attr('data-zoom', ~~map.zoom());
tilegroup.call(background);
if (map.editable()) {
connection.loadTiles(projection, dimensions);
drawVector(difference);
} else {
editOff();
}
transformStart = [
projection.scale(),
projection.translate().slice()];
return map;
}
@@ -249,9 +258,19 @@ iD.Map = function() {
t[0] - ll[0] + c[0],
t[1] - ll[1] + c[1]]);
zoom.translate(projection.translate());
dispatch.move(map);
return true;
}
map.pan = function(d) {
var t = projection.translate();
t[0] += d[0];
t[1] += d[1];
projection.translate(t);
zoom.translate(projection.translate());
return map;
};
map.size = function(_) {
if (!arguments.length) return dimensions;
dimensions = _;

View File

@@ -15,19 +15,15 @@ iD.svg.Midpoints = function(projection) {
b = nodes[j + 1],
id = [a.id, b.id].sort().join('-');
if (!midpoints[id] &&
iD.geo.dist(projection(a.loc), projection(b.loc)) > 40) {
var midpoint_loc = iD.geo.interp(a.loc, b.loc, 0.5),
parents = _.intersection(graph.parentWays(a),
graph.parentWays(b));
if (midpoints[id]) {
midpoints[id].ways.push({id: entity.id, index: j + 1});
} else if (iD.geo.dist(projection(a.loc), projection(b.loc)) > 40) {
midpoints[id] = {
loc: midpoint_loc,
ways: parents,
nodes: [a.id, b.id],
type: 'midpoint',
id: id,
midpoint: true
loc: iD.geo.interp(a.loc, b.loc, 0.5),
ways: [{id: entity.id, index: j + 1}]
};
}
}
@@ -35,7 +31,7 @@ iD.svg.Midpoints = function(projection) {
var groups = surface.select('.layer-hit').selectAll('g.midpoint')
.filter(filter)
.data(_.values(midpoints), function (d) { return [d.parents, d.id].join(","); });
.data(_.values(midpoints), function (d) { return d.id; });
var group = groups.enter()
.insert('g', ':first-child')

View File

@@ -31,33 +31,8 @@ iD.ui.commit = function(map) {
header = selection.append('div').attr('class', 'header modal-section fillL'),
body = selection.append('div').attr('class', 'body');
var user_details = header
.append('div')
.attr('class', 'user-details');
var user_link = user_details
.append('div')
.append('a')
.attr('href', connection.url() + '/user/' +
user.display_name)
.attr('target', '_blank');
if (user.image_url) {
user_link
.append('img')
.attr('src', user.image_url)
.attr('class', 'user-icon');
}
user_link
.append('div')
.text(user.display_name);
header.append('h2').text('Save Changes');
header.append('p').text('The changes you upload will be visible on all maps that use OpenStreetMap data.');
// Comment Box
var comment_section = body.append('div').attr('class','modal-section fillD');
comment_section.append('textarea')
@@ -66,6 +41,28 @@ iD.ui.commit = function(map) {
.property('value', localStorage.comment || '')
.node().select();
var commit_info =
comment_section
.append('p')
.attr('class','commit-info');
commit_info.append('span').text('The changes you upload as ');
var user_link = commit_info.append('a')
.attr('class','user-info')
.text(user.display_name)
.attr('href', connection.url() + '/user/' + user.display_name)
.attr('target', '_blank');
commit_info.append('span').text(' will be visible on all maps that use OpenStreetMap data:');
if (user.image_url) {
user_link
.append('img')
.attr('src', user.image_url)
.attr('class', 'icon icon-pre-text user-icon');
}
// Confirm / Cancel Buttons
var buttonwrap = comment_section.append('div')
.attr('class', 'buttons cf')
@@ -89,7 +86,6 @@ iD.ui.commit = function(map) {
.on('click.cancel', function() {
event.cancel();
});
cancelbutton.append('span').attr('class','icon close icon-pre-text');
cancelbutton.append('span').attr('class','label').text('Cancel');
var warnings = body.selectAll('div.warning-section')
@@ -111,7 +107,7 @@ iD.ui.commit = function(map) {
.attr('class', 'minor')
.on('click', event.fix)
.append('span')
.attr('class', 'icon inspect');
.attr('class', 'icon warning');
warning_li.append('strong').text(function(d) {
return d.message;

View File

@@ -22,20 +22,20 @@ iD.ui.inspector = function() {
.attr('class', 'inspector-inner tag-wrap fillL2');
inspectorwrap.append('h4')
.text('Edit tags');
.text(t('edit_tags'));
tagList = inspectorwrap.append('ul');
inspectorwrap
.append('div')
.attr('class', 'add-tag-row')
.append('button')
.attr('class', 'add-tag')
.text('+ Add New Tag')
.on('click', function() {
addTag();
focusNewKey();
});
var newTag = inspectorwrap.append('button')
.attr('class', 'add-tag');
newTag.on('click', function() {
addTag();
focusNewKey();
});
newTag.append('span').attr('class', 'icon icon-pre-text plus');
newTag.append('span').attr('class','label').text('New tag')
drawTags(entity.tags);
@@ -63,7 +63,6 @@ iD.ui.inspector = function() {
.attr('class', 'apply action')
.on('click', apply);
inspectorButton.append('span').attr('class','icon icon-pre-text apply');
inspectorButton.append('span').attr('class','label').text('Okay');
var minorButtons = selection.append('div').attr('class','minor-buttons fl');
@@ -118,7 +117,7 @@ iD.ui.inspector = function() {
.on('click', removeTag);
removeBtn.append('span')
.attr('class', 'icon remove');
.attr('class', 'icon delete');
var helpBtn = row.append('button')
.attr('tabindex', -1)
@@ -149,7 +148,7 @@ iD.ui.inspector = function() {
iD.ui.flash()
.select('.content')
.append('h3')
.text('This is no documentation available for this tag combination');
.text(t('no_documentation_combination'));
}
});
} else if (d.key) {
@@ -167,7 +166,7 @@ iD.ui.inspector = function() {
iD.ui.flash()
.select('.content')
.append('h3')
.text('This is no documentation available for this key');
.text(t('no_documentation_key'));
}
});
}

View File

@@ -35,7 +35,7 @@ iD.ui.layerswitcher = function(map) {
.append('button')
.attr('tabindex', -1)
.attr('class', 'fillD')
.attr('title', 'Layer Settings')
.attr('title', t('layer_settings'))
.html("<span class='layers icon'></span>")
.on('click.layerswitcher-toggle', toggle);
@@ -59,7 +59,7 @@ iD.ui.layerswitcher = function(map) {
.append('div')
.attr('class', 'opacity-options-wrapper');
opa.append('h4').text('Layers');
opa.append('h4').text(t('layers'));
opa.append('ul')
.attr('class', 'opacity-options')
@@ -68,7 +68,7 @@ iD.ui.layerswitcher = function(map) {
.enter()
.append('li')
.attr('data-original-title', function(d) {
return (d * 100) + "% opacity";
return t('percent_opacity', { opacity: (d * 100) });
})
.on('click.set-opacity', function(d) {
d3.select('#tile-g')

View File

@@ -4,7 +4,7 @@ iD.ui.loading = function(message, blocking) {
var loadertext = modal.select('.content')
.classed('loading-modal', true)
.append('div').attr('class','modal-section fillL');
loadertext.append('img').attr('class','loader').attr('src', '/img/loader.gif');
loadertext.append('img').attr('class','loader').attr('src', 'img/loader.gif');
loadertext.append('h3').text(message || '');
return modal;

View File

@@ -1,6 +1,13 @@
iD.ui.modal = function(blocking) {
var animate = d3.select('div.modal').empty();
var keybinding = d3.keybinding('modal')
.on('⌫', close)
.on('⎋', close);
d3.select(document).call(keybinding);
d3.select('div.modal').transition()
.style('opacity', 0).remove();
@@ -16,7 +23,7 @@ iD.ui.modal = function(blocking) {
.attr('class', 'modal');
modal.append('button')
.attr('class', 'icon remove close-modal')
.attr('class', 'icon close-modal')
.on('click', function() {
if (!blocking) shaded.remove();
});
@@ -30,5 +37,10 @@ iD.ui.modal = function(blocking) {
shaded.style('opacity', 1);
}
function close() {
shaded.remove();
keybinding.off();
}
return shaded;
};

View File

@@ -18,7 +18,7 @@ iD.ui.notice = function(selection) {
div.append('span')
.attr('class', 'notice-text')
.text('zoom in to edit the map');
.text(t('zoom_in_edit'));
notice.message = function(_) {
if (_) {

View File

@@ -1,116 +1,94 @@
iD.ui.RadialMenu = function(entity, history, map) {
var arcs;
iD.ui.RadialMenu = function(operations) {
var menu;
var radialMenu = function(selection, center) {
var operations,
graph = history.graph(),
geometry = entity.geometry(graph);
if (geometry === 'vertex') {
operations = [
{
id: 'delete',
text: 'Delete',
description: 'deleted a node',
action: iD.actions.DeleteNode(entity.id)
},
{
id: 'split',
text: 'Split Way',
description: 'split a way',
action: iD.actions.SplitWay(entity.id)
},
{
id: 'unjoin',
text: 'Unjoin',
description: 'unjoined lines',
action: iD.actions.UnjoinNode(entity.id)
}
];
} else if (geometry === 'point') {
operations = [
{
id: 'delete',
text: 'Delete',
description: 'deleted a point',
action: iD.actions.DeleteNode(entity.id)
}
];
} else if (geometry === 'line') {
operations = [
{
id: 'delete',
text: 'Delete',
description: 'deleted a line',
action: iD.actions.DeleteWay(entity.id)
},
{
id: 'reverse',
text: 'Reverse',
description: 'reversed a way',
action: iD.actions.ReverseWay(entity.id)
}
];
if (entity.isClosed()) {
operations.push({
id: 'circlar',
text: 'Circular',
description: 'made way circular',
action: iD.actions.Circular(entity.id, map)
});
}
} else if (geometry === 'area') {
operations = [
{
id: 'delete',
text: 'Delete',
description: 'deleted an area',
action: iD.actions.DeleteWay(entity.id)
},
{
id: 'circlar',
text: 'Circular',
description: 'made area circular',
action: iD.actions.Circular(entity.id, map)
}
];
} else {
// Relation, not implemented yet.
if (!operations.length)
return;
function click(operation) {
d3.event.stopPropagation();
operation();
}
var arc = d3.svg.arc()
.outerRadius(70)
.innerRadius(30)
.startAngle(function (d, i) { return 2 * Math.PI / operations.length * i; })
.endAngle(function (d, i) { return 2 * Math.PI / operations.length * (i + 1); });
arcs = selection.selectAll()
.data(operations)
.enter().append('g')
menu = selection.append('g')
.attr('class', 'radial-menu')
.attr('transform', "translate(" + center + ")")
.attr('opacity', 0);
arcs.transition()
menu.transition()
.attr('opacity', 0.8);
arcs.append('path')
.attr('class', function (d) { return 'radial-menu-item radial-menu-item-' + d.id; })
.attr('d', arc)
.classed('disabled', function (d) { return !d.action.enabled(history.graph()); })
.on('click', function (d) { history.perform(d.action, d.description); });
var r = 50,
a = Math.PI / 4,
a0 = -Math.PI / 4,
a1 = a0 + (operations.length - 1) * a;
arcs.append('text')
.attr("transform", function(d, i) { return "translate(" + arc.centroid(d, i) + ")"; })
.attr("dy", ".35em")
.style("text-anchor", "middle")
.text(function(d) { return d.text; });
menu.append('path')
.attr('class', 'radial-menu-background')
.attr('d', 'M' + r * Math.sin(a0) + ',' +
r * Math.cos(a0) +
' A' + r + ',' + r + ' 0 0,0 ' +
r * Math.sin(a1) + ',' +
r * Math.cos(a1))
.attr('stroke-width', 50)
.attr('stroke-linecap', 'round');
var button = menu.selectAll()
.data(operations)
.enter().append('g')
.attr('transform', function(d, i) {
return 'translate(' + r * Math.sin(a0 + i * a) + ',' +
r * Math.cos(a0 + i * a) + ')';
});
button.append('circle')
.attr('class', function (d) { return 'radial-menu-item radial-menu-item-' + d.id; })
.attr('r', 15)
.attr('title', function (d) { return d.title; })
.classed('disabled', function (d) { return !d.enabled(); })
.on('click', click)
.on('mouseover', mouseover)
.on('mouseout', mouseout);
var image = button.append('foreignObject')
.style('pointer-events', 'none')
.attr('width', 20)
.attr('height', 20)
.attr('x', -10)
.attr('y', -10);
image.append('xhtml:span')
.attr('class', function (d) { return 'icon icon-operation icon-operation-' + d.id; });
var tooltip = menu.append('foreignObject')
.style('display', 'none')
.attr('width', 200)
.attr('height', 400);
tooltip.append('xhtml:div')
.attr('class', 'radial-menu-tooltip');
function mouseover(d, i) {
var angle = a0 + i * a,
dx = angle < 0 ? -200 : 0,
dy = 0;
tooltip
.attr('x', (r + 30) * Math.sin(angle) + dx)
.attr('y', (r + 30) * Math.cos(angle) + dy)
.style('display', 'block')
.select('div')
.text(d.description);
}
function mouseout() {
tooltip.style('display', 'none');
}
};
radialMenu.close = function(selection) {
if (arcs) {
arcs.transition()
if (menu) {
menu.transition()
.attr('opacity', 0)
.remove();
}

View File

@@ -9,8 +9,8 @@ iD.ui.save = function() {
tooltip = bootstrap.tooltip()
.placement('bottom');
selection.html("<span class='label'>Save</span><small id='as-username'></small>")
.attr('title', 'Save changes to OpenStreetMap, making them visible to other users')
selection.html("<span class='label'>" + t('save') + "</span><small id='as-username'></small>")
.attr('title', t('save_help'))
.attr('tabindex', -1)
.property('disabled', true)
.call(tooltip)
@@ -18,7 +18,7 @@ iD.ui.save = function() {
function commit(e) {
d3.select('.shaded').remove();
var l = iD.ui.loading('Uploading changes to OpenStreetMap.', true);
var l = iD.ui.loading(t('uploading_changes'), true);
connection.putChangeset(history.changes(), e.comment, history.imagery_used(), function(err, changeset_id) {
l.remove();
history.reset();
@@ -27,7 +27,7 @@ iD.ui.save = function() {
var desc = iD.ui.confirm()
.select('.description');
desc.append('h2')
.text('An error occurred while trying to save');
.text(t('save_error'));
desc.append('p').text(err.responseText);
} else {
var modal = iD.ui.modal();
@@ -37,7 +37,7 @@ iD.ui.save = function() {
id: changeset_id,
comment: e.comment
})
.call(iD.ui.success()
.call(iD.ui.success(connection)
.on('cancel', function() {
modal.remove();
}));
@@ -67,7 +67,7 @@ iD.ui.save = function() {
});
} else {
iD.ui.confirm().select('.description')
.append('h3').text('You don\'t have any changes to save.');
.append('h3').text(t('no_changes'));
}
});

View File

@@ -1,4 +1,4 @@
iD.ui.success = function() {
iD.ui.success = function(connection) {
var event = d3.dispatch('cancel', 'save');
function success(selection) {
@@ -8,23 +8,32 @@ iD.ui.success = function() {
var section = body.append('div').attr('class','modal-section fillD');
header.append('h2').text('You Just Edited OpenStreetMap!');
header.append('p').text('You just improved the world\'s best free map');
header.append('h2').text(t('just_edited'));
var m = '';
if (changeset.comment) {
m = '"' + changeset.comment.substring(0, 20) + '" ';
}
var message = 'Edited OpenStreetMap! ' + m +
'http://osm.org/browse/changeset/' + changeset.id;
var message = (m || 'Edited OSM!') +
connection.changesetUrl(changeset.id);
section.append('a')
header.append('a')
.attr('href', function(d) {
return connection.changesetUrl(changeset.id);
})
.attr('target', '_blank')
.attr('class', 'success-action')
.text(t('view_on_osm'));
header.append('a')
.attr('target', '_blank')
.attr('href', function(d) {
return 'https://twitter.com/intent/tweet?source=webclient&text=' +
encodeURIComponent(message);
})
.text('Tweet: ' + message);
.attr('class', 'success-action')
.text('Tweet');
var buttonwrap = section.append('div')
.attr('class', 'buttons cf');

View File

@@ -24,7 +24,7 @@ iD.ui.tagReference = function(selection) {
referenceBody
.append('h5')
.text('Description');
.text(t('description'));
if (selection.datum().image) {
referenceBody

View File

@@ -18,7 +18,7 @@ iD.ui.userpanel = function(connection) {
// Add thumbnail or dont
if (user_details.image_url) {
userLink.append('img')
.attr('class', 'icon icon-pre-text')
.attr('class', 'icon icon-pre-text user-icon')
.attr('src', user_details.image_url);
} else {
userLink.append('span')
@@ -34,7 +34,7 @@ iD.ui.userpanel = function(connection) {
.append('a')
.attr('class', 'logout')
.attr('href', '#')
.text('logout')
.text(t('logout'))
.on('click.logout', function() {
d3.event.preventDefault();
event.logout();

View File

@@ -32,7 +32,7 @@ d3.tail = function() {
function mousemove() {
if (text === false) return;
var xoffset = ((d3.event.x + tooltip_size[0] + xmargin) > selection_size[0]) ?
-tooltip_size[0] - xmargin : xoffset = xmargin;
-tooltip_size[0] - xmargin : xmargin;
container.style(transformProp, 'translate(' +
(~~d3.event.x + xoffset) + 'px,' +
~~d3.event.y + 'px)');

40
locale/en.js Normal file
View File

@@ -0,0 +1,40 @@
locale.en = {
"browse": "Browse",
"point": "Point",
"line": "Line",
"area": "Area",
"save": "Save",
"save_help": "Save changes to OpenStreetMap, making them visible to other users",
"no_changes": "You don't have any changes to save.",
"save_error": "An error occurred while trying to save",
"uploading_changes": "Uploading changes to OpenStreetMap.",
"just_edited": "You Just Edited OpenStreetMap!",
"okay": "Okay",
"zoom-in": "Zoom In",
"zoom-out": "Zoom Out",
"browser_notice": "This editor is supported in Firefox, Chrome, Safari, Opera, and Internet Explorer 9 and above. Please upgrade your browser or use Potlatch 2 to edit the map.",
"layer_settings": "Layer Settings",
"no_documentation_combination": "This is no documentation available for this tag combination",
"no_documentation_key": "This is no documentation available for this key",
"view_on_osm": "View on OSM",
"zoom_in_edit": "zoom in to edit the map",
"edit_tags": "Edit tags",
"find_location": "Find A Location",
"find_placeholder": "find a place",
"description": "Description",
"logout": "logout",
"layers": "Layers",
"percent_opacity": "{opacity}% opacity"
}

11
locale/locale.js Normal file
View File

@@ -0,0 +1,11 @@
var locale = { current: 'en' };
function t(s, o) {
if (locale[locale.current][s] !== undefined) {
var rep = locale[locale.current][s];
if (o) for (var k in o) rep = rep.replace('{' + k + '}', o[k]);
return rep;
} else {
if (console) console.error('key ' + s + ' not found');
}
}

View File

@@ -68,10 +68,12 @@
<script src='../js/id/ui/confirm.js'></script>
<script src='../js/id/actions.js'></script>
<script src="../js/id/actions/add_midpoint.js"></script>
<script src='../js/id/actions/add_node.js'></script>
<script src='../js/id/actions/add_way.js'></script>
<script src='../js/id/actions/add_way_node.js'></script>
<script src='../js/id/actions/change_entity_tags.js'></script>
<script src='../js/id/actions/circularize.js'></script>
<script src="../js/id/actions/delete_node.js"></script>
<script src="../js/id/actions/delete_way.js"></script>
<script src='../js/id/actions/move_node.js'></script>
@@ -86,7 +88,6 @@
<script src='../js/id/behavior/drag.js'></script>
<script src='../js/id/behavior/drag_midpoint.js'></script>
<script src='../js/id/behavior/drag_node.js'></script>
<script src='../js/id/behavior/drag_way.js'></script>
<script src='../js/id/behavior/draw.js'></script>
<script src='../js/id/behavior/draw_way.js'></script>
<script src='../js/id/behavior/hover.js'></script>
@@ -98,8 +99,17 @@
<script src='../js/id/modes/browse.js'></script>
<script src='../js/id/modes/draw_area.js'></script>
<script src='../js/id/modes/draw_line.js'></script>
<script src='../js/id/modes/move_way.js'></script>
<script src='../js/id/modes/select.js'></script>
<script src='../js/id/operations.js'></script>
<script src='../js/id/operations/circularize.js'></script>
<script src='../js/id/operations/delete.js'></script>
<script src='../js/id/operations/move.js'></script>
<script src='../js/id/operations/reverse.js'></script>
<script src='../js/id/operations/split.js'></script>
<script src='../js/id/operations/unjoin.js'></script>
<script src='../js/id/controller/controller.js'></script>
<script src='../js/id/graph/entity.js'></script>
@@ -111,6 +121,9 @@
<script src='../js/id/connection.js'></script>
<script src='../locale/locale.js'></script>
<script src='../locale/en.js'></script>
<script>
iD.debug = true;
mocha.setup({
@@ -125,6 +138,7 @@
<!-- include spec files here... -->
<script src="spec/lib/d3.keybinding.js"></script>
<script src="spec/actions/add_midpoint.js"></script>
<script src="spec/actions/add_node.js"></script>
<script src="spec/actions/add_way.js"></script>
<script src="spec/actions/change_entity_tags.js"></script>
@@ -158,6 +172,7 @@
<script src="spec/svg/areas.js"></script>
<script src="spec/svg/lines.js"></script>
<script src="spec/svg/member_classes.js"></script>
<script src="spec/svg/midpoints.js"></script>
<script src="spec/svg/multipolygons.js"></script>
<script src="spec/svg/points.js"></script>
<script src="spec/svg/vertices.js"></script>

View File

@@ -32,9 +32,9 @@
<!-- include spec files here... -->
<script src="spec/lib/d3.keybinding.js"></script>
<script src="spec/actions/add_midpoint.js"></script>
<script src="spec/actions/add_node.js"></script>
<script src="spec/actions/add_way.js"></script>
<script src="spec/actions/add_way_node.js"></script>
<script src="spec/actions/change_entity_tags.js"></script>
<script src="spec/actions/delete_node.js"></script>
<script src="spec/actions/delete_way.js"></script>
@@ -66,6 +66,7 @@
<script src="spec/svg/areas.js"></script>
<script src="spec/svg/lines.js"></script>
<script src="spec/svg/member_classes.js"></script>
<script src="spec/svg/midpoints.js"></script>
<script src="spec/svg/multipolygons.js"></script>
<script src="spec/svg/points.js"></script>
<script src="spec/svg/vertices.js"></script>

View File

@@ -34,6 +34,20 @@
<script src='../js/id/graph/relation.js'></script>
<script src='../js/id/graph/way.js'></script>
<form style="position: fixed; right: 10px; bottom: 10px">
<input id="background-color" type="range" min="0" max="255" value="255">
<label for="background-color">Background Color</label>
</form>
<script>
var bg = d3.select("#background-color")
.on("change", function () {
var v = bg.property("value");
d3.select("body")
.style("background-color", d3.rgb(v,v,v));
});
</script>
<table>
<thead>
<tr><th></th><th colspan="3">z16</th><th colspan="3">z17</th></tr>
@@ -105,6 +119,7 @@
})
.enter()
.append('td')
.attr('class', function (d) { return d.mode === 'selected' ? 'mode-select' : 'mode-browse'; })
.append('svg')
.attr('width', 200)
.attr('height', 30)
@@ -115,7 +130,7 @@
graph = iD.Graph([a, b, highway]);
d3.select(this)
.attr('class', d.mode === 'selected' ? 'mode-select' : 'mode-browse')
.attr('class', 'behavior-hover')
.call(vertices, graph, [a, b], filter)
.call(lines, graph, [highway], filter)
.call(midpoints, graph, [highway], filter)
@@ -123,5 +138,67 @@
.classed(d.mode, d.mode !== 'base');
});
</script>
<table>
<thead>
<tr><th></th><th>Base</th><th>Selected</th></tr>
</thead>
<tbody class="areas">
</tbody>
</table>
<script>
var modes = ['base', 'selected'],
tags = [
{area: 'yes'},
{natural: 'yes'},
{natural: 'water'},
{natural: 'wood'},
{building: 'yes'},
{amenity: 'parking'}
];
var row = d3.select('.areas').selectAll('tr')
.data(tags)
.enter().append('tr');
row.append('th')
.html(function (d) { return _.map(d, function (value, key) { return key + "=" + value;}).join("<br>"); });
var a = iD.Node({loc: [15, 15]}),
b = iD.Node({loc: [85, 15]}),
c = iD.Node({loc: [85, 85]}),
d = iD.Node({loc: [15, 85]}),
way = iD.Way({nodes: [a.id, b.id, c.id, d.id, a.id]}),
vertices = iD.svg.Vertices(projection),
areas = iD.svg.Areas(projection),
midpoints = iD.svg.Midpoints(projection);
row.selectAll('td')
.data(function (d) {
return modes.map(function (m) {
return { mode: m, tags: d };
});
})
.enter()
.append('td')
.append('svg')
.attr('width', 100)
.attr('height', 100)
.call(iD.svg.Surface())
.each(function (datum) {
var area = way.update({tags: datum.tags}),
graph = iD.Graph([a, b, c, d, area]);
d3.select(this)
.attr('class', datum.mode === 'selected' ? 'mode-select' : 'mode-browse')
.call(vertices, graph, [a, b, c, d], filter)
.call(areas, graph, [area], filter)
.call(midpoints, graph, [area], filter)
.selectAll('.area')
.classed(datum.mode, datum.mode !== 'base');
});
</script>
</body>
</html>

View File

@@ -0,0 +1,22 @@
describe("iD.actions.AddMidpoint", function () {
it("adds the node at the midpoint location", function () {
var node = iD.Node(),
midpoint = {loc: [1, 2], ways: []},
graph = iD.actions.AddMidpoint(midpoint, node)(iD.Graph());
expect(graph.entity(node.id).loc).to.eql([1, 2]);
});
it("adds the node to all ways at the respective indexes", function () {
var node = iD.Node(),
a = iD.Node(),
b = iD.Node(),
w1 = iD.Way(),
w2 = iD.Way({nodes: [a.id, b.id]}),
midpoint = {loc: [1, 2], ways: [{id: w1.id, index: 0}, {id: w2.id, index: 1}]},
graph = iD.actions.AddMidpoint(midpoint, node)(iD.Graph([a, b, w1, w2]));
expect(graph.entity(w1.id).nodes).to.eql([node.id]);
expect(graph.entity(w2.id).nodes).to.eql([a.id, node.id, b.id]);
});
});

View File

@@ -9,8 +9,23 @@ describe("iD.behavior.Hover", function() {
container.remove();
});
describe("#on", function () {
it("adds the .behavior-hover class to the selection", function () {
container.call(iD.behavior.Hover());
expect(container).to.be.classed('behavior-hover')
});
});
describe("#off", function () {
it("removes the .behavior-hover class from the selection", function () {
container.classed('behavior-hover', true);
container.call(iD.behavior.Hover().off);
expect(container).not.to.be.classed('behavior-hover')
});
});
describe("mouseover", function () {
it("adds the 'hover' class to all elements to which the same datum is bound", function () {
it("adds the .hover class to all elements to which the same datum is bound", function () {
container.selectAll('span')
.data(['a', 'b', 'a', 'b'])
.enter().append('span').attr('class', Object);
@@ -24,7 +39,7 @@ describe("iD.behavior.Hover", function() {
});
describe("mouseout", function () {
it("removes the 'hover' class from all elements", function () {
it("removes the .hover class from all elements", function () {
container.append('span').attr('class', 'hover');
container.call(iD.behavior.Hover());

View File

@@ -0,0 +1,52 @@
describe("iD.svg.Midpoints", function () {
var surface,
projection = Object,
filter = d3.functor(true);
beforeEach(function () {
surface = d3.select(document.createElementNS('http://www.w3.org/2000/svg', 'svg'))
.call(iD.svg.Surface());
});
it("finds the location of the midpoints", function () {
var a = iD.Node({loc: [0, 0]}),
b = iD.Node({loc: [50, 0]}),
line = iD.Way({nodes: [a.id, b.id]}),
graph = iD.Graph([a, b, line]);
surface.call(iD.svg.Midpoints(projection), graph, [line], filter);
expect(surface.select('.midpoint').datum().loc).to.eql([25, 0]);
});
it("doesn't create midpoints on segments with pixel length less than 40", function () {
var a = iD.Node({loc: [0, 0]}),
b = iD.Node({loc: [39, 0]}),
line = iD.Way({nodes: [a.id, b.id]}),
graph = iD.Graph([a, b, line]);
surface.call(iD.svg.Midpoints(projection), graph, [line], filter);
expect(surface.selectAll('.midpoint')[0]).to.have.length(0);
});
it("binds a datum whose 'ways' property lists ways which include the segement", function () {
var a = iD.Node({loc: [0, 0]}),
b = iD.Node({loc: [50, 0]}),
c = iD.Node({loc: [1, 1]}),
d = iD.Node({loc: [2, 2]}),
l1 = iD.Way({nodes: [a.id, b.id]}),
l2 = iD.Way({nodes: [b.id, a.id]}),
l3 = iD.Way({nodes: [c.id, a.id, b.id, d.id]}),
l4 = iD.Way({nodes: [a.id, d.id, b.id]}),
graph = iD.Graph([a, b, c, d, l1, l2, l3, l4]),
ab = function (d) { return d.id === [a.id, b.id].sort().join("-"); };
surface.call(iD.svg.Midpoints(projection), graph, [l1, l2, l3, l4], filter);
expect(surface.selectAll('.midpoint').filter(ab).datum().ways).to.eql([
{id: l1.id, index: 1},
{id: l2.id, index: 1},
{id: l3.id, index: 2}]);
});
});