Initial migration of the Workspace to bnd

Change-Id: I2f9378c44ce017a75edd18d6ef0992104d7f8e2f
Signed-off-by: Jürgen Albert <j.albert@data-in-motion.biz>
diff --git a/bnd/.gitattributes b/bnd/.gitattributes
new file mode 100644
index 0000000..b21186b
--- /dev/null
+++ b/bnd/.gitattributes
@@ -0,0 +1,75 @@
+# Text files with LF eol
+*.auth crlf=input
+*.awk crlf=input
+*.bnd crlf=input
+*.bndrun crlf=input
+*.c crlf=input ident
+*.conf crlf=input
+*.cpp crlf=input ident
+*.css crlf=input
+*.ddf crlf=input
+*.ee crlf=input
+*.gradle crlf=input
+*.groovy crlf=input
+*.h crlf=input ident
+*.html crlf=input ident
+*.java crlf=input ident
+*.js crlf=input
+*.lib crlf=input
+*.md crlf=input
+*.MF crlf=input
+*.mf crlf=input
+*.perm crlf=input
+*.php crlf=input
+*.pl crlf=input
+*.pom crlf=input
+*.prefs crlf=input
+*.properties crlf=input
+*.py crlf=input
+*.schema crlf=input
+*.SF crlf=input
+*.sh crlf=input
+*.tcl crlf=input
+*.txt crlf=input
+*.xml crlf=input
+*.xsd crlf=input ident
+*.xsl crlf=input
+*.xslt crlf=input
+*.yml crlf=input
+.classpath crlf=input
+.project crlf=input
+gradlew crlf=input
+packageinfo crlf=input
+Makefile crlf=input
+README crlf=input
+LICENSE crlf=input
+
+# No EOL translation
+*.bat -crlf
+
+# Binary. No EOL translation, no diff
+*.ico binary
+*.jpeg binary
+*.jpg binary
+*.png binary
+*.crt binary
+*.pdf binary
+*.dll binary
+*.jar binary
+*.jnilib binary
+*.so binary
+*.zip binary
+*.doc binary
+*.ppt binary
+*.xls binary
+*.odg binary
+*.odp binary
+*.ods binary
+*.odt binary
+*.otg binary
+*.otp binary
+*.ots binary
+*.ott binary
+*.key binary
+*.numbers binary
+*.pages binary
diff --git a/bnd/.github/workflows/build.yml b/bnd/.github/workflows/build.yml
new file mode 100644
index 0000000..9ab3712
--- /dev/null
+++ b/bnd/.github/workflows/build.yml
@@ -0,0 +1,26 @@
+name: CI Build
+  
+on: 
+    push:
+    pull_request:
+
+env:
+    LC_ALL:       en_US.UTF-8
+    GRADLE_OPTS: -Dorg.gradle.parallel=false
+
+jobs:
+    build:
+        name:     build on OpenJDK Linux
+        runs-on:  ubuntu-latest
+        steps:
+        -   name: Git Checkout
+            uses: actions/checkout@v1
+        -   name: Gradle Wrapper Validation
+            uses: gradle/wrapper-validation-action@v1
+        -   name: Set up Java
+            uses: actions/setup-java@v1
+            with: 
+                java-version: 1.8
+        -   name: Build
+            shell: bash
+            run: ./gradlew build
diff --git a/bnd/.gitignore b/bnd/.gitignore
new file mode 100644
index 0000000..1de799b
--- /dev/null
+++ b/bnd/.gitignore
@@ -0,0 +1,4 @@
+.DS_Store
+.gradle/
+/generated/
+.metadata
diff --git a/bnd/.gradle-wrapper/gradle-wrapper.jar b/bnd/.gradle-wrapper/gradle-wrapper.jar
new file mode 100644
index 0000000..f3d88b1
--- /dev/null
+++ b/bnd/.gradle-wrapper/gradle-wrapper.jar
Binary files differ
diff --git a/bnd/.gradle-wrapper/gradle-wrapper.properties b/bnd/.gradle-wrapper/gradle-wrapper.properties
new file mode 100644
index 0000000..1b16c34
--- /dev/null
+++ b/bnd/.gradle-wrapper/gradle-wrapper.properties
@@ -0,0 +1,5 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-6.1.1-bin.zip
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists
diff --git a/bnd/.project b/bnd/.project
new file mode 100644
index 0000000..465c8a3
--- /dev/null
+++ b/bnd/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>bnd</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+	</buildSpec>
+	<natures>
+	</natures>
+</projectDescription>
diff --git a/bnd/README.MD b/bnd/README.MD
new file mode 100644
index 0000000..f386f05
--- /dev/null
+++ b/bnd/README.MD
@@ -0,0 +1,3 @@
+# This is an example README.MD 
+
+Your text here!
\ No newline at end of file
diff --git a/bnd/build.gradle b/bnd/build.gradle
new file mode 100644
index 0000000..653b3e3
--- /dev/null
+++ b/bnd/build.gradle
@@ -0,0 +1,4 @@
+// Available to customize the build
+tasks.named('wrapper') {
+  jarFile = rootProject.file('.gradle-wrapper/gradle-wrapper.jar')
+}
diff --git a/bnd/cnf/.gitignore b/bnd/cnf/.gitignore
new file mode 100644
index 0000000..0a2101f
--- /dev/null
+++ b/bnd/cnf/.gitignore
@@ -0,0 +1 @@
+/cache/
diff --git a/bnd/cnf/.project b/bnd/cnf/.project
new file mode 100644
index 0000000..1397bbe
--- /dev/null
+++ b/bnd/cnf/.project
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>cnf</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+	</buildSpec>
+	<natures>
+	</natures>
+</projectDescription>
diff --git a/bnd/cnf/build.bnd b/bnd/cnf/build.bnd
new file mode 100644
index 0000000..66bd62a
--- /dev/null
+++ b/bnd/cnf/build.bnd
@@ -0,0 +1 @@
+ ## Place your settings in ext/.
diff --git a/bnd/cnf/ext/central.maven b/bnd/cnf/ext/central.maven
new file mode 100644
index 0000000..99e8805
--- /dev/null
+++ b/bnd/cnf/ext/central.maven
@@ -0,0 +1,45 @@
+
+org.apache.felix:org.apache.felix.configurator:1.0.8
+org.apache.felix:org.apache.felix.configadmin:1.9.10
+org.apache.felix:org.apache.felix.coordinator:1.0.2
+org.apache.felix:org.apache.felix.fileinstall:3.6.4
+org.apache.felix:org.apache.felix.framework:6.0.1
+org.apache.felix:org.apache.felix.gogo.command:1.0.2
+org.apache.felix:org.apache.felix.gogo.runtime:1.1.0
+org.apache.felix:org.apache.felix.gogo.shell:1.1.0
+org.apache.felix:org.apache.felix.http.servlet-api:1.1.2
+
+org.apache.felix:org.apache.felix.log:1.2.0
+org.apache.felix:org.apache.felix.logback:1.0.0
+org.apache.felix:org.apache.felix.metatype:1.2.2
+org.apache.felix:org.apache.felix.prefs:1.1.0
+org.apache.felix:org.apache.felix.webconsole:jar:all:4.3.4
+org.apache.felix:org.apache.felix.webconsole.plugins.ds:2.0.8
+org.apache.servicemix.bundles:org.apache.servicemix.bundles.junit:4.12_1
+
+ch.qos.logback:logback-classic:1.2.3
+ch.qos.logback:logback-core:1.2.3
+org.slf4j:jul-to-slf4j:1.7.25
+org.slf4j:log4j-over-slf4j:1.7.25
+org.slf4j:osgi-over-slf4j:1.7.25
+org.slf4j:slf4j-api:1.7.25
+org.slf4j:slf4j-ext:1.7.25
+org.slf4j:slf4j-jcl:1.7.25
+
+org.osgi:osgi.annotation:7.0.0
+org.osgi:osgi.cmpn:7.0.0
+org.osgi:osgi.core:7.0.0
+org.osgi:org.osgi.util.pushstream:1.0.0
+org.osgi:org.osgi.util.function:1.1.0
+org.osgi:org.osgi.util.promise:1.1.0
+
+org.bndtools:org.bndtools.templates.osgi:5.0.1
+
+org.hamcrest:hamcrest-core:1.3
+org.mockito:mockito-core:1.10.19
+
+javax.xml.bind:jaxb-api:jar:2.3.1
+javax.annotation:javax.annotation-api:jar:1.3.2
+org.apache.servicemix.specs:org.apache.servicemix.specs.annotation-api-1.3:jar:1.3_1
+
+org.eclipse.jdt:org.eclipse.jdt.debug:3.15.100
diff --git a/bnd/cnf/ext/defaults.bnd b/bnd/cnf/ext/defaults.bnd
new file mode 100644
index 0000000..b51824c
--- /dev/null
+++ b/bnd/cnf/ext/defaults.bnd
@@ -0,0 +1,49 @@
+java: java
+javac: javac
+javac.source: 1.8
+javac.target: 1.8
+javac.debug:  on
+
+#Bundle-DocURL: https://yourdoc.de
+Bundle-License: Eclipse Public License 1.0
+Bundle-Vendor: CEA LETI
+
+#if you want bnd to tell you more during the build
+#-verbose: true
+
+# Includes sources from bundle
+-sources: true
+
+-includeresource.license: \
+	${workspace}/cnf/license/about.html
+
+		
+-removeheaders: Bnd-LastModified, Tool, Created-By
+
+# String to substitute for "SNAPSHOT" in the bundle version's qualifier.
+#-snapshot: ${tstamp}
+-releaserepo: Release
+
+# Enable semantic versioning for all bundles
+-baselinerepo: Release
+-baseline: *
+
+-maven-release: pom
+
+# Provide a useful group-id
+-groupid: org.eclipse.sensinact.studio
+
+# Ignore files for baselining
+-diffignore: *.xml,\
+    */pom.properties,\
+     OSGI-OPT/*
+
+# define global blacklist
+-runblacklist.default: osgi.identity;filter:='(osgi.identity=osgi.cmpn)'
+
+-resolve.effective: active
+#-resolve.effective: active;skip:="osgi.service"
+
+# > Java 8 runtime
+#modules: --add-opens=java.base/jdk.internal.loader=ALL-UNNAMED, --add-opens=java.base/java.lang=ALL-UNNAMED, --add-opens=java.base/java.net=ALL-UNNAMED, --add-opens=java.base/java.security=ALL-UNNAMED
+#-runvm.default: ${if;${isempty;${system_allow_fail;java --list-modules}};;${modules}}
\ No newline at end of file
diff --git a/bnd/cnf/ext/dim_release.maven b/bnd/cnf/ext/dim_release.maven
new file mode 100644
index 0000000..72f3f14
--- /dev/null
+++ b/bnd/cnf/ext/dim_release.maven
@@ -0,0 +1,34 @@
+com.ibm:com.ibm.icu:64.2.0.v20190507-1337
+lpg.runtime:lpg.runtime.java:2.0.17.v201004271640
+
+org.eclipse.emf:org.eclipse.emf.ecore:2.19.0.v20190822-1451
+org.eclipse.emf:org.eclipse.emf.ecore.change:2.14.0.v20190528-0725
+org.eclipse.emf:org.eclipse.emf.ecore.xmi:2.16.0.v20190528-0725
+org.eclipse.emf:org.eclipse.emf.common:2.16.0.v20190625-1131
+org.eclipse.emf:org.eclipse.emf.compare:3.5.3.201909101346
+
+org.eclipse.ocl:org.eclipse.ocl:3.10.400.201911041049
+org.eclipse.ocl:org.eclipse.ocl.common:1.8.400.v20190910-0937
+org.eclipse.ocl:org.eclipse.ocl.ecore:3.14.0.v20190910-0937
+
+org.eclipse.m2m:org.eclipse.m2m.qvt.oml.common:3.9.0.v20190909-1952
+org.eclipse.m2m:org.eclipse.m2m.qvt.oml.cst.parser:3.9.0.v20190909-1952
+org.eclipse.m2m:org.eclipse.m2m.qvt.oml.ecore.imperativeocl:3.9.0.v20190909-1952
+org.eclipse.m2m:org.eclipse.m2m.qvt.oml.ocl:3.9.0.v20190909-1952
+org.eclipse.m2m:org.eclipse.m2m.qvt.oml:3.10.0.201911041036
+org.eclipse.m2m:org.eclipse.m2m.qvt.oml.emf.util:3.9.0.201911041041
+
+org.eclipse.equinox:org.eclipse.equinox.preferences:3.7.500.v20190815-1535
+
+org.gecko.emf.addons:org.gecko.qvt.osgi.api:4.1.0
+org.gecko.emf.addons:org.gecko.qvt.osgi.component:1.0.5
+org.gecko.core:org.gecko.core.pool:1.1.0
+
+
+org.gecko.core:org.gecko.core.test:2.0.2
+
+org.gecko.emf.repository:org.gecko.emf.repository.api:9.2.2
+org.gecko.emf.repository:org.gecko.emf.repository.mongo:3.1.0
+org.gecko.emf.addons:org.gecko.emf.osgi.compare.api:1.1.1
+org.gecko.emf.addons:org.gecko.emf.osgi.compare.component:1.0.3
+
diff --git a/bnd/cnf/ext/project.maven b/bnd/cnf/ext/project.maven
new file mode 100644
index 0000000..0c19378
--- /dev/null
+++ b/bnd/cnf/ext/project.maven
@@ -0,0 +1,26 @@
+com.google.inject:guice:3.0
+com.fasterxml.jackson.core:jackson-annotations:2.10.3
+com.fasterxml.jackson.core:jackson-databind:2.10.3
+com.fasterxml.jackson.core:jackson-core:2.10.3
+com.fasterxml.jackson.dataformat:jackson-dataformat-csv:2.1.0
+com.fasterxml.jackson.dataformat:jackson-dataformat-smile:2.1.0
+com.fasterxml.jackson.dataformat:jackson-dataformat-xml:2.1.0
+com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.1.0
+com.fasterxml.jackson.module:jackson-module-jaxb-annotations:2.1.0
+
+org.restlet.osgi:org.restlet:2.2.3
+org.restlet.osgi:org.restlet.ext.json:2.2.3
+org.restlet.osgi:org.restlet.ext.jackson:2.2.3
+org.yaml:snakeyaml:1.14
+org.codehaus.woodstox:stax2-api:3.1.3
+org.json:json:20210307
+
+org.eclipse.jetty:jetty-server:9.4.15.v20190215
+org.eclipse.jetty:jetty-http:9.4.15.v20190215
+org.eclipse.jetty:jetty-io:9.4.15.v20190215
+org.eclipse.jetty:jetty-xml:9.4.15.v20190215
+org.eclipse.jetty:jetty-util:9.4.15.v20190215
+org.eclipse.jetty:jetty-client:9.4.15.v20190215
+org.eclipse.jetty.websocket:websocket-common:9.4.15.v20190215
+org.eclipse.jetty.websocket:websocket-client:9.4.15.v20190215
+org.eclipse.jetty.websocket:websocket-api:9.4.15.v20190215
diff --git a/bnd/cnf/ext/repo_common.bnd b/bnd/cnf/ext/repo_common.bnd
new file mode 100644
index 0000000..b3cc473
--- /dev/null
+++ b/bnd/cnf/ext/repo_common.bnd
@@ -0,0 +1,23 @@
+-include: ${if;${def;release.dir};\
+              ${workspace}/cnf/releng/release.bnd;\
+              ${workspace}/cnf/releng/snapshot.bnd\
+          }
+
+# Configure Repositories
+-plugin.Central: \
+	aQute.bnd.repository.maven.provider.MavenBndRepository; \
+		releaseUrl=https://repo.maven.apache.org/maven2/; \
+		index=${workspace}/cnf/ext/central.maven; \
+		name="Maven Central"
+
+-plugin.Local: \
+	aQute.bnd.deployer.repository.LocalIndexedRepo; \
+		name = Local; \
+		pretty = true; \
+		local = ${workspace}/cnf/local
+
+-plugin.Temp: \
+	aQute.bnd.deployer.repository.LocalIndexedRepo; \
+		name = Temp; \
+		pretty = true; \
+		local = ${workspace}/cnf/cache/temp
\ No newline at end of file
diff --git a/bnd/cnf/ext/repo_gecko.bnd b/bnd/cnf/ext/repo_gecko.bnd
new file mode 100644
index 0000000..c742174
--- /dev/null
+++ b/bnd/cnf/ext/repo_gecko.bnd
@@ -0,0 +1,21 @@
+#-plugin.gecko: \
+#	aQute.bnd.repository.maven.provider.MavenBndRepository;\
+#		releaseUrl=https://devel.data-in-motion.biz/nexus/repository/dim-release/;\
+#		snapshotUrl=https://devel.data-in-motion.biz/nexus/repository/dim-snapshot/;\
+#		index=${.}/dim_release.maven;\
+#		name='DIM_Release',\
+#	aQute.bnd.repository.maven.provider.MavenBndRepository;\
+#		releaseUrl=https://devel.data-in-motion.biz/nexus/repository/maven-public/;\
+#		index=${.}/dim_nexus.maven;\
+#		name='DIM_Nexus'
+
+-plugin.geckorcp:\
+	aQute.bnd.repository.maven.pom.provider.BndPomRepository;\
+        name="Gecko Equinox RCP";\
+        releaseUrls="https://devel.data-in-motion.biz/nexus/repository/dim-release/,https://repo.maven.apache.org/maven2/";\
+        snapshotUrls=https://devel.data-in-motion.biz/nexus/repository/dim-snapshot/;\
+        revision="org.geckoprojects.equinox:org.gecko.bnd.eclipse.bom:1.1.1"
+        
+-include: \
+	https://gitlab.com/gecko.io/geckoEMF/-/raw/master/cnf/geckoEMF/geckoEMF.bnd,\
+	https://gitlab.com/gecko.io/geckoBndTemplates/-/raw/develop/cnf/common/slf4j.bnd
\ No newline at end of file
diff --git a/bnd/cnf/ext/repo_project.bnd b/bnd/cnf/ext/repo_project.bnd
new file mode 100644
index 0000000..a83b27a
--- /dev/null
+++ b/bnd/cnf/ext/repo_project.bnd
@@ -0,0 +1,46 @@
+-plugin.project: \
+	aQute.bnd.repository.maven.provider.MavenBndRepository; \
+		releaseUrl='https://repo.maven.apache.org/maven2/,https://maven.restlet.talend.com/'; \
+		index=${.}/project.maven; \
+		name="Project Specific Maven Central"
+
+#-plugin.eclipse.2019.09: \
+#		aQute.bnd.repository.osgi.OSGiRepository;\
+#		name=Eclipse_2020.06;\
+#		locations=file:///c:/Users/ungei/.p2/test/pool/plugins/index.xml
+		
+-plugin.Eclipse:\
+    aQute.bnd.repository.osgi.OSGiRepository;\
+        name="Eclipse 2020-06";\
+        locations="https://bndtools.jfrog.io/bndtools/bnd-build/eclipse/4.16/index.xml.gz";\
+        poll.time=-1;\
+        cache="${workspace}/cnf/cache/stable/Eclipse-2020-06"
+
+#eclipse.importpackage: \
+# org.eclipse.*;bundle-symbolic-name="${@bundlesymbolicname}";bundle-version="${range;[==,+);${@bundleversion}}";version=!;ui.workbench=!;common=!;registry=!;texteditor=!;text=!
+
+-plugin.xtext: aQute.bnd.repository.p2.provider.P2Repository;\
+		location			= ${workspace}/cnf/cache/xtext;\
+		name                ='XText P2 2.22';\
+		url                 ='https://download.eclipse.org/modeling/tmf/xtext/updates/releases/2.22.0/'
+
+-plugin.mwq: aQute.bnd.repository.p2.provider.P2Repository;\
+		location			= ${workspace}/cnf/cache/mwe;\
+		name                ='MWE P2 2.11';\
+		url                 ='https://download.eclipse.org/modeling/emft/mwe/updates/releases/2.11.3/'
+
+-plugin.xpand: aQute.bnd.repository.p2.provider.P2Repository;\
+		location			= ${workspace}/cnf/cache/xpand;\
+		name                ='XPand P2 2.2.0';\
+		url                 ='https://download.eclipse.org/modeling/m2t/xpand/updates/releases/R201605260315/'
+
+-plugin.nebula: aQute.bnd.repository.p2.provider.P2Repository;\
+		location			= ${workspace}/cnf/cache/nebula;\
+		name                ='Nebula P2 1.1.0';\
+		url                 ='https://download.eclipse.org/nebula/releases/1.1.0'
+
+-plugin.misc: aQute.bnd.repository.p2.provider.P2Repository;\
+		location			= ${workspace}/cnf/cache/misc;\
+		name                ='Misc P2 1.1.0';\
+		url                 ='${fileuri;${workspace}/cnf/p2/targetPlatform.target}'
+
diff --git a/bnd/cnf/jdt.bnd b/bnd/cnf/jdt.bnd
new file mode 100644
index 0000000..3343071
--- /dev/null
+++ b/bnd/cnf/jdt.bnd
@@ -0,0 +1,4 @@
+-include: ${project}/.settings/org.eclipse.jdt.core.prefs
+javac.source 			= ${org.eclipse.jdt.core.compiler.source}
+javac.target 			= ${org.eclipse.jdt.core.compiler.codegen.targetPlatform}
+javac.compliance 		= ${org.eclipse.jdt.core.compiler.compliance}
diff --git a/bnd/cnf/license/about.html b/bnd/cnf/license/about.html
new file mode 100644
index 0000000..3b39f88
--- /dev/null
+++ b/bnd/cnf/license/about.html
@@ -0,0 +1,26 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml"><head>
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+<title>About</title>
+</head>
+<body lang="EN-US">
+<h2>About This Content</h2>
+ 
+<p>June 5, 2006</p>	
+<h3>License</h3>
+
+<p>The Eclipse Foundation makes available all content in this plug-in ("Content").  Unless otherwise 
+indicated below, the Content is provided to you under the terms and conditions of the
+Eclipse Public License Version 1.0 ("EPL").  A copy of the EPL is available 
+at <a href="http://www.eclipse.org/legal/epl-v10.html">http://www.eclipse.org/legal/epl-v10.html</a>.
+For purposes of the EPL, "Program" will mean the Content.</p>
+
+<p>If you did not receive this Content directly from the Eclipse Foundation, the Content is 
+being redistributed by another party ("Redistributor") and different terms and conditions may
+apply to your use of any object code in the Content.  Check the Redistributor's license that was 
+provided with the Content.  If no such license exists, contact the Redistributor.  Unless otherwise
+indicated below, the terms and conditions of the EPL still apply to any source code in the Content
+and such source code may be obtained at <a href="http://www.eclipse.org/">http://www.eclipse.org</a>.</p>
+
+
+</body></html>
\ No newline at end of file
diff --git a/bnd/cnf/local/index.xml b/bnd/cnf/local/index.xml
new file mode 100644
index 0000000..268fa9b
--- /dev/null
+++ b/bnd/cnf/local/index.xml
@@ -0,0 +1,2 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<repository xmlns="http://www.osgi.org/xmlns/repository/v1.0.0" name="Local" increment="1627563781237"/>
diff --git a/bnd/cnf/local/index.xml.sha b/bnd/cnf/local/index.xml.sha
new file mode 100644
index 0000000..5008222
--- /dev/null
+++ b/bnd/cnf/local/index.xml.sha
@@ -0,0 +1 @@
+2e88721d96db26da773df26d5b9e5302907bb845063a56e35a39b44b757e4521
\ No newline at end of file
diff --git a/bnd/cnf/p2/targetPlatform.target b/bnd/cnf/p2/targetPlatform.target
new file mode 100644
index 0000000..54324a8
--- /dev/null
+++ b/bnd/cnf/p2/targetPlatform.target
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<?pde version="3.8"?>
+<target name="targetPlatform">
+	<locations>
+		<location includeAllPlatforms="false" includeConfigurePhase="true" includeMode="planner" includeSource="true" type="InstallableUnit">
+			<repository location="http://download.eclipse.org/releases/2020-06"/>
+			<unit id="org.eclipse.draw2d" version="3.10.100.201606061308"/>
+		</location>
+	</locations>
+</target>
\ No newline at end of file
diff --git a/bnd/cnf/release/index.xml b/bnd/cnf/release/index.xml
new file mode 100644
index 0000000..5710d77
--- /dev/null
+++ b/bnd/cnf/release/index.xml
@@ -0,0 +1,2 @@
+<?xml version='1.0' encoding='UTF-8'?>
+<repository xmlns="http://www.osgi.org/xmlns/repository/v1.0.0" name="Release" increment="1572856360242"/>
diff --git a/bnd/cnf/releng/release.bnd b/bnd/cnf/releng/release.bnd
new file mode 100644
index 0000000..d6efe5f
--- /dev/null
+++ b/bnd/cnf/releng/release.bnd
@@ -0,0 +1,9 @@
+-plugin.Release: \
+	aQute.bnd.deployer.repository.LocalIndexedRepo; \
+		name = Release; \
+		pretty = true; \
+		local = ${release.dir}
+				
+#We have to substitude the -SNAPSHOT with an empty String for releases				
+-snapshot: 
+-pom: true
\ No newline at end of file
diff --git a/bnd/cnf/releng/snapshot.bnd b/bnd/cnf/releng/snapshot.bnd
new file mode 100644
index 0000000..5eec0c8
--- /dev/null
+++ b/bnd/cnf/releng/snapshot.bnd
@@ -0,0 +1,8 @@
+-plugin.Release: \
+	aQute.bnd.deployer.repository.LocalIndexedRepo; \
+		name = Release; \
+		pretty = true; \
+		local = ${build}/release
+
+-pom: version=${versionmask;===s;${@version}}
+		
\ No newline at end of file
diff --git a/bnd/gradle.properties b/bnd/gradle.properties
new file mode 100644
index 0000000..4f62d06
--- /dev/null
+++ b/bnd/gradle.properties
@@ -0,0 +1,2 @@
+bnd_version=5.0.1
+bnd_snapshots=https://bndtools.jfrog.io/bndtools/libs-snapshot-local
diff --git a/bnd/gradlew b/bnd/gradlew
new file mode 100644
index 0000000..53a9720
--- /dev/null
+++ b/bnd/gradlew
@@ -0,0 +1,183 @@
+#!/usr/bin/env sh
+
+#
+# Copyright 2015 the original author or authors.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#      https://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >/dev/null
+APP_HOME="`pwd -P`"
+cd "$SAVED" >/dev/null
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn () {
+    echo "$*"
+}
+
+die () {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+nonstop=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+  NONSTOP* )
+    nonstop=true
+    ;;
+esac
+
+CLASSPATH=$APP_HOME/.gradle-wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin or MSYS, switch paths to Windows format before running java
+if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+    JAVACMD=`cygpath --unix "$JAVACMD"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=`expr $i + 1`
+    done
+    case $i in
+        0) set -- ;;
+        1) set -- "$args0" ;;
+        2) set -- "$args0" "$args1" ;;
+        3) set -- "$args0" "$args1" "$args2" ;;
+        4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Escape application args
+save () {
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
+    echo " "
+}
+APP_ARGS=`save "$@"`
+
+# Collect all arguments for the java command, following the shell quoting and substitution rules
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
+
+exec "$JAVACMD" "$@"
diff --git a/bnd/gradlew.bat b/bnd/gradlew.bat
new file mode 100644
index 0000000..4c549bf
--- /dev/null
+++ b/bnd/gradlew.bat
@@ -0,0 +1,100 @@
+@rem

+@rem Copyright 2015 the original author or authors.

+@rem

+@rem Licensed under the Apache License, Version 2.0 (the "License");

+@rem you may not use this file except in compliance with the License.

+@rem You may obtain a copy of the License at

+@rem

+@rem      https://www.apache.org/licenses/LICENSE-2.0

+@rem

+@rem Unless required by applicable law or agreed to in writing, software

+@rem distributed under the License is distributed on an "AS IS" BASIS,

+@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.

+@rem See the License for the specific language governing permissions and

+@rem limitations under the License.

+@rem

+

+@if "%DEBUG%" == "" @echo off

+@rem ##########################################################################

+@rem

+@rem  Gradle startup script for Windows

+@rem

+@rem ##########################################################################

+

+@rem Set local scope for the variables with windows NT shell

+if "%OS%"=="Windows_NT" setlocal

+

+set DIRNAME=%~dp0

+if "%DIRNAME%" == "" set DIRNAME=.

+set APP_BASE_NAME=%~n0

+set APP_HOME=%DIRNAME%

+

+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.

+set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"

+

+@rem Find java.exe

+if defined JAVA_HOME goto findJavaFromJavaHome

+

+set JAVA_EXE=java.exe

+%JAVA_EXE% -version >NUL 2>&1

+if "%ERRORLEVEL%" == "0" goto init

+

+echo.

+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:findJavaFromJavaHome

+set JAVA_HOME=%JAVA_HOME:"=%

+set JAVA_EXE=%JAVA_HOME%/bin/java.exe

+

+if exist "%JAVA_EXE%" goto init

+

+echo.

+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%

+echo.

+echo Please set the JAVA_HOME variable in your environment to match the

+echo location of your Java installation.

+

+goto fail

+

+:init

+@rem Get command-line arguments, handling Windows variants

+

+if not "%OS%" == "Windows_NT" goto win9xME_args

+

+:win9xME_args

+@rem Slurp the command line arguments.

+set CMD_LINE_ARGS=

+set _SKIP=2

+

+:win9xME_args_slurp

+if "x%~1" == "x" goto execute

+

+set CMD_LINE_ARGS=%*

+

+:execute

+@rem Setup the command line

+

+set CLASSPATH=%APP_HOME%\.gradle-wrapper\gradle-wrapper.jar

+

+@rem Execute Gradle

+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%

+

+:end

+@rem End local scope for the variables with windows NT shell

+if "%ERRORLEVEL%"=="0" goto mainEnd

+

+:fail

+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of

+rem the _cmd.exe /c_ return code!

+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1

+exit /b 1

+

+:mainEnd

+if "%OS%"=="Windows_NT" endlocal

+

+:omega

diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/.classpath b/bnd/org.eclipse.sensinact.studio.http.messages/.classpath
new file mode 100644
index 0000000..7a6fc25
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="src" output="bin" path="src"/>
+	<classpathentry kind="src" output="bin_test" path="test">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/.gitignore b/bnd/org.eclipse.sensinact.studio.http.messages/.gitignore
new file mode 100644
index 0000000..c2b941a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/.gitignore
@@ -0,0 +1,2 @@
+/bin_test/
+/generated/
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/.project b/bnd/org.eclipse.sensinact.studio.http.messages/.project
new file mode 100644
index 0000000..7dd0728
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.sensinact.studio.http.messages</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+	</natures>
+</projectDescription>
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/.settings/org.eclipse.jdt.core.prefs b/bnd/org.eclipse.sensinact.studio.http.messages/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..0c68a61
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/bnd.bnd b/bnd/org.eclipse.sensinact.studio.http.messages/bnd.bnd
new file mode 100644
index 0000000..92f1aea
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/bnd.bnd
@@ -0,0 +1,13 @@
+Bundle-Version: 1.0.0.SNAPSHOT
+
+-buildpath: \
+	org.eclipse.core.runtime,\
+	org.restlet,\
+	json,\
+	org.apache.log4j,\
+	org.eclipse.sensinact.studio.preferences;version=project,\
+	com.fasterxml.jackson.core.jackson-databind,\
+	com.fasterxml.jackson.core.jackson-core,\
+	org.eclipse.jetty.websocket.common,\
+	com.fasterxml.jackson.core.jackson-annotations,\
+	osgi.annotation
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/HTTP_CODE.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/HTTP_CODE.java
new file mode 100644
index 0000000..2d3e3c2
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/HTTP_CODE.java
@@ -0,0 +1,136 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages;
+
+/**
+ * @author Etienne Gandrille
+ */
+public enum HTTP_CODE {
+	CODE_100(100, "Continue"),
+	CODE_101(101, "Switching Protocols"),
+	CODE_102(102, "Processing"),
+	CODE_200(200, "OK"),
+	CODE_201(201, "Created"),
+	CODE_202(202, "Accepted"),
+	CODE_203(203, "Non-Authoritative Information"),
+	CODE_204(204, "No Content"),
+	CODE_205(205, "Reset Content"),
+	CODE_206(206, "Partial Content"),
+	CODE_207(207, "Multi-Status (WebDAV; RFC 4918)"),
+	CODE_208(208, "Already Reported (WebDAV; RFC 5842)"),
+	CODE_226(226, "IM Used (RFC 3229)"),
+	CODE_300(300, "Multiple Choices"),
+	CODE_301(301, "301 Moved Permanently"),
+	CODE_302(302, "Found"),
+	CODE_303(303, "See Other"),
+	CODE_304(304, "Not Modified"),
+	CODE_305(305, "Use Proxy (since HTTP/1.1)"),
+	CODE_306(306, "Switch Proxy"),
+	CODE_307(307, "Temporary Redirect (since HTTP/1.1)"),
+	CODE_308(308, "Permanent Redirect (RFC 7538)"),
+	CODE_400(400, "Bad Request"),
+	CODE_401(401, "Unauthorized"),
+	CODE_402(402, "Payment Required"),
+	CODE_403(403, "Forbidden"),
+	CODE_404(404, "Not Found"),
+	CODE_405(405, "Method Not Allowed"),
+	CODE_406(406, "Not Acceptable"),
+	CODE_407(407, "Proxy Authentication Required"),
+	CODE_408(408, "Request Timeout"),
+	CODE_409(409, "Conflict"),
+	CODE_410(410, "Gone"),
+	CODE_411(411, "Length Required"),
+	CODE_412(412, "Precondition Failed"),
+	CODE_413(413, "Payload Too Large"),
+	CODE_414(414, "URI Too Long"),
+	CODE_415(415, "Unsupported Media Type"),
+	CODE_416(416, "Range Not Satisfiable"),
+	CODE_417(417, "Expectation Failed"),
+	CODE_418(418, "I'm a teapot (RFC 2324)"),
+	CODE_419(419, "Authentication Timeout"),
+	CODE_420(420, "Method Failure"),
+	CODE_421(421, "Misdirected Request"),
+	CODE_422(422, "Unprocessable Entity (WebDAV; RFC 4918)"),
+	CODE_423(423, "Locked (WebDAV; RFC 4918)"),
+	CODE_424(424, "Failed Dependency (WebDAV; RFC 4918)"),
+	CODE_426(426, "Upgrade Required"),
+	CODE_428(428, "Precondition Required"),
+	CODE_429(429, "Too Many Requests"),
+	CODE_431(431, "Request Header Fields Too Large"),
+	CODE_440(440, "Login Timeout (Microsoft)"),
+	CODE_444(444, "No Response (Nginx)"),
+	CODE_449(449, "Retry With (Microsoft)"),
+	CODE_450(450, "Blocked by Windows Parental Controls (Microsoft)"),
+	CODE_451(451, "Unavailable For Legal Reasons"),
+	CODE_494(494, "Request Header Too Large (Nginx)"),
+	CODE_495(495, "Cert Error (Nginx)"),
+	CODE_496(496, "No Cert (Nginx)"),
+	CODE_497(497, "HTTP to HTTPS (Nginx)"),
+	CODE_498(498, "Token expired/invalid (Esri)"),
+	CODE_499(499, "Client Closed Request (Nginx)"),
+	CODE_500(500, "Internal Server Error"),
+	CODE_501(501, "Not Implemented"),
+	CODE_502(502, "Bad Gateway"),
+	CODE_503(503, "Service Unavailable"),
+	CODE_504(504, "Gateway Timeout"),
+	CODE_505(505, "HTTP Version Not Supported"),
+	CODE_506(506, "Variant Also Negotiates (RFC 2295)"),
+	CODE_507(507, "Insufficient Storage (WebDAV; RFC 4918)"),
+	CODE_508(508, "Loop Detected (WebDAV; RFC 5842)"),
+	CODE_509(509, "Bandwidth Limit Exceeded (Apache bw/limited extension)"),
+	CODE_510(510, "Not Extended (RFC 2774)"),
+	CODE_511(511, "Network Authentication Required"),
+	CODE_520(520, "Unknown Error"),
+	CODE_522(522, "Origin Connection Time-out"),
+	CODE_598(598, "Network read timeout error (Unknown)"),
+	CODE_599(599, "Network connect timeout error (Unknown)");
+	  
+	private final int code;
+	private final String message;
+	   
+	private HTTP_CODE(int code, String message) {
+		this.code = code;
+		this.message = message;
+	}
+	
+	public String getType() {
+		if (code >= 100 && code <= 199)
+			return "Informational";
+		if (code >= 200 && code <= 299)
+			return "Success";
+		if (code >= 300 && code <= 399)
+			return "Redirection";
+		if (code >= 400 && code <= 499)
+			return "Client Error";
+		if (code >= 500 && code <= 599)
+			return "Server Error";
+		throw new IllegalArgumentException("Unknown HTTP CODE " + code);
+	}
+	
+	public String toString(){
+		return "HTTP " + code + ": " + getType() + " (" + message + ")";
+	}
+	
+	public int getCode() {
+		return code;
+	}
+	
+	public String getMessage() {
+		return message;
+	}
+	
+	public static HTTP_CODE toCode(int code) {
+		for (HTTP_CODE hc : HTTP_CODE.values())
+			if (hc.getCode() == code)
+				return hc;
+		throw new IllegalArgumentException("Unknown HTTP CODE " + code);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/package-info.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/package-info.java
new file mode 100644
index 0000000..3c23137
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.messages;
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/MsgCategory.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/MsgCategory.java
new file mode 100644
index 0000000..8fe8f29
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/MsgCategory.java
@@ -0,0 +1,15 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage;
+
+public enum MsgCategory {
+	LIFECYCLE, VALUE, RESPONSE, OTHER;
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/MsgFactory.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/MsgFactory.java
new file mode 100644
index 0000000..61b871e
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/MsgFactory.java
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage;
+
+import org.apache.log4j.Logger;
+import org.eclipse.sensinact.studio.http.messages.snamessage.basic.MsgExceptionError;
+import org.eclipse.sensinact.studio.http.messages.snamessage.basic.MsgHttpError;
+import org.eclipse.sensinact.studio.http.messages.snamessage.basic.MsgOk;
+import org.json.JSONObject;
+
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgFactory {
+
+	private static final Logger logger = Logger.getLogger(MsgFactory.class);
+
+	
+	private MsgFactory() {
+		throw new RuntimeException("do no instantiate");
+	}
+
+	public static MsgSensinact build(JSONObject jsonObject) {
+		return build(jsonObject, -1); // it gonna fail if httpCode is not available 
+	}
+	
+	public static MsgSensinact build(JSONObject jsonObject, int defaultCode) {
+		
+		int httpCode = getStatusCode(jsonObject, defaultCode);
+		String msgType = jsonObject.optString("type", null);
+		
+		// HTTP error code
+		if (httpCode != -1 && (httpCode < 200 || httpCode >= 300)) {
+			logger.info("Building message with type MsgHttpError");
+			return new MsgHttpError(httpCode, jsonObject);
+		}
+		
+		// assert type exists	
+		if (msgType == null) {
+			if (httpCode != -1)
+				return new MsgOk(httpCode, jsonObject);
+			else
+				throw new RuntimeException("type not found in json message");
+		}
+		
+		logger.info("Building message with type " + msgType);
+			
+		// assert builder exists
+		MsgTypes registeredType = MsgTypes.get(msgType);
+		if (registeredType == null) {
+			if (httpCode != -1)
+				return new MsgOk(httpCode, jsonObject);
+			else
+				throw new RuntimeException("unknown type " + msgType + " in json message");	
+		}
+			
+		// build!
+		ObjectMapper mapper = getMapper();
+		try {
+			Object object = mapper.readValue(jsonObject.toString(), registeredType.getTargetClass());
+			return (MsgSensinact) object;
+		} catch (Exception e) {
+			String msg = "Error while unmarshalling json " + jsonObject.toString();
+			
+			logger.error(msg);
+			logger.error(e.getMessage(), e);
+			
+			if (httpCode != -1)
+				return new MsgOk(httpCode, jsonObject);
+			else
+				throw new RuntimeException("Error while unmarshalling json " + jsonObject.toString(), e);
+		}
+	}
+	
+	private static final int getStatusCode(JSONObject jsonObject, int defaultCode) {
+		String code = jsonObject.optString("statusCode", null);
+		if (code == null)
+			return defaultCode;
+		else
+			return Integer.parseInt(code);	
+	}
+	
+	private static ObjectMapper getMapper() {
+		ObjectMapper mapper = new ObjectMapper();
+        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
+		SimpleModule module = new SimpleModule();
+		module.addDeserializer(ObjectNameTypeValue.class, new NameTypeValueDeserializer());
+		mapper.registerModule(module);
+		return mapper;
+	}
+	
+	public static MsgSensinact build(String json, Exception e) {
+		return new MsgExceptionError(json, e);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/MsgNotification.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/MsgNotification.java
new file mode 100644
index 0000000..f9a84aa
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/MsgNotification.java
@@ -0,0 +1,68 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage;
+
+/**
+ * @author Etienne Gandrille
+ */
+public abstract class MsgNotification<V> extends MsgSensinact {
+
+	protected V notification;
+	
+	public MsgNotification(String type) {
+		super(type);
+	}
+
+	public V getNotification() {
+		return notification;
+	}
+
+	public void setNotification(V notification) {
+		this.notification = notification;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((notification == null) ? 0 : notification.hashCode());
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgNotification<?> other = (MsgNotification<?>) obj;
+		if (notification == null) {
+			if (other.notification != null)
+				return false;
+		} else if (!notification.equals(other.notification))
+			return false;
+		if (type == null) {
+			if (other.type != null)
+				return false;
+		} else if (!type.equals(other.type))
+			return false;
+		if (uri == null) {
+			if (other.uri != null)
+				return false;
+		} else if (!uri.equals(other.uri))
+			return false;
+		return true;
+	}
+}
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/MsgSensinact.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/MsgSensinact.java
new file mode 100644
index 0000000..7692394
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/MsgSensinact.java
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage;
+
+import java.util.List;
+
+/**
+ * @author Etienne Gandrille
+ */
+public abstract class MsgSensinact {
+
+	public static final String KEY = "KEY";
+	public static final int PRIME = 31;
+	
+	protected final String type;
+	protected String uri;
+	
+	private List<ObjectFilter> filters;
+
+	public MsgSensinact(String type) {
+		this.type = type;
+	}
+	
+	public String getUri() {
+		return uri;
+	}
+	
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+
+	public String getType() {
+		return type;
+	}
+	
+	public final void setType(String type) {
+		if (! this.type.equals(type))
+			throw new IllegalArgumentException();
+	}
+
+	public List<ObjectFilter> getFilters() {
+		return filters;
+	}
+	
+	public ObjectFilter getFilter(String filterType) {
+		for (ObjectFilter filter : filters)
+			if (filter.getType().equals(filterType))
+				return filter;
+		return null;
+	}
+
+	public void setFilters(List<ObjectFilter> filters) {
+		this.filters = filters;
+	}
+
+	public boolean isValid() {
+		return true;
+	}
+	
+	public abstract MsgCategory getCategory();
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/MsgTypes.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/MsgTypes.java
new file mode 100644
index 0000000..a059b3c
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/MsgTypes.java
@@ -0,0 +1,80 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.actresponse.MsgActResponse;
+import org.eclipse.sensinact.studio.http.messages.snamessage.attributevalueupdated.MsgAttributeValueUpdated;
+import org.eclipse.sensinact.studio.http.messages.snamessage.completelist.MsgCompleteList;
+import org.eclipse.sensinact.studio.http.messages.snamessage.describeresource.MsgDescribeRessource;
+import org.eclipse.sensinact.studio.http.messages.snamessage.getresponse.MsgGetResponse;
+import org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle.*;
+import org.eclipse.sensinact.studio.http.messages.snamessage.resourceslist.MsgResourcesList;
+import org.eclipse.sensinact.studio.http.messages.snamessage.serviceslist.MsgServicesList;
+import org.eclipse.sensinact.studio.http.messages.snamessage.setresponse.MsgSetResponse;
+import org.eclipse.sensinact.studio.http.messages.snamessage.subscriberesponse.MsgSubscribeResponse;
+import org.eclipse.sensinact.studio.http.messages.snamessage.tokencreation.MsgTokenCreation;
+import org.eclipse.sensinact.studio.http.messages.snamessage.unsubscriberesponse.MsgUnsubscribeResponse;
+
+/**
+ * @author Etienne Gandrille
+ */
+public enum MsgTypes {
+
+	// Token management
+	TOKEN_CREATION          (MsgTokenCreation.KEY,        MsgTokenCreation.class),
+	/* TOKEN_RENEW */
+	
+	// List and describe (there will be much more than this two...)
+	COMPLETE_LIST           (MsgCompleteList.KEY,         MsgCompleteList.class),
+	SERVICES_LIST           (MsgServicesList.KEY,         MsgServicesList.class), 
+	RESOURCES_LIST          (MsgResourcesList.KEY,        MsgResourcesList.class), 
+	DESCRIBE_RESOURCE       (MsgDescribeRessource.KEY,    MsgDescribeRessource.class),
+	
+	// Access methods
+	GET_RESPONSE            (MsgGetResponse.KEY,          MsgGetResponse.class),
+	SET_RESPONSE            (MsgSetResponse.KEY,          MsgSetResponse.class),
+	ACT_RESPONSE            (MsgActResponse.KEY,          MsgActResponse.class),
+	SUBSCRIBE_RESPONSE      (MsgSubscribeResponse.KEY,    MsgSubscribeResponse.class),
+	UNSUBSCRIBE_RESPONSE    (MsgUnsubscribeResponse.KEY,  MsgUnsubscribeResponse.class),
+	
+	// CALLBACK 
+	PROVIDER_APPEARING      (MsgProviderAppearing.KEY,    MsgProviderAppearing.class),
+	PROVIDER_DISAPPEARING   (MsgProviderDisappearing.KEY, MsgProviderDisappearing.class),
+	SERVICE_APPEARING       (MsgServiceAppearing.KEY,     MsgServiceAppearing.class),
+	SERVICE_DISAPPEARING    (MsgServiceDisappearing.KEY,  MsgServiceDisappearing.class),
+	RESOURCE_APPEARING      (MsgResourceAppearing.KEY,    MsgResourceAppearing.class),
+	RESOURCE_DISAPPEARING   (MsgResourceDisappearing.KEY, MsgResourceDisappearing.class),
+	
+	// Other
+	ATTRIBUTE_VALUE_UPDATED (MsgAttributeValueUpdated.KEY, MsgAttributeValueUpdated.class);
+	
+	
+	private final String type;
+	private final Class<?> clazz;
+	
+	private MsgTypes(String type, Class<?> clazz) {
+		this.type = type;
+		this.clazz = clazz;
+	}
+
+	public static MsgTypes get(String type) {
+		
+		for (MsgTypes val : values()) {
+			if (val.type.equals(type))
+				return val;
+		}
+		return null;
+	}
+	
+	public Class<?> getTargetClass() {
+		return clazz;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/NameTypeValueDeserializer.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/NameTypeValueDeserializer.java
new file mode 100644
index 0000000..ad2ea76
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/NameTypeValueDeserializer.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage;
+
+import java.io.IOException;
+import java.util.Optional;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.JsonProcessingException;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.JsonNode;
+import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class NameTypeValueDeserializer extends StdDeserializer<ObjectNameTypeValue> {
+
+	private static final long serialVersionUID = -2698830271936665275L;
+
+	public NameTypeValueDeserializer() { 
+        this(null); 
+    } 
+ 
+    public NameTypeValueDeserializer(Class<?> vc) { 
+        super(vc); 
+    }
+	
+	@Override
+	public ObjectNameTypeValue deserialize(JsonParser parser, DeserializationContext ctx) throws IOException, JsonProcessingException {
+		
+		JsonNode node = parser.getCodec().readTree(parser);
+        
+		String name = node.get("name").textValue();
+		
+		String typeName = node.get("type").textValue();
+		ValueType type = ValueType.fromName(typeName);
+		if (type == null)
+			throw new RuntimeException("Type value with typeName " + typeName + " NOT FOUND");		
+		
+		Object value = type.getObject(node.get("value"));
+		
+		Optional<Long> timestamp;
+		if (node.has("timestamp"))
+			timestamp = Optional.of(node.get("timestamp").asLong());
+		else
+			timestamp = Optional.empty();
+
+		return new  ObjectNameTypeValue(name, type, value, timestamp);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/ObjectFilter.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/ObjectFilter.java
new file mode 100644
index 0000000..ec7c6c2
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/ObjectFilter.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ObjectFilter {
+	
+	private String type;
+	private String definition;
+	
+	public String getType() {
+		return type;
+	}
+	
+	public void setType(String type) {
+		this.type = type;
+	}
+	
+	public String getDefinition() {
+		return definition;
+	}
+	
+	public void setDefinition(String definition) {
+		this.definition = definition;
+	}
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		result = prime * result + ((definition == null) ? 0 : definition.hashCode());
+		return result;
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ObjectFilter other = (ObjectFilter) obj;
+		if (type == null) {
+			if (other.type != null)
+				return false;
+		} else if (!type.equals(other.type))
+			return false;
+		if (definition == null) {
+			if (other.definition != null)
+				return false;
+		} else if (!definition.equals(other.definition))
+			return false;
+		return true;
+	}
+	
+	@Override
+	public String toString() {
+		return "ObjectFilter [definition=" + definition + ", type=" + type + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/ObjectNameTypeValue.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/ObjectNameTypeValue.java
new file mode 100644
index 0000000..7ea8519
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/ObjectNameTypeValue.java
@@ -0,0 +1,103 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage;
+
+import java.util.Optional;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ObjectNameTypeValue {
+	
+	private final String name;
+	private final ValueType type;
+	private final Object value;
+	private final Optional<Long> timestamp;
+	
+	public ObjectNameTypeValue(String name, ValueType type, Object value, long timestamp) {
+		this(name, type, value, Optional.of(timestamp));
+	}
+
+	public ObjectNameTypeValue(String name, ValueType type, Object value) {
+		this(name, type, value, Optional.empty());
+	}
+	
+	public ObjectNameTypeValue(String name, ValueType type, Object value, Optional<Long> timestamp) {
+		this.name = name;
+		this.type = type;
+		this.value = value;
+		this.timestamp = timestamp;
+	}
+	
+	public String getName() {
+		return name;
+	}
+		
+	public ValueType getType() {
+		return type;
+	}
+	
+	public String getValueAsString() {
+		if (value == null)
+			return "null";
+		else
+			return value.toString();
+	}
+	
+	public Optional<Long> getTimestamp() {
+		return timestamp;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		result = prime * result + ((timestamp == null) ? 0 : timestamp.hashCode());
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		result = prime * result + ((value == null) ? 0 : value.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ObjectNameTypeValue other = (ObjectNameTypeValue) obj;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		if (timestamp == null) {
+			if (other.timestamp != null)
+				return false;
+		} else if (!timestamp.equals(other.timestamp))
+			return false;
+		if (type != other.type)
+			return false;
+		if (value == null) {
+			if (other.value != null)
+				return false;
+		} else if (!value.equals(other.value))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "ObjectNameTypeValue [name=" + name + ", type=" + type + ", value=" + value + ", timestamp=" + timestamp	+ "]";
+	}	
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/ValueType.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/ValueType.java
new file mode 100644
index 0000000..bb821db
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/ValueType.java
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.function.Function;
+
+import org.apache.log4j.Logger;
+
+import com.fasterxml.jackson.databind.JsonNode;
+
+/**
+ * @author Etienne Gandrille
+ */
+public enum ValueType {
+
+	// Should be temporary, since the gateway does not implements the enums yet.
+	// Remove this when gateway will be updated
+	OTHER("other", n -> n.asText()),
+	OBJECT("object", n -> n.toString()), /* do NOT use asText with 'object' */
+	STRING("string", n -> n.asText()),
+	LONG("long", n -> n.asLong()),
+	DOUBLE("double", n -> n.asDouble()),
+	FLOAT("float", n -> n.asDouble()),
+	INT("int", n -> n.asInt()),
+	BOOLEAN("boolean", n -> n.asBoolean()),
+	ARRAY("array", n -> computeArray(n));
+	
+	private String name;
+	private Function<JsonNode, Object> nodeToObject;
+
+	private static final Logger logger = Logger.getLogger(ValueType.class);
+
+	private ValueType(String name, Function<JsonNode, Object> nodeToObject) {
+		this.name = name;
+		this.nodeToObject = nodeToObject;
+	}
+	
+	public static ValueType fromName(String name) {
+		for (ValueType value : values()) {
+			if (value.getName().equals(name))
+				return value;
+		}
+		return OTHER;
+	}
+
+	public String getName() {
+		return name;
+	}
+
+	public Object getObject(JsonNode jsonNode) {
+		return nodeToObject.apply(jsonNode);
+	}
+	
+	private static List<String> computeArray(JsonNode n) {
+		List<String> list = new ArrayList<>();
+		
+		for (Iterator<JsonNode> it = n.iterator(); it.hasNext();) {
+			JsonNode elem = it.next();
+			list.add(elem.asText());
+		}
+			
+		return list;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/actresponse/MsgActResponse.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/actresponse/MsgActResponse.java
new file mode 100644
index 0000000..8d15f90
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/actresponse/MsgActResponse.java
@@ -0,0 +1,117 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.actresponse;
+
+import java.util.List;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+import org.eclipse.sensinact.studio.http.messages.snamessage.ObjectNameTypeValue;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgActResponse extends MsgSensinact {
+
+	public static final String KEY = "ACT_RESPONSE";
+	
+	private List<ObjectNameTypeValue> triggered;
+	private ObjectResponse response;
+	private String uri;
+	private int statusCode;
+	
+	public MsgActResponse() {
+		super(KEY);
+	}
+
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.RESPONSE;
+	}
+	
+	public List<ObjectNameTypeValue> getTriggered() {
+		return triggered;
+	}
+
+	public void setTriggered(List<ObjectNameTypeValue> triggered) {
+		this.triggered = triggered;
+	}
+
+	public ObjectResponse getResponse() {
+		return response;
+	}
+
+	public void setResponse(ObjectResponse response) {
+		this.response = response;
+	}
+
+	public String getUri() {
+		return uri;
+	}
+
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+
+	public int getStatusCode() {
+		return statusCode;
+	}
+
+	public void setStatusCode(int statusCode) {
+		this.statusCode = statusCode;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((response == null) ? 0 : response.hashCode());
+		result = prime * result + statusCode;
+		result = prime * result + ((triggered == null) ? 0 : triggered.hashCode());
+		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgActResponse other = (MsgActResponse) obj;
+		if (response == null) {
+			if (other.response != null)
+				return false;
+		} else if (!response.equals(other.response))
+			return false;
+		if (statusCode != other.statusCode)
+			return false;
+		if (triggered == null) {
+			if (other.triggered != null)
+				return false;
+		} else if (!triggered.equals(other.triggered))
+			return false;
+		if (uri == null) {
+			if (other.uri != null)
+				return false;
+		} else if (!uri.equals(other.uri))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "MsgActResponse [triggered=" + triggered + ", response=" + response + ", uri=" + uri + ", statusCode="
+				+ statusCode + "]";
+	}
+}
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/actresponse/ObjectResponse.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/actresponse/ObjectResponse.java
new file mode 100644
index 0000000..e9ce80a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/actresponse/ObjectResponse.java
@@ -0,0 +1,112 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.actresponse;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ObjectResponse {
+	
+	private String task;
+	private long start;
+	private long end;
+	private String uri;
+	private String status;
+	
+	public String getTask() {
+		return task;
+	}
+	
+	public void setTask(String task) {
+		this.task = task;
+	}
+	
+	public long getStart() {
+		return start;
+	}
+	
+	public void setStart(long start) {
+		this.start = start;
+	}
+	
+	public long getEnd() {
+		return end;
+	}
+	
+	public void setEnd(long end) {
+		this.end = end;
+	}
+	
+	public String getUri() {
+		return uri;
+	}
+	
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+	
+	public String getStatus() {
+		return status;
+	}
+	
+	public void setStatus(String status) {
+		this.status = status;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + (int) (end ^ (end >>> 32));
+		result = prime * result + (int) (start ^ (start >>> 32));
+		result = prime * result + ((status == null) ? 0 : status.hashCode());
+		result = prime * result + ((task == null) ? 0 : task.hashCode());
+		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ObjectResponse other = (ObjectResponse) obj;
+		if (end != other.end)
+			return false;
+		if (start != other.start)
+			return false;
+		if (status == null) {
+			if (other.status != null)
+				return false;
+		} else if (!status.equals(other.status))
+			return false;
+		if (task == null) {
+			if (other.task != null)
+				return false;
+		} else if (!task.equals(other.task))
+			return false;
+		if (uri == null) {
+			if (other.uri != null)
+				return false;
+		} else if (!uri.equals(other.uri))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "ObjectResponse [task=" + task + ", start=" + start + ", end=" + end + ", uri=" + uri + ", status="
+				+ status + "]";
+	}	
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/actresponse/package-info.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/actresponse/package-info.java
new file mode 100644
index 0000000..13a98dd
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/actresponse/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.messages.snamessage.actresponse;
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/attributevalueupdated/MsgAttributeValueUpdated.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/attributevalueupdated/MsgAttributeValueUpdated.java
new file mode 100644
index 0000000..971f059
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/attributevalueupdated/MsgAttributeValueUpdated.java
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.attributevalueupdated;
+
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+import org.eclipse.sensinact.studio.http.messages.snamessage.ObjectNameTypeValue;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgAttributeValueUpdated extends MsgSensinact {
+
+	public static final String KEY = "ATTRIBUTE_VALUE_UPDATED";
+
+	private ObjectNameTypeValue notification;
+	private String uri;
+	
+	public MsgAttributeValueUpdated() {
+		super(KEY);
+	}
+
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.VALUE;
+	}
+	
+	public ObjectNameTypeValue getNotification() {
+		return notification;
+	}
+
+	public void setNotification(ObjectNameTypeValue notification) {
+		this.notification = notification;
+	}
+
+	public String getUri() {
+		return uri;
+	}
+
+	public boolean isLocationValue() {
+		return uri != null && uri.endsWith("/admin/location/value");
+	}
+
+
+	public boolean isIconValue() {
+		return uri != null && uri.endsWith("/admin/icon/value");
+	}	
+	
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((notification == null) ? 0 : notification.hashCode());
+		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgAttributeValueUpdated other = (MsgAttributeValueUpdated) obj;
+		if (notification == null) {
+			if (other.notification != null)
+				return false;
+		} else if (!notification.equals(other.notification))
+			return false;
+		if (uri == null) {
+			if (other.uri != null)
+				return false;
+		} else if (!uri.equals(other.uri))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "MsgAttributeValueUpdated [notification=" + notification + ", uri=" + uri + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/attributevalueupdated/package-info.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/attributevalueupdated/package-info.java
new file mode 100644
index 0000000..b96b27e
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/attributevalueupdated/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.messages.snamessage.attributevalueupdated;
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/basic/MsgBasic.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/basic/MsgBasic.java
new file mode 100644
index 0000000..8147e4a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/basic/MsgBasic.java
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.basic;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+
+public abstract class MsgBasic extends MsgSensinact {
+
+	public MsgBasic(String type) {
+		super(type);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/basic/MsgError.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/basic/MsgError.java
new file mode 100644
index 0000000..5eeb0d3
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/basic/MsgError.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.basic;
+
+/**
+ * @author Etienne Gandrille
+ */
+public abstract class MsgError extends MsgBasic {
+	public MsgError() {
+		super("ERROR");
+	}
+	
+	public boolean isValid() {
+		return false;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/basic/MsgExceptionError.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/basic/MsgExceptionError.java
new file mode 100644
index 0000000..4e28785
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/basic/MsgExceptionError.java
@@ -0,0 +1,76 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.basic;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgExceptionError extends MsgError {
+
+	private final String jsonObject;
+	private final Exception exception;
+	
+	public MsgExceptionError(String jsonObject, Exception exception) {
+		this.jsonObject = jsonObject;
+		this.exception = exception;
+	}
+
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.OTHER;
+	}
+	
+	public String getJsonObject() {
+		return jsonObject;
+	}
+
+	public Exception getException() {
+		return exception;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((exception == null) ? 0 : exception.hashCode());
+		result = prime * result + ((jsonObject == null) ? 0 : jsonObject.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgExceptionError other = (MsgExceptionError) obj;
+		if (exception == null) {
+			if (other.exception != null)
+				return false;
+		} else if (!exception.equals(other.exception))
+			return false;
+		if (jsonObject == null) {
+			if (other.jsonObject != null)
+				return false;
+		} else if (!jsonObject.equals(other.jsonObject))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "MsgExceptionError [jsonObject=" + jsonObject + ", exception=" + exception + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/basic/MsgHttpError.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/basic/MsgHttpError.java
new file mode 100644
index 0000000..3825327
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/basic/MsgHttpError.java
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.basic;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.json.JSONObject;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgHttpError extends MsgError {
+
+	private final int code;
+	private final JSONObject jsonObject;
+	
+	public MsgHttpError(int code, JSONObject jsonObject) {
+		this.code = code;
+		this.jsonObject = jsonObject;
+	}
+	
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.OTHER;
+	}
+	
+	public int getCode() {
+		return code;
+	}
+	
+	public JSONObject getJsonObject() {
+		return jsonObject;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + code;
+		result = prime * result + ((jsonObject == null) ? 0 : jsonObject.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgHttpError other = (MsgHttpError) obj;
+		if (code != other.code)
+			return false;
+		if (jsonObject == null) {
+			if (other.jsonObject != null)
+				return false;
+		} else if (!jsonObject.equals(other.jsonObject))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "MsgHttpError [code=" + code + ", jsonObject=" + jsonObject + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/basic/MsgOk.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/basic/MsgOk.java
new file mode 100644
index 0000000..902ac83
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/basic/MsgOk.java
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.basic;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.json.JSONObject;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgOk extends MsgBasic {
+
+	private final int code;
+	private final JSONObject jsonObject;
+	
+	public MsgOk(int code, JSONObject jsonObject) {
+		super("OK");
+		this.code = code;
+		this.jsonObject = jsonObject;
+	}
+	
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.OTHER;
+	}
+	
+	public int getCode() {
+		return code;
+	}
+	
+	public JSONObject getJsonObject() {
+		return jsonObject;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + code;
+		result = prime * result + ((jsonObject == null) ? 0 : jsonObject.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgOk other = (MsgOk) obj;
+		if (code != other.code)
+			return false;
+		if (jsonObject == null) {
+			if (other.jsonObject != null)
+				return false;
+		} else if (!jsonObject.equals(other.jsonObject))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "MsgOk [code=" + code + ", jsonObject=" + jsonObject + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/basic/package-info.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/basic/package-info.java
new file mode 100644
index 0000000..1fc632b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/basic/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.messages.snamessage.basic;
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/completelist/MsgCompleteList.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/completelist/MsgCompleteList.java
new file mode 100644
index 0000000..3aad20e
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/completelist/MsgCompleteList.java
@@ -0,0 +1,117 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.completelist;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgCompleteList extends MsgSensinact {
+
+	public static final String KEY = "COMPLETE_LIST";
+
+	private List<ObjectProvider> providers;
+	private String uri;
+	private int statusCode;
+	
+	public MsgCompleteList() {
+		super(KEY);
+	}
+	
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.OTHER;
+	}
+	
+	public List<ObjectProvider> getProviders() {
+		return providers;
+	}
+
+	public List<String> getProvidersId() {
+		List<ObjectProvider>  providers = getProviders();
+		if(providers == null || providers.isEmpty())
+			return Collections.emptyList();
+		return providers.stream().collect(ArrayList::new,(l,o) -> l.add(o.getName()),List::addAll);
+	}
+	
+	public ObjectProvider getProvider(String providerName) {
+		for (ObjectProvider provider : providers)
+			if (provider.getName().equals(providerName))
+				return provider;
+		return null;
+	}
+	
+	
+	public void setProviders(List<ObjectProvider> providers) {
+		this.providers = providers;
+	}
+	
+	public String getUri() {
+		return uri;
+	}
+	
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+	
+	public int getStatusCode() {
+		return statusCode;
+	}
+	
+	public void setStatusCode(int statusCode) {
+		this.statusCode = statusCode;
+	}
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((providers == null) ? 0 : providers.hashCode());
+		result = prime * result + statusCode;
+		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+		return result;
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgCompleteList other = (MsgCompleteList) obj;
+		if (providers == null) {
+			if (other.providers != null)
+				return false;
+		} else if (!providers.equals(other.providers))
+			return false;
+		if (statusCode != other.statusCode)
+			return false;
+		if (uri == null) {
+			if (other.uri != null)
+				return false;
+		} else if (!uri.equals(other.uri))
+			return false;
+		return true;
+	}
+	
+	@Override
+	public String toString() {
+		return "MsgCompleteList [providers=" + providers + ", uri=" + uri + ", statusCode=" + statusCode + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/completelist/ObjectProvider.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/completelist/ObjectProvider.java
new file mode 100644
index 0000000..7112255
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/completelist/ObjectProvider.java
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.completelist;
+
+import java.util.List;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ObjectProvider {
+	
+	private String name;
+	private String location;
+	private List<ObjectService> services;
+	private String icon;
+	
+	public String getName() {
+		return name;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public String getLocation() {
+		return location;
+	}
+	
+	public void setLocation(String location) {
+		this.location = location;
+	}
+	
+	public List<ObjectService> getServices() {
+		return services;
+	}
+	
+	public void setServices(List<ObjectService> services) {
+		this.services = services;
+	}
+
+	public String getIcon() {
+		return this.icon;
+	}
+	
+	public void setIcon(String icon) {
+		this.icon = icon;
+	}
+	
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((location == null) ? 0 : location.hashCode());
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		result = prime * result + ((services == null) ? 0 : services.hashCode());
+		result = prime * result + ((icon == null) ? 0 : icon.hashCode());
+		return result;
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ObjectProvider other = (ObjectProvider) obj;
+		if (location == null) {
+			if (other.location != null)
+				return false;
+		} else if (!location.equals(other.location))
+			return false;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		if (services == null) {
+			if (other.services != null)
+				return false;
+		} else if (!services.equals(other.services))
+			return false;
+		return true;
+	}
+	
+	@Override
+	public String toString() {
+		return "ObjectProviders [name=" + name + ", location=" + location + ", services=" + services + (icon==null?"":", icon=" + icon)+"]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/completelist/ObjectResource.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/completelist/ObjectResource.java
new file mode 100644
index 0000000..18bd786
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/completelist/ObjectResource.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.completelist;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ObjectResource {
+	
+	private String name;
+	private String type;
+	
+	public String getName() {
+		return name;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public String getType() {
+		return type;
+	}
+	
+	public void setType(String type) {
+		this.type = type;
+	}
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		return result;
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ObjectResource other = (ObjectResource) obj;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		if (type == null) {
+			if (other.type != null)
+				return false;
+		} else if (!type.equals(other.type))
+			return false;
+		return true;
+	}
+	
+	@Override
+	public String toString() {
+		return "ObjectResource [name=" + name + ", type=" + type + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/completelist/ObjectService.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/completelist/ObjectService.java
new file mode 100644
index 0000000..02bcd51
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/completelist/ObjectService.java
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.completelist;
+
+import java.util.List;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ObjectService {
+	
+	private String name;
+	private List<ObjectResource> resources;
+	
+	public String getName() {
+		return name;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public List<ObjectResource> getResources() {
+		return resources;
+	}
+	
+	public void setResources(List<ObjectResource> resources) {
+		this.resources = resources;
+	}
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		result = prime * result + ((resources == null) ? 0 : resources.hashCode());
+		return result;
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ObjectService other = (ObjectService) obj;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		if (resources == null) {
+			if (other.resources != null)
+				return false;
+		} else if (!resources.equals(other.resources))
+			return false;
+		return true;
+	}
+	
+	@Override
+	public String toString() {
+		return "ObjectService [name=" + name + ", resources=" + resources + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/completelist/package-info.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/completelist/package-info.java
new file mode 100644
index 0000000..c23a985
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/completelist/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.messages.snamessage.completelist;
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/MsgDescribeRessource.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/MsgDescribeRessource.java
new file mode 100644
index 0000000..033c7e0
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/MsgDescribeRessource.java
@@ -0,0 +1,101 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.describeresource;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgDescribeRessource extends MsgSensinact {
+	public static final String KEY = "DESCRIBE_RESOURCE";
+
+	private String uri;
+	private int statusCode;
+	private ObjectResponse response;
+	
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.OTHER;
+	}
+	
+	public MsgDescribeRessource() {
+		super(KEY);
+	}
+
+	public String getUri() {
+		return uri;
+	}
+
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+
+	public int getStatusCode() {
+		return statusCode;
+	}
+
+	public void setStatusCode(int statusCode) {
+		this.statusCode = statusCode;
+	}
+
+	public ObjectResponse getResponse() {
+		return response;
+	}
+
+	public void setResponse(ObjectResponse response) {
+		this.response = response;
+	}
+
+	public static String getKey() {
+		return KEY;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((response == null) ? 0 : response.hashCode());
+		result = prime * result + statusCode;
+		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgDescribeRessource other = (MsgDescribeRessource) obj;
+		if (response == null) {
+			if (other.response != null)
+				return false;
+		} else if (!response.equals(other.response))
+			return false;
+		if (statusCode != other.statusCode)
+			return false;
+		if (uri == null) {
+			if (other.uri != null)
+				return false;
+		} else if (!uri.equals(other.uri))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "MsgDescribeRessource [uri=" + uri + ", statusCode=" + statusCode + ", response=" + response + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/ObjectAccessMethods.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/ObjectAccessMethods.java
new file mode 100644
index 0000000..f3402d1
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/ObjectAccessMethods.java
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.describeresource;
+
+import java.util.List;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ObjectAccessMethods {
+	
+	private String name;
+	private List<ObjectParameter> parameters;
+	
+	public String getName() {
+		return name;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public List<ObjectParameter> getParameters() {
+		return parameters;
+	}
+	
+	public void setParameters(List<ObjectParameter> parameters) {
+		this.parameters = parameters;
+	}
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		result = prime * result + ((parameters == null) ? 0 : parameters.hashCode());
+		return result;
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ObjectAccessMethods other = (ObjectAccessMethods) obj;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		if (parameters == null) {
+			if (other.parameters != null)
+				return false;
+		} else if (!parameters.equals(other.parameters))
+			return false;
+		return true;
+	}
+	
+	@Override
+	public String toString() {
+		return "ObjectAccessMethods [name=" + name + ", parameters=" + parameters + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/ObjectAttribute.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/ObjectAttribute.java
new file mode 100644
index 0000000..6f01ca4
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/ObjectAttribute.java
@@ -0,0 +1,106 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.describeresource;
+
+import java.util.List;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.ObjectNameTypeValue;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ObjectAttribute {
+	
+	private List<ObjectNameTypeValue> metadata;
+	private String name;
+	private String type;
+	private String value;
+	
+	public List<ObjectNameTypeValue> getMetadata() {
+		return metadata;
+	}
+	
+	public void setMetadata(List<ObjectNameTypeValue> metadata) {
+		this.metadata = metadata;
+	}
+	
+	public String getName() {
+		return name;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public String getType() {
+		return type;
+	}
+	
+	public void setType(String type) {
+		this.type = type;
+	}
+	
+	public String getValue() {
+		return value;
+	}
+	
+	public void setValue(String value) {
+		this.value = value;
+	}
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((metadata == null) ? 0 : metadata.hashCode());
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		result = prime * result + ((value == null) ? 0 : value.hashCode());
+		return result;
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ObjectAttribute other = (ObjectAttribute) obj;
+		if (metadata == null) {
+			if (other.metadata != null)
+				return false;
+		} else if (!metadata.equals(other.metadata))
+			return false;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		if (type == null) {
+			if (other.type != null)
+				return false;
+		} else if (!type.equals(other.type))
+			return false;
+		if (value == null) {
+			if (other.value != null)
+				return false;
+		} else if (!value.equals(other.value))
+			return false;
+		return true;
+	}
+	
+	@Override
+	public String toString() {
+		return "ObjectAttribute [metadata=" + metadata + ", name=" + name + ", type=" + type + ", value=" + value + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/ObjectConstraint.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/ObjectConstraint.java
new file mode 100644
index 0000000..b09dc8b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/ObjectConstraint.java
@@ -0,0 +1,100 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.describeresource;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ObjectConstraint {
+	
+	private String type;
+	private boolean complement;
+	private String operator;
+	private String operand;
+	
+	public String getType() {
+		return type;
+	}
+	
+	public void setType(String type) {
+		this.type = type;
+	}
+	
+	public boolean isComplement() {
+		return complement;
+	}
+	
+	public void setComplement(boolean complement) {
+		this.complement = complement;
+	}
+	
+	public String getOperator() {
+		return operator;
+	}
+	
+	public void setOperator(String operator) {
+		this.operator = operator;
+	}
+	
+	public String getOperand() {
+		return operand;
+	}
+	
+	public void setOperand(String operand) {
+		this.operand = operand;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + (complement ? 1231 : 1237);
+		result = prime * result + ((operand == null) ? 0 : operand.hashCode());
+		result = prime * result + ((operator == null) ? 0 : operator.hashCode());
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ObjectConstraint other = (ObjectConstraint) obj;
+		if (complement != other.complement)
+			return false;
+		if (operand == null) {
+			if (other.operand != null)
+				return false;
+		} else if (!operand.equals(other.operand))
+			return false;
+		if (operator == null) {
+			if (other.operator != null)
+				return false;
+		} else if (!operator.equals(other.operator))
+			return false;
+		if (type == null) {
+			if (other.type != null)
+				return false;
+		} else if (!type.equals(other.type))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "ObjectConstraint [type=" + type + ", complement=" + complement + ", operator=" + operator + ", operand="
+				+ operand + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/ObjectParameter.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/ObjectParameter.java
new file mode 100644
index 0000000..b10446b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/ObjectParameter.java
@@ -0,0 +1,102 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.describeresource;
+
+import java.util.List;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ObjectParameter {
+	
+	private String name;
+	private boolean fixed;
+	private String type;
+	List<ObjectConstraint> constraints;
+	
+	public String getName() {
+		return name;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public boolean isFixed() {
+		return fixed;
+	}
+	
+	public void setFixed(boolean fixed) {
+		this.fixed = fixed;
+	}
+	
+	public String getType() {
+		return type;
+	}
+	
+	public void setType(String type) {
+		this.type = type;
+	}
+	
+	public List<ObjectConstraint> getConstraints() {
+		return constraints;
+	}
+	
+	public void setConstraints(List<ObjectConstraint> constraints) {
+		this.constraints = constraints;
+	}
+		
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((constraints == null) ? 0 : constraints.hashCode());
+		result = prime * result + (fixed ? 1231 : 1237);
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		return result;
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ObjectParameter other = (ObjectParameter) obj;
+		if (constraints == null) {
+			if (other.constraints != null)
+				return false;
+		} else if (!constraints.equals(other.constraints))
+			return false;
+		if (fixed != other.fixed)
+			return false;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		if (type == null) {
+			if (other.type != null)
+				return false;
+		} else if (!type.equals(other.type))
+			return false;
+		return true;
+	}
+	
+	@Override
+	public String toString() {
+		return "ObjectParameter [name=" + name + ", fixed=" + fixed + ", type=" + type + ", constraints=" + constraints
+				+ "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/ObjectResponse.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/ObjectResponse.java
new file mode 100644
index 0000000..2dc3c72
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/ObjectResponse.java
@@ -0,0 +1,105 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.describeresource;
+
+import java.util.List;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ObjectResponse {
+	
+	private String name;
+	private String type;
+	private List<ObjectAttribute> attributes;
+	private List<ObjectAccessMethods> accessMethods;
+	
+	public String getName() {
+		return name;
+	}
+	
+	public void setName(String name) {
+		this.name = name;
+	}
+	
+	public String getType() {
+		return type;
+	}
+	
+	public void setType(String type) {
+		this.type = type;
+	}
+	
+	public List<ObjectAttribute> getAttributes() {
+		return attributes;
+	}
+	
+	public void setAttributes(List<ObjectAttribute> attributes) {
+		this.attributes = attributes;
+	}
+	
+	public List<ObjectAccessMethods> getAccessMethods() {
+		return accessMethods;
+	}
+	
+	public void setAccessMethods(List<ObjectAccessMethods> accessMethods) {
+		this.accessMethods = accessMethods;
+	}
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((accessMethods == null) ? 0 : accessMethods.hashCode());
+		result = prime * result + ((attributes == null) ? 0 : attributes.hashCode());
+		result = prime * result + ((name == null) ? 0 : name.hashCode());
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		return result;
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ObjectResponse other = (ObjectResponse) obj;
+		if (accessMethods == null) {
+			if (other.accessMethods != null)
+				return false;
+		} else if (!accessMethods.equals(other.accessMethods))
+			return false;
+		if (attributes == null) {
+			if (other.attributes != null)
+				return false;
+		} else if (!attributes.equals(other.attributes))
+			return false;
+		if (name == null) {
+			if (other.name != null)
+				return false;
+		} else if (!name.equals(other.name))
+			return false;
+		if (type == null) {
+			if (other.type != null)
+				return false;
+		} else if (!type.equals(other.type))
+			return false;
+		return true;
+	}
+	
+	@Override
+	public String toString() {
+		return "ObjectResponse [name=" + name + ", type=" + type + ", attributes=" + attributes + ", accessMethods="
+				+ accessMethods + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/package-info.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/package-info.java
new file mode 100644
index 0000000..a39ca00
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/describeresource/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.messages.snamessage.describeresource;
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/getresponse/MsgGetResponse.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/getresponse/MsgGetResponse.java
new file mode 100644
index 0000000..87c41a6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/getresponse/MsgGetResponse.java
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.getresponse;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+import org.eclipse.sensinact.studio.http.messages.snamessage.ObjectNameTypeValue;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgGetResponse extends MsgSensinact {
+
+	public static final String KEY = "GET_RESPONSE";
+	
+	private ObjectNameTypeValue response;
+	private String uri;
+	private int statusCode;
+	
+	public MsgGetResponse() {
+		super(KEY);
+	}
+
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.RESPONSE;
+	}
+	
+	public ObjectNameTypeValue getResponse() {
+		return response;
+	}
+
+	public void setResponse(ObjectNameTypeValue response) {
+		this.response = response;
+	}
+
+	public String getUri() {
+		return uri;
+	}
+
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+
+	public int getStatusCode() {
+		return statusCode;
+	}
+
+	public void setStatusCode(int statusCode) {
+		this.statusCode = statusCode;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((response == null) ? 0 : response.hashCode());
+		result = prime * result + statusCode;
+		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgGetResponse other = (MsgGetResponse) obj;
+		if (response == null) {
+			if (other.response != null)
+				return false;
+		} else if (!response.equals(other.response))
+			return false;
+		if (statusCode != other.statusCode)
+			return false;
+		if (uri == null) {
+			if (other.uri != null)
+				return false;
+		} else if (!uri.equals(other.uri))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "MsgGetResponse [response=" + response + ", uri=" + uri + ", statusCode=" + statusCode + "]";
+	}
+}
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/getresponse/package-info.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/getresponse/package-info.java
new file mode 100644
index 0000000..0192c45
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/getresponse/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.messages.snamessage.getresponse;
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/MsgProviderAppearing.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/MsgProviderAppearing.java
new file mode 100644
index 0000000..9896bc2
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/MsgProviderAppearing.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgProviderAppearing extends MsgSensinact {
+	
+	public static final String KEY = "PROVIDER_APPEARING";
+	
+	private String type;
+	private String uri;
+	private ObjectNotificationWithType notification;
+	
+	public MsgProviderAppearing() {
+		super(KEY);
+	}
+
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.LIFECYCLE;
+	}
+
+	public String getUri() {
+		return uri;
+	}
+
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+
+	public ObjectNotificationWithType getNotification() {
+		return notification;
+	}
+
+	public void setNotification(ObjectNotificationWithType notification) {
+		this.notification = notification;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((notification == null) ? 0 : notification.hashCode());
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgProviderAppearing other = (MsgProviderAppearing) obj;
+		if (notification == null) {
+			if (other.notification != null)
+				return false;
+		} else if (!notification.equals(other.notification))
+			return false;
+		if (type == null) {
+			if (other.type != null)
+				return false;
+		} else if (!type.equals(other.type))
+			return false;
+		if (uri == null) {
+			if (other.uri != null)
+				return false;
+		} else if (!uri.equals(other.uri))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "MsgProviderAppearing [type=" + type + ", uri=" + uri + ", notification=" + notification + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/MsgProviderDisappearing.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/MsgProviderDisappearing.java
new file mode 100644
index 0000000..f4073d9
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/MsgProviderDisappearing.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgProviderDisappearing extends MsgSensinact {
+	
+	public static final String KEY = "PROVIDER_DISAPPEARING";
+	
+	private String type;
+	private String uri;
+	private ObjectNotification notification;
+	
+	public MsgProviderDisappearing() {
+		super(KEY);
+	}
+
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.LIFECYCLE;
+	}
+
+	public String getUri() {
+		return uri;
+	}
+
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+
+	public ObjectNotification getNotification() {
+		return notification;
+	}
+
+	public void setNotification(ObjectNotification notification) {
+		this.notification = notification;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((notification == null) ? 0 : notification.hashCode());
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgProviderDisappearing other = (MsgProviderDisappearing) obj;
+		if (notification == null) {
+			if (other.notification != null)
+				return false;
+		} else if (!notification.equals(other.notification))
+			return false;
+		if (type == null) {
+			if (other.type != null)
+				return false;
+		} else if (!type.equals(other.type))
+			return false;
+		if (uri == null) {
+			if (other.uri != null)
+				return false;
+		} else if (!uri.equals(other.uri))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "MsgProviderDisappearing [type=" + type + ", uri=" + uri + ", notification=" + notification + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/MsgResourceAppearing.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/MsgResourceAppearing.java
new file mode 100644
index 0000000..9c09900
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/MsgResourceAppearing.java
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+import org.eclipse.sensinact.studio.http.messages.snamessage.ObjectNameTypeValue;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgResourceAppearing extends MsgSensinact {
+
+	public static final String KEY = "RESOURCE_APPEARING";
+	
+	private String type;
+	private String uri;
+	private ObjectNotificationWithType notification;
+	private ObjectNameTypeValue initial;
+	
+	public MsgResourceAppearing() {
+		super(KEY);
+	}
+
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.LIFECYCLE;
+	}
+
+	public String getUri() {
+		return uri;
+	}
+
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+
+	public ObjectNotificationWithType getNotification() {
+		return notification;
+	}
+
+	public void setNotification(ObjectNotificationWithType notification) {
+		this.notification = notification;
+	}
+	
+	public ObjectNameTypeValue getInitial() {
+		return initial;
+	}
+	
+	public void setInitial(ObjectNameTypeValue initial) {
+		this.initial = initial;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((initial == null) ? 0 : initial.hashCode());
+		result = prime * result + ((notification == null) ? 0 : notification.hashCode());
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgResourceAppearing other = (MsgResourceAppearing) obj;
+		if (initial == null) {
+			if (other.initial != null)
+				return false;
+		} else if (!initial.equals(other.initial))
+			return false;
+		if (notification == null) {
+			if (other.notification != null)
+				return false;
+		} else if (!notification.equals(other.notification))
+			return false;
+		if (type == null) {
+			if (other.type != null)
+				return false;
+		} else if (!type.equals(other.type))
+			return false;
+		if (uri == null) {
+			if (other.uri != null)
+				return false;
+		} else if (!uri.equals(other.uri))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "MsgResourceAppearing [type=" + type + ", uri=" + uri + ", notification=" + notification + ", initial="
+				+ initial + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/MsgResourceDisappearing.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/MsgResourceDisappearing.java
new file mode 100644
index 0000000..ae1b226
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/MsgResourceDisappearing.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgResourceDisappearing extends MsgSensinact {
+
+	public static final String KEY = "RESOURCE_DISAPPEARING";
+	
+	private String type;
+	private String uri;
+	private ObjectNotification notification;
+	
+	public MsgResourceDisappearing() {
+		super(KEY);
+	}
+
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.LIFECYCLE;
+	}
+
+	public String getUri() {
+		return uri;
+	}
+
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+
+	public ObjectNotification getNotification() {
+		return notification;
+	}
+
+	public void setNotification(ObjectNotification notification) {
+		this.notification = notification;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((notification == null) ? 0 : notification.hashCode());
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgResourceDisappearing other = (MsgResourceDisappearing) obj;
+		if (notification == null) {
+			if (other.notification != null)
+				return false;
+		} else if (!notification.equals(other.notification))
+			return false;
+		if (type == null) {
+			if (other.type != null)
+				return false;
+		} else if (!type.equals(other.type))
+			return false;
+		if (uri == null) {
+			if (other.uri != null)
+				return false;
+		} else if (!uri.equals(other.uri))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "MsgResourceDisappearing [type=" + type + ", uri=" + uri + ", notification=" + notification + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/MsgServiceAppearing.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/MsgServiceAppearing.java
new file mode 100644
index 0000000..a1650e5
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/MsgServiceAppearing.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgServiceAppearing extends MsgSensinact {
+	
+	public static final String KEY = "SERVICE_APPEARING";
+	
+	private String type;
+	private String uri;
+	private ObjectNotification notification;
+	
+	public MsgServiceAppearing() {
+		super(KEY);
+	}
+
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.LIFECYCLE;
+	}
+
+	public String getUri() {
+		return uri;
+	}
+
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+
+	public ObjectNotification getNotification() {
+		return notification;
+	}
+
+	public void setNotification(ObjectNotification notification) {
+		this.notification = notification;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((notification == null) ? 0 : notification.hashCode());
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgServiceAppearing other = (MsgServiceAppearing) obj;
+		if (notification == null) {
+			if (other.notification != null)
+				return false;
+		} else if (!notification.equals(other.notification))
+			return false;
+		if (type == null) {
+			if (other.type != null)
+				return false;
+		} else if (!type.equals(other.type))
+			return false;
+		if (uri == null) {
+			if (other.uri != null)
+				return false;
+		} else if (!uri.equals(other.uri))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "MsgServiceAppearing [type=" + type + ", uri=" + uri + ", notification=" + notification + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/MsgServiceDisappearing.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/MsgServiceDisappearing.java
new file mode 100644
index 0000000..8d01316
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/MsgServiceDisappearing.java
@@ -0,0 +1,93 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgServiceDisappearing extends MsgSensinact {
+	
+	public static final String KEY = "SERVICE_DISAPPEARING";
+	
+	private String type;
+	private String uri;
+	private ObjectNotification notification;
+	
+	public MsgServiceDisappearing() {
+		super(KEY);
+	}
+
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.LIFECYCLE;
+	}
+
+	public String getUri() {
+		return uri;
+	}
+
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+
+	public ObjectNotification getNotification() {
+		return notification;
+	}
+
+	public void setNotification(ObjectNotification notification) {
+		this.notification = notification;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((notification == null) ? 0 : notification.hashCode());
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgServiceDisappearing other = (MsgServiceDisappearing) obj;
+		if (notification == null) {
+			if (other.notification != null)
+				return false;
+		} else if (!notification.equals(other.notification))
+			return false;
+		if (type == null) {
+			if (other.type != null)
+				return false;
+		} else if (!type.equals(other.type))
+			return false;
+		if (uri == null) {
+			if (other.uri != null)
+				return false;
+		} else if (!uri.equals(other.uri))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "MsgServiceDisappearing [type=" + type + ", uri=" + uri + ", notification=" + notification + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/ObjectNotification.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/ObjectNotification.java
new file mode 100644
index 0000000..c1f2ce2
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/ObjectNotification.java
@@ -0,0 +1,57 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ObjectNotification {
+
+	private String lifecycle;
+
+	public String getLifecycle() {
+		return lifecycle;
+	}
+
+	public void setLifecycle(String lifecycle) {
+		this.lifecycle = lifecycle;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((lifecycle == null) ? 0 : lifecycle.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ObjectNotification other = (ObjectNotification) obj;
+		if (lifecycle == null) {
+			if (other.lifecycle != null)
+				return false;
+		} else if (!lifecycle.equals(other.lifecycle))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "ObjectNotification [lifecycle=" + lifecycle + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/ObjectNotificationWithType.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/ObjectNotificationWithType.java
new file mode 100644
index 0000000..877e719
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/ObjectNotificationWithType.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ObjectNotificationWithType {
+	
+	private String lifecycle;
+	private String type;
+	
+	public String getLifecycle() {
+		return lifecycle;
+	}
+	
+	public void setLifecycle(String lifecycle) {
+		this.lifecycle = lifecycle;
+	}
+	
+	public String getType() {
+		return type;
+	}
+	
+	public void setType(String type) {
+		this.type = type;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((lifecycle == null) ? 0 : lifecycle.hashCode());
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ObjectNotificationWithType other = (ObjectNotificationWithType) obj;
+		if (lifecycle == null) {
+			if (other.lifecycle != null)
+				return false;
+		} else if (!lifecycle.equals(other.lifecycle))
+			return false;
+		if (type == null) {
+			if (other.type != null)
+				return false;
+		} else if (!type.equals(other.type))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "ObjectNotificationWithType [lifecycle=" + lifecycle + ", type=" + type + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/package-info.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/package-info.java
new file mode 100644
index 0000000..d880c0c
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/lifecycle/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle;
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/package-info.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/package-info.java
new file mode 100644
index 0000000..1a157e5
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.messages.snamessage;
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/resourceslist/MsgResourcesList.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/resourceslist/MsgResourcesList.java
new file mode 100644
index 0000000..dc62d9a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/resourceslist/MsgResourcesList.java
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.resourceslist;
+
+import java.util.List;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgResourcesList extends MsgSensinact {
+	
+	public static final String KEY = "RESOURCES_LIST";
+	
+	private String uri;
+	private int statusCode;
+	private List<String> resources;
+	
+	public MsgResourcesList() {
+		super(KEY);
+	}
+
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.OTHER;
+	}
+	
+	public String getUri() {
+		return uri;
+	}
+
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+
+	public int getStatusCode() {
+		return statusCode;
+	}
+
+	public void setStatusCode(int statusCode) {
+		this.statusCode = statusCode;
+	}
+
+	public List<String> getResources() {
+		return resources;
+	}
+
+	public void setResources(List<String> resources) {
+		this.resources = resources;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((resources == null) ? 0 : resources.hashCode());
+		result = prime * result + statusCode;
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgResourcesList other = (MsgResourcesList) obj;
+		if (resources == null) {
+			if (other.resources != null)
+				return false;
+		} else if (!resources.equals(other.resources))
+			return false;
+		if (statusCode != other.statusCode)
+			return false;
+		if (type == null) {
+			if (other.type != null)
+				return false;
+		} else if (!type.equals(other.type))
+			return false;
+		if (uri == null) {
+			if (other.uri != null)
+				return false;
+		} else if (!uri.equals(other.uri))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "MsgResourcesList [type=" + type + ", uri=" + uri + ", statusCode=" + statusCode + ", resources="
+				+ resources + "]";
+	}	
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/resourceslist/package-info.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/resourceslist/package-info.java
new file mode 100644
index 0000000..35f70f0
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/resourceslist/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.messages.snamessage.resourceslist;
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/serviceslist/MsgServicesList.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/serviceslist/MsgServicesList.java
new file mode 100644
index 0000000..a1040ea
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/serviceslist/MsgServicesList.java
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.serviceslist;
+
+import java.util.List;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgServicesList extends MsgSensinact {
+	
+	public static final String KEY = "SERVICES_LIST";
+	
+	private String uri;
+	private int statusCode;
+	private List<String> services;
+	
+	public MsgServicesList() {
+		super(KEY);
+	}
+
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.OTHER;
+	}
+	
+	public String getUri() {
+		return uri;
+	}
+
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+
+	public int getStatusCode() {
+		return statusCode;
+	}
+
+	public void setStatusCode(int statusCode) {
+		this.statusCode = statusCode;
+	}
+
+	public List<String> getServices() {
+		return services;
+	}
+
+	public void setServices(List<String> services) {
+		this.services = services;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((services == null) ? 0 : services.hashCode());
+		result = prime * result + statusCode;
+		result = prime * result + ((type == null) ? 0 : type.hashCode());
+		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgServicesList other = (MsgServicesList) obj;
+		if (services == null) {
+			if (other.services != null)
+				return false;
+		} else if (!services.equals(other.services))
+			return false;
+		if (statusCode != other.statusCode)
+			return false;
+		if (type == null) {
+			if (other.type != null)
+				return false;
+		} else if (!type.equals(other.type))
+			return false;
+		if (uri == null) {
+			if (other.uri != null)
+				return false;
+		} else if (!uri.equals(other.uri))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "MsgServicesList [type=" + type + ", uri=" + uri + ", statusCode=" + statusCode + ", services="
+				+ services + "]";
+	}	
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/serviceslist/package-info.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/serviceslist/package-info.java
new file mode 100644
index 0000000..ef255b0
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/serviceslist/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.messages.snamessage.serviceslist;
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/setresponse/MsgSetResponse.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/setresponse/MsgSetResponse.java
new file mode 100644
index 0000000..2dcc2e8
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/setresponse/MsgSetResponse.java
@@ -0,0 +1,99 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.setresponse;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+import org.eclipse.sensinact.studio.http.messages.snamessage.ObjectNameTypeValue;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgSetResponse extends MsgSensinact {
+
+	public static final String KEY = "SET_RESPONSE";
+	
+	private ObjectNameTypeValue response;
+	private String uri;
+	private int statusCode;
+	
+	public MsgSetResponse() {
+		super(KEY);
+	}
+
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.RESPONSE;
+	}
+	
+	public ObjectNameTypeValue getResponse() {
+		return response;
+	}
+
+	public void setResponse(ObjectNameTypeValue response) {
+		this.response = response;
+	}
+
+	public String getUri() {
+		return uri;
+	}
+
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+
+	public int getStatusCode() {
+		return statusCode;
+	}
+
+	public void setStatusCode(int statusCode) {
+		this.statusCode = statusCode;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((response == null) ? 0 : response.hashCode());
+		result = prime * result + statusCode;
+		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgSetResponse other = (MsgSetResponse) obj;
+		if (response == null) {
+			if (other.response != null)
+				return false;
+		} else if (!response.equals(other.response))
+			return false;
+		if (statusCode != other.statusCode)
+			return false;
+		if (uri == null) {
+			if (other.uri != null)
+				return false;
+		} else if (!uri.equals(other.uri))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "MsgSetResponse [response=" + response + ", uri=" + uri + ", statusCode=" + statusCode + "]";
+	}
+}
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/setresponse/package-info.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/setresponse/package-info.java
new file mode 100644
index 0000000..0086e3c
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/setresponse/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.messages.snamessage.setresponse;
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/subscriberesponse/MsgSubscribeResponse.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/subscriberesponse/MsgSubscribeResponse.java
new file mode 100644
index 0000000..7869056
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/subscriberesponse/MsgSubscribeResponse.java
@@ -0,0 +1,98 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.subscriberesponse;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgSubscribeResponse extends MsgSensinact {
+
+	public static final String KEY = "SUBSCRIBE_RESPONSE";
+	
+	private ObjectResponse response;
+	private String uri;
+	private int statusCode;
+	
+	public MsgSubscribeResponse() {
+		super(KEY);
+	}
+
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.RESPONSE;
+	}
+
+	public ObjectResponse getResponse() {
+		return response;
+	}
+
+	public void setResponse(ObjectResponse response) {
+		this.response = response;
+	}
+
+	public String getUri() {
+		return uri;
+	}
+
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+
+	public int getStatusCode() {
+		return statusCode;
+	}
+
+	public void setStatusCode(int statusCode) {
+		this.statusCode = statusCode;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((response == null) ? 0 : response.hashCode());
+		result = prime * result + statusCode;
+		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgSubscribeResponse other = (MsgSubscribeResponse) obj;
+		if (response == null) {
+			if (other.response != null)
+				return false;
+		} else if (!response.equals(other.response))
+			return false;
+		if (statusCode != other.statusCode)
+			return false;
+		if (uri == null) {
+			if (other.uri != null)
+				return false;
+		} else if (!uri.equals(other.uri))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "MsgSubscribeResponse [response=" + response + ", uri=" + uri + ", statusCode=" + statusCode + "]";
+	}	
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/subscriberesponse/ObjectResponse.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/subscriberesponse/ObjectResponse.java
new file mode 100644
index 0000000..14d6390
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/subscriberesponse/ObjectResponse.java
@@ -0,0 +1,75 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.subscriberesponse;
+
+import java.util.Optional;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.ObjectNameTypeValue;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ObjectResponse {
+	private String subscriptionId;
+	private Optional<ObjectNameTypeValue> initial = Optional.empty();
+	
+	public String getSubscriptionId() {
+		return subscriptionId;
+	}
+
+	public void setSubscriptionId(String subscriptionId) {
+		this.subscriptionId = subscriptionId;
+	}
+	
+	public Optional<ObjectNameTypeValue> getInitial() {
+		return initial;
+	}
+	
+	public void setInitial(ObjectNameTypeValue initial) {
+		this.initial = Optional.of(initial);
+	}
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((initial == null) ? 0 : initial.hashCode());
+		result = prime * result + ((subscriptionId == null) ? 0 : subscriptionId.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ObjectResponse other = (ObjectResponse) obj;
+		if (initial == null) {
+			if (other.initial != null)
+				return false;
+		} else if (!initial.equals(other.initial))
+			return false;
+		if (subscriptionId == null) {
+			if (other.subscriptionId != null)
+				return false;
+		} else if (!subscriptionId.equals(other.subscriptionId))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "ObjectResponse [subscriptionId=" + subscriptionId + ", initial=" + initial + "]";
+	}	
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/subscriberesponse/package-info.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/subscriberesponse/package-info.java
new file mode 100644
index 0000000..98d9199
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/subscriberesponse/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.messages.snamessage.subscriberesponse;
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/tokencreation/MsgTokenCreation.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/tokencreation/MsgTokenCreation.java
new file mode 100644
index 0000000..515e62b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/tokencreation/MsgTokenCreation.java
@@ -0,0 +1,111 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.tokencreation;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgTokenCreation extends MsgSensinact {
+
+	public static final String KEY = "TOKEN_CREATION";
+	
+	private long generated;
+	private long validUntil;
+	private String uri;
+	private String token;
+	
+	public MsgTokenCreation() {
+		super(KEY);
+	}
+	
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.OTHER;
+	}
+	
+	public long getGenerated() {
+		return generated;
+	}
+	
+	public void setGenerated(long generated) {
+		this.generated = generated;
+	}
+	
+	public long getValidUntil() {
+		return validUntil;
+	}
+	
+	public void setValidUntil(long validUntil) {
+		this.validUntil = validUntil;
+	}
+	
+	public String getUri() {
+		return uri;
+	}
+	
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+	
+	public String getToken() {
+		return token;
+	}
+	
+	public void setToken(String token) {
+		this.token = token;
+	}
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + (int) (generated ^ (generated >>> 32));
+		result = prime * result + ((token == null) ? 0 : token.hashCode());
+		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+		result = prime * result + (int) (validUntil ^ (validUntil >>> 32));
+		return result;
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgTokenCreation other = (MsgTokenCreation) obj;
+		if (generated != other.generated)
+			return false;
+		if (token == null) {
+			if (other.token != null)
+				return false;
+		} else if (!token.equals(other.token))
+			return false;
+		if (uri == null) {
+			if (other.uri != null)
+				return false;
+		} else if (!uri.equals(other.uri))
+			return false;
+		if (validUntil != other.validUntil)
+			return false;
+		return true;
+	}
+	
+	@Override
+	public String toString() {
+		return "MsgTokenCreation [generated=" + generated + ", validUntil=" + validUntil + ", uri=" + uri + ", token="
+				+ token + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/tokencreation/package-info.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/tokencreation/package-info.java
new file mode 100644
index 0000000..b8e6e39
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/tokencreation/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.messages.snamessage.tokencreation;
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/unsubscriberesponse/MsgUnsubscribeResponse.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/unsubscriberesponse/MsgUnsubscribeResponse.java
new file mode 100644
index 0000000..9b650a6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/unsubscriberesponse/MsgUnsubscribeResponse.java
@@ -0,0 +1,98 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.unsubscriberesponse;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MsgUnsubscribeResponse extends MsgSensinact {
+
+	public static final String KEY = "UNSUBSCRIBE_RESPONSE";
+	
+	private ObjectResponse response;
+	private String uri;
+	private int statusCode;
+
+	public MsgUnsubscribeResponse() {
+		super(KEY);
+	}
+
+	@Override
+	public MsgCategory getCategory() {
+		return MsgCategory.RESPONSE;
+	}
+	
+	public ObjectResponse getResponse() {
+		return response;
+	}
+
+	public void setResponse(ObjectResponse response) {
+		this.response = response;
+	}
+
+	public String getUri() {
+		return uri;
+	}
+
+	public void setUri(String uri) {
+		this.uri = uri;
+	}
+
+	public int getStatusCode() {
+		return statusCode;
+	}
+
+	public void setStatusCode(int statusCode) {
+		this.statusCode = statusCode;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((response == null) ? 0 : response.hashCode());
+		result = prime * result + statusCode;
+		result = prime * result + ((uri == null) ? 0 : uri.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		MsgUnsubscribeResponse other = (MsgUnsubscribeResponse) obj;
+		if (response == null) {
+			if (other.response != null)
+				return false;
+		} else if (!response.equals(other.response))
+			return false;
+		if (statusCode != other.statusCode)
+			return false;
+		if (uri == null) {
+			if (other.uri != null)
+				return false;
+		} else if (!uri.equals(other.uri))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "MsgUnsubscribeResponse [response=" + response + ", uri=" + uri + ", statusCode=" + statusCode + "]";
+	}
+}
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/unsubscriberesponse/ObjectResponse.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/unsubscriberesponse/ObjectResponse.java
new file mode 100644
index 0000000..f9be966
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/unsubscriberesponse/ObjectResponse.java
@@ -0,0 +1,56 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.messages.snamessage.unsubscriberesponse;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ObjectResponse {
+	private String message;
+
+	public String getMessage() {
+		return message;
+	}
+
+	public void setMessage(String message) {
+		this.message = message;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((message == null) ? 0 : message.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		ObjectResponse other = (ObjectResponse) obj;
+		if (message == null) {
+			if (other.message != null)
+				return false;
+		} else if (!message.equals(other.message))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "ObjectResponse [message=" + message + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/unsubscriberesponse/package-info.java b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/unsubscriberesponse/package-info.java
new file mode 100644
index 0000000..f9b8dea
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.messages/src/org/eclipse/sensinact/studio/http/messages/snamessage/unsubscriberesponse/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.messages.snamessage.unsubscriberesponse;
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/.classpath b/bnd/org.eclipse.sensinact.studio.http.services/.classpath
new file mode 100644
index 0000000..7a6fc25
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="src" output="bin" path="src"/>
+	<classpathentry kind="src" output="bin_test" path="test">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/.gitignore b/bnd/org.eclipse.sensinact.studio.http.services/.gitignore
new file mode 100644
index 0000000..c2b941a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/.gitignore
@@ -0,0 +1,2 @@
+/bin_test/
+/generated/
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/.project b/bnd/org.eclipse.sensinact.studio.http.services/.project
new file mode 100644
index 0000000..7b0e849
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.sensinact.studio.http.services</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+	</natures>
+</projectDescription>
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/.settings/org.eclipse.jdt.core.prefs b/bnd/org.eclipse.sensinact.studio.http.services/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..0c68a61
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,7 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8
+org.eclipse.jdt.core.compiler.compliance=1.8
+org.eclipse.jdt.core.compiler.problem.assertIdentifier=error
+org.eclipse.jdt.core.compiler.problem.enumIdentifier=error
+org.eclipse.jdt.core.compiler.source=1.8
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/bnd.bnd b/bnd/org.eclipse.sensinact.studio.http.services/bnd.bnd
new file mode 100644
index 0000000..cffd46b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/bnd.bnd
@@ -0,0 +1,14 @@
+Bundle-Version: 1.0.0.SNAPSHOT
+-buildpath: \
+	org.eclipse.sensinact.studio.preferences,\
+	org.apache.log4j,\
+	org.eclipse.sensinact.studio.http.messages,\
+	org.eclipse.sensinact.studio.model.resource,\
+	org.restlet,\
+	json,\
+	org.eclipse.emf.common,\
+	org.eclipse.jetty.websocket.client,\
+	org.eclipse.jetty.websocket.common,\
+	org.eclipse.jetty.websocket.api,\
+	osgi.annotation,\
+	org.eclipse.jetty.util
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/AccessToken.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/AccessToken.java
new file mode 100644
index 0000000..17fba03
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/AccessToken.java
@@ -0,0 +1,40 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.client;
+
+import java.util.Date;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.tokencreation.MsgTokenCreation;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class AccessToken {
+	
+	private final String token;
+	private final long generated;
+	private final long validUntil;
+	
+	public AccessToken(MsgTokenCreation reponse) {
+		this.token = reponse.getToken();
+		this.generated = reponse.getGenerated();
+		this.validUntil = reponse.getValidUntil();
+	}
+
+	public boolean isValid() {
+		Date now = new Date();
+		return now.before(new Date(validUntil));
+	}
+	
+	public String getToken() {
+		return token;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/BasicConfigurator.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/BasicConfigurator.java
new file mode 100644
index 0000000..6259b3b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/BasicConfigurator.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.client;
+
+import org.eclipse.sensinact.studio.preferences.GatewayHttpConfig;
+import org.restlet.resource.ClientResource;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class BasicConfigurator implements RequestConfigurator {
+	@Override
+	public void configure(GatewayHttpConfig gwInfo, ClientResource clientResource) {
+		// do nothing
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/GatewayHttpClient.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/GatewayHttpClient.java
new file mode 100644
index 0000000..ddba65a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/GatewayHttpClient.java
@@ -0,0 +1,231 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.client;
+
+import java.io.IOException;
+import java.io.StringWriter;
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgFactory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+import org.eclipse.sensinact.studio.http.messages.snamessage.tokencreation.MsgTokenCreation;
+import org.eclipse.sensinact.studio.model.resource.utils.JsonUtil;
+import org.eclipse.sensinact.studio.model.resource.utils.Segments;
+import org.eclipse.sensinact.studio.preferences.ConfigurationManager;
+import org.eclipse.sensinact.studio.preferences.GatewayHttpConfig;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.restlet.Context;
+import org.restlet.Response;
+import org.restlet.data.Encoding;
+import org.restlet.data.MediaType;
+import org.restlet.data.Method;
+import org.restlet.data.Parameter;
+import org.restlet.data.Preference;
+import org.restlet.data.Status;
+import org.restlet.engine.application.DecodeRepresentation;
+import org.restlet.representation.Representation;
+import org.restlet.representation.StringRepresentation;
+import org.restlet.resource.ClientResource;
+
+/**
+ * Central point for SYNCHRONUS communication with the sensinact gateway.
+ * @author Etienne Gandrille
+ */
+public class GatewayHttpClient {
+		
+	private static final Logger logger = Logger.getLogger(GatewayHttpClient.class);
+	
+	private GatewayHttpClient() {
+		throw new IllegalArgumentException("Should not be instantiated!");
+	}
+
+	public static MsgSensinact sendGetRequest(Segments segments) throws IOException {
+		return sendGetRequest(segments, null);
+	}
+		
+	public static MsgSensinact sendGetRequest(Segments segments, Map<String, String> params) throws IOException {		
+		GatewayHttpConfig gwInfo = ConfigurationManager.getGateway(segments.getGateway());
+		
+		RequestConfigurator configurator = getRequestConfiguratorToken(gwInfo);
+		
+		return sendGetRequest(segments, gwInfo, params, configurator);
+	}
+		
+	private static RequestConfigurator getRequestConfiguratorToken(GatewayHttpConfig gwInfo) throws IOException {
+		if (gwInfo.hasAuthentication()) {
+			AccessToken token = getToken(gwInfo);
+			return new RequestConfiguratorToken(token);
+		} else {
+			return new BasicConfigurator();
+		}
+	}
+	
+	private static synchronized AccessToken getToken(GatewayHttpConfig gwInfo) throws IOException {
+		String gwName = gwInfo.getName();
+		AccessToken token = TokenStore.getInstance().getToken(gwName);
+		if (token != null && token.isValid())
+			return token;
+		
+		Segments segments = new Segments.Builder().gateway(gwInfo.getName()).login().build();
+		MsgSensinact reponse = sendGetRequest(segments, gwInfo, null, new RequestConfiguratorCred());
+		
+		if (reponse instanceof MsgTokenCreation) {
+			token = new AccessToken((MsgTokenCreation) reponse);
+			TokenStore.getInstance().save(gwName, token);
+			return token;
+		}
+		
+		return null;
+	}
+	
+	public static MsgSensinact sendPostRequest(Segments segments, Collection<Parameter> queryParameter,RequestParameter... parameters) throws IOException {
+		JSONArray jsonParameters = new JSONArray();
+		for (RequestParameter parameter : parameters) {
+			try {
+				jsonParameters.put(JsonUtil.createNameTypeValue(parameter.name, parameter.type, parameter.value));
+			} catch (JSONException e) {
+				throw new IOException(e);
+			}
+		}
+		return sendPostRequest(segments, jsonParameters,queryParameter);
+	}
+	
+	public static MsgSensinact sendPostRequest(Segments segments, JSONArray parameters,Collection<Parameter> queryParameter) throws IOException {
+		GatewayHttpConfig gwInfo = ConfigurationManager.getGateway(segments.getGateway());
+		RequestConfigurator configurator = getRequestConfiguratorToken(gwInfo);
+		
+		if (parameters==null || parameters.length() == 0)
+			return sendPostRequest(segments, "{}",queryParameter, configurator);
+		else
+			return sendPostRequest(segments, parameters.toString(), queryParameter, configurator);
+	}
+	
+	public static MsgSensinact sendPostRequest(Segments segments, JSONArray parameters) throws IOException {
+		GatewayHttpConfig gwInfo = ConfigurationManager.getGateway(segments.getGateway());
+		RequestConfigurator configurator = getRequestConfiguratorToken(gwInfo);
+		
+		if (parameters.length() == 0)
+			return sendPostRequest(segments, "{}", null, configurator);
+		else
+			return sendPostRequest(segments, parameters.toString(),null, configurator);
+	}
+
+	public static MsgSensinact sendPostRequest(Segments segments, JSONObject parameters) throws IOException {
+		GatewayHttpConfig gwInfo = ConfigurationManager.getGateway(segments.getGateway());
+		RequestConfigurator configurator = getRequestConfiguratorToken(gwInfo);
+		return sendPostRequest(segments, parameters.toString(), null, configurator);
+	}
+
+	/* ======== */
+	/* Internal */
+	/* ======== */
+
+	private static MsgSensinact sendGetRequest(Segments segments, GatewayHttpConfig gwInfo, Map<String, String> params, RequestConfigurator configurator) throws IOException {
+		ClientResource clientResource = new ClientResource(getContext(gwInfo.getTimeout()), gwInfo.getURL().toString());
+		configurator.configure(gwInfo, clientResource);
+		clientResource.setRetryOnError(false);
+		segments.addToClientResource(clientResource);
+		
+		if (params != null) {
+			for (String param : params.keySet()) {
+				clientResource.addQueryParameter(new Parameter(param, params.get(param)));			
+			}
+		}
+		
+		// Allow gzip encoding
+		clientResource.getClientInfo().getAcceptedEncodings().add(new Preference<Encoding>(Encoding.GZIP)); 
+				
+		String json = null;
+		MsgSensinact retval;
+		try {
+			Representation representation = clientResource.get();
+			if (representation.getEncodings().contains(Encoding.GZIP)) {
+				representation = new DecodeRepresentation(representation);
+			}
+			json = representation.getText();
+			representation.exhaust();
+			representation.release();
+			retval = MsgFactory.build(new JSONObject(json));
+		} catch (Exception e) {
+			retval = MsgFactory.build(json, e);
+		} 
+		
+		return retval;
+	}
+	
+	private static MsgSensinact sendPostRequest(Segments segments, String jsonRequest, Collection<Parameter> queryParameter, RequestConfigurator configurator) throws IOException {
+		GatewayHttpConfig gwInfo = ConfigurationManager.getGateway(segments.getGateway());		
+		ClientResource clientResource = new ClientResource(getContext(gwInfo.getTimeout()), Method.POST, gwInfo.getURL().toString()) {
+			@Override
+			public Representation handleInbound(Response response) {
+				return (response == null) ? null : response.getEntity();				
+			}
+		};
+		
+		configurator.configure(gwInfo, clientResource);
+		clientResource.setRetryOnError(false);
+		clientResource.getRequestAttributes();
+		segments.addToClientResource(clientResource);
+		StringRepresentation stringRep = new StringRepresentation(jsonRequest,MediaType.APPLICATION_JSON);
+		if(queryParameter != null){
+			clientResource.addQueryParameters(queryParameter);
+		}
+		
+		Representation postResponse = clientResource.post(stringRep);
+		if (postResponse == null) {
+			logger.error("postResponse is null for " + stringRep);
+		}
+		
+		Status status = clientResource.getResponse().getStatus();
+		
+		
+		int code = status.getCode();
+		
+		StringWriter sw = new StringWriter();
+		postResponse.write(sw);
+		String jsonResponse = sw.toString();
+
+		postResponse.exhaust();
+		postResponse.release();
+		
+		try {
+			return MsgFactory.build(new JSONObject(jsonResponse));
+		} catch (Exception e) {
+			logger.error(e.getMessage());
+			throw new IllegalArgumentException(jsonResponse, e);
+		}
+	}
+	
+	private static Context getContext(int timeout) throws IOException {
+		Context context = new Context();
+		context.getParameters().add("socketTimeout", Integer.toString(timeout));
+		context.getParameters().add("idleTimeout", Integer.toString(timeout));
+		context.getParameters().add("readTimeout", Integer.toString(timeout));
+		
+		return context;
+	}
+
+	public static class RequestParameter {
+		public final String name;
+		public final String type;
+		public final String value;
+
+		public RequestParameter(String name, String type, String value) {
+			this.name = name;
+			this.type = type;
+			this.value = value;
+		}
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/RequestConfigurator.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/RequestConfigurator.java
new file mode 100644
index 0000000..072865d
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/RequestConfigurator.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.client;
+
+import java.util.Map;
+
+import org.eclipse.sensinact.studio.preferences.GatewayHttpConfig;
+import org.restlet.engine.header.Header; // import org.restlet.data.Header;
+import org.restlet.resource.ClientResource;
+import org.restlet.util.Series;
+
+/**
+ * @author Etienne Gandrille
+ */
+public interface RequestConfigurator {	
+	public void configure(GatewayHttpConfig gwInfo, ClientResource clientResource);
+		
+	default Series<Header> getHeaders(ClientResource clientResource) {
+		String KEY = "org.restlet.http.headers";	
+		Map<String, Object> attr = clientResource.getRequestAttributes();
+		if (! attr.containsKey(KEY))
+			attr.put(KEY, new Series<>(Header.class));
+		Series<Header> headers = (Series<Header>) attr.get(KEY);
+		return headers;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/RequestConfiguratorCred.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/RequestConfiguratorCred.java
new file mode 100644
index 0000000..3d264bc
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/RequestConfiguratorCred.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.client;
+
+import org.eclipse.sensinact.studio.preferences.GatewayHttpConfig;
+import org.restlet.data.ChallengeScheme;
+import org.restlet.resource.ClientResource;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class RequestConfiguratorCred implements RequestConfigurator {
+	
+	@Override
+	public void configure(GatewayHttpConfig gwInfo, ClientResource clientResource) {
+		if (gwInfo.hasAuthentication())
+			setAuthentication(clientResource, gwInfo);
+	}
+	
+	private static void setAuthentication(ClientResource clientResource, GatewayHttpConfig gwInfo) {
+		clientResource.setChallengeResponse(ChallengeScheme.HTTP_BASIC, gwInfo.getUsername(), gwInfo.getPassword());
+	}
+	
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/RequestConfiguratorToken.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/RequestConfiguratorToken.java
new file mode 100644
index 0000000..6dc6783
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/RequestConfiguratorToken.java
@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.client;
+
+import org.eclipse.sensinact.studio.preferences.GatewayHttpConfig;
+import org.restlet.engine.header.Header; // import org.restlet.data.Header;
+import org.restlet.resource.ClientResource;
+import org.restlet.util.Series;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class RequestConfiguratorToken implements RequestConfigurator {
+
+
+	private final String HEADER = "X-AUTH-TOKEN"; 
+	private final AccessToken token;
+	
+	public RequestConfiguratorToken(AccessToken token) {
+		this.token = token;
+	}
+
+	@Override
+	public void configure(GatewayHttpConfig gwInfo, ClientResource clientResource) {
+		Series<Header> headers = getHeaders(clientResource);			
+		headers.set(HEADER, token.getToken());
+		// think twice before removing...
+		headers.set("Connection", "close");
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/StudioRequest.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/StudioRequest.java
new file mode 100644
index 0000000..887cf58
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/StudioRequest.java
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.client;
+
+import java.io.IOException;
+import java.util.Collection;
+
+import org.apache.log4j.Logger;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+import org.eclipse.sensinact.studio.http.messages.snamessage.actresponse.MsgActResponse;
+import org.eclipse.sensinact.studio.http.messages.snamessage.actresponse.ObjectResponse;
+import org.eclipse.sensinact.studio.http.messages.snamessage.getresponse.MsgGetResponse;
+import org.eclipse.sensinact.studio.http.services.client.UIResult.DialogStatus;
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+import org.eclipse.sensinact.studio.model.resource.utils.Segments;
+import org.eclipse.sensinact.studio.resource.AccessMethodType;
+import org.restlet.data.Parameter;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class StudioRequest {
+
+	private final ResourceDescriptor descriptor;
+	private final AccessMethodType type;
+	
+	private static final Logger logger = Logger.getLogger(StudioRequest.class);
+	
+	public StudioRequest(ResourceDescriptor descriptor, AccessMethodType type) {
+		this.descriptor = descriptor;
+		this.type = type;	
+	}
+	
+	public MsgSensinact sendRequest(Collection<Parameter> queryParameter){
+		Segments segments = new Segments.Builder().resource(descriptor).method(type).build();
+		try {
+			if (type.equals(AccessMethodType.GET)) 				
+				return GatewayHttpClient.sendGetRequest(segments);
+			else if (type.equals(AccessMethodType.ACT))
+				return GatewayHttpClient.sendPostRequest(segments,null,queryParameter);
+			else 
+				throw new IllegalArgumentException("BasicRequest not implemented with " + type.getName() + " method");
+		} catch (IOException e) {
+			throw new IllegalArgumentException("BasicRequest not implemented with " + type.getName() + " method");
+		}
+	}
+	
+	public MsgSensinact sendRequest() throws IOException {
+		return sendRequest(null);
+	}
+	
+	public UIResult sendRequestForIU() {
+		String title = descriptor.getDevice();
+		String message;
+		DialogStatus dialogType;
+		MsgSensinact response=null;
+		try {
+			response = sendRequest();
+			// errors 404,...
+			if (response instanceof MsgActResponse) {
+				MsgActResponse actResponse = (MsgActResponse) response;
+				ObjectResponse res = actResponse.getResponse();
+				if(res == null)
+					message = "ACTION SUCCEEDED";
+				else
+					message = res.getTask();
+				dialogType = DialogStatus.SUCCESS;
+			} else if (response instanceof MsgGetResponse) {
+				MsgGetResponse getResponse = (MsgGetResponse) response;
+				message = getResponse.getResponse().getValueAsString();
+				dialogType = DialogStatus.SUCCESS;
+			} else {
+				message = "Message type : " + response.getType();
+				dialogType = response.isValid() ? DialogStatus.SUCCESS : DialogStatus.ERROR;
+			}
+		} catch (Exception e) {
+			title = "Error";
+			message = e.getMessage();
+			dialogType = DialogStatus.ERROR;
+		}
+		logger.info(dialogType.toString() + " " + message);
+		return new UIResult(title, message, dialogType);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/TokenStore.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/TokenStore.java
new file mode 100644
index 0000000..bd11036
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/TokenStore.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.client;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+public class TokenStore {
+	
+	private final Map<String, AccessToken> tokens = new HashMap<>(); 
+
+	private static final Logger logger = Logger.getLogger(TokenStore.class);
+
+	private static TokenStore INSTANCE = null;
+
+	private TokenStore() {
+	}
+
+	public synchronized static TokenStore getInstance() {
+		if (INSTANCE == null)
+			INSTANCE = new TokenStore();
+		return INSTANCE;
+	}
+
+	public AccessToken getToken(String gwName) {
+		return tokens.get(gwName);
+	}
+
+	public void save(String gwName, AccessToken token) {
+		tokens.put(gwName, token);
+	}	
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/UIResult.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/UIResult.java
new file mode 100644
index 0000000..cb3281e
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/UIResult.java
@@ -0,0 +1,61 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.client;
+
+import org.apache.log4j.Logger;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class UIResult {
+	
+	private final String title;
+	private final String message;
+	private final DialogStatus status;
+	
+	private static final Logger logger = Logger.getLogger(UIResult.class);
+	
+	public UIResult(String title, String message, DialogStatus status) {
+		this.title = title;
+		this.message = message;
+		this.status = status;
+	}
+	
+	public String getTitle() {
+		return title;
+	}
+	
+	public String getMessage() {
+		return message;
+	}
+	
+	public DialogStatus getStatus() {
+		return status;
+	}
+	
+	public enum DialogStatus {
+		SUCCESS, ERROR;
+	}
+
+	public JSONObject asJson() {
+		JSONObject result = new JSONObject();
+		try {
+			result.put("title", title);
+			result.put("message", message);
+			result.put("status", status.name());
+		} catch (JSONException e) {
+			logger.error(e);
+		}
+		return result;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/agent/Agent.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/agent/Agent.java
new file mode 100644
index 0000000..4b55c58
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/agent/Agent.java
@@ -0,0 +1,158 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.client.agent;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+import org.eclipse.sensinact.studio.http.messages.snamessage.subscriberesponse.MsgSubscribeResponse;
+import org.eclipse.sensinact.studio.http.services.client.GatewayHttpClient;
+import org.eclipse.sensinact.studio.model.resource.utils.Segments;
+import org.eclipse.sensinact.studio.preferences.ConfigurationManager;
+import org.eclipse.sensinact.studio.preferences.GatewayHttpConfig;
+import org.eclipse.sensinact.studio.preferences.StudioHttpConfig;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.restlet.data.Status;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class Agent {
+
+	private static Agent INSTANCE = null;
+
+	private SubscriptionStorage storage = new SubscriptionStorage();
+	
+	private Agent() {
+	}
+	
+	public static Agent getInstance() {
+		if (INSTANCE == null)
+			INSTANCE = new Agent();
+		return INSTANCE;
+	}
+	
+	public void subscribe(GatewayHttpConfig gateway) throws JSONException, IOException {
+		
+		String gatewayName = gateway.getName();
+		Segments segments = new Segments.BuilderGateway(gatewayName).subscribeAgent().build();
+		String url = getCallbackUrl(gateway);
+		
+		String locId = getId(GatewayHttpClient.sendPostRequest(segments, createJsonForLocation(url)), url);
+		String lcId = getId(GatewayHttpClient.sendPostRequest(segments, createJsonForLifecycle(url)), url);
+		String icId = getId(GatewayHttpClient.sendPostRequest(segments, createJsonForIcon(url)), url);
+
+		storage.add(new Subscription(gatewayName, locId, lcId, icId));
+	}
+
+	public void unsubscribe(GatewayHttpConfig gateway) throws IOException, JSONException {
+		
+		String gatewayName = gateway.getName();
+		Segments segments = new Segments.BuilderGateway(gatewayName).unsubscribeAgent().build();
+
+		Subscription subscription = storage.getByGateway(gateway.getName());
+		if (subscription == null) {
+			throw new IllegalArgumentException("Can't get subscription for " + gatewayName);
+		}
+
+		GatewayHttpClient.sendPostRequest(segments, createJsonForUnscubscribe(subscription.getLocationId()));
+		GatewayHttpClient.sendPostRequest(segments, createJsonForUnscubscribe(subscription.getLifecycleId()));
+		
+		storage.remove(subscription);
+	}
+	
+	private static String getId(MsgSensinact msg, String url) {
+		if (msg instanceof MsgSubscribeResponse)
+			return ((MsgSubscribeResponse) msg).getResponse().getSubscriptionId();
+		throw new IllegalArgumentException("Can't get subscription on " + url);
+	}
+		
+	private static String getCallbackUrl(GatewayHttpConfig gateway) throws IOException {
+		int port = ConfigurationManager.getStudioPort();
+		StudioHttpConfig studioConfig = new StudioHttpConfig(gateway, port);
+		String url = studioConfig.getUrl().toString();
+		if (url == null || url.isEmpty())
+			throw new IOException("URL is not valid - subscribtion fail");
+		// TODO update this with a constant --> see also InitRoutes.java
+		url += "/callback";
+		return url;
+	}
+
+	private static JSONArray createJsonForLocation(String url) throws JSONException {
+		return createJson(url, "/[^/]+/admin/location(/[^/]+)?", "UPDATE");
+	}
+
+	private static JSONArray createJsonForIcon(String url) throws JSONException {
+		return createJson(url, "/[^/]+/admin/icon(/[^/]+)?", "UPDATE");
+	}
+	
+	private static JSONArray createJsonForLifecycle(String url) throws JSONException {
+		return createJson(url, "(/[^/]+)+", "LIFECYCLE");
+	}
+	
+	private static JSONArray createJsonForUnscubscribe(String subscriptionid) throws JSONException {
+		JSONArray array = new JSONArray();
+		array.put(nameTypeValue("subscriptionId", "string", subscriptionid));
+		return array;
+	}
+	
+	private static JSONArray createJson(String url, String sender, String type) throws JSONException {
+		JSONArray array = new JSONArray();
+		array.put(nameTypeValue("sender",     "string",  sender));
+		array.put(nameTypeValue("pattern",    "boolean", "true"));
+		array.put(nameTypeValue("complement", "boolean", "false"));
+		array.put(nameTypeValue("types",      "array",   "[\"" + type + "\"]"));
+		array.put(nameTypeValue("callback",   "string",  url));
+		return array;
+	}
+	
+	private static JSONObject nameTypeValue(String name, String type, String value) throws JSONException {
+		JSONObject retval = new JSONObject();
+		retval.put("name", name);
+		retval.put("type", type);
+		retval.put("value", value);
+		return retval;
+	}
+
+	public boolean isConnected(String name) {
+		return (storage.getByGateway(name) != null);
+	}
+
+	public Status callbackRecieved(String id, List<MsgSensinact> messages) {
+		
+		Subscription lifeSub = storage.getByLifecycleId(id);
+		Subscription locSub = storage.getByLocationId(id);
+		Subscription locIcon = storage.getByIconId(id);
+		
+		if (lifeSub != null) {
+			String gateway = lifeSub.getGatewayName();
+			SubscriptionManager.getInstance().notifyLifecycle(gateway, messages);			
+			return Status.SUCCESS_OK;	
+		}
+
+		if (locSub != null) {
+			String gateway = locSub.getGatewayName();
+			SubscriptionManager.getInstance().notifyLocation(gateway, messages);
+			return Status.SUCCESS_OK;	
+		}
+
+		if (locIcon != null) {
+			String gateway = locIcon.getGatewayName();
+			SubscriptionManager.getInstance().notifyLocation(gateway, messages);
+			return Status.SUCCESS_OK;	
+		}
+
+		return  Status.CLIENT_ERROR_NOT_FOUND;				
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/agent/Subscription.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/agent/Subscription.java
new file mode 100644
index 0000000..360a82d
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/agent/Subscription.java
@@ -0,0 +1,94 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.client.agent;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class Subscription {
+	
+	private final String gatewayName;
+	private final String locationId;
+	private final String lifecycleId;
+	private final String iconId;
+
+	public Subscription(String gatewayName, String locationId, String lifecycleId, String iconId) {
+		this.gatewayName = gatewayName;
+		this.locationId = locationId;
+		this.lifecycleId = lifecycleId;
+		this.iconId = iconId;
+	}
+
+	public String getGatewayName() {
+		return gatewayName;
+	}
+
+	public String getLocationId() {
+		return locationId;
+	}
+
+	public String getLifecycleId() {
+		return lifecycleId;
+	}
+
+	public String getIconId() {
+		return iconId;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((gatewayName == null) ? 0 : gatewayName.hashCode());
+		result = prime * result + ((lifecycleId == null) ? 0 : lifecycleId.hashCode());
+		result = prime * result + ((locationId == null) ? 0 : locationId.hashCode());
+		result = prime * result + ((iconId == null) ? 0 : iconId.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Subscription other = (Subscription) obj;
+		if (gatewayName == null) {
+			if (other.gatewayName != null)
+				return false;
+		} else if (!gatewayName.equals(other.gatewayName))
+			return false;
+		if (lifecycleId == null) {
+			if (other.lifecycleId != null)
+				return false;
+		} else if (!lifecycleId.equals(other.lifecycleId))
+			return false;
+		if (locationId == null) {
+			if (other.locationId != null)
+				return false;
+		} else if (!locationId.equals(other.locationId))
+			return false;
+		if (iconId == null) {
+			if (other.iconId != null)
+				return false;
+		} else if (!iconId.equals(other.iconId))
+			return false;
+		return true;
+	}
+
+	@Override
+	public String toString() {
+		return "Subscription [gatewayName=" + gatewayName + ", locationId=" + locationId + ", lifecycleId="
+				+ lifecycleId + ", iconId=" + lifecycleId + "]";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/agent/SubscriptionManager.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/agent/SubscriptionManager.java
new file mode 100644
index 0000000..9ca483d
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/agent/SubscriptionManager.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.client.agent;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+import org.eclipse.sensinact.studio.http.services.client.listener.NotifSubscriptionListener;
+
+
+/**
+ * @author Etienne Gandrille
+ */
+public class SubscriptionManager {
+
+	private static SubscriptionManager INSTANCE = null;
+	List<NotifSubscriptionListener> listeners = new ArrayList<NotifSubscriptionListener>();	
+	
+	public static SubscriptionManager getInstance() {
+		if (INSTANCE == null)
+			INSTANCE = new SubscriptionManager();
+		return INSTANCE;
+	}
+	
+	public SubscriptionManager() {
+	}
+
+	public void subscribe(NotifSubscriptionListener listener) {
+		listeners.add(listener);
+	}
+	
+	public void unsubscribe(NotifSubscriptionListener listener) {
+		listeners.remove(listener);
+	}
+	
+	void notifyLocation(String gateway, List<MsgSensinact> message) {
+		for (NotifSubscriptionListener listener : listeners)
+			listener.onLocationEvent(gateway, message);
+	}
+
+	void notifyIcon(String gateway, List<MsgSensinact> message) {
+		for (NotifSubscriptionListener listener : listeners)
+			listener.onIconEvent(gateway, message);
+	}
+	
+	void notifyLifecycle(String gateway, List<MsgSensinact> message) {
+		for (NotifSubscriptionListener listener : listeners)
+			listener.onLifecycleEvent(gateway, message);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/agent/SubscriptionStorage.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/agent/SubscriptionStorage.java
new file mode 100644
index 0000000..eca1a01
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/agent/SubscriptionStorage.java
@@ -0,0 +1,55 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.client.agent;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class SubscriptionStorage {
+		
+	private final Map<String, Subscription> byGatway = new HashMap<String, Subscription>();
+	private final Map<String, Subscription> byLocation = new HashMap<String, Subscription>();
+	private final Map<String, Subscription> byLifecycle = new HashMap<String, Subscription>();
+	private final Map<String, Subscription> byIcon = new HashMap<String, Subscription>();
+	
+	void add(Subscription subscription) {
+		byGatway.put(subscription.getGatewayName(), subscription);
+		byLocation.put(subscription.getLocationId(), subscription);
+		byLifecycle.put(subscription.getLifecycleId(), subscription);
+		byIcon.put(subscription.getIconId(), subscription);
+	}
+	
+	void remove(Subscription subscription) {
+		byGatway.remove(subscription.getGatewayName());
+		byLocation.remove(subscription.getLocationId());
+		byLifecycle.remove(subscription.getLifecycleId());
+		byIcon.remove(subscription.getIconId());
+	}
+	
+	public Subscription getByGateway(String gateway) {
+		return byGatway.get(gateway);
+	}
+	
+	public Subscription getByLocationId(String locationId) {
+		return byLocation.get(locationId);
+	}
+
+	public Subscription getByLifecycleId(String lifecycleId) {
+		return byLifecycle.get(lifecycleId);
+	}
+	
+	public Subscription getByIconId(String iconId) {
+		return byIcon.get(iconId);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/agent/package-info.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/agent/package-info.java
new file mode 100644
index 0000000..d2cf417
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/agent/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.services.client.agent;
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/connectionmanager/Connection.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/connectionmanager/Connection.java
new file mode 100644
index 0000000..dc4e4b2
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/connectionmanager/Connection.java
@@ -0,0 +1,79 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.client.connectionmanager;
+
+import java.net.ConnectException;
+import java.net.URI;
+
+import org.apache.log4j.Logger;
+import org.eclipse.jetty.websocket.client.ClientUpgradeRequest;
+import org.eclipse.jetty.websocket.client.WebSocketClient;
+
+public class Connection {
+
+	private final String gatewayName;
+	
+	private SensinactSocket socket;
+	private WebSocketClient client;
+	
+	private static final Logger logger = Logger.getLogger(Connection.class);
+	
+	public Connection(String gatewayName) {
+		this.gatewayName = gatewayName;
+	}
+	
+	boolean isConnected() {
+		return client != null && socket != null && socket.isConnected();
+	}
+
+	public void connect(URI url) throws ConnectException {
+		if (isConnected())
+			throw new ConnectException("Cant (re)connect gateway " + gatewayName + ": already connected");
+		ClientUpgradeRequest request = new ClientUpgradeRequest();
+		this.socket = new SensinactSocket(gatewayName);
+		this.client = new WebSocketClient();
+		
+		try {
+			client.start();
+			client.connect(socket, url, request);
+		} catch (Throwable t) {
+			throw new ConnectException("Cant (re)connect gateway " + gatewayName + ": " + t.getMessage());
+		}
+	}
+
+	public void disconnect() {
+		if ( ! isConnected()) {
+			logger.error("Can't disconnect " + gatewayName + ": gateway is NOT connected");
+		}
+		
+		boolean error = false;
+		if (client == null) {
+			logger.error("Can't disconnect " + gatewayName + " correctly: client is null");
+			error = true;
+		}
+		if (socket == null) {
+			logger.error("Can't disconnect " + gatewayName + " correctly: socket is null");
+			error = true;
+		}
+		
+		if (!error) {
+			try {
+				socket.send(gatewayName+": Bye bye");
+				client.stop();
+			} catch (Exception e) {
+				logger.error("Error closing websocket for gateway " + gatewayName, e);
+			}
+		}
+		
+		client = null;
+		socket = null;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/connectionmanager/ConnectionListener.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/connectionmanager/ConnectionListener.java
new file mode 100644
index 0000000..6e162b8
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/connectionmanager/ConnectionListener.java
@@ -0,0 +1,21 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.client.connectionmanager;
+
+/**
+ * @author Etienne Gandrille
+ */
+public interface ConnectionListener {
+
+	void onConnect(String gatewayname);
+	
+	void onDisconnect(String gatewayname);
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/connectionmanager/ConnectionManager.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/connectionmanager/ConnectionManager.java
new file mode 100644
index 0000000..c03d6c3
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/connectionmanager/ConnectionManager.java
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.client.connectionmanager;
+
+import java.net.ConnectException;
+import java.net.URI;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.log4j.Logger;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ConnectionManager {
+
+	private static final Logger logger = Logger.getLogger(ConnectionManager.class);
+
+	private static ConnectionManager INSTANCE = null;
+
+	private final Map<String, Connection> conByGateway = new HashMap<>();
+	
+	private ConnectionManager() {
+	}
+
+	public synchronized static ConnectionManager getInstance() {
+		if (INSTANCE == null)
+			INSTANCE = new ConnectionManager();
+		return INSTANCE;
+	}
+	
+	public void connect(String gatewayName, URI url) throws ConnectException {
+		logger.info("Connecting gateway " + gatewayName);
+		Connection existingCon = conByGateway.get(gatewayName);
+		if (existingCon != null) {
+			if (! existingCon.isConnected()) {
+				existingCon.connect(url);
+			}
+		} else {
+			Connection con = new Connection(gatewayName);
+			conByGateway.put(gatewayName, con);
+			con.connect(url);
+		}
+	}
+	
+	public void disconnect(String gatewayName) throws ConnectException {
+		logger.info("Disconnecting gateway " + gatewayName);	
+		Connection existingCon = conByGateway.get(gatewayName);
+		if (existingCon == null) {
+			throw new ConnectException("Gateway " + gatewayName + " is NOT connected");
+		}
+		existingCon.disconnect();
+	}
+
+	public boolean isConnected(String gatewayName) {
+		Connection existingCon = conByGateway.get(gatewayName);
+		if (existingCon != null) {
+			return existingCon.isConnected();
+		}
+		return false;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/connectionmanager/NotifDispatcher.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/connectionmanager/NotifDispatcher.java
new file mode 100644
index 0000000..d4e6a45
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/connectionmanager/NotifDispatcher.java
@@ -0,0 +1,139 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.client.connectionmanager;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgCategory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgFactory;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+import org.eclipse.sensinact.studio.http.messages.snamessage.attributevalueupdated.MsgAttributeValueUpdated;
+import org.eclipse.sensinact.studio.http.services.client.listener.NotifSubscriptionListener;
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+public class NotifDispatcher {
+
+	private static NotifDispatcher INSTANCE = null;
+
+	private Set<NotifSubscriptionListener> notifSublisteners = new HashSet<>();
+	
+	private Set<ConnectionListener> conlisteners = new HashSet<>();
+
+	private static final Logger logger = Logger.getLogger(NotifDispatcher.class);
+
+	public synchronized static NotifDispatcher getInstance() {
+		if (INSTANCE == null)
+			INSTANCE = new NotifDispatcher();
+		return INSTANCE;
+	}
+
+	private NotifDispatcher() {
+	}
+
+	public void subscribe(NotifSubscriptionListener listener) {
+		notifSublisteners.add(listener);
+	}
+
+	public void unsubscribe(NotifSubscriptionListener listener) {
+		notifSublisteners.remove(listener);
+	}
+
+	public void subscribe(ConnectionListener listener) {
+		conlisteners.add(listener);
+	}
+
+	public void unsubscribe(ConnectionListener listener) {
+		conlisteners.remove(listener);
+	}
+		
+	void notifyMessage(String gatewayName, String msg) {
+
+		List<MsgSensinact> lifecycleMsgs = new ArrayList<>();
+		List<MsgSensinact> valueMsgs = new ArrayList<>();
+		List<MsgSensinact> locationMsgs = new ArrayList<>();
+		List<MsgSensinact> iconMsgs = new ArrayList<>();
+		List<MsgSensinact> otherMsgs = new ArrayList<>();
+
+		try {
+			JSONObject jsonObject = new JSONObject(msg);
+			if ("CALLBACK".equals(jsonObject.optString("type"))) {
+				JSONArray array = jsonObject.getJSONArray("messages");
+				for (int i = 0; i < array.length(); i++) {
+					JSONObject jsonMsg = array.getJSONObject(i);
+					MsgSensinact message = MsgFactory.build(jsonMsg, 200);
+
+					if (message.getCategory() == MsgCategory.LIFECYCLE) {
+						lifecycleMsgs.add(message);
+					} else if (message.getCategory() == MsgCategory.VALUE) {
+						if (message instanceof MsgAttributeValueUpdated) {
+							if (((MsgAttributeValueUpdated) message).isLocationValue()) 
+								locationMsgs.add(message);
+							else if (((MsgAttributeValueUpdated) message).isIconValue()) 
+								iconMsgs.add(message);							
+						}
+						valueMsgs.add(message);
+					} else {
+						otherMsgs.add(message);
+					}
+				}
+			}
+		} catch (Exception e) {
+			logger.error(e);
+		}
+
+		if (lifecycleMsgs.size() != 0)
+			notifyLifecycle(gatewayName, lifecycleMsgs);
+
+		if (locationMsgs.size() != 0)
+			notifyLocation(gatewayName, locationMsgs);
+
+		if (iconMsgs.size() != 0)
+			notifyIcon(gatewayName, iconMsgs);
+		
+		if (valueMsgs.size() != 0)
+			notifyValue(gatewayName, valueMsgs);
+	}
+
+	void notifyGatewayConnected(String gatewayName) {
+		for (ConnectionListener listener : conlisteners)
+			listener.onConnect(gatewayName);
+	}
+
+	void notifyGatewayDisconnected(String gatewayName) {
+		for (ConnectionListener listener : conlisteners)
+			listener.onDisconnect(gatewayName);
+	}
+
+	private void notifyLocation(String gateway, List<MsgSensinact> message) {
+		for (NotifSubscriptionListener listener : notifSublisteners)
+			listener.onLocationEvent(gateway, message);
+	}
+
+	private void notifyIcon(String gateway, List<MsgSensinact> message) {
+		for (NotifSubscriptionListener listener : notifSublisteners)
+			listener.onIconEvent(gateway, message);
+	}
+
+	private void notifyLifecycle(String gateway, List<MsgSensinact> message) {
+		for (NotifSubscriptionListener listener : notifSublisteners)
+			listener.onLifecycleEvent(gateway, message);
+	}
+	
+	private void notifyValue(String gateway, List<MsgSensinact> message) {
+		for (NotifSubscriptionListener listener : notifSublisteners)
+			listener.onValueEvent(gateway, message);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/connectionmanager/SensinactSocket.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/connectionmanager/SensinactSocket.java
new file mode 100644
index 0000000..77daa89
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/connectionmanager/SensinactSocket.java
@@ -0,0 +1,114 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.client.connectionmanager;
+
+import java.io.IOException;
+
+import org.apache.log4j.Logger;
+import org.eclipse.jetty.websocket.common.OpCode;
+import org.eclipse.jetty.websocket.api.RemoteEndpoint;
+import org.eclipse.jetty.websocket.api.Session;
+import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose;
+import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect;
+import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError;
+import org.eclipse.jetty.websocket.api.annotations.OnWebSocketFrame;
+import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage;
+import org.eclipse.jetty.websocket.api.annotations.WebSocket;
+import org.eclipse.jetty.websocket.api.extensions.Frame;
+
+/**
+ * @author Jander Nascimento, Etienne Gandrille
+ */
+@WebSocket(maxIdleTime = 0, maxTextMessageSize = 64*1024)
+public class SensinactSocket {
+
+	private static final Logger logger = Logger.getLogger(SensinactSocket.class);
+
+	private Session session;
+	private String gatewayName;
+	private static NotifDispatcher dispatcher = NotifDispatcher.getInstance();
+	
+	public SensinactSocket(String gatewayName) {
+		this.gatewayName = gatewayName;
+	}
+
+	public boolean isConnected() {
+		return session != null;
+	}
+	
+	@OnWebSocketConnect
+	public void onConnect(Session session) throws IOException {
+		logger.info("WebSocket connected to the gateway " + gatewayName);
+		this.session = session;
+		String msg = "{\"uri\":\"sensinact/SUBSCRIBE\",\"parameters\":[{\"name\":\"sender\",\"type\":\"string\",\"value\":\"(/[^/]*)+\"},{\"name\":\"pattern\",\"type\":\"boolean\",\"value\":true},{\"name\":\"complement\",\"type\":\"boolean\",\"value\":false},{\"name\":\"types\",\"type\":\"array\",\"value\":[\"UPDATE\",\"LIFECYCLE\",\"REMOTE\",\"RESPONSE\",\"ERROR\"]}]}";
+		session.getRemote().sendString(msg);
+		dispatcher.notifyGatewayConnected(gatewayName);
+	}
+
+	public void send(String str) throws IOException {		
+		if ( ! isConnected())
+			throw new IOException("Socket is NOT connected to gateway " + gatewayName);
+		
+		RemoteEndpoint remote = session.getRemote();
+		if (remote == null)
+			throw new IOException("remote endpoint is null");
+		
+		remote.sendString(str);
+	}
+	
+	@OnWebSocketClose
+	public void onClose(int statusCode, String reason) {
+		session = null;
+		logger.info("WebSocket connection closed from the gateway " + gatewayName);
+		dispatcher.notifyGatewayDisconnected(gatewayName);
+	}
+
+    private boolean partial;
+	private byte[] payload; 
+	
+	@OnWebSocketFrame
+	public void onFrame(Frame frame) {
+		if(OpCode.CONTINUATION != frame.getOpCode() && frame.isFin()) {
+			partial = false;
+			return;
+		}
+		partial = true;
+		byte[] bytes = new byte[frame.getPayloadLength()];
+		frame.getPayload().get(bytes);
+		int length = payload==null?0:payload.length;
+		byte[] tmpArray = new byte[length+bytes.length] ;
+		if(bytes.length > 0)
+			System.arraycopy(bytes,0, tmpArray, length, bytes.length);
+		if(length > 0)
+			System.arraycopy(payload, 0, tmpArray, 0, length);
+		payload = tmpArray;	
+		tmpArray = null;
+		if(frame.isFin()) {
+			partial = false;
+			onMessage(new String(payload));
+			payload = null;
+			partial = true;
+		}
+	}	
+
+	@OnWebSocketMessage
+	public void onMessage(String msg) {
+		if(partial)
+			return;
+		dispatcher.notifyMessage(gatewayName, msg);
+	}	
+	
+	@OnWebSocketError
+	public void onError(Throwable t) {
+		t.printStackTrace();
+		logger.error("Error: " + t.getMessage());
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/connectionmanager/package-info.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/connectionmanager/package-info.java
new file mode 100644
index 0000000..ceb35f3
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/connectionmanager/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.services.client.connectionmanager;
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/listener/NotifSubscriptionListener.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/listener/NotifSubscriptionListener.java
new file mode 100644
index 0000000..1492ac4
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/listener/NotifSubscriptionListener.java
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.client.listener;
+
+import java.util.List;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+
+/**
+ * @author Etienne Gandrille
+ */
+public interface NotifSubscriptionListener {
+	
+	void onLifecycleEvent(String gateway, List<MsgSensinact> messages);
+
+	void onLocationEvent(String gateway, List<MsgSensinact> messages);
+	
+	void onIconEvent(String gateway, List<MsgSensinact> messages);
+
+	void onValueEvent(String gateway, List<MsgSensinact> messages);
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/listener/package-info.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/listener/package-info.java
new file mode 100644
index 0000000..8abbdba
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/listener/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.services.client.listener;
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/package-info.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/package-info.java
new file mode 100644
index 0000000..a5c468c
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/client/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.services.client;
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/BundleResourceClientHelper.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/BundleResourceClientHelper.java
new file mode 100644
index 0000000..70ce748
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/BundleResourceClientHelper.java
@@ -0,0 +1,96 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.server;
+
+import java.net.URL;
+import java.util.Date;
+
+import org.restlet.Client;
+import org.restlet.Request;
+import org.restlet.Response;
+import org.restlet.data.Method;
+import org.restlet.data.Protocol;
+import org.restlet.data.Status;
+import org.restlet.engine.local.Entity;
+import org.restlet.engine.local.LocalClientHelper;
+import org.restlet.representation.InputRepresentation;
+import org.restlet.representation.Representation;
+
+/**
+ * @author Nicolas Hili
+ * @since  Nov 19, 2014
+ * 
+ * @see http://permalink.gmane.org/gmane.comp.java.restlet/12378
+ */
+public class BundleResourceClientHelper extends LocalClientHelper {
+
+	public static final Protocol BUNDLERESOURCE = new Protocol("bundleresource","BUNDLERESOURCE", "OSGI Bundle Resource", Protocol.UNKNOWN_PORT);
+	
+	public BundleResourceClientHelper(Client client) {
+		super(client);
+		getProtocols().add(BUNDLERESOURCE);
+	}
+	
+	@Override
+	protected void handleLocal(Request request, Response response, String decodedPath) {
+		String scheme = request.getResourceRef().getScheme();
+		if(BUNDLERESOURCE.getSchemeName().equalsIgnoreCase(scheme)) {
+			handleFile(request,response);
+		} else {
+			throw new IllegalArgumentException("Protocol " + scheme + " not supported, only BUNDLERESOURCE is supported");
+		}
+	}
+	
+	private void handleFile(Request request, Response response)
+	{
+		if(Method.GET.equals(request.getMethod()) || Method.HEAD.equals(request.getMethod())) {
+			handleGet(request,response);
+		}
+		else {
+            response.setStatus(Status.CLIENT_ERROR_METHOD_NOT_ALLOWED);
+            response.getAllowedMethods().add(Method.GET);
+            response.getAllowedMethods().add(Method.HEAD);
+        }
+	}
+	
+	private void handleGet(Request request, Response response)
+	{
+		try {
+			String path = request.getResourceRef().getPath();
+			URL url = new URL(request.getResourceRef().toString());
+            Representation output = new InputRepresentation(url.openStream(), getMetadataService().getDefaultMediaType());
+            output.setLocationRef(request.getResourceRef());
+            output.setModificationDate(new Date());
+
+            // Update the expiration date
+            long timeToLive = getTimeToLive();
+
+            if (timeToLive == 0) {
+                output.setExpirationDate(null);
+            } else if (timeToLive > 0) {
+                output.setExpirationDate(new Date(System
+                        .currentTimeMillis()
+                        + (1000L * timeToLive)));
+            }
+
+            // Update the metadata based on file extensions
+            String name = path.substring(path.lastIndexOf('/') + 1);
+            Entity.updateMetadata(name, output, true, getMetadataService());
+
+            // Update the response
+            response.setEntity(output);
+            response.setStatus(Status.SUCCESS_OK);						
+		} catch(Exception e) {
+			response.setStatus(Status.CLIENT_ERROR_NOT_FOUND);			
+		}
+	}
+
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/GatewayHttpServer.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/GatewayHttpServer.java
new file mode 100644
index 0000000..f5765b5
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/GatewayHttpServer.java
@@ -0,0 +1,158 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.server;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.logging.Level;
+
+import org.apache.log4j.Logger;
+import org.eclipse.sensinact.studio.http.services.server.serverstarted.PortUpdate;
+import org.eclipse.sensinact.studio.http.services.server.serverstarted.ResourceAddedUpdate;
+import org.eclipse.sensinact.studio.http.services.server.serverstarted.ServerUpdatedManager;
+import org.eclipse.sensinact.studio.preferences.ConfigurationListerner;
+import org.eclipse.sensinact.studio.preferences.ConfigurationManager;
+import org.eclipse.sensinact.studio.preferences.GatewayHttpConfig;
+import org.restlet.Component;
+import org.restlet.Restlet;
+import org.restlet.data.Protocol;
+import org.restlet.engine.Engine;
+import org.restlet.resource.ServerResource;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class GatewayHttpServer extends SensinactServerResource implements ConfigurationListerner {
+
+	private static final Logger logger = Logger.getLogger(GatewayHttpServer.class);
+
+	private Component serverComponent;
+
+	private List<String> registeredPaths = new ArrayList<>();
+
+	private boolean serverRuning = false;
+
+	private static GatewayHttpServer instance;
+
+	synchronized public static GatewayHttpServer getInstance() {
+		if (instance == null) {
+			instance = new GatewayHttpServer();
+			try {
+				int port = ConfigurationManager.getStudioPort();
+				instance.initServer();
+				instance.updateServerPort(port);
+			} catch (Exception e) {
+				logger.error("GatewayHttpServer creation", e);
+			}
+		}
+		return instance;
+	}
+
+	public boolean isServerRuning() {
+		return serverRuning;
+	}
+
+	private GatewayHttpServer() {
+		ConfigurationManager.addListener(this);
+		configureEngine();
+	}
+
+	private void configureEngine() {
+		// Restlet global config
+		Engine.setLogLevel(Level.OFF);
+
+		// This is used to allow the server to return bundle resources
+		Engine.getInstance().getRegisteredClients().add(new BundleResourceClientHelper(null));
+	}
+
+	private void initServer() throws Exception {
+		if (serverComponent == null) {
+
+			// Create the webapp component
+			serverComponent = new Component();
+			serverComponent.getClients().add(BundleResourceClientHelper.BUNDLERESOURCE);
+		}
+	}
+
+	public void attach(String uriPattern, Restlet target) throws Exception {
+		logger.debug("http resource registered: " + uriPattern);
+		registeredPaths.add(uriPattern);
+		serverComponent.getDefaultHost().attach(uriPattern, target);
+		if (serverComponent.isStarted())
+			ServerUpdatedManager.getInstance().notifyServerUpdated(new ResourceAddedUpdate(uriPattern, registeredPaths));
+	}
+
+	public void attach(String pathTemplate, Class<? extends ServerResource> targetClass) throws Exception {
+		logger.debug("http resource registered: " + pathTemplate);
+		registeredPaths.add(pathTemplate);
+		serverComponent.getDefaultHost().attach(pathTemplate, targetClass);
+		if (serverComponent.isStarted())
+			ServerUpdatedManager.getInstance().notifyServerUpdated(new ResourceAddedUpdate(pathTemplate, registeredPaths));
+	}
+
+	public void detach(String uriPattern, Restlet target) throws Exception {
+		registeredPaths.remove(uriPattern);
+		serverComponent.getDefaultHost().detach(target);
+		if (serverComponent.isStarted())
+			ServerUpdatedManager.getInstance().notifyServerUpdated(new ResourceAddedUpdate(uriPattern, registeredPaths));
+		logger.debug("http resource unregistered: " + uriPattern);
+	}
+	
+	public void detach(String pathTemplate, Class<? extends ServerResource> targetClass) throws Exception {
+		registeredPaths.remove(pathTemplate);
+		serverComponent.getDefaultHost().detach(targetClass);
+		if (serverComponent.isStarted())
+			ServerUpdatedManager.getInstance().notifyServerUpdated(new ResourceAddedUpdate(pathTemplate, registeredPaths));
+		logger.debug("http resource unregistered: " + pathTemplate);
+	}
+
+	public void updateServerPort(int port) throws Exception {
+		// stop running server
+		if (serverRuning) {
+			serverRuning = false;
+			serverComponent.stop();
+			serverComponent.getServers().remove(0);
+		}
+
+		// start new server
+		if (port != 0) {
+			serverComponent.getServers().add(Protocol.HTTP, port);
+			serverComponent.start();
+			serverRuning = true;
+		}
+
+		// notify
+		ServerUpdatedManager.getInstance().notifyServerUpdated(new PortUpdate(port));
+	}
+
+	/* ======================== */
+	/* Config listener callback */
+	/* ======================== */
+
+	@Override
+	public void studioPortUpdatedNotif(int port) {
+		try {
+			updateServerPort(port);
+		} catch (Exception e) {
+			logger.error("update server port", e);
+		}
+	}
+
+	@Override
+	public void gatewayAddedOrUpdatedNotif(GatewayHttpConfig gateway) {
+		// do nothing
+	}
+
+	@Override
+	public void gatewayRemovedNotif(String name) {
+		// do nothing
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/RouteUtil.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/RouteUtil.java
new file mode 100644
index 0000000..709a21c
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/RouteUtil.java
@@ -0,0 +1,67 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.server;
+
+import org.apache.log4j.Logger;
+import org.restlet.Application;
+import org.restlet.resource.ServerResource;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class RouteUtil {
+
+	public static final String ENCODING = "UTF-8";
+	
+	private static final Logger logger = Logger.getLogger(RouteUtil.class);
+	
+	private static final GatewayHttpServer server = GatewayHttpServer.getInstance();
+	
+	public static boolean attachRoute(String pathTemplate, Class<? extends ServerResource> targetClass) {
+		try {
+			server.attach(pathTemplate, targetClass);
+			return true;
+		} catch (Exception e) {
+			logger.error("attach route fails", e);
+			return false;
+		}
+	}
+
+	public static boolean detachRoute(String pathTemplate, Class<? extends ServerResource> targetClass) {
+		try {
+			server.detach(pathTemplate, targetClass);
+			return true;
+		} catch (Exception e) {
+			logger.error("attach route fails", e);
+			return false;
+		}
+	}
+	
+	public static boolean attachRoute(String pathTemplate, Application application) {
+		try {
+			server.attach(pathTemplate, application);
+			return true;
+		} catch (Exception e) {
+			logger.error("attach route fails", e);
+			return false;
+		}
+	}	
+
+	public static boolean detachRoute(String pathTemplate, Application application) {
+		try {
+			server.detach(pathTemplate, application);
+			return true;
+		} catch (Exception e) {
+			logger.error("attach route fails", e);
+			return false;
+		}
+	}	
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/SensinactServerResource.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/SensinactServerResource.java
new file mode 100644
index 0000000..110ff58
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/SensinactServerResource.java
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.server;
+
+import java.io.UnsupportedEncodingException;
+import java.net.URLDecoder;
+
+import org.restlet.resource.ServerResource;
+
+/**
+ * @author Etienne Gandrille
+ */
+public abstract class SensinactServerResource extends ServerResource {
+
+	protected String getRequestAttribute(String name) throws UnsupportedEncodingException {		
+		return URLDecoder.decode(getRequestAttributes().get(name).toString(), RouteUtil.ENCODING);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/package-info.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/package-info.java
new file mode 100644
index 0000000..8fa2530
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.services.server;
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/serverstarted/PortUpdate.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/serverstarted/PortUpdate.java
new file mode 100644
index 0000000..3c35880
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/serverstarted/PortUpdate.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.server.serverstarted;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class PortUpdate extends UpdateDescriptor {
+
+	private final int port;
+
+	public PortUpdate(int port) {
+		super(UpdateType.PORT_UPDATE);
+		this.port = port;
+	}
+
+	public int getPort() {
+		return port;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/serverstarted/ResourceAddedUpdate.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/serverstarted/ResourceAddedUpdate.java
new file mode 100644
index 0000000..51cd015
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/serverstarted/ResourceAddedUpdate.java
@@ -0,0 +1,36 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.server.serverstarted;
+
+import java.util.List;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ResourceAddedUpdate extends UpdateDescriptor {
+	
+	private final String curPath;
+	private final List<String> registeredPaths;
+
+	public ResourceAddedUpdate(String curPath, List<String> registeredPaths) {
+		super(UpdateType.RESOURCE_ADDED);
+		this.curPath = curPath;
+		this.registeredPaths = registeredPaths;
+	}
+
+	public List<String> getRegisteredPath() {
+		return registeredPaths;
+	}
+	
+	public String getCurPath() {
+		return curPath;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/serverstarted/ServerUpdatedListener.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/serverstarted/ServerUpdatedListener.java
new file mode 100644
index 0000000..ca60b8b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/serverstarted/ServerUpdatedListener.java
@@ -0,0 +1,19 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.server.serverstarted;
+
+/**
+ * @author Etienne Gandrille
+ */
+public interface ServerUpdatedListener {
+
+	public void serverUpdated(UpdateDescriptor descriptor);
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/serverstarted/ServerUpdatedManager.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/serverstarted/ServerUpdatedManager.java
new file mode 100644
index 0000000..b7deddd
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/serverstarted/ServerUpdatedManager.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.server.serverstarted;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ServerUpdatedManager {
+
+	private static final Logger logger = Logger.getLogger(ServerUpdatedManager.class);
+	
+	private static ServerUpdatedManager INSTANCE = null;
+	private final Set<ServerUpdatedListener> listeners = new HashSet<ServerUpdatedListener>(); 
+	
+	private ServerUpdatedManager() {
+	}
+
+	public static ServerUpdatedManager getInstance() {
+		if (INSTANCE == null)
+			INSTANCE = new ServerUpdatedManager();
+		return INSTANCE;
+	}
+	
+	public void removeServerUpdatedListener(ServerUpdatedListener listener) {
+		listeners.remove(listener);
+	}
+
+	public void addServerUpdatedListener(ServerUpdatedListener listener) {
+		listeners.add(listener);
+	}
+
+	public void notifyServerUpdated(UpdateDescriptor descriptor) {
+		logger.debug("Server updated. Notification fired (" + listeners.size() + " listeners");
+		for (ServerUpdatedListener listener : listeners) {
+			listener.serverUpdated(descriptor);
+		}
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/serverstarted/UpdateDescriptor.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/serverstarted/UpdateDescriptor.java
new file mode 100644
index 0000000..ee9d1b3
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/serverstarted/UpdateDescriptor.java
@@ -0,0 +1,31 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.http.services.server.serverstarted;
+
+/**
+ * @author Etienne Gandrille
+ */
+public abstract class UpdateDescriptor {
+
+	private final UpdateType type;
+
+	protected UpdateDescriptor(UpdateType type) {
+		this.type = type;
+	}
+	
+	public UpdateType getType() {
+		return type;
+	}
+	
+	public enum UpdateType {
+		PORT_UPDATE, RESOURCE_ADDED;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/serverstarted/package-info.java b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/serverstarted/package-info.java
new file mode 100644
index 0000000..2b2357b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.http.services/src/org/eclipse/sensinact/studio/http/services/server/serverstarted/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.http.services.server.serverstarted;
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/.classpath b/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/.classpath
new file mode 100644
index 0000000..a68d431
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/.classpath
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="src" output="bin" path="src"/>
+	<classpathentry kind="src" output="bin_test" path="test">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" path="src-gen"/>
+	<classpathentry kind="src" path="xtend-gen"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/.gitignore b/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/.gitignore
new file mode 100644
index 0000000..c2b941a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/.gitignore
@@ -0,0 +1,2 @@
+/bin_test/
+/generated/
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/.project b/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/.project
new file mode 100644
index 0000000..76d9b0a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/.project
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.sensinact.studio.language.sensinact.ide</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+		<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
+	</natures>
+</projectDescription>
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/bnd.bnd b/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/bnd.bnd
new file mode 100644
index 0000000..eb1aa8a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/bnd.bnd
@@ -0,0 +1,30 @@
+src: ${^src},src-gen,xtend-gen
+
+-enable-gecko-emf: true
+
+Bundle-Version: 1.0.0.SNAPSHOT
+Bundle-ActivationPolicy: lazy
+
+-buildpath: \
+	com.google.inject,\
+	org.eclipse.xtext.xtext.generator,\
+	org.eclipse.emf.mwe2.runtime,\
+	org.eclipse.emf.mwe.core,\
+	org.eclipse.xtext,\
+	org.eclipse.xtext.xbase,\
+	org.eclipse.equinox.common,\
+	org.eclipse.xtext.xbase.lib,\
+	org.eclipse.xtext.util,\
+	org.eclipse.xtend.lib,\
+	org.apache.log4j,\
+	org.antlr.runtime,\
+	org.eclipse.sensinact.studio.model.resource;version=project,\
+	org.eclipse.sensinact.studio.model.manager;version=project,\
+	org.eclipse.xtext.ui,\
+	org.eclipse.xtext.ide,\
+	com.google.guava;version=latest,\
+	org.eclipse.sensinact.studio.language.sensinact;version=project
+Export-Package: \
+	org.eclipse.sensinact.studio.language.ide,\
+	org.eclipse.sensinact.studio.language.ide.contentassist.antlr,\
+	org.eclipse.sensinact.studio.language.ide.contentassist.antlr.internal
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/src/org/eclipse/sensinact/studio/language/ide/SensinactIdeModule.xtend b/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/src/org/eclipse/sensinact/studio/language/ide/SensinactIdeModule.xtend
new file mode 100644
index 0000000..dbc5f00
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/src/org/eclipse/sensinact/studio/language/ide/SensinactIdeModule.xtend
@@ -0,0 +1,11 @@
+/*
+ * generated by Xtext 2.12.0
+ */
+package org.eclipse.sensinact.studio.language.ide
+
+
+/**
+ * Use this class to register ide components.
+ */
+class SensinactIdeModule extends AbstractSensinactIdeModule {
+}
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/src/org/eclipse/sensinact/studio/language/ide/SensinactIdeSetup.xtend b/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/src/org/eclipse/sensinact/studio/language/ide/SensinactIdeSetup.xtend
new file mode 100644
index 0000000..52512e1
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/src/org/eclipse/sensinact/studio/language/ide/SensinactIdeSetup.xtend
@@ -0,0 +1,20 @@
+/*
+ * generated by Xtext 2.12.0
+ */
+package org.eclipse.sensinact.studio.language.ide
+
+import com.google.inject.Guice
+import org.eclipse.sensinact.studio.language.SensinactRuntimeModule
+import org.eclipse.sensinact.studio.language.SensinactStandaloneSetup
+import org.eclipse.xtext.util.Modules2
+
+/**
+ * Initialization support for running Xtext languages as language servers.
+ */
+class SensinactIdeSetup extends SensinactStandaloneSetup {
+
+	override createInjector() {
+		Guice.createInjector(Modules2.mixin(new SensinactRuntimeModule, new SensinactIdeModule))
+	}
+	
+}
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/src/org/eclipse/sensinact/studio/language/ide/packageinfo b/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/src/org/eclipse/sensinact/studio/language/ide/packageinfo
new file mode 100644
index 0000000..9ad81f6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ide/src/org/eclipse/sensinact/studio/language/ide/packageinfo
@@ -0,0 +1 @@
+version 1.0.0
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/.classpath b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/.classpath
new file mode 100644
index 0000000..734d19e
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/.classpath
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="src" output="bin" path="src"/>
+	<classpathentry kind="src" output="bin" path="xtend-gen"/>
+	<classpathentry kind="src" output="bin_test" path="test">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" path="src-gen"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/.gitignore b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/.gitignore
new file mode 100644
index 0000000..c2b941a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/.gitignore
@@ -0,0 +1,2 @@
+/bin_test/
+/generated/
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/.project b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/.project
new file mode 100644
index 0000000..d430bb6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/.project
@@ -0,0 +1,35 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.sensinact.studio.language.sensinact.ui</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.classpathchecker.classpathBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+		<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
+		<nature>org.classpathchecker.classpathNature</nature>
+	</natures>
+</projectDescription>
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/bnd.bnd b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/bnd.bnd
new file mode 100644
index 0000000..5b0c488
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/bnd.bnd
@@ -0,0 +1,111 @@
+src: ${^src},src-gen,xtend-gen
+
+-enable-gecko-emf: true
+
+Bundle-Version: 1.0.0.SNAPSHOT
+Bundle-SymbolicName: ${p};singleton:=true
+Bundle-ActivationPolicy: lazy
+Bundle-Activator: org.eclipse.sensinact.studio.language.sensinact.ui.internal.SensinactActivator
+
+-includeresource.model: \
+	plugin.xml
+	
+-buildpath: \
+	com.google.inject,\
+	org.eclipse.xtext.xtext.generator,\
+	org.eclipse.emf.edit.ui,\
+	org.eclipse.emf.mwe2.runtime,\
+	org.eclipse.emf.mwe.core,\
+	org.eclipse.xtext,\
+	org.eclipse.xtext.xbase,\
+	org.eclipse.equinox.common,\
+	org.eclipse.xtext.xbase.lib,\
+	org.eclipse.xtext.util,\
+	org.eclipse.xtend.lib,\
+	org.apache.log4j,\
+	org.antlr.runtime,\
+	org.eclipse.compare,\
+	org.eclipse.core.resources,\
+	org.eclipse.jface,\
+	org.eclipse.jface.text,\
+	org.eclipse.ui.editors,\
+	org.eclipse.ui.workbench,\
+	org.eclipse.xtext.builder,\
+	org.eclipse.xtext.ide,\
+	org.eclipse.xtext.ui,\
+	org.eclipse.ui.ide,\
+	org.eclipse.xtext.ui.codetemplates.ui,\
+	org.eclipse.xtext.ui.shared,\
+	org.eclipse.swt,\
+	org.eclipse.swt.win32.win32.x86_64,\
+	org.eclipse.sensinact.studio.model.resource;version=project,\
+	org.eclipse.sensinact.studio.language.sensinact.ide;version=project,\
+	org.eclipse.sensinact.studio.model.manager;version=project,\
+	org.eclipse.sensinact.studio.language.sensinact;version=project,\
+	org.eclipse.core.runtime,\
+	org.eclipse.equinox.common,\
+	org.eclipse.equinox.registry,\
+	com.google.guava;version=latest,\
+	org.eclipse.xtext.ui,\
+	org.eclipse.core.runtime,\
+	org.eclipse.osgi,\
+	org.eclipse.osgi.compatibility.state,\
+	org.eclipse.core.jobs,\
+	org.eclipse.equinox.registry,\
+	org.eclipse.equinox.preferences,\
+	org.eclipse.core.contenttype,\
+	org.eclipse.equinox.app,\
+	org.eclipse.core.resources,\
+	org.eclipse.core.commands,\
+	org.eclipse.e4.ui.workbench3,\
+	org.eclipse.core.filebuffers,\
+	org.eclipse.text,\
+	org.apache.commons.cli,\
+	org.eclipse.emf.mwe.utils,\
+	javax.inject,\
+	org.eclipse.ui.views,\
+	org.eclipse.emf.ecore.change,\
+	org.eclipse.emf.common.ui,\
+	org.eclipse.ltk.core.refactoring,\
+	org.eclipse.xtext.ui.codetemplates,\
+	org.eclipse.xtext.ui.codetemplates.ide,\
+	org.eclipse.e4.ui.ide,\
+	org.eclipse.compare.core,\
+	org.eclipse.debug.ui,\
+	org.eclipse.debug.core,\
+	org.eclipse.xtend.lib.macro,\
+	org.eclipse.ui.workbench.texteditor,\
+	org.eclipse.compare,\
+	org.eclipse.core.expressions,\
+	org.eclipse.core.filesystem,\
+	org.eclipse.core.resources,\
+	org.eclipse.core.runtime,\
+	org.eclipse.emf.edit.ui,\
+	org.eclipse.jdt.core,\
+	org.eclipse.jdt.launching,\
+	org.eclipse.jdt.ui,\
+	org.eclipse.jface.text,\
+	org.eclipse.ltk.core.refactoring,\
+	org.eclipse.ltk.ui.refactoring,\
+	org.eclipse.search,\
+	org.eclipse.team.core,\
+	org.eclipse.team.ui,\
+	org.eclipse.ui.editors,\
+	org.eclipse.ui.forms,\
+	org.eclipse.ui.ide,\
+	org.eclipse.ui.views,\
+	org.eclipse.ui.workbench.texteditor,\
+	org.eclipse.ui,\
+	org.eclipse.xtend.lib,\
+	org.eclipse.xtext.ide,\
+	org.eclipse.xtext.util,\
+	org.eclipse.xtext,\
+	org.eclipse.emf.edit
+
+Export-Package: \
+	org.eclipse.sensinact.studio.language.sensinact.ui.internal,\
+	org.eclipse.sensinact.studio.language.ui,\
+	org.eclipse.sensinact.studio.language.ui.contentassist,\
+	org.eclipse.sensinact.studio.language.ui.labeling,\
+	org.eclipse.sensinact.studio.language.ui.outline,\
+	org.eclipse.sensinact.studio.language.ui.quickfix
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/plugin.xml b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/plugin.xml
new file mode 100644
index 0000000..6967574
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/plugin.xml
@@ -0,0 +1,422 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2018 CEA.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+
+     Contributors:
+        CEA - initial API and implementation and/or initial documentation
+
+-->
+<?eclipse version="3.0"?>
+<plugin>
+	<extension
+		point="org.eclipse.ui.editors">
+		<editor
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.editor.XtextEditor"
+			contributorClass="org.eclipse.ui.editors.text.TextEditorActionContributor"
+			default="true"
+			extensions="sna"
+			id="org.eclipse.sensinact.studio.language.Sensinact"
+			name="Sensinact Editor">
+		</editor>
+	</extension>
+	<extension
+		point="org.eclipse.ui.handlers">
+		<handler
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.editor.hyperlinking.OpenDeclarationHandler"
+			commandId="org.eclipse.xtext.ui.editor.hyperlinking.OpenDeclaration">
+			<activeWhen>
+				<reference
+					definitionId="org.eclipse.sensinact.studio.language.Sensinact.Editor.opened">
+				</reference>
+			</activeWhen>
+		</handler>
+		<handler
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.editor.handler.ValidateActionHandler"
+			commandId="org.eclipse.sensinact.studio.language.Sensinact.validate">
+		<activeWhen>
+			<reference
+					definitionId="org.eclipse.sensinact.studio.language.Sensinact.Editor.opened">
+			</reference>
+		</activeWhen>
+		</handler>
+		<!-- copy qualified name -->
+		<handler
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.editor.copyqualifiedname.EditorCopyQualifiedNameHandler"
+			commandId="org.eclipse.xtext.ui.editor.copyqualifiedname.EditorCopyQualifiedName">
+			<activeWhen>
+				<reference definitionId="org.eclipse.sensinact.studio.language.Sensinact.Editor.opened" />
+			</activeWhen>
+		</handler>
+		<handler
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.editor.copyqualifiedname.OutlineCopyQualifiedNameHandler"
+			commandId="org.eclipse.xtext.ui.editor.copyqualifiedname.OutlineCopyQualifiedName">
+			<activeWhen>
+				<and>
+					<reference definitionId="org.eclipse.sensinact.studio.language.Sensinact.XtextEditor.opened" />
+					<iterate>
+						<adapt type="org.eclipse.xtext.ui.editor.outline.IOutlineNode" />
+					</iterate>
+				</and>
+			</activeWhen>
+		</handler>
+	</extension>
+	<extension point="org.eclipse.core.expressions.definitions">
+		<definition id="org.eclipse.sensinact.studio.language.Sensinact.Editor.opened">
+			<and>
+				<reference definitionId="isActiveEditorAnInstanceOfXtextEditor"/>
+				<with variable="activeEditor">
+					<test property="org.eclipse.xtext.ui.editor.XtextEditor.languageName" 
+						value="org.eclipse.sensinact.studio.language.Sensinact" 
+						forcePluginActivation="true"/>
+				</with>		
+			</and>
+		</definition>
+		<definition id="org.eclipse.sensinact.studio.language.Sensinact.XtextEditor.opened">
+			<and>
+				<reference definitionId="isXtextEditorActive"/>
+				<with variable="activeEditor">
+					<test property="org.eclipse.xtext.ui.editor.XtextEditor.languageName" 
+						value="org.eclipse.sensinact.studio.language.Sensinact" 
+						forcePluginActivation="true"/>
+				</with>		
+			</and>
+		</definition>
+	</extension>
+	<extension
+			point="org.eclipse.ui.preferencePages">
+		<page
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.editor.preferences.LanguageRootPreferencePage"
+			id="org.eclipse.sensinact.studio.language.Sensinact"
+			name="Sensinact">
+			<keywordReference id="org.eclipse.sensinact.studio.language.ui.keyword_Sensinact"/>
+		</page>
+		<page
+			category="org.eclipse.sensinact.studio.language.Sensinact"
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.editor.syntaxcoloring.SyntaxColoringPreferencePage"
+			id="org.eclipse.sensinact.studio.language.Sensinact.coloring"
+			name="Syntax Coloring">
+			<keywordReference id="org.eclipse.sensinact.studio.language.ui.keyword_Sensinact"/>
+		</page>
+		<page
+			category="org.eclipse.sensinact.studio.language.Sensinact"
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.editor.templates.XtextTemplatePreferencePage"
+			id="org.eclipse.sensinact.studio.language.Sensinact.templates"
+			name="Templates">
+			<keywordReference id="org.eclipse.sensinact.studio.language.ui.keyword_Sensinact"/>
+		</page>
+	</extension>
+	<extension
+			point="org.eclipse.ui.propertyPages">
+		<page
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.editor.preferences.LanguageRootPreferencePage"
+			id="org.eclipse.sensinact.studio.language.Sensinact"
+			name="Sensinact">
+			<keywordReference id="org.eclipse.sensinact.studio.language.ui.keyword_Sensinact"/>
+			<enabledWhen>
+				<adapt type="org.eclipse.core.resources.IProject"/>
+			</enabledWhen>
+			<filter name="projectNature" value="org.eclipse.xtext.ui.shared.xtextNature"/>
+		</page>
+	</extension>
+	<extension
+		point="org.eclipse.ui.keywords">
+		<keyword
+			id="org.eclipse.sensinact.studio.language.ui.keyword_Sensinact"
+			label="Sensinact"/>
+	</extension>
+	<extension
+		point="org.eclipse.ui.commands">
+	<command
+			description="Trigger expensive validation"
+			id="org.eclipse.sensinact.studio.language.Sensinact.validate"
+			name="Validate">
+	</command>
+	<!-- copy qualified name -->
+	<command
+			id="org.eclipse.xtext.ui.editor.copyqualifiedname.EditorCopyQualifiedName"
+			categoryId="org.eclipse.ui.category.edit"
+			description="Copy the qualified name for the selected element"
+			name="Copy Qualified Name">
+	</command>
+	<command
+			id="org.eclipse.xtext.ui.editor.copyqualifiedname.OutlineCopyQualifiedName"
+			categoryId="org.eclipse.ui.category.edit"
+			description="Copy the qualified name for the selected element"
+			name="Copy Qualified Name">
+	</command>
+	</extension>
+	<extension point="org.eclipse.ui.menus">
+		<menuContribution
+			locationURI="popup:#TextEditorContext?after=group.edit">
+			 <command
+				 commandId="org.eclipse.sensinact.studio.language.Sensinact.validate"
+				 style="push"
+				 tooltip="Trigger expensive validation">
+			<visibleWhen checkEnabled="false">
+				<reference
+					definitionId="org.eclipse.sensinact.studio.language.Sensinact.Editor.opened">
+				</reference>
+			</visibleWhen>
+		</command>  
+		</menuContribution>
+		<!-- copy qualified name -->
+		<menuContribution locationURI="popup:#TextEditorContext?after=copy">
+			<command commandId="org.eclipse.xtext.ui.editor.copyqualifiedname.EditorCopyQualifiedName" 
+				style="push" tooltip="Copy Qualified Name">
+				<visibleWhen checkEnabled="false">
+					<reference definitionId="org.eclipse.sensinact.studio.language.Sensinact.Editor.opened" />
+				</visibleWhen>
+			</command>  
+		</menuContribution>
+		<menuContribution locationURI="menu:edit?after=copy">
+			<command commandId="org.eclipse.xtext.ui.editor.copyqualifiedname.EditorCopyQualifiedName"
+				style="push" tooltip="Copy Qualified Name">
+				<visibleWhen checkEnabled="false">
+					<reference definitionId="org.eclipse.sensinact.studio.language.Sensinact.Editor.opened" />
+				</visibleWhen>
+			</command>  
+		</menuContribution>
+		<menuContribution locationURI="popup:org.eclipse.xtext.ui.outline?after=additions">
+			<command commandId="org.eclipse.xtext.ui.editor.copyqualifiedname.OutlineCopyQualifiedName" 
+				style="push" tooltip="Copy Qualified Name">
+				<visibleWhen checkEnabled="false">
+					<and>
+						<reference definitionId="org.eclipse.sensinact.studio.language.Sensinact.XtextEditor.opened" />
+						<iterate>
+							<adapt type="org.eclipse.xtext.ui.editor.outline.IOutlineNode" />
+						</iterate>
+					</and>
+				</visibleWhen>
+			</command>
+		</menuContribution>
+	</extension>
+	<extension point="org.eclipse.ui.menus">
+		<menuContribution locationURI="popup:#TextEditorContext?endof=group.find">
+			<command commandId="org.eclipse.xtext.ui.editor.FindReferences">
+				<visibleWhen checkEnabled="false">
+					<reference definitionId="org.eclipse.sensinact.studio.language.Sensinact.Editor.opened">
+					</reference>
+				</visibleWhen>
+			</command>
+		</menuContribution>
+	</extension>
+	<extension point="org.eclipse.ui.handlers">
+		<handler
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.editor.findrefs.FindReferencesHandler"
+			commandId="org.eclipse.xtext.ui.editor.FindReferences">
+			<activeWhen>
+				<reference
+					definitionId="org.eclipse.sensinact.studio.language.Sensinact.Editor.opened">
+				</reference>
+			</activeWhen>
+		</handler>
+	</extension>
+	<!-- adding resource factories -->
+	<extension
+		point="org.eclipse.emf.ecore.extension_parser">
+		<parser
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.resource.IResourceFactory"
+			type="sna">
+		</parser>
+	</extension>
+	<extension point="org.eclipse.xtext.extension_resourceServiceProvider">
+	    <resourceServiceProvider
+	        class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.resource.IResourceUIServiceProvider"
+	        uriExtension="sna">
+	    </resourceServiceProvider>
+	</extension>
+	<!-- marker definitions for org.eclipse.sensinact.studio.language.Sensinact -->
+	<extension
+			id="sensinact.check.fast"
+			name="Sensinact Problem"
+			point="org.eclipse.core.resources.markers">
+		<super type="org.eclipse.xtext.ui.check.fast"/>
+		<persistent value="true"/>
+	</extension>
+	<extension
+			id="sensinact.check.normal"
+			name="Sensinact Problem"
+			point="org.eclipse.core.resources.markers">
+		<super type="org.eclipse.xtext.ui.check.normal"/>
+		<persistent value="true"/>
+	</extension>
+	<extension
+			id="sensinact.check.expensive"
+			name="Sensinact Problem"
+			point="org.eclipse.core.resources.markers">
+		<super type="org.eclipse.xtext.ui.check.expensive"/>
+		<persistent value="true"/>
+	</extension>
+	<extension point="org.eclipse.xtext.builder.participant">
+		<participant
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.builder.IXtextBuilderParticipant"
+			fileExtensions="sna"/>
+	</extension>
+	<extension point="org.eclipse.ui.preferencePages">
+		<page
+			category="org.eclipse.sensinact.studio.language.Sensinact"
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.builder.preferences.BuilderPreferencePage"
+			id="org.eclipse.sensinact.studio.language.Sensinact.compiler.preferencePage"
+			name="Compiler">
+			<keywordReference id="org.eclipse.sensinact.studio.language.ui.keyword_Sensinact"/>
+		</page>
+	</extension>
+	<extension point="org.eclipse.ui.propertyPages">
+		<page
+			category="org.eclipse.sensinact.studio.language.Sensinact"
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.builder.preferences.BuilderPreferencePage"
+			id="org.eclipse.sensinact.studio.language.Sensinact.compiler.propertyPage"
+			name="Compiler">
+			<keywordReference id="org.eclipse.sensinact.studio.language.ui.keyword_Sensinact"/>
+			<enabledWhen>
+				<adapt type="org.eclipse.core.resources.IProject"/>
+			</enabledWhen>
+			<filter name="projectNature" value="org.eclipse.xtext.ui.shared.xtextNature"/>
+		</page>
+	</extension>
+	<extension point="org.eclipse.ui.menus">
+		<menuContribution locationURI="popup:#TextEditorContext?after=xtext.ui.openDeclaration">
+			<command
+				commandId="org.eclipse.xtext.ui.OpenGeneratedFileCommand"
+				id="org.eclipse.sensinact.studio.language.Sensinact.OpenGeneratedCode"
+				style="push">
+				<visibleWhen checkEnabled="false">
+					<reference definitionId="org.eclipse.sensinact.studio.language.Sensinact.Editor.opened" />
+				</visibleWhen>
+			</command>
+		</menuContribution>
+	</extension>
+	<extension point="org.eclipse.ui.handlers">
+		<handler
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.generator.trace.OpenGeneratedFileHandler"
+			commandId="org.eclipse.xtext.ui.OpenGeneratedFileCommand">
+			<activeWhen>
+				<reference definitionId="org.eclipse.sensinact.studio.language.Sensinact.Editor.opened" />
+			</activeWhen>
+		</handler>
+	</extension>
+	<!-- Quick Outline -->
+	<extension
+		point="org.eclipse.ui.handlers">
+		<handler 
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.editor.outline.quickoutline.ShowQuickOutlineActionHandler"
+			commandId="org.eclipse.xtext.ui.editor.outline.QuickOutline">
+			<activeWhen>
+				<reference
+					definitionId="org.eclipse.sensinact.studio.language.Sensinact.Editor.opened">
+				</reference>
+			</activeWhen>
+		</handler>
+	</extension>
+	<extension
+		point="org.eclipse.ui.commands">
+		<command
+			description="Open the quick outline."
+			id="org.eclipse.xtext.ui.editor.outline.QuickOutline"
+			name="Quick Outline">
+		</command>
+	</extension>
+	<extension point="org.eclipse.ui.menus">
+		<menuContribution
+			locationURI="popup:#TextEditorContext?after=group.open">
+			<command commandId="org.eclipse.xtext.ui.editor.outline.QuickOutline"
+				style="push"
+				tooltip="Open Quick Outline">
+				<visibleWhen checkEnabled="false">
+					<reference definitionId="org.eclipse.sensinact.studio.language.Sensinact.Editor.opened"/>
+				</visibleWhen>
+			</command>
+		</menuContribution>
+	</extension>
+	<!-- quickfix marker resolution generator for org.eclipse.sensinact.studio.language.Sensinact -->
+	<extension
+	        point="org.eclipse.ui.ide.markerResolution">
+	    <markerResolutionGenerator
+	        class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.editor.quickfix.MarkerResolutionGenerator"
+	        markerType="org.eclipse.sensinact.studio.language.sensinact.ui.sensinact.check.fast">
+	        <attribute
+	            name="FIXABLE_KEY"
+	            value="true">
+	        </attribute>
+	    </markerResolutionGenerator>
+	    <markerResolutionGenerator
+	        class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.editor.quickfix.MarkerResolutionGenerator"
+	        markerType="org.eclipse.sensinact.studio.language.sensinact.ui.sensinact.check.normal">
+	        <attribute
+	            name="FIXABLE_KEY"
+	            value="true">
+	        </attribute>
+	    </markerResolutionGenerator>
+	    <markerResolutionGenerator
+	        class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.editor.quickfix.MarkerResolutionGenerator"
+	        markerType="org.eclipse.sensinact.studio.language.sensinact.ui.sensinact.check.expensive">
+	        <attribute
+	            name="FIXABLE_KEY"
+	            value="true">
+	        </attribute>
+	    </markerResolutionGenerator>
+	</extension>
+	<!-- Rename Refactoring -->
+	<extension point="org.eclipse.ui.handlers">
+		<handler 
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.refactoring.ui.DefaultRenameElementHandler"
+			commandId="org.eclipse.xtext.ui.refactoring.RenameElement">
+			<activeWhen>
+				<reference
+					definitionId="org.eclipse.sensinact.studio.language.Sensinact.Editor.opened">
+				</reference>
+			</activeWhen>
+		</handler>
+	</extension>
+	<extension point="org.eclipse.ui.menus">
+		<menuContribution
+			locationURI="popup:#TextEditorContext?after=group.edit">
+			<command commandId="org.eclipse.xtext.ui.refactoring.RenameElement"
+				style="push">
+				<visibleWhen checkEnabled="false">
+					<reference
+						definitionId="org.eclipse.sensinact.studio.language.Sensinact.Editor.opened">
+					</reference>
+				</visibleWhen>
+			</command>
+		</menuContribution>
+	</extension>
+	<extension point="org.eclipse.ui.preferencePages">
+		<page
+			category="org.eclipse.sensinact.studio.language.Sensinact"
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.refactoring.ui.RefactoringPreferencePage"
+			id="org.eclipse.sensinact.studio.language.Sensinact.refactoring"
+			name="Refactoring">
+			<keywordReference id="org.eclipse.sensinact.studio.language.ui.keyword_Sensinact"/>
+		</page>
+	</extension>
+	<extension point="org.eclipse.compare.contentViewers">
+		<viewer id="org.eclipse.sensinact.studio.language.Sensinact.compare.contentViewers"
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.compare.InjectableViewerCreator"
+			extensions="sna">
+		</viewer>
+	</extension>
+	<extension point="org.eclipse.compare.contentMergeViewers">
+		<viewer id="org.eclipse.sensinact.studio.language.Sensinact.compare.contentMergeViewers"
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.compare.InjectableViewerCreator"
+			extensions="sna" label="Sensinact Compare">
+		</viewer>
+	</extension>
+	<extension point="org.eclipse.ui.editors.documentProviders">
+		<provider id="org.eclipse.sensinact.studio.language.Sensinact.editors.documentProviders"
+			class="org.eclipse.sensinact.studio.language.ui.SensinactExecutableExtensionFactory:org.eclipse.xtext.ui.editor.model.XtextDocumentProvider"
+			extensions="sna">
+		</provider>
+	</extension>
+	<extension point="org.eclipse.team.core.fileTypes">
+		<fileTypes
+			extension="sna"
+			type="text">
+		</fileTypes>
+	</extension>
+</plugin>
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/SensinactUiModule.xtend b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/SensinactUiModule.xtend
new file mode 100644
index 0000000..1386922
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/SensinactUiModule.xtend
@@ -0,0 +1,23 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+/*
+ * generated by Xtext 2.9.1
+ */
+package org.eclipse.sensinact.studio.language.ui
+
+import org.eclipse.xtend.lib.annotations.FinalFieldsConstructor
+
+/**
+ * Use this class to register components to be used within the Eclipse IDE.
+ */
+@FinalFieldsConstructor
+class SensinactUiModule extends AbstractSensinactUiModule {
+}
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/contentassist/NullGlobalScopeProvider.xtend b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/contentassist/NullGlobalScopeProvider.xtend
new file mode 100644
index 0000000..1e47c30
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/contentassist/NullGlobalScopeProvider.xtend
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.language.ui.contentassist
+
+import org.eclipse.emf.ecore.EReference
+import org.eclipse.xtext.scoping.IScope
+import org.eclipse.xtext.scoping.IScopeProvider
+import org.eclipse.emf.ecore.EObject
+
+/**
+ * This scope erase ALL available cross references.
+ */
+class NullGlobalScopeProvider implements IScopeProvider {
+	
+	override getScope(EObject context, EReference reference) {
+		return IScope.NULLSCOPE;
+	}
+}
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/contentassist/SensinactProposalProvider.xtend b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/contentassist/SensinactProposalProvider.xtend
new file mode 100644
index 0000000..296a68c
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/contentassist/SensinactProposalProvider.xtend
@@ -0,0 +1,70 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.language.ui.contentassist
+
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Resource;
+import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelEditor
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.xtext.Assignment
+import org.eclipse.xtext.RuleCall
+import org.eclipse.xtext.ui.editor.contentassist.ContentAssistContext
+import org.eclipse.xtext.ui.editor.contentassist.ICompletionProposalAcceptor
+import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelUpdater
+
+/**
+ * @author Etienne Gandrille
+ */
+class SensinactProposalProvider extends AbstractSensinactProposalProvider {
+
+	override complete_EXTENDED_ID(EObject model, RuleCall ruleCall, ContentAssistContext context,
+		ICompletionProposalAcceptor acceptor) {
+
+		var rsrc = model as DSL_Resource;
+		var gatewayID = rsrc.gatewayID;
+		var deviceID = rsrc.deviceID;
+		var serviceID = rsrc.serviceID;
+
+		var container = ruleCall.eContainer as Assignment;
+		var feature = container.feature;
+
+		// gateway completion
+		if ("gatewayID".equals(feature)) {
+			var candidates = ModelEditor.getInstance().getGatewaysId;
+			for (candidate : candidates) {
+				acceptor.accept(createCompletionProposal(candidate + "/", context));
+			}
+		}
+
+		// device completion
+		if ("deviceID".equals(feature)) {
+			var candidates = ModelEditor.getInstance().getDevicesId(gatewayID);
+			for (candidate : candidates) {
+				acceptor.accept(createCompletionProposal(candidate + "/", context));
+			}
+		} // service completion
+		else if ("serviceID".equals(feature)) {
+			// Ensure to fetch the info during the code completion
+			ModelUpdater.getInstance().updateServices(gatewayID, deviceID);
+
+			var candidates = ModelEditor.getInstance().getServicesId(gatewayID, deviceID);
+			for (candidate : candidates) {
+				acceptor.accept(createCompletionProposal(candidate + "/", context));
+			}
+		} // resource completion
+		else if ("resourceID".equals(feature)) {
+			ModelUpdater.getInstance().updateResources(gatewayID, deviceID, serviceID);
+			var candidates = ModelEditor.getInstance().getResourcesId(gatewayID, deviceID, serviceID);
+			for (candidate : candidates) {
+				acceptor.accept(createCompletionProposal(candidate, context));
+			}
+		}
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/contentassist/packageinfo b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/contentassist/packageinfo
new file mode 100644
index 0000000..9ad81f6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/contentassist/packageinfo
@@ -0,0 +1 @@
+version 1.0.0
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/labeling/SensinactDescriptionLabelProvider.xtend b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/labeling/SensinactDescriptionLabelProvider.xtend
new file mode 100644
index 0000000..798da7a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/labeling/SensinactDescriptionLabelProvider.xtend
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+/*
+ * generated by Xtext 2.9.1
+ */
+package org.eclipse.sensinact.studio.language.ui.labeling
+
+import org.eclipse.xtext.ui.label.DefaultDescriptionLabelProvider
+
+/**
+ * Provides labels for IEObjectDescriptions and IResourceDescriptions.
+ * 
+ * See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#label-provider
+ */
+class SensinactDescriptionLabelProvider extends DefaultDescriptionLabelProvider {
+
+	// Labels and icons can be computed like this:
+	
+//	override text(IEObjectDescription ele) {
+//		ele.name.toString
+//	}
+//	 
+//	override image(IEObjectDescription ele) {
+//		ele.EClass.name + '.gif'
+//	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/labeling/SensinactLabelProvider.xtend b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/labeling/SensinactLabelProvider.xtend
new file mode 100644
index 0000000..1db8e08
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/labeling/SensinactLabelProvider.xtend
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+/*
+ * generated by Xtext 2.9.1
+ */
+package org.eclipse.sensinact.studio.language.ui.labeling
+
+import com.google.inject.Inject
+import org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider
+import org.eclipse.xtext.ui.label.DefaultEObjectLabelProvider
+import org.eclipse.jface.viewers.ILabelProvider
+
+/**
+ * Provides labels for EObjects.
+ * 
+ * See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#label-provider
+ */
+class SensinactLabelProvider extends DefaultEObjectLabelProvider implements  ILabelProvider {
+
+	@Inject
+	new(AdapterFactoryLabelProvider delegate) {
+		super(delegate);
+	}
+
+	// Labels and icons can be computed like this:
+	
+//	def text(Greeting ele) {
+//		'A greeting to ' + ele.name
+//	}
+//
+//	def image(Greeting ele) {
+//		'Greeting.gif'
+//	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/labeling/packageinfo b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/labeling/packageinfo
new file mode 100644
index 0000000..9ad81f6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/labeling/packageinfo
@@ -0,0 +1 @@
+version 1.0.0
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/outline/SensinactOutlineTreeProvider.xtend b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/outline/SensinactOutlineTreeProvider.xtend
new file mode 100644
index 0000000..b4c18c1
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/outline/SensinactOutlineTreeProvider.xtend
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+/*
+ * generated by Xtext 2.9.1
+ */
+package org.eclipse.sensinact.studio.language.ui.outline
+
+import org.eclipse.xtext.ui.editor.outline.impl.DefaultOutlineTreeProvider
+
+/**
+ * Customization of the default outline structure.
+ *
+ * See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#outline
+ */
+class SensinactOutlineTreeProvider extends DefaultOutlineTreeProvider {
+
+}
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/outline/packageinfo b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/outline/packageinfo
new file mode 100644
index 0000000..9ad81f6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/outline/packageinfo
@@ -0,0 +1 @@
+version 1.0.0
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/packageinfo b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/packageinfo
new file mode 100644
index 0000000..9ad81f6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/packageinfo
@@ -0,0 +1 @@
+version 1.0.0
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/quickfix/SensinactQuickfixProvider.xtend b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/quickfix/SensinactQuickfixProvider.xtend
new file mode 100644
index 0000000..f0bfa7d
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/quickfix/SensinactQuickfixProvider.xtend
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+/*
+ * generated by Xtext 2.9.1
+ */
+package org.eclipse.sensinact.studio.language.ui.quickfix
+
+import org.eclipse.xtext.ui.editor.quickfix.DefaultQuickfixProvider
+
+/**
+ * Custom quickfixes.
+ *
+ * See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#quick-fixes
+ */
+class SensinactQuickfixProvider extends DefaultQuickfixProvider {
+
+//	@Fix(SensinactValidator.INVALID_NAME)
+//	def capitalizeName(Issue issue, IssueResolutionAcceptor acceptor) {
+//		acceptor.accept(issue, 'Capitalize name', 'Capitalize the name.', 'upcase.png') [
+//			context |
+//			val xtextDocument = context.xtextDocument
+//			val firstLetter = xtextDocument.get(issue.offset, 1)
+//			xtextDocument.replace(issue.offset, 1, firstLetter.toUpperCase)
+//		]
+//	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/quickfix/packageinfo b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/quickfix/packageinfo
new file mode 100644
index 0000000..9ad81f6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/src/org/eclipse/sensinact/studio/language/ui/quickfix/packageinfo
@@ -0,0 +1 @@
+version 1.0.0
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/test.bndrun b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/test.bndrun
new file mode 100644
index 0000000..d522968
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact.ui/test.bndrun
@@ -0,0 +1,167 @@
+-runee: JavaSE-1.8
+-runprovidedcapabilities: ${native_capability}
+
+-runsystempackages: \
+        javax.annotation;version=1.3
+
+
+-runpath:\
+	org.gecko.bnd.eclipse.launcher.plugin;version='[1.0.6,2)',\
+	org.gecko.bnd.equinox.launcher.splashscreen;version='[1.0.1,2)'
+
+-runfw: org.eclipse.osgi;version='[3.15.300.v20200520-1959,3.15.300.v20200520-1959]'
+
+-runproperties.eclipse: \
+	eclipse.product=org.eclipse.sensinact.studio.language.sensinact.sensinact
+	eclipse.application=org.eclipse.e4.ui.workbench.swt.E4Application,\
+
+-runproperties.common: \
+	eclipse.product=org.eclipse.sensinact.studio.language.sensinact.sensinact,\
+	osgi.console=,\
+	console=,\
+	eclipse.consoleLog=,\
+	osgi.console.enable.builtin=false,\
+	consoleLog=,\
+	osgi.instance.area=${.}/test_workspace,\
+	name=,\
+	splash.location=splash/splash.bmp
+
+-runrequires: bnd.identity;id='org.eclipse.sensinact.studio.language.sensinact.ui'
+-runbundles: \
+	com.fasterxml.jackson.core.jackson-annotations;version='[2.10.3,2.10.4)',\
+	com.fasterxml.jackson.core.jackson-core;version='[2.10.3,2.10.4)',\
+	com.fasterxml.jackson.core.jackson-databind;version='[2.10.3,2.10.4)',\
+	com.google.guava;version='[21.0.0,21.0.1)',\
+	com.google.guava;version='[25.1.0,25.1.1)',\
+	com.google.guava;version='[27.1.0,27.1.1)',\
+	com.google.inject;version='[4.2.1,4.2.2)',\
+	com.ibm.icu;version='[64.2.0,64.2.1)',\
+	javax.inject;version='[1.0.0,1.0.1)',\
+	log4j.over.slf4j;version='[1.7.25,1.7.26)',\
+	org.antlr.runtime;version='[3.2.0,3.2.1)',\
+	org.aopalliance;version='[1.0.0,1.0.1)',\
+	org.apache.batik.constants;version='[1.11.0,1.11.1)',\
+	org.apache.batik.css;version='[1.11.0,1.11.1)',\
+	org.apache.batik.i18n;version='[1.11.0,1.11.1)',\
+	org.apache.batik.util;version='[1.11.0,1.11.1)',\
+	org.apache.commons.io;version='[2.6.0,2.6.1)',\
+	org.apache.commons.jxpath;version='[1.3.0,1.3.1)',\
+	org.apache.commons.lang;version='[2.6.0,2.6.1)',\
+	org.apache.commons.logging;version='[1.2.0,1.2.1)',\
+	org.apache.felix.http.servlet-api;version='[1.1.2,1.1.3)',\
+	org.apache.felix.scr;version='[2.1.24,2.1.25)',\
+	org.apache.xmlgraphics;version='[2.3.0,2.3.1)',\
+	org.eclipse.compare;version='[3.7.1000,3.7.1001)',\
+	org.eclipse.compare.core;version='[3.6.900,3.6.901)',\
+	org.eclipse.core.commands;version='[3.9.700,3.9.701)',\
+	org.eclipse.core.contenttype;version='[3.7.700,3.7.701)',\
+	org.eclipse.core.databinding;version='[1.9.0,1.9.1)',\
+	org.eclipse.core.databinding.observable;version='[1.9.0,1.9.1)',\
+	org.eclipse.core.databinding.property;version='[1.8.0,1.8.1)',\
+	org.eclipse.core.expressions;version='[3.6.800,3.6.801)',\
+	org.eclipse.core.filebuffers;version='[3.6.1000,3.6.1001)',\
+	org.eclipse.core.filesystem;version='[1.7.700,1.7.701)',\
+	org.eclipse.core.jobs;version='[3.10.800,3.10.801)',\
+	org.eclipse.core.resources;version='[3.13.700,3.13.701)',\
+	org.eclipse.core.runtime;version='[3.18.0,3.18.1)',\
+	org.eclipse.core.variables;version='[3.4.800,3.4.801)',\
+	org.eclipse.e4.core.commands;version='[0.12.900,0.12.901)',\
+	org.eclipse.e4.core.contexts;version='[1.8.400,1.8.401)',\
+	org.eclipse.e4.core.di;version='[1.7.600,1.7.601)',\
+	org.eclipse.e4.core.di.annotations;version='[1.6.600,1.6.601)',\
+	org.eclipse.e4.core.di.extensions;version='[0.16.0,0.16.1)',\
+	org.eclipse.e4.core.di.extensions.supplier;version='[0.15.600,0.15.601)',\
+	org.eclipse.e4.core.services;version='[2.2.300,2.2.301)',\
+	org.eclipse.e4.emf.xpath;version='[0.2.700,0.2.701)',\
+	org.eclipse.e4.ui.bindings;version='[0.12.900,0.12.901)',\
+	org.eclipse.e4.ui.css.core;version='[0.12.1200,0.12.1201)',\
+	org.eclipse.e4.ui.css.swt;version='[0.13.1000,0.13.1001)',\
+	org.eclipse.e4.ui.css.swt.theme;version='[0.12.700,0.12.701)',\
+	org.eclipse.e4.ui.di;version='[1.2.800,1.2.801)',\
+	org.eclipse.e4.ui.dialogs;version='[1.1.800,1.1.801)',\
+	org.eclipse.e4.ui.ide;version='[3.15.100,3.15.101)',\
+	org.eclipse.e4.ui.model.workbench;version='[2.1.700,2.1.701)',\
+	org.eclipse.e4.ui.services;version='[1.3.700,1.3.701)',\
+	org.eclipse.e4.ui.widgets;version='[1.2.700,1.2.701)',\
+	org.eclipse.e4.ui.workbench;version='[1.11.300,1.11.301)',\
+	org.eclipse.e4.ui.workbench.addons.swt;version='[1.3.1000,1.3.1001)',\
+	org.eclipse.e4.ui.workbench.renderers.swt;version='[0.14.1200,0.14.1201)',\
+	org.eclipse.e4.ui.workbench.swt;version='[0.14.1000,0.14.1001)',\
+	org.eclipse.e4.ui.workbench3;version='[0.15.400,0.15.401)',\
+	org.eclipse.emf.common;version='[2.20.0,2.20.1)',\
+	org.eclipse.emf.common.ui;version='[2.18.0,2.18.1)',\
+	org.eclipse.emf.ecore;version='[2.23.0,2.23.1)',\
+	org.eclipse.emf.ecore.change;version='[2.14.0,2.14.1)',\
+	org.eclipse.emf.ecore.xmi;version='[2.16.0,2.16.1)',\
+	org.eclipse.emf.edit;version='[2.16.0,2.16.1)',\
+	org.eclipse.emf.edit.ui;version='[2.18.0,2.18.1)',\
+	org.eclipse.emf.transaction;version='[1.9.1,1.9.2)',\
+	org.eclipse.emf.validation;version='[1.8.0,1.8.1)',\
+	org.eclipse.equinox.app;version='[1.4.500,1.4.501)',\
+	org.eclipse.equinox.bidi;version='[1.2.300,1.2.301)',\
+	org.eclipse.equinox.common;version='[3.12.0,3.12.1)',\
+	org.eclipse.equinox.event;version='[1.5.400,1.5.401)',\
+	org.eclipse.equinox.p2.core;version='[2.6.300,2.6.301)',\
+	org.eclipse.equinox.p2.engine;version='[2.6.700,2.6.701)',\
+	org.eclipse.equinox.p2.metadata;version='[2.5.0,2.5.1)',\
+	org.eclipse.equinox.p2.metadata.repository;version='[1.3.400,1.3.401)',\
+	org.eclipse.equinox.p2.repository;version='[2.4.700,2.4.701)',\
+	org.eclipse.equinox.preferences;version='[3.8.0,3.8.1)',\
+	org.eclipse.equinox.registry;version='[3.8.800,3.8.801)',\
+	org.eclipse.equinox.security;version='[1.3.500,1.3.501)',\
+	org.eclipse.help;version='[3.8.800,3.8.801)',\
+	org.eclipse.jetty.client;version='[9.4.15,9.4.16)',\
+	org.eclipse.jetty.http;version='[9.4.29,9.4.30)',\
+	org.eclipse.jetty.io;version='[9.4.29,9.4.30)',\
+	org.eclipse.jetty.util;version='[9.4.29,9.4.30)',\
+	org.eclipse.jetty.websocket.api;version='[9.4.15,9.4.16)',\
+	org.eclipse.jetty.websocket.client;version='[9.4.15,9.4.16)',\
+	org.eclipse.jetty.websocket.common;version='[9.4.15,9.4.16)',\
+	org.eclipse.jetty.xml;version='[9.4.15,9.4.16)',\
+	org.eclipse.jface;version='[3.20.0,3.20.1)',\
+	org.eclipse.jface.databinding;version='[1.11.100,1.11.101)',\
+	org.eclipse.jface.text;version='[3.16.300,3.16.301)',\
+	org.eclipse.osgi.services;version='[3.8.0,3.8.1)',\
+	org.eclipse.sensinact.studio.http.messages;version=snapshot,\
+	org.eclipse.sensinact.studio.http.services;version=snapshot,\
+	org.eclipse.sensinact.studio.language.sensinact;version=snapshot,\
+	org.eclipse.sensinact.studio.language.sensinact.ide;version=snapshot,\
+	org.eclipse.sensinact.studio.language.sensinact.ui;version=snapshot,\
+	org.eclipse.sensinact.studio.model.manager;version=snapshot,\
+	org.eclipse.sensinact.studio.model.resource;version=snapshot,\
+	org.eclipse.sensinact.studio.preferences;version=snapshot,\
+	org.eclipse.swt;version='[3.114.100,3.114.101)',\
+	org.eclipse.text;version='[3.10.200,3.10.201)',\
+	org.eclipse.ui;version='[3.117.0,3.117.1)',\
+	org.eclipse.ui.console;version='[3.9.200,3.9.201)',\
+	org.eclipse.ui.editors;version='[3.13.200,3.13.201)',\
+	org.eclipse.ui.forms;version='[3.9.100,3.9.101)',\
+	org.eclipse.ui.ide;version='[3.17.100,3.17.101)',\
+	org.eclipse.ui.navigator;version='[3.9.300,3.9.301)',\
+	org.eclipse.ui.views;version='[3.10.300,3.10.301)',\
+	org.eclipse.ui.workbench;version='[3.119.0,3.119.1)',\
+	org.eclipse.ui.workbench.texteditor;version='[3.14.200,3.14.201)',\
+	org.eclipse.urischeme;version='[1.1.0,1.1.1)',\
+	org.eclipse.xtend.lib;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtend.lib.macro;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.builder;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.ide;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.smap;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.ui;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.ui.codetemplates;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.ui.codetemplates.ide;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.ui.codetemplates.ui;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.ui.shared;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.util;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.xbase.lib;version='[2.22.0,2.22.1)',\
+	org.json;version='[1.0.0,1.0.1)',\
+	org.osgi.util.function;version='[1.1.0,1.1.1)',\
+	org.osgi.util.promise;version='[1.1.1,1.1.2)',\
+	org.restlet;version='[2.2.3,2.2.4)',\
+	org.slf4j.api;version='[1.7.30,1.7.31)',\
+	org.tukaani.xz;version='[1.8.0,1.8.1)',\
+	org.w3c.css.sac;version='[1.3.1,1.3.2)',\
+	org.w3c.dom.events;version='[3.0.0,3.0.1)',\
+	org.w3c.dom.smil;version='[1.0.1,1.0.2)',\
+	org.w3c.dom.svg;version='[1.1.0,1.1.1)'
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/.antlr-generator-3.2.0-patch.jar b/bnd/org.eclipse.sensinact.studio.language.sensinact/.antlr-generator-3.2.0-patch.jar
new file mode 100644
index 0000000..90516fd
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/.antlr-generator-3.2.0-patch.jar
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/.classpath b/bnd/org.eclipse.sensinact.studio.language.sensinact/.classpath
new file mode 100644
index 0000000..734d19e
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/.classpath
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="src" output="bin" path="src"/>
+	<classpathentry kind="src" output="bin" path="xtend-gen"/>
+	<classpathentry kind="src" output="bin_test" path="test">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" path="src-gen"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/.gitignore b/bnd/org.eclipse.sensinact.studio.language.sensinact/.gitignore
new file mode 100644
index 0000000..6797bd3
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/.gitignore
@@ -0,0 +1,3 @@
+/bin_test/
+/generated/
+/test_workspace/
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/.project b/bnd/org.eclipse.sensinact.studio.language.sensinact/.project
new file mode 100644
index 0000000..d96a18c
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/.project
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.sensinact.studio.language.sensinact</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.xtext.ui.shared.xtextBuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+		<nature>org.eclipse.xtext.ui.shared.xtextNature</nature>
+	</natures>
+</projectDescription>
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/bnd.bnd b/bnd/org.eclipse.sensinact.studio.language.sensinact/bnd.bnd
new file mode 100644
index 0000000..2d3648b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/bnd.bnd
@@ -0,0 +1,48 @@
+src: ${^src},src-gen,xtend-gen
+
+-enable-gecko-emf: true
+
+Bundle-Version: 1.0.0-SNAPSHOT
+Bundle-SymbolicName: ${p};singleton:=true
+Bundle-ActivationPolicy: lazy
+
+-includeresource.model: \
+	model=model/generated,\
+	plugin.xml
+	
+-buildpath: \
+	com.google.inject,\
+	org.eclipse.xtext.xtext.generator,\
+	org.eclipse.emf.mwe2.runtime,\
+	org.eclipse.emf.mwe.core,\
+	org.eclipse.xtext,\
+	org.eclipse.xtext.xbase,\
+	org.eclipse.equinox.common,\
+	org.eclipse.xtext.xbase.lib,\
+	org.eclipse.xtext.util,\
+	org.eclipse.xtend.lib,\
+	org.apache.log4j,\
+	org.antlr.runtime,\
+	org.eclipse.sensinact.studio.model.resource;version=project,\
+	org.eclipse.sensinact.studio.model.manager;version=project,\
+	org.gecko.eclipse.compatibility,\
+	org.gecko.eclipse.compatibility.equinox.config,\
+	com.google.guava;version=latest,\
+	org.eclipse.xtend.lib.macro,\
+	org.eclipse.xtext.xbase.lib,\
+	org.gecko.bnd.eclipse.launcher.plugin,\
+	org.eclipse.draw2d
+	
+Export-Package: \
+	org.eclipse.sensinact.studio.language,\
+	org.eclipse.sensinact.studio.language.parser.antlr,\
+	org.eclipse.sensinact.studio.language.parser.antlr.internal,\
+	org.eclipse.sensinact.studio.language.scoping,\
+	org.eclipse.sensinact.studio.language.sensinact,\
+	org.eclipse.sensinact.studio.language.sensinact.impl,\
+	org.eclipse.sensinact.studio.language.sensinact.util,\
+	org.eclipse.sensinact.studio.language.serializer,\
+	org.eclipse.sensinact.studio.language.services,\
+	org.eclipse.sensinact.studio.language.validation,\
+	org.eclipse.sensinact.studio.language.generator
+	
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/launch_base.bndrun b/bnd/org.eclipse.sensinact.studio.language.sensinact/launch_base.bndrun
new file mode 100644
index 0000000..c3fce76
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/launch_base.bndrun
@@ -0,0 +1,261 @@
+-runee: JavaSE-1.8
+
+#-resolve.effective: active;skip:="osgi.service"
+
+# the system package must have the verison, because there is the 
+# org.apache.servicemix.specs.annotation-api-1.3 and javax.annotation bundle 
+# that export it with the version 1.3, so some, bundles get wired to the system javax. annotation 
+# packages and some to the ones from providing bundles. This is only necessary when running on java < 9
+-runsystempackages: \
+        javax.annotation;version=1.3,\
+        com.sun.net.httpserver
+
+-runsystemcapabilities: \
+	osgi.service;objectClass:List<String>="java.lang.Object"
+
+-runpath:\
+	org.gecko.bnd.eclipse.launcher.plugin,\
+	org.gecko.bnd.equinox.launcher.splashscreen;version='[1.0.1,2)',\
+	log4j.over.slf4j;version='[1.7.25,1.7.26)',\
+
+-enable-slf4j-logback: true
+
+-runfw: org.eclipse.osgi;version='[3.15.300.v20200520-1959,3.15.300.v20200520-1959]'
+
+-runproperties.eclipse: \
+	eclipse.product=org.eclipse.sensinact.studio.language.sensinact.sensinact,\
+	eclipse.application=org.eclipse.ui.ide.workbench,\
+	osgi.compatibility.eagerStart.LazyActivation=false
+
+-runproperties.common: \
+	osgi.console=,\
+	console=,\
+	eclipse.consoleLog=,\
+	osgi.console.enable.builtin=false,\
+	consoleLog=,\
+	osgi.instance.area=${.}/test_workspace,\
+	name=,\
+	splash.location=splash.bmp,\
+	ds.loglevel=DEBUG
+	
+# A couple of older bundles in the Eclipse targetplatform, expect certain packages e.g. from the javax namespace to be loaded from the System ClassLoader.
+# Uncomment this if you stume about ClassNotFoundExceptions for javax.* Classes or org.w3c.* etc. 
+#-runproperties.compatible.bootdelegation: \
+#	osgi.compatibility.bootdelegation=true
+	
+-includeresource: \
+	/splash.bmp=${.}/splash.bmp
+
+-runrequires: \
+	bnd.identity;id='org.eclipse.equinox.console',\
+	bnd.identity;id='org.apache.felix.gogo.shell',\
+	bnd.identity;id='org.apache.felix.gogo.command',\
+	bnd.identity;id='org.apache.felix.gogo.runtime',\
+	bnd.identity;id='org.eclipse.ui.ide',\
+	bnd.identity;id='org.eclipse.ui.ide.application',\
+	bnd.identity;id='org.eclipse.e4.ui.ide',\
+	osgi.identity;filter:='(&(osgi.identity=org.eclipse.xtext.common.types.ui)(version>=2.22.0))',\
+	osgi.identity;filter:='(&(osgi.identity=org.eclipse.xtend.typesystem.emf)(version>=2.2.0))',\
+	osgi.identity;filter:='(&(osgi.identity=org.eclipse.xtend)(version>=2.2.0))',\
+	osgi.identity;filter:='(&(osgi.identity=org.objectweb.asm)(version>=8.0.1))',\
+	osgi.identity;filter:='(&(osgi.identity=org.eclipse.emf.mwe.utils)(version>=1.5.3))',\
+	osgi.identity;filter:='(&(osgi.identity=org.eclipse.emf.mwe.core)(version>=1.5.3))',\
+	bnd.identity;id='org.eclipse.sensinact.studio.http.messages',\
+	bnd.identity;id='org.eclipse.sensinact.studio.http.services',\
+	bnd.identity;id='org.eclipse.sensinact.studio.language.sensinact',\
+	bnd.identity;id='org.eclipse.sensinact.studio.language.sensinact.ide',\
+	bnd.identity;id='org.eclipse.sensinact.studio.language.sensinact.ui',\
+	bnd.identity;id='org.eclipse.sensinact.studio.model.manager',\
+	bnd.identity;id='org.eclipse.sensinact.studio.model.resource',\
+	bnd.identity;id='org.eclipse.sensinact.studio.navigator.device',\
+	bnd.identity;id='org.eclipse.sensinact.studio.perspective',\
+	bnd.identity;id='org.eclipse.sensinact.studio.preferences',\
+	bnd.identity;id='org.eclipse.sensinact.studio.ui.common',\
+	bnd.identity;id='org.eclipse.sensinact.studio.view.outdoor',\
+	bnd.identity;id='org.eclipse.sensinact.studio.view.projectexplorer',\
+	bnd.identity;id='org.eclipse.sensinact.studio.view.visualizer',\
+	bnd.identity;id='org.eclipse.sensinact.studio.webapp.indoor',\
+	bnd.identity;id='org.eclipse.sensinact.studio.webapp.outdoor',\
+	bnd.identity;id='org.gecko.eclipse.compatibility'
+
+
+-runblacklist: \
+	bnd.identity;id='org.apache.felix.eventadmin',\
+	bnd.identity;version='[21, 27)';id='com.google.guava'
+-runbundles: \
+	com.fasterxml.jackson.core.jackson-annotations;version='[2.10.3,2.10.4)',\
+	com.fasterxml.jackson.core.jackson-core;version='[2.10.3,2.10.4)',\
+	com.fasterxml.jackson.core.jackson-databind;version='[2.10.3,2.10.4)',\
+	com.google.guava;version='[27.1.0,27.1.1)',\
+	com.google.inject;version='[3.0.0,3.0.1)',\
+	com.ibm.icu;version='[64.2.0,64.2.1)',\
+	io.github.classgraph;version='[4.8.35,4.8.36)',\
+	javax.inject;version='[1.0.0,1.0.1)',\
+	org.antlr.runtime;version='[3.2.0,3.2.1)',\
+	org.aopalliance;version='[1.0.0,1.0.1)',\
+	org.apache.batik.constants;version='[1.11.0,1.11.1)',\
+	org.apache.batik.css;version='[1.11.0,1.11.1)',\
+	org.apache.batik.i18n;version='[1.11.0,1.11.1)',\
+	org.apache.batik.util;version='[1.11.0,1.11.1)',\
+	org.apache.commons.cli;version='[1.2.0,1.2.1)',\
+	org.apache.commons.io;version='[2.6.0,2.6.1)',\
+	org.apache.commons.jxpath;version='[1.3.0,1.3.1)',\
+	org.apache.commons.lang;version='[2.6.0,2.6.1)',\
+	org.apache.commons.logging;version='[1.2.0,1.2.1)',\
+	org.apache.felix.gogo.command;version='[1.0.2,1.0.3)',\
+	org.apache.felix.gogo.runtime;version='[1.1.0,1.1.1)',\
+	org.apache.felix.gogo.shell;version='[1.1.0,1.1.1)',\
+	org.apache.felix.http.servlet-api;version='[1.1.2,1.1.3)',\
+	org.apache.xmlgraphics;version='[2.3.0,2.3.1)',\
+	org.eclipse.compare;version='[3.7.1000,3.7.1001)',\
+	org.eclipse.compare.core;version='[3.6.900,3.6.901)',\
+	org.eclipse.core.commands;version='[3.9.700,3.9.701)',\
+	org.eclipse.core.contenttype;version='[3.7.700,3.7.701)',\
+	org.eclipse.core.databinding;version='[1.9.0,1.9.1)',\
+	org.eclipse.core.databinding.observable;version='[1.9.0,1.9.1)',\
+	org.eclipse.core.databinding.property;version='[1.8.0,1.8.1)',\
+	org.eclipse.core.expressions;version='[3.6.800,3.6.801)',\
+	org.eclipse.core.filebuffers;version='[3.6.1000,3.6.1001)',\
+	org.eclipse.core.filesystem;version='[1.7.700,1.7.701)',\
+	org.eclipse.core.jobs;version='[3.10.800,3.10.801)',\
+	org.eclipse.core.net;version='[1.3.900,1.3.901)',\
+	org.eclipse.core.resources;version='[3.13.700,3.13.701)',\
+	org.eclipse.core.runtime;version='[3.18.0,3.18.1)',\
+	org.eclipse.core.variables;version='[3.4.800,3.4.801)',\
+	org.eclipse.debug.core;version='[3.15.100,3.15.101)',\
+	org.eclipse.debug.ui;version='[3.14.500,3.14.501)',\
+	org.eclipse.e4.core.commands;version='[0.12.900,0.12.901)',\
+	org.eclipse.e4.core.contexts;version='[1.8.400,1.8.401)',\
+	org.eclipse.e4.core.di;version='[1.7.600,1.7.601)',\
+	org.eclipse.e4.core.di.annotations;version='[1.6.600,1.6.601)',\
+	org.eclipse.e4.core.di.extensions;version='[0.16.0,0.16.1)',\
+	org.eclipse.e4.core.di.extensions.supplier;version='[0.15.600,0.15.601)',\
+	org.eclipse.e4.core.services;version='[2.2.300,2.2.301)',\
+	org.eclipse.e4.emf.xpath;version='[0.2.700,0.2.701)',\
+	org.eclipse.e4.ui.bindings;version='[0.12.900,0.12.901)',\
+	org.eclipse.e4.ui.css.core;version='[0.12.1200,0.12.1201)',\
+	org.eclipse.e4.ui.css.swt;version='[0.13.1000,0.13.1001)',\
+	org.eclipse.e4.ui.css.swt.theme;version='[0.12.700,0.12.701)',\
+	org.eclipse.e4.ui.di;version='[1.2.800,1.2.801)',\
+	org.eclipse.e4.ui.dialogs;version='[1.1.800,1.1.801)',\
+	org.eclipse.e4.ui.ide;version='[3.15.100,3.15.101)',\
+	org.eclipse.e4.ui.model.workbench;version='[2.1.700,2.1.701)',\
+	org.eclipse.e4.ui.services;version='[1.3.700,1.3.701)',\
+	org.eclipse.e4.ui.widgets;version='[1.2.700,1.2.701)',\
+	org.eclipse.e4.ui.workbench;version='[1.11.300,1.11.301)',\
+	org.eclipse.e4.ui.workbench.addons.swt;version='[1.3.1000,1.3.1001)',\
+	org.eclipse.e4.ui.workbench.renderers.swt;version='[0.14.1200,0.14.1201)',\
+	org.eclipse.e4.ui.workbench.swt;version='[0.14.1000,0.14.1001)',\
+	org.eclipse.e4.ui.workbench3;version='[0.15.400,0.15.401)',\
+	org.eclipse.emf.common;version='[2.20.0,2.20.1)',\
+	org.eclipse.emf.common.ui;version='[2.18.0,2.18.1)',\
+	org.eclipse.emf.ecore;version='[2.23.0,2.23.1)',\
+	org.eclipse.emf.ecore.change;version='[2.14.0,2.14.1)',\
+	org.eclipse.emf.ecore.xmi;version='[2.16.0,2.16.1)',\
+	org.eclipse.emf.edit;version='[2.16.0,2.16.1)',\
+	org.eclipse.emf.edit.ui;version='[2.18.0,2.18.1)',\
+	org.eclipse.emf.mwe.core;version='[1.5.3,1.5.4)',\
+	org.eclipse.emf.mwe.utils;version='[1.5.3,1.5.4)',\
+	org.eclipse.emf.mwe2.runtime;version='[2.11.3,2.11.4)',\
+	org.eclipse.emf.transaction;version='[1.9.1,1.9.2)',\
+	org.eclipse.emf.validation;version='[1.8.0,1.8.1)',\
+	org.eclipse.equinox.app;version='[1.4.500,1.4.501)',\
+	org.eclipse.equinox.bidi;version='[1.2.300,1.2.301)',\
+	org.eclipse.equinox.common;version='[3.12.0,3.12.1)',\
+	org.eclipse.equinox.console;version='[1.4.100,1.4.101)',\
+	org.eclipse.equinox.event;version='[1.5.400,1.5.401)',\
+	org.eclipse.equinox.p2.core;version='[2.6.300,2.6.301)',\
+	org.eclipse.equinox.p2.engine;version='[2.6.700,2.6.701)',\
+	org.eclipse.equinox.p2.metadata;version='[2.5.0,2.5.1)',\
+	org.eclipse.equinox.p2.metadata.repository;version='[1.3.400,1.3.401)',\
+	org.eclipse.equinox.p2.repository;version='[2.4.700,2.4.701)',\
+	org.eclipse.equinox.preferences;version='[3.8.0,3.8.1)',\
+	org.eclipse.equinox.registry;version='[3.8.800,3.8.801)',\
+	org.eclipse.equinox.security;version='[1.3.500,1.3.501)',\
+	org.eclipse.help;version='[3.8.800,3.8.801)',\
+	org.eclipse.jdt.core;version='[3.22.0,3.22.1)',\
+	org.eclipse.jdt.core.manipulation;version='[1.14.0,1.14.1)',\
+	org.eclipse.jdt.debug;version='[3.15.100,3.15.101)',\
+	org.eclipse.jdt.launching;version='[3.17.100,3.17.101)',\
+	org.eclipse.jdt.ui;version='[3.21.100,3.21.101)',\
+	org.eclipse.jetty.client;version='[9.4.15,9.4.16)',\
+	org.eclipse.jetty.http;version='[9.4.15,9.4.16)',\
+	org.eclipse.jetty.io;version='[9.4.15,9.4.16)',\
+	org.eclipse.jetty.util;version='[9.4.15,9.4.16)',\
+	org.eclipse.jetty.websocket.api;version='[9.4.15,9.4.16)',\
+	org.eclipse.jetty.websocket.client;version='[9.4.15,9.4.16)',\
+	org.eclipse.jetty.websocket.common;version='[9.4.15,9.4.16)',\
+	org.eclipse.jetty.xml;version='[9.4.15,9.4.16)',\
+	org.eclipse.jface;version='[3.20.0,3.20.1)',\
+	org.eclipse.jface.databinding;version='[1.11.100,1.11.101)',\
+	org.eclipse.jface.text;version='[3.16.300,3.16.301)',\
+	org.eclipse.ltk.core.refactoring;version='[3.11.0,3.11.1)',\
+	org.eclipse.ltk.ui.refactoring;version='[3.11.0,3.11.1)',\
+	org.eclipse.osgi.services;version='[3.8.0,3.8.1)',\
+	org.eclipse.search;version='[3.11.1000,3.11.1001)',\
+	org.eclipse.sensinact.studio.http.messages;version=snapshot,\
+	org.eclipse.sensinact.studio.http.services;version=snapshot,\
+	org.eclipse.sensinact.studio.language.sensinact;version=snapshot,\
+	org.eclipse.sensinact.studio.language.sensinact.ide;version=snapshot,\
+	org.eclipse.sensinact.studio.language.sensinact.ui;version=snapshot,\
+	org.eclipse.sensinact.studio.model.manager;version=snapshot,\
+	org.eclipse.sensinact.studio.model.resource;version=snapshot,\
+	org.eclipse.sensinact.studio.navigator.device;version=snapshot,\
+	org.eclipse.sensinact.studio.perspective;version=snapshot,\
+	org.eclipse.sensinact.studio.preferences;version=snapshot,\
+	org.eclipse.sensinact.studio.ui.common;version=snapshot,\
+	org.eclipse.sensinact.studio.view.outdoor;version=snapshot,\
+	org.eclipse.sensinact.studio.view.projectexplorer;version=snapshot,\
+	org.eclipse.sensinact.studio.view.visualizer;version=snapshot,\
+	org.eclipse.sensinact.studio.webapp.indoor;version=snapshot,\
+	org.eclipse.sensinact.studio.webapp.outdoor;version=snapshot,\
+	org.eclipse.swt;version='[3.114.100,3.114.101)',\
+	org.eclipse.swt.gtk.linux.ppc64le;version='[3.114.100,3.114.101)',\
+	org.eclipse.team.core;version='[3.8.1000,3.8.1001)',\
+	org.eclipse.team.ui;version='[3.8.900,3.8.901)',\
+	org.eclipse.text;version='[3.10.200,3.10.201)',\
+	org.eclipse.ui;version='[3.117.0,3.117.1)',\
+	org.eclipse.ui.console;version='[3.9.200,3.9.201)',\
+	org.eclipse.ui.editors;version='[3.13.200,3.13.201)',\
+	org.eclipse.ui.forms;version='[3.9.100,3.9.101)',\
+	org.eclipse.ui.ide;version='[3.17.100,3.17.101)',\
+	org.eclipse.ui.ide.application;version='[1.3.700,1.3.701)',\
+	org.eclipse.ui.navigator;version='[3.9.300,3.9.301)',\
+	org.eclipse.ui.navigator.resources;version='[3.7.300,3.7.301)',\
+	org.eclipse.ui.views;version='[3.10.300,3.10.301)',\
+	org.eclipse.ui.views.properties.tabbed;version='[3.8.900,3.8.901)',\
+	org.eclipse.ui.workbench;version='[3.119.0,3.119.1)',\
+	org.eclipse.ui.workbench.texteditor;version='[3.14.200,3.14.201)',\
+	org.eclipse.urischeme;version='[1.1.0,1.1.1)',\
+	org.eclipse.xtend;version='[2.2.0,2.2.1)',\
+	org.eclipse.xtend.lib;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtend.lib.macro;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtend.typesystem.emf;version='[2.2.0,2.2.1)',\
+	org.eclipse.xtext;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.builder;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.common.types;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.common.types.ui;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.ide;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.smap;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.ui;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.ui.codetemplates;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.ui.codetemplates.ide;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.ui.codetemplates.ui;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.ui.shared;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.util;version='[2.22.0,2.22.1)',\
+	org.eclipse.xtext.xbase.lib;version='[2.22.0,2.22.1)',\
+	org.gecko.eclipse.compatibility;version='[1.1.1,1.1.2)',\
+	org.gecko.eclipse.compatibility.equinox.config;version='[1.1.1,1.1.2)',\
+	org.objectweb.asm;version='[8.0.1,8.0.2)',\
+	org.osgi.util.function;version='[1.1.0,1.1.1)',\
+	org.osgi.util.promise;version='[1.1.1,1.1.2)',\
+	org.restlet;version='[2.2.3,2.2.4)',\
+	org.tukaani.xz;version='[1.8.0,1.8.1)',\
+	org.w3c.css.sac;version='[1.3.1,1.3.2)',\
+	org.w3c.dom.events;version='[3.0.0,3.0.1)',\
+	org.w3c.dom.smil;version='[1.0.1,1.0.2)',\
+	org.w3c.dom.svg;version='[1.1.0,1.1.1)',\
+	org.apache.felix.scr;version='[2.1.24,2.1.25)',\
+	json;version='[20210307.0.0,20210307.0.1)',\
+	org.eclipse.draw2d;version='[3.10.100,3.10.101)',\
+	org.eclipse.nebula.visualization.xygraph;version='[2.1.0,2.1.1)'
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/launch_linux.bndrun b/bnd/org.eclipse.sensinact.studio.language.sensinact/launch_linux.bndrun
new file mode 100644
index 0000000..04c9112
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/launch_linux.bndrun
@@ -0,0 +1,18 @@
+-include: launch_base.bndrun
+
+-runsystemcapabilities: ${native_capability;osname=Linux;osversion=3.14;processor=x86_64}
+-runprovidedcapabilities: ${native_capability;osname=Linux;osversion=3.14;processor=x86_64}
+
+
+-runrequires.win32: \
+	bnd.identity;id='org.eclipse.swt.gtk.linux.x86_64',\
+	bnd.identity;id='org.eclipse.core.filesystem.linux.x86_64',\
+	bnd.identity;id='org.eclipse.core.net.linux.x86_64',\
+	bnd.identity;id='org.eclipse.equinox.security.linux.x86_64'
+	
+-runbundles.win32: \
+	org.eclipse.core.filesystem.linux.x86_64;version='[1.4.200,1.4.201)',\
+	org.eclipse.core.net.linux.x86_64;version='[1.1.400,1.1.401)',\
+	org.eclipse.equinox.security.linux.x86_64;version='[1.1.200,1.1.201)',\
+	org.eclipse.swt.gtk.linux.x86_64;version='[3.112.0,3.112.1)'
+
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/launch_win32.bndrun b/bnd/org.eclipse.sensinact.studio.language.sensinact/launch_win32.bndrun
new file mode 100644
index 0000000..d988ac5
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/launch_win32.bndrun
@@ -0,0 +1,17 @@
+-include: launch_base.bndrun
+
+-runsystemcapabilities.native: ${native_capability;osname=Windows;osversion=10;processor=x86_64}
+
+-runrequires.win32: \
+	bnd.identity;id='org.eclipse.swt.win32.win32.x86_64',\
+	bnd.identity;id='org.eclipse.core.filesystem.win32.x86_64',\
+	bnd.identity;id='org.eclipse.core.net.win32.x86_64',\
+	bnd.identity;id='org.eclipse.equinox.security.win32.x86_64'
+	
+-runbundles.win32: \
+	org.eclipse.core.filesystem.win32.x86_64,\
+	org.eclipse.core.net.win32.x86_64,\
+	org.eclipse.equinox.security.win32.x86_64,\
+	org.eclipse.swt.win32.win32.x86_64
+	
+-runtrace: true
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/logback.xml b/bnd/org.eclipse.sensinact.studio.language.sensinact/logback.xml
new file mode 100644
index 0000000..12b325f
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/logback.xml
@@ -0,0 +1,23 @@
+<configuration>
+    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
+        <file>gecko_logback.log</file>
+    	<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+    		<level>INFO</level>
+    	</filter>
+        <encoder>
+        	<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+    </appender>
+    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
+    	<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
+    		<level>DEBUG</level>
+    	</filter>
+        <encoder>
+        	<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
+        </encoder>
+    </appender>
+    
+    <root level="INFO">
+        <appender-ref ref="CONSOLE" />
+    </root>
+</configuration>
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/model/generated/Sensinact.ecore b/bnd/org.eclipse.sensinact.studio.language.sensinact/model/generated/Sensinact.ecore
new file mode 100644
index 0000000..76374b3
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/model/generated/Sensinact.ecore
@@ -0,0 +1,245 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="sensinact" nsURI="http://www.eclipse.org/sensinact/studio/language/Sensinact"
+    nsPrefix="sensinact">
+  <eClassifiers xsi:type="ecore:EClass" name="Sensinact">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="eca" eType="#//DSL_SENSINACT"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_SENSINACT">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="autostart" eType="#//DSL_FLAG_AUTOSTART"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="resources" upperBound="-1"
+        eType="#//DSL_Resource" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="cep" upperBound="-1" eType="#//DSL_CEP_STATEMENT"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="on" eType="#//DSL_On" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="eca" eType="#//DSL_ECA_STATEMENT"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_FLAG_AUTOSTART">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="activated" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Resource" eSuperTypes="#//DSL_REF">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="gatewayID" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="deviceID" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="serviceID" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="resourceID" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_On">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="triggers" upperBound="-1"
+        eType="#//DSL_REF_CONDITION" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_ECA_STATEMENT">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ifdo" eType="#//DSL_IfDo"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="elseIfdo" upperBound="-1"
+        eType="#//DSL_ElseIfDo" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="elsedo" eType="#//DSL_ElseDo"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_IfDo">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="condition" eType="#//DSL_Expression"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="actions" eType="#//DSL_ListActions"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_ElseIfDo">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="condition" eType="#//DSL_Expression"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="actions" eType="#//DSL_ListActions"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_ElseDo">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="actions" eType="#//DSL_ListActions"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_REF">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_REF_CONDITION">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ref" eType="#//DSL_REF"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_CEP_STATEMENT" eSuperTypes="#//DSL_REF">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="operation" eType="ecore:EClass http://www.eclipse.org/emf/2002/Ecore#//EObject"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_CEP_AFTER">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ref1" eType="#//DSL_REF_CONDITION"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ref2" eType="#//DSL_REF_CONDITION"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="start" eType="#//DSL_CEP_DURATION"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="end" eType="#//DSL_CEP_DURATION"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_CEP_BEFORE">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ref1" eType="#//DSL_REF_CONDITION"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ref2" eType="#//DSL_REF_CONDITION"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="start" eType="#//DSL_CEP_DURATION"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="end" eType="#//DSL_CEP_DURATION"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_CEP_COINCIDE">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ref1" eType="#//DSL_REF_CONDITION"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ref2" eType="#//DSL_REF_CONDITION"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="window" eType="#//DSL_CEP_DURATION"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_CEP_MIN">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ref" eType="#//DSL_REF_CONDITION"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="window" eType="#//DSL_CEP_DURATION"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_CEP_MAX">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ref" eType="#//DSL_REF_CONDITION"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="window" eType="#//DSL_CEP_DURATION"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_CEP_AVG">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ref" eType="#//DSL_REF_CONDITION"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="window" eType="#//DSL_CEP_DURATION"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_CEP_SUM">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ref" eType="#//DSL_REF_CONDITION"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="window" eType="#//DSL_CEP_DURATION"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_CEP_COUNT">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ref" eType="#//DSL_REF_CONDITION"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="window" eType="#//DSL_CEP_DURATION"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_CEP_DURATION">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="units" upperBound="-1"
+        eType="ecore:EClass http://www.eclipse.org/emf/2002/Ecore#//EObject" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_CEP_DURATION_MIN">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="min" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBigDecimal"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_CEP_DURATION_SEC">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="sec" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBigDecimal"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_ListActions">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="actionList" upperBound="-1"
+        eType="#//DSL_ResourceAction" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_ResourceAction">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="variable" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="ref" eType="#//DSL_REF"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="actiontype" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="listParam" eType="#//DSL_ListParam"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_ListParam">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="param" upperBound="-1"
+        eType="#//DSL_Expression" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Expression"/>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Expression_Or" eSuperTypes="#//DSL_Expression">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="left" eType="#//DSL_Expression"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="right" eType="#//DSL_Expression"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Expression_And" eSuperTypes="#//DSL_Expression">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="left" eType="#//DSL_Expression"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="right" eType="#//DSL_Expression"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Expression_Diff" eSuperTypes="#//DSL_Expression">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="left" eType="#//DSL_Expression"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="right" eType="#//DSL_Expression"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Expression_Equal" eSuperTypes="#//DSL_Expression">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="left" eType="#//DSL_Expression"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="right" eType="#//DSL_Expression"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Expression_Larger" eSuperTypes="#//DSL_Expression">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="left" eType="#//DSL_Expression"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="right" eType="#//DSL_Expression"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Expression_Larger_Equal" eSuperTypes="#//DSL_Expression">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="left" eType="#//DSL_Expression"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="right" eType="#//DSL_Expression"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Expression_Smaller" eSuperTypes="#//DSL_Expression">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="left" eType="#//DSL_Expression"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="right" eType="#//DSL_Expression"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Expression_Smaller_Equal" eSuperTypes="#//DSL_Expression">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="left" eType="#//DSL_Expression"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="right" eType="#//DSL_Expression"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Expression_Plus" eSuperTypes="#//DSL_Expression">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="left" eType="#//DSL_Expression"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="right" eType="#//DSL_Expression"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Expression_Minus" eSuperTypes="#//DSL_Expression">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="left" eType="#//DSL_Expression"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="right" eType="#//DSL_Expression"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Expression_Multiplication" eSuperTypes="#//DSL_Expression">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="left" eType="#//DSL_Expression"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="right" eType="#//DSL_Expression"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Expression_Division" eSuperTypes="#//DSL_Expression">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="left" eType="#//DSL_Expression"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="right" eType="#//DSL_Expression"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Expression_Modulo" eSuperTypes="#//DSL_Expression">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="left" eType="#//DSL_Expression"
+        containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="right" eType="#//DSL_Expression"
+        containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Object_Number" eSuperTypes="#//DSL_Expression">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBigDecimal"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Object_String" eSuperTypes="#//DSL_Expression">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Object_Boolean" eSuperTypes="#//DSL_Expression">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EBoolean"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Object_Ref" eSuperTypes="#//DSL_Expression">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="value" eType="#//DSL_REF"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="DSL_Expression_Negate" eSuperTypes="#//DSL_Expression">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="exp" eType="#//DSL_Expression"
+        containment="true"/>
+  </eClassifiers>
+</ecore:EPackage>
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/model/generated/Sensinact.genmodel b/bnd/org.eclipse.sensinact.studio.language.sensinact/model/generated/Sensinact.genmodel
new file mode 100644
index 0000000..1cc2842
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/model/generated/Sensinact.genmodel
@@ -0,0 +1,183 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<genmodel:GenModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+    xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" copyrightText="generated by Xtext 2.22.0" modelDirectory="/org.eclipse.sensinact.studio.language.sensinact/src-gen"
+    modelPluginID="org.eclipse.sensinact.studio.language.sensinact" forceOverwrite="true"
+    modelName="Sensinact" updateClasspath="false" rootExtendsClass="org.eclipse.emf.ecore.impl.MinimalEObjectImpl$Container"
+    complianceLevel="8.0" copyrightFields="false" runtimeVersion="2.20">
+  <genPackages prefix="Sensinact" basePackage="org.eclipse.sensinact.studio.language"
+      disposableProviderFactory="true" fileExtensions="sna" ecorePackage="Sensinact.ecore#/">
+    <genClasses ecoreClass="Sensinact.ecore#//Sensinact">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//Sensinact/eca"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_SENSINACT">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_SENSINACT/autostart"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_SENSINACT/resources"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_SENSINACT/cep"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_SENSINACT/on"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_SENSINACT/eca"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_FLAG_AUTOSTART">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Sensinact.ecore#//DSL_FLAG_AUTOSTART/activated"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Resource">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Sensinact.ecore#//DSL_Resource/gatewayID"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Sensinact.ecore#//DSL_Resource/deviceID"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Sensinact.ecore#//DSL_Resource/serviceID"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Sensinact.ecore#//DSL_Resource/resourceID"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_On">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_On/triggers"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_ECA_STATEMENT">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_ECA_STATEMENT/ifdo"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_ECA_STATEMENT/elseIfdo"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_ECA_STATEMENT/elsedo"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_IfDo">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_IfDo/condition"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_IfDo/actions"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_ElseIfDo">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_ElseIfDo/condition"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_ElseIfDo/actions"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_ElseDo">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_ElseDo/actions"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_REF">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Sensinact.ecore#//DSL_REF/name"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_REF_CONDITION">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_REF_CONDITION/ref"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_CEP_STATEMENT">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_STATEMENT/operation"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_CEP_AFTER">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_AFTER/ref1"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_AFTER/ref2"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_AFTER/start"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_AFTER/end"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_CEP_BEFORE">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_BEFORE/ref1"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_BEFORE/ref2"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_BEFORE/start"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_BEFORE/end"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_CEP_COINCIDE">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_COINCIDE/ref1"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_COINCIDE/ref2"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_COINCIDE/window"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_CEP_MIN">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_MIN/ref"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_MIN/window"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_CEP_MAX">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_MAX/ref"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_MAX/window"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_CEP_AVG">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_AVG/ref"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_AVG/window"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_CEP_SUM">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_SUM/ref"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_SUM/window"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_CEP_COUNT">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_COUNT/ref"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_COUNT/window"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_CEP_DURATION">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_CEP_DURATION/units"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_CEP_DURATION_MIN">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Sensinact.ecore#//DSL_CEP_DURATION_MIN/min"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_CEP_DURATION_SEC">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Sensinact.ecore#//DSL_CEP_DURATION_SEC/sec"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_ListActions">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_ListActions/actionList"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_ResourceAction">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Sensinact.ecore#//DSL_ResourceAction/variable"/>
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_ResourceAction/ref"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Sensinact.ecore#//DSL_ResourceAction/actiontype"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_ResourceAction/listParam"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_ListParam">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_ListParam/param"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Expression"/>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Expression_Or">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Or/left"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Or/right"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Expression_And">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_And/left"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_And/right"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Expression_Diff">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Diff/left"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Diff/right"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Expression_Equal">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Equal/left"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Equal/right"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Expression_Larger">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Larger/left"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Larger/right"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Expression_Larger_Equal">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Larger_Equal/left"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Larger_Equal/right"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Expression_Smaller">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Smaller/left"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Smaller/right"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Expression_Smaller_Equal">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Smaller_Equal/left"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Smaller_Equal/right"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Expression_Plus">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Plus/left"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Plus/right"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Expression_Minus">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Minus/left"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Minus/right"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Expression_Multiplication">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Multiplication/left"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Multiplication/right"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Expression_Division">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Division/left"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Division/right"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Expression_Modulo">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Modulo/left"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Modulo/right"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Object_Number">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Sensinact.ecore#//DSL_Object_Number/value"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Object_String">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Sensinact.ecore#//DSL_Object_String/value"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Object_Boolean">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute Sensinact.ecore#//DSL_Object_Boolean/value"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Object_Ref">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Object_Ref/value"/>
+    </genClasses>
+    <genClasses ecoreClass="Sensinact.ecore#//DSL_Expression_Negate">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference Sensinact.ecore#//DSL_Expression_Negate/exp"/>
+    </genClasses>
+  </genPackages>
+</genmodel:GenModel>
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/plugin.xml b/bnd/org.eclipse.sensinact.studio.language.sensinact/plugin.xml
new file mode 100644
index 0000000..f9c5545
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/plugin.xml
@@ -0,0 +1,49 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2018 CEA.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+
+     Contributors:
+        CEA - initial API and implementation and/or initial documentation
+
+-->
+<?eclipse version="3.0"?>
+
+<plugin>
+
+  <extension point="org.eclipse.emf.ecore.generated_package">
+    <package 
+       uri = "http://www.eclipse.org/sensinact/studio/language/Sensinact" 
+       class = "org.eclipse.sensinact.studio.language.sensinact.SensinactPackage"
+       genModel = "model/generated/Sensinact.genmodel" /> 
+	
+  </extension>
+  <extension
+        id="sensinact"
+        point="org.eclipse.core.runtime.products">
+     <product
+           application="org.eclipse.ui.ide.workbench"
+           name="Sensinact Studio">
+        <property
+              name="aboutText"
+              value="Sensinact Studio">
+        </property>
+        <property
+              name="aboutImage"
+              value="platform:/plugin/org.eclipse.sensinact.studio.ui.common/images/icons/icon128.png">
+        </property>
+        <property
+              name="appName"
+              value="Sensinact Studio">
+        </property>
+        <property
+              name="windowImages"
+              value="platform:/plugin/org.eclipse.sensinact.studio.ui.common/images/icons/icon16.png,platform:/plugin/org.eclipse.sensinact.studio.ui.common/images/icons/icon32.png,platform:/plugin/org.eclipse.sensinact.studio.ui.common/images/icons/icon48.png,platform:/plugin/org.eclipse.sensinact.studio.ui.common/images/icons/icon64.png,platform:/plugin/org.eclipse.sensinact.studio.ui.common/images/icons/icon128.png,platform:/plugin/org.eclipse.sensinact.studio.ui.common/images/icons/icon256.png">
+        </property>
+     </product>
+  </extension>
+</plugin>
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/splash.bmp b/bnd/org.eclipse.sensinact.studio.language.sensinact/splash.bmp
new file mode 100644
index 0000000..464af41
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/splash.bmp
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/splash.svg b/bnd/org.eclipse.sensinact.studio.language.sensinact/splash.svg
new file mode 100644
index 0000000..272ef2c
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/splash.svg
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="452"
+   height="302"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="splash.svg"
+   inkscape:export-filename="/home/nj246216/Bureau/dessin.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90">
+  <defs
+     id="defs4" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.9707943"
+     inkscape:cx="221.58834"
+     inkscape:cy="167.29186"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1680"
+     inkscape:window-height="974"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Calque 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-750.36218)">
+    <image
+       y="751.83411"
+       x="0.29843709"
+       id="image2992"
+       xlink:href="data:image/png;base64,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 lk+M957lJ5zix93/HozosR34dyxPr1ixYsWKFStWrFjx/yn8/82cs2LFihUrVqxYsWLF3ydWeXrF ihUrVqxYsWLFiqfHKk+vWLFixYoVK1asWPH0WOXpFStWrFixYsWKFSueHqs8vWLFihUrVqxYsWLF 02OVp1esWLFixYoVK1aseHqs8vSKFStWrFixYsWKFU+PVZ5esWLFihUrVqxYseLpscrTK1asWLFi xYoVK1Y8PVZ5esWKFStWrFixYsWKp8cqT69YsWLFihUrVqxY8fRY5ekVK1asWLFixYoVK54eqzy9 YsWKFStWrFixYsXTY5WnV6xYsWLFihUrVqx4evArX/nKv+8+rFixYsWKFStWrFjxHyso6d93H1as WLFixYoVK1as+I8Va7zHihUrVqxYsWLFihVPj1WeXrFixYoVK1asWLHi6bHK0ytWrFixYsWKFStW PD1WeXrFihUrVqxYsWLFiqfHKk+vWLFixYoVK1asWPH0WOXpFStWrFixYsWKFSueHqs8vWLFihUr VqxYsWLF02OVp1esWLFixYoVK1aseHqs8vSKFStWrFixYsWKFU+PVZ5esWLFihUrVqxYseLpscrT K1asWLFixYoVK1Y8Pf5f4oNuhzMZVbgAAAAASUVORK5CYII= "
+       height="310.48569"
+       width="452.00153"
+       inkscape:export-filename="/home/nj246216/Bureau/image3015.bmp.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <rect
+       style="opacity:0.82795697;fill:#f2f2f2;stroke:none"
+       id="rect2995"
+       width="455.18536"
+       height="290.78833"
+       x="-1.6019229"
+       y="749.92841"
+       inkscape:export-filename="/home/nj246216/Bureau/image3015.bmp.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <image
+       y="841.05444"
+       x="38.711227"
+       id="image3004"
+       xlink:href="data:image/png;base64,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 QyerZIMAAAAASUVORK5CYII= "
+       height="80"
+       width="390"
+       inkscape:export-filename="/home/nj246216/Bureau/image3015.bmp.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <image
+       y="957.52509"
+       x="2.1960022"
+       id="image3015"
+       xlink:href="data:image/png;base64,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 "
+       height="44.580276"
+       width="54.811813"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+  </g>
+</svg>
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/GenerateSensinact.mwe2 b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/GenerateSensinact.mwe2
new file mode 100644
index 0000000..0305959
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/GenerateSensinact.mwe2
@@ -0,0 +1,43 @@
+module org.eclipse.sensinact.studio.language.GenerateSensinact
+
+import org.eclipse.xtext.xtext.generator.*
+import org.eclipse.xtext.xtext.generator.model.project.*
+
+var rootPath = ".."
+
+Workflow {
+	
+	component = XtextGenerator {
+		configuration = {
+			project = StandardProjectConfig {
+				baseName = "org.eclipse.sensinact.studio.language.sensinact"
+				rootPath = rootPath
+				runtimeTest = {
+					enabled = false
+				}
+				eclipsePlugin = {
+					enabled = true
+				}
+				eclipsePluginTest = {
+					enabled = false
+				}
+				createEclipseMetaData = true
+			}
+			code = {
+				encoding = "UTF-8"
+				fileHeader = "/*\n * generated by Xtext \${version}\n */"
+			}
+		}
+		language = StandardLanguage {
+			name = "org.eclipse.sensinact.studio.language.Sensinact"
+			fileExtensions = "sna"
+
+			serializer = {
+				generateStub = false
+			}
+			validator = {
+				// composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator"
+			}
+		}
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/Sensinact.xtext b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/Sensinact.xtext
new file mode 100644
index 0000000..6ceb460
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/Sensinact.xtext
@@ -0,0 +1,222 @@
+grammar org.eclipse.sensinact.studio.language.Sensinact with org.eclipse.xtext.common.Terminals
+
+generate sensinact "http://www.eclipse.org/sensinact/studio/language/Sensinact"
+
+import "http://www.eclipse.org/emf/2002/Ecore" as ecore
+
+
+// ==============
+// Main structure
+// ==============
+
+Sensinact:
+    {Sensinact}
+    (eca=DSL_SENSINACT)
+;
+
+DSL_SENSINACT:
+	autostart=DSL_FLAG_AUTOSTART? (resources+=DSL_Resource)+ (cep+=DSL_CEP_STATEMENT)* on=DSL_On eca=DSL_ECA_STATEMENT  
+;
+
+DSL_FLAG_AUTOSTART:
+	'option' 'autostart' '=' activated=BOOLEAN
+;
+
+DSL_Resource:
+    'resource' name=ID '=' '[' gatewayID=EXTENDED_ID '/' deviceID=EXTENDED_ID '/' serviceID=EXTENDED_ID '/' resourceID=EXTENDED_ID ']' 
+;
+
+DSL_On:
+	'on' triggers+=DSL_REF_CONDITION (',' triggers+=DSL_REF_CONDITION)*
+;
+
+DSL_ECA_STATEMENT:
+	ifdo=DSL_IfDo (elseIfdo+=DSL_ElseIfDo)* elsedo=DSL_ElseDo? 'end if' 	
+;
+
+DSL_IfDo:
+	'if' condition=DSL_Expression_Or 'do' actions=DSL_ListActions 
+;
+
+DSL_ElseIfDo:
+	'else if' condition=DSL_Expression_Or 'do' actions=DSL_ListActions 
+;
+
+DSL_ElseDo:
+	'else do' actions=DSL_ListActions
+;
+
+
+// ============
+// Basic values
+// ============
+
+terminal BOOLEAN returns ecore::EBoolean: 'true' | 'false';
+
+// IMPORTANT : we are mixing terminal and non terminal rules
+//  * terminal rules are parsed in a FIRST & stupid step (but fast) way by the "lexer"
+//  * DataTypes rules are parsed in a SECOND step by the "parser"
+//
+// INFO : remember that terminal rules are executed one after the other, IN THE ORDER OF WRITING
+
+terminal INT returns ecore::EInt: ('0'..'9')+;
+NUMBER returns ecore::EBigDecimal: INT | INT '.' INT; 
+
+terminal ID : ('a'..'z'|'A'..'Z'|'_'|'0'..'9'|':'|'-')+;
+EXTENDED_ID : ID ('.' ID)*;
+
+
+// ================
+// Basic structures 
+// ================
+
+DSL_REF:
+	DSL_CEP_STATEMENT | DSL_Resource
+;
+
+
+// =============
+// REF condition
+// =============
+
+DSL_REF_CONDITION:
+	ref=[DSL_REF] '.' 'subscribe' '(' ')' 
+;
+
+
+// ==========
+// CEP engine
+// ==========
+
+DSL_CEP_STATEMENT:
+	'define' name=ID '=' operation=(DSL_CEP_AFTER | DSL_CEP_BEFORE | DSL_CEP_COINCIDE | DSL_CEP_MIN | DSL_CEP_MAX | DSL_CEP_AVG | DSL_CEP_SUM | DSL_CEP_COUNT)  
+;
+
+DSL_CEP_AFTER:
+	'after' '(' ref1=DSL_REF_CONDITION ','  ref2=DSL_REF_CONDITION ',' (start=DSL_CEP_DURATION ',')? end=DSL_CEP_DURATION ')'
+;
+
+DSL_CEP_BEFORE:
+	'before' '(' ref1=DSL_REF_CONDITION ','  ref2=DSL_REF_CONDITION ',' (start=DSL_CEP_DURATION ',')? end=DSL_CEP_DURATION ')' 
+;
+
+DSL_CEP_COINCIDE:
+	'coincide' '(' ref1=DSL_REF_CONDITION ','  ref2=DSL_REF_CONDITION ',' window=DSL_CEP_DURATION ')'
+;
+
+DSL_CEP_MIN:
+	'min' '(' ref=DSL_REF_CONDITION ','  window=DSL_CEP_DURATION ')'
+;
+
+DSL_CEP_MAX:
+	'max' '(' ref=DSL_REF_CONDITION ','  window=DSL_CEP_DURATION ')'
+;
+
+DSL_CEP_AVG:
+	'avg' '(' ref=DSL_REF_CONDITION ','  window=DSL_CEP_DURATION ')'
+;
+
+DSL_CEP_SUM:
+	'sum' '(' ref=DSL_REF_CONDITION ','  window=DSL_CEP_DURATION ')'
+;
+
+DSL_CEP_COUNT:
+	'count' '(' ref=DSL_REF_CONDITION ','  window=DSL_CEP_DURATION ')'
+;
+
+DSL_CEP_DURATION:
+	(units+=(DSL_CEP_DURATION_MIN | DSL_CEP_DURATION_SEC))+
+;
+
+DSL_CEP_DURATION_MIN:
+	min=NUMBER 'min'
+;
+
+DSL_CEP_DURATION_SEC:
+	sec=NUMBER 'sec'
+;
+
+
+// ============================
+// ECA engine : DSL_ListActions 
+// ============================
+
+DSL_ListActions:
+	 actionList+=DSL_ResourceAction (',' actionList+=DSL_ResourceAction)* 
+;
+
+DSL_ResourceAction:
+    (variable=ID '=')? ref=[DSL_REF] '.' actiontype=('act'|'set') '(' listParam=DSL_ListParam? ')'
+;
+
+DSL_ListParam:
+	param+=DSL_Expression_Or (',' param+=DSL_Expression_Or )*
+;
+
+// ===========
+// Expressions
+// ===========
+
+// 
+// 7  ()   functions : not, concatenate 
+// 6  *    /    %
+// 5  +    -
+// 4  <    >    <=   >=
+// 3  ==   !=
+// 2  and
+// 1  or
+// 
+
+
+// Or: left associative, priority 1
+DSL_Expression_Or returns DSL_Expression:
+    DSL_Expression_And ('or' {DSL_Expression_Or.left=current} right=DSL_Expression_And)*;
+ 
+// And: left associative, priority 2
+DSL_Expression_And returns DSL_Expression:
+    DSL_Expression_DiffEqual ('and' {DSL_Expression_And.left=current} right=DSL_Expression_DiffEqual)*;
+ 
+// different/equal: left associative, priority 3
+DSL_Expression_DiffEqual returns DSL_Expression:
+    DSL_Expression_Compare (
+        ('!='  {DSL_Expression_Diff.left=current} right=DSL_Expression_Compare) |
+        ('=='  {DSL_Expression_Equal.left=current} right=DSL_Expression_Compare)
+    )*
+;
+
+// Comparisons: left associative, priority 4
+DSL_Expression_Compare returns DSL_Expression:
+    DSL_Expression_PlusMinus (
+        ('>'  {DSL_Expression_Larger.left=current} right=DSL_Expression_PlusMinus) |
+        ('>=' {DSL_Expression_Larger_Equal.left=current} right=DSL_Expression_PlusMinus) |
+        ('<'  {DSL_Expression_Smaller.left=current} right=DSL_Expression_PlusMinus) |
+        ('<=' {DSL_Expression_Smaller_Equal.left=current} right=DSL_Expression_PlusMinus)
+    )*
+;
+ 
+// addition/subtraction: left associative, priority 5
+DSL_Expression_PlusMinus returns DSL_Expression:
+    DSL_Expression_MultiplicationDivision (
+        ('+'  {DSL_Expression_Plus.left=current} right=DSL_Expression_MultiplicationDivision) |
+        ('-'  {DSL_Expression_Minus.left=current} right=DSL_Expression_MultiplicationDivision)
+    )*
+;
+ 
+// multiplication/division, left associative, priority 6
+DSL_Expression_MultiplicationDivision returns DSL_Expression:
+    DSL_Expression_Unary (
+        ('*'  {DSL_Expression_Multiplication.left=current} right=DSL_Expression_Unary) |
+        ('/'  {DSL_Expression_Division.left=current} right=DSL_Expression_Unary) |
+        ('%'  {DSL_Expression_Modulo.left=current} right=DSL_Expression_Unary)
+    )*
+;
+ 
+// Unary operators: right associative, priority 7
+DSL_Expression_Unary returns DSL_Expression:
+    {DSL_Object_Number}   value=NUMBER    | 
+    {DSL_Object_String}   value=STRING    |
+    {DSL_Object_Boolean}  value=BOOLEAN   |
+    {DSL_Object_Ref}      value=[DSL_REF] '.get()' |
+    '(' DSL_Expression_Or ')'|
+    'not' {DSL_Expression_Negate} exp=DSL_Expression_Unary
+;
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/SensinactRuntimeModule.xtend b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/SensinactRuntimeModule.xtend
new file mode 100644
index 0000000..998ffe6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/SensinactRuntimeModule.xtend
@@ -0,0 +1,21 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+/*
+ * generated by Xtext 2.9.1
+ */
+package org.eclipse.sensinact.studio.language
+
+
+/**
+ * Use this class to register components to be used at runtime / without the Equinox extension registry.
+ */
+class SensinactRuntimeModule extends AbstractSensinactRuntimeModule {
+}
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/SensinactStandaloneSetup.xtend b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/SensinactStandaloneSetup.xtend
new file mode 100644
index 0000000..7841aa6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/SensinactStandaloneSetup.xtend
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+/*
+ * generated by Xtext 2.9.1
+ */
+package org.eclipse.sensinact.studio.language
+
+
+/**
+ * Initialization support for running Xtext languages without Equinox extension registry.
+ */
+class SensinactStandaloneSetup extends SensinactStandaloneSetupGenerated {
+
+	def static void doSetup() {
+		new SensinactStandaloneSetup().createInjectorAndDoEMFRegistration()
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/generator/SensinactGenerator.xtend b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/generator/SensinactGenerator.xtend
new file mode 100644
index 0000000..49786fd
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/generator/SensinactGenerator.xtend
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+/*
+ * generated by Xtext 2.9.1
+ */
+package org.eclipse.sensinact.studio.language.generator
+
+import org.eclipse.emf.ecore.resource.Resource
+import org.eclipse.xtext.generator.AbstractGenerator
+import org.eclipse.xtext.generator.IFileSystemAccess2
+import org.eclipse.xtext.generator.IGeneratorContext
+
+/**
+ * Generates code from your model files on save.
+ * 
+ * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation
+ */
+class SensinactGenerator extends AbstractGenerator {
+
+	override void doGenerate(Resource resource, IFileSystemAccess2 fsa, IGeneratorContext context) {
+//		fsa.generateFile('greetings.txt', 'People to greet: ' + 
+//			resource.allContents
+//				.filter(typeof(Greeting))
+//				.map[name]
+//				.join(', '))
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/generator/packageinfo b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/generator/packageinfo
new file mode 100644
index 0000000..9ad81f6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/generator/packageinfo
@@ -0,0 +1 @@
+version 1.0.0
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/packageinfo b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/packageinfo
new file mode 100644
index 0000000..9ad81f6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/packageinfo
@@ -0,0 +1 @@
+version 1.0.0
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/scoping/SensinactScopeProvider.xtend b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/scoping/SensinactScopeProvider.xtend
new file mode 100644
index 0000000..77146d8
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/scoping/SensinactScopeProvider.xtend
@@ -0,0 +1,48 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+/*
+ * generated by Xtext 2.9.1
+ */
+package org.eclipse.sensinact.studio.language.scoping
+
+import org.eclipse.emf.ecore.EObject
+import org.eclipse.emf.ecore.EReference
+import org.eclipse.xtext.scoping.impl.FilteringScope
+import org.eclipse.xtext.resource.IEObjectDescription
+import com.google.common.base.Predicate
+import org.eclipse.sensinact.studio.language.sensinact.DSL_SENSINACT
+
+/**
+ * Filer elements to "stay" in the current file. 
+ *
+ * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#scoping
+ * on how and when to use it.
+ */
+class SensinactScopeProvider extends AbstractSensinactScopeProvider {
+
+	override getScope(EObject context, EReference reference) {
+		return new FilteringScope(super.getScope(context, reference), new Predicate<IEObjectDescription>() {
+			override apply(IEObjectDescription input) {
+				var curECA = getEca(input.EObjectOrProxy);
+				var contextEca = getEca(context);
+				return curECA == contextEca;
+			}
+		});
+	}
+	
+	def DSL_SENSINACT getEca(EObject object) {
+		if (object === null)
+			return null;
+		if (object instanceof DSL_SENSINACT)
+			return object as DSL_SENSINACT;
+		return getEca(object.eContainer);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/scoping/packageinfo b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/scoping/packageinfo
new file mode 100644
index 0000000..9ad81f6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/scoping/packageinfo
@@ -0,0 +1 @@
+version 1.0.0
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/validation/SensinactValidator.xtend b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/validation/SensinactValidator.xtend
new file mode 100644
index 0000000..5d8ee78
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/validation/SensinactValidator.xtend
@@ -0,0 +1,196 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+/*
+ * generated by Xtext 2.9.1
+ */
+package org.eclipse.sensinact.studio.language.validation
+
+import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_AFTER
+import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_BEFORE
+import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_DURATION
+import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_DURATION_MIN
+import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_DURATION_SEC
+import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_STATEMENT
+import org.eclipse.sensinact.studio.language.sensinact.DSL_ListParam
+import org.eclipse.sensinact.studio.language.sensinact.DSL_REF
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Resource
+import org.eclipse.sensinact.studio.language.sensinact.DSL_ResourceAction
+import org.eclipse.sensinact.studio.language.sensinact.DSL_SENSINACT
+import org.eclipse.sensinact.studio.language.sensinact.SensinactPackage
+import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelEditor
+import org.eclipse.sensinact.studio.resource.AccessMethodType
+import java.math.BigDecimal
+import org.eclipse.emf.ecore.EStructuralFeature
+import org.eclipse.xtext.validation.Check
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor
+import org.eclipse.sensinact.studio.language.sensinact.impl.DSL_REFImpl
+
+/**
+ * This class contains custom validation rules. 
+ *
+ * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#validation
+ */
+class SensinactValidator extends AbstractSensinactValidator {
+	
+	def isConnected() {
+		return ModelEditor.getInstance().getGatewaysId.length != 0;
+	}
+
+	@Check
+	def checkGatewayIsConnected(DSL_SENSINACT eca) {
+		if (!isConnected())
+			warning("Please connect the studio to your gateway", SensinactPackage.Literals.DSL_SENSINACT__RESOURCES);
+	}
+
+	@Check
+	def void refNameIsUnique(DSL_REF ref) {
+		var nameOccurences = 0;
+		var name = ref.getName();
+
+		var superEntity = (ref.eContainer() as DSL_SENSINACT);
+		if (superEntity !== null) {
+			for (other : superEntity.resources) {
+				if (name.equals(other.getName())) {
+					nameOccurences++;
+				}
+			}
+			for (other : superEntity.cep) {
+				if (name.equals(other.getName())) {
+					nameOccurences++;
+				}
+			}
+
+			if (nameOccurences > 1) {
+				error("Reference names names have to be unique", SensinactPackage.Literals.DSL_REF__NAME, ref.getName());
+			}
+		}
+	}
+
+	@Check
+	def checkResourceExists(DSL_Resource dslResource) {
+		if (isConnected()) {
+			var gatewayID = dslResource.gatewayID;
+			var deviceID = dslResource.deviceID;
+			var serviceID = dslResource.serviceID;
+			var resourceID = dslResource.resourceID;
+
+			if (! ModelEditor.getInstance().existsGateway(gatewayID)) {
+				warning("The gateway " + gatewayID + " does not exist",
+					SensinactPackage.Literals.DSL_RESOURCE__GATEWAY_ID, 'INVALID_NAME');
+			} else if (! ModelEditor.getInstance().existsDevice(gatewayID, deviceID)) {
+				warning("The device " + deviceID + " does not exist in gateway " + gatewayID,
+					SensinactPackage.Literals.DSL_RESOURCE__DEVICE_ID, 'INVALID_NAME');
+			} else if (! ModelEditor.getInstance().existsService(gatewayID, deviceID, serviceID)) {
+				warning("The service " + serviceID + " does not exist in gateway " + gatewayID,
+						SensinactPackage.Literals.DSL_RESOURCE__SERVICE_ID, 'INVALID_NAME');
+			} else if (! ModelEditor.getInstance().existsResource(gatewayID, deviceID, serviceID, resourceID)) {
+				warning("The resource " + resourceID + " does not exist in gateway " + gatewayID,
+						SensinactPackage.Literals.DSL_RESOURCE__RESOURCE_ID, 'INVALID_NAME');
+			}
+		}
+	}
+
+	@Check
+	def checkActionAccessMethod(DSL_ResourceAction resourceAction) {
+		if (isConnected()) {
+			var ref = resourceAction.ref;
+			var AccessMethodType actionType = AccessMethodType.getByName(resourceAction.actiontype);
+			var nbParams = getNbParams(resourceAction.listParam);
+			checkParameters(ref, actionType, nbParams, SensinactPackage.Literals.DSL_RESOURCE_ACTION__ACTIONTYPE);
+		}
+	}
+
+	def getNbParams(DSL_ListParam params) {
+		if (params === null)
+			return 0;
+		if (params.param === null)
+			return 0;
+		return params.param.size;
+	}
+
+	def checkParameters(DSL_REF ref, AccessMethodType actionType, int nbParams, EStructuralFeature feature) {
+		if (ref instanceof DSL_Resource) {
+
+			var dslResource = ref as DSL_Resource;
+
+			var gatewayID = dslResource.gatewayID;
+			var deviceID = dslResource.deviceID;
+			var serviceID = dslResource.serviceID;
+			var resourceID = dslResource.resourceID;
+
+			var descriptor = new ResourceDescriptor(gatewayID, deviceID, serviceID, resourceID);
+
+
+			// finding method
+			if (descriptor !== null && actionType !== null) {
+				var method = ModelEditor.getInstance().getAccessMethodWithTypeNbParams(descriptor, actionType, nbParams);
+												
+				if (method === null) {
+					var String msg = null;
+					if (nbParams == 0) {
+						msg = "This action type without parameters is not available for this resource";
+					} else if (nbParams == 1) {
+						msg = "This action type with one parameter is not available for this resource";
+					} else if (nbParams == 0) {
+						msg = "This action type with " + nbParams + " parameters is not available for this resource";
+					}
+					error(msg, feature);
+				}
+			}
+
+		} else if (ref instanceof DSL_CEP_STATEMENT) {
+			// no check
+		} else if (ref.class.equals(typeof(DSL_REFImpl))) {
+			// exact same class (no subclassing)
+		} else {
+			throw new RuntimeException("Should never happen");
+		}
+	}
+
+	@Check
+	def checkCepAfter(DSL_CEP_AFTER operation) {
+		var start = timestamp(operation.start);
+		var end = timestamp(operation.end);
+
+		if (start.compareTo(end) >= 0) {
+			var msg = "end must be after start";
+			error(msg, SensinactPackage.Literals.DSL_CEP_AFTER__END);
+		}
+	}
+
+	@Check
+	def checkCepBefore(DSL_CEP_BEFORE operation) {
+		var start = timestamp(operation.start);
+		var end = timestamp(operation.end);
+
+		if (start.compareTo(end) >= 0) {
+			var msg = "end must be after start";
+			error(msg, SensinactPackage.Literals.DSL_CEP_BEFORE__END);
+		}
+	}
+
+	def timestamp(DSL_CEP_DURATION duration) {
+		var retval = BigDecimal.ZERO;
+		if (duration !== null && duration.units !== null) {
+			for (unit : duration.units) {
+				if (unit instanceof DSL_CEP_DURATION_MIN) {
+					var min = unit as DSL_CEP_DURATION_MIN;
+					retval = retval.add(min.min.multiply(new BigDecimal("60")));
+				} else if (unit instanceof DSL_CEP_DURATION_SEC) {
+					var sec = unit as DSL_CEP_DURATION_SEC;
+					retval = retval.add(sec.sec);
+				}
+			}
+		}
+		return retval;
+	}
+	
+}
diff --git a/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/validation/packageinfo b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/validation/packageinfo
new file mode 100644
index 0000000..9ad81f6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.language.sensinact/src/org/eclipse/sensinact/studio/language/validation/packageinfo
@@ -0,0 +1 @@
+version 1.0.0
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/.classpath b/bnd/org.eclipse.sensinact.studio.model.manager/.classpath
new file mode 100644
index 0000000..7a6fc25
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="src" output="bin" path="src"/>
+	<classpathentry kind="src" output="bin_test" path="test">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/.gitignore b/bnd/org.eclipse.sensinact.studio.model.manager/.gitignore
new file mode 100644
index 0000000..c2b941a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/.gitignore
@@ -0,0 +1,2 @@
+/bin_test/
+/generated/
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/.project b/bnd/org.eclipse.sensinact.studio.model.manager/.project
new file mode 100644
index 0000000..e5d3295
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.sensinact.studio.model.manager</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+	</natures>
+</projectDescription>
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/bnd.bnd b/bnd/org.eclipse.sensinact.studio.model.manager/bnd.bnd
new file mode 100644
index 0000000..ba62e35
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/bnd.bnd
@@ -0,0 +1,23 @@
+Bundle-Version: 1.0.0.SNAPSHOT
+Bundle-SymbolicName: ${p};singleton:=true
+Bundle-ActivationPolicy: lazy
+
+-includeresource.plugin: \
+	plugin.xml
+		
+-buildpath: \
+	org.apache.log4j,\
+	org.eclipse.sensinact.studio.http.services;version=project,\
+	org.restlet,\
+	org.eclipse.sensinact.studio.model.resource;version=project,\
+	org.eclipse.sensinact.studio.http.messages;version=project,\
+	org.eclipse.emf.ecore,\
+	org.eclipse.emf.common,\
+	org.eclipse.emf.edit,\
+	org.eclipse.emf.transaction,\
+	org.eclipse.sensinact.studio.preferences;version=project,\
+	org.eclipse.core.runtime,\
+	org.eclipse.equinox.common,\
+	osgi.cmpn,\
+	osgi.annotation,\
+	json
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/plugin.xml b/bnd/org.eclipse.sensinact.studio.model.manager/plugin.xml
new file mode 100644
index 0000000..0e8e593
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/plugin.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2018 CEA.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+
+     Contributors:
+        CEA - initial API and implementation and/or initial documentation
+
+-->
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.emf.transaction.editingDomains">
+      <editingDomain
+            id="org.eclipse.sensinact.studio.model.resource.editingDomain">
+      </editingDomain>
+   </extension>
+   <extension
+         point="org.eclipse.emf.transaction.listeners">
+      <listener
+            class="org.eclipse.sensinact.studio.model.manager.listener.modelset.ResourceModelSetListenerInternal">
+         <editingDomain
+               id="org.eclipse.sensinact.studio.model.resource.editingDomain">
+         </editingDomain>
+      </listener>
+   </extension>
+</plugin>
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/http/DeviceInfoRoute.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/http/DeviceInfoRoute.java
new file mode 100644
index 0000000..6236ace
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/http/DeviceInfoRoute.java
@@ -0,0 +1,62 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.manager.http;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.eclipse.sensinact.studio.http.services.server.SensinactServerResource;
+import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelEditor;
+import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelUpdater;
+import org.restlet.resource.Get;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class DeviceInfoRoute extends SensinactServerResource {
+
+	private static final Logger logger = Logger.getLogger(DeviceInfoRoute.class);
+	
+	@Get
+	public String getValue(String params) {
+
+		StringBuilder sb = new StringBuilder();
+		
+		try {
+			String gatewayName = getRequestAttribute("gateway");
+			String deviceName = getRequestAttribute("device");
+			
+			String fullName = gatewayName + "/" + deviceName;
+			
+			sb.append("<b>" + fullName + "</b><br/>");
+			List<String> serviceIds = ModelEditor.getInstance().getServicesId(gatewayName, deviceName);
+			if(serviceIds.size()==0){
+				ModelUpdater.getInstance().updateServices(gatewayName, deviceName);
+				serviceIds = ModelEditor.getInstance().getServicesId(gatewayName, deviceName);
+			}
+			for (String serviceId : serviceIds) {
+				String link = "updatePopupOnClick('" + fullName + "','" + serviceId + "')";
+				String symbol = "+";
+				sb.append("<a href=\"#\" onclick=\"" + link + "\"> " + symbol + " " + serviceId + "</a><br/>\n");
+			}
+			
+			return sb.toString();
+		} catch (UnsupportedEncodingException e) {
+			logger.error("DeviceInfoRoute - decode error", e);
+			return "ERROR - see logs";
+		} catch (IOException e) {
+			logger.error("DeviceInfoRoute - decode error", e);
+			return "ERROR - see logs";
+		}
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/http/InitRoutes.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/http/InitRoutes.java
new file mode 100644
index 0000000..c05cc98
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/http/InitRoutes.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.manager.http;
+
+import org.eclipse.sensinact.studio.http.services.server.RouteUtil;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+
+/**
+ * @author Etienne Gandrille
+ */
+@Component
+public class InitRoutes {
+	
+	@Activate
+	public void activate() {
+		RouteUtil.attachRoute("/webapp/deviceinfo/{gateway}/{device}", DeviceInfoRoute.class);
+		RouteUtil.attachRoute("/webapp/deviceinfo/{gateway}/{device}/{service}", ServiceInfoRoute.class);
+		RouteUtil.attachRoute("/webapp/performAction/{gateway}/{device}/{service}/{ressource}", PerformActionRoute.class);
+		RouteUtil.attachRoute("/webapp/updatelocation/{gateway}/{device}", UpdateLocationRoute.class);
+	}
+	
+	@Deactivate
+	public void deactivate() {
+		RouteUtil.detachRoute("/webapp/deviceinfo/{gateway}/{device}", DeviceInfoRoute.class);
+		RouteUtil.detachRoute("/webapp/deviceinfo/{gateway}/{device}/{service}", ServiceInfoRoute.class);
+		RouteUtil.detachRoute("/webapp/performAction/{gateway}/{device}/{service}/{ressource}", PerformActionRoute.class);
+		RouteUtil.detachRoute("/webapp/updatelocation/{gateway}/{device}", UpdateLocationRoute.class);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/http/PerformActionRoute.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/http/PerformActionRoute.java
new file mode 100644
index 0000000..2dda93d
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/http/PerformActionRoute.java
@@ -0,0 +1,51 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.manager.http;
+
+import java.io.UnsupportedEncodingException;
+
+import org.apache.log4j.Logger;
+import org.eclipse.sensinact.studio.http.services.client.StudioRequest;
+import org.eclipse.sensinact.studio.http.services.client.UIResult;
+import org.eclipse.sensinact.studio.http.services.server.SensinactServerResource;
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+import org.restlet.resource.Get;
+
+import org.eclipse.sensinact.studio.resource.AccessMethodType;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class PerformActionRoute extends SensinactServerResource {
+
+	private static final Logger logger = Logger.getLogger(PerformActionRoute.class);
+
+	@Get
+	public String getValue(String params) {
+		try {
+			String gatewayName = getRequestAttribute("gateway");
+			String deviceName = getRequestAttribute("device");
+			String serviceName = getRequestAttribute("service");
+			String ressourceName = getRequestAttribute("ressource");
+
+			ResourceDescriptor descriptor = new ResourceDescriptor(gatewayName, deviceName, serviceName, ressourceName);
+			StudioRequest request = new StudioRequest(descriptor, AccessMethodType.ACT);
+			UIResult result = request.sendRequestForIU();
+
+			logger.debug(result.asJson());
+
+			return result.asJson().toString();
+		} catch (UnsupportedEncodingException e) {
+			logger.error("DeviceInfoRoute - decode error", e);
+			return "";
+		}
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/http/ServiceInfoRoute.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/http/ServiceInfoRoute.java
new file mode 100644
index 0000000..9363a2a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/http/ServiceInfoRoute.java
@@ -0,0 +1,148 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.manager.http;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+import org.eclipse.sensinact.studio.http.messages.snamessage.getresponse.MsgGetResponse;
+import org.eclipse.sensinact.studio.http.services.client.StudioRequest;
+import org.eclipse.sensinact.studio.http.services.server.SensinactServerResource;
+import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelEditor;
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+import org.restlet.resource.Get;
+
+import org.eclipse.sensinact.studio.resource.AccessMethodType;
+import org.eclipse.sensinact.studio.resource.ResourcePackage;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ServiceInfoRoute extends SensinactServerResource {
+
+	private static final Logger logger = Logger.getLogger(ServiceInfoRoute.class);
+	
+	@Get
+	public String getValue(String params) {
+
+		StringBuilder sb = new StringBuilder();
+
+		try {
+			String gatewayName = getRequestAttribute("gateway");
+			String deviceName = getRequestAttribute("device");
+			String serviceName = getRequestAttribute("service");
+
+			String fullName = gatewayName + "/" + deviceName;
+			
+			sb.append("<b>" + fullName + "</b><br/>");
+
+			List<String> serviceIds = ModelEditor.getInstance().getServicesId(gatewayName, deviceName);
+			for (String serviceId : serviceIds) {
+
+				// service name
+				
+				String symbol;
+				String linkParams;
+				if (serviceName.equals(serviceId)) {
+					symbol = "-";
+					linkParams = "'" + fullName + "'";
+				} else {
+					symbol = "+";
+					linkParams = "'" + fullName + "','" + serviceId + "'";
+				}
+				String link = "updatePopupOnClick(" + linkParams + ")";				
+				sb.append("<a href=\"#\" onclick=\"" + link + "\"> " + symbol + " " + serviceId + "</a><br/>\n");
+
+				// resources, if needed
+				if (serviceName.equals(serviceId)) {
+					List<String> resourceIds = ModelEditor.getInstance().getResourcesId(gatewayName, deviceName, serviceName);
+					for (String resourceId : resourceIds) {
+						
+						ResourceDescriptor descriptor = new ResourceDescriptor(gatewayName, deviceName, serviceName, resourceId);						
+						int classifierID = ModelEditor.getInstance().getResourceClass(descriptor).getClassifierID();
+	
+						// ACTION
+						if ( classifierID == ResourcePackage.ACTION) {
+							String jsParams = "'" + gatewayName + "','" + deviceName + "','" + serviceName + "','" + resourceId + "'";
+							
+							// <a onclick="performAction(...)">...</a>
+							String resourceValueWithLink = writeOnClickStatement("performAction", jsParams, "&lt;Action&gt;");
+							
+							sb.append("&nbsp;&nbsp;&nbsp;" + resourceId + ": " + resourceValueWithLink + "<br/>");							
+						}
+						
+						// OTHER
+						else {
+							StudioRequest request = new StudioRequest(descriptor, AccessMethodType.GET);
+							MsgSensinact response = request.sendRequest();
+							
+							String resourceValue = "<unknown>";
+							if (response instanceof MsgGetResponse) {
+								resourceValue = ((MsgGetResponse) response).getResponse().getValueAsString();
+							}
+							resourceValue = ((resourceValue == null) ? "null" : resourceValue);
+							
+							resourceValue = resourceValue.replaceAll("\n", "<br/>");
+														
+							if (isImageUrl(resourceValue)) {
+								// IMAGE URL
+								// <a onclick="showImage(...)">...</a>
+								String resourceValueWithLink = writeOnClickStatement("showImage", "'" + resourceValue + "'", resourceValue);
+								sb.append("&nbsp;&nbsp;&nbsp;" + resourceId + ": " + resourceValueWithLink + "<br/>");
+							} else if (isBase64Image(resourceValue)) {
+								// IMAGE DATA
+								String img="<object data=\"" + resourceValue + "\"></object>";
+								sb.append("&nbsp;&nbsp;&nbsp;" + resourceId + ": <br/>" + img);
+							}
+							else {
+								// NOT AN IMAGE
+								sb.append("&nbsp;&nbsp;&nbsp;" + resourceId + ": " + resourceValue + "<br/>");
+							}
+						}
+					}
+				}
+			}
+
+			return sb.toString();
+		} catch (IOException | InterruptedException e) {
+			logger.error("Service info route", e);
+		}
+		return "";
+	}
+
+	// returns '<a onclick="$jsFunction($jsParams)">$linkText</a>'
+	private String writeOnClickStatement(String jsFunction, String jsParams, String linkText) {
+		return "<a href=\"#\" onclick=\"" + jsFunction + "(" + jsParams + ")" +"\">" + linkText + "</a>";
+	}
+	
+	private boolean isImageUrl(String resourceValue) {
+		
+		String[] exts ={"gif", "jpg", "jpeg", "png"};
+		
+		// protocol check : must be an url
+		if (! resourceValue.startsWith("http://") && ! resourceValue.startsWith("https://"))
+			return false;
+
+		// extension check : must be an image
+		for (String ext : exts) {
+			if (resourceValue.toLowerCase().endsWith("." + ext))
+				return true;
+		}
+
+		return false;
+	}
+	
+	private boolean isBase64Image(String resourceValue) {
+		return resourceValue.startsWith("data:image/");
+	}
+}
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/http/UpdateLocationRoute.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/http/UpdateLocationRoute.java
new file mode 100644
index 0000000..2a58ef3
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/http/UpdateLocationRoute.java
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.manager.http;
+
+import java.io.UnsupportedEncodingException;
+
+import org.apache.log4j.Logger;
+import org.eclipse.sensinact.studio.http.services.server.SensinactServerResource;
+import org.eclipse.sensinact.studio.model.manager.listener.devicelocation.DeviceUpdateManager;
+import org.eclipse.sensinact.studio.model.resource.utils.DeviceDescriptor;
+import org.eclipse.sensinact.studio.model.resource.utils.GPScoordinates;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.restlet.Response;
+import org.restlet.data.MediaType;
+import org.restlet.data.Status;
+import org.restlet.resource.Post;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class UpdateLocationRoute extends SensinactServerResource {
+
+	private static final Logger logger = Logger.getLogger(UpdateLocationRoute.class);
+	
+	@Post("json")
+	public Response getValue(String params) throws UnsupportedEncodingException {
+		Response response = getResponse();
+
+		DeviceUpdateManager locationManager = DeviceUpdateManager.getInstance();
+		String gatewayName = getRequestAttribute("gateway");
+		String deviceName = getRequestAttribute("device");
+		DeviceDescriptor deviceDescriptor = new DeviceDescriptor(gatewayName, deviceName);
+		GPScoordinates oldLocation = locationManager.getKnownLocation(deviceDescriptor);
+		try {		
+			JSONObject jsonMsg = new JSONObject(params);
+			double lat = (Double) jsonMsg.get("lat");
+			double lng = (Double) jsonMsg.get("lng");
+			boolean isUpdated = locationManager.updateLocationInServer(deviceDescriptor, new GPScoordinates(lat, lng));
+			if (isUpdated) {
+				response.setStatus(Status.SUCCESS_OK);
+				setCoordinatesInEntity(response, lat, lng);
+			}
+			else {
+				response.setStatus(Status.CLIENT_ERROR_UNAUTHORIZED);
+				setCoordinatesInEntity(response, oldLocation.getLat(), oldLocation.getLng());
+			}
+		} catch (NullPointerException | JSONException e) {
+			logger.error("Update Location Route", e);
+			setCoordinatesInEntity(response, oldLocation.getLat(), oldLocation.getLng());
+			response.setStatus(Status.SERVER_ERROR_INTERNAL);
+		}
+
+		return response;
+	}
+
+	private void setCoordinatesInEntity(Response response, double lat, double lng) {
+		String msg = "{\"lat\": " + lat + ", \"lng\": " + lng + "}";
+		response.setEntity(msg, MediaType.APPLICATION_JSON);		
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/http/package-info.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/http/package-info.java
new file mode 100644
index 0000000..424ab87
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/http/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.model.manager.http;
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/devicelocation/DeviceIconListener.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/devicelocation/DeviceIconListener.java
new file mode 100644
index 0000000..9ecfd17
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/devicelocation/DeviceIconListener.java
@@ -0,0 +1,23 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.manager.listener.devicelocation;
+
+import org.eclipse.sensinact.studio.model.resource.utils.DeviceDescriptor;
+
+/**
+ * 
+ */
+public interface DeviceIconListener {
+
+	public void deviceIconUpdated(DeviceDescriptor descriptor);
+	
+	public void deviceRemoved(DeviceDescriptor descriptor);
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/devicelocation/DeviceLocationListener.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/devicelocation/DeviceLocationListener.java
new file mode 100644
index 0000000..a7577db
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/devicelocation/DeviceLocationListener.java
@@ -0,0 +1,24 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.manager.listener.devicelocation;
+
+import org.eclipse.sensinact.studio.model.resource.utils.DeviceDescriptor;
+import org.eclipse.sensinact.studio.model.resource.utils.GPScoordinates;
+
+/**
+ * @author Etienne Gandrille
+ */
+public interface DeviceLocationListener {
+
+	public void deviceLocationUpdated(GPScoordinates coordinate, DeviceDescriptor descriptor);
+	
+	public void deviceRemoved(DeviceDescriptor descriptor);
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/devicelocation/DeviceSelectionListener.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/devicelocation/DeviceSelectionListener.java
new file mode 100644
index 0000000..8a55cde
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/devicelocation/DeviceSelectionListener.java
@@ -0,0 +1,11 @@
+package org.eclipse.sensinact.studio.model.manager.listener.devicelocation;
+
+import org.eclipse.sensinact.studio.model.resource.utils.GPScoordinates;
+
+/**
+ *
+ */
+public interface DeviceSelectionListener {
+	
+	void deviceSelected(final GPScoordinates coordinate);
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/devicelocation/DeviceUpdateManager.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/devicelocation/DeviceUpdateManager.java
new file mode 100644
index 0000000..e3773da
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/devicelocation/DeviceUpdateManager.java
@@ -0,0 +1,235 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.manager.listener.devicelocation;
+
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+import org.apache.log4j.Logger;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.ecore.EAttribute;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.edit.provider.INotifyChangedListener;
+import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelEditor;
+import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelUpdater;
+import org.eclipse.sensinact.studio.model.resource.utils.DeviceDescriptor;
+import org.eclipse.sensinact.studio.model.resource.utils.GPScoordinates;
+import org.eclipse.sensinact.studio.model.resource.utils.GPSparsingException;
+import org.eclipse.sensinact.studio.resource.Device;
+import org.eclipse.sensinact.studio.resource.Gateway;
+import org.eclipse.sensinact.studio.resource.Service;
+
+/**
+ * @author Etienne Gandrille
+ * @contributor Christophe Munilla
+ */
+public class DeviceUpdateManager implements INotifyChangedListener {
+
+	private static DeviceUpdateManager INSTANCE = null;
+	private static final Logger logger = Logger.getLogger(DeviceUpdateManager.class);
+
+	private final Set<DeviceLocationListener> locationListeners = new HashSet<DeviceLocationListener>();
+	private final Set<DeviceIconListener> iconListeners = new HashSet<DeviceIconListener>();
+	private final Set<DeviceSelectionListener> selectionListeners = new HashSet<DeviceSelectionListener>();
+
+	public synchronized static DeviceUpdateManager getInstance() {
+		if (INSTANCE == null)
+			INSTANCE = new DeviceUpdateManager();
+		return INSTANCE;
+	}
+	
+	DeviceUpdateManager() {
+		ModelEditor.getInstance().addNotifyChangedListener(this);
+	}
+
+	@Override
+	public void notifyChanged(Notification arg0) {		
+		if(arg0.getEventType() == Notification.SET && arg0.getFeature() instanceof EAttribute) {
+			if("location".equals(((EAttribute)arg0.getFeature()).getName())) {
+				try {
+					DeviceDescriptor descriptor = new DeviceDescriptor(((Gateway)((EObject)
+						arg0.getNotifier()).eContainer()).getName(), ((Device)arg0.getNotifier()
+								).getName());
+					
+					descriptor.setIcon(((Device)arg0.getNotifier()).getIcon());
+					descriptor.setLocation((String) arg0.getNewValue());
+					
+					GPScoordinates gps = new GPScoordinates((String) arg0.getNewValue());
+
+					for (DeviceLocationListener listener : locationListeners) {
+						listener.deviceLocationUpdated(gps,descriptor);
+					}
+				} catch (GPSparsingException e) {				
+					logger.error(e.getMessage(),e); 
+				}
+			}
+			if("icon".equals(((EAttribute)arg0.getFeature()).getName())) {
+				DeviceDescriptor descriptor = new DeviceDescriptor(((Gateway)((EObject)
+					arg0.getNotifier()).eContainer()).getName(), ((Device)arg0.getNotifier()
+							).getName());
+				
+				descriptor.setLocation(((Device)arg0.getNotifier()).getLocation());
+				descriptor.setIcon((String) arg0.getNewValue());
+				
+				for (DeviceIconListener listener : iconListeners) {
+					listener.deviceIconUpdated(descriptor);
+				}
+			}
+		} else if(arg0.getEventType() == Notification.REMOVE 
+				&& arg0.getNotifier() instanceof Gateway
+				&& arg0.getOldValue() instanceof Device){			
+			
+			DeviceDescriptor descriptor = new DeviceDescriptor(((Gateway)
+				arg0.getNotifier()).getName(), ((Device)arg0.getOldValue()
+						).getName());
+			
+			for (DeviceLocationListener listener : locationListeners) {
+				listener.deviceRemoved(descriptor);
+			}
+		} else if(arg0.getEventType() == Notification.ADD) {
+		
+			if(arg0.getNotifier() instanceof Gateway && arg0.getNewValue() instanceof Device){			
+			
+				DeviceDescriptor descriptor = new DeviceDescriptor(((Gateway)
+					arg0.getNotifier()).getName(), ((Device)arg0.getNewValue()
+							).getName());	
+				
+				String location = ((Device)arg0.getNewValue()).getLocation();
+				String icon = ((Device)arg0.getNewValue()).getIcon();
+				
+				descriptor.setIcon(icon);
+				descriptor.setLocation(location);
+				
+				if(location != null && !"null".equals(location)) {			
+					GPScoordinates gps = null;
+					try {
+						gps = new GPScoordinates(((Device)arg0.getNewValue()).getLocation());
+					} catch (GPSparsingException e) {				
+						e.printStackTrace();
+					}
+					for (DeviceLocationListener listener : locationListeners) {
+						listener.deviceLocationUpdated(gps, descriptor);;
+					}
+				}
+				if(icon != null && !"null".equals(icon)) {
+					for (DeviceIconListener listener : iconListeners) {
+						listener.deviceIconUpdated(descriptor);
+					}
+				}
+				try {
+					ModelUpdater.getInstance().updateServices(((Gateway)
+						arg0.getNotifier()).getName(), ((Device)arg0.getNewValue()
+								).getName());
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+			else if(arg0.getNotifier() instanceof Device && arg0.getNewValue() instanceof Service){			
+				try {
+					ModelUpdater.getInstance().updateResources(((Gateway)((Device)(arg0.getNotifier())).eContainer()).getName(), 
+						((Device)arg0.getNotifier()).getName(), ((Service)arg0.getNewValue()
+								).getName());
+				} catch (IOException e) {
+					e.printStackTrace();
+				}
+			}
+		}
+	}
+	
+	/**
+	 * 
+	 * @param deviceDescriptor
+	 * @param newCoordinates
+	 * @return true if success, false if update location failed. It happens when the location is not updatable. 
+	 */
+	public boolean updateLocationInServer(DeviceDescriptor deviceDescriptor, GPScoordinates newCoordinates) {
+		if (needUpdate(deviceDescriptor, newCoordinates)) {
+			if (ModelUpdater.getInstance().updateLocationOnServer(deviceDescriptor, newCoordinates)) {
+				return true;
+			} else {
+				return false;
+			}
+		} else {
+			return false;
+		}
+	}
+	
+	public void updateDeviceSelection(GPScoordinates coordinates) {		
+		for (DeviceSelectionListener listener : selectionListeners) {
+				listener.deviceSelected(coordinates);
+		}
+	}
+	
+	private boolean needUpdate(DeviceDescriptor deviceDescriptor, GPScoordinates newCoordinates) {
+		GPScoordinates oldCoordinates = ModelEditor.getInstance().getLocation(deviceDescriptor);		
+		return (! newCoordinates.equals(oldCoordinates));
+	}
+
+	public void removeDeviceIconListener(DeviceIconListener listener) {
+		iconListeners.remove(listener);
+	}
+
+	public void addDeviceIconListener(DeviceIconListener listener) {
+		iconListeners.add(listener);
+	}
+
+	
+	public void removeDeviceLocationListener(DeviceLocationListener listener) {
+		locationListeners.remove(listener);
+	}
+
+	public void addDeviceLocationListener(DeviceLocationListener listener) {
+		locationListeners.add(listener);
+	}
+
+	public void removeDeviceSelectionListener(DeviceSelectionListener listener) {
+		selectionListeners.remove(listener);
+	}
+
+	public void addDeviceSelectionListener(DeviceSelectionListener listener) {
+		selectionListeners.add(listener);
+	}
+
+	public void deleteDeviceInStudio(DeviceDescriptor deviceDescriptor) {
+		if(deviceDescriptor == null)
+			return;
+		logger.debug("Device location removed for " + deviceDescriptor + ". Notification fired (" + locationListeners.size() + " listeners");
+		for (DeviceLocationListener listener : locationListeners) {
+			listener.deviceRemoved(deviceDescriptor);
+		}
+	}
+	
+	public void deleteGatewayInStudio(String gatewayName) {
+		// for iterating safely over the keyset while deleting elements in the map
+		List<String> list  = ModelEditor.getInstance().getDevicesId(gatewayName);
+		list.stream().forEach(d -> deleteDeviceInStudio(ModelEditor.getInstance().getDeviceDescriptor(gatewayName, d)));
+	}
+	
+	public GPScoordinates getKnownLocation(DeviceDescriptor deviceDescriptor) {
+		DeviceDescriptor desc =  ModelEditor.getInstance().getDeviceDescriptor(deviceDescriptor.getGateway(),deviceDescriptor.getDevice());
+		if(desc == null )
+			return null;
+		String location = desc.getLocation();
+		if(location == null)
+			return null;
+		String[] coordinates = location.split(":");
+		if(coordinates.length != 2)
+			return null;
+		try {
+			return new GPScoordinates(Double.parseDouble(coordinates[0]),Double.parseDouble(coordinates[1]));
+		} catch(Exception e) {
+			e.printStackTrace();
+		}
+		return null;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/devicelocation/package-info.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/devicelocation/package-info.java
new file mode 100644
index 0000000..e213042
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/devicelocation/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.model.manager.listener.devicelocation;
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/modelset/ResourceModelSetListener.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/modelset/ResourceModelSetListener.java
new file mode 100644
index 0000000..88bfc16
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/modelset/ResourceModelSetListener.java
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.manager.listener.modelset;
+
+import org.eclipse.emf.transaction.ResourceSetChangeEvent;
+
+/**
+ * @author Etienne Gandrille
+ */
+public interface ResourceModelSetListener {
+	public void modelSetUpdated(ResourceSetChangeEvent event);
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/modelset/ResourceModelSetListenerInternal.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/modelset/ResourceModelSetListenerInternal.java
new file mode 100644
index 0000000..c220df9
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/modelset/ResourceModelSetListenerInternal.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.manager.listener.modelset;
+
+import org.eclipse.emf.common.command.Command;
+import org.eclipse.emf.transaction.NotificationFilter;
+import org.eclipse.emf.transaction.ResourceSetChangeEvent;
+import org.eclipse.emf.transaction.ResourceSetListener;
+import org.eclipse.emf.transaction.RollbackException;
+
+/**
+ * @author Yazid Benazzouz
+ */
+public class ResourceModelSetListenerInternal implements ResourceSetListener {
+
+	@Override
+	public NotificationFilter getFilter() {
+		return null;
+	}
+
+	@Override
+	public Command transactionAboutToCommit(ResourceSetChangeEvent event) throws RollbackException {
+		return null;
+	}
+
+	@Override
+	public void resourceSetChanged(final ResourceSetChangeEvent event) {
+		ResourceModelSetManager.getInstance().notifyListeners(event);
+	}
+
+	@Override
+	public boolean isAggregatePrecommitListener() {
+		return false;
+	}
+
+	@Override
+	public boolean isPrecommitOnly() {
+		return false;
+	}
+
+	@Override
+	public boolean isPostcommitOnly() {
+		return false;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/modelset/ResourceModelSetManager.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/modelset/ResourceModelSetManager.java
new file mode 100644
index 0000000..5dfbc1e
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/modelset/ResourceModelSetManager.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.manager.listener.modelset;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.eclipse.emf.transaction.ResourceSetChangeEvent;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ResourceModelSetManager {
+
+	private static final Logger logger = Logger.getLogger(ResourceModelSetManager.class);
+	
+	private static ResourceModelSetManager INSTANCE = null;
+
+	private List<ResourceModelSetListener> listeners = new ArrayList<>();
+	
+	private ResourceModelSetManager() {
+	}
+
+	public static ResourceModelSetManager getInstance() {
+		if (INSTANCE == null)
+			INSTANCE = new ResourceModelSetManager();
+		return INSTANCE;
+	}
+	
+	public boolean subscribe(ResourceModelSetListener listener) {
+		return listeners.add(listener);
+	}
+	
+	public boolean unsubscribe(ResourceModelSetListener listener) {
+		return listeners.remove(listener);
+	}
+	
+	void notifyListeners(ResourceSetChangeEvent event) {
+		logger.debug("Resource model set updated. Notification fired (" + listeners.size() + " listeners");
+		for (ResourceModelSetListener listener : listeners) {
+			listener.modelSetUpdated(event);
+		}
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/modelset/package-info.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/modelset/package-info.java
new file mode 100644
index 0000000..04d1dca
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/listener/modelset/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.model.manager.listener.modelset;
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/DeviceAppearing.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/DeviceAppearing.java
new file mode 100644
index 0000000..be1469a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/DeviceAppearing.java
@@ -0,0 +1,59 @@
+/**
+ * 
+ */
+package org.eclipse.sensinact.studio.model.manager.modelupdater;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.ObjectNameTypeValue;
+import org.eclipse.sensinact.studio.model.resource.utils.DeviceDescriptor;
+
+/**
+ *
+ */
+public class DeviceAppearing extends ModelUpdate<DeviceDescriptor> {
+
+	/**
+	 * @param object
+	 */
+	public DeviceAppearing(DeviceDescriptor object) {
+		super(object);
+	}
+
+	@Override
+	public boolean addNext(ModelUpdate<?> next){
+		if(super.addNext(next)){
+			if(next instanceof ResourceAppearing
+				&& "location".equals(((ResourceAppearing)next).object.getResource()) 
+				&& "admin".equals(((ResourceAppearing)next).object.getService())){	
+					ObjectNameTypeValue ontv = ((ResourceAppearing)next).object.getInitial();
+					if(ontv!=null)
+						super.object.setLocation(ontv.getValueAsString());
+				}
+			return true;
+		}
+		return false;
+	}
+
+	@Override
+	protected void doApply(){
+		ModelUpdater.executeInThread( () -> {
+			ModelEditor.getInstance().addDeviceIfNotExist(
+			super.object.getGateway(),
+			super.object.getDevice(),
+			super.object.getIcon(),
+			super.object.getLocation());
+		});
+	}
+	
+	@Override
+	public boolean complete(){		
+		return doComplete();
+	}
+	
+	@Override
+	protected boolean doComplete() {
+		return super.object.getGateway()!=null 
+		   && super.object.getDevice()!=null 
+		   && super.object.getLocation()!=null 
+		   && super.existsGateway(super.object.getGateway());
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/DeviceDisappearing.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/DeviceDisappearing.java
new file mode 100644
index 0000000..ddbcb36
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/DeviceDisappearing.java
@@ -0,0 +1,31 @@
+package org.eclipse.sensinact.studio.model.manager.modelupdater;
+
+
+import org.eclipse.sensinact.studio.model.resource.utils.DeviceDescriptor;
+
+public class DeviceDisappearing extends ModelUpdate<DeviceDescriptor> {
+
+	/**
+	 * @param object
+	 */
+	public DeviceDisappearing(DeviceDescriptor object) {
+		super(object);
+	}
+
+	@Override
+	protected void doApply(){		
+		ModelUpdater.executeInThread( () -> {
+			ModelEditor.getInstance().removeDevice(
+				super.object.getGateway(),
+				super.object.getDevice());
+			}
+		);
+	}
+
+	@Override
+	protected boolean doComplete() {
+		return super.object.getGateway()!=null &&
+			   super.object.getDevice()!=null;
+	}
+
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ModelEditor.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ModelEditor.java
new file mode 100644
index 0000000..cc5aee8
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ModelEditor.java
@@ -0,0 +1,934 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.manager.modelupdater;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.eclipse.emf.common.notify.Notification;
+import org.eclipse.emf.common.util.BasicEList;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.common.util.WrappedException;
+import org.eclipse.emf.ecore.EClass;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.ecore.util.EContentAdapter;
+import org.eclipse.emf.edit.provider.INotifyChangedListener;
+import org.eclipse.emf.transaction.RecordingCommand;
+import org.eclipse.emf.transaction.RunnableWithResult;
+import org.eclipse.emf.transaction.TransactionalEditingDomain;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+import org.eclipse.sensinact.studio.http.messages.snamessage.describeresource.MsgDescribeRessource;
+import org.eclipse.sensinact.studio.http.messages.snamessage.describeresource.ObjectAccessMethods;
+import org.eclipse.sensinact.studio.http.messages.snamessage.describeresource.ObjectParameter;
+import org.eclipse.sensinact.studio.http.services.client.GatewayHttpClient;
+import org.eclipse.sensinact.studio.http.services.client.connectionmanager.ConnectionListener;
+import org.eclipse.sensinact.studio.http.services.client.connectionmanager.NotifDispatcher;
+import org.eclipse.sensinact.studio.model.resource.utils.DeviceDescriptor;
+import org.eclipse.sensinact.studio.model.resource.utils.GPScoordinates;
+import org.eclipse.sensinact.studio.model.resource.utils.GPSparsingException;
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+import org.eclipse.sensinact.studio.model.resource.utils.Segments;
+import org.eclipse.sensinact.studio.model.resource.utils.ServiceDescriptor;
+import org.eclipse.sensinact.studio.preferences.ConfigurationListerner;
+import org.eclipse.sensinact.studio.preferences.ConfigurationManager;
+import org.eclipse.sensinact.studio.preferences.GatewayHttpConfig;
+import org.eclipse.sensinact.studio.resource.AccessMethod;
+import org.eclipse.sensinact.studio.resource.AccessMethodType;
+import org.eclipse.sensinact.studio.resource.Device;
+import org.eclipse.sensinact.studio.resource.Gateway;
+import org.eclipse.sensinact.studio.resource.Parameter;
+import org.eclipse.sensinact.studio.resource.Resource;
+import org.eclipse.sensinact.studio.resource.ResourceFactory;
+import org.eclipse.sensinact.studio.resource.ResourcePackage;
+import org.eclipse.sensinact.studio.resource.Service;
+import org.eclipse.sensinact.studio.resource.Studio;
+
+/**
+ * @author Nicolas Hili, Etienne Gandrille
+ * @contributor Christophe Munilla
+ */
+public class ModelEditor implements ConfigurationListerner, ConnectionListener {
+
+	/* ===================== */
+	/* Model data structures */
+	/* ===================== */
+
+	private static org.eclipse.emf.ecore.resource.Resource resource;
+
+	private final static String EDITING_DOMAIN_ID = "org.eclipse.sensinact.studio.model.resource.editingDomain";
+
+	private static TransactionalEditingDomain editingDomain;
+
+	private static final Logger logger = Logger.getLogger(ModelEditor.class);
+
+	private static ModelEditor INSTANCE = null;
+
+	private List<INotifyChangedListener> listeners;
+	
+	private ModelEditor() {
+		NotifDispatcher.getInstance().subscribe(this);
+		ConfigurationManager.addListener(this);
+		
+		this.listeners = new ArrayList<INotifyChangedListener>();		
+		getEditingDomain().getResourceSet().eAdapters().add(new EContentAdapter() {
+			@Override
+			public void notifyChanged(Notification notification) {
+				synchronized(listeners){
+					Iterator<INotifyChangedListener> it= ModelEditor.this.listeners.iterator();
+					while(it.hasNext()){
+						it.next().notifyChanged(notification);
+					}
+				}
+				super.notifyChanged(notification);
+			}
+		});
+		
+	}
+
+	public synchronized static ModelEditor getInstance() {
+		if (INSTANCE == null)
+			INSTANCE = new ModelEditor();
+		return INSTANCE;
+	}
+	
+	public void addNotifyChangedListener(INotifyChangedListener listener){
+		if(listener==null){
+			return;
+		}
+		synchronized(listeners){
+			this.listeners.add(listener);
+		}
+	}
+
+	public void deleteNotifyChangedListener(INotifyChangedListener listener){
+		if(listener==null){
+			return;
+		}
+		synchronized(listeners){
+			int index =listeners.indexOf(listener);
+			if(index < 0){
+				return;
+			}
+			this.listeners.remove(index);
+		}
+	}
+	
+	@Override
+	public void gatewayAddedOrUpdatedNotif(GatewayHttpConfig gateway) {
+		addGatewayIfNotExist_UNSAFE(gateway.getName());
+	}
+
+	@Override
+	public void gatewayRemovedNotif(String name) {
+		removeGateway_UNSAFE(name);
+	}
+
+	@Override
+	public void studioPortUpdatedNotif(int port) {
+		// do nothing
+	}
+
+	private synchronized static TransactionalEditingDomain getEditingDomain() {
+		if (editingDomain == null) {
+			editingDomain = TransactionalEditingDomain.Registry.INSTANCE.getEditingDomain(EDITING_DOMAIN_ID);
+		}
+		return editingDomain;
+	}
+
+	private static org.eclipse.emf.ecore.resource.Resource getResource() {
+		if (resource == null) {
+			String path = "/org.eclipse.sensinact.studio.model.resource/cache/resource.cache";
+			URI uri = URI.createPlatformPluginURI(path, true);
+			resource = getEditingDomain().getResourceSet().createResource(uri);
+		}
+		return resource;
+	}
+
+	/**
+	 * IMPORTANT. This method MUST NOT BE USED TO UPDATE THE MODEL !!!!
+	 * 
+	 * @return
+	 * @throws InterruptedException
+	 */
+	public Studio getViewerInput() throws InterruptedException {
+
+		setupStudio();
+
+		// Init available gateways names
+		for (GatewayHttpConfig gateway : ConfigurationManager.getGateways()) {
+			addGatewayIfNotExist_UNSAFE(gateway.getName());
+		}
+
+		return (Studio) getEditingDomain().runExclusive(new RunnableWithResult.Impl<Studio>() {
+			@Override
+			public void run() {
+				setResult(USE_IN_RUNEXLUSIVE_getStudio());
+				return;
+			}
+		});
+	}
+
+	private void setupStudio() {
+		
+		final String label=getResource() instanceof Resource?((Resource)getResource()).getName():"Unknown resource";
+		
+		RecordingCommand command = new RecordingCommand(getEditingDomain(),label) {
+			@Override
+			protected void doExecute() {
+				EList<EObject> contents = getResource().getContents();
+				if (contents.size() == 0)
+					getResource().getContents().add(ResourceFactory.eINSTANCE.createStudio());
+			}
+		};
+		getEditingDomain().getCommandStack().execute(command);
+	}
+
+	/* ====================== */
+	/* Internal NON EXCLUSIVE */
+	/* ====================== */
+
+	private static Studio USE_IN_RUNEXLUSIVE_getStudio() {
+		EList<EObject> contents = getResource().getContents();
+		return (Studio) contents.get(0);
+	}
+
+	private static Gateway USE_IN_RUNEXLUSIVE_getGateway(String gatewayName) {
+		EList<Gateway> gateways = USE_IN_RUNEXLUSIVE_getStudio().getGateways();
+		for (Gateway gateway : gateways) {
+			if (gateway.getName().equals(gatewayName)) {
+				return gateway;
+			}
+		}
+		return null;
+	}
+
+	private static Device USE_IN_RUNEXLUSIVE_getDevice(String gatewayName, String devicename) {
+
+		Gateway gateway = USE_IN_RUNEXLUSIVE_getGateway(gatewayName);
+		if (gateway == null)
+			return null;
+		EList<Device> devices = gateway.getDevice();
+		for (Device device : devices) {
+			if (device.getName().equals(devicename)) {
+				return device;
+			}
+		}
+		return null;
+	}
+
+	private static Service USE_IN_RUNEXLUSIVE_getService(String gatewayName, String devicename, String servicename) {
+		Device device = USE_IN_RUNEXLUSIVE_getDevice(gatewayName, devicename);
+		if (device == null)
+			return null;
+
+		for (Service service : device.getService()) {
+			if (service.getName().equals(servicename)) {
+				return service;
+			}
+		}
+
+		return null;
+	}
+
+	private static Resource USE_IN_RUNEXLUSIVE_getResource(ResourceDescriptor descriptor) {
+		Service service = USE_IN_RUNEXLUSIVE_getService(descriptor.getGateway(), descriptor.getDevice(), descriptor.getService());
+		if (service == null)
+			return null;
+
+		for (Resource resource : service.getResource()) {
+			if (resource.getName().equals(descriptor.getResource())) {
+				return resource;
+			}
+		}
+
+		return null;
+	}
+
+	private void USE_IN_RUNEXLUSIVE_addDeviceIfNotExist(final String gatewayName, final String deviceId,
+			String icon, String location)
+	{
+		Device addedDevice;
+		if ((addedDevice = USE_IN_RUNEXLUSIVE_getDevice(gatewayName, deviceId)) != null)
+		{
+			addedDevice.setLocation(location);
+			return;
+		}
+		addedDevice = ResourceFactory.eINSTANCE.createDevice();
+		addedDevice.setName(deviceId);
+		addedDevice.setIcon(icon);
+		addedDevice.setLocation(location);
+		USE_IN_RUNEXLUSIVE_getGateway(gatewayName).getDevice().add(addedDevice);
+	}
+
+	private void USE_IN_RUNEXLUSIVE_addServiceIfNotExist(final String gatewayName, final String deviceId, final String serviceId) {
+		if (USE_IN_RUNEXLUSIVE_getService(gatewayName, deviceId, serviceId) != null)
+			return;
+
+		final Service addedService = ResourceFactory.eINSTANCE.createService();
+		addedService.setName(serviceId);
+		try {
+			USE_IN_RUNEXLUSIVE_getDevice(gatewayName, deviceId).getService().add(addedService);
+		} catch (NullPointerException e) {
+			e.printStackTrace();
+		}
+	}
+
+	public List<ServiceDescriptor> findApplications() throws InterruptedException {
+		return USE_IN_RUNEXCLUSIVE_findApplications();
+	}
+	
+	protected List<ServiceDescriptor> USE_IN_RUNEXCLUSIVE_findApplications() {
+		List<ServiceDescriptor> retval = new ArrayList<>();
+		EList<Gateway> gateways = USE_IN_RUNEXLUSIVE_getStudio().getGateways();
+		for (Gateway gateway : gateways) {
+			Device appManager = findAppManager(gateway.getDevice());
+			if (appManager != null) {
+				retval.addAll(findApplications(appManager));
+			}
+		}
+		return retval;
+	}
+	
+
+	protected Device findAppManager(EList<Device> devices) {
+		for (Device device : devices) {
+			if (device.getName().equals("AppManager"))
+				return device;
+		}
+		return null;
+	}
+
+	protected List<ServiceDescriptor> findApplications(Device appManager) {
+		List<ServiceDescriptor> retval = new ArrayList<>();
+
+		String gateway = ((Gateway) appManager.eContainer()).getName();
+		String device = appManager.getName();
+
+		for (Service service : appManager.getService()) {
+			String srvName = service.getName();
+			if (srvName != null && (!srvName.equalsIgnoreCase("admin"))) {
+				retval.add(new ServiceDescriptor(gateway, device, srvName));
+			}
+		}
+		return retval;
+	}
+	
+	protected List<String> USE_IN_RUNEXCLUSIVE_getConnectedGatewaysId() {
+		List<String> retval = new ArrayList<String>();
+		EList<Gateway> gateways = USE_IN_RUNEXLUSIVE_getStudio().getGateways();
+		for (Gateway gateway : gateways) {
+			if (gateway.getDevice().size() != 0)
+				retval.add(gateway.getName());
+		}
+		return retval;
+	}
+	
+	public List<String> getConnectedGatewaysId() throws InterruptedException {
+		return USE_IN_RUNEXCLUSIVE_getConnectedGatewaysId();
+	}
+	
+	/* ======= */
+	/* Get/Set Location */
+	/* ======= */
+
+	public GPScoordinates getLocation(final DeviceDescriptor descriptor) {
+
+		GPScoordinates coordinates = null;
+		try {
+			coordinates = (GPScoordinates) getEditingDomain().runExclusive(new RunnableWithResult.Impl<GPScoordinates>() {
+				@Override
+				public void run() {
+					Device device = USE_IN_RUNEXLUSIVE_getDevice(descriptor.getGateway(),descriptor.getDevice());
+					GPScoordinates coordinates=null;
+					try {
+						coordinates = new GPScoordinates(device.getLocation());				
+					} catch (NullPointerException | GPSparsingException e) {
+						logger.error(e.getMessage(),e);
+					}
+					setResult(coordinates);
+					return;
+				}
+			});
+		} catch (InterruptedException e) {
+			Thread.interrupted();
+			e.printStackTrace();
+		}
+		return coordinates;
+	}
+
+	public String getIcon(final DeviceDescriptor descriptor) {
+
+		String icon = null;
+		try {
+			icon = (String) getEditingDomain().runExclusive(
+				new RunnableWithResult.Impl<String>() {
+				@Override
+				public void run() {
+					Device device = USE_IN_RUNEXLUSIVE_getDevice(descriptor.getGateway(),descriptor.getDevice());
+					String icon=null;
+					try {
+						icon =  device.getIcon();				
+					} catch (NullPointerException e) {
+						logger.error(e.getMessage(),e);
+					}
+					setResult(icon);
+					return;
+				}
+			});
+		} catch (InterruptedException e) {
+			Thread.interrupted();
+		}
+		return icon;
+	}
+
+	public void setLocation(final DeviceDescriptor descriptor, final GPScoordinates coordinates) {
+		RecordingCommand command = new RecordingCommand(getEditingDomain()) {
+			@Override
+			protected void doExecute() {
+				if(coordinates == null){
+					return;
+				}
+				Device device = ModelEditor.USE_IN_RUNEXLUSIVE_getDevice(descriptor.getGateway(),descriptor.getDevice());
+				if(device == null){
+					return;
+				}
+				device.setLocation(new StringBuilder().append(coordinates.getLat()
+					).append(":").append(coordinates.getLng()).toString());
+			}
+		};
+		getEditingDomain().getCommandStack().execute(command);
+	}
+
+	public void setIcon(final DeviceDescriptor descriptor, final String icon) {
+		RecordingCommand command = new RecordingCommand(getEditingDomain()) {
+			@Override
+			protected void doExecute() {
+				if(icon == null){
+					return;
+				}
+				Device device = ModelEditor.USE_IN_RUNEXLUSIVE_getDevice(descriptor.getGateway(),descriptor.getDevice());
+				if(device == null){
+					return;
+				}
+				device.setIcon(icon);
+			}
+		};
+		getEditingDomain().getCommandStack().execute(command);
+	}
+	
+	/* ======= */
+	/* Get IDs */
+	/* ======= */
+
+	@SuppressWarnings("unchecked")
+	public List<String> getGatewaysId() {
+
+		setupStudio();
+		try {
+			return (List<String>) getEditingDomain().runExclusive(new RunnableWithResult.Impl<List<String>>() {
+				@Override
+				public void run() {
+					List<String> retval = new ArrayList<String>();
+					EList<Gateway> gateways = USE_IN_RUNEXLUSIVE_getStudio().getGateways();
+					for (Gateway gateway : gateways) {
+						retval.add(gateway.getName());
+					}
+					setResult(retval);
+					return;
+				}
+			});
+		} catch (InterruptedException e) {
+			Thread.interrupted();
+		}
+		return Collections.emptyList();
+	}
+
+	@SuppressWarnings("unchecked")
+	public List<String> getDevicesId(final String gatewayName) {
+		try {
+			return (List<String>) getEditingDomain().runExclusive(new RunnableWithResult.Impl<List<String>>() {
+				@Override
+				public void run() {
+					List<String> retval = new ArrayList<String>();
+					EList<Device> devices = USE_IN_RUNEXLUSIVE_getGateway(gatewayName).getDevice();
+					for (Device device : devices) {
+						retval.add(device.getName());
+					}
+					setResult(retval);
+					return;
+				}
+			});
+		} catch(InterruptedException e) {
+			Thread.interrupted();
+		} catch(Exception e) {
+			e.printStackTrace();
+		}
+		return Collections.<String>emptyList();
+	}
+
+	@SuppressWarnings("unchecked")
+	public List<String> getServicesId(final String gatewayName, final String devicename)  {
+		try {
+			return (List<String>) getEditingDomain().runExclusive(new RunnableWithResult.Impl<List<String>>() {
+				@Override
+				public void run() {
+					List<String> retval = new ArrayList<String>();
+					Device device = USE_IN_RUNEXLUSIVE_getDevice(gatewayName, devicename);
+					if (device != null) {
+						for (Service service : device.getService()) {
+							retval.add(service.getName());
+						}
+					}
+					setResult(retval);
+					return;
+				}
+			});
+		} catch (InterruptedException e) {
+			Thread.interrupted();
+		} catch(Exception e) {
+			e.printStackTrace();
+		}
+		return Collections.<String>emptyList();
+	}
+
+	@SuppressWarnings("unchecked")
+	public List<String> getResourcesId(final String gatewayName, final String devicename, final String servicename) {
+		try {
+			return (List<String>) getEditingDomain().runExclusive(new RunnableWithResult.Impl<List<String>>() {
+				@Override
+				public void run() {
+					List<String> retval = new ArrayList<String>();
+	
+					Service service = USE_IN_RUNEXLUSIVE_getService(gatewayName, devicename, servicename);
+	
+					if (service != null) {
+						for (Resource resource : service.getResource()) {
+							retval.add(resource.getName());
+						}
+					}
+	
+					setResult(retval);
+					return;
+				}
+			});
+		} catch (InterruptedException e) {
+			Thread.interrupted();
+		} catch(Exception e) {
+			e.printStackTrace();
+		}
+		return Collections.<String>emptyList();
+	}
+
+	/* ============= */
+	/* Checks exists */
+	/* ============= */
+
+	public boolean existsGateway(final String gatewayId) throws InterruptedException {
+		return getGatewaysId().contains(gatewayId);
+	}
+
+	public boolean existsDevice(final String gatewayId, String deviceId) throws InterruptedException {
+		return getDevicesId(gatewayId).contains(deviceId);
+	}
+
+	public boolean existsService(final String gatewayId, String deviceId, String serviceId) throws InterruptedException {
+		return getServicesId(gatewayId, deviceId).contains(serviceId);
+	}
+
+	public boolean existsResource(final String gatewayId, String deviceId, String serviceId, String resourceId) throws InterruptedException {
+		return existsResource(new ResourceDescriptor(gatewayId, deviceId, serviceId, resourceId));
+	}
+
+	public boolean existsResource(ResourceDescriptor descriptor) throws InterruptedException {
+		return getResourcesId(descriptor.getGateway(), descriptor.getDevice(), descriptor.getService()).contains(descriptor.getResource());
+	}
+
+	/* ============== */
+	/* Access Methods */
+	/* ============== */
+
+	@SuppressWarnings("unchecked")
+	public EList<AccessMethod> getAccessMethods(final ResourceDescriptor descriptor) throws InterruptedException {
+		EList<AccessMethod> accessMethods = null;
+		accessMethods = (EList<AccessMethod>) getEditingDomain().runExclusive(new RunnableWithResult.Impl<EList<AccessMethod>>() {
+			@Override
+			public void run() {
+				EList<AccessMethod> accessMethods = new BasicEList<AccessMethod>();
+				Resource resource = USE_IN_RUNEXLUSIVE_getResource(descriptor);
+				for (AccessMethod accessMethod : resource.getAccessMethod()) {
+					accessMethods.add(accessMethod);
+				}
+				setResult(accessMethods);
+				return;
+			}
+		});
+		return accessMethods;
+	}
+
+	@SuppressWarnings("unchecked")
+	public EList<AccessMethod> getAccessMethodsWithType(final ResourceDescriptor descriptor, final AccessMethodType type) throws InterruptedException {
+		EList<AccessMethod> accessMethods = null;
+		accessMethods = (EList<AccessMethod>) getEditingDomain().runExclusive(new RunnableWithResult.Impl<EList<AccessMethod>>() {
+			@Override
+			public void run() {
+				EList<AccessMethod> accessMethods = new BasicEList<AccessMethod>();
+				Resource resource = USE_IN_RUNEXLUSIVE_getResource(descriptor);
+				for (AccessMethod accessMethod : resource.getAccessMethod()) {
+					if (accessMethod.getType().equals(type)) {
+						accessMethods.add(accessMethod);
+					}
+				}
+				setResult(accessMethods);
+				return;
+			}
+		});
+		return accessMethods;
+	}
+
+	public AccessMethod getAccessMethodWithTypeNbParams(final ResourceDescriptor descriptor, final AccessMethodType type, final int nbOfParameters)
+			throws InterruptedException {
+		return (AccessMethod) getEditingDomain().runExclusive(new RunnableWithResult.Impl<AccessMethod>() {
+			@Override
+			public void run() {
+				Resource resource = USE_IN_RUNEXLUSIVE_getResource(descriptor);
+				for (AccessMethod accessMethod : resource.getAccessMethod()) {
+					if (accessMethod.getType().equals(type)) {
+						if (accessMethod.getParameter().size() == nbOfParameters) {
+							setResult(accessMethod);
+							return;
+						}
+					}
+				}
+				setResult(null);
+				return;
+			}
+		});
+	}
+
+	/* ================= */
+	/* ADD Objects by ID */
+	/* ================= */
+
+	// USE CAREFULLY
+	// usually, if you want to add a gateway, use
+	// ConfigurationManager.addGateway
+	private void addGatewayIfNotExist_UNSAFE(final String gatewayName) {
+
+		//setupStudio();
+
+		RecordingCommand command = new RecordingCommand(getEditingDomain()) {
+
+			@Override
+			protected void doExecute() {
+				if (USE_IN_RUNEXLUSIVE_getGateway(gatewayName) != null)
+					return;
+
+				final Gateway addedGateway = ResourceFactory.eINSTANCE.createGateway();
+				addedGateway.setName(gatewayName);
+//				System.err.println("####################################");
+//
+//				ResourceEditPlugin.ADAPTER_FACTORY.adaptAllNew(addedGateway);
+//
+//				ResourceEditPlugin.ADAPTER_FACTORY.adapt(addedGateway, Gateway.class);
+//				Adapter a = ResourceEditPlugin.ADAPTER_FACTORY.adaptNew(addedGateway, Device.class);
+//
+//				System.err.println("#################################### \t"+a);
+				USE_IN_RUNEXLUSIVE_getStudio().getGateways().add(addedGateway);
+				
+				return;
+			}
+		};
+		getEditingDomain().getCommandStack().execute(command);
+	}
+
+	public void addDeviceIfNotExist(final String gatewayName, final String deviceId,
+			final String icon, final String location) 
+	{
+		//setupStudio();
+
+		RecordingCommand command = new RecordingCommand(getEditingDomain()) {
+			@Override
+			protected void doExecute() {
+				USE_IN_RUNEXLUSIVE_addDeviceIfNotExist(gatewayName, deviceId, icon, location);
+			}
+		};
+		getEditingDomain().getCommandStack().execute(command);
+	}
+
+
+	public DeviceDescriptor getDeviceDescriptor(String gatewayId, String deviceId) {
+		DeviceDescriptor deviceDescriptor = null;
+		try {
+			deviceDescriptor = (DeviceDescriptor) getEditingDomain().runExclusive(
+				new RunnableWithResult.Impl<DeviceDescriptor>() {
+					@Override
+					public void run() {
+						Device device = USE_IN_RUNEXLUSIVE_getDevice(gatewayId,deviceId);
+						DeviceDescriptor descriptor = new DeviceDescriptor(gatewayId,deviceId);
+						descriptor.setIcon(device.getIcon());
+						descriptor.setLocation(device.getLocation());
+						setResult(descriptor);
+						return;
+					}
+				});
+		} catch (InterruptedException e) {
+			Thread.interrupted();
+			e.printStackTrace();
+		}
+		return deviceDescriptor;
+	}
+	
+	public void addServiceIfNotExist(final String gatewayName, final String deviceId, final String serviceId) {
+
+		//setupStudio();
+
+		RecordingCommand command = new RecordingCommand(getEditingDomain()) {
+			@Override
+			protected void doExecute() {
+				//USE_IN_RUNEXLUSIVE_addDeviceIfNotExist(gatewayName, deviceId);
+				USE_IN_RUNEXLUSIVE_addServiceIfNotExist(gatewayName, deviceId, serviceId);
+			}
+		};
+		getEditingDomain().getCommandStack().execute(command);
+	}
+
+	public void addResourceIfNotExist(final ResourceDescriptor descriptor) {
+
+		//setupStudio();		
+		//addServiceIfNotExist(descriptor.getGateway(), descriptor.getDevice(), descriptor.getService());
+
+		try {
+			if (!existsResource(descriptor)) {
+				Segments segment = new Segments.Builder().resource(descriptor).build();
+				
+				
+				MsgSensinact response = null;
+				try {
+					response = GatewayHttpClient.sendGetRequest(segment);
+				} catch (IOException e) {
+					throw new RuntimeException("Get request on " + segment + " failed", e);
+				}
+				
+				if (! (response instanceof MsgDescribeRessource))
+					throw new RuntimeException("Can't get remote resources info for " + descriptor);
+				
+				final MsgDescribeRessource responseMessage = (MsgDescribeRessource) response;
+
+				RecordingCommand command = new RecordingCommand(getEditingDomain()) {
+					@Override
+					protected void doExecute() {
+
+						if (USE_IN_RUNEXLUSIVE_getResource(descriptor) != null)
+							return;
+
+						// create resource
+						String resourceType = responseMessage.getResponse().getType();
+						EClass type = literalToType(resourceType);
+						Resource createdResource = (Resource) ResourceFactory.eINSTANCE.create(type);
+						createdResource.setName(descriptor.getResource());
+
+						// create access methods
+						for (ObjectAccessMethods am : responseMessage.getResponse().getAccessMethods()) {
+							if (am != null) { // test to be removed after gateway bug fix 
+								AccessMethod accessMethod = ResourceFactory.eINSTANCE.createAccessMethod();
+								accessMethod.setType(AccessMethodType.get(am.getName()));
+	
+								Parameter[] parameters = new Parameter[am.getParameters().size()];
+								for (int i = 0; i < am.getParameters().size(); i++) {
+									ObjectParameter param = am.getParameters().get(i);
+									Parameter parameter = ResourceFactory.eINSTANCE.createParameter();
+									parameter.setName(param.getName());
+									parameter.setType(param.getType());
+									parameters[i] = parameter;
+								}
+	
+								for (Parameter parameter : parameters) {
+									accessMethod.getParameter().add(parameter);
+								}
+								createdResource.getAccessMethod().add(accessMethod);
+							}
+						}
+						USE_IN_RUNEXLUSIVE_getService(descriptor.getGateway(), descriptor.getDevice(), descriptor.getService()
+								).getResource().add(createdResource);
+						return;
+					}
+				};
+				try {
+					getEditingDomain().getCommandStack().execute(command);
+				}catch (WrappedException we){
+					getEditingDomain().getCommandStack().flush();
+					//Caused by multiple events received.
+				}
+			}
+		} catch (NullPointerException | InterruptedException e) {
+			getEditingDomain().getCommandStack().flush();
+			throw new RuntimeException("Unexpected exception... " + descriptor);
+		}
+	}
+
+	static EClass literalToType(final String type) {
+
+		final EClass resourceType;
+		// Literals
+		EClass stateVariableLiteral = ResourcePackage.Literals.STATE_VARIABLE;
+		EClass actionLiteral = ResourcePackage.Literals.ACTION;
+		EClass propertyLiteral = ResourcePackage.Literals.PROPERTY;
+		EClass sensorDataLiteral = ResourcePackage.Literals.SENSOR_DATA;
+
+		if ("STATE_VARIABLE".equals(type)) {
+			resourceType = stateVariableLiteral;
+		} else if ("ACTION".equals(type)) {
+			resourceType = actionLiteral;
+		} else if ("PROPERTY".equals(type)) {
+			resourceType = propertyLiteral;
+		} else if ("SENSOR".equals(type)) {
+			resourceType = sensorDataLiteral;
+		} else {
+			logger.error(ModelEditor.class.getCanonicalName() + "::updateResource with type=" + type + " - Is it a bug or a feature ?");
+			resourceType = actionLiteral;
+		}
+		return resourceType;
+	}
+
+	/* ==================== */
+	/* REMOVE Objects by ID */
+	/* ==================== */
+
+	// USE CAREFULLY
+	// usually, if you want to remove a gateway, use
+	// ConfigurationManager.removeGateway
+	private void removeGateway_UNSAFE(final String gatewayName) {
+		RecordingCommand command = new RecordingCommand(getEditingDomain()) {
+			@Override
+			protected void doExecute() {
+				EList<Gateway> gateways = USE_IN_RUNEXLUSIVE_getStudio().getGateways();
+
+				for (int i = 0; i < gateways.size(); i++) {
+					Gateway gateway = gateways.get(i);
+					if (gateway.getName().equals(gatewayName)) {
+						gateways.remove(i);
+						return;
+					}
+				}
+			}
+		};
+		getEditingDomain().getCommandStack().execute(command);
+		//DeviceLocationManager.getInstance().deleteGatewayInStudio(gatewayName);
+	}
+
+	public void clearGatewayContent(String name) {
+		for (String device : getDevicesId(name)) {
+			removeDevice(name, device);
+		}
+	}
+
+	public void removeDevice(final String gatewayName, final String deviceId) {
+		RecordingCommand command = new RecordingCommand(getEditingDomain()) {
+			@Override
+			protected void doExecute() {
+				Gateway gateway = USE_IN_RUNEXLUSIVE_getGateway(gatewayName);
+				if (gateway != null) {
+					EList<Device> devices = gateway.getDevice();
+					for (int i = 0; i < devices.size(); i++) {
+						Device device = devices.get(i);
+						if (deviceId.equals(device.getName())) {
+							devices.remove(i);
+							return;
+						}
+					}
+				}
+			}
+		};
+		getEditingDomain().getCommandStack().execute(command);
+
+//		DeviceLocationObservable.INSTANCE.deleteDeviceInStudio(new DeviceDescriptor(gatewayName, deviceId));
+	}
+
+	public void removeService(final String gatewayName, final String deviceId, final String serviceId) {
+		RecordingCommand command = new RecordingCommand(getEditingDomain()) {
+			@Override
+			protected void doExecute() {
+				Device device = USE_IN_RUNEXLUSIVE_getDevice(gatewayName, deviceId);
+				if (device != null) {
+					EList<Service> services = device.getService();
+					for (int i = 0; i < services.size(); i++) {
+						Service service = services.get(i);
+						if (serviceId.equals(service.getName())) {
+							services.remove(i);
+							return;
+						}
+					}
+				}
+			}
+		};
+		getEditingDomain().getCommandStack().execute(command);
+	}
+
+	public void removeResource(final ResourceDescriptor descriptor) {
+		RecordingCommand command = new RecordingCommand(getEditingDomain()) {
+			@Override
+			protected void doExecute() {
+				Service service = USE_IN_RUNEXLUSIVE_getService(descriptor.getGateway(), descriptor.getDevice(), descriptor.getService());
+				if (service != null) {
+					EList<Resource> resources = service.getResource();
+					for (int i = 0; i < resources.size(); i++) {
+						Resource resource = resources.get(i);
+						if (descriptor.getResource().equals(resource.getName())) {
+							resources.remove(i);
+							return;
+						}
+					}
+				}
+			}
+		};
+		getEditingDomain().getCommandStack().execute(command);
+	}
+
+	/* ==== */
+	/* MISC */
+	/* ==== */
+
+	public EClass getResourceClass(final ResourceDescriptor descriptor) throws InterruptedException {
+		return (EClass) getEditingDomain().runExclusive(new RunnableWithResult.Impl<EClass>() {
+			@Override
+			public void run() {
+				Resource resource = USE_IN_RUNEXLUSIVE_getResource(descriptor);
+				setResult(resource.eClass());
+				return;
+			}
+		});
+	}
+
+	public int getAccessMethodNb(final ResourceDescriptor descriptor) throws InterruptedException {
+		return (Integer) getEditingDomain().runExclusive(new RunnableWithResult.Impl<Integer>() {
+			@Override
+			public void run() {
+				Resource resource = USE_IN_RUNEXLUSIVE_getResource(descriptor);
+				setResult(new Integer(resource.getAccessMethod().size()));
+				return;
+			}
+		});
+	}
+
+	@Override
+	public void onConnect(String gatewayname) {
+	}
+
+	@Override
+	public void onDisconnect(String gatewayname) {
+		this.clearGatewayContent(gatewayname);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ModelUpdate.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ModelUpdate.java
new file mode 100644
index 0000000..c086b1f
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ModelUpdate.java
@@ -0,0 +1,82 @@
+package org.eclipse.sensinact.studio.model.manager.modelupdater;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.sensinact.studio.model.resource.utils.Descriptor;
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+
+public abstract class ModelUpdate<D extends Descriptor> {
+
+	protected abstract void doApply();
+	protected abstract boolean doComplete();
+	
+	protected final D object;
+	protected List<ModelUpdate<?>> next;
+
+	public ModelUpdate(D object){
+		this.object = object;
+		next = new ArrayList<>();
+	}
+
+	public boolean complete(){		
+		if(doComplete()){			
+			for(ModelUpdate<?> mu:next){				
+				if(!mu.complete())
+					return false;
+			}
+			return true;
+		}
+		return false;
+	}
+	
+	public void apply(){		
+		if(!complete())
+			return;
+		this.doApply();
+		for(ModelUpdate<?> mu:next){
+			mu.apply();
+		}
+	}
+
+	private Descriptor getDescriptor(){
+		return this.object;
+	}
+	
+	public boolean addNext(ModelUpdate<?> next){		
+		int compare = this.object.compareTo(next.getDescriptor());		
+		if(compare==0 || compare==1)
+			return false;
+		for(ModelUpdate<?> mu:this.next){			
+			if(mu.addNext(next))
+				return true;
+		}
+		return this.next.add(next);
+	}
+	
+	public boolean branch(ModelUpdate<?> mu) {
+		Descriptor d = mu.object;
+		String branch = d.commonBranch(object);
+		return branch!=null && branch.length()>1;
+	}
+
+	protected boolean existsGateway(final String gatewayId) {
+		return ModelEditor.getInstance().getGatewaysId().contains(gatewayId);
+	}
+
+	protected boolean existsDevice(final String gatewayId, String deviceId) {
+		return ModelEditor.getInstance().getDevicesId(gatewayId).contains(deviceId);
+	}
+
+	protected boolean existsService(final String gatewayId, String deviceId, String serviceId){
+		return ModelEditor.getInstance().getServicesId(gatewayId, deviceId).contains(serviceId);
+	}
+
+	protected boolean existsResource(final String gatewayId, String deviceId, String serviceId, String resourceId) {
+		return this.existsResource(new ResourceDescriptor(gatewayId, deviceId, serviceId, resourceId));
+	}
+
+	protected boolean existsResource(ResourceDescriptor descriptor) {
+		return ModelEditor.getInstance().getResourcesId(descriptor.getGateway(), descriptor.getDevice(), descriptor.getService()).contains(descriptor.getResource());
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ModelUpdateStack.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ModelUpdateStack.java
new file mode 100644
index 0000000..790af31
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ModelUpdateStack.java
@@ -0,0 +1,63 @@
+/**
+ * 
+ */
+package org.eclipse.sensinact.studio.model.manager.modelupdater;
+
+import java.util.AbstractList;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * 
+ */
+public class ModelUpdateStack extends AbstractList<ModelUpdate<?>> {
+
+	List<ModelUpdate<?>> stack;
+	
+	public ModelUpdateStack() {
+		super();
+		this.stack = Collections.synchronizedList(new ArrayList<ModelUpdate<?>>());
+	}
+	
+	@Override
+	public ModelUpdate<?> get(int index) {
+		return this.stack.get(index);
+	}
+	
+	public boolean add(ModelUpdate<?> mu){
+		if(mu == null)
+			return false;
+        if(mu.complete()){
+        	mu.apply();
+        	return true;
+        }
+		synchronized (stack){			
+	        Iterator<ModelUpdate<?>> i = stack.iterator(); 
+	        while (i.hasNext()){
+	    	    ModelUpdate<?> model = i.next();
+	            if(model.addNext(mu)){
+	        	    if(model.complete()){
+	        		    model.apply();
+	        		    i.remove();
+	        	   }
+	        	   return true;
+	            } if(mu.addNext(model)){
+ 	        	   i.remove();
+ 	               if(mu.complete()){
+ 	        	       mu.apply();
+ 	        	       return true;
+ 	               }
+ 	        	   break;
+	            }
+	        }
+		}
+	    return stack.add(mu);
+	}
+
+	@Override
+	public int size() {
+		return this.stack.size();
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ModelUpdater.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ModelUpdater.java
new file mode 100644
index 0000000..a9af094
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ModelUpdater.java
@@ -0,0 +1,364 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.manager.modelupdater;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+import org.eclipse.sensinact.studio.http.messages.snamessage.ObjectNameTypeValue;
+import org.eclipse.sensinact.studio.http.messages.snamessage.attributevalueupdated.MsgAttributeValueUpdated;
+import org.eclipse.sensinact.studio.http.messages.snamessage.basic.MsgHttpError;
+import org.eclipse.sensinact.studio.http.messages.snamessage.completelist.MsgCompleteList;
+import org.eclipse.sensinact.studio.http.messages.snamessage.completelist.ObjectProvider;
+import org.eclipse.sensinact.studio.http.messages.snamessage.getresponse.MsgGetResponse;
+import org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle.MsgProviderAppearing;
+import org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle.MsgProviderDisappearing;
+import org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle.MsgResourceAppearing;
+import org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle.MsgResourceDisappearing;
+import org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle.MsgServiceAppearing;
+import org.eclipse.sensinact.studio.http.messages.snamessage.lifecycle.MsgServiceDisappearing;
+import org.eclipse.sensinact.studio.http.messages.snamessage.resourceslist.MsgResourcesList;
+import org.eclipse.sensinact.studio.http.messages.snamessage.serviceslist.MsgServicesList;
+import org.eclipse.sensinact.studio.http.services.client.GatewayHttpClient;
+import org.eclipse.sensinact.studio.http.services.client.GatewayHttpClient.RequestParameter;
+import org.eclipse.sensinact.studio.http.services.client.connectionmanager.NotifDispatcher;
+import org.eclipse.sensinact.studio.http.services.client.listener.NotifSubscriptionListener;
+import org.eclipse.sensinact.studio.model.resource.utils.DeviceDescriptor;
+import org.eclipse.sensinact.studio.model.resource.utils.GPScoordinates;
+import org.eclipse.sensinact.studio.model.resource.utils.GPSparsingException;
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+import org.eclipse.sensinact.studio.model.resource.utils.Segments;
+import org.eclipse.sensinact.studio.model.resource.utils.ServiceDescriptor;
+import org.eclipse.sensinact.studio.resource.AccessMethodType;
+
+/**
+ * @author Nicolas Hili, Etienne Gandrille, Jander and others
+ */
+public class ModelUpdater implements NotifSubscriptionListener {
+
+	private static final Logger logger = Logger.getLogger(ModelUpdater.class);
+	
+	private static ModelUpdater INSTANCE;
+	
+	public static ModelUpdater getInstance() {
+		if (INSTANCE == null)
+			INSTANCE = new ModelUpdater();
+		return INSTANCE;
+	}
+
+
+	private final ModelUpdateStack stack = new ModelUpdateStack();
+	
+	private ModelUpdater() {
+		NotifDispatcher.getInstance().subscribe(this);
+	}
+
+	/**
+	 * Get all devices from the gateway and updates the model.
+	 * 
+	 * @throws IOException
+	 */
+	public void updateDevices(final String gatewayName) throws IOException {
+		
+			logger.info("Full model update triggered");
+
+			Segments segments = new Segments.Builder().gateway(gatewayName).root().build();
+			MsgSensinact snaMsg = GatewayHttpClient.sendGetRequest(segments);
+			
+			if (!(snaMsg instanceof MsgCompleteList)) {
+				displayLogOnError(snaMsg, "devices");
+				return;
+			}
+
+			MsgCompleteList list = (MsgCompleteList) snaMsg;
+			
+			// update devices list
+			new Thread() {
+				public void run() {
+					// remove device
+					for (String localDeviceId : ModelEditor.getInstance().getDevicesId(gatewayName)) {	
+						try {
+							if(!list.getProvidersId().contains(localDeviceId))
+								stack.add(new DeviceDisappearing(new DeviceDescriptor(gatewayName, localDeviceId)));							
+						}catch(Exception e) {
+							logger.error(e.getMessage(),e);							
+						}
+					}
+					// add devices						
+					for (ObjectProvider provider : list.getProviders()){
+						if(provider.getLocation() == null){
+							continue;
+						}
+						DeviceDescriptor desc = new DeviceDescriptor(gatewayName, provider.getName());
+						desc.setLocation(provider.getLocation());
+						stack.add(new DeviceAppearing(desc));
+					}
+				}
+			}.start();
+	}
+
+	/**
+	 * Get all services on a device, from the gateway, and updates the model.
+	 * 
+	 * @param device
+	 *            the device from which services need to be retrieved
+	 * @throws IOException
+	 */
+	public void updateServices(final String gatewayName, final String deviceId) throws IOException {
+		
+		Segments segments = new Segments.Builder().gateway(gatewayName).device(deviceId).services().build();		
+		MsgSensinact snaMsg = GatewayHttpClient.sendGetRequest(segments);
+		
+		if (!(snaMsg instanceof MsgServicesList)) {
+			System.out.println(snaMsg);
+			displayLogOnError(snaMsg, "services");
+			return;
+		}
+		if(((MsgServicesList) snaMsg).getServices() == null)
+			return;
+
+		// remove service
+		for (String localServiceId : ModelEditor.getInstance().getServicesId(gatewayName, deviceId)) {		
+			try {		
+				if(!((MsgServicesList) snaMsg).getServices().contains(localServiceId)) 
+					stack.add(new ServiceDisappearing(new ServiceDescriptor(gatewayName, deviceId, localServiceId)));
+			} catch(Exception ex) {
+				logger.error(ex.getMessage(),ex);
+			}
+		}
+		
+		for (String service : ((MsgServicesList) snaMsg).getServices()){
+			stack.add(new ServiceAppearing(new ServiceDescriptor(gatewayName, deviceId, service)));
+		}
+	}
+	
+	/* ================ */
+	/* Update resources */
+	/* ================ */
+	
+	/**
+	 * Retrieve all resources from one service
+	 * 
+	 * @param service
+	 *            the service from which resources need to be retrieved
+	 * @throws IOException
+	 */
+	public void updateResources(final String gatewayName, final String deviceId, final String serviceId) throws IOException {
+		Segments segment = new Segments.Builder().gateway(gatewayName).device(deviceId).service(serviceId).resources().build();
+
+		MsgSensinact msg = GatewayHttpClient.sendGetRequest(segment);
+		
+		if (!(msg instanceof MsgResourcesList)) {
+			displayLogOnError(msg, "resources");
+			return;
+		}			
+		if(((MsgResourcesList) msg).getResources() == null)
+			return;
+
+		// remove resources
+		for (String localResourceId : ModelEditor.getInstance().getResourcesId(gatewayName, deviceId, serviceId)) {		
+			try {		
+				if(!((MsgResourcesList) msg).getResources().contains(localResourceId)) 
+					stack.add(new ResourceDisappearing(new ResourceDescriptor(gatewayName, deviceId, serviceId,localResourceId)));
+			} catch(Exception ex) {
+				logger.error(ex.getMessage(),ex);
+			}
+		}
+		//add resources
+		for (String resource : ((MsgResourcesList) msg).getResources()) {
+			if(serviceId.equals("admin") && resource.equals("icon")) {
+				try {
+					ResourceDescriptor rd = updateResource(gatewayName, deviceId, serviceId, resource);
+					if(rd != null) {
+						stack.add(new ResourceAppearing(rd));
+						String icon = null;
+						ObjectNameTypeValue ontv = rd.getInitial();
+						if(ontv != null) {
+							String ic = ontv.getValueAsString();
+							icon = "null".equals(ic)?null:ic;							
+						}
+						ModelEditor.getInstance().setIcon(new DeviceDescriptor(rd.getGateway(), rd.getDevice()), icon);
+					}
+				} catch(Exception ex) {
+					logger.error(ex.getMessage(),ex);
+				}
+			} else
+				stack.add(new ResourceAppearing(new ResourceDescriptor(gatewayName, deviceId, serviceId, resource)));
+		}		
+	}
+
+	/**
+	 * Retrieve all resources from one service
+	 * 
+	 * @param service
+	 *            the service from which resources need to be retrieved
+	 * @throws IOException
+	 */
+	public ResourceDescriptor updateResource(final String gatewayName, final String deviceId, final String serviceId, final String resourceId) throws IOException {
+		Segments segment = new Segments.Builder().gateway(gatewayName).device(deviceId).service(serviceId).resource(resourceId).method(AccessMethodType.GET).build();
+		MsgSensinact msg = GatewayHttpClient.sendGetRequest(segment);
+		if (!(msg instanceof MsgGetResponse)) {
+			displayLogOnError(msg, "GET");
+			return null;
+		}
+		MsgGetResponse response  = (MsgGetResponse)msg;
+		ResourceDescriptor desc = new ResourceDescriptor(gatewayName, deviceId, serviceId, resourceId);
+		desc.setInitial(response.getResponse());
+		return desc;	
+	}
+	
+	/* =============== */
+	/* Update location */
+	/* =============== */
+
+	public boolean updateLocationOnServer(DeviceDescriptor deviceDescriptor, GPScoordinates coordinates) {
+		Segments segments = new Segments.Builder().device(deviceDescriptor).service("admin").resource("location").method(AccessMethodType.SET).build();
+		RequestParameter param = new RequestParameter("location", "string", coordinates.getLat() + ":" + coordinates.getLng());
+		try {
+			MsgSensinact msg = GatewayHttpClient.sendPostRequest(segments, null,param);
+			if (msg instanceof MsgHttpError) {
+				return false;
+			} else {
+				return true;
+			}
+		} catch (IOException e) {
+			logger.error("Update location on server failed", e);
+			return false;
+		}		
+	}
+	
+	/* ========= */
+	/* Listeners */
+	/* ========= */
+	
+	@Override
+	public void onLifecycleEvent(String gateway, List<MsgSensinact> messages) {
+		for (MsgSensinact message : messages)
+			onLifecycleEvent(gateway, message);
+	}
+	
+	public void onLifecycleEvent(String gateway, MsgSensinact message) {
+		
+		String uri = message.getUri();
+		ModelUpdate<?> mu = null;
+		
+		if (message instanceof MsgProviderAppearing) {
+			mu = new DeviceAppearing(new DeviceDescriptor(gateway, getProviderName(uri)));
+			
+		} else if (message instanceof MsgProviderDisappearing) {
+			mu = new DeviceDisappearing(new DeviceDescriptor(gateway, getProviderName(uri)));			
+			
+		} else if (message instanceof MsgServiceAppearing) {
+			mu = new ServiceAppearing(new ServiceDescriptor(gateway, getProviderName(uri),getServiceName(uri)));
+		
+		} else if (message instanceof MsgServiceDisappearing) {
+			mu = new ServiceDisappearing(new ServiceDescriptor(gateway, getProviderName(uri),getServiceName(uri)));
+			
+		} else if (message instanceof MsgResourceAppearing) {
+			ResourceDescriptor d = new ResourceDescriptor(gateway,getProviderName(uri),getServiceName(uri),getResourceName(uri));
+			d.setInitial(((MsgResourceAppearing)message).getInitial());
+			mu = new ResourceAppearing(d);
+			
+		} else if (message instanceof MsgResourceDisappearing) {
+			mu = new ResourceDisappearing(new ResourceDescriptor(gateway, 
+					getProviderName(uri),getServiceName(uri),
+					getResourceName(uri)));
+		} else {
+			displayLogOnError(message, "lifecycle");
+			return;
+		}
+		stack.add(mu);
+	}
+
+	@Override
+	public void onLocationEvent(String gateway, List<MsgSensinact> messages) {
+		for (MsgSensinact message : messages)
+			onLocationEvent(gateway, message);
+	}
+	
+	public void onLocationEvent(String gateway, MsgSensinact message) {
+	
+		if(!(message instanceof MsgAttributeValueUpdated) || !((MsgAttributeValueUpdated)message).isLocationValue()){
+			return;
+		}
+		MsgAttributeValueUpdated lu = (MsgAttributeValueUpdated)message;
+		String uri = lu.getUri();
+		String device = getProviderName(uri);
+		try {
+			lu.getUri();
+			ModelEditor.getInstance().setLocation(new DeviceDescriptor(gateway, device), 
+			new GPScoordinates(lu.getNotification().getValueAsString()));
+			
+		} catch (GPSparsingException e) {			
+			logger.error(e.getMessage(),e);
+		}
+	}
+	
+	static void executeInThread(Runnable r){
+		Runnable runnableWithTry = () -> {
+			try {
+				r.run();
+			} catch (Exception e) {
+				logger.error(e);
+			}
+		}; 		
+		new Thread(runnableWithTry).start();
+    }
+
+
+	@Override
+	public void onIconEvent(String gateway, List<MsgSensinact> messages) {
+		for (MsgSensinact message : messages)
+			onIconEvent(gateway, message);
+	}
+	
+	public void onIconEvent(String gateway, MsgSensinact message) {
+		if(!(message instanceof MsgAttributeValueUpdated) || !((MsgAttributeValueUpdated)message).isIconValue()){
+			return;
+		}
+		MsgAttributeValueUpdated lu = (MsgAttributeValueUpdated)message;
+		String uri = lu.getUri();
+		String device = getProviderName(uri);
+		ModelEditor.getInstance().setIcon(new DeviceDescriptor(gateway, device),  lu.getNotification().getValueAsString());
+	}
+
+	@Override
+	public void onValueEvent(String gateway, List<MsgSensinact> messages) {
+		// do nothing for now
+		
+	}
+	
+	private String getProviderName(String uri) {
+		String[] tokens = uri.split("/");
+		return tokens[1];
+	}
+
+	private String getServiceName(String uri) {
+		String[] tokens = uri.split("/");
+		return tokens[2];
+	}
+	
+	private String getResourceName(String uri) {
+		String[] tokens = uri.split("/");
+		return tokens[3];
+	}
+	
+	/* ========= */
+	/* Exception */
+	/* ========= */
+	
+	private void displayLogOnError(MsgSensinact response, String elementName) {
+		String fullMsg = String.format("Error sent by gateway while getting %s (%s)", elementName, response.getType());
+		logger.error(fullMsg);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ResourceAppearing.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ResourceAppearing.java
new file mode 100644
index 0000000..5321a54
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ResourceAppearing.java
@@ -0,0 +1,61 @@
+/**
+ * 
+ */
+package org.eclipse.sensinact.studio.model.manager.modelupdater;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.ObjectNameTypeValue;
+import org.eclipse.sensinact.studio.model.resource.utils.DeviceDescriptor;
+import org.eclipse.sensinact.studio.model.resource.utils.GPScoordinates;
+import org.eclipse.sensinact.studio.model.resource.utils.GPSparsingException;
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+
+/**
+ *
+ */
+public class ResourceAppearing extends ModelUpdate<ResourceDescriptor> {
+
+	/**
+	 * @param object
+	 */
+	public ResourceAppearing(ResourceDescriptor object) {
+		super(object);
+	}
+
+	@Override
+	protected void doApply(){		
+		ResourceDescriptor d = super.object;
+		ModelUpdater.executeInThread(
+			() -> ModelEditor.getInstance().addResourceIfNotExist(super.object)
+		);
+		ObjectNameTypeValue ontv = d.getInitial();
+		if(ontv==null) 
+			return;
+		String value = ontv.getValueAsString();
+		if(value==null || "null".equals(value))
+			return;
+		final DeviceDescriptor descriptor = new DeviceDescriptor(d.getGateway(),d.getDevice());
+		if("location".equals(d.getResource()) && "admin".equals(d.getService())){				
+			GPScoordinates gps;
+			try {
+				gps = new GPScoordinates(value);
+			} catch (GPSparsingException e) {
+				e.printStackTrace();
+				return;
+			}
+			ModelUpdater.executeInThread(() -> ModelEditor.getInstance().setLocation(descriptor, gps));
+		}		
+		if("icon".equals(d.getResource()) && "admin".equals(d.getService())){
+			ModelUpdater.executeInThread(() -> ModelEditor.getInstance().setIcon(descriptor, value));
+		}
+	}
+
+	@Override
+	protected boolean doComplete() {
+		return super.object.getGateway()!=null &&
+			   super.object.getDevice()!=null  &&
+			   super.object.getService()!=null &&
+			   super.object.getResource()!=null &&
+			   super.existsService(super.object.getGateway(),super.object.getDevice(),super.object.getService());
+	}
+
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ResourceDisappearing.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ResourceDisappearing.java
new file mode 100644
index 0000000..a63346c
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ResourceDisappearing.java
@@ -0,0 +1,40 @@
+/**
+ * 
+ */
+package org.eclipse.sensinact.studio.model.manager.modelupdater;
+
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+
+/**
+ *
+ */
+public class ResourceDisappearing extends ModelUpdate<ResourceDescriptor> {
+
+	/**
+	 * @param object
+	 */
+	public ResourceDisappearing(ResourceDescriptor object) {
+		super(object);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.sensinact.studio.model.manager.modelupdater.ModelUpdate#doApply()
+	 */
+	@Override
+	protected void doApply(){
+		
+		ModelUpdater.executeInThread(
+				() -> ModelEditor.getInstance().removeResource(
+						super.object)
+			);
+	}
+
+	@Override
+	protected boolean doComplete() {
+		return super.object.getGateway()!=null &&
+			   super.object.getDevice()!=null &&
+			   super.object.getService()!=null &&
+			   super.object.getResource()!=null;
+	}
+
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ServiceAppearing.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ServiceAppearing.java
new file mode 100644
index 0000000..f21d6dc
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ServiceAppearing.java
@@ -0,0 +1,38 @@
+/**
+ * 
+ */
+package org.eclipse.sensinact.studio.model.manager.modelupdater;
+
+import org.eclipse.sensinact.studio.model.resource.utils.ServiceDescriptor;
+
+/**
+ *
+ */
+public class ServiceAppearing extends ModelUpdate<ServiceDescriptor> {
+
+	/**
+	 * @param object
+	 */
+	public ServiceAppearing(ServiceDescriptor object) {
+		super(object);
+	}
+
+	@Override
+	protected void doApply(){
+		ModelUpdater.executeInThread(
+			() -> ModelEditor.getInstance().addServiceIfNotExist(
+					super.object.getGateway(),
+					super.object.getDevice(),
+					super.object.getService())
+			);
+	}
+	
+	@Override
+	protected boolean doComplete() {
+		return super.object.getGateway()!=null &&
+			   super.object.getDevice()!=null &&
+			   super.object.getService()!=null &&
+			   super.existsDevice(super.object.getGateway(),super.object.getDevice());
+	}
+
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ServiceDisappearing.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ServiceDisappearing.java
new file mode 100644
index 0000000..825c474
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/ServiceDisappearing.java
@@ -0,0 +1,38 @@
+/**
+ * 
+ */
+package org.eclipse.sensinact.studio.model.manager.modelupdater;
+
+import org.eclipse.sensinact.studio.model.resource.utils.ServiceDescriptor;
+
+/**
+ *
+ */
+public class ServiceDisappearing extends ModelUpdate<ServiceDescriptor> {
+
+	/**
+	 * @param object
+	 */
+	public ServiceDisappearing(ServiceDescriptor object) {
+		super(object);
+	}
+
+	@Override
+	protected void doApply(){
+		
+		ModelUpdater.executeInThread(
+				() -> ModelEditor.getInstance().removeService(
+					super.object.getGateway(),
+					super.object.getDevice(),
+					super.object.getService())
+			);
+	}
+
+	@Override
+	protected boolean doComplete() {
+		return super.object.getGateway()!=null &&
+			   super.object.getDevice()!=null &&
+			   super.object.getService()!=null;
+	}
+
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/package-info.java b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/package-info.java
new file mode 100644
index 0000000..71bd589
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.manager/src/org/eclipse/sensinact/studio/model/manager/modelupdater/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.model.manager.modelupdater;
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/.classpath b/bnd/org.eclipse.sensinact.studio.model.resource/.classpath
new file mode 100644
index 0000000..b8a2d22
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/.classpath
@@ -0,0 +1,14 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
+	</classpathentry>
+	<classpathentry kind="src" output="bin" path="src"/>
+	<classpathentry kind="src" output="bin_test" path="test">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="src" path="src-gen"/>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/.gitignore b/bnd/org.eclipse.sensinact.studio.model.resource/.gitignore
new file mode 100644
index 0000000..c2b941a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/.gitignore
@@ -0,0 +1,2 @@
+/bin_test/
+/generated/
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/.project b/bnd/org.eclipse.sensinact.studio.model.resource/.project
new file mode 100644
index 0000000..08bbde1
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.sensinact.studio.model.resource</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+	</natures>
+</projectDescription>
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/bnd.bnd b/bnd/org.eclipse.sensinact.studio.model.resource/bnd.bnd
new file mode 100644
index 0000000..84339f3
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/bnd.bnd
@@ -0,0 +1,17 @@
+src: ${^src},src-gen
+
+-enable-gecko-emf: true
+
+Bundle-Version: 1.0.0.SNAPSHOT
+Bundle-SymbolicName: ${p};singleton:=true
+Bundle-ActivationPolicy: lazy
+
+-includeresource.model: \
+	model=models,\
+	plugin.properties,\
+	plugin.xml
+	
+-buildpath: \
+	org.eclipse.sensinact.studio.http.messages,\
+	json,\
+	org.restlet
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/models/resource.aird b/bnd/org.eclipse.sensinact.studio.model.resource/models/resource.aird
new file mode 100644
index 0000000..a283ab7
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/models/resource.aird
@@ -0,0 +1,2242 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xmi:XMI xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:description="http://www.eclipse.org/sirius/description/1.1.0" xmlns:description_1="http://www.eclipse.org/sirius/diagram/description/1.1.0" xmlns:diagram="http://www.eclipse.org/sirius/diagram/1.1.0" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.3/notation" xmlns:style="http://www.eclipse.org/sirius/diagram/description/style/1.1.0" xmlns:viewpoint="http://www.eclipse.org/sirius/1.1.0" xsi:schemaLocation="http://www.eclipse.org/sirius/description/1.1.0 http://www.eclipse.org/sirius/1.1.0#//description http://www.eclipse.org/sirius/diagram/description/1.1.0 http://www.eclipse.org/sirius/diagram/1.1.0#//description http://www.eclipse.org/sirius/diagram/description/style/1.1.0 http://www.eclipse.org/sirius/diagram/1.1.0#//description/style">
+  <viewpoint:DAnalysis uid="_4ocfQJKFEeW9FdUPGRS2og" selectedViews="_5Jn5sJKFEeW9FdUPGRS2og _77ZdwJKFEeW9FdUPGRS2og _77kc4JKFEeW9FdUPGRS2og _79qHkJKFEeW9FdUPGRS2og" version="14.3.1.202003261200">
+    <semanticResources>resource.ecore</semanticResources>
+    <semanticResources>http://www.eclipse.org/emf/2002/Ecore</semanticResources>
+    <ownedViews xmi:type="viewpoint:DView" uid="_5Jn5sJKFEeW9FdUPGRS2og">
+      <viewpoint xmi:type="description:Viewpoint" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']"/>
+      <ownedRepresentationDescriptors xmi:type="viewpoint:DRepresentationDescriptor" uid="_2M2NcOo4Eeusl77uIP-YcQ" name="resource class diagram" repPath="#_5YZVgJKFEeW9FdUPGRS2og" changeId="5738d137-21b2-47d4-806a-ca24fc0461ac">
+        <description xmi:type="description_1:DiagramDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']"/>
+        <target xmi:type="ecore:EPackage" href="resource.ecore#/"/>
+      </ownedRepresentationDescriptors>
+      <ownedRepresentationDescriptors xmi:type="viewpoint:DRepresentationDescriptor" uid="_2PvwcOo4Eeusl77uIP-YcQ" name="ecore class diagram" repPath="#_77Gi0JKFEeW9FdUPGRS2og">
+        <description xmi:type="description_1:DiagramDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']"/>
+        <target xmi:type="ecore:EPackage" href="http://www.eclipse.org/emf/2002/Ecore#/"/>
+      </ownedRepresentationDescriptors>
+      <ownedRepresentationDescriptors xmi:type="viewpoint:DRepresentationDescriptor" uid="_2Pw-kOo4Eeusl77uIP-YcQ" name="resource class diagram" repPath="#_IOoJ8JKGEeW9FdUPGRS2og">
+        <description xmi:type="description_1:DiagramDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']"/>
+        <target xmi:type="ecore:EPackage" href="resource.ecore#/"/>
+      </ownedRepresentationDescriptors>
+    </ownedViews>
+    <ownedViews xmi:type="viewpoint:DView" uid="_77ZdwJKFEeW9FdUPGRS2og">
+      <viewpoint xmi:type="description:Viewpoint" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Review']"/>
+    </ownedViews>
+    <ownedViews xmi:type="viewpoint:DView" uid="_77kc4JKFEeW9FdUPGRS2og">
+      <viewpoint xmi:type="description:Viewpoint" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Archetype']"/>
+    </ownedViews>
+    <ownedViews xmi:type="viewpoint:DView" uid="_79qHkJKFEeW9FdUPGRS2og">
+      <viewpoint xmi:type="description:Viewpoint" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Generation']"/>
+    </ownedViews>
+  </viewpoint:DAnalysis>
+  <diagram:DSemanticDiagram uid="_5YZVgJKFEeW9FdUPGRS2og">
+    <ownedAnnotationEntries xmi:type="description:AnnotationEntry" uid="_5ZBAkJKFEeW9FdUPGRS2og" source="GMF_DIAGRAMS">
+      <data xmi:type="notation:Diagram" xmi:id="_5ZBAkZKFEeW9FdUPGRS2og" type="Sirius" element="_5YZVgJKFEeW9FdUPGRS2og" measurementUnit="Pixel">
+        <children xmi:type="notation:Node" xmi:id="_87R0UOo4Eeusl77uIP-YcQ" type="2003" element="_85z0sOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87Ws0Oo4Eeusl77uIP-YcQ" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_87XT4Oo4Eeusl77uIP-YcQ" type="7004">
+            <children xmi:type="notation:Node" xmi:id="_87hE4Oo4Eeusl77uIP-YcQ" type="3010" element="_86me4eo4Eeusl77uIP-YcQ">
+              <styles xmi:type="notation:FontStyle" xmi:id="_87hE4eo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_87hE4uo4Eeusl77uIP-YcQ"/>
+            </children>
+            <styles xmi:type="notation:SortingStyle" xmi:id="_87XT4eo4Eeusl77uIP-YcQ"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_87XT4uo4Eeusl77uIP-YcQ"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_87R0Ueo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87R0Uuo4Eeusl77uIP-YcQ" x="374" y="481"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_87X68Oo4Eeusl77uIP-YcQ" type="2003" element="_858-oOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87X68-o4Eeusl77uIP-YcQ" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_87YiAOo4Eeusl77uIP-YcQ" type="7004">
+            <children xmi:type="notation:Node" xmi:id="_87hE4-o4Eeusl77uIP-YcQ" type="3010" element="_86xeAuo4Eeusl77uIP-YcQ">
+              <styles xmi:type="notation:FontStyle" xmi:id="_87hE5Oo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_87hE5eo4Eeusl77uIP-YcQ"/>
+            </children>
+            <children xmi:type="notation:Node" xmi:id="_87hr8Oo4Eeusl77uIP-YcQ" type="3010" element="_86yFEeo4Eeusl77uIP-YcQ">
+              <styles xmi:type="notation:FontStyle" xmi:id="_87hr8eo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_87hr8uo4Eeusl77uIP-YcQ"/>
+            </children>
+            <children xmi:type="notation:Node" xmi:id="_87hr8-o4Eeusl77uIP-YcQ" type="3010" element="_86ysIOo4Eeusl77uIP-YcQ">
+              <styles xmi:type="notation:FontStyle" xmi:id="_87hr9Oo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_87hr9eo4Eeusl77uIP-YcQ"/>
+            </children>
+            <children xmi:type="notation:Node" xmi:id="_87hr9uo4Eeusl77uIP-YcQ" type="3010" element="_86ysIuo4Eeusl77uIP-YcQ">
+              <styles xmi:type="notation:FontStyle" xmi:id="_87hr9-o4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_87hr-Oo4Eeusl77uIP-YcQ"/>
+            </children>
+            <children xmi:type="notation:Node" xmi:id="_87iTAOo4Eeusl77uIP-YcQ" type="3010" element="_86zTMOo4Eeusl77uIP-YcQ">
+              <styles xmi:type="notation:FontStyle" xmi:id="_87iTAeo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_87iTAuo4Eeusl77uIP-YcQ"/>
+            </children>
+            <styles xmi:type="notation:SortingStyle" xmi:id="_87YiAeo4Eeusl77uIP-YcQ"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_87YiAuo4Eeusl77uIP-YcQ"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_87X68eo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87X68uo4Eeusl77uIP-YcQ"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_87YiA-o4Eeusl77uIP-YcQ" type="2003" element="_859lseo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87YiBuo4Eeusl77uIP-YcQ" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_87YiB-o4Eeusl77uIP-YcQ" type="7004">
+            <styles xmi:type="notation:SortingStyle" xmi:id="_87YiCOo4Eeusl77uIP-YcQ"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_87YiCeo4Eeusl77uIP-YcQ"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_87YiBOo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87YiBeo4Eeusl77uIP-YcQ" x="288" y="960"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_87ZJEOo4Eeusl77uIP-YcQ" type="2003" element="_85_a4Oo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87ZJE-o4Eeusl77uIP-YcQ" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_87ZJFOo4Eeusl77uIP-YcQ" type="7004">
+            <styles xmi:type="notation:SortingStyle" xmi:id="_87ZJFeo4Eeusl77uIP-YcQ"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_87ZJFuo4Eeusl77uIP-YcQ"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_87ZJEeo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87ZJEuo4Eeusl77uIP-YcQ" x="625" y="481"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_87ZwIOo4Eeusl77uIP-YcQ" type="2003" element="_86ApAOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87ZwI-o4Eeusl77uIP-YcQ" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_87ZwJOo4Eeusl77uIP-YcQ" type="7004">
+            <children xmi:type="notation:Node" xmi:id="_87iTA-o4Eeusl77uIP-YcQ" type="3010" element="_86o7IOo4Eeusl77uIP-YcQ">
+              <styles xmi:type="notation:FontStyle" xmi:id="_87iTBOo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_87iTBeo4Eeusl77uIP-YcQ"/>
+            </children>
+            <children xmi:type="notation:Node" xmi:id="_87i6EOo4Eeusl77uIP-YcQ" type="3010" element="_86piMeo4Eeusl77uIP-YcQ">
+              <styles xmi:type="notation:FontStyle" xmi:id="_87i6Eeo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_87i6Euo4Eeusl77uIP-YcQ"/>
+            </children>
+            <children xmi:type="notation:Node" xmi:id="_87i6E-o4Eeusl77uIP-YcQ" type="3010" element="_86qJQeo4Eeusl77uIP-YcQ">
+              <styles xmi:type="notation:FontStyle" xmi:id="_87i6FOo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_87i6Feo4Eeusl77uIP-YcQ"/>
+            </children>
+            <styles xmi:type="notation:SortingStyle" xmi:id="_87ZwJeo4Eeusl77uIP-YcQ"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_87ZwJuo4Eeusl77uIP-YcQ"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_87ZwIeo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87ZwIuo4Eeusl77uIP-YcQ" x="780" y="960"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_87ZwJ-o4Eeusl77uIP-YcQ" type="2003" element="_86CeMOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87aXMOo4Eeusl77uIP-YcQ" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_87aXMeo4Eeusl77uIP-YcQ" type="7004">
+            <styles xmi:type="notation:SortingStyle" xmi:id="_87aXMuo4Eeusl77uIP-YcQ"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_87aXM-o4Eeusl77uIP-YcQ"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_87ZwKOo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87ZwKeo4Eeusl77uIP-YcQ" x="912" y="1116"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_87aXNOo4Eeusl77uIP-YcQ" type="2003" element="_86ETYOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87a-QOo4Eeusl77uIP-YcQ" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_87a-Qeo4Eeusl77uIP-YcQ" type="7004">
+            <styles xmi:type="notation:SortingStyle" xmi:id="_87a-Quo4Eeusl77uIP-YcQ"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_87a-Q-o4Eeusl77uIP-YcQ"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_87aXNeo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87aXNuo4Eeusl77uIP-YcQ" x="588" y="324"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_87a-ROo4Eeusl77uIP-YcQ" type="2003" element="_86GIkOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87a-R-o4Eeusl77uIP-YcQ" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_87blUOo4Eeusl77uIP-YcQ" type="7004">
+            <children xmi:type="notation:Node" xmi:id="_87i6Fuo4Eeusl77uIP-YcQ" type="3010" element="_86rXYOo4Eeusl77uIP-YcQ">
+              <styles xmi:type="notation:FontStyle" xmi:id="_87i6F-o4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_87i6GOo4Eeusl77uIP-YcQ"/>
+            </children>
+            <styles xmi:type="notation:SortingStyle" xmi:id="_87blUeo4Eeusl77uIP-YcQ"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_87blUuo4Eeusl77uIP-YcQ"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_87a-Reo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87a-Ruo4Eeusl77uIP-YcQ" x="765"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_87blU-o4Eeusl77uIP-YcQ" type="2003" element="_86HWseo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87cMYOo4Eeusl77uIP-YcQ" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_87cMYeo4Eeusl77uIP-YcQ" type="7004">
+            <styles xmi:type="notation:SortingStyle" xmi:id="_87cMYuo4Eeusl77uIP-YcQ"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_87cMY-o4Eeusl77uIP-YcQ"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_87blVOo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87blVeo4Eeusl77uIP-YcQ" x="411" y="324"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_87cMZOo4Eeusl77uIP-YcQ" type="2003" element="_86Ik0eo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87cMZ-o4Eeusl77uIP-YcQ" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_87cMaOo4Eeusl77uIP-YcQ" type="7004">
+            <styles xmi:type="notation:SortingStyle" xmi:id="_87cMaeo4Eeusl77uIP-YcQ"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_87cMauo4Eeusl77uIP-YcQ"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_87cMZeo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87cMZuo4Eeusl77uIP-YcQ" x="387" y="804"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_87czcOo4Eeusl77uIP-YcQ" type="2003" element="_86Jy8eo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87czc-o4Eeusl77uIP-YcQ" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_87czdOo4Eeusl77uIP-YcQ" type="7004">
+            <children xmi:type="notation:Node" xmi:id="_87jhIOo4Eeusl77uIP-YcQ" type="3010" element="_86slgOo4Eeusl77uIP-YcQ">
+              <styles xmi:type="notation:FontStyle" xmi:id="_87jhIeo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_87jhIuo4Eeusl77uIP-YcQ"/>
+            </children>
+            <children xmi:type="notation:Node" xmi:id="_87jhI-o4Eeusl77uIP-YcQ" type="3010" element="_86tMkeo4Eeusl77uIP-YcQ">
+              <styles xmi:type="notation:FontStyle" xmi:id="_87jhJOo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_87jhJeo4Eeusl77uIP-YcQ"/>
+            </children>
+            <styles xmi:type="notation:SortingStyle" xmi:id="_87czdeo4Eeusl77uIP-YcQ"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_87czduo4Eeusl77uIP-YcQ"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_87czceo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87czcuo4Eeusl77uIP-YcQ" x="387" y="636"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_87dagOo4Eeusl77uIP-YcQ" type="2003" element="_86M2Qeo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87dag-o4Eeusl77uIP-YcQ" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_87dahOo4Eeusl77uIP-YcQ" type="7004">
+            <styles xmi:type="notation:SortingStyle" xmi:id="_87daheo4Eeusl77uIP-YcQ"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_87dahuo4Eeusl77uIP-YcQ"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_87dageo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87daguo4Eeusl77uIP-YcQ" x="576" y="804"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_87dah-o4Eeusl77uIP-YcQ" type="2003" element="_86OrcOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87eBkOo4Eeusl77uIP-YcQ" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_87eBkeo4Eeusl77uIP-YcQ" type="7004">
+            <children xmi:type="notation:Node" xmi:id="_87kIMOo4Eeusl77uIP-YcQ" type="3010" element="_86vBwOo4Eeusl77uIP-YcQ">
+              <styles xmi:type="notation:FontStyle" xmi:id="_87kIMeo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_87kIMuo4Eeusl77uIP-YcQ"/>
+            </children>
+            <styles xmi:type="notation:SortingStyle" xmi:id="_87eBkuo4Eeusl77uIP-YcQ"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_87eBk-o4Eeusl77uIP-YcQ"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_87daiOo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87daieo4Eeusl77uIP-YcQ" x="753" y="804"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_87eBlOo4Eeusl77uIP-YcQ" type="2003" element="_86P5kOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87eBl-o4Eeusl77uIP-YcQ" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_87eooOo4Eeusl77uIP-YcQ" type="7004">
+            <styles xmi:type="notation:SortingStyle" xmi:id="_87eooeo4Eeusl77uIP-YcQ"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_87eoouo4Eeusl77uIP-YcQ"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_87eBleo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87eBluo4Eeusl77uIP-YcQ" x="144" y="804"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_87eoo-o4Eeusl77uIP-YcQ" type="2003" element="_86SV0Oo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87eopuo4Eeusl77uIP-YcQ" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_87eop-o4Eeusl77uIP-YcQ" type="7004">
+            <styles xmi:type="notation:SortingStyle" xmi:id="_87eoqOo4Eeusl77uIP-YcQ"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_87eoqeo4Eeusl77uIP-YcQ"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_87eopOo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87eopeo4Eeusl77uIP-YcQ" x="912" y="1284"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_87fPsOo4Eeusl77uIP-YcQ" type="2003" element="_86Tj8Oo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87f2wOo4Eeusl77uIP-YcQ" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_87f2weo4Eeusl77uIP-YcQ" type="7004">
+            <children xmi:type="notation:Node" xmi:id="_87kvQOo4Eeusl77uIP-YcQ" type="3010" element="_86vo0Oo4Eeusl77uIP-YcQ">
+              <styles xmi:type="notation:FontStyle" xmi:id="_87kvQeo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_87kvQuo4Eeusl77uIP-YcQ"/>
+            </children>
+            <children xmi:type="notation:Node" xmi:id="_87kvQ-o4Eeusl77uIP-YcQ" type="3010" element="_86wP4eo4Eeusl77uIP-YcQ">
+              <styles xmi:type="notation:FontStyle" xmi:id="_87kvROo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_87kvReo4Eeusl77uIP-YcQ"/>
+            </children>
+            <styles xmi:type="notation:SortingStyle" xmi:id="_87f2wuo4Eeusl77uIP-YcQ"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_87f2w-o4Eeusl77uIP-YcQ"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_87fPseo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87fPsuo4Eeusl77uIP-YcQ" x="625" y="156"/>
+        </children>
+        <styles xmi:type="notation:DiagramStyle" xmi:id="_5ZBAkpKFEeW9FdUPGRS2og"/>
+        <edges xmi:type="notation:Edge" xmi:id="_87nLgOo4Eeusl77uIP-YcQ" type="4001" element="_861IYOo4Eeusl77uIP-YcQ" source="_87R0UOo4Eeusl77uIP-YcQ" target="_87blU-o4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87nykOo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87nykeo4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87oZoOo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87oZoeo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87oZouo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87oZo-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_87nLgeo4Eeusl77uIP-YcQ" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_87nLguo4Eeusl77uIP-YcQ" fontColor="7490599" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_87nLg-o4Eeusl77uIP-YcQ" points="[-1, 0, -1, 60]$[-1, -60, -1, 0]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87q14Oo4Eeusl77uIP-YcQ" id="(0.5026178010471204,0.0)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87q14eo4Eeusl77uIP-YcQ" id="(0.5084745762711864,1.0)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_87rc8Oo4Eeusl77uIP-YcQ" type="4001" element="_863koOo4Eeusl77uIP-YcQ" source="_87czcOo4Eeusl77uIP-YcQ" target="_87ZJEOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87rc9Oo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87rc9eo4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87rc9uo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87rc9-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87rc-Oo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87rc-eo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_87rc8eo4Eeusl77uIP-YcQ" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_87rc8uo4Eeusl77uIP-YcQ" fontColor="7490599" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_87rc8-o4Eeusl77uIP-YcQ" points="[-1, 0, -131, 60]$[129, -60, -1, 0]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87rc-uo4Eeusl77uIP-YcQ" id="(0.5015105740181269,0.0)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87rc--o4Eeusl77uIP-YcQ" id="(0.5084745762711864,1.0)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_87sEAOo4Eeusl77uIP-YcQ" type="4001" element="_864Ltuo4Eeusl77uIP-YcQ" source="_87czcOo4Eeusl77uIP-YcQ" target="_87R0UOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87sEBOo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87sEBeo4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87sEBuo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87sEB-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87sECOo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87sECeo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_87sEAeo4Eeusl77uIP-YcQ" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_87sEAuo4Eeusl77uIP-YcQ" fontColor="7490599" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_87sEA-o4Eeusl77uIP-YcQ" points="[0, -50, 87, 110]$[-87, -110, 0, 50]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87srEOo4Eeusl77uIP-YcQ" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87srEeo4Eeusl77uIP-YcQ" id="(0.5,0.5)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_87srEuo4Eeusl77uIP-YcQ" type="4001" element="_865Z0Oo4Eeusl77uIP-YcQ" source="_87ZJEOo4Eeusl77uIP-YcQ" target="_87aXNOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87srFuo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87srF-o4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87srGOo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87srGeo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87srGuo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87srG-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_87srE-o4Eeusl77uIP-YcQ" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_87srFOo4Eeusl77uIP-YcQ" fontColor="7490599" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_87srFeo4Eeusl77uIP-YcQ" points="[-1, 0, 36, 60]$[-38, -60, -1, 0]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87tSIOo4Eeusl77uIP-YcQ" id="(0.5084745762711864,0.0)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87tSIeo4Eeusl77uIP-YcQ" id="(0.5084745762711864,1.0)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_87tSIuo4Eeusl77uIP-YcQ" type="4001" element="_866A4-o4Eeusl77uIP-YcQ" source="_87ZwIOo4Eeusl77uIP-YcQ" target="_87dah-o4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87tSJuo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87tSJ-o4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87tSKOo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87tSKeo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87tSKuo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87tSK-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_87tSI-o4Eeusl77uIP-YcQ" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_87tSJOo4Eeusl77uIP-YcQ" fontColor="7490599" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_87tSJeo4Eeusl77uIP-YcQ" points="[-1, 0, 30, 60]$[-32, -60, -1, 0]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87tSLOo4Eeusl77uIP-YcQ" id="(0.5034965034965035,0.0)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87tSLeo4Eeusl77uIP-YcQ" id="(0.5034965034965035,1.0)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_87tSLuo4Eeusl77uIP-YcQ" type="4001" element="_866n9uo4Eeusl77uIP-YcQ" source="_87ZwJ-o4Eeusl77uIP-YcQ" target="_87ZwIOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87t5MOo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87t5Meo4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87t5Muo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87t5M-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87t5NOo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87t5Neo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_87tSL-o4Eeusl77uIP-YcQ" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_87tSMOo4Eeusl77uIP-YcQ" fontColor="7490599" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_87tSMeo4Eeusl77uIP-YcQ" points="[-1, 0, 117, 60]$[-119, -60, -1, 0]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87ugQOo4Eeusl77uIP-YcQ" id="(0.5084745762711864,0.0)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87ugQeo4Eeusl77uIP-YcQ" id="(0.5034965034965035,1.0)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_87ugQuo4Eeusl77uIP-YcQ" type="4001" element="_867PBuo4Eeusl77uIP-YcQ" source="_87dah-o4Eeusl77uIP-YcQ" target="_87czcOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87ugRuo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87ugR-o4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87ugSOo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87ugSeo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87ugSuo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87ugS-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_87ugQ-o4Eeusl77uIP-YcQ" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_87ugROo4Eeusl77uIP-YcQ" fontColor="7490599" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_87ugReo4Eeusl77uIP-YcQ" points="[-1, 0, 265, 60]$[-267, -60, -1, 0]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87vHUOo4Eeusl77uIP-YcQ" id="(0.5034965034965035,0.0)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87vHUeo4Eeusl77uIP-YcQ" id="(0.5015105740181269,1.0)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_87vHUuo4Eeusl77uIP-YcQ" type="4001" element="_868dIOo4Eeusl77uIP-YcQ" source="_87eoo-o4Eeusl77uIP-YcQ" target="_87ZwJ-o4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87vHVuo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87vHV-o4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87vHWOo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87vHWeo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87vHWuo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87vHW-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_87vHU-o4Eeusl77uIP-YcQ" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_87vHVOo4Eeusl77uIP-YcQ" fontColor="7490599" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_87vHVeo4Eeusl77uIP-YcQ" points="[0, -50, 0, 110]$[0, -110, 0, 50]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87vuYOo4Eeusl77uIP-YcQ" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87vuYeo4Eeusl77uIP-YcQ" id="(0.5,0.5)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_87vuYuo4Eeusl77uIP-YcQ" type="4001" element="_869rQOo4Eeusl77uIP-YcQ" source="_87YiA-o4Eeusl77uIP-YcQ" target="_87czcOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87vuZuo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87vuZ-o4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87vuaOo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87vuaeo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87vuauo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87vua-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_87vuY-o4Eeusl77uIP-YcQ" routing="Tree"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_87vuZOo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_87vuZeo4Eeusl77uIP-YcQ" points="[-1, 0, -213, 220]$[0, -160, -212, 60]$[211, -220, -1, 0]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87wVcOo4Eeusl77uIP-YcQ" id="(0.5084745762711864,0.0)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87wVceo4Eeusl77uIP-YcQ" id="(0.5015105740181269,1.0)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_87wVcuo4Eeusl77uIP-YcQ" type="4001" element="_87Auk-o4Eeusl77uIP-YcQ" source="_87ZJEOo4Eeusl77uIP-YcQ" target="_87fPsOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87wVduo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87wVd-o4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87wVeOo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87wVeeo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87wVeuo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87wVe-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_87wVc-o4Eeusl77uIP-YcQ" routing="Tree"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_87wVdOo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_87wVdeo4Eeusl77uIP-YcQ" points="[-1, 0, -1, 220]$[66, -61, 66, 159]$[66, -160, 66, 60]$[-1, -220, -1, 0]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87w8gOo4Eeusl77uIP-YcQ" id="(0.5084745762711864,0.0)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87w8geo4Eeusl77uIP-YcQ" id="(0.5084745762711864,1.0)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_87w8guo4Eeusl77uIP-YcQ" type="4001" element="_87CjwOo4Eeusl77uIP-YcQ" source="_87ZwIOo4Eeusl77uIP-YcQ" target="_87a-ROo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87w8huo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87w8h-o4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87w8iOo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87w8ieo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87w8iuo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87w8i-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_87w8g-o4Eeusl77uIP-YcQ" routing="Tree"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_87w8hOo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_87w8heo4Eeusl77uIP-YcQ" points="[-1, 0, 30, 860]$[85, -61, 116, 799]$[85, -160, 116, 700]$[-2, -800, 29, 60]$[-32, -860, -1, 0]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87w8jOo4Eeusl77uIP-YcQ" id="(0.5034965034965035,0.0)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87w8jeo4Eeusl77uIP-YcQ" id="(0.5084745762711864,1.0)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_87xjkOo4Eeusl77uIP-YcQ" type="4001" element="_87EY8Oo4Eeusl77uIP-YcQ" source="_87ZwJ-o4Eeusl77uIP-YcQ" target="_87a-ROo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87xjlOo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87xjleo4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87xjluo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87xjl-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87xjmOo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87xjmeo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_87xjkeo4Eeusl77uIP-YcQ" routing="Tree"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_87xjkuo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_87xjk-o4Eeusl77uIP-YcQ" points="[-1, 0, 148, 1020]$[-2, -960, 147, 60]$[-150, -1020, -1, 0]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87xjmuo4Eeusl77uIP-YcQ" id="(0.5084745762711864,0.0)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87xjm-o4Eeusl77uIP-YcQ" id="(0.5084745762711864,1.0)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_87xjnOo4Eeusl77uIP-YcQ" type="4001" element="_87FABuo4Eeusl77uIP-YcQ" source="_87aXNOo4Eeusl77uIP-YcQ" target="_87fPsOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87yKoOo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87yKoeo4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87yKouo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87yKo-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87yKpOo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87yKpeo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_87xjneo4Eeusl77uIP-YcQ" routing="Tree"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_87xjnuo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_87xjn-o4Eeusl77uIP-YcQ" points="[-1, 0, -38, 60]$[36, -60, -1, 0]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87yKpuo4Eeusl77uIP-YcQ" id="(0.5084745762711864,0.0)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87yKp-o4Eeusl77uIP-YcQ" id="(0.5084745762711864,1.0)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_87yKqOo4Eeusl77uIP-YcQ" type="4001" element="_87GOIOo4Eeusl77uIP-YcQ" source="_87blU-o4Eeusl77uIP-YcQ" target="_87fPsOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87yKrOo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87yKreo4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87yKruo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87yKr-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87yxsOo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87yxseo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_87yKqeo4Eeusl77uIP-YcQ" routing="Tree"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_87yKquo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_87yKq-o4Eeusl77uIP-YcQ" points="[-1, 0, -218, 60]$[216, -60, -1, 0]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87yxsuo4Eeusl77uIP-YcQ" id="(0.5084745762711864,0.0)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87yxs-o4Eeusl77uIP-YcQ" id="(0.5084745762711864,1.0)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_87yxtOo4Eeusl77uIP-YcQ" type="4001" element="_87G1Nuo4Eeusl77uIP-YcQ" source="_87cMZOo4Eeusl77uIP-YcQ" target="_87czcOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_87zYwOo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87zYweo4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87zYwuo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87zYw-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_87zYxOo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_87zYxeo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_87yxteo4Eeusl77uIP-YcQ" routing="Tree"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_87yxtuo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_87yxt-o4Eeusl77uIP-YcQ" points="[-1, 0, -107, 60]$[105, -60, -1, 0]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87zYxuo4Eeusl77uIP-YcQ" id="(0.5084745762711864,0.0)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_87zYx-o4Eeusl77uIP-YcQ" id="(0.5015105740181269,1.0)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_87z_0Oo4Eeusl77uIP-YcQ" type="4001" element="_87HcRuo4Eeusl77uIP-YcQ" source="_87czcOo4Eeusl77uIP-YcQ" target="_87a-ROo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_870m4Oo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_870m4eo4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_870m4uo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_870m4-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_871N8Oo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_871N8eo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_87z_0eo4Eeusl77uIP-YcQ" routing="Tree"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_87z_0uo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_87z_0-o4Eeusl77uIP-YcQ" points="[-1, 0, -267, 540]$[233, -61, -33, 479]$[235, -480, -31, 60]$[265, -540, -1, 0]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_871N8uo4Eeusl77uIP-YcQ" id="(0.5015105740181269,0.0)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_871N8-o4Eeusl77uIP-YcQ" id="(0.5084745762711864,1.0)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_8711AOo4Eeusl77uIP-YcQ" type="4001" element="_87IqYOo4Eeusl77uIP-YcQ" source="_87dagOo4Eeusl77uIP-YcQ" target="_87czcOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_8711BOo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_8711Beo4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_8711Buo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_8711B-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_8711COo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_8711Ceo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_8711Aeo4Eeusl77uIP-YcQ" routing="Tree"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_8711Auo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_8711A-o4Eeusl77uIP-YcQ" points="[-1, 0, 73, 60]$[-75, -60, -1, 0]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_872cEOo4Eeusl77uIP-YcQ" id="(0.5084745762711864,0.0)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_872cEeo4Eeusl77uIP-YcQ" id="(0.5015105740181269,1.0)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_872cEuo4Eeusl77uIP-YcQ" type="4001" element="_87IqZ-o4Eeusl77uIP-YcQ" source="_87dah-o4Eeusl77uIP-YcQ" target="_87a-ROo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_872cFuo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_872cF-o4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_872cGOo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_872cGeo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_872cGuo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_872cG-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_872cE-o4Eeusl77uIP-YcQ" routing="Tree"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_872cFOo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_872cFeo4Eeusl77uIP-YcQ" points="[-1, 0, -1, 700]$[-1, -700, -1, 0]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_872cHOo4Eeusl77uIP-YcQ" id="(0.5034965034965035,0.0)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_872cHeo4Eeusl77uIP-YcQ" id="(0.5084745762711864,1.0)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_872cHuo4Eeusl77uIP-YcQ" type="4001" element="_87JRduo4Eeusl77uIP-YcQ" source="_87eBlOo4Eeusl77uIP-YcQ" target="_87czcOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_873DIOo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_873DIeo4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_873DIuo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_873DI-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_873DJOo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_873DJeo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_872cH-o4Eeusl77uIP-YcQ" routing="Tree"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_872cIOo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_872cIeo4Eeusl77uIP-YcQ" points="[-1, 0, -318, 60]$[316, -60, -1, 0]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_873DJuo4Eeusl77uIP-YcQ" id="(0.5084745762711864,0.0)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_873DJ-o4Eeusl77uIP-YcQ" id="(0.5015105740181269,1.0)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_873DKOo4Eeusl77uIP-YcQ" type="4001" element="_87J4huo4Eeusl77uIP-YcQ" source="_87fPsOo4Eeusl77uIP-YcQ" target="_87a-ROo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_873DLOo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_873DLeo4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_873DLuo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_873DL-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_873DMOo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_873DMeo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_873DKeo4Eeusl77uIP-YcQ" routing="Tree"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_873DKuo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_873DK-o4Eeusl77uIP-YcQ" points="[-1, 0, -137, 60]$[135, -60, -1, 0]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_873qMOo4Eeusl77uIP-YcQ" id="(0.5084745762711864,0.0)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_873qMeo4Eeusl77uIP-YcQ" id="(0.5084745762711864,1.0)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_873qMuo4Eeusl77uIP-YcQ" type="4001" element="_87Kfk-o4Eeusl77uIP-YcQ" source="_87YiA-o4Eeusl77uIP-YcQ" target="_87eBlOo4Eeusl77uIP-YcQ">
+          <children xmi:type="notation:Node" xmi:id="_873qNuo4Eeusl77uIP-YcQ" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_873qN-o4Eeusl77uIP-YcQ" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_873qOOo4Eeusl77uIP-YcQ" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_873qOeo4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_873qOuo4Eeusl77uIP-YcQ" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_873qO-o4Eeusl77uIP-YcQ" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_873qM-o4Eeusl77uIP-YcQ" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_873qNOo4Eeusl77uIP-YcQ" fontName="Segoe UI" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_873qNeo4Eeusl77uIP-YcQ" points="[-1, 0, 104, 60]$[-106, -60, -1, 0]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_874RQOo4Eeusl77uIP-YcQ" id="(0.5084745762711864,0.0)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_874RQeo4Eeusl77uIP-YcQ" id="(0.5084745762711864,1.0)"/>
+        </edges>
+      </data>
+    </ownedAnnotationEntries>
+    <ownedAnnotationEntries xmi:type="description:AnnotationEntry" uid="_2P3sQOo4Eeusl77uIP-YcQ" source="DANNOTATION_CUSTOMIZATION_KEY">
+      <data xmi:type="diagram:ComputedStyleDescriptionRegistry" uid="_2P3sQeo4Eeusl77uIP-YcQ">
+        <computedStyleDescriptions xmi:type="style:EdgeStyleDescription" xmi:id="_8629kOo4Eeusl77uIP-YcQ" sourceArrow="FillDiamond" routingStyle="manhattan">
+          <strokeColor xmi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='black']"/>
+          <centerLabelStyleDescription xmi:type="style:CenterLabelStyleDescription" xmi:id="_8629keo4Eeusl77uIP-YcQ" showIcon="false" labelExpression="service:render">
+            <labelColor xmi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='black']"/>
+          </centerLabelStyleDescription>
+          <endLabelStyleDescription xmi:type="style:EndLabelStyleDescription" xmi:id="_8629kuo4Eeusl77uIP-YcQ" labelSize="6" showIcon="false" labelExpression="service:eKeysLabel">
+            <labelColor xmi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='dark_blue']"/>
+          </endLabelStyleDescription>
+        </computedStyleDescriptions>
+      </data>
+    </ownedAnnotationEntries>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_85z0sOo4Eeusl77uIP-YcQ" name="AccessMethod" tooltipText="" outgoingEdges="_861IYOo4Eeusl77uIP-YcQ" incomingEdges="_864Ltuo4Eeusl77uIP-YcQ" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//AccessMethod"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//AccessMethod"/>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_854tMOo4Eeusl77uIP-YcQ" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_86me4eo4Eeusl77uIP-YcQ" name="type : AccessMethodType = GET" tooltipText="">
+        <target xmi:type="ecore:EAttribute" href="resource.ecore#//AccessMethod/type"/>
+        <semanticElements xmi:type="ecore:EAttribute" href="resource.ecore#//AccessMethod/type"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_86oUEOo4Eeusl77uIP-YcQ" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']"/>
+      </ownedElements>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_858-oOo4Eeusl77uIP-YcQ" name="AccessMethodType" tooltipText="" width="12" height="10">
+      <target xmi:type="ecore:EEnum" href="resource.ecore#//AccessMethodType"/>
+      <semanticElements xmi:type="ecore:EEnum" href="resource.ecore#//AccessMethodType"/>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_858-oeo4Eeusl77uIP-YcQ" borderSize="1" borderSizeComputationExpression="1" borderColor="125,125,125" backgroundStyle="Liquid" foregroundColor="221,236,202">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']"/>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_86xeAuo4Eeusl77uIP-YcQ" name="GET" tooltipText="">
+        <target xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/GET"/>
+        <semanticElements xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/GET"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_86yFEOo4Eeusl77uIP-YcQ" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']"/>
+      </ownedElements>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_86yFEeo4Eeusl77uIP-YcQ" name="SET" tooltipText="">
+        <target xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/SET"/>
+        <semanticElements xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/SET"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_86yFEuo4Eeusl77uIP-YcQ" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']"/>
+      </ownedElements>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_86ysIOo4Eeusl77uIP-YcQ" name="ACT" tooltipText="">
+        <target xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/ACT"/>
+        <semanticElements xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/ACT"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_86ysIeo4Eeusl77uIP-YcQ" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']"/>
+      </ownedElements>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_86ysIuo4Eeusl77uIP-YcQ" name="SUBSCRIBE" tooltipText="">
+        <target xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/SUBSCRIBE"/>
+        <semanticElements xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/SUBSCRIBE"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_86ysI-o4Eeusl77uIP-YcQ" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']"/>
+      </ownedElements>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_86zTMOo4Eeusl77uIP-YcQ" name="UNSUBSCRIBE" tooltipText="">
+        <target xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/UNSUBSCRIBE"/>
+        <semanticElements xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/UNSUBSCRIBE"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_86zTMeo4Eeusl77uIP-YcQ" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']"/>
+      </ownedElements>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_859lseo4Eeusl77uIP-YcQ" name="Action" tooltipText="" outgoingEdges="_869rQOo4Eeusl77uIP-YcQ _87Kfk-o4Eeusl77uIP-YcQ" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Action"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Action"/>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_85-MwOo4Eeusl77uIP-YcQ" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_85_a4Oo4Eeusl77uIP-YcQ" name="Attribute" tooltipText="" outgoingEdges="_865Z0Oo4Eeusl77uIP-YcQ _87Auk-o4Eeusl77uIP-YcQ" incomingEdges="_863koOo4Eeusl77uIP-YcQ" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Attribute"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Attribute"/>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_85_a4eo4Eeusl77uIP-YcQ" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_86ApAOo4Eeusl77uIP-YcQ" name="Device" tooltipText="" outgoingEdges="_866A4-o4Eeusl77uIP-YcQ _87CjwOo4Eeusl77uIP-YcQ" incomingEdges="_866n9uo4Eeusl77uIP-YcQ" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Device"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Device"/>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_86BQEOo4Eeusl77uIP-YcQ" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_86o7IOo4Eeusl77uIP-YcQ" name="friendlyName : EString" tooltipText="">
+        <target xmi:type="ecore:EAttribute" href="resource.ecore#//Device/friendlyName"/>
+        <semanticElements xmi:type="ecore:EAttribute" href="resource.ecore#//Device/friendlyName"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_86piMOo4Eeusl77uIP-YcQ" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']"/>
+      </ownedElements>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_86piMeo4Eeusl77uIP-YcQ" name="location : EString" tooltipText="">
+        <target xmi:type="ecore:EAttribute" href="resource.ecore#//Device/location"/>
+        <semanticElements xmi:type="ecore:EAttribute" href="resource.ecore#//Device/location"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_86qJQOo4Eeusl77uIP-YcQ" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']"/>
+      </ownedElements>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_86qJQeo4Eeusl77uIP-YcQ" name="icon : EString" tooltipText="">
+        <target xmi:type="ecore:EAttribute" href="resource.ecore#//Device/icon"/>
+        <semanticElements xmi:type="ecore:EAttribute" href="resource.ecore#//Device/icon"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_86qwUOo4Eeusl77uIP-YcQ" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']"/>
+      </ownedElements>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_86CeMOo4Eeusl77uIP-YcQ" name="Gateway" tooltipText="" outgoingEdges="_866n9uo4Eeusl77uIP-YcQ _87EY8Oo4Eeusl77uIP-YcQ" incomingEdges="_868dIOo4Eeusl77uIP-YcQ" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Gateway"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Gateway"/>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_86DsUOo4Eeusl77uIP-YcQ" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_86ETYOo4Eeusl77uIP-YcQ" name="Metadata" tooltipText="" outgoingEdges="_87FABuo4Eeusl77uIP-YcQ" incomingEdges="_865Z0Oo4Eeusl77uIP-YcQ" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Metadata"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Metadata"/>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_86E6cOo4Eeusl77uIP-YcQ" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_86GIkOo4Eeusl77uIP-YcQ" name="NamedElement" tooltipText="" incomingEdges="_87CjwOo4Eeusl77uIP-YcQ _87EY8Oo4Eeusl77uIP-YcQ _87HcRuo4Eeusl77uIP-YcQ _87IqZ-o4Eeusl77uIP-YcQ _87J4huo4Eeusl77uIP-YcQ" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//NamedElement"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//NamedElement"/>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_86GvoOo4Eeusl77uIP-YcQ" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_86rXYOo4Eeusl77uIP-YcQ" name="name : EString" tooltipText="">
+        <target xmi:type="ecore:EAttribute" href="resource.ecore#//NamedElement/name"/>
+        <semanticElements xmi:type="ecore:EAttribute" href="resource.ecore#//NamedElement/name"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_86r-cOo4Eeusl77uIP-YcQ" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']"/>
+      </ownedElements>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_86HWseo4Eeusl77uIP-YcQ" name="Parameter" tooltipText="" outgoingEdges="_87GOIOo4Eeusl77uIP-YcQ" incomingEdges="_861IYOo4Eeusl77uIP-YcQ" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Parameter"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Parameter"/>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_86H9wOo4Eeusl77uIP-YcQ" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_86Ik0eo4Eeusl77uIP-YcQ" name="Property" tooltipText="" outgoingEdges="_87G1Nuo4Eeusl77uIP-YcQ" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Property"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Property"/>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_86JL4Oo4Eeusl77uIP-YcQ" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_86Jy8eo4Eeusl77uIP-YcQ" name="Resource" tooltipText="&#xA;WARNING : This GenModel annotation will ignore its references" outgoingEdges="_863koOo4Eeusl77uIP-YcQ _864Ltuo4Eeusl77uIP-YcQ _87HcRuo4Eeusl77uIP-YcQ" incomingEdges="_867PBuo4Eeusl77uIP-YcQ _869rQOo4Eeusl77uIP-YcQ _87G1Nuo4Eeusl77uIP-YcQ _87IqYOo4Eeusl77uIP-YcQ _87JRduo4Eeusl77uIP-YcQ" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Resource"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Resource"/>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_86MPMOo4Eeusl77uIP-YcQ" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_86slgOo4Eeusl77uIP-YcQ" name="friendlyName : EString" tooltipText="">
+        <target xmi:type="ecore:EAttribute" href="resource.ecore#//Resource/friendlyName"/>
+        <semanticElements xmi:type="ecore:EAttribute" href="resource.ecore#//Resource/friendlyName"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_86tMkOo4Eeusl77uIP-YcQ" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']"/>
+      </ownedElements>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_86tMkeo4Eeusl77uIP-YcQ" name="getAccessMethod(type AccessMethodType) : AccessMethod" tooltipText="getAccessMethod(type) : AccessMethod">
+        <target xmi:type="ecore:EOperation" href="resource.ecore#//Resource/getAccessMethod"/>
+        <semanticElements xmi:type="ecore:EOperation" href="resource.ecore#//Resource/getAccessMethod"/>
+        <semanticElements xmi:type="ecore:EParameter" href="resource.ecore#//Resource/getAccessMethod/type"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_86uasOo4Eeusl77uIP-YcQ" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='Operation']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='Operation']"/>
+      </ownedElements>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_86M2Qeo4Eeusl77uIP-YcQ" name="SensorData" tooltipText="" outgoingEdges="_87IqYOo4Eeusl77uIP-YcQ" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//SensorData"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//SensorData"/>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_86NdUOo4Eeusl77uIP-YcQ" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_86OrcOo4Eeusl77uIP-YcQ" name="Service" tooltipText="" outgoingEdges="_867PBuo4Eeusl77uIP-YcQ _87IqZ-o4Eeusl77uIP-YcQ" incomingEdges="_866A4-o4Eeusl77uIP-YcQ" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Service"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Service"/>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_86PSgOo4Eeusl77uIP-YcQ" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_86vBwOo4Eeusl77uIP-YcQ" name="friendlyName : EString" tooltipText="">
+        <target xmi:type="ecore:EAttribute" href="resource.ecore#//Service/friendlyName"/>
+        <semanticElements xmi:type="ecore:EAttribute" href="resource.ecore#//Service/friendlyName"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_86vBweo4Eeusl77uIP-YcQ" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']"/>
+      </ownedElements>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_86P5kOo4Eeusl77uIP-YcQ" name="StateVariable" tooltipText="" outgoingEdges="_87JRduo4Eeusl77uIP-YcQ" incomingEdges="_87Kfk-o4Eeusl77uIP-YcQ" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//StateVariable"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//StateVariable"/>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_86QgoOo4Eeusl77uIP-YcQ" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_86SV0Oo4Eeusl77uIP-YcQ" name="Studio" tooltipText="" outgoingEdges="_868dIOo4Eeusl77uIP-YcQ" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Studio"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Studio"/>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_86SV0eo4Eeusl77uIP-YcQ" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_86Tj8Oo4Eeusl77uIP-YcQ" name="TypedElement" tooltipText="" outgoingEdges="_87J4huo4Eeusl77uIP-YcQ" incomingEdges="_87Auk-o4Eeusl77uIP-YcQ _87FABuo4Eeusl77uIP-YcQ _87GOIOo4Eeusl77uIP-YcQ" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//TypedElement"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//TypedElement"/>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_86UyEOo4Eeusl77uIP-YcQ" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_86vo0Oo4Eeusl77uIP-YcQ" name="type : EString" tooltipText="">
+        <target xmi:type="ecore:EAttribute" href="resource.ecore#//TypedElement/type"/>
+        <semanticElements xmi:type="ecore:EAttribute" href="resource.ecore#//TypedElement/type"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_86wP4Oo4Eeusl77uIP-YcQ" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']"/>
+      </ownedElements>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_86wP4eo4Eeusl77uIP-YcQ" name="value : EString" tooltipText="">
+        <target xmi:type="ecore:EAttribute" href="resource.ecore#//TypedElement/value"/>
+        <semanticElements xmi:type="ecore:EAttribute" href="resource.ecore#//TypedElement/value"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_86w28Oo4Eeusl77uIP-YcQ" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']"/>
+      </ownedElements>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_861IYOo4Eeusl77uIP-YcQ" name="[0..*] parameter" sourceNode="_85z0sOo4Eeusl77uIP-YcQ" targetNode="_86HWseo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EReference" href="resource.ecore#//AccessMethod/parameter"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//AccessMethod/parameter"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_8629k-o4Eeusl77uIP-YcQ" description="_8629kOo4Eeusl77uIP-YcQ" sourceArrow="FillDiamond" routingStyle="manhattan" strokeColor="0,0,0">
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_8629leo4Eeusl77uIP-YcQ" showIcon="false">
+          <customFeatures>labelSize</customFeatures>
+        </centerLabelStyle>
+        <endLabelStyle xmi:type="diagram:EndLabelStyle" uid="_8629lOo4Eeusl77uIP-YcQ" showIcon="false" labelColor="39,76,114">
+          <customFeatures>labelSize</customFeatures>
+        </endLabelStyle>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC_EReference']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_863koOo4Eeusl77uIP-YcQ" name="[0..*] attribute" sourceNode="_86Jy8eo4Eeusl77uIP-YcQ" targetNode="_85_a4Oo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EReference" href="resource.ecore#//Resource/attribute"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//Resource/attribute"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_864LsOo4Eeusl77uIP-YcQ" description="_8629kOo4Eeusl77uIP-YcQ" sourceArrow="FillDiamond" routingStyle="manhattan" strokeColor="0,0,0">
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_864Lsuo4Eeusl77uIP-YcQ" showIcon="false">
+          <customFeatures>labelSize</customFeatures>
+        </centerLabelStyle>
+        <endLabelStyle xmi:type="diagram:EndLabelStyle" uid="_864Lseo4Eeusl77uIP-YcQ" showIcon="false" labelColor="39,76,114">
+          <customFeatures>labelSize</customFeatures>
+        </endLabelStyle>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC_EReference']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_864Ltuo4Eeusl77uIP-YcQ" name="[0..*] accessMethod" sourceNode="_86Jy8eo4Eeusl77uIP-YcQ" targetNode="_85z0sOo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EReference" href="resource.ecore#//Resource/accessMethod"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//Resource/accessMethod"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_864ywOo4Eeusl77uIP-YcQ" description="_8629kOo4Eeusl77uIP-YcQ" sourceArrow="FillDiamond" routingStyle="manhattan" strokeColor="0,0,0">
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_864ywuo4Eeusl77uIP-YcQ" showIcon="false">
+          <customFeatures>labelSize</customFeatures>
+        </centerLabelStyle>
+        <endLabelStyle xmi:type="diagram:EndLabelStyle" uid="_864yweo4Eeusl77uIP-YcQ" showIcon="false" labelColor="39,76,114">
+          <customFeatures>labelSize</customFeatures>
+        </endLabelStyle>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC_EReference']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_865Z0Oo4Eeusl77uIP-YcQ" name="[0..*] metadata" sourceNode="_85_a4Oo4Eeusl77uIP-YcQ" targetNode="_86ETYOo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EReference" href="resource.ecore#//Attribute/metadata"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//Attribute/metadata"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_865Z0eo4Eeusl77uIP-YcQ" description="_8629kOo4Eeusl77uIP-YcQ" sourceArrow="FillDiamond" routingStyle="manhattan" strokeColor="0,0,0">
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_865Z0-o4Eeusl77uIP-YcQ" showIcon="false">
+          <customFeatures>labelSize</customFeatures>
+        </centerLabelStyle>
+        <endLabelStyle xmi:type="diagram:EndLabelStyle" uid="_865Z0uo4Eeusl77uIP-YcQ" showIcon="false" labelColor="39,76,114">
+          <customFeatures>labelSize</customFeatures>
+        </endLabelStyle>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC_EReference']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_866A4-o4Eeusl77uIP-YcQ" name="[0..*] service" sourceNode="_86ApAOo4Eeusl77uIP-YcQ" targetNode="_86OrcOo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EReference" href="resource.ecore#//Device/service"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//Device/service"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_866n8Oo4Eeusl77uIP-YcQ" description="_8629kOo4Eeusl77uIP-YcQ" sourceArrow="FillDiamond" routingStyle="manhattan" strokeColor="0,0,0">
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_866n8uo4Eeusl77uIP-YcQ" showIcon="false">
+          <customFeatures>labelSize</customFeatures>
+        </centerLabelStyle>
+        <endLabelStyle xmi:type="diagram:EndLabelStyle" uid="_866n8eo4Eeusl77uIP-YcQ" showIcon="false" labelColor="39,76,114">
+          <customFeatures>labelSize</customFeatures>
+        </endLabelStyle>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC_EReference']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_866n9uo4Eeusl77uIP-YcQ" name="[0..*] device" sourceNode="_86CeMOo4Eeusl77uIP-YcQ" targetNode="_86ApAOo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EReference" href="resource.ecore#//Gateway/device"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//Gateway/device"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_867PAOo4Eeusl77uIP-YcQ" description="_8629kOo4Eeusl77uIP-YcQ" sourceArrow="FillDiamond" routingStyle="manhattan" strokeColor="0,0,0">
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_867PAuo4Eeusl77uIP-YcQ" showIcon="false">
+          <customFeatures>labelSize</customFeatures>
+        </centerLabelStyle>
+        <endLabelStyle xmi:type="diagram:EndLabelStyle" uid="_867PAeo4Eeusl77uIP-YcQ" showIcon="false" labelColor="39,76,114">
+          <customFeatures>labelSize</customFeatures>
+        </endLabelStyle>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC_EReference']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_867PBuo4Eeusl77uIP-YcQ" name="[0..*] resource" sourceNode="_86OrcOo4Eeusl77uIP-YcQ" targetNode="_86Jy8eo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EReference" href="resource.ecore#//Service/resource"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//Service/resource"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_8672EOo4Eeusl77uIP-YcQ" description="_8629kOo4Eeusl77uIP-YcQ" sourceArrow="FillDiamond" routingStyle="manhattan" strokeColor="0,0,0">
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_8672Euo4Eeusl77uIP-YcQ" showIcon="false">
+          <customFeatures>labelSize</customFeatures>
+        </centerLabelStyle>
+        <endLabelStyle xmi:type="diagram:EndLabelStyle" uid="_8672Eeo4Eeusl77uIP-YcQ" showIcon="false" labelColor="39,76,114">
+          <customFeatures>labelSize</customFeatures>
+        </endLabelStyle>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC_EReference']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_868dIOo4Eeusl77uIP-YcQ" name="[0..*] gateways" sourceNode="_86SV0Oo4Eeusl77uIP-YcQ" targetNode="_86CeMOo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EReference" href="resource.ecore#//Studio/gateways"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//Studio/gateways"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_869EMOo4Eeusl77uIP-YcQ" description="_8629kOo4Eeusl77uIP-YcQ" sourceArrow="FillDiamond" routingStyle="manhattan" strokeColor="0,0,0">
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_869EMuo4Eeusl77uIP-YcQ" showIcon="false">
+          <customFeatures>labelSize</customFeatures>
+        </centerLabelStyle>
+        <endLabelStyle xmi:type="diagram:EndLabelStyle" uid="_869EMeo4Eeusl77uIP-YcQ" showIcon="false" labelColor="39,76,114">
+          <customFeatures>labelSize</customFeatures>
+        </endLabelStyle>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC_EReference']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_869rQOo4Eeusl77uIP-YcQ" sourceNode="_859lseo4Eeusl77uIP-YcQ" targetNode="_86Jy8eo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Action"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Action"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_87AHgOo4Eeusl77uIP-YcQ" targetArrow="InputClosedArrow" routingStyle="tree">
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_87AHgeo4Eeusl77uIP-YcQ" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_87AHguo4Eeusl77uIP-YcQ" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_87Auk-o4Eeusl77uIP-YcQ" sourceNode="_85_a4Oo4Eeusl77uIP-YcQ" targetNode="_86Tj8Oo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Attribute"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Attribute"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_87B8sOo4Eeusl77uIP-YcQ" targetArrow="InputClosedArrow" routingStyle="tree">
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_87B8seo4Eeusl77uIP-YcQ" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_87B8suo4Eeusl77uIP-YcQ" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_87CjwOo4Eeusl77uIP-YcQ" sourceNode="_86ApAOo4Eeusl77uIP-YcQ" targetNode="_86GIkOo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Device"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Device"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_87Dx4Oo4Eeusl77uIP-YcQ" targetArrow="InputClosedArrow" routingStyle="tree">
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_87Dx4eo4Eeusl77uIP-YcQ" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_87Dx4uo4Eeusl77uIP-YcQ" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_87EY8Oo4Eeusl77uIP-YcQ" sourceNode="_86CeMOo4Eeusl77uIP-YcQ" targetNode="_86GIkOo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Gateway"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Gateway"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_87FAAOo4Eeusl77uIP-YcQ" targetArrow="InputClosedArrow" routingStyle="tree">
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_87FAAeo4Eeusl77uIP-YcQ" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_87FAAuo4Eeusl77uIP-YcQ" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_87FABuo4Eeusl77uIP-YcQ" sourceNode="_86ETYOo4Eeusl77uIP-YcQ" targetNode="_86Tj8Oo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Metadata"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Metadata"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_87FnEOo4Eeusl77uIP-YcQ" targetArrow="InputClosedArrow" routingStyle="tree">
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_87FnEeo4Eeusl77uIP-YcQ" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_87FnEuo4Eeusl77uIP-YcQ" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_87GOIOo4Eeusl77uIP-YcQ" sourceNode="_86HWseo4Eeusl77uIP-YcQ" targetNode="_86Tj8Oo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Parameter"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Parameter"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_87G1MOo4Eeusl77uIP-YcQ" targetArrow="InputClosedArrow" routingStyle="tree">
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_87G1Meo4Eeusl77uIP-YcQ" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_87G1Muo4Eeusl77uIP-YcQ" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_87G1Nuo4Eeusl77uIP-YcQ" sourceNode="_86Ik0eo4Eeusl77uIP-YcQ" targetNode="_86Jy8eo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Property"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Property"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_87HcQOo4Eeusl77uIP-YcQ" targetArrow="InputClosedArrow" routingStyle="tree">
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_87HcQeo4Eeusl77uIP-YcQ" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_87HcQuo4Eeusl77uIP-YcQ" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_87HcRuo4Eeusl77uIP-YcQ" sourceNode="_86Jy8eo4Eeusl77uIP-YcQ" targetNode="_86GIkOo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Resource"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Resource"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_87IDUOo4Eeusl77uIP-YcQ" targetArrow="InputClosedArrow" routingStyle="tree">
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_87IDUeo4Eeusl77uIP-YcQ" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_87IDUuo4Eeusl77uIP-YcQ" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_87IqYOo4Eeusl77uIP-YcQ" sourceNode="_86M2Qeo4Eeusl77uIP-YcQ" targetNode="_86Jy8eo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//SensorData"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//SensorData"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_87IqYeo4Eeusl77uIP-YcQ" targetArrow="InputClosedArrow" routingStyle="tree">
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_87IqYuo4Eeusl77uIP-YcQ" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_87IqY-o4Eeusl77uIP-YcQ" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_87IqZ-o4Eeusl77uIP-YcQ" sourceNode="_86OrcOo4Eeusl77uIP-YcQ" targetNode="_86GIkOo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Service"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Service"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_87JRcOo4Eeusl77uIP-YcQ" targetArrow="InputClosedArrow" routingStyle="tree">
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_87JRceo4Eeusl77uIP-YcQ" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_87JRcuo4Eeusl77uIP-YcQ" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_87JRduo4Eeusl77uIP-YcQ" sourceNode="_86P5kOo4Eeusl77uIP-YcQ" targetNode="_86Jy8eo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//StateVariable"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//StateVariable"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_87J4gOo4Eeusl77uIP-YcQ" targetArrow="InputClosedArrow" routingStyle="tree">
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_87J4geo4Eeusl77uIP-YcQ" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_87J4guo4Eeusl77uIP-YcQ" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_87J4huo4Eeusl77uIP-YcQ" sourceNode="_86Tj8Oo4Eeusl77uIP-YcQ" targetNode="_86GIkOo4Eeusl77uIP-YcQ">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//TypedElement"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//TypedElement"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_87J4h-o4Eeusl77uIP-YcQ" targetArrow="InputClosedArrow" routingStyle="tree">
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_87J4iOo4Eeusl77uIP-YcQ" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_87J4ieo4Eeusl77uIP-YcQ" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_87Kfk-o4Eeusl77uIP-YcQ" sourceNode="_859lseo4Eeusl77uIP-YcQ" targetNode="_86P5kOo4Eeusl77uIP-YcQ" beginLabel="[0..*] modifier" endLabel="[0..*] state">
+      <target xmi:type="ecore:EReference" href="resource.ecore#//Action/state"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//StateVariable/modifier"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//Action/state"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_87LGoOo4Eeusl77uIP-YcQ" sourceArrow="InputArrow" routingStyle="manhattan" strokeColor="0,0,0">
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='Bi-directional%20EC_EReference%20']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_87LGoeo4Eeusl77uIP-YcQ" showIcon="false"/>
+        <endLabelStyle xmi:type="diagram:EndLabelStyle" uid="_87LGouo4Eeusl77uIP-YcQ" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='Bi-directional%20EC_EReference%20']"/>
+    </ownedDiagramElements>
+    <description xmi:type="description_1:DiagramDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']"/>
+    <filterVariableHistory xmi:type="diagram:FilterVariableHistory" uid="_5YZVhZKFEeW9FdUPGRS2og"/>
+    <activatedLayers xmi:type="description_1:Layer" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer"/>
+    <activatedLayers xmi:type="description_1:AdditionalLayer" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@additionalLayers[name='Package']"/>
+    <activatedLayers xmi:type="description_1:AdditionalLayer" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@additionalLayers[name='Validation']"/>
+    <activatedLayers xmi:type="description_1:AdditionalLayer" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Archetype']/@ownedRepresentationExtensions[name='Entities%20With%20Archetypes']/@layers[name='Archetypes']"/>
+    <target xmi:type="ecore:EPackage" href="resource.ecore#/"/>
+  </diagram:DSemanticDiagram>
+  <diagram:DSemanticDiagram uid="_77Gi0JKFEeW9FdUPGRS2og">
+    <ownedAnnotationEntries xmi:type="description:AnnotationEntry" uid="_77Gi1pKFEeW9FdUPGRS2og" source="GMF_DIAGRAMS">
+      <data xmi:type="notation:Diagram" xmi:id="_77Gi15KFEeW9FdUPGRS2og" type="Sirius" element="_77Gi0JKFEeW9FdUPGRS2og" measurementUnit="Pixel">
+        <children xmi:type="notation:Node" xmi:id="_77HJ4JKFEeW9FdUPGRS2og" type="2001" element="_77Gi0ZKFEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_77HJ45KFEeW9FdUPGRS2og" type="5002">
+            <layoutConstraint xmi:type="notation:Location" xmi:id="_77HJ5JKFEeW9FdUPGRS2og" y="5"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_77Hw8JKFEeW9FdUPGRS2og" type="3005" element="_77Gi0pKFEeW9FdUPGRS2og">
+            <styles xmi:type="notation:ShapeStyle" xmi:id="_77Hw8ZKFEeW9FdUPGRS2og" fontName="Cantarell"/>
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_77Hw8pKFEeW9FdUPGRS2og"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_77HJ4ZKFEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_77HJ4pKFEeW9FdUPGRS2og" width="672" height="67"/>
+        </children>
+        <styles xmi:type="notation:DiagramStyle" xmi:id="_77Gi2JKFEeW9FdUPGRS2og"/>
+      </data>
+    </ownedAnnotationEntries>
+    <ownedAnnotationEntries xmi:type="description:AnnotationEntry" uid="_2P5hcOo4Eeusl77uIP-YcQ" source="DANNOTATION_CUSTOMIZATION_KEY">
+      <data xmi:type="diagram:ComputedStyleDescriptionRegistry" uid="_2P5hceo4Eeusl77uIP-YcQ"/>
+    </ownedAnnotationEntries>
+    <ownedDiagramElements xmi:type="diagram:DNode" uid="_77Gi0ZKFEeW9FdUPGRS2og" width="-1" height="-1">
+      <target xmi:type="ecore:EPackage" href="http://www.eclipse.org/emf/2002/Ecore#/"/>
+      <semanticElements xmi:type="ecore:EPackage" href="http://www.eclipse.org/emf/2002/Ecore#/"/>
+      <ownedStyle xmi:type="diagram:WorkspaceImage" uid="_77Gi0pKFEeW9FdUPGRS2og" showIcon="false" labelPosition="node" workspacePath="/org.eclipse.emf.ecoretools.design/icons/full/back/empty.svg">
+        <description xmi:type="style:WorkspaceImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@nodeMappings[name='Empty%20Diagram']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@nodeMappings[name='Empty%20Diagram']"/>
+    </ownedDiagramElements>
+    <description xmi:type="description_1:DiagramDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']"/>
+    <filterVariableHistory xmi:type="diagram:FilterVariableHistory" uid="_77Gi1ZKFEeW9FdUPGRS2og"/>
+    <activatedLayers xmi:type="description_1:Layer" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer"/>
+    <activatedLayers xmi:type="description_1:AdditionalLayer" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@additionalLayers[name='Package']"/>
+    <activatedLayers xmi:type="description_1:AdditionalLayer" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@additionalLayers[name='Validation']"/>
+    <activatedLayers xmi:type="description_1:AdditionalLayer" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Archetype']/@ownedRepresentationExtensions[name='Entities%20With%20Archetypes']/@layers[name='Archetypes']"/>
+    <target xmi:type="ecore:EPackage" href="http://www.eclipse.org/emf/2002/Ecore#/"/>
+  </diagram:DSemanticDiagram>
+  <diagram:DSemanticDiagram uid="_IOoJ8JKGEeW9FdUPGRS2og">
+    <ownedAnnotationEntries xmi:type="description:AnnotationEntry" uid="_IOoxAJKGEeW9FdUPGRS2og" source="GMF_DIAGRAMS">
+      <data xmi:type="notation:Diagram" xmi:id="_IOoxAZKGEeW9FdUPGRS2og" type="Sirius" element="_IOoJ8JKGEeW9FdUPGRS2og" measurementUnit="Pixel">
+        <children xmi:type="notation:Node" xmi:id="_M_QnYJKGEeW9FdUPGRS2og" type="2003" element="_M8r0gJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_R1gJKGEeW9FdUPGRS2og" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_M_TqsJKGEeW9FdUPGRS2og" type="7004">
+            <children xmi:type="notation:Node" xmi:id="_M_hGEJKGEeW9FdUPGRS2og" type="3010" element="_M-E7oJKGEeW9FdUPGRS2og">
+              <styles xmi:type="notation:FontStyle" xmi:id="_2QUYMOo4Eeusl77uIP-YcQ"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_M_hGEZKGEeW9FdUPGRS2og"/>
+            </children>
+            <styles xmi:type="notation:SortingStyle" xmi:id="_M_TqsZKGEeW9FdUPGRS2og"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_M_TqspKGEeW9FdUPGRS2og"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_M_QnYZKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_QnYpKGEeW9FdUPGRS2og" x="960" y="190"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_M_U40JKGEeW9FdUPGRS2og" type="2003" element="_M80XYJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_U405KGEeW9FdUPGRS2og" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_M_Vf4JKGEeW9FdUPGRS2og" type="7004">
+            <children xmi:type="notation:Node" xmi:id="_M_htIJKGEeW9FdUPGRS2og" type="3010" element="_M-TlIJKGEeW9FdUPGRS2og">
+              <styles xmi:type="notation:FontStyle" xmi:id="_2QUYMeo4Eeusl77uIP-YcQ"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_M_htIZKGEeW9FdUPGRS2og"/>
+            </children>
+            <children xmi:type="notation:Node" xmi:id="_M_htIpKGEeW9FdUPGRS2og" type="3010" element="_M-UzQJKGEeW9FdUPGRS2og">
+              <styles xmi:type="notation:FontStyle" xmi:id="_2QUYMuo4Eeusl77uIP-YcQ"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_M_htI5KGEeW9FdUPGRS2og"/>
+            </children>
+            <children xmi:type="notation:Node" xmi:id="_M_htJJKGEeW9FdUPGRS2og" type="3010" element="_M-VaUJKGEeW9FdUPGRS2og">
+              <styles xmi:type="notation:FontStyle" xmi:id="_2QUYM-o4Eeusl77uIP-YcQ"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_M_htJZKGEeW9FdUPGRS2og"/>
+            </children>
+            <children xmi:type="notation:Node" xmi:id="_M_iUMJKGEeW9FdUPGRS2og" type="3010" element="_M-WBYJKGEeW9FdUPGRS2og">
+              <styles xmi:type="notation:FontStyle" xmi:id="_2QUYNOo4Eeusl77uIP-YcQ"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_M_iUMZKGEeW9FdUPGRS2og"/>
+            </children>
+            <children xmi:type="notation:Node" xmi:id="_M_iUMpKGEeW9FdUPGRS2og" type="3010" element="_M-WocJKGEeW9FdUPGRS2og">
+              <styles xmi:type="notation:FontStyle" xmi:id="_2QUYNeo4Eeusl77uIP-YcQ"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_M_iUM5KGEeW9FdUPGRS2og"/>
+            </children>
+            <styles xmi:type="notation:SortingStyle" xmi:id="_M_Vf4ZKGEeW9FdUPGRS2og"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_M_Vf4pKGEeW9FdUPGRS2og"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_M_U40ZKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_U40pKGEeW9FdUPGRS2og" x="1025" y="65"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_M_Vf45KGEeW9FdUPGRS2og" type="2003" element="_M82zoJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_WG8JKGEeW9FdUPGRS2og" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_M_WG8ZKGEeW9FdUPGRS2og" type="7004">
+            <styles xmi:type="notation:SortingStyle" xmi:id="_M_WG8pKGEeW9FdUPGRS2og"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_M_WG85KGEeW9FdUPGRS2og"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_M_Vf5JKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_Vf5ZKGEeW9FdUPGRS2og" x="465" y="740"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_M_WG9JKGEeW9FdUPGRS2og" type="2003" element="_M8528JKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_WuAJKGEeW9FdUPGRS2og" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_M_WuAZKGEeW9FdUPGRS2og" type="7004">
+            <styles xmi:type="notation:SortingStyle" xmi:id="_M_WuApKGEeW9FdUPGRS2og"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_M_WuA5KGEeW9FdUPGRS2og"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_M_WG9ZKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_WG9pKGEeW9FdUPGRS2og" x="1495" y="380"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_M_XVEJKGEeW9FdUPGRS2og" type="2003" element="_M886QJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_X8IJKGEeW9FdUPGRS2og" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_M_X8IZKGEeW9FdUPGRS2og" type="7004">
+            <children xmi:type="notation:Node" xmi:id="_M_i7QJKGEeW9FdUPGRS2og" type="3010" element="_M-ImAJKGEeW9FdUPGRS2og">
+              <styles xmi:type="notation:FontStyle" xmi:id="_2QUYNuo4Eeusl77uIP-YcQ"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_M_i7QZKGEeW9FdUPGRS2og"/>
+            </children>
+            <styles xmi:type="notation:SortingStyle" xmi:id="_M_X8IpKGEeW9FdUPGRS2og"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_M_X8I5KGEeW9FdUPGRS2og"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_M_XVEZKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_XVEpKGEeW9FdUPGRS2og" x="280" y="380"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_M_YjMJKGEeW9FdUPGRS2og" type="2003" element="_M8_WgJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_ZKQJKGEeW9FdUPGRS2og" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_M_ZKQZKGEeW9FdUPGRS2og" type="7004">
+            <styles xmi:type="notation:SortingStyle" xmi:id="_M_ZKQpKGEeW9FdUPGRS2og"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_M_ZKQ5KGEeW9FdUPGRS2og"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_M_YjMZKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_YjMpKGEeW9FdUPGRS2og" x="-190" y="375"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_M_ZKRJKGEeW9FdUPGRS2og" type="2003" element="_M9BywJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_ZxUJKGEeW9FdUPGRS2og" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_M_ZxUZKGEeW9FdUPGRS2og" type="7004">
+            <styles xmi:type="notation:SortingStyle" xmi:id="_M_ZxUpKGEeW9FdUPGRS2og"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_M_ZxU5KGEeW9FdUPGRS2og"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_M_ZKRZKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_ZKRpKGEeW9FdUPGRS2og" x="1875" y="370"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_M_ZxVJKGEeW9FdUPGRS2og" type="2003" element="_M9EPAJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_aYYJKGEeW9FdUPGRS2og" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_M_aYYZKGEeW9FdUPGRS2og" type="7004">
+            <children xmi:type="notation:Node" xmi:id="_M_jiUJKGEeW9FdUPGRS2og" type="3010" element="_M-KbMJKGEeW9FdUPGRS2og">
+              <styles xmi:type="notation:FontStyle" xmi:id="_2QUYN-o4Eeusl77uIP-YcQ"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_M_jiUZKGEeW9FdUPGRS2og"/>
+            </children>
+            <styles xmi:type="notation:SortingStyle" xmi:id="_M_aYYpKGEeW9FdUPGRS2og"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_M_aYY5KGEeW9FdUPGRS2og"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_M_ZxVZKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_ZxVpKGEeW9FdUPGRS2og" x="505" y="-255"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_M_a_cJKGEeW9FdUPGRS2og" type="2003" element="_M9GrQJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_a_c5KGEeW9FdUPGRS2og" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_M_bmgJKGEeW9FdUPGRS2og" type="7004">
+            <styles xmi:type="notation:SortingStyle" xmi:id="_M_bmgZKGEeW9FdUPGRS2og"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_M_bmgpKGEeW9FdUPGRS2og"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_M_a_cZKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_a_cpKGEeW9FdUPGRS2og" x="1370" y="195"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_M_bmg5KGEeW9FdUPGRS2og" type="2003" element="_M9JHgJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_cNkJKGEeW9FdUPGRS2og" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_M_cNkZKGEeW9FdUPGRS2og" type="7004">
+            <styles xmi:type="notation:SortingStyle" xmi:id="_M_cNkpKGEeW9FdUPGRS2og"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_M_cNk5KGEeW9FdUPGRS2og"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_M_bmhJKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_bmhZKGEeW9FdUPGRS2og" x="860" y="740"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_M_cNlJKGEeW9FdUPGRS2og" type="2003" element="_M9LjwJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_c0oJKGEeW9FdUPGRS2og" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_M_c0oZKGEeW9FdUPGRS2og" type="7004">
+            <children xmi:type="notation:Node" xmi:id="_M_jiUpKGEeW9FdUPGRS2og" type="3010" element="_M-MQYJKGEeW9FdUPGRS2og">
+              <styles xmi:type="notation:FontStyle" xmi:id="_2QUYOOo4Eeusl77uIP-YcQ"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_M_jiU5KGEeW9FdUPGRS2og"/>
+            </children>
+            <children xmi:type="notation:Node" xmi:id="_M_kJYJKGEeW9FdUPGRS2og" type="3010" element="_M-NegJKGEeW9FdUPGRS2og">
+              <styles xmi:type="notation:FontStyle" xmi:id="_2QUYOeo4Eeusl77uIP-YcQ"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_M_kJYZKGEeW9FdUPGRS2og"/>
+            </children>
+            <styles xmi:type="notation:SortingStyle" xmi:id="_M_c0opKGEeW9FdUPGRS2og"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_M_c0o5KGEeW9FdUPGRS2og"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_M_cNlZKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_cNlpKGEeW9FdUPGRS2og" x="730" y="390"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_M_dbsJKGEeW9FdUPGRS2og" type="2003" element="_M9OAAJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_dbs5KGEeW9FdUPGRS2og" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_M_eCwJKGEeW9FdUPGRS2og" type="7004">
+            <styles xmi:type="notation:SortingStyle" xmi:id="_M_eCwZKGEeW9FdUPGRS2og"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_M_eCwpKGEeW9FdUPGRS2og"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_M_dbsZKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_dbspKGEeW9FdUPGRS2og" x="995" y="740"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_M_eCw5KGEeW9FdUPGRS2og" type="2003" element="_M9QcQJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_ep0JKGEeW9FdUPGRS2og" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_M_ep0ZKGEeW9FdUPGRS2og" type="7004">
+            <children xmi:type="notation:Node" xmi:id="_M_kJYpKGEeW9FdUPGRS2og" type="3010" element="_M-P6wJKGEeW9FdUPGRS2og">
+              <styles xmi:type="notation:FontStyle" xmi:id="_2QUYOuo4Eeusl77uIP-YcQ"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_M_kJY5KGEeW9FdUPGRS2og"/>
+            </children>
+            <styles xmi:type="notation:SortingStyle" xmi:id="_M_ep0pKGEeW9FdUPGRS2og"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_M_ep05KGEeW9FdUPGRS2og"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_M_eCxJKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_eCxZKGEeW9FdUPGRS2og" x="515" y="385"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_M_ep1JKGEeW9FdUPGRS2og" type="2003" element="_M9SRcJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_fQ4JKGEeW9FdUPGRS2og" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_M_fQ4ZKGEeW9FdUPGRS2og" type="7004">
+            <styles xmi:type="notation:SortingStyle" xmi:id="_M_fQ4pKGEeW9FdUPGRS2og"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_M_fQ45KGEeW9FdUPGRS2og"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_M_ep1ZKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_ep1pKGEeW9FdUPGRS2og" x="730" y="740"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_M_f38JKGEeW9FdUPGRS2og" type="2003" element="_M9VUwJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_f385KGEeW9FdUPGRS2og" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_M_f39JKGEeW9FdUPGRS2og" type="7004">
+            <children xmi:type="notation:Node" xmi:id="_M_kwcJKGEeW9FdUPGRS2og" type="3010" element="_M-RI4JKGEeW9FdUPGRS2og">
+              <styles xmi:type="notation:FontStyle" xmi:id="_2QUYO-o4Eeusl77uIP-YcQ"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_M_kwcZKGEeW9FdUPGRS2og"/>
+            </children>
+            <children xmi:type="notation:Node" xmi:id="_M_kwcpKGEeW9FdUPGRS2og" type="3010" element="_M-SXAJKGEeW9FdUPGRS2og">
+              <styles xmi:type="notation:FontStyle" xmi:id="_2QUYPOo4Eeusl77uIP-YcQ"/>
+              <layoutConstraint xmi:type="notation:Location" xmi:id="_M_kwc5KGEeW9FdUPGRS2og"/>
+            </children>
+            <styles xmi:type="notation:SortingStyle" xmi:id="_M_f39ZKGEeW9FdUPGRS2og"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_M_f39pKGEeW9FdUPGRS2og"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_M_f38ZKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_f38pKGEeW9FdUPGRS2og" x="1485" y="-255"/>
+        </children>
+        <children xmi:type="notation:Node" xmi:id="_V0JSgJKIEeW9FdUPGRS2og" type="2003" element="_VzDGUJKIEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_V0KgoJKIEeW9FdUPGRS2og" type="5007"/>
+          <children xmi:type="notation:Node" xmi:id="_V0KgoZKIEeW9FdUPGRS2og" type="7004">
+            <styles xmi:type="notation:SortingStyle" xmi:id="_V0KgopKIEeW9FdUPGRS2og"/>
+            <styles xmi:type="notation:FilteringStyle" xmi:id="_V0Kgo5KIEeW9FdUPGRS2og"/>
+          </children>
+          <styles xmi:type="notation:ShapeStyle" xmi:id="_V0JSgZKIEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <layoutConstraint xmi:type="notation:Bounds" xmi:id="_V0J5kJKIEeW9FdUPGRS2og" x="65" y="375" width="120" height="100"/>
+        </children>
+        <styles xmi:type="notation:DiagramStyle" xmi:id="_IOoxApKGEeW9FdUPGRS2og"/>
+        <edges xmi:type="notation:Edge" xmi:id="_M_q3EJKGEeW9FdUPGRS2og" type="4001" element="_M-d9MJKGEeW9FdUPGRS2og" source="_M_QnYJKGEeW9FdUPGRS2og" target="_M_a_cJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_sFMJKGEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_sFMZKGEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_M_ssQJKGEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_ssQZKGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_M_ssQpKGEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_ssQ5KGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_M_q3EZKGEeW9FdUPGRS2og" routing="Rectilinear" jumpLinkStatus="Above"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_M_q3EpKGEeW9FdUPGRS2og" fontColor="7490599" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_M_q3E5KGEeW9FdUPGRS2og" points="[920, 194, 920, 194]$[1160, 434, 1160, 434]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_M_yy4JKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_M_yy4ZKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_M_zZ8JKGEeW9FdUPGRS2og" type="4001" element="_M-jcwJKGEeW9FdUPGRS2og" source="_M_cNlJKGEeW9FdUPGRS2og" target="_M_WG9JKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_0BAJKGEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_0BAZKGEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_M_0BApKGEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_0BA5KGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_M_0BBJKGEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_0BBZKGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_M_zZ8ZKGEeW9FdUPGRS2og" routing="Rectilinear" jumpLinkStatus="Above"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_M_zZ8pKGEeW9FdUPGRS2og" fontColor="7490599" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_M_zZ85KGEeW9FdUPGRS2og" points="[1220, 494, 1220, 494]$[1010, 284, 1010, 284]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_M_0oEJKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_M_0oEZKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_M_0oEpKGEeW9FdUPGRS2og" type="4001" element="_M-lR8JKGEeW9FdUPGRS2og" source="_M_cNlJKGEeW9FdUPGRS2og" target="_M_QnYJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_1PIJKGEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_1PIZKGEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_M_1PIpKGEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_1PI5KGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_M_1PJJKGEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_1PJZKGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_M_0oE5KGEeW9FdUPGRS2og" routing="Rectilinear" jumpLinkStatus="Above"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_M_0oFJKGEeW9FdUPGRS2og" fontColor="7490599" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_M_0oFZKGEeW9FdUPGRS2og" points="[98, -49, -42, 151]$[98, -105, -42, 95]$[106, -105, -34, 95]$[106, -151, -34, 49]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_M_12MJKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_M_12MZKGEeW9FdUPGRS2og" id="(0.2648648648648649,0.94)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_M_12MpKGEeW9FdUPGRS2og" type="4001" element="_M-mgEJKGEeW9FdUPGRS2og" source="_M_WG9JKGEeW9FdUPGRS2og" target="_M_ZKRJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_2dQJKGEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_2dQZKGEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_M_2dQpKGEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_2dQ5KGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_M_2dRJKGEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_2dRZKGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_M_12M5KGEeW9FdUPGRS2og" routing="Rectilinear" jumpLinkStatus="Above"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_M_12NJKGEeW9FdUPGRS2og" fontColor="7490599" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_M_12NZKGEeW9FdUPGRS2og" points="[1010, 284, 1010, 284]$[1100, 374, 1100, 374]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_M_3EUJKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_M_3EUZKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_M_3EUpKGEeW9FdUPGRS2og" type="4001" element="_M-nuMJKGEeW9FdUPGRS2og" source="_M_XVEJKGEeW9FdUPGRS2og" target="_M_eCw5KGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_3EVpKGEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_3EV5KGEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_M_3rYJKGEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_3rYZKGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_M_3rYpKGEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_3rY5KGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_M_3EU5KGEeW9FdUPGRS2og" routing="Rectilinear" jumpLinkStatus="Above"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_M_3EVJKGEeW9FdUPGRS2og" fontColor="7490599" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_M_3EVZKGEeW9FdUPGRS2og" points="[1040, 314, 1040, 314]$[1280, 554, 1280, 554]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_M_3rZJKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_M_4ScJKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_M_5gkJKGEeW9FdUPGRS2og" type="4001" element="_M-qxgJKGEeW9FdUPGRS2og" source="_M_eCw5KGEeW9FdUPGRS2og" target="_M_cNlJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_5glJKGEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_5glZKGEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_M_5glpKGEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_5gl5KGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_M_6HoJKGEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_6HoZKGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_M_5gkZKGEeW9FdUPGRS2og" routing="Rectilinear" jumpLinkStatus="Above"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_M_5gkpKGEeW9FdUPGRS2og" fontColor="7490599" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_M_5gk5KGEeW9FdUPGRS2og" points="[1280, 554, 1280, 554]$[1220, 494, 1220, 494]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_M_6HopKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_M_6Ho5KGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_M_6HpJKGEeW9FdUPGRS2og" type="4001" element="_M-tNwJKGEeW9FdUPGRS2og" source="_M_Vf45KGEeW9FdUPGRS2og" target="_M_cNlJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_6usJKGEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_6usZKGEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_M_6uspKGEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_6us5KGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_M_6utJKGEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_6utZKGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_M_6HpZKGEeW9FdUPGRS2og" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_M_6HppKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_M_6Hp5KGEeW9FdUPGRS2og" points="[19, -49, -329, 254]$[19, -174, -329, 129]$[236, -174, -112, 129]$[236, -301, -112, 2]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_M_7VwJKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_M_7VwZKGEeW9FdUPGRS2og" id="(0.4554140127388535,0.98)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_M_8j4pKGEeW9FdUPGRS2og" type="4001" element="_M-vqAJKGEeW9FdUPGRS2og" source="_M_WG9JKGEeW9FdUPGRS2og" target="_M_f38JKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_9K8JKGEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_9K8ZKGEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_M_9K8pKGEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_9K85KGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_M_9K9JKGEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_9K9ZKGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_M_8j45KGEeW9FdUPGRS2og" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_M_8j5JKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_M_8j5ZKGEeW9FdUPGRS2og" points="[-15, -49, 13, 543]$[-15, -586, 13, 6]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_M_9yAJKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_M_9yAZKGEeW9FdUPGRS2og" id="(0.5666666666666667,0.94)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_M_9yApKGEeW9FdUPGRS2og" type="4001" element="_M-w4IJKGEeW9FdUPGRS2og" source="_M_XVEJKGEeW9FdUPGRS2og" target="_M_ZxVJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_M_-ZEJKGEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_-ZEZKGEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_M_-ZEpKGEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_-ZE5KGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_M_-ZFJKGEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_M_-ZFZKGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_M_9yA5KGEeW9FdUPGRS2og" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_M_9yBJKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_M_9yBZKGEeW9FdUPGRS2og" points="[15, -49, -170, 544]$[15, -318, -170, 275]$[202, -318, 17, 275]$[202, -586, 17, 7]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_M__AIJKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_M__AIZKGEeW9FdUPGRS2og" id="(0.24166666666666667,0.93)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_NAAOQpKGEeW9FdUPGRS2og" type="4001" element="_M-ytVpKGEeW9FdUPGRS2og" source="_M_ZKRJKGEeW9FdUPGRS2og" target="_M_f38JKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_NAAORpKGEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NAAOR5KGEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_NAA1UJKGEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NAA1UZKGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_NAA1UpKGEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NAA1U5KGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_NAAOQ5KGEeW9FdUPGRS2og" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_NAAORJKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_NAAORZKGEeW9FdUPGRS2og" points="[-9, -49, 416, 576]$[-9, -409, 416, 216]$[-379, -409, 46, 216]$[-379, -576, 46, 49]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NAA1VJKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NAA1VZKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_NACDdJKGEeW9FdUPGRS2og" type="4001" element="_M-1JkJKGEeW9FdUPGRS2og" source="_M_a_cJKGEeW9FdUPGRS2og" target="_M_f38JKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_NACqgpKGEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NACqg5KGEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_NACqhJKGEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NACqhZKGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_NACqhpKGEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NACqh5KGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_NACDdZKGEeW9FdUPGRS2og" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_NACqgJKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_NACqgZKGEeW9FdUPGRS2og" points="[-13, -49, -83, 359]$[-13, -240, -83, 168]$[91, -240, 21, 168]$[91, -401, 21, 7]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NADRkJKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NADRkZKGEeW9FdUPGRS2og" id="(0.125,0.93)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_NAD4oJKGEeW9FdUPGRS2og" type="4001" element="_M-2XsJKGEeW9FdUPGRS2og" source="_M_bmg5KGEeW9FdUPGRS2og" target="_M_cNlJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_NAEfsJKGEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NAEfsZKGEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_NAFGwJKGEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NAFGwZKGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_NAFGwpKGEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NAFGw5KGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_NAD4oZKGEeW9FdUPGRS2og" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_NAD4opKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_NAD4o5KGEeW9FdUPGRS2og" points="[1, -49, -54, 277]$[1, -301, -54, 25]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NAFt0JKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NAFt0ZKGEeW9FdUPGRS2og" id="(0.7834394904458599,0.75)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_NAFt0pKGEeW9FdUPGRS2og" type="4001" element="_M-3l0JKGEeW9FdUPGRS2og" source="_M_cNlJKGEeW9FdUPGRS2og" target="_M_ZxVJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_NAGU4JKGEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NAGU4ZKGEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_NAGU4pKGEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NAGU45KGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_NAGU5JKGEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NAGU5ZKGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_NAFt05KGEeW9FdUPGRS2og" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_NAFt1JKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_NAFt1ZKGEeW9FdUPGRS2og" points="[24, -49, 29, 645]$[24, -596, 29, 98]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NAG78JKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NAG78ZKGEeW9FdUPGRS2og" id="(0.8083333333333333,0.91)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_NAG78pKGEeW9FdUPGRS2og" type="4001" element="_M-4z8JKGEeW9FdUPGRS2og" source="_M_dbsJKGEeW9FdUPGRS2og" target="_M_cNlJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_NAHjAJKGEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NAHjAZKGEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_NAHjApKGEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NAHjA5KGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_NAHjBJKGEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NAHjBZKGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_NAG785KGEeW9FdUPGRS2og" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_NAG79JKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_NAG79ZKGEeW9FdUPGRS2og" points="[-29, -49, 14, 350]$[-29, -301, 14, 98]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NAIKEJKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NAIKEZKGEeW9FdUPGRS2og" id="(0.9012738853503185,0.0)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_NAIKEpKGEeW9FdUPGRS2og" type="4001" element="_M-5bBpKGEeW9FdUPGRS2og" source="_M_eCw5KGEeW9FdUPGRS2og" target="_M_ZxVJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_NAIxIJKGEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NAIxIZKGEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_NAIxIpKGEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NAIxI5KGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_NAIxJJKGEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NAIxJZKGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_NAIKE5KGEeW9FdUPGRS2og" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_NAIKFJKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_NAIKFZKGEeW9FdUPGRS2og" points="[-3, -49, 16, 545]$[-3, -591, 16, 3]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NAJYMJKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NAJYMZKGEeW9FdUPGRS2og" id="(0.5083333333333333,0.97)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_NAJYMpKGEeW9FdUPGRS2og" type="4001" element="_M-6pIJKGEeW9FdUPGRS2og" source="_M_ep1JKGEeW9FdUPGRS2og" target="_M_cNlJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_NAJ_QJKGEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NAJ_QZKGEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_NAJ_QpKGEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NAJ_Q5KGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_NAJ_RJKGEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NAJ_RZKGEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_NAJYM5KGEeW9FdUPGRS2og" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_NAJYNJKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_NAJYNZKGEeW9FdUPGRS2og" points="[16, -49, -81, 301]$[16, -301, -81, 49]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NAKmUJKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_NAKmUpKGEeW9FdUPGRS2og" type="4001" element="_M-8eUJKGEeW9FdUPGRS2og" source="_M_Vf45KGEeW9FdUPGRS2og" target="_M_ep1JKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_NAKmVpKGEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NAKmV5KGEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_NALNYJKGEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NALNYZKGEeW9FdUPGRS2og" x="17" y="14"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_NALNYpKGEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_NALNY5KGEeW9FdUPGRS2og" x="-7" y="14"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_NAKmU5KGEeW9FdUPGRS2og" routing="Rectilinear" jumpLinkStatus="Above"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_NAKmVJKGEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_NAKmVZKGEeW9FdUPGRS2og" points="[980, 254, 980, 254]$[1310, 584, 1310, 584]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NALNZJKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_NALNZZKGEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_bJF98JKIEeW9FdUPGRS2og" type="4001" element="_bI5JoJKIEeW9FdUPGRS2og" source="_V0JSgJKIEeW9FdUPGRS2og" target="_M_ZxVJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_bJGlAJKIEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_bJGlAZKIEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_bJGlApKIEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_bJGlA5KIEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_bJHMEJKIEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_bJHMEZKIEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_bJF98ZKIEeW9FdUPGRS2og" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_bJF98pKIEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_bJF985KIEeW9FdUPGRS2og" points="[-16, -49, -422, 583]$[-16, -380, -422, 252]$[400, -380, -6, 252]$[400, -581, -6, 51]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_bJSyQJKIEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_bJSyQZKIEeW9FdUPGRS2og" id="(0.21666666666666667,0.48)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_hJn9AJKIEeW9FdUPGRS2og" type="4001" element="_M-pjYJKGEeW9FdUPGRS2og" source="_V0JSgJKIEeW9FdUPGRS2og" target="_M_XVEJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_hJokEJKIEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_hJokEZKIEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_hJokEpKIEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_hJpLIJKIEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_hJpLIZKIEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_hJpLIpKIEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_hJn9AZKIEeW9FdUPGRS2og" routing="Rectilinear" jumpLinkStatus="Above"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_hJn9ApKIEeW9FdUPGRS2og" fontColor="7490599" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_hJn9A5KIEeW9FdUPGRS2og" points="[168, 200, 168, 200]$[280, 380, 280, 380]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_hJpyMJKIEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_hJpyMZKIEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_o6ssoJKIEeW9FdUPGRS2og" type="4001" element="_o5lSUJKIEeW9FdUPGRS2og" source="_M_YjMJKGEeW9FdUPGRS2og" target="_V0JSgJKIEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_o6tTsJKIEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_o6tTsZKIEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_o6t6wJKIEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_o6t6wZKIEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_o6t6wpKIEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_o6t6w5KIEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_o6ssoZKIEeW9FdUPGRS2og" routing="Rectilinear" jumpLinkStatus="Above"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_o6ssopKIEeW9FdUPGRS2og" fontColor="7490599" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_o6sso5KIEeW9FdUPGRS2og" points="[59, 0, -196, 0]$[196, 0, -59, 0]"/>
+        </edges>
+        <edges xmi:type="notation:Edge" xmi:id="_T15LMJKKEeW9FdUPGRS2og" type="4001" element="_T1rv0JKKEeW9FdUPGRS2og" source="_M_f38JKGEeW9FdUPGRS2og" target="_M_ZxVJKGEeW9FdUPGRS2og">
+          <children xmi:type="notation:Node" xmi:id="_T15yQJKKEeW9FdUPGRS2og" type="6001">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_T15yQZKKEeW9FdUPGRS2og" y="-10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_T15yQpKKEeW9FdUPGRS2og" type="6002">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_T15yQ5KKEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <children xmi:type="notation:Node" xmi:id="_T16ZUJKKEeW9FdUPGRS2og" type="6003">
+            <layoutConstraint xmi:type="notation:Bounds" xmi:id="_T16ZUZKKEeW9FdUPGRS2og" y="10"/>
+          </children>
+          <styles xmi:type="notation:ConnectorStyle" xmi:id="_T15LMZKKEeW9FdUPGRS2og" routing="Rectilinear"/>
+          <styles xmi:type="notation:FontStyle" xmi:id="_T15LMpKKEeW9FdUPGRS2og" fontName="Cantarell" fontHeight="8"/>
+          <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_T15LM5KKEeW9FdUPGRS2og" points="[-1, 49, 724, 44]$[-1, 11, 724, 6]$[-724, 11, 1, 6]$[-724, 54, 1, 49]"/>
+          <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_T16ZUpKKEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+          <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_T16ZU5KKEeW9FdUPGRS2og" id="(0.5,0.5)"/>
+        </edges>
+      </data>
+    </ownedAnnotationEntries>
+    <ownedAnnotationEntries xmi:type="description:AnnotationEntry" uid="_M-fLUJKGEeW9FdUPGRS2og" source="DANNOTATION_CUSTOMIZATION_KEY">
+      <data xmi:type="diagram:ComputedStyleDescriptionRegistry" uid="_M-fyYJKGEeW9FdUPGRS2og">
+        <computedStyleDescriptions xmi:type="style:EdgeStyleDescription" xmi:id="_M-hAgZKGEeW9FdUPGRS2og" sourceArrow="FillDiamond" routingStyle="manhattan">
+          <strokeColor xmi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='black']"/>
+          <centerLabelStyleDescription xmi:type="style:CenterLabelStyleDescription" xmi:id="_M-hAgpKGEeW9FdUPGRS2og" showIcon="false" labelExpression="service:render">
+            <labelColor xmi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='black']"/>
+          </centerLabelStyleDescription>
+          <endLabelStyleDescription xmi:type="style:EndLabelStyleDescription" xmi:id="_M-hAg5KGEeW9FdUPGRS2og" labelSize="6" showIcon="false" labelExpression="service:eKeysLabel">
+            <labelColor xmi:type="description:SystemColor" href="environment:/viewpoint#//@systemColors/@entries[name='dark_blue']"/>
+          </endLabelStyleDescription>
+        </computedStyleDescriptions>
+      </data>
+    </ownedAnnotationEntries>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_M8r0gJKGEeW9FdUPGRS2og" name="AccessMethod" tooltipText="" outgoingEdges="_M-d9MJKGEeW9FdUPGRS2og" incomingEdges="_M-lR8JKGEeW9FdUPGRS2og" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//AccessMethod"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//AccessMethod"/>
+      <arrangeConstraints>KEEP_LOCATION</arrangeConstraints>
+      <arrangeConstraints>KEEP_SIZE</arrangeConstraints>
+      <arrangeConstraints>KEEP_RATIO</arrangeConstraints>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_M8xUEJKGEeW9FdUPGRS2og" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_M-E7oJKGEeW9FdUPGRS2og" name="type : AccessMethodType = GET" tooltipText="">
+        <target xmi:type="ecore:EAttribute" href="resource.ecore#//AccessMethod/type"/>
+        <semanticElements xmi:type="ecore:EAttribute" href="resource.ecore#//AccessMethod/type"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_M-Gw0JKGEeW9FdUPGRS2og" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']"/>
+      </ownedElements>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_M80XYJKGEeW9FdUPGRS2og" name="AccessMethodType" tooltipText="">
+      <target xmi:type="ecore:EEnum" href="resource.ecore#//AccessMethodType"/>
+      <semanticElements xmi:type="ecore:EEnum" href="resource.ecore#//AccessMethodType"/>
+      <arrangeConstraints>KEEP_LOCATION</arrangeConstraints>
+      <arrangeConstraints>KEEP_SIZE</arrangeConstraints>
+      <arrangeConstraints>KEEP_RATIO</arrangeConstraints>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_M80-cJKGEeW9FdUPGRS2og" borderSize="1" borderSizeComputationExpression="1" borderColor="125,125,125" backgroundStyle="Liquid" foregroundColor="221,236,202">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']"/>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_M-TlIJKGEeW9FdUPGRS2og" name="GET" tooltipText="">
+        <target xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/GET"/>
+        <semanticElements xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/GET"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_M-UMMJKGEeW9FdUPGRS2og" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']"/>
+      </ownedElements>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_M-UzQJKGEeW9FdUPGRS2og" name="SET" tooltipText="">
+        <target xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/SET"/>
+        <semanticElements xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/SET"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_M-UzQZKGEeW9FdUPGRS2og" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']"/>
+      </ownedElements>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_M-VaUJKGEeW9FdUPGRS2og" name="ACT" tooltipText="">
+        <target xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/ACT"/>
+        <semanticElements xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/ACT"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_M-VaUZKGEeW9FdUPGRS2og" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']"/>
+      </ownedElements>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_M-WBYJKGEeW9FdUPGRS2og" name="SUBSCRIBE" tooltipText="">
+        <target xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/SUBSCRIBE"/>
+        <semanticElements xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/SUBSCRIBE"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_M-WBYZKGEeW9FdUPGRS2og" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']"/>
+      </ownedElements>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_M-WocJKGEeW9FdUPGRS2og" name="UNSUBSCRIBE" tooltipText="">
+        <target xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/UNSUBSCRIBE"/>
+        <semanticElements xmi:type="ecore:EEnumLiteral" href="resource.ecore#//AccessMethodType/UNSUBSCRIBE"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_M-WocZKGEeW9FdUPGRS2og" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EEnum']/@subNodeMappings[name='EC%20EEnumLiteral']"/>
+      </ownedElements>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_M82zoJKGEeW9FdUPGRS2og" name="Action" tooltipText="" outgoingEdges="_M-tNwJKGEeW9FdUPGRS2og _M-8eUJKGEeW9FdUPGRS2og" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Action"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Action"/>
+      <arrangeConstraints>KEEP_LOCATION</arrangeConstraints>
+      <arrangeConstraints>KEEP_SIZE</arrangeConstraints>
+      <arrangeConstraints>KEEP_RATIO</arrangeConstraints>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_M84o0JKGEeW9FdUPGRS2og" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_M8528JKGEeW9FdUPGRS2og" name="Attribute" tooltipText="" outgoingEdges="_M-mgEJKGEeW9FdUPGRS2og _M-vqAJKGEeW9FdUPGRS2og" incomingEdges="_M-jcwJKGEeW9FdUPGRS2og" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Attribute"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Attribute"/>
+      <arrangeConstraints>KEEP_LOCATION</arrangeConstraints>
+      <arrangeConstraints>KEEP_SIZE</arrangeConstraints>
+      <arrangeConstraints>KEEP_RATIO</arrangeConstraints>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_M87FEJKGEeW9FdUPGRS2og" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_M886QJKGEeW9FdUPGRS2og" name="Device" tooltipText="" outgoingEdges="_M-nuMJKGEeW9FdUPGRS2og _M-w4IJKGEeW9FdUPGRS2og" incomingEdges="_M-pjYJKGEeW9FdUPGRS2og" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Device"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Device"/>
+      <arrangeConstraints>KEEP_LOCATION</arrangeConstraints>
+      <arrangeConstraints>KEEP_SIZE</arrangeConstraints>
+      <arrangeConstraints>KEEP_RATIO</arrangeConstraints>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_M8-IYJKGEeW9FdUPGRS2og" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_M-ImAJKGEeW9FdUPGRS2og" name="friendlyName : EString" tooltipText="">
+        <target xmi:type="ecore:EAttribute" href="resource.ecore#//Device/friendlyName"/>
+        <semanticElements xmi:type="ecore:EAttribute" href="resource.ecore#//Device/friendlyName"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_M-JNEJKGEeW9FdUPGRS2og" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']"/>
+      </ownedElements>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_M8_WgJKGEeW9FdUPGRS2og" name="Studio" tooltipText="" outgoingEdges="_o5lSUJKIEeW9FdUPGRS2og" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Studio"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Studio"/>
+      <arrangeConstraints>KEEP_LOCATION</arrangeConstraints>
+      <arrangeConstraints>KEEP_SIZE</arrangeConstraints>
+      <arrangeConstraints>KEEP_RATIO</arrangeConstraints>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_M9AkoJKGEeW9FdUPGRS2og" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_M9BywJKGEeW9FdUPGRS2og" name="Metadata" tooltipText="" outgoingEdges="_M-ytVpKGEeW9FdUPGRS2og" incomingEdges="_M-mgEJKGEeW9FdUPGRS2og" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Metadata"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Metadata"/>
+      <arrangeConstraints>KEEP_LOCATION</arrangeConstraints>
+      <arrangeConstraints>KEEP_SIZE</arrangeConstraints>
+      <arrangeConstraints>KEEP_RATIO</arrangeConstraints>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_M9DA4JKGEeW9FdUPGRS2og" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_M9EPAJKGEeW9FdUPGRS2og" name="NamedElement" tooltipText="" incomingEdges="_M-w4IJKGEeW9FdUPGRS2og _M-3l0JKGEeW9FdUPGRS2og _M-5bBpKGEeW9FdUPGRS2og _bI5JoJKIEeW9FdUPGRS2og _T1rv0JKKEeW9FdUPGRS2og" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//NamedElement"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//NamedElement"/>
+      <arrangeConstraints>KEEP_LOCATION</arrangeConstraints>
+      <arrangeConstraints>KEEP_SIZE</arrangeConstraints>
+      <arrangeConstraints>KEEP_RATIO</arrangeConstraints>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_M9FdIJKGEeW9FdUPGRS2og" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_M-KbMJKGEeW9FdUPGRS2og" name="name : EString" tooltipText="">
+        <target xmi:type="ecore:EAttribute" href="resource.ecore#//NamedElement/name"/>
+        <semanticElements xmi:type="ecore:EAttribute" href="resource.ecore#//NamedElement/name"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_M-LCQJKGEeW9FdUPGRS2og" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']"/>
+      </ownedElements>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_M9GrQJKGEeW9FdUPGRS2og" name="Parameter" tooltipText="" outgoingEdges="_M-1JkJKGEeW9FdUPGRS2og" incomingEdges="_M-d9MJKGEeW9FdUPGRS2og" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Parameter"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Parameter"/>
+      <arrangeConstraints>KEEP_LOCATION</arrangeConstraints>
+      <arrangeConstraints>KEEP_SIZE</arrangeConstraints>
+      <arrangeConstraints>KEEP_RATIO</arrangeConstraints>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_M9H5YJKGEeW9FdUPGRS2og" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_M9JHgJKGEeW9FdUPGRS2og" name="Property" tooltipText="" outgoingEdges="_M-2XsJKGEeW9FdUPGRS2og" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Property"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Property"/>
+      <arrangeConstraints>KEEP_LOCATION</arrangeConstraints>
+      <arrangeConstraints>KEEP_SIZE</arrangeConstraints>
+      <arrangeConstraints>KEEP_RATIO</arrangeConstraints>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_M9JukJKGEeW9FdUPGRS2og" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_M9LjwJKGEeW9FdUPGRS2og" name="Resource" tooltipText="" outgoingEdges="_M-jcwJKGEeW9FdUPGRS2og _M-lR8JKGEeW9FdUPGRS2og _M-3l0JKGEeW9FdUPGRS2og" incomingEdges="_M-qxgJKGEeW9FdUPGRS2og _M-tNwJKGEeW9FdUPGRS2og _M-2XsJKGEeW9FdUPGRS2og _M-4z8JKGEeW9FdUPGRS2og _M-6pIJKGEeW9FdUPGRS2og" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Resource"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Resource"/>
+      <arrangeConstraints>KEEP_LOCATION</arrangeConstraints>
+      <arrangeConstraints>KEEP_SIZE</arrangeConstraints>
+      <arrangeConstraints>KEEP_RATIO</arrangeConstraints>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_M9Mx4JKGEeW9FdUPGRS2og" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_M-MQYJKGEeW9FdUPGRS2og" name="friendlyName : EString" tooltipText="">
+        <target xmi:type="ecore:EAttribute" href="resource.ecore#//Resource/friendlyName"/>
+        <semanticElements xmi:type="ecore:EAttribute" href="resource.ecore#//Resource/friendlyName"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_M-M3cJKGEeW9FdUPGRS2og" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']"/>
+      </ownedElements>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_M-NegJKGEeW9FdUPGRS2og" name="getAccessMethod(type AccessMethodType) : AccessMethod" tooltipText="getAccessMethod(type) : AccessMethod">
+        <target xmi:type="ecore:EOperation" href="resource.ecore#//Resource/getAccessMethod"/>
+        <semanticElements xmi:type="ecore:EOperation" href="resource.ecore#//Resource/getAccessMethod"/>
+        <semanticElements xmi:type="ecore:EParameter" href="resource.ecore#//Resource/getAccessMethod/type"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_M-OsoJKGEeW9FdUPGRS2og" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='Operation']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='Operation']"/>
+      </ownedElements>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_M9OAAJKGEeW9FdUPGRS2og" name="SensorData" tooltipText="" outgoingEdges="_M-4z8JKGEeW9FdUPGRS2og" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//SensorData"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//SensorData"/>
+      <arrangeConstraints>KEEP_LOCATION</arrangeConstraints>
+      <arrangeConstraints>KEEP_SIZE</arrangeConstraints>
+      <arrangeConstraints>KEEP_RATIO</arrangeConstraints>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_M9OnEJKGEeW9FdUPGRS2og" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_M9QcQJKGEeW9FdUPGRS2og" name="Service" tooltipText="" outgoingEdges="_M-qxgJKGEeW9FdUPGRS2og _M-5bBpKGEeW9FdUPGRS2og" incomingEdges="_M-nuMJKGEeW9FdUPGRS2og" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Service"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Service"/>
+      <arrangeConstraints>KEEP_LOCATION</arrangeConstraints>
+      <arrangeConstraints>KEEP_SIZE</arrangeConstraints>
+      <arrangeConstraints>KEEP_RATIO</arrangeConstraints>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_M9RDUJKGEeW9FdUPGRS2og" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_M-P6wJKGEeW9FdUPGRS2og" name="friendlyName : EString" tooltipText="">
+        <target xmi:type="ecore:EAttribute" href="resource.ecore#//Service/friendlyName"/>
+        <semanticElements xmi:type="ecore:EAttribute" href="resource.ecore#//Service/friendlyName"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_M-Qh0JKGEeW9FdUPGRS2og" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']"/>
+      </ownedElements>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_M9SRcJKGEeW9FdUPGRS2og" name="StateVariable" tooltipText="" outgoingEdges="_M-6pIJKGEeW9FdUPGRS2og" incomingEdges="_M-8eUJKGEeW9FdUPGRS2og" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//StateVariable"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//StateVariable"/>
+      <arrangeConstraints>KEEP_LOCATION</arrangeConstraints>
+      <arrangeConstraints>KEEP_SIZE</arrangeConstraints>
+      <arrangeConstraints>KEEP_RATIO</arrangeConstraints>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_M9TfkJKGEeW9FdUPGRS2og" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_M9VUwJKGEeW9FdUPGRS2og" name="TypedElement" tooltipText="" outgoingEdges="_T1rv0JKKEeW9FdUPGRS2og" incomingEdges="_M-vqAJKGEeW9FdUPGRS2og _M-ytVpKGEeW9FdUPGRS2og _M-1JkJKGEeW9FdUPGRS2og" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//TypedElement"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//TypedElement"/>
+      <arrangeConstraints>KEEP_LOCATION</arrangeConstraints>
+      <arrangeConstraints>KEEP_SIZE</arrangeConstraints>
+      <arrangeConstraints>KEEP_RATIO</arrangeConstraints>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_M9V70JKGEeW9FdUPGRS2og" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_M-RI4JKGEeW9FdUPGRS2og" name="type : EString" tooltipText="">
+        <target xmi:type="ecore:EAttribute" href="resource.ecore#//TypedElement/type"/>
+        <semanticElements xmi:type="ecore:EAttribute" href="resource.ecore#//TypedElement/type"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_M-Rv8JKGEeW9FdUPGRS2og" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']"/>
+      </ownedElements>
+      <ownedElements xmi:type="diagram:DNodeListElement" uid="_M-SXAJKGEeW9FdUPGRS2og" name="value : EString" tooltipText="">
+        <target xmi:type="ecore:EAttribute" href="resource.ecore#//TypedElement/value"/>
+        <semanticElements xmi:type="ecore:EAttribute" href="resource.ecore#//TypedElement/value"/>
+        <ownedStyle xmi:type="diagram:BundledImage" uid="_M-SXAZKGEeW9FdUPGRS2og" labelAlignment="LEFT">
+          <description xmi:type="style:BundledImageDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']/@style"/>
+        </ownedStyle>
+        <actualMapping xmi:type="description_1:NodeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@subNodeMappings[name='EC%20EAttribute']"/>
+      </ownedElements>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_M-d9MJKGEeW9FdUPGRS2og" name="[0..*] parameter" sourceNode="_M8r0gJKGEeW9FdUPGRS2og" targetNode="_M9GrQJKGEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EReference" href="resource.ecore#//AccessMethod/parameter"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//AccessMethod/parameter"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_M-i1sJKGEeW9FdUPGRS2og" description="_M-hAgZKGEeW9FdUPGRS2og" sourceArrow="FillDiamond" routingStyle="manhattan" strokeColor="0,0,0">
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_M-i1spKGEeW9FdUPGRS2og" showIcon="false">
+          <customFeatures>labelSize</customFeatures>
+        </centerLabelStyle>
+        <endLabelStyle xmi:type="diagram:EndLabelStyle" uid="_M-i1tJKGEeW9FdUPGRS2og" showIcon="false" labelColor="39,76,114">
+          <customFeatures>labelSize</customFeatures>
+        </endLabelStyle>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC_EReference']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_M-jcwJKGEeW9FdUPGRS2og" name="[0..*] attribute" sourceNode="_M9LjwJKGEeW9FdUPGRS2og" targetNode="_M8528JKGEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EReference" href="resource.ecore#//Resource/attribute"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//Resource/attribute"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_M-kq4ZKGEeW9FdUPGRS2og" description="_M-hAgZKGEeW9FdUPGRS2og" sourceArrow="FillDiamond" routingStyle="manhattan" strokeColor="0,0,0">
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_M-kq45KGEeW9FdUPGRS2og" showIcon="false">
+          <customFeatures>labelSize</customFeatures>
+        </centerLabelStyle>
+        <endLabelStyle xmi:type="diagram:EndLabelStyle" uid="_M-kq5ZKGEeW9FdUPGRS2og" showIcon="false" labelColor="39,76,114">
+          <customFeatures>labelSize</customFeatures>
+        </endLabelStyle>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC_EReference']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_M-lR8JKGEeW9FdUPGRS2og" name="[0..*] accessMethod" sourceNode="_M9LjwJKGEeW9FdUPGRS2og" targetNode="_M8r0gJKGEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EReference" href="resource.ecore#//Resource/accessMethod"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//Resource/accessMethod"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_M-l5BpKGEeW9FdUPGRS2og" description="_M-hAgZKGEeW9FdUPGRS2og" sourceArrow="FillDiamond" routingStyle="manhattan" strokeColor="0,0,0">
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_M-l5CJKGEeW9FdUPGRS2og" showIcon="false">
+          <customFeatures>labelSize</customFeatures>
+        </centerLabelStyle>
+        <endLabelStyle xmi:type="diagram:EndLabelStyle" uid="_M-l5CpKGEeW9FdUPGRS2og" showIcon="false" labelColor="39,76,114">
+          <customFeatures>labelSize</customFeatures>
+        </endLabelStyle>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC_EReference']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_M-mgEJKGEeW9FdUPGRS2og" name="[0..*] metadata" sourceNode="_M8528JKGEeW9FdUPGRS2og" targetNode="_M9BywJKGEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EReference" href="resource.ecore#//Attribute/metadata"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//Attribute/metadata"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_M-nHJpKGEeW9FdUPGRS2og" description="_M-hAgZKGEeW9FdUPGRS2og" sourceArrow="FillDiamond" routingStyle="manhattan" strokeColor="0,0,0">
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_M-nHKJKGEeW9FdUPGRS2og" showIcon="false">
+          <customFeatures>labelSize</customFeatures>
+        </centerLabelStyle>
+        <endLabelStyle xmi:type="diagram:EndLabelStyle" uid="_M-nHKpKGEeW9FdUPGRS2og" showIcon="false" labelColor="39,76,114">
+          <customFeatures>labelSize</customFeatures>
+        </endLabelStyle>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC_EReference']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_M-nuMJKGEeW9FdUPGRS2og" name="[0..*] service" sourceNode="_M886QJKGEeW9FdUPGRS2og" targetNode="_M9QcQJKGEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EReference" href="resource.ecore#//Device/service"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//Device/service"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_M-o8UZKGEeW9FdUPGRS2og" description="_M-hAgZKGEeW9FdUPGRS2og" sourceArrow="FillDiamond" routingStyle="manhattan" strokeColor="0,0,0">
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_M-o8U5KGEeW9FdUPGRS2og" showIcon="false">
+          <customFeatures>labelSize</customFeatures>
+        </centerLabelStyle>
+        <endLabelStyle xmi:type="diagram:EndLabelStyle" uid="_M-o8VZKGEeW9FdUPGRS2og" showIcon="false" labelColor="39,76,114">
+          <customFeatures>labelSize</customFeatures>
+        </endLabelStyle>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC_EReference']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_M-pjYJKGEeW9FdUPGRS2og" name="[0..*] device" sourceNode="_VzDGUJKIEeW9FdUPGRS2og" targetNode="_M886QJKGEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EReference" href="resource.ecore#//Gateway/device"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//Gateway/device"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_hKxMgZKIEeW9FdUPGRS2og" description="_M-hAgZKGEeW9FdUPGRS2og" sourceArrow="FillDiamond" routingStyle="manhattan" strokeColor="0,0,0">
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_hKxMg5KIEeW9FdUPGRS2og" showIcon="false"/>
+        <endLabelStyle xmi:type="diagram:EndLabelStyle" uid="_hKxMhZKIEeW9FdUPGRS2og" labelSize="6" showIcon="false" labelColor="39,76,114"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC_EReference']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_M-qxgJKGEeW9FdUPGRS2og" name="[0..*] resource" sourceNode="_M9QcQJKGEeW9FdUPGRS2og" targetNode="_M9LjwJKGEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EReference" href="resource.ecore#//Service/resource"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//Service/resource"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_M-rYlpKGEeW9FdUPGRS2og" description="_M-hAgZKGEeW9FdUPGRS2og" sourceArrow="FillDiamond" routingStyle="manhattan" strokeColor="0,0,0">
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_M-rYmJKGEeW9FdUPGRS2og" showIcon="false">
+          <customFeatures>labelSize</customFeatures>
+        </centerLabelStyle>
+        <endLabelStyle xmi:type="diagram:EndLabelStyle" uid="_M-rYmpKGEeW9FdUPGRS2og" showIcon="false" labelColor="39,76,114">
+          <customFeatures>labelSize</customFeatures>
+        </endLabelStyle>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC_EReference']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_M-tNwJKGEeW9FdUPGRS2og" sourceNode="_M82zoJKGEeW9FdUPGRS2og" targetNode="_M9LjwJKGEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Action"/>
+      <semanticElements xmi:type="ecore:EGenericType" href="resource.ecore#//Action/@eGenericSuperTypes.0"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_M-t00JKGEeW9FdUPGRS2og" targetArrow="InputClosedArrow" routingStyle="manhattan">
+        <customFeatures>routingStyle</customFeatures>
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_M-t00pKGEeW9FdUPGRS2og" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_M-t01JKGEeW9FdUPGRS2og" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_M-vqAJKGEeW9FdUPGRS2og" sourceNode="_M8528JKGEeW9FdUPGRS2og" targetNode="_M9VUwJKGEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Attribute"/>
+      <semanticElements xmi:type="ecore:EGenericType" href="resource.ecore#//Attribute/@eGenericSuperTypes.0"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_M-wREJKGEeW9FdUPGRS2og" targetArrow="InputClosedArrow" routingStyle="manhattan">
+        <customFeatures>routingStyle</customFeatures>
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_M-wREpKGEeW9FdUPGRS2og" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_M-wRFJKGEeW9FdUPGRS2og" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_M-w4IJKGEeW9FdUPGRS2og" sourceNode="_M886QJKGEeW9FdUPGRS2og" targetNode="_M9EPAJKGEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Device"/>
+      <semanticElements xmi:type="ecore:EGenericType" href="resource.ecore#//Device/@eGenericSuperTypes.0"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_M-xfMJKGEeW9FdUPGRS2og" targetArrow="InputClosedArrow" routingStyle="manhattan">
+        <customFeatures>routingStyle</customFeatures>
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_M-xfMpKGEeW9FdUPGRS2og" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_M-xfNJKGEeW9FdUPGRS2og" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_M-ytVpKGEeW9FdUPGRS2og" sourceNode="_M9BywJKGEeW9FdUPGRS2og" targetNode="_M9VUwJKGEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Metadata"/>
+      <semanticElements xmi:type="ecore:EGenericType" href="resource.ecore#//Metadata/@eGenericSuperTypes.0"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_M-zUYJKGEeW9FdUPGRS2og" targetArrow="InputClosedArrow" routingStyle="manhattan">
+        <customFeatures>routingStyle</customFeatures>
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_M-zUYpKGEeW9FdUPGRS2og" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_M-zUZJKGEeW9FdUPGRS2og" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_M-1JkJKGEeW9FdUPGRS2og" sourceNode="_M9GrQJKGEeW9FdUPGRS2og" targetNode="_M9VUwJKGEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Parameter"/>
+      <semanticElements xmi:type="ecore:EGenericType" href="resource.ecore#//Parameter/@eGenericSuperTypes.0"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_M-1woJKGEeW9FdUPGRS2og" targetArrow="InputClosedArrow" routingStyle="manhattan">
+        <customFeatures>routingStyle</customFeatures>
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_M-1wopKGEeW9FdUPGRS2og" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_M-1wpJKGEeW9FdUPGRS2og" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_M-2XsJKGEeW9FdUPGRS2og" sourceNode="_M9JHgJKGEeW9FdUPGRS2og" targetNode="_M9LjwJKGEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Property"/>
+      <semanticElements xmi:type="ecore:EGenericType" href="resource.ecore#//Property/@eGenericSuperTypes.0"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_M-2-wJKGEeW9FdUPGRS2og" targetArrow="InputClosedArrow" routingStyle="manhattan">
+        <customFeatures>routingStyle</customFeatures>
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_M-2-wpKGEeW9FdUPGRS2og" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_M-2-xJKGEeW9FdUPGRS2og" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_M-3l0JKGEeW9FdUPGRS2og" sourceNode="_M9LjwJKGEeW9FdUPGRS2og" targetNode="_M9EPAJKGEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Resource"/>
+      <semanticElements xmi:type="ecore:EGenericType" href="resource.ecore#//Resource/@eGenericSuperTypes.0"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_M-4M4JKGEeW9FdUPGRS2og" targetArrow="InputClosedArrow" routingStyle="manhattan">
+        <customFeatures>routingStyle</customFeatures>
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_M-4M4pKGEeW9FdUPGRS2og" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_M-4M5JKGEeW9FdUPGRS2og" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_M-4z8JKGEeW9FdUPGRS2og" sourceNode="_M9OAAJKGEeW9FdUPGRS2og" targetNode="_M9LjwJKGEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//SensorData"/>
+      <semanticElements xmi:type="ecore:EGenericType" href="resource.ecore#//SensorData/@eGenericSuperTypes.0"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_M-5bAJKGEeW9FdUPGRS2og" targetArrow="InputClosedArrow" routingStyle="manhattan">
+        <customFeatures>routingStyle</customFeatures>
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_M-5bApKGEeW9FdUPGRS2og" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_M-5bBJKGEeW9FdUPGRS2og" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_M-5bBpKGEeW9FdUPGRS2og" sourceNode="_M9QcQJKGEeW9FdUPGRS2og" targetNode="_M9EPAJKGEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Service"/>
+      <semanticElements xmi:type="ecore:EGenericType" href="resource.ecore#//Service/@eGenericSuperTypes.0"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_M-6CEJKGEeW9FdUPGRS2og" targetArrow="InputClosedArrow" routingStyle="manhattan">
+        <customFeatures>routingStyle</customFeatures>
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_M-6CEpKGEeW9FdUPGRS2og" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_M-6CFJKGEeW9FdUPGRS2og" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_M-6pIJKGEeW9FdUPGRS2og" sourceNode="_M9SRcJKGEeW9FdUPGRS2og" targetNode="_M9LjwJKGEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//StateVariable"/>
+      <semanticElements xmi:type="ecore:EGenericType" href="resource.ecore#//StateVariable/@eGenericSuperTypes.0"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_M-7QMJKGEeW9FdUPGRS2og" targetArrow="InputClosedArrow" routingStyle="manhattan">
+        <customFeatures>routingStyle</customFeatures>
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_M-7QMpKGEeW9FdUPGRS2og" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_M-7QNJKGEeW9FdUPGRS2og" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_M-8eUJKGEeW9FdUPGRS2og" sourceNode="_M82zoJKGEeW9FdUPGRS2og" targetNode="_M9SRcJKGEeW9FdUPGRS2og" beginLabel="[0..*] modifier" endLabel="[0..*] state">
+      <target xmi:type="ecore:EReference" href="resource.ecore#//Action/state"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//StateVariable/modifier"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//Action/state"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_M-9scJKGEeW9FdUPGRS2og" sourceArrow="InputArrow" routingStyle="manhattan" strokeColor="0,0,0">
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='Bi-directional%20EC_EReference%20']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_M-9scpKGEeW9FdUPGRS2og" showIcon="false"/>
+        <endLabelStyle xmi:type="diagram:EndLabelStyle" uid="_M-9sdJKGEeW9FdUPGRS2og" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='Bi-directional%20EC_EReference%20']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DNodeList" uid="_VzDGUJKIEeW9FdUPGRS2og" name="Gateway" tooltipText="" outgoingEdges="_bI5JoJKIEeW9FdUPGRS2og _M-pjYJKGEeW9FdUPGRS2og" incomingEdges="_o5lSUJKIEeW9FdUPGRS2og" width="12" height="10">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Gateway"/>
+      <semanticElements xmi:type="ecore:EClass" href="resource.ecore#//Gateway"/>
+      <arrangeConstraints>KEEP_LOCATION</arrangeConstraints>
+      <arrangeConstraints>KEEP_SIZE</arrangeConstraints>
+      <arrangeConstraints>KEEP_RATIO</arrangeConstraints>
+      <ownedStyle xmi:type="diagram:FlatContainerStyle" uid="_VzDtYJKIEeW9FdUPGRS2og" borderSize="1" borderSizeComputationExpression="1" backgroundStyle="Liquid" foregroundColor="255,252,216">
+        <description xmi:type="style:FlatContainerStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']/@style"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:ContainerMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@containerMappings[name='EC%20EClass']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_bI5JoJKIEeW9FdUPGRS2og" sourceNode="_VzDGUJKIEeW9FdUPGRS2og" targetNode="_M9EPAJKGEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//Gateway"/>
+      <semanticElements xmi:type="ecore:EGenericType" href="resource.ecore#//Gateway/@eGenericSuperTypes.0"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_bI5wsJKIEeW9FdUPGRS2og" targetArrow="InputClosedArrow" routingStyle="manhattan">
+        <customFeatures>routingStyle</customFeatures>
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_bI5wspKIEeW9FdUPGRS2og" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_bI5wtJKIEeW9FdUPGRS2og" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_o5lSUJKIEeW9FdUPGRS2og" name="[0..*] gateways" sourceNode="_M8_WgJKGEeW9FdUPGRS2og" targetNode="_VzDGUJKIEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EReference" href="resource.ecore#//Studio/gateways"/>
+      <semanticElements xmi:type="ecore:EReference" href="resource.ecore#//Studio/gateways"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_Pj4_8ZKJEeW9FdUPGRS2og" description="_M-hAgZKGEeW9FdUPGRS2og" sourceArrow="FillDiamond" routingStyle="manhattan" strokeColor="0,0,0">
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_Pj4_85KJEeW9FdUPGRS2og" showIcon="false"/>
+        <endLabelStyle xmi:type="diagram:EndLabelStyle" uid="_Pj4_9ZKJEeW9FdUPGRS2og" labelSize="6" showIcon="false" labelColor="39,76,114"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC_EReference']"/>
+    </ownedDiagramElements>
+    <ownedDiagramElements xmi:type="diagram:DEdge" uid="_T1rv0JKKEeW9FdUPGRS2og" sourceNode="_M9VUwJKGEeW9FdUPGRS2og" targetNode="_M9EPAJKGEeW9FdUPGRS2og">
+      <target xmi:type="ecore:EClass" href="resource.ecore#//TypedElement"/>
+      <semanticElements xmi:type="ecore:EGenericType" href="resource.ecore#//TypedElement/@eGenericSuperTypes.0"/>
+      <ownedStyle xmi:type="diagram:EdgeStyle" uid="_T1sW4JKKEeW9FdUPGRS2og" targetArrow="InputClosedArrow" routingStyle="manhattan">
+        <customFeatures>routingStyle</customFeatures>
+        <description xmi:type="style:EdgeStyleDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']/@style"/>
+        <beginLabelStyle xmi:type="diagram:BeginLabelStyle" uid="_T1sW4pKKEeW9FdUPGRS2og" showIcon="false">
+          <labelFormat>italic</labelFormat>
+        </beginLabelStyle>
+        <centerLabelStyle xmi:type="diagram:CenterLabelStyle" uid="_T1sW5JKKEeW9FdUPGRS2og" showIcon="false"/>
+      </ownedStyle>
+      <actualMapping xmi:type="description_1:EdgeMapping" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer/@edgeMappings[name='EC%20ESupertypes']"/>
+    </ownedDiagramElements>
+    <description xmi:type="description_1:DiagramDescription" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']"/>
+    <filterVariableHistory xmi:type="diagram:FilterVariableHistory" uid="_IOoJ9ZKGEeW9FdUPGRS2og"/>
+    <activatedLayers xmi:type="description_1:Layer" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@defaultLayer"/>
+    <activatedLayers xmi:type="description_1:AdditionalLayer" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@additionalLayers[name='Package']"/>
+    <activatedLayers xmi:type="description_1:AdditionalLayer" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Design']/@ownedRepresentations[name='Entities']/@additionalLayers[name='Validation']"/>
+    <activatedLayers xmi:type="description_1:AdditionalLayer" href="platform:/plugin/org.eclipse.emf.ecoretools.design/description/ecore.odesign#//@ownedViewpoints[name='Archetype']/@ownedRepresentationExtensions[name='Entities%20With%20Archetypes']/@layers[name='Archetypes']"/>
+    <target xmi:type="ecore:EPackage" href="resource.ecore#/"/>
+  </diagram:DSemanticDiagram>
+</xmi:XMI>
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/models/resource.ecore b/bnd/org.eclipse.sensinact.studio.model.resource/models/resource.ecore
new file mode 100644
index 0000000..c73c31c
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/models/resource.ecore
@@ -0,0 +1,72 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ecore:EPackage xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+    xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" name="resource" nsURI="http://SENSINACT_RESOURCE/0.1" nsPrefix="resource">
+  <eClassifiers xsi:type="ecore:EClass" name="Studio">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="gateways" upperBound="-1"
+        eType="#//Gateway" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Device" eSuperTypes="#//NamedElement">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="friendlyName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="service" upperBound="-1"
+        eType="#//Service" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="location" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="icon" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="NamedElement">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="name" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="TypedElement" eSuperTypes="#//NamedElement">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="value" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Service" eSuperTypes="#//NamedElement">
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="friendlyName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="resource" upperBound="-1"
+        eType="#//Resource" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Resource" eSuperTypes="#//NamedElement">
+    <eOperations name="getAccessMethod" upperBound="-1" eType="#//AccessMethod">
+      <eAnnotations source="http://www.eclipse.org/emf/2002/GenModel" references="#//Resource/getAccessMethod">
+        <details key="body" value="EList&lt;AccessMethod> accessMethodByType = new EObjectContainmentEList&lt;AccessMethod>(AccessMethod.class, this, ResourcePackage.RESOURCE__ACCESS_METHOD);&#xA;&#x9;&#x9;for (AccessMethod accessMethod : getAccessMethod()) {&#xA;&#x9;&#x9;&#x9;if (accessMethod.getType().equals(type))&#xA;&#x9;&#x9;&#x9;&#x9;accessMethodByType.add(accessMethod);&#xA;&#x9;&#x9;}&#xA;&#x9;&#x9;return accessMethodByType;"/>
+      </eAnnotations>
+      <eParameters name="type" eType="#//AccessMethodType"/>
+    </eOperations>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="friendlyName" eType="ecore:EDataType http://www.eclipse.org/emf/2002/Ecore#//EString"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="attribute" upperBound="-1"
+        eType="#//Attribute" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EReference" name="accessMethod" upperBound="-1"
+        eType="#//AccessMethod" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Property" eSuperTypes="#//Resource"/>
+  <eClassifiers xsi:type="ecore:EClass" name="SensorData" eSuperTypes="#//Resource"/>
+  <eClassifiers xsi:type="ecore:EClass" name="StateVariable" eSuperTypes="#//Resource">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="modifier" upperBound="-1"
+        eType="#//Action" eOpposite="#//Action/state"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Action" eSuperTypes="#//Resource">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="state" upperBound="-1"
+        eType="#//StateVariable" eOpposite="#//StateVariable/modifier"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Attribute" eSuperTypes="#//TypedElement">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="metadata" upperBound="-1"
+        eType="#//Metadata" containment="true"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Metadata" eSuperTypes="#//TypedElement"/>
+  <eClassifiers xsi:type="ecore:EClass" name="AccessMethod">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="parameter" upperBound="-1"
+        eType="#//Parameter" containment="true"/>
+    <eStructuralFeatures xsi:type="ecore:EAttribute" name="type" eType="#//AccessMethodType"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Parameter" eSuperTypes="#//TypedElement"/>
+  <eClassifiers xsi:type="ecore:EEnum" name="AccessMethodType">
+    <eLiterals name="GET" literal="GET"/>
+    <eLiterals name="SET"/>
+    <eLiterals name="ACT"/>
+    <eLiterals name="SUBSCRIBE"/>
+    <eLiterals name="UNSUBSCRIBE"/>
+  </eClassifiers>
+  <eClassifiers xsi:type="ecore:EClass" name="Gateway" eSuperTypes="#//NamedElement">
+    <eStructuralFeatures xsi:type="ecore:EReference" name="device" upperBound="-1"
+        eType="#//Device" containment="true"/>
+  </eClassifiers>
+</ecore:EPackage>
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/models/resource.ecore_diagram b/bnd/org.eclipse.sensinact.studio.model.resource/models/resource.ecore_diagram
new file mode 100644
index 0000000..212f9eb
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/models/resource.ecore_diagram
@@ -0,0 +1,449 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<notation:Diagram xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore" xmlns:notation="http://www.eclipse.org/gmf/runtime/1.0.2/notation" xmi:id="_i66qMGN5EeSbPJZNvDzNmw" type="Ecore" measurementUnit="Pixel">
+  <children xmi:type="notation:Shape" xmi:id="_jQyMgGN5EeSbPJZNvDzNmw" type="2001" fontName="Cantarell">
+    <children xmi:type="notation:DecorationNode" xmi:id="_jQzaoGN5EeSbPJZNvDzNmw" type="5001"/>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ0owGN5EeSbPJZNvDzNmw" type="7001">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ0owWN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ0owmN5EeSbPJZNvDzNmw"/>
+      <layoutConstraint xmi:type="notation:Ratio" xmi:id="_7tc6QGN6EeSbPJZNvDzNmw" value="0.22641509433962265"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ1P0GN5EeSbPJZNvDzNmw" type="7002">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ1P0WN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ1P0mN5EeSbPJZNvDzNmw"/>
+      <layoutConstraint xmi:type="notation:Ratio" xmi:id="_7tdhUGN6EeSbPJZNvDzNmw" value="0.22641509433962265"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ1P02N5EeSbPJZNvDzNmw" type="7003">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ1P1GN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ1P1WN5EeSbPJZNvDzNmw"/>
+      <layoutConstraint xmi:type="notation:Ratio" xmi:id="_7tdhUWN6EeSbPJZNvDzNmw" value="0.22641509433962265"/>
+    </children>
+    <element xmi:type="ecore:EClass" href="resource.ecore#//Devices"/>
+    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_jQyMgWN5EeSbPJZNvDzNmw" x="-48" y="-180" width="145"/>
+  </children>
+  <children xmi:type="notation:Shape" xmi:id="_jQ1P1mN5EeSbPJZNvDzNmw" type="2001" fontName="Cantarell">
+    <children xmi:type="notation:DecorationNode" xmi:id="_jQ124GN5EeSbPJZNvDzNmw" type="5001"/>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ124WN5EeSbPJZNvDzNmw" type="7001">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ124mN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ1242N5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ125GN5EeSbPJZNvDzNmw" type="7002">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ125WN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ125mN5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ1252N5EeSbPJZNvDzNmw" type="7003">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ126GN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ126WN5EeSbPJZNvDzNmw"/>
+    </children>
+    <element xmi:type="ecore:EClass" href="resource.ecore#//Device"/>
+    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_jQ1P12N5EeSbPJZNvDzNmw" x="12" y="-72"/>
+  </children>
+  <children xmi:type="notation:Shape" xmi:id="_jQ126mN5EeSbPJZNvDzNmw" type="2001" fontName="Cantarell">
+    <children xmi:type="notation:DecorationNode" xmi:id="_jQ2d8WN5EeSbPJZNvDzNmw" type="5001"/>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ2d8mN5EeSbPJZNvDzNmw" type="7001">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ2d82N5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ2d9GN5EeSbPJZNvDzNmw"/>
+      <layoutConstraint xmi:type="notation:Ratio" xmi:id="_8-2QsGN6EeSbPJZNvDzNmw" value="0.32786885245901637"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ2d9WN5EeSbPJZNvDzNmw" type="7002">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ2d9mN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ2d92N5EeSbPJZNvDzNmw"/>
+      <layoutConstraint xmi:type="notation:Ratio" xmi:id="_8-2QsWN6EeSbPJZNvDzNmw" value="0.19672131147540983"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ2d-GN5EeSbPJZNvDzNmw" type="7003">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ2d-WN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ2d-mN5EeSbPJZNvDzNmw"/>
+      <layoutConstraint xmi:type="notation:Ratio" xmi:id="_8-23wGN6EeSbPJZNvDzNmw" value="0.19672131147540983"/>
+    </children>
+    <element xmi:type="ecore:EClass" href="resource.ecore#//NamedElement"/>
+    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_jQ2d8GN5EeSbPJZNvDzNmw" x="276" y="-180"/>
+  </children>
+  <children xmi:type="notation:Shape" xmi:id="_jQ3FAGN5EeSbPJZNvDzNmw" type="2001" fontName="Cantarell">
+    <children xmi:type="notation:DecorationNode" xmi:id="_jQ3FAmN5EeSbPJZNvDzNmw" type="5001"/>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ3FA2N5EeSbPJZNvDzNmw" type="7001">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ3FBGN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ3FBWN5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ3FBmN5EeSbPJZNvDzNmw" type="7002">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ3FB2N5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ3FCGN5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ3FCWN5EeSbPJZNvDzNmw" type="7003">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ3FCmN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ3FC2N5EeSbPJZNvDzNmw"/>
+    </children>
+    <element xmi:type="ecore:EClass" href="resource.ecore#//TypedElement"/>
+    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_jQ3FAWN5EeSbPJZNvDzNmw" x="408" y="-72"/>
+  </children>
+  <children xmi:type="notation:Shape" xmi:id="_jQ3sEGN5EeSbPJZNvDzNmw" type="2001" fontName="Cantarell">
+    <children xmi:type="notation:DecorationNode" xmi:id="_jQ3sEmN5EeSbPJZNvDzNmw" type="5001"/>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ3sE2N5EeSbPJZNvDzNmw" type="7001">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ3sFGN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ3sFWN5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ3sFmN5EeSbPJZNvDzNmw" type="7002">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ3sF2N5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ3sGGN5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ3sGWN5EeSbPJZNvDzNmw" type="7003">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ3sGmN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ4TIGN5EeSbPJZNvDzNmw"/>
+    </children>
+    <element xmi:type="ecore:EClass" href="resource.ecore#//Service"/>
+    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_jQ3sEWN5EeSbPJZNvDzNmw" x="36" y="72"/>
+  </children>
+  <children xmi:type="notation:Shape" xmi:id="_jQ4TIWN5EeSbPJZNvDzNmw" type="2001" fontName="Cantarell">
+    <children xmi:type="notation:DecorationNode" xmi:id="_jQ4TI2N5EeSbPJZNvDzNmw" type="5001"/>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ4TJGN5EeSbPJZNvDzNmw" type="7001">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ4TJWN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ4TJmN5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ4TJ2N5EeSbPJZNvDzNmw" type="7002">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ4TKGN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ4TKWN5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ46MGN5EeSbPJZNvDzNmw" type="7003">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ46MWN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ46MmN5EeSbPJZNvDzNmw"/>
+    </children>
+    <element xmi:type="ecore:EClass" href="resource.ecore#//Resource"/>
+    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_jQ4TImN5EeSbPJZNvDzNmw" x="72" y="216"/>
+  </children>
+  <children xmi:type="notation:Shape" xmi:id="_jQ46M2N5EeSbPJZNvDzNmw" type="2001" fontName="Cantarell">
+    <children xmi:type="notation:DecorationNode" xmi:id="_jQ46NWN5EeSbPJZNvDzNmw" type="5001"/>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ46NmN5EeSbPJZNvDzNmw" type="7001">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ46N2N5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ46OGN5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ46OWN5EeSbPJZNvDzNmw" type="7002">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ46OmN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ46O2N5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ5hQGN5EeSbPJZNvDzNmw" type="7003">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ5hQWN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ5hQmN5EeSbPJZNvDzNmw"/>
+    </children>
+    <element xmi:type="ecore:EClass" href="resource.ecore#//Property"/>
+    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_jQ46NGN5EeSbPJZNvDzNmw" x="-60" y="384"/>
+  </children>
+  <children xmi:type="notation:Shape" xmi:id="_jQ5hQ2N5EeSbPJZNvDzNmw" type="2001" fontName="Cantarell">
+    <children xmi:type="notation:DecorationNode" xmi:id="_jQ5hRWN5EeSbPJZNvDzNmw" type="5001"/>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ5hRmN5EeSbPJZNvDzNmw" type="7001">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ5hR2N5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ5hSGN5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ6IUGN5EeSbPJZNvDzNmw" type="7002">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ6IUWN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ6IUmN5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ6IU2N5EeSbPJZNvDzNmw" type="7003">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ6IVGN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ6IVWN5EeSbPJZNvDzNmw"/>
+    </children>
+    <element xmi:type="ecore:EClass" href="resource.ecore#//SensorData"/>
+    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_jQ5hRGN5EeSbPJZNvDzNmw" x="12" y="384"/>
+  </children>
+  <children xmi:type="notation:Shape" xmi:id="_jQ6IVmN5EeSbPJZNvDzNmw" type="2001" fontName="Cantarell">
+    <children xmi:type="notation:DecorationNode" xmi:id="_jQ6IWGN5EeSbPJZNvDzNmw" type="5001"/>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ6IWWN5EeSbPJZNvDzNmw" type="7001">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ6IWmN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ6IW2N5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ6vYGN5EeSbPJZNvDzNmw" type="7002">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ6vYWN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ6vYmN5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ6vY2N5EeSbPJZNvDzNmw" type="7003">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ6vZGN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ6vZWN5EeSbPJZNvDzNmw"/>
+    </children>
+    <element xmi:type="ecore:EClass" href="resource.ecore#//StateVariable"/>
+    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_jQ6IV2N5EeSbPJZNvDzNmw" x="264" y="384"/>
+  </children>
+  <children xmi:type="notation:Shape" xmi:id="_jQ6vZmN5EeSbPJZNvDzNmw" type="2001" fontName="Cantarell">
+    <children xmi:type="notation:DecorationNode" xmi:id="_jQ6vaGN5EeSbPJZNvDzNmw" type="5001"/>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ6vaWN5EeSbPJZNvDzNmw" type="7001">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ7WcGN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ7WcWN5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ7WcmN5EeSbPJZNvDzNmw" type="7002">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ7Wc2N5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ7WdGN5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ7WdWN5EeSbPJZNvDzNmw" type="7003">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ7WdmN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ7Wd2N5EeSbPJZNvDzNmw"/>
+    </children>
+    <element xmi:type="ecore:EClass" href="resource.ecore#//Action"/>
+    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_jQ6vZ2N5EeSbPJZNvDzNmw" x="120" y="384"/>
+  </children>
+  <children xmi:type="notation:Shape" xmi:id="_jQ7WeGN5EeSbPJZNvDzNmw" type="2001" fontName="Cantarell">
+    <children xmi:type="notation:DecorationNode" xmi:id="_jQ7WemN5EeSbPJZNvDzNmw" type="5001"/>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ79gGN5EeSbPJZNvDzNmw" type="7001">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ79gWN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ79gmN5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ79g2N5EeSbPJZNvDzNmw" type="7002">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ79hGN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ79hWN5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ79hmN5EeSbPJZNvDzNmw" type="7003">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ79h2N5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ79iGN5EeSbPJZNvDzNmw"/>
+    </children>
+    <element xmi:type="ecore:EClass" href="resource.ecore#//Attribute"/>
+    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_jQ7WeWN5EeSbPJZNvDzNmw" x="300" y="72"/>
+  </children>
+  <children xmi:type="notation:Shape" xmi:id="_jQ79iWN5EeSbPJZNvDzNmw" type="2001" fontName="Cantarell">
+    <children xmi:type="notation:DecorationNode" xmi:id="_jQ8kkGN5EeSbPJZNvDzNmw" type="5001"/>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ8kkWN5EeSbPJZNvDzNmw" type="7001">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ8kkmN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ8kk2N5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ8klGN5EeSbPJZNvDzNmw" type="7002">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ8klWN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ8klmN5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ8kl2N5EeSbPJZNvDzNmw" type="7003">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ8kmGN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ8kmWN5EeSbPJZNvDzNmw"/>
+    </children>
+    <element xmi:type="ecore:EClass" href="resource.ecore#//Metadata"/>
+    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_jQ79imN5EeSbPJZNvDzNmw" x="444" y="72"/>
+  </children>
+  <children xmi:type="notation:Shape" xmi:id="_jQ8kmmN5EeSbPJZNvDzNmw" type="2001" fontName="Cantarell">
+    <children xmi:type="notation:DecorationNode" xmi:id="_jQ9LoGN5EeSbPJZNvDzNmw" type="5001"/>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ9LoWN5EeSbPJZNvDzNmw" type="7001">
+      <children xmi:type="notation:Node" xmi:id="_9BX1sGN5EeSbPJZNvDzNmw" type="3001">
+        <element xmi:type="ecore:EAttribute" href="resource.ecore#//AccessMethod/type"/>
+        <layoutConstraint xmi:type="notation:Location" xmi:id="_9BX1sWN5EeSbPJZNvDzNmw"/>
+      </children>
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ9LomN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ9Lo2N5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ9LpGN5EeSbPJZNvDzNmw" type="7002">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ9LpWN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ9LpmN5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ9Lp2N5EeSbPJZNvDzNmw" type="7003">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ9LqGN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ9LqWN5EeSbPJZNvDzNmw"/>
+    </children>
+    <element xmi:type="ecore:EClass" href="resource.ecore#//AccessMethod"/>
+    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_jQ8km2N5EeSbPJZNvDzNmw" x="300" y="276"/>
+  </children>
+  <children xmi:type="notation:Shape" xmi:id="_jQ9LqmN5EeSbPJZNvDzNmw" type="2001" fontName="Cantarell">
+    <children xmi:type="notation:DecorationNode" xmi:id="_jQ9ysGN5EeSbPJZNvDzNmw" type="5001"/>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ9ysWN5EeSbPJZNvDzNmw" type="7001">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ9ysmN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ9ys2N5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ9ytGN5EeSbPJZNvDzNmw" type="7002">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ9ytWN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ9ytmN5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ9yt2N5EeSbPJZNvDzNmw" type="7003">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ9yuGN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ9yuWN5EeSbPJZNvDzNmw"/>
+    </children>
+    <element xmi:type="ecore:EClass" href="resource.ecore#//Parameter"/>
+    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_jQ9Lq2N5EeSbPJZNvDzNmw" x="528" y="72"/>
+  </children>
+  <children xmi:type="notation:Shape" xmi:id="_jQ-ZwGN5EeSbPJZNvDzNmw" type="2005" fontName="Cantarell">
+    <children xmi:type="notation:DecorationNode" xmi:id="_jQ-ZwmN5EeSbPJZNvDzNmw" type="5005"/>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ-Zw2N5EeSbPJZNvDzNmw" type="7011">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ-ZxGN5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ-ZxWN5EeSbPJZNvDzNmw"/>
+    </children>
+    <children xmi:type="notation:BasicCompartment" xmi:id="_jQ-ZxmN5EeSbPJZNvDzNmw" type="7012">
+      <styles xmi:type="notation:SortingStyle" xmi:id="_jQ-Zx2N5EeSbPJZNvDzNmw"/>
+      <styles xmi:type="notation:FilteringStyle" xmi:id="_jQ-ZyGN5EeSbPJZNvDzNmw"/>
+    </children>
+    <element xmi:type="ecore:EEnum" href="resource.ecore#//AccessMethodType"/>
+    <layoutConstraint xmi:type="notation:Bounds" xmi:id="_jQ-ZwWN5EeSbPJZNvDzNmw" x="648" y="120"/>
+  </children>
+  <styles xmi:type="notation:DiagramStyle" xmi:id="_i66qMWN5EeSbPJZNvDzNmw"/>
+  <element xmi:type="ecore:EPackage" href="resource.ecore#/"/>
+  <edges xmi:type="notation:Connector" xmi:id="_jTAaEGN5EeSbPJZNvDzNmw" type="4004" source="_jQ1P1mN5EeSbPJZNvDzNmw" target="_jQ126mN5EeSbPJZNvDzNmw" routing="Tree">
+    <styles xmi:type="notation:FontStyle" xmi:id="_jTAaEWN5EeSbPJZNvDzNmw" fontName="Cantarell"/>
+    <element xsi:nil="true"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_jTAaEmN5EeSbPJZNvDzNmw" points="[1, -7, -108, 108]$[1, -19, -108, 96]$[133, -19, 24, 96]$[133, -54, 24, 61]"/>
+    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUb9cWN5EeSbPJZNvDzNmw" id="(0.8095238095238095,0.11475409836065574)"/>
+    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUb9cmN5EeSbPJZNvDzNmw" id="(0.34285714285714286,0.0)"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_jTFSkGN5EeSbPJZNvDzNmw" type="4004" source="_jQ3sEGN5EeSbPJZNvDzNmw" target="_jQ126mN5EeSbPJZNvDzNmw" routing="Tree">
+    <styles xmi:type="notation:FontStyle" xmi:id="_jTFSkWN5EeSbPJZNvDzNmw" fontName="Cantarell"/>
+    <element xsi:nil="true"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_jTFSkmN5EeSbPJZNvDzNmw" points="[0, -14, -162, 252]$[0, -170, -162, 96]$[168, -170, 6, 96]$[168, -205, 6, 61]"/>
+    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUckgGN5EeSbPJZNvDzNmw" id="(0.8979591836734694,0.22950819672131148)"/>
+    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUckgWN5EeSbPJZNvDzNmw" id="(0.5142857142857142,0.0)"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_jTKLEGN5EeSbPJZNvDzNmw" type="4004" source="_jQ4TIWN5EeSbPJZNvDzNmw" target="_jQ126mN5EeSbPJZNvDzNmw" routing="Tree">
+    <styles xmi:type="notation:FontStyle" xmi:id="_jTKLEWN5EeSbPJZNvDzNmw" fontName="Cantarell"/>
+    <element xsi:nil="true"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_jTKLEmN5EeSbPJZNvDzNmw" points="[92, -61, -156, 396]$[92, -361, -156, 96]$[224, -361, -24, 96]$[224, -396, -24, 61]"/>
+    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUckgmN5EeSbPJZNvDzNmw" id="(0.272108843537415,1.0)"/>
+    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUckg2N5EeSbPJZNvDzNmw" id="(0.8,0.0)"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_jTMAQGN5EeSbPJZNvDzNmw" type="4004" source="_jQ46M2N5EeSbPJZNvDzNmw" target="_jQ4TIWN5EeSbPJZNvDzNmw" routing="Tree">
+    <styles xmi:type="notation:FontStyle" xmi:id="_jTMAQWN5EeSbPJZNvDzNmw" fontName="Cantarell"/>
+    <element xsi:nil="true"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_jTMAQmN5EeSbPJZNvDzNmw" points="[0, -53, -123, 168]$[0, -77, -123, 144]$[173, -77, 50, 144]$[173, -160, 50, 61]"/>
+    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUY6IWN5EeSbPJZNvDzNmw" id="(0.49230769230769234,1.0)"/>
+    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUY6ImN5EeSbPJZNvDzNmw" id="(0.1564625850340136,0.0)"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_jTN1cGN5EeSbPJZNvDzNmw" type="4004" source="_jQ5hQ2N5EeSbPJZNvDzNmw" target="_jQ4TIWN5EeSbPJZNvDzNmw" routing="Tree">
+    <styles xmi:type="notation:FontStyle" xmi:id="_jTN1cWN5EeSbPJZNvDzNmw" fontName="Cantarell"/>
+    <element xsi:nil="true"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_jTN1cmN5EeSbPJZNvDzNmw" points="[0, -53, -136, 168]$[0, -77, -136, 144]$[93, -77, -43, 144]$[93, -160, -43, 61]"/>
+    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUYTE2N5EeSbPJZNvDzNmw" id="(0.49382716049382713,1.0)"/>
+    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUY6IGN5EeSbPJZNvDzNmw" id="(0.7891156462585034,0.0)"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_jTPDkGN5EeSbPJZNvDzNmw" type="4002" source="_jQ6IVmN5EeSbPJZNvDzNmw" target="_jQ6vZmN5EeSbPJZNvDzNmw" routing="Rectilinear">
+    <children xmi:type="notation:DecorationNode" xmi:id="_jTPqoGN5EeSbPJZNvDzNmw" type="6001">
+      <layoutConstraint xmi:type="notation:Location" xmi:id="_jTPqoWN5EeSbPJZNvDzNmw" x="17" y="-20"/>
+    </children>
+    <children xmi:type="notation:DecorationNode" xmi:id="_jTPqomN5EeSbPJZNvDzNmw" type="6003">
+      <layoutConstraint xmi:type="notation:Location" xmi:id="_jTPqo2N5EeSbPJZNvDzNmw" x="-4" y="16"/>
+    </children>
+    <styles xmi:type="notation:FontStyle" xmi:id="_jTPDkWN5EeSbPJZNvDzNmw" fontName="Cantarell"/>
+    <element xmi:type="ecore:EReference" href="resource.ecore#//StateVariable/modifier"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_jTPDkmN5EeSbPJZNvDzNmw" points="[-83, 24, 82, -29]$[-139, 24, 26, -29]"/>
+    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUaIQmN5EeSbPJZNvDzNmw" id="(0.9222222222222223,0.0)"/>
+    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUaIQ2N5EeSbPJZNvDzNmw" id="(0.5,1.0)"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_jTRf0GN5EeSbPJZNvDzNmw" type="4004" source="_jQ6IVmN5EeSbPJZNvDzNmw" target="_jQ4TIWN5EeSbPJZNvDzNmw" routing="Tree">
+    <styles xmi:type="notation:FontStyle" xmi:id="_jTRf0WN5EeSbPJZNvDzNmw" fontName="Cantarell"/>
+    <element xsi:nil="true"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_jTRf0mN5EeSbPJZNvDzNmw" points="[0, -53, 183, 168]$[0, -77, 183, 144]$[-165, -77, 18, 144]$[-165, -160, 18, 61]"/>
+    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUaIQGN5EeSbPJZNvDzNmw" id="(0.5,1.0)"/>
+    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUaIQWN5EeSbPJZNvDzNmw" id="(0.3673469387755102,0.0)"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_jTTVAGN5EeSbPJZNvDzNmw" type="4002" source="_jQ6vZmN5EeSbPJZNvDzNmw" target="_jQ6IVmN5EeSbPJZNvDzNmw" routing="Rectilinear">
+    <children xmi:type="notation:DecorationNode" xmi:id="_jTTVA2N5EeSbPJZNvDzNmw" type="6001">
+      <layoutConstraint xmi:type="notation:Location" xmi:id="_jTTVBGN5EeSbPJZNvDzNmw" x="12" y="-15"/>
+    </children>
+    <children xmi:type="notation:DecorationNode" xmi:id="_jTTVBWN5EeSbPJZNvDzNmw" type="6003">
+      <layoutConstraint xmi:type="notation:Location" xmi:id="_jTTVBmN5EeSbPJZNvDzNmw" x="3" y="21"/>
+    </children>
+    <styles xmi:type="notation:FontStyle" xmi:id="_jTTVAWN5EeSbPJZNvDzNmw" fontName="Cantarell"/>
+    <element xmi:type="ecore:EReference" href="resource.ecore#//Action/state"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_jTTVAmN5EeSbPJZNvDzNmw" points="[39, -30, -133, 23]$[95, -30, -77, 23]"/>
+    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUXE8mN5EeSbPJZNvDzNmw" id="(0.25,1.0)"/>
+    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUXE82N5EeSbPJZNvDzNmw" id="(0.8555555555555555,0.0)"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_jTVKMGN5EeSbPJZNvDzNmw" type="4004" source="_jQ6vZmN5EeSbPJZNvDzNmw" target="_jQ4TIWN5EeSbPJZNvDzNmw" routing="Tree">
+    <styles xmi:type="notation:FontStyle" xmi:id="_jTVKMWN5EeSbPJZNvDzNmw" fontName="Cantarell"/>
+    <element xsi:nil="true"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_jTVKMmN5EeSbPJZNvDzNmw" points="[-15, -53, -49, 168]$[-15, -89, -49, 132]$[21, -89, -13, 132]$[21, -160, -13, 61]"/>
+    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUdLkGN5EeSbPJZNvDzNmw" id="(0.75,1.0)"/>
+    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUdLkWN5EeSbPJZNvDzNmw" id="(0.5782312925170068,0.0)"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_jTW_YGN5EeSbPJZNvDzNmw" type="4004" source="_jQ7WeGN5EeSbPJZNvDzNmw" target="_jQ126mN5EeSbPJZNvDzNmw" routing="Tree">
+    <styles xmi:type="notation:FontStyle" xmi:id="_jTW_YWN5EeSbPJZNvDzNmw" fontName="Cantarell"/>
+    <element xsi:nil="true"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_jTW_YmN5EeSbPJZNvDzNmw" points="[19, -53, -35, 396]$[19, -356, -35, 93]$[19, -356, -35, 93]$[19, -388, -35, 61]"/>
+    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUZhMGN5EeSbPJZNvDzNmw" id="(0.25,1.0)"/>
+    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUZhMWN5EeSbPJZNvDzNmw" id="(0.9047619047619048,0.0)"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_jTYNgGN5EeSbPJZNvDzNmw" type="4004" source="_jQ7WeGN5EeSbPJZNvDzNmw" target="_jQ3FAGN5EeSbPJZNvDzNmw" routing="Rectilinear">
+    <styles xmi:type="notation:FontStyle" xmi:id="_jTYNgWN5EeSbPJZNvDzNmw" fontName="Cantarell"/>
+    <element xsi:nil="true"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_jTYNgmN5EeSbPJZNvDzNmw" points="[14, -53, -110, 144]$[14, -77, -110, 120]$[146, -77, 22, 120]$[146, -136, 22, 61]"/>
+    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUZhMmN5EeSbPJZNvDzNmw" id="(0.5,1.0)"/>
+    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUZhM2N5EeSbPJZNvDzNmw" id="(0.49504950495049505,0.0)"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_jTaCsGN5EeSbPJZNvDzNmw" type="4004" source="_jQ79iWN5EeSbPJZNvDzNmw" target="_jQ126mN5EeSbPJZNvDzNmw" routing="Tree">
+    <styles xmi:type="notation:FontStyle" xmi:id="_jTaCsWN5EeSbPJZNvDzNmw" fontName="Cantarell"/>
+    <element xsi:nil="true"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_jTaCsmN5EeSbPJZNvDzNmw" points="[12, -53, 101, 252]$[12, -65, 101, 240]$[-119, -65, -30, 240]$[-119, -244, -30, 61]"/>
+    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUavUmN5EeSbPJZNvDzNmw" id="(0.32857142857142857,1.0)"/>
+    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUbWYGN5EeSbPJZNvDzNmw" id="(0.8571428571428571,0.0)"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_jTbQ0GN5EeSbPJZNvDzNmw" type="4004" source="_jQ79iWN5EeSbPJZNvDzNmw" target="_jQ3FAGN5EeSbPJZNvDzNmw" routing="Rectilinear">
+    <styles xmi:type="notation:FontStyle" xmi:id="_jTbQ0WN5EeSbPJZNvDzNmw" fontName="Cantarell"/>
+    <element xsi:nil="true"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_jTbQ0mN5EeSbPJZNvDzNmw" points="[-10, -53, 47, 144]$[-10, -136, 47, 61]"/>
+    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUavUGN5EeSbPJZNvDzNmw" id="(0.6571428571428571,1.0)"/>
+    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUavUWN5EeSbPJZNvDzNmw" id="(0.24752475247524752,0.0)"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_jTfiQGN5EeSbPJZNvDzNmw" type="4004" source="_jQ9LqmN5EeSbPJZNvDzNmw" target="_jQ126mN5EeSbPJZNvDzNmw" routing="Tree">
+    <styles xmi:type="notation:FontStyle" xmi:id="_jTfiQWN5EeSbPJZNvDzNmw" fontName="Cantarell"/>
+    <element xsi:nil="true"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_jTfiQmN5EeSbPJZNvDzNmw" points="[0, -17, 216, 439]$[0, -413, 216, 43]$[-251, -413, -35, 43]$[-251, -448, -35, 8]"/>
+    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUXsAmN5EeSbPJZNvDzNmw" id="(0.8082191780821918,0.32075471698113206)"/>
+    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUYTEGN5EeSbPJZNvDzNmw" id="(0.9047619047619048,0.8688524590163934)"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_jTgwYGN5EeSbPJZNvDzNmw" type="4004" source="_jQ9LqmN5EeSbPJZNvDzNmw" target="_jQ3FAGN5EeSbPJZNvDzNmw" routing="Rectilinear">
+    <styles xmi:type="notation:FontStyle" xmi:id="_jTgwYWN5EeSbPJZNvDzNmw" fontName="Cantarell"/>
+    <element xsi:nil="true"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_jTgwYmN5EeSbPJZNvDzNmw" points="[-17, -53, 76, 144]$[-17, -77, 76, 120]$[-96, -77, -3, 120]$[-96, -136, -3, 61]"/>
+    <sourceAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUXsAGN5EeSbPJZNvDzNmw" id="(0.6575342465753424,1.0)"/>
+    <targetAnchor xmi:type="notation:IdentityAnchor" xmi:id="_jUXsAWN5EeSbPJZNvDzNmw" id="(0.7425742574257426,0.0)"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_o9M8wGN5EeSbPJZNvDzNmw" type="4003" source="_jQyMgGN5EeSbPJZNvDzNmw" target="_jQ1P1mN5EeSbPJZNvDzNmw" routing="Rectilinear">
+    <children xmi:type="notation:DecorationNode" xmi:id="_o9Nj0GN5EeSbPJZNvDzNmw" type="6002">
+      <layoutConstraint xmi:type="notation:Location" xmi:id="_o9Nj0WN5EeSbPJZNvDzNmw" x="12" y="-23"/>
+    </children>
+    <children xmi:type="notation:DecorationNode" xmi:id="_o9Nj0mN5EeSbPJZNvDzNmw" type="6004">
+      <layoutConstraint xmi:type="notation:Location" xmi:id="_o9Nj02N5EeSbPJZNvDzNmw" x="-8" y="19"/>
+    </children>
+    <styles xmi:type="notation:FontStyle" xmi:id="_o9M8wWN5EeSbPJZNvDzNmw" fontName="Cantarell"/>
+    <element xmi:type="ecore:EReference" href="resource.ecore#//Devices/device"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_o9M8wmN5EeSbPJZNvDzNmw" points="[17, 27, -102, -154]$[99, 151, -20, -30]"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_-VPNsGPvEeS6p_6z2x3SEA" type="4003" source="_jQ1P1mN5EeSbPJZNvDzNmw" target="_jQ3sEGN5EeSbPJZNvDzNmw" routing="Rectilinear">
+    <children xmi:type="notation:DecorationNode" xmi:id="_-VP0wGPvEeS6p_6z2x3SEA" type="6002">
+      <layoutConstraint xmi:type="notation:Location" xmi:id="_-VP0wWPvEeS6p_6z2x3SEA" x="25" y="-29"/>
+    </children>
+    <children xmi:type="notation:DecorationNode" xmi:id="_-VP0wmPvEeS6p_6z2x3SEA" type="6004">
+      <layoutConstraint xmi:type="notation:Location" xmi:id="_-VP0w2PvEeS6p_6z2x3SEA" x="-4" y="15"/>
+    </children>
+    <styles xmi:type="notation:FontStyle" xmi:id="_-VPNsWPvEeS6p_6z2x3SEA" fontName="Cantarell"/>
+    <element xmi:type="ecore:EReference" href="resource.ecore#//Device/service"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_-VPNsmPvEeS6p_6z2x3SEA" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_-VTfIGPvEeS6p_6z2x3SEA" type="4003" source="_jQ3sEGN5EeSbPJZNvDzNmw" target="_jQ4TIWN5EeSbPJZNvDzNmw" routing="Rectilinear">
+    <children xmi:type="notation:DecorationNode" xmi:id="_-VTfI2PvEeS6p_6z2x3SEA" type="6002">
+      <layoutConstraint xmi:type="notation:Location" xmi:id="_-VTfJGPvEeS6p_6z2x3SEA" x="25" y="-27"/>
+    </children>
+    <children xmi:type="notation:DecorationNode" xmi:id="_-VUGMGPvEeS6p_6z2x3SEA" type="6004">
+      <layoutConstraint xmi:type="notation:Location" xmi:id="_-VUGMWPvEeS6p_6z2x3SEA" x="-4" y="21"/>
+    </children>
+    <styles xmi:type="notation:FontStyle" xmi:id="_-VTfIWPvEeS6p_6z2x3SEA" fontName="Cantarell"/>
+    <element xmi:type="ecore:EReference" href="resource.ecore#//Service/resource"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_-VTfImPvEeS6p_6z2x3SEA" points="[0, 0, 0, 0]$[0, 0, 0, 0]"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_-VWicGPvEeS6p_6z2x3SEA" type="4003" source="_jQ4TIWN5EeSbPJZNvDzNmw" target="_jQ7WeGN5EeSbPJZNvDzNmw" routing="Rectilinear">
+    <children xmi:type="notation:DecorationNode" xmi:id="_-VXJgGPvEeS6p_6z2x3SEA" type="6002">
+      <layoutConstraint xmi:type="notation:Location" xmi:id="_-VXJgWPvEeS6p_6z2x3SEA" x="43" y="-88"/>
+    </children>
+    <children xmi:type="notation:DecorationNode" xmi:id="_-VXJgmPvEeS6p_6z2x3SEA" type="6004">
+      <layoutConstraint xmi:type="notation:Location" xmi:id="_-VXJg2PvEeS6p_6z2x3SEA" x="18" y="-14"/>
+    </children>
+    <styles xmi:type="notation:FontStyle" xmi:id="_-VWicWPvEeS6p_6z2x3SEA" fontName="Cantarell"/>
+    <element xmi:type="ecore:EReference" href="resource.ecore#//Resource/attribute"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_-VWicmPvEeS6p_6z2x3SEA" points="[74, -18, -115, 130]$[191, -18, 2, 130]$[191, -121, 2, 27]"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_-VZlwGPvEeS6p_6z2x3SEA" type="4003" source="_jQ4TIWN5EeSbPJZNvDzNmw" target="_jQ8kmmN5EeSbPJZNvDzNmw" routing="Rectilinear">
+    <children xmi:type="notation:DecorationNode" xmi:id="_-VZlw2PvEeS6p_6z2x3SEA" type="6002">
+      <layoutConstraint xmi:type="notation:Location" xmi:id="_-VaM0GPvEeS6p_6z2x3SEA" x="117" y="14"/>
+    </children>
+    <children xmi:type="notation:DecorationNode" xmi:id="_-VaM0WPvEeS6p_6z2x3SEA" type="6004">
+      <layoutConstraint xmi:type="notation:Location" xmi:id="_-VaM0mPvEeS6p_6z2x3SEA" x="18" y="14"/>
+    </children>
+    <styles xmi:type="notation:FontStyle" xmi:id="_-VZlwWPvEeS6p_6z2x3SEA" fontName="Cantarell"/>
+    <element xmi:type="ecore:EReference" href="resource.ecore#//Resource/accessMethod"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_-VZlwmPvEeS6p_6z2x3SEA" points="[74, -6, -163, -54]$[239, -6, 2, -54]$[239, 18, 2, -30]"/>
+  </edges>
+  <edges xmi:type="notation:Connector" xmi:id="_-VfsYGPvEeS6p_6z2x3SEA" type="4003" source="_jQ8kmmN5EeSbPJZNvDzNmw" target="_jQ9LqmN5EeSbPJZNvDzNmw" routing="Rectilinear">
+    <children xmi:type="notation:DecorationNode" xmi:id="_-VgTcGPvEeS6p_6z2x3SEA" type="6002">
+      <layoutConstraint xmi:type="notation:Location" xmi:id="_-VgTcWPvEeS6p_6z2x3SEA" x="122" y="-33"/>
+    </children>
+    <children xmi:type="notation:DecorationNode" xmi:id="_-VgTcmPvEeS6p_6z2x3SEA" type="6004">
+      <layoutConstraint xmi:type="notation:Location" xmi:id="_-VgTc2PvEeS6p_6z2x3SEA" x="32" y="22"/>
+    </children>
+    <styles xmi:type="notation:FontStyle" xmi:id="_-VfsYWPvEeS6p_6z2x3SEA" fontName="Cantarell"/>
+    <element xmi:type="ecore:EReference" href="resource.ecore#//AccessMethod/parameter"/>
+    <bendpoints xmi:type="notation:RelativeBendpoints" xmi:id="_-VfsYmPvEeS6p_6z2x3SEA" points="[83, -6, -99, 202]$[182, -6, 0, 202]$[182, -181, 0, 27]"/>
+  </edges>
+</notation:Diagram>
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/models/resource.genmodel b/bnd/org.eclipse.sensinact.studio.model.resource/models/resource.genmodel
new file mode 100644
index 0000000..5b5bbcf
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/models/resource.genmodel
@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<genmodel:GenModel xmi:version="2.0" xmlns:xmi="http://www.omg.org/XMI" xmlns:ecore="http://www.eclipse.org/emf/2002/Ecore"
+    xmlns:genmodel="http://www.eclipse.org/emf/2002/GenModel" modelDirectory="/org.eclipse.sensinact.studio.model.resource/src-gen"
+    modelPluginID="org.eclipse.sensinact.studio.model.resource" modelName="Resource"
+    rootExtendsClass="org.eclipse.emf.ecore.impl.MinimalEObjectImpl$Container" importerID="org.eclipse.emf.importer.ecore"
+    complianceLevel="6.0" copyrightFields="false" operationReflection="true" importOrganizing="true">
+  <foreignModel>resource.ecore</foreignModel>
+  <genPackages prefix="Resource" basePackage="org.eclipse.sensinact.studio" disposableProviderFactory="true"
+      ecorePackage="resource.ecore#/">
+    <genEnums typeSafeEnumCompatible="false" ecoreEnum="resource.ecore#//AccessMethodType">
+      <genEnumLiterals ecoreEnumLiteral="resource.ecore#//AccessMethodType/GET"/>
+      <genEnumLiterals ecoreEnumLiteral="resource.ecore#//AccessMethodType/SET"/>
+      <genEnumLiterals ecoreEnumLiteral="resource.ecore#//AccessMethodType/ACT"/>
+      <genEnumLiterals ecoreEnumLiteral="resource.ecore#//AccessMethodType/SUBSCRIBE"/>
+      <genEnumLiterals ecoreEnumLiteral="resource.ecore#//AccessMethodType/UNSUBSCRIBE"/>
+    </genEnums>
+    <genClasses ecoreClass="resource.ecore#//Studio">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference resource.ecore#//Studio/gateways"/>
+    </genClasses>
+    <genClasses ecoreClass="resource.ecore#//Device">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute resource.ecore#//Device/friendlyName"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference resource.ecore#//Device/service"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute resource.ecore#//Device/location"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute resource.ecore#//Device/icon"/>
+    </genClasses>
+    <genClasses ecoreClass="resource.ecore#//NamedElement">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute resource.ecore#//NamedElement/name"/>
+    </genClasses>
+    <genClasses ecoreClass="resource.ecore#//TypedElement">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute resource.ecore#//TypedElement/type"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute resource.ecore#//TypedElement/value"/>
+    </genClasses>
+    <genClasses ecoreClass="resource.ecore#//Service">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute resource.ecore#//Service/friendlyName"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference resource.ecore#//Service/resource"/>
+    </genClasses>
+    <genClasses ecoreClass="resource.ecore#//Resource">
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute resource.ecore#//Resource/friendlyName"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference resource.ecore#//Resource/attribute"/>
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference resource.ecore#//Resource/accessMethod"/>
+      <genOperations ecoreOperation="resource.ecore#//Resource/getAccessMethod" body="EList&lt;AccessMethod> accessMethodByType = new EObjectContainmentEList&lt;AccessMethod>(AccessMethod.class, this, ResourcePackage.RESOURCE__ACCESS_METHOD);&#xA;&#x9;&#x9;for (AccessMethod accessMethod : getAccessMethod()) {&#xA;&#x9;&#x9;&#x9;if (accessMethod.getType().equals(type))&#xA;&#x9;&#x9;&#x9;&#x9;accessMethodByType.add(accessMethod);&#xA;&#x9;&#x9;}&#xA;&#x9;&#x9;return accessMethodByType;">
+        <genParameters ecoreParameter="resource.ecore#//Resource/getAccessMethod/type"/>
+      </genOperations>
+    </genClasses>
+    <genClasses ecoreClass="resource.ecore#//Property"/>
+    <genClasses ecoreClass="resource.ecore#//SensorData"/>
+    <genClasses ecoreClass="resource.ecore#//StateVariable">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference resource.ecore#//StateVariable/modifier"/>
+    </genClasses>
+    <genClasses ecoreClass="resource.ecore#//Action">
+      <genFeatures notify="false" createChild="false" propertySortChoices="true" ecoreFeature="ecore:EReference resource.ecore#//Action/state"/>
+    </genClasses>
+    <genClasses ecoreClass="resource.ecore#//Attribute">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference resource.ecore#//Attribute/metadata"/>
+    </genClasses>
+    <genClasses ecoreClass="resource.ecore#//Metadata"/>
+    <genClasses ecoreClass="resource.ecore#//AccessMethod">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference resource.ecore#//AccessMethod/parameter"/>
+      <genFeatures createChild="false" ecoreFeature="ecore:EAttribute resource.ecore#//AccessMethod/type"/>
+    </genClasses>
+    <genClasses ecoreClass="resource.ecore#//Parameter"/>
+    <genClasses ecoreClass="resource.ecore#//Gateway">
+      <genFeatures property="None" children="true" createChild="true" ecoreFeature="ecore:EReference resource.ecore#//Gateway/device"/>
+    </genClasses>
+  </genPackages>
+</genmodel:GenModel>
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/plugin.properties b/bnd/org.eclipse.sensinact.studio.model.resource/plugin.properties
new file mode 100644
index 0000000..2b3b100
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/plugin.properties
@@ -0,0 +1,15 @@
+#
+# Copyright (c) 2018 CEA.
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License v1.0
+# which accompanies this distribution, and is available at
+# http://www.eclipse.org/legal/epl-v10.html
+#
+#  Contributors:
+#     CEA - initial API and implementation and/or initial documentation
+#
+
+#
+
+pluginName = Sensinact-resource Model
+providerName = www.example.org
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/plugin.xml b/bnd/org.eclipse.sensinact.studio.model.resource/plugin.xml
new file mode 100644
index 0000000..42cc0bf
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/plugin.xml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2018 CEA.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+
+     Contributors:
+        CEA - initial API and implementation and/or initial documentation
+
+-->
+<?eclipse version="3.0"?>
+
+<plugin>
+   <extension point="org.eclipse.emf.ecore.generated_package">
+      <!-- @generated sensinact-resource -->
+      <package
+            uri="http://eclipse.org/sensinact/resource"
+            class="org.eclipse.sensinact.studio.resource.ResourcePackage"
+            genModel="models/resource.genmodel"/>
+   </extension>
+
+   <extension point="org.eclipse.emf.ecore.extension_parser">
+      <!-- @generated sensinact-resource -->
+      <parser
+            type="resource"
+            class="org.eclipse.sensinact.studio.resource.impl.ResourceFactoryImpl"/>
+   </extension>
+</plugin>
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/AbstractDescriptor.java b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/AbstractDescriptor.java
new file mode 100644
index 0000000..4f5eb92
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/AbstractDescriptor.java
@@ -0,0 +1,114 @@
+package org.eclipse.sensinact.studio.model.resource.utils;
+
+/**
+ *
+ */
+public abstract class AbstractDescriptor implements Descriptor{
+
+	public static String pathFormat(String path) {
+		if(path == null || path.trim().equals("/"))
+			return "/";
+
+		String formatedPath = path.trim();
+		if(!path.startsWith("/"))
+			formatedPath="/"+formatedPath;
+
+		if(path.endsWith("/"))
+			formatedPath=formatedPath.substring(0,formatedPath.length()-1);	
+
+		return formatedPath;
+	}
+	
+	protected String gateway;
+
+	protected AbstractDescriptor(String gateway) {
+		this.gateway = gateway;
+	}
+	
+	public String getParentPath() {
+		String path =  getPath();
+		int index = path.lastIndexOf('/');
+		return path.substring(0, index);
+	}
+
+	@Override
+	public String toString() {
+		return this.gateway + getPath();
+	}
+
+	@Override
+	public String commonBranch(Descriptor descriptor) {
+		if(descriptor == null || !this.gateway.equals(descriptor.getGateway()))
+			return null;
+
+		String path = pathFormat(descriptor.getPath());
+		String localPath = pathFormat(getPath());
+		
+		int localLength = localPath.length();
+		int pathLength = path.length();
+		
+		int lastSep = -1;
+		int index = 0;
+		
+		while(index < pathLength && index < localLength) {
+			if(localPath.charAt(index)!=path.charAt(index)) {
+				index = lastSep;
+				break;
+			}
+			if(localPath.charAt(index)=='/')
+				lastSep = index;
+
+			index++;
+		}
+		if(index==0)
+			return null;
+
+		return localPath.substring(0,index);	
+	}
+
+	@Override
+	public String getGateway(){
+		return this.gateway;
+	}
+	
+	/** 
+	 * @inheritDoc
+	 * 
+	 * @see java.lang.Comparable#compareTo(java.lang.Object)
+	 * 
+	 * TODO Documentation:
+	 * Compares this object with the specified object for order. Returns a 
+	 * negative integer, zero, or a positive integer as this object is less 
+	 * than, equal to, or greater than the specified object. The implementor 
+	 * must ensure sgn(x.compareTo(y)) == -sgn(y.compareTo(x)) for all x and y. 
+	 * (This implies that x.compareTo(y) must throw an exception 
+	 * iff y.compareTo(x) throws an exception.)
+	 * The implementor must also ensure that the relation is transitive: 
+	 * (x.compareTo(y)>0 && y.compareTo(z)>0) implies x.compareTo(z)>0.
+	 * Finally, the implementor must ensure that x.compareTo(y)==0 implies that 
+	 * sgn(x.compareTo(z)) == sgn(y.compareTo(z)), for all z. It is strongly 
+	 * recommended, but not strictly required that (x.compareTo(y)==0) == (x.equals(y)). 
+	 * Generally speaking, any class that implements the Comparable interface and 
+	 * violates this condition should clearly indicate this fact. The recommended 
+	 * language is "Note: this class has a natural ordering that is inconsistent 
+	 * with equals." In the foregoing description, the notation sgn(expression) 
+	 * designates the mathematical signum function, which is defined to return 
+	 * one of -1, 0, or 1 according to whether the value of expression is negative, 
+	 * zero or positive.
+	 */
+	@Override
+	public int compareTo(Descriptor descriptor) {
+		if(this.gateway.equals(descriptor.getGateway())){
+			
+			String path = pathFormat(descriptor.getPath());
+			String localPath = pathFormat(getPath());
+
+			if(path.startsWith(localPath))
+				return -1;
+
+			if(localPath.startsWith(path))
+				return 1;
+		}
+		return 0;	
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/Constants.java b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/Constants.java
new file mode 100644
index 0000000..a6a3c5e
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/Constants.java
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.resource.utils;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class Constants {
+	
+	public static final ResourceDescriptor createInstallAppRD(String gatewayID) {
+		return new ResourceDescriptor(gatewayID, "AppManager", "admin", "INSTALL");
+	}
+	
+	public static final ResourceDescriptor createUninstallAppRD(String gatewayID) {
+		return new ResourceDescriptor(gatewayID, "AppManager", "admin", "UNINSTALL");
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/Descriptor.java b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/Descriptor.java
new file mode 100644
index 0000000..ab757ad
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/Descriptor.java
@@ -0,0 +1,10 @@
+package org.eclipse.sensinact.studio.model.resource.utils;
+
+public interface Descriptor extends Comparable<Descriptor> {
+
+	String getGateway();
+	
+	String getPath();
+	
+	String commonBranch(Descriptor descriptor);
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/DeviceDescriptor.java b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/DeviceDescriptor.java
new file mode 100644
index 0000000..4ee0126
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/DeviceDescriptor.java
@@ -0,0 +1,92 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.resource.utils;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class DeviceDescriptor extends AbstractDescriptor{
+
+	private final String device;
+	private String icon;
+	private String location;
+
+	public DeviceDescriptor(String gateway, String device) {
+		super(gateway);
+		this.device = device;
+	}
+	
+	public String getGateway() {
+		return gateway;
+	}
+
+	public String getDevice() {
+		return device;
+	}
+
+	public String getIcon() {
+		return icon;
+	}
+
+	public void setIcon(String icon) {
+		this.icon = icon;
+	}
+
+	public String getLocation() {
+		return location;
+	}
+
+	public void setLocation(String location) {
+		this.location=location;
+	}
+	
+	@Override
+	public String toString() {
+		return getGateway() + "/" + getDevice();
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((gateway == null) ? 0 : gateway.hashCode());
+		result = prime * result + ((device == null) ? 0 : device.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		DeviceDescriptor other = (DeviceDescriptor) obj;
+		if (device == null) {
+			if (other.device != null)
+				return false;
+		} else if (!device.equals(other.device))
+			return false;
+		if (gateway == null) {
+			if (other.gateway != null)
+				return false;
+		} else if (!gateway.equals(other.gateway))
+			return false;
+		return true;
+	}
+	
+	@Override
+	public String getPath() {
+		return  "/" + getDevice();
+	}
+	
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/GPScoordinates.java b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/GPScoordinates.java
new file mode 100644
index 0000000..f9de039
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/GPScoordinates.java
@@ -0,0 +1,69 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.resource.utils;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class GPScoordinates {
+
+	private final double lat;
+	private final double lng;
+	
+	public GPScoordinates(double lat, double lng) {
+		this.lat = lat;
+		this.lng = lng;
+	}
+	
+	/**
+	 * 
+	 * @param coords expected format is two flots separated by a ','. ie "3.1245,4.365212"
+	 * @throws InvalidAttributesException 
+	 * @throws GPSparsingException 
+	 */
+	public GPScoordinates(String coords) throws GPSparsingException {
+		try {
+			coords = coords.replace(',', ':');
+			final String[] coordinates = coords.split(":");
+			lat = Double.valueOf(coordinates[0].trim());
+			lng = Double.valueOf(coordinates[1].trim());
+		} catch (Exception e) {
+			throw new GPSparsingException();
+		}
+	}
+	
+	public double getLat() {
+		return lat;
+	}
+	
+	public double getLng() {
+		return lng;
+	}
+	
+	@Override
+	public String toString() {
+		return "[" + lat + ":" + lng + "]";
+	}
+	
+	public boolean equals(Object other) {
+		if (this == other)
+			return true;
+		if (!(other instanceof GPScoordinates))
+			return false;
+		final GPScoordinates that = (GPScoordinates) other;
+		return this.getLat() == that.getLat() && this.getLng() == that.getLng();
+	}
+
+	public int hashCode() {
+		// basic hash, only with lat
+		return new Double(lat).hashCode();
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/GPSparsingException.java b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/GPSparsingException.java
new file mode 100644
index 0000000..0db9694
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/GPSparsingException.java
@@ -0,0 +1,15 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.resource.utils;
+
+public class GPSparsingException extends Exception {
+
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/GatewayDescriptor.java b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/GatewayDescriptor.java
new file mode 100644
index 0000000..160b542
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/GatewayDescriptor.java
@@ -0,0 +1,18 @@
+package org.eclipse.sensinact.studio.model.resource.utils;
+
+/**
+ *
+ */
+public class GatewayDescriptor extends AbstractDescriptor {
+
+
+	protected GatewayDescriptor(String gateway) {
+		super(gateway);
+	}
+
+	@Override
+	public String getPath() {
+		return "/";
+	}
+	
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/JsonUtil.java b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/JsonUtil.java
new file mode 100644
index 0000000..ec715f8
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/JsonUtil.java
@@ -0,0 +1,210 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.resource.utils;
+
+import java.math.BigDecimal;
+import java.util.Iterator;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class JsonUtil {
+
+	public static final String NAME_KEY = "name";
+	public static final String TYPE_KEY = "type";
+	public static final String VALUE_KEY = "value";
+	
+	public static JSONObject createObject(Object... keysValues) throws JSONException {
+		JSONObject retval = new JSONObject();
+
+		for (int i = 0; i < keysValues.length; i += 2) {
+			retval.put((String) keysValues[i], keysValues[i + 1]);
+		}
+
+		return retval;
+	}
+
+	public static JSONArray createArray(Object... elements) throws JSONException {
+		JSONArray jsonArray = new JSONArray();
+		for (Object element : elements) {
+			jsonArray.put(element);
+		}
+		return jsonArray;
+	}
+
+	public static JSONObject createNameTypeValue(String name, String type, Object value) throws JSONException {
+		JSONObject retval = new JSONObject();
+
+		if (value == null)
+			throw new RuntimeException("value is null (name=" + name + " type=" + type + ")");
+		
+		// Types definition
+		final String intType = int.class.toString(); // int
+		final String integerType = Integer.class.getName(); // java.lang.Integer
+		final String bigDecimalType = BigDecimal.class.getName(); // java.math.BigDecimal
+		final String doubleType = double.class.toString(); // double
+		final String objectDoubleType = Double.class.getName(); // java.lang.Double
+		final String booleanType = boolean.class.toString(); // boolean
+		final String objectBooleanType = Boolean.class.getName(); // java.lang.Boolean
+		final String stringType = String.class.getName(); // java.lang.String
+		final String JSONObjectType = JSONObject.class.getName(); // org.json.JSONObject
+		final String JSONObjectTypeShort = "object"; // org.json.JSONObject
+		final String JSONArrayType = JSONArray.class.getName(); // org.json.JSONObject
+		final String JSONArrayTypeShort = "array"; // org.json.JSONObject
+		
+		retval.put(NAME_KEY, name);
+
+		// Integer
+		if (intType.equals(type) || integerType.equals(type) || bigDecimalType.equals(type)) {
+			retval.put(TYPE_KEY, integerType);
+			if (value instanceof Integer) {
+				retval.put(VALUE_KEY, ((Integer) value).intValue());
+				return retval;
+			} else if (value instanceof String) {
+				retval.put(VALUE_KEY, Integer.parseInt((String) value));
+				return retval;
+			} else if (value instanceof BigDecimal) {
+				retval.put(VALUE_KEY, ((BigDecimal) value).intValue());
+				return retval;
+			} else {
+				throw new RuntimeException("expected type is " + type + " but value is of type " + value.getClass().getName());
+			}
+		}
+
+		// Double
+		if (doubleType.equals(type) || objectDoubleType.equals(type)) {
+			retval.put(TYPE_KEY, objectDoubleType);
+			if (value instanceof Double) {
+				retval.put(VALUE_KEY, ((Double) value).doubleValue());
+				return retval;
+			} else if (value instanceof BigDecimal) {
+				retval.put(VALUE_KEY, ((BigDecimal) value).doubleValue());
+				return retval;
+			} else if (value instanceof String) {
+				retval.put(VALUE_KEY, Double.parseDouble((String) value));
+				return retval;
+			} else {
+				throw new RuntimeException("expected type is " + type + " but value is of type " + value.getClass().getName());
+			}
+		}
+
+		// Boolean
+		if (booleanType.equals(type) || objectBooleanType.equals(type)) {
+			retval.put(TYPE_KEY, objectBooleanType);
+			if (value instanceof Boolean) {
+				retval.put(VALUE_KEY, ((Boolean) value).booleanValue());
+				return retval;
+			} else if (value instanceof String) {
+				retval.put(VALUE_KEY, Boolean.parseBoolean((String) value));
+				return retval;
+			} else {
+				throw new RuntimeException("expected type is " + type + " but value is of type " + value.getClass().getCanonicalName());
+			}
+		}
+
+		// String
+		if (stringType.equals(type) || "string".equals(type)) {
+			retval.put(TYPE_KEY, stringType);
+			if (value instanceof String) {
+				String val = (String) value;
+				if (val.length() >= 2) {
+					if ((val.startsWith("\"") && val.endsWith("\"")) || (val.startsWith("'") && val.endsWith("'"))) {
+						val = val.substring(1, val.length() - 1);
+					}
+				}
+				retval.put(VALUE_KEY, val);
+				return retval;
+			} else {
+				throw new RuntimeException("expected type is " + type + " but value is of type " + value.getClass().getCanonicalName());
+			}
+		}
+
+		// JSON Object
+		if (JSONObjectType.equals(type) || JSONObjectTypeShort.equals(type)) {
+			retval.put(TYPE_KEY, JSONObjectTypeShort);
+			if (value instanceof JSONObject) {
+				retval.put(VALUE_KEY, (JSONObject) value);
+				return retval;
+			} else if (value instanceof String) {
+				retval.put(VALUE_KEY, new JSONObject((String) value));
+				return retval;
+			} else {
+				throw new RuntimeException("expected type is " + type + " but value is of type " + value.getClass().getCanonicalName());
+			}
+		}
+
+		// JSON Array
+		if (JSONArrayType.equals(type) || JSONArrayTypeShort.equals(type)) {
+			retval.put(TYPE_KEY, JSONArrayTypeShort);
+			if (value instanceof JSONArray) {
+				retval.put(VALUE_KEY, (JSONArray) value);
+				return retval;
+			} else if (value instanceof String) {
+				retval.put(VALUE_KEY, new JSONArray((String) value));
+				return retval;
+			} else {
+				throw new RuntimeException("expected type is " + type + " but value is of type " + value.getClass().getCanonicalName());
+			}
+		}
+		// Other...
+		throw new RuntimeException("Should never happen");
+	}
+
+	public static String prettyPrintJsonArray(JSONArray array, boolean fullMessage) {
+		StringBuilder sb = new StringBuilder();
+
+		try {
+			if (array.length() == 0) {
+				sb.append("<empty array>");
+			} else if (array.length() == 1) {
+				sb.append("1 element : ");
+				sb.append(array.getString(0));
+			} else {
+				sb.append(array.length() + " elements");
+				if (fullMessage) {
+					for (int i = 0; i < array.length(); i++) {
+						sb.append("\n * " + array.getString(i));
+					}
+				}
+			}
+		} catch (JSONException e) {
+			return "<Error during JSON decoding>";
+		}
+
+		return sb.toString();
+	}
+
+	public static String prettyPrintJsonObject(JSONObject object) {
+		StringBuilder sb = new StringBuilder();
+
+		try {
+			boolean begin = true;
+			Iterator<?> keys = object.keys();
+			while (keys.hasNext()) {
+				String key = (String) keys.next();
+				String value = object.get(key).toString();
+				if (begin)
+					begin = false;
+				else
+					sb.append("\n");
+				sb.append(" * ").append(key).append(" = ").append(value);
+			}
+		} catch (JSONException e) {
+			return "<Error during JSON decoding>";
+		}
+
+		return sb.toString();
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/ResourceDescriptor.java b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/ResourceDescriptor.java
new file mode 100644
index 0000000..2dfed26
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/ResourceDescriptor.java
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.resource.utils;
+
+import org.eclipse.sensinact.studio.http.messages.snamessage.ObjectNameTypeValue;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ResourceDescriptor extends AbstractDescriptor {
+
+	private final String device;
+	private final String service;
+	private final String resource;
+	private ObjectNameTypeValue initial;
+
+	public ResourceDescriptor(String gateway, String device, String service, String resource) {
+		super(gateway);
+		this.device = device;
+		this.service = service;
+		this.resource = resource;
+	}
+
+	public ResourceDescriptor(String text) {
+		super(null);
+		// The substring removes the prefix and suffix used to refer to a resource in the SNA DSL, respectively remove the '[' and ']'.
+		text = text.trim();
+		if (text.startsWith("/") || text.startsWith("["))
+			text = text.substring(1);
+		if (text.endsWith("/") || text.endsWith("]"))
+			text = text.substring(0, text.length()-1);
+		
+		String[] tokens = text.split("/");
+		if (tokens.length != 4 && tokens.length != 5)
+			throw new RuntimeException("Parsing fail while building ResourceDescriptor");
+		 
+		super.gateway  = tokens[0];
+		this.device   = tokens[1];
+		this.service  = tokens[2];
+		this.resource = tokens[3];
+	}
+
+	public void setInitial(ObjectNameTypeValue initial){
+		this.initial = initial;
+	}
+
+	public ObjectNameTypeValue getInitial(){
+		return this.initial;
+	}
+	
+	public DeviceDescriptor toDeviceDescriptor() {
+		return new DeviceDescriptor(gateway, device);
+	}
+
+	public String getDevice() {
+		return device;
+	}
+
+	public String getService() {
+		return service;
+	}
+
+	public String getResource() {
+		return resource;
+	}
+
+	@Override
+	public String getPath() {
+		return  "/" + getDevice()+ "/" + getService()+ "/" + getResource();
+	}
+	
+	public boolean equals(Object other) {
+		if (this == other)
+			return true;
+		if (!(other instanceof ResourceDescriptor))
+			return false;
+		final ResourceDescriptor that = (ResourceDescriptor) other;
+		return eqStr(this.getGateway(), that.getGateway()) && eqStr(this.getDevice(), that.getDevice()) && eqStr(this.getService(), that.getService())
+				&& eqStr(this.getResource(), that.getResource());
+	}
+
+	public int hashCode() {
+		return hash(gateway) * hash(device) * hash(service) * hash(resource);
+	}
+
+	private boolean eqStr(String str1, String str2) {
+		if (str1 == null)
+			if (str2 == null)
+				return true;
+			else
+				return false;
+		else
+			return str1.equals(str2);
+	}
+	
+	private int hash(String str) {
+		if (str == null)
+			return 2;
+		else
+			return str.hashCode();
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/Segments.java b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/Segments.java
new file mode 100644
index 0000000..b78f5f4
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/Segments.java
@@ -0,0 +1,221 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.resource.utils;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.restlet.resource.ClientResource;
+
+import org.eclipse.sensinact.studio.resource.AccessMethodType;
+
+/**
+ * This class is used to represents a REST path in the sensinact API.
+ * For any refactoring in the rest API, just update this (and only this)
+ * class.
+ * 
+ * There is a nested class, called Builder, which goal is to build
+ * Segment instance, checking if constraints are satisfied.
+ * @author Etienne Gandrille
+ */
+public class Segments {
+	
+	private final List<String> segments;
+	private final String gateway;
+
+	private static final String ROOT_SEGMENT = "sensinact";
+	private static final String PROVIDERS  = "providers";
+	private static final String SERVICES = "services";
+	private static final String RESOURCES = "resources";
+	private static final String LOGIN = "login";
+	private static final String AGENT_SUBSCRIBE = "SUBSCRIBE";
+	private static final String AGENT_UNSUBSCRIBE = "UNSUBSCRIBE";
+	
+	private Segments(String gateway, List<String> segments) {
+		this.gateway = gateway;
+		this.segments = segments;
+	}
+	
+	public void addToClientResource(ClientResource clientResource) {
+		for (String segment : segments) {
+			clientResource.addSegment(segment);
+		}
+	}
+
+	public String getGateway() {
+		return gateway;
+	}
+	
+	public List<String> getSegments() {
+		return segments;
+	}
+	
+	@Override
+	public String toString() {
+		StringBuilder sb = new StringBuilder();
+		for (String seg : segments) {
+			sb.append("/");
+			sb.append(seg);
+		}
+		return sb.toString();
+	}
+
+	public static class Builder {
+		
+		public Builder() {
+		}
+
+		public BuilderGateway gateway(String gatewayName) {
+			return new BuilderGateway(gatewayName);
+		}
+
+		public BuilderResouce resource(ResourceDescriptor resource) {
+			String gateway = resource.getGateway();
+			String device = resource.getDevice();
+			String service = resource.getService();
+			String res = resource.getResource();
+			
+			return new BuilderResouce(gateway, device, service, res);
+		}
+
+		public BuilderDevice device(DeviceDescriptor descriptor) {
+			return new BuilderDevice(descriptor.getGateway(), descriptor.getDevice());
+		}
+	}
+	
+	public static class BuilderGateway {
+		private final String gateway; 		
+		public BuilderGateway(String gateway) {
+			this.gateway = gateway;
+		}
+		
+		public BuilderDevice device(String deviceId) {
+			return new BuilderDevice(gateway, deviceId);
+		}
+		
+		public BuilderLocation locations() {
+			return new BuilderLocation(gateway);
+		}
+		
+		public BuilderReady root() {
+			return new BuilderReady(gateway, ROOT_SEGMENT);
+		}
+
+		public BuilderReady root(String expr) {
+			return new BuilderReady(gateway, ROOT_SEGMENT + "?" + expr);
+		}
+
+		public BuilderReady devices() {
+			return new BuilderReady(gateway, ROOT_SEGMENT, PROVIDERS);
+		}
+		
+		public BuilderReady login() {
+			return new BuilderReady(gateway, LOGIN);
+		}
+
+		public BuilderReady subscribeAgent() {
+			return new BuilderReady(gateway, ROOT_SEGMENT, AGENT_SUBSCRIBE);
+		}
+		
+		public BuilderReady unsubscribeAgent() {
+			return new BuilderReady(gateway, ROOT_SEGMENT, AGENT_UNSUBSCRIBE);
+		}
+	}
+	
+	public static class BuilderDevice {
+		private final String gateway;
+		private final String device;
+		public BuilderDevice(String gateway, String device) {
+			this.gateway = gateway;
+			this.device = device;
+		}
+		
+		public BuilderReady services() {
+			return new BuilderReady(gateway, ROOT_SEGMENT, PROVIDERS, device, SERVICES);
+		}
+
+		public BuilderService service(String serviceId) {
+			return new BuilderService(gateway, device, serviceId);
+		}
+	}
+		
+	public static class BuilderLocation {
+		private final String gateway;
+		public BuilderLocation(String gateway) {
+			this.gateway = gateway;
+		}
+		
+		public BuilderReady getLocations() {
+			return new BuilderReady(gateway, "jsonpath", "location","GET");
+		}
+	}
+	
+	public static class BuilderService {
+		private final String gateway;
+		private final String device;
+		private final String service;
+		public BuilderService(String gateway, String device, String service) {
+			this.gateway = gateway;
+			this.device = device;
+			this.service = service;
+		}
+		
+		public BuilderReady resources() {
+			return new BuilderReady(gateway, ROOT_SEGMENT, PROVIDERS, device, SERVICES, service, RESOURCES);
+		}
+
+		public BuilderResouce resource(String resource) {
+			return new BuilderResouce(gateway, device, service, resource);
+		}
+	}
+	
+	public static class BuilderResouce {
+		private final String gateway;
+		private final String device;
+		private final String service;
+		private final String resource;
+		
+		public BuilderResouce(String gateway, String device, String service, String resource) {
+			this.gateway = gateway;
+			this.device = device;
+			this.service = service;
+			this.resource = resource;
+		}
+		
+		public Segments build() {
+			return new BuilderReady(gateway, ROOT_SEGMENT, PROVIDERS, device, SERVICES, service, RESOURCES, resource).build();
+		}
+		
+		public BuilderReady method(AccessMethodType access) {
+			return new BuilderReady(gateway, ROOT_SEGMENT, PROVIDERS, device, SERVICES, service, RESOURCES, resource, access.getName());
+		}
+	}
+	
+	public static class BuilderReady {
+		private final List<String> segments;
+		private final String gateway;
+		
+		private BuilderReady(String gateway, String... segments) {
+			this.gateway = gateway;
+			this.segments = Arrays.asList(segments);
+			if (this.segments.size() == 0)
+				throw new IllegalArgumentException("no segments available");
+			for (String segment : segments) {
+				if (segment == null || segment.isEmpty())
+					throw new IllegalArgumentException("a segment is null or empty");
+			}
+		}
+				
+		public Segments build() {
+			return new Segments(gateway, segments);
+		}
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/ServiceDescriptor.java b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/ServiceDescriptor.java
new file mode 100644
index 0000000..f86ad64
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/ServiceDescriptor.java
@@ -0,0 +1,76 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.model.resource.utils;
+
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ServiceDescriptor extends AbstractDescriptor {
+
+	private final String device;
+	private final String service;
+
+	public ServiceDescriptor(String gateway, String device, String service) {
+		super(gateway);
+		this.device = device;
+		this.service = service;
+	}
+
+	public DeviceDescriptor toDeviceDescriptor() {
+		return new DeviceDescriptor(gateway, device);
+	}
+	
+	public String getDevice() {
+		return device;
+	}
+
+	public String getService() {
+		return service;
+	}
+
+	@Override
+	public String getPath() {
+		return  "/" + getDevice()+ "/" + getService();
+	}
+	
+	public boolean equals(Object other) {
+		if (this == other)
+			return true;
+		if (!(other instanceof ServiceDescriptor))
+			return false;
+		final ServiceDescriptor that = (ServiceDescriptor) other;
+		return eqStr(this.getGateway(), that.getGateway()) 
+				&& eqStr(this.getDevice(), that.getDevice()) 
+				&& eqStr(this.getService(), that.getService());
+	}
+
+	public int hashCode() {
+		return hash(gateway) * hash(device) * hash(service);
+	}
+
+	private boolean eqStr(String str1, String str2) {
+		if (str1 == null)
+			if (str2 == null)
+				return true;
+			else
+				return false;
+		else
+			return str1.equals(str2);
+	}
+	
+	private int hash(String str) {
+		if (str == null)
+			return 2;
+		else
+			return str.hashCode();
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/package-info.java b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/package-info.java
new file mode 100644
index 0000000..0319049
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.model.resource/src/org/eclipse/sensinact/studio/model/resource/utils/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.model.resource.utils;
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/.classpath b/bnd/org.eclipse.sensinact.studio.navigator.device/.classpath
new file mode 100644
index 0000000..7a6fc25
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="src" output="bin" path="src"/>
+	<classpathentry kind="src" output="bin_test" path="test">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/.gitignore b/bnd/org.eclipse.sensinact.studio.navigator.device/.gitignore
new file mode 100644
index 0000000..c2b941a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/.gitignore
@@ -0,0 +1,2 @@
+/bin_test/
+/generated/
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/.project b/bnd/org.eclipse.sensinact.studio.navigator.device/.project
new file mode 100644
index 0000000..57d6222
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.sensinact.studio.navigator.device</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+	</natures>
+</projectDescription>
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/bnd.bnd b/bnd/org.eclipse.sensinact.studio.navigator.device/bnd.bnd
new file mode 100644
index 0000000..cb0c3f9
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/bnd.bnd
@@ -0,0 +1,68 @@
+Bundle-Version: 1.0.0.SNAPSHOT
+Bundle-SymbolicName: ${p};singleton:=true
+Bundle-ActivationPolicy: lazy
+
+-includeresource.model: \
+	icons=icons,\
+	plugin.xml
+	
+-buildpath: \
+	org.eclipse.jface,\
+	org.eclipse.emf.ecore,\
+	org.eclipse.emf.common,\
+	org.eclipse.sensinact.studio.model.manager,\
+	org.eclipse.sensinact.studio.model.resource,\
+	org.apache.log4j,\
+	org.eclipse.emf.transaction,\
+	org.eclipse.sensinact.studio.preferences,\
+	org.eclipse.swt.win32.win32.x86_64,\
+	org.eclipse.core.commands,\
+	org.eclipse.core.jobs,\
+	org.eclipse.equinox.common,\
+	org.eclipse.core.runtime,\
+	org.eclipse.sensinact.studio.http.services,\
+	org.eclipse.sensinact.studio.ui.common,\
+	json,\
+	org.eclipse.sensinact.studio.http.messages,\
+	org.restlet,\
+	org.eclipse.sensinact.studio.view.outdoor,\
+	org.eclipse.core.runtime,\
+	org.eclipse.jface,\
+	org.eclipse.jface.text,\
+	org.eclipse.core.resources,\
+	org.eclipse.swt,\
+	org.eclipse.text,\
+	org.eclipse.ui,\
+	org.eclipse.ui.ide,\
+	org.eclipse.ui.browser,\
+	org.eclipse.ui.editors,\
+	org.eclipse.ui.workbench,\
+	org.eclipse.e4.ui.workbench,\
+	org.eclipse.core.jobs,\
+	org.eclipse.equinox.common,\
+	org.eclipse.equinox.registry,\
+	org.eclipse.jdt.core,\
+	org.eclipse.jdt.ui,\
+	org.eclipse.jdt.core.manipulation,\
+	org.eclipse.osgi,\
+	org.eclipse.core.commands,\
+	org.eclipse.team.core,\
+	org.eclipse.ui.forms,\
+	org.eclipse.ui.workbench.texteditor,\
+	org.eclipse.ui.views,\
+	org.eclipse.debug.core,\
+	org.eclipse.debug.ui,\
+	org.eclipse.equinox.preferences,\
+	org.eclipse.help.base,\
+	org.eclipse.ltk.core.refactoring,\
+	org.eclipse.ltk.ui.refactoring,\
+	org.eclipse.core.filebuffers,\
+	org.eclipse.core.expressions,\
+	org.eclipse.core.filesystem,\
+	org.eclipse.core.contenttype,\
+	org.eclipse.search,\
+	org.eclipse.ui.navigator,\
+	osgi.annotation
+	osgi.annotation
+	
+Require-Bundle: org.eclipse.ui.workbench
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/icons/add.png b/bnd/org.eclipse.sensinact.studio.navigator.device/icons/add.png
new file mode 100644
index 0000000..b9f0ac6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/icons/add.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/icons/connect-icon.xcf b/bnd/org.eclipse.sensinact.studio.navigator.device/icons/connect-icon.xcf
new file mode 100644
index 0000000..fd2d097
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/icons/connect-icon.xcf
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/icons/connect.png b/bnd/org.eclipse.sensinact.studio.navigator.device/icons/connect.png
new file mode 100644
index 0000000..582cb3b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/icons/connect.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/icons/disconnect.png b/bnd/org.eclipse.sensinact.studio.navigator.device/icons/disconnect.png
new file mode 100644
index 0000000..7f23224
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/icons/disconnect.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/icons/remove.png b/bnd/org.eclipse.sensinact.studio.navigator.device/icons/remove.png
new file mode 100644
index 0000000..dbbc6c3
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/icons/remove.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/plugin.xml b/bnd/org.eclipse.sensinact.studio.navigator.device/plugin.xml
new file mode 100644
index 0000000..c555b8e
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/plugin.xml
@@ -0,0 +1,217 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2018 CEA.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+
+     Contributors:
+        CEA - initial API and implementation and/or initial documentation
+
+-->
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.ui.views">
+      <view
+            category="org.eclipse.sensinact.studio.views.category"
+            class="org.eclipse.sensinact.studio.navigator.device.DeviceNavigatorFilterView"
+            id="org.eclipse.sensinact.studio.navigator.device"
+            name="Device Navigator"
+            restorable="true">
+      </view>
+   </extension>
+   <extension
+         point="org.eclipse.ui.navigator.navigatorContent">
+      <navigatorContent
+            activeByDefault="true"
+            contentProvider="org.eclipse.sensinact.studio.navigator.device.DeviceNavigatorContentProvider"
+            id="org.eclipse.sensinact.studio.navigator.device.navigatorContent"
+            labelProvider="org.eclipse.sensinact.studio.navigator.device.DeviceNavigatorLabelProvider"
+            name="Device Navigator Content"
+            priority="normal">
+         <triggerPoints>
+            <or>
+               <instanceof
+                     value="org.eclipse.sensinact.studio.resource.Studio">
+               </instanceof>
+            </or>
+         </triggerPoints>
+         <possibleChildren>
+            <or>
+               <instanceof
+                     value="org.eclipse.sensinact.studio.resource.Resource">
+               </instanceof>
+               <instanceof
+                     value="org.eclipse.sensinact.studio.resource.Device">
+               </instanceof>
+               <instanceof
+                     value="org.eclipse.sensinact.studio.resource.Service">
+               </instanceof>
+               <instanceof
+                     value="org.eclipse.sensinact.studio.resource.Gateway">
+               </instanceof>
+            </or>
+         </possibleChildren>
+         <dropAssistant
+               class="org.eclipse.sensinact.studio.navigator.device.SensinactDropAdapterAssistant"
+               id="org.eclipse.sensinact.studio.navigator.device.SensinactDropAdapterAssistant">
+            <possibleDropTargets>
+               <with
+                     variable="selection">
+                  <iterate
+                        ifEmpty="false"
+                        operator="and">
+                     <instanceof
+                           value="org.eclipse.sensinact.studio.resource.Device">
+                     </instanceof>
+                  </iterate>
+               </with>
+            </possibleDropTargets>
+         </dropAssistant>
+         <commonSorter
+               class="org.eclipse.sensinact.studio.navigator.device.DeviceNavigatorSorter">
+         </commonSorter>
+      </navigatorContent>
+   </extension>
+   <extension
+         point="org.eclipse.ui.navigator.viewer">
+      <viewer
+            popupMenuId="org.eclipse.sensinact.studio.navigator.device"
+            viewerId="org.eclipse.sensinact.studio.navigator.device">
+      </viewer>
+      <viewerContentBinding
+            viewerId="org.eclipse.sensinact.studio.navigator.device">
+         <includes>
+            <contentExtension
+                  isRoot="false"
+                  pattern="org.eclipse.sensinact.studio.navigator.device.navigatorContent">
+            </contentExtension>
+         </includes>
+      </viewerContentBinding>
+      <dragAssistant
+            class="org.eclipse.sensinact.studio.navigator.device.SensinactDragAdapterAssistant"
+            viewerId="org.eclipse.sensinact.studio.navigator.device">
+      </dragAssistant>
+   </extension>
+   <extension
+         point="org.eclipse.ui.commands">
+      <command
+            id="org.eclipse.sensinact.studio.navigator.device.openResourceInvokerHandler"
+            name="Open Resource Invoker">
+      </command>
+      <command id="org.eclipse.sensinact.studio.navigator.device.toolbar.add" name="Add Gateway"></command>
+      <command id="org.eclipse.sensinact.studio.navigator.device.toolbar.remove" name="Remove Gateway"></command>
+      <command id="org.eclipse.sensinact.studio.navigator.device.toolbar.connect" name="Connect Gateway"></command>
+      <command id="org.eclipse.sensinact.studio.navigator.device.toolbar.disconnect" name="Disconnect Gateway"></command>
+   </extension>
+   <extension
+         point="org.eclipse.ui.menus">
+      <menuContribution
+            allPopups="false"
+            locationURI="popup:org.eclipse.sensinact.studio.navigator.device">
+         <command
+               commandId="org.eclipse.sensinact.studio.navigator.device.openResourceInvokerHandler"
+               label="Open resource invoker"
+               style="push">
+            <visibleWhen
+                  checkEnabled="false">
+               <with
+                     variable="selection">
+                  <iterate
+                        ifEmpty="false"
+                        operator="and">
+                     <instanceof
+                           value="org.eclipse.sensinact.studio.resource.Resource">
+                     </instanceof>
+                  </iterate>
+               </with>
+            </visibleWhen>
+         </command>
+      </menuContribution>
+      <menuContribution
+            allPopups="false"
+            locationURI="toolbar:org.eclipse.sensinact.studio.navigator.device">
+         <command 
+               commandId="org.eclipse.sensinact.studio.navigator.device.toolbar.add"
+               icon="icons/add.png"
+               label="Add Gateway"
+               style="push">
+         </command>
+         <command 
+               commandId="org.eclipse.sensinact.studio.navigator.device.toolbar.remove"
+               icon="icons/remove.png"
+               label="Remove Gateway"
+               style="push">
+         </command>
+         <command 
+               commandId="org.eclipse.sensinact.studio.navigator.device.toolbar.connect"
+               icon="icons/connect.png"
+               label="Connect Gateway"
+               style="push">
+         </command>
+         <command 
+               commandId="org.eclipse.sensinact.studio.navigator.device.toolbar.disconnect"
+               icon="icons/disconnect.png"
+               label="Disconnect Gateway"
+               style="push">
+         </command>
+      </menuContribution>
+   </extension>
+   <extension
+         point="org.eclipse.ui.handlers">
+      <handler
+            class="org.eclipse.sensinact.studio.navigator.device.commands.OpenResourceInvokerHandler"
+            commandId="org.eclipse.sensinact.studio.navigator.device.openResourceInvokerHandler">
+         <enabledWhen>
+            <with
+                  variable="selection">
+               <iterate
+                     ifEmpty="false"
+                     operator="and">
+                  <instanceof
+                        value="org.eclipse.sensinact.studio.resource.Resource">
+                  </instanceof>
+               </iterate>
+            </with>
+         </enabledWhen>
+      </handler>
+      <handler
+            class="org.eclipse.sensinact.studio.navigator.device.toolbar.AddHandler"
+            commandId="org.eclipse.sensinact.studio.navigator.device.toolbar.add">
+      </handler>
+      <handler
+            class="org.eclipse.sensinact.studio.navigator.device.toolbar.RemoveHandler"
+            commandId="org.eclipse.sensinact.studio.navigator.device.toolbar.remove">
+      </handler>
+      <handler
+            class="org.eclipse.sensinact.studio.navigator.device.toolbar.ConnectHandler"
+            commandId="org.eclipse.sensinact.studio.navigator.device.toolbar.connect">
+      </handler>
+      <handler
+            class="org.eclipse.sensinact.studio.navigator.device.toolbar.DisconnectHandler"
+            commandId="org.eclipse.sensinact.studio.navigator.device.toolbar.disconnect">
+      </handler>
+   </extension>
+   <extension
+         point="org.eclipse.ui.decorators">
+      <decorator
+            adaptable="true"
+            class="org.eclipse.sensinact.studio.navigator.device.DeviceNavigatorDecorator"
+            id="org.eclipse.sensinact.studio.navigator.device.decorators.ReadOnly"
+            label="SNA decorator"
+            lightweight="true"
+            state="true">
+         <enablement>
+            <or>
+               <objectClass name="org.eclipse.sensinact.studio.resource.Device"></objectClass>
+               <objectClass name="org.eclipse.sensinact.studio.resource.Service"></objectClass>
+               <objectClass name="org.eclipse.sensinact.studio.resource.Resource"></objectClass>
+             </or>
+         </enablement>
+      </decorator>
+   </extension>
+
+</plugin>
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/DeviceNavigatorContentProvider.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/DeviceNavigatorContentProvider.java
new file mode 100644
index 0000000..c422976
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/DeviceNavigatorContentProvider.java
@@ -0,0 +1,110 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device;
+
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelEditor;
+import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelUpdater;
+import org.eclipse.sensinact.studio.navigator.device.filter.SensinactTreeViewer;
+import org.eclipse.sensinact.studio.resource.Device;
+import org.eclipse.sensinact.studio.resource.Gateway;
+import org.eclipse.sensinact.studio.resource.Resource;
+import org.eclipse.sensinact.studio.resource.Service;
+import org.eclipse.sensinact.studio.resource.Studio;
+import org.eclipse.sensinact.studio.resource.impl.DeviceImpl;
+import org.eclipse.sensinact.studio.resource.impl.GatewayImpl;
+
+/**
+ * @author Nicolas Hili, Etienne Gandrille
+ *
+ */
+public class DeviceNavigatorContentProvider implements ITreeContentProvider {
+
+	protected SensinactTreeViewer viewer;
+	
+	public DeviceNavigatorContentProvider() {
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.IContentProvider#dispose()
+	 */
+	@Override
+	public void dispose() {
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.IContentProvider#inputChanged(org.eclipse.jface.viewers.Viewer, java.lang.Object, java.lang.Object)
+	 */
+	@Override
+	public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+		this.viewer=(SensinactTreeViewer)viewer;
+		this.viewer.setLabelProvider(new DeviceNavigatorLabelProvider());
+	}
+	
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ITreeContentProvider#getElements(java.lang.Object)
+	 */
+	@Override
+	public Object[] getElements(Object inputElement) {
+		return getChildren(inputElement);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ITreeContentProvider#getChildren(java.lang.Object)
+	 */
+	@Override
+	public Object[] getChildren(Object parentElement) {
+		if (parentElement instanceof Studio) {
+			return ((Studio) parentElement).getGateways().toArray();
+		} else if (parentElement instanceof Gateway) {
+			return ((Gateway) parentElement).getDevice().toArray();	
+		} else if (parentElement instanceof Device) {
+//			try {
+//				DeviceImpl device=(DeviceImpl)parentElement;
+//				GatewayImpl gateway=(GatewayImpl)device.eContainer();
+//				if(ModelEditor.getInstance().getServicesId(gateway.getName(),device.getName()).size()==0)
+//					ModelUpdater.getInstance().updateServices(gateway.getName(),device.getName());				
+//			} catch (Exception e) {
+//				e.printStackTrace();
+//			}
+			return ((Device) parentElement).getService().toArray();
+		} else if (parentElement instanceof Service) {
+			return ((Service) parentElement).getResource().toArray();
+		} 
+		
+		return new Object[0];
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ITreeContentProvider#getParent(java.lang.Object)
+	 */
+	@Override
+	public Object getParent(Object element) {
+		return ((EObject) element).eContainer();
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.ITreeContentProvider#hasChildren(java.lang.Object)
+	 */
+	@Override
+	public boolean hasChildren(Object element) {
+		EObject eobject=(EObject)element;
+		if(element instanceof Device){
+			return true;
+		}else if(element instanceof Resource){
+			return false;
+		}
+		return eobject.eContents().size()>0;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/DeviceNavigatorDecorator.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/DeviceNavigatorDecorator.java
new file mode 100644
index 0000000..3581c91
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/DeviceNavigatorDecorator.java
@@ -0,0 +1,37 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device;
+
+import org.eclipse.jface.viewers.IDecoration;
+import org.eclipse.jface.viewers.ILabelProviderListener;
+import org.eclipse.jface.viewers.ILightweightLabelDecorator;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class DeviceNavigatorDecorator implements ILightweightLabelDecorator {
+
+	public void decorate(Object element, IDecoration decoration) {
+	}
+
+	public void addListener(ILabelProviderListener listener) {
+	}
+
+	public void dispose() {
+	}
+
+	public boolean isLabelProperty(Object element, String property) {
+		return false;
+	}
+
+	public void removeListener(ILabelProviderListener listener) {
+	}
+}
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/DeviceNavigatorFilterView.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/DeviceNavigatorFilterView.java
new file mode 100644
index 0000000..c41a227
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/DeviceNavigatorFilterView.java
@@ -0,0 +1,211 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+/**
+ * Navigator Widget with the filter bar on the top
+
+
+ */
+package org.eclipse.sensinact.studio.navigator.device;
+
+import org.apache.log4j.Logger;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.emf.transaction.ResourceSetChangeEvent;
+import org.eclipse.jface.action.MenuManager;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IDoubleClickListener;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.jface.window.Window;
+import org.eclipse.sensinact.studio.model.manager.listener.devicelocation.DeviceUpdateManager;
+import org.eclipse.sensinact.studio.model.manager.listener.modelset.ResourceModelSetListener;
+import org.eclipse.sensinact.studio.model.manager.listener.modelset.ResourceModelSetManager;
+import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelEditor;
+import org.eclipse.sensinact.studio.model.resource.utils.GPScoordinates;
+import org.eclipse.sensinact.studio.navigator.device.commands.OpenResourceInvokerHandler;
+import org.eclipse.sensinact.studio.navigator.device.doubleclick.BasicQueryResourceHelper;
+import org.eclipse.sensinact.studio.navigator.device.filter.SensinactFilteredTree;
+import org.eclipse.sensinact.studio.navigator.device.filter.SensinactPatternFilter;
+import org.eclipse.sensinact.studio.navigator.device.toolbar.dialog.GatewayConfigDialog;
+import org.eclipse.sensinact.studio.preferences.ConfigurationManager;
+import org.eclipse.sensinact.studio.preferences.GatewayHttpConfig;
+import org.eclipse.sensinact.studio.resource.Device;
+import org.eclipse.sensinact.studio.resource.Gateway;
+import org.eclipse.sensinact.studio.resource.Resource;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Menu;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.FilteredTree;
+import org.eclipse.ui.dialogs.PatternFilter;
+import org.eclipse.ui.handlers.IHandlerService;
+import org.eclipse.ui.internal.navigator.NavigatorContentService;
+import org.eclipse.ui.navigator.CommonDragAdapter;
+import org.eclipse.ui.navigator.INavigatorContentService;
+import org.eclipse.ui.part.ViewPart;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class DeviceNavigatorFilterView extends ViewPart implements ResourceModelSetListener,IDoubleClickListener, ISelectionChangedListener {
+
+	private static final Logger logger = Logger.getLogger(DeviceNavigatorFilterView.class);
+
+	public static final String VIEW_ID = "org.eclipse.sensinact.studio.navigator.device";
+
+	private TreeViewer viewer;
+	private NavigatorContentService contentService;
+
+	private FilteredTree tree;
+
+	@Override
+	public void createPartControl(Composite aParent) {
+
+		contentService = new NavigatorContentService(super.getViewSite().getId());
+		
+		PatternFilter filter = new SensinactPatternFilter();
+		filter.setIncludeLeadingWildcard(true);
+		tree = new SensinactFilteredTree(this, aParent, SWT.H_SCROLL | SWT.V_SCROLL, filter, true);
+		viewer = tree.getViewer();
+		getSite().setSelectionProvider(viewer);
+		GridData gd = new GridData(GridData.FILL_BOTH);
+		tree.setLayoutData(gd);
+				
+		viewer.setSorter(new DeviceNavigatorSorter());
+		viewer.setContentProvider(new DeviceNavigatorContentProvider());
+		viewer.setLabelProvider(new DeviceNavigatorLabelProvider());
+		viewer.setSelection(getSite().getSelectionProvider().getSelection());
+		
+		INavigatorContentService ncs = contentService;//getSite().getService(INavigatorContentService.class);
+		CommonDragAdapter cd = new CommonDragAdapter(ncs, getSite().getSelectionProvider());
+		int ops = org.eclipse.swt.dnd.DND.DROP_MOVE | org.eclipse.swt.dnd.DND.DROP_COPY;
+		Transfer[] transfers = new Transfer[] { TextTransfer.getInstance() };
+		viewer.addDragSupport(ops, transfers, cd);
+		viewer.addDoubleClickListener(this);
+		viewer.addSelectionChangedListener(this);
+		
+		try {
+			tree.getViewer().setInput(ModelEditor.getInstance().getViewerInput());
+		} catch (InterruptedException e) {
+			logger.error("Error while setting input for the view", e);
+		} 
+		
+		IHandlerService handlerService = (IHandlerService) getSite()
+				.getService(IHandlerService.class);
+		OpenResourceInvokerHandler invoker=new OpenResourceInvokerHandler();
+		handlerService.activateHandler(VIEW_ID,invoker);
+		
+		MenuManager menuMgr = new MenuManager();
+		Menu menu = menuMgr.createContextMenu(tree.getViewer().getControl());
+		tree.getViewer().getControl().setMenu(menu);
+		getSite().registerContextMenu(menuMgr, tree.getViewer());
+
+		ResourceModelSetManager.getInstance().subscribe(this);
+	}
+	
+	@Override
+	public void doubleClick(DoubleClickEvent event) {
+
+		IStructuredSelection selection = (IStructuredSelection) event.getSelection();
+		Object element = selection.getFirstElement();
+		Shell parent = getViewSite().getShell();
+		
+		if (element != null && element instanceof Resource) {
+			Resource resource = (Resource) element;
+			BasicQueryResourceHelper manager = new BasicQueryResourceHelper(parent, resource);
+			try {
+				manager.execute();
+			} catch (InterruptedException e) {
+				logger.error("Error during double click handler processing", e);
+			}
+		}
+
+		if (element != null && element instanceof Gateway) {
+			Gateway gateway = (Gateway) element;
+			GatewayHttpConfig config = ConfigurationManager.getGateway(gateway.getName());
+			
+			if (config == null) {
+				MessageDialog.openError(parent, "Error", "Can't find gateway " + gateway.getName());
+				logger.error("Can't find gateway " + gateway.getName());
+			} else {
+				GatewayConfigDialog dialog = new GatewayConfigDialog(parent, config.getName(), config.getURL().getHost(), config.getURL().getPort(), config.getTimeout(), config.getUsername(), config.getPassword(), config.getVersion());
+				
+				if (dialog.open() == Window.OK) {
+					GatewayHttpConfig gatewayConfig = dialog.getGateway();
+					if (! ConfigurationManager.addGateway(gatewayConfig))
+						MessageDialog.openError(parent, "Update Error", "Please check logs.");
+				}
+			}
+		}
+	}
+	
+
+	@Override
+	public void modelSetUpdated(ResourceSetChangeEvent event) {
+		Display.getDefault().asyncExec(new Runnable() {
+			public void run() {
+				if(contentService!=null){
+					contentService.getActivationService().persistExtensionActivations();
+					contentService.update();
+					contentService.dispose();
+				}
+//				tree.update();
+				viewer.refresh();
+			}
+		});
+	}
+
+	@Override
+	public void setFocus() {
+		viewer.getTree().setFocus();		
+	}
+
+	@Override
+	public void selectionChanged(SelectionChangedEvent event) {
+		IStructuredSelection selection = (IStructuredSelection) event.getSelection();
+		Object element = selection.getFirstElement();
+		if(element != null && element instanceof EObject) {			
+			while(true) {
+				if(element instanceof Device) {
+					break;
+				}
+				if(((EObject)element).eContainer()==null) {
+					element = null;
+					break;
+				}
+				element = ((EObject)element).eContainer();
+			}
+		}
+		if(element == null)
+			return;		
+		Device device = (Device) element;
+		String location = device.getLocation();
+		if(location == null)
+			return;
+		String[] coordinates = location.split(":");
+		if(coordinates.length != 2)
+			return;
+		try {			
+			DeviceUpdateManager manager =DeviceUpdateManager.getInstance();
+			double lat = Double.valueOf(coordinates[0]);
+			double lon = Double.valueOf(coordinates[1]);
+			manager.updateDeviceSelection(new GPScoordinates(lat, lon));
+		}catch(Exception e) {
+			e.printStackTrace();
+		}		
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/DeviceNavigatorLabelProvider.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/DeviceNavigatorLabelProvider.java
new file mode 100644
index 0000000..34fc81d
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/DeviceNavigatorLabelProvider.java
@@ -0,0 +1,153 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device;
+
+import org.eclipse.jface.viewers.IBaseLabelProvider;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.sensinact.studio.ui.common.images.StudioImage;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.ui.ISharedImages;
+import org.eclipse.ui.PlatformUI;
+import org.eclipse.ui.navigator.IDescriptionProvider;
+
+import org.eclipse.sensinact.studio.resource.Action;
+import org.eclipse.sensinact.studio.resource.Device;
+import org.eclipse.sensinact.studio.resource.Gateway;
+import org.eclipse.sensinact.studio.resource.Property;
+import org.eclipse.sensinact.studio.resource.Resource;
+import org.eclipse.sensinact.studio.resource.SensorData;
+import org.eclipse.sensinact.studio.resource.Service;
+import org.eclipse.sensinact.studio.resource.StateVariable;
+import org.eclipse.sensinact.studio.resource.Studio;
+
+/**
+ * @author Nicolas Hili, Etienne Gandrille
+ *
+ */
+public class DeviceNavigatorLabelProvider extends LabelProvider implements ILabelProvider, IDescriptionProvider,IBaseLabelProvider {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.LabelProvider#getText(java.lang.Object)
+	 */
+	@Override
+	public String getText(Object element) {
+		
+		if (element instanceof Studio) {
+			return getText((Studio) element);
+		} else if (element instanceof Gateway) {
+			return getText((Gateway) element);
+		} else if (element instanceof Device) {
+			return getText((Device) element);
+		} else if (element instanceof Service) {
+			return getText((Service) element);
+		} else if (element instanceof Resource) {
+			return getText((Resource) element);
+		}
+		return null;
+	}
+	
+	public String getText(Studio studio) {
+		return "Root";
+	}
+	
+	public String getText(Gateway gateway) {
+		return gateway.getName();
+	}
+	
+	public String getText(Device device) {	
+		if (device.getService().size() == 0) {
+			return device.getName();// + " [loading...]";
+		}
+		
+		return device.getName();
+	}
+	
+	public String getText(Service service) {
+		if (service.getResource().size() == 0) {
+			return service.getName();// + " [loading...]";
+		}
+		return service.getName();
+	}
+	
+	public String getText(Resource resource) {
+		return resource.getName();
+	}
+	
+	/* (non-Javadoc)
+	 * @see org.eclipse.jface.viewers.LabelProvider#getImage(java.lang.Object)
+	 */
+	@Override
+	public Image getImage(Object element) {
+		
+		if (element instanceof Studio) {
+			return getImage((Studio) element);
+		} else if (element instanceof Gateway) {
+			return getImage((Gateway) element);
+		} else if (element instanceof Device) {
+			return getImage((Device)element);
+        } else if (element instanceof Service) {
+        	return getImage((Service)element);
+        } else if (element instanceof Resource) {
+        	return getImage((Resource)element);
+        }
+        return null;
+	}
+	
+	public Image getImage(Studio studio) {
+		return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
+	}
+	
+	public Image getImage(Gateway gateway) {
+		return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_ELEMENT);
+	}
+	
+	public Image getImage(Device device) {
+		//if (device.getService().size() == 0) {
+		//	return StudioImage.LOAD.getImage();
+		//}
+		return PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_OBJ_FOLDER);
+	}
+	
+	public Image getImage(Service service) {
+		if (service.getResource().size() == 0) {
+			return StudioImage.LOAD.getImage();
+		}
+        return PlatformUI.getWorkbench().getSharedImages()
+                .getImage(ISharedImages.IMG_OBJ_FILE);
+	}
+	
+	public Image getImage(Resource resource) {
+		
+		String img = ISharedImages.IMG_OBJ_ADD;
+		
+		if (resource instanceof StateVariable) {
+			img = ISharedImages.IMG_OBJS_INFO_TSK;
+		} else if (resource instanceof Action) {
+			img = ISharedImages.IMG_OBJ_ADD;
+		} else if (resource instanceof Property) {
+			img = ISharedImages.IMG_LCL_LINKTO_HELP;
+		} else if (resource instanceof SensorData) {
+			img = ISharedImages.IMG_ETOOL_HOME_NAV;
+		}
+        return PlatformUI.getWorkbench().getSharedImages()
+                .getImage(img);
+	}
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.ui.navigator.IDescriptionProvider#getDescription(java.lang.Object)
+	 */
+	@Override
+	public String getDescription(Object element) {
+		String text = getText(element);
+        return "This is a description of " + text;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/DeviceNavigatorSorter.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/DeviceNavigatorSorter.java
new file mode 100644
index 0000000..e3e6673
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/DeviceNavigatorSorter.java
@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device;
+
+import java.text.Collator;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerSorter;
+import org.eclipse.sensinact.studio.resource.impl.NamedElementImpl;
+
+/**
+ * @author Etienne Gandrille
+ */
+ public class DeviceNavigatorSorter extends ViewerSorter {
+
+	public DeviceNavigatorSorter() {
+	}
+
+	public DeviceNavigatorSorter(Collator collator) {
+		super(collator);
+	}
+	
+	@Override
+	public int compare(Viewer viewer, Object e1, Object e2) {
+		NamedElementImpl object1 = (NamedElementImpl) e1;
+		NamedElementImpl object2 = (NamedElementImpl) e2;
+		
+		return object1.getName().compareToIgnoreCase(object2.getName());
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/DeviceNavigatorView.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/DeviceNavigatorView.java
new file mode 100644
index 0000000..a332870
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/DeviceNavigatorView.java
@@ -0,0 +1,85 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device;
+
+import org.apache.log4j.Logger;
+import org.eclipse.emf.transaction.ResourceSetChangeEvent;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.sensinact.studio.model.manager.listener.modelset.ResourceModelSetListener;
+import org.eclipse.sensinact.studio.model.manager.listener.modelset.ResourceModelSetManager;
+import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelEditor;
+import org.eclipse.sensinact.studio.navigator.device.doubleclick.BasicQueryResourceHelper;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.ui.navigator.CommonNavigator;
+import org.eclipse.ui.navigator.INavigatorContentService;
+
+import org.eclipse.sensinact.studio.resource.Resource;
+
+/**
+ * @author Nicolas Hili, Etienne Gandrille
+ */
+public class DeviceNavigatorView extends CommonNavigator implements ResourceModelSetListener {
+
+	private static final Logger logger = Logger.getLogger(DeviceNavigatorView.class);
+	
+	public static final String VIEW_ID = "org.eclipse.sensinact.studio.navigator.device";
+	
+	@Override
+	protected void initListeners(TreeViewer viewer) {
+		super.initListeners(viewer);
+		ResourceModelSetManager.getInstance().subscribe(this);
+	}
+	
+	@Override
+	public void modelSetUpdated(ResourceSetChangeEvent event) {
+		Display.getDefault().asyncExec(new Runnable() {
+			  public void run() {
+				  INavigatorContentService contentService = getNavigatorContentService();		            
+				  contentService.getActivationService().persistExtensionActivations();
+				  contentService.update();
+				  contentService.dispose();
+			  }
+		});
+	}
+	
+	@Override
+	protected Object getInitialInput() {
+		try {
+			return ModelEditor.getInstance().getViewerInput();
+		} catch (InterruptedException e) {
+			logger.error("Can't get initial value for tree viewer", e);
+			return null;
+		}
+	}
+
+	@Override
+	protected void handleDoubleClick(DoubleClickEvent event) {
+
+		IStructuredSelection selection = (IStructuredSelection) event.getSelection();
+		Object element = selection.getFirstElement();
+
+		if (element != null && element instanceof Resource) {
+			Resource resource = (Resource) element;
+			BasicQueryResourceHelper manager = new BasicQueryResourceHelper(getViewSite().getShell(), resource);
+			try {
+				manager.execute();
+				return;
+			} catch (InterruptedException e) {
+				logger.error("Error during double click handler processing", e);
+			}
+		}
+
+		// if no special action, perform the default one
+		super.handleDoubleClick(event);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/SensinactDragAdapterAssistant.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/SensinactDragAdapterAssistant.java
new file mode 100644
index 0000000..ee96ff6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/SensinactDragAdapterAssistant.java
@@ -0,0 +1,134 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device;
+
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.sensinact.studio.view.outdoor.OutdoorDeploymentView;
+import org.eclipse.swt.dnd.DragSourceEvent;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.ui.navigator.CommonDragAdapterAssistant;
+
+import org.eclipse.sensinact.studio.resource.Device;
+import org.eclipse.sensinact.studio.resource.Gateway;
+import org.eclipse.sensinact.studio.resource.NamedElement;
+import org.eclipse.sensinact.studio.resource.Resource;
+import org.eclipse.sensinact.studio.resource.Service;
+
+/**
+ * @author Nicolas Hili
+ */
+public class SensinactDragAdapterAssistant extends CommonDragAdapterAssistant {
+
+	public SensinactDragAdapterAssistant() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.navigator.CommonDragAdapterAssistant#getSupportedTransferTypes
+	 * ()
+	 */
+	@Override
+	public Transfer[] getSupportedTransferTypes() {
+		Transfer[] transferTypes = new Transfer[] { TextTransfer.getInstance() };
+		return transferTypes;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.navigator.CommonDragAdapterAssistant#setDragData(org.eclipse
+	 * .swt.dnd.DragSourceEvent, org.eclipse.jface.viewers.IStructuredSelection)
+	 */
+	@Override
+	public boolean setDragData(DragSourceEvent event, IStructuredSelection selection) {
+		
+		// Gateway
+		if (selection.getFirstElement() instanceof Gateway) {
+			Gateway gateway = (Gateway) selection.getFirstElement();
+			if (TextTransfer.getInstance().isSupportedType(event.dataType)) {
+				event.data = "["+gateway.getName()+"/]";
+			}
+			return true;
+		}
+		
+		// Device
+		if (selection.getFirstElement() instanceof Device) {
+			Device device = (Device) selection.getFirstElement();
+			if (TextTransfer.getInstance().isSupportedType(event.dataType)) {
+				String gatewayName = ((NamedElement) device.eContainer()).getName();
+				event.data = "["+gatewayName + "/" + device.getName()+"/]";
+			}
+			return true;
+		}
+		
+		// Service
+		if (selection.getFirstElement() instanceof Service) {
+			Service service = (Service) selection.getFirstElement();
+			if (TextTransfer.getInstance().isSupportedType(event.dataType)) {
+				String gatewayName = ((NamedElement) service.eContainer().eContainer()).getName();
+				String deviceName  = ((NamedElement) service.eContainer()).getName();
+				String serviceName = ((NamedElement) service).getName();
+				event.data = "["+gatewayName + "/" + deviceName + "/" + serviceName+"/]";
+			}
+			return true;
+		}
+		
+		// Resource
+		if (selection.getFirstElement() instanceof Resource) {
+			Resource resource = (Resource) selection.getFirstElement();
+			if (TextTransfer.getInstance().isSupportedType(event.dataType)) {
+				String gatewayName  = ((NamedElement) resource.eContainer().eContainer().eContainer()).getName();
+				String deviceName   = ((NamedElement) resource.eContainer().eContainer()).getName();
+				String serviceName  = ((NamedElement) resource.eContainer()).getName();
+				String resourceName = ((NamedElement) resource).getName();		
+				event.data = "["+gatewayName + "/" + deviceName + "/" + serviceName + "/" + resourceName+"]";
+			}
+			return true;
+		}
+		
+		return false;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.navigator.CommonDragAdapterAssistant#dragStart(org.eclipse
+	 * .swt.dnd.DragSourceEvent, org.eclipse.jface.viewers.IStructuredSelection)
+	 */
+	@Override
+	public void dragStart(DragSourceEvent event, IStructuredSelection selection) {
+		super.dragStart(event, selection);
+		if (selection.getFirstElement() instanceof Device) {
+			OutdoorDeploymentView.beginDrag();
+		}
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.navigator.CommonDragAdapterAssistant#dragFinished(org.
+	 * eclipse.swt.dnd.DragSourceEvent,
+	 * org.eclipse.jface.viewers.IStructuredSelection)
+	 */
+	@Override
+	public void dragFinished(DragSourceEvent event, IStructuredSelection selection) {
+		super.dragFinished(event, selection);
+		if (selection.getFirstElement() instanceof Device) {
+			OutdoorDeploymentView.endDrag();
+		}
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/SensinactDropAdapterAssistant.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/SensinactDropAdapterAssistant.java
new file mode 100644
index 0000000..fda275b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/SensinactDropAdapterAssistant.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device;
+
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.sensinact.studio.view.outdoor.OutdoorDeploymentView;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.TransferData;
+import org.eclipse.ui.navigator.CommonDropAdapter;
+import org.eclipse.ui.navigator.CommonDropAdapterAssistant;
+
+/**
+ * @author Nicolas Hili
+ * @since Nov 13, 2014
+ *
+ */
+public class SensinactDropAdapterAssistant extends CommonDropAdapterAssistant {
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.navigator.CommonDropAdapterAssistant#validateDrop(java
+	 * .lang.Object, int, org.eclipse.swt.dnd.TransferData)
+	 */
+	@Override
+	public IStatus validateDrop(Object target, int operation, TransferData transferType) {
+		return Status.OK_STATUS;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * 
+	 * @see
+	 * org.eclipse.ui.navigator.CommonDropAdapterAssistant#handleDrop(org.eclipse
+	 * .ui.navigator.CommonDropAdapter, org.eclipse.swt.dnd.DropTargetEvent,
+	 * java.lang.Object)
+	 */
+	@Override
+	public IStatus handleDrop(CommonDropAdapter aDropAdapter, DropTargetEvent aDropTargetEvent, Object aTarget) {
+		OutdoorDeploymentView.endDrag();
+		return null;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/commands/OpenResourceInvokerHandler.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/commands/OpenResourceInvokerHandler.java
new file mode 100644
index 0000000..fcdd7bf
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/commands/OpenResourceInvokerHandler.java
@@ -0,0 +1,74 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.commands;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+import org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker.ResourceInvokerDialog;
+import org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker.methodprovider.GUIDefinedMethodProvider;
+import org.eclipse.ui.PlatformUI;
+
+import org.eclipse.sensinact.studio.resource.Device;
+import org.eclipse.sensinact.studio.resource.Gateway;
+import org.eclipse.sensinact.studio.resource.Resource;
+import org.eclipse.sensinact.studio.resource.Service;
+
+/**
+ * @author Nicolas Hili
+ */
+public class OpenResourceInvokerHandler extends AbstractHandler {
+
+	/* (non-Javadoc)
+	 * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent)
+	 */
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		showMenu(PlatformUI.getWorkbench().getActiveWorkbenchWindow().getSelectionService().getSelection());
+		return null;
+	}
+	
+	public void showMenu(ISelection iselection){
+		Object selection = iselection;
+		// Get first element if the selection is an IStructuredSelection
+		if(selection instanceof IStructuredSelection) {
+			IStructuredSelection structuredSelection = (IStructuredSelection)selection;
+			selection = structuredSelection.getFirstElement();
+		}
+		
+		// Treat non-null selected object (try to adapt and return EObject)
+		if(selection instanceof Resource) {
+			Resource resource = (Resource) selection;
+			Service service = (Service) resource.eContainer();
+			Device device = (Device) service.eContainer();
+			Gateway gateway = (Gateway) device.eContainer();
+			
+			String deviceId = device.getName();
+			String serviceId = service.getName();
+			String resourceId = resource.getName();
+			String gatewayId = gateway.getName();
+			ResourceDescriptor descriptor = new ResourceDescriptor(gatewayId, deviceId, serviceId, resourceId);
+			
+			// TODO new Shell() pour le parent ???? 
+			ResourceInvokerDialog dialog = new ResourceInvokerDialog(null, descriptor, new GUIDefinedMethodProvider(descriptor));
+			dialog.create();
+			dialog.open();
+		}
+	}
+	
+	@Override
+	public boolean isEnabled() {
+		return super.isEnabled();
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/doubleclick/BasicQueryResourceHelper.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/doubleclick/BasicQueryResourceHelper.java
new file mode 100644
index 0000000..12bdf01
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/doubleclick/BasicQueryResourceHelper.java
@@ -0,0 +1,132 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.doubleclick;
+
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.sensinact.studio.http.services.client.StudioRequest;
+import org.eclipse.sensinact.studio.http.services.client.UIResult;
+import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelEditor;
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+import org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker.ResourceInvokerDialog;
+import org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker.methodprovider.APIDefinedMethodProvider;
+import org.eclipse.sensinact.studio.ui.common.dialog.SimpleDialog;
+import org.eclipse.sensinact.studio.ui.common.notification.NotifierDialog;
+import org.eclipse.swt.widgets.Shell;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import org.eclipse.sensinact.studio.resource.AccessMethod;
+import org.eclipse.sensinact.studio.resource.AccessMethodType;
+import org.eclipse.sensinact.studio.resource.NamedElement;
+import org.eclipse.sensinact.studio.resource.Resource;
+import org.eclipse.sensinact.studio.resource.ResourcePackage;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class BasicQueryResourceHelper {
+	
+	private final ResourceDescriptor descriptor;
+
+	private final int resourceClassClassifierID;
+	
+	private final Shell parent;
+
+	public BasicQueryResourceHelper(Shell parent, Resource resource) {
+		this.parent = parent;
+
+		String gatewayID = ((NamedElement) resource.eContainer().eContainer().eContainer()).getName();
+		String deviceID = ((NamedElement) resource.eContainer().eContainer()).getName();
+		String serviceID = ((NamedElement) resource.eContainer()).getName();
+		String resourceID = resource.getName();
+		descriptor = new ResourceDescriptor(gatewayID, deviceID, serviceID, resourceID);
+
+		// Represents the type of the resource as an integer
+		resourceClassClassifierID = resource.eClass().getClassifierID();
+	}
+
+	public void execute() throws InterruptedException {
+
+		// access method selection
+		AccessMethodType type = null;
+		int nbParam = -1;
+		AccessMethod selectedMethod = null;
+		for (AccessMethod method : ModelEditor.getInstance().getAccessMethods(descriptor)) {
+
+			int curSize = method.getParameter().size();
+			AccessMethodType curType = method.getType();
+
+			if (isCompatibleResourceMethod(curType)) {
+				if (nbParam == -1 || curSize < nbParam) {
+					nbParam = curSize;
+					type = curType;
+					selectedMethod = method;
+				}
+			}
+		}
+	
+		// no access method available
+		if (nbParam == -1) {
+			MessageDialog.openError(parent, "Error", "No default access method available");
+
+			// method with NO parameters available (great !)
+		} else if (nbParam == 0) {
+			executeWithoutParameters(type);
+
+			// execution WITH parameters
+		} else {
+			executeWithParameters(selectedMethod);
+		}
+	}
+
+	private boolean isCompatibleResourceMethod(AccessMethodType type) {
+		if (resourceClassClassifierID == ResourcePackage.ACTION)
+			if (type == AccessMethodType.ACT)
+				return true;
+			else
+				return false;
+		if (type == AccessMethodType.GET)
+			return true;
+		if (type == AccessMethodType.SET)
+			return true;
+		return false;
+	}
+
+	private void executeWithParameters(AccessMethod selectedMethod) {
+		ResourceInvokerDialog dialog = new ResourceInvokerDialog(null, descriptor, new APIDefinedMethodProvider(descriptor, selectedMethod));
+		dialog.open();
+	}
+
+	private void executeWithoutParameters(AccessMethodType type) {
+		StudioRequest request = new StudioRequest(descriptor, type);
+		UIResult result = request.sendRequestForIU();
+		
+		switch(result.getStatus()) {
+			case SUCCESS:
+				if (type != AccessMethodType.ACT)
+					try {
+						new SimpleDialog(parent, result.getTitle(), new JSONObject(result.getMessage()).toString(4), MessageDialog.INFORMATION).open();
+					} catch (JSONException e) {
+						new SimpleDialog(parent, result.getTitle(), result.getMessage(), MessageDialog.INFORMATION).open();
+					}
+				else
+					NotifierDialog.notify(result.getTitle(), result.getMessage());
+				break;
+			case ERROR:
+				try {
+					new SimpleDialog(parent, result.getTitle(), new JSONObject(result.getMessage()).toString(4), MessageDialog.ERROR).open();
+				} catch (JSONException e) {
+					new SimpleDialog(parent, result.getTitle(), result.getMessage(), MessageDialog.ERROR).open();
+				}
+				break;
+		}
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/doubleclick/package-info.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/doubleclick/package-info.java
new file mode 100644
index 0000000..81b25c4
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/doubleclick/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.navigator.device.doubleclick;
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/filter/SensinactFilteredTree.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/filter/SensinactFilteredTree.java
new file mode 100644
index 0000000..e788d50
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/filter/SensinactFilteredTree.java
@@ -0,0 +1,78 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.filter;
+
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.sensinact.studio.model.manager.listener.modelset.ResourceModelSetListener;
+import org.eclipse.swt.events.TraverseEvent;
+import org.eclipse.swt.events.TraverseListener;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.ui.dialogs.FilteredTree;
+import org.eclipse.ui.dialogs.PatternFilter;
+
+/**
+ * Class that allows to interfere with the filter submitted to the tree
+ * 
+ * @author Jander Nascimento
+ */
+public class SensinactFilteredTree extends FilteredTree {
+
+	private ResourceModelSetListener listener;
+
+	public SensinactFilteredTree(Composite parent, boolean useNewLook) {
+		super(parent, useNewLook);
+	}
+
+	public SensinactFilteredTree(ResourceModelSetListener listener, Composite parent, int treeStyle,
+			PatternFilter filter, boolean useNewLook) {
+		super(parent, treeStyle, filter, useNewLook);
+		this.listener = listener;
+		super.getFilterControl().addTraverseListener(new TraverseListener() {
+			
+			@Override
+			public void keyTraversed(TraverseEvent e) {
+				if(e.keyCode==13){
+					doCreateRefreshJob();
+				}
+			}
+		});
+	}
+
+	@Override
+	protected TreeViewer doCreateTreeViewer(Composite parent, int style) {
+		// TODO Auto-generated method stub
+		return new SensinactTreeViewer(parent,style);//super.doCreateTreeViewer(parent, style);
+	}
+
+    @Override
+    protected void updateToolbar(boolean visible) {
+        super.updateToolbar(visible);
+    }
+	
+	@Override
+	protected void textChanged() {
+		
+		super.textChanged();
+/*
+		if(super.getFilterString().trim().equals("")){
+			doCreateRefreshJob();	
+		}
+		
+		if (listener != null) {
+			listener.modelSetUpdated(null);
+		}
+		
+		*/
+	}
+
+	
+	
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/filter/SensinactPatternFilter.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/filter/SensinactPatternFilter.java
new file mode 100644
index 0000000..812acf6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/filter/SensinactPatternFilter.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.filter;
+
+import org.eclipse.jface.viewers.AbstractTreeViewer;
+import org.eclipse.jface.viewers.ILabelProvider;
+import org.eclipse.jface.viewers.ITreeContentProvider;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.ui.dialogs.PatternFilter;
+
+/**
+ * PatternFilter extension that add the Children of those who matches in the
+ * result list
+ * 
+ * @author Jander Nascimento
+ *
+ */
+public class SensinactPatternFilter extends PatternFilter {
+
+	protected boolean isChildMatch(Viewer viewer, Object element) {
+		Object parent = ((ITreeContentProvider) ((AbstractTreeViewer) viewer).getContentProvider()).getParent(element);
+
+		if (parent != null) {
+			return (isLeafMatch(viewer, parent) ? true : isChildMatch(viewer, parent));
+		}
+		return false;
+
+	}
+
+	@Override
+	protected boolean isLeafMatch(Viewer viewer, Object element) {
+		String labelText = ((ILabelProvider) ((StructuredViewer) viewer).getLabelProvider()).getText(element);
+
+		if (labelText == null) {
+			return false;
+		}
+
+		return (wordMatches(labelText) ? true : isChildMatch(viewer, element));
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/filter/SensinactTreeViewer.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/filter/SensinactTreeViewer.java
new file mode 100644
index 0000000..9287d6e
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/filter/SensinactTreeViewer.java
@@ -0,0 +1,38 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.filter;
+
+import org.eclipse.jface.viewers.TreeViewer;
+import org.eclipse.swt.events.TreeEvent;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Tree;
+
+/**
+ * @author Jander Nascimento
+ */
+public class SensinactTreeViewer extends TreeViewer {
+
+	public SensinactTreeViewer(Composite parent) {
+		super(parent);
+	}
+	
+	public SensinactTreeViewer(Composite parent, int style) {
+		super(parent, style);
+	}
+
+	public SensinactTreeViewer(Tree tree) {
+		super(tree);
+	}
+
+	public void handleEvent(TreeEvent event){
+		super.handleTreeExpand(event);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/filter/package-info.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/filter/package-info.java
new file mode 100644
index 0000000..8ad9b54
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/filter/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.navigator.device.filter;
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/package-info.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/package-info.java
new file mode 100644
index 0000000..711dc73
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.navigator.device;
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/AddHandler.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/AddHandler.java
new file mode 100644
index 0000000..1a6d1b1
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/AddHandler.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.toolbar;
+
+import org.apache.log4j.Logger;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.sensinact.studio.navigator.device.toolbar.dialog.GatewayConfigDialog;
+import org.eclipse.sensinact.studio.preferences.ConfigurationManager;
+import org.eclipse.sensinact.studio.preferences.GatewayHttpConfig;
+import org.eclipse.sensinact.studio.ui.common.dialog.SnaHandler;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class AddHandler extends SnaHandler {
+
+	private static final Logger logger = Logger.getLogger(AddHandler.class);
+	
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		
+		Shell shell = getShell(event);
+		
+		GatewayConfigDialog dialog = new GatewayConfigDialog(shell, ConfigurationManager.getGatewayNames());		
+		dialog.create();
+	
+		if (dialog.open() == Window.OK) {
+			GatewayHttpConfig gateway = dialog.getGateway();
+			if (! ConfigurationManager.addGateway(gateway)) {
+				MessageDialog.openError(shell, "Update Error", "Please check logs.");
+				logger.error("Error while adding a new gateway with config:" + gateway);
+			}
+		}
+		
+		return null;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/ConnectHandler.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/ConnectHandler.java
new file mode 100644
index 0000000..86b66ea
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/ConnectHandler.java
@@ -0,0 +1,95 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.toolbar;
+
+import java.lang.reflect.InvocationTargetException;
+
+import org.apache.log4j.Logger;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.dialogs.ProgressMonitorDialog;
+import org.eclipse.jface.operation.IRunnableWithProgress;
+import org.eclipse.sensinact.studio.http.services.client.connectionmanager.ConnectionManager;
+import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelUpdater;
+import org.eclipse.sensinact.studio.preferences.ConfigurationManager;
+import org.eclipse.sensinact.studio.preferences.GatewayHttpConfig;
+import org.eclipse.sensinact.studio.resource.Gateway;
+import org.eclipse.sensinact.studio.ui.common.dialog.SnaHandler;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ConnectHandler extends SnaHandler {
+	
+	private static final Logger logger = Logger.getLogger(ConnectHandler.class);
+
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+
+		Shell parent = getShell(event);
+
+		Object element = getSelectedElement(event);
+		if (element != null && element instanceof Gateway) {
+			Gateway gateway = (Gateway) element;
+			String name = gateway.getName();
+			GatewayHttpConfig gwConfig = ConfigurationManager.getGateway(name);
+			if (gwConfig == null) {
+				MessageDialog.openError(parent, "Error", "Can't find gateway info.");
+				logger.error("Error while getting gateway config for " + name);
+			} else if (ConnectionManager.getInstance().isConnected(name)) {
+				MessageDialog.openError(parent, "Error", "Gateway already connected.");
+			} else {
+				connect(parent, gwConfig);
+			}
+		} else {
+			MessageDialog.openError(parent, "Error", "Please select a gateway in the tree viewer.");
+		}
+
+		return null;
+	}
+
+	private void connect(final Shell parent, final GatewayHttpConfig gateway) {
+
+		ProgressMonitorDialog dialog = new ProgressMonitorDialog(parent);
+
+		try {
+			dialog.run(false, false, new IRunnableWithProgress() {
+				public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException {
+					ModelUpdater mu = ModelUpdater.getInstance();
+					monitor.subTask("Fetching devices from:" + gateway.getURL());
+					try {
+						mu.updateDevices(gateway.getName());
+						if (monitor.isCanceled()) {
+							throw new InterruptedException("Operation Canceled");
+						}
+						monitor.worked(100);
+						Job connectJob=new ConnectJob(gateway,parent);
+						connectJob.schedule();
+					} catch (Exception e) {
+						Display.getDefault().asyncExec(new Runnable() {
+							 public void run() {
+								 MessageDialog.openError(parent, "Connection Error", "Connection failed.");
+							 }
+							});
+						throw new InvocationTargetException(new Exception("Connection Failed", e));
+					}
+				}
+			});
+		} catch (Exception e2) {
+			logger.error("Exception during update", e2);
+		}
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/ConnectJob.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/ConnectJob.java
new file mode 100644
index 0000000..ec2725b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/ConnectJob.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.toolbar;
+
+import java.net.URI;
+
+import org.apache.log4j.Logger;
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.jobs.Job;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.sensinact.studio.http.services.client.connectionmanager.ConnectionManager;
+import org.eclipse.sensinact.studio.preferences.ConfigurationManager;
+import org.eclipse.sensinact.studio.preferences.GatewayHttpConfig;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ConnectJob extends Job {
+
+	private static final Logger logger = Logger.getLogger(ConnectJob.class);
+	
+	private final GatewayHttpConfig gateway;
+	private Shell parent;
+	public ConnectJob(final GatewayHttpConfig gateway, Shell parent){
+		super(gateway.getName());
+		this.gateway=gateway;
+		this.parent=parent;
+	}
+	
+	@Override
+	protected IStatus run(IProgressMonitor monitor) {
+		super.setThread(new Thread());
+		monitor.beginTask("Connecting...", 100);
+		try {
+
+			if (monitor.isCanceled()) {
+				throw new InterruptedException("Operation Canceled");
+			}
+			monitor.setTaskName("Connecting websocket");
+			GatewayHttpConfig gatewayConfig = ConfigurationManager.getGateway(gateway.getName());
+			URI uri = gatewayConfig.getWebsocketURI();
+			ConnectionManager.getInstance().connect(gateway.getName(), uri);
+			monitor.done();
+			monitor.setTaskName("Done.");
+		} catch (Exception e) {
+			monitor.setCanceled(true);
+			Display.getDefault().asyncExec(new Runnable() {
+				 public void run() {
+					 MessageDialog.openError(parent, "Connection Error", "Connection to the gateway couldn't be established");
+				 }
+			});
+			
+			return Status.CANCEL_STATUS;
+		} finally {
+			monitor.done();
+		}
+		
+		return Status.OK_STATUS;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/DisconnectHandler.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/DisconnectHandler.java
new file mode 100644
index 0000000..532bdb3
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/DisconnectHandler.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.toolbar;
+
+import java.net.ConnectException;
+
+import org.apache.log4j.Logger;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.sensinact.studio.http.services.client.connectionmanager.ConnectionManager;
+import org.eclipse.sensinact.studio.preferences.ConfigurationManager;
+import org.eclipse.sensinact.studio.preferences.GatewayHttpConfig;
+import org.eclipse.sensinact.studio.resource.Gateway;
+import org.eclipse.sensinact.studio.ui.common.dialog.SnaHandler;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class DisconnectHandler extends SnaHandler {
+
+	private static final Logger logger = Logger.getLogger(DisconnectHandler.class);
+	
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		
+		Shell parent = getShell(event);
+
+		Object element = getSelectedElement(event);
+		if (element != null && element instanceof Gateway) {
+			Gateway gateway = (Gateway) element;
+			String name = gateway.getName();
+			GatewayHttpConfig gwConfig = ConfigurationManager.getGateway(name);
+			if (gwConfig == null) {
+				MessageDialog.openError(parent, "Error", "Can't find gateway info.");
+				logger.error("Error while getting gateway config for " + name);
+			} else if ( ! ConnectionManager.getInstance().isConnected(name)) {
+				MessageDialog.openError(parent, "Error", "Gateway is not connected.");
+			} else {
+				try {
+					disconnect(parent, gwConfig);
+				}catch (Exception e) {
+					MessageDialog.openError(parent, "Error", e.getMessage());
+				}
+			}
+		} else {
+			MessageDialog.openError(parent, "Error", "Please select a gateway in the tree viewer.");
+		}
+		
+		return null;
+	}
+
+	private void disconnect(Shell parent, GatewayHttpConfig gwConfig) throws ConnectException {
+		ConnectionManager.getInstance().disconnect(gwConfig.getName());
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/RemoveHandler.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/RemoveHandler.java
new file mode 100644
index 0000000..51710b5
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/RemoveHandler.java
@@ -0,0 +1,46 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.toolbar;
+
+import org.apache.log4j.Logger;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.sensinact.studio.preferences.ConfigurationManager;
+import org.eclipse.sensinact.studio.resource.Gateway;
+import org.eclipse.sensinact.studio.ui.common.dialog.SnaHandler;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class RemoveHandler extends SnaHandler {
+
+	private static final Logger logger = Logger.getLogger(RemoveHandler.class);
+
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		
+		Object element = getSelectedElement(event);
+		if (element != null && element instanceof Gateway) {
+			Gateway gateway = (Gateway) element;
+			String name = gateway.getName();
+			if (MessageDialog.openConfirm(getShell(event), "Please confirm", "Do you want to remove the gateway " + name + "?")) {
+				if (!ConfigurationManager.removeGateway(name)) {
+					logger.error("Error while removing gateway with name " + name);
+				}
+			}
+		} else {
+			MessageDialog.openError(getShell(event), "Error", "Please select the gateway to be deleted in the ree viewer.");
+		}
+
+		return null;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/dialog/GatewayConfigDialog.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/dialog/GatewayConfigDialog.java
new file mode 100644
index 0000000..77c016d
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/dialog/GatewayConfigDialog.java
@@ -0,0 +1,277 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.toolbar.dialog;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.sensinact.studio.preferences.GatewayHttpConfig;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.events.KeyEvent;
+import org.eclipse.swt.events.KeyListener;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Spinner;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class GatewayConfigDialog extends TitleAreaDialog {
+
+	// default model values
+	// also used for storing values while closing window
+	private String name = "NewConfiguration";
+	private String address = "";
+	private int version = -1;
+	private int port = 8080;
+	private int timeout = 10000;
+	private String username;
+	private String password;
+	
+	
+	// Widgets
+	private Text nameText;
+	private Text addressText;
+	private Combo versionList;
+	private Spinner portSpinner;
+	private Spinner timeoutSpinner;
+	private Text usernameText;
+	private Text passwordText;
+	private boolean isEditable;
+	private final String[] gatewayNames;
+
+	public GatewayConfigDialog(Shell parent, String[] gatewayNames) {
+		super(parent);
+		isEditable = true;
+		this.gatewayNames = gatewayNames;
+		this.username = "";
+		this.password = "";
+	}
+	
+	public GatewayConfigDialog(Shell parent, String name, String address, int port, int timeout, String username, String password,int version) {
+		super(parent);
+		this.name = name;
+		this.address = address;
+		this.version = version;
+		this.port = port;
+		this.timeout = timeout;
+		this.isEditable = false;
+		this.gatewayNames = null;
+		this.username = username;
+		this.password = password;
+	}
+
+	public GatewayHttpConfig getGateway() {
+		return new GatewayHttpConfig(name, address, port, timeout, username, password, version);
+	}
+	
+	@Override
+	public void create() {
+		super.create();
+		setTitle("New gateway configuration");
+		validateAll(gatewayNames);
+	}
+
+	@Override
+	protected Control createDialogArea(Composite parent) {
+		Composite area = (Composite) super.createDialogArea(parent);
+
+		// container with two columns
+		Composite container = new Composite(area, SWT.NONE);
+		container.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, true));
+		container.setLayout(new GridLayout(2, false));
+
+		// text fields
+		nameText = createTextField(container, "Configuration Name", gatewayNames, name, isEditable, false);
+		addressText = createTextField(container, "Address", gatewayNames, address, true, false); 
+		addressText.setToolTipText("The address of the gateway.\navailable addresses:\nhttp://localhost\nhttp://192.168.1.69\nlocalhost\n192.168.1.69");				
+		
+		versionList = createList(container, "Version", new String[] {"1","2"}, version);
+		
+		// Spinner fields
+		portSpinner = createSpinnerField(container, "Port", 10000, port);
+		timeoutSpinner = createSpinnerField(container, "Timeout (ms)", 60000, timeout);		
+	
+		// credentials
+		usernameText = createTextField(container, "Username", new String[0], username, true, false); 
+		passwordText = createTextField(container, "Password", new String[0], password, true, true);
+		
+		return area;
+	}
+
+	private Text createTextField(Composite container, String label, final String[] gatewayNames, String initValue, boolean readOnly, boolean ispassword) {
+		
+		// label
+		new Label(container, SWT.NONE).setText(label);
+		
+		// field
+		Text text = new Text(container, SWT.BORDER);
+		if (ispassword)
+			text.setEchoChar('*');
+		text.setText(initValue);
+		text.setEditable(readOnly);
+		text.setLayoutData(new GridData(GridData.FILL, SWT.TOP, true, false));
+		
+		
+		// listeners
+		text.addFocusListener(new FocusListener() {
+			@Override
+			public void focusGained(FocusEvent e) {}
+			@Override
+			public void focusLost(FocusEvent e) {
+				validateAll(gatewayNames);
+			}
+		});
+		text.addKeyListener(new KeyListener() {
+			@Override
+			public void keyPressed(KeyEvent e) {}
+			@Override
+			public void keyReleased(KeyEvent e) {
+				validateAll(gatewayNames);
+			}
+		});
+		
+		return text;
+	}
+	
+	private Spinner createSpinnerField(Composite container, String label, int maximum, int initValue) {
+		
+		// label
+		new Label(container, SWT.NONE).setText(label);
+
+		// field
+		Spinner portSpinner = new Spinner(container, SWT.BORDER);
+		portSpinner.setMaximum(maximum);
+		portSpinner.setSelection(initValue);
+		portSpinner.setLayoutData(new GridData(GridData.FILL, SWT.TOP, true, false));
+		
+		return portSpinner;
+	}
+	
+	
+	private Combo createList(Composite container, String label, String[] versions, int initValue) {
+		// label
+		new Label(container, SWT.NONE).setText(label);
+		// label
+		Combo list = new Combo(container, SWT.DROP_DOWN);
+		list.setLayoutData(new GridData(GridData.FILL, SWT.TOP, true, false));
+		
+		// field
+		int i=0; 
+		for(;i<versions.length;i++) {
+			if(Integer.parseInt(versions[i]) == initValue)
+				break;
+		}
+		final AtomicInteger index = new AtomicInteger(i);
+		list.setItems(versions);
+		list.select(i);
+		list.addSelectionListener(new SelectionListener() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {	
+				Combo c = ((Combo)e.getSource());
+				GatewayConfigDialog.this.version = Integer.parseInt(c.getItem(c.getSelectionIndex()));
+			}
+
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {
+			}			
+		});
+		return list;
+	}
+	
+	protected void createButtonsForButtonBar(Composite parent) {
+		createButton(parent, IDialogConstants.OK_ID, IDialogConstants.OK_LABEL, true);
+		createButton(parent, IDialogConstants.CANCEL_ID, IDialogConstants.CANCEL_LABEL, false);
+	}
+
+	@Override
+	protected void okPressed() {
+		this.name = nameText.getText();
+		this.address = addressText.getText();
+		this.port = portSpinner.getSelection();
+		this.timeout = timeoutSpinner.getSelection();
+		this.username = usernameText.getText();
+		this.password = passwordText.getText();
+		this.version = Integer.parseInt(versionList.getItem(versionList.getSelectionIndex()));
+		super.okPressed();
+	}
+	
+	// ==========
+	// Validation
+	// ==========
+
+	private void validateAll(String[] gatewayNames) {
+		String error = getError(gatewayNames);
+		if (error != null) {
+			setErrorMessage(error);
+			getButton(OK).setEnabled(false);
+		} else {
+			setErrorMessage(null);
+			getButton(OK).setEnabled(true);
+		}
+	}
+
+	private String getError(String[] gatewayNames) {
+		String nameError = checkName(gatewayNames);
+		if (nameError != null) {
+			return nameError;
+		}
+
+		String addressError = checkAddress();
+		if (addressError != null) {
+			return addressError;
+		}
+		
+		return null;
+	}
+	
+	private String checkName(String[] gatewayNames) {
+		String name = nameText.getText();
+		if (name.trim().equals("")) {
+			return "The configuration name must be set";
+		}
+		if (gatewayNames != null) {
+			for (String gatewayName : gatewayNames) {
+				if (gatewayName.trim().equals(name.trim()))
+						return "The gateway " + name + " already exists";
+			}
+		}
+		
+		return null;
+	}
+
+	private String checkAddress() {
+		String address = addressText.getText().trim();
+		if (address.equals("")) {
+			return "The gateway address must be set";
+		}
+
+		boolean isLocalhost = address.equals("localhost") || address.equals("http://localhost");
+		boolean isIPv4 = address.matches("^(http://|https://)?[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$");
+		boolean isDnsName = address.matches("^(http://|https://)?[0-9A-Za-z\\.]+\\.[A-Za-z]{2,8}$");
+		if (!isLocalhost && !isIPv4 & !isDnsName) {
+			return "The gateway address is not well formed";
+		}
+
+		return null;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/dialog/package-info.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/dialog/package-info.java
new file mode 100644
index 0000000..e0e0314
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/dialog/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.navigator.device.toolbar.dialog;
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/package-info.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/package-info.java
new file mode 100644
index 0000000..686cb36
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/toolbar/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.navigator.device.toolbar;
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/ParametersComposite.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/ParametersComposite.java
new file mode 100644
index 0000000..a03fb97
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/ParametersComposite.java
@@ -0,0 +1,129 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.sensinact.studio.http.services.client.GatewayHttpClient.RequestParameter;
+import org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker.parameterfield.ParameterField;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+
+import org.eclipse.sensinact.studio.resource.AccessMethod;
+import org.eclipse.sensinact.studio.resource.Parameter;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ParametersComposite {
+
+	private Composite globalComposite;
+	private Label header;
+	private Composite parameterListComposite;
+	private List<ParameterField> fields = new ArrayList<>();
+
+	ParametersComposite(Composite area) {
+		globalComposite = new Composite(area, SWT.NONE);
+		globalComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
+		globalComposite.setLayout(new GridLayout(1, false));
+		globalComposite.setVisible(false);
+
+		initHeader();
+		initparameterListComposite(false);
+	}
+
+	private void initHeader() {
+		header = new Label(globalComposite, SWT.NONE);
+		header.setText("Parameters:");
+	}
+	
+	private void initparameterListComposite(boolean visible) {
+		parameterListComposite = new Composite(globalComposite, SWT.BORDER);
+		parameterListComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
+		parameterListComposite.setLayout(new GridLayout(3, false));
+		parameterListComposite.setVisible(visible);
+	}
+	
+	private void init() {
+		initHeader();
+		initparameterListComposite(true);
+	}
+	
+	/**
+	 * This method is in charge of clearing the parameter composite by disposing
+	 * all its children (the label as well as the parameter list) When the
+	 * parameter composite is cleared, it is layouted
+	 */
+	void clearContent() {
+		for (Control children : globalComposite.getChildren())
+			if (children != null && !children.isDisposed())
+				children.dispose();
+		globalComposite.layout(true);
+		fields.clear();
+	}
+
+	/**
+	 * This method create the parameter list according to the access method
+	 * (type and signature) selected. It begins to clear the parameter parameter
+	 * composite if it already contains children (i.e. is an other access method
+	 * has been selected before)
+	 * 
+	 * @param AccessMethod
+	 *            accessMethod : the current access method
+	 */
+	void createParameterList(AccessMethod accessMethod) {
+		clearContent();
+
+		if (accessMethod.getParameter().size() == 0)
+			return;
+
+		init();
+
+		// For each parameter
+		for (int i = 0; i < accessMethod.getParameter().size(); i++) {
+			final Parameter parameter = accessMethod.getParameter().get(i);
+			String name = parameter.getName();
+			String type = parameter.getType();
+			ParameterField field = ParameterField.create(parameterListComposite, name, type);
+			fields.add(field);
+		}
+
+		globalComposite.setVisible(true);
+		globalComposite.layout(true);
+	}
+
+	public RequestParameter[] getParametersValues(AccessMethod accessMethod) {
+		List<RequestParameter> params = new ArrayList<>();
+		if (accessMethod != null) {
+			for (int i = 0; i < accessMethod.getParameter().size(); i++) {
+				Parameter parameter = accessMethod.getParameter().get(i);
+				String name = parameter.getName();
+				String type = parameter.getType();
+				String value = getParameterValue(name);
+				params.add(new RequestParameter(name, type, value));
+			}
+		}
+		return params.toArray(new RequestParameter[0]);
+	}
+
+	private String getParameterValue(String name) {
+		for (ParameterField field : fields)
+			if (field.getName().equals(name))
+				return field.getValue();
+		throw new RuntimeException("No available field with name " + name);
+	}
+}
+
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/ResourceInvokerDialog.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/ResourceInvokerDialog.java
new file mode 100644
index 0000000..2f8c3c0
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/ResourceInvokerDialog.java
@@ -0,0 +1,215 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker;
+
+import org.apache.log4j.Logger;
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.TitleAreaDialog;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+import org.eclipse.sensinact.studio.http.services.client.GatewayHttpClient;
+import org.eclipse.sensinact.studio.http.services.client.GatewayHttpClient.RequestParameter;
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+import org.eclipse.sensinact.studio.model.resource.utils.Segments;
+import org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker.methodprovider.MethodProvider;
+import org.eclipse.sensinact.studio.resource.AccessMethod;
+import org.eclipse.sensinact.studio.resource.AccessMethodType;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * @author Nicolas Hili, Etienne Gandrille
+ */
+public class ResourceInvokerDialog extends TitleAreaDialog {
+
+	private static final Logger logger = Logger.getLogger(ResourceInvokerDialog.class);
+	
+	private final ResourceDescriptor descriptor;	
+	private final MethodProvider methodProvider;
+
+	private ParametersComposite parameterComposite;
+	private ResultLabel resultLabel;
+	
+	public ResourceInvokerDialog(Shell parent, ResourceDescriptor descriptor, MethodProvider methodProvider) {
+		super(parent);
+		
+		this.descriptor = descriptor;
+		
+		this.methodProvider = methodProvider;
+		methodProvider.registerResourceInvokerDialog(this);
+		setHelpAvailable(false);
+	}
+	
+	@Override
+	public void create() {
+		super.create();
+		setTitle("Resource Invoker");
+		setShellStyle(SWT.DIALOG_TRIM | SWT.RESIZE | SWT.MAX);
+	}
+		
+	@Override
+	protected Control createDialogArea(Composite parent) {
+		Composite area = (Composite) super.createDialogArea(parent);
+		configureDialogArea(area);
+
+		methodProvider.createDialogArea(area);
+		parameterComposite = new ParametersComposite(area);
+		resultLabel = new ResultLabel(area);
+			
+		return area;
+	}
+	
+	@Override
+	protected Control createContents(Composite parent) {
+		Control control = super.createContents(parent);
+		updateWidgets();
+		return control;
+	}
+	
+	
+	private static void configureDialogArea(Composite area) {
+		GridLayout gridLayout = (GridLayout) area.getLayout();
+		gridLayout.marginRight = 5;
+		gridLayout.marginLeft = 5;
+		GridData gridData = (GridData) area.getLayoutData();
+		gridData.widthHint = 640;
+	}
+	
+	@Override
+	protected void createButtonsForButtonBar(Composite parent) {
+		createButton(parent, IDialogConstants.PROCEED_ID, "Proceed", true);
+		getButton(IDialogConstants.PROCEED_ID).setEnabled(false);
+		super.createButtonsForButtonBar(parent);
+		getButton(OK).setVisible(false);
+		getButton(CANCEL).setText("Close");
+		setDialogHelpAvailable(false);
+		getButton(IDialogConstants.PROCEED_ID).addMouseListener(new MouseListener() {		
+			@Override
+			public void mouseUp(MouseEvent e) {
+				launchRequest(e);
+			}
+
+			@Override
+			public void mouseDown(MouseEvent e) {}
+
+			@Override
+			public void mouseDoubleClick(MouseEvent e) {}
+		});
+	}
+	
+	public void updateWidgets() {
+		String type = methodProvider.getAccessMethodType();
+		AccessMethod method = methodProvider.getAccessMethod();
+		
+        // update parameters
+		if (method != null) {
+			parameterComposite.createParameterList(method);
+			getShell().pack(true);
+			getShell().setSize(getShell().computeSize(SWT.DEFAULT, SWT.DEFAULT, true));	
+		} else {
+			parameterComposite.clearContent();
+		}
+		
+		// button value
+		if (type != null) {
+			getButton(IDialogConstants.PROCEED_ID).setText(type);
+		} else {
+			getButton(IDialogConstants.PROCEED_ID).setText("Proceed");
+		}
+		
+		// click button 
+		if (method != null && type != null) {
+			getButton(IDialogConstants.PROCEED_ID).setEnabled(true);
+		} else {
+			getButton(IDialogConstants.PROCEED_ID).setEnabled(false);
+		}
+	}
+
+	protected void launchRequest(MouseEvent e) {
+		AccessMethodType type = AccessMethodType.get(methodProvider.getAccessMethodType());		
+		String message = "";
+		switch (type) {
+		case GET:
+			message = actionPressed();
+			break;
+		case ACT:
+			message = actionPressed();
+			break;
+		case SUBSCRIBE:
+			message = subscribePressed();
+			break;
+		case UNSUBSCRIBE:
+			message = unsubscribePressed();
+			break;
+		case SET:
+			message = actionPressed();
+			break;
+		default:
+			break;
+		}
+		
+		resultLabel.setText(message);		
+	}
+	
+	/**
+	 * This method is called when the user selected an ACT/GET/SET access method.
+	 * It sends an ACT/GET/SET request to the gateway and get the result of the request
+	 * @return the result of the request
+	 */
+	private String actionPressed() {
+		try {
+			AccessMethod method = methodProvider.getAccessMethod();
+			AccessMethodType type = method.getType();
+			Segments segments = new Segments.Builder().resource(descriptor).method(type).build();
+			if (type.equals(AccessMethodType.GET)) {
+				MsgSensinact msg = GatewayHttpClient.sendGetRequest(segments);
+				return msg.getType() + "\n" + msg.toString();
+			} else {
+				RequestParameter[] params = parameterComposite.getParametersValues(method);
+				GatewayHttpClient.sendPostRequest(segments,null, params);
+				MsgSensinact msg = GatewayHttpClient.sendPostRequest(segments,null, params);
+				return msg.getType() + "\n" + msg.toString();
+			}
+		} catch (Exception e) {
+			logger.error("action failure", e);
+			return "[ERROR] " + e.getMessage();
+		}
+	}
+	
+	/**
+	 * This method is called when the user selected an SUBSCRIBE access method.
+	 * It sends a SUBSCRIBE request to the gateway and get the result of the request
+	 * @return the result of the request
+	 */
+	private String subscribePressed() 
+	{
+		// TODO update this class with implements SubscriptionListener {
+		return "Not yet implemented";
+	}
+
+	/**
+	 * This method is called when the user selected an UNSUBSCRIBE access method.
+	 * It sends an UNSUBSCRIBE request to the gateway using the current subscriptionId 
+	 * of the resource  passed as parameter
+	 * 
+	 * @return the result of the request
+	 */
+	private String unsubscribePressed() 
+	{
+		// TODO update this class with implements SubscriptionListener {
+		return "Not yet implemented";
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/ResultLabel.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/ResultLabel.java
new file mode 100644
index 0000000..6bc36b4
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/ResultLabel.java
@@ -0,0 +1,47 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ResultLabel {
+
+	/**
+	 * The label of the result Text
+	 */
+	private Label resultLabel;
+
+	/**
+	 * The Text widget to display the return value of the gateway, for an ACT, GET, SET
+	 */
+	private Text resultText;
+	
+	ResultLabel(Composite area) {
+		resultLabel = new Label(area, SWT.NONE);
+		resultLabel.setText("Result:");
+		
+		resultText = new Text(area, SWT.BORDER | SWT.READ_ONLY | SWT.MULTI | SWT.WRAP);
+		GridData gridData = new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1);
+		gridData.heightHint = 5 * resultText.getLineHeight();
+		resultText.setLayoutData(gridData);
+	}
+	
+	void setText(String text) {
+		resultText.setText(text);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/methodprovider/APIDefinedMethodProvider.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/methodprovider/APIDefinedMethodProvider.java
new file mode 100644
index 0000000..d90ad10
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/methodprovider/APIDefinedMethodProvider.java
@@ -0,0 +1,49 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker.methodprovider;
+
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+import org.eclipse.sensinact.studio.resource.AccessMethod;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class APIDefinedMethodProvider extends MethodProvider {
+
+	private final AccessMethod method;
+	
+	public APIDefinedMethodProvider(ResourceDescriptor descriptor, AccessMethod method) {
+		super(descriptor);
+		this.method = method;
+	}
+
+	@Override
+	public Control createDialogArea(Composite area) {
+		return area;
+	}
+
+	protected void updateWidgets() {
+		super.updateWidgets();
+	}
+	
+	@Override
+	public String getAccessMethodType() {
+		return method.getType().getLiteral();
+	}
+	
+	@Override
+	public AccessMethod getAccessMethod() {
+		return method;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/methodprovider/GUIDefinedMethodProvider.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/methodprovider/GUIDefinedMethodProvider.java
new file mode 100644
index 0000000..1dc1f34
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/methodprovider/GUIDefinedMethodProvider.java
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker.methodprovider;
+
+import org.apache.log4j.Logger;
+import org.eclipse.jface.dialogs.IMessageProvider;
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+import org.eclipse.swt.events.SelectionEvent;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+import org.eclipse.sensinact.studio.resource.AccessMethod;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class GUIDefinedMethodProvider extends MethodProvider {
+
+	private MethodComposite methodComposite;
+	
+	private static final Logger logger = Logger.getLogger(GUIDefinedMethodProvider.class);
+	
+	public GUIDefinedMethodProvider(ResourceDescriptor descriptor) {
+		super(descriptor);
+	}
+
+	@Override
+	public Control createDialogArea(Composite area) {
+		methodComposite = new MethodComposite(area, descriptor) ;
+		addListeners();
+		return area;
+	}
+	
+	private void addListeners() {
+		// listeners
+		methodComposite.addTypeComboListener(new SelectionListener() {
+			@Override
+			public void widgetSelected(SelectionEvent event) {
+				updateWidgets();
+				try {
+					methodComposite.updateAccessMethods();
+				} catch (InterruptedException e) {
+					logger.error("Error while updating access methods", e);
+				}
+			}
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {}
+		});
+		
+		methodComposite.addSignatureComboListener(new SelectionListener() {
+			@Override
+			public void widgetSelected(SelectionEvent e) {
+				updateWidgets();
+			}
+			@Override
+			public void widgetDefaultSelected(SelectionEvent e) {}
+		});
+	}
+
+	protected void updateWidgets() {
+		super.updateWidgets();
+		
+		if (getAccessMethod() != null) {
+			setDialogMessage("", IMessageProvider.NONE);
+		} else {
+			if (getAccessMethodType() == null) {
+				setDialogMessage("Select one access method", IMessageProvider.WARNING);
+			} else {
+				setDialogMessage("Multiple signatures for the access method " + getAccessMethodType() + ". Please select one signature", IMessageProvider.INFORMATION);		
+			}
+		}
+	}
+	
+	@Override
+	public String getAccessMethodType() {
+		return methodComposite.getSelectedAccessMethodType();
+	}
+	
+	@Override
+	public AccessMethod getAccessMethod() {
+		try {
+			return methodComposite.getSelectedAccessMethod();
+		} catch (InterruptedException e) {
+			logger.error("Error while getting selected access method", e);
+			return null;
+		}
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/methodprovider/MethodComposite.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/methodprovider/MethodComposite.java
new file mode 100644
index 0000000..c98a6c9
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/methodprovider/MethodComposite.java
@@ -0,0 +1,181 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker.methodprovider;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelEditor;
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.SelectionListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Label;
+
+import org.eclipse.sensinact.studio.resource.AccessMethod;
+import org.eclipse.sensinact.studio.resource.AccessMethodType;
+import org.eclipse.sensinact.studio.resource.Parameter;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MethodComposite {
+
+	private static final Logger logger = Logger.getLogger(MethodComposite.class);
+	
+	/**
+	 * A composite to hold both type and signature labels and combo widgets.
+	 */
+	private Composite methodComposite;
+
+	/**
+	 * The label for the access method type
+	 */
+	private Label typeLabel;
+	
+	/**
+	 * The combo widget for the access method type (SET, ACT, etc.)
+	 */
+	private Combo typeCombo;
+
+	/**
+	 * The label for the signatures of a particular access method
+	 */
+	private Label signatureLabel;
+
+	/**
+	 * The combo widget for the access method signature
+	 */
+	private Combo signatureCombo;
+	
+	private final ResourceDescriptor descriptor;
+	
+	MethodComposite(Composite area, ResourceDescriptor descriptor) {
+		
+		this.descriptor = descriptor;
+		
+		methodComposite = new Composite(area, SWT.BORDER);
+		methodComposite.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false, 1, 1));
+		methodComposite.setLayout(new GridLayout(2, true));
+		
+		typeLabel = new Label(methodComposite, SWT.NONE);
+		typeLabel.setText("Type:");
+		
+		signatureLabel = new Label(methodComposite, SWT.NONE);
+		signatureLabel.setText("Signature:");
+		signatureLabel.setVisible(false);
+		
+		typeCombo = new Combo(methodComposite, SWT.NONE | SWT.DROP_DOWN | SWT.READ_ONLY);
+		
+		// populate type combo
+		ArrayList<String> items = new ArrayList<String>();
+		items.add("Choose type...");
+		
+		try {
+			for (AccessMethod accessMethod : ModelEditor.getInstance().getAccessMethods(descriptor)) {
+				String type = accessMethod.getType().getLiteral();
+				if (!items.contains(type)) {
+					items.add(type);
+				}
+			}
+		} catch (InterruptedException e) {
+			logger.error("Error while getting access methods");
+		}
+		
+		typeCombo.setItems(items.toArray(new String[]{}));
+		typeCombo.select(0);
+		typeCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));	
+		signatureCombo = new Combo(methodComposite, SWT.NONE | SWT.DROP_DOWN | SWT.READ_ONLY);
+		signatureCombo.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+		signatureCombo.setVisible(false);
+	}
+	
+	void updateAccessMethods() throws InterruptedException {
+		String type = getSelectedAccessMethodType();
+		
+        // if the user did not choose an access method
+		if (type == null) {								
+			setVisibleSignature(false);
+		} else {
+			// Get all access methods for this type
+			List<AccessMethod> accessMethods = ModelEditor.getInstance().getAccessMethodsWithType(descriptor, AccessMethodType.get(type));
+			
+			// Fill the signature combo
+			if (accessMethods.size() > 1) {				
+				signatureCombo.clearSelection();
+				ArrayList<String> signatures = new ArrayList<String>();
+				signatures.add("Choose signature...");
+				for (AccessMethod accessMethod : accessMethods) {
+					String signature = "";
+					for (Parameter parameter : accessMethod.getParameter())
+						signature = signature.concat(parameter.getName() + " : " + parameter.getType() + ", ");
+					if (signature.endsWith(", "))
+						signature = signature.substring(0, signature.length()-2);
+					if (signature.equals(""))
+						signature = "<no parameter>";
+					signatures.add(signature);
+				}
+				signatureCombo.setItems(signatures.toArray(new String[]{}));
+				signatureCombo.select(0);
+				
+				// Display signature combo and label
+				setVisibleSignature(true);
+			}
+			
+			// If there is only one access method, create the parameterList
+			else { 
+				setVisibleSignature(false);
+			}
+		}
+	}
+	
+	String getSelectedAccessMethodType() {
+		int index = typeCombo.getSelectionIndex();
+		if (index == 0)
+			return null;
+		else 
+			return typeCombo.getItem(index);
+	}
+	
+	AccessMethod getSelectedAccessMethod() throws InterruptedException {
+		String type = getSelectedAccessMethodType();
+		
+		if (type == null)
+			return null;
+		
+		List<AccessMethod> accessMethods = ModelEditor.getInstance().getAccessMethodsWithType(descriptor, AccessMethodType.get(type));		
+		if (accessMethods.size() > 1) {
+			int index = signatureCombo.getSelectionIndex();
+			if (index == 0 || index == -1)
+				return null;
+			return ModelEditor.getInstance().getAccessMethodsWithType(descriptor, AccessMethodType.get(type)).get(index-1);	
+		} else {
+			return accessMethods.get(0);
+		}
+	}
+	
+	void addTypeComboListener(SelectionListener listener) {
+		typeCombo.addSelectionListener(listener);
+	}
+
+	void addSignatureComboListener(SelectionListener listener) {
+		signatureCombo.addSelectionListener(listener);		
+	}
+	
+	private void setVisibleSignature(boolean isVisible) {
+		signatureCombo.setVisible(isVisible);
+		signatureLabel.setVisible(isVisible);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/methodprovider/MethodProvider.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/methodprovider/MethodProvider.java
new file mode 100644
index 0000000..39cc444
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/methodprovider/MethodProvider.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker.methodprovider;
+
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+import org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker.ResourceInvokerDialog;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+import org.eclipse.sensinact.studio.resource.AccessMethod;
+
+/**
+ * @author Etienne Gandrille
+ */
+public abstract class MethodProvider {
+
+	protected ResourceInvokerDialog resourceInvokerDialog;
+	
+	protected final ResourceDescriptor descriptor;
+	
+	public MethodProvider(ResourceDescriptor descriptor) {
+		this.descriptor = descriptor;
+	}
+	
+	protected void setDialogMessage(String message, int type) {
+		resourceInvokerDialog.setMessage(message, type);
+	}
+	
+	public abstract Control createDialogArea(Composite parent);
+	
+	public abstract String getAccessMethodType();
+	
+	public abstract AccessMethod getAccessMethod();
+	
+	protected void updateWidgets() {
+		resourceInvokerDialog.updateWidgets();
+	}
+
+	public void registerResourceInvokerDialog(ResourceInvokerDialog resourceInvokerDialog) {
+		this.resourceInvokerDialog = resourceInvokerDialog;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/methodprovider/package-info.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/methodprovider/package-info.java
new file mode 100644
index 0000000..5c41fe8
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/methodprovider/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker.methodprovider;
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/package-info.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/package-info.java
new file mode 100644
index 0000000..f768b75
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker;
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/parameterfield/BooleanField.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/parameterfield/BooleanField.java
new file mode 100644
index 0000000..103f324
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/parameterfield/BooleanField.java
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker.parameterfield;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class BooleanField extends ParameterField {
+
+	protected BooleanField(Composite composite, String name, String type) {
+		super(composite, name, type, "false");
+	}
+	
+	public static List<String> getAcceptedTypes() {
+		return Arrays.asList("boolean", "bool", "Boolean");
+	}
+	
+	protected Control createWidget(Composite parameterListComposite, final String name) {
+
+		final Button control = new Button(parameterListComposite, SWT.CHECK);
+		control.setSelection(false);
+				
+		control.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+
+		control.addFocusListener(new FocusListener() {
+			@Override
+			public void focusLost(FocusEvent e) {
+				String value = Boolean.toString(control.getSelection());
+				setValue(value);
+			}
+			
+			@Override
+			public void focusGained(FocusEvent e) {
+			}
+		});
+
+		return control;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/parameterfield/NumberField.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/parameterfield/NumberField.java
new file mode 100644
index 0000000..0c05ef8
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/parameterfield/NumberField.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker.parameterfield;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Spinner;
+
+
+/**
+ * @author Etienne Gandrille
+ */
+public class NumberField extends ParameterField {
+
+	protected NumberField(Composite composite, String name, String type) {
+		super(composite, name, type, "0");
+	}
+
+	public static List<String> getAcceptedTypes() {
+		return Arrays.asList(Integer.class.getName(), "int", Double.class.getName());
+	}
+	
+	protected Control createWidget(Composite parameterListComposite, final String name) {
+
+		final Spinner control = new Spinner(parameterListComposite, SWT.BORDER);
+
+		control.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+		control.setMaximum(65000); // default is 100
+
+		control.addFocusListener(new FocusListener() {
+			@Override
+			public void focusLost(FocusEvent e) {
+				String value = Integer.toString(control.getSelection());
+				setValue(value);
+			}
+
+			@Override
+			public void focusGained(FocusEvent e) {
+			}
+		});
+
+		return control;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/parameterfield/ParameterField.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/parameterfield/ParameterField.java
new file mode 100644
index 0000000..e61f89a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/parameterfield/ParameterField.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker.parameterfield;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * @author Etienne Gandrille
+ */
+public abstract class ParameterField {
+
+	// graphic
+	private Label namelabel;
+	private Control widget;
+	private Label typeLabel;
+	
+	// model
+	private String name;
+	private String value;
+	
+	public static ParameterField create(Composite composite, String name, String type) {	
+		
+		if (NumberField.getAcceptedTypes().contains(type))
+			return new NumberField(composite, name, type);
+		
+		if (TextField.getAcceptedTypes().contains(type))
+			return new TextField(composite, name, type);
+		
+		if (BooleanField.getAcceptedTypes().contains(type))
+			return new BooleanField(composite, name, type);
+		
+		throw new RuntimeException("No field available to display variable " + name + " of type " + type);
+	}
+	
+	protected ParameterField(Composite composite, String name, String type, String defaultValue) {
+		this.namelabel = createNameLabel(composite, name);
+		this.widget = createWidget(composite, name);
+		this.typeLabel = createTypeLabel(composite, type);
+		this.name = name;
+		this.value = defaultValue;
+	}
+	
+	private static Label createNameLabel(Composite composite, String name) {
+		Label label = new Label(composite, SWT.NONE);
+		label.setText(name + ":");
+		return label;
+	}
+	
+	protected abstract Control createWidget(Composite parameterListComposite, final String name);
+	
+	private static Label createTypeLabel(Composite parameterListComposite, String type) {
+		Label typeLabel = new Label(parameterListComposite, SWT.NONE);
+		typeLabel.setText(type);
+		typeLabel.setLayoutData(new GridData(SWT.RIGHT, SWT.CENTER, false, false, 1, 1));
+		return typeLabel;		
+	}
+	
+	protected void setValue(String value) {
+		this.value = value;
+	}
+	
+	public String getName() {
+		return name;
+	}
+	
+	public String getValue() {
+		return value;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/parameterfield/TextField.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/parameterfield/TextField.java
new file mode 100644
index 0000000..f7b5197
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/parameterfield/TextField.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker.parameterfield;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.FocusEvent;
+import org.eclipse.swt.events.FocusListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Text;
+import org.json.JSONArray;
+import org.json.JSONObject;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class TextField extends ParameterField {
+
+	protected TextField(Composite composite, String name, String type) {
+		super(composite, name, type, "");
+	}
+
+	public static List<String> getAcceptedTypes() {
+		return Arrays.asList("string", "object", "array", JSONArray.class.getName(), JSONObject.class.getName());
+	}
+
+	protected Control createWidget(Composite parameterListComposite, final String name) {
+
+		final Text control = new Text(parameterListComposite, SWT.BORDER);
+
+		control.setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 1, 1));
+
+		control.addFocusListener(new FocusListener() {
+			@Override
+			public void focusLost(FocusEvent e) {
+				String value = control.getText();
+				setValue(value);
+			}
+			
+			@Override
+			public void focusGained(FocusEvent e) {
+			}
+		});
+
+		return control;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/parameterfield/package-info.java b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/parameterfield/package-info.java
new file mode 100644
index 0000000..88f041e
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.navigator.device/src/org/eclipse/sensinact/studio/navigator/device/ui/dialogs/resourceInvoker/parameterfield/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.navigator.device.ui.dialogs.resourceInvoker.parameterfield;
diff --git a/bnd/org.eclipse.sensinact.studio.perspective/.classpath b/bnd/org.eclipse.sensinact.studio.perspective/.classpath
new file mode 100644
index 0000000..7a6fc25
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.perspective/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="src" output="bin" path="src"/>
+	<classpathentry kind="src" output="bin_test" path="test">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bnd/org.eclipse.sensinact.studio.perspective/.gitignore b/bnd/org.eclipse.sensinact.studio.perspective/.gitignore
new file mode 100644
index 0000000..c2b941a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.perspective/.gitignore
@@ -0,0 +1,2 @@
+/bin_test/
+/generated/
diff --git a/bnd/org.eclipse.sensinact.studio.perspective/.project b/bnd/org.eclipse.sensinact.studio.perspective/.project
new file mode 100644
index 0000000..3612e2a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.perspective/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.sensinact.studio.perspective</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+	</natures>
+</projectDescription>
diff --git a/bnd/org.eclipse.sensinact.studio.perspective/bnd.bnd b/bnd/org.eclipse.sensinact.studio.perspective/bnd.bnd
new file mode 100644
index 0000000..561bc05
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.perspective/bnd.bnd
@@ -0,0 +1,11 @@
+Bundle-Version: 1.0.0.SNAPSHOT
+Bundle-SymbolicName: ${p};singleton:=true
+Bundle-ActivationPolicy: lazy
+
+-includeresource.model: \
+	plugin.xml
+-buildpath: \
+	org.eclipse.ui.workbench,\
+	org.eclipse.sensinact.studio.view.visualizer;version=project,\
+	org.eclipse.sensinact.studio.view.outdoor;version=project,\
+	org.eclipse.sensinact.studio.navigator.device;version=project
diff --git a/bnd/org.eclipse.sensinact.studio.perspective/plugin.xml b/bnd/org.eclipse.sensinact.studio.perspective/plugin.xml
new file mode 100644
index 0000000..3f5a48e
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.perspective/plugin.xml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2018 CEA.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+
+     Contributors:
+        CEA - initial API and implementation and/or initial documentation
+
+-->
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.ui.perspectives">
+      <perspective
+            class="org.eclipse.sensinact.studio.perspective.PerspectiveFactory"
+            fixed="false"
+            id="org.eclipse.sensinact.studio.perspective.main"
+            name="Sensinact Studio">
+         <description>
+            This extension point contributes to add the Sensinact Studio perspective.
+         </description>
+      </perspective>
+   </extension>
+   <extension
+         point="org.eclipse.ui.views">
+      <category
+            id="org.eclipse.sensinact.studio.views.category"
+            name="Sensinact">
+      </category>
+   </extension>
+
+</plugin>
diff --git a/bnd/org.eclipse.sensinact.studio.perspective/src/org/eclipse/sensinact/studio/perspective/PerspectiveFactory.java b/bnd/org.eclipse.sensinact.studio.perspective/src/org/eclipse/sensinact/studio/perspective/PerspectiveFactory.java
new file mode 100644
index 0000000..4022010
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.perspective/src/org/eclipse/sensinact/studio/perspective/PerspectiveFactory.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.perspective;
+
+import org.eclipse.sensinact.studio.navigator.device.DeviceNavigatorView;
+import org.eclipse.sensinact.studio.view.outdoor.OutdoorDeploymentView;
+import org.eclipse.sensinact.studio.view.visualizer.VisualizerView;
+import org.eclipse.ui.IFolderLayout;
+import org.eclipse.ui.IPageLayout;
+import org.eclipse.ui.IPerspectiveFactory;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class PerspectiveFactory implements IPerspectiveFactory {
+
+	public final static String NAVIGATOR_FOLDER_ID = "org.eclipse.sensinact.studio.folderLayout.navigator";
+	public final static String VIZUALIZER_FOLDER_ID = "org.eclipse.sensinact.studio.folderLayout.visualizer";
+	public final static String DEPLOY_FOLDER_ID = "org.eclipse.sensinact.studio.folderLayout.deploymentView";
+	public final static String GATEWAY_FOLDER_ID = "org.eclipse.sensinact.studio.folderLayout.gateway";
+	
+	@Override
+	public void createInitialLayout(IPageLayout layout) {
+		String editorArea = layout.getEditorArea();
+		IFolderLayout navigatorFolderLayout = layout.createFolder(NAVIGATOR_FOLDER_ID, IPageLayout.LEFT, 0.25f,editorArea);
+		IFolderLayout visualizerFolderLayout = layout.createFolder(VIZUALIZER_FOLDER_ID, IPageLayout.BOTTOM, 0.80f, NAVIGATOR_FOLDER_ID);
+		IFolderLayout deploymentViewFolderLayout = layout.createFolder(DEPLOY_FOLDER_ID, IPageLayout.TOP, 0.50f,editorArea);
+		
+		navigatorFolderLayout.addView(DeviceNavigatorView.VIEW_ID);
+		navigatorFolderLayout.addView(IPageLayout.ID_PROJECT_EXPLORER);
+		
+		visualizerFolderLayout.addView(VisualizerView.VIEW_ID);
+		
+		deploymentViewFolderLayout.addView(OutdoorDeploymentView.VIEW_ID);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.preferences/.classpath b/bnd/org.eclipse.sensinact.studio.preferences/.classpath
new file mode 100644
index 0000000..7a6fc25
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.preferences/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="src" output="bin" path="src"/>
+	<classpathentry kind="src" output="bin_test" path="test">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bnd/org.eclipse.sensinact.studio.preferences/.gitignore b/bnd/org.eclipse.sensinact.studio.preferences/.gitignore
new file mode 100644
index 0000000..c2b941a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.preferences/.gitignore
@@ -0,0 +1,2 @@
+/bin_test/
+/generated/
diff --git a/bnd/org.eclipse.sensinact.studio.preferences/.project b/bnd/org.eclipse.sensinact.studio.preferences/.project
new file mode 100644
index 0000000..b96326b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.preferences/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.sensinact.studio.preferences</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+	</natures>
+</projectDescription>
diff --git a/bnd/org.eclipse.sensinact.studio.preferences/bnd.bnd b/bnd/org.eclipse.sensinact.studio.preferences/bnd.bnd
new file mode 100644
index 0000000..3a8d75b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.preferences/bnd.bnd
@@ -0,0 +1,6 @@
+-buildpath: \
+	org.eclipse.core.runtime,\
+	osgi.annotation,\
+	org.eclipse.equinox.preferences,\
+	org.apache.log4j
+Bundle-Version: 1.0.0.SNAPSHOT
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.preferences/src/org/eclipse/sensinact/studio/preferences/ConfigurationListerner.java b/bnd/org.eclipse.sensinact.studio.preferences/src/org/eclipse/sensinact/studio/preferences/ConfigurationListerner.java
new file mode 100644
index 0000000..62cfb4f
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.preferences/src/org/eclipse/sensinact/studio/preferences/ConfigurationListerner.java
@@ -0,0 +1,20 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.preferences;
+
+public interface ConfigurationListerner {
+
+	void gatewayAddedOrUpdatedNotif(GatewayHttpConfig gateway);
+
+	void gatewayRemovedNotif(String name);
+
+	void studioPortUpdatedNotif(int port);
+}
diff --git a/bnd/org.eclipse.sensinact.studio.preferences/src/org/eclipse/sensinact/studio/preferences/ConfigurationManager.java b/bnd/org.eclipse.sensinact.studio.preferences/src/org/eclipse/sensinact/studio/preferences/ConfigurationManager.java
new file mode 100644
index 0000000..5ce796f
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.preferences/src/org/eclipse/sensinact/studio/preferences/ConfigurationManager.java
@@ -0,0 +1,194 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.preferences;
+
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.osgi.service.prefs.BackingStoreException;
+import org.osgi.service.prefs.Preferences;
+import org.apache.log4j.Logger;
+import org.eclipse.core.runtime.preferences.IEclipsePreferences;
+import org.eclipse.core.runtime.preferences.InstanceScope;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ConfigurationManager {
+
+	private static String NODE = ConfigurationManager.class.getName();
+	private static String GATEWAYS_NODE = "gateway";
+	private static String STUDIO_NODE = "studio";
+	private static String ADDRESS_KEY = "address";
+	private static String PORT_KEY = "port";
+	private static String VERSION_KEY = "version";	
+	private static String TIMEOUT_KEY = "timeout";
+	private static String USERNAME_KEY = "username";
+	private static String PASSWORD_KEY = "password";
+		
+	private static final Logger logger = Logger.getLogger(ConfigurationManager.class);
+	
+	public static final List<ConfigurationListerner> listeners = new ArrayList<>();
+	
+	private ConfigurationManager() {	
+	}
+
+	/* ========= */
+	/* LISTENERS */
+	/* ========= */
+	
+	public static void addListener(ConfigurationListerner listener) {
+		listeners.add(listener);
+	}
+	
+	public static void removeListener(ConfigurationListerner listener) {
+		listeners.remove(listener);
+	}
+	
+	/* ======= */
+	/* GETTERS */
+	/* ======= */
+	
+	public static GatewayHttpConfig[] getGateways() {
+		List<GatewayHttpConfig> gateways = new ArrayList<GatewayHttpConfig>();
+		
+		IEclipsePreferences root = InstanceScope.INSTANCE.getNode(NODE);
+		Preferences gatewaysNode = root.node(GATEWAYS_NODE);
+		
+		try {
+			for (String name : gatewaysNode.childrenNames()) {
+				Preferences gwPref = gatewaysNode.node(name);
+				String address = gwPref.get(ADDRESS_KEY, "");
+				int port = gwPref.getInt(PORT_KEY, 0);
+				int version = gwPref.getInt(VERSION_KEY, 2);
+				int timeout = gwPref.getInt(TIMEOUT_KEY, 0);
+				String username = gwPref.get(USERNAME_KEY, "");
+				String password = gwPref.get(PASSWORD_KEY, "");
+				
+				try {
+					GatewayHttpConfig gateway = new GatewayHttpConfig(name, address, port, timeout, username, password, version);
+					gateways.add(gateway);
+				} catch (IllegalArgumentException e) {
+					// ignore
+				}
+			}
+		} catch (BackingStoreException e) {
+			logger.error("Preferences read failed", e);
+		}
+		
+		return gateways.toArray(new GatewayHttpConfig[0]);
+	}
+	
+	public static String[] getGatewayNames() {
+		List<String> names = new ArrayList<>();
+		
+		for (GatewayHttpConfig gateway : getGateways())
+			names.add(gateway.getName());
+		
+		return names.toArray(new String[0]);
+	}
+	
+	public static GatewayHttpConfig getGateway(String name) {
+		for (GatewayHttpConfig gateway : getGateways())
+			if (gateway.getName().equals(name))
+				return gateway;
+		return null;
+	}	
+	
+	public static int getStudioPort() {
+		IEclipsePreferences root = InstanceScope.INSTANCE.getNode(NODE);
+		Preferences studioNode = root.node(STUDIO_NODE);
+		return studioNode.getInt(PORT_KEY, 8081);
+	}
+	
+	/* ======= */
+	/* UPDATES */
+	/* ======= */
+	
+	public static boolean addGateway(GatewayHttpConfig gateway) {
+
+		IEclipsePreferences root = InstanceScope.INSTANCE.getNode(NODE);
+		Preferences gatewaysNode = root.node(GATEWAYS_NODE);
+
+		Preferences curGatewayNode = gatewaysNode.node(gateway.getName());
+		curGatewayNode.put(ADDRESS_KEY, gateway.getURL().getHost());
+		curGatewayNode.putInt(PORT_KEY, gateway.getURL().getPort());
+		curGatewayNode.putInt(TIMEOUT_KEY, gateway.getTimeout());
+		curGatewayNode.putInt(VERSION_KEY, gateway.getVersion());
+		curGatewayNode.put(USERNAME_KEY, gateway.getUsername());
+		curGatewayNode.put(PASSWORD_KEY, gateway.getPassword());	
+		
+		try {
+			root.flush();
+		} catch (BackingStoreException e) {
+			logger.error("Preferences write failed", e);
+			return false;
+		}
+		logger.info("Preferences write success");
+		
+		gatewayAddedOrUpdated(gateway);
+		
+		return true;
+	}
+
+	private static void gatewayAddedOrUpdated(GatewayHttpConfig gateway) {
+		for (ConfigurationListerner listener : listeners)
+			listener.gatewayAddedOrUpdatedNotif(gateway);
+	}
+
+	public static boolean removeGateway(String name) {
+		IEclipsePreferences root = InstanceScope.INSTANCE.getNode(NODE);
+		Preferences gatewaysNode = root.node(GATEWAYS_NODE);
+		
+		try {
+			gatewaysNode.node(name).clear();
+			root.flush();
+		} catch (BackingStoreException e) {
+			logger.error("Preferences remove failed", e);
+			return false;
+		}
+		logger.trace("Preferences remove success");
+		
+		gatewayRemoved(name);
+		
+		return true;
+	}
+	
+	private static void gatewayRemoved(String name) {
+		for (ConfigurationListerner listener : listeners)
+			listener.gatewayRemovedNotif(name);
+	}
+	
+	public static boolean setStudioPort(int port) {
+		IEclipsePreferences root = InstanceScope.INSTANCE.getNode(NODE);
+		Preferences studioNode = root.node(STUDIO_NODE);
+		
+		studioNode.putInt(PORT_KEY, port);
+		
+		try {
+			root.flush();
+		} catch (BackingStoreException e) {
+			logger.error("Preferences write failed", e);
+			return false;
+		}
+		logger.info("Preferences write success");
+		
+		studioPortUpdated(port);
+		
+		return true;
+	}
+
+	private static void studioPortUpdated(int port) {
+		for (ConfigurationListerner listener : listeners)
+			listener.studioPortUpdatedNotif(port);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.preferences/src/org/eclipse/sensinact/studio/preferences/GatewayHttpConfig.java b/bnd/org.eclipse.sensinact.studio.preferences/src/org/eclipse/sensinact/studio/preferences/GatewayHttpConfig.java
new file mode 100644
index 0000000..f01370c
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.preferences/src/org/eclipse/sensinact/studio/preferences/GatewayHttpConfig.java
@@ -0,0 +1,128 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.preferences;
+
+import java.net.MalformedURLException;
+import java.net.URI;
+import java.net.URISyntaxException;
+import java.net.URL;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class GatewayHttpConfig {
+
+	private final String name;
+	private final int version;
+	private final URL gatewayURL;
+	private final int timeout;
+	private final String username;
+	private final String password;
+	
+	public GatewayHttpConfig(String name, String address, int port, int timeout, String username, String password, int version) {
+		this(name, generateGatewayURL(address, port), timeout, username, password, version);		
+	}
+	
+	private static URL generateGatewayURL(String address, int port) {
+		if (address == null || address.isEmpty())
+			throw new IllegalArgumentException("address can't be null or empty");
+		if (address.startsWith("http://")) {
+			address = address.substring(7, address.length());
+		}
+		
+		if (port <= 0)
+			throw new IllegalArgumentException("port must be positive");
+		
+		try {
+			return new URL("http", address, port, "");
+		} catch (MalformedURLException e) {
+			throw new IllegalArgumentException("Malformed URL", e);
+		}
+	}
+
+	public GatewayHttpConfig(String name, URL gatewayURL, int timeout, String username, String password, int version) {	
+		this.version = version;
+		if (name == null || name.isEmpty())
+			throw new IllegalArgumentException("name can't be null or empty");
+		this.name = name;
+		if (gatewayURL == null)
+			throw new IllegalArgumentException("gatewayURL can't be null");
+		this.gatewayURL = gatewayURL ;
+		
+		if (timeout <= 0)
+			throw new IllegalArgumentException("timeout must be positive");
+		this.timeout = timeout;
+		
+		this.username = username == null ? "" : username;
+		this.password = password == null ? "" : password;
+	}
+	
+	public boolean hasAuthentication() {
+		return username != null && (!username.isEmpty());
+	}
+	
+	public String getName() {
+		return name;
+	}
+	
+	public URL getURL() {
+		return gatewayURL;
+	}
+	
+	public URI getWebsocketURI() throws URISyntaxException {
+		URL url = getURL();
+		String host = url.getHost();
+		int port = url.getPort();
+		String wsuri = null;
+		if(version == 2)
+			wsuri = String.format("ws://%s:%d/ws/sensinact", host, port);
+		else 
+			wsuri = String.format("ws://%s:%d/ws", host, port);
+		System.out.println("------------------------------------");
+		System.out.println(wsuri);
+		System.out.println("------------------------------------");
+		return new URI(wsuri);
+	}
+
+	public int getVersion() {
+		return version;
+	}
+	
+	public int getTimeout() {
+		return timeout;
+	}
+	
+	public String getUsername() {
+		return username;
+	}
+	
+	public String getPassword() {
+		return password;
+	}
+	
+	@Override
+	public String toString() {
+		return gatewayURL.toString();
+	}
+
+	public boolean equals(Object other) {
+		if (this == other)
+			return true;
+		if (!(other instanceof GatewayHttpConfig))
+			return false;
+		final GatewayHttpConfig that = (GatewayHttpConfig) other;
+		return this.getTimeout() == that.getTimeout() && this.getURL() == that.getURL();
+	}
+
+	public int hashCode() {
+		return gatewayURL.hashCode() + timeout;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.preferences/src/org/eclipse/sensinact/studio/preferences/StudioHttpConfig.java b/bnd/org.eclipse.sensinact.studio.preferences/src/org/eclipse/sensinact/studio/preferences/StudioHttpConfig.java
new file mode 100644
index 0000000..1a31bfa
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.preferences/src/org/eclipse/sensinact/studio/preferences/StudioHttpConfig.java
@@ -0,0 +1,133 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.preferences;
+
+import java.io.IOException;
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+import java.net.NetworkInterface;
+import java.net.SocketException;
+import java.net.URL;
+import java.util.Enumeration;
+
+import org.apache.log4j.Logger;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class StudioHttpConfig {
+
+	private final int port;
+	private final URL url;
+
+	private static final Logger logger = Logger.getLogger(StudioHttpConfig.class);
+
+	public StudioHttpConfig(GatewayHttpConfig gwConfig, int port) {
+		this.port = port;
+		URL url = null;
+		try {
+			url = computeStudioURL(port, gwConfig);
+		} catch (IOException e) {
+			logger.error("Can't compute studio URL");
+		}
+		this.url = url;
+	}
+
+	public int getPort() {
+		return port;
+	}
+
+	public URL getUrl() throws IOException {
+		if (isValid())
+			return url;
+		throw new IOException("Didn't mange to compute the Studio URL");
+	}
+
+	public boolean isValid() {
+		return url != null;
+	}
+
+	private static URL computeStudioURL(int studioPort, GatewayHttpConfig gwConfig) throws IOException {
+		try {
+			String gwHost = gwConfig.getURL().getHost();
+			InetAddress inetAddressGateway = InetAddress.getByName(gwHost);
+			String hostAddress = getHostAddress(inetAddressGateway, 1000);
+			return new URL("http", hostAddress, studioPort, "");
+		} catch (Exception e) {
+			throw new IOException("Can't compute studio URL", e);
+		}
+	}
+
+	private static String getHostAddress(InetAddress gatewayAddress, int timeout) throws SocketException, IOException {
+		Enumeration<NetworkInterface> localInterfaces = NetworkInterface.getNetworkInterfaces();
+		logger.info("Gateway address: " + gatewayAddress.getHostAddress());
+		while (localInterfaces.hasMoreElements()) {
+			NetworkInterface localInterface = localInterfaces.nextElement();
+			logger.info(" * Analyzing Interface: " + localInterface.getInterfaceAddresses());
+
+			
+			if (localInterface.isUp()) {
+				Enumeration<InetAddress> addresses = localInterface.getInetAddresses();
+				while (addresses.hasMoreElements()) {
+					InetAddress address = addresses.nextElement();
+					logger.info("    - Verify IPv4: " + address.getHostAddress());
+					if (address instanceof Inet4Address) {
+						logger.debug("    - Checking IPv4 address: " + address);
+						String retval = address.getHostAddress();
+						if (retval != null && !retval.isEmpty()) {					
+							if (! retval.equals("127.0.0.1")) {
+								logger.info("--> Selected for Studio IP --->" + retval);
+								return retval;
+							}
+						}
+					} else if (address instanceof Inet6Address) {
+						logger.debug("    - IPv6 address ignored: " + address);
+					}
+				}
+			}
+		}
+		throw new IOException("Can't compute studio IP address");
+	}
+
+	public boolean equals(Object other) {
+		if (this == other)
+			return true;
+		if (!(other instanceof StudioHttpConfig))
+			return false;
+		final StudioHttpConfig that = (StudioHttpConfig) other;
+
+		if (this.getPort() != that.getPort())
+			return false;
+
+		URL thisURL = null;
+		try {
+			thisURL = this.getUrl();
+		} catch (IOException e) {
+			// doNothing
+		}
+
+		URL thatURL = null;
+		try {
+			thatURL = that.getUrl();
+		} catch (IOException e) {
+			// doNothing
+		}
+
+		if (thisURL == null)
+			return thatURL == null;
+		return thisURL.equals(thatURL);
+	}
+
+	public int hashCode() {
+		return url.hashCode() % (port + 7);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.preferences/src/org/eclipse/sensinact/studio/preferences/package-info.java b/bnd/org.eclipse.sensinact.studio.preferences/src/org/eclipse/sensinact/studio/preferences/package-info.java
new file mode 100644
index 0000000..fcb0809
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.preferences/src/org/eclipse/sensinact/studio/preferences/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.preferences;
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/.classpath b/bnd/org.eclipse.sensinact.studio.ui.common/.classpath
new file mode 100644
index 0000000..7a6fc25
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="src" output="bin" path="src"/>
+	<classpathentry kind="src" output="bin_test" path="test">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/.gitignore b/bnd/org.eclipse.sensinact.studio.ui.common/.gitignore
new file mode 100644
index 0000000..c2b941a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/.gitignore
@@ -0,0 +1,2 @@
+/bin_test/
+/generated/
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/.project b/bnd/org.eclipse.sensinact.studio.ui.common/.project
new file mode 100644
index 0000000..cc1d227
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/.project
@@ -0,0 +1,43 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.sensinact.studio.ui.common</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+	</natures>
+	<filteredResources>
+		<filter>
+			<id>0</id>
+			<name>images</name>
+			<type>5</type>
+			<matcher>
+				<id>org.eclipse.ui.ide.multiFilter</id>
+				<arguments>1.0-name-matches-false-false-*.png</arguments>
+			</matcher>
+		</filter>
+		<filter>
+			<id>0</id>
+			<name>images</name>
+			<type>5</type>
+			<matcher>
+				<id>org.eclipse.ui.ide.multiFilter</id>
+				<arguments>1.0-name-matches-false-false-*.gif</arguments>
+			</matcher>
+		</filter>
+	</filteredResources>
+</projectDescription>
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/bnd.bnd b/bnd/org.eclipse.sensinact.studio.ui.common/bnd.bnd
new file mode 100644
index 0000000..82060fa
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/bnd.bnd
@@ -0,0 +1,13 @@
+Bundle-Version: 1.0.0.SNAPSHOT
+-includeresource.images:\
+	images=images
+	
+-buildpath: \
+	org.eclipse.core.runtime,\
+	org.eclipse.ui.workbench,\
+	org.eclipse.equinox.common,\
+	osgi.core,\
+	org.eclipse.jface,\
+	org.eclipse.swt.win32.win32.x86_64,\
+	org.eclipse.core.commands,\
+	osgi.annotation
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/images/greenCheck-wikipedia.png b/bnd/org.eclipse.sensinact.studio.ui.common/images/greenCheck-wikipedia.png
new file mode 100644
index 0000000..d6e292d
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/images/greenCheck-wikipedia.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/favicon.svg b/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/favicon.svg
new file mode 100644
index 0000000..1ec31a7
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/favicon.svg
@@ -0,0 +1,75 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   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="69.492188"
+   height="69.489998"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="favicon.svg">
+  <defs
+     id="defs4" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="1.4"
+     inkscape:cx="303.32414"
+     inkscape:cy="29.145288"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     fit-margin-top="0"
+     fit-margin-left="0"
+     fit-margin-right="0"
+     fit-margin-bottom="0"
+     inkscape:window-width="1680"
+     inkscape:window-height="984"
+     inkscape:window-x="0"
+     inkscape:window-y="27"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title />
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Calque 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(-102.16797,-632.01)">
+    <text
+       xml:space="preserve"
+       style="font-size:40px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans"
+       x="100"
+       y="680.93359"
+       id="text2985"
+       sodipodi:linespacing="125%"><tspan
+         sodipodi:role="line"
+         id="tspan2987"
+         x="100"
+         y="680.93359"><tspan
+           style="fill:#1a9292;fill-opacity:1"
+           id="tspan3757">sN</tspan><tspan
+           style="fill:#fa6417;fill-opacity:1"
+           id="tspan3771">a</tspan></tspan></text>
+  </g>
+</svg>
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/icon128.png b/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/icon128.png
new file mode 100644
index 0000000..dbcf39e
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/icon128.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/icon16.png b/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/icon16.png
new file mode 100644
index 0000000..6e77c8d
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/icon16.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/icon256.png b/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/icon256.png
new file mode 100644
index 0000000..1f3ca42
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/icon256.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/icon32.png b/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/icon32.png
new file mode 100644
index 0000000..d7e042f
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/icon32.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/icon48.png b/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/icon48.png
new file mode 100644
index 0000000..5a5f200
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/icon48.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/icon64.png b/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/icon64.png
new file mode 100644
index 0000000..ed48145
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/images/icons/icon64.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/images/loader.gif b/bnd/org.eclipse.sensinact.studio.ui.common/images/loader.gif
new file mode 100644
index 0000000..d0bce15
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/images/loader.gif
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/images/lock.gif b/bnd/org.eclipse.sensinact.studio.ui.common/images/lock.gif
new file mode 100644
index 0000000..dde3cbd
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/images/lock.gif
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/images/splash.svg b/bnd/org.eclipse.sensinact.studio.ui.common/images/splash.svg
new file mode 100644
index 0000000..69d8d4b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/images/splash.svg
@@ -0,0 +1,4467 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   width="452"
+   height="302"
+   id="svg2"
+   version="1.1"
+   inkscape:version="0.48.4 r9939"
+   sodipodi:docname="dessin.svg"
+   inkscape:export-filename="/home/nj246216/Bureau/dessin.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90">
+  <defs
+     id="defs4" />
+  <sodipodi:namedview
+     id="base"
+     pagecolor="#ffffff"
+     bordercolor="#666666"
+     borderopacity="1.0"
+     inkscape:pageopacity="0.0"
+     inkscape:pageshadow="2"
+     inkscape:zoom="0.68144379"
+     inkscape:cx="802.29166"
+     inkscape:cy="340.47974"
+     inkscape:document-units="px"
+     inkscape:current-layer="layer1"
+     showgrid="false"
+     inkscape:window-width="1680"
+     inkscape:window-height="974"
+     inkscape:window-x="0"
+     inkscape:window-y="24"
+     inkscape:window-maximized="1" />
+  <metadata
+     id="metadata7">
+    <rdf:RDF>
+      <cc:Work
+         rdf:about="">
+        <dc:format>image/svg+xml</dc:format>
+        <dc:type
+           rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+        <dc:title></dc:title>
+      </cc:Work>
+    </rdf:RDF>
+  </metadata>
+  <g
+     inkscape:label="Calque 1"
+     inkscape:groupmode="layer"
+     id="layer1"
+     transform="translate(0,-750.36218)">
+    <rect
+       style="opacity:0.82795697;fill:#ffffff;stroke:none"
+       id="rect3784"
+       width="491.60324"
+       height="344.85605"
+       x="-30.816919"
+       y="735.38812" />
+    <image
+       y="803.5899"
+       x="0.29843709"
+       id="image2992"
+       xlink:href="data:image/png;base64,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
+lk+M957lJ5zix93/HozosR34dyxPr1ixYsWKFStWrFjx/yn8/82cs2LFihUrVqxYsWLF3ydWeXrF
+ihUrVqxYsWLFiqfHKk+vWLFixYoVK1asWPH0WOXpFStWrFixYsWKFSueHqs8vWLFihUrVqxYsWLF
+02OVp1esWLFixYoVK1aseHqs8vSKFStWrFixYsWKFU+PVZ5esWLFihUrVqxYseLpscrTK1asWLFi
+xYoVK1Y8PVZ5esWKFStWrFixYsWKp8cqT69YsWLFihUrVqxY8fRY5ekVK1asWLFixYoVK54eqzy9
+YsWKFStWrFixYsXTY5WnV6xYsWLFihUrVqx4evArX/nKv+8+rFixYsWKFStWrFjxHyso6d93H1as
+WLFixYoVK1as+I8Va7zHihUrVqxYsWLFihVPj1WeXrFixYoVK1asWLHi6bHK0ytWrFixYsWKFStW
+PD1WeXrFihUrVqxYsWLFiqfHKk+vWLFixYoVK1asWPH0WOXpFStWrFixYsWKFSueHqs8vWLFihUr
+VqxYsWLF02OVp1esWLFixYoVK1aseHqs8vSKFStWrFixYsWKFU+PVZ5esWLFihUrVqxYseLpscrT
+K1asWLFixYoVK1Y8Pf5f4oNuhzMZVbgAAAAASUVORK5CYII=
+"
+       height="248.07431"
+       width="448.44968"
+       inkscape:export-filename="/home/nj246216/Bureau/image3015.bmp.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <rect
+       style="opacity:0.82795697000000001;fill:#f2f2f2;stroke:none;stroke-width:0.73109131999999999"
+       id="rect2995"
+       width="455.18536"
+       height="305.5032"
+       x="-1.6019229"
+       y="749.92841"
+       inkscape:export-filename="/home/nj246216/Bureau/image3015.bmp.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <image
+       y="841.05444"
+       x="38.711227"
+       id="image3004"
+       xlink:href="data:image/png;base64,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 QyerZIMAAAAASUVORK5CYII= "
+       height="80"
+       width="390"
+       inkscape:export-filename="/home/nj246216/Bureau/image3015.bmp.png"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+    <image
+       y="994.05859"
+       x="38.729496"
+       id="image3015"
+       xlink:href="data:image/png;base64,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 "
+       height="44.580276"
+       width="54.811813"
+       inkscape:export-xdpi="90"
+       inkscape:export-ydpi="90" />
+  </g>
+</svg>
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/color/Colors.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/color/Colors.java
new file mode 100644
index 0000000..20ea5aa
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/color/Colors.java
@@ -0,0 +1,54 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.ui.common.color;
+
+import java.util.HashMap;
+
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class Colors {
+
+	private static Colors INSTANCE = null; 	
+	private HashMap<RGB, Color> cache = new HashMap<>();
+	
+	public final Color RED;
+	public final Color GREEN;
+	public final Color BLUE;
+
+	private Colors() {
+		RED   = getColor(255, 0, 0);
+		GREEN = getColor(0, 255, 0);
+		BLUE  = getColor(0, 0, 255);
+	}
+	
+	public static Colors getINSTANCE() {
+		if (INSTANCE == null)
+			INSTANCE = new Colors();
+		return INSTANCE;
+	}
+	
+	public Color getColor(int r, int g, int b) {
+		return getColor(new RGB(r, g, b));
+	}
+	
+	public Color getColor(RGB rgb) {
+		Color color = cache.get(rgb);
+		if (color == null) {
+			color = new Color(Display.getCurrent(), rgb.r, rgb.g, rgb.b);
+			cache.put(rgb, color);
+		}
+		return color;
+	}	
+}
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/color/RGB.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/color/RGB.java
new file mode 100644
index 0000000..a51cca6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/color/RGB.java
@@ -0,0 +1,63 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.ui.common.color;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class RGB {
+
+	public final int r;
+	public final int g;
+	public final int b;
+	
+	public RGB(int r, int g, int b) {
+		if (r < 0 || r > 255)
+			throw new IllegalArgumentException("r should be between 1 and 255");
+		if (g < 0 || g > 255)
+			throw new IllegalArgumentException("g should be between 1 and 255");
+		if (b < 0 || b > 255)
+			throw new IllegalArgumentException("b should be between 1 and 255");
+		this.r = r;
+		this.g = g;
+		this.b = b;
+	}
+	
+	@Override
+	public String toString() {
+		return r + "/" + g + "/" + b;
+	}
+	
+	@Override
+	public int hashCode() {
+		return toString().hashCode();	
+	}
+	
+	@Override
+	public boolean equals(Object obj) {
+        if (obj == null)
+        	return false;
+
+		if (obj == this)
+            return true;
+         
+        if (obj instanceof RGB) {
+        	RGB other = (RGB) obj;
+ 
+            if (this.r != other.r || this.g != other.g || this.b != other.b) {
+                return false; 
+            }
+ 
+            return true;
+        }
+        return false;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/color/package-info.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/color/package-info.java
new file mode 100644
index 0000000..fbfeed4
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/color/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.ui.common.color;
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/dialog/BasicListDialog.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/dialog/BasicListDialog.java
new file mode 100644
index 0000000..0a2ffd6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/dialog/BasicListDialog.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.ui.common.dialog;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.dialogs.ListDialog;
+
+/**
+ * Dialog to pick a SINGLE element from a list.
+ * 
+ * getFirstResult method added for convinience. 
+ * 
+ * @author Etienne Gandrille
+ */
+public class BasicListDialog extends ListDialog {
+	public BasicListDialog(Shell parent, String title, String message, String[] elements) {
+		super(parent);
+		setTitle(title);
+		setMessage(message);
+		setAddCancelButton(true);
+		setInput(elements);
+		setHelpAvailable(false);
+		
+		setContentProvider(new IStructuredContentProvider() {
+			public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+			}
+
+			public void dispose() {
+			}
+
+			public Object[] getElements(Object inputElement) {
+				return (String[]) inputElement;
+			}
+		});
+		
+		setLabelProvider(new LabelProvider());
+	}
+	
+	@Override
+	public String[] getResult() {
+		Object[] result = super.getResult();
+		if (result == null || result.length == 0)
+			return null;
+		
+		List<String> list = new ArrayList<String>(); 
+		for (Object o : result)
+			list.add((String) o);
+		
+		return list.toArray(new String[0]);
+	}
+	
+	public String getFirstResult() {
+		String[] results = getResult();
+		if (results == null || results.length == 0)
+			return null;
+		return results[0];
+	}	
+}
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/dialog/ShellUtil.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/dialog/ShellUtil.java
new file mode 100644
index 0000000..4f1b99b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/dialog/ShellUtil.java
@@ -0,0 +1,30 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.ui.common.dialog;
+
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ShellUtil {
+
+	public static Shell getShell(Control control) {
+		while (control != null && !(control instanceof Shell))
+			control = control.getParent();
+
+		if (control == null)
+			return null;
+
+		return (Shell) control;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/dialog/SimpleDialog.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/dialog/SimpleDialog.java
new file mode 100644
index 0000000..09982f1
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/dialog/SimpleDialog.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.ui.common.dialog;
+
+import org.eclipse.jface.dialogs.IDialogConstants;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class SimpleDialog extends MessageDialog {
+
+    /**
+     * Create a message dialog. Note that the dialog will have no visual
+     * representation (no widgets) until it is told to open.
+     *
+     * @param parentShell
+     *            the parent shell, or <code>null</code> to create a top-level shell
+     * @param dialogTitle
+     *            the dialog title, or <code>null</code> if none
+     * @param dialogMessage
+     *            the dialog message
+     * @param dialogImageType
+     *            one of the following values:
+     *            <ul>
+     *            <li><code>MessageDialog.NONE</code> for a dialog with no
+     *            image</li>
+     *            <li><code>MessageDialog.ERROR</code> for a dialog with an
+     *            error image</li>
+     *            <li><code>MessageDialog.INFORMATION</code> for a dialog
+     *            with an information image</li>
+     *            <li><code>MessageDialog.QUESTION </code> for a dialog with a
+     *            question image</li>
+     *            <li><code>MessageDialog.WARNING</code> for a dialog with a
+     *            warning image</li>
+     *            </ul>
+     */
+	public SimpleDialog(Shell parentShell, String dialogTitle, String dialogMessage, int dialogImageType) {
+		super(parentShell, dialogTitle, null, dialogMessage, dialogImageType, new String[] { IDialogConstants.OK_LABEL, }, 0);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/dialog/SnaHandler.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/dialog/SnaHandler.java
new file mode 100644
index 0000000..7b558f0
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/dialog/SnaHandler.java
@@ -0,0 +1,42 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.ui.common.dialog;
+
+import org.eclipse.core.commands.AbstractHandler;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.jface.viewers.DoubleClickEvent;
+import org.eclipse.jface.viewers.ISelection;
+import org.eclipse.jface.viewers.IStructuredSelection;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.handlers.HandlerUtil;
+
+/**
+ * @author Etienne Gandrille
+ */
+public abstract class SnaHandler extends AbstractHandler {
+
+	protected Shell getShell(ExecutionEvent event) {
+		return HandlerUtil.getActiveWorkbenchWindow(event).getShell();
+	}
+	
+	protected Object getSelectedElement(ExecutionEvent event) {
+		ISelection selection = HandlerUtil.getCurrentSelection(event);
+		if (selection != null && selection instanceof IStructuredSelection) {
+			IStructuredSelection structuredSelection = (IStructuredSelection) selection;
+			return structuredSelection.getFirstElement();
+		}
+		return null;
+	}
+	
+	public static Shell getShell(DoubleClickEvent event) {
+		return event.getViewer().getControl().getShell();
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/dialog/package-info.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/dialog/package-info.java
new file mode 100644
index 0000000..e1037c2
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/dialog/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.ui.common.dialog;
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/images/StudioImage.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/images/StudioImage.java
new file mode 100644
index 0000000..cb78d1b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/images/StudioImage.java
@@ -0,0 +1,41 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.ui.common.images;
+
+import java.net.URL;
+
+import org.eclipse.core.runtime.FileLocator;
+import org.eclipse.core.runtime.Path;
+import org.eclipse.jface.resource.ImageDescriptor;
+import org.eclipse.swt.graphics.Image;
+import org.osgi.framework.Bundle;
+import org.osgi.framework.FrameworkUtil;
+
+/**
+ * @author Etienne Gandrille
+ */
+public enum StudioImage {
+
+	OK("images/greenCheck-wikipedia.png"), LOAD("images/loader.gif"), LOCK("images/lock.gif");
+	
+	private final Image image;
+	
+	private StudioImage(String path) {
+		Bundle bundle = FrameworkUtil.getBundle(this.getClass());
+		URL url = FileLocator.find(bundle, new Path(path), null);
+		ImageDescriptor imageDescriptor = ImageDescriptor.createFromURL(url);
+		image = imageDescriptor.createImage();		
+	}
+	
+	public Image getImage() {
+		return image;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/images/package-info.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/images/package-info.java
new file mode 100644
index 0000000..86b9d3d
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/images/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.ui.common.images;
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/notification/FontCache.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/notification/FontCache.java
new file mode 100644
index 0000000..2cd08c6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/notification/FontCache.java
@@ -0,0 +1,189 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.ui.common.notification;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * Caching class for fonts. Also deals with re-creating fonts should they have been disposed when the 
+ * caller asks for a font.
+ */
+public class FontCache {
+
+    private static List<OneFont> _existing = new ArrayList<OneFont>();
+
+    /**
+     * Disposes all fonts and clears out the cache. Never call this unless you are shutting down your 
+     * code/client/etc.
+     */
+    public static void disposeAll() {
+        for (OneFont of : _existing) {
+            if (of.getFont() != null && !of.getFont().isDisposed()) {
+                of.getFont().dispose();
+            }
+        }
+        
+        _existing.clear();
+    }
+    
+    /**
+     * Gets a font from existing FontData
+     * 
+     * @param fd FontData
+     * @return Font or null on error
+     */
+    public static Font getFont(FontData fd) {
+        try {
+            boolean disposed = false;
+            OneFont toRemove = null;
+            for (OneFont of : _existing) {
+                if (of.matches(fd)) {
+                    if (of.getFont().isDisposed()) {
+                        disposed = true;
+                        toRemove = of;
+                        break;
+                    }
+                        
+                    return of.getFont(); 
+                }
+            }
+            if (disposed) {
+                _existing.remove(toRemove);
+            }
+            
+            OneFont of = new OneFont(fd);
+            _existing.add(of);
+            return of.getFont();
+        } catch (Exception err) {
+            err.printStackTrace();
+        }
+
+        return null;
+    }
+
+    public static int getCount() {
+        return _existing.size();
+    }
+    
+    /**
+     * Gets a font from an existing fonts data.
+     * 
+     * @param font Font
+     * @return Font or null on error
+     */
+    public static Font getFont(Font font) {
+        try {
+            if (font == null || font.isDisposed()) return null;
+
+            FontData fd = font.getFontData()[0];
+            return getFont(fd);
+
+        } catch (Exception err) {
+            err.printStackTrace();
+        }
+
+        return null;
+    }
+
+    /**
+     * Gets a font for a given font name and style.
+     * 
+     * @param fontName Name of font
+     * @param height Height of font
+     * @param style Style of font
+     * @return Font or null on error
+     */
+    public static Font getFont(String fontName, int height, int style) {
+        try {
+            boolean disposed = false;
+            OneFont toRemove = null;
+            for (OneFont of : _existing) {
+                if (of.getName().equals(fontName) && of.getHeight() == height && of.getStyle() == style) {
+                    if (of.getFont().isDisposed()) {
+                        disposed = true;
+                        toRemove = of;
+                        break;
+                    }
+                    return of.getFont();
+                }
+            }
+            if (disposed) {
+                _existing.remove(toRemove);
+            }
+            
+            OneFont of = new OneFont(fontName, height, style);
+            _existing.add(of);
+            return of.getFont();
+        }
+        catch (Exception err) {
+            err.printStackTrace();
+        }
+        
+        return null;
+    }
+
+}
+
+class OneFont {
+
+    private String _name;
+    private int    _height;
+    private int    _style;
+    private Font   _font;
+
+    public OneFont(String name, int height, int style) {
+        _name = name;
+        _height = height;
+        _style = style;
+        _font = new Font(Display.getDefault(), name, height, style);
+    }
+
+    public OneFont(FontData fd) {
+        _name = fd.getName();
+        _height = fd.getHeight();
+        _style = fd.getStyle();
+        _font = new Font(Display.getDefault(), fd);
+    }
+
+    public String getName() {
+        return _name;
+    }
+
+    public int getHeight() {
+        return _height;
+    }
+
+    public int getStyle() {
+        return _style;
+    }
+
+    public void setFont(Font font) {
+        _font = font;
+    }
+
+    public Font getFont() {
+        return _font;
+    }
+
+    public boolean matches(FontData fd) {
+        return (fd.getName().equals(_name) && fd.getHeight() == _height && fd.getStyle() == _style);
+    }
+
+    @Override
+    public String toString() {
+        return "Font: " + _name + " " + _height + " " + _style;
+    }
+}
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/notification/NotifierDialog.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/notification/NotifierDialog.java
new file mode 100644
index 0000000..943fd24
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/notification/NotifierDialog.java
@@ -0,0 +1,292 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.ui.common.notification;
+
+// SEE http://hexapixel.com/2009/06/30/creating-a-notification-popup-widget
+
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.eclipse.sensinact.studio.ui.common.color.Colors;
+import org.eclipse.sensinact.studio.ui.common.images.StudioImage;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.custom.CLabel;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.layout.FillLayout;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Label;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Shell;
+
+public class NotifierDialog {
+
+    // how long the the tray popup is displayed after fading in (in milliseconds)
+    private static final int   DISPLAY_TIME  = 4500;
+    // how long each tick is when fading in (in ms)
+    private static final int   FADE_TIMER    = 50;
+    // how long each tick is when fading out (in ms)
+    private static final int   FADE_IN_STEP  = 30;
+    // how many tick steps we use when fading out 
+    private static final int   FADE_OUT_STEP = 8;
+
+    // how high the alpha value is when we have finished fading in 
+    private static final int   FINAL_ALPHA   = 225;
+
+    // title foreground color
+    private static Color       _titleFgColor = Colors.getINSTANCE().getColor(40, 73, 97);
+    // text foreground color
+    private static Color       _fgColor      = _titleFgColor;
+
+    // shell gradient background color - top
+    private static Color       _bgFgGradient = Colors.getINSTANCE().getColor(226, 239, 249);
+    // shell gradient background color - bottom    
+    private static Color       _bgBgGradient = Colors.getINSTANCE().getColor(177, 211, 243);
+    // shell border color
+    private static Color       _borderColor  = Colors.getINSTANCE().getColor(40, 73, 97);
+
+    // contains list of all active popup shells
+    private static List<Shell> _activeShells = new ArrayList<Shell>();
+
+    // image used when drawing
+    private static Image       _oldImage;
+
+    private static Shell       _shell;
+
+    /**
+     * Creates and shows a notification dialog with a specific title, message and a
+     * 
+     * @param title
+     * @param message
+     * @param type
+     */
+    public static void notify(String title, String message) {
+        _shell = new Shell(Display.getDefault().getActiveShell(), SWT.NO_FOCUS | SWT.NO_TRIM);
+        _shell.setLayout(new FillLayout());
+        _shell.setForeground(_fgColor);
+        _shell.setBackgroundMode(SWT.INHERIT_DEFAULT);
+        _shell.addListener(SWT.Dispose, new Listener() {
+            @Override
+            public void handleEvent(Event event) {
+                _activeShells.remove(_shell);
+            }
+        });
+
+        final Composite inner = new Composite(_shell, SWT.NONE);
+
+        GridLayout gl = new GridLayout(2, false);
+        gl.marginLeft = 5;
+        gl.marginTop = 0;
+        gl.marginRight = 5;
+        gl.marginBottom = 5;
+
+        inner.setLayout(gl);
+        _shell.addListener(SWT.Resize, new Listener() {
+
+            @Override
+            public void handleEvent(Event e) {
+                try {
+                    // get the size of the drawing area
+                    Rectangle rect = _shell.getClientArea();
+                    // create a new image with that size
+                    Image newImage = new Image(Display.getDefault(), Math.max(1, rect.width), rect.height);
+                    // create a GC object we can use to draw with
+                    GC gc = new GC(newImage);
+
+                    // fill background
+                    gc.setForeground(_bgFgGradient);
+                    gc.setBackground(_bgBgGradient);
+                    gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height, true);
+
+                    // draw shell edge
+                    gc.setLineWidth(2);
+                    gc.setForeground(_borderColor);
+                    gc.drawRectangle(rect.x + 1, rect.y + 1, rect.width - 2, rect.height - 2);
+                    // remember to dipose the GC object!
+                    gc.dispose();
+
+                    // now set the background image on the shell
+                    _shell.setBackgroundImage(newImage);
+
+                    // remember/dispose old used iamge
+                    if (_oldImage != null) {
+                        _oldImage.dispose();
+                    }
+                    _oldImage = newImage;
+                } catch (Exception err) {
+                    err.printStackTrace();
+                }
+            }
+        });
+
+        GC gc = new GC(_shell);
+
+        String lines[] = message.split("\n");
+        Point longest = null;
+        int typicalHeight = gc.stringExtent("X").y;
+
+        for (String line : lines) {
+            Point extent = gc.stringExtent(line);
+            if (longest == null) {
+                longest = extent;
+                continue;
+            }
+
+            if (extent.x > longest.x) {
+                longest = extent;
+            }
+        }
+        gc.dispose();
+
+        int minHeight = typicalHeight * lines.length;
+
+        CLabel imgLabel = new CLabel(inner, SWT.NONE);
+        imgLabel.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING | GridData.HORIZONTAL_ALIGN_BEGINNING));
+        imgLabel.setImage(StudioImage.OK.getImage()); // TODO customize here !!!
+
+        CLabel titleLabel = new CLabel(inner, SWT.NONE);
+        titleLabel.setLayoutData(new GridData(GridData.FILL_HORIZONTAL | GridData.VERTICAL_ALIGN_CENTER));
+        titleLabel.setText(title);
+        titleLabel.setForeground(_titleFgColor);
+        Font f = titleLabel.getFont();
+        FontData fd = f.getFontData()[0];
+        fd.setStyle(SWT.BOLD);
+        fd.height = 11;
+        titleLabel.setFont(FontCache.getFont(fd));
+
+        Label text = new Label(inner, SWT.WRAP);
+        Font tf = text.getFont();
+        FontData tfd = tf.getFontData()[0];
+        tfd.setStyle(SWT.BOLD);
+        tfd.height = 8;
+        text.setFont(FontCache.getFont(tfd));
+        GridData gd = new GridData(GridData.FILL_BOTH);
+        gd.horizontalSpan = 2;
+        text.setLayoutData(gd);
+        text.setForeground(_fgColor);
+        text.setText(message);
+
+        minHeight = 100;
+
+        _shell.setSize(350, minHeight);
+
+        if (Display.getDefault().getActiveShell() == null || Display.getDefault().getActiveShell().getMonitor() == null) { return; }
+
+        Rectangle clientArea = Display.getDefault().getActiveShell().getMonitor().getClientArea();
+
+        int startX = clientArea.x + clientArea.width - 352;
+        int startY = clientArea.y + clientArea.height - 102;
+
+        // move other shells up
+        if (!_activeShells.isEmpty()) {
+            List<Shell> modifiable = new ArrayList<Shell>(_activeShells);
+            Collections.reverse(modifiable);
+            for (Shell shell : modifiable) {
+                Point curLoc = shell.getLocation();
+                shell.setLocation(curLoc.x, curLoc.y - 100);
+                if (curLoc.y - 100 < 0) {
+                    _activeShells.remove(shell);
+                    shell.dispose();
+                }
+            }
+        }
+
+        _shell.setLocation(startX, startY);
+        _shell.setAlpha(0);
+        _shell.setVisible(true);
+
+        _activeShells.add(_shell);
+
+        fadeIn(_shell);
+    }
+
+    private static void fadeIn(final Shell _shell) {
+        Runnable run = new Runnable() {
+
+            @Override
+            public void run() {
+                try {
+                    if (_shell == null || _shell.isDisposed()) { return; }
+
+                    int cur = _shell.getAlpha();
+                    cur += FADE_IN_STEP;
+
+                    if (cur > FINAL_ALPHA) {
+                        _shell.setAlpha(FINAL_ALPHA);
+                        startTimer(_shell);
+                        return;
+                    }
+
+                    _shell.setAlpha(cur);
+                    Display.getDefault().timerExec(FADE_TIMER, this);
+                } catch (Exception err) {
+                    err.printStackTrace();
+                }
+            }
+
+        };
+        Display.getDefault().timerExec(FADE_TIMER, run);
+    }
+
+    private static void startTimer(final Shell _shell) {
+        Runnable run = new Runnable() {
+
+            @Override
+            public void run() {
+                try {
+                    if (_shell == null || _shell.isDisposed()) { return; }
+
+                    fadeOut(_shell);
+                } catch (Exception err) {
+                    err.printStackTrace();
+                }
+            }
+
+        };
+        Display.getDefault().timerExec(DISPLAY_TIME, run);
+
+    }
+
+    private static void fadeOut(final Shell _shell) {
+        final Runnable run = new Runnable() {
+
+            @Override
+            public void run() {
+                try {
+                    if (_shell == null || _shell.isDisposed()) { return; }
+
+                    if (_oldImage != null) {
+                        _oldImage.dispose();
+                    }
+                    _shell.dispose();
+                    _activeShells.remove(_shell);
+                    return;
+                    
+                } catch (Exception err) {
+                    err.printStackTrace();
+                }
+            }
+
+        };
+        Display.getDefault().timerExec(FADE_TIMER, run);
+    }
+}
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/notification/package-info.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/notification/package-info.java
new file mode 100644
index 0000000..04cf2d8
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/notification/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.ui.common.notification;
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/AbstractEditor.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/AbstractEditor.java
new file mode 100644
index 0000000..e976fa1
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/AbstractEditor.java
@@ -0,0 +1,73 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.ui.common.widget;
+
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * An editor is a dialog part. From SWT point of view, it's a composite composed
+ * of a few SWT widgets. Here is a base class for implementing editors, such as
+ * list editors and map editors.
+ * 
+ * @author Etienne Gandrille
+ */
+public abstract class AbstractEditor {
+
+	/** The parent Shell */
+	protected Shell shell;
+
+	// labels
+	protected final String addLabel = "Add";
+	protected final String removeLabel = "Remove";
+
+	/** The JFace viewer */
+	protected StructuredViewer jFaceViewer;
+
+	/** The main composite for this widget. */
+	protected Composite widgetComposite;
+
+	public AbstractEditor(Composite parent) {
+		this.shell = parent.getShell();
+	}
+
+	/**
+	 * Sets the comparator, for sorting values.
+	 * 
+	 * @param comparator
+	 *            the new comparator
+	 */
+	public void setComparator(ViewerComparator comparator) {
+		jFaceViewer.setComparator(comparator);
+		refresh();
+	}
+
+	/**
+	 * Gets the default comparator.
+	 * 
+	 * @return the default comparator
+	 */
+	protected abstract ViewerComparator getDefaultComparator();
+
+	/**
+	 * Sets the composite layout data.
+	 */
+	public void setLayoutData(Object layoutData) {
+		widgetComposite.setLayoutData(layoutData);
+	}
+
+	/**
+	 * Repaints the widget.
+	 */
+	public abstract void refresh();
+}
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/ComboField.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/ComboField.java
new file mode 100644
index 0000000..7b1f809
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/ComboField.java
@@ -0,0 +1,72 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.ui.common.widget;
+
+import java.util.List;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Combo;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ComboField extends KeyValueField {
+
+	private final List<String> keyList;
+	
+	public ComboField(List<String> keyList) {
+		this.keyList = keyList;
+	}
+
+	@Override
+	protected Control createControl(Composite parent) {
+		Combo combo = new Combo(parent, SWT.BORDER);
+		for (String key : keyList)
+			combo.add(key);
+		
+		// combo.select(0); // less visual confusion is nothing is selected at
+
+		return combo;
+	}
+	
+	@Override
+	public String getValue() {
+		Combo combo = (Combo) getControl();
+		return combo.getText();
+	}
+
+	@Override
+	public void setValue(String value) {
+		Combo combo = (Combo) getControl();
+		combo.select(getIndex(value));
+	}
+
+	@Override
+	public void resetValue() {
+		Combo combo = (Combo) getControl();
+		combo.select(0);
+	}
+
+	private int getIndex(String value) {
+		Combo combo = (Combo) getControl();
+		for (int i = 0; i < combo.getItemCount(); i++) {
+			String name = combo.getItem(i);
+			if (name.equals(value))
+				return i;
+		}
+
+		// not found. A general purpose implementation would return -1 or throw
+		// an exception
+		return 0;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/KeyValueEditor.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/KeyValueEditor.java
new file mode 100644
index 0000000..abb6cbd
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/KeyValueEditor.java
@@ -0,0 +1,340 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.ui.common.widget;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.ISelectionChangedListener;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.SelectionChangedEvent;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+/**
+ * Base class for implementing key value editors.
+ * 
+ * @author Etienne Gandrille
+ */
+public class KeyValueEditor extends AbstractEditor {
+
+	private final Map<String, String> model;
+
+	// header widgets
+	private final KeyValueField keyField;
+	private final KeyValueField valueField;
+
+	// validators
+	private IInputValidator keyValidator = null;
+	private IInputValidator valueValidator = null;
+	
+	// table labels
+	private final String keyLabel;
+	private final String valueLabel;
+
+	private final ResizeListener resizeListener;
+
+	public KeyValueEditor(Composite parent, Map<String, String> input, String keyLabel, String valueLabel, KeyValueField keyField, KeyValueField valueField) {
+		super(parent);
+
+		this.model = input;
+		this.keyLabel = keyLabel;
+		this.valueLabel = valueLabel;
+		this.keyField = keyField;
+		this.valueField = valueField;
+		
+		
+		// Composite
+		widgetComposite = new Composite(parent, SWT.NONE);
+		widgetComposite.setLayout(new GridLayout(3, false));
+
+		// fields
+		keyField.setParent(widgetComposite);
+		keyField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+		valueField.setParent(widgetComposite);
+		valueField.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+		
+		// Add Button
+		final Button btnAdd = new Button(widgetComposite, SWT.NONE);
+		btnAdd.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
+		btnAdd.setText(addLabel);
+
+		// JFace Table Viewer
+		jFaceViewer = new TableViewer(widgetComposite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
+		jFaceViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
+		final TableViewerColumn col1 = createTableViewerColumn(jFaceViewer, 0, keyLabel);
+		final TableViewerColumn col2 = createTableViewerColumn(jFaceViewer, 1, valueLabel);
+		jFaceViewer.setContentProvider(new TableContentProvider());
+		jFaceViewer.setInput(input);
+		jFaceViewer.setComparator(getDefaultComparator());
+
+		// SWT Table widget configuration
+		Table swtTable = ((TableViewer) jFaceViewer).getTable();
+		swtTable.setHeaderVisible(true);
+		swtTable.setLinesVisible(true);
+
+		// Remove Button
+		final Button btnRemove = new Button(widgetComposite, SWT.NONE);
+		btnRemove.setText(removeLabel);
+		btnRemove.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
+
+		// Listeners
+		btnAdd.addMouseListener(new AddButtonListener(jFaceViewer));
+		resizeListener = new ResizeListener(col1, col2, jFaceViewer);
+		widgetComposite.addControlListener(resizeListener);
+		jFaceViewer.addSelectionChangedListener(new SelectTableListener());
+		btnRemove.addMouseListener(new RemoveButtonListener(parent.getShell(), jFaceViewer));
+	}
+
+	public Map<String, String> getModel() {
+		return model;
+	}
+
+	public void setKeyValidator(IInputValidator keyValidator) {
+		this.keyValidator = keyValidator;
+	}
+
+	public void setValueValidator(IInputValidator valueValidator) {
+		this.valueValidator = valueValidator;
+	}
+
+	private static class TableContentProvider implements IStructuredContentProvider {
+
+		@Override
+		public Object[] getElements(Object inputElement) {
+
+			@SuppressWarnings("unchecked")
+			Map<String, String> items = (Map<String, String>) inputElement;
+
+			List<String[]> retval = new ArrayList<String[]>();
+
+			for (String key : items.keySet()) {
+				String value = items.get(key);
+				String[] keyValue = new String[2];
+				keyValue[0] = key;
+				keyValue[1] = value;
+				retval.add(keyValue);
+			}
+
+			return retval.toArray();
+		}
+
+		@Override
+		public void dispose() {
+			// do nothing
+		}
+
+		@Override
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+			// do nothing
+		}
+	}
+
+	private static TableViewerColumn createTableViewerColumn(StructuredViewer viewer, final int index, String title) {
+		final TableViewerColumn viewerColumn = new TableViewerColumn(((TableViewer) viewer), SWT.NONE);
+		final TableColumn column = viewerColumn.getColumn();
+		column.setText(title);
+		column.setResizable(false);
+		column.setMoveable(false);
+		column.setAlignment(SWT.CENTER);
+
+		viewerColumn.setLabelProvider(new ColumnLabelProvider() {
+			@Override
+			public String getText(Object element) {
+				String[] keyValue = (String[]) element;
+				return keyValue[index];
+			}
+		});
+
+		return viewerColumn;
+	}
+
+	private class AddButtonListener implements MouseListener {
+		
+		/** The table. */
+		private StructuredViewer table;
+
+		public AddButtonListener(StructuredViewer table) {
+			this.table = table;
+		}
+
+		@Override
+		public void mouseDoubleClick(MouseEvent e) {
+			// do nothing
+		}
+
+		@Override
+		public void mouseDown(MouseEvent e) {
+			// do nothing
+		}
+
+		@Override
+		public void mouseUp(MouseEvent e) {
+			String str1 = keyField.getValue().trim();
+			String str2 = valueField.getValue().trim();
+
+			if (keyValidator != null) {
+				String msg = keyValidator.isValid(str1);
+				if (msg != null) {
+					String title = "Invalid \"" + keyLabel + "\" value";
+					MessageDialog.openError(shell, title, msg);
+					keyField.setFocus();
+					return;
+				}
+			}
+
+			if (valueValidator != null) {
+				String msg = valueValidator.isValid(str2);
+				if (msg != null) {
+					String title = "Invalid \"" + valueLabel + "\" value";
+					MessageDialog.openError(shell, title, msg);
+					valueField.setFocus();
+					return;
+				}
+			}
+
+			model.remove(str1);
+			model.put(str1, str2);
+			table.refresh();
+
+			keyField.resetValue();
+			valueField.resetValue();		
+			keyField.setFocus();
+		}
+	}
+
+	/**
+	 * Resize the table column as soon as a composite is resized.
+	 * 
+	 * @see ResizeEvent
+	 */
+	private class ResizeListener implements ControlListener {
+
+		final TableViewerColumn col1;
+		final TableViewerColumn col2;
+		final StructuredViewer table;
+
+		public ResizeListener(TableViewerColumn col1, TableViewerColumn col2, StructuredViewer table) {
+			this.col1 = col1;
+			this.col2 = col2;
+			this.table = table;
+		}
+
+		@Override
+		public void controlResized(ControlEvent e) {
+			Control control = table.getControl();
+			int width = control.getBounds().width / 2 - 2;
+			col1.getColumn().setWidth(width);
+			col2.getColumn().setWidth(width);
+			table.refresh();
+			table.getControl().redraw();
+		}
+
+		@Override
+		public void controlMoved(ControlEvent e) {
+			// do nothing
+		}
+	}
+
+	/**
+	 * Listener called when an element is selected in the table.
+	 * 
+	 * @see SelectTableEvent
+	 */
+	public class SelectTableListener implements ISelectionChangedListener {
+
+		public SelectTableListener() {
+		}
+
+		@Override
+		public void selectionChanged(SelectionChangedEvent event) {
+			StructuredSelection sel = (StructuredSelection) jFaceViewer.getSelection();
+			String[] line = (String[]) sel.getFirstElement();
+
+			if (line != null) {
+				String key = line[0];
+				String value = line[1];
+				
+				keyField.setValue(key);
+				valueField.setValue(value);
+			}
+		}
+	}
+
+	private class RemoveButtonListener implements MouseListener {
+
+		private Shell shell;
+		private StructuredViewer table;
+
+		public RemoveButtonListener(Shell shell, StructuredViewer table) {
+			this.shell = shell;
+			this.table = table;
+		}
+
+		@Override
+		public void mouseDoubleClick(MouseEvent e) {
+		}
+
+		@Override
+		public void mouseDown(MouseEvent e) {
+		}
+
+		@Override
+		public void mouseUp(MouseEvent e) {
+			StructuredSelection sel = (StructuredSelection) table.getSelection();
+			String[] line = (String[]) sel.getFirstElement();
+
+			if (line == null) {
+				MessageDialog.openError(shell, "Error", "Please select an element first.");
+			} else {
+				model.remove(line[0]);
+				table.refresh();
+			}
+		}
+	}
+
+	public void refresh() {
+		resizeListener.controlResized(null);
+	}
+
+	@Override
+	protected ViewerComparator getDefaultComparator() {
+		return new ViewerComparator() {
+			@Override
+			public int compare(Viewer viewer, Object e1, Object e2) {
+				String str1 = ((String[]) e1)[0];
+				String str2 = ((String[]) e2)[0];
+				return (str1.toUpperCase()).compareTo(str2.toUpperCase());
+			}
+		};
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/KeyValueField.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/KeyValueField.java
new file mode 100644
index 0000000..06f9455
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/KeyValueField.java
@@ -0,0 +1,53 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.ui.common.widget;
+
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+
+/**
+ * @author Etienne Gandrille
+ */
+public abstract class KeyValueField {
+
+	Composite parent = null;
+	Control control = null;
+	
+	public void setParent(Composite parent) {
+		this.parent = parent;
+	}
+	
+	public Control getControl() {
+		if (control == null) {
+			if (parent == null)
+				throw new RuntimeException("parent should be set");
+			control = createControl(parent);
+		}
+		return control;
+	}
+	
+	public void setLayoutData(Object layoutData) {
+		getControl().setLayoutData(layoutData);
+	}
+
+	public void setFocus() {
+		getControl().setFocus();
+	}
+	
+	protected abstract Control createControl(Composite parent);
+	
+	public abstract String getValue();
+	
+	public abstract void setValue(String value);
+	
+	public abstract void resetValue();
+}
+
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/KeyValueWidget.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/KeyValueWidget.java
new file mode 100644
index 0000000..5052e2c
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/KeyValueWidget.java
@@ -0,0 +1,177 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.ui.common.widget;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class KeyValueWidget {
+
+	private ControlListener resizeListener;
+	private final Control control;
+
+	KeyValueWidget(Composite parent, Map<String, String> input, String keyLabel, String valueLabel) {
+		control = createComposite(parent, input, keyLabel, valueLabel);
+	}
+
+	public Control getControl() {
+		return control;
+	}
+
+	public void setLayoutData(Object layoutData) {
+		control.setLayoutData(layoutData);
+	}
+
+	private Control createComposite(Composite parent, Map<String, String> input, String keyLabel, String valueLabel) {
+
+		// JFace Table Viewer
+		StructuredViewer jFaceViewer = new TableViewer(parent, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
+		jFaceViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+		final TableViewerColumn col1 = createTableViewerColumn(jFaceViewer, 0, keyLabel);
+		final TableViewerColumn col2 = createTableViewerColumn(jFaceViewer, 1, valueLabel);
+		jFaceViewer.setContentProvider(new TableContentProvider());
+		jFaceViewer.setInput(input);
+		jFaceViewer.setComparator(getDefaultComparator());
+
+		// SWT Table widget configuration
+		Table swtTable = ((TableViewer) jFaceViewer).getTable();
+		swtTable.setHeaderVisible(true);
+		swtTable.setLinesVisible(true);
+
+		// Listener
+		resizeListener = new ResizeListener(col1, col2, jFaceViewer);
+		jFaceViewer.getControl().addControlListener(resizeListener);
+
+		return jFaceViewer.getControl();
+	}
+
+	private static class TableContentProvider implements IStructuredContentProvider {
+
+		@Override
+		public Object[] getElements(Object inputElement) {
+
+			@SuppressWarnings("unchecked")
+			Map<String, String> items = (Map<String, String>) inputElement;
+
+			List<String[]> retval = new ArrayList<String[]>();
+
+			for (String key : items.keySet()) {
+				String value = items.get(key);
+				String[] keyValue = new String[2];
+				keyValue[0] = key;
+				keyValue[1] = value;
+				retval.add(keyValue);
+			}
+
+			return retval.toArray();
+		}
+
+		@Override
+		public void dispose() {
+			// do nothing
+		}
+
+		@Override
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+			// do nothing
+		}
+	}
+
+	private static TableViewerColumn createTableViewerColumn(StructuredViewer viewer, final int index, String title) {
+		final TableViewerColumn viewerColumn = new TableViewerColumn(((TableViewer) viewer), SWT.NONE);
+		final TableColumn column = viewerColumn.getColumn();
+		column.setText(title);
+		column.setResizable(false);
+		column.setMoveable(false);
+		column.setAlignment(SWT.LEFT);
+
+		viewerColumn.setLabelProvider(new ColumnLabelProvider() {
+			private String getTextFromObject(Object element) {
+				String[] keyValue = (String[]) element;
+				return keyValue[index];
+			}
+
+			@Override
+			public String getText(Object element) {
+				return getTextFromObject(element);
+			}
+
+			@Override
+			public String getToolTipText(Object element) {
+				return getTextFromObject(element);
+			}
+		});
+
+		return viewerColumn;
+	}
+
+	/**
+	 * Resize the table column as soon as a composite is resized.
+	 * 
+	 * @see ResizeEvent
+	 */
+	private static class ResizeListener implements ControlListener {
+
+		final TableViewerColumn col1;
+		final TableViewerColumn col2;
+		final StructuredViewer table;
+
+		public ResizeListener(TableViewerColumn col1, TableViewerColumn col2, StructuredViewer table) {
+			this.col1 = col1;
+			this.col2 = col2;
+			this.table = table;
+		}
+
+		@Override
+		public void controlResized(ControlEvent e) {
+			Control control = table.getControl();
+			int width = control.getBounds().width / 2 - 2;
+			col1.getColumn().setWidth(width);
+			col2.getColumn().setWidth(width);
+		}
+
+		@Override
+		public void controlMoved(ControlEvent e) {
+			// do nothing
+		}
+	}
+
+	private static ViewerComparator getDefaultComparator() {
+		return new ViewerComparator() {
+			@Override
+			public int compare(Viewer viewer, Object e1, Object e2) {
+				String str1 = ((String[]) e1)[0];
+				String str2 = ((String[]) e2)[0];
+				return (str1.toUpperCase()).compareTo(str2.toUpperCase());
+			}
+		};
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/ListEditor.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/ListEditor.java
new file mode 100644
index 0000000..36905f9
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/ListEditor.java
@@ -0,0 +1,196 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.ui.common.widget;
+
+import java.util.Comparator;
+import java.util.List;
+
+import org.eclipse.jface.dialogs.IInputValidator;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.viewers.ArrayContentProvider;
+import org.eclipse.jface.viewers.LabelProvider;
+import org.eclipse.jface.viewers.ListViewer;
+import org.eclipse.jface.viewers.StructuredSelection;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * A simple list<String> editor, with an add an a remove button.
+ * 
+ * @author Etienne Gandrille
+ */
+public class ListEditor extends AbstractEditor {
+
+	private List<String> model;
+
+	private Text text;
+
+	private IInputValidator validator = null;
+	
+	/**
+	 * Constructor.
+	 * 
+	 * @param parent
+	 *            the parent composite.
+	 * @param model
+	 *            the input, which can be an empty list, but mustn't be null.
+	 */
+	public ListEditor(Composite parent, List<String> model) {
+		super(parent);
+
+		this.model = model;
+
+		// Composite
+		widgetComposite = new Composite(parent, SWT.NONE);
+		widgetComposite.setLayout(new GridLayout(2, false));
+
+		// Text
+		text = new Text(widgetComposite, SWT.BORDER);
+		text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, false));
+
+		// Add Button
+		final Button btnAdd = new Button(widgetComposite, SWT.NONE);
+		btnAdd.setLayoutData(new GridData(SWT.FILL, SWT.FILL, false, false));
+		btnAdd.setText(addLabel);
+
+		// JFace List Viewer
+		jFaceViewer = new ListViewer(widgetComposite, SWT.H_SCROLL | SWT.V_SCROLL | SWT.BORDER);
+		jFaceViewer.setContentProvider(new ArrayContentProvider());
+		jFaceViewer.setLabelProvider(new LabelProvider());
+		jFaceViewer.setInput(model);
+		jFaceViewer.setComparator(getDefaultComparator());
+		jFaceViewer.getControl().setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
+
+		// Remove Button
+		final Button btnRemove = new Button(widgetComposite, SWT.NONE);
+		btnRemove.setText(removeLabel);
+		btnRemove.setLayoutData(new GridData(SWT.CENTER, SWT.CENTER, false, false));
+
+		// Listeners
+		btnAdd.addMouseListener(new AddButtonListener(shell, text, jFaceViewer));
+		btnRemove.addMouseListener(new RemoveButtonListener(shell, jFaceViewer));
+	}
+
+	public void setValidator(IInputValidator validator) {
+		this.validator = validator;
+	}
+	
+	private class AddButtonListener implements MouseListener {
+
+		private Text text;
+		private Shell shell;
+		private StructuredViewer list;
+
+		public AddButtonListener(Shell shell, Text text, StructuredViewer list) {
+			this.shell = shell;
+			this.text = text;
+			this.list = list;
+		}
+
+		@Override
+		public void mouseDoubleClick(MouseEvent e) {
+		}
+
+		@Override
+		public void mouseDown(MouseEvent e) {
+		}
+
+		@Override
+		public void mouseUp(MouseEvent e) {
+			String str = text.getText().trim();
+
+			if (str.isEmpty()) {
+				displayError("Can't add an empty string");
+				return;
+			} 
+			
+			if (model.contains(str)) {
+				displayError("\"" + str + "\"" + " is already in the list.");
+				return;
+			}
+			
+			if (validator != null) {
+				String msg = validator.isValid(str);
+				if (msg != null) {
+					displayError(msg);
+					return;
+				}
+			}
+			
+			model.add(str);
+			list.refresh();
+
+			text.setText("");
+			text.setFocus();
+		}
+		
+		void displayError(String message) {
+			MessageDialog.openError(shell, "Error", message);
+		}
+	}
+
+	/**
+	 * Listener called when clicking on the remove button.
+	 */
+	private class RemoveButtonListener implements MouseListener {
+
+		private Shell shell;
+		private StructuredViewer list;
+
+		public RemoveButtonListener(Shell shell, StructuredViewer list) {
+			this.shell = shell;
+			this.list = list;
+		}
+
+		@Override
+		public void mouseDoubleClick(MouseEvent e) {
+		}
+
+		@Override
+		public void mouseDown(MouseEvent e) {
+		}
+
+		@Override
+		public void mouseUp(MouseEvent e) {
+			StructuredSelection sel = (StructuredSelection) list.getSelection();
+			String str = (String) sel.getFirstElement();
+
+			if (str == null)
+				MessageDialog.openError(shell, "Error", "Please select an element first.");
+			else
+				model.remove(str);
+			list.refresh();
+		}
+	}
+
+	@Override
+	public void refresh() {
+	}
+
+	@Override
+	protected ViewerComparator getDefaultComparator() {
+		return new ViewerComparator(new Comparator<String>() {
+			@Override
+			public int compare(String o1, String o2) {
+				return o1.toUpperCase().compareTo(o2.toUpperCase());
+			}
+		});
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/MultiColumnTableWidget/DoubleClickListener.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/MultiColumnTableWidget/DoubleClickListener.java
new file mode 100644
index 0000000..a9d0a56
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/MultiColumnTableWidget/DoubleClickListener.java
@@ -0,0 +1,18 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.ui.common.widget.MultiColumnTableWidget;
+
+/**
+ * @author Etienne Gandrille
+ */
+public interface DoubleClickListener {
+	void onDoubleClick(String[] line, int columnNb);
+}
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/MultiColumnTableWidget/MultiColumnsTableWidget.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/MultiColumnTableWidget/MultiColumnsTableWidget.java
new file mode 100644
index 0000000..2004120
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/MultiColumnTableWidget/MultiColumnsTableWidget.java
@@ -0,0 +1,195 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.ui.common.widget.MultiColumnTableWidget;
+
+import java.math.BigDecimal;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.jface.viewers.ColumnLabelProvider;
+import org.eclipse.jface.viewers.IStructuredContentProvider;
+import org.eclipse.jface.viewers.StructuredViewer;
+import org.eclipse.jface.viewers.TableViewer;
+import org.eclipse.jface.viewers.TableViewerColumn;
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.events.PaintEvent;
+import org.eclipse.swt.events.PaintListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Event;
+import org.eclipse.swt.widgets.Listener;
+import org.eclipse.swt.widgets.Table;
+import org.eclipse.swt.widgets.TableColumn;
+import org.eclipse.swt.widgets.TableItem;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class MultiColumnsTableWidget {
+
+	final TableViewer jFaceViewer;
+
+	public MultiColumnsTableWidget(Composite parent, Object layoutData, boolean headerVisible, boolean linesVisible, String[] headers, int[] colWeight,
+			String[][] model, ViewerComparator comparator, final DoubleClickListener listener) {
+
+		// default comparator
+		if (comparator == null)
+			comparator = ViewerComparatorFactory.getAlphanumericalComparator();
+
+		// JFace Table Viewer
+		jFaceViewer = new TableViewer(parent, SWT.V_SCROLL | SWT.BORDER);
+		
+		jFaceViewer.getControl().setLayoutData(layoutData);
+		jFaceViewer.getControl().setSize(jFaceViewer.getControl().computeSize(600, 200, true));
+		List<TableViewerColumn> cols = new ArrayList<>();
+		for (int i = 0; i < headers.length; i++) {
+			cols.add(createTableViewerColumn(jFaceViewer, i, headers[i]));
+		}
+		jFaceViewer.setContentProvider(new TableContentProvider());
+		jFaceViewer.setInput(model);
+		jFaceViewer.setComparator(comparator);
+
+		// Double click on Table cell
+		if (listener != null) {
+			jFaceViewer.getTable().addListener(SWT.MouseDoubleClick, new Listener() {
+				@Override
+				public void handleEvent(Event event) {
+					Point clickPoint = new Point(event.x, event.y);
+					Table swtTable = jFaceViewer.getTable();
+
+					for (int lineNb = swtTable.getTopIndex(); lineNb < swtTable.getItemCount(); lineNb++) {
+						final TableItem curLine = swtTable.getItem(lineNb);
+						for (int columnNb = 0; columnNb < swtTable.getColumnCount(); columnNb++) {
+							Rectangle cellArea = curLine.getBounds(columnNb);
+							if (cellArea.contains(clickPoint)) {
+								String[] element = (String[]) jFaceViewer.getElementAt(lineNb);
+								listener.onDoubleClick(element, columnNb);
+							}
+						}
+					}
+				}
+			});
+		}
+
+		// SWT Table widget configuration
+		Table swtTable = jFaceViewer.getTable();
+		swtTable.setHeaderVisible(headerVisible);
+		swtTable.setLinesVisible(linesVisible);
+
+		// resize listener
+		ResizeOnPaintListener resizeListener = new ResizeOnPaintListener(cols, colWeight, jFaceViewer);
+		parent.addPaintListener(resizeListener);
+	}
+
+	public Control getControl(){
+		return jFaceViewer.getControl();
+	}
+	
+	public String[][] getModel() {
+		return (String[][]) jFaceViewer.getInput();
+	}
+
+	public void setModel(String[][] model) {
+		jFaceViewer.setInput(model);
+	}
+
+	public String[] getSelectedElement() {
+		TableItem[] sel = jFaceViewer.getTable().getSelection();
+		if (sel.length != 0) {
+			return (String[]) sel[0].getData();
+		}
+		return null;
+	}
+
+	public Object getLayoutData() {
+		return jFaceViewer.getTable().getLayoutData();
+	}
+
+	public void setFocus() {
+		jFaceViewer.getTable().setFocus();
+	}
+
+	private static TableViewerColumn createTableViewerColumn(TableViewer viewer, final int index, String title) {
+		final TableViewerColumn viewerColumn = new TableViewerColumn(viewer, SWT.NONE);
+		final TableColumn column = viewerColumn.getColumn();
+		column.setWidth(200);
+		column.setText(title);
+		column.setResizable(false);
+		column.setMoveable(false);
+		column.setAlignment(SWT.CENTER);
+		viewerColumn.setLabelProvider(new ColumnLabelProvider() {
+			@Override
+			public String getText(Object element) {
+				String[] keyValue = (String[]) element;
+				return keyValue[index];
+			}
+		});
+		return viewerColumn;
+	}
+
+	private static class TableContentProvider implements IStructuredContentProvider {
+		@Override
+		public Object[] getElements(Object inputElement) {
+			if (inputElement == null)
+				return new String[0][0];
+			else
+				return (String[][]) inputElement;
+		}
+
+		@Override
+		public void dispose() {
+			// do nothing
+		}
+
+		@Override
+		public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
+			// do nothing
+		}
+	}
+
+	private class ResizeOnPaintListener implements PaintListener {
+		final List<TableViewerColumn> cols;
+		final int[] colWeight;
+		final int sumWeight;
+		final StructuredViewer table;
+
+		public ResizeOnPaintListener(List<TableViewerColumn> cols, int[] colWeight, StructuredViewer table) {
+			this.cols = cols;
+			this.colWeight = colWeight;
+			this.sumWeight = computeSumWeight(colWeight);
+			this.table = table;
+		}
+
+		private int computeSumWeight(int[] colWeight2) {
+			int sum = 0;
+			for (int cur : colWeight2)
+				sum += cur;
+			return sum;
+		}
+
+		@Override
+		public void paintControl(PaintEvent e) {
+			Control control = table.getControl();
+			int availableWidth = control.getBounds().width - 2;
+			BigDecimal pointValue = new BigDecimal(availableWidth).divide(new BigDecimal(sumWeight), BigDecimal.ROUND_DOWN);
+			for (int i = 0; i < cols.size(); i++) {
+				BigDecimal curWidth = pointValue.multiply(new BigDecimal(colWeight[i]));
+				cols.get(i).getColumn().setWidth(curWidth.intValue() - 1);
+			}
+			table.refresh();
+			table.getControl().redraw();
+		}
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/MultiColumnTableWidget/ViewerComparatorFactory.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/MultiColumnTableWidget/ViewerComparatorFactory.java
new file mode 100644
index 0000000..039025c
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/MultiColumnTableWidget/ViewerComparatorFactory.java
@@ -0,0 +1,50 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.ui.common.widget.MultiColumnTableWidget;
+
+import org.eclipse.jface.viewers.Viewer;
+import org.eclipse.jface.viewers.ViewerComparator;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ViewerComparatorFactory {
+
+	public static ViewerComparator getAlphanumericalComparator() {
+		return new ViewerComparator() {
+			@Override
+			public int compare(Viewer viewer, Object e1, Object e2) {
+				String key1 = ((String[]) e1)[0];				
+				String key2 = ((String[]) e2)[0];
+				return key1.compareTo(key2);
+			}
+		};
+	}
+	
+	public static ViewerComparator getFullOrderComparator(final String[] keyList) {
+		return new ViewerComparator() {
+						
+			@Override
+			public int compare(Viewer viewer, Object e1, Object e2) {
+				String key1 = ((String[]) e1)[0];				
+				String key2 = ((String[]) e2)[0];
+				return getIndex(key1) - getIndex(key2);
+			}
+			
+			int getIndex(String key) {
+				for (int i=0; i<keyList.length; i++)
+					if (keyList[i].equals(key))
+						return i;
+				return -1;
+			}
+		};
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/MultiColumnTableWidget/package-info.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/MultiColumnTableWidget/package-info.java
new file mode 100644
index 0000000..50177da
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/MultiColumnTableWidget/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.ui.common.widget.MultiColumnTableWidget;
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/TextField.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/TextField.java
new file mode 100644
index 0000000..cbda515
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/TextField.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.ui.common.widget;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Text;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class TextField extends KeyValueField {
+	
+	@Override
+	protected Control createControl(Composite parent) {
+		return new Text(parent, SWT.BORDER);
+	}
+	
+	@Override
+	public String getValue() {
+		Text text = (Text) getControl();
+		return text.getText();
+	}
+
+	@Override
+	public void setValue(String value) {
+		Text text = (Text) getControl();
+		text.setText(value);
+	}
+
+	@Override
+	public void resetValue() {
+		setValue("");
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/package-info.java b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/package-info.java
new file mode 100644
index 0000000..bc38466
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.ui.common/src/org/eclipse/sensinact/studio/ui/common/widget/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.ui.common.widget;
diff --git a/bnd/org.eclipse.sensinact.studio.view.outdoor/.classpath b/bnd/org.eclipse.sensinact.studio.view.outdoor/.classpath
new file mode 100644
index 0000000..7a6fc25
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.outdoor/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="src" output="bin" path="src"/>
+	<classpathentry kind="src" output="bin_test" path="test">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bnd/org.eclipse.sensinact.studio.view.outdoor/.gitignore b/bnd/org.eclipse.sensinact.studio.view.outdoor/.gitignore
new file mode 100644
index 0000000..c2b941a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.outdoor/.gitignore
@@ -0,0 +1,2 @@
+/bin_test/
+/generated/
diff --git a/bnd/org.eclipse.sensinact.studio.view.outdoor/.project b/bnd/org.eclipse.sensinact.studio.view.outdoor/.project
new file mode 100644
index 0000000..ff4107c
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.outdoor/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.sensinact.studio.view.outdoor</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+	</natures>
+</projectDescription>
diff --git a/bnd/org.eclipse.sensinact.studio.view.outdoor/bnd.bnd b/bnd/org.eclipse.sensinact.studio.view.outdoor/bnd.bnd
new file mode 100644
index 0000000..828e1f6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.outdoor/bnd.bnd
@@ -0,0 +1,26 @@
+-buildpath: \
+	org.eclipse.ui.workbench,\
+	org.eclipse.core.runtime,\
+	org.eclipse.equinox.common,\
+	osgi.core,\
+	org.apache.log4j,\
+	org.eclipse.jface,\
+	org.eclipse.swt.win32.win32.x86_64,\
+	org.eclipse.sensinact.studio.model.resource;version=project,\
+	org.eclipse.draw2d,\
+	org.eclipse.nebula.visualization.xygraph,\
+	org.eclipse.sensinact.studio.http.messages;version=project,\
+	org.eclipse.sensinact.studio.http.services;version=project,\
+	org.eclipse.sensinact.studio.model.manager;version=project,\
+	org.eclipse.emf.ecore,\
+	org.eclipse.sensinact.studio.preferences,\
+	org.eclipse.emf.edit,\
+	org.eclipse.sensinact.studio.webapp.outdoor,\
+	osgi.annotation
+	
+Bundle-Version: 1.0.0.SNAPSHOT
+Bundle-SymbolicName: ${p};singleton:=true
+Bundle-ActivationPolicy: lazy
+
+-includeresource.model: \
+	plugin.xml
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.view.outdoor/plugin.xml b/bnd/org.eclipse.sensinact.studio.view.outdoor/plugin.xml
new file mode 100644
index 0000000..f74e957
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.outdoor/plugin.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2018 CEA.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+
+     Contributors:
+        CEA - initial API and implementation and/or initial documentation
+
+-->
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.ui.views">
+      <e4view
+            category="org.eclipse.sensinact.studio.views.category"
+            class="org.eclipse.sensinact.studio.view.outdoor.OutdoorDeploymentView"
+            id="org.eclipse.sensinact.studio.view.outdoor.view"
+            name="Deployment"
+            restorable="true">
+      </e4view>
+   </extension>
+</plugin>
diff --git a/bnd/org.eclipse.sensinact.studio.view.outdoor/src/org/eclipse/sensinact/studio/view/outdoor/OutdoorDeploymentView.java b/bnd/org.eclipse.sensinact.studio.view.outdoor/src/org/eclipse/sensinact/studio/view/outdoor/OutdoorDeploymentView.java
new file mode 100644
index 0000000..ce0a345
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.outdoor/src/org/eclipse/sensinact/studio/view/outdoor/OutdoorDeploymentView.java
@@ -0,0 +1,338 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.view.outdoor;
+
+import java.util.Arrays;
+import java.util.List;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+
+import org.apache.log4j.Logger;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.sensinact.studio.http.services.server.GatewayHttpServer;
+import org.eclipse.sensinact.studio.http.services.server.serverstarted.PortUpdate;
+import org.eclipse.sensinact.studio.http.services.server.serverstarted.ResourceAddedUpdate;
+import org.eclipse.sensinact.studio.http.services.server.serverstarted.ServerUpdatedListener;
+import org.eclipse.sensinact.studio.http.services.server.serverstarted.ServerUpdatedManager;
+import org.eclipse.sensinact.studio.http.services.server.serverstarted.UpdateDescriptor;
+import org.eclipse.sensinact.studio.model.manager.listener.devicelocation.DeviceIconListener;
+import org.eclipse.sensinact.studio.model.manager.listener.devicelocation.DeviceLocationListener;
+import org.eclipse.sensinact.studio.model.manager.listener.devicelocation.DeviceUpdateManager;
+import org.eclipse.sensinact.studio.model.manager.listener.devicelocation.DeviceSelectionListener;
+import org.eclipse.sensinact.studio.model.resource.utils.DeviceDescriptor;
+import org.eclipse.sensinact.studio.model.resource.utils.GPScoordinates;
+import org.eclipse.sensinact.studio.preferences.ConfigurationManager;
+import org.eclipse.sensinact.studio.webapp.outdoor.Startup;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.browser.Browser;
+import org.eclipse.swt.browser.ProgressEvent;
+import org.eclipse.swt.browser.ProgressListener;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DropTarget;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.DropTargetListener;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.ControlEvent;
+import org.eclipse.swt.events.ControlListener;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Control;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+import org.eclipse.ui.PlatformUI;
+
+/**
+ * @author Nicolas Hili, Etienne Gandrille
+ */
+public class OutdoorDeploymentView implements ServerUpdatedListener, DeviceLocationListener,  DeviceIconListener, DeviceSelectionListener {
+
+	private static final Logger logger = Logger.getLogger(OutdoorDeploymentView.class);
+	
+	public static final String VIEW_ID = "org.eclipse.sensinact.studio.view.outdoor.view";
+	
+	private static Browser browser;
+	private int studioPort = 0;
+	private static Composite dndComposite;
+	private static Shell dndShell;
+
+	private static boolean browserStarted = false;
+
+	public OutdoorDeploymentView() {
+		// stats server
+		GatewayHttpServer.getInstance();
+	}
+
+	@PostConstruct
+	public void createControls(final Composite parent) {
+		parent.setLayout(null);
+		parent.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, true, 1, 1));
+		browser = new Browser(parent, SWT.NONE);
+		
+		// Invisible shell and composite for Drag'n Drop feature
+		dndShell = new Shell(Display.getCurrent(), SWT.ON_TOP);
+		dndShell.open();
+		dndShell.setAlpha(125);
+		dndShell.setVisible(false);
+		dndComposite = new Composite(dndShell, SWT.NO_BACKGROUND);
+		dndComposite.setVisible(false);
+		DeviceUpdateManager manager = DeviceUpdateManager.getInstance();
+		// updates device position on the map
+		manager.addDeviceLocationListener(this);
+		manager.addDeviceSelectionListener(this);
+		manager.addDeviceIconListener(this);
+		
+		// swap browserStarted flag to true when browser is ready
+		browser.addProgressListener(new BrowserProgressListener());
+
+		// updates dnd elements when browser (more precisely, parent) geometry
+		// changes
+		parent.addControlListener(new ControlSizePositionListener(parent));
+
+		// drop target configuration
+		int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT;
+		Transfer[] transferTypes = new Transfer[] { TextTransfer.getInstance() };
+		DropTarget target = new DropTarget(dndComposite, operations);
+		target.setTransfer(transferTypes);
+
+		// when a device is dropped, updates its location
+		target.addDropListener(new DropListenerForDevices());
+
+		// when the server parameters are updated, the browser URL also
+		ServerUpdatedManager.getInstance().addServerUpdatedListener(this);
+		serverUpdated(null);
+	}
+
+	@PreDestroy
+	public void dispose() {
+		ServerUpdatedManager.getInstance().removeServerUpdatedListener(this);
+	}
+
+	public static void beginDrag() {
+		if (browserStarted) {
+			dndShell.setVisible(true);
+			dndComposite.setVisible(true);
+			updateDndInvisibleElementsGeometry();
+		}
+	}
+
+	public static void endDrag() {
+		dndShell.setVisible(false);
+		dndComposite.setVisible(false);
+	}
+
+	private static void updateDndInvisibleElementsGeometry() {
+		Point absolutePos = browser.toDisplay(0, 0);
+		dndShell.setBounds(absolutePos.x, absolutePos.y, browser.getBounds().width, browser.getBounds().height);
+		dndComposite.setBounds(0, 0, browser.getBounds().width, browser.getBounds().height);
+	}
+
+	/* ============== */
+	/* DeviceLocation */
+	/* ============== */
+
+	
+	@Override
+	public void deviceLocationUpdated(final GPScoordinates coordinate, final DeviceDescriptor descriptor) {	
+		Display.getDefault().asyncExec(new Runnable() {
+			@Override
+			public void run() {
+				String dev = "'" + descriptor.toString() + "'";
+				String icon = "'" + descriptor.getIcon() + "'";
+				String cmd = "updateDeviceLocation(" + coordinate.getLat() + "," + coordinate.getLng() + "," + dev + "," + icon + ");";
+				browser.execute(cmd);
+			}
+		});	
+	}
+
+	@Override
+	public void deviceRemoved(final DeviceDescriptor descriptor) {
+		Display.getDefault().asyncExec(new Runnable() {
+			@Override
+			public void run() {
+				String dev = "'" + descriptor.toString() + "'";
+				browser.execute("deleteMarker(" + dev + ");");
+			}
+		});
+	}
+
+	/* =========================== */
+	/* Gateway HTTP ServerListener */
+	/* =========================== */
+
+	@Override
+	public void serverUpdated(UpdateDescriptor descriptor) {
+		if (isUpdateNeeded(descriptor)) {
+			studioPort = ConfigurationManager.getStudioPort();
+			if (studioPort != 0) {
+				Display.getDefault().asyncExec(new Runnable() {
+					public void run() {
+						logger.debug("refresh browser");
+						browser.setUrl("http://localhost:" + studioPort + "/webapp/outdoor/static/outdoor.html");
+					}
+				});
+			}
+		}
+	}
+
+	private boolean isUpdateNeeded(UpdateDescriptor descriptor) {
+
+		if (descriptor == null) {
+			// server just started
+			return true;
+		} else {
+			switch (descriptor.getType()) {
+			case PORT_UPDATE:
+				PortUpdate pu = (PortUpdate) descriptor;
+				if (pu.getPort() != 0)
+					return true;
+				else
+					return false;
+			case RESOURCE_ADDED:
+				ResourceAddedUpdate ra = (ResourceAddedUpdate) descriptor;
+				List<String> paths = ra.getRegisteredPath();
+
+				if (! Arrays.asList(Startup.BUNDLE_PATHS).contains(ra.getCurPath()))
+					return false;
+				
+				for (String bundlePath : Startup.BUNDLE_PATHS) {
+					if (!paths.contains(bundlePath))
+						return false;
+				}
+				return true;
+			default:
+				throw new RuntimeException("Should never happend (" + descriptor.getType() + ")");
+			}
+		}
+	}
+
+	/* ================= */
+	/* Control listeners */
+	/* ================= */
+
+	private final class BrowserProgressListener implements ProgressListener {
+		public void changed(ProgressEvent event) {
+		}
+
+		public void completed(ProgressEvent event) {
+			browserStarted = true;
+		}
+	}
+
+	private final class ControlSizePositionListener implements ControlListener {
+		private final Composite parent;
+
+		private ControlSizePositionListener(Composite parent) {
+			this.parent = parent;
+		}
+
+		private void update(ControlEvent e) {
+			browser.setBounds(0, 0, parent.getBounds().width, parent.getBounds().height);
+			if (e.widget instanceof Control) {
+				updateDndInvisibleElementsGeometry();
+			}
+		}
+
+		@Override
+		public void controlResized(ControlEvent e) {
+			update(e);
+		}
+
+		@Override
+		public void controlMoved(ControlEvent e) {
+			update(e);
+		}
+	}
+
+	private final class DropListenerForDevices implements DropTargetListener {
+		@Override
+		public void dragEnter(DropTargetEvent event) {
+		}
+
+		@Override
+		public void dragLeave(DropTargetEvent event) {
+		}
+
+		@Override
+		public void dragOperationChanged(DropTargetEvent event) {
+		}
+
+		@Override
+		public void dragOver(DropTargetEvent event) {
+		}
+
+		@Override
+		public void drop(DropTargetEvent event) {
+
+			endDrag();
+
+			if (TextTransfer.getInstance().isSupportedType(event.currentDataType)) {
+				String dropText = (String) event.data;
+
+				if (event.widget instanceof DropTarget) {					
+					// Retrieve lat and lng
+					Point relativePos = ((DropTarget) event.widget).getControl().toControl(event.x, event.y);
+					String cmd1 = "return computeCoordinates(" + relativePos.x + "," + relativePos.y + ");";
+					Object[] coordinates = (Object[]) browser.evaluate(cmd1);
+					Double lat = (Double) coordinates[0];
+					Double lng = (Double) coordinates[1];
+
+					// Retrieve gateway and device
+					String[] tab = dropText.split("/");
+					String gateway = tab[0];
+					if (gateway.startsWith("["))
+						gateway = gateway.substring(1);
+					String device = tab[1];
+					
+					// try to update on server
+					boolean locationUpdated = DeviceUpdateManager.getInstance().updateLocationInServer(new DeviceDescriptor(gateway, device), new GPScoordinates(lat, lng));
+					
+					if (locationUpdated) {
+						String dev = "'" + gateway + "/" + device + "'";
+						String cmd = "return updateDeviceLocation(" + lat + "," + lng + "," + dev + ", 'default');";
+						browser.evaluate(cmd);
+					} else {
+						Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();						
+						MessageDialog.openWarning(shell, "Error", "The location of " + device + " device is NOT updatable");
+					}
+				}
+			}
+		}
+
+		@Override
+		public void dropAccept(DropTargetEvent event) {
+		}
+	}
+
+	@Override
+	public void deviceSelected(GPScoordinates coordinate) {
+		Display.getDefault().asyncExec(new Runnable() {
+			@Override
+			public void run() {
+				browser.execute("map.setView(["+coordinate.getLat()+","+coordinate.getLng()+"]);");
+			}
+		});
+		
+	}
+
+	@Override
+	public void deviceIconUpdated(DeviceDescriptor descriptor) {
+		Display.getDefault().asyncExec(new Runnable() {
+			@Override
+			public void run() {
+				String cmd = "updateDeviceIcon(\"" + descriptor.toString() + "\",\"" + descriptor.getIcon() + "\");";
+				browser.execute(cmd);
+			}
+		});
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.view.outdoor/src/org/eclipse/sensinact/studio/view/outdoor/package-info.java b/bnd/org.eclipse.sensinact.studio.view.outdoor/src/org/eclipse/sensinact/studio/view/outdoor/package-info.java
new file mode 100644
index 0000000..1293fd5
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.outdoor/src/org/eclipse/sensinact/studio/view/outdoor/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.view.outdoor;
diff --git a/bnd/org.eclipse.sensinact.studio.view.projectexplorer/.classpath b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/.classpath
new file mode 100644
index 0000000..9d984c5
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/.classpath
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry combineaccessrules="false" kind="src" path="/org.eclipse.sensinact.studio.language.sensinact"/>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="src" output="bin" path="src"/>
+	<classpathentry kind="src" output="bin_test" path="test">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bnd/org.eclipse.sensinact.studio.view.projectexplorer/.gitignore b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/.gitignore
new file mode 100644
index 0000000..c2b941a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/.gitignore
@@ -0,0 +1,2 @@
+/bin_test/
+/generated/
diff --git a/bnd/org.eclipse.sensinact.studio.view.projectexplorer/.project b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/.project
new file mode 100644
index 0000000..cf12bd7
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.sensinact.studio.view.projectexplorer</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+	</natures>
+</projectDescription>
diff --git a/bnd/org.eclipse.sensinact.studio.view.projectexplorer/bnd.bnd b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/bnd.bnd
new file mode 100644
index 0000000..bdce11d
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/bnd.bnd
@@ -0,0 +1,25 @@
+Bundle-Version: 1.0.0-SNAPSHOT
+Bundle-SymbolicName: ${p};singleton:=true
+Bundle-ActivationPolicy: lazy
+
+-enable-gecko-emf: true
+
+-includeresource.plugin: \
+	plugin.xml
+	
+-buildpath: \
+	org.eclipse.sensinact.studio.http.messages;verion=project,\
+	org.eclipse.sensinact.studio.ui.common;verion=project,\
+	org.eclipse.sensinact.studio.http.services;verion=project,\
+	org.eclipse.sensinact.studio.model.resource;verion=project,\
+	org.eclipse.sensinact.studio.model.manager;verion=project,\
+	org.eclipse.core.resources,\
+	org.eclipse.core.runtime,\
+	org.eclipse.equinox.common,\
+	org.eclipse.ui.ide,\
+	org.eclipse.ui.workbench,\
+	org.eclipse.jface,\
+	org.eclipse.core.commands,\
+	org.eclipse.swt.win32.win32.x86_64,\
+	org.apache.log4j,\
+	json
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.view.projectexplorer/plugin.xml b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/plugin.xml
new file mode 100644
index 0000000..6de7fd8
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/plugin.xml
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2018 CEA.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+
+     Contributors:
+        CEA - initial API and implementation and/or initial documentation
+
+-->
+<?eclipse version="3.0"?>
+
+<plugin>
+  <extension
+        point="org.eclipse.ui.handlers">
+     <handler
+           class="org.eclipse.sensinact.studio.view.projectexplorer.handler.SnaDeployHandler"
+           commandId="org.eclipse.sensinact.studio.language.sensinact.ui.handler.GenerationCommand">
+     </handler>
+  </extension>
+  
+  <extension
+        point="org.eclipse.ui.handlers">
+     <handler
+           class="org.eclipse.sensinact.studio.view.projectexplorer.handler.SnaRemoveHandler"
+           commandId="org.eclipse.sensinact.studio.language.sensinact.ui.handler.StopCommand">
+     </handler>
+  </extension>
+  
+  <extension
+        point="org.eclipse.ui.commands">
+     <command
+           id="org.eclipse.sensinact.studio.language.sensinact.ui.handler.GenerationCommand"
+           name="Deploy IoT application">
+     </command>
+  </extension>
+  
+  <extension
+        point="org.eclipse.ui.commands">
+     <command
+           id="org.eclipse.sensinact.studio.language.sensinact.ui.handler.StopCommand"
+           name="Remove IoT application">
+     </command>
+  </extension>
+  
+  <extension point="org.eclipse.ui.menus">
+	    <menuContribution locationURI="popup:org.eclipse.ui.navigator.ProjectExplorer#PopupMenu">
+	        <command
+	            commandId="org.eclipse.sensinact.studio.language.sensinact.ui.handler.GenerationCommand">
+	            <visibleWhen>
+					           <with variable="activeMenuSelection">
+					            <iterate
+					                 ifEmpty="false">
+					             <adapt type="org.eclipse.core.resources.IResource">
+					               <test property="org.eclipse.core.resources.name" value="*.sna" />
+					             </adapt>
+					            </iterate>
+					           </with>
+	         	</visibleWhen>
+	        </command>
+	    </menuContribution>
+	</extension>
+	
+	<extension point="org.eclipse.ui.menus">
+	    <menuContribution locationURI="popup:org.eclipse.ui.navigator.ProjectExplorer#PopupMenu">
+	        <command
+	            commandId="org.eclipse.sensinact.studio.language.sensinact.ui.handler.StopCommand">
+	            <visibleWhen>
+					           <with variable="activeMenuSelection">
+					            <iterate
+					                 ifEmpty="false">
+					             <adapt type="org.eclipse.core.resources.IResource">
+					               <test property="org.eclipse.core.resources.name" value="*.sna" />
+					             </adapt>
+					            </iterate>
+					           </with>
+	         	</visibleWhen>
+	        </command>
+	    </menuContribution>
+	</extension>
+		
+	<extension point="org.eclipse.ui.menus">
+	    <menuContribution locationURI="popup:#TextEditorContext?after=group.edit">
+	        <command
+	            commandId="org.eclipse.sensinact.studio.language.sensinact.ui.handler.GenerationCommand"
+	            style="push">
+	            <visibleWhen checkEnabled="false">
+	                   <reference
+	                         definitionId="org.eclipse.sensinact.studio.language.Sensinact.Editor.opened">
+	                   </reference>
+	            </visibleWhen>
+	        </command>
+	    </menuContribution>
+	</extension>
+	
+	<extension point="org.eclipse.ui.menus">
+	    <menuContribution locationURI="popup:#TextEditorContext?after=group.edit">
+	        <command
+	            commandId="org.eclipse.sensinact.studio.language.sensinact.ui.handler.StopCommand"
+	            style="push">
+	            <visibleWhen checkEnabled="false">
+	                   <reference
+	                         definitionId="org.eclipse.sensinact.studio.language.Sensinact.Editor.opened">
+	                   </reference>
+	            </visibleWhen>
+	        </command>
+	    </menuContribution>
+	</extension>
+</plugin>
diff --git a/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/Activator.java b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/Activator.java
new file mode 100644
index 0000000..67768ed
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/Activator.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.view.projectexplorer;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.sensinact.studio.view.projectexplorer"; //$NON-NLS-1$
+
+	// The shared instance
+	private static Activator plugin;
+	
+	/**
+	 * The constructor
+	 */
+	public Activator() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/SnaAppHandler.java b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/SnaAppHandler.java
new file mode 100644
index 0000000..f883779
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/SnaAppHandler.java
@@ -0,0 +1,84 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.view.projectexplorer.handler;
+
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.resources.IFile;
+import org.eclipse.core.resources.IFolder;
+import org.eclipse.core.resources.IProject;
+import org.eclipse.core.runtime.CoreException;
+import org.eclipse.core.runtime.NullProgressMonitor;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.emf.ecore.resource.ResourceSet;
+import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_SENSINACT;
+import org.eclipse.sensinact.studio.language.sensinact.Sensinact;
+import org.eclipse.sensinact.studio.ui.common.dialog.SnaHandler;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * @author Etienne Gandrille
+ */
+public abstract class SnaAppHandler extends SnaHandler {
+	
+	protected DSL_SENSINACT fileURI2eca(URI uri) {
+		ResourceSet rs = new ResourceSetImpl();
+		org.eclipse.emf.ecore.resource.Resource r = rs.getResource(uri, true);
+		Sensinact sens = (Sensinact) r.getContents().get(0);
+		return sens.getEca();
+	}
+	
+	protected URI selection2fileURI(ExecutionEvent event) {
+		Object firstElement = getSelectedElement(event);
+		if (firstElement != null && firstElement instanceof IFile) {
+			IFile file = (IFile) firstElement;			
+			// IProject project = file.getProject();
+			// createFolder(project);
+			return URI.createURI(file.getFullPath().toString());
+			//return URI.createPlatformResourceURI(file.getFullPath().toString(), true);
+		}
+
+		return null;
+	}
+
+	protected void createFolder(IProject project) throws CoreException {
+		IFolder srcGenFolder = project.getFolder("src-gen");
+		if (!srcGenFolder.exists()) {
+			srcGenFolder.create(true, true, new NullProgressMonitor());
+		}
+	}
+		
+	protected String computeRuleName(URI snaFileURI) {
+		String fileName = snaFileURI.segment(snaFileURI.segmentCount()-1);
+		
+		// removes extension at the end of the filename
+		if (fileName.lastIndexOf(".") != -1)
+			fileName = fileName.substring(0, fileName.lastIndexOf("."));
+		return fileName;
+	}
+	
+	protected void displayResult(Shell shell, String title, String fileName, MsgSensinact response) {
+		// TODO Needs to be improved. Displayed information are a bit weak...
+		
+		String description = response.toString();	
+		if (response.isValid())
+			MessageDialog.openInformation(shell, title, description);
+		else
+			MessageDialog.openError(shell, title, description);
+	}
+	
+	protected void displayResult(Shell shell, String title, String fileName, Exception e) {
+		String description = e.getMessage() + "\n" + "filename: " + fileName;
+		MessageDialog.openError(shell, title, description);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/SnaDeployHandler.java b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/SnaDeployHandler.java
new file mode 100644
index 0000000..a69a61e
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/SnaDeployHandler.java
@@ -0,0 +1,88 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.view.projectexplorer.handler;
+
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+import org.eclipse.sensinact.studio.http.services.client.GatewayHttpClient;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_SENSINACT;
+import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelEditor;
+import org.eclipse.sensinact.studio.model.resource.utils.Constants;
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+import org.eclipse.sensinact.studio.model.resource.utils.Segments;
+import org.eclipse.sensinact.studio.view.projectexplorer.handler.sna2json.SnaToJsonUtil;
+import org.eclipse.swt.widgets.Shell;
+import org.json.JSONException;
+import org.json.JSONObject;
+import org.eclipse.sensinact.studio.resource.AccessMethodType;
+import org.eclipse.sensinact.studio.ui.common.dialog.BasicListDialog;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class SnaDeployHandler extends SnaAppHandler {
+
+	private static final Logger logger = Logger.getLogger(SnaDeployHandler.class);
+	
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+			
+		Shell shell = getShell(event);
+		URI snaFileURI = selection2fileURI(event);
+		String fileName = computeRuleName(snaFileURI);
+		
+		try {
+			DSL_SENSINACT sna = fileURI2eca(snaFileURI);
+			JSONObject app = generateJsonApplication(sna, fileName);
+			
+			List<String> gatewayIds = ModelEditor.getInstance().getConnectedGatewaysId();
+			if (gatewayIds.size() == 0) {
+				MessageDialog.openError(getShell(event), "Application installation failed", "No connected gateway available.");
+			} else {
+				BasicListDialog listDialog = new BasicListDialog(getShell(event), "Connected gateways", "Please choose a Gateway", gatewayIds.toArray(new String[0]));
+				if (listDialog.open() == Window.OK) {
+					String gatewayID = listDialog.getFirstResult();
+					MsgSensinact response = install(Constants.createInstallAppRD(gatewayID), app);
+					String title = response.isValid() ? "Application deployed" : "Application deploy failed"; 
+					displayResult(shell, title, fileName, response);
+				}
+			}
+		} catch (Exception e) {
+			displayResult(shell, "Application deploy failed", fileName, e);
+			logger.error("Application deploy failed", e);
+			return null;
+		}
+
+		return null;
+	}
+
+	private MsgSensinact install(ResourceDescriptor resource, JSONObject json) throws IOException {
+		Thread.dumpStack();
+		Segments path = new Segments.Builder().resource(resource).method(AccessMethodType.ACT).build();
+		return GatewayHttpClient.sendPostRequest(path, json);
+	}
+	
+	private JSONObject generateJsonApplication(DSL_SENSINACT sna, String fileName) throws JSONException {
+		SnaParsingResult parsingResult = SnaToJsonUtil.parseSnaFile(sna, fileName);
+		JSONObject app = parsingResult.getApplication();
+		logger.debug("json generated");
+		logger.debug(app);
+		return app;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/SnaParsingResult.java b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/SnaParsingResult.java
new file mode 100644
index 0000000..433753c
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/SnaParsingResult.java
@@ -0,0 +1,29 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.view.projectexplorer.handler;
+
+import org.json.JSONObject;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class SnaParsingResult {
+
+	private final JSONObject jsonApplication;
+	
+	public SnaParsingResult(JSONObject jsonApplication) {
+		this.jsonApplication = jsonApplication;
+	}
+
+	public JSONObject getApplication() {
+		return jsonApplication;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/SnaRemoveHandler.java b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/SnaRemoveHandler.java
new file mode 100644
index 0000000..240ebe4
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/SnaRemoveHandler.java
@@ -0,0 +1,81 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.view.projectexplorer.handler;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.stream.Collectors;
+
+import org.apache.log4j.Logger;
+import org.eclipse.core.commands.ExecutionEvent;
+import org.eclipse.core.commands.ExecutionException;
+import org.eclipse.emf.common.util.URI;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.jface.window.Window;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+import org.eclipse.sensinact.studio.http.services.client.GatewayHttpClient;
+import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelEditor;
+import org.eclipse.sensinact.studio.model.resource.utils.Constants;
+import org.eclipse.sensinact.studio.model.resource.utils.JsonUtil;
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+import org.eclipse.sensinact.studio.model.resource.utils.Segments;
+import org.eclipse.sensinact.studio.resource.AccessMethodType;
+import org.eclipse.sensinact.studio.ui.common.dialog.BasicListDialog;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class SnaRemoveHandler extends SnaAppHandler {
+
+	private static final Logger logger = Logger.getLogger(SnaRemoveHandler.class);
+	
+	@Override
+	public Object execute(ExecutionEvent event) throws ExecutionException {
+		
+		URI snaFileURI = selection2fileURI(event);
+		String fileName = computeRuleName(snaFileURI);
+		
+		try {
+			List<String> gatewayIds = ModelEditor.getInstance().findApplications().stream().filter(sd -> sd.getService().equals(fileName)).map(sd -> sd.getGateway()).collect(Collectors.toList());
+			
+			if (gatewayIds.size() == 0) {
+				MessageDialog.openError(getShell(event), "Application removal failed", "Application not found.\nIs the gateway connected?");
+			} else {
+				BasicListDialog listDialog = new BasicListDialog(getShell(event), "Connected gateways", "Please choose a Gateway", gatewayIds.toArray(new String[0]));
+				if (listDialog.open() == Window.OK) {
+					String gatewayID = listDialog.getFirstResult();
+					MsgSensinact response = uninstall(Constants.createUninstallAppRD(gatewayID), fileName);
+					displayResult(getShell(event), "Application removed", fileName, response);					
+				}
+			}
+		} catch (Exception e) {
+			displayResult(getShell(event), "Application removed", fileName, e);
+			logger.error("Application removal failed", e);
+			return null;
+		}
+
+		return null;
+	}
+
+	private MsgSensinact uninstall(ResourceDescriptor resource, String name) throws JSONException, IOException {
+		JSONArray jsonParameters = new JSONArray();
+		JSONObject info = JsonUtil.createNameTypeValue("name", String.class.getName(), name);
+		jsonParameters.put(info);
+		JSONObject params = new JSONObject();
+		params.put("parameters", jsonParameters);
+		Segments path = new Segments.Builder().resource(resource).method(AccessMethodType.ACT).build();
+		MsgSensinact msg = GatewayHttpClient.sendPostRequest(path, jsonParameters);
+		return msg;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/BooleanVariableEventManager.java b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/BooleanVariableEventManager.java
new file mode 100644
index 0000000..bf92078
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/BooleanVariableEventManager.java
@@ -0,0 +1,52 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.view.projectexplorer.handler.sna2json;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class BooleanVariableEventManager implements EventManager {
+	
+	private final boolean trueFalse;
+	private final Variable variable;
+	
+	public BooleanVariableEventManager(Variable variable, boolean trueFalse) {
+		this.trueFalse = trueFalse;
+		this.variable = variable;
+	}
+	
+	@Override
+	public List<JSONObject> getDefaultEvents() throws JSONException {
+		List<JSONObject> list = new ArrayList<>();
+		
+		JSONObject vt = ComponentBuilder.valueType(variable.getFullName(), "variable");
+		JSONObject cond = new JSONObject();
+		cond.put("operator", "=");
+		cond.put("value", trueFalse);
+		cond.put("type", "boolean");
+		cond.put("complement", false);
+		
+		JSONArray array = new JSONArray();
+		array.put(cond);
+		
+		vt.put("conditions", array);
+		list.add(vt);		
+
+		return list;
+	}
+}
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/ComponentBuilder.java b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/ComponentBuilder.java
new file mode 100644
index 0000000..08440e1
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/ComponentBuilder.java
@@ -0,0 +1,199 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.view.projectexplorer.handler.sna2json;
+
+import java.util.UUID;
+
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import org.eclipse.sensinact.studio.language.sensinact.DSL_REF;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Resource;
+
+/**
+ * Helper class to build components which are JSON objects.
+ * @author Etienne Gandrille
+ */
+class ComponentBuilder {
+
+	private final String functionName;
+	private final String identifier;
+	private final boolean register;
+	
+	private final JSONArray events = new JSONArray();
+	private final JSONArray runparameters = new JSONArray();
+	
+	private final EventManager eventManager;
+	private final ResourcesDeclarationManager resMgr;
+	
+	// To prevent the object from being built twice
+	private boolean isBuilt = false;
+	
+	public ComponentBuilder(String functionName, String identifier, boolean register, EventManager eventManager, ResourcesDeclarationManager resMgr) {
+		this.functionName = functionName;
+		if (identifier == null || identifier.isEmpty())
+			this.identifier = UUID.randomUUID().toString();
+		else
+			this.identifier = identifier;
+		this.register = register;
+		this.eventManager = eventManager;
+		this.resMgr = resMgr;
+	}
+		
+	public JSONObject build() throws JSONException {
+		
+		if (isBuilt)
+			throw new RuntimeException("Object has already been built");
+		isBuilt = true;
+		
+		JSONObject component = new JSONObject();
+		component.put("events", events);	
+		component.put("function", buildFunction(functionName, runparameters));
+		component.put("identifier", identifier);
+		
+		// register
+		JSONObject reg = new JSONObject();
+		reg.put("register", register);
+		component.put("properties", reg);
+		
+		// default events
+		if (events.length() == 0) {
+			for (JSONObject object : eventManager.getDefaultEvents())
+				events.put(object);
+		}
+		
+		return component;
+	}
+		
+	private JSONObject buildFunction(String name, JSONArray runparameters) throws JSONException {
+		JSONObject function = new JSONObject();
+		function.put("name", name);
+		function.put("runparameters", runparameters);
+		return function;
+	}
+
+	public ComponentBuilder parameter(String value) throws JSONException {
+		runparameters.put(valueType(value, "string"));
+		return this;
+	}
+	
+	public ComponentBuilder parameter(long value) throws JSONException {
+		runparameters.put(valueType(value));
+		return this;
+	}	
+	
+	public ComponentBuilder parameter(double value) throws JSONException {
+		runparameters.put(valueType(value));
+		return this;
+	}	
+	
+	public ComponentBuilder parameter(boolean value) throws JSONException {
+		runparameters.put(valueType(value));
+		return this;
+	}	
+	
+	public ComponentBuilder parameter(DSL_REF value) throws JSONException {
+		return resourceVariable(value, runparameters);
+	}
+	
+	public ComponentBuilder parameterEvents(DSL_REF[] values) throws JSONException {
+		runparameters.put(valueType(values));
+		return this;
+	}
+
+	public ComponentBuilder parameterEvent(DSL_REF value) throws JSONException {
+		runparameters.put(valueType(value));
+		return this;
+	}
+
+	public ComponentBuilder parameterEvent(String name) throws JSONException {
+		runparameters.put(valueType(name, "event"));
+		return this;
+	}
+	
+	public ComponentBuilder event(DSL_REF value) throws JSONException {
+		return resourceVariable(value, events);
+	}
+			
+	public ComponentBuilder eventVariable(String value) throws JSONException {
+		events.put(valueType(value, "variable"));
+		return this;
+	}
+	
+	private ComponentBuilder resourceVariable(DSL_REF value, JSONArray array) throws JSONException {
+		array.put(resourceVariableInternal(resMgr, value));
+		return this;
+	}
+	
+	static JSONObject resourceVariableInternal(ResourcesDeclarationManager resMgr, DSL_REF value) throws JSONException {
+		String v = resMgr.getPathFromName(value.getName());
+		String t = getTypeName(value);
+		return valueType(v, t);
+	}
+	
+	private JSONObject valueType(double value) throws JSONException {
+		JSONObject vt = new JSONObject();
+		vt.put("value", value);
+		vt.put("type", "double");
+		return vt;
+	}
+	
+	private JSONObject valueType(long value) throws JSONException {
+		JSONObject vt = new JSONObject();
+		vt.put("value", value);
+		vt.put("type", "long");
+		return vt;
+	}
+	
+	private JSONObject valueType(Boolean value) throws JSONException {
+		JSONObject vt = new JSONObject();
+		vt.put("value", value);
+		vt.put("type", "boolean");
+		return vt;
+	}	
+
+	
+	private JSONObject valueType(DSL_REF value) throws JSONException {
+		String v = resMgr.getPathFromName(value.getName());
+		String t = getTypeName(value); 
+		return valueType(v, t);
+	}
+	
+	private static String getTypeName(DSL_REF value) {
+		if (value instanceof DSL_Resource)
+			return"resource";
+		else
+			return "variable";
+	}	
+	
+	static JSONObject valueType(String value, String type) throws JSONException {
+		JSONObject vt = new JSONObject();
+		vt.put("value", value);
+		vt.put("type", type);
+		return vt;
+	}	
+	
+	private JSONObject valueType(DSL_REF[] values) throws JSONException {
+		JSONObject vt = new JSONObject();	
+		JSONArray val = new JSONArray();
+		for (DSL_REF v : values)
+			val.put(resMgr.getPathFromName(v.getName()));
+		vt.put("value", val);
+		vt.put("type", "todo"); // syntax error : we can't assume all values have the same type
+		return vt;
+	}
+
+	public ComponentBuilder parameterVariable(String name) throws JSONException {
+		runparameters.put(valueType(name, "variable"));
+		return this;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/EventManager.java b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/EventManager.java
new file mode 100644
index 0000000..3ebbc84
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/EventManager.java
@@ -0,0 +1,26 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.view.projectexplorer.handler.sna2json;
+
+import java.util.List;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+/**
+ * The goal of an event manager is to provide the default events which should trigger a component if the component doesn't have any events. 
+ * The EventManager is designed to be used by a component builder, just before a component is built.  
+ * @author Etienne Gandrille
+ */
+public interface EventManager {
+	
+	public abstract List<JSONObject> getDefaultEvents() throws JSONException;		
+}
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/IfEventManager.java b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/IfEventManager.java
new file mode 100644
index 0000000..6eb6c53
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/IfEventManager.java
@@ -0,0 +1,45 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.view.projectexplorer.handler.sna2json;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import org.eclipse.sensinact.studio.language.sensinact.DSL_REF;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class IfEventManager implements EventManager {
+
+	private final List<DSL_REF> triggers;
+	private final ResourcesDeclarationManager resMgr;
+	
+	public IfEventManager(ResourcesDeclarationManager resMgr, List<DSL_REF> triggers) {
+		this.triggers = triggers;
+		this.resMgr = resMgr;
+	}
+
+	@Override
+	public List<JSONObject> getDefaultEvents() throws JSONException {
+		List<JSONObject> list = new ArrayList<>();
+		
+		for (DSL_REF ref : triggers) {
+			list.add(ComponentBuilder.resourceVariableInternal(resMgr, ref));
+		}
+		
+		return list;
+	}
+	
+}
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/ResourcesDeclarationManager.java b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/ResourcesDeclarationManager.java
new file mode 100644
index 0000000..ceb3f26
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/ResourcesDeclarationManager.java
@@ -0,0 +1,44 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.view.projectexplorer.handler.sna2json;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.eclipse.emf.common.util.EList;
+
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Resource;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class ResourcesDeclarationManager {
+
+	private final Map<String, DSL_Resource> name2fullPath = new HashMap<>();
+	
+	public ResourcesDeclarationManager(EList<DSL_Resource> resources) {
+		for (DSL_Resource resource : resources) {
+			name2fullPath.put(resource.getName(), resource);
+		}
+	}
+	
+	public DSL_Resource getResourceFromName(String name) {
+		DSL_Resource resource = name2fullPath.get(name);
+		if (resource == null)
+			throw new IllegalArgumentException(name);
+		return resource;
+	}
+	
+	public String getPathFromName(String name) {
+		DSL_Resource resource = getResourceFromName(name);
+		return "/" + resource.getDeviceID() + "/" + resource.getServiceID() + "/" + resource.getResourceID();
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/SnaToJsonUtil.java b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/SnaToJsonUtil.java
new file mode 100644
index 0000000..9c539a0
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/SnaToJsonUtil.java
@@ -0,0 +1,616 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.view.projectexplorer.handler.sna2json;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.eclipse.emf.common.util.EList;
+import org.eclipse.emf.ecore.EObject;
+import org.eclipse.sensinact.studio.model.resource.utils.JsonUtil;
+import org.eclipse.sensinact.studio.view.projectexplorer.handler.SnaParsingResult;
+import org.json.JSONArray;
+import org.json.JSONException;
+import org.json.JSONObject;
+
+import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_AFTER;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_AVG;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_BEFORE;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_COINCIDE;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_COUNT;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_DURATION;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_DURATION_MIN;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_DURATION_SEC;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_MAX;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_MIN;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_STATEMENT;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_CEP_SUM;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_ECA_STATEMENT;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_ElseDo;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_ElseIfDo;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Expression;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Expression_And;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Expression_Diff;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Expression_Division;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Expression_Equal;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Expression_Larger;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Expression_Larger_Equal;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Expression_Minus;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Expression_Modulo;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Expression_Multiplication;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Expression_Negate;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Expression_Or;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Expression_Plus;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Expression_Smaller;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Expression_Smaller_Equal;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_IfDo;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Object_Boolean;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Object_Number;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Object_Ref;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_Object_String;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_REF;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_REF_CONDITION;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_ResourceAction;
+import org.eclipse.sensinact.studio.language.sensinact.DSL_SENSINACT;
+
+/**
+ * Converts a SNA file into a JSON one packed into a SnaParsingResult object.
+ * 
+ * This class offers a single entry point : the static public method
+ * parseSnaFile.
+ * @author Etienne Gandrille
+ */
+public abstract class SnaToJsonUtil {
+
+	/** The logger */
+	private static final Logger logger = Logger.getLogger(SnaToJsonUtil.class);
+
+	/**
+	 * Converts a SNA file into a JSON one packed into a SnaParsingResult
+	 * object.
+	 * 
+	 * @param fileModel
+	 *            the file model
+	 * @param fileName
+	 *            the file name
+	 * @return A JSON packed into a SnaParsingResult object
+	 * @throws JSONException
+	 */
+	public static SnaParsingResult parseSnaFile(DSL_SENSINACT fileModel, String fileName) throws JSONException {
+
+		JSONArray components = new JSONArray();
+		JSONObject initialize = new JSONObject();
+		JSONObject finalize = new JSONObject();
+		
+		ResourcesDeclarationManager resMgr = new ResourcesDeclarationManager(fileModel.getResources());
+		
+		// initialize : autostart
+		setupInitializeOptions(fileModel, initialize);
+		
+		// set up file structure
+		JSONObject root = initFileStructure(fileName, components, initialize, finalize);
+
+		// CEP
+		for (DSL_CEP_STATEMENT cep : fileModel.getCep()) {
+			components.put(parseCepStatement(resMgr, cep));
+		}
+
+		// On
+		List<DSL_REF> triggers = new ArrayList<>();
+		for (DSL_REF_CONDITION triger : fileModel.getOn().getTriggers()) {
+			triggers.add(triger.getRef());
+		}
+
+		// If ... do ... else if ... do ... else do ... endif
+		DSL_ECA_STATEMENT eca = fileModel.getEca();
+		parseEcaStatement(fileName, resMgr, eca, components, triggers);
+
+		return new SnaParsingResult(root);
+	}
+
+	private static void setupInitializeOptions(DSL_SENSINACT fileModel, JSONObject initialize) throws JSONException {
+		
+		boolean autostart = true; // default value
+		if (fileModel.getAutostart() != null)
+			autostart = fileModel.getAutostart().isActivated();
+		
+		JSONObject object = new JSONObject();
+		object.put("autostart", autostart);
+		initialize.put("options", object);
+	}
+
+	/**
+	 * Parse an ECA statement and updates the JSON component array.
+	 * 
+	 * @param eca
+	 * @param components 
+	 * @param triggers
+	 * @throws JSONException
+	 */
+	private static void parseEcaStatement(String fileName, ResourcesDeclarationManager resMgr, DSL_ECA_STATEMENT eca, JSONArray components, List<DSL_REF> triggers) throws JSONException {
+		
+		VariableGenerator var = VariableGenerator.get(fileName, "condition");
+		
+		// if ...
+		try {
+			DSL_Expression expre = eca.getIfdo().getCondition();
+			EventManager eventManager = new IfEventManager(resMgr, triggers);
+			parseExpression(fileName, components, expre, triggers, eventManager, resMgr, var.newVariable());
+		} catch (JSONException e) {
+			logger.error("condition parsing error", e);
+		}
+
+		// do ...
+		DSL_IfDo ifDo = eca.getIfdo();
+		if (ifDo != null && ifDo.getActions() != null && ifDo.getActions().getActionList() != null) {
+			EList<DSL_ResourceAction> actionsTrue = ifDo.getActions().getActionList();
+			parseConditionalActions(fileName, resMgr, components, var.curVariable(), true, actionsTrue);
+		}
+
+		// else if ... do ...
+		EList<DSL_ElseIfDo> elseIfDoList = eca.getElseIfdo();
+		if (elseIfDoList != null) {
+			
+			for (DSL_ElseIfDo elseIfDo : elseIfDoList) {
+		
+				// else if ...
+				try {
+					DSL_Expression expre = elseIfDo.getCondition();
+					EventManager eventManager = new BooleanVariableEventManager(var.curVariable(), false);
+					parseExpression(fileName, components, expre, null, eventManager, resMgr, var.newVariable());
+				} catch (JSONException e) {
+					logger.error("condition parsing error", e);
+				}
+
+				// do ...
+				if (elseIfDo.getActions() != null && elseIfDo.getActions().getActionList() != null) {
+					EList<DSL_ResourceAction> actionsTrue = elseIfDo.getActions().getActionList();
+					parseConditionalActions(fileName, resMgr, components, var.curVariable(), true, actionsTrue);
+				}
+			}
+		}
+		
+		// else do ...
+		DSL_ElseDo elseDo = eca.getElsedo();
+		if (elseDo != null && elseDo.getActions() != null && elseDo.getActions().getActionList() != null) {
+			EList<DSL_ResourceAction> actionsFalse = elseDo.getActions().getActionList();
+			parseConditionalActions(fileName, resMgr, components, var.curVariable(), false, actionsFalse);
+		}
+	}
+
+	/**
+	 * Creates a JSON skeleton.
+	 * 
+	 * @param fileName
+	 *            the file name
+	 * @param components
+	 *            a components array
+	 * @param finalize
+	 *            a finalize statement array
+	 * @return the JSON skeleton
+	 */
+	private static JSONObject initFileStructure(String fileName, JSONArray components, JSONObject initialize, JSONObject finalize) {
+		try {
+			JSONObject root = new JSONObject();
+
+			JSONArray parameters = new JSONArray();
+			root.put("parameters", parameters);
+
+			JSONObject info = JsonUtil.createNameTypeValue("name", String.class.getName(), fileName);
+			parameters.put(info);
+
+			JSONObject contentValue = new JSONObject();
+			JSONObject content = JsonUtil.createNameTypeValue("content", JSONObject.class.getName(), contentValue);
+			parameters.put(content);
+
+			// initialize
+			contentValue.put("initialize", initialize);
+
+			// application
+			contentValue.put("application", components);
+
+			// finalize
+			contentValue.put("finalize", finalize);
+
+			return root;
+		} catch (JSONException e) {
+			logger.error("JSON init failed", e);
+			throw new RuntimeException("JSON init failed", e);
+		}
+	}
+
+	/**
+	 * Creates a JSON component representing a CEP statement. This component is
+	 * triggered by the function parameters and the output is the variable name.
+	 * 
+	 * @param statement
+	 *            a cep statement
+	 * @return a JSON component
+	 */
+	private static JSONObject parseCepStatement(ResourcesDeclarationManager resMgr, DSL_CEP_STATEMENT statement) {
+		try {
+			String variableName = statement.getName();
+			EObject operation = statement.getOperation();
+
+			if (operation instanceof DSL_CEP_AFTER) {
+				DSL_CEP_AFTER after = (DSL_CEP_AFTER) operation;
+
+				DSL_REF ref1 = after.getRef1().getRef();
+				DSL_REF ref2 = after.getRef2().getRef();
+				String start = buildDurationString(after.getStart());
+				String end = buildDurationString(after.getEnd());
+
+				ComponentBuilder cb = new ComponentBuilder("after", variableName, true, null, resMgr);
+				cb.event(ref1).event(ref2);
+				DSL_REF[] events = { ref1, ref2 };
+				cb.parameterEvents(events).parameter(start).parameter(end);
+
+				return cb.build();
+
+			} else if (operation instanceof DSL_CEP_BEFORE) {
+				DSL_CEP_BEFORE before = (DSL_CEP_BEFORE) operation;
+
+				DSL_REF ref1 = before.getRef1().getRef();
+				DSL_REF ref2 = before.getRef2().getRef();
+				String start = buildDurationString(before.getStart());
+				String end = buildDurationString(before.getEnd());
+
+				ComponentBuilder cb = new ComponentBuilder("before", variableName, true, null, resMgr);
+				cb.event(ref1).event(ref2);
+				DSL_REF[] events = { ref1, ref2 };
+				cb.parameterEvents(events).parameter(start).parameter(end);
+
+				return cb.build();
+
+			} else if (operation instanceof DSL_CEP_COINCIDE) {
+				DSL_CEP_COINCIDE coincide = (DSL_CEP_COINCIDE) operation;
+
+				DSL_REF ref1 = coincide.getRef1().getRef();
+				DSL_REF ref2 = coincide.getRef2().getRef();
+				String window = buildDurationString(coincide.getWindow());
+
+				ComponentBuilder cb = new ComponentBuilder("coincides", variableName, true, null, resMgr);
+				cb.event(ref1).event(ref2);
+				DSL_REF[] events = { ref1, ref2 };
+				cb.parameterEvents(events).parameter(window);
+
+				return cb.build();
+
+			} else if (operation instanceof DSL_CEP_MIN) {
+				DSL_CEP_MIN min = (DSL_CEP_MIN) operation;
+
+				DSL_REF ref = min.getRef().getRef();
+				String window = buildDurationString(min.getWindow());
+
+				ComponentBuilder cb = new ComponentBuilder("min", variableName, true, null, resMgr);
+				cb.event(ref);
+				cb.parameterEvent(ref).parameter(window);
+
+				return cb.build();
+
+			} else if (operation instanceof DSL_CEP_MAX) {
+				DSL_CEP_MAX max = (DSL_CEP_MAX) operation;
+
+				DSL_REF ref = max.getRef().getRef();
+				String window = buildDurationString(max.getWindow());
+
+				ComponentBuilder cb = new ComponentBuilder("max", variableName, true, null, resMgr);
+				cb.event(ref);
+				cb.parameterEvent(ref).parameter(window);
+
+				return cb.build();
+
+			} else if (operation instanceof DSL_CEP_AVG) {
+				DSL_CEP_AVG avg = (DSL_CEP_AVG) operation;
+
+				DSL_REF ref = avg.getRef().getRef();
+				String window = buildDurationString(avg.getWindow());
+
+				ComponentBuilder cb = new ComponentBuilder("avg", variableName, true, null, resMgr);
+				cb.event(ref);
+				cb.parameterEvent(ref).parameter(window);
+
+				return cb.build();
+
+			} else if (operation instanceof DSL_CEP_SUM) {
+				DSL_CEP_SUM sum = (DSL_CEP_SUM) operation;
+
+				DSL_REF ref = sum.getRef().getRef();
+				String window = buildDurationString(sum.getWindow());
+
+				ComponentBuilder cb = new ComponentBuilder("sum", variableName, true, null, resMgr);
+				cb.event(ref);
+				cb.parameterEvent(ref).parameter(window);
+
+				return cb.build();
+
+			} else if (operation instanceof DSL_CEP_COUNT) {
+				DSL_CEP_COUNT count = (DSL_CEP_COUNT) operation;
+
+				DSL_REF ref = count.getRef().getRef();
+				String window = buildDurationString(count.getWindow());
+
+				ComponentBuilder cb = new ComponentBuilder("count", variableName, true, null, resMgr);
+				cb.event(ref);
+				cb.parameterEvent(ref).parameter(window);
+
+				return cb.build();
+
+			} else {
+				throw new RuntimeException("Unknown statement operation : should never happen");
+			}
+		} catch (JSONException e) {
+			logger.error("DSL_CEP_STATEMENT parsing error", e);
+			throw new RuntimeException("DSL_CEP_STATEMENT parsing error", e);
+		}
+	}
+
+	/**
+	 * Parse actions which are embedded into a conditional statement. Creates
+	 * components accordingly.
+	 * 
+	 * @param actions
+	 *            an action list
+	 * @param components
+	 *            the components array, to be populated
+	 * @param triggerTrueFalse
+	 *            the conditional statement part
+	 * @throws JSONException
+	 */
+	private static void parseConditionalActions(String fileName, ResourcesDeclarationManager resMgr, JSONArray components, Variable triggerVariable, boolean triggerTrueFalse, EList<DSL_ResourceAction> actions) throws JSONException {
+		for (DSL_ResourceAction action : actions) {
+			parseConditionalAction(fileName, resMgr, components, triggerVariable, triggerTrueFalse, action);
+		}
+	}
+
+	/**
+	 * Parse an action which is embedded into a conditional statement. Creates
+	 * components accordingly.
+	 * 
+	 * @param actions
+	 *            an action
+	 * @param components
+	 *            the components array, to be populated
+	 * @param triggerTrueFalse
+	 *            the conditional statement part
+	 * @throws JSONException
+	 */
+	private static void parseConditionalAction(String fileName, ResourcesDeclarationManager resMgr, JSONArray components, Variable triggerVariable, boolean triggerTrueFalse, DSL_ResourceAction action) throws JSONException {
+
+		BooleanVariableEventManager eventManager = new BooleanVariableEventManager(triggerVariable, triggerTrueFalse);
+		String identifier = action.getVariable();
+		boolean register = identifier != null;
+		ComponentBuilder cb = new ComponentBuilder(action.getActiontype(), identifier, register, eventManager, resMgr);
+
+		// First parameter is the resource name on which the act is applied 
+		cb.parameter(action.getRef());
+		if (action.getListParam() != null && action.getListParam().getParam() != null)
+		{
+			for (DSL_Expression param : action.getListParam().getParam()) {
+				addParameter(fileName, param, cb, components, null, eventManager, resMgr);
+			}
+		}
+		components.put(cb.build());
+	}
+
+	/**
+	 * Add component to handle an expression.
+	 * 
+	 * @param expr
+	 *            The expression to be translated into components
+	 * @param output
+	 *            The expression output variable name
+	 * @param components
+	 *            The list of components, updated during the process
+	 * @param triggers
+	 * @param eventManager
+	 * @throws JSONException
+	 */
+	private static void parseExpression(String fileName, JSONArray components, DSL_Expression expr, List<DSL_REF> triggers, EventManager eventManager, ResourcesDeclarationManager resMgr, Variable output)
+			throws JSONException {
+
+		// Or: left associative, priority 1
+		if (expr instanceof DSL_Expression_Or) {
+			DSL_Expression_Or or = (DSL_Expression_Or) expr;
+			DSL_Expression left = or.getLeft();
+			DSL_Expression right = or.getRight();
+			parseExpressionInternal(fileName, resMgr, components, "or", triggers, eventManager, output, left, right);
+		}
+
+		// And: left associative, priority 2
+		else if (expr instanceof DSL_Expression_And) {
+			DSL_Expression_And and = (DSL_Expression_And) expr;
+			DSL_Expression left = and.getLeft();
+			DSL_Expression right = and.getRight();
+			parseExpressionInternal(fileName, resMgr, components, "and", triggers, eventManager, output, left, right);
+		}
+
+		// different/equal: left associative, priority 3
+		else if (expr instanceof DSL_Expression_Diff) {
+			DSL_Expression_Diff diff = (DSL_Expression_Diff) expr;
+			DSL_Expression left = diff.getLeft();
+			DSL_Expression right = diff.getRight();
+			parseExpressionInternal(fileName, resMgr, components, "diff", triggers, eventManager, output, left, right);
+
+		} else if (expr instanceof DSL_Expression_Equal) {
+			DSL_Expression_Equal equal = (DSL_Expression_Equal) expr;
+			DSL_Expression left = equal.getLeft();
+			DSL_Expression right = equal.getRight();
+			parseExpressionInternal(fileName, resMgr, components, "equal", triggers, eventManager, output, left, right);
+		}
+
+		// Comparisons: left associative, priority 4
+		else if (expr instanceof DSL_Expression_Larger) {
+			DSL_Expression_Larger largerThan = (DSL_Expression_Larger) expr;
+			DSL_Expression left = largerThan.getLeft();
+			DSL_Expression right = largerThan.getRight();
+			parseExpressionInternal(fileName, resMgr, components, "greaterThan", triggers, eventManager, output, left, right);
+
+		} else if (expr instanceof DSL_Expression_Larger_Equal) {
+			DSL_Expression_Larger_Equal largerEqual = (DSL_Expression_Larger_Equal) expr;
+			DSL_Expression left = largerEqual.getLeft();
+			DSL_Expression right = largerEqual.getRight();
+			parseExpressionInternal(fileName, resMgr, components, "greaterEqual", triggers, eventManager, output, left, right);
+
+		} else if (expr instanceof DSL_Expression_Smaller) {
+			DSL_Expression_Smaller smallerThan = (DSL_Expression_Smaller) expr;
+			DSL_Expression left = smallerThan.getLeft();
+			DSL_Expression right = smallerThan.getRight();
+			parseExpressionInternal(fileName, resMgr, components, "lesserThan", triggers, eventManager, output, left, right);
+
+		} else if (expr instanceof DSL_Expression_Smaller_Equal) {
+			DSL_Expression_Smaller_Equal smallerEqual = (DSL_Expression_Smaller_Equal) expr;
+			DSL_Expression left = smallerEqual.getLeft();
+			DSL_Expression right = smallerEqual.getRight();
+			parseExpressionInternal(fileName, resMgr, components, "lesserEqual", triggers, eventManager, output, left, right);
+		}
+
+		// addition/subtraction: left associative, priority 5
+		else if (expr instanceof DSL_Expression_Plus) {
+			DSL_Expression_Plus plus = (DSL_Expression_Plus) expr;
+			DSL_Expression left = plus.getLeft();
+			DSL_Expression right = plus.getRight();
+			parseExpressionInternal(fileName, resMgr, components, "add", triggers, eventManager, output, left, right);
+
+		} else if (expr instanceof DSL_Expression_Minus) {
+			DSL_Expression_Minus minus = (DSL_Expression_Minus) expr;
+			DSL_Expression left = minus.getLeft();
+			DSL_Expression right = minus.getRight();
+			parseExpressionInternal(fileName, resMgr, components, "sub", triggers, eventManager, output, left, right);
+		}
+
+		// multiplication/division/modulo, left associative, priority 6
+		else if (expr instanceof DSL_Expression_Multiplication) {
+			DSL_Expression_Multiplication multiply = (DSL_Expression_Multiplication) expr;
+			DSL_Expression left = multiply.getLeft();
+			DSL_Expression right = multiply.getRight();
+			parseExpressionInternal(fileName, resMgr, components, "times", triggers, eventManager, output, left, right);
+
+		} else if (expr instanceof DSL_Expression_Division) {
+			DSL_Expression_Division divide = (DSL_Expression_Division) expr;
+			DSL_Expression left = divide.getLeft();
+			DSL_Expression right = divide.getRight();
+			parseExpressionInternal(fileName, resMgr, components, "div", triggers, eventManager, output, left, right);
+
+		} else if (expr instanceof DSL_Expression_Modulo) {
+			DSL_Expression_Modulo modulo = (DSL_Expression_Modulo) expr;
+			DSL_Expression left = modulo.getLeft();
+			DSL_Expression right = modulo.getRight();
+			parseExpressionInternal(fileName, resMgr, components, "mod", triggers, eventManager, output, left, right);
+		}
+
+		// Unary operators: right associative, priority 7
+		else if (expr instanceof DSL_Expression_Negate) {
+			DSL_Expression_Negate negate = (DSL_Expression_Negate) expr;
+			DSL_Expression exp = negate.getExp();
+			parseExpressionInternal(fileName, resMgr, components, "not", triggers, eventManager, output, exp);
+		}
+
+		else
+			throw new RuntimeException("Should never happend");
+	}
+
+	private static void parseExpressionInternal(String fileName, ResourcesDeclarationManager resMgr, JSONArray components, String function, List<DSL_REF> triggers, EventManager eventManager,
+			Variable identifier, DSL_Expression... params) throws JSONException {
+		ComponentBuilder cb = new ComponentBuilder(function, identifier.getShortName(), false, eventManager, resMgr);
+		for (DSL_Expression param : params)
+			addParameter(fileName, param, cb, components, triggers, eventManager, resMgr);
+
+		components.put(cb.build());
+	}
+
+	private static void addParameter(String fileName, DSL_Expression expr, ComponentBuilder cb, JSONArray components, List<DSL_REF> triggers, EventManager eventManager, ResourcesDeclarationManager resMgr)
+			throws JSONException {
+
+		if (expr instanceof DSL_Object_Number) {
+			DSL_Object_Number number = (DSL_Object_Number) expr;
+
+			try {
+				long value = number.getValue().longValueExact();
+				cb.parameter(value);
+			} catch (ArithmeticException e) {
+				double value = number.getValue().doubleValue();
+				cb.parameter(value);
+			}
+
+		} else if (expr instanceof DSL_Object_String) {
+			DSL_Object_String str = (DSL_Object_String) expr;
+			cb.parameter(str.getValue());
+
+		} else if (expr instanceof DSL_Object_Boolean) {
+			DSL_Object_Boolean bool = (DSL_Object_Boolean) expr;
+			cb.parameter(bool.isValue());
+
+		} else if (expr instanceof DSL_Object_Ref) {
+			DSL_Object_Ref objRef = (DSL_Object_Ref) expr;
+			DSL_REF ref = objRef.getValue();
+
+			if (triggers != null && refInList(ref, triggers)) {
+				cb.parameterEvent(ref);
+				cb.event(ref);
+			} else {
+				cb.parameter(ref);
+			}
+		} else {
+			Variable outputVariable = VariableGenerator.get(fileName, "var").newVariable();
+			cb.parameterEvent(outputVariable.getFullName());
+			cb.eventVariable(outputVariable.getFullName());
+			parseExpression(fileName, components, expr, triggers, eventManager, resMgr, outputVariable);
+		}
+	}
+
+	/**
+	 * Checks if a reference is inside a list.
+	 * 
+	 * @param ref
+	 *            a reference
+	 * @param a
+	 *            list of references
+	 * @return true if the reference is inside the list, false otherwise.
+	 */
+	private static boolean refInList(DSL_REF ref, List<DSL_REF> list) {
+		for (DSL_REF trigger : list)
+			if (trigger.getName().equals(ref.getName()))
+				return true;
+		return false;
+	}
+
+	/**
+	 * Converts a cep duration into a string.
+	 * 
+	 * @param duration
+	 * @return a string
+	 */
+	private static String buildDurationString(DSL_CEP_DURATION duration) {
+		StringBuilder sb = new StringBuilder();
+
+		if (duration != null && duration.getUnits() != null) {
+			for (EObject unit : duration.getUnits()) {
+				if (unit instanceof DSL_CEP_DURATION_MIN) {
+					DSL_CEP_DURATION_MIN min = (DSL_CEP_DURATION_MIN) unit;
+					sb.append(min.getMin());
+					sb.append(" min ");
+				} else if (unit instanceof DSL_CEP_DURATION_SEC) {
+					DSL_CEP_DURATION_SEC sec = (DSL_CEP_DURATION_SEC) unit;
+					sb.append(sec.getSec());
+					sb.append(" sec ");
+				} else {
+					throw new RuntimeException("Should never happen");
+				}
+			}
+		} else {
+			sb.append("0 sec");
+		}
+
+		return sb.toString().trim();
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/Variable.java b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/Variable.java
new file mode 100644
index 0000000..8010ccf
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/Variable.java
@@ -0,0 +1,71 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.view.projectexplorer.handler.sna2json;
+
+public class Variable {
+
+	private final String appName;
+	private final String prefix;
+	private final int cpt;
+	
+	public Variable(String appName, String prefix, int cpt) {
+		this.appName = appName;
+		this.prefix = prefix;
+		this.cpt = cpt;
+	}
+
+	public String getShortName() {
+		return prefix + cpt;
+	}
+	
+	public String getFullName() {
+		return "/" + appName + "/" + prefix + cpt + "/result";
+	}
+	
+	@Override
+	public String toString() {
+		return "Variable [appName=" + appName + ", prefix=" + prefix + ", cpt=" + cpt + "]";
+	}
+	
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((appName == null) ? 0 : appName.hashCode());
+		result = prime * result + cpt;
+		result = prime * result + ((prefix == null) ? 0 : prefix.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		Variable other = (Variable) obj;
+		if (appName == null) {
+			if (other.appName != null)
+				return false;
+		} else if (!appName.equals(other.appName))
+			return false;
+		if (cpt != other.cpt)
+			return false;
+		if (prefix == null) {
+			if (other.prefix != null)
+				return false;
+		} else if (!prefix.equals(other.prefix))
+			return false;
+		return true;
+	}	
+}
diff --git a/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/VariableGenerator.java b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/VariableGenerator.java
new file mode 100644
index 0000000..77f16f9
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.projectexplorer/src/org/eclipse/sensinact/studio/view/projectexplorer/handler/sna2json/VariableGenerator.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.view.projectexplorer.handler.sna2json;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class VariableGenerator {
+	
+	private final static List<VariableGenerator> variables = new ArrayList<>();
+
+	private final String appName;
+	private final String prefix;
+	private int cpt = 0;
+	
+	private VariableGenerator(String appName, String prefix) {
+		this.appName = appName;
+		this.prefix = prefix;
+	}
+	
+	public static VariableGenerator get(String appName, String prefix) {
+
+		if (appName == null || appName.isEmpty())
+			throw new IllegalArgumentException("AppName should not be null or empty");
+		
+		if (prefix == null || prefix.isEmpty())
+			throw new IllegalArgumentException("Prefix should not be null or empty");
+		
+	
+		for (VariableGenerator variable : variables)
+			if (variable.getPrefix().equals(prefix) && variable.getAppName().equals(appName))
+				return variable;
+		
+		VariableGenerator var = new VariableGenerator(appName, prefix);
+		variables.add(var);
+		return var;
+	}
+
+	public String getAppName() {
+		return appName;
+	}
+	
+	public String getPrefix() {
+		return prefix;
+	} 
+	
+	public Variable newVariable() {
+		cpt++;
+		return new Variable(appName, prefix, cpt);
+	}
+	
+	public Variable curVariable() {
+		return new Variable(appName, prefix, cpt);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.view.visualizer/.classpath b/bnd/org.eclipse.sensinact.studio.view.visualizer/.classpath
new file mode 100644
index 0000000..7a6fc25
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.visualizer/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="src" output="bin" path="src"/>
+	<classpathentry kind="src" output="bin_test" path="test">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bnd/org.eclipse.sensinact.studio.view.visualizer/.gitignore b/bnd/org.eclipse.sensinact.studio.view.visualizer/.gitignore
new file mode 100644
index 0000000..c2b941a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.visualizer/.gitignore
@@ -0,0 +1,2 @@
+/bin_test/
+/generated/
diff --git a/bnd/org.eclipse.sensinact.studio.view.visualizer/.project b/bnd/org.eclipse.sensinact.studio.view.visualizer/.project
new file mode 100644
index 0000000..1678a13
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.visualizer/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.sensinact.studio.view.visualizer</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+	</natures>
+</projectDescription>
diff --git a/bnd/org.eclipse.sensinact.studio.view.visualizer/bnd.bnd b/bnd/org.eclipse.sensinact.studio.view.visualizer/bnd.bnd
new file mode 100644
index 0000000..6f5473e
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.visualizer/bnd.bnd
@@ -0,0 +1,24 @@
+-buildpath: \
+	org.eclipse.ui.workbench,\
+	org.eclipse.core.runtime,\
+	org.eclipse.equinox.common,\
+	osgi.core,\
+	org.apache.log4j,\
+	org.eclipse.jface,\
+	org.eclipse.swt.win32.win32.x86_64,\
+	org.eclipse.sensinact.studio.model.resource;version=project,\
+	org.eclipse.draw2d,\
+	org.eclipse.nebula.visualization.xygraph,\
+	org.eclipse.sensinact.studio.http.messages;version=project,\
+	org.eclipse.sensinact.studio.http.services;version=project,\
+	org.eclipse.sensinact.studio.model.manager;version=project,\
+	org.eclipse.emf.ecore,\
+	osgi.annotation
+	
+Bundle-Version: 1.0.0.SNAPSHOT
+Bundle-SymbolicName: ${p};singleton:=true
+Bundle-ActivationPolicy: lazy
+Bundle-Activator: org.eclipse.sensinact.studio.view.visualizer.Activator
+
+-includeresource.model: \
+	plugin.xml
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.view.visualizer/plugin.xml b/bnd/org.eclipse.sensinact.studio.view.visualizer/plugin.xml
new file mode 100644
index 0000000..5ea460d
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.visualizer/plugin.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2018 CEA.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+
+     Contributors:
+        CEA - initial API and implementation and/or initial documentation
+
+-->
+<?eclipse version="3.4"?>
+<plugin>
+   <extension
+         point="org.eclipse.ui.views">
+      <e4view
+            category="org.eclipse.sensinact.studio.views.category"
+            class="org.eclipse.sensinact.studio.view.visualizer.VisualizerView"
+            id="org.eclipse.sensinact.studio.view.visualizer.view"
+            name="Visualizer"
+            restorable="true">
+      </e4view>
+   </extension>
+
+</plugin>
diff --git a/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/Activator.java b/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/Activator.java
new file mode 100644
index 0000000..edce7f8
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/Activator.java
@@ -0,0 +1,58 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.view.visualizer;
+
+import org.eclipse.ui.plugin.AbstractUIPlugin;
+import org.osgi.framework.BundleContext;
+/**
+ * The activator class controls the plug-in life cycle
+ */
+public class Activator extends AbstractUIPlugin {
+
+	// The plug-in ID
+	public static final String PLUGIN_ID = "org.eclipse.sensinact.studio.view.visualizer"; //$NON-NLS-1$
+
+	// The shared instance
+	private static Activator plugin;
+	
+	/**
+	 * The constructor
+	 */
+	public Activator() {
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#start(org.osgi.framework.BundleContext)
+	 */
+	public void start(BundleContext context) throws Exception {
+		super.start(context);
+		plugin = this;
+	}
+
+	/*
+	 * (non-Javadoc)
+	 * @see org.eclipse.ui.plugin.AbstractUIPlugin#stop(org.osgi.framework.BundleContext)
+	 */
+	public void stop(BundleContext context) throws Exception {
+		plugin = null;
+		super.stop(context);
+	}
+
+	/**
+	 * Returns the shared instance
+	 *
+	 * @return the shared instance
+	 */
+	public static Activator getDefault() {
+		return plugin;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/VisualizerDropListener.java b/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/VisualizerDropListener.java
new file mode 100644
index 0000000..bedb280
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/VisualizerDropListener.java
@@ -0,0 +1,83 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.view.visualizer;
+
+import org.apache.log4j.Logger;
+import org.eclipse.jface.dialogs.MessageDialog;
+import org.eclipse.sensinact.studio.model.manager.modelupdater.ModelEditor;
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+import org.eclipse.swt.dnd.DropTarget;
+import org.eclipse.swt.dnd.DropTargetEvent;
+import org.eclipse.swt.dnd.DropTargetListener;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Shell;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class VisualizerDropListener implements DropTargetListener {
+
+	private final VisualizerView visualizerView;
+
+	private static final Logger logger = Logger.getLogger(VisualizerDropListener.class);
+	
+	public VisualizerDropListener(VisualizerView visualizerView) {
+		this.visualizerView = visualizerView;
+	}
+
+	@Override
+	public void dragEnter(DropTargetEvent event) {
+	}
+
+	@Override
+	public void dragLeave(DropTargetEvent event) {
+	}
+
+	@Override
+	public void dragOperationChanged(DropTargetEvent event) {
+	}
+
+	@Override
+	public void dragOver(DropTargetEvent event) {
+	}
+
+	@Override
+	public void drop(DropTargetEvent event) {
+		try {
+			if (TextTransfer.getInstance().isSupportedType(event.currentDataType)) {
+				if (event.widget instanceof DropTarget) {	
+					
+					ResourceDescriptor rDescriptor = null;
+					try {
+						rDescriptor = new ResourceDescriptor((String) event.data);
+					} catch (Exception e) {
+						throw new Exception("Only resources can be displayed in the visualizer");
+					}
+					
+					String typeName = ModelEditor.getInstance().getResourceClass(rDescriptor).getName();
+
+					VisualizerSettings visuSettings = new VisualizerSettings(rDescriptor, typeName);
+					visualizerView.dropValidated(visuSettings);
+				}
+			}
+		} catch (Exception e) {
+			Shell shell = Display.getCurrent().getActiveShell();
+			String msg = e.getMessage();
+			logger.error("Drop error: " + msg);
+			MessageDialog.openError(shell, "Error", msg);
+		}
+	}
+
+	@Override
+	public void dropAccept(DropTargetEvent event) {
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/VisualizerSettings.java b/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/VisualizerSettings.java
new file mode 100644
index 0000000..22341d2
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/VisualizerSettings.java
@@ -0,0 +1,35 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.view.visualizer;
+
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class VisualizerSettings {
+
+	private final ResourceDescriptor rDescriptor;
+	private final String typeName;
+	
+	public VisualizerSettings(ResourceDescriptor rDescriptor, String typeName) {
+		this.rDescriptor = rDescriptor;
+		this.typeName = typeName;
+	}
+	
+	public ResourceDescriptor getDescriptor() {
+		return rDescriptor;
+	}
+
+	public String getTypeName() {
+		return typeName;
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/VisualizerView.java b/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/VisualizerView.java
new file mode 100644
index 0000000..fa3e893
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/VisualizerView.java
@@ -0,0 +1,252 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.view.visualizer;
+
+import java.io.IOException;
+import java.util.List;
+
+import javax.annotation.PostConstruct;
+import javax.annotation.PreDestroy;
+
+import org.apache.log4j.Logger;
+import org.eclipse.draw2d.LightweightSystem;
+import org.eclipse.nebula.visualization.xygraph.figures.XYGraph;
+import org.eclipse.sensinact.studio.http.messages.snamessage.MsgSensinact;
+import org.eclipse.sensinact.studio.http.messages.snamessage.ObjectNameTypeValue;
+import org.eclipse.sensinact.studio.http.messages.snamessage.ValueType;
+import org.eclipse.sensinact.studio.http.messages.snamessage.attributevalueupdated.MsgAttributeValueUpdated;
+import org.eclipse.sensinact.studio.http.services.client.connectionmanager.NotifDispatcher;
+import org.eclipse.sensinact.studio.http.services.client.listener.NotifSubscriptionListener;
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+import org.eclipse.sensinact.studio.view.visualizer.graphmanager.GraphManager;
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.dnd.DND;
+import org.eclipse.swt.dnd.DropTarget;
+import org.eclipse.swt.dnd.TextTransfer;
+import org.eclipse.swt.dnd.Transfer;
+import org.eclipse.swt.events.MouseEvent;
+import org.eclipse.swt.events.MouseListener;
+import org.eclipse.swt.layout.GridData;
+import org.eclipse.swt.layout.GridLayout;
+import org.eclipse.swt.widgets.Button;
+import org.eclipse.swt.widgets.Canvas;
+import org.eclipse.swt.widgets.Composite;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.swt.widgets.Label;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class VisualizerView implements NotifSubscriptionListener {
+
+	private static final Logger logger = Logger.getLogger(VisualizerView.class);
+	
+	public static final String VIEW_ID = "org.eclipse.sensinact.studio.view.visualizer.view";
+	
+	private Label titleLabel = null;
+	private Composite contentComposite = null;
+	private Button btn = null;
+	private Label msgLabel = null;
+	private XYGraph xyGraph = null;
+	private GraphManager graphUpdater = null;
+	
+	private VisualizerSettings visuSettings = null;
+
+	private final String DEFAULT_TITLE = "";
+	private final String DEFAULT_MESSAGE = "Drag and drop a resource here !";
+	private final String DEFAULT_BTN_TEXT = "Listener not activated";
+	
+	@PostConstruct
+	public void createControls(Composite parent) {
+		parent.setLayout(new GridLayout(1, true));
+
+		// Label
+		GridData labelGridData = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
+		titleLabel = new Label(parent, SWT.CENTER);
+		titleLabel.setLayoutData(labelGridData);
+
+		// Composite : place holder for visualizer
+		GridData comositeGridData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
+		contentComposite = new Composite(parent, SWT.NONE);
+		contentComposite.setLayoutData(comositeGridData);
+		contentComposite.setLayout(new GridLayout(1, true));
+
+		// Message Label = to be updated -->
+		GridData msgGridData = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
+		msgLabel = new Label(contentComposite, SWT.WRAP);
+		msgLabel.setLayoutData(msgGridData);
+
+		// LightweightSystem creates the bridge between SWT and draw2D
+		GridData canevasData = new GridData(SWT.FILL, SWT.FILL, true, true, 1, 1);
+		Canvas canvas = new Canvas(contentComposite, SWT.NONE);
+		canvas.setLayoutData(canevasData);
+		final LightweightSystem lws = new LightweightSystem(canvas);
+	
+		// create a new XY Graph.
+		xyGraph = new XYGraph();
+		lws.setContents(xyGraph);	
+		graphUpdater = new GraphManager(xyGraph);
+		
+		// Button
+		GridData btnGridData = new GridData(SWT.FILL, SWT.FILL, true, false, 1, 1);
+		btn = new Button(parent, SWT.CENTER);
+		btn.setLayoutData(btnGridData);
+		btn.addMouseListener(new BtnListener());
+
+		// DND
+		int operations = DND.DROP_MOVE | DND.DROP_COPY | DND.DROP_DEFAULT;
+		Transfer[] transferTypes = new Transfer[] { TextTransfer.getInstance() };
+		DropTarget target = new DropTarget(parent, operations);
+		target.setTransfer(transferTypes);
+		target.addDropListener(new VisualizerDropListener(this));
+		
+		// set labels
+		resetUI();
+	}
+
+	@PreDestroy
+	public void dispose() {
+	}
+
+	void dropValidated(VisualizerSettings newSettings) throws IOException {
+
+		// unsubscribe
+		try {
+			if (visuSettings != null) {
+				unsubscribe(false);
+			}
+		} catch (IOException e) {
+			logger.error("unsubscribe failed", e);
+		}
+		
+		// subscribe
+		subscribe(newSettings, true);
+	}
+
+	private void subscribe(VisualizerSettings newSettings, boolean updateUI) throws IOException {
+		ResourceDescriptor resource = newSettings.getDescriptor();
+		NotifDispatcher.getInstance().subscribe(this);
+		this.visuSettings = newSettings;
+		
+		if (updateUI) {
+			graphUpdater.stop();
+			titleLabel.setText(resource.toString());
+			msgLabel.setText("Waiting for notification...");
+			btn.setText("Stop listener");
+			btn.setEnabled(true);
+		}
+	}
+	
+	private void unsubscribe(boolean updateUI) throws IOException {
+		NotifDispatcher.getInstance().unsubscribe(this);
+		visuSettings = null;
+		
+		if (updateUI) {
+			graphUpdater.stop();
+			resetUI();
+		}
+	}
+	
+	@Override
+	public void onLifecycleEvent(String gateway, List<MsgSensinact> message) {
+		// do nothing
+	}
+
+	@Override
+	public void onLocationEvent(String gateway, List<MsgSensinact> message) {
+		// do nothing
+	}
+	
+	@Override
+	public void onIconEvent(String gateway, List<MsgSensinact> message) {
+		// do nothing
+	}
+
+	@Override
+	public void onValueEvent(String gateway, List<MsgSensinact> messages) {
+		if (visuSettings != null) {
+			ResourceDescriptor desc = visuSettings.getDescriptor();
+			if (desc.getGateway().equals(gateway)) {
+				for (MsgSensinact m : messages) {
+					if (m instanceof MsgAttributeValueUpdated) {
+						MsgAttributeValueUpdated msg = (MsgAttributeValueUpdated) m;
+						if (msg.getUri().equals("/" + desc.getDevice() + "/" + desc.getService() + "/" + desc.getResource() + "/value")) {
+							ObjectNameTypeValue val = msg.getNotification();
+							onRelevantValue(val);
+						}						
+					}
+				}
+			}
+		}
+	}
+	
+	private void onRelevantValue(final ObjectNameTypeValue val) 
+	{
+		final String label = "New value: " + val.getValueAsString();
+		final ValueType type = val.getType();
+		final String valAsStr = val.getValueAsString();
+		final ResourceDescriptor resource = visuSettings.getDescriptor();
+		
+		Display.getDefault().asyncExec(new Runnable() {
+			public void run() 
+			{
+				msgLabel.setText(label);
+								
+				if (type == ValueType.INT) {
+					int value = Integer.parseInt(valAsStr);
+					updateGraph(resource, value);
+				} else if (type == ValueType.LONG) {
+					float value = Long.parseLong(valAsStr);
+					updateGraph(resource, value);
+				} else if (type == ValueType.DOUBLE) {
+					double value = Double.parseDouble(valAsStr);
+					updateGraph(resource, value);
+				} else {
+					logger.info(this.getClass().getCanonicalName() + ": Type " + type + " cannot produce chart");
+				}
+			}
+		});
+	}
+		
+	private void updateGraph(ResourceDescriptor resource, double value) {
+		graphUpdater.start(resource);
+		graphUpdater.setValue(value);
+	}
+	
+	private void resetUI() {
+		titleLabel.setText(DEFAULT_TITLE);
+		msgLabel.setText(DEFAULT_MESSAGE);
+		btn.setText(DEFAULT_BTN_TEXT);
+		btn.setEnabled(false);
+	}
+	
+	private class BtnListener implements MouseListener {
+
+		private final Logger logger = Logger.getLogger(BtnListener.class);
+		
+		@Override
+		public void mouseDoubleClick(MouseEvent e) {
+		}
+
+		@Override
+		public void mouseDown(MouseEvent e) {
+		}
+
+		@Override
+		public void mouseUp(MouseEvent e) {
+			try {
+				unsubscribe(true);
+			} catch (IOException e1) {
+				logger.error("Unsubscribe failed", e1);
+			}
+		}
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/graphmanager/GraphManager.java b/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/graphmanager/GraphManager.java
new file mode 100644
index 0000000..b6963d8
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/graphmanager/GraphManager.java
@@ -0,0 +1,107 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.view.visualizer.graphmanager;
+
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import org.eclipse.nebula.visualization.xygraph.dataprovider.CircularBufferDataProvider;
+import org.eclipse.nebula.visualization.xygraph.figures.Trace;
+import org.eclipse.nebula.visualization.xygraph.figures.Trace.PointStyle;
+import org.eclipse.sensinact.studio.model.resource.utils.ResourceDescriptor;
+import org.eclipse.nebula.visualization.xygraph.figures.XYGraph;
+import org.eclipse.swt.widgets.Display;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class GraphManager {
+
+	private final XYGraph graph;
+	private final AtomicBoolean isRuning;
+	private double value;
+	private final CircularBufferDataProvider traceDataProvider;
+	private final Trace trace;
+
+	private final double Y_MIN_INIT = 0;
+	private final double Y_MAX_INIT = 1;
+	private double yMin = Y_MIN_INIT;
+	private double yMax = Y_MAX_INIT;
+
+	private final int TIMER_PERIOD_MS = 250;
+	private final int NUMBER_OF_VALUES = 100;
+	
+	public GraphManager(XYGraph graph) {
+		this.graph = graph;
+		this.isRuning = new AtomicBoolean(false);
+
+		graph.setTitle("");
+		graph.primaryXAxis.setTitle("Time");
+		graph.primaryXAxis.setDateEnabled(true);
+		graph.primaryXAxis.setFormatPattern("HH:mm:ss");
+		
+		
+		graph.primaryYAxis.setTitle("value");
+		graph.primaryYAxis.setAutoScale(false);
+		graph.primaryXAxis.setAutoScale(true);
+		
+		traceDataProvider = new CircularBufferDataProvider(true);
+		traceDataProvider.setBufferSize(NUMBER_OF_VALUES);
+
+		trace = new Trace("values", graph.primaryXAxis, graph.primaryYAxis, traceDataProvider);
+		trace.setPointStyle(PointStyle.POINT);
+		graph.addTrace(trace);
+		graph.setShowLegend(false);
+	}
+
+	public void start(ResourceDescriptor rDescriptor) {
+		if (!isRuning.getAndSet(true)) {
+			traceDataProvider.clearTrace();
+
+			graph.setTitle(rDescriptor.getDevice() + "/" + rDescriptor.getService() + "/" + rDescriptor.getResource());
+			yMin = Y_MIN_INIT;
+			yMax = Y_MAX_INIT;
+			trace.getYAxis().setRange(Y_MIN_INIT,Y_MAX_INIT);
+						
+			Runnable updater = new Runnable() {
+				public void run() {
+					double curVal = value; // local copy
+					traceDataProvider.setCurrentYData(curVal, System.currentTimeMillis());
+					
+					if (yMin > curVal) {
+						yMin = curVal;
+						trace.getYAxis().setRange(yMin, yMax);
+					} else if (yMax < curVal) {
+						yMax = curVal;
+						trace.getYAxis().setRange(yMin, yMax);
+					}
+
+					if (isRuning.get()) {
+						Display.getDefault().timerExec(TIMER_PERIOD_MS, this);
+					}
+				}
+			};
+
+			Display.getDefault().timerExec(0, updater);
+		}
+	}
+
+	public void stop() {
+		isRuning.set(false);
+	}
+
+	public void setValue(double newValue) {
+		value = newValue;
+	}
+
+	boolean isRunning() {
+		return isRuning.get();
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/graphmanager/package-info.java b/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/graphmanager/package-info.java
new file mode 100644
index 0000000..3b9a46a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/graphmanager/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.view.visualizer.graphmanager;
diff --git a/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/package-info.java b/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/package-info.java
new file mode 100644
index 0000000..0f6800e
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.view.visualizer/src/org/eclipse/sensinact/studio/view/visualizer/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.view.visualizer;
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.indoor/.classpath b/bnd/org.eclipse.sensinact.studio.webapp.indoor/.classpath
new file mode 100644
index 0000000..7a6fc25
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.indoor/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="src" output="bin" path="src"/>
+	<classpathentry kind="src" output="bin_test" path="test">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.indoor/.gitignore b/bnd/org.eclipse.sensinact.studio.webapp.indoor/.gitignore
new file mode 100644
index 0000000..c2b941a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.indoor/.gitignore
@@ -0,0 +1,2 @@
+/bin_test/
+/generated/
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.indoor/.project b/bnd/org.eclipse.sensinact.studio.webapp.indoor/.project
new file mode 100644
index 0000000..bb959ac
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.indoor/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.sensinact.studio.webapp.indoor</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+	</natures>
+</projectDescription>
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.indoor/bnd.bnd b/bnd/org.eclipse.sensinact.studio.webapp.indoor/bnd.bnd
new file mode 100644
index 0000000..6186fb9
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.indoor/bnd.bnd
@@ -0,0 +1,7 @@
+Bundle-Version: 1.0.0.SNAPSHOT
+-buildpath: \
+	osgi.cmpn,\
+	org.eclipse.sensinact.studio.http.services;version=project,\
+	org.restlet
+-includeresource.webapp: \
+	webapp=webapp
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.indoor/src/org/eclipse/sensinact/studio/webapp/indoor/Startup.java b/bnd/org.eclipse.sensinact.studio.webapp.indoor/src/org/eclipse/sensinact/studio/webapp/indoor/Startup.java
new file mode 100644
index 0000000..929275f
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.indoor/src/org/eclipse/sensinact/studio/webapp/indoor/Startup.java
@@ -0,0 +1,34 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.webapp.indoor;
+
+import org.eclipse.sensinact.studio.http.services.server.RouteUtil;
+import org.eclipse.sensinact.studio.webapp.indoor.content.IndoorApplication;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+
+/**
+ * @author Etienne Gandrille
+ */
+@Component
+public class Startup{
+
+	private IndoorApplication route;
+
+	@Activate
+	public void activate() {
+		RouteUtil.attachRoute("/webapp/indoor", route = new IndoorApplication());
+	}
+	
+	public void deactivate() {
+		RouteUtil.detachRoute("/webapp/indoor", route);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.indoor/src/org/eclipse/sensinact/studio/webapp/indoor/content/IndoorApplication.java b/bnd/org.eclipse.sensinact.studio.webapp.indoor/src/org/eclipse/sensinact/studio/webapp/indoor/content/IndoorApplication.java
new file mode 100644
index 0000000..8e07a0b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.indoor/src/org/eclipse/sensinact/studio/webapp/indoor/content/IndoorApplication.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.webapp.indoor.content;
+
+import org.restlet.Application;
+import org.restlet.Restlet;
+import org.restlet.data.Reference;
+import org.restlet.resource.Directory;
+
+/**
+ * @author Nicolas Hili
+ * @since  Nov 19, 2014
+ */
+public class IndoorApplication extends Application {
+	@Override
+    public Restlet createInboundRoot() {
+    	Directory dir = new Directory(getContext(), new Reference(getClass().getClassLoader().getResource("/webapp")));
+    	return dir;
+    }
+}
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/WEB-INF/web.xml b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..2dc8359
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/WEB-INF/web.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+
+    Copyright (c) 2018 CEA.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+
+     Contributors:
+        CEA - initial API and implementation and/or initial documentation
+
+-->
+<web-app>
+	<welcome-file-list>
+		<welcome-file>outdoor.html</welcome-file> 
+	</welcome-file-list>
+</web-app> 
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/css/custom.css b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/css/custom.css
new file mode 100644
index 0000000..caa6364
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/css/custom.css
@@ -0,0 +1,15 @@
+/**
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+html, body, #map {
+	height:100%;
+	margin:0px;
+	padding:0px;
+}
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/css/leaflet.css b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/css/leaflet.css
new file mode 100644
index 0000000..dea175f
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/css/leaflet.css
@@ -0,0 +1,479 @@
+/* required styles */
+
+.leaflet-map-pane,
+.leaflet-tile,
+.leaflet-marker-icon,
+.leaflet-marker-shadow,
+.leaflet-tile-pane,
+.leaflet-tile-container,
+.leaflet-overlay-pane,
+.leaflet-shadow-pane,
+.leaflet-marker-pane,
+.leaflet-popup-pane,
+.leaflet-overlay-pane svg,
+.leaflet-zoom-box,
+.leaflet-image-layer,
+.leaflet-layer {
+	position: absolute;
+	left: 0;
+	top: 0;
+	}
+.leaflet-container {
+	overflow: hidden;
+	-ms-touch-action: none;
+	touch-action: none;
+	}
+.leaflet-tile,
+.leaflet-marker-icon,
+.leaflet-marker-shadow {
+	-webkit-user-select: none;
+	   -moz-user-select: none;
+	        user-select: none;
+	-webkit-user-drag: none;
+	}
+.leaflet-marker-icon,
+.leaflet-marker-shadow {
+	display: block;
+	}
+/* map is broken in FF if you have max-width: 100% on tiles */
+.leaflet-container img {
+	max-width: none !important;
+	}
+/* stupid Android 2 doesn't understand "max-width: none" properly */
+.leaflet-container img.leaflet-image-layer {
+	max-width: 15000px !important;
+	}
+.leaflet-tile {
+	filter: inherit;
+	visibility: hidden;
+	}
+.leaflet-tile-loaded {
+	visibility: inherit;
+	}
+.leaflet-zoom-box {
+	width: 0;
+	height: 0;
+	}
+/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
+.leaflet-overlay-pane svg {
+	-moz-user-select: none;
+	}
+
+.leaflet-tile-pane    { z-index: 2; }
+.leaflet-objects-pane { z-index: 3; }
+.leaflet-overlay-pane { z-index: 4; }
+.leaflet-shadow-pane  { z-index: 5; }
+.leaflet-marker-pane  { z-index: 6; }
+.leaflet-popup-pane   { z-index: 7; }
+
+.leaflet-vml-shape {
+	width: 1px;
+	height: 1px;
+	}
+.lvml {
+	behavior: url(#default#VML);
+	display: inline-block;
+	position: absolute;
+	}
+
+
+/* control positioning */
+
+.leaflet-control {
+	position: relative;
+	z-index: 7;
+	pointer-events: auto;
+	}
+.leaflet-top,
+.leaflet-bottom {
+	position: absolute;
+	z-index: 1000;
+	pointer-events: none;
+	}
+.leaflet-top {
+	top: 0;
+	}
+.leaflet-right {
+	right: 0;
+	}
+.leaflet-bottom {
+	bottom: 0;
+	}
+.leaflet-left {
+	left: 0;
+	}
+.leaflet-control {
+	float: left;
+	clear: both;
+	}
+.leaflet-right .leaflet-control {
+	float: right;
+	}
+.leaflet-top .leaflet-control {
+	margin-top: 10px;
+	}
+.leaflet-bottom .leaflet-control {
+	margin-bottom: 10px;
+	}
+.leaflet-left .leaflet-control {
+	margin-left: 10px;
+	}
+.leaflet-right .leaflet-control {
+	margin-right: 10px;
+	}
+
+
+/* zoom and fade animations */
+
+.leaflet-fade-anim .leaflet-tile,
+.leaflet-fade-anim .leaflet-popup {
+	opacity: 0;
+	-webkit-transition: opacity 0.2s linear;
+	   -moz-transition: opacity 0.2s linear;
+	     -o-transition: opacity 0.2s linear;
+	        transition: opacity 0.2s linear;
+	}
+.leaflet-fade-anim .leaflet-tile-loaded,
+.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
+	opacity: 1;
+	}
+
+.leaflet-zoom-anim .leaflet-zoom-animated {
+	-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
+	   -moz-transition:    -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
+	     -o-transition:      -o-transform 0.25s cubic-bezier(0,0,0.25,1);
+	        transition:         transform 0.25s cubic-bezier(0,0,0.25,1);
+	}
+.leaflet-zoom-anim .leaflet-tile,
+.leaflet-pan-anim .leaflet-tile,
+.leaflet-touching .leaflet-zoom-animated {
+	-webkit-transition: none;
+	   -moz-transition: none;
+	     -o-transition: none;
+	        transition: none;
+	}
+
+.leaflet-zoom-anim .leaflet-zoom-hide {
+	visibility: hidden;
+	}
+
+
+/* cursors */
+
+.leaflet-clickable {
+	cursor: pointer;
+	}
+.leaflet-container {
+	cursor: -webkit-grab;
+	cursor:    -moz-grab;
+	}
+.leaflet-popup-pane,
+.leaflet-control {
+	cursor: auto;
+	}
+.leaflet-dragging .leaflet-container,
+.leaflet-dragging .leaflet-clickable {
+	cursor: move;
+	cursor: -webkit-grabbing;
+	cursor:    -moz-grabbing;
+	}
+
+
+/* visual tweaks */
+
+.leaflet-container {
+	background: #ddd;
+	outline: 0;
+	}
+.leaflet-container a {
+	color: #0078A8;
+	}
+.leaflet-container a.leaflet-active {
+	outline: 2px solid orange;
+	}
+.leaflet-zoom-box {
+	border: 2px dotted #38f;
+	background: rgba(255,255,255,0.5);
+	}
+
+
+/* general typography */
+.leaflet-container {
+	font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
+	}
+
+
+/* general toolbar styles */
+
+.leaflet-bar {
+	box-shadow: 0 1px 5px rgba(0,0,0,0.65);
+	border-radius: 4px;
+	}
+.leaflet-bar a,
+.leaflet-bar a:hover {
+	background-color: #fff;
+	border-bottom: 1px solid #ccc;
+	width: 26px;
+	height: 26px;
+	line-height: 26px;
+	display: block;
+	text-align: center;
+	text-decoration: none;
+	color: black;
+	}
+.leaflet-bar a,
+.leaflet-control-layers-toggle {
+	background-position: 50% 50%;
+	background-repeat: no-repeat;
+	display: block;
+	}
+.leaflet-bar a:hover {
+	background-color: #f4f4f4;
+	}
+.leaflet-bar a:first-child {
+	border-top-left-radius: 4px;
+	border-top-right-radius: 4px;
+	}
+.leaflet-bar a:last-child {
+	border-bottom-left-radius: 4px;
+	border-bottom-right-radius: 4px;
+	border-bottom: none;
+	}
+.leaflet-bar a.leaflet-disabled {
+	cursor: default;
+	background-color: #f4f4f4;
+	color: #bbb;
+	}
+
+.leaflet-touch .leaflet-bar a {
+	width: 30px;
+	height: 30px;
+	line-height: 30px;
+	}
+
+
+/* zoom control */
+
+.leaflet-control-zoom-in,
+.leaflet-control-zoom-out {
+	font: bold 18px 'Lucida Console', Monaco, monospace;
+	text-indent: 1px;
+	}
+.leaflet-control-zoom-out {
+	font-size: 20px;
+	}
+
+.leaflet-touch .leaflet-control-zoom-in {
+	font-size: 22px;
+	}
+.leaflet-touch .leaflet-control-zoom-out {
+	font-size: 24px;
+	}
+
+
+/* layers control */
+
+.leaflet-control-layers {
+	box-shadow: 0 1px 5px rgba(0,0,0,0.4);
+	background: #fff;
+	border-radius: 5px;
+	}
+.leaflet-control-layers-toggle {
+	background-image: url(images/layers.png);
+	width: 36px;
+	height: 36px;
+	}
+.leaflet-retina .leaflet-control-layers-toggle {
+	background-image: url(images/layers-2x.png);
+	background-size: 26px 26px;
+	}
+.leaflet-touch .leaflet-control-layers-toggle {
+	width: 44px;
+	height: 44px;
+	}
+.leaflet-control-layers .leaflet-control-layers-list,
+.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
+	display: none;
+	}
+.leaflet-control-layers-expanded .leaflet-control-layers-list {
+	display: block;
+	position: relative;
+	}
+.leaflet-control-layers-expanded {
+	padding: 6px 10px 6px 6px;
+	color: #333;
+	background: #fff;
+	}
+.leaflet-control-layers-selector {
+	margin-top: 2px;
+	position: relative;
+	top: 1px;
+	}
+.leaflet-control-layers label {
+	display: block;
+	}
+.leaflet-control-layers-separator {
+	height: 0;
+	border-top: 1px solid #ddd;
+	margin: 5px -10px 5px -6px;
+	}
+
+
+/* attribution and scale controls */
+
+.leaflet-container .leaflet-control-attribution {
+	background: #fff;
+	background: rgba(255, 255, 255, 0.7);
+	margin: 0;
+	}
+.leaflet-control-attribution,
+.leaflet-control-scale-line {
+	padding: 0 5px;
+	color: #333;
+	}
+.leaflet-control-attribution a {
+	text-decoration: none;
+	}
+.leaflet-control-attribution a:hover {
+	text-decoration: underline;
+	}
+.leaflet-container .leaflet-control-attribution,
+.leaflet-container .leaflet-control-scale {
+	font-size: 11px;
+	}
+.leaflet-left .leaflet-control-scale {
+	margin-left: 5px;
+	}
+.leaflet-bottom .leaflet-control-scale {
+	margin-bottom: 5px;
+	}
+.leaflet-control-scale-line {
+	border: 2px solid #777;
+	border-top: none;
+	line-height: 1.1;
+	padding: 2px 5px 1px;
+	font-size: 11px;
+	white-space: nowrap;
+	overflow: hidden;
+	-moz-box-sizing: content-box;
+	     box-sizing: content-box;
+
+	background: #fff;
+	background: rgba(255, 255, 255, 0.5);
+	}
+.leaflet-control-scale-line:not(:first-child) {
+	border-top: 2px solid #777;
+	border-bottom: none;
+	margin-top: -2px;
+	}
+.leaflet-control-scale-line:not(:first-child):not(:last-child) {
+	border-bottom: 2px solid #777;
+	}
+
+.leaflet-touch .leaflet-control-attribution,
+.leaflet-touch .leaflet-control-layers,
+.leaflet-touch .leaflet-bar {
+	box-shadow: none;
+	}
+.leaflet-touch .leaflet-control-layers,
+.leaflet-touch .leaflet-bar {
+	border: 2px solid rgba(0,0,0,0.2);
+	background-clip: padding-box;
+	}
+
+
+/* popup */
+
+.leaflet-popup {
+	position: absolute;
+	text-align: center;
+	}
+.leaflet-popup-content-wrapper {
+	padding: 1px;
+	text-align: left;
+	border-radius: 12px;
+	}
+.leaflet-popup-content {
+	margin: 13px 19px;
+	line-height: 1.4;
+	}
+.leaflet-popup-content p {
+	margin: 18px 0;
+	}
+.leaflet-popup-tip-container {
+	margin: 0 auto;
+	width: 40px;
+	height: 20px;
+	position: relative;
+	overflow: hidden;
+	}
+.leaflet-popup-tip {
+	width: 17px;
+	height: 17px;
+	padding: 1px;
+
+	margin: -10px auto 0;
+
+	-webkit-transform: rotate(45deg);
+	   -moz-transform: rotate(45deg);
+	    -ms-transform: rotate(45deg);
+	     -o-transform: rotate(45deg);
+	        transform: rotate(45deg);
+	}
+.leaflet-popup-content-wrapper,
+.leaflet-popup-tip {
+	background: white;
+
+	box-shadow: 0 3px 14px rgba(0,0,0,0.4);
+	}
+.leaflet-container a.leaflet-popup-close-button {
+	position: absolute;
+	top: 0;
+	right: 0;
+	padding: 4px 4px 0 0;
+	text-align: center;
+	width: 18px;
+	height: 14px;
+	font: 16px/14px Tahoma, Verdana, sans-serif;
+	color: #c3c3c3;
+	text-decoration: none;
+	font-weight: bold;
+	background: transparent;
+	}
+.leaflet-container a.leaflet-popup-close-button:hover {
+	color: #999;
+	}
+.leaflet-popup-scrolled {
+	overflow: auto;
+	border-bottom: 1px solid #ddd;
+	border-top: 1px solid #ddd;
+	}
+
+.leaflet-oldie .leaflet-popup-content-wrapper {
+	zoom: 1;
+	}
+.leaflet-oldie .leaflet-popup-tip {
+	width: 24px;
+	margin: 0 auto;
+
+	-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
+	filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
+	}
+.leaflet-oldie .leaflet-popup-tip-container {
+	margin-top: -1px;
+	}
+
+.leaflet-oldie .leaflet-control-zoom,
+.leaflet-oldie .leaflet-control-layers,
+.leaflet-oldie .leaflet-popup-content-wrapper,
+.leaflet-oldie .leaflet-popup-tip {
+	border: 1px solid #999;
+	}
+
+
+/* div icon */
+
+.leaflet-div-icon {
+	background: #fff;
+	border: 1px solid #666;
+	}
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/indoor.html b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/indoor.html
new file mode 100644
index 0000000..0bac813
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/indoor.html
@@ -0,0 +1,28 @@
+<!--
+
+    Copyright (c) 2018 CEA.
+    All rights reserved. This program and the accompanying materials
+    are made available under the terms of the Eclipse Public License v1.0
+    which accompanies this distribution, and is available at
+    http://www.eclipse.org/legal/epl-v10.html
+
+     Contributors:
+        CEA - initial API and implementation and/or initial documentation
+
+-->
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+		<title>Outdoor Map</title>
+		<link rel="stylesheet" href="css/leaflet.css" />
+		<link rel="stylesheet" href="css/custom.css" />
+	</head>
+	<body>
+		<div id="map"></div>
+		<script src="js/leaflet.js"></script>
+		<script src="js/custom.js"></script>
+	</body>
+</html>
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/custom.js b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/custom.js
new file mode 100644
index 0000000..4dbe860
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/custom.js
@@ -0,0 +1,22 @@
+/*
+ * Copyright (c) 2018 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+var map = L.map('map').setView([43.464304, -3.810365], 15);
+
+L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+	attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors'
+}).addTo(map);
+
+function onMapClick(e) {
+   var marker = L.marker([43.464304, -3.810365]).bindPopup("<b>Hello world!</b><br>I am a popup.").addTo(map);
+}
+
+
+map.on('click', onMapClick);
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/images/layers-2x.png b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/images/layers-2x.png
new file mode 100644
index 0000000..a2cf7f9
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/images/layers-2x.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/images/layers.png b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/images/layers.png
new file mode 100644
index 0000000..bca0a0e
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/images/layers.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/images/marker-icon-2x.png b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/images/marker-icon-2x.png
new file mode 100644
index 0000000..0015b64
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/images/marker-icon-2x.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/images/marker-icon.png b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/images/marker-icon.png
new file mode 100644
index 0000000..e2e9f75
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/images/marker-icon.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/images/marker-shadow.png b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/images/marker-shadow.png
new file mode 100644
index 0000000..d1e773c
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/images/marker-shadow.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/leaflet-src.js b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/leaflet-src.js
new file mode 100644
index 0000000..d3d5635
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/leaflet-src.js
@@ -0,0 +1,9168 @@
+/*
+ Leaflet, a JavaScript library for mobile-friendly interactive maps. http://leafletjs.com
+ (c) 2010-2013, Vladimir Agafonkin
+ (c) 2010-2011, CloudMade
+*/
+(function (window, document, undefined) {
+var oldL = window.L,
+    L = {};
+
+L.version = '0.7.7';
+
+// define Leaflet for Node module pattern loaders, including Browserify
+if (typeof module === 'object' && typeof module.exports === 'object') {
+	module.exports = L;
+
+// define Leaflet as an AMD module
+} else if (typeof define === 'function' && define.amd) {
+	define(L);
+}
+
+// define Leaflet as a global L variable, saving the original L to restore later if needed
+
+L.noConflict = function () {
+	window.L = oldL;
+	return this;
+};
+
+window.L = L;
+
+
+/*
+ * L.Util contains various utility functions used throughout Leaflet code.
+ */
+
+L.Util = {
+	extend: function (dest) { // (Object[, Object, ...]) ->
+		var sources = Array.prototype.slice.call(arguments, 1),
+		    i, j, len, src;
+
+		for (j = 0, len = sources.length; j < len; j++) {
+			src = sources[j] || {};
+			for (i in src) {
+				if (src.hasOwnProperty(i)) {
+					dest[i] = src[i];
+				}
+			}
+		}
+		return dest;
+	},
+
+	bind: function (fn, obj) { // (Function, Object) -> Function
+		var args = arguments.length > 2 ? Array.prototype.slice.call(arguments, 2) : null;
+		return function () {
+			return fn.apply(obj, args || arguments);
+		};
+	},
+
+	stamp: (function () {
+		var lastId = 0,
+		    key = '_leaflet_id';
+		return function (obj) {
+			obj[key] = obj[key] || ++lastId;
+			return obj[key];
+		};
+	}()),
+
+	invokeEach: function (obj, method, context) {
+		var i, args;
+
+		if (typeof obj === 'object') {
+			args = Array.prototype.slice.call(arguments, 3);
+
+			for (i in obj) {
+				method.apply(context, [i, obj[i]].concat(args));
+			}
+			return true;
+		}
+
+		return false;
+	},
+
+	limitExecByInterval: function (fn, time, context) {
+		var lock, execOnUnlock;
+
+		return function wrapperFn() {
+			var args = arguments;
+
+			if (lock) {
+				execOnUnlock = true;
+				return;
+			}
+
+			lock = true;
+
+			setTimeout(function () {
+				lock = false;
+
+				if (execOnUnlock) {
+					wrapperFn.apply(context, args);
+					execOnUnlock = false;
+				}
+			}, time);
+
+			fn.apply(context, args);
+		};
+	},
+
+	falseFn: function () {
+		return false;
+	},
+
+	formatNum: function (num, digits) {
+		var pow = Math.pow(10, digits || 5);
+		return Math.round(num * pow) / pow;
+	},
+
+	trim: function (str) {
+		return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, '');
+	},
+
+	splitWords: function (str) {
+		return L.Util.trim(str).split(/\s+/);
+	},
+
+	setOptions: function (obj, options) {
+		obj.options = L.extend({}, obj.options, options);
+		return obj.options;
+	},
+
+	getParamString: function (obj, existingUrl, uppercase) {
+		var params = [];
+		for (var i in obj) {
+			params.push(encodeURIComponent(uppercase ? i.toUpperCase() : i) + '=' + encodeURIComponent(obj[i]));
+		}
+		return ((!existingUrl || existingUrl.indexOf('?') === -1) ? '?' : '&') + params.join('&');
+	},
+	template: function (str, data) {
+		return str.replace(/\{ *([\w_]+) *\}/g, function (str, key) {
+			var value = data[key];
+			if (value === undefined) {
+				throw new Error('No value provided for variable ' + str);
+			} else if (typeof value === 'function') {
+				value = value(data);
+			}
+			return value;
+		});
+	},
+
+	isArray: Array.isArray || function (obj) {
+		return (Object.prototype.toString.call(obj) === '[object Array]');
+	},
+
+	emptyImageUrl: 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs='
+};
+
+(function () {
+
+	// inspired by http://paulirish.com/2011/requestanimationframe-for-smart-animating/
+
+	function getPrefixed(name) {
+		var i, fn,
+		    prefixes = ['webkit', 'moz', 'o', 'ms'];
+
+		for (i = 0; i < prefixes.length && !fn; i++) {
+			fn = window[prefixes[i] + name];
+		}
+
+		return fn;
+	}
+
+	var lastTime = 0;
+
+	function timeoutDefer(fn) {
+		var time = +new Date(),
+		    timeToCall = Math.max(0, 16 - (time - lastTime));
+
+		lastTime = time + timeToCall;
+		return window.setTimeout(fn, timeToCall);
+	}
+
+	var requestFn = window.requestAnimationFrame ||
+	        getPrefixed('RequestAnimationFrame') || timeoutDefer;
+
+	var cancelFn = window.cancelAnimationFrame ||
+	        getPrefixed('CancelAnimationFrame') ||
+	        getPrefixed('CancelRequestAnimationFrame') ||
+	        function (id) { window.clearTimeout(id); };
+
+
+	L.Util.requestAnimFrame = function (fn, context, immediate, element) {
+		fn = L.bind(fn, context);
+
+		if (immediate && requestFn === timeoutDefer) {
+			fn();
+		} else {
+			return requestFn.call(window, fn, element);
+		}
+	};
+
+	L.Util.cancelAnimFrame = function (id) {
+		if (id) {
+			cancelFn.call(window, id);
+		}
+	};
+
+}());
+
+// shortcuts for most used utility functions
+L.extend = L.Util.extend;
+L.bind = L.Util.bind;
+L.stamp = L.Util.stamp;
+L.setOptions = L.Util.setOptions;
+
+
+/*
+ * L.Class powers the OOP facilities of the library.
+ * Thanks to John Resig and Dean Edwards for inspiration!
+ */
+
+L.Class = function () {};
+
+L.Class.extend = function (props) {
+
+	// extended class with the new prototype
+	var NewClass = function () {
+
+		// call the constructor
+		if (this.initialize) {
+			this.initialize.apply(this, arguments);
+		}
+
+		// call all constructor hooks
+		if (this._initHooks) {
+			this.callInitHooks();
+		}
+	};
+
+	// instantiate class without calling constructor
+	var F = function () {};
+	F.prototype = this.prototype;
+
+	var proto = new F();
+	proto.constructor = NewClass;
+
+	NewClass.prototype = proto;
+
+	//inherit parent's statics
+	for (var i in this) {
+		if (this.hasOwnProperty(i) && i !== 'prototype') {
+			NewClass[i] = this[i];
+		}
+	}
+
+	// mix static properties into the class
+	if (props.statics) {
+		L.extend(NewClass, props.statics);
+		delete props.statics;
+	}
+
+	// mix includes into the prototype
+	if (props.includes) {
+		L.Util.extend.apply(null, [proto].concat(props.includes));
+		delete props.includes;
+	}
+
+	// merge options
+	if (props.options && proto.options) {
+		props.options = L.extend({}, proto.options, props.options);
+	}
+
+	// mix given properties into the prototype
+	L.extend(proto, props);
+
+	proto._initHooks = [];
+
+	var parent = this;
+	// jshint camelcase: false
+	NewClass.__super__ = parent.prototype;
+
+	// add method for calling all hooks
+	proto.callInitHooks = function () {
+
+		if (this._initHooksCalled) { return; }
+
+		if (parent.prototype.callInitHooks) {
+			parent.prototype.callInitHooks.call(this);
+		}
+
+		this._initHooksCalled = true;
+
+		for (var i = 0, len = proto._initHooks.length; i < len; i++) {
+			proto._initHooks[i].call(this);
+		}
+	};
+
+	return NewClass;
+};
+
+
+// method for adding properties to prototype
+L.Class.include = function (props) {
+	L.extend(this.prototype, props);
+};
+
+// merge new default options to the Class
+L.Class.mergeOptions = function (options) {
+	L.extend(this.prototype.options, options);
+};
+
+// add a constructor hook
+L.Class.addInitHook = function (fn) { // (Function) || (String, args...)
+	var args = Array.prototype.slice.call(arguments, 1);
+
+	var init = typeof fn === 'function' ? fn : function () {
+		this[fn].apply(this, args);
+	};
+
+	this.prototype._initHooks = this.prototype._initHooks || [];
+	this.prototype._initHooks.push(init);
+};
+
+
+/*
+ * L.Mixin.Events is used to add custom events functionality to Leaflet classes.
+ */
+
+var eventsKey = '_leaflet_events';
+
+L.Mixin = {};
+
+L.Mixin.Events = {
+
+	addEventListener: function (types, fn, context) { // (String, Function[, Object]) or (Object[, Object])
+
+		// types can be a map of types/handlers
+		if (L.Util.invokeEach(types, this.addEventListener, this, fn, context)) { return this; }
+
+		var events = this[eventsKey] = this[eventsKey] || {},
+		    contextId = context && context !== this && L.stamp(context),
+		    i, len, event, type, indexKey, indexLenKey, typeIndex;
+
+		// types can be a string of space-separated words
+		types = L.Util.splitWords(types);
+
+		for (i = 0, len = types.length; i < len; i++) {
+			event = {
+				action: fn,
+				context: context || this
+			};
+			type = types[i];
+
+			if (contextId) {
+				// store listeners of a particular context in a separate hash (if it has an id)
+				// gives a major performance boost when removing thousands of map layers
+
+				indexKey = type + '_idx';
+				indexLenKey = indexKey + '_len';
+
+				typeIndex = events[indexKey] = events[indexKey] || {};
+
+				if (!typeIndex[contextId]) {
+					typeIndex[contextId] = [];
+
+					// keep track of the number of keys in the index to quickly check if it's empty
+					events[indexLenKey] = (events[indexLenKey] || 0) + 1;
+				}
+
+				typeIndex[contextId].push(event);
+
+
+			} else {
+				events[type] = events[type] || [];
+				events[type].push(event);
+			}
+		}
+
+		return this;
+	},
+
+	hasEventListeners: function (type) { // (String) -> Boolean
+		var events = this[eventsKey];
+		return !!events && ((type in events && events[type].length > 0) ||
+		                    (type + '_idx' in events && events[type + '_idx_len'] > 0));
+	},
+
+	removeEventListener: function (types, fn, context) { // ([String, Function, Object]) or (Object[, Object])
+
+		if (!this[eventsKey]) {
+			return this;
+		}
+
+		if (!types) {
+			return this.clearAllEventListeners();
+		}
+
+		if (L.Util.invokeEach(types, this.removeEventListener, this, fn, context)) { return this; }
+
+		var events = this[eventsKey],
+		    contextId = context && context !== this && L.stamp(context),
+		    i, len, type, listeners, j, indexKey, indexLenKey, typeIndex, removed;
+
+		types = L.Util.splitWords(types);
+
+		for (i = 0, len = types.length; i < len; i++) {
+			type = types[i];
+			indexKey = type + '_idx';
+			indexLenKey = indexKey + '_len';
+
+			typeIndex = events[indexKey];
+
+			if (!fn) {
+				// clear all listeners for a type if function isn't specified
+				delete events[type];
+				delete events[indexKey];
+				delete events[indexLenKey];
+
+			} else {
+				listeners = contextId && typeIndex ? typeIndex[contextId] : events[type];
+
+				if (listeners) {
+					for (j = listeners.length - 1; j >= 0; j--) {
+						if ((listeners[j].action === fn) && (!context || (listeners[j].context === context))) {
+							removed = listeners.splice(j, 1);
+							// set the old action to a no-op, because it is possible
+							// that the listener is being iterated over as part of a dispatch
+							removed[0].action = L.Util.falseFn;
+						}
+					}
+
+					if (context && typeIndex && (listeners.length === 0)) {
+						delete typeIndex[contextId];
+						events[indexLenKey]--;
+					}
+				}
+			}
+		}
+
+		return this;
+	},
+
+	clearAllEventListeners: function () {
+		delete this[eventsKey];
+		return this;
+	},
+
+	fireEvent: function (type, data) { // (String[, Object])
+		if (!this.hasEventListeners(type)) {
+			return this;
+		}
+
+		var event = L.Util.extend({}, data, { type: type, target: this });
+
+		var events = this[eventsKey],
+		    listeners, i, len, typeIndex, contextId;
+
+		if (events[type]) {
+			// make sure adding/removing listeners inside other listeners won't cause infinite loop
+			listeners = events[type].slice();
+
+			for (i = 0, len = listeners.length; i < len; i++) {
+				listeners[i].action.call(listeners[i].context, event);
+			}
+		}
+
+		// fire event for the context-indexed listeners as well
+		typeIndex = events[type + '_idx'];
+
+		for (contextId in typeIndex) {
+			listeners = typeIndex[contextId].slice();
+
+			if (listeners) {
+				for (i = 0, len = listeners.length; i < len; i++) {
+					listeners[i].action.call(listeners[i].context, event);
+				}
+			}
+		}
+
+		return this;
+	},
+
+	addOneTimeEventListener: function (types, fn, context) {
+
+		if (L.Util.invokeEach(types, this.addOneTimeEventListener, this, fn, context)) { return this; }
+
+		var handler = L.bind(function () {
+			this
+			    .removeEventListener(types, fn, context)
+			    .removeEventListener(types, handler, context);
+		}, this);
+
+		return this
+		    .addEventListener(types, fn, context)
+		    .addEventListener(types, handler, context);
+	}
+};
+
+L.Mixin.Events.on = L.Mixin.Events.addEventListener;
+L.Mixin.Events.off = L.Mixin.Events.removeEventListener;
+L.Mixin.Events.once = L.Mixin.Events.addOneTimeEventListener;
+L.Mixin.Events.fire = L.Mixin.Events.fireEvent;
+
+
+/*
+ * L.Browser handles different browser and feature detections for internal Leaflet use.
+ */
+
+(function () {
+
+	var ie = 'ActiveXObject' in window,
+		ielt9 = ie && !document.addEventListener,
+
+	    // terrible browser detection to work around Safari / iOS / Android browser bugs
+	    ua = navigator.userAgent.toLowerCase(),
+	    webkit = ua.indexOf('webkit') !== -1,
+	    chrome = ua.indexOf('chrome') !== -1,
+	    phantomjs = ua.indexOf('phantom') !== -1,
+	    android = ua.indexOf('android') !== -1,
+	    android23 = ua.search('android [23]') !== -1,
+		gecko = ua.indexOf('gecko') !== -1,
+
+	    mobile = typeof orientation !== undefined + '',
+	    msPointer = !window.PointerEvent && window.MSPointerEvent,
+		pointer = (window.PointerEvent && window.navigator.pointerEnabled) ||
+				  msPointer,
+	    retina = ('devicePixelRatio' in window && window.devicePixelRatio > 1) ||
+	             ('matchMedia' in window && window.matchMedia('(min-resolution:144dpi)') &&
+	              window.matchMedia('(min-resolution:144dpi)').matches),
+
+	    doc = document.documentElement,
+	    ie3d = ie && ('transition' in doc.style),
+	    webkit3d = ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()) && !android23,
+	    gecko3d = 'MozPerspective' in doc.style,
+	    opera3d = 'OTransition' in doc.style,
+	    any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d || opera3d) && !phantomjs;
+
+	var touch = !window.L_NO_TOUCH && !phantomjs && (pointer || 'ontouchstart' in window ||
+		(window.DocumentTouch && document instanceof window.DocumentTouch));
+
+	L.Browser = {
+		ie: ie,
+		ielt9: ielt9,
+		webkit: webkit,
+		gecko: gecko && !webkit && !window.opera && !ie,
+
+		android: android,
+		android23: android23,
+
+		chrome: chrome,
+
+		ie3d: ie3d,
+		webkit3d: webkit3d,
+		gecko3d: gecko3d,
+		opera3d: opera3d,
+		any3d: any3d,
+
+		mobile: mobile,
+		mobileWebkit: mobile && webkit,
+		mobileWebkit3d: mobile && webkit3d,
+		mobileOpera: mobile && window.opera,
+
+		touch: touch,
+		msPointer: msPointer,
+		pointer: pointer,
+
+		retina: retina
+	};
+
+}());
+
+
+/*
+ * L.Point represents a point with x and y coordinates.
+ */
+
+L.Point = function (/*Number*/ x, /*Number*/ y, /*Boolean*/ round) {
+	this.x = (round ? Math.round(x) : x);
+	this.y = (round ? Math.round(y) : y);
+};
+
+L.Point.prototype = {
+
+	clone: function () {
+		return new L.Point(this.x, this.y);
+	},
+
+	// non-destructive, returns a new point
+	add: function (point) {
+		return this.clone()._add(L.point(point));
+	},
+
+	// destructive, used directly for performance in situations where it's safe to modify existing point
+	_add: function (point) {
+		this.x += point.x;
+		this.y += point.y;
+		return this;
+	},
+
+	subtract: function (point) {
+		return this.clone()._subtract(L.point(point));
+	},
+
+	_subtract: function (point) {
+		this.x -= point.x;
+		this.y -= point.y;
+		return this;
+	},
+
+	divideBy: function (num) {
+		return this.clone()._divideBy(num);
+	},
+
+	_divideBy: function (num) {
+		this.x /= num;
+		this.y /= num;
+		return this;
+	},
+
+	multiplyBy: function (num) {
+		return this.clone()._multiplyBy(num);
+	},
+
+	_multiplyBy: function (num) {
+		this.x *= num;
+		this.y *= num;
+		return this;
+	},
+
+	round: function () {
+		return this.clone()._round();
+	},
+
+	_round: function () {
+		this.x = Math.round(this.x);
+		this.y = Math.round(this.y);
+		return this;
+	},
+
+	floor: function () {
+		return this.clone()._floor();
+	},
+
+	_floor: function () {
+		this.x = Math.floor(this.x);
+		this.y = Math.floor(this.y);
+		return this;
+	},
+
+	distanceTo: function (point) {
+		point = L.point(point);
+
+		var x = point.x - this.x,
+		    y = point.y - this.y;
+
+		return Math.sqrt(x * x + y * y);
+	},
+
+	equals: function (point) {
+		point = L.point(point);
+
+		return point.x === this.x &&
+		       point.y === this.y;
+	},
+
+	contains: function (point) {
+		point = L.point(point);
+
+		return Math.abs(point.x) <= Math.abs(this.x) &&
+		       Math.abs(point.y) <= Math.abs(this.y);
+	},
+
+	toString: function () {
+		return 'Point(' +
+		        L.Util.formatNum(this.x) + ', ' +
+		        L.Util.formatNum(this.y) + ')';
+	}
+};
+
+L.point = function (x, y, round) {
+	if (x instanceof L.Point) {
+		return x;
+	}
+	if (L.Util.isArray(x)) {
+		return new L.Point(x[0], x[1]);
+	}
+	if (x === undefined || x === null) {
+		return x;
+	}
+	return new L.Point(x, y, round);
+};
+
+
+/*
+ * L.Bounds represents a rectangular area on the screen in pixel coordinates.
+ */
+
+L.Bounds = function (a, b) { //(Point, Point) or Point[]
+	if (!a) { return; }
+
+	var points = b ? [a, b] : a;
+
+	for (var i = 0, len = points.length; i < len; i++) {
+		this.extend(points[i]);
+	}
+};
+
+L.Bounds.prototype = {
+	// extend the bounds to contain the given point
+	extend: function (point) { // (Point)
+		point = L.point(point);
+
+		if (!this.min && !this.max) {
+			this.min = point.clone();
+			this.max = point.clone();
+		} else {
+			this.min.x = Math.min(point.x, this.min.x);
+			this.max.x = Math.max(point.x, this.max.x);
+			this.min.y = Math.min(point.y, this.min.y);
+			this.max.y = Math.max(point.y, this.max.y);
+		}
+		return this;
+	},
+
+	getCenter: function (round) { // (Boolean) -> Point
+		return new L.Point(
+		        (this.min.x + this.max.x) / 2,
+		        (this.min.y + this.max.y) / 2, round);
+	},
+
+	getBottomLeft: function () { // -> Point
+		return new L.Point(this.min.x, this.max.y);
+	},
+
+	getTopRight: function () { // -> Point
+		return new L.Point(this.max.x, this.min.y);
+	},
+
+	getSize: function () {
+		return this.max.subtract(this.min);
+	},
+
+	contains: function (obj) { // (Bounds) or (Point) -> Boolean
+		var min, max;
+
+		if (typeof obj[0] === 'number' || obj instanceof L.Point) {
+			obj = L.point(obj);
+		} else {
+			obj = L.bounds(obj);
+		}
+
+		if (obj instanceof L.Bounds) {
+			min = obj.min;
+			max = obj.max;
+		} else {
+			min = max = obj;
+		}
+
+		return (min.x >= this.min.x) &&
+		       (max.x <= this.max.x) &&
+		       (min.y >= this.min.y) &&
+		       (max.y <= this.max.y);
+	},
+
+	intersects: function (bounds) { // (Bounds) -> Boolean
+		bounds = L.bounds(bounds);
+
+		var min = this.min,
+		    max = this.max,
+		    min2 = bounds.min,
+		    max2 = bounds.max,
+		    xIntersects = (max2.x >= min.x) && (min2.x <= max.x),
+		    yIntersects = (max2.y >= min.y) && (min2.y <= max.y);
+
+		return xIntersects && yIntersects;
+	},
+
+	isValid: function () {
+		return !!(this.min && this.max);
+	}
+};
+
+L.bounds = function (a, b) { // (Bounds) or (Point, Point) or (Point[])
+	if (!a || a instanceof L.Bounds) {
+		return a;
+	}
+	return new L.Bounds(a, b);
+};
+
+
+/*
+ * L.Transformation is an utility class to perform simple point transformations through a 2d-matrix.
+ */
+
+L.Transformation = function (a, b, c, d) {
+	this._a = a;
+	this._b = b;
+	this._c = c;
+	this._d = d;
+};
+
+L.Transformation.prototype = {
+	transform: function (point, scale) { // (Point, Number) -> Point
+		return this._transform(point.clone(), scale);
+	},
+
+	// destructive transform (faster)
+	_transform: function (point, scale) {
+		scale = scale || 1;
+		point.x = scale * (this._a * point.x + this._b);
+		point.y = scale * (this._c * point.y + this._d);
+		return point;
+	},
+
+	untransform: function (point, scale) {
+		scale = scale || 1;
+		return new L.Point(
+		        (point.x / scale - this._b) / this._a,
+		        (point.y / scale - this._d) / this._c);
+	}
+};
+
+
+/*
+ * L.DomUtil contains various utility functions for working with DOM.
+ */
+
+L.DomUtil = {
+	get: function (id) {
+		return (typeof id === 'string' ? document.getElementById(id) : id);
+	},
+
+	getStyle: function (el, style) {
+
+		var value = el.style[style];
+
+		if (!value && el.currentStyle) {
+			value = el.currentStyle[style];
+		}
+
+		if ((!value || value === 'auto') && document.defaultView) {
+			var css = document.defaultView.getComputedStyle(el, null);
+			value = css ? css[style] : null;
+		}
+
+		return value === 'auto' ? null : value;
+	},
+
+	getViewportOffset: function (element) {
+
+		var top = 0,
+		    left = 0,
+		    el = element,
+		    docBody = document.body,
+		    docEl = document.documentElement,
+		    pos;
+
+		do {
+			top  += el.offsetTop  || 0;
+			left += el.offsetLeft || 0;
+
+			//add borders
+			top += parseInt(L.DomUtil.getStyle(el, 'borderTopWidth'), 10) || 0;
+			left += parseInt(L.DomUtil.getStyle(el, 'borderLeftWidth'), 10) || 0;
+
+			pos = L.DomUtil.getStyle(el, 'position');
+
+			if (el.offsetParent === docBody && pos === 'absolute') { break; }
+
+			if (pos === 'fixed') {
+				top  += docBody.scrollTop  || docEl.scrollTop  || 0;
+				left += docBody.scrollLeft || docEl.scrollLeft || 0;
+				break;
+			}
+
+			if (pos === 'relative' && !el.offsetLeft) {
+				var width = L.DomUtil.getStyle(el, 'width'),
+				    maxWidth = L.DomUtil.getStyle(el, 'max-width'),
+				    r = el.getBoundingClientRect();
+
+				if (width !== 'none' || maxWidth !== 'none') {
+					left += r.left + el.clientLeft;
+				}
+
+				//calculate full y offset since we're breaking out of the loop
+				top += r.top + (docBody.scrollTop  || docEl.scrollTop  || 0);
+
+				break;
+			}
+
+			el = el.offsetParent;
+
+		} while (el);
+
+		el = element;
+
+		do {
+			if (el === docBody) { break; }
+
+			top  -= el.scrollTop  || 0;
+			left -= el.scrollLeft || 0;
+
+			el = el.parentNode;
+		} while (el);
+
+		return new L.Point(left, top);
+	},
+
+	documentIsLtr: function () {
+		if (!L.DomUtil._docIsLtrCached) {
+			L.DomUtil._docIsLtrCached = true;
+			L.DomUtil._docIsLtr = L.DomUtil.getStyle(document.body, 'direction') === 'ltr';
+		}
+		return L.DomUtil._docIsLtr;
+	},
+
+	create: function (tagName, className, container) {
+
+		var el = document.createElement(tagName);
+		el.className = className;
+
+		if (container) {
+			container.appendChild(el);
+		}
+
+		return el;
+	},
+
+	hasClass: function (el, name) {
+		if (el.classList !== undefined) {
+			return el.classList.contains(name);
+		}
+		var className = L.DomUtil._getClass(el);
+		return className.length > 0 && new RegExp('(^|\\s)' + name + '(\\s|$)').test(className);
+	},
+
+	addClass: function (el, name) {
+		if (el.classList !== undefined) {
+			var classes = L.Util.splitWords(name);
+			for (var i = 0, len = classes.length; i < len; i++) {
+				el.classList.add(classes[i]);
+			}
+		} else if (!L.DomUtil.hasClass(el, name)) {
+			var className = L.DomUtil._getClass(el);
+			L.DomUtil._setClass(el, (className ? className + ' ' : '') + name);
+		}
+	},
+
+	removeClass: function (el, name) {
+		if (el.classList !== undefined) {
+			el.classList.remove(name);
+		} else {
+			L.DomUtil._setClass(el, L.Util.trim((' ' + L.DomUtil._getClass(el) + ' ').replace(' ' + name + ' ', ' ')));
+		}
+	},
+
+	_setClass: function (el, name) {
+		if (el.className.baseVal === undefined) {
+			el.className = name;
+		} else {
+			// in case of SVG element
+			el.className.baseVal = name;
+		}
+	},
+
+	_getClass: function (el) {
+		return el.className.baseVal === undefined ? el.className : el.className.baseVal;
+	},
+
+	setOpacity: function (el, value) {
+
+		if ('opacity' in el.style) {
+			el.style.opacity = value;
+
+		} else if ('filter' in el.style) {
+
+			var filter = false,
+			    filterName = 'DXImageTransform.Microsoft.Alpha';
+
+			// filters collection throws an error if we try to retrieve a filter that doesn't exist
+			try {
+				filter = el.filters.item(filterName);
+			} catch (e) {
+				// don't set opacity to 1 if we haven't already set an opacity,
+				// it isn't needed and breaks transparent pngs.
+				if (value === 1) { return; }
+			}
+
+			value = Math.round(value * 100);
+
+			if (filter) {
+				filter.Enabled = (value !== 100);
+				filter.Opacity = value;
+			} else {
+				el.style.filter += ' progid:' + filterName + '(opacity=' + value + ')';
+			}
+		}
+	},
+
+	testProp: function (props) {
+
+		var style = document.documentElement.style;
+
+		for (var i = 0; i < props.length; i++) {
+			if (props[i] in style) {
+				return props[i];
+			}
+		}
+		return false;
+	},
+
+	getTranslateString: function (point) {
+		// on WebKit browsers (Chrome/Safari/iOS Safari/Android) using translate3d instead of translate
+		// makes animation smoother as it ensures HW accel is used. Firefox 13 doesn't care
+		// (same speed either way), Opera 12 doesn't support translate3d
+
+		var is3d = L.Browser.webkit3d,
+		    open = 'translate' + (is3d ? '3d' : '') + '(',
+		    close = (is3d ? ',0' : '') + ')';
+
+		return open + point.x + 'px,' + point.y + 'px' + close;
+	},
+
+	getScaleString: function (scale, origin) {
+
+		var preTranslateStr = L.DomUtil.getTranslateString(origin.add(origin.multiplyBy(-1 * scale))),
+		    scaleStr = ' scale(' + scale + ') ';
+
+		return preTranslateStr + scaleStr;
+	},
+
+	setPosition: function (el, point, disable3D) { // (HTMLElement, Point[, Boolean])
+
+		// jshint camelcase: false
+		el._leaflet_pos = point;
+
+		if (!disable3D && L.Browser.any3d) {
+			el.style[L.DomUtil.TRANSFORM] =  L.DomUtil.getTranslateString(point);
+		} else {
+			el.style.left = point.x + 'px';
+			el.style.top = point.y + 'px';
+		}
+	},
+
+	getPosition: function (el) {
+		// this method is only used for elements previously positioned using setPosition,
+		// so it's safe to cache the position for performance
+
+		// jshint camelcase: false
+		return el._leaflet_pos;
+	}
+};
+
+
+// prefix style property names
+
+L.DomUtil.TRANSFORM = L.DomUtil.testProp(
+        ['transform', 'WebkitTransform', 'OTransform', 'MozTransform', 'msTransform']);
+
+// webkitTransition comes first because some browser versions that drop vendor prefix don't do
+// the same for the transitionend event, in particular the Android 4.1 stock browser
+
+L.DomUtil.TRANSITION = L.DomUtil.testProp(
+        ['webkitTransition', 'transition', 'OTransition', 'MozTransition', 'msTransition']);
+
+L.DomUtil.TRANSITION_END =
+        L.DomUtil.TRANSITION === 'webkitTransition' || L.DomUtil.TRANSITION === 'OTransition' ?
+        L.DomUtil.TRANSITION + 'End' : 'transitionend';
+
+(function () {
+    if ('onselectstart' in document) {
+        L.extend(L.DomUtil, {
+            disableTextSelection: function () {
+                L.DomEvent.on(window, 'selectstart', L.DomEvent.preventDefault);
+            },
+
+            enableTextSelection: function () {
+                L.DomEvent.off(window, 'selectstart', L.DomEvent.preventDefault);
+            }
+        });
+    } else {
+        var userSelectProperty = L.DomUtil.testProp(
+            ['userSelect', 'WebkitUserSelect', 'OUserSelect', 'MozUserSelect', 'msUserSelect']);
+
+        L.extend(L.DomUtil, {
+            disableTextSelection: function () {
+                if (userSelectProperty) {
+                    var style = document.documentElement.style;
+                    this._userSelect = style[userSelectProperty];
+                    style[userSelectProperty] = 'none';
+                }
+            },
+
+            enableTextSelection: function () {
+                if (userSelectProperty) {
+                    document.documentElement.style[userSelectProperty] = this._userSelect;
+                    delete this._userSelect;
+                }
+            }
+        });
+    }
+
+	L.extend(L.DomUtil, {
+		disableImageDrag: function () {
+			L.DomEvent.on(window, 'dragstart', L.DomEvent.preventDefault);
+		},
+
+		enableImageDrag: function () {
+			L.DomEvent.off(window, 'dragstart', L.DomEvent.preventDefault);
+		}
+	});
+})();
+
+
+/*
+ * L.LatLng represents a geographical point with latitude and longitude coordinates.
+ */
+
+L.LatLng = function (lat, lng, alt) { // (Number, Number, Number)
+	lat = parseFloat(lat);
+	lng = parseFloat(lng);
+
+	if (isNaN(lat) || isNaN(lng)) {
+		throw new Error('Invalid LatLng object: (' + lat + ', ' + lng + ')');
+	}
+
+	this.lat = lat;
+	this.lng = lng;
+
+	if (alt !== undefined) {
+		this.alt = parseFloat(alt);
+	}
+};
+
+L.extend(L.LatLng, {
+	DEG_TO_RAD: Math.PI / 180,
+	RAD_TO_DEG: 180 / Math.PI,
+	MAX_MARGIN: 1.0E-9 // max margin of error for the "equals" check
+});
+
+L.LatLng.prototype = {
+	equals: function (obj) { // (LatLng) -> Boolean
+		if (!obj) { return false; }
+
+		obj = L.latLng(obj);
+
+		var margin = Math.max(
+		        Math.abs(this.lat - obj.lat),
+		        Math.abs(this.lng - obj.lng));
+
+		return margin <= L.LatLng.MAX_MARGIN;
+	},
+
+	toString: function (precision) { // (Number) -> String
+		return 'LatLng(' +
+		        L.Util.formatNum(this.lat, precision) + ', ' +
+		        L.Util.formatNum(this.lng, precision) + ')';
+	},
+
+	// Haversine distance formula, see http://en.wikipedia.org/wiki/Haversine_formula
+	// TODO move to projection code, LatLng shouldn't know about Earth
+	distanceTo: function (other) { // (LatLng) -> Number
+		other = L.latLng(other);
+
+		var R = 6378137, // earth radius in meters
+		    d2r = L.LatLng.DEG_TO_RAD,
+		    dLat = (other.lat - this.lat) * d2r,
+		    dLon = (other.lng - this.lng) * d2r,
+		    lat1 = this.lat * d2r,
+		    lat2 = other.lat * d2r,
+		    sin1 = Math.sin(dLat / 2),
+		    sin2 = Math.sin(dLon / 2);
+
+		var a = sin1 * sin1 + sin2 * sin2 * Math.cos(lat1) * Math.cos(lat2);
+
+		return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
+	},
+
+	wrap: function (a, b) { // (Number, Number) -> LatLng
+		var lng = this.lng;
+
+		a = a || -180;
+		b = b ||  180;
+
+		lng = (lng + b) % (b - a) + (lng < a || lng === b ? b : a);
+
+		return new L.LatLng(this.lat, lng);
+	}
+};
+
+L.latLng = function (a, b) { // (LatLng) or ([Number, Number]) or (Number, Number)
+	if (a instanceof L.LatLng) {
+		return a;
+	}
+	if (L.Util.isArray(a)) {
+		if (typeof a[0] === 'number' || typeof a[0] === 'string') {
+			return new L.LatLng(a[0], a[1], a[2]);
+		} else {
+			return null;
+		}
+	}
+	if (a === undefined || a === null) {
+		return a;
+	}
+	if (typeof a === 'object' && 'lat' in a) {
+		return new L.LatLng(a.lat, 'lng' in a ? a.lng : a.lon);
+	}
+	if (b === undefined) {
+		return null;
+	}
+	return new L.LatLng(a, b);
+};
+
+
+
+/*
+ * L.LatLngBounds represents a rectangular area on the map in geographical coordinates.
+ */
+
+L.LatLngBounds = function (southWest, northEast) { // (LatLng, LatLng) or (LatLng[])
+	if (!southWest) { return; }
+
+	var latlngs = northEast ? [southWest, northEast] : southWest;
+
+	for (var i = 0, len = latlngs.length; i < len; i++) {
+		this.extend(latlngs[i]);
+	}
+};
+
+L.LatLngBounds.prototype = {
+	// extend the bounds to contain the given point or bounds
+	extend: function (obj) { // (LatLng) or (LatLngBounds)
+		if (!obj) { return this; }
+
+		var latLng = L.latLng(obj);
+		if (latLng !== null) {
+			obj = latLng;
+		} else {
+			obj = L.latLngBounds(obj);
+		}
+
+		if (obj instanceof L.LatLng) {
+			if (!this._southWest && !this._northEast) {
+				this._southWest = new L.LatLng(obj.lat, obj.lng);
+				this._northEast = new L.LatLng(obj.lat, obj.lng);
+			} else {
+				this._southWest.lat = Math.min(obj.lat, this._southWest.lat);
+				this._southWest.lng = Math.min(obj.lng, this._southWest.lng);
+
+				this._northEast.lat = Math.max(obj.lat, this._northEast.lat);
+				this._northEast.lng = Math.max(obj.lng, this._northEast.lng);
+			}
+		} else if (obj instanceof L.LatLngBounds) {
+			this.extend(obj._southWest);
+			this.extend(obj._northEast);
+		}
+		return this;
+	},
+
+	// extend the bounds by a percentage
+	pad: function (bufferRatio) { // (Number) -> LatLngBounds
+		var sw = this._southWest,
+		    ne = this._northEast,
+		    heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio,
+		    widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio;
+
+		return new L.LatLngBounds(
+		        new L.LatLng(sw.lat - heightBuffer, sw.lng - widthBuffer),
+		        new L.LatLng(ne.lat + heightBuffer, ne.lng + widthBuffer));
+	},
+
+	getCenter: function () { // -> LatLng
+		return new L.LatLng(
+		        (this._southWest.lat + this._northEast.lat) / 2,
+		        (this._southWest.lng + this._northEast.lng) / 2);
+	},
+
+	getSouthWest: function () {
+		return this._southWest;
+	},
+
+	getNorthEast: function () {
+		return this._northEast;
+	},
+
+	getNorthWest: function () {
+		return new L.LatLng(this.getNorth(), this.getWest());
+	},
+
+	getSouthEast: function () {
+		return new L.LatLng(this.getSouth(), this.getEast());
+	},
+
+	getWest: function () {
+		return this._southWest.lng;
+	},
+
+	getSouth: function () {
+		return this._southWest.lat;
+	},
+
+	getEast: function () {
+		return this._northEast.lng;
+	},
+
+	getNorth: function () {
+		return this._northEast.lat;
+	},
+
+	contains: function (obj) { // (LatLngBounds) or (LatLng) -> Boolean
+		if (typeof obj[0] === 'number' || obj instanceof L.LatLng) {
+			obj = L.latLng(obj);
+		} else {
+			obj = L.latLngBounds(obj);
+		}
+
+		var sw = this._southWest,
+		    ne = this._northEast,
+		    sw2, ne2;
+
+		if (obj instanceof L.LatLngBounds) {
+			sw2 = obj.getSouthWest();
+			ne2 = obj.getNorthEast();
+		} else {
+			sw2 = ne2 = obj;
+		}
+
+		return (sw2.lat >= sw.lat) && (ne2.lat <= ne.lat) &&
+		       (sw2.lng >= sw.lng) && (ne2.lng <= ne.lng);
+	},
+
+	intersects: function (bounds) { // (LatLngBounds)
+		bounds = L.latLngBounds(bounds);
+
+		var sw = this._southWest,
+		    ne = this._northEast,
+		    sw2 = bounds.getSouthWest(),
+		    ne2 = bounds.getNorthEast(),
+
+		    latIntersects = (ne2.lat >= sw.lat) && (sw2.lat <= ne.lat),
+		    lngIntersects = (ne2.lng >= sw.lng) && (sw2.lng <= ne.lng);
+
+		return latIntersects && lngIntersects;
+	},
+
+	toBBoxString: function () {
+		return [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()].join(',');
+	},
+
+	equals: function (bounds) { // (LatLngBounds)
+		if (!bounds) { return false; }
+
+		bounds = L.latLngBounds(bounds);
+
+		return this._southWest.equals(bounds.getSouthWest()) &&
+		       this._northEast.equals(bounds.getNorthEast());
+	},
+
+	isValid: function () {
+		return !!(this._southWest && this._northEast);
+	}
+};
+
+//TODO International date line?
+
+L.latLngBounds = function (a, b) { // (LatLngBounds) or (LatLng, LatLng)
+	if (!a || a instanceof L.LatLngBounds) {
+		return a;
+	}
+	return new L.LatLngBounds(a, b);
+};
+
+
+/*
+ * L.Projection contains various geographical projections used by CRS classes.
+ */
+
+L.Projection = {};
+
+
+/*
+ * Spherical Mercator is the most popular map projection, used by EPSG:3857 CRS used by default.
+ */
+
+L.Projection.SphericalMercator = {
+	MAX_LATITUDE: 85.0511287798,
+
+	project: function (latlng) { // (LatLng) -> Point
+		var d = L.LatLng.DEG_TO_RAD,
+		    max = this.MAX_LATITUDE,
+		    lat = Math.max(Math.min(max, latlng.lat), -max),
+		    x = latlng.lng * d,
+		    y = lat * d;
+
+		y = Math.log(Math.tan((Math.PI / 4) + (y / 2)));
+
+		return new L.Point(x, y);
+	},
+
+	unproject: function (point) { // (Point, Boolean) -> LatLng
+		var d = L.LatLng.RAD_TO_DEG,
+		    lng = point.x * d,
+		    lat = (2 * Math.atan(Math.exp(point.y)) - (Math.PI / 2)) * d;
+
+		return new L.LatLng(lat, lng);
+	}
+};
+
+
+/*
+ * Simple equirectangular (Plate Carree) projection, used by CRS like EPSG:4326 and Simple.
+ */
+
+L.Projection.LonLat = {
+	project: function (latlng) {
+		return new L.Point(latlng.lng, latlng.lat);
+	},
+
+	unproject: function (point) {
+		return new L.LatLng(point.y, point.x);
+	}
+};
+
+
+/*
+ * L.CRS is a base object for all defined CRS (Coordinate Reference Systems) in Leaflet.
+ */
+
+L.CRS = {
+	latLngToPoint: function (latlng, zoom) { // (LatLng, Number) -> Point
+		var projectedPoint = this.projection.project(latlng),
+		    scale = this.scale(zoom);
+
+		return this.transformation._transform(projectedPoint, scale);
+	},
+
+	pointToLatLng: function (point, zoom) { // (Point, Number[, Boolean]) -> LatLng
+		var scale = this.scale(zoom),
+		    untransformedPoint = this.transformation.untransform(point, scale);
+
+		return this.projection.unproject(untransformedPoint);
+	},
+
+	project: function (latlng) {
+		return this.projection.project(latlng);
+	},
+
+	scale: function (zoom) {
+		return 256 * Math.pow(2, zoom);
+	},
+
+	getSize: function (zoom) {
+		var s = this.scale(zoom);
+		return L.point(s, s);
+	}
+};
+
+
+/*
+ * A simple CRS that can be used for flat non-Earth maps like panoramas or game maps.
+ */
+
+L.CRS.Simple = L.extend({}, L.CRS, {
+	projection: L.Projection.LonLat,
+	transformation: new L.Transformation(1, 0, -1, 0),
+
+	scale: function (zoom) {
+		return Math.pow(2, zoom);
+	}
+});
+
+
+/*
+ * L.CRS.EPSG3857 (Spherical Mercator) is the most common CRS for web mapping
+ * and is used by Leaflet by default.
+ */
+
+L.CRS.EPSG3857 = L.extend({}, L.CRS, {
+	code: 'EPSG:3857',
+
+	projection: L.Projection.SphericalMercator,
+	transformation: new L.Transformation(0.5 / Math.PI, 0.5, -0.5 / Math.PI, 0.5),
+
+	project: function (latlng) { // (LatLng) -> Point
+		var projectedPoint = this.projection.project(latlng),
+		    earthRadius = 6378137;
+		return projectedPoint.multiplyBy(earthRadius);
+	}
+});
+
+L.CRS.EPSG900913 = L.extend({}, L.CRS.EPSG3857, {
+	code: 'EPSG:900913'
+});
+
+
+/*
+ * L.CRS.EPSG4326 is a CRS popular among advanced GIS specialists.
+ */
+
+L.CRS.EPSG4326 = L.extend({}, L.CRS, {
+	code: 'EPSG:4326',
+
+	projection: L.Projection.LonLat,
+	transformation: new L.Transformation(1 / 360, 0.5, -1 / 360, 0.5)
+});
+
+
+/*
+ * L.Map is the central class of the API - it is used to create a map.
+ */
+
+L.Map = L.Class.extend({
+
+	includes: L.Mixin.Events,
+
+	options: {
+		crs: L.CRS.EPSG3857,
+
+		/*
+		center: LatLng,
+		zoom: Number,
+		layers: Array,
+		*/
+
+		fadeAnimation: L.DomUtil.TRANSITION && !L.Browser.android23,
+		trackResize: true,
+		markerZoomAnimation: L.DomUtil.TRANSITION && L.Browser.any3d
+	},
+
+	initialize: function (id, options) { // (HTMLElement or String, Object)
+		options = L.setOptions(this, options);
+
+
+		this._initContainer(id);
+		this._initLayout();
+
+		// hack for https://github.com/Leaflet/Leaflet/issues/1980
+		this._onResize = L.bind(this._onResize, this);
+
+		this._initEvents();
+
+		if (options.maxBounds) {
+			this.setMaxBounds(options.maxBounds);
+		}
+
+		if (options.center && options.zoom !== undefined) {
+			this.setView(L.latLng(options.center), options.zoom, {reset: true});
+		}
+
+		this._handlers = [];
+
+		this._layers = {};
+		this._zoomBoundLayers = {};
+		this._tileLayersNum = 0;
+
+		this.callInitHooks();
+
+		this._addLayers(options.layers);
+	},
+
+
+	// public methods that modify map state
+
+	// replaced by animation-powered implementation in Map.PanAnimation.js
+	setView: function (center, zoom) {
+		zoom = zoom === undefined ? this.getZoom() : zoom;
+		this._resetView(L.latLng(center), this._limitZoom(zoom));
+		return this;
+	},
+
+	setZoom: function (zoom, options) {
+		if (!this._loaded) {
+			this._zoom = this._limitZoom(zoom);
+			return this;
+		}
+		return this.setView(this.getCenter(), zoom, {zoom: options});
+	},
+
+	zoomIn: function (delta, options) {
+		return this.setZoom(this._zoom + (delta || 1), options);
+	},
+
+	zoomOut: function (delta, options) {
+		return this.setZoom(this._zoom - (delta || 1), options);
+	},
+
+	setZoomAround: function (latlng, zoom, options) {
+		var scale = this.getZoomScale(zoom),
+		    viewHalf = this.getSize().divideBy(2),
+		    containerPoint = latlng instanceof L.Point ? latlng : this.latLngToContainerPoint(latlng),
+
+		    centerOffset = containerPoint.subtract(viewHalf).multiplyBy(1 - 1 / scale),
+		    newCenter = this.containerPointToLatLng(viewHalf.add(centerOffset));
+
+		return this.setView(newCenter, zoom, {zoom: options});
+	},
+
+	fitBounds: function (bounds, options) {
+
+		options = options || {};
+		bounds = bounds.getBounds ? bounds.getBounds() : L.latLngBounds(bounds);
+
+		var paddingTL = L.point(options.paddingTopLeft || options.padding || [0, 0]),
+		    paddingBR = L.point(options.paddingBottomRight || options.padding || [0, 0]),
+
+		    zoom = this.getBoundsZoom(bounds, false, paddingTL.add(paddingBR));
+
+		zoom = (options.maxZoom) ? Math.min(options.maxZoom, zoom) : zoom;
+
+		var paddingOffset = paddingBR.subtract(paddingTL).divideBy(2),
+
+		    swPoint = this.project(bounds.getSouthWest(), zoom),
+		    nePoint = this.project(bounds.getNorthEast(), zoom),
+		    center = this.unproject(swPoint.add(nePoint).divideBy(2).add(paddingOffset), zoom);
+
+		return this.setView(center, zoom, options);
+	},
+
+	fitWorld: function (options) {
+		return this.fitBounds([[-90, -180], [90, 180]], options);
+	},
+
+	panTo: function (center, options) { // (LatLng)
+		return this.setView(center, this._zoom, {pan: options});
+	},
+
+	panBy: function (offset) { // (Point)
+		// replaced with animated panBy in Map.PanAnimation.js
+		this.fire('movestart');
+
+		this._rawPanBy(L.point(offset));
+
+		this.fire('move');
+		return this.fire('moveend');
+	},
+
+	setMaxBounds: function (bounds) {
+		bounds = L.latLngBounds(bounds);
+
+		this.options.maxBounds = bounds;
+
+		if (!bounds) {
+			return this.off('moveend', this._panInsideMaxBounds, this);
+		}
+
+		if (this._loaded) {
+			this._panInsideMaxBounds();
+		}
+
+		return this.on('moveend', this._panInsideMaxBounds, this);
+	},
+
+	panInsideBounds: function (bounds, options) {
+		var center = this.getCenter(),
+			newCenter = this._limitCenter(center, this._zoom, bounds);
+
+		if (center.equals(newCenter)) { return this; }
+
+		return this.panTo(newCenter, options);
+	},
+
+	addLayer: function (layer) {
+		// TODO method is too big, refactor
+
+		var id = L.stamp(layer);
+
+		if (this._layers[id]) { return this; }
+
+		this._layers[id] = layer;
+
+		// TODO getMaxZoom, getMinZoom in ILayer (instead of options)
+		if (layer.options && (!isNaN(layer.options.maxZoom) || !isNaN(layer.options.minZoom))) {
+			this._zoomBoundLayers[id] = layer;
+			this._updateZoomLevels();
+		}
+
+		// TODO looks ugly, refactor!!!
+		if (this.options.zoomAnimation && L.TileLayer && (layer instanceof L.TileLayer)) {
+			this._tileLayersNum++;
+			this._tileLayersToLoad++;
+			layer.on('load', this._onTileLayerLoad, this);
+		}
+
+		if (this._loaded) {
+			this._layerAdd(layer);
+		}
+
+		return this;
+	},
+
+	removeLayer: function (layer) {
+		var id = L.stamp(layer);
+
+		if (!this._layers[id]) { return this; }
+
+		if (this._loaded) {
+			layer.onRemove(this);
+		}
+
+		delete this._layers[id];
+
+		if (this._loaded) {
+			this.fire('layerremove', {layer: layer});
+		}
+
+		if (this._zoomBoundLayers[id]) {
+			delete this._zoomBoundLayers[id];
+			this._updateZoomLevels();
+		}
+
+		// TODO looks ugly, refactor
+		if (this.options.zoomAnimation && L.TileLayer && (layer instanceof L.TileLayer)) {
+			this._tileLayersNum--;
+			this._tileLayersToLoad--;
+			layer.off('load', this._onTileLayerLoad, this);
+		}
+
+		return this;
+	},
+
+	hasLayer: function (layer) {
+		if (!layer) { return false; }
+
+		return (L.stamp(layer) in this._layers);
+	},
+
+	eachLayer: function (method, context) {
+		for (var i in this._layers) {
+			method.call(context, this._layers[i]);
+		}
+		return this;
+	},
+
+	invalidateSize: function (options) {
+		if (!this._loaded) { return this; }
+
+		options = L.extend({
+			animate: false,
+			pan: true
+		}, options === true ? {animate: true} : options);
+
+		var oldSize = this.getSize();
+		this._sizeChanged = true;
+		this._initialCenter = null;
+
+		var newSize = this.getSize(),
+		    oldCenter = oldSize.divideBy(2).round(),
+		    newCenter = newSize.divideBy(2).round(),
+		    offset = oldCenter.subtract(newCenter);
+
+		if (!offset.x && !offset.y) { return this; }
+
+		if (options.animate && options.pan) {
+			this.panBy(offset);
+
+		} else {
+			if (options.pan) {
+				this._rawPanBy(offset);
+			}
+
+			this.fire('move');
+
+			if (options.debounceMoveend) {
+				clearTimeout(this._sizeTimer);
+				this._sizeTimer = setTimeout(L.bind(this.fire, this, 'moveend'), 200);
+			} else {
+				this.fire('moveend');
+			}
+		}
+
+		return this.fire('resize', {
+			oldSize: oldSize,
+			newSize: newSize
+		});
+	},
+
+	// TODO handler.addTo
+	addHandler: function (name, HandlerClass) {
+		if (!HandlerClass) { return this; }
+
+		var handler = this[name] = new HandlerClass(this);
+
+		this._handlers.push(handler);
+
+		if (this.options[name]) {
+			handler.enable();
+		}
+
+		return this;
+	},
+
+	remove: function () {
+		if (this._loaded) {
+			this.fire('unload');
+		}
+
+		this._initEvents('off');
+
+		try {
+			// throws error in IE6-8
+			delete this._container._leaflet;
+		} catch (e) {
+			this._container._leaflet = undefined;
+		}
+
+		this._clearPanes();
+		if (this._clearControlPos) {
+			this._clearControlPos();
+		}
+
+		this._clearHandlers();
+
+		return this;
+	},
+
+
+	// public methods for getting map state
+
+	getCenter: function () { // (Boolean) -> LatLng
+		this._checkIfLoaded();
+
+		if (this._initialCenter && !this._moved()) {
+			return this._initialCenter;
+		}
+		return this.layerPointToLatLng(this._getCenterLayerPoint());
+	},
+
+	getZoom: function () {
+		return this._zoom;
+	},
+
+	getBounds: function () {
+		var bounds = this.getPixelBounds(),
+		    sw = this.unproject(bounds.getBottomLeft()),
+		    ne = this.unproject(bounds.getTopRight());
+
+		return new L.LatLngBounds(sw, ne);
+	},
+
+	getMinZoom: function () {
+		return this.options.minZoom === undefined ?
+			(this._layersMinZoom === undefined ? 0 : this._layersMinZoom) :
+			this.options.minZoom;
+	},
+
+	getMaxZoom: function () {
+		return this.options.maxZoom === undefined ?
+			(this._layersMaxZoom === undefined ? Infinity : this._layersMaxZoom) :
+			this.options.maxZoom;
+	},
+
+	getBoundsZoom: function (bounds, inside, padding) { // (LatLngBounds[, Boolean, Point]) -> Number
+		bounds = L.latLngBounds(bounds);
+
+		var zoom = this.getMinZoom() - (inside ? 1 : 0),
+		    maxZoom = this.getMaxZoom(),
+		    size = this.getSize(),
+
+		    nw = bounds.getNorthWest(),
+		    se = bounds.getSouthEast(),
+
+		    zoomNotFound = true,
+		    boundsSize;
+
+		padding = L.point(padding || [0, 0]);
+
+		do {
+			zoom++;
+			boundsSize = this.project(se, zoom).subtract(this.project(nw, zoom)).add(padding);
+			zoomNotFound = !inside ? size.contains(boundsSize) : boundsSize.x < size.x || boundsSize.y < size.y;
+
+		} while (zoomNotFound && zoom <= maxZoom);
+
+		if (zoomNotFound && inside) {
+			return null;
+		}
+
+		return inside ? zoom : zoom - 1;
+	},
+
+	getSize: function () {
+		if (!this._size || this._sizeChanged) {
+			this._size = new L.Point(
+				this._container.clientWidth,
+				this._container.clientHeight);
+
+			this._sizeChanged = false;
+		}
+		return this._size.clone();
+	},
+
+	getPixelBounds: function () {
+		var topLeftPoint = this._getTopLeftPoint();
+		return new L.Bounds(topLeftPoint, topLeftPoint.add(this.getSize()));
+	},
+
+	getPixelOrigin: function () {
+		this._checkIfLoaded();
+		return this._initialTopLeftPoint;
+	},
+
+	getPanes: function () {
+		return this._panes;
+	},
+
+	getContainer: function () {
+		return this._container;
+	},
+
+
+	// TODO replace with universal implementation after refactoring projections
+
+	getZoomScale: function (toZoom) {
+		var crs = this.options.crs;
+		return crs.scale(toZoom) / crs.scale(this._zoom);
+	},
+
+	getScaleZoom: function (scale) {
+		return this._zoom + (Math.log(scale) / Math.LN2);
+	},
+
+
+	// conversion methods
+
+	project: function (latlng, zoom) { // (LatLng[, Number]) -> Point
+		zoom = zoom === undefined ? this._zoom : zoom;
+		return this.options.crs.latLngToPoint(L.latLng(latlng), zoom);
+	},
+
+	unproject: function (point, zoom) { // (Point[, Number]) -> LatLng
+		zoom = zoom === undefined ? this._zoom : zoom;
+		return this.options.crs.pointToLatLng(L.point(point), zoom);
+	},
+
+	layerPointToLatLng: function (point) { // (Point)
+		var projectedPoint = L.point(point).add(this.getPixelOrigin());
+		return this.unproject(projectedPoint);
+	},
+
+	latLngToLayerPoint: function (latlng) { // (LatLng)
+		var projectedPoint = this.project(L.latLng(latlng))._round();
+		return projectedPoint._subtract(this.getPixelOrigin());
+	},
+
+	containerPointToLayerPoint: function (point) { // (Point)
+		return L.point(point).subtract(this._getMapPanePos());
+	},
+
+	layerPointToContainerPoint: function (point) { // (Point)
+		return L.point(point).add(this._getMapPanePos());
+	},
+
+	containerPointToLatLng: function (point) {
+		var layerPoint = this.containerPointToLayerPoint(L.point(point));
+		return this.layerPointToLatLng(layerPoint);
+	},
+
+	latLngToContainerPoint: function (latlng) {
+		return this.layerPointToContainerPoint(this.latLngToLayerPoint(L.latLng(latlng)));
+	},
+
+	mouseEventToContainerPoint: function (e) { // (MouseEvent)
+		return L.DomEvent.getMousePosition(e, this._container);
+	},
+
+	mouseEventToLayerPoint: function (e) { // (MouseEvent)
+		return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(e));
+	},
+
+	mouseEventToLatLng: function (e) { // (MouseEvent)
+		return this.layerPointToLatLng(this.mouseEventToLayerPoint(e));
+	},
+
+
+	// map initialization methods
+
+	_initContainer: function (id) {
+		var container = this._container = L.DomUtil.get(id);
+
+		if (!container) {
+			throw new Error('Map container not found.');
+		} else if (container._leaflet) {
+			throw new Error('Map container is already initialized.');
+		}
+
+		container._leaflet = true;
+	},
+
+	_initLayout: function () {
+		var container = this._container;
+
+		L.DomUtil.addClass(container, 'leaflet-container' +
+			(L.Browser.touch ? ' leaflet-touch' : '') +
+			(L.Browser.retina ? ' leaflet-retina' : '') +
+			(L.Browser.ielt9 ? ' leaflet-oldie' : '') +
+			(this.options.fadeAnimation ? ' leaflet-fade-anim' : ''));
+
+		var position = L.DomUtil.getStyle(container, 'position');
+
+		if (position !== 'absolute' && position !== 'relative' && position !== 'fixed') {
+			container.style.position = 'relative';
+		}
+
+		this._initPanes();
+
+		if (this._initControlPos) {
+			this._initControlPos();
+		}
+	},
+
+	_initPanes: function () {
+		var panes = this._panes = {};
+
+		this._mapPane = panes.mapPane = this._createPane('leaflet-map-pane', this._container);
+
+		this._tilePane = panes.tilePane = this._createPane('leaflet-tile-pane', this._mapPane);
+		panes.objectsPane = this._createPane('leaflet-objects-pane', this._mapPane);
+		panes.shadowPane = this._createPane('leaflet-shadow-pane');
+		panes.overlayPane = this._createPane('leaflet-overlay-pane');
+		panes.markerPane = this._createPane('leaflet-marker-pane');
+		panes.popupPane = this._createPane('leaflet-popup-pane');
+
+		var zoomHide = ' leaflet-zoom-hide';
+
+		if (!this.options.markerZoomAnimation) {
+			L.DomUtil.addClass(panes.markerPane, zoomHide);
+			L.DomUtil.addClass(panes.shadowPane, zoomHide);
+			L.DomUtil.addClass(panes.popupPane, zoomHide);
+		}
+	},
+
+	_createPane: function (className, container) {
+		return L.DomUtil.create('div', className, container || this._panes.objectsPane);
+	},
+
+	_clearPanes: function () {
+		this._container.removeChild(this._mapPane);
+	},
+
+	_addLayers: function (layers) {
+		layers = layers ? (L.Util.isArray(layers) ? layers : [layers]) : [];
+
+		for (var i = 0, len = layers.length; i < len; i++) {
+			this.addLayer(layers[i]);
+		}
+	},
+
+
+	// private methods that modify map state
+
+	_resetView: function (center, zoom, preserveMapOffset, afterZoomAnim) {
+
+		var zoomChanged = (this._zoom !== zoom);
+
+		if (!afterZoomAnim) {
+			this.fire('movestart');
+
+			if (zoomChanged) {
+				this.fire('zoomstart');
+			}
+		}
+
+		this._zoom = zoom;
+		this._initialCenter = center;
+
+		this._initialTopLeftPoint = this._getNewTopLeftPoint(center);
+
+		if (!preserveMapOffset) {
+			L.DomUtil.setPosition(this._mapPane, new L.Point(0, 0));
+		} else {
+			this._initialTopLeftPoint._add(this._getMapPanePos());
+		}
+
+		this._tileLayersToLoad = this._tileLayersNum;
+
+		var loading = !this._loaded;
+		this._loaded = true;
+
+		this.fire('viewreset', {hard: !preserveMapOffset});
+
+		if (loading) {
+			this.fire('load');
+			this.eachLayer(this._layerAdd, this);
+		}
+
+		this.fire('move');
+
+		if (zoomChanged || afterZoomAnim) {
+			this.fire('zoomend');
+		}
+
+		this.fire('moveend', {hard: !preserveMapOffset});
+	},
+
+	_rawPanBy: function (offset) {
+		L.DomUtil.setPosition(this._mapPane, this._getMapPanePos().subtract(offset));
+	},
+
+	_getZoomSpan: function () {
+		return this.getMaxZoom() - this.getMinZoom();
+	},
+
+	_updateZoomLevels: function () {
+		var i,
+			minZoom = Infinity,
+			maxZoom = -Infinity,
+			oldZoomSpan = this._getZoomSpan();
+
+		for (i in this._zoomBoundLayers) {
+			var layer = this._zoomBoundLayers[i];
+			if (!isNaN(layer.options.minZoom)) {
+				minZoom = Math.min(minZoom, layer.options.minZoom);
+			}
+			if (!isNaN(layer.options.maxZoom)) {
+				maxZoom = Math.max(maxZoom, layer.options.maxZoom);
+			}
+		}
+
+		if (i === undefined) { // we have no tilelayers
+			this._layersMaxZoom = this._layersMinZoom = undefined;
+		} else {
+			this._layersMaxZoom = maxZoom;
+			this._layersMinZoom = minZoom;
+		}
+
+		if (oldZoomSpan !== this._getZoomSpan()) {
+			this.fire('zoomlevelschange');
+		}
+	},
+
+	_panInsideMaxBounds: function () {
+		this.panInsideBounds(this.options.maxBounds);
+	},
+
+	_checkIfLoaded: function () {
+		if (!this._loaded) {
+			throw new Error('Set map center and zoom first.');
+		}
+	},
+
+	// map events
+
+	_initEvents: function (onOff) {
+		if (!L.DomEvent) { return; }
+
+		onOff = onOff || 'on';
+
+		L.DomEvent[onOff](this._container, 'click', this._onMouseClick, this);
+
+		var events = ['dblclick', 'mousedown', 'mouseup', 'mouseenter',
+		              'mouseleave', 'mousemove', 'contextmenu'],
+		    i, len;
+
+		for (i = 0, len = events.length; i < len; i++) {
+			L.DomEvent[onOff](this._container, events[i], this._fireMouseEvent, this);
+		}
+
+		if (this.options.trackResize) {
+			L.DomEvent[onOff](window, 'resize', this._onResize, this);
+		}
+	},
+
+	_onResize: function () {
+		L.Util.cancelAnimFrame(this._resizeRequest);
+		this._resizeRequest = L.Util.requestAnimFrame(
+		        function () { this.invalidateSize({debounceMoveend: true}); }, this, false, this._container);
+	},
+
+	_onMouseClick: function (e) {
+		if (!this._loaded || (!e._simulated &&
+		        ((this.dragging && this.dragging.moved()) ||
+		         (this.boxZoom  && this.boxZoom.moved()))) ||
+		            L.DomEvent._skipped(e)) { return; }
+
+		this.fire('preclick');
+		this._fireMouseEvent(e);
+	},
+
+	_fireMouseEvent: function (e) {
+		if (!this._loaded || L.DomEvent._skipped(e)) { return; }
+
+		var type = e.type;
+
+		type = (type === 'mouseenter' ? 'mouseover' : (type === 'mouseleave' ? 'mouseout' : type));
+
+		if (!this.hasEventListeners(type)) { return; }
+
+		if (type === 'contextmenu') {
+			L.DomEvent.preventDefault(e);
+		}
+
+		var containerPoint = this.mouseEventToContainerPoint(e),
+		    layerPoint = this.containerPointToLayerPoint(containerPoint),
+		    latlng = this.layerPointToLatLng(layerPoint);
+
+		this.fire(type, {
+			latlng: latlng,
+			layerPoint: layerPoint,
+			containerPoint: containerPoint,
+			originalEvent: e
+		});
+	},
+
+	_onTileLayerLoad: function () {
+		this._tileLayersToLoad--;
+		if (this._tileLayersNum && !this._tileLayersToLoad) {
+			this.fire('tilelayersload');
+		}
+	},
+
+	_clearHandlers: function () {
+		for (var i = 0, len = this._handlers.length; i < len; i++) {
+			this._handlers[i].disable();
+		}
+	},
+
+	whenReady: function (callback, context) {
+		if (this._loaded) {
+			callback.call(context || this, this);
+		} else {
+			this.on('load', callback, context);
+		}
+		return this;
+	},
+
+	_layerAdd: function (layer) {
+		layer.onAdd(this);
+		this.fire('layeradd', {layer: layer});
+	},
+
+
+	// private methods for getting map state
+
+	_getMapPanePos: function () {
+		return L.DomUtil.getPosition(this._mapPane);
+	},
+
+	_moved: function () {
+		var pos = this._getMapPanePos();
+		return pos && !pos.equals([0, 0]);
+	},
+
+	_getTopLeftPoint: function () {
+		return this.getPixelOrigin().subtract(this._getMapPanePos());
+	},
+
+	_getNewTopLeftPoint: function (center, zoom) {
+		var viewHalf = this.getSize()._divideBy(2);
+		// TODO round on display, not calculation to increase precision?
+		return this.project(center, zoom)._subtract(viewHalf)._round();
+	},
+
+	_latLngToNewLayerPoint: function (latlng, newZoom, newCenter) {
+		var topLeft = this._getNewTopLeftPoint(newCenter, newZoom).add(this._getMapPanePos());
+		return this.project(latlng, newZoom)._subtract(topLeft);
+	},
+
+	// layer point of the current center
+	_getCenterLayerPoint: function () {
+		return this.containerPointToLayerPoint(this.getSize()._divideBy(2));
+	},
+
+	// offset of the specified place to the current center in pixels
+	_getCenterOffset: function (latlng) {
+		return this.latLngToLayerPoint(latlng).subtract(this._getCenterLayerPoint());
+	},
+
+	// adjust center for view to get inside bounds
+	_limitCenter: function (center, zoom, bounds) {
+
+		if (!bounds) { return center; }
+
+		var centerPoint = this.project(center, zoom),
+		    viewHalf = this.getSize().divideBy(2),
+		    viewBounds = new L.Bounds(centerPoint.subtract(viewHalf), centerPoint.add(viewHalf)),
+		    offset = this._getBoundsOffset(viewBounds, bounds, zoom);
+
+		return this.unproject(centerPoint.add(offset), zoom);
+	},
+
+	// adjust offset for view to get inside bounds
+	_limitOffset: function (offset, bounds) {
+		if (!bounds) { return offset; }
+
+		var viewBounds = this.getPixelBounds(),
+		    newBounds = new L.Bounds(viewBounds.min.add(offset), viewBounds.max.add(offset));
+
+		return offset.add(this._getBoundsOffset(newBounds, bounds));
+	},
+
+	// returns offset needed for pxBounds to get inside maxBounds at a specified zoom
+	_getBoundsOffset: function (pxBounds, maxBounds, zoom) {
+		var nwOffset = this.project(maxBounds.getNorthWest(), zoom).subtract(pxBounds.min),
+		    seOffset = this.project(maxBounds.getSouthEast(), zoom).subtract(pxBounds.max),
+
+		    dx = this._rebound(nwOffset.x, -seOffset.x),
+		    dy = this._rebound(nwOffset.y, -seOffset.y);
+
+		return new L.Point(dx, dy);
+	},
+
+	_rebound: function (left, right) {
+		return left + right > 0 ?
+			Math.round(left - right) / 2 :
+			Math.max(0, Math.ceil(left)) - Math.max(0, Math.floor(right));
+	},
+
+	_limitZoom: function (zoom) {
+		var min = this.getMinZoom(),
+		    max = this.getMaxZoom();
+
+		return Math.max(min, Math.min(max, zoom));
+	}
+});
+
+L.map = function (id, options) {
+	return new L.Map(id, options);
+};
+
+
+/*
+ * Mercator projection that takes into account that the Earth is not a perfect sphere.
+ * Less popular than spherical mercator; used by projections like EPSG:3395.
+ */
+
+L.Projection.Mercator = {
+	MAX_LATITUDE: 85.0840591556,
+
+	R_MINOR: 6356752.314245179,
+	R_MAJOR: 6378137,
+
+	project: function (latlng) { // (LatLng) -> Point
+		var d = L.LatLng.DEG_TO_RAD,
+		    max = this.MAX_LATITUDE,
+		    lat = Math.max(Math.min(max, latlng.lat), -max),
+		    r = this.R_MAJOR,
+		    r2 = this.R_MINOR,
+		    x = latlng.lng * d * r,
+		    y = lat * d,
+		    tmp = r2 / r,
+		    eccent = Math.sqrt(1.0 - tmp * tmp),
+		    con = eccent * Math.sin(y);
+
+		con = Math.pow((1 - con) / (1 + con), eccent * 0.5);
+
+		var ts = Math.tan(0.5 * ((Math.PI * 0.5) - y)) / con;
+		y = -r * Math.log(ts);
+
+		return new L.Point(x, y);
+	},
+
+	unproject: function (point) { // (Point, Boolean) -> LatLng
+		var d = L.LatLng.RAD_TO_DEG,
+		    r = this.R_MAJOR,
+		    r2 = this.R_MINOR,
+		    lng = point.x * d / r,
+		    tmp = r2 / r,
+		    eccent = Math.sqrt(1 - (tmp * tmp)),
+		    ts = Math.exp(- point.y / r),
+		    phi = (Math.PI / 2) - 2 * Math.atan(ts),
+		    numIter = 15,
+		    tol = 1e-7,
+		    i = numIter,
+		    dphi = 0.1,
+		    con;
+
+		while ((Math.abs(dphi) > tol) && (--i > 0)) {
+			con = eccent * Math.sin(phi);
+			dphi = (Math.PI / 2) - 2 * Math.atan(ts *
+			            Math.pow((1.0 - con) / (1.0 + con), 0.5 * eccent)) - phi;
+			phi += dphi;
+		}
+
+		return new L.LatLng(phi * d, lng);
+	}
+};
+
+
+
+L.CRS.EPSG3395 = L.extend({}, L.CRS, {
+	code: 'EPSG:3395',
+
+	projection: L.Projection.Mercator,
+
+	transformation: (function () {
+		var m = L.Projection.Mercator,
+		    r = m.R_MAJOR,
+		    scale = 0.5 / (Math.PI * r);
+
+		return new L.Transformation(scale, 0.5, -scale, 0.5);
+	}())
+});
+
+
+/*
+ * L.TileLayer is used for standard xyz-numbered tile layers.
+ */
+
+L.TileLayer = L.Class.extend({
+	includes: L.Mixin.Events,
+
+	options: {
+		minZoom: 0,
+		maxZoom: 18,
+		tileSize: 256,
+		subdomains: 'abc',
+		errorTileUrl: '',
+		attribution: '',
+		zoomOffset: 0,
+		opacity: 1,
+		/*
+		maxNativeZoom: null,
+		zIndex: null,
+		tms: false,
+		continuousWorld: false,
+		noWrap: false,
+		zoomReverse: false,
+		detectRetina: false,
+		reuseTiles: false,
+		bounds: false,
+		*/
+		unloadInvisibleTiles: L.Browser.mobile,
+		updateWhenIdle: L.Browser.mobile
+	},
+
+	initialize: function (url, options) {
+		options = L.setOptions(this, options);
+
+		// detecting retina displays, adjusting tileSize and zoom levels
+		if (options.detectRetina && L.Browser.retina && options.maxZoom > 0) {
+
+			options.tileSize = Math.floor(options.tileSize / 2);
+			options.zoomOffset++;
+
+			if (options.minZoom > 0) {
+				options.minZoom--;
+			}
+			this.options.maxZoom--;
+		}
+
+		if (options.bounds) {
+			options.bounds = L.latLngBounds(options.bounds);
+		}
+
+		this._url = url;
+
+		var subdomains = this.options.subdomains;
+
+		if (typeof subdomains === 'string') {
+			this.options.subdomains = subdomains.split('');
+		}
+	},
+
+	onAdd: function (map) {
+		this._map = map;
+		this._animated = map._zoomAnimated;
+
+		// create a container div for tiles
+		this._initContainer();
+
+		// set up events
+		map.on({
+			'viewreset': this._reset,
+			'moveend': this._update
+		}, this);
+
+		if (this._animated) {
+			map.on({
+				'zoomanim': this._animateZoom,
+				'zoomend': this._endZoomAnim
+			}, this);
+		}
+
+		if (!this.options.updateWhenIdle) {
+			this._limitedUpdate = L.Util.limitExecByInterval(this._update, 150, this);
+			map.on('move', this._limitedUpdate, this);
+		}
+
+		this._reset();
+		this._update();
+	},
+
+	addTo: function (map) {
+		map.addLayer(this);
+		return this;
+	},
+
+	onRemove: function (map) {
+		this._container.parentNode.removeChild(this._container);
+
+		map.off({
+			'viewreset': this._reset,
+			'moveend': this._update
+		}, this);
+
+		if (this._animated) {
+			map.off({
+				'zoomanim': this._animateZoom,
+				'zoomend': this._endZoomAnim
+			}, this);
+		}
+
+		if (!this.options.updateWhenIdle) {
+			map.off('move', this._limitedUpdate, this);
+		}
+
+		this._container = null;
+		this._map = null;
+	},
+
+	bringToFront: function () {
+		var pane = this._map._panes.tilePane;
+
+		if (this._container) {
+			pane.appendChild(this._container);
+			this._setAutoZIndex(pane, Math.max);
+		}
+
+		return this;
+	},
+
+	bringToBack: function () {
+		var pane = this._map._panes.tilePane;
+
+		if (this._container) {
+			pane.insertBefore(this._container, pane.firstChild);
+			this._setAutoZIndex(pane, Math.min);
+		}
+
+		return this;
+	},
+
+	getAttribution: function () {
+		return this.options.attribution;
+	},
+
+	getContainer: function () {
+		return this._container;
+	},
+
+	setOpacity: function (opacity) {
+		this.options.opacity = opacity;
+
+		if (this._map) {
+			this._updateOpacity();
+		}
+
+		return this;
+	},
+
+	setZIndex: function (zIndex) {
+		this.options.zIndex = zIndex;
+		this._updateZIndex();
+
+		return this;
+	},
+
+	setUrl: function (url, noRedraw) {
+		this._url = url;
+
+		if (!noRedraw) {
+			this.redraw();
+		}
+
+		return this;
+	},
+
+	redraw: function () {
+		if (this._map) {
+			this._reset({hard: true});
+			this._update();
+		}
+		return this;
+	},
+
+	_updateZIndex: function () {
+		if (this._container && this.options.zIndex !== undefined) {
+			this._container.style.zIndex = this.options.zIndex;
+		}
+	},
+
+	_setAutoZIndex: function (pane, compare) {
+
+		var layers = pane.children,
+		    edgeZIndex = -compare(Infinity, -Infinity), // -Infinity for max, Infinity for min
+		    zIndex, i, len;
+
+		for (i = 0, len = layers.length; i < len; i++) {
+
+			if (layers[i] !== this._container) {
+				zIndex = parseInt(layers[i].style.zIndex, 10);
+
+				if (!isNaN(zIndex)) {
+					edgeZIndex = compare(edgeZIndex, zIndex);
+				}
+			}
+		}
+
+		this.options.zIndex = this._container.style.zIndex =
+		        (isFinite(edgeZIndex) ? edgeZIndex : 0) + compare(1, -1);
+	},
+
+	_updateOpacity: function () {
+		var i,
+		    tiles = this._tiles;
+
+		if (L.Browser.ielt9) {
+			for (i in tiles) {
+				L.DomUtil.setOpacity(tiles[i], this.options.opacity);
+			}
+		} else {
+			L.DomUtil.setOpacity(this._container, this.options.opacity);
+		}
+	},
+
+	_initContainer: function () {
+		var tilePane = this._map._panes.tilePane;
+
+		if (!this._container) {
+			this._container = L.DomUtil.create('div', 'leaflet-layer');
+
+			this._updateZIndex();
+
+			if (this._animated) {
+				var className = 'leaflet-tile-container';
+
+				this._bgBuffer = L.DomUtil.create('div', className, this._container);
+				this._tileContainer = L.DomUtil.create('div', className, this._container);
+
+			} else {
+				this._tileContainer = this._container;
+			}
+
+			tilePane.appendChild(this._container);
+
+			if (this.options.opacity < 1) {
+				this._updateOpacity();
+			}
+		}
+	},
+
+	_reset: function (e) {
+		for (var key in this._tiles) {
+			this.fire('tileunload', {tile: this._tiles[key]});
+		}
+
+		this._tiles = {};
+		this._tilesToLoad = 0;
+
+		if (this.options.reuseTiles) {
+			this._unusedTiles = [];
+		}
+
+		this._tileContainer.innerHTML = '';
+
+		if (this._animated && e && e.hard) {
+			this._clearBgBuffer();
+		}
+
+		this._initContainer();
+	},
+
+	_getTileSize: function () {
+		var map = this._map,
+		    zoom = map.getZoom() + this.options.zoomOffset,
+		    zoomN = this.options.maxNativeZoom,
+		    tileSize = this.options.tileSize;
+
+		if (zoomN && zoom > zoomN) {
+			tileSize = Math.round(map.getZoomScale(zoom) / map.getZoomScale(zoomN) * tileSize);
+		}
+
+		return tileSize;
+	},
+
+	_update: function () {
+
+		if (!this._map) { return; }
+
+		var map = this._map,
+		    bounds = map.getPixelBounds(),
+		    zoom = map.getZoom(),
+		    tileSize = this._getTileSize();
+
+		if (zoom > this.options.maxZoom || zoom < this.options.minZoom) {
+			return;
+		}
+
+		var tileBounds = L.bounds(
+		        bounds.min.divideBy(tileSize)._floor(),
+		        bounds.max.divideBy(tileSize)._floor());
+
+		this._addTilesFromCenterOut(tileBounds);
+
+		if (this.options.unloadInvisibleTiles || this.options.reuseTiles) {
+			this._removeOtherTiles(tileBounds);
+		}
+	},
+
+	_addTilesFromCenterOut: function (bounds) {
+		var queue = [],
+		    center = bounds.getCenter();
+
+		var j, i, point;
+
+		for (j = bounds.min.y; j <= bounds.max.y; j++) {
+			for (i = bounds.min.x; i <= bounds.max.x; i++) {
+				point = new L.Point(i, j);
+
+				if (this._tileShouldBeLoaded(point)) {
+					queue.push(point);
+				}
+			}
+		}
+
+		var tilesToLoad = queue.length;
+
+		if (tilesToLoad === 0) { return; }
+
+		// load tiles in order of their distance to center
+		queue.sort(function (a, b) {
+			return a.distanceTo(center) - b.distanceTo(center);
+		});
+
+		var fragment = document.createDocumentFragment();
+
+		// if its the first batch of tiles to load
+		if (!this._tilesToLoad) {
+			this.fire('loading');
+		}
+
+		this._tilesToLoad += tilesToLoad;
+
+		for (i = 0; i < tilesToLoad; i++) {
+			this._addTile(queue[i], fragment);
+		}
+
+		this._tileContainer.appendChild(fragment);
+	},
+
+	_tileShouldBeLoaded: function (tilePoint) {
+		if ((tilePoint.x + ':' + tilePoint.y) in this._tiles) {
+			return false; // already loaded
+		}
+
+		var options = this.options;
+
+		if (!options.continuousWorld) {
+			var limit = this._getWrapTileNum();
+
+			// don't load if exceeds world bounds
+			if ((options.noWrap && (tilePoint.x < 0 || tilePoint.x >= limit.x)) ||
+				tilePoint.y < 0 || tilePoint.y >= limit.y) { return false; }
+		}
+
+		if (options.bounds) {
+			var tileSize = this._getTileSize(),
+			    nwPoint = tilePoint.multiplyBy(tileSize),
+			    sePoint = nwPoint.add([tileSize, tileSize]),
+			    nw = this._map.unproject(nwPoint),
+			    se = this._map.unproject(sePoint);
+
+			// TODO temporary hack, will be removed after refactoring projections
+			// https://github.com/Leaflet/Leaflet/issues/1618
+			if (!options.continuousWorld && !options.noWrap) {
+				nw = nw.wrap();
+				se = se.wrap();
+			}
+
+			if (!options.bounds.intersects([nw, se])) { return false; }
+		}
+
+		return true;
+	},
+
+	_removeOtherTiles: function (bounds) {
+		var kArr, x, y, key;
+
+		for (key in this._tiles) {
+			kArr = key.split(':');
+			x = parseInt(kArr[0], 10);
+			y = parseInt(kArr[1], 10);
+
+			// remove tile if it's out of bounds
+			if (x < bounds.min.x || x > bounds.max.x || y < bounds.min.y || y > bounds.max.y) {
+				this._removeTile(key);
+			}
+		}
+	},
+
+	_removeTile: function (key) {
+		var tile = this._tiles[key];
+
+		this.fire('tileunload', {tile: tile, url: tile.src});
+
+		if (this.options.reuseTiles) {
+			L.DomUtil.removeClass(tile, 'leaflet-tile-loaded');
+			this._unusedTiles.push(tile);
+
+		} else if (tile.parentNode === this._tileContainer) {
+			this._tileContainer.removeChild(tile);
+		}
+
+		// for https://github.com/CloudMade/Leaflet/issues/137
+		if (!L.Browser.android) {
+			tile.onload = null;
+			tile.src = L.Util.emptyImageUrl;
+		}
+
+		delete this._tiles[key];
+	},
+
+	_addTile: function (tilePoint, container) {
+		var tilePos = this._getTilePos(tilePoint);
+
+		// get unused tile - or create a new tile
+		var tile = this._getTile();
+
+		/*
+		Chrome 20 layouts much faster with top/left (verify with timeline, frames)
+		Android 4 browser has display issues with top/left and requires transform instead
+		(other browsers don't currently care) - see debug/hacks/jitter.html for an example
+		*/
+		L.DomUtil.setPosition(tile, tilePos, L.Browser.chrome);
+
+		this._tiles[tilePoint.x + ':' + tilePoint.y] = tile;
+
+		this._loadTile(tile, tilePoint);
+
+		if (tile.parentNode !== this._tileContainer) {
+			container.appendChild(tile);
+		}
+	},
+
+	_getZoomForUrl: function () {
+
+		var options = this.options,
+		    zoom = this._map.getZoom();
+
+		if (options.zoomReverse) {
+			zoom = options.maxZoom - zoom;
+		}
+
+		zoom += options.zoomOffset;
+
+		return options.maxNativeZoom ? Math.min(zoom, options.maxNativeZoom) : zoom;
+	},
+
+	_getTilePos: function (tilePoint) {
+		var origin = this._map.getPixelOrigin(),
+		    tileSize = this._getTileSize();
+
+		return tilePoint.multiplyBy(tileSize).subtract(origin);
+	},
+
+	// image-specific code (override to implement e.g. Canvas or SVG tile layer)
+
+	getTileUrl: function (tilePoint) {
+		return L.Util.template(this._url, L.extend({
+			s: this._getSubdomain(tilePoint),
+			z: tilePoint.z,
+			x: tilePoint.x,
+			y: tilePoint.y
+		}, this.options));
+	},
+
+	_getWrapTileNum: function () {
+		var crs = this._map.options.crs,
+		    size = crs.getSize(this._map.getZoom());
+		return size.divideBy(this._getTileSize())._floor();
+	},
+
+	_adjustTilePoint: function (tilePoint) {
+
+		var limit = this._getWrapTileNum();
+
+		// wrap tile coordinates
+		if (!this.options.continuousWorld && !this.options.noWrap) {
+			tilePoint.x = ((tilePoint.x % limit.x) + limit.x) % limit.x;
+		}
+
+		if (this.options.tms) {
+			tilePoint.y = limit.y - tilePoint.y - 1;
+		}
+
+		tilePoint.z = this._getZoomForUrl();
+	},
+
+	_getSubdomain: function (tilePoint) {
+		var index = Math.abs(tilePoint.x + tilePoint.y) % this.options.subdomains.length;
+		return this.options.subdomains[index];
+	},
+
+	_getTile: function () {
+		if (this.options.reuseTiles && this._unusedTiles.length > 0) {
+			var tile = this._unusedTiles.pop();
+			this._resetTile(tile);
+			return tile;
+		}
+		return this._createTile();
+	},
+
+	// Override if data stored on a tile needs to be cleaned up before reuse
+	_resetTile: function (/*tile*/) {},
+
+	_createTile: function () {
+		var tile = L.DomUtil.create('img', 'leaflet-tile');
+		tile.style.width = tile.style.height = this._getTileSize() + 'px';
+		tile.galleryimg = 'no';
+
+		tile.onselectstart = tile.onmousemove = L.Util.falseFn;
+
+		if (L.Browser.ielt9 && this.options.opacity !== undefined) {
+			L.DomUtil.setOpacity(tile, this.options.opacity);
+		}
+		// without this hack, tiles disappear after zoom on Chrome for Android
+		// https://github.com/Leaflet/Leaflet/issues/2078
+		if (L.Browser.mobileWebkit3d) {
+			tile.style.WebkitBackfaceVisibility = 'hidden';
+		}
+		return tile;
+	},
+
+	_loadTile: function (tile, tilePoint) {
+		tile._layer  = this;
+		tile.onload  = this._tileOnLoad;
+		tile.onerror = this._tileOnError;
+
+		this._adjustTilePoint(tilePoint);
+		tile.src     = this.getTileUrl(tilePoint);
+
+		this.fire('tileloadstart', {
+			tile: tile,
+			url: tile.src
+		});
+	},
+
+	_tileLoaded: function () {
+		this._tilesToLoad--;
+
+		if (this._animated) {
+			L.DomUtil.addClass(this._tileContainer, 'leaflet-zoom-animated');
+		}
+
+		if (!this._tilesToLoad) {
+			this.fire('load');
+
+			if (this._animated) {
+				// clear scaled tiles after all new tiles are loaded (for performance)
+				clearTimeout(this._clearBgBufferTimer);
+				this._clearBgBufferTimer = setTimeout(L.bind(this._clearBgBuffer, this), 500);
+			}
+		}
+	},
+
+	_tileOnLoad: function () {
+		var layer = this._layer;
+
+		//Only if we are loading an actual image
+		if (this.src !== L.Util.emptyImageUrl) {
+			L.DomUtil.addClass(this, 'leaflet-tile-loaded');
+
+			layer.fire('tileload', {
+				tile: this,
+				url: this.src
+			});
+		}
+
+		layer._tileLoaded();
+	},
+
+	_tileOnError: function () {
+		var layer = this._layer;
+
+		layer.fire('tileerror', {
+			tile: this,
+			url: this.src
+		});
+
+		var newUrl = layer.options.errorTileUrl;
+		if (newUrl) {
+			this.src = newUrl;
+		}
+
+		layer._tileLoaded();
+	}
+});
+
+L.tileLayer = function (url, options) {
+	return new L.TileLayer(url, options);
+};
+
+
+/*
+ * L.TileLayer.WMS is used for putting WMS tile layers on the map.
+ */
+
+L.TileLayer.WMS = L.TileLayer.extend({
+
+	defaultWmsParams: {
+		service: 'WMS',
+		request: 'GetMap',
+		version: '1.1.1',
+		layers: '',
+		styles: '',
+		format: 'image/jpeg',
+		transparent: false
+	},
+
+	initialize: function (url, options) { // (String, Object)
+
+		this._url = url;
+
+		var wmsParams = L.extend({}, this.defaultWmsParams),
+		    tileSize = options.tileSize || this.options.tileSize;
+
+		if (options.detectRetina && L.Browser.retina) {
+			wmsParams.width = wmsParams.height = tileSize * 2;
+		} else {
+			wmsParams.width = wmsParams.height = tileSize;
+		}
+
+		for (var i in options) {
+			// all keys that are not TileLayer options go to WMS params
+			if (!this.options.hasOwnProperty(i) && i !== 'crs') {
+				wmsParams[i] = options[i];
+			}
+		}
+
+		this.wmsParams = wmsParams;
+
+		L.setOptions(this, options);
+	},
+
+	onAdd: function (map) {
+
+		this._crs = this.options.crs || map.options.crs;
+
+		this._wmsVersion = parseFloat(this.wmsParams.version);
+
+		var projectionKey = this._wmsVersion >= 1.3 ? 'crs' : 'srs';
+		this.wmsParams[projectionKey] = this._crs.code;
+
+		L.TileLayer.prototype.onAdd.call(this, map);
+	},
+
+	getTileUrl: function (tilePoint) { // (Point, Number) -> String
+
+		var map = this._map,
+		    tileSize = this.options.tileSize,
+
+		    nwPoint = tilePoint.multiplyBy(tileSize),
+		    sePoint = nwPoint.add([tileSize, tileSize]),
+
+		    nw = this._crs.project(map.unproject(nwPoint, tilePoint.z)),
+		    se = this._crs.project(map.unproject(sePoint, tilePoint.z)),
+		    bbox = this._wmsVersion >= 1.3 && this._crs === L.CRS.EPSG4326 ?
+		        [se.y, nw.x, nw.y, se.x].join(',') :
+		        [nw.x, se.y, se.x, nw.y].join(','),
+
+		    url = L.Util.template(this._url, {s: this._getSubdomain(tilePoint)});
+
+		return url + L.Util.getParamString(this.wmsParams, url, true) + '&BBOX=' + bbox;
+	},
+
+	setParams: function (params, noRedraw) {
+
+		L.extend(this.wmsParams, params);
+
+		if (!noRedraw) {
+			this.redraw();
+		}
+
+		return this;
+	}
+});
+
+L.tileLayer.wms = function (url, options) {
+	return new L.TileLayer.WMS(url, options);
+};
+
+
+/*
+ * L.TileLayer.Canvas is a class that you can use as a base for creating
+ * dynamically drawn Canvas-based tile layers.
+ */
+
+L.TileLayer.Canvas = L.TileLayer.extend({
+	options: {
+		async: false
+	},
+
+	initialize: function (options) {
+		L.setOptions(this, options);
+	},
+
+	redraw: function () {
+		if (this._map) {
+			this._reset({hard: true});
+			this._update();
+		}
+
+		for (var i in this._tiles) {
+			this._redrawTile(this._tiles[i]);
+		}
+		return this;
+	},
+
+	_redrawTile: function (tile) {
+		this.drawTile(tile, tile._tilePoint, this._map._zoom);
+	},
+
+	_createTile: function () {
+		var tile = L.DomUtil.create('canvas', 'leaflet-tile');
+		tile.width = tile.height = this.options.tileSize;
+		tile.onselectstart = tile.onmousemove = L.Util.falseFn;
+		return tile;
+	},
+
+	_loadTile: function (tile, tilePoint) {
+		tile._layer = this;
+		tile._tilePoint = tilePoint;
+
+		this._redrawTile(tile);
+
+		if (!this.options.async) {
+			this.tileDrawn(tile);
+		}
+	},
+
+	drawTile: function (/*tile, tilePoint*/) {
+		// override with rendering code
+	},
+
+	tileDrawn: function (tile) {
+		this._tileOnLoad.call(tile);
+	}
+});
+
+
+L.tileLayer.canvas = function (options) {
+	return new L.TileLayer.Canvas(options);
+};
+
+
+/*
+ * L.ImageOverlay is used to overlay images over the map (to specific geographical bounds).
+ */
+
+L.ImageOverlay = L.Class.extend({
+	includes: L.Mixin.Events,
+
+	options: {
+		opacity: 1
+	},
+
+	initialize: function (url, bounds, options) { // (String, LatLngBounds, Object)
+		this._url = url;
+		this._bounds = L.latLngBounds(bounds);
+
+		L.setOptions(this, options);
+	},
+
+	onAdd: function (map) {
+		this._map = map;
+
+		if (!this._image) {
+			this._initImage();
+		}
+
+		map._panes.overlayPane.appendChild(this._image);
+
+		map.on('viewreset', this._reset, this);
+
+		if (map.options.zoomAnimation && L.Browser.any3d) {
+			map.on('zoomanim', this._animateZoom, this);
+		}
+
+		this._reset();
+	},
+
+	onRemove: function (map) {
+		map.getPanes().overlayPane.removeChild(this._image);
+
+		map.off('viewreset', this._reset, this);
+
+		if (map.options.zoomAnimation) {
+			map.off('zoomanim', this._animateZoom, this);
+		}
+	},
+
+	addTo: function (map) {
+		map.addLayer(this);
+		return this;
+	},
+
+	setOpacity: function (opacity) {
+		this.options.opacity = opacity;
+		this._updateOpacity();
+		return this;
+	},
+
+	// TODO remove bringToFront/bringToBack duplication from TileLayer/Path
+	bringToFront: function () {
+		if (this._image) {
+			this._map._panes.overlayPane.appendChild(this._image);
+		}
+		return this;
+	},
+
+	bringToBack: function () {
+		var pane = this._map._panes.overlayPane;
+		if (this._image) {
+			pane.insertBefore(this._image, pane.firstChild);
+		}
+		return this;
+	},
+
+	setUrl: function (url) {
+		this._url = url;
+		this._image.src = this._url;
+	},
+
+	getAttribution: function () {
+		return this.options.attribution;
+	},
+
+	_initImage: function () {
+		this._image = L.DomUtil.create('img', 'leaflet-image-layer');
+
+		if (this._map.options.zoomAnimation && L.Browser.any3d) {
+			L.DomUtil.addClass(this._image, 'leaflet-zoom-animated');
+		} else {
+			L.DomUtil.addClass(this._image, 'leaflet-zoom-hide');
+		}
+
+		this._updateOpacity();
+
+		//TODO createImage util method to remove duplication
+		L.extend(this._image, {
+			galleryimg: 'no',
+			onselectstart: L.Util.falseFn,
+			onmousemove: L.Util.falseFn,
+			onload: L.bind(this._onImageLoad, this),
+			src: this._url
+		});
+	},
+
+	_animateZoom: function (e) {
+		var map = this._map,
+		    image = this._image,
+		    scale = map.getZoomScale(e.zoom),
+		    nw = this._bounds.getNorthWest(),
+		    se = this._bounds.getSouthEast(),
+
+		    topLeft = map._latLngToNewLayerPoint(nw, e.zoom, e.center),
+		    size = map._latLngToNewLayerPoint(se, e.zoom, e.center)._subtract(topLeft),
+		    origin = topLeft._add(size._multiplyBy((1 / 2) * (1 - 1 / scale)));
+
+		image.style[L.DomUtil.TRANSFORM] =
+		        L.DomUtil.getTranslateString(origin) + ' scale(' + scale + ') ';
+	},
+
+	_reset: function () {
+		var image   = this._image,
+		    topLeft = this._map.latLngToLayerPoint(this._bounds.getNorthWest()),
+		    size = this._map.latLngToLayerPoint(this._bounds.getSouthEast())._subtract(topLeft);
+
+		L.DomUtil.setPosition(image, topLeft);
+
+		image.style.width  = size.x + 'px';
+		image.style.height = size.y + 'px';
+	},
+
+	_onImageLoad: function () {
+		this.fire('load');
+	},
+
+	_updateOpacity: function () {
+		L.DomUtil.setOpacity(this._image, this.options.opacity);
+	}
+});
+
+L.imageOverlay = function (url, bounds, options) {
+	return new L.ImageOverlay(url, bounds, options);
+};
+
+
+/*
+ * L.Icon is an image-based icon class that you can use with L.Marker for custom markers.
+ */
+
+L.Icon = L.Class.extend({
+	options: {
+		/*
+		iconUrl: (String) (required)
+		iconRetinaUrl: (String) (optional, used for retina devices if detected)
+		iconSize: (Point) (can be set through CSS)
+		iconAnchor: (Point) (centered by default, can be set in CSS with negative margins)
+		popupAnchor: (Point) (if not specified, popup opens in the anchor point)
+		shadowUrl: (String) (no shadow by default)
+		shadowRetinaUrl: (String) (optional, used for retina devices if detected)
+		shadowSize: (Point)
+		shadowAnchor: (Point)
+		*/
+		className: ''
+	},
+
+	initialize: function (options) {
+		L.setOptions(this, options);
+	},
+
+	createIcon: function (oldIcon) {
+		return this._createIcon('icon', oldIcon);
+	},
+
+	createShadow: function (oldIcon) {
+		return this._createIcon('shadow', oldIcon);
+	},
+
+	_createIcon: function (name, oldIcon) {
+		var src = this._getIconUrl(name);
+
+		if (!src) {
+			if (name === 'icon') {
+				throw new Error('iconUrl not set in Icon options (see the docs).');
+			}
+			return null;
+		}
+
+		var img;
+		if (!oldIcon || oldIcon.tagName !== 'IMG') {
+			img = this._createImg(src);
+		} else {
+			img = this._createImg(src, oldIcon);
+		}
+		this._setIconStyles(img, name);
+
+		return img;
+	},
+
+	_setIconStyles: function (img, name) {
+		var options = this.options,
+		    size = L.point(options[name + 'Size']),
+		    anchor;
+
+		if (name === 'shadow') {
+			anchor = L.point(options.shadowAnchor || options.iconAnchor);
+		} else {
+			anchor = L.point(options.iconAnchor);
+		}
+
+		if (!anchor && size) {
+			anchor = size.divideBy(2, true);
+		}
+
+		img.className = 'leaflet-marker-' + name + ' ' + options.className;
+
+		if (anchor) {
+			img.style.marginLeft = (-anchor.x) + 'px';
+			img.style.marginTop  = (-anchor.y) + 'px';
+		}
+
+		if (size) {
+			img.style.width  = size.x + 'px';
+			img.style.height = size.y + 'px';
+		}
+	},
+
+	_createImg: function (src, el) {
+		el = el || document.createElement('img');
+		el.src = src;
+		return el;
+	},
+
+	_getIconUrl: function (name) {
+		if (L.Browser.retina && this.options[name + 'RetinaUrl']) {
+			return this.options[name + 'RetinaUrl'];
+		}
+		return this.options[name + 'Url'];
+	}
+});
+
+L.icon = function (options) {
+	return new L.Icon(options);
+};
+
+
+/*
+ * L.Icon.Default is the blue marker icon used by default in Leaflet.
+ */
+
+L.Icon.Default = L.Icon.extend({
+
+	options: {
+		iconSize: [25, 41],
+		iconAnchor: [12, 41],
+		popupAnchor: [1, -34],
+
+		shadowSize: [41, 41]
+	},
+
+	_getIconUrl: function (name) {
+		var key = name + 'Url';
+
+		if (this.options[key]) {
+			return this.options[key];
+		}
+
+		if (L.Browser.retina && name === 'icon') {
+			name += '-2x';
+		}
+
+		var path = L.Icon.Default.imagePath;
+
+		if (!path) {
+			throw new Error('Couldn\'t autodetect L.Icon.Default.imagePath, set it manually.');
+		}
+
+		return path + '/marker-' + name + '.png';
+	}
+});
+
+L.Icon.Default.imagePath = (function () {
+	var scripts = document.getElementsByTagName('script'),
+	    leafletRe = /[\/^]leaflet[\-\._]?([\w\-\._]*)\.js\??/;
+
+	var i, len, src, matches, path;
+
+	for (i = 0, len = scripts.length; i < len; i++) {
+		src = scripts[i].src;
+		matches = src.match(leafletRe);
+
+		if (matches) {
+			path = src.split(leafletRe)[0];
+			return (path ? path + '/' : '') + 'images';
+		}
+	}
+}());
+
+
+/*
+ * L.Marker is used to display clickable/draggable icons on the map.
+ */
+
+L.Marker = L.Class.extend({
+
+	includes: L.Mixin.Events,
+
+	options: {
+		icon: new L.Icon.Default(),
+		title: '',
+		alt: '',
+		clickable: true,
+		draggable: false,
+		keyboard: true,
+		zIndexOffset: 0,
+		opacity: 1,
+		riseOnHover: false,
+		riseOffset: 250
+	},
+
+	initialize: function (latlng, options) {
+		L.setOptions(this, options);
+		this._latlng = L.latLng(latlng);
+	},
+
+	onAdd: function (map) {
+		this._map = map;
+
+		map.on('viewreset', this.update, this);
+
+		this._initIcon();
+		this.update();
+		this.fire('add');
+
+		if (map.options.zoomAnimation && map.options.markerZoomAnimation) {
+			map.on('zoomanim', this._animateZoom, this);
+		}
+	},
+
+	addTo: function (map) {
+		map.addLayer(this);
+		return this;
+	},
+
+	onRemove: function (map) {
+		if (this.dragging) {
+			this.dragging.disable();
+		}
+
+		this._removeIcon();
+		this._removeShadow();
+
+		this.fire('remove');
+
+		map.off({
+			'viewreset': this.update,
+			'zoomanim': this._animateZoom
+		}, this);
+
+		this._map = null;
+	},
+
+	getLatLng: function () {
+		return this._latlng;
+	},
+
+	setLatLng: function (latlng) {
+		this._latlng = L.latLng(latlng);
+
+		this.update();
+
+		return this.fire('move', { latlng: this._latlng });
+	},
+
+	setZIndexOffset: function (offset) {
+		this.options.zIndexOffset = offset;
+		this.update();
+
+		return this;
+	},
+
+	setIcon: function (icon) {
+
+		this.options.icon = icon;
+
+		if (this._map) {
+			this._initIcon();
+			this.update();
+		}
+
+		if (this._popup) {
+			this.bindPopup(this._popup);
+		}
+
+		return this;
+	},
+
+	update: function () {
+		if (this._icon) {
+			this._setPos(this._map.latLngToLayerPoint(this._latlng).round());
+		}
+		return this;
+	},
+
+	_initIcon: function () {
+		var options = this.options,
+		    map = this._map,
+		    animation = (map.options.zoomAnimation && map.options.markerZoomAnimation),
+		    classToAdd = animation ? 'leaflet-zoom-animated' : 'leaflet-zoom-hide';
+
+		var icon = options.icon.createIcon(this._icon),
+			addIcon = false;
+
+		// if we're not reusing the icon, remove the old one and init new one
+		if (icon !== this._icon) {
+			if (this._icon) {
+				this._removeIcon();
+			}
+			addIcon = true;
+
+			if (options.title) {
+				icon.title = options.title;
+			}
+
+			if (options.alt) {
+				icon.alt = options.alt;
+			}
+		}
+
+		L.DomUtil.addClass(icon, classToAdd);
+
+		if (options.keyboard) {
+			icon.tabIndex = '0';
+		}
+
+		this._icon = icon;
+
+		this._initInteraction();
+
+		if (options.riseOnHover) {
+			L.DomEvent
+				.on(icon, 'mouseover', this._bringToFront, this)
+				.on(icon, 'mouseout', this._resetZIndex, this);
+		}
+
+		var newShadow = options.icon.createShadow(this._shadow),
+			addShadow = false;
+
+		if (newShadow !== this._shadow) {
+			this._removeShadow();
+			addShadow = true;
+		}
+
+		if (newShadow) {
+			L.DomUtil.addClass(newShadow, classToAdd);
+		}
+		this._shadow = newShadow;
+
+
+		if (options.opacity < 1) {
+			this._updateOpacity();
+		}
+
+
+		var panes = this._map._panes;
+
+		if (addIcon) {
+			panes.markerPane.appendChild(this._icon);
+		}
+
+		if (newShadow && addShadow) {
+			panes.shadowPane.appendChild(this._shadow);
+		}
+	},
+
+	_removeIcon: function () {
+		if (this.options.riseOnHover) {
+			L.DomEvent
+			    .off(this._icon, 'mouseover', this._bringToFront)
+			    .off(this._icon, 'mouseout', this._resetZIndex);
+		}
+
+		this._map._panes.markerPane.removeChild(this._icon);
+
+		this._icon = null;
+	},
+
+	_removeShadow: function () {
+		if (this._shadow) {
+			this._map._panes.shadowPane.removeChild(this._shadow);
+		}
+		this._shadow = null;
+	},
+
+	_setPos: function (pos) {
+		L.DomUtil.setPosition(this._icon, pos);
+
+		if (this._shadow) {
+			L.DomUtil.setPosition(this._shadow, pos);
+		}
+
+		this._zIndex = pos.y + this.options.zIndexOffset;
+
+		this._resetZIndex();
+	},
+
+	_updateZIndex: function (offset) {
+		this._icon.style.zIndex = this._zIndex + offset;
+	},
+
+	_animateZoom: function (opt) {
+		var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round();
+
+		this._setPos(pos);
+	},
+
+	_initInteraction: function () {
+
+		if (!this.options.clickable) { return; }
+
+		// TODO refactor into something shared with Map/Path/etc. to DRY it up
+
+		var icon = this._icon,
+		    events = ['dblclick', 'mousedown', 'mouseover', 'mouseout', 'contextmenu'];
+
+		L.DomUtil.addClass(icon, 'leaflet-clickable');
+		L.DomEvent.on(icon, 'click', this._onMouseClick, this);
+		L.DomEvent.on(icon, 'keypress', this._onKeyPress, this);
+
+		for (var i = 0; i < events.length; i++) {
+			L.DomEvent.on(icon, events[i], this._fireMouseEvent, this);
+		}
+
+		if (L.Handler.MarkerDrag) {
+			this.dragging = new L.Handler.MarkerDrag(this);
+
+			if (this.options.draggable) {
+				this.dragging.enable();
+			}
+		}
+	},
+
+	_onMouseClick: function (e) {
+		var wasDragged = this.dragging && this.dragging.moved();
+
+		if (this.hasEventListeners(e.type) || wasDragged) {
+			L.DomEvent.stopPropagation(e);
+		}
+
+		if (wasDragged) { return; }
+
+		if ((!this.dragging || !this.dragging._enabled) && this._map.dragging && this._map.dragging.moved()) { return; }
+
+		this.fire(e.type, {
+			originalEvent: e,
+			latlng: this._latlng
+		});
+	},
+
+	_onKeyPress: function (e) {
+		if (e.keyCode === 13) {
+			this.fire('click', {
+				originalEvent: e,
+				latlng: this._latlng
+			});
+		}
+	},
+
+	_fireMouseEvent: function (e) {
+
+		this.fire(e.type, {
+			originalEvent: e,
+			latlng: this._latlng
+		});
+
+		// TODO proper custom event propagation
+		// this line will always be called if marker is in a FeatureGroup
+		if (e.type === 'contextmenu' && this.hasEventListeners(e.type)) {
+			L.DomEvent.preventDefault(e);
+		}
+		if (e.type !== 'mousedown') {
+			L.DomEvent.stopPropagation(e);
+		} else {
+			L.DomEvent.preventDefault(e);
+		}
+	},
+
+	setOpacity: function (opacity) {
+		this.options.opacity = opacity;
+		if (this._map) {
+			this._updateOpacity();
+		}
+
+		return this;
+	},
+
+	_updateOpacity: function () {
+		L.DomUtil.setOpacity(this._icon, this.options.opacity);
+		if (this._shadow) {
+			L.DomUtil.setOpacity(this._shadow, this.options.opacity);
+		}
+	},
+
+	_bringToFront: function () {
+		this._updateZIndex(this.options.riseOffset);
+	},
+
+	_resetZIndex: function () {
+		this._updateZIndex(0);
+	}
+});
+
+L.marker = function (latlng, options) {
+	return new L.Marker(latlng, options);
+};
+
+
+/*
+ * L.DivIcon is a lightweight HTML-based icon class (as opposed to the image-based L.Icon)
+ * to use with L.Marker.
+ */
+
+L.DivIcon = L.Icon.extend({
+	options: {
+		iconSize: [12, 12], // also can be set through CSS
+		/*
+		iconAnchor: (Point)
+		popupAnchor: (Point)
+		html: (String)
+		bgPos: (Point)
+		*/
+		className: 'leaflet-div-icon',
+		html: false
+	},
+
+	createIcon: function (oldIcon) {
+		var div = (oldIcon && oldIcon.tagName === 'DIV') ? oldIcon : document.createElement('div'),
+		    options = this.options;
+
+		if (options.html !== false) {
+			div.innerHTML = options.html;
+		} else {
+			div.innerHTML = '';
+		}
+
+		if (options.bgPos) {
+			div.style.backgroundPosition =
+			        (-options.bgPos.x) + 'px ' + (-options.bgPos.y) + 'px';
+		}
+
+		this._setIconStyles(div, 'icon');
+		return div;
+	},
+
+	createShadow: function () {
+		return null;
+	}
+});
+
+L.divIcon = function (options) {
+	return new L.DivIcon(options);
+};
+
+
+/*
+ * L.Popup is used for displaying popups on the map.
+ */
+
+L.Map.mergeOptions({
+	closePopupOnClick: true
+});
+
+L.Popup = L.Class.extend({
+	includes: L.Mixin.Events,
+
+	options: {
+		minWidth: 50,
+		maxWidth: 300,
+		// maxHeight: null,
+		autoPan: true,
+		closeButton: true,
+		offset: [0, 7],
+		autoPanPadding: [5, 5],
+		// autoPanPaddingTopLeft: null,
+		// autoPanPaddingBottomRight: null,
+		keepInView: false,
+		className: '',
+		zoomAnimation: true
+	},
+
+	initialize: function (options, source) {
+		L.setOptions(this, options);
+
+		this._source = source;
+		this._animated = L.Browser.any3d && this.options.zoomAnimation;
+		this._isOpen = false;
+	},
+
+	onAdd: function (map) {
+		this._map = map;
+
+		if (!this._container) {
+			this._initLayout();
+		}
+
+		var animFade = map.options.fadeAnimation;
+
+		if (animFade) {
+			L.DomUtil.setOpacity(this._container, 0);
+		}
+		map._panes.popupPane.appendChild(this._container);
+
+		map.on(this._getEvents(), this);
+
+		this.update();
+
+		if (animFade) {
+			L.DomUtil.setOpacity(this._container, 1);
+		}
+
+		this.fire('open');
+
+		map.fire('popupopen', {popup: this});
+
+		if (this._source) {
+			this._source.fire('popupopen', {popup: this});
+		}
+	},
+
+	addTo: function (map) {
+		map.addLayer(this);
+		return this;
+	},
+
+	openOn: function (map) {
+		map.openPopup(this);
+		return this;
+	},
+
+	onRemove: function (map) {
+		map._panes.popupPane.removeChild(this._container);
+
+		L.Util.falseFn(this._container.offsetWidth); // force reflow
+
+		map.off(this._getEvents(), this);
+
+		if (map.options.fadeAnimation) {
+			L.DomUtil.setOpacity(this._container, 0);
+		}
+
+		this._map = null;
+
+		this.fire('close');
+
+		map.fire('popupclose', {popup: this});
+
+		if (this._source) {
+			this._source.fire('popupclose', {popup: this});
+		}
+	},
+
+	getLatLng: function () {
+		return this._latlng;
+	},
+
+	setLatLng: function (latlng) {
+		this._latlng = L.latLng(latlng);
+		if (this._map) {
+			this._updatePosition();
+			this._adjustPan();
+		}
+		return this;
+	},
+
+	getContent: function () {
+		return this._content;
+	},
+
+	setContent: function (content) {
+		this._content = content;
+		this.update();
+		return this;
+	},
+
+	update: function () {
+		if (!this._map) { return; }
+
+		this._container.style.visibility = 'hidden';
+
+		this._updateContent();
+		this._updateLayout();
+		this._updatePosition();
+
+		this._container.style.visibility = '';
+
+		this._adjustPan();
+	},
+
+	_getEvents: function () {
+		var events = {
+			viewreset: this._updatePosition
+		};
+
+		if (this._animated) {
+			events.zoomanim = this._zoomAnimation;
+		}
+		if ('closeOnClick' in this.options ? this.options.closeOnClick : this._map.options.closePopupOnClick) {
+			events.preclick = this._close;
+		}
+		if (this.options.keepInView) {
+			events.moveend = this._adjustPan;
+		}
+
+		return events;
+	},
+
+	_close: function () {
+		if (this._map) {
+			this._map.closePopup(this);
+		}
+	},
+
+	_initLayout: function () {
+		var prefix = 'leaflet-popup',
+			containerClass = prefix + ' ' + this.options.className + ' leaflet-zoom-' +
+			        (this._animated ? 'animated' : 'hide'),
+			container = this._container = L.DomUtil.create('div', containerClass),
+			closeButton;
+
+		if (this.options.closeButton) {
+			closeButton = this._closeButton =
+			        L.DomUtil.create('a', prefix + '-close-button', container);
+			closeButton.href = '#close';
+			closeButton.innerHTML = '&#215;';
+			L.DomEvent.disableClickPropagation(closeButton);
+
+			L.DomEvent.on(closeButton, 'click', this._onCloseButtonClick, this);
+		}
+
+		var wrapper = this._wrapper =
+		        L.DomUtil.create('div', prefix + '-content-wrapper', container);
+		L.DomEvent.disableClickPropagation(wrapper);
+
+		this._contentNode = L.DomUtil.create('div', prefix + '-content', wrapper);
+
+		L.DomEvent.disableScrollPropagation(this._contentNode);
+		L.DomEvent.on(wrapper, 'contextmenu', L.DomEvent.stopPropagation);
+
+		this._tipContainer = L.DomUtil.create('div', prefix + '-tip-container', container);
+		this._tip = L.DomUtil.create('div', prefix + '-tip', this._tipContainer);
+	},
+
+	_updateContent: function () {
+		if (!this._content) { return; }
+
+		if (typeof this._content === 'string') {
+			this._contentNode.innerHTML = this._content;
+		} else {
+			while (this._contentNode.hasChildNodes()) {
+				this._contentNode.removeChild(this._contentNode.firstChild);
+			}
+			this._contentNode.appendChild(this._content);
+		}
+		this.fire('contentupdate');
+	},
+
+	_updateLayout: function () {
+		var container = this._contentNode,
+		    style = container.style;
+
+		style.width = '';
+		style.whiteSpace = 'nowrap';
+
+		var width = container.offsetWidth;
+		width = Math.min(width, this.options.maxWidth);
+		width = Math.max(width, this.options.minWidth);
+
+		style.width = (width + 1) + 'px';
+		style.whiteSpace = '';
+
+		style.height = '';
+
+		var height = container.offsetHeight,
+		    maxHeight = this.options.maxHeight,
+		    scrolledClass = 'leaflet-popup-scrolled';
+
+		if (maxHeight && height > maxHeight) {
+			style.height = maxHeight + 'px';
+			L.DomUtil.addClass(container, scrolledClass);
+		} else {
+			L.DomUtil.removeClass(container, scrolledClass);
+		}
+
+		this._containerWidth = this._container.offsetWidth;
+	},
+
+	_updatePosition: function () {
+		if (!this._map) { return; }
+
+		var pos = this._map.latLngToLayerPoint(this._latlng),
+		    animated = this._animated,
+		    offset = L.point(this.options.offset);
+
+		if (animated) {
+			L.DomUtil.setPosition(this._container, pos);
+		}
+
+		this._containerBottom = -offset.y - (animated ? 0 : pos.y);
+		this._containerLeft = -Math.round(this._containerWidth / 2) + offset.x + (animated ? 0 : pos.x);
+
+		// bottom position the popup in case the height of the popup changes (images loading etc)
+		this._container.style.bottom = this._containerBottom + 'px';
+		this._container.style.left = this._containerLeft + 'px';
+	},
+
+	_zoomAnimation: function (opt) {
+		var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center);
+
+		L.DomUtil.setPosition(this._container, pos);
+	},
+
+	_adjustPan: function () {
+		if (!this.options.autoPan) { return; }
+
+		var map = this._map,
+		    containerHeight = this._container.offsetHeight,
+		    containerWidth = this._containerWidth,
+
+		    layerPos = new L.Point(this._containerLeft, -containerHeight - this._containerBottom);
+
+		if (this._animated) {
+			layerPos._add(L.DomUtil.getPosition(this._container));
+		}
+
+		var containerPos = map.layerPointToContainerPoint(layerPos),
+		    padding = L.point(this.options.autoPanPadding),
+		    paddingTL = L.point(this.options.autoPanPaddingTopLeft || padding),
+		    paddingBR = L.point(this.options.autoPanPaddingBottomRight || padding),
+		    size = map.getSize(),
+		    dx = 0,
+		    dy = 0;
+
+		if (containerPos.x + containerWidth + paddingBR.x > size.x) { // right
+			dx = containerPos.x + containerWidth - size.x + paddingBR.x;
+		}
+		if (containerPos.x - dx - paddingTL.x < 0) { // left
+			dx = containerPos.x - paddingTL.x;
+		}
+		if (containerPos.y + containerHeight + paddingBR.y > size.y) { // bottom
+			dy = containerPos.y + containerHeight - size.y + paddingBR.y;
+		}
+		if (containerPos.y - dy - paddingTL.y < 0) { // top
+			dy = containerPos.y - paddingTL.y;
+		}
+
+		if (dx || dy) {
+			map
+			    .fire('autopanstart')
+			    .panBy([dx, dy]);
+		}
+	},
+
+	_onCloseButtonClick: function (e) {
+		this._close();
+		L.DomEvent.stop(e);
+	}
+});
+
+L.popup = function (options, source) {
+	return new L.Popup(options, source);
+};
+
+
+L.Map.include({
+	openPopup: function (popup, latlng, options) { // (Popup) or (String || HTMLElement, LatLng[, Object])
+		this.closePopup();
+
+		if (!(popup instanceof L.Popup)) {
+			var content = popup;
+
+			popup = new L.Popup(options)
+			    .setLatLng(latlng)
+			    .setContent(content);
+		}
+		popup._isOpen = true;
+
+		this._popup = popup;
+		return this.addLayer(popup);
+	},
+
+	closePopup: function (popup) {
+		if (!popup || popup === this._popup) {
+			popup = this._popup;
+			this._popup = null;
+		}
+		if (popup) {
+			this.removeLayer(popup);
+			popup._isOpen = false;
+		}
+		return this;
+	}
+});
+
+
+/*
+ * Popup extension to L.Marker, adding popup-related methods.
+ */
+
+L.Marker.include({
+	openPopup: function () {
+		if (this._popup && this._map && !this._map.hasLayer(this._popup)) {
+			this._popup.setLatLng(this._latlng);
+			this._map.openPopup(this._popup);
+		}
+
+		return this;
+	},
+
+	closePopup: function () {
+		if (this._popup) {
+			this._popup._close();
+		}
+		return this;
+	},
+
+	togglePopup: function () {
+		if (this._popup) {
+			if (this._popup._isOpen) {
+				this.closePopup();
+			} else {
+				this.openPopup();
+			}
+		}
+		return this;
+	},
+
+	bindPopup: function (content, options) {
+		var anchor = L.point(this.options.icon.options.popupAnchor || [0, 0]);
+
+		anchor = anchor.add(L.Popup.prototype.options.offset);
+
+		if (options && options.offset) {
+			anchor = anchor.add(options.offset);
+		}
+
+		options = L.extend({offset: anchor}, options);
+
+		if (!this._popupHandlersAdded) {
+			this
+			    .on('click', this.togglePopup, this)
+			    .on('remove', this.closePopup, this)
+			    .on('move', this._movePopup, this);
+			this._popupHandlersAdded = true;
+		}
+
+		if (content instanceof L.Popup) {
+			L.setOptions(content, options);
+			this._popup = content;
+			content._source = this;
+		} else {
+			this._popup = new L.Popup(options, this)
+				.setContent(content);
+		}
+
+		return this;
+	},
+
+	setPopupContent: function (content) {
+		if (this._popup) {
+			this._popup.setContent(content);
+		}
+		return this;
+	},
+
+	unbindPopup: function () {
+		if (this._popup) {
+			this._popup = null;
+			this
+			    .off('click', this.togglePopup, this)
+			    .off('remove', this.closePopup, this)
+			    .off('move', this._movePopup, this);
+			this._popupHandlersAdded = false;
+		}
+		return this;
+	},
+
+	getPopup: function () {
+		return this._popup;
+	},
+
+	_movePopup: function (e) {
+		this._popup.setLatLng(e.latlng);
+	}
+});
+
+
+/*
+ * L.LayerGroup is a class to combine several layers into one so that
+ * you can manipulate the group (e.g. add/remove it) as one layer.
+ */
+
+L.LayerGroup = L.Class.extend({
+	initialize: function (layers) {
+		this._layers = {};
+
+		var i, len;
+
+		if (layers) {
+			for (i = 0, len = layers.length; i < len; i++) {
+				this.addLayer(layers[i]);
+			}
+		}
+	},
+
+	addLayer: function (layer) {
+		var id = this.getLayerId(layer);
+
+		this._layers[id] = layer;
+
+		if (this._map) {
+			this._map.addLayer(layer);
+		}
+
+		return this;
+	},
+
+	removeLayer: function (layer) {
+		var id = layer in this._layers ? layer : this.getLayerId(layer);
+
+		if (this._map && this._layers[id]) {
+			this._map.removeLayer(this._layers[id]);
+		}
+
+		delete this._layers[id];
+
+		return this;
+	},
+
+	hasLayer: function (layer) {
+		if (!layer) { return false; }
+
+		return (layer in this._layers || this.getLayerId(layer) in this._layers);
+	},
+
+	clearLayers: function () {
+		this.eachLayer(this.removeLayer, this);
+		return this;
+	},
+
+	invoke: function (methodName) {
+		var args = Array.prototype.slice.call(arguments, 1),
+		    i, layer;
+
+		for (i in this._layers) {
+			layer = this._layers[i];
+
+			if (layer[methodName]) {
+				layer[methodName].apply(layer, args);
+			}
+		}
+
+		return this;
+	},
+
+	onAdd: function (map) {
+		this._map = map;
+		this.eachLayer(map.addLayer, map);
+	},
+
+	onRemove: function (map) {
+		this.eachLayer(map.removeLayer, map);
+		this._map = null;
+	},
+
+	addTo: function (map) {
+		map.addLayer(this);
+		return this;
+	},
+
+	eachLayer: function (method, context) {
+		for (var i in this._layers) {
+			method.call(context, this._layers[i]);
+		}
+		return this;
+	},
+
+	getLayer: function (id) {
+		return this._layers[id];
+	},
+
+	getLayers: function () {
+		var layers = [];
+
+		for (var i in this._layers) {
+			layers.push(this._layers[i]);
+		}
+		return layers;
+	},
+
+	setZIndex: function (zIndex) {
+		return this.invoke('setZIndex', zIndex);
+	},
+
+	getLayerId: function (layer) {
+		return L.stamp(layer);
+	}
+});
+
+L.layerGroup = function (layers) {
+	return new L.LayerGroup(layers);
+};
+
+
+/*
+ * L.FeatureGroup extends L.LayerGroup by introducing mouse events and additional methods
+ * shared between a group of interactive layers (like vectors or markers).
+ */
+
+L.FeatureGroup = L.LayerGroup.extend({
+	includes: L.Mixin.Events,
+
+	statics: {
+		EVENTS: 'click dblclick mouseover mouseout mousemove contextmenu popupopen popupclose'
+	},
+
+	addLayer: function (layer) {
+		if (this.hasLayer(layer)) {
+			return this;
+		}
+
+		if ('on' in layer) {
+			layer.on(L.FeatureGroup.EVENTS, this._propagateEvent, this);
+		}
+
+		L.LayerGroup.prototype.addLayer.call(this, layer);
+
+		if (this._popupContent && layer.bindPopup) {
+			layer.bindPopup(this._popupContent, this._popupOptions);
+		}
+
+		return this.fire('layeradd', {layer: layer});
+	},
+
+	removeLayer: function (layer) {
+		if (!this.hasLayer(layer)) {
+			return this;
+		}
+		if (layer in this._layers) {
+			layer = this._layers[layer];
+		}
+
+		if ('off' in layer) {
+			layer.off(L.FeatureGroup.EVENTS, this._propagateEvent, this);
+		}
+
+		L.LayerGroup.prototype.removeLayer.call(this, layer);
+
+		if (this._popupContent) {
+			this.invoke('unbindPopup');
+		}
+
+		return this.fire('layerremove', {layer: layer});
+	},
+
+	bindPopup: function (content, options) {
+		this._popupContent = content;
+		this._popupOptions = options;
+		return this.invoke('bindPopup', content, options);
+	},
+
+	openPopup: function (latlng) {
+		// open popup on the first layer
+		for (var id in this._layers) {
+			this._layers[id].openPopup(latlng);
+			break;
+		}
+		return this;
+	},
+
+	setStyle: function (style) {
+		return this.invoke('setStyle', style);
+	},
+
+	bringToFront: function () {
+		return this.invoke('bringToFront');
+	},
+
+	bringToBack: function () {
+		return this.invoke('bringToBack');
+	},
+
+	getBounds: function () {
+		var bounds = new L.LatLngBounds();
+
+		this.eachLayer(function (layer) {
+			bounds.extend(layer instanceof L.Marker ? layer.getLatLng() : layer.getBounds());
+		});
+
+		return bounds;
+	},
+
+	_propagateEvent: function (e) {
+		e = L.extend({
+			layer: e.target,
+			target: this
+		}, e);
+		this.fire(e.type, e);
+	}
+});
+
+L.featureGroup = function (layers) {
+	return new L.FeatureGroup(layers);
+};
+
+
+/*
+ * L.Path is a base class for rendering vector paths on a map. Inherited by Polyline, Circle, etc.
+ */
+
+L.Path = L.Class.extend({
+	includes: [L.Mixin.Events],
+
+	statics: {
+		// how much to extend the clip area around the map view
+		// (relative to its size, e.g. 0.5 is half the screen in each direction)
+		// set it so that SVG element doesn't exceed 1280px (vectors flicker on dragend if it is)
+		CLIP_PADDING: (function () {
+			var max = L.Browser.mobile ? 1280 : 2000,
+			    target = (max / Math.max(window.outerWidth, window.outerHeight) - 1) / 2;
+			return Math.max(0, Math.min(0.5, target));
+		})()
+	},
+
+	options: {
+		stroke: true,
+		color: '#0033ff',
+		dashArray: null,
+		lineCap: null,
+		lineJoin: null,
+		weight: 5,
+		opacity: 0.5,
+
+		fill: false,
+		fillColor: null, //same as color by default
+		fillOpacity: 0.2,
+
+		clickable: true
+	},
+
+	initialize: function (options) {
+		L.setOptions(this, options);
+	},
+
+	onAdd: function (map) {
+		this._map = map;
+
+		if (!this._container) {
+			this._initElements();
+			this._initEvents();
+		}
+
+		this.projectLatlngs();
+		this._updatePath();
+
+		if (this._container) {
+			this._map._pathRoot.appendChild(this._container);
+		}
+
+		this.fire('add');
+
+		map.on({
+			'viewreset': this.projectLatlngs,
+			'moveend': this._updatePath
+		}, this);
+	},
+
+	addTo: function (map) {
+		map.addLayer(this);
+		return this;
+	},
+
+	onRemove: function (map) {
+		map._pathRoot.removeChild(this._container);
+
+		// Need to fire remove event before we set _map to null as the event hooks might need the object
+		this.fire('remove');
+		this._map = null;
+
+		if (L.Browser.vml) {
+			this._container = null;
+			this._stroke = null;
+			this._fill = null;
+		}
+
+		map.off({
+			'viewreset': this.projectLatlngs,
+			'moveend': this._updatePath
+		}, this);
+	},
+
+	projectLatlngs: function () {
+		// do all projection stuff here
+	},
+
+	setStyle: function (style) {
+		L.setOptions(this, style);
+
+		if (this._container) {
+			this._updateStyle();
+		}
+
+		return this;
+	},
+
+	redraw: function () {
+		if (this._map) {
+			this.projectLatlngs();
+			this._updatePath();
+		}
+		return this;
+	}
+});
+
+L.Map.include({
+	_updatePathViewport: function () {
+		var p = L.Path.CLIP_PADDING,
+		    size = this.getSize(),
+		    panePos = L.DomUtil.getPosition(this._mapPane),
+		    min = panePos.multiplyBy(-1)._subtract(size.multiplyBy(p)._round()),
+		    max = min.add(size.multiplyBy(1 + p * 2)._round());
+
+		this._pathViewport = new L.Bounds(min, max);
+	}
+});
+
+
+/*
+ * Extends L.Path with SVG-specific rendering code.
+ */
+
+L.Path.SVG_NS = 'http://www.w3.org/2000/svg';
+
+L.Browser.svg = !!(document.createElementNS && document.createElementNS(L.Path.SVG_NS, 'svg').createSVGRect);
+
+L.Path = L.Path.extend({
+	statics: {
+		SVG: L.Browser.svg
+	},
+
+	bringToFront: function () {
+		var root = this._map._pathRoot,
+		    path = this._container;
+
+		if (path && root.lastChild !== path) {
+			root.appendChild(path);
+		}
+		return this;
+	},
+
+	bringToBack: function () {
+		var root = this._map._pathRoot,
+		    path = this._container,
+		    first = root.firstChild;
+
+		if (path && first !== path) {
+			root.insertBefore(path, first);
+		}
+		return this;
+	},
+
+	getPathString: function () {
+		// form path string here
+	},
+
+	_createElement: function (name) {
+		return document.createElementNS(L.Path.SVG_NS, name);
+	},
+
+	_initElements: function () {
+		this._map._initPathRoot();
+		this._initPath();
+		this._initStyle();
+	},
+
+	_initPath: function () {
+		this._container = this._createElement('g');
+
+		this._path = this._createElement('path');
+
+		if (this.options.className) {
+			L.DomUtil.addClass(this._path, this.options.className);
+		}
+
+		this._container.appendChild(this._path);
+	},
+
+	_initStyle: function () {
+		if (this.options.stroke) {
+			this._path.setAttribute('stroke-linejoin', 'round');
+			this._path.setAttribute('stroke-linecap', 'round');
+		}
+		if (this.options.fill) {
+			this._path.setAttribute('fill-rule', 'evenodd');
+		}
+		if (this.options.pointerEvents) {
+			this._path.setAttribute('pointer-events', this.options.pointerEvents);
+		}
+		if (!this.options.clickable && !this.options.pointerEvents) {
+			this._path.setAttribute('pointer-events', 'none');
+		}
+		this._updateStyle();
+	},
+
+	_updateStyle: function () {
+		if (this.options.stroke) {
+			this._path.setAttribute('stroke', this.options.color);
+			this._path.setAttribute('stroke-opacity', this.options.opacity);
+			this._path.setAttribute('stroke-width', this.options.weight);
+			if (this.options.dashArray) {
+				this._path.setAttribute('stroke-dasharray', this.options.dashArray);
+			} else {
+				this._path.removeAttribute('stroke-dasharray');
+			}
+			if (this.options.lineCap) {
+				this._path.setAttribute('stroke-linecap', this.options.lineCap);
+			}
+			if (this.options.lineJoin) {
+				this._path.setAttribute('stroke-linejoin', this.options.lineJoin);
+			}
+		} else {
+			this._path.setAttribute('stroke', 'none');
+		}
+		if (this.options.fill) {
+			this._path.setAttribute('fill', this.options.fillColor || this.options.color);
+			this._path.setAttribute('fill-opacity', this.options.fillOpacity);
+		} else {
+			this._path.setAttribute('fill', 'none');
+		}
+	},
+
+	_updatePath: function () {
+		var str = this.getPathString();
+		if (!str) {
+			// fix webkit empty string parsing bug
+			str = 'M0 0';
+		}
+		this._path.setAttribute('d', str);
+	},
+
+	// TODO remove duplication with L.Map
+	_initEvents: function () {
+		if (this.options.clickable) {
+			if (L.Browser.svg || !L.Browser.vml) {
+				L.DomUtil.addClass(this._path, 'leaflet-clickable');
+			}
+
+			L.DomEvent.on(this._container, 'click', this._onMouseClick, this);
+
+			var events = ['dblclick', 'mousedown', 'mouseover',
+			              'mouseout', 'mousemove', 'contextmenu'];
+			for (var i = 0; i < events.length; i++) {
+				L.DomEvent.on(this._container, events[i], this._fireMouseEvent, this);
+			}
+		}
+	},
+
+	_onMouseClick: function (e) {
+		if (this._map.dragging && this._map.dragging.moved()) { return; }
+
+		this._fireMouseEvent(e);
+	},
+
+	_fireMouseEvent: function (e) {
+		if (!this._map || !this.hasEventListeners(e.type)) { return; }
+
+		var map = this._map,
+		    containerPoint = map.mouseEventToContainerPoint(e),
+		    layerPoint = map.containerPointToLayerPoint(containerPoint),
+		    latlng = map.layerPointToLatLng(layerPoint);
+
+		this.fire(e.type, {
+			latlng: latlng,
+			layerPoint: layerPoint,
+			containerPoint: containerPoint,
+			originalEvent: e
+		});
+
+		if (e.type === 'contextmenu') {
+			L.DomEvent.preventDefault(e);
+		}
+		if (e.type !== 'mousemove') {
+			L.DomEvent.stopPropagation(e);
+		}
+	}
+});
+
+L.Map.include({
+	_initPathRoot: function () {
+		if (!this._pathRoot) {
+			this._pathRoot = L.Path.prototype._createElement('svg');
+			this._panes.overlayPane.appendChild(this._pathRoot);
+
+			if (this.options.zoomAnimation && L.Browser.any3d) {
+				L.DomUtil.addClass(this._pathRoot, 'leaflet-zoom-animated');
+
+				this.on({
+					'zoomanim': this._animatePathZoom,
+					'zoomend': this._endPathZoom
+				});
+			} else {
+				L.DomUtil.addClass(this._pathRoot, 'leaflet-zoom-hide');
+			}
+
+			this.on('moveend', this._updateSvgViewport);
+			this._updateSvgViewport();
+		}
+	},
+
+	_animatePathZoom: function (e) {
+		var scale = this.getZoomScale(e.zoom),
+		    offset = this._getCenterOffset(e.center)._multiplyBy(-scale)._add(this._pathViewport.min);
+
+		this._pathRoot.style[L.DomUtil.TRANSFORM] =
+		        L.DomUtil.getTranslateString(offset) + ' scale(' + scale + ') ';
+
+		this._pathZooming = true;
+	},
+
+	_endPathZoom: function () {
+		this._pathZooming = false;
+	},
+
+	_updateSvgViewport: function () {
+
+		if (this._pathZooming) {
+			// Do not update SVGs while a zoom animation is going on otherwise the animation will break.
+			// When the zoom animation ends we will be updated again anyway
+			// This fixes the case where you do a momentum move and zoom while the move is still ongoing.
+			return;
+		}
+
+		this._updatePathViewport();
+
+		var vp = this._pathViewport,
+		    min = vp.min,
+		    max = vp.max,
+		    width = max.x - min.x,
+		    height = max.y - min.y,
+		    root = this._pathRoot,
+		    pane = this._panes.overlayPane;
+
+		// Hack to make flicker on drag end on mobile webkit less irritating
+		if (L.Browser.mobileWebkit) {
+			pane.removeChild(root);
+		}
+
+		L.DomUtil.setPosition(root, min);
+		root.setAttribute('width', width);
+		root.setAttribute('height', height);
+		root.setAttribute('viewBox', [min.x, min.y, width, height].join(' '));
+
+		if (L.Browser.mobileWebkit) {
+			pane.appendChild(root);
+		}
+	}
+});
+
+
+/*
+ * Popup extension to L.Path (polylines, polygons, circles), adding popup-related methods.
+ */
+
+L.Path.include({
+
+	bindPopup: function (content, options) {
+
+		if (content instanceof L.Popup) {
+			this._popup = content;
+		} else {
+			if (!this._popup || options) {
+				this._popup = new L.Popup(options, this);
+			}
+			this._popup.setContent(content);
+		}
+
+		if (!this._popupHandlersAdded) {
+			this
+			    .on('click', this._openPopup, this)
+			    .on('remove', this.closePopup, this);
+
+			this._popupHandlersAdded = true;
+		}
+
+		return this;
+	},
+
+	unbindPopup: function () {
+		if (this._popup) {
+			this._popup = null;
+			this
+			    .off('click', this._openPopup)
+			    .off('remove', this.closePopup);
+
+			this._popupHandlersAdded = false;
+		}
+		return this;
+	},
+
+	openPopup: function (latlng) {
+
+		if (this._popup) {
+			// open the popup from one of the path's points if not specified
+			latlng = latlng || this._latlng ||
+			         this._latlngs[Math.floor(this._latlngs.length / 2)];
+
+			this._openPopup({latlng: latlng});
+		}
+
+		return this;
+	},
+
+	closePopup: function () {
+		if (this._popup) {
+			this._popup._close();
+		}
+		return this;
+	},
+
+	_openPopup: function (e) {
+		this._popup.setLatLng(e.latlng);
+		this._map.openPopup(this._popup);
+	}
+});
+
+
+/*
+ * Vector rendering for IE6-8 through VML.
+ * Thanks to Dmitry Baranovsky and his Raphael library for inspiration!
+ */
+
+L.Browser.vml = !L.Browser.svg && (function () {
+	try {
+		var div = document.createElement('div');
+		div.innerHTML = '<v:shape adj="1"/>';
+
+		var shape = div.firstChild;
+		shape.style.behavior = 'url(#default#VML)';
+
+		return shape && (typeof shape.adj === 'object');
+
+	} catch (e) {
+		return false;
+	}
+}());
+
+L.Path = L.Browser.svg || !L.Browser.vml ? L.Path : L.Path.extend({
+	statics: {
+		VML: true,
+		CLIP_PADDING: 0.02
+	},
+
+	_createElement: (function () {
+		try {
+			document.namespaces.add('lvml', 'urn:schemas-microsoft-com:vml');
+			return function (name) {
+				return document.createElement('<lvml:' + name + ' class="lvml">');
+			};
+		} catch (e) {
+			return function (name) {
+				return document.createElement(
+				        '<' + name + ' xmlns="urn:schemas-microsoft.com:vml" class="lvml">');
+			};
+		}
+	}()),
+
+	_initPath: function () {
+		var container = this._container = this._createElement('shape');
+
+		L.DomUtil.addClass(container, 'leaflet-vml-shape' +
+			(this.options.className ? ' ' + this.options.className : ''));
+
+		if (this.options.clickable) {
+			L.DomUtil.addClass(container, 'leaflet-clickable');
+		}
+
+		container.coordsize = '1 1';
+
+		this._path = this._createElement('path');
+		container.appendChild(this._path);
+
+		this._map._pathRoot.appendChild(container);
+	},
+
+	_initStyle: function () {
+		this._updateStyle();
+	},
+
+	_updateStyle: function () {
+		var stroke = this._stroke,
+		    fill = this._fill,
+		    options = this.options,
+		    container = this._container;
+
+		container.stroked = options.stroke;
+		container.filled = options.fill;
+
+		if (options.stroke) {
+			if (!stroke) {
+				stroke = this._stroke = this._createElement('stroke');
+				stroke.endcap = 'round';
+				container.appendChild(stroke);
+			}
+			stroke.weight = options.weight + 'px';
+			stroke.color = options.color;
+			stroke.opacity = options.opacity;
+
+			if (options.dashArray) {
+				stroke.dashStyle = L.Util.isArray(options.dashArray) ?
+				    options.dashArray.join(' ') :
+				    options.dashArray.replace(/( *, *)/g, ' ');
+			} else {
+				stroke.dashStyle = '';
+			}
+			if (options.lineCap) {
+				stroke.endcap = options.lineCap.replace('butt', 'flat');
+			}
+			if (options.lineJoin) {
+				stroke.joinstyle = options.lineJoin;
+			}
+
+		} else if (stroke) {
+			container.removeChild(stroke);
+			this._stroke = null;
+		}
+
+		if (options.fill) {
+			if (!fill) {
+				fill = this._fill = this._createElement('fill');
+				container.appendChild(fill);
+			}
+			fill.color = options.fillColor || options.color;
+			fill.opacity = options.fillOpacity;
+
+		} else if (fill) {
+			container.removeChild(fill);
+			this._fill = null;
+		}
+	},
+
+	_updatePath: function () {
+		var style = this._container.style;
+
+		style.display = 'none';
+		this._path.v = this.getPathString() + ' '; // the space fixes IE empty path string bug
+		style.display = '';
+	}
+});
+
+L.Map.include(L.Browser.svg || !L.Browser.vml ? {} : {
+	_initPathRoot: function () {
+		if (this._pathRoot) { return; }
+
+		var root = this._pathRoot = document.createElement('div');
+		root.className = 'leaflet-vml-container';
+		this._panes.overlayPane.appendChild(root);
+
+		this.on('moveend', this._updatePathViewport);
+		this._updatePathViewport();
+	}
+});
+
+
+/*
+ * Vector rendering for all browsers that support canvas.
+ */
+
+L.Browser.canvas = (function () {
+	return !!document.createElement('canvas').getContext;
+}());
+
+L.Path = (L.Path.SVG && !window.L_PREFER_CANVAS) || !L.Browser.canvas ? L.Path : L.Path.extend({
+	statics: {
+		//CLIP_PADDING: 0.02, // not sure if there's a need to set it to a small value
+		CANVAS: true,
+		SVG: false
+	},
+
+	redraw: function () {
+		if (this._map) {
+			this.projectLatlngs();
+			this._requestUpdate();
+		}
+		return this;
+	},
+
+	setStyle: function (style) {
+		L.setOptions(this, style);
+
+		if (this._map) {
+			this._updateStyle();
+			this._requestUpdate();
+		}
+		return this;
+	},
+
+	onRemove: function (map) {
+		map
+		    .off('viewreset', this.projectLatlngs, this)
+		    .off('moveend', this._updatePath, this);
+
+		if (this.options.clickable) {
+			this._map.off('click', this._onClick, this);
+			this._map.off('mousemove', this._onMouseMove, this);
+		}
+
+		this._requestUpdate();
+		
+		this.fire('remove');
+		this._map = null;
+	},
+
+	_requestUpdate: function () {
+		if (this._map && !L.Path._updateRequest) {
+			L.Path._updateRequest = L.Util.requestAnimFrame(this._fireMapMoveEnd, this._map);
+		}
+	},
+
+	_fireMapMoveEnd: function () {
+		L.Path._updateRequest = null;
+		this.fire('moveend');
+	},
+
+	_initElements: function () {
+		this._map._initPathRoot();
+		this._ctx = this._map._canvasCtx;
+	},
+
+	_updateStyle: function () {
+		var options = this.options;
+
+		if (options.stroke) {
+			this._ctx.lineWidth = options.weight;
+			this._ctx.strokeStyle = options.color;
+		}
+		if (options.fill) {
+			this._ctx.fillStyle = options.fillColor || options.color;
+		}
+
+		if (options.lineCap) {
+			this._ctx.lineCap = options.lineCap;
+		}
+		if (options.lineJoin) {
+			this._ctx.lineJoin = options.lineJoin;
+		}
+	},
+
+	_drawPath: function () {
+		var i, j, len, len2, point, drawMethod;
+
+		this._ctx.beginPath();
+
+		for (i = 0, len = this._parts.length; i < len; i++) {
+			for (j = 0, len2 = this._parts[i].length; j < len2; j++) {
+				point = this._parts[i][j];
+				drawMethod = (j === 0 ? 'move' : 'line') + 'To';
+
+				this._ctx[drawMethod](point.x, point.y);
+			}
+			// TODO refactor ugly hack
+			if (this instanceof L.Polygon) {
+				this._ctx.closePath();
+			}
+		}
+	},
+
+	_checkIfEmpty: function () {
+		return !this._parts.length;
+	},
+
+	_updatePath: function () {
+		if (this._checkIfEmpty()) { return; }
+
+		var ctx = this._ctx,
+		    options = this.options;
+
+		this._drawPath();
+		ctx.save();
+		this._updateStyle();
+
+		if (options.fill) {
+			ctx.globalAlpha = options.fillOpacity;
+			ctx.fill(options.fillRule || 'evenodd');
+		}
+
+		if (options.stroke) {
+			ctx.globalAlpha = options.opacity;
+			ctx.stroke();
+		}
+
+		ctx.restore();
+
+		// TODO optimization: 1 fill/stroke for all features with equal style instead of 1 for each feature
+	},
+
+	_initEvents: function () {
+		if (this.options.clickable) {
+			this._map.on('mousemove', this._onMouseMove, this);
+			this._map.on('click dblclick contextmenu', this._fireMouseEvent, this);
+		}
+	},
+
+	_fireMouseEvent: function (e) {
+		if (this._containsPoint(e.layerPoint)) {
+			this.fire(e.type, e);
+		}
+	},
+
+	_onMouseMove: function (e) {
+		if (!this._map || this._map._animatingZoom) { return; }
+
+		// TODO don't do on each move
+		if (this._containsPoint(e.layerPoint)) {
+			this._ctx.canvas.style.cursor = 'pointer';
+			this._mouseInside = true;
+			this.fire('mouseover', e);
+
+		} else if (this._mouseInside) {
+			this._ctx.canvas.style.cursor = '';
+			this._mouseInside = false;
+			this.fire('mouseout', e);
+		}
+	}
+});
+
+L.Map.include((L.Path.SVG && !window.L_PREFER_CANVAS) || !L.Browser.canvas ? {} : {
+	_initPathRoot: function () {
+		var root = this._pathRoot,
+		    ctx;
+
+		if (!root) {
+			root = this._pathRoot = document.createElement('canvas');
+			root.style.position = 'absolute';
+			ctx = this._canvasCtx = root.getContext('2d');
+
+			ctx.lineCap = 'round';
+			ctx.lineJoin = 'round';
+
+			this._panes.overlayPane.appendChild(root);
+
+			if (this.options.zoomAnimation) {
+				this._pathRoot.className = 'leaflet-zoom-animated';
+				this.on('zoomanim', this._animatePathZoom);
+				this.on('zoomend', this._endPathZoom);
+			}
+			this.on('moveend', this._updateCanvasViewport);
+			this._updateCanvasViewport();
+		}
+	},
+
+	_updateCanvasViewport: function () {
+		// don't redraw while zooming. See _updateSvgViewport for more details
+		if (this._pathZooming) { return; }
+		this._updatePathViewport();
+
+		var vp = this._pathViewport,
+		    min = vp.min,
+		    size = vp.max.subtract(min),
+		    root = this._pathRoot;
+
+		//TODO check if this works properly on mobile webkit
+		L.DomUtil.setPosition(root, min);
+		root.width = size.x;
+		root.height = size.y;
+		root.getContext('2d').translate(-min.x, -min.y);
+	}
+});
+
+
+/*
+ * L.LineUtil contains different utility functions for line segments
+ * and polylines (clipping, simplification, distances, etc.)
+ */
+
+/*jshint bitwise:false */ // allow bitwise operations for this file
+
+L.LineUtil = {
+
+	// Simplify polyline with vertex reduction and Douglas-Peucker simplification.
+	// Improves rendering performance dramatically by lessening the number of points to draw.
+
+	simplify: function (/*Point[]*/ points, /*Number*/ tolerance) {
+		if (!tolerance || !points.length) {
+			return points.slice();
+		}
+
+		var sqTolerance = tolerance * tolerance;
+
+		// stage 1: vertex reduction
+		points = this._reducePoints(points, sqTolerance);
+
+		// stage 2: Douglas-Peucker simplification
+		points = this._simplifyDP(points, sqTolerance);
+
+		return points;
+	},
+
+	// distance from a point to a segment between two points
+	pointToSegmentDistance:  function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2) {
+		return Math.sqrt(this._sqClosestPointOnSegment(p, p1, p2, true));
+	},
+
+	closestPointOnSegment: function (/*Point*/ p, /*Point*/ p1, /*Point*/ p2) {
+		return this._sqClosestPointOnSegment(p, p1, p2);
+	},
+
+	// Douglas-Peucker simplification, see http://en.wikipedia.org/wiki/Douglas-Peucker_algorithm
+	_simplifyDP: function (points, sqTolerance) {
+
+		var len = points.length,
+		    ArrayConstructor = typeof Uint8Array !== undefined + '' ? Uint8Array : Array,
+		    markers = new ArrayConstructor(len);
+
+		markers[0] = markers[len - 1] = 1;
+
+		this._simplifyDPStep(points, markers, sqTolerance, 0, len - 1);
+
+		var i,
+		    newPoints = [];
+
+		for (i = 0; i < len; i++) {
+			if (markers[i]) {
+				newPoints.push(points[i]);
+			}
+		}
+
+		return newPoints;
+	},
+
+	_simplifyDPStep: function (points, markers, sqTolerance, first, last) {
+
+		var maxSqDist = 0,
+		    index, i, sqDist;
+
+		for (i = first + 1; i <= last - 1; i++) {
+			sqDist = this._sqClosestPointOnSegment(points[i], points[first], points[last], true);
+
+			if (sqDist > maxSqDist) {
+				index = i;
+				maxSqDist = sqDist;
+			}
+		}
+
+		if (maxSqDist > sqTolerance) {
+			markers[index] = 1;
+
+			this._simplifyDPStep(points, markers, sqTolerance, first, index);
+			this._simplifyDPStep(points, markers, sqTolerance, index, last);
+		}
+	},
+
+	// reduce points that are too close to each other to a single point
+	_reducePoints: function (points, sqTolerance) {
+		var reducedPoints = [points[0]];
+
+		for (var i = 1, prev = 0, len = points.length; i < len; i++) {
+			if (this._sqDist(points[i], points[prev]) > sqTolerance) {
+				reducedPoints.push(points[i]);
+				prev = i;
+			}
+		}
+		if (prev < len - 1) {
+			reducedPoints.push(points[len - 1]);
+		}
+		return reducedPoints;
+	},
+
+	// Cohen-Sutherland line clipping algorithm.
+	// Used to avoid rendering parts of a polyline that are not currently visible.
+
+	clipSegment: function (a, b, bounds, useLastCode) {
+		var codeA = useLastCode ? this._lastCode : this._getBitCode(a, bounds),
+		    codeB = this._getBitCode(b, bounds),
+
+		    codeOut, p, newCode;
+
+		// save 2nd code to avoid calculating it on the next segment
+		this._lastCode = codeB;
+
+		while (true) {
+			// if a,b is inside the clip window (trivial accept)
+			if (!(codeA | codeB)) {
+				return [a, b];
+			// if a,b is outside the clip window (trivial reject)
+			} else if (codeA & codeB) {
+				return false;
+			// other cases
+			} else {
+				codeOut = codeA || codeB;
+				p = this._getEdgeIntersection(a, b, codeOut, bounds);
+				newCode = this._getBitCode(p, bounds);
+
+				if (codeOut === codeA) {
+					a = p;
+					codeA = newCode;
+				} else {
+					b = p;
+					codeB = newCode;
+				}
+			}
+		}
+	},
+
+	_getEdgeIntersection: function (a, b, code, bounds) {
+		var dx = b.x - a.x,
+		    dy = b.y - a.y,
+		    min = bounds.min,
+		    max = bounds.max;
+
+		if (code & 8) { // top
+			return new L.Point(a.x + dx * (max.y - a.y) / dy, max.y);
+		} else if (code & 4) { // bottom
+			return new L.Point(a.x + dx * (min.y - a.y) / dy, min.y);
+		} else if (code & 2) { // right
+			return new L.Point(max.x, a.y + dy * (max.x - a.x) / dx);
+		} else if (code & 1) { // left
+			return new L.Point(min.x, a.y + dy * (min.x - a.x) / dx);
+		}
+	},
+
+	_getBitCode: function (/*Point*/ p, bounds) {
+		var code = 0;
+
+		if (p.x < bounds.min.x) { // left
+			code |= 1;
+		} else if (p.x > bounds.max.x) { // right
+			code |= 2;
+		}
+		if (p.y < bounds.min.y) { // bottom
+			code |= 4;
+		} else if (p.y > bounds.max.y) { // top
+			code |= 8;
+		}
+
+		return code;
+	},
+
+	// square distance (to avoid unnecessary Math.sqrt calls)
+	_sqDist: function (p1, p2) {
+		var dx = p2.x - p1.x,
+		    dy = p2.y - p1.y;
+		return dx * dx + dy * dy;
+	},
+
+	// return closest point on segment or distance to that point
+	_sqClosestPointOnSegment: function (p, p1, p2, sqDist) {
+		var x = p1.x,
+		    y = p1.y,
+		    dx = p2.x - x,
+		    dy = p2.y - y,
+		    dot = dx * dx + dy * dy,
+		    t;
+
+		if (dot > 0) {
+			t = ((p.x - x) * dx + (p.y - y) * dy) / dot;
+
+			if (t > 1) {
+				x = p2.x;
+				y = p2.y;
+			} else if (t > 0) {
+				x += dx * t;
+				y += dy * t;
+			}
+		}
+
+		dx = p.x - x;
+		dy = p.y - y;
+
+		return sqDist ? dx * dx + dy * dy : new L.Point(x, y);
+	}
+};
+
+
+/*
+ * L.Polyline is used to display polylines on a map.
+ */
+
+L.Polyline = L.Path.extend({
+	initialize: function (latlngs, options) {
+		L.Path.prototype.initialize.call(this, options);
+
+		this._latlngs = this._convertLatLngs(latlngs);
+	},
+
+	options: {
+		// how much to simplify the polyline on each zoom level
+		// more = better performance and smoother look, less = more accurate
+		smoothFactor: 1.0,
+		noClip: false
+	},
+
+	projectLatlngs: function () {
+		this._originalPoints = [];
+
+		for (var i = 0, len = this._latlngs.length; i < len; i++) {
+			this._originalPoints[i] = this._map.latLngToLayerPoint(this._latlngs[i]);
+		}
+	},
+
+	getPathString: function () {
+		for (var i = 0, len = this._parts.length, str = ''; i < len; i++) {
+			str += this._getPathPartStr(this._parts[i]);
+		}
+		return str;
+	},
+
+	getLatLngs: function () {
+		return this._latlngs;
+	},
+
+	setLatLngs: function (latlngs) {
+		this._latlngs = this._convertLatLngs(latlngs);
+		return this.redraw();
+	},
+
+	addLatLng: function (latlng) {
+		this._latlngs.push(L.latLng(latlng));
+		return this.redraw();
+	},
+
+	spliceLatLngs: function () { // (Number index, Number howMany)
+		var removed = [].splice.apply(this._latlngs, arguments);
+		this._convertLatLngs(this._latlngs, true);
+		this.redraw();
+		return removed;
+	},
+
+	closestLayerPoint: function (p) {
+		var minDistance = Infinity, parts = this._parts, p1, p2, minPoint = null;
+
+		for (var j = 0, jLen = parts.length; j < jLen; j++) {
+			var points = parts[j];
+			for (var i = 1, len = points.length; i < len; i++) {
+				p1 = points[i - 1];
+				p2 = points[i];
+				var sqDist = L.LineUtil._sqClosestPointOnSegment(p, p1, p2, true);
+				if (sqDist < minDistance) {
+					minDistance = sqDist;
+					minPoint = L.LineUtil._sqClosestPointOnSegment(p, p1, p2);
+				}
+			}
+		}
+		if (minPoint) {
+			minPoint.distance = Math.sqrt(minDistance);
+		}
+		return minPoint;
+	},
+
+	getBounds: function () {
+		return new L.LatLngBounds(this.getLatLngs());
+	},
+
+	_convertLatLngs: function (latlngs, overwrite) {
+		var i, len, target = overwrite ? latlngs : [];
+
+		for (i = 0, len = latlngs.length; i < len; i++) {
+			if (L.Util.isArray(latlngs[i]) && typeof latlngs[i][0] !== 'number') {
+				return;
+			}
+			target[i] = L.latLng(latlngs[i]);
+		}
+		return target;
+	},
+
+	_initEvents: function () {
+		L.Path.prototype._initEvents.call(this);
+	},
+
+	_getPathPartStr: function (points) {
+		var round = L.Path.VML;
+
+		for (var j = 0, len2 = points.length, str = '', p; j < len2; j++) {
+			p = points[j];
+			if (round) {
+				p._round();
+			}
+			str += (j ? 'L' : 'M') + p.x + ' ' + p.y;
+		}
+		return str;
+	},
+
+	_clipPoints: function () {
+		var points = this._originalPoints,
+		    len = points.length,
+		    i, k, segment;
+
+		if (this.options.noClip) {
+			this._parts = [points];
+			return;
+		}
+
+		this._parts = [];
+
+		var parts = this._parts,
+		    vp = this._map._pathViewport,
+		    lu = L.LineUtil;
+
+		for (i = 0, k = 0; i < len - 1; i++) {
+			segment = lu.clipSegment(points[i], points[i + 1], vp, i);
+			if (!segment) {
+				continue;
+			}
+
+			parts[k] = parts[k] || [];
+			parts[k].push(segment[0]);
+
+			// if segment goes out of screen, or it's the last one, it's the end of the line part
+			if ((segment[1] !== points[i + 1]) || (i === len - 2)) {
+				parts[k].push(segment[1]);
+				k++;
+			}
+		}
+	},
+
+	// simplify each clipped part of the polyline
+	_simplifyPoints: function () {
+		var parts = this._parts,
+		    lu = L.LineUtil;
+
+		for (var i = 0, len = parts.length; i < len; i++) {
+			parts[i] = lu.simplify(parts[i], this.options.smoothFactor);
+		}
+	},
+
+	_updatePath: function () {
+		if (!this._map) { return; }
+
+		this._clipPoints();
+		this._simplifyPoints();
+
+		L.Path.prototype._updatePath.call(this);
+	}
+});
+
+L.polyline = function (latlngs, options) {
+	return new L.Polyline(latlngs, options);
+};
+
+
+/*
+ * L.PolyUtil contains utility functions for polygons (clipping, etc.).
+ */
+
+/*jshint bitwise:false */ // allow bitwise operations here
+
+L.PolyUtil = {};
+
+/*
+ * Sutherland-Hodgeman polygon clipping algorithm.
+ * Used to avoid rendering parts of a polygon that are not currently visible.
+ */
+L.PolyUtil.clipPolygon = function (points, bounds) {
+	var clippedPoints,
+	    edges = [1, 4, 2, 8],
+	    i, j, k,
+	    a, b,
+	    len, edge, p,
+	    lu = L.LineUtil;
+
+	for (i = 0, len = points.length; i < len; i++) {
+		points[i]._code = lu._getBitCode(points[i], bounds);
+	}
+
+	// for each edge (left, bottom, right, top)
+	for (k = 0; k < 4; k++) {
+		edge = edges[k];
+		clippedPoints = [];
+
+		for (i = 0, len = points.length, j = len - 1; i < len; j = i++) {
+			a = points[i];
+			b = points[j];
+
+			// if a is inside the clip window
+			if (!(a._code & edge)) {
+				// if b is outside the clip window (a->b goes out of screen)
+				if (b._code & edge) {
+					p = lu._getEdgeIntersection(b, a, edge, bounds);
+					p._code = lu._getBitCode(p, bounds);
+					clippedPoints.push(p);
+				}
+				clippedPoints.push(a);
+
+			// else if b is inside the clip window (a->b enters the screen)
+			} else if (!(b._code & edge)) {
+				p = lu._getEdgeIntersection(b, a, edge, bounds);
+				p._code = lu._getBitCode(p, bounds);
+				clippedPoints.push(p);
+			}
+		}
+		points = clippedPoints;
+	}
+
+	return points;
+};
+
+
+/*
+ * L.Polygon is used to display polygons on a map.
+ */
+
+L.Polygon = L.Polyline.extend({
+	options: {
+		fill: true
+	},
+
+	initialize: function (latlngs, options) {
+		L.Polyline.prototype.initialize.call(this, latlngs, options);
+		this._initWithHoles(latlngs);
+	},
+
+	_initWithHoles: function (latlngs) {
+		var i, len, hole;
+		if (latlngs && L.Util.isArray(latlngs[0]) && (typeof latlngs[0][0] !== 'number')) {
+			this._latlngs = this._convertLatLngs(latlngs[0]);
+			this._holes = latlngs.slice(1);
+
+			for (i = 0, len = this._holes.length; i < len; i++) {
+				hole = this._holes[i] = this._convertLatLngs(this._holes[i]);
+				if (hole[0].equals(hole[hole.length - 1])) {
+					hole.pop();
+				}
+			}
+		}
+
+		// filter out last point if its equal to the first one
+		latlngs = this._latlngs;
+
+		if (latlngs.length >= 2 && latlngs[0].equals(latlngs[latlngs.length - 1])) {
+			latlngs.pop();
+		}
+	},
+
+	projectLatlngs: function () {
+		L.Polyline.prototype.projectLatlngs.call(this);
+
+		// project polygon holes points
+		// TODO move this logic to Polyline to get rid of duplication
+		this._holePoints = [];
+
+		if (!this._holes) { return; }
+
+		var i, j, len, len2;
+
+		for (i = 0, len = this._holes.length; i < len; i++) {
+			this._holePoints[i] = [];
+
+			for (j = 0, len2 = this._holes[i].length; j < len2; j++) {
+				this._holePoints[i][j] = this._map.latLngToLayerPoint(this._holes[i][j]);
+			}
+		}
+	},
+
+	setLatLngs: function (latlngs) {
+		if (latlngs && L.Util.isArray(latlngs[0]) && (typeof latlngs[0][0] !== 'number')) {
+			this._initWithHoles(latlngs);
+			return this.redraw();
+		} else {
+			return L.Polyline.prototype.setLatLngs.call(this, latlngs);
+		}
+	},
+
+	_clipPoints: function () {
+		var points = this._originalPoints,
+		    newParts = [];
+
+		this._parts = [points].concat(this._holePoints);
+
+		if (this.options.noClip) { return; }
+
+		for (var i = 0, len = this._parts.length; i < len; i++) {
+			var clipped = L.PolyUtil.clipPolygon(this._parts[i], this._map._pathViewport);
+			if (clipped.length) {
+				newParts.push(clipped);
+			}
+		}
+
+		this._parts = newParts;
+	},
+
+	_getPathPartStr: function (points) {
+		var str = L.Polyline.prototype._getPathPartStr.call(this, points);
+		return str + (L.Browser.svg ? 'z' : 'x');
+	}
+});
+
+L.polygon = function (latlngs, options) {
+	return new L.Polygon(latlngs, options);
+};
+
+
+/*
+ * Contains L.MultiPolyline and L.MultiPolygon layers.
+ */
+
+(function () {
+	function createMulti(Klass) {
+
+		return L.FeatureGroup.extend({
+
+			initialize: function (latlngs, options) {
+				this._layers = {};
+				this._options = options;
+				this.setLatLngs(latlngs);
+			},
+
+			setLatLngs: function (latlngs) {
+				var i = 0,
+				    len = latlngs.length;
+
+				this.eachLayer(function (layer) {
+					if (i < len) {
+						layer.setLatLngs(latlngs[i++]);
+					} else {
+						this.removeLayer(layer);
+					}
+				}, this);
+
+				while (i < len) {
+					this.addLayer(new Klass(latlngs[i++], this._options));
+				}
+
+				return this;
+			},
+
+			getLatLngs: function () {
+				var latlngs = [];
+
+				this.eachLayer(function (layer) {
+					latlngs.push(layer.getLatLngs());
+				});
+
+				return latlngs;
+			}
+		});
+	}
+
+	L.MultiPolyline = createMulti(L.Polyline);
+	L.MultiPolygon = createMulti(L.Polygon);
+
+	L.multiPolyline = function (latlngs, options) {
+		return new L.MultiPolyline(latlngs, options);
+	};
+
+	L.multiPolygon = function (latlngs, options) {
+		return new L.MultiPolygon(latlngs, options);
+	};
+}());
+
+
+/*
+ * L.Rectangle extends Polygon and creates a rectangle when passed a LatLngBounds object.
+ */
+
+L.Rectangle = L.Polygon.extend({
+	initialize: function (latLngBounds, options) {
+		L.Polygon.prototype.initialize.call(this, this._boundsToLatLngs(latLngBounds), options);
+	},
+
+	setBounds: function (latLngBounds) {
+		this.setLatLngs(this._boundsToLatLngs(latLngBounds));
+	},
+
+	_boundsToLatLngs: function (latLngBounds) {
+		latLngBounds = L.latLngBounds(latLngBounds);
+		return [
+			latLngBounds.getSouthWest(),
+			latLngBounds.getNorthWest(),
+			latLngBounds.getNorthEast(),
+			latLngBounds.getSouthEast()
+		];
+	}
+});
+
+L.rectangle = function (latLngBounds, options) {
+	return new L.Rectangle(latLngBounds, options);
+};
+
+
+/*
+ * L.Circle is a circle overlay (with a certain radius in meters).
+ */
+
+L.Circle = L.Path.extend({
+	initialize: function (latlng, radius, options) {
+		L.Path.prototype.initialize.call(this, options);
+
+		this._latlng = L.latLng(latlng);
+		this._mRadius = radius;
+	},
+
+	options: {
+		fill: true
+	},
+
+	setLatLng: function (latlng) {
+		this._latlng = L.latLng(latlng);
+		return this.redraw();
+	},
+
+	setRadius: function (radius) {
+		this._mRadius = radius;
+		return this.redraw();
+	},
+
+	projectLatlngs: function () {
+		var lngRadius = this._getLngRadius(),
+		    latlng = this._latlng,
+		    pointLeft = this._map.latLngToLayerPoint([latlng.lat, latlng.lng - lngRadius]);
+
+		this._point = this._map.latLngToLayerPoint(latlng);
+		this._radius = Math.max(this._point.x - pointLeft.x, 1);
+	},
+
+	getBounds: function () {
+		var lngRadius = this._getLngRadius(),
+		    latRadius = (this._mRadius / 40075017) * 360,
+		    latlng = this._latlng;
+
+		return new L.LatLngBounds(
+		        [latlng.lat - latRadius, latlng.lng - lngRadius],
+		        [latlng.lat + latRadius, latlng.lng + lngRadius]);
+	},
+
+	getLatLng: function () {
+		return this._latlng;
+	},
+
+	getPathString: function () {
+		var p = this._point,
+		    r = this._radius;
+
+		if (this._checkIfEmpty()) {
+			return '';
+		}
+
+		if (L.Browser.svg) {
+			return 'M' + p.x + ',' + (p.y - r) +
+			       'A' + r + ',' + r + ',0,1,1,' +
+			       (p.x - 0.1) + ',' + (p.y - r) + ' z';
+		} else {
+			p._round();
+			r = Math.round(r);
+			return 'AL ' + p.x + ',' + p.y + ' ' + r + ',' + r + ' 0,' + (65535 * 360);
+		}
+	},
+
+	getRadius: function () {
+		return this._mRadius;
+	},
+
+	// TODO Earth hardcoded, move into projection code!
+
+	_getLatRadius: function () {
+		return (this._mRadius / 40075017) * 360;
+	},
+
+	_getLngRadius: function () {
+		return this._getLatRadius() / Math.cos(L.LatLng.DEG_TO_RAD * this._latlng.lat);
+	},
+
+	_checkIfEmpty: function () {
+		if (!this._map) {
+			return false;
+		}
+		var vp = this._map._pathViewport,
+		    r = this._radius,
+		    p = this._point;
+
+		return p.x - r > vp.max.x || p.y - r > vp.max.y ||
+		       p.x + r < vp.min.x || p.y + r < vp.min.y;
+	}
+});
+
+L.circle = function (latlng, radius, options) {
+	return new L.Circle(latlng, radius, options);
+};
+
+
+/*
+ * L.CircleMarker is a circle overlay with a permanent pixel radius.
+ */
+
+L.CircleMarker = L.Circle.extend({
+	options: {
+		radius: 10,
+		weight: 2
+	},
+
+	initialize: function (latlng, options) {
+		L.Circle.prototype.initialize.call(this, latlng, null, options);
+		this._radius = this.options.radius;
+	},
+
+	projectLatlngs: function () {
+		this._point = this._map.latLngToLayerPoint(this._latlng);
+	},
+
+	_updateStyle : function () {
+		L.Circle.prototype._updateStyle.call(this);
+		this.setRadius(this.options.radius);
+	},
+
+	setLatLng: function (latlng) {
+		L.Circle.prototype.setLatLng.call(this, latlng);
+		if (this._popup && this._popup._isOpen) {
+			this._popup.setLatLng(latlng);
+		}
+		return this;
+	},
+
+	setRadius: function (radius) {
+		this.options.radius = this._radius = radius;
+		return this.redraw();
+	},
+
+	getRadius: function () {
+		return this._radius;
+	}
+});
+
+L.circleMarker = function (latlng, options) {
+	return new L.CircleMarker(latlng, options);
+};
+
+
+/*
+ * Extends L.Polyline to be able to manually detect clicks on Canvas-rendered polylines.
+ */
+
+L.Polyline.include(!L.Path.CANVAS ? {} : {
+	_containsPoint: function (p, closed) {
+		var i, j, k, len, len2, dist, part,
+		    w = this.options.weight / 2;
+
+		if (L.Browser.touch) {
+			w += 10; // polyline click tolerance on touch devices
+		}
+
+		for (i = 0, len = this._parts.length; i < len; i++) {
+			part = this._parts[i];
+			for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) {
+				if (!closed && (j === 0)) {
+					continue;
+				}
+
+				dist = L.LineUtil.pointToSegmentDistance(p, part[k], part[j]);
+
+				if (dist <= w) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+});
+
+
+/*
+ * Extends L.Polygon to be able to manually detect clicks on Canvas-rendered polygons.
+ */
+
+L.Polygon.include(!L.Path.CANVAS ? {} : {
+	_containsPoint: function (p) {
+		var inside = false,
+		    part, p1, p2,
+		    i, j, k,
+		    len, len2;
+
+		// TODO optimization: check if within bounds first
+
+		if (L.Polyline.prototype._containsPoint.call(this, p, true)) {
+			// click on polygon border
+			return true;
+		}
+
+		// ray casting algorithm for detecting if point is in polygon
+
+		for (i = 0, len = this._parts.length; i < len; i++) {
+			part = this._parts[i];
+
+			for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) {
+				p1 = part[j];
+				p2 = part[k];
+
+				if (((p1.y > p.y) !== (p2.y > p.y)) &&
+						(p.x < (p2.x - p1.x) * (p.y - p1.y) / (p2.y - p1.y) + p1.x)) {
+					inside = !inside;
+				}
+			}
+		}
+
+		return inside;
+	}
+});
+
+
+/*
+ * Extends L.Circle with Canvas-specific code.
+ */
+
+L.Circle.include(!L.Path.CANVAS ? {} : {
+	_drawPath: function () {
+		var p = this._point;
+		this._ctx.beginPath();
+		this._ctx.arc(p.x, p.y, this._radius, 0, Math.PI * 2, false);
+	},
+
+	_containsPoint: function (p) {
+		var center = this._point,
+		    w2 = this.options.stroke ? this.options.weight / 2 : 0;
+
+		return (p.distanceTo(center) <= this._radius + w2);
+	}
+});
+
+
+/*
+ * CircleMarker canvas specific drawing parts.
+ */
+
+L.CircleMarker.include(!L.Path.CANVAS ? {} : {
+	_updateStyle: function () {
+		L.Path.prototype._updateStyle.call(this);
+	}
+});
+
+
+/*
+ * L.GeoJSON turns any GeoJSON data into a Leaflet layer.
+ */
+
+L.GeoJSON = L.FeatureGroup.extend({
+
+	initialize: function (geojson, options) {
+		L.setOptions(this, options);
+
+		this._layers = {};
+
+		if (geojson) {
+			this.addData(geojson);
+		}
+	},
+
+	addData: function (geojson) {
+		var features = L.Util.isArray(geojson) ? geojson : geojson.features,
+		    i, len, feature;
+
+		if (features) {
+			for (i = 0, len = features.length; i < len; i++) {
+				// Only add this if geometry or geometries are set and not null
+				feature = features[i];
+				if (feature.geometries || feature.geometry || feature.features || feature.coordinates) {
+					this.addData(features[i]);
+				}
+			}
+			return this;
+		}
+
+		var options = this.options;
+
+		if (options.filter && !options.filter(geojson)) { return; }
+
+		var layer = L.GeoJSON.geometryToLayer(geojson, options.pointToLayer, options.coordsToLatLng, options);
+		layer.feature = L.GeoJSON.asFeature(geojson);
+
+		layer.defaultOptions = layer.options;
+		this.resetStyle(layer);
+
+		if (options.onEachFeature) {
+			options.onEachFeature(geojson, layer);
+		}
+
+		return this.addLayer(layer);
+	},
+
+	resetStyle: function (layer) {
+		var style = this.options.style;
+		if (style) {
+			// reset any custom styles
+			L.Util.extend(layer.options, layer.defaultOptions);
+
+			this._setLayerStyle(layer, style);
+		}
+	},
+
+	setStyle: function (style) {
+		this.eachLayer(function (layer) {
+			this._setLayerStyle(layer, style);
+		}, this);
+	},
+
+	_setLayerStyle: function (layer, style) {
+		if (typeof style === 'function') {
+			style = style(layer.feature);
+		}
+		if (layer.setStyle) {
+			layer.setStyle(style);
+		}
+	}
+});
+
+L.extend(L.GeoJSON, {
+	geometryToLayer: function (geojson, pointToLayer, coordsToLatLng, vectorOptions) {
+		var geometry = geojson.type === 'Feature' ? geojson.geometry : geojson,
+		    coords = geometry.coordinates,
+		    layers = [],
+		    latlng, latlngs, i, len;
+
+		coordsToLatLng = coordsToLatLng || this.coordsToLatLng;
+
+		switch (geometry.type) {
+		case 'Point':
+			latlng = coordsToLatLng(coords);
+			return pointToLayer ? pointToLayer(geojson, latlng) : new L.Marker(latlng);
+
+		case 'MultiPoint':
+			for (i = 0, len = coords.length; i < len; i++) {
+				latlng = coordsToLatLng(coords[i]);
+				layers.push(pointToLayer ? pointToLayer(geojson, latlng) : new L.Marker(latlng));
+			}
+			return new L.FeatureGroup(layers);
+
+		case 'LineString':
+			latlngs = this.coordsToLatLngs(coords, 0, coordsToLatLng);
+			return new L.Polyline(latlngs, vectorOptions);
+
+		case 'Polygon':
+			if (coords.length === 2 && !coords[1].length) {
+				throw new Error('Invalid GeoJSON object.');
+			}
+			latlngs = this.coordsToLatLngs(coords, 1, coordsToLatLng);
+			return new L.Polygon(latlngs, vectorOptions);
+
+		case 'MultiLineString':
+			latlngs = this.coordsToLatLngs(coords, 1, coordsToLatLng);
+			return new L.MultiPolyline(latlngs, vectorOptions);
+
+		case 'MultiPolygon':
+			latlngs = this.coordsToLatLngs(coords, 2, coordsToLatLng);
+			return new L.MultiPolygon(latlngs, vectorOptions);
+
+		case 'GeometryCollection':
+			for (i = 0, len = geometry.geometries.length; i < len; i++) {
+
+				layers.push(this.geometryToLayer({
+					geometry: geometry.geometries[i],
+					type: 'Feature',
+					properties: geojson.properties
+				}, pointToLayer, coordsToLatLng, vectorOptions));
+			}
+			return new L.FeatureGroup(layers);
+
+		default:
+			throw new Error('Invalid GeoJSON object.');
+		}
+	},
+
+	coordsToLatLng: function (coords) { // (Array[, Boolean]) -> LatLng
+		return new L.LatLng(coords[1], coords[0], coords[2]);
+	},
+
+	coordsToLatLngs: function (coords, levelsDeep, coordsToLatLng) { // (Array[, Number, Function]) -> Array
+		var latlng, i, len,
+		    latlngs = [];
+
+		for (i = 0, len = coords.length; i < len; i++) {
+			latlng = levelsDeep ?
+			        this.coordsToLatLngs(coords[i], levelsDeep - 1, coordsToLatLng) :
+			        (coordsToLatLng || this.coordsToLatLng)(coords[i]);
+
+			latlngs.push(latlng);
+		}
+
+		return latlngs;
+	},
+
+	latLngToCoords: function (latlng) {
+		var coords = [latlng.lng, latlng.lat];
+
+		if (latlng.alt !== undefined) {
+			coords.push(latlng.alt);
+		}
+		return coords;
+	},
+
+	latLngsToCoords: function (latLngs) {
+		var coords = [];
+
+		for (var i = 0, len = latLngs.length; i < len; i++) {
+			coords.push(L.GeoJSON.latLngToCoords(latLngs[i]));
+		}
+
+		return coords;
+	},
+
+	getFeature: function (layer, newGeometry) {
+		return layer.feature ? L.extend({}, layer.feature, {geometry: newGeometry}) : L.GeoJSON.asFeature(newGeometry);
+	},
+
+	asFeature: function (geoJSON) {
+		if (geoJSON.type === 'Feature') {
+			return geoJSON;
+		}
+
+		return {
+			type: 'Feature',
+			properties: {},
+			geometry: geoJSON
+		};
+	}
+});
+
+var PointToGeoJSON = {
+	toGeoJSON: function () {
+		return L.GeoJSON.getFeature(this, {
+			type: 'Point',
+			coordinates: L.GeoJSON.latLngToCoords(this.getLatLng())
+		});
+	}
+};
+
+L.Marker.include(PointToGeoJSON);
+L.Circle.include(PointToGeoJSON);
+L.CircleMarker.include(PointToGeoJSON);
+
+L.Polyline.include({
+	toGeoJSON: function () {
+		return L.GeoJSON.getFeature(this, {
+			type: 'LineString',
+			coordinates: L.GeoJSON.latLngsToCoords(this.getLatLngs())
+		});
+	}
+});
+
+L.Polygon.include({
+	toGeoJSON: function () {
+		var coords = [L.GeoJSON.latLngsToCoords(this.getLatLngs())],
+		    i, len, hole;
+
+		coords[0].push(coords[0][0]);
+
+		if (this._holes) {
+			for (i = 0, len = this._holes.length; i < len; i++) {
+				hole = L.GeoJSON.latLngsToCoords(this._holes[i]);
+				hole.push(hole[0]);
+				coords.push(hole);
+			}
+		}
+
+		return L.GeoJSON.getFeature(this, {
+			type: 'Polygon',
+			coordinates: coords
+		});
+	}
+});
+
+(function () {
+	function multiToGeoJSON(type) {
+		return function () {
+			var coords = [];
+
+			this.eachLayer(function (layer) {
+				coords.push(layer.toGeoJSON().geometry.coordinates);
+			});
+
+			return L.GeoJSON.getFeature(this, {
+				type: type,
+				coordinates: coords
+			});
+		};
+	}
+
+	L.MultiPolyline.include({toGeoJSON: multiToGeoJSON('MultiLineString')});
+	L.MultiPolygon.include({toGeoJSON: multiToGeoJSON('MultiPolygon')});
+
+	L.LayerGroup.include({
+		toGeoJSON: function () {
+
+			var geometry = this.feature && this.feature.geometry,
+				jsons = [],
+				json;
+
+			if (geometry && geometry.type === 'MultiPoint') {
+				return multiToGeoJSON('MultiPoint').call(this);
+			}
+
+			var isGeometryCollection = geometry && geometry.type === 'GeometryCollection';
+
+			this.eachLayer(function (layer) {
+				if (layer.toGeoJSON) {
+					json = layer.toGeoJSON();
+					jsons.push(isGeometryCollection ? json.geometry : L.GeoJSON.asFeature(json));
+				}
+			});
+
+			if (isGeometryCollection) {
+				return L.GeoJSON.getFeature(this, {
+					geometries: jsons,
+					type: 'GeometryCollection'
+				});
+			}
+
+			return {
+				type: 'FeatureCollection',
+				features: jsons
+			};
+		}
+	});
+}());
+
+L.geoJson = function (geojson, options) {
+	return new L.GeoJSON(geojson, options);
+};
+
+
+/*
+ * L.DomEvent contains functions for working with DOM events.
+ */
+
+L.DomEvent = {
+	/* inspired by John Resig, Dean Edwards and YUI addEvent implementations */
+	addListener: function (obj, type, fn, context) { // (HTMLElement, String, Function[, Object])
+
+		var id = L.stamp(fn),
+		    key = '_leaflet_' + type + id,
+		    handler, originalHandler, newType;
+
+		if (obj[key]) { return this; }
+
+		handler = function (e) {
+			return fn.call(context || obj, e || L.DomEvent._getEvent());
+		};
+
+		if (L.Browser.pointer && type.indexOf('touch') === 0) {
+			return this.addPointerListener(obj, type, handler, id);
+		}
+		if (L.Browser.touch && (type === 'dblclick') && this.addDoubleTapListener) {
+			this.addDoubleTapListener(obj, handler, id);
+		}
+
+		if ('addEventListener' in obj) {
+
+			if (type === 'mousewheel') {
+				obj.addEventListener('DOMMouseScroll', handler, false);
+				obj.addEventListener(type, handler, false);
+
+			} else if ((type === 'mouseenter') || (type === 'mouseleave')) {
+
+				originalHandler = handler;
+				newType = (type === 'mouseenter' ? 'mouseover' : 'mouseout');
+
+				handler = function (e) {
+					if (!L.DomEvent._checkMouse(obj, e)) { return; }
+					return originalHandler(e);
+				};
+
+				obj.addEventListener(newType, handler, false);
+
+			} else if (type === 'click' && L.Browser.android) {
+				originalHandler = handler;
+				handler = function (e) {
+					return L.DomEvent._filterClick(e, originalHandler);
+				};
+
+				obj.addEventListener(type, handler, false);
+			} else {
+				obj.addEventListener(type, handler, false);
+			}
+
+		} else if ('attachEvent' in obj) {
+			obj.attachEvent('on' + type, handler);
+		}
+
+		obj[key] = handler;
+
+		return this;
+	},
+
+	removeListener: function (obj, type, fn) {  // (HTMLElement, String, Function)
+
+		var id = L.stamp(fn),
+		    key = '_leaflet_' + type + id,
+		    handler = obj[key];
+
+		if (!handler) { return this; }
+
+		if (L.Browser.pointer && type.indexOf('touch') === 0) {
+			this.removePointerListener(obj, type, id);
+		} else if (L.Browser.touch && (type === 'dblclick') && this.removeDoubleTapListener) {
+			this.removeDoubleTapListener(obj, id);
+
+		} else if ('removeEventListener' in obj) {
+
+			if (type === 'mousewheel') {
+				obj.removeEventListener('DOMMouseScroll', handler, false);
+				obj.removeEventListener(type, handler, false);
+
+			} else if ((type === 'mouseenter') || (type === 'mouseleave')) {
+				obj.removeEventListener((type === 'mouseenter' ? 'mouseover' : 'mouseout'), handler, false);
+			} else {
+				obj.removeEventListener(type, handler, false);
+			}
+		} else if ('detachEvent' in obj) {
+			obj.detachEvent('on' + type, handler);
+		}
+
+		obj[key] = null;
+
+		return this;
+	},
+
+	stopPropagation: function (e) {
+
+		if (e.stopPropagation) {
+			e.stopPropagation();
+		} else {
+			e.cancelBubble = true;
+		}
+		L.DomEvent._skipped(e);
+
+		return this;
+	},
+
+	disableScrollPropagation: function (el) {
+		var stop = L.DomEvent.stopPropagation;
+
+		return L.DomEvent
+			.on(el, 'mousewheel', stop)
+			.on(el, 'MozMousePixelScroll', stop);
+	},
+
+	disableClickPropagation: function (el) {
+		var stop = L.DomEvent.stopPropagation;
+
+		for (var i = L.Draggable.START.length - 1; i >= 0; i--) {
+			L.DomEvent.on(el, L.Draggable.START[i], stop);
+		}
+
+		return L.DomEvent
+			.on(el, 'click', L.DomEvent._fakeStop)
+			.on(el, 'dblclick', stop);
+	},
+
+	preventDefault: function (e) {
+
+		if (e.preventDefault) {
+			e.preventDefault();
+		} else {
+			e.returnValue = false;
+		}
+		return this;
+	},
+
+	stop: function (e) {
+		return L.DomEvent
+			.preventDefault(e)
+			.stopPropagation(e);
+	},
+
+	getMousePosition: function (e, container) {
+		if (!container) {
+			return new L.Point(e.clientX, e.clientY);
+		}
+
+		var rect = container.getBoundingClientRect();
+
+		return new L.Point(
+			e.clientX - rect.left - container.clientLeft,
+			e.clientY - rect.top - container.clientTop);
+	},
+
+	getWheelDelta: function (e) {
+
+		var delta = 0;
+
+		if (e.wheelDelta) {
+			delta = e.wheelDelta / 120;
+		}
+		if (e.detail) {
+			delta = -e.detail / 3;
+		}
+		return delta;
+	},
+
+	_skipEvents: {},
+
+	_fakeStop: function (e) {
+		// fakes stopPropagation by setting a special event flag, checked/reset with L.DomEvent._skipped(e)
+		L.DomEvent._skipEvents[e.type] = true;
+	},
+
+	_skipped: function (e) {
+		var skipped = this._skipEvents[e.type];
+		// reset when checking, as it's only used in map container and propagates outside of the map
+		this._skipEvents[e.type] = false;
+		return skipped;
+	},
+
+	// check if element really left/entered the event target (for mouseenter/mouseleave)
+	_checkMouse: function (el, e) {
+
+		var related = e.relatedTarget;
+
+		if (!related) { return true; }
+
+		try {
+			while (related && (related !== el)) {
+				related = related.parentNode;
+			}
+		} catch (err) {
+			return false;
+		}
+		return (related !== el);
+	},
+
+	_getEvent: function () { // evil magic for IE
+		/*jshint noarg:false */
+		var e = window.event;
+		if (!e) {
+			var caller = arguments.callee.caller;
+			while (caller) {
+				e = caller['arguments'][0];
+				if (e && window.Event === e.constructor) {
+					break;
+				}
+				caller = caller.caller;
+			}
+		}
+		return e;
+	},
+
+	// this is a horrible workaround for a bug in Android where a single touch triggers two click events
+	_filterClick: function (e, handler) {
+		var timeStamp = (e.timeStamp || e.originalEvent.timeStamp),
+			elapsed = L.DomEvent._lastClick && (timeStamp - L.DomEvent._lastClick);
+
+		// are they closer together than 500ms yet more than 100ms?
+		// Android typically triggers them ~300ms apart while multiple listeners
+		// on the same event should be triggered far faster;
+		// or check if click is simulated on the element, and if it is, reject any non-simulated events
+
+		if ((elapsed && elapsed > 100 && elapsed < 500) || (e.target._simulatedClick && !e._simulated)) {
+			L.DomEvent.stop(e);
+			return;
+		}
+		L.DomEvent._lastClick = timeStamp;
+
+		return handler(e);
+	}
+};
+
+L.DomEvent.on = L.DomEvent.addListener;
+L.DomEvent.off = L.DomEvent.removeListener;
+
+
+/*
+ * L.Draggable allows you to add dragging capabilities to any element. Supports mobile devices too.
+ */
+
+L.Draggable = L.Class.extend({
+	includes: L.Mixin.Events,
+
+	statics: {
+		START: L.Browser.touch ? ['touchstart', 'mousedown'] : ['mousedown'],
+		END: {
+			mousedown: 'mouseup',
+			touchstart: 'touchend',
+			pointerdown: 'touchend',
+			MSPointerDown: 'touchend'
+		},
+		MOVE: {
+			mousedown: 'mousemove',
+			touchstart: 'touchmove',
+			pointerdown: 'touchmove',
+			MSPointerDown: 'touchmove'
+		}
+	},
+
+	initialize: function (element, dragStartTarget) {
+		this._element = element;
+		this._dragStartTarget = dragStartTarget || element;
+	},
+
+	enable: function () {
+		if (this._enabled) { return; }
+
+		for (var i = L.Draggable.START.length - 1; i >= 0; i--) {
+			L.DomEvent.on(this._dragStartTarget, L.Draggable.START[i], this._onDown, this);
+		}
+
+		this._enabled = true;
+	},
+
+	disable: function () {
+		if (!this._enabled) { return; }
+
+		for (var i = L.Draggable.START.length - 1; i >= 0; i--) {
+			L.DomEvent.off(this._dragStartTarget, L.Draggable.START[i], this._onDown, this);
+		}
+
+		this._enabled = false;
+		this._moved = false;
+	},
+
+	_onDown: function (e) {
+		this._moved = false;
+
+		if (e.shiftKey || ((e.which !== 1) && (e.button !== 1) && !e.touches)) { return; }
+
+		L.DomEvent.stopPropagation(e);
+
+		if (L.Draggable._disabled) { return; }
+
+		L.DomUtil.disableImageDrag();
+		L.DomUtil.disableTextSelection();
+
+		if (this._moving) { return; }
+
+		var first = e.touches ? e.touches[0] : e;
+
+		this._startPoint = new L.Point(first.clientX, first.clientY);
+		this._startPos = this._newPos = L.DomUtil.getPosition(this._element);
+
+		L.DomEvent
+		    .on(document, L.Draggable.MOVE[e.type], this._onMove, this)
+		    .on(document, L.Draggable.END[e.type], this._onUp, this);
+	},
+
+	_onMove: function (e) {
+		if (e.touches && e.touches.length > 1) {
+			this._moved = true;
+			return;
+		}
+
+		var first = (e.touches && e.touches.length === 1 ? e.touches[0] : e),
+		    newPoint = new L.Point(first.clientX, first.clientY),
+		    offset = newPoint.subtract(this._startPoint);
+
+		if (!offset.x && !offset.y) { return; }
+		if (L.Browser.touch && Math.abs(offset.x) + Math.abs(offset.y) < 3) { return; }
+
+		L.DomEvent.preventDefault(e);
+
+		if (!this._moved) {
+			this.fire('dragstart');
+
+			this._moved = true;
+			this._startPos = L.DomUtil.getPosition(this._element).subtract(offset);
+
+			L.DomUtil.addClass(document.body, 'leaflet-dragging');
+			this._lastTarget = e.target || e.srcElement;
+			L.DomUtil.addClass(this._lastTarget, 'leaflet-drag-target');
+		}
+
+		this._newPos = this._startPos.add(offset);
+		this._moving = true;
+
+		L.Util.cancelAnimFrame(this._animRequest);
+		this._animRequest = L.Util.requestAnimFrame(this._updatePosition, this, true, this._dragStartTarget);
+	},
+
+	_updatePosition: function () {
+		this.fire('predrag');
+		L.DomUtil.setPosition(this._element, this._newPos);
+		this.fire('drag');
+	},
+
+	_onUp: function () {
+		L.DomUtil.removeClass(document.body, 'leaflet-dragging');
+
+		if (this._lastTarget) {
+			L.DomUtil.removeClass(this._lastTarget, 'leaflet-drag-target');
+			this._lastTarget = null;
+		}
+
+		for (var i in L.Draggable.MOVE) {
+			L.DomEvent
+			    .off(document, L.Draggable.MOVE[i], this._onMove)
+			    .off(document, L.Draggable.END[i], this._onUp);
+		}
+
+		L.DomUtil.enableImageDrag();
+		L.DomUtil.enableTextSelection();
+
+		if (this._moved && this._moving) {
+			// ensure drag is not fired after dragend
+			L.Util.cancelAnimFrame(this._animRequest);
+
+			this.fire('dragend', {
+				distance: this._newPos.distanceTo(this._startPos)
+			});
+		}
+
+		this._moving = false;
+	}
+});
+
+
+/*
+	L.Handler is a base class for handler classes that are used internally to inject
+	interaction features like dragging to classes like Map and Marker.
+*/
+
+L.Handler = L.Class.extend({
+	initialize: function (map) {
+		this._map = map;
+	},
+
+	enable: function () {
+		if (this._enabled) { return; }
+
+		this._enabled = true;
+		this.addHooks();
+	},
+
+	disable: function () {
+		if (!this._enabled) { return; }
+
+		this._enabled = false;
+		this.removeHooks();
+	},
+
+	enabled: function () {
+		return !!this._enabled;
+	}
+});
+
+
+/*
+ * L.Handler.MapDrag is used to make the map draggable (with panning inertia), enabled by default.
+ */
+
+L.Map.mergeOptions({
+	dragging: true,
+
+	inertia: !L.Browser.android23,
+	inertiaDeceleration: 3400, // px/s^2
+	inertiaMaxSpeed: Infinity, // px/s
+	inertiaThreshold: L.Browser.touch ? 32 : 18, // ms
+	easeLinearity: 0.25,
+
+	// TODO refactor, move to CRS
+	worldCopyJump: false
+});
+
+L.Map.Drag = L.Handler.extend({
+	addHooks: function () {
+		if (!this._draggable) {
+			var map = this._map;
+
+			this._draggable = new L.Draggable(map._mapPane, map._container);
+
+			this._draggable.on({
+				'dragstart': this._onDragStart,
+				'drag': this._onDrag,
+				'dragend': this._onDragEnd
+			}, this);
+
+			if (map.options.worldCopyJump) {
+				this._draggable.on('predrag', this._onPreDrag, this);
+				map.on('viewreset', this._onViewReset, this);
+
+				map.whenReady(this._onViewReset, this);
+			}
+		}
+		this._draggable.enable();
+	},
+
+	removeHooks: function () {
+		this._draggable.disable();
+	},
+
+	moved: function () {
+		return this._draggable && this._draggable._moved;
+	},
+
+	_onDragStart: function () {
+		var map = this._map;
+
+		if (map._panAnim) {
+			map._panAnim.stop();
+		}
+
+		map
+		    .fire('movestart')
+		    .fire('dragstart');
+
+		if (map.options.inertia) {
+			this._positions = [];
+			this._times = [];
+		}
+	},
+
+	_onDrag: function () {
+		if (this._map.options.inertia) {
+			var time = this._lastTime = +new Date(),
+			    pos = this._lastPos = this._draggable._newPos;
+
+			this._positions.push(pos);
+			this._times.push(time);
+
+			if (time - this._times[0] > 200) {
+				this._positions.shift();
+				this._times.shift();
+			}
+		}
+
+		this._map
+		    .fire('move')
+		    .fire('drag');
+	},
+
+	_onViewReset: function () {
+		// TODO fix hardcoded Earth values
+		var pxCenter = this._map.getSize()._divideBy(2),
+		    pxWorldCenter = this._map.latLngToLayerPoint([0, 0]);
+
+		this._initialWorldOffset = pxWorldCenter.subtract(pxCenter).x;
+		this._worldWidth = this._map.project([0, 180]).x;
+	},
+
+	_onPreDrag: function () {
+		// TODO refactor to be able to adjust map pane position after zoom
+		var worldWidth = this._worldWidth,
+		    halfWidth = Math.round(worldWidth / 2),
+		    dx = this._initialWorldOffset,
+		    x = this._draggable._newPos.x,
+		    newX1 = (x - halfWidth + dx) % worldWidth + halfWidth - dx,
+		    newX2 = (x + halfWidth + dx) % worldWidth - halfWidth - dx,
+		    newX = Math.abs(newX1 + dx) < Math.abs(newX2 + dx) ? newX1 : newX2;
+
+		this._draggable._newPos.x = newX;
+	},
+
+	_onDragEnd: function (e) {
+		var map = this._map,
+		    options = map.options,
+		    delay = +new Date() - this._lastTime,
+
+		    noInertia = !options.inertia || delay > options.inertiaThreshold || !this._positions[0];
+
+		map.fire('dragend', e);
+
+		if (noInertia) {
+			map.fire('moveend');
+
+		} else {
+
+			var direction = this._lastPos.subtract(this._positions[0]),
+			    duration = (this._lastTime + delay - this._times[0]) / 1000,
+			    ease = options.easeLinearity,
+
+			    speedVector = direction.multiplyBy(ease / duration),
+			    speed = speedVector.distanceTo([0, 0]),
+
+			    limitedSpeed = Math.min(options.inertiaMaxSpeed, speed),
+			    limitedSpeedVector = speedVector.multiplyBy(limitedSpeed / speed),
+
+			    decelerationDuration = limitedSpeed / (options.inertiaDeceleration * ease),
+			    offset = limitedSpeedVector.multiplyBy(-decelerationDuration / 2).round();
+
+			if (!offset.x || !offset.y) {
+				map.fire('moveend');
+
+			} else {
+				offset = map._limitOffset(offset, map.options.maxBounds);
+
+				L.Util.requestAnimFrame(function () {
+					map.panBy(offset, {
+						duration: decelerationDuration,
+						easeLinearity: ease,
+						noMoveStart: true
+					});
+				});
+			}
+		}
+	}
+});
+
+L.Map.addInitHook('addHandler', 'dragging', L.Map.Drag);
+
+
+/*
+ * L.Handler.DoubleClickZoom is used to handle double-click zoom on the map, enabled by default.
+ */
+
+L.Map.mergeOptions({
+	doubleClickZoom: true
+});
+
+L.Map.DoubleClickZoom = L.Handler.extend({
+	addHooks: function () {
+		this._map.on('dblclick', this._onDoubleClick, this);
+	},
+
+	removeHooks: function () {
+		this._map.off('dblclick', this._onDoubleClick, this);
+	},
+
+	_onDoubleClick: function (e) {
+		var map = this._map,
+		    zoom = map.getZoom() + (e.originalEvent.shiftKey ? -1 : 1);
+
+		if (map.options.doubleClickZoom === 'center') {
+			map.setZoom(zoom);
+		} else {
+			map.setZoomAround(e.containerPoint, zoom);
+		}
+	}
+});
+
+L.Map.addInitHook('addHandler', 'doubleClickZoom', L.Map.DoubleClickZoom);
+
+
+/*
+ * L.Handler.ScrollWheelZoom is used by L.Map to enable mouse scroll wheel zoom on the map.
+ */
+
+L.Map.mergeOptions({
+	scrollWheelZoom: true
+});
+
+L.Map.ScrollWheelZoom = L.Handler.extend({
+	addHooks: function () {
+		L.DomEvent.on(this._map._container, 'mousewheel', this._onWheelScroll, this);
+		L.DomEvent.on(this._map._container, 'MozMousePixelScroll', L.DomEvent.preventDefault);
+		this._delta = 0;
+	},
+
+	removeHooks: function () {
+		L.DomEvent.off(this._map._container, 'mousewheel', this._onWheelScroll);
+		L.DomEvent.off(this._map._container, 'MozMousePixelScroll', L.DomEvent.preventDefault);
+	},
+
+	_onWheelScroll: function (e) {
+		var delta = L.DomEvent.getWheelDelta(e);
+
+		this._delta += delta;
+		this._lastMousePos = this._map.mouseEventToContainerPoint(e);
+
+		if (!this._startTime) {
+			this._startTime = +new Date();
+		}
+
+		var left = Math.max(40 - (+new Date() - this._startTime), 0);
+
+		clearTimeout(this._timer);
+		this._timer = setTimeout(L.bind(this._performZoom, this), left);
+
+		L.DomEvent.preventDefault(e);
+		L.DomEvent.stopPropagation(e);
+	},
+
+	_performZoom: function () {
+		var map = this._map,
+		    delta = this._delta,
+		    zoom = map.getZoom();
+
+		delta = delta > 0 ? Math.ceil(delta) : Math.floor(delta);
+		delta = Math.max(Math.min(delta, 4), -4);
+		delta = map._limitZoom(zoom + delta) - zoom;
+
+		this._delta = 0;
+		this._startTime = null;
+
+		if (!delta) { return; }
+
+		if (map.options.scrollWheelZoom === 'center') {
+			map.setZoom(zoom + delta);
+		} else {
+			map.setZoomAround(this._lastMousePos, zoom + delta);
+		}
+	}
+});
+
+L.Map.addInitHook('addHandler', 'scrollWheelZoom', L.Map.ScrollWheelZoom);
+
+
+/*
+ * Extends the event handling code with double tap support for mobile browsers.
+ */
+
+L.extend(L.DomEvent, {
+
+	_touchstart: L.Browser.msPointer ? 'MSPointerDown' : L.Browser.pointer ? 'pointerdown' : 'touchstart',
+	_touchend: L.Browser.msPointer ? 'MSPointerUp' : L.Browser.pointer ? 'pointerup' : 'touchend',
+
+	// inspired by Zepto touch code by Thomas Fuchs
+	addDoubleTapListener: function (obj, handler, id) {
+		var last,
+		    doubleTap = false,
+		    delay = 250,
+		    touch,
+		    pre = '_leaflet_',
+		    touchstart = this._touchstart,
+		    touchend = this._touchend,
+		    trackedTouches = [];
+
+		function onTouchStart(e) {
+			var count;
+
+			if (L.Browser.pointer) {
+				trackedTouches.push(e.pointerId);
+				count = trackedTouches.length;
+			} else {
+				count = e.touches.length;
+			}
+			if (count > 1) {
+				return;
+			}
+
+			var now = Date.now(),
+				delta = now - (last || now);
+
+			touch = e.touches ? e.touches[0] : e;
+			doubleTap = (delta > 0 && delta <= delay);
+			last = now;
+		}
+
+		function onTouchEnd(e) {
+			if (L.Browser.pointer) {
+				var idx = trackedTouches.indexOf(e.pointerId);
+				if (idx === -1) {
+					return;
+				}
+				trackedTouches.splice(idx, 1);
+			}
+
+			if (doubleTap) {
+				if (L.Browser.pointer) {
+					// work around .type being readonly with MSPointer* events
+					var newTouch = { },
+						prop;
+
+					// jshint forin:false
+					for (var i in touch) {
+						prop = touch[i];
+						if (typeof prop === 'function') {
+							newTouch[i] = prop.bind(touch);
+						} else {
+							newTouch[i] = prop;
+						}
+					}
+					touch = newTouch;
+				}
+				touch.type = 'dblclick';
+				handler(touch);
+				last = null;
+			}
+		}
+		obj[pre + touchstart + id] = onTouchStart;
+		obj[pre + touchend + id] = onTouchEnd;
+
+		// on pointer we need to listen on the document, otherwise a drag starting on the map and moving off screen
+		// will not come through to us, so we will lose track of how many touches are ongoing
+		var endElement = L.Browser.pointer ? document.documentElement : obj;
+
+		obj.addEventListener(touchstart, onTouchStart, false);
+		endElement.addEventListener(touchend, onTouchEnd, false);
+
+		if (L.Browser.pointer) {
+			endElement.addEventListener(L.DomEvent.POINTER_CANCEL, onTouchEnd, false);
+		}
+
+		return this;
+	},
+
+	removeDoubleTapListener: function (obj, id) {
+		var pre = '_leaflet_';
+
+		obj.removeEventListener(this._touchstart, obj[pre + this._touchstart + id], false);
+		(L.Browser.pointer ? document.documentElement : obj).removeEventListener(
+		        this._touchend, obj[pre + this._touchend + id], false);
+
+		if (L.Browser.pointer) {
+			document.documentElement.removeEventListener(L.DomEvent.POINTER_CANCEL, obj[pre + this._touchend + id],
+				false);
+		}
+
+		return this;
+	}
+});
+
+
+/*
+ * Extends L.DomEvent to provide touch support for Internet Explorer and Windows-based devices.
+ */
+
+L.extend(L.DomEvent, {
+
+	//static
+	POINTER_DOWN: L.Browser.msPointer ? 'MSPointerDown' : 'pointerdown',
+	POINTER_MOVE: L.Browser.msPointer ? 'MSPointerMove' : 'pointermove',
+	POINTER_UP: L.Browser.msPointer ? 'MSPointerUp' : 'pointerup',
+	POINTER_CANCEL: L.Browser.msPointer ? 'MSPointerCancel' : 'pointercancel',
+
+	_pointers: [],
+	_pointerDocumentListener: false,
+
+	// Provides a touch events wrapper for (ms)pointer events.
+	// Based on changes by veproza https://github.com/CloudMade/Leaflet/pull/1019
+	//ref http://www.w3.org/TR/pointerevents/ https://www.w3.org/Bugs/Public/show_bug.cgi?id=22890
+
+	addPointerListener: function (obj, type, handler, id) {
+
+		switch (type) {
+		case 'touchstart':
+			return this.addPointerListenerStart(obj, type, handler, id);
+		case 'touchend':
+			return this.addPointerListenerEnd(obj, type, handler, id);
+		case 'touchmove':
+			return this.addPointerListenerMove(obj, type, handler, id);
+		default:
+			throw 'Unknown touch event type';
+		}
+	},
+
+	addPointerListenerStart: function (obj, type, handler, id) {
+		var pre = '_leaflet_',
+		    pointers = this._pointers;
+
+		var cb = function (e) {
+			if (e.pointerType !== 'mouse' && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) {
+				L.DomEvent.preventDefault(e);
+			}
+
+			var alreadyInArray = false;
+			for (var i = 0; i < pointers.length; i++) {
+				if (pointers[i].pointerId === e.pointerId) {
+					alreadyInArray = true;
+					break;
+				}
+			}
+			if (!alreadyInArray) {
+				pointers.push(e);
+			}
+
+			e.touches = pointers.slice();
+			e.changedTouches = [e];
+
+			handler(e);
+		};
+
+		obj[pre + 'touchstart' + id] = cb;
+		obj.addEventListener(this.POINTER_DOWN, cb, false);
+
+		// need to also listen for end events to keep the _pointers list accurate
+		// this needs to be on the body and never go away
+		if (!this._pointerDocumentListener) {
+			var internalCb = function (e) {
+				for (var i = 0; i < pointers.length; i++) {
+					if (pointers[i].pointerId === e.pointerId) {
+						pointers.splice(i, 1);
+						break;
+					}
+				}
+			};
+			//We listen on the documentElement as any drags that end by moving the touch off the screen get fired there
+			document.documentElement.addEventListener(this.POINTER_UP, internalCb, false);
+			document.documentElement.addEventListener(this.POINTER_CANCEL, internalCb, false);
+
+			this._pointerDocumentListener = true;
+		}
+
+		return this;
+	},
+
+	addPointerListenerMove: function (obj, type, handler, id) {
+		var pre = '_leaflet_',
+		    touches = this._pointers;
+
+		function cb(e) {
+
+			// don't fire touch moves when mouse isn't down
+			if ((e.pointerType === e.MSPOINTER_TYPE_MOUSE || e.pointerType === 'mouse') && e.buttons === 0) { return; }
+
+			for (var i = 0; i < touches.length; i++) {
+				if (touches[i].pointerId === e.pointerId) {
+					touches[i] = e;
+					break;
+				}
+			}
+
+			e.touches = touches.slice();
+			e.changedTouches = [e];
+
+			handler(e);
+		}
+
+		obj[pre + 'touchmove' + id] = cb;
+		obj.addEventListener(this.POINTER_MOVE, cb, false);
+
+		return this;
+	},
+
+	addPointerListenerEnd: function (obj, type, handler, id) {
+		var pre = '_leaflet_',
+		    touches = this._pointers;
+
+		var cb = function (e) {
+			for (var i = 0; i < touches.length; i++) {
+				if (touches[i].pointerId === e.pointerId) {
+					touches.splice(i, 1);
+					break;
+				}
+			}
+
+			e.touches = touches.slice();
+			e.changedTouches = [e];
+
+			handler(e);
+		};
+
+		obj[pre + 'touchend' + id] = cb;
+		obj.addEventListener(this.POINTER_UP, cb, false);
+		obj.addEventListener(this.POINTER_CANCEL, cb, false);
+
+		return this;
+	},
+
+	removePointerListener: function (obj, type, id) {
+		var pre = '_leaflet_',
+		    cb = obj[pre + type + id];
+
+		switch (type) {
+		case 'touchstart':
+			obj.removeEventListener(this.POINTER_DOWN, cb, false);
+			break;
+		case 'touchmove':
+			obj.removeEventListener(this.POINTER_MOVE, cb, false);
+			break;
+		case 'touchend':
+			obj.removeEventListener(this.POINTER_UP, cb, false);
+			obj.removeEventListener(this.POINTER_CANCEL, cb, false);
+			break;
+		}
+
+		return this;
+	}
+});
+
+
+/*
+ * L.Handler.TouchZoom is used by L.Map to add pinch zoom on supported mobile browsers.
+ */
+
+L.Map.mergeOptions({
+	touchZoom: L.Browser.touch && !L.Browser.android23,
+	bounceAtZoomLimits: true
+});
+
+L.Map.TouchZoom = L.Handler.extend({
+	addHooks: function () {
+		L.DomEvent.on(this._map._container, 'touchstart', this._onTouchStart, this);
+	},
+
+	removeHooks: function () {
+		L.DomEvent.off(this._map._container, 'touchstart', this._onTouchStart, this);
+	},
+
+	_onTouchStart: function (e) {
+		var map = this._map;
+
+		if (!e.touches || e.touches.length !== 2 || map._animatingZoom || this._zooming) { return; }
+
+		var p1 = map.mouseEventToLayerPoint(e.touches[0]),
+		    p2 = map.mouseEventToLayerPoint(e.touches[1]),
+		    viewCenter = map._getCenterLayerPoint();
+
+		this._startCenter = p1.add(p2)._divideBy(2);
+		this._startDist = p1.distanceTo(p2);
+
+		this._moved = false;
+		this._zooming = true;
+
+		this._centerOffset = viewCenter.subtract(this._startCenter);
+
+		if (map._panAnim) {
+			map._panAnim.stop();
+		}
+
+		L.DomEvent
+		    .on(document, 'touchmove', this._onTouchMove, this)
+		    .on(document, 'touchend', this._onTouchEnd, this);
+
+		L.DomEvent.preventDefault(e);
+	},
+
+	_onTouchMove: function (e) {
+		var map = this._map;
+
+		if (!e.touches || e.touches.length !== 2 || !this._zooming) { return; }
+
+		var p1 = map.mouseEventToLayerPoint(e.touches[0]),
+		    p2 = map.mouseEventToLayerPoint(e.touches[1]);
+
+		this._scale = p1.distanceTo(p2) / this._startDist;
+		this._delta = p1._add(p2)._divideBy(2)._subtract(this._startCenter);
+
+		if (this._scale === 1) { return; }
+
+		if (!map.options.bounceAtZoomLimits) {
+			if ((map.getZoom() === map.getMinZoom() && this._scale < 1) ||
+			    (map.getZoom() === map.getMaxZoom() && this._scale > 1)) { return; }
+		}
+
+		if (!this._moved) {
+			L.DomUtil.addClass(map._mapPane, 'leaflet-touching');
+
+			map
+			    .fire('movestart')
+			    .fire('zoomstart');
+
+			this._moved = true;
+		}
+
+		L.Util.cancelAnimFrame(this._animRequest);
+		this._animRequest = L.Util.requestAnimFrame(
+		        this._updateOnMove, this, true, this._map._container);
+
+		L.DomEvent.preventDefault(e);
+	},
+
+	_updateOnMove: function () {
+		var map = this._map,
+		    origin = this._getScaleOrigin(),
+		    center = map.layerPointToLatLng(origin),
+		    zoom = map.getScaleZoom(this._scale);
+
+		map._animateZoom(center, zoom, this._startCenter, this._scale, this._delta, false, true);
+	},
+
+	_onTouchEnd: function () {
+		if (!this._moved || !this._zooming) {
+			this._zooming = false;
+			return;
+		}
+
+		var map = this._map;
+
+		this._zooming = false;
+		L.DomUtil.removeClass(map._mapPane, 'leaflet-touching');
+		L.Util.cancelAnimFrame(this._animRequest);
+
+		L.DomEvent
+		    .off(document, 'touchmove', this._onTouchMove)
+		    .off(document, 'touchend', this._onTouchEnd);
+
+		var origin = this._getScaleOrigin(),
+		    center = map.layerPointToLatLng(origin),
+
+		    oldZoom = map.getZoom(),
+		    floatZoomDelta = map.getScaleZoom(this._scale) - oldZoom,
+		    roundZoomDelta = (floatZoomDelta > 0 ?
+		            Math.ceil(floatZoomDelta) : Math.floor(floatZoomDelta)),
+
+		    zoom = map._limitZoom(oldZoom + roundZoomDelta),
+		    scale = map.getZoomScale(zoom) / this._scale;
+
+		map._animateZoom(center, zoom, origin, scale);
+	},
+
+	_getScaleOrigin: function () {
+		var centerOffset = this._centerOffset.subtract(this._delta).divideBy(this._scale);
+		return this._startCenter.add(centerOffset);
+	}
+});
+
+L.Map.addInitHook('addHandler', 'touchZoom', L.Map.TouchZoom);
+
+
+/*
+ * L.Map.Tap is used to enable mobile hacks like quick taps and long hold.
+ */
+
+L.Map.mergeOptions({
+	tap: true,
+	tapTolerance: 15
+});
+
+L.Map.Tap = L.Handler.extend({
+	addHooks: function () {
+		L.DomEvent.on(this._map._container, 'touchstart', this._onDown, this);
+	},
+
+	removeHooks: function () {
+		L.DomEvent.off(this._map._container, 'touchstart', this._onDown, this);
+	},
+
+	_onDown: function (e) {
+		if (!e.touches) { return; }
+
+		L.DomEvent.preventDefault(e);
+
+		this._fireClick = true;
+
+		// don't simulate click or track longpress if more than 1 touch
+		if (e.touches.length > 1) {
+			this._fireClick = false;
+			clearTimeout(this._holdTimeout);
+			return;
+		}
+
+		var first = e.touches[0],
+		    el = first.target;
+
+		this._startPos = this._newPos = new L.Point(first.clientX, first.clientY);
+
+		// if touching a link, highlight it
+		if (el.tagName && el.tagName.toLowerCase() === 'a') {
+			L.DomUtil.addClass(el, 'leaflet-active');
+		}
+
+		// simulate long hold but setting a timeout
+		this._holdTimeout = setTimeout(L.bind(function () {
+			if (this._isTapValid()) {
+				this._fireClick = false;
+				this._onUp();
+				this._simulateEvent('contextmenu', first);
+			}
+		}, this), 1000);
+
+		L.DomEvent
+			.on(document, 'touchmove', this._onMove, this)
+			.on(document, 'touchend', this._onUp, this);
+	},
+
+	_onUp: function (e) {
+		clearTimeout(this._holdTimeout);
+
+		L.DomEvent
+			.off(document, 'touchmove', this._onMove, this)
+			.off(document, 'touchend', this._onUp, this);
+
+		if (this._fireClick && e && e.changedTouches) {
+
+			var first = e.changedTouches[0],
+			    el = first.target;
+
+			if (el && el.tagName && el.tagName.toLowerCase() === 'a') {
+				L.DomUtil.removeClass(el, 'leaflet-active');
+			}
+
+			// simulate click if the touch didn't move too much
+			if (this._isTapValid()) {
+				this._simulateEvent('click', first);
+			}
+		}
+	},
+
+	_isTapValid: function () {
+		return this._newPos.distanceTo(this._startPos) <= this._map.options.tapTolerance;
+	},
+
+	_onMove: function (e) {
+		var first = e.touches[0];
+		this._newPos = new L.Point(first.clientX, first.clientY);
+	},
+
+	_simulateEvent: function (type, e) {
+		var simulatedEvent = document.createEvent('MouseEvents');
+
+		simulatedEvent._simulated = true;
+		e.target._simulatedClick = true;
+
+		simulatedEvent.initMouseEvent(
+		        type, true, true, window, 1,
+		        e.screenX, e.screenY,
+		        e.clientX, e.clientY,
+		        false, false, false, false, 0, null);
+
+		e.target.dispatchEvent(simulatedEvent);
+	}
+});
+
+if (L.Browser.touch && !L.Browser.pointer) {
+	L.Map.addInitHook('addHandler', 'tap', L.Map.Tap);
+}
+
+
+/*
+ * L.Handler.ShiftDragZoom is used to add shift-drag zoom interaction to the map
+  * (zoom to a selected bounding box), enabled by default.
+ */
+
+L.Map.mergeOptions({
+	boxZoom: true
+});
+
+L.Map.BoxZoom = L.Handler.extend({
+	initialize: function (map) {
+		this._map = map;
+		this._container = map._container;
+		this._pane = map._panes.overlayPane;
+		this._moved = false;
+	},
+
+	addHooks: function () {
+		L.DomEvent.on(this._container, 'mousedown', this._onMouseDown, this);
+	},
+
+	removeHooks: function () {
+		L.DomEvent.off(this._container, 'mousedown', this._onMouseDown);
+		this._moved = false;
+	},
+
+	moved: function () {
+		return this._moved;
+	},
+
+	_onMouseDown: function (e) {
+		this._moved = false;
+
+		if (!e.shiftKey || ((e.which !== 1) && (e.button !== 1))) { return false; }
+
+		L.DomUtil.disableTextSelection();
+		L.DomUtil.disableImageDrag();
+
+		this._startLayerPoint = this._map.mouseEventToLayerPoint(e);
+
+		L.DomEvent
+		    .on(document, 'mousemove', this._onMouseMove, this)
+		    .on(document, 'mouseup', this._onMouseUp, this)
+		    .on(document, 'keydown', this._onKeyDown, this);
+	},
+
+	_onMouseMove: function (e) {
+		if (!this._moved) {
+			this._box = L.DomUtil.create('div', 'leaflet-zoom-box', this._pane);
+			L.DomUtil.setPosition(this._box, this._startLayerPoint);
+
+			//TODO refactor: move cursor to styles
+			this._container.style.cursor = 'crosshair';
+			this._map.fire('boxzoomstart');
+		}
+
+		var startPoint = this._startLayerPoint,
+		    box = this._box,
+
+		    layerPoint = this._map.mouseEventToLayerPoint(e),
+		    offset = layerPoint.subtract(startPoint),
+
+		    newPos = new L.Point(
+		        Math.min(layerPoint.x, startPoint.x),
+		        Math.min(layerPoint.y, startPoint.y));
+
+		L.DomUtil.setPosition(box, newPos);
+
+		this._moved = true;
+
+		// TODO refactor: remove hardcoded 4 pixels
+		box.style.width  = (Math.max(0, Math.abs(offset.x) - 4)) + 'px';
+		box.style.height = (Math.max(0, Math.abs(offset.y) - 4)) + 'px';
+	},
+
+	_finish: function () {
+		if (this._moved) {
+			this._pane.removeChild(this._box);
+			this._container.style.cursor = '';
+		}
+
+		L.DomUtil.enableTextSelection();
+		L.DomUtil.enableImageDrag();
+
+		L.DomEvent
+		    .off(document, 'mousemove', this._onMouseMove)
+		    .off(document, 'mouseup', this._onMouseUp)
+		    .off(document, 'keydown', this._onKeyDown);
+	},
+
+	_onMouseUp: function (e) {
+
+		this._finish();
+
+		var map = this._map,
+		    layerPoint = map.mouseEventToLayerPoint(e);
+
+		if (this._startLayerPoint.equals(layerPoint)) { return; }
+
+		var bounds = new L.LatLngBounds(
+		        map.layerPointToLatLng(this._startLayerPoint),
+		        map.layerPointToLatLng(layerPoint));
+
+		map.fitBounds(bounds);
+
+		map.fire('boxzoomend', {
+			boxZoomBounds: bounds
+		});
+	},
+
+	_onKeyDown: function (e) {
+		if (e.keyCode === 27) {
+			this._finish();
+		}
+	}
+});
+
+L.Map.addInitHook('addHandler', 'boxZoom', L.Map.BoxZoom);
+
+
+/*
+ * L.Map.Keyboard is handling keyboard interaction with the map, enabled by default.
+ */
+
+L.Map.mergeOptions({
+	keyboard: true,
+	keyboardPanOffset: 80,
+	keyboardZoomOffset: 1
+});
+
+L.Map.Keyboard = L.Handler.extend({
+
+	keyCodes: {
+		left:    [37],
+		right:   [39],
+		down:    [40],
+		up:      [38],
+		zoomIn:  [187, 107, 61, 171],
+		zoomOut: [189, 109, 173]
+	},
+
+	initialize: function (map) {
+		this._map = map;
+
+		this._setPanOffset(map.options.keyboardPanOffset);
+		this._setZoomOffset(map.options.keyboardZoomOffset);
+	},
+
+	addHooks: function () {
+		var container = this._map._container;
+
+		// make the container focusable by tabbing
+		if (container.tabIndex === -1) {
+			container.tabIndex = '0';
+		}
+
+		L.DomEvent
+		    .on(container, 'focus', this._onFocus, this)
+		    .on(container, 'blur', this._onBlur, this)
+		    .on(container, 'mousedown', this._onMouseDown, this);
+
+		this._map
+		    .on('focus', this._addHooks, this)
+		    .on('blur', this._removeHooks, this);
+	},
+
+	removeHooks: function () {
+		this._removeHooks();
+
+		var container = this._map._container;
+
+		L.DomEvent
+		    .off(container, 'focus', this._onFocus, this)
+		    .off(container, 'blur', this._onBlur, this)
+		    .off(container, 'mousedown', this._onMouseDown, this);
+
+		this._map
+		    .off('focus', this._addHooks, this)
+		    .off('blur', this._removeHooks, this);
+	},
+
+	_onMouseDown: function () {
+		if (this._focused) { return; }
+
+		var body = document.body,
+		    docEl = document.documentElement,
+		    top = body.scrollTop || docEl.scrollTop,
+		    left = body.scrollLeft || docEl.scrollLeft;
+
+		this._map._container.focus();
+
+		window.scrollTo(left, top);
+	},
+
+	_onFocus: function () {
+		this._focused = true;
+		this._map.fire('focus');
+	},
+
+	_onBlur: function () {
+		this._focused = false;
+		this._map.fire('blur');
+	},
+
+	_setPanOffset: function (pan) {
+		var keys = this._panKeys = {},
+		    codes = this.keyCodes,
+		    i, len;
+
+		for (i = 0, len = codes.left.length; i < len; i++) {
+			keys[codes.left[i]] = [-1 * pan, 0];
+		}
+		for (i = 0, len = codes.right.length; i < len; i++) {
+			keys[codes.right[i]] = [pan, 0];
+		}
+		for (i = 0, len = codes.down.length; i < len; i++) {
+			keys[codes.down[i]] = [0, pan];
+		}
+		for (i = 0, len = codes.up.length; i < len; i++) {
+			keys[codes.up[i]] = [0, -1 * pan];
+		}
+	},
+
+	_setZoomOffset: function (zoom) {
+		var keys = this._zoomKeys = {},
+		    codes = this.keyCodes,
+		    i, len;
+
+		for (i = 0, len = codes.zoomIn.length; i < len; i++) {
+			keys[codes.zoomIn[i]] = zoom;
+		}
+		for (i = 0, len = codes.zoomOut.length; i < len; i++) {
+			keys[codes.zoomOut[i]] = -zoom;
+		}
+	},
+
+	_addHooks: function () {
+		L.DomEvent.on(document, 'keydown', this._onKeyDown, this);
+	},
+
+	_removeHooks: function () {
+		L.DomEvent.off(document, 'keydown', this._onKeyDown, this);
+	},
+
+	_onKeyDown: function (e) {
+		var key = e.keyCode,
+		    map = this._map;
+
+		if (key in this._panKeys) {
+
+			if (map._panAnim && map._panAnim._inProgress) { return; }
+
+			map.panBy(this._panKeys[key]);
+
+			if (map.options.maxBounds) {
+				map.panInsideBounds(map.options.maxBounds);
+			}
+
+		} else if (key in this._zoomKeys) {
+			map.setZoom(map.getZoom() + this._zoomKeys[key]);
+
+		} else {
+			return;
+		}
+
+		L.DomEvent.stop(e);
+	}
+});
+
+L.Map.addInitHook('addHandler', 'keyboard', L.Map.Keyboard);
+
+
+/*
+ * L.Handler.MarkerDrag is used internally by L.Marker to make the markers draggable.
+ */
+
+L.Handler.MarkerDrag = L.Handler.extend({
+	initialize: function (marker) {
+		this._marker = marker;
+	},
+
+	addHooks: function () {
+		var icon = this._marker._icon;
+		if (!this._draggable) {
+			this._draggable = new L.Draggable(icon, icon);
+		}
+
+		this._draggable
+			.on('dragstart', this._onDragStart, this)
+			.on('drag', this._onDrag, this)
+			.on('dragend', this._onDragEnd, this);
+		this._draggable.enable();
+		L.DomUtil.addClass(this._marker._icon, 'leaflet-marker-draggable');
+	},
+
+	removeHooks: function () {
+		this._draggable
+			.off('dragstart', this._onDragStart, this)
+			.off('drag', this._onDrag, this)
+			.off('dragend', this._onDragEnd, this);
+
+		this._draggable.disable();
+		L.DomUtil.removeClass(this._marker._icon, 'leaflet-marker-draggable');
+	},
+
+	moved: function () {
+		return this._draggable && this._draggable._moved;
+	},
+
+	_onDragStart: function () {
+		this._marker
+		    .closePopup()
+		    .fire('movestart')
+		    .fire('dragstart');
+	},
+
+	_onDrag: function () {
+		var marker = this._marker,
+		    shadow = marker._shadow,
+		    iconPos = L.DomUtil.getPosition(marker._icon),
+		    latlng = marker._map.layerPointToLatLng(iconPos);
+
+		// update shadow position
+		if (shadow) {
+			L.DomUtil.setPosition(shadow, iconPos);
+		}
+
+		marker._latlng = latlng;
+
+		marker
+		    .fire('move', {latlng: latlng})
+		    .fire('drag');
+	},
+
+	_onDragEnd: function (e) {
+		this._marker
+		    .fire('moveend')
+		    .fire('dragend', e);
+	}
+});
+
+
+/*
+ * L.Control is a base class for implementing map controls. Handles positioning.
+ * All other controls extend from this class.
+ */
+
+L.Control = L.Class.extend({
+	options: {
+		position: 'topright'
+	},
+
+	initialize: function (options) {
+		L.setOptions(this, options);
+	},
+
+	getPosition: function () {
+		return this.options.position;
+	},
+
+	setPosition: function (position) {
+		var map = this._map;
+
+		if (map) {
+			map.removeControl(this);
+		}
+
+		this.options.position = position;
+
+		if (map) {
+			map.addControl(this);
+		}
+
+		return this;
+	},
+
+	getContainer: function () {
+		return this._container;
+	},
+
+	addTo: function (map) {
+		this._map = map;
+
+		var container = this._container = this.onAdd(map),
+		    pos = this.getPosition(),
+		    corner = map._controlCorners[pos];
+
+		L.DomUtil.addClass(container, 'leaflet-control');
+
+		if (pos.indexOf('bottom') !== -1) {
+			corner.insertBefore(container, corner.firstChild);
+		} else {
+			corner.appendChild(container);
+		}
+
+		return this;
+	},
+
+	removeFrom: function (map) {
+		var pos = this.getPosition(),
+		    corner = map._controlCorners[pos];
+
+		corner.removeChild(this._container);
+		this._map = null;
+
+		if (this.onRemove) {
+			this.onRemove(map);
+		}
+
+		return this;
+	},
+
+	_refocusOnMap: function () {
+		if (this._map) {
+			this._map.getContainer().focus();
+		}
+	}
+});
+
+L.control = function (options) {
+	return new L.Control(options);
+};
+
+
+// adds control-related methods to L.Map
+
+L.Map.include({
+	addControl: function (control) {
+		control.addTo(this);
+		return this;
+	},
+
+	removeControl: function (control) {
+		control.removeFrom(this);
+		return this;
+	},
+
+	_initControlPos: function () {
+		var corners = this._controlCorners = {},
+		    l = 'leaflet-',
+		    container = this._controlContainer =
+		            L.DomUtil.create('div', l + 'control-container', this._container);
+
+		function createCorner(vSide, hSide) {
+			var className = l + vSide + ' ' + l + hSide;
+
+			corners[vSide + hSide] = L.DomUtil.create('div', className, container);
+		}
+
+		createCorner('top', 'left');
+		createCorner('top', 'right');
+		createCorner('bottom', 'left');
+		createCorner('bottom', 'right');
+	},
+
+	_clearControlPos: function () {
+		this._container.removeChild(this._controlContainer);
+	}
+});
+
+
+/*
+ * L.Control.Zoom is used for the default zoom buttons on the map.
+ */
+
+L.Control.Zoom = L.Control.extend({
+	options: {
+		position: 'topleft',
+		zoomInText: '+',
+		zoomInTitle: 'Zoom in',
+		zoomOutText: '-',
+		zoomOutTitle: 'Zoom out'
+	},
+
+	onAdd: function (map) {
+		var zoomName = 'leaflet-control-zoom',
+		    container = L.DomUtil.create('div', zoomName + ' leaflet-bar');
+
+		this._map = map;
+
+		this._zoomInButton  = this._createButton(
+		        this.options.zoomInText, this.options.zoomInTitle,
+		        zoomName + '-in',  container, this._zoomIn,  this);
+		this._zoomOutButton = this._createButton(
+		        this.options.zoomOutText, this.options.zoomOutTitle,
+		        zoomName + '-out', container, this._zoomOut, this);
+
+		this._updateDisabled();
+		map.on('zoomend zoomlevelschange', this._updateDisabled, this);
+
+		return container;
+	},
+
+	onRemove: function (map) {
+		map.off('zoomend zoomlevelschange', this._updateDisabled, this);
+	},
+
+	_zoomIn: function (e) {
+		this._map.zoomIn(e.shiftKey ? 3 : 1);
+	},
+
+	_zoomOut: function (e) {
+		this._map.zoomOut(e.shiftKey ? 3 : 1);
+	},
+
+	_createButton: function (html, title, className, container, fn, context) {
+		var link = L.DomUtil.create('a', className, container);
+		link.innerHTML = html;
+		link.href = '#';
+		link.title = title;
+
+		var stop = L.DomEvent.stopPropagation;
+
+		L.DomEvent
+		    .on(link, 'click', stop)
+		    .on(link, 'mousedown', stop)
+		    .on(link, 'dblclick', stop)
+		    .on(link, 'click', L.DomEvent.preventDefault)
+		    .on(link, 'click', fn, context)
+		    .on(link, 'click', this._refocusOnMap, context);
+
+		return link;
+	},
+
+	_updateDisabled: function () {
+		var map = this._map,
+			className = 'leaflet-disabled';
+
+		L.DomUtil.removeClass(this._zoomInButton, className);
+		L.DomUtil.removeClass(this._zoomOutButton, className);
+
+		if (map._zoom === map.getMinZoom()) {
+			L.DomUtil.addClass(this._zoomOutButton, className);
+		}
+		if (map._zoom === map.getMaxZoom()) {
+			L.DomUtil.addClass(this._zoomInButton, className);
+		}
+	}
+});
+
+L.Map.mergeOptions({
+	zoomControl: true
+});
+
+L.Map.addInitHook(function () {
+	if (this.options.zoomControl) {
+		this.zoomControl = new L.Control.Zoom();
+		this.addControl(this.zoomControl);
+	}
+});
+
+L.control.zoom = function (options) {
+	return new L.Control.Zoom(options);
+};
+
+
+
+/*
+ * L.Control.Attribution is used for displaying attribution on the map (added by default).
+ */
+
+L.Control.Attribution = L.Control.extend({
+	options: {
+		position: 'bottomright',
+		prefix: '<a href="http://leafletjs.com" title="A JS library for interactive maps">Leaflet</a>'
+	},
+
+	initialize: function (options) {
+		L.setOptions(this, options);
+
+		this._attributions = {};
+	},
+
+	onAdd: function (map) {
+		this._container = L.DomUtil.create('div', 'leaflet-control-attribution');
+		L.DomEvent.disableClickPropagation(this._container);
+
+		for (var i in map._layers) {
+			if (map._layers[i].getAttribution) {
+				this.addAttribution(map._layers[i].getAttribution());
+			}
+		}
+		
+		map
+		    .on('layeradd', this._onLayerAdd, this)
+		    .on('layerremove', this._onLayerRemove, this);
+
+		this._update();
+
+		return this._container;
+	},
+
+	onRemove: function (map) {
+		map
+		    .off('layeradd', this._onLayerAdd)
+		    .off('layerremove', this._onLayerRemove);
+
+	},
+
+	setPrefix: function (prefix) {
+		this.options.prefix = prefix;
+		this._update();
+		return this;
+	},
+
+	addAttribution: function (text) {
+		if (!text) { return; }
+
+		if (!this._attributions[text]) {
+			this._attributions[text] = 0;
+		}
+		this._attributions[text]++;
+
+		this._update();
+
+		return this;
+	},
+
+	removeAttribution: function (text) {
+		if (!text) { return; }
+
+		if (this._attributions[text]) {
+			this._attributions[text]--;
+			this._update();
+		}
+
+		return this;
+	},
+
+	_update: function () {
+		if (!this._map) { return; }
+
+		var attribs = [];
+
+		for (var i in this._attributions) {
+			if (this._attributions[i]) {
+				attribs.push(i);
+			}
+		}
+
+		var prefixAndAttribs = [];
+
+		if (this.options.prefix) {
+			prefixAndAttribs.push(this.options.prefix);
+		}
+		if (attribs.length) {
+			prefixAndAttribs.push(attribs.join(', '));
+		}
+
+		this._container.innerHTML = prefixAndAttribs.join(' | ');
+	},
+
+	_onLayerAdd: function (e) {
+		if (e.layer.getAttribution) {
+			this.addAttribution(e.layer.getAttribution());
+		}
+	},
+
+	_onLayerRemove: function (e) {
+		if (e.layer.getAttribution) {
+			this.removeAttribution(e.layer.getAttribution());
+		}
+	}
+});
+
+L.Map.mergeOptions({
+	attributionControl: true
+});
+
+L.Map.addInitHook(function () {
+	if (this.options.attributionControl) {
+		this.attributionControl = (new L.Control.Attribution()).addTo(this);
+	}
+});
+
+L.control.attribution = function (options) {
+	return new L.Control.Attribution(options);
+};
+
+
+/*
+ * L.Control.Scale is used for displaying metric/imperial scale on the map.
+ */
+
+L.Control.Scale = L.Control.extend({
+	options: {
+		position: 'bottomleft',
+		maxWidth: 100,
+		metric: true,
+		imperial: true,
+		updateWhenIdle: false
+	},
+
+	onAdd: function (map) {
+		this._map = map;
+
+		var className = 'leaflet-control-scale',
+		    container = L.DomUtil.create('div', className),
+		    options = this.options;
+
+		this._addScales(options, className, container);
+
+		map.on(options.updateWhenIdle ? 'moveend' : 'move', this._update, this);
+		map.whenReady(this._update, this);
+
+		return container;
+	},
+
+	onRemove: function (map) {
+		map.off(this.options.updateWhenIdle ? 'moveend' : 'move', this._update, this);
+	},
+
+	_addScales: function (options, className, container) {
+		if (options.metric) {
+			this._mScale = L.DomUtil.create('div', className + '-line', container);
+		}
+		if (options.imperial) {
+			this._iScale = L.DomUtil.create('div', className + '-line', container);
+		}
+	},
+
+	_update: function () {
+		var bounds = this._map.getBounds(),
+		    centerLat = bounds.getCenter().lat,
+		    halfWorldMeters = 6378137 * Math.PI * Math.cos(centerLat * Math.PI / 180),
+		    dist = halfWorldMeters * (bounds.getNorthEast().lng - bounds.getSouthWest().lng) / 180,
+
+		    size = this._map.getSize(),
+		    options = this.options,
+		    maxMeters = 0;
+
+		if (size.x > 0) {
+			maxMeters = dist * (options.maxWidth / size.x);
+		}
+
+		this._updateScales(options, maxMeters);
+	},
+
+	_updateScales: function (options, maxMeters) {
+		if (options.metric && maxMeters) {
+			this._updateMetric(maxMeters);
+		}
+
+		if (options.imperial && maxMeters) {
+			this._updateImperial(maxMeters);
+		}
+	},
+
+	_updateMetric: function (maxMeters) {
+		var meters = this._getRoundNum(maxMeters);
+
+		this._mScale.style.width = this._getScaleWidth(meters / maxMeters) + 'px';
+		this._mScale.innerHTML = meters < 1000 ? meters + ' m' : (meters / 1000) + ' km';
+	},
+
+	_updateImperial: function (maxMeters) {
+		var maxFeet = maxMeters * 3.2808399,
+		    scale = this._iScale,
+		    maxMiles, miles, feet;
+
+		if (maxFeet > 5280) {
+			maxMiles = maxFeet / 5280;
+			miles = this._getRoundNum(maxMiles);
+
+			scale.style.width = this._getScaleWidth(miles / maxMiles) + 'px';
+			scale.innerHTML = miles + ' mi';
+
+		} else {
+			feet = this._getRoundNum(maxFeet);
+
+			scale.style.width = this._getScaleWidth(feet / maxFeet) + 'px';
+			scale.innerHTML = feet + ' ft';
+		}
+	},
+
+	_getScaleWidth: function (ratio) {
+		return Math.round(this.options.maxWidth * ratio) - 10;
+	},
+
+	_getRoundNum: function (num) {
+		var pow10 = Math.pow(10, (Math.floor(num) + '').length - 1),
+		    d = num / pow10;
+
+		d = d >= 10 ? 10 : d >= 5 ? 5 : d >= 3 ? 3 : d >= 2 ? 2 : 1;
+
+		return pow10 * d;
+	}
+});
+
+L.control.scale = function (options) {
+	return new L.Control.Scale(options);
+};
+
+
+/*
+ * L.Control.Layers is a control to allow users to switch between different layers on the map.
+ */
+
+L.Control.Layers = L.Control.extend({
+	options: {
+		collapsed: true,
+		position: 'topright',
+		autoZIndex: true
+	},
+
+	initialize: function (baseLayers, overlays, options) {
+		L.setOptions(this, options);
+
+		this._layers = {};
+		this._lastZIndex = 0;
+		this._handlingClick = false;
+
+		for (var i in baseLayers) {
+			this._addLayer(baseLayers[i], i);
+		}
+
+		for (i in overlays) {
+			this._addLayer(overlays[i], i, true);
+		}
+	},
+
+	onAdd: function (map) {
+		this._initLayout();
+		this._update();
+
+		map
+		    .on('layeradd', this._onLayerChange, this)
+		    .on('layerremove', this._onLayerChange, this);
+
+		return this._container;
+	},
+
+	onRemove: function (map) {
+		map
+		    .off('layeradd', this._onLayerChange, this)
+		    .off('layerremove', this._onLayerChange, this);
+	},
+
+	addBaseLayer: function (layer, name) {
+		this._addLayer(layer, name);
+		this._update();
+		return this;
+	},
+
+	addOverlay: function (layer, name) {
+		this._addLayer(layer, name, true);
+		this._update();
+		return this;
+	},
+
+	removeLayer: function (layer) {
+		var id = L.stamp(layer);
+		delete this._layers[id];
+		this._update();
+		return this;
+	},
+
+	_initLayout: function () {
+		var className = 'leaflet-control-layers',
+		    container = this._container = L.DomUtil.create('div', className);
+
+		//Makes this work on IE10 Touch devices by stopping it from firing a mouseout event when the touch is released
+		container.setAttribute('aria-haspopup', true);
+
+		if (!L.Browser.touch) {
+			L.DomEvent
+				.disableClickPropagation(container)
+				.disableScrollPropagation(container);
+		} else {
+			L.DomEvent.on(container, 'click', L.DomEvent.stopPropagation);
+		}
+
+		var form = this._form = L.DomUtil.create('form', className + '-list');
+
+		if (this.options.collapsed) {
+			if (!L.Browser.android) {
+				L.DomEvent
+				    .on(container, 'mouseover', this._expand, this)
+				    .on(container, 'mouseout', this._collapse, this);
+			}
+			var link = this._layersLink = L.DomUtil.create('a', className + '-toggle', container);
+			link.href = '#';
+			link.title = 'Layers';
+
+			if (L.Browser.touch) {
+				L.DomEvent
+				    .on(link, 'click', L.DomEvent.stop)
+				    .on(link, 'click', this._expand, this);
+			}
+			else {
+				L.DomEvent.on(link, 'focus', this._expand, this);
+			}
+			//Work around for Firefox android issue https://github.com/Leaflet/Leaflet/issues/2033
+			L.DomEvent.on(form, 'click', function () {
+				setTimeout(L.bind(this._onInputClick, this), 0);
+			}, this);
+
+			this._map.on('click', this._collapse, this);
+			// TODO keyboard accessibility
+		} else {
+			this._expand();
+		}
+
+		this._baseLayersList = L.DomUtil.create('div', className + '-base', form);
+		this._separator = L.DomUtil.create('div', className + '-separator', form);
+		this._overlaysList = L.DomUtil.create('div', className + '-overlays', form);
+
+		container.appendChild(form);
+	},
+
+	_addLayer: function (layer, name, overlay) {
+		var id = L.stamp(layer);
+
+		this._layers[id] = {
+			layer: layer,
+			name: name,
+			overlay: overlay
+		};
+
+		if (this.options.autoZIndex && layer.setZIndex) {
+			this._lastZIndex++;
+			layer.setZIndex(this._lastZIndex);
+		}
+	},
+
+	_update: function () {
+		if (!this._container) {
+			return;
+		}
+
+		this._baseLayersList.innerHTML = '';
+		this._overlaysList.innerHTML = '';
+
+		var baseLayersPresent = false,
+		    overlaysPresent = false,
+		    i, obj;
+
+		for (i in this._layers) {
+			obj = this._layers[i];
+			this._addItem(obj);
+			overlaysPresent = overlaysPresent || obj.overlay;
+			baseLayersPresent = baseLayersPresent || !obj.overlay;
+		}
+
+		this._separator.style.display = overlaysPresent && baseLayersPresent ? '' : 'none';
+	},
+
+	_onLayerChange: function (e) {
+		var obj = this._layers[L.stamp(e.layer)];
+
+		if (!obj) { return; }
+
+		if (!this._handlingClick) {
+			this._update();
+		}
+
+		var type = obj.overlay ?
+			(e.type === 'layeradd' ? 'overlayadd' : 'overlayremove') :
+			(e.type === 'layeradd' ? 'baselayerchange' : null);
+
+		if (type) {
+			this._map.fire(type, obj);
+		}
+	},
+
+	// IE7 bugs out if you create a radio dynamically, so you have to do it this hacky way (see http://bit.ly/PqYLBe)
+	_createRadioElement: function (name, checked) {
+
+		var radioHtml = '<input type="radio" class="leaflet-control-layers-selector" name="' + name + '"';
+		if (checked) {
+			radioHtml += ' checked="checked"';
+		}
+		radioHtml += '/>';
+
+		var radioFragment = document.createElement('div');
+		radioFragment.innerHTML = radioHtml;
+
+		return radioFragment.firstChild;
+	},
+
+	_addItem: function (obj) {
+		var label = document.createElement('label'),
+		    input,
+		    checked = this._map.hasLayer(obj.layer);
+
+		if (obj.overlay) {
+			input = document.createElement('input');
+			input.type = 'checkbox';
+			input.className = 'leaflet-control-layers-selector';
+			input.defaultChecked = checked;
+		} else {
+			input = this._createRadioElement('leaflet-base-layers', checked);
+		}
+
+		input.layerId = L.stamp(obj.layer);
+
+		L.DomEvent.on(input, 'click', this._onInputClick, this);
+
+		var name = document.createElement('span');
+		name.innerHTML = ' ' + obj.name;
+
+		label.appendChild(input);
+		label.appendChild(name);
+
+		var container = obj.overlay ? this._overlaysList : this._baseLayersList;
+		container.appendChild(label);
+
+		return label;
+	},
+
+	_onInputClick: function () {
+		var i, input, obj,
+		    inputs = this._form.getElementsByTagName('input'),
+		    inputsLen = inputs.length;
+
+		this._handlingClick = true;
+
+		for (i = 0; i < inputsLen; i++) {
+			input = inputs[i];
+			obj = this._layers[input.layerId];
+
+			if (input.checked && !this._map.hasLayer(obj.layer)) {
+				this._map.addLayer(obj.layer);
+
+			} else if (!input.checked && this._map.hasLayer(obj.layer)) {
+				this._map.removeLayer(obj.layer);
+			}
+		}
+
+		this._handlingClick = false;
+
+		this._refocusOnMap();
+	},
+
+	_expand: function () {
+		L.DomUtil.addClass(this._container, 'leaflet-control-layers-expanded');
+	},
+
+	_collapse: function () {
+		this._container.className = this._container.className.replace(' leaflet-control-layers-expanded', '');
+	}
+});
+
+L.control.layers = function (baseLayers, overlays, options) {
+	return new L.Control.Layers(baseLayers, overlays, options);
+};
+
+
+/*
+ * L.PosAnimation is used by Leaflet internally for pan animations.
+ */
+
+L.PosAnimation = L.Class.extend({
+	includes: L.Mixin.Events,
+
+	run: function (el, newPos, duration, easeLinearity) { // (HTMLElement, Point[, Number, Number])
+		this.stop();
+
+		this._el = el;
+		this._inProgress = true;
+		this._newPos = newPos;
+
+		this.fire('start');
+
+		el.style[L.DomUtil.TRANSITION] = 'all ' + (duration || 0.25) +
+		        's cubic-bezier(0,0,' + (easeLinearity || 0.5) + ',1)';
+
+		L.DomEvent.on(el, L.DomUtil.TRANSITION_END, this._onTransitionEnd, this);
+		L.DomUtil.setPosition(el, newPos);
+
+		// toggle reflow, Chrome flickers for some reason if you don't do this
+		L.Util.falseFn(el.offsetWidth);
+
+		// there's no native way to track value updates of transitioned properties, so we imitate this
+		this._stepTimer = setInterval(L.bind(this._onStep, this), 50);
+	},
+
+	stop: function () {
+		if (!this._inProgress) { return; }
+
+		// if we just removed the transition property, the element would jump to its final position,
+		// so we need to make it stay at the current position
+
+		L.DomUtil.setPosition(this._el, this._getPos());
+		this._onTransitionEnd();
+		L.Util.falseFn(this._el.offsetWidth); // force reflow in case we are about to start a new animation
+	},
+
+	_onStep: function () {
+		var stepPos = this._getPos();
+		if (!stepPos) {
+			this._onTransitionEnd();
+			return;
+		}
+		// jshint camelcase: false
+		// make L.DomUtil.getPosition return intermediate position value during animation
+		this._el._leaflet_pos = stepPos;
+
+		this.fire('step');
+	},
+
+	// you can't easily get intermediate values of properties animated with CSS3 Transitions,
+	// we need to parse computed style (in case of transform it returns matrix string)
+
+	_transformRe: /([-+]?(?:\d*\.)?\d+)\D*, ([-+]?(?:\d*\.)?\d+)\D*\)/,
+
+	_getPos: function () {
+		var left, top, matches,
+		    el = this._el,
+		    style = window.getComputedStyle(el);
+
+		if (L.Browser.any3d) {
+			matches = style[L.DomUtil.TRANSFORM].match(this._transformRe);
+			if (!matches) { return; }
+			left = parseFloat(matches[1]);
+			top  = parseFloat(matches[2]);
+		} else {
+			left = parseFloat(style.left);
+			top  = parseFloat(style.top);
+		}
+
+		return new L.Point(left, top, true);
+	},
+
+	_onTransitionEnd: function () {
+		L.DomEvent.off(this._el, L.DomUtil.TRANSITION_END, this._onTransitionEnd, this);
+
+		if (!this._inProgress) { return; }
+		this._inProgress = false;
+
+		this._el.style[L.DomUtil.TRANSITION] = '';
+
+		// jshint camelcase: false
+		// make sure L.DomUtil.getPosition returns the final position value after animation
+		this._el._leaflet_pos = this._newPos;
+
+		clearInterval(this._stepTimer);
+
+		this.fire('step').fire('end');
+	}
+
+});
+
+
+/*
+ * Extends L.Map to handle panning animations.
+ */
+
+L.Map.include({
+
+	setView: function (center, zoom, options) {
+
+		zoom = zoom === undefined ? this._zoom : this._limitZoom(zoom);
+		center = this._limitCenter(L.latLng(center), zoom, this.options.maxBounds);
+		options = options || {};
+
+		if (this._panAnim) {
+			this._panAnim.stop();
+		}
+
+		if (this._loaded && !options.reset && options !== true) {
+
+			if (options.animate !== undefined) {
+				options.zoom = L.extend({animate: options.animate}, options.zoom);
+				options.pan = L.extend({animate: options.animate}, options.pan);
+			}
+
+			// try animating pan or zoom
+			var animated = (this._zoom !== zoom) ?
+				this._tryAnimatedZoom && this._tryAnimatedZoom(center, zoom, options.zoom) :
+				this._tryAnimatedPan(center, options.pan);
+
+			if (animated) {
+				// prevent resize handler call, the view will refresh after animation anyway
+				clearTimeout(this._sizeTimer);
+				return this;
+			}
+		}
+
+		// animation didn't start, just reset the map view
+		this._resetView(center, zoom);
+
+		return this;
+	},
+
+	panBy: function (offset, options) {
+		offset = L.point(offset).round();
+		options = options || {};
+
+		if (!offset.x && !offset.y) {
+			return this;
+		}
+
+		if (!this._panAnim) {
+			this._panAnim = new L.PosAnimation();
+
+			this._panAnim.on({
+				'step': this._onPanTransitionStep,
+				'end': this._onPanTransitionEnd
+			}, this);
+		}
+
+		// don't fire movestart if animating inertia
+		if (!options.noMoveStart) {
+			this.fire('movestart');
+		}
+
+		// animate pan unless animate: false specified
+		if (options.animate !== false) {
+			L.DomUtil.addClass(this._mapPane, 'leaflet-pan-anim');
+
+			var newPos = this._getMapPanePos().subtract(offset);
+			this._panAnim.run(this._mapPane, newPos, options.duration || 0.25, options.easeLinearity);
+		} else {
+			this._rawPanBy(offset);
+			this.fire('move').fire('moveend');
+		}
+
+		return this;
+	},
+
+	_onPanTransitionStep: function () {
+		this.fire('move');
+	},
+
+	_onPanTransitionEnd: function () {
+		L.DomUtil.removeClass(this._mapPane, 'leaflet-pan-anim');
+		this.fire('moveend');
+	},
+
+	_tryAnimatedPan: function (center, options) {
+		// difference between the new and current centers in pixels
+		var offset = this._getCenterOffset(center)._floor();
+
+		// don't animate too far unless animate: true specified in options
+		if ((options && options.animate) !== true && !this.getSize().contains(offset)) { return false; }
+
+		this.panBy(offset, options);
+
+		return true;
+	}
+});
+
+
+/*
+ * L.PosAnimation fallback implementation that powers Leaflet pan animations
+ * in browsers that don't support CSS3 Transitions.
+ */
+
+L.PosAnimation = L.DomUtil.TRANSITION ? L.PosAnimation : L.PosAnimation.extend({
+
+	run: function (el, newPos, duration, easeLinearity) { // (HTMLElement, Point[, Number, Number])
+		this.stop();
+
+		this._el = el;
+		this._inProgress = true;
+		this._duration = duration || 0.25;
+		this._easeOutPower = 1 / Math.max(easeLinearity || 0.5, 0.2);
+
+		this._startPos = L.DomUtil.getPosition(el);
+		this._offset = newPos.subtract(this._startPos);
+		this._startTime = +new Date();
+
+		this.fire('start');
+
+		this._animate();
+	},
+
+	stop: function () {
+		if (!this._inProgress) { return; }
+
+		this._step();
+		this._complete();
+	},
+
+	_animate: function () {
+		// animation loop
+		this._animId = L.Util.requestAnimFrame(this._animate, this);
+		this._step();
+	},
+
+	_step: function () {
+		var elapsed = (+new Date()) - this._startTime,
+		    duration = this._duration * 1000;
+
+		if (elapsed < duration) {
+			this._runFrame(this._easeOut(elapsed / duration));
+		} else {
+			this._runFrame(1);
+			this._complete();
+		}
+	},
+
+	_runFrame: function (progress) {
+		var pos = this._startPos.add(this._offset.multiplyBy(progress));
+		L.DomUtil.setPosition(this._el, pos);
+
+		this.fire('step');
+	},
+
+	_complete: function () {
+		L.Util.cancelAnimFrame(this._animId);
+
+		this._inProgress = false;
+		this.fire('end');
+	},
+
+	_easeOut: function (t) {
+		return 1 - Math.pow(1 - t, this._easeOutPower);
+	}
+});
+
+
+/*
+ * Extends L.Map to handle zoom animations.
+ */
+
+L.Map.mergeOptions({
+	zoomAnimation: true,
+	zoomAnimationThreshold: 4
+});
+
+if (L.DomUtil.TRANSITION) {
+
+	L.Map.addInitHook(function () {
+		// don't animate on browsers without hardware-accelerated transitions or old Android/Opera
+		this._zoomAnimated = this.options.zoomAnimation && L.DomUtil.TRANSITION &&
+				L.Browser.any3d && !L.Browser.android23 && !L.Browser.mobileOpera;
+
+		// zoom transitions run with the same duration for all layers, so if one of transitionend events
+		// happens after starting zoom animation (propagating to the map pane), we know that it ended globally
+		if (this._zoomAnimated) {
+			L.DomEvent.on(this._mapPane, L.DomUtil.TRANSITION_END, this._catchTransitionEnd, this);
+		}
+	});
+}
+
+L.Map.include(!L.DomUtil.TRANSITION ? {} : {
+
+	_catchTransitionEnd: function (e) {
+		if (this._animatingZoom && e.propertyName.indexOf('transform') >= 0) {
+			this._onZoomTransitionEnd();
+		}
+	},
+
+	_nothingToAnimate: function () {
+		return !this._container.getElementsByClassName('leaflet-zoom-animated').length;
+	},
+
+	_tryAnimatedZoom: function (center, zoom, options) {
+
+		if (this._animatingZoom) { return true; }
+
+		options = options || {};
+
+		// don't animate if disabled, not supported or zoom difference is too large
+		if (!this._zoomAnimated || options.animate === false || this._nothingToAnimate() ||
+		        Math.abs(zoom - this._zoom) > this.options.zoomAnimationThreshold) { return false; }
+
+		// offset is the pixel coords of the zoom origin relative to the current center
+		var scale = this.getZoomScale(zoom),
+		    offset = this._getCenterOffset(center)._divideBy(1 - 1 / scale),
+			origin = this._getCenterLayerPoint()._add(offset);
+
+		// don't animate if the zoom origin isn't within one screen from the current center, unless forced
+		if (options.animate !== true && !this.getSize().contains(offset)) { return false; }
+
+		this
+		    .fire('movestart')
+		    .fire('zoomstart');
+
+		this._animateZoom(center, zoom, origin, scale, null, true);
+
+		return true;
+	},
+
+	_animateZoom: function (center, zoom, origin, scale, delta, backwards, forTouchZoom) {
+
+		if (!forTouchZoom) {
+			this._animatingZoom = true;
+		}
+
+		// put transform transition on all layers with leaflet-zoom-animated class
+		L.DomUtil.addClass(this._mapPane, 'leaflet-zoom-anim');
+
+		// remember what center/zoom to set after animation
+		this._animateToCenter = center;
+		this._animateToZoom = zoom;
+
+		// disable any dragging during animation
+		if (L.Draggable) {
+			L.Draggable._disabled = true;
+		}
+
+		L.Util.requestAnimFrame(function () {
+			this.fire('zoomanim', {
+				center: center,
+				zoom: zoom,
+				origin: origin,
+				scale: scale,
+				delta: delta,
+				backwards: backwards
+			});
+			// horrible hack to work around a Chrome bug https://github.com/Leaflet/Leaflet/issues/3689
+			setTimeout(L.bind(this._onZoomTransitionEnd, this), 250);
+		}, this);
+	},
+
+	_onZoomTransitionEnd: function () {
+		if (!this._animatingZoom) { return; }
+
+		this._animatingZoom = false;
+
+		L.DomUtil.removeClass(this._mapPane, 'leaflet-zoom-anim');
+
+		L.Util.requestAnimFrame(function () {
+			this._resetView(this._animateToCenter, this._animateToZoom, true, true);
+
+			if (L.Draggable) {
+				L.Draggable._disabled = false;
+			}
+		}, this);
+	}
+});
+
+
+/*
+	Zoom animation logic for L.TileLayer.
+*/
+
+L.TileLayer.include({
+	_animateZoom: function (e) {
+		if (!this._animating) {
+			this._animating = true;
+			this._prepareBgBuffer();
+		}
+
+		var bg = this._bgBuffer,
+		    transform = L.DomUtil.TRANSFORM,
+		    initialTransform = e.delta ? L.DomUtil.getTranslateString(e.delta) : bg.style[transform],
+		    scaleStr = L.DomUtil.getScaleString(e.scale, e.origin);
+
+		bg.style[transform] = e.backwards ?
+				scaleStr + ' ' + initialTransform :
+				initialTransform + ' ' + scaleStr;
+	},
+
+	_endZoomAnim: function () {
+		var front = this._tileContainer,
+		    bg = this._bgBuffer;
+
+		front.style.visibility = '';
+		front.parentNode.appendChild(front); // Bring to fore
+
+		// force reflow
+		L.Util.falseFn(bg.offsetWidth);
+
+		var zoom = this._map.getZoom();
+		if (zoom > this.options.maxZoom || zoom < this.options.minZoom) {
+			this._clearBgBuffer();
+		}
+
+		this._animating = false;
+	},
+
+	_clearBgBuffer: function () {
+		var map = this._map;
+
+		if (map && !map._animatingZoom && !map.touchZoom._zooming) {
+			this._bgBuffer.innerHTML = '';
+			this._bgBuffer.style[L.DomUtil.TRANSFORM] = '';
+		}
+	},
+
+	_prepareBgBuffer: function () {
+
+		var front = this._tileContainer,
+		    bg = this._bgBuffer;
+
+		// if foreground layer doesn't have many tiles but bg layer does,
+		// keep the existing bg layer and just zoom it some more
+
+		var bgLoaded = this._getLoadedTilesPercentage(bg),
+		    frontLoaded = this._getLoadedTilesPercentage(front);
+
+		if (bg && bgLoaded > 0.5 && frontLoaded < 0.5) {
+
+			front.style.visibility = 'hidden';
+			this._stopLoadingImages(front);
+			return;
+		}
+
+		// prepare the buffer to become the front tile pane
+		bg.style.visibility = 'hidden';
+		bg.style[L.DomUtil.TRANSFORM] = '';
+
+		// switch out the current layer to be the new bg layer (and vice-versa)
+		this._tileContainer = bg;
+		bg = this._bgBuffer = front;
+
+		this._stopLoadingImages(bg);
+
+		//prevent bg buffer from clearing right after zoom
+		clearTimeout(this._clearBgBufferTimer);
+	},
+
+	_getLoadedTilesPercentage: function (container) {
+		var tiles = container.getElementsByTagName('img'),
+		    i, len, count = 0;
+
+		for (i = 0, len = tiles.length; i < len; i++) {
+			if (tiles[i].complete) {
+				count++;
+			}
+		}
+		return count / len;
+	},
+
+	// stops loading all tiles in the background layer
+	_stopLoadingImages: function (container) {
+		var tiles = Array.prototype.slice.call(container.getElementsByTagName('img')),
+		    i, len, tile;
+
+		for (i = 0, len = tiles.length; i < len; i++) {
+			tile = tiles[i];
+
+			if (!tile.complete) {
+				tile.onload = L.Util.falseFn;
+				tile.onerror = L.Util.falseFn;
+				tile.src = L.Util.emptyImageUrl;
+
+				tile.parentNode.removeChild(tile);
+			}
+		}
+	}
+});
+
+
+/*
+ * Provides L.Map with convenient shortcuts for using browser geolocation features.
+ */
+
+L.Map.include({
+	_defaultLocateOptions: {
+		watch: false,
+		setView: false,
+		maxZoom: Infinity,
+		timeout: 10000,
+		maximumAge: 0,
+		enableHighAccuracy: false
+	},
+
+	locate: function (/*Object*/ options) {
+
+		options = this._locateOptions = L.extend(this._defaultLocateOptions, options);
+
+		if (!navigator.geolocation) {
+			this._handleGeolocationError({
+				code: 0,
+				message: 'Geolocation not supported.'
+			});
+			return this;
+		}
+
+		var onResponse = L.bind(this._handleGeolocationResponse, this),
+			onError = L.bind(this._handleGeolocationError, this);
+
+		if (options.watch) {
+			this._locationWatchId =
+			        navigator.geolocation.watchPosition(onResponse, onError, options);
+		} else {
+			navigator.geolocation.getCurrentPosition(onResponse, onError, options);
+		}
+		return this;
+	},
+
+	stopLocate: function () {
+		if (navigator.geolocation) {
+			navigator.geolocation.clearWatch(this._locationWatchId);
+		}
+		if (this._locateOptions) {
+			this._locateOptions.setView = false;
+		}
+		return this;
+	},
+
+	_handleGeolocationError: function (error) {
+		var c = error.code,
+		    message = error.message ||
+		            (c === 1 ? 'permission denied' :
+		            (c === 2 ? 'position unavailable' : 'timeout'));
+
+		if (this._locateOptions.setView && !this._loaded) {
+			this.fitWorld();
+		}
+
+		this.fire('locationerror', {
+			code: c,
+			message: 'Geolocation error: ' + message + '.'
+		});
+	},
+
+	_handleGeolocationResponse: function (pos) {
+		var lat = pos.coords.latitude,
+		    lng = pos.coords.longitude,
+		    latlng = new L.LatLng(lat, lng),
+
+		    latAccuracy = 180 * pos.coords.accuracy / 40075017,
+		    lngAccuracy = latAccuracy / Math.cos(L.LatLng.DEG_TO_RAD * lat),
+
+		    bounds = L.latLngBounds(
+		            [lat - latAccuracy, lng - lngAccuracy],
+		            [lat + latAccuracy, lng + lngAccuracy]),
+
+		    options = this._locateOptions;
+
+		if (options.setView) {
+			var zoom = Math.min(this.getBoundsZoom(bounds), options.maxZoom);
+			this.setView(latlng, zoom);
+		}
+
+		var data = {
+			latlng: latlng,
+			bounds: bounds,
+			timestamp: pos.timestamp
+		};
+
+		for (var i in pos.coords) {
+			if (typeof pos.coords[i] === 'number') {
+				data[i] = pos.coords[i];
+			}
+		}
+
+		this.fire('locationfound', data);
+	}
+});
+
+
+}(window, document));
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/leaflet.js b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/leaflet.js
new file mode 100644
index 0000000..ee5ff5a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.indoor/webapp/js/leaflet.js
@@ -0,0 +1,9 @@
+/*
+ Leaflet, a JavaScript library for mobile-friendly interactive maps. http://leafletjs.com
+ (c) 2010-2013, Vladimir Agafonkin
+ (c) 2010-2011, CloudMade
+*/
+!function(t,e,i){var n=t.L,o={};o.version="0.7.7","object"==typeof module&&"object"==typeof module.exports?module.exports=o:"function"==typeof define&&define.amd&&define(o),o.noConflict=function(){return t.L=n,this},t.L=o,o.Util={extend:function(t){var e,i,n,o,s=Array.prototype.slice.call(arguments,1);for(i=0,n=s.length;n>i;i++){o=s[i]||{};for(e in o)o.hasOwnProperty(e)&&(t[e]=o[e])}return t},bind:function(t,e){var i=arguments.length>2?Array.prototype.slice.call(arguments,2):null;return function(){return t.apply(e,i||arguments)}},stamp:function(){var t=0,e="_leaflet_id";return function(i){return i[e]=i[e]||++t,i[e]}}(),invokeEach:function(t,e,i){var n,o;if("object"==typeof t){o=Array.prototype.slice.call(arguments,3);for(n in t)e.apply(i,[n,t[n]].concat(o));return!0}return!1},limitExecByInterval:function(t,e,i){var n,o;return function s(){var a=arguments;return n?void(o=!0):(n=!0,setTimeout(function(){n=!1,o&&(s.apply(i,a),o=!1)},e),void t.apply(i,a))}},falseFn:function(){return!1},formatNum:function(t,e){var i=Math.pow(10,e||5);return Math.round(t*i)/i},trim:function(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")},splitWords:function(t){return o.Util.trim(t).split(/\s+/)},setOptions:function(t,e){return t.options=o.extend({},t.options,e),t.options},getParamString:function(t,e,i){var n=[];for(var o in t)n.push(encodeURIComponent(i?o.toUpperCase():o)+"="+encodeURIComponent(t[o]));return(e&&-1!==e.indexOf("?")?"&":"?")+n.join("&")},template:function(t,e){return t.replace(/\{ *([\w_]+) *\}/g,function(t,n){var o=e[n];if(o===i)throw new Error("No value provided for variable "+t);return"function"==typeof o&&(o=o(e)),o})},isArray:Array.isArray||function(t){return"[object Array]"===Object.prototype.toString.call(t)},emptyImageUrl:"data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs="},function(){function e(e){var i,n,o=["webkit","moz","o","ms"];for(i=0;i<o.length&&!n;i++)n=t[o[i]+e];return n}function i(e){var i=+new Date,o=Math.max(0,16-(i-n));return n=i+o,t.setTimeout(e,o)}var n=0,s=t.requestAnimationFrame||e("RequestAnimationFrame")||i,a=t.cancelAnimationFrame||e("CancelAnimationFrame")||e("CancelRequestAnimationFrame")||function(e){t.clearTimeout(e)};o.Util.requestAnimFrame=function(e,n,a,r){return e=o.bind(e,n),a&&s===i?void e():s.call(t,e,r)},o.Util.cancelAnimFrame=function(e){e&&a.call(t,e)}}(),o.extend=o.Util.extend,o.bind=o.Util.bind,o.stamp=o.Util.stamp,o.setOptions=o.Util.setOptions,o.Class=function(){},o.Class.extend=function(t){var e=function(){this.initialize&&this.initialize.apply(this,arguments),this._initHooks&&this.callInitHooks()},i=function(){};i.prototype=this.prototype;var n=new i;n.constructor=e,e.prototype=n;for(var s in this)this.hasOwnProperty(s)&&"prototype"!==s&&(e[s]=this[s]);t.statics&&(o.extend(e,t.statics),delete t.statics),t.includes&&(o.Util.extend.apply(null,[n].concat(t.includes)),delete t.includes),t.options&&n.options&&(t.options=o.extend({},n.options,t.options)),o.extend(n,t),n._initHooks=[];var a=this;return e.__super__=a.prototype,n.callInitHooks=function(){if(!this._initHooksCalled){a.prototype.callInitHooks&&a.prototype.callInitHooks.call(this),this._initHooksCalled=!0;for(var t=0,e=n._initHooks.length;e>t;t++)n._initHooks[t].call(this)}},e},o.Class.include=function(t){o.extend(this.prototype,t)},o.Class.mergeOptions=function(t){o.extend(this.prototype.options,t)},o.Class.addInitHook=function(t){var e=Array.prototype.slice.call(arguments,1),i="function"==typeof t?t:function(){this[t].apply(this,e)};this.prototype._initHooks=this.prototype._initHooks||[],this.prototype._initHooks.push(i)};var s="_leaflet_events";o.Mixin={},o.Mixin.Events={addEventListener:function(t,e,i){if(o.Util.invokeEach(t,this.addEventListener,this,e,i))return this;var n,a,r,h,l,u,c,d=this[s]=this[s]||{},p=i&&i!==this&&o.stamp(i);for(t=o.Util.splitWords(t),n=0,a=t.length;a>n;n++)r={action:e,context:i||this},h=t[n],p?(l=h+"_idx",u=l+"_len",c=d[l]=d[l]||{},c[p]||(c[p]=[],d[u]=(d[u]||0)+1),c[p].push(r)):(d[h]=d[h]||[],d[h].push(r));return this},hasEventListeners:function(t){var e=this[s];return!!e&&(t in e&&e[t].length>0||t+"_idx"in e&&e[t+"_idx_len"]>0)},removeEventListener:function(t,e,i){if(!this[s])return this;if(!t)return this.clearAllEventListeners();if(o.Util.invokeEach(t,this.removeEventListener,this,e,i))return this;var n,a,r,h,l,u,c,d,p,_=this[s],m=i&&i!==this&&o.stamp(i);for(t=o.Util.splitWords(t),n=0,a=t.length;a>n;n++)if(r=t[n],u=r+"_idx",c=u+"_len",d=_[u],e){if(h=m&&d?d[m]:_[r]){for(l=h.length-1;l>=0;l--)h[l].action!==e||i&&h[l].context!==i||(p=h.splice(l,1),p[0].action=o.Util.falseFn);i&&d&&0===h.length&&(delete d[m],_[c]--)}}else delete _[r],delete _[u],delete _[c];return this},clearAllEventListeners:function(){return delete this[s],this},fireEvent:function(t,e){if(!this.hasEventListeners(t))return this;var i,n,a,r,h,l=o.Util.extend({},e,{type:t,target:this}),u=this[s];if(u[t])for(i=u[t].slice(),n=0,a=i.length;a>n;n++)i[n].action.call(i[n].context,l);r=u[t+"_idx"];for(h in r)if(i=r[h].slice())for(n=0,a=i.length;a>n;n++)i[n].action.call(i[n].context,l);return this},addOneTimeEventListener:function(t,e,i){if(o.Util.invokeEach(t,this.addOneTimeEventListener,this,e,i))return this;var n=o.bind(function(){this.removeEventListener(t,e,i).removeEventListener(t,n,i)},this);return this.addEventListener(t,e,i).addEventListener(t,n,i)}},o.Mixin.Events.on=o.Mixin.Events.addEventListener,o.Mixin.Events.off=o.Mixin.Events.removeEventListener,o.Mixin.Events.once=o.Mixin.Events.addOneTimeEventListener,o.Mixin.Events.fire=o.Mixin.Events.fireEvent,function(){var n="ActiveXObject"in t,s=n&&!e.addEventListener,a=navigator.userAgent.toLowerCase(),r=-1!==a.indexOf("webkit"),h=-1!==a.indexOf("chrome"),l=-1!==a.indexOf("phantom"),u=-1!==a.indexOf("android"),c=-1!==a.search("android [23]"),d=-1!==a.indexOf("gecko"),p=typeof orientation!=i+"",_=!t.PointerEvent&&t.MSPointerEvent,m=t.PointerEvent&&t.navigator.pointerEnabled||_,f="devicePixelRatio"in t&&t.devicePixelRatio>1||"matchMedia"in t&&t.matchMedia("(min-resolution:144dpi)")&&t.matchMedia("(min-resolution:144dpi)").matches,g=e.documentElement,v=n&&"transition"in g.style,y="WebKitCSSMatrix"in t&&"m11"in new t.WebKitCSSMatrix&&!c,P="MozPerspective"in g.style,L="OTransition"in g.style,x=!t.L_DISABLE_3D&&(v||y||P||L)&&!l,w=!t.L_NO_TOUCH&&!l&&(m||"ontouchstart"in t||t.DocumentTouch&&e instanceof t.DocumentTouch);o.Browser={ie:n,ielt9:s,webkit:r,gecko:d&&!r&&!t.opera&&!n,android:u,android23:c,chrome:h,ie3d:v,webkit3d:y,gecko3d:P,opera3d:L,any3d:x,mobile:p,mobileWebkit:p&&r,mobileWebkit3d:p&&y,mobileOpera:p&&t.opera,touch:w,msPointer:_,pointer:m,retina:f}}(),o.Point=function(t,e,i){this.x=i?Math.round(t):t,this.y=i?Math.round(e):e},o.Point.prototype={clone:function(){return new o.Point(this.x,this.y)},add:function(t){return this.clone()._add(o.point(t))},_add:function(t){return this.x+=t.x,this.y+=t.y,this},subtract:function(t){return this.clone()._subtract(o.point(t))},_subtract:function(t){return this.x-=t.x,this.y-=t.y,this},divideBy:function(t){return this.clone()._divideBy(t)},_divideBy:function(t){return this.x/=t,this.y/=t,this},multiplyBy:function(t){return this.clone()._multiplyBy(t)},_multiplyBy:function(t){return this.x*=t,this.y*=t,this},round:function(){return this.clone()._round()},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this},floor:function(){return this.clone()._floor()},_floor:function(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this},distanceTo:function(t){t=o.point(t);var e=t.x-this.x,i=t.y-this.y;return Math.sqrt(e*e+i*i)},equals:function(t){return t=o.point(t),t.x===this.x&&t.y===this.y},contains:function(t){return t=o.point(t),Math.abs(t.x)<=Math.abs(this.x)&&Math.abs(t.y)<=Math.abs(this.y)},toString:function(){return"Point("+o.Util.formatNum(this.x)+", "+o.Util.formatNum(this.y)+")"}},o.point=function(t,e,n){return t instanceof o.Point?t:o.Util.isArray(t)?new o.Point(t[0],t[1]):t===i||null===t?t:new o.Point(t,e,n)},o.Bounds=function(t,e){if(t)for(var i=e?[t,e]:t,n=0,o=i.length;o>n;n++)this.extend(i[n])},o.Bounds.prototype={extend:function(t){return t=o.point(t),this.min||this.max?(this.min.x=Math.min(t.x,this.min.x),this.max.x=Math.max(t.x,this.max.x),this.min.y=Math.min(t.y,this.min.y),this.max.y=Math.max(t.y,this.max.y)):(this.min=t.clone(),this.max=t.clone()),this},getCenter:function(t){return new o.Point((this.min.x+this.max.x)/2,(this.min.y+this.max.y)/2,t)},getBottomLeft:function(){return new o.Point(this.min.x,this.max.y)},getTopRight:function(){return new o.Point(this.max.x,this.min.y)},getSize:function(){return this.max.subtract(this.min)},contains:function(t){var e,i;return t="number"==typeof t[0]||t instanceof o.Point?o.point(t):o.bounds(t),t instanceof o.Bounds?(e=t.min,i=t.max):e=i=t,e.x>=this.min.x&&i.x<=this.max.x&&e.y>=this.min.y&&i.y<=this.max.y},intersects:function(t){t=o.bounds(t);var e=this.min,i=this.max,n=t.min,s=t.max,a=s.x>=e.x&&n.x<=i.x,r=s.y>=e.y&&n.y<=i.y;return a&&r},isValid:function(){return!(!this.min||!this.max)}},o.bounds=function(t,e){return!t||t instanceof o.Bounds?t:new o.Bounds(t,e)},o.Transformation=function(t,e,i,n){this._a=t,this._b=e,this._c=i,this._d=n},o.Transformation.prototype={transform:function(t,e){return this._transform(t.clone(),e)},_transform:function(t,e){return e=e||1,t.x=e*(this._a*t.x+this._b),t.y=e*(this._c*t.y+this._d),t},untransform:function(t,e){return e=e||1,new o.Point((t.x/e-this._b)/this._a,(t.y/e-this._d)/this._c)}},o.DomUtil={get:function(t){return"string"==typeof t?e.getElementById(t):t},getStyle:function(t,i){var n=t.style[i];if(!n&&t.currentStyle&&(n=t.currentStyle[i]),(!n||"auto"===n)&&e.defaultView){var o=e.defaultView.getComputedStyle(t,null);n=o?o[i]:null}return"auto"===n?null:n},getViewportOffset:function(t){var i,n=0,s=0,a=t,r=e.body,h=e.documentElement;do{if(n+=a.offsetTop||0,s+=a.offsetLeft||0,n+=parseInt(o.DomUtil.getStyle(a,"borderTopWidth"),10)||0,s+=parseInt(o.DomUtil.getStyle(a,"borderLeftWidth"),10)||0,i=o.DomUtil.getStyle(a,"position"),a.offsetParent===r&&"absolute"===i)break;if("fixed"===i){n+=r.scrollTop||h.scrollTop||0,s+=r.scrollLeft||h.scrollLeft||0;break}if("relative"===i&&!a.offsetLeft){var l=o.DomUtil.getStyle(a,"width"),u=o.DomUtil.getStyle(a,"max-width"),c=a.getBoundingClientRect();("none"!==l||"none"!==u)&&(s+=c.left+a.clientLeft),n+=c.top+(r.scrollTop||h.scrollTop||0);break}a=a.offsetParent}while(a);a=t;do{if(a===r)break;n-=a.scrollTop||0,s-=a.scrollLeft||0,a=a.parentNode}while(a);return new o.Point(s,n)},documentIsLtr:function(){return o.DomUtil._docIsLtrCached||(o.DomUtil._docIsLtrCached=!0,o.DomUtil._docIsLtr="ltr"===o.DomUtil.getStyle(e.body,"direction")),o.DomUtil._docIsLtr},create:function(t,i,n){var o=e.createElement(t);return o.className=i,n&&n.appendChild(o),o},hasClass:function(t,e){if(t.classList!==i)return t.classList.contains(e);var n=o.DomUtil._getClass(t);return n.length>0&&new RegExp("(^|\\s)"+e+"(\\s|$)").test(n)},addClass:function(t,e){if(t.classList!==i)for(var n=o.Util.splitWords(e),s=0,a=n.length;a>s;s++)t.classList.add(n[s]);else if(!o.DomUtil.hasClass(t,e)){var r=o.DomUtil._getClass(t);o.DomUtil._setClass(t,(r?r+" ":"")+e)}},removeClass:function(t,e){t.classList!==i?t.classList.remove(e):o.DomUtil._setClass(t,o.Util.trim((" "+o.DomUtil._getClass(t)+" ").replace(" "+e+" "," ")))},_setClass:function(t,e){t.className.baseVal===i?t.className=e:t.className.baseVal=e},_getClass:function(t){return t.className.baseVal===i?t.className:t.className.baseVal},setOpacity:function(t,e){if("opacity"in t.style)t.style.opacity=e;else if("filter"in t.style){var i=!1,n="DXImageTransform.Microsoft.Alpha";try{i=t.filters.item(n)}catch(o){if(1===e)return}e=Math.round(100*e),i?(i.Enabled=100!==e,i.Opacity=e):t.style.filter+=" progid:"+n+"(opacity="+e+")"}},testProp:function(t){for(var i=e.documentElement.style,n=0;n<t.length;n++)if(t[n]in i)return t[n];return!1},getTranslateString:function(t){var e=o.Browser.webkit3d,i="translate"+(e?"3d":"")+"(",n=(e?",0":"")+")";return i+t.x+"px,"+t.y+"px"+n},getScaleString:function(t,e){var i=o.DomUtil.getTranslateString(e.add(e.multiplyBy(-1*t))),n=" scale("+t+") ";return i+n},setPosition:function(t,e,i){t._leaflet_pos=e,!i&&o.Browser.any3d?t.style[o.DomUtil.TRANSFORM]=o.DomUtil.getTranslateString(e):(t.style.left=e.x+"px",t.style.top=e.y+"px")},getPosition:function(t){return t._leaflet_pos}},o.DomUtil.TRANSFORM=o.DomUtil.testProp(["transform","WebkitTransform","OTransform","MozTransform","msTransform"]),o.DomUtil.TRANSITION=o.DomUtil.testProp(["webkitTransition","transition","OTransition","MozTransition","msTransition"]),o.DomUtil.TRANSITION_END="webkitTransition"===o.DomUtil.TRANSITION||"OTransition"===o.DomUtil.TRANSITION?o.DomUtil.TRANSITION+"End":"transitionend",function(){if("onselectstart"in e)o.extend(o.DomUtil,{disableTextSelection:function(){o.DomEvent.on(t,"selectstart",o.DomEvent.preventDefault)},enableTextSelection:function(){o.DomEvent.off(t,"selectstart",o.DomEvent.preventDefault)}});else{var i=o.DomUtil.testProp(["userSelect","WebkitUserSelect","OUserSelect","MozUserSelect","msUserSelect"]);o.extend(o.DomUtil,{disableTextSelection:function(){if(i){var t=e.documentElement.style;this._userSelect=t[i],t[i]="none"}},enableTextSelection:function(){i&&(e.documentElement.style[i]=this._userSelect,delete this._userSelect)}})}o.extend(o.DomUtil,{disableImageDrag:function(){o.DomEvent.on(t,"dragstart",o.DomEvent.preventDefault)},enableImageDrag:function(){o.DomEvent.off(t,"dragstart",o.DomEvent.preventDefault)}})}(),o.LatLng=function(t,e,n){if(t=parseFloat(t),e=parseFloat(e),isNaN(t)||isNaN(e))throw new Error("Invalid LatLng object: ("+t+", "+e+")");this.lat=t,this.lng=e,n!==i&&(this.alt=parseFloat(n))},o.extend(o.LatLng,{DEG_TO_RAD:Math.PI/180,RAD_TO_DEG:180/Math.PI,MAX_MARGIN:1e-9}),o.LatLng.prototype={equals:function(t){if(!t)return!1;t=o.latLng(t);var e=Math.max(Math.abs(this.lat-t.lat),Math.abs(this.lng-t.lng));return e<=o.LatLng.MAX_MARGIN},toString:function(t){return"LatLng("+o.Util.formatNum(this.lat,t)+", "+o.Util.formatNum(this.lng,t)+")"},distanceTo:function(t){t=o.latLng(t);var e=6378137,i=o.LatLng.DEG_TO_RAD,n=(t.lat-this.lat)*i,s=(t.lng-this.lng)*i,a=this.lat*i,r=t.lat*i,h=Math.sin(n/2),l=Math.sin(s/2),u=h*h+l*l*Math.cos(a)*Math.cos(r);return 2*e*Math.atan2(Math.sqrt(u),Math.sqrt(1-u))},wrap:function(t,e){var i=this.lng;return t=t||-180,e=e||180,i=(i+e)%(e-t)+(t>i||i===e?e:t),new o.LatLng(this.lat,i)}},o.latLng=function(t,e){return t instanceof o.LatLng?t:o.Util.isArray(t)?"number"==typeof t[0]||"string"==typeof t[0]?new o.LatLng(t[0],t[1],t[2]):null:t===i||null===t?t:"object"==typeof t&&"lat"in t?new o.LatLng(t.lat,"lng"in t?t.lng:t.lon):e===i?null:new o.LatLng(t,e)},o.LatLngBounds=function(t,e){if(t)for(var i=e?[t,e]:t,n=0,o=i.length;o>n;n++)this.extend(i[n])},o.LatLngBounds.prototype={extend:function(t){if(!t)return this;var e=o.latLng(t);return t=null!==e?e:o.latLngBounds(t),t instanceof o.LatLng?this._southWest||this._northEast?(this._southWest.lat=Math.min(t.lat,this._southWest.lat),this._southWest.lng=Math.min(t.lng,this._southWest.lng),this._northEast.lat=Math.max(t.lat,this._northEast.lat),this._northEast.lng=Math.max(t.lng,this._northEast.lng)):(this._southWest=new o.LatLng(t.lat,t.lng),this._northEast=new o.LatLng(t.lat,t.lng)):t instanceof o.LatLngBounds&&(this.extend(t._southWest),this.extend(t._northEast)),this},pad:function(t){var e=this._southWest,i=this._northEast,n=Math.abs(e.lat-i.lat)*t,s=Math.abs(e.lng-i.lng)*t;return new o.LatLngBounds(new o.LatLng(e.lat-n,e.lng-s),new o.LatLng(i.lat+n,i.lng+s))},getCenter:function(){return new o.LatLng((this._southWest.lat+this._northEast.lat)/2,(this._southWest.lng+this._northEast.lng)/2)},getSouthWest:function(){return this._southWest},getNorthEast:function(){return this._northEast},getNorthWest:function(){return new o.LatLng(this.getNorth(),this.getWest())},getSouthEast:function(){return new o.LatLng(this.getSouth(),this.getEast())},getWest:function(){return this._southWest.lng},getSouth:function(){return this._southWest.lat},getEast:function(){return this._northEast.lng},getNorth:function(){return this._northEast.lat},contains:function(t){t="number"==typeof t[0]||t instanceof o.LatLng?o.latLng(t):o.latLngBounds(t);var e,i,n=this._southWest,s=this._northEast;return t instanceof o.LatLngBounds?(e=t.getSouthWest(),i=t.getNorthEast()):e=i=t,e.lat>=n.lat&&i.lat<=s.lat&&e.lng>=n.lng&&i.lng<=s.lng},intersects:function(t){t=o.latLngBounds(t);var e=this._southWest,i=this._northEast,n=t.getSouthWest(),s=t.getNorthEast(),a=s.lat>=e.lat&&n.lat<=i.lat,r=s.lng>=e.lng&&n.lng<=i.lng;return a&&r},toBBoxString:function(){return[this.getWest(),this.getSouth(),this.getEast(),this.getNorth()].join(",")},equals:function(t){return t?(t=o.latLngBounds(t),this._southWest.equals(t.getSouthWest())&&this._northEast.equals(t.getNorthEast())):!1},isValid:function(){return!(!this._southWest||!this._northEast)}},o.latLngBounds=function(t,e){return!t||t instanceof o.LatLngBounds?t:new o.LatLngBounds(t,e)},o.Projection={},o.Projection.SphericalMercator={MAX_LATITUDE:85.0511287798,project:function(t){var e=o.LatLng.DEG_TO_RAD,i=this.MAX_LATITUDE,n=Math.max(Math.min(i,t.lat),-i),s=t.lng*e,a=n*e;return a=Math.log(Math.tan(Math.PI/4+a/2)),new o.Point(s,a)},unproject:function(t){var e=o.LatLng.RAD_TO_DEG,i=t.x*e,n=(2*Math.atan(Math.exp(t.y))-Math.PI/2)*e;return new o.LatLng(n,i)}},o.Projection.LonLat={project:function(t){return new o.Point(t.lng,t.lat)},unproject:function(t){return new o.LatLng(t.y,t.x)}},o.CRS={latLngToPoint:function(t,e){var i=this.projection.project(t),n=this.scale(e);return this.transformation._transform(i,n)},pointToLatLng:function(t,e){var i=this.scale(e),n=this.transformation.untransform(t,i);return this.projection.unproject(n)},project:function(t){return this.projection.project(t)},scale:function(t){return 256*Math.pow(2,t)},getSize:function(t){var e=this.scale(t);return o.point(e,e)}},o.CRS.Simple=o.extend({},o.CRS,{projection:o.Projection.LonLat,transformation:new o.Transformation(1,0,-1,0),scale:function(t){return Math.pow(2,t)}}),o.CRS.EPSG3857=o.extend({},o.CRS,{code:"EPSG:3857",projection:o.Projection.SphericalMercator,transformation:new o.Transformation(.5/Math.PI,.5,-.5/Math.PI,.5),project:function(t){var e=this.projection.project(t),i=6378137;return e.multiplyBy(i)}}),o.CRS.EPSG900913=o.extend({},o.CRS.EPSG3857,{code:"EPSG:900913"}),o.CRS.EPSG4326=o.extend({},o.CRS,{code:"EPSG:4326",projection:o.Projection.LonLat,transformation:new o.Transformation(1/360,.5,-1/360,.5)}),o.Map=o.Class.extend({includes:o.Mixin.Events,options:{crs:o.CRS.EPSG3857,fadeAnimation:o.DomUtil.TRANSITION&&!o.Browser.android23,trackResize:!0,markerZoomAnimation:o.DomUtil.TRANSITION&&o.Browser.any3d},initialize:function(t,e){e=o.setOptions(this,e),this._initContainer(t),this._initLayout(),this._onResize=o.bind(this._onResize,this),this._initEvents(),e.maxBounds&&this.setMaxBounds(e.maxBounds),e.center&&e.zoom!==i&&this.setView(o.latLng(e.center),e.zoom,{reset:!0}),this._handlers=[],this._layers={},this._zoomBoundLayers={},this._tileLayersNum=0,this.callInitHooks(),this._addLayers(e.layers)},setView:function(t,e){return e=e===i?this.getZoom():e,this._resetView(o.latLng(t),this._limitZoom(e)),this},setZoom:function(t,e){return this._loaded?this.setView(this.getCenter(),t,{zoom:e}):(this._zoom=this._limitZoom(t),this)},zoomIn:function(t,e){return this.setZoom(this._zoom+(t||1),e)},zoomOut:function(t,e){return this.setZoom(this._zoom-(t||1),e)},setZoomAround:function(t,e,i){var n=this.getZoomScale(e),s=this.getSize().divideBy(2),a=t instanceof o.Point?t:this.latLngToContainerPoint(t),r=a.subtract(s).multiplyBy(1-1/n),h=this.containerPointToLatLng(s.add(r));return this.setView(h,e,{zoom:i})},fitBounds:function(t,e){e=e||{},t=t.getBounds?t.getBounds():o.latLngBounds(t);var i=o.point(e.paddingTopLeft||e.padding||[0,0]),n=o.point(e.paddingBottomRight||e.padding||[0,0]),s=this.getBoundsZoom(t,!1,i.add(n));s=e.maxZoom?Math.min(e.maxZoom,s):s;var a=n.subtract(i).divideBy(2),r=this.project(t.getSouthWest(),s),h=this.project(t.getNorthEast(),s),l=this.unproject(r.add(h).divideBy(2).add(a),s);return this.setView(l,s,e)},fitWorld:function(t){return this.fitBounds([[-90,-180],[90,180]],t)},panTo:function(t,e){return this.setView(t,this._zoom,{pan:e})},panBy:function(t){return this.fire("movestart"),this._rawPanBy(o.point(t)),this.fire("move"),this.fire("moveend")},setMaxBounds:function(t){return t=o.latLngBounds(t),this.options.maxBounds=t,t?(this._loaded&&this._panInsideMaxBounds(),this.on("moveend",this._panInsideMaxBounds,this)):this.off("moveend",this._panInsideMaxBounds,this)},panInsideBounds:function(t,e){var i=this.getCenter(),n=this._limitCenter(i,this._zoom,t);return i.equals(n)?this:this.panTo(n,e)},addLayer:function(t){var e=o.stamp(t);return this._layers[e]?this:(this._layers[e]=t,!t.options||isNaN(t.options.maxZoom)&&isNaN(t.options.minZoom)||(this._zoomBoundLayers[e]=t,this._updateZoomLevels()),this.options.zoomAnimation&&o.TileLayer&&t instanceof o.TileLayer&&(this._tileLayersNum++,this._tileLayersToLoad++,t.on("load",this._onTileLayerLoad,this)),this._loaded&&this._layerAdd(t),this)},removeLayer:function(t){var e=o.stamp(t);return this._layers[e]?(this._loaded&&t.onRemove(this),delete this._layers[e],this._loaded&&this.fire("layerremove",{layer:t}),this._zoomBoundLayers[e]&&(delete this._zoomBoundLayers[e],this._updateZoomLevels()),this.options.zoomAnimation&&o.TileLayer&&t instanceof o.TileLayer&&(this._tileLayersNum--,this._tileLayersToLoad--,t.off("load",this._onTileLayerLoad,this)),this):this},hasLayer:function(t){return t?o.stamp(t)in this._layers:!1},eachLayer:function(t,e){for(var i in this._layers)t.call(e,this._layers[i]);return this},invalidateSize:function(t){if(!this._loaded)return this;t=o.extend({animate:!1,pan:!0},t===!0?{animate:!0}:t);var e=this.getSize();this._sizeChanged=!0,this._initialCenter=null;var i=this.getSize(),n=e.divideBy(2).round(),s=i.divideBy(2).round(),a=n.subtract(s);return a.x||a.y?(t.animate&&t.pan?this.panBy(a):(t.pan&&this._rawPanBy(a),this.fire("move"),t.debounceMoveend?(clearTimeout(this._sizeTimer),this._sizeTimer=setTimeout(o.bind(this.fire,this,"moveend"),200)):this.fire("moveend")),this.fire("resize",{oldSize:e,newSize:i})):this},addHandler:function(t,e){if(!e)return this;var i=this[t]=new e(this);return this._handlers.push(i),this.options[t]&&i.enable(),this},remove:function(){this._loaded&&this.fire("unload"),this._initEvents("off");try{delete this._container._leaflet}catch(t){this._container._leaflet=i}return this._clearPanes(),this._clearControlPos&&this._clearControlPos(),this._clearHandlers(),this},getCenter:function(){return this._checkIfLoaded(),this._initialCenter&&!this._moved()?this._initialCenter:this.layerPointToLatLng(this._getCenterLayerPoint())},getZoom:function(){return this._zoom},getBounds:function(){var t=this.getPixelBounds(),e=this.unproject(t.getBottomLeft()),i=this.unproject(t.getTopRight());return new o.LatLngBounds(e,i)},getMinZoom:function(){return this.options.minZoom===i?this._layersMinZoom===i?0:this._layersMinZoom:this.options.minZoom},getMaxZoom:function(){return this.options.maxZoom===i?this._layersMaxZoom===i?1/0:this._layersMaxZoom:this.options.maxZoom},getBoundsZoom:function(t,e,i){t=o.latLngBounds(t);var n,s=this.getMinZoom()-(e?1:0),a=this.getMaxZoom(),r=this.getSize(),h=t.getNorthWest(),l=t.getSouthEast(),u=!0;i=o.point(i||[0,0]);do s++,n=this.project(l,s).subtract(this.project(h,s)).add(i),u=e?n.x<r.x||n.y<r.y:r.contains(n);while(u&&a>=s);return u&&e?null:e?s:s-1},getSize:function(){return(!this._size||this._sizeChanged)&&(this._size=new o.Point(this._container.clientWidth,this._container.clientHeight),this._sizeChanged=!1),this._size.clone()},getPixelBounds:function(){var t=this._getTopLeftPoint();return new o.Bounds(t,t.add(this.getSize()))},getPixelOrigin:function(){return this._checkIfLoaded(),this._initialTopLeftPoint},getPanes:function(){return this._panes},getContainer:function(){return this._container},getZoomScale:function(t){var e=this.options.crs;return e.scale(t)/e.scale(this._zoom)},getScaleZoom:function(t){return this._zoom+Math.log(t)/Math.LN2},project:function(t,e){return e=e===i?this._zoom:e,this.options.crs.latLngToPoint(o.latLng(t),e)},unproject:function(t,e){return e=e===i?this._zoom:e,this.options.crs.pointToLatLng(o.point(t),e)},layerPointToLatLng:function(t){var e=o.point(t).add(this.getPixelOrigin());return this.unproject(e)},latLngToLayerPoint:function(t){var e=this.project(o.latLng(t))._round();return e._subtract(this.getPixelOrigin())},containerPointToLayerPoint:function(t){return o.point(t).subtract(this._getMapPanePos())},layerPointToContainerPoint:function(t){return o.point(t).add(this._getMapPanePos())},containerPointToLatLng:function(t){var e=this.containerPointToLayerPoint(o.point(t));return this.layerPointToLatLng(e)},latLngToContainerPoint:function(t){return this.layerPointToContainerPoint(this.latLngToLayerPoint(o.latLng(t)))},mouseEventToContainerPoint:function(t){return o.DomEvent.getMousePosition(t,this._container)},mouseEventToLayerPoint:function(t){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(t))},mouseEventToLatLng:function(t){return this.layerPointToLatLng(this.mouseEventToLayerPoint(t))},_initContainer:function(t){var e=this._container=o.DomUtil.get(t);if(!e)throw new Error("Map container not found.");if(e._leaflet)throw new Error("Map container is already initialized.");e._leaflet=!0},_initLayout:function(){var t=this._container;o.DomUtil.addClass(t,"leaflet-container"+(o.Browser.touch?" leaflet-touch":"")+(o.Browser.retina?" leaflet-retina":"")+(o.Browser.ielt9?" leaflet-oldie":"")+(this.options.fadeAnimation?" leaflet-fade-anim":""));var e=o.DomUtil.getStyle(t,"position");"absolute"!==e&&"relative"!==e&&"fixed"!==e&&(t.style.position="relative"),this._initPanes(),this._initControlPos&&this._initControlPos()},_initPanes:function(){var t=this._panes={};this._mapPane=t.mapPane=this._createPane("leaflet-map-pane",this._container),this._tilePane=t.tilePane=this._createPane("leaflet-tile-pane",this._mapPane),t.objectsPane=this._createPane("leaflet-objects-pane",this._mapPane),t.shadowPane=this._createPane("leaflet-shadow-pane"),t.overlayPane=this._createPane("leaflet-overlay-pane"),t.markerPane=this._createPane("leaflet-marker-pane"),t.popupPane=this._createPane("leaflet-popup-pane");var e=" leaflet-zoom-hide";this.options.markerZoomAnimation||(o.DomUtil.addClass(t.markerPane,e),o.DomUtil.addClass(t.shadowPane,e),o.DomUtil.addClass(t.popupPane,e))},_createPane:function(t,e){return o.DomUtil.create("div",t,e||this._panes.objectsPane)},_clearPanes:function(){this._container.removeChild(this._mapPane)},_addLayers:function(t){t=t?o.Util.isArray(t)?t:[t]:[];for(var e=0,i=t.length;i>e;e++)this.addLayer(t[e])},_resetView:function(t,e,i,n){var s=this._zoom!==e;n||(this.fire("movestart"),s&&this.fire("zoomstart")),this._zoom=e,this._initialCenter=t,this._initialTopLeftPoint=this._getNewTopLeftPoint(t),i?this._initialTopLeftPoint._add(this._getMapPanePos()):o.DomUtil.setPosition(this._mapPane,new o.Point(0,0)),this._tileLayersToLoad=this._tileLayersNum;var a=!this._loaded;this._loaded=!0,this.fire("viewreset",{hard:!i}),a&&(this.fire("load"),this.eachLayer(this._layerAdd,this)),this.fire("move"),(s||n)&&this.fire("zoomend"),this.fire("moveend",{hard:!i})},_rawPanBy:function(t){o.DomUtil.setPosition(this._mapPane,this._getMapPanePos().subtract(t))},_getZoomSpan:function(){return this.getMaxZoom()-this.getMinZoom()},_updateZoomLevels:function(){var t,e=1/0,n=-(1/0),o=this._getZoomSpan();for(t in this._zoomBoundLayers){var s=this._zoomBoundLayers[t];isNaN(s.options.minZoom)||(e=Math.min(e,s.options.minZoom)),isNaN(s.options.maxZoom)||(n=Math.max(n,s.options.maxZoom))}t===i?this._layersMaxZoom=this._layersMinZoom=i:(this._layersMaxZoom=n,this._layersMinZoom=e),o!==this._getZoomSpan()&&this.fire("zoomlevelschange")},_panInsideMaxBounds:function(){this.panInsideBounds(this.options.maxBounds)},_checkIfLoaded:function(){if(!this._loaded)throw new Error("Set map center and zoom first.")},_initEvents:function(e){if(o.DomEvent){e=e||"on",o.DomEvent[e](this._container,"click",this._onMouseClick,this);var i,n,s=["dblclick","mousedown","mouseup","mouseenter","mouseleave","mousemove","contextmenu"];for(i=0,n=s.length;n>i;i++)o.DomEvent[e](this._container,s[i],this._fireMouseEvent,this);this.options.trackResize&&o.DomEvent[e](t,"resize",this._onResize,this)}},_onResize:function(){o.Util.cancelAnimFrame(this._resizeRequest),this._resizeRequest=o.Util.requestAnimFrame(function(){this.invalidateSize({debounceMoveend:!0})},this,!1,this._container)},_onMouseClick:function(t){!this._loaded||!t._simulated&&(this.dragging&&this.dragging.moved()||this.boxZoom&&this.boxZoom.moved())||o.DomEvent._skipped(t)||(this.fire("preclick"),this._fireMouseEvent(t))},_fireMouseEvent:function(t){if(this._loaded&&!o.DomEvent._skipped(t)){var e=t.type;if(e="mouseenter"===e?"mouseover":"mouseleave"===e?"mouseout":e,this.hasEventListeners(e)){"contextmenu"===e&&o.DomEvent.preventDefault(t);var i=this.mouseEventToContainerPoint(t),n=this.containerPointToLayerPoint(i),s=this.layerPointToLatLng(n);this.fire(e,{latlng:s,layerPoint:n,containerPoint:i,originalEvent:t})}}},_onTileLayerLoad:function(){this._tileLayersToLoad--,this._tileLayersNum&&!this._tileLayersToLoad&&this.fire("tilelayersload")},_clearHandlers:function(){for(var t=0,e=this._handlers.length;e>t;t++)this._handlers[t].disable()},whenReady:function(t,e){return this._loaded?t.call(e||this,this):this.on("load",t,e),this},_layerAdd:function(t){t.onAdd(this),this.fire("layeradd",{layer:t})},_getMapPanePos:function(){return o.DomUtil.getPosition(this._mapPane)},_moved:function(){var t=this._getMapPanePos();return t&&!t.equals([0,0])},_getTopLeftPoint:function(){return this.getPixelOrigin().subtract(this._getMapPanePos())},_getNewTopLeftPoint:function(t,e){var i=this.getSize()._divideBy(2);return this.project(t,e)._subtract(i)._round()},_latLngToNewLayerPoint:function(t,e,i){var n=this._getNewTopLeftPoint(i,e).add(this._getMapPanePos());return this.project(t,e)._subtract(n)},_getCenterLayerPoint:function(){return this.containerPointToLayerPoint(this.getSize()._divideBy(2))},_getCenterOffset:function(t){return this.latLngToLayerPoint(t).subtract(this._getCenterLayerPoint())},_limitCenter:function(t,e,i){if(!i)return t;var n=this.project(t,e),s=this.getSize().divideBy(2),a=new o.Bounds(n.subtract(s),n.add(s)),r=this._getBoundsOffset(a,i,e);return this.unproject(n.add(r),e)},_limitOffset:function(t,e){if(!e)return t;var i=this.getPixelBounds(),n=new o.Bounds(i.min.add(t),i.max.add(t));return t.add(this._getBoundsOffset(n,e))},_getBoundsOffset:function(t,e,i){var n=this.project(e.getNorthWest(),i).subtract(t.min),s=this.project(e.getSouthEast(),i).subtract(t.max),a=this._rebound(n.x,-s.x),r=this._rebound(n.y,-s.y);return new o.Point(a,r)},_rebound:function(t,e){return t+e>0?Math.round(t-e)/2:Math.max(0,Math.ceil(t))-Math.max(0,Math.floor(e))},_limitZoom:function(t){var e=this.getMinZoom(),i=this.getMaxZoom();return Math.max(e,Math.min(i,t))}}),o.map=function(t,e){return new o.Map(t,e)},o.Projection.Mercator={MAX_LATITUDE:85.0840591556,R_MINOR:6356752.314245179,R_MAJOR:6378137,project:function(t){var e=o.LatLng.DEG_TO_RAD,i=this.MAX_LATITUDE,n=Math.max(Math.min(i,t.lat),-i),s=this.R_MAJOR,a=this.R_MINOR,r=t.lng*e*s,h=n*e,l=a/s,u=Math.sqrt(1-l*l),c=u*Math.sin(h);c=Math.pow((1-c)/(1+c),.5*u);var d=Math.tan(.5*(.5*Math.PI-h))/c;return h=-s*Math.log(d),new o.Point(r,h)},unproject:function(t){for(var e,i=o.LatLng.RAD_TO_DEG,n=this.R_MAJOR,s=this.R_MINOR,a=t.x*i/n,r=s/n,h=Math.sqrt(1-r*r),l=Math.exp(-t.y/n),u=Math.PI/2-2*Math.atan(l),c=15,d=1e-7,p=c,_=.1;Math.abs(_)>d&&--p>0;)e=h*Math.sin(u),_=Math.PI/2-2*Math.atan(l*Math.pow((1-e)/(1+e),.5*h))-u,u+=_;return new o.LatLng(u*i,a)}},o.CRS.EPSG3395=o.extend({},o.CRS,{code:"EPSG:3395",projection:o.Projection.Mercator,
+transformation:function(){var t=o.Projection.Mercator,e=t.R_MAJOR,i=.5/(Math.PI*e);return new o.Transformation(i,.5,-i,.5)}()}),o.TileLayer=o.Class.extend({includes:o.Mixin.Events,options:{minZoom:0,maxZoom:18,tileSize:256,subdomains:"abc",errorTileUrl:"",attribution:"",zoomOffset:0,opacity:1,unloadInvisibleTiles:o.Browser.mobile,updateWhenIdle:o.Browser.mobile},initialize:function(t,e){e=o.setOptions(this,e),e.detectRetina&&o.Browser.retina&&e.maxZoom>0&&(e.tileSize=Math.floor(e.tileSize/2),e.zoomOffset++,e.minZoom>0&&e.minZoom--,this.options.maxZoom--),e.bounds&&(e.bounds=o.latLngBounds(e.bounds)),this._url=t;var i=this.options.subdomains;"string"==typeof i&&(this.options.subdomains=i.split(""))},onAdd:function(t){this._map=t,this._animated=t._zoomAnimated,this._initContainer(),t.on({viewreset:this._reset,moveend:this._update},this),this._animated&&t.on({zoomanim:this._animateZoom,zoomend:this._endZoomAnim},this),this.options.updateWhenIdle||(this._limitedUpdate=o.Util.limitExecByInterval(this._update,150,this),t.on("move",this._limitedUpdate,this)),this._reset(),this._update()},addTo:function(t){return t.addLayer(this),this},onRemove:function(t){this._container.parentNode.removeChild(this._container),t.off({viewreset:this._reset,moveend:this._update},this),this._animated&&t.off({zoomanim:this._animateZoom,zoomend:this._endZoomAnim},this),this.options.updateWhenIdle||t.off("move",this._limitedUpdate,this),this._container=null,this._map=null},bringToFront:function(){var t=this._map._panes.tilePane;return this._container&&(t.appendChild(this._container),this._setAutoZIndex(t,Math.max)),this},bringToBack:function(){var t=this._map._panes.tilePane;return this._container&&(t.insertBefore(this._container,t.firstChild),this._setAutoZIndex(t,Math.min)),this},getAttribution:function(){return this.options.attribution},getContainer:function(){return this._container},setOpacity:function(t){return this.options.opacity=t,this._map&&this._updateOpacity(),this},setZIndex:function(t){return this.options.zIndex=t,this._updateZIndex(),this},setUrl:function(t,e){return this._url=t,e||this.redraw(),this},redraw:function(){return this._map&&(this._reset({hard:!0}),this._update()),this},_updateZIndex:function(){this._container&&this.options.zIndex!==i&&(this._container.style.zIndex=this.options.zIndex)},_setAutoZIndex:function(t,e){var i,n,o,s=t.children,a=-e(1/0,-(1/0));for(n=0,o=s.length;o>n;n++)s[n]!==this._container&&(i=parseInt(s[n].style.zIndex,10),isNaN(i)||(a=e(a,i)));this.options.zIndex=this._container.style.zIndex=(isFinite(a)?a:0)+e(1,-1)},_updateOpacity:function(){var t,e=this._tiles;if(o.Browser.ielt9)for(t in e)o.DomUtil.setOpacity(e[t],this.options.opacity);else o.DomUtil.setOpacity(this._container,this.options.opacity)},_initContainer:function(){var t=this._map._panes.tilePane;if(!this._container){if(this._container=o.DomUtil.create("div","leaflet-layer"),this._updateZIndex(),this._animated){var e="leaflet-tile-container";this._bgBuffer=o.DomUtil.create("div",e,this._container),this._tileContainer=o.DomUtil.create("div",e,this._container)}else this._tileContainer=this._container;t.appendChild(this._container),this.options.opacity<1&&this._updateOpacity()}},_reset:function(t){for(var e in this._tiles)this.fire("tileunload",{tile:this._tiles[e]});this._tiles={},this._tilesToLoad=0,this.options.reuseTiles&&(this._unusedTiles=[]),this._tileContainer.innerHTML="",this._animated&&t&&t.hard&&this._clearBgBuffer(),this._initContainer()},_getTileSize:function(){var t=this._map,e=t.getZoom()+this.options.zoomOffset,i=this.options.maxNativeZoom,n=this.options.tileSize;return i&&e>i&&(n=Math.round(t.getZoomScale(e)/t.getZoomScale(i)*n)),n},_update:function(){if(this._map){var t=this._map,e=t.getPixelBounds(),i=t.getZoom(),n=this._getTileSize();if(!(i>this.options.maxZoom||i<this.options.minZoom)){var s=o.bounds(e.min.divideBy(n)._floor(),e.max.divideBy(n)._floor());this._addTilesFromCenterOut(s),(this.options.unloadInvisibleTiles||this.options.reuseTiles)&&this._removeOtherTiles(s)}}},_addTilesFromCenterOut:function(t){var i,n,s,a=[],r=t.getCenter();for(i=t.min.y;i<=t.max.y;i++)for(n=t.min.x;n<=t.max.x;n++)s=new o.Point(n,i),this._tileShouldBeLoaded(s)&&a.push(s);var h=a.length;if(0!==h){a.sort(function(t,e){return t.distanceTo(r)-e.distanceTo(r)});var l=e.createDocumentFragment();for(this._tilesToLoad||this.fire("loading"),this._tilesToLoad+=h,n=0;h>n;n++)this._addTile(a[n],l);this._tileContainer.appendChild(l)}},_tileShouldBeLoaded:function(t){if(t.x+":"+t.y in this._tiles)return!1;var e=this.options;if(!e.continuousWorld){var i=this._getWrapTileNum();if(e.noWrap&&(t.x<0||t.x>=i.x)||t.y<0||t.y>=i.y)return!1}if(e.bounds){var n=this._getTileSize(),o=t.multiplyBy(n),s=o.add([n,n]),a=this._map.unproject(o),r=this._map.unproject(s);if(e.continuousWorld||e.noWrap||(a=a.wrap(),r=r.wrap()),!e.bounds.intersects([a,r]))return!1}return!0},_removeOtherTiles:function(t){var e,i,n,o;for(o in this._tiles)e=o.split(":"),i=parseInt(e[0],10),n=parseInt(e[1],10),(i<t.min.x||i>t.max.x||n<t.min.y||n>t.max.y)&&this._removeTile(o)},_removeTile:function(t){var e=this._tiles[t];this.fire("tileunload",{tile:e,url:e.src}),this.options.reuseTiles?(o.DomUtil.removeClass(e,"leaflet-tile-loaded"),this._unusedTiles.push(e)):e.parentNode===this._tileContainer&&this._tileContainer.removeChild(e),o.Browser.android||(e.onload=null,e.src=o.Util.emptyImageUrl),delete this._tiles[t]},_addTile:function(t,e){var i=this._getTilePos(t),n=this._getTile();o.DomUtil.setPosition(n,i,o.Browser.chrome),this._tiles[t.x+":"+t.y]=n,this._loadTile(n,t),n.parentNode!==this._tileContainer&&e.appendChild(n)},_getZoomForUrl:function(){var t=this.options,e=this._map.getZoom();return t.zoomReverse&&(e=t.maxZoom-e),e+=t.zoomOffset,t.maxNativeZoom?Math.min(e,t.maxNativeZoom):e},_getTilePos:function(t){var e=this._map.getPixelOrigin(),i=this._getTileSize();return t.multiplyBy(i).subtract(e)},getTileUrl:function(t){return o.Util.template(this._url,o.extend({s:this._getSubdomain(t),z:t.z,x:t.x,y:t.y},this.options))},_getWrapTileNum:function(){var t=this._map.options.crs,e=t.getSize(this._map.getZoom());return e.divideBy(this._getTileSize())._floor()},_adjustTilePoint:function(t){var e=this._getWrapTileNum();this.options.continuousWorld||this.options.noWrap||(t.x=(t.x%e.x+e.x)%e.x),this.options.tms&&(t.y=e.y-t.y-1),t.z=this._getZoomForUrl()},_getSubdomain:function(t){var e=Math.abs(t.x+t.y)%this.options.subdomains.length;return this.options.subdomains[e]},_getTile:function(){if(this.options.reuseTiles&&this._unusedTiles.length>0){var t=this._unusedTiles.pop();return this._resetTile(t),t}return this._createTile()},_resetTile:function(){},_createTile:function(){var t=o.DomUtil.create("img","leaflet-tile");return t.style.width=t.style.height=this._getTileSize()+"px",t.galleryimg="no",t.onselectstart=t.onmousemove=o.Util.falseFn,o.Browser.ielt9&&this.options.opacity!==i&&o.DomUtil.setOpacity(t,this.options.opacity),o.Browser.mobileWebkit3d&&(t.style.WebkitBackfaceVisibility="hidden"),t},_loadTile:function(t,e){t._layer=this,t.onload=this._tileOnLoad,t.onerror=this._tileOnError,this._adjustTilePoint(e),t.src=this.getTileUrl(e),this.fire("tileloadstart",{tile:t,url:t.src})},_tileLoaded:function(){this._tilesToLoad--,this._animated&&o.DomUtil.addClass(this._tileContainer,"leaflet-zoom-animated"),this._tilesToLoad||(this.fire("load"),this._animated&&(clearTimeout(this._clearBgBufferTimer),this._clearBgBufferTimer=setTimeout(o.bind(this._clearBgBuffer,this),500)))},_tileOnLoad:function(){var t=this._layer;this.src!==o.Util.emptyImageUrl&&(o.DomUtil.addClass(this,"leaflet-tile-loaded"),t.fire("tileload",{tile:this,url:this.src})),t._tileLoaded()},_tileOnError:function(){var t=this._layer;t.fire("tileerror",{tile:this,url:this.src});var e=t.options.errorTileUrl;e&&(this.src=e),t._tileLoaded()}}),o.tileLayer=function(t,e){return new o.TileLayer(t,e)},o.TileLayer.WMS=o.TileLayer.extend({defaultWmsParams:{service:"WMS",request:"GetMap",version:"1.1.1",layers:"",styles:"",format:"image/jpeg",transparent:!1},initialize:function(t,e){this._url=t;var i=o.extend({},this.defaultWmsParams),n=e.tileSize||this.options.tileSize;e.detectRetina&&o.Browser.retina?i.width=i.height=2*n:i.width=i.height=n;for(var s in e)this.options.hasOwnProperty(s)||"crs"===s||(i[s]=e[s]);this.wmsParams=i,o.setOptions(this,e)},onAdd:function(t){this._crs=this.options.crs||t.options.crs,this._wmsVersion=parseFloat(this.wmsParams.version);var e=this._wmsVersion>=1.3?"crs":"srs";this.wmsParams[e]=this._crs.code,o.TileLayer.prototype.onAdd.call(this,t)},getTileUrl:function(t){var e=this._map,i=this.options.tileSize,n=t.multiplyBy(i),s=n.add([i,i]),a=this._crs.project(e.unproject(n,t.z)),r=this._crs.project(e.unproject(s,t.z)),h=this._wmsVersion>=1.3&&this._crs===o.CRS.EPSG4326?[r.y,a.x,a.y,r.x].join(","):[a.x,r.y,r.x,a.y].join(","),l=o.Util.template(this._url,{s:this._getSubdomain(t)});return l+o.Util.getParamString(this.wmsParams,l,!0)+"&BBOX="+h},setParams:function(t,e){return o.extend(this.wmsParams,t),e||this.redraw(),this}}),o.tileLayer.wms=function(t,e){return new o.TileLayer.WMS(t,e)},o.TileLayer.Canvas=o.TileLayer.extend({options:{async:!1},initialize:function(t){o.setOptions(this,t)},redraw:function(){this._map&&(this._reset({hard:!0}),this._update());for(var t in this._tiles)this._redrawTile(this._tiles[t]);return this},_redrawTile:function(t){this.drawTile(t,t._tilePoint,this._map._zoom)},_createTile:function(){var t=o.DomUtil.create("canvas","leaflet-tile");return t.width=t.height=this.options.tileSize,t.onselectstart=t.onmousemove=o.Util.falseFn,t},_loadTile:function(t,e){t._layer=this,t._tilePoint=e,this._redrawTile(t),this.options.async||this.tileDrawn(t)},drawTile:function(){},tileDrawn:function(t){this._tileOnLoad.call(t)}}),o.tileLayer.canvas=function(t){return new o.TileLayer.Canvas(t)},o.ImageOverlay=o.Class.extend({includes:o.Mixin.Events,options:{opacity:1},initialize:function(t,e,i){this._url=t,this._bounds=o.latLngBounds(e),o.setOptions(this,i)},onAdd:function(t){this._map=t,this._image||this._initImage(),t._panes.overlayPane.appendChild(this._image),t.on("viewreset",this._reset,this),t.options.zoomAnimation&&o.Browser.any3d&&t.on("zoomanim",this._animateZoom,this),this._reset()},onRemove:function(t){t.getPanes().overlayPane.removeChild(this._image),t.off("viewreset",this._reset,this),t.options.zoomAnimation&&t.off("zoomanim",this._animateZoom,this)},addTo:function(t){return t.addLayer(this),this},setOpacity:function(t){return this.options.opacity=t,this._updateOpacity(),this},bringToFront:function(){return this._image&&this._map._panes.overlayPane.appendChild(this._image),this},bringToBack:function(){var t=this._map._panes.overlayPane;return this._image&&t.insertBefore(this._image,t.firstChild),this},setUrl:function(t){this._url=t,this._image.src=this._url},getAttribution:function(){return this.options.attribution},_initImage:function(){this._image=o.DomUtil.create("img","leaflet-image-layer"),this._map.options.zoomAnimation&&o.Browser.any3d?o.DomUtil.addClass(this._image,"leaflet-zoom-animated"):o.DomUtil.addClass(this._image,"leaflet-zoom-hide"),this._updateOpacity(),o.extend(this._image,{galleryimg:"no",onselectstart:o.Util.falseFn,onmousemove:o.Util.falseFn,onload:o.bind(this._onImageLoad,this),src:this._url})},_animateZoom:function(t){var e=this._map,i=this._image,n=e.getZoomScale(t.zoom),s=this._bounds.getNorthWest(),a=this._bounds.getSouthEast(),r=e._latLngToNewLayerPoint(s,t.zoom,t.center),h=e._latLngToNewLayerPoint(a,t.zoom,t.center)._subtract(r),l=r._add(h._multiplyBy(.5*(1-1/n)));i.style[o.DomUtil.TRANSFORM]=o.DomUtil.getTranslateString(l)+" scale("+n+") "},_reset:function(){var t=this._image,e=this._map.latLngToLayerPoint(this._bounds.getNorthWest()),i=this._map.latLngToLayerPoint(this._bounds.getSouthEast())._subtract(e);o.DomUtil.setPosition(t,e),t.style.width=i.x+"px",t.style.height=i.y+"px"},_onImageLoad:function(){this.fire("load")},_updateOpacity:function(){o.DomUtil.setOpacity(this._image,this.options.opacity)}}),o.imageOverlay=function(t,e,i){return new o.ImageOverlay(t,e,i)},o.Icon=o.Class.extend({options:{className:""},initialize:function(t){o.setOptions(this,t)},createIcon:function(t){return this._createIcon("icon",t)},createShadow:function(t){return this._createIcon("shadow",t)},_createIcon:function(t,e){var i=this._getIconUrl(t);if(!i){if("icon"===t)throw new Error("iconUrl not set in Icon options (see the docs).");return null}var n;return n=e&&"IMG"===e.tagName?this._createImg(i,e):this._createImg(i),this._setIconStyles(n,t),n},_setIconStyles:function(t,e){var i,n=this.options,s=o.point(n[e+"Size"]);i="shadow"===e?o.point(n.shadowAnchor||n.iconAnchor):o.point(n.iconAnchor),!i&&s&&(i=s.divideBy(2,!0)),t.className="leaflet-marker-"+e+" "+n.className,i&&(t.style.marginLeft=-i.x+"px",t.style.marginTop=-i.y+"px"),s&&(t.style.width=s.x+"px",t.style.height=s.y+"px")},_createImg:function(t,i){return i=i||e.createElement("img"),i.src=t,i},_getIconUrl:function(t){return o.Browser.retina&&this.options[t+"RetinaUrl"]?this.options[t+"RetinaUrl"]:this.options[t+"Url"]}}),o.icon=function(t){return new o.Icon(t)},o.Icon.Default=o.Icon.extend({options:{iconSize:[25,41],iconAnchor:[12,41],popupAnchor:[1,-34],shadowSize:[41,41]},_getIconUrl:function(t){var e=t+"Url";if(this.options[e])return this.options[e];o.Browser.retina&&"icon"===t&&(t+="-2x");var i=o.Icon.Default.imagePath;if(!i)throw new Error("Couldn't autodetect L.Icon.Default.imagePath, set it manually.");return i+"/marker-"+t+".png"}}),o.Icon.Default.imagePath=function(){var t,i,n,o,s,a=e.getElementsByTagName("script"),r=/[\/^]leaflet[\-\._]?([\w\-\._]*)\.js\??/;for(t=0,i=a.length;i>t;t++)if(n=a[t].src,o=n.match(r))return s=n.split(r)[0],(s?s+"/":"")+"images"}(),o.Marker=o.Class.extend({includes:o.Mixin.Events,options:{icon:new o.Icon.Default,title:"",alt:"",clickable:!0,draggable:!1,keyboard:!0,zIndexOffset:0,opacity:1,riseOnHover:!1,riseOffset:250},initialize:function(t,e){o.setOptions(this,e),this._latlng=o.latLng(t)},onAdd:function(t){this._map=t,t.on("viewreset",this.update,this),this._initIcon(),this.update(),this.fire("add"),t.options.zoomAnimation&&t.options.markerZoomAnimation&&t.on("zoomanim",this._animateZoom,this)},addTo:function(t){return t.addLayer(this),this},onRemove:function(t){this.dragging&&this.dragging.disable(),this._removeIcon(),this._removeShadow(),this.fire("remove"),t.off({viewreset:this.update,zoomanim:this._animateZoom},this),this._map=null},getLatLng:function(){return this._latlng},setLatLng:function(t){return this._latlng=o.latLng(t),this.update(),this.fire("move",{latlng:this._latlng})},setZIndexOffset:function(t){return this.options.zIndexOffset=t,this.update(),this},setIcon:function(t){return this.options.icon=t,this._map&&(this._initIcon(),this.update()),this._popup&&this.bindPopup(this._popup),this},update:function(){return this._icon&&this._setPos(this._map.latLngToLayerPoint(this._latlng).round()),this},_initIcon:function(){var t=this.options,e=this._map,i=e.options.zoomAnimation&&e.options.markerZoomAnimation,n=i?"leaflet-zoom-animated":"leaflet-zoom-hide",s=t.icon.createIcon(this._icon),a=!1;s!==this._icon&&(this._icon&&this._removeIcon(),a=!0,t.title&&(s.title=t.title),t.alt&&(s.alt=t.alt)),o.DomUtil.addClass(s,n),t.keyboard&&(s.tabIndex="0"),this._icon=s,this._initInteraction(),t.riseOnHover&&o.DomEvent.on(s,"mouseover",this._bringToFront,this).on(s,"mouseout",this._resetZIndex,this);var r=t.icon.createShadow(this._shadow),h=!1;r!==this._shadow&&(this._removeShadow(),h=!0),r&&o.DomUtil.addClass(r,n),this._shadow=r,t.opacity<1&&this._updateOpacity();var l=this._map._panes;a&&l.markerPane.appendChild(this._icon),r&&h&&l.shadowPane.appendChild(this._shadow)},_removeIcon:function(){this.options.riseOnHover&&o.DomEvent.off(this._icon,"mouseover",this._bringToFront).off(this._icon,"mouseout",this._resetZIndex),this._map._panes.markerPane.removeChild(this._icon),this._icon=null},_removeShadow:function(){this._shadow&&this._map._panes.shadowPane.removeChild(this._shadow),this._shadow=null},_setPos:function(t){o.DomUtil.setPosition(this._icon,t),this._shadow&&o.DomUtil.setPosition(this._shadow,t),this._zIndex=t.y+this.options.zIndexOffset,this._resetZIndex()},_updateZIndex:function(t){this._icon.style.zIndex=this._zIndex+t},_animateZoom:function(t){var e=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center).round();this._setPos(e)},_initInteraction:function(){if(this.options.clickable){var t=this._icon,e=["dblclick","mousedown","mouseover","mouseout","contextmenu"];o.DomUtil.addClass(t,"leaflet-clickable"),o.DomEvent.on(t,"click",this._onMouseClick,this),o.DomEvent.on(t,"keypress",this._onKeyPress,this);for(var i=0;i<e.length;i++)o.DomEvent.on(t,e[i],this._fireMouseEvent,this);o.Handler.MarkerDrag&&(this.dragging=new o.Handler.MarkerDrag(this),this.options.draggable&&this.dragging.enable())}},_onMouseClick:function(t){var e=this.dragging&&this.dragging.moved();(this.hasEventListeners(t.type)||e)&&o.DomEvent.stopPropagation(t),e||(this.dragging&&this.dragging._enabled||!this._map.dragging||!this._map.dragging.moved())&&this.fire(t.type,{originalEvent:t,latlng:this._latlng})},_onKeyPress:function(t){13===t.keyCode&&this.fire("click",{originalEvent:t,latlng:this._latlng})},_fireMouseEvent:function(t){this.fire(t.type,{originalEvent:t,latlng:this._latlng}),"contextmenu"===t.type&&this.hasEventListeners(t.type)&&o.DomEvent.preventDefault(t),"mousedown"!==t.type?o.DomEvent.stopPropagation(t):o.DomEvent.preventDefault(t)},setOpacity:function(t){return this.options.opacity=t,this._map&&this._updateOpacity(),this},_updateOpacity:function(){o.DomUtil.setOpacity(this._icon,this.options.opacity),this._shadow&&o.DomUtil.setOpacity(this._shadow,this.options.opacity)},_bringToFront:function(){this._updateZIndex(this.options.riseOffset)},_resetZIndex:function(){this._updateZIndex(0)}}),o.marker=function(t,e){return new o.Marker(t,e)},o.DivIcon=o.Icon.extend({options:{iconSize:[12,12],className:"leaflet-div-icon",html:!1},createIcon:function(t){var i=t&&"DIV"===t.tagName?t:e.createElement("div"),n=this.options;return n.html!==!1?i.innerHTML=n.html:i.innerHTML="",n.bgPos&&(i.style.backgroundPosition=-n.bgPos.x+"px "+-n.bgPos.y+"px"),this._setIconStyles(i,"icon"),i},createShadow:function(){return null}}),o.divIcon=function(t){return new o.DivIcon(t)},o.Map.mergeOptions({closePopupOnClick:!0}),o.Popup=o.Class.extend({includes:o.Mixin.Events,options:{minWidth:50,maxWidth:300,autoPan:!0,closeButton:!0,offset:[0,7],autoPanPadding:[5,5],keepInView:!1,className:"",zoomAnimation:!0},initialize:function(t,e){o.setOptions(this,t),this._source=e,this._animated=o.Browser.any3d&&this.options.zoomAnimation,this._isOpen=!1},onAdd:function(t){this._map=t,this._container||this._initLayout();var e=t.options.fadeAnimation;e&&o.DomUtil.setOpacity(this._container,0),t._panes.popupPane.appendChild(this._container),t.on(this._getEvents(),this),this.update(),e&&o.DomUtil.setOpacity(this._container,1),this.fire("open"),t.fire("popupopen",{popup:this}),this._source&&this._source.fire("popupopen",{popup:this})},addTo:function(t){return t.addLayer(this),this},openOn:function(t){return t.openPopup(this),this},onRemove:function(t){t._panes.popupPane.removeChild(this._container),o.Util.falseFn(this._container.offsetWidth),t.off(this._getEvents(),this),t.options.fadeAnimation&&o.DomUtil.setOpacity(this._container,0),this._map=null,this.fire("close"),t.fire("popupclose",{popup:this}),this._source&&this._source.fire("popupclose",{popup:this})},getLatLng:function(){return this._latlng},setLatLng:function(t){return this._latlng=o.latLng(t),this._map&&(this._updatePosition(),this._adjustPan()),this},getContent:function(){return this._content},setContent:function(t){return this._content=t,this.update(),this},update:function(){this._map&&(this._container.style.visibility="hidden",this._updateContent(),this._updateLayout(),this._updatePosition(),this._container.style.visibility="",this._adjustPan())},_getEvents:function(){var t={viewreset:this._updatePosition};return this._animated&&(t.zoomanim=this._zoomAnimation),("closeOnClick"in this.options?this.options.closeOnClick:this._map.options.closePopupOnClick)&&(t.preclick=this._close),this.options.keepInView&&(t.moveend=this._adjustPan),t},_close:function(){this._map&&this._map.closePopup(this)},_initLayout:function(){var t,e="leaflet-popup",i=e+" "+this.options.className+" leaflet-zoom-"+(this._animated?"animated":"hide"),n=this._container=o.DomUtil.create("div",i);this.options.closeButton&&(t=this._closeButton=o.DomUtil.create("a",e+"-close-button",n),t.href="#close",t.innerHTML="&#215;",o.DomEvent.disableClickPropagation(t),o.DomEvent.on(t,"click",this._onCloseButtonClick,this));var s=this._wrapper=o.DomUtil.create("div",e+"-content-wrapper",n);o.DomEvent.disableClickPropagation(s),this._contentNode=o.DomUtil.create("div",e+"-content",s),o.DomEvent.disableScrollPropagation(this._contentNode),o.DomEvent.on(s,"contextmenu",o.DomEvent.stopPropagation),this._tipContainer=o.DomUtil.create("div",e+"-tip-container",n),this._tip=o.DomUtil.create("div",e+"-tip",this._tipContainer)},_updateContent:function(){if(this._content){if("string"==typeof this._content)this._contentNode.innerHTML=this._content;else{for(;this._contentNode.hasChildNodes();)this._contentNode.removeChild(this._contentNode.firstChild);this._contentNode.appendChild(this._content)}this.fire("contentupdate")}},_updateLayout:function(){var t=this._contentNode,e=t.style;e.width="",e.whiteSpace="nowrap";var i=t.offsetWidth;i=Math.min(i,this.options.maxWidth),i=Math.max(i,this.options.minWidth),e.width=i+1+"px",e.whiteSpace="",e.height="";var n=t.offsetHeight,s=this.options.maxHeight,a="leaflet-popup-scrolled";s&&n>s?(e.height=s+"px",o.DomUtil.addClass(t,a)):o.DomUtil.removeClass(t,a),this._containerWidth=this._container.offsetWidth},_updatePosition:function(){if(this._map){var t=this._map.latLngToLayerPoint(this._latlng),e=this._animated,i=o.point(this.options.offset);e&&o.DomUtil.setPosition(this._container,t),this._containerBottom=-i.y-(e?0:t.y),this._containerLeft=-Math.round(this._containerWidth/2)+i.x+(e?0:t.x),this._container.style.bottom=this._containerBottom+"px",this._container.style.left=this._containerLeft+"px"}},_zoomAnimation:function(t){var e=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center);o.DomUtil.setPosition(this._container,e)},_adjustPan:function(){if(this.options.autoPan){var t=this._map,e=this._container.offsetHeight,i=this._containerWidth,n=new o.Point(this._containerLeft,-e-this._containerBottom);this._animated&&n._add(o.DomUtil.getPosition(this._container));var s=t.layerPointToContainerPoint(n),a=o.point(this.options.autoPanPadding),r=o.point(this.options.autoPanPaddingTopLeft||a),h=o.point(this.options.autoPanPaddingBottomRight||a),l=t.getSize(),u=0,c=0;s.x+i+h.x>l.x&&(u=s.x+i-l.x+h.x),s.x-u-r.x<0&&(u=s.x-r.x),s.y+e+h.y>l.y&&(c=s.y+e-l.y+h.y),s.y-c-r.y<0&&(c=s.y-r.y),(u||c)&&t.fire("autopanstart").panBy([u,c])}},_onCloseButtonClick:function(t){this._close(),o.DomEvent.stop(t)}}),o.popup=function(t,e){return new o.Popup(t,e)},o.Map.include({openPopup:function(t,e,i){if(this.closePopup(),!(t instanceof o.Popup)){var n=t;t=new o.Popup(i).setLatLng(e).setContent(n)}return t._isOpen=!0,this._popup=t,this.addLayer(t)},closePopup:function(t){return t&&t!==this._popup||(t=this._popup,this._popup=null),t&&(this.removeLayer(t),t._isOpen=!1),this}}),o.Marker.include({openPopup:function(){return this._popup&&this._map&&!this._map.hasLayer(this._popup)&&(this._popup.setLatLng(this._latlng),this._map.openPopup(this._popup)),this},closePopup:function(){return this._popup&&this._popup._close(),this},togglePopup:function(){return this._popup&&(this._popup._isOpen?this.closePopup():this.openPopup()),this},bindPopup:function(t,e){var i=o.point(this.options.icon.options.popupAnchor||[0,0]);return i=i.add(o.Popup.prototype.options.offset),e&&e.offset&&(i=i.add(e.offset)),e=o.extend({offset:i},e),this._popupHandlersAdded||(this.on("click",this.togglePopup,this).on("remove",this.closePopup,this).on("move",this._movePopup,this),this._popupHandlersAdded=!0),t instanceof o.Popup?(o.setOptions(t,e),this._popup=t,t._source=this):this._popup=new o.Popup(e,this).setContent(t),this},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},unbindPopup:function(){return this._popup&&(this._popup=null,this.off("click",this.togglePopup,this).off("remove",this.closePopup,this).off("move",this._movePopup,this),this._popupHandlersAdded=!1),this},getPopup:function(){return this._popup},_movePopup:function(t){this._popup.setLatLng(t.latlng)}}),o.LayerGroup=o.Class.extend({initialize:function(t){this._layers={};var e,i;if(t)for(e=0,i=t.length;i>e;e++)this.addLayer(t[e])},addLayer:function(t){var e=this.getLayerId(t);return this._layers[e]=t,this._map&&this._map.addLayer(t),this},removeLayer:function(t){var e=t in this._layers?t:this.getLayerId(t);return this._map&&this._layers[e]&&this._map.removeLayer(this._layers[e]),delete this._layers[e],this},hasLayer:function(t){return t?t in this._layers||this.getLayerId(t)in this._layers:!1},clearLayers:function(){return this.eachLayer(this.removeLayer,this),this},invoke:function(t){var e,i,n=Array.prototype.slice.call(arguments,1);for(e in this._layers)i=this._layers[e],i[t]&&i[t].apply(i,n);return this},onAdd:function(t){this._map=t,this.eachLayer(t.addLayer,t)},onRemove:function(t){this.eachLayer(t.removeLayer,t),this._map=null},addTo:function(t){return t.addLayer(this),this},eachLayer:function(t,e){for(var i in this._layers)t.call(e,this._layers[i]);return this},getLayer:function(t){return this._layers[t]},getLayers:function(){var t=[];for(var e in this._layers)t.push(this._layers[e]);return t},setZIndex:function(t){return this.invoke("setZIndex",t)},getLayerId:function(t){return o.stamp(t)}}),o.layerGroup=function(t){return new o.LayerGroup(t)},o.FeatureGroup=o.LayerGroup.extend({includes:o.Mixin.Events,statics:{EVENTS:"click dblclick mouseover mouseout mousemove contextmenu popupopen popupclose"},addLayer:function(t){return this.hasLayer(t)?this:("on"in t&&t.on(o.FeatureGroup.EVENTS,this._propagateEvent,this),o.LayerGroup.prototype.addLayer.call(this,t),this._popupContent&&t.bindPopup&&t.bindPopup(this._popupContent,this._popupOptions),this.fire("layeradd",{layer:t}))},removeLayer:function(t){return this.hasLayer(t)?(t in this._layers&&(t=this._layers[t]),"off"in t&&t.off(o.FeatureGroup.EVENTS,this._propagateEvent,this),o.LayerGroup.prototype.removeLayer.call(this,t),this._popupContent&&this.invoke("unbindPopup"),this.fire("layerremove",{layer:t})):this},bindPopup:function(t,e){return this._popupContent=t,this._popupOptions=e,this.invoke("bindPopup",t,e)},openPopup:function(t){for(var e in this._layers){this._layers[e].openPopup(t);break}return this},setStyle:function(t){return this.invoke("setStyle",t)},bringToFront:function(){return this.invoke("bringToFront")},bringToBack:function(){return this.invoke("bringToBack")},getBounds:function(){var t=new o.LatLngBounds;return this.eachLayer(function(e){t.extend(e instanceof o.Marker?e.getLatLng():e.getBounds())}),t},_propagateEvent:function(t){t=o.extend({layer:t.target,target:this},t),this.fire(t.type,t)}}),o.featureGroup=function(t){return new o.FeatureGroup(t)},o.Path=o.Class.extend({includes:[o.Mixin.Events],statics:{CLIP_PADDING:function(){var e=o.Browser.mobile?1280:2e3,i=(e/Math.max(t.outerWidth,t.outerHeight)-1)/2;return Math.max(0,Math.min(.5,i))}()},options:{stroke:!0,color:"#0033ff",dashArray:null,lineCap:null,lineJoin:null,weight:5,opacity:.5,fill:!1,fillColor:null,fillOpacity:.2,clickable:!0},initialize:function(t){o.setOptions(this,t)},onAdd:function(t){this._map=t,this._container||(this._initElements(),this._initEvents()),this.projectLatlngs(),this._updatePath(),this._container&&this._map._pathRoot.appendChild(this._container),this.fire("add"),t.on({viewreset:this.projectLatlngs,moveend:this._updatePath},this)},addTo:function(t){return t.addLayer(this),this},onRemove:function(t){t._pathRoot.removeChild(this._container),this.fire("remove"),this._map=null,o.Browser.vml&&(this._container=null,this._stroke=null,this._fill=null),t.off({viewreset:this.projectLatlngs,moveend:this._updatePath},this)},projectLatlngs:function(){},setStyle:function(t){return o.setOptions(this,t),this._container&&this._updateStyle(),this},redraw:function(){return this._map&&(this.projectLatlngs(),this._updatePath()),this}}),o.Map.include({_updatePathViewport:function(){var t=o.Path.CLIP_PADDING,e=this.getSize(),i=o.DomUtil.getPosition(this._mapPane),n=i.multiplyBy(-1)._subtract(e.multiplyBy(t)._round()),s=n.add(e.multiplyBy(1+2*t)._round());this._pathViewport=new o.Bounds(n,s)}}),o.Path.SVG_NS="http://www.w3.org/2000/svg",o.Browser.svg=!(!e.createElementNS||!e.createElementNS(o.Path.SVG_NS,"svg").createSVGRect),o.Path=o.Path.extend({statics:{SVG:o.Browser.svg},bringToFront:function(){var t=this._map._pathRoot,e=this._container;return e&&t.lastChild!==e&&t.appendChild(e),this},bringToBack:function(){var t=this._map._pathRoot,e=this._container,i=t.firstChild;return e&&i!==e&&t.insertBefore(e,i),this},getPathString:function(){},_createElement:function(t){return e.createElementNS(o.Path.SVG_NS,t)},_initElements:function(){this._map._initPathRoot(),this._initPath(),this._initStyle()},_initPath:function(){this._container=this._createElement("g"),this._path=this._createElement("path"),this.options.className&&o.DomUtil.addClass(this._path,this.options.className),this._container.appendChild(this._path)},_initStyle:function(){this.options.stroke&&(this._path.setAttribute("stroke-linejoin","round"),this._path.setAttribute("stroke-linecap","round")),this.options.fill&&this._path.setAttribute("fill-rule","evenodd"),this.options.pointerEvents&&this._path.setAttribute("pointer-events",this.options.pointerEvents),this.options.clickable||this.options.pointerEvents||this._path.setAttribute("pointer-events","none"),this._updateStyle()},_updateStyle:function(){this.options.stroke?(this._path.setAttribute("stroke",this.options.color),this._path.setAttribute("stroke-opacity",this.options.opacity),this._path.setAttribute("stroke-width",this.options.weight),this.options.dashArray?this._path.setAttribute("stroke-dasharray",this.options.dashArray):this._path.removeAttribute("stroke-dasharray"),this.options.lineCap&&this._path.setAttribute("stroke-linecap",this.options.lineCap),this.options.lineJoin&&this._path.setAttribute("stroke-linejoin",this.options.lineJoin)):this._path.setAttribute("stroke","none"),this.options.fill?(this._path.setAttribute("fill",this.options.fillColor||this.options.color),this._path.setAttribute("fill-opacity",this.options.fillOpacity)):this._path.setAttribute("fill","none")},_updatePath:function(){var t=this.getPathString();t||(t="M0 0"),this._path.setAttribute("d",t)},_initEvents:function(){if(this.options.clickable){(o.Browser.svg||!o.Browser.vml)&&o.DomUtil.addClass(this._path,"leaflet-clickable"),o.DomEvent.on(this._container,"click",this._onMouseClick,this);for(var t=["dblclick","mousedown","mouseover","mouseout","mousemove","contextmenu"],e=0;e<t.length;e++)o.DomEvent.on(this._container,t[e],this._fireMouseEvent,this)}},_onMouseClick:function(t){this._map.dragging&&this._map.dragging.moved()||this._fireMouseEvent(t)},_fireMouseEvent:function(t){if(this._map&&this.hasEventListeners(t.type)){var e=this._map,i=e.mouseEventToContainerPoint(t),n=e.containerPointToLayerPoint(i),s=e.layerPointToLatLng(n);this.fire(t.type,{latlng:s,layerPoint:n,containerPoint:i,originalEvent:t}),"contextmenu"===t.type&&o.DomEvent.preventDefault(t),"mousemove"!==t.type&&o.DomEvent.stopPropagation(t)}}}),o.Map.include({_initPathRoot:function(){this._pathRoot||(this._pathRoot=o.Path.prototype._createElement("svg"),this._panes.overlayPane.appendChild(this._pathRoot),this.options.zoomAnimation&&o.Browser.any3d?(o.DomUtil.addClass(this._pathRoot,"leaflet-zoom-animated"),
+this.on({zoomanim:this._animatePathZoom,zoomend:this._endPathZoom})):o.DomUtil.addClass(this._pathRoot,"leaflet-zoom-hide"),this.on("moveend",this._updateSvgViewport),this._updateSvgViewport())},_animatePathZoom:function(t){var e=this.getZoomScale(t.zoom),i=this._getCenterOffset(t.center)._multiplyBy(-e)._add(this._pathViewport.min);this._pathRoot.style[o.DomUtil.TRANSFORM]=o.DomUtil.getTranslateString(i)+" scale("+e+") ",this._pathZooming=!0},_endPathZoom:function(){this._pathZooming=!1},_updateSvgViewport:function(){if(!this._pathZooming){this._updatePathViewport();var t=this._pathViewport,e=t.min,i=t.max,n=i.x-e.x,s=i.y-e.y,a=this._pathRoot,r=this._panes.overlayPane;o.Browser.mobileWebkit&&r.removeChild(a),o.DomUtil.setPosition(a,e),a.setAttribute("width",n),a.setAttribute("height",s),a.setAttribute("viewBox",[e.x,e.y,n,s].join(" ")),o.Browser.mobileWebkit&&r.appendChild(a)}}}),o.Path.include({bindPopup:function(t,e){return t instanceof o.Popup?this._popup=t:((!this._popup||e)&&(this._popup=new o.Popup(e,this)),this._popup.setContent(t)),this._popupHandlersAdded||(this.on("click",this._openPopup,this).on("remove",this.closePopup,this),this._popupHandlersAdded=!0),this},unbindPopup:function(){return this._popup&&(this._popup=null,this.off("click",this._openPopup).off("remove",this.closePopup),this._popupHandlersAdded=!1),this},openPopup:function(t){return this._popup&&(t=t||this._latlng||this._latlngs[Math.floor(this._latlngs.length/2)],this._openPopup({latlng:t})),this},closePopup:function(){return this._popup&&this._popup._close(),this},_openPopup:function(t){this._popup.setLatLng(t.latlng),this._map.openPopup(this._popup)}}),o.Browser.vml=!o.Browser.svg&&function(){try{var t=e.createElement("div");t.innerHTML='<v:shape adj="1"/>';var i=t.firstChild;return i.style.behavior="url(#default#VML)",i&&"object"==typeof i.adj}catch(n){return!1}}(),o.Path=o.Browser.svg||!o.Browser.vml?o.Path:o.Path.extend({statics:{VML:!0,CLIP_PADDING:.02},_createElement:function(){try{return e.namespaces.add("lvml","urn:schemas-microsoft-com:vml"),function(t){return e.createElement("<lvml:"+t+' class="lvml">')}}catch(t){return function(t){return e.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}}(),_initPath:function(){var t=this._container=this._createElement("shape");o.DomUtil.addClass(t,"leaflet-vml-shape"+(this.options.className?" "+this.options.className:"")),this.options.clickable&&o.DomUtil.addClass(t,"leaflet-clickable"),t.coordsize="1 1",this._path=this._createElement("path"),t.appendChild(this._path),this._map._pathRoot.appendChild(t)},_initStyle:function(){this._updateStyle()},_updateStyle:function(){var t=this._stroke,e=this._fill,i=this.options,n=this._container;n.stroked=i.stroke,n.filled=i.fill,i.stroke?(t||(t=this._stroke=this._createElement("stroke"),t.endcap="round",n.appendChild(t)),t.weight=i.weight+"px",t.color=i.color,t.opacity=i.opacity,i.dashArray?t.dashStyle=o.Util.isArray(i.dashArray)?i.dashArray.join(" "):i.dashArray.replace(/( *, *)/g," "):t.dashStyle="",i.lineCap&&(t.endcap=i.lineCap.replace("butt","flat")),i.lineJoin&&(t.joinstyle=i.lineJoin)):t&&(n.removeChild(t),this._stroke=null),i.fill?(e||(e=this._fill=this._createElement("fill"),n.appendChild(e)),e.color=i.fillColor||i.color,e.opacity=i.fillOpacity):e&&(n.removeChild(e),this._fill=null)},_updatePath:function(){var t=this._container.style;t.display="none",this._path.v=this.getPathString()+" ",t.display=""}}),o.Map.include(o.Browser.svg||!o.Browser.vml?{}:{_initPathRoot:function(){if(!this._pathRoot){var t=this._pathRoot=e.createElement("div");t.className="leaflet-vml-container",this._panes.overlayPane.appendChild(t),this.on("moveend",this._updatePathViewport),this._updatePathViewport()}}}),o.Browser.canvas=function(){return!!e.createElement("canvas").getContext}(),o.Path=o.Path.SVG&&!t.L_PREFER_CANVAS||!o.Browser.canvas?o.Path:o.Path.extend({statics:{CANVAS:!0,SVG:!1},redraw:function(){return this._map&&(this.projectLatlngs(),this._requestUpdate()),this},setStyle:function(t){return o.setOptions(this,t),this._map&&(this._updateStyle(),this._requestUpdate()),this},onRemove:function(t){t.off("viewreset",this.projectLatlngs,this).off("moveend",this._updatePath,this),this.options.clickable&&(this._map.off("click",this._onClick,this),this._map.off("mousemove",this._onMouseMove,this)),this._requestUpdate(),this.fire("remove"),this._map=null},_requestUpdate:function(){this._map&&!o.Path._updateRequest&&(o.Path._updateRequest=o.Util.requestAnimFrame(this._fireMapMoveEnd,this._map))},_fireMapMoveEnd:function(){o.Path._updateRequest=null,this.fire("moveend")},_initElements:function(){this._map._initPathRoot(),this._ctx=this._map._canvasCtx},_updateStyle:function(){var t=this.options;t.stroke&&(this._ctx.lineWidth=t.weight,this._ctx.strokeStyle=t.color),t.fill&&(this._ctx.fillStyle=t.fillColor||t.color),t.lineCap&&(this._ctx.lineCap=t.lineCap),t.lineJoin&&(this._ctx.lineJoin=t.lineJoin)},_drawPath:function(){var t,e,i,n,s,a;for(this._ctx.beginPath(),t=0,i=this._parts.length;i>t;t++){for(e=0,n=this._parts[t].length;n>e;e++)s=this._parts[t][e],a=(0===e?"move":"line")+"To",this._ctx[a](s.x,s.y);this instanceof o.Polygon&&this._ctx.closePath()}},_checkIfEmpty:function(){return!this._parts.length},_updatePath:function(){if(!this._checkIfEmpty()){var t=this._ctx,e=this.options;this._drawPath(),t.save(),this._updateStyle(),e.fill&&(t.globalAlpha=e.fillOpacity,t.fill(e.fillRule||"evenodd")),e.stroke&&(t.globalAlpha=e.opacity,t.stroke()),t.restore()}},_initEvents:function(){this.options.clickable&&(this._map.on("mousemove",this._onMouseMove,this),this._map.on("click dblclick contextmenu",this._fireMouseEvent,this))},_fireMouseEvent:function(t){this._containsPoint(t.layerPoint)&&this.fire(t.type,t)},_onMouseMove:function(t){this._map&&!this._map._animatingZoom&&(this._containsPoint(t.layerPoint)?(this._ctx.canvas.style.cursor="pointer",this._mouseInside=!0,this.fire("mouseover",t)):this._mouseInside&&(this._ctx.canvas.style.cursor="",this._mouseInside=!1,this.fire("mouseout",t)))}}),o.Map.include(o.Path.SVG&&!t.L_PREFER_CANVAS||!o.Browser.canvas?{}:{_initPathRoot:function(){var t,i=this._pathRoot;i||(i=this._pathRoot=e.createElement("canvas"),i.style.position="absolute",t=this._canvasCtx=i.getContext("2d"),t.lineCap="round",t.lineJoin="round",this._panes.overlayPane.appendChild(i),this.options.zoomAnimation&&(this._pathRoot.className="leaflet-zoom-animated",this.on("zoomanim",this._animatePathZoom),this.on("zoomend",this._endPathZoom)),this.on("moveend",this._updateCanvasViewport),this._updateCanvasViewport())},_updateCanvasViewport:function(){if(!this._pathZooming){this._updatePathViewport();var t=this._pathViewport,e=t.min,i=t.max.subtract(e),n=this._pathRoot;o.DomUtil.setPosition(n,e),n.width=i.x,n.height=i.y,n.getContext("2d").translate(-e.x,-e.y)}}}),o.LineUtil={simplify:function(t,e){if(!e||!t.length)return t.slice();var i=e*e;return t=this._reducePoints(t,i),t=this._simplifyDP(t,i)},pointToSegmentDistance:function(t,e,i){return Math.sqrt(this._sqClosestPointOnSegment(t,e,i,!0))},closestPointOnSegment:function(t,e,i){return this._sqClosestPointOnSegment(t,e,i)},_simplifyDP:function(t,e){var n=t.length,o=typeof Uint8Array!=i+""?Uint8Array:Array,s=new o(n);s[0]=s[n-1]=1,this._simplifyDPStep(t,s,e,0,n-1);var a,r=[];for(a=0;n>a;a++)s[a]&&r.push(t[a]);return r},_simplifyDPStep:function(t,e,i,n,o){var s,a,r,h=0;for(a=n+1;o-1>=a;a++)r=this._sqClosestPointOnSegment(t[a],t[n],t[o],!0),r>h&&(s=a,h=r);h>i&&(e[s]=1,this._simplifyDPStep(t,e,i,n,s),this._simplifyDPStep(t,e,i,s,o))},_reducePoints:function(t,e){for(var i=[t[0]],n=1,o=0,s=t.length;s>n;n++)this._sqDist(t[n],t[o])>e&&(i.push(t[n]),o=n);return s-1>o&&i.push(t[s-1]),i},clipSegment:function(t,e,i,n){var o,s,a,r=n?this._lastCode:this._getBitCode(t,i),h=this._getBitCode(e,i);for(this._lastCode=h;;){if(!(r|h))return[t,e];if(r&h)return!1;o=r||h,s=this._getEdgeIntersection(t,e,o,i),a=this._getBitCode(s,i),o===r?(t=s,r=a):(e=s,h=a)}},_getEdgeIntersection:function(t,e,i,n){var s=e.x-t.x,a=e.y-t.y,r=n.min,h=n.max;return 8&i?new o.Point(t.x+s*(h.y-t.y)/a,h.y):4&i?new o.Point(t.x+s*(r.y-t.y)/a,r.y):2&i?new o.Point(h.x,t.y+a*(h.x-t.x)/s):1&i?new o.Point(r.x,t.y+a*(r.x-t.x)/s):void 0},_getBitCode:function(t,e){var i=0;return t.x<e.min.x?i|=1:t.x>e.max.x&&(i|=2),t.y<e.min.y?i|=4:t.y>e.max.y&&(i|=8),i},_sqDist:function(t,e){var i=e.x-t.x,n=e.y-t.y;return i*i+n*n},_sqClosestPointOnSegment:function(t,e,i,n){var s,a=e.x,r=e.y,h=i.x-a,l=i.y-r,u=h*h+l*l;return u>0&&(s=((t.x-a)*h+(t.y-r)*l)/u,s>1?(a=i.x,r=i.y):s>0&&(a+=h*s,r+=l*s)),h=t.x-a,l=t.y-r,n?h*h+l*l:new o.Point(a,r)}},o.Polyline=o.Path.extend({initialize:function(t,e){o.Path.prototype.initialize.call(this,e),this._latlngs=this._convertLatLngs(t)},options:{smoothFactor:1,noClip:!1},projectLatlngs:function(){this._originalPoints=[];for(var t=0,e=this._latlngs.length;e>t;t++)this._originalPoints[t]=this._map.latLngToLayerPoint(this._latlngs[t])},getPathString:function(){for(var t=0,e=this._parts.length,i="";e>t;t++)i+=this._getPathPartStr(this._parts[t]);return i},getLatLngs:function(){return this._latlngs},setLatLngs:function(t){return this._latlngs=this._convertLatLngs(t),this.redraw()},addLatLng:function(t){return this._latlngs.push(o.latLng(t)),this.redraw()},spliceLatLngs:function(){var t=[].splice.apply(this._latlngs,arguments);return this._convertLatLngs(this._latlngs,!0),this.redraw(),t},closestLayerPoint:function(t){for(var e,i,n=1/0,s=this._parts,a=null,r=0,h=s.length;h>r;r++)for(var l=s[r],u=1,c=l.length;c>u;u++){e=l[u-1],i=l[u];var d=o.LineUtil._sqClosestPointOnSegment(t,e,i,!0);n>d&&(n=d,a=o.LineUtil._sqClosestPointOnSegment(t,e,i))}return a&&(a.distance=Math.sqrt(n)),a},getBounds:function(){return new o.LatLngBounds(this.getLatLngs())},_convertLatLngs:function(t,e){var i,n,s=e?t:[];for(i=0,n=t.length;n>i;i++){if(o.Util.isArray(t[i])&&"number"!=typeof t[i][0])return;s[i]=o.latLng(t[i])}return s},_initEvents:function(){o.Path.prototype._initEvents.call(this)},_getPathPartStr:function(t){for(var e,i=o.Path.VML,n=0,s=t.length,a="";s>n;n++)e=t[n],i&&e._round(),a+=(n?"L":"M")+e.x+" "+e.y;return a},_clipPoints:function(){var t,e,i,n=this._originalPoints,s=n.length;if(this.options.noClip)return void(this._parts=[n]);this._parts=[];var a=this._parts,r=this._map._pathViewport,h=o.LineUtil;for(t=0,e=0;s-1>t;t++)i=h.clipSegment(n[t],n[t+1],r,t),i&&(a[e]=a[e]||[],a[e].push(i[0]),(i[1]!==n[t+1]||t===s-2)&&(a[e].push(i[1]),e++))},_simplifyPoints:function(){for(var t=this._parts,e=o.LineUtil,i=0,n=t.length;n>i;i++)t[i]=e.simplify(t[i],this.options.smoothFactor)},_updatePath:function(){this._map&&(this._clipPoints(),this._simplifyPoints(),o.Path.prototype._updatePath.call(this))}}),o.polyline=function(t,e){return new o.Polyline(t,e)},o.PolyUtil={},o.PolyUtil.clipPolygon=function(t,e){var i,n,s,a,r,h,l,u,c,d=[1,4,2,8],p=o.LineUtil;for(n=0,l=t.length;l>n;n++)t[n]._code=p._getBitCode(t[n],e);for(a=0;4>a;a++){for(u=d[a],i=[],n=0,l=t.length,s=l-1;l>n;s=n++)r=t[n],h=t[s],r._code&u?h._code&u||(c=p._getEdgeIntersection(h,r,u,e),c._code=p._getBitCode(c,e),i.push(c)):(h._code&u&&(c=p._getEdgeIntersection(h,r,u,e),c._code=p._getBitCode(c,e),i.push(c)),i.push(r));t=i}return t},o.Polygon=o.Polyline.extend({options:{fill:!0},initialize:function(t,e){o.Polyline.prototype.initialize.call(this,t,e),this._initWithHoles(t)},_initWithHoles:function(t){var e,i,n;if(t&&o.Util.isArray(t[0])&&"number"!=typeof t[0][0])for(this._latlngs=this._convertLatLngs(t[0]),this._holes=t.slice(1),e=0,i=this._holes.length;i>e;e++)n=this._holes[e]=this._convertLatLngs(this._holes[e]),n[0].equals(n[n.length-1])&&n.pop();t=this._latlngs,t.length>=2&&t[0].equals(t[t.length-1])&&t.pop()},projectLatlngs:function(){if(o.Polyline.prototype.projectLatlngs.call(this),this._holePoints=[],this._holes){var t,e,i,n;for(t=0,i=this._holes.length;i>t;t++)for(this._holePoints[t]=[],e=0,n=this._holes[t].length;n>e;e++)this._holePoints[t][e]=this._map.latLngToLayerPoint(this._holes[t][e])}},setLatLngs:function(t){return t&&o.Util.isArray(t[0])&&"number"!=typeof t[0][0]?(this._initWithHoles(t),this.redraw()):o.Polyline.prototype.setLatLngs.call(this,t)},_clipPoints:function(){var t=this._originalPoints,e=[];if(this._parts=[t].concat(this._holePoints),!this.options.noClip){for(var i=0,n=this._parts.length;n>i;i++){var s=o.PolyUtil.clipPolygon(this._parts[i],this._map._pathViewport);s.length&&e.push(s)}this._parts=e}},_getPathPartStr:function(t){var e=o.Polyline.prototype._getPathPartStr.call(this,t);return e+(o.Browser.svg?"z":"x")}}),o.polygon=function(t,e){return new o.Polygon(t,e)},function(){function t(t){return o.FeatureGroup.extend({initialize:function(t,e){this._layers={},this._options=e,this.setLatLngs(t)},setLatLngs:function(e){var i=0,n=e.length;for(this.eachLayer(function(t){n>i?t.setLatLngs(e[i++]):this.removeLayer(t)},this);n>i;)this.addLayer(new t(e[i++],this._options));return this},getLatLngs:function(){var t=[];return this.eachLayer(function(e){t.push(e.getLatLngs())}),t}})}o.MultiPolyline=t(o.Polyline),o.MultiPolygon=t(o.Polygon),o.multiPolyline=function(t,e){return new o.MultiPolyline(t,e)},o.multiPolygon=function(t,e){return new o.MultiPolygon(t,e)}}(),o.Rectangle=o.Polygon.extend({initialize:function(t,e){o.Polygon.prototype.initialize.call(this,this._boundsToLatLngs(t),e)},setBounds:function(t){this.setLatLngs(this._boundsToLatLngs(t))},_boundsToLatLngs:function(t){return t=o.latLngBounds(t),[t.getSouthWest(),t.getNorthWest(),t.getNorthEast(),t.getSouthEast()]}}),o.rectangle=function(t,e){return new o.Rectangle(t,e)},o.Circle=o.Path.extend({initialize:function(t,e,i){o.Path.prototype.initialize.call(this,i),this._latlng=o.latLng(t),this._mRadius=e},options:{fill:!0},setLatLng:function(t){return this._latlng=o.latLng(t),this.redraw()},setRadius:function(t){return this._mRadius=t,this.redraw()},projectLatlngs:function(){var t=this._getLngRadius(),e=this._latlng,i=this._map.latLngToLayerPoint([e.lat,e.lng-t]);this._point=this._map.latLngToLayerPoint(e),this._radius=Math.max(this._point.x-i.x,1)},getBounds:function(){var t=this._getLngRadius(),e=this._mRadius/40075017*360,i=this._latlng;return new o.LatLngBounds([i.lat-e,i.lng-t],[i.lat+e,i.lng+t])},getLatLng:function(){return this._latlng},getPathString:function(){var t=this._point,e=this._radius;return this._checkIfEmpty()?"":o.Browser.svg?"M"+t.x+","+(t.y-e)+"A"+e+","+e+",0,1,1,"+(t.x-.1)+","+(t.y-e)+" z":(t._round(),e=Math.round(e),"AL "+t.x+","+t.y+" "+e+","+e+" 0,23592600")},getRadius:function(){return this._mRadius},_getLatRadius:function(){return this._mRadius/40075017*360},_getLngRadius:function(){return this._getLatRadius()/Math.cos(o.LatLng.DEG_TO_RAD*this._latlng.lat)},_checkIfEmpty:function(){if(!this._map)return!1;var t=this._map._pathViewport,e=this._radius,i=this._point;return i.x-e>t.max.x||i.y-e>t.max.y||i.x+e<t.min.x||i.y+e<t.min.y}}),o.circle=function(t,e,i){return new o.Circle(t,e,i)},o.CircleMarker=o.Circle.extend({options:{radius:10,weight:2},initialize:function(t,e){o.Circle.prototype.initialize.call(this,t,null,e),this._radius=this.options.radius},projectLatlngs:function(){this._point=this._map.latLngToLayerPoint(this._latlng)},_updateStyle:function(){o.Circle.prototype._updateStyle.call(this),this.setRadius(this.options.radius)},setLatLng:function(t){return o.Circle.prototype.setLatLng.call(this,t),this._popup&&this._popup._isOpen&&this._popup.setLatLng(t),this},setRadius:function(t){return this.options.radius=this._radius=t,this.redraw()},getRadius:function(){return this._radius}}),o.circleMarker=function(t,e){return new o.CircleMarker(t,e)},o.Polyline.include(o.Path.CANVAS?{_containsPoint:function(t,e){var i,n,s,a,r,h,l,u=this.options.weight/2;for(o.Browser.touch&&(u+=10),i=0,a=this._parts.length;a>i;i++)for(l=this._parts[i],n=0,r=l.length,s=r-1;r>n;s=n++)if((e||0!==n)&&(h=o.LineUtil.pointToSegmentDistance(t,l[s],l[n]),u>=h))return!0;return!1}}:{}),o.Polygon.include(o.Path.CANVAS?{_containsPoint:function(t){var e,i,n,s,a,r,h,l,u=!1;if(o.Polyline.prototype._containsPoint.call(this,t,!0))return!0;for(s=0,h=this._parts.length;h>s;s++)for(e=this._parts[s],a=0,l=e.length,r=l-1;l>a;r=a++)i=e[a],n=e[r],i.y>t.y!=n.y>t.y&&t.x<(n.x-i.x)*(t.y-i.y)/(n.y-i.y)+i.x&&(u=!u);return u}}:{}),o.Circle.include(o.Path.CANVAS?{_drawPath:function(){var t=this._point;this._ctx.beginPath(),this._ctx.arc(t.x,t.y,this._radius,0,2*Math.PI,!1)},_containsPoint:function(t){var e=this._point,i=this.options.stroke?this.options.weight/2:0;return t.distanceTo(e)<=this._radius+i}}:{}),o.CircleMarker.include(o.Path.CANVAS?{_updateStyle:function(){o.Path.prototype._updateStyle.call(this)}}:{}),o.GeoJSON=o.FeatureGroup.extend({initialize:function(t,e){o.setOptions(this,e),this._layers={},t&&this.addData(t)},addData:function(t){var e,i,n,s=o.Util.isArray(t)?t:t.features;if(s){for(e=0,i=s.length;i>e;e++)n=s[e],(n.geometries||n.geometry||n.features||n.coordinates)&&this.addData(s[e]);return this}var a=this.options;if(!a.filter||a.filter(t)){var r=o.GeoJSON.geometryToLayer(t,a.pointToLayer,a.coordsToLatLng,a);return r.feature=o.GeoJSON.asFeature(t),r.defaultOptions=r.options,this.resetStyle(r),a.onEachFeature&&a.onEachFeature(t,r),this.addLayer(r)}},resetStyle:function(t){var e=this.options.style;e&&(o.Util.extend(t.options,t.defaultOptions),this._setLayerStyle(t,e))},setStyle:function(t){this.eachLayer(function(e){this._setLayerStyle(e,t)},this)},_setLayerStyle:function(t,e){"function"==typeof e&&(e=e(t.feature)),t.setStyle&&t.setStyle(e)}}),o.extend(o.GeoJSON,{geometryToLayer:function(t,e,i,n){var s,a,r,h,l="Feature"===t.type?t.geometry:t,u=l.coordinates,c=[];switch(i=i||this.coordsToLatLng,l.type){case"Point":return s=i(u),e?e(t,s):new o.Marker(s);case"MultiPoint":for(r=0,h=u.length;h>r;r++)s=i(u[r]),c.push(e?e(t,s):new o.Marker(s));return new o.FeatureGroup(c);case"LineString":return a=this.coordsToLatLngs(u,0,i),new o.Polyline(a,n);case"Polygon":if(2===u.length&&!u[1].length)throw new Error("Invalid GeoJSON object.");return a=this.coordsToLatLngs(u,1,i),new o.Polygon(a,n);case"MultiLineString":return a=this.coordsToLatLngs(u,1,i),new o.MultiPolyline(a,n);case"MultiPolygon":return a=this.coordsToLatLngs(u,2,i),new o.MultiPolygon(a,n);case"GeometryCollection":for(r=0,h=l.geometries.length;h>r;r++)c.push(this.geometryToLayer({geometry:l.geometries[r],type:"Feature",properties:t.properties},e,i,n));return new o.FeatureGroup(c);default:throw new Error("Invalid GeoJSON object.")}},coordsToLatLng:function(t){return new o.LatLng(t[1],t[0],t[2])},coordsToLatLngs:function(t,e,i){var n,o,s,a=[];for(o=0,s=t.length;s>o;o++)n=e?this.coordsToLatLngs(t[o],e-1,i):(i||this.coordsToLatLng)(t[o]),a.push(n);return a},latLngToCoords:function(t){var e=[t.lng,t.lat];return t.alt!==i&&e.push(t.alt),e},latLngsToCoords:function(t){for(var e=[],i=0,n=t.length;n>i;i++)e.push(o.GeoJSON.latLngToCoords(t[i]));return e},getFeature:function(t,e){return t.feature?o.extend({},t.feature,{geometry:e}):o.GeoJSON.asFeature(e)},asFeature:function(t){return"Feature"===t.type?t:{type:"Feature",properties:{},geometry:t}}});var a={toGeoJSON:function(){return o.GeoJSON.getFeature(this,{type:"Point",coordinates:o.GeoJSON.latLngToCoords(this.getLatLng())})}};o.Marker.include(a),o.Circle.include(a),o.CircleMarker.include(a),o.Polyline.include({toGeoJSON:function(){return o.GeoJSON.getFeature(this,{type:"LineString",coordinates:o.GeoJSON.latLngsToCoords(this.getLatLngs())})}}),o.Polygon.include({toGeoJSON:function(){var t,e,i,n=[o.GeoJSON.latLngsToCoords(this.getLatLngs())];if(n[0].push(n[0][0]),this._holes)for(t=0,e=this._holes.length;e>t;t++)i=o.GeoJSON.latLngsToCoords(this._holes[t]),i.push(i[0]),n.push(i);return o.GeoJSON.getFeature(this,{type:"Polygon",coordinates:n})}}),function(){function t(t){return function(){var e=[];return this.eachLayer(function(t){e.push(t.toGeoJSON().geometry.coordinates)}),o.GeoJSON.getFeature(this,{type:t,coordinates:e})}}o.MultiPolyline.include({toGeoJSON:t("MultiLineString")}),o.MultiPolygon.include({toGeoJSON:t("MultiPolygon")}),o.LayerGroup.include({toGeoJSON:function(){var e,i=this.feature&&this.feature.geometry,n=[];if(i&&"MultiPoint"===i.type)return t("MultiPoint").call(this);var s=i&&"GeometryCollection"===i.type;return this.eachLayer(function(t){t.toGeoJSON&&(e=t.toGeoJSON(),n.push(s?e.geometry:o.GeoJSON.asFeature(e)))}),s?o.GeoJSON.getFeature(this,{geometries:n,type:"GeometryCollection"}):{type:"FeatureCollection",features:n}}})}(),o.geoJson=function(t,e){return new o.GeoJSON(t,e)},o.DomEvent={addListener:function(t,e,i,n){var s,a,r,h=o.stamp(i),l="_leaflet_"+e+h;return t[l]?this:(s=function(e){return i.call(n||t,e||o.DomEvent._getEvent())},o.Browser.pointer&&0===e.indexOf("touch")?this.addPointerListener(t,e,s,h):(o.Browser.touch&&"dblclick"===e&&this.addDoubleTapListener&&this.addDoubleTapListener(t,s,h),"addEventListener"in t?"mousewheel"===e?(t.addEventListener("DOMMouseScroll",s,!1),t.addEventListener(e,s,!1)):"mouseenter"===e||"mouseleave"===e?(a=s,r="mouseenter"===e?"mouseover":"mouseout",s=function(e){return o.DomEvent._checkMouse(t,e)?a(e):void 0},t.addEventListener(r,s,!1)):"click"===e&&o.Browser.android?(a=s,s=function(t){return o.DomEvent._filterClick(t,a)},t.addEventListener(e,s,!1)):t.addEventListener(e,s,!1):"attachEvent"in t&&t.attachEvent("on"+e,s),t[l]=s,this))},removeListener:function(t,e,i){var n=o.stamp(i),s="_leaflet_"+e+n,a=t[s];return a?(o.Browser.pointer&&0===e.indexOf("touch")?this.removePointerListener(t,e,n):o.Browser.touch&&"dblclick"===e&&this.removeDoubleTapListener?this.removeDoubleTapListener(t,n):"removeEventListener"in t?"mousewheel"===e?(t.removeEventListener("DOMMouseScroll",a,!1),t.removeEventListener(e,a,!1)):"mouseenter"===e||"mouseleave"===e?t.removeEventListener("mouseenter"===e?"mouseover":"mouseout",a,!1):t.removeEventListener(e,a,!1):"detachEvent"in t&&t.detachEvent("on"+e,a),t[s]=null,this):this},stopPropagation:function(t){return t.stopPropagation?t.stopPropagation():t.cancelBubble=!0,o.DomEvent._skipped(t),this},disableScrollPropagation:function(t){var e=o.DomEvent.stopPropagation;return o.DomEvent.on(t,"mousewheel",e).on(t,"MozMousePixelScroll",e)},disableClickPropagation:function(t){for(var e=o.DomEvent.stopPropagation,i=o.Draggable.START.length-1;i>=0;i--)o.DomEvent.on(t,o.Draggable.START[i],e);return o.DomEvent.on(t,"click",o.DomEvent._fakeStop).on(t,"dblclick",e)},preventDefault:function(t){return t.preventDefault?t.preventDefault():t.returnValue=!1,this},stop:function(t){return o.DomEvent.preventDefault(t).stopPropagation(t)},getMousePosition:function(t,e){if(!e)return new o.Point(t.clientX,t.clientY);var i=e.getBoundingClientRect();return new o.Point(t.clientX-i.left-e.clientLeft,t.clientY-i.top-e.clientTop)},getWheelDelta:function(t){var e=0;return t.wheelDelta&&(e=t.wheelDelta/120),t.detail&&(e=-t.detail/3),e},_skipEvents:{},_fakeStop:function(t){o.DomEvent._skipEvents[t.type]=!0},_skipped:function(t){var e=this._skipEvents[t.type];return this._skipEvents[t.type]=!1,e},_checkMouse:function(t,e){var i=e.relatedTarget;if(!i)return!0;try{for(;i&&i!==t;)i=i.parentNode}catch(n){return!1}return i!==t},_getEvent:function(){var e=t.event;if(!e)for(var i=arguments.callee.caller;i&&(e=i.arguments[0],!e||t.Event!==e.constructor);)i=i.caller;return e},_filterClick:function(t,e){var i=t.timeStamp||t.originalEvent.timeStamp,n=o.DomEvent._lastClick&&i-o.DomEvent._lastClick;return n&&n>100&&500>n||t.target._simulatedClick&&!t._simulated?void o.DomEvent.stop(t):(o.DomEvent._lastClick=i,e(t))}},o.DomEvent.on=o.DomEvent.addListener,o.DomEvent.off=o.DomEvent.removeListener,o.Draggable=o.Class.extend({includes:o.Mixin.Events,statics:{START:o.Browser.touch?["touchstart","mousedown"]:["mousedown"],END:{mousedown:"mouseup",touchstart:"touchend",pointerdown:"touchend",MSPointerDown:"touchend"},MOVE:{mousedown:"mousemove",touchstart:"touchmove",pointerdown:"touchmove",MSPointerDown:"touchmove"}},initialize:function(t,e){this._element=t,this._dragStartTarget=e||t},enable:function(){if(!this._enabled){for(var t=o.Draggable.START.length-1;t>=0;t--)o.DomEvent.on(this._dragStartTarget,o.Draggable.START[t],this._onDown,this);this._enabled=!0}},disable:function(){if(this._enabled){for(var t=o.Draggable.START.length-1;t>=0;t--)o.DomEvent.off(this._dragStartTarget,o.Draggable.START[t],this._onDown,this);this._enabled=!1,this._moved=!1}},_onDown:function(t){if(this._moved=!1,!t.shiftKey&&(1===t.which||1===t.button||t.touches)&&(o.DomEvent.stopPropagation(t),!o.Draggable._disabled&&(o.DomUtil.disableImageDrag(),o.DomUtil.disableTextSelection(),!this._moving))){var i=t.touches?t.touches[0]:t;this._startPoint=new o.Point(i.clientX,i.clientY),this._startPos=this._newPos=o.DomUtil.getPosition(this._element),o.DomEvent.on(e,o.Draggable.MOVE[t.type],this._onMove,this).on(e,o.Draggable.END[t.type],this._onUp,this)}},_onMove:function(t){if(t.touches&&t.touches.length>1)return void(this._moved=!0);var i=t.touches&&1===t.touches.length?t.touches[0]:t,n=new o.Point(i.clientX,i.clientY),s=n.subtract(this._startPoint);(s.x||s.y)&&(o.Browser.touch&&Math.abs(s.x)+Math.abs(s.y)<3||(o.DomEvent.preventDefault(t),this._moved||(this.fire("dragstart"),this._moved=!0,this._startPos=o.DomUtil.getPosition(this._element).subtract(s),o.DomUtil.addClass(e.body,"leaflet-dragging"),this._lastTarget=t.target||t.srcElement,o.DomUtil.addClass(this._lastTarget,"leaflet-drag-target")),this._newPos=this._startPos.add(s),this._moving=!0,o.Util.cancelAnimFrame(this._animRequest),this._animRequest=o.Util.requestAnimFrame(this._updatePosition,this,!0,this._dragStartTarget)))},_updatePosition:function(){this.fire("predrag"),o.DomUtil.setPosition(this._element,this._newPos),this.fire("drag")},_onUp:function(){o.DomUtil.removeClass(e.body,"leaflet-dragging"),this._lastTarget&&(o.DomUtil.removeClass(this._lastTarget,"leaflet-drag-target"),this._lastTarget=null);for(var t in o.Draggable.MOVE)o.DomEvent.off(e,o.Draggable.MOVE[t],this._onMove).off(e,o.Draggable.END[t],this._onUp);o.DomUtil.enableImageDrag(),o.DomUtil.enableTextSelection(),this._moved&&this._moving&&(o.Util.cancelAnimFrame(this._animRequest),this.fire("dragend",{distance:this._newPos.distanceTo(this._startPos)})),this._moving=!1}}),o.Handler=o.Class.extend({initialize:function(t){this._map=t},enable:function(){this._enabled||(this._enabled=!0,this.addHooks())},disable:function(){this._enabled&&(this._enabled=!1,this.removeHooks())},enabled:function(){return!!this._enabled}}),o.Map.mergeOptions({dragging:!0,inertia:!o.Browser.android23,inertiaDeceleration:3400,inertiaMaxSpeed:1/0,inertiaThreshold:o.Browser.touch?32:18,easeLinearity:.25,worldCopyJump:!1}),o.Map.Drag=o.Handler.extend({addHooks:function(){if(!this._draggable){var t=this._map;this._draggable=new o.Draggable(t._mapPane,t._container),this._draggable.on({dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this),t.options.worldCopyJump&&(this._draggable.on("predrag",this._onPreDrag,this),t.on("viewreset",this._onViewReset,this),t.whenReady(this._onViewReset,this))}this._draggable.enable()},removeHooks:function(){this._draggable.disable()},moved:function(){return this._draggable&&this._draggable._moved},_onDragStart:function(){var t=this._map;t._panAnim&&t._panAnim.stop(),t.fire("movestart").fire("dragstart"),t.options.inertia&&(this._positions=[],this._times=[])},_onDrag:function(){if(this._map.options.inertia){var t=this._lastTime=+new Date,e=this._lastPos=this._draggable._newPos;this._positions.push(e),this._times.push(t),t-this._times[0]>200&&(this._positions.shift(),this._times.shift())}this._map.fire("move").fire("drag")},_onViewReset:function(){var t=this._map.getSize()._divideBy(2),e=this._map.latLngToLayerPoint([0,0]);this._initialWorldOffset=e.subtract(t).x,this._worldWidth=this._map.project([0,180]).x},_onPreDrag:function(){var t=this._worldWidth,e=Math.round(t/2),i=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-e+i)%t+e-i,s=(n+e+i)%t-e-i,a=Math.abs(o+i)<Math.abs(s+i)?o:s;this._draggable._newPos.x=a},_onDragEnd:function(t){var e=this._map,i=e.options,n=+new Date-this._lastTime,s=!i.inertia||n>i.inertiaThreshold||!this._positions[0];if(e.fire("dragend",t),s)e.fire("moveend");else{var a=this._lastPos.subtract(this._positions[0]),r=(this._lastTime+n-this._times[0])/1e3,h=i.easeLinearity,l=a.multiplyBy(h/r),u=l.distanceTo([0,0]),c=Math.min(i.inertiaMaxSpeed,u),d=l.multiplyBy(c/u),p=c/(i.inertiaDeceleration*h),_=d.multiplyBy(-p/2).round();_.x&&_.y?(_=e._limitOffset(_,e.options.maxBounds),o.Util.requestAnimFrame(function(){e.panBy(_,{duration:p,easeLinearity:h,noMoveStart:!0})})):e.fire("moveend")}}}),o.Map.addInitHook("addHandler","dragging",o.Map.Drag),o.Map.mergeOptions({doubleClickZoom:!0}),o.Map.DoubleClickZoom=o.Handler.extend({addHooks:function(){this._map.on("dblclick",this._onDoubleClick,this)},removeHooks:function(){this._map.off("dblclick",this._onDoubleClick,this)},_onDoubleClick:function(t){var e=this._map,i=e.getZoom()+(t.originalEvent.shiftKey?-1:1);"center"===e.options.doubleClickZoom?e.setZoom(i):e.setZoomAround(t.containerPoint,i)}}),o.Map.addInitHook("addHandler","doubleClickZoom",o.Map.DoubleClickZoom),o.Map.mergeOptions({scrollWheelZoom:!0}),o.Map.ScrollWheelZoom=o.Handler.extend({addHooks:function(){o.DomEvent.on(this._map._container,"mousewheel",this._onWheelScroll,this),o.DomEvent.on(this._map._container,"MozMousePixelScroll",o.DomEvent.preventDefault),this._delta=0},removeHooks:function(){o.DomEvent.off(this._map._container,"mousewheel",this._onWheelScroll),o.DomEvent.off(this._map._container,"MozMousePixelScroll",o.DomEvent.preventDefault)},_onWheelScroll:function(t){var e=o.DomEvent.getWheelDelta(t);this._delta+=e,this._lastMousePos=this._map.mouseEventToContainerPoint(t),this._startTime||(this._startTime=+new Date);var i=Math.max(40-(+new Date-this._startTime),0);clearTimeout(this._timer),this._timer=setTimeout(o.bind(this._performZoom,this),i),o.DomEvent.preventDefault(t),o.DomEvent.stopPropagation(t)},_performZoom:function(){var t=this._map,e=this._delta,i=t.getZoom();e=e>0?Math.ceil(e):Math.floor(e),e=Math.max(Math.min(e,4),-4),e=t._limitZoom(i+e)-i,this._delta=0,this._startTime=null,e&&("center"===t.options.scrollWheelZoom?t.setZoom(i+e):t.setZoomAround(this._lastMousePos,i+e))}}),o.Map.addInitHook("addHandler","scrollWheelZoom",o.Map.ScrollWheelZoom),o.extend(o.DomEvent,{_touchstart:o.Browser.msPointer?"MSPointerDown":o.Browser.pointer?"pointerdown":"touchstart",_touchend:o.Browser.msPointer?"MSPointerUp":o.Browser.pointer?"pointerup":"touchend",addDoubleTapListener:function(t,i,n){function s(t){var e;if(o.Browser.pointer?(_.push(t.pointerId),e=_.length):e=t.touches.length,!(e>1)){var i=Date.now(),n=i-(r||i);h=t.touches?t.touches[0]:t,l=n>0&&u>=n,r=i}}function a(t){if(o.Browser.pointer){var e=_.indexOf(t.pointerId);if(-1===e)return;_.splice(e,1)}if(l){if(o.Browser.pointer){var n,s={};for(var a in h)n=h[a],"function"==typeof n?s[a]=n.bind(h):s[a]=n;h=s}h.type="dblclick",i(h),r=null}}var r,h,l=!1,u=250,c="_leaflet_",d=this._touchstart,p=this._touchend,_=[];t[c+d+n]=s,t[c+p+n]=a;var m=o.Browser.pointer?e.documentElement:t;return t.addEventListener(d,s,!1),m.addEventListener(p,a,!1),o.Browser.pointer&&m.addEventListener(o.DomEvent.POINTER_CANCEL,a,!1),this},removeDoubleTapListener:function(t,i){var n="_leaflet_";return t.removeEventListener(this._touchstart,t[n+this._touchstart+i],!1),(o.Browser.pointer?e.documentElement:t).removeEventListener(this._touchend,t[n+this._touchend+i],!1),o.Browser.pointer&&e.documentElement.removeEventListener(o.DomEvent.POINTER_CANCEL,t[n+this._touchend+i],!1),this}}),o.extend(o.DomEvent,{POINTER_DOWN:o.Browser.msPointer?"MSPointerDown":"pointerdown",POINTER_MOVE:o.Browser.msPointer?"MSPointerMove":"pointermove",POINTER_UP:o.Browser.msPointer?"MSPointerUp":"pointerup",POINTER_CANCEL:o.Browser.msPointer?"MSPointerCancel":"pointercancel",_pointers:[],_pointerDocumentListener:!1,addPointerListener:function(t,e,i,n){switch(e){case"touchstart":return this.addPointerListenerStart(t,e,i,n);
+case"touchend":return this.addPointerListenerEnd(t,e,i,n);case"touchmove":return this.addPointerListenerMove(t,e,i,n);default:throw"Unknown touch event type"}},addPointerListenerStart:function(t,i,n,s){var a="_leaflet_",r=this._pointers,h=function(t){"mouse"!==t.pointerType&&t.pointerType!==t.MSPOINTER_TYPE_MOUSE&&o.DomEvent.preventDefault(t);for(var e=!1,i=0;i<r.length;i++)if(r[i].pointerId===t.pointerId){e=!0;break}e||r.push(t),t.touches=r.slice(),t.changedTouches=[t],n(t)};if(t[a+"touchstart"+s]=h,t.addEventListener(this.POINTER_DOWN,h,!1),!this._pointerDocumentListener){var l=function(t){for(var e=0;e<r.length;e++)if(r[e].pointerId===t.pointerId){r.splice(e,1);break}};e.documentElement.addEventListener(this.POINTER_UP,l,!1),e.documentElement.addEventListener(this.POINTER_CANCEL,l,!1),this._pointerDocumentListener=!0}return this},addPointerListenerMove:function(t,e,i,n){function o(t){if(t.pointerType!==t.MSPOINTER_TYPE_MOUSE&&"mouse"!==t.pointerType||0!==t.buttons){for(var e=0;e<a.length;e++)if(a[e].pointerId===t.pointerId){a[e]=t;break}t.touches=a.slice(),t.changedTouches=[t],i(t)}}var s="_leaflet_",a=this._pointers;return t[s+"touchmove"+n]=o,t.addEventListener(this.POINTER_MOVE,o,!1),this},addPointerListenerEnd:function(t,e,i,n){var o="_leaflet_",s=this._pointers,a=function(t){for(var e=0;e<s.length;e++)if(s[e].pointerId===t.pointerId){s.splice(e,1);break}t.touches=s.slice(),t.changedTouches=[t],i(t)};return t[o+"touchend"+n]=a,t.addEventListener(this.POINTER_UP,a,!1),t.addEventListener(this.POINTER_CANCEL,a,!1),this},removePointerListener:function(t,e,i){var n="_leaflet_",o=t[n+e+i];switch(e){case"touchstart":t.removeEventListener(this.POINTER_DOWN,o,!1);break;case"touchmove":t.removeEventListener(this.POINTER_MOVE,o,!1);break;case"touchend":t.removeEventListener(this.POINTER_UP,o,!1),t.removeEventListener(this.POINTER_CANCEL,o,!1)}return this}}),o.Map.mergeOptions({touchZoom:o.Browser.touch&&!o.Browser.android23,bounceAtZoomLimits:!0}),o.Map.TouchZoom=o.Handler.extend({addHooks:function(){o.DomEvent.on(this._map._container,"touchstart",this._onTouchStart,this)},removeHooks:function(){o.DomEvent.off(this._map._container,"touchstart",this._onTouchStart,this)},_onTouchStart:function(t){var i=this._map;if(t.touches&&2===t.touches.length&&!i._animatingZoom&&!this._zooming){var n=i.mouseEventToLayerPoint(t.touches[0]),s=i.mouseEventToLayerPoint(t.touches[1]),a=i._getCenterLayerPoint();this._startCenter=n.add(s)._divideBy(2),this._startDist=n.distanceTo(s),this._moved=!1,this._zooming=!0,this._centerOffset=a.subtract(this._startCenter),i._panAnim&&i._panAnim.stop(),o.DomEvent.on(e,"touchmove",this._onTouchMove,this).on(e,"touchend",this._onTouchEnd,this),o.DomEvent.preventDefault(t)}},_onTouchMove:function(t){var e=this._map;if(t.touches&&2===t.touches.length&&this._zooming){var i=e.mouseEventToLayerPoint(t.touches[0]),n=e.mouseEventToLayerPoint(t.touches[1]);this._scale=i.distanceTo(n)/this._startDist,this._delta=i._add(n)._divideBy(2)._subtract(this._startCenter),1!==this._scale&&(e.options.bounceAtZoomLimits||!(e.getZoom()===e.getMinZoom()&&this._scale<1||e.getZoom()===e.getMaxZoom()&&this._scale>1))&&(this._moved||(o.DomUtil.addClass(e._mapPane,"leaflet-touching"),e.fire("movestart").fire("zoomstart"),this._moved=!0),o.Util.cancelAnimFrame(this._animRequest),this._animRequest=o.Util.requestAnimFrame(this._updateOnMove,this,!0,this._map._container),o.DomEvent.preventDefault(t))}},_updateOnMove:function(){var t=this._map,e=this._getScaleOrigin(),i=t.layerPointToLatLng(e),n=t.getScaleZoom(this._scale);t._animateZoom(i,n,this._startCenter,this._scale,this._delta,!1,!0)},_onTouchEnd:function(){if(!this._moved||!this._zooming)return void(this._zooming=!1);var t=this._map;this._zooming=!1,o.DomUtil.removeClass(t._mapPane,"leaflet-touching"),o.Util.cancelAnimFrame(this._animRequest),o.DomEvent.off(e,"touchmove",this._onTouchMove).off(e,"touchend",this._onTouchEnd);var i=this._getScaleOrigin(),n=t.layerPointToLatLng(i),s=t.getZoom(),a=t.getScaleZoom(this._scale)-s,r=a>0?Math.ceil(a):Math.floor(a),h=t._limitZoom(s+r),l=t.getZoomScale(h)/this._scale;t._animateZoom(n,h,i,l)},_getScaleOrigin:function(){var t=this._centerOffset.subtract(this._delta).divideBy(this._scale);return this._startCenter.add(t)}}),o.Map.addInitHook("addHandler","touchZoom",o.Map.TouchZoom),o.Map.mergeOptions({tap:!0,tapTolerance:15}),o.Map.Tap=o.Handler.extend({addHooks:function(){o.DomEvent.on(this._map._container,"touchstart",this._onDown,this)},removeHooks:function(){o.DomEvent.off(this._map._container,"touchstart",this._onDown,this)},_onDown:function(t){if(t.touches){if(o.DomEvent.preventDefault(t),this._fireClick=!0,t.touches.length>1)return this._fireClick=!1,void clearTimeout(this._holdTimeout);var i=t.touches[0],n=i.target;this._startPos=this._newPos=new o.Point(i.clientX,i.clientY),n.tagName&&"a"===n.tagName.toLowerCase()&&o.DomUtil.addClass(n,"leaflet-active"),this._holdTimeout=setTimeout(o.bind(function(){this._isTapValid()&&(this._fireClick=!1,this._onUp(),this._simulateEvent("contextmenu",i))},this),1e3),o.DomEvent.on(e,"touchmove",this._onMove,this).on(e,"touchend",this._onUp,this)}},_onUp:function(t){if(clearTimeout(this._holdTimeout),o.DomEvent.off(e,"touchmove",this._onMove,this).off(e,"touchend",this._onUp,this),this._fireClick&&t&&t.changedTouches){var i=t.changedTouches[0],n=i.target;n&&n.tagName&&"a"===n.tagName.toLowerCase()&&o.DomUtil.removeClass(n,"leaflet-active"),this._isTapValid()&&this._simulateEvent("click",i)}},_isTapValid:function(){return this._newPos.distanceTo(this._startPos)<=this._map.options.tapTolerance},_onMove:function(t){var e=t.touches[0];this._newPos=new o.Point(e.clientX,e.clientY)},_simulateEvent:function(i,n){var o=e.createEvent("MouseEvents");o._simulated=!0,n.target._simulatedClick=!0,o.initMouseEvent(i,!0,!0,t,1,n.screenX,n.screenY,n.clientX,n.clientY,!1,!1,!1,!1,0,null),n.target.dispatchEvent(o)}}),o.Browser.touch&&!o.Browser.pointer&&o.Map.addInitHook("addHandler","tap",o.Map.Tap),o.Map.mergeOptions({boxZoom:!0}),o.Map.BoxZoom=o.Handler.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane,this._moved=!1},addHooks:function(){o.DomEvent.on(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){o.DomEvent.off(this._container,"mousedown",this._onMouseDown),this._moved=!1},moved:function(){return this._moved},_onMouseDown:function(t){return this._moved=!1,!t.shiftKey||1!==t.which&&1!==t.button?!1:(o.DomUtil.disableTextSelection(),o.DomUtil.disableImageDrag(),this._startLayerPoint=this._map.mouseEventToLayerPoint(t),void o.DomEvent.on(e,"mousemove",this._onMouseMove,this).on(e,"mouseup",this._onMouseUp,this).on(e,"keydown",this._onKeyDown,this))},_onMouseMove:function(t){this._moved||(this._box=o.DomUtil.create("div","leaflet-zoom-box",this._pane),o.DomUtil.setPosition(this._box,this._startLayerPoint),this._container.style.cursor="crosshair",this._map.fire("boxzoomstart"));var e=this._startLayerPoint,i=this._box,n=this._map.mouseEventToLayerPoint(t),s=n.subtract(e),a=new o.Point(Math.min(n.x,e.x),Math.min(n.y,e.y));o.DomUtil.setPosition(i,a),this._moved=!0,i.style.width=Math.max(0,Math.abs(s.x)-4)+"px",i.style.height=Math.max(0,Math.abs(s.y)-4)+"px"},_finish:function(){this._moved&&(this._pane.removeChild(this._box),this._container.style.cursor=""),o.DomUtil.enableTextSelection(),o.DomUtil.enableImageDrag(),o.DomEvent.off(e,"mousemove",this._onMouseMove).off(e,"mouseup",this._onMouseUp).off(e,"keydown",this._onKeyDown)},_onMouseUp:function(t){this._finish();var e=this._map,i=e.mouseEventToLayerPoint(t);if(!this._startLayerPoint.equals(i)){var n=new o.LatLngBounds(e.layerPointToLatLng(this._startLayerPoint),e.layerPointToLatLng(i));e.fitBounds(n),e.fire("boxzoomend",{boxZoomBounds:n})}},_onKeyDown:function(t){27===t.keyCode&&this._finish()}}),o.Map.addInitHook("addHandler","boxZoom",o.Map.BoxZoom),o.Map.mergeOptions({keyboard:!0,keyboardPanOffset:80,keyboardZoomOffset:1}),o.Map.Keyboard=o.Handler.extend({keyCodes:{left:[37],right:[39],down:[40],up:[38],zoomIn:[187,107,61,171],zoomOut:[189,109,173]},initialize:function(t){this._map=t,this._setPanOffset(t.options.keyboardPanOffset),this._setZoomOffset(t.options.keyboardZoomOffset)},addHooks:function(){var t=this._map._container;-1===t.tabIndex&&(t.tabIndex="0"),o.DomEvent.on(t,"focus",this._onFocus,this).on(t,"blur",this._onBlur,this).on(t,"mousedown",this._onMouseDown,this),this._map.on("focus",this._addHooks,this).on("blur",this._removeHooks,this)},removeHooks:function(){this._removeHooks();var t=this._map._container;o.DomEvent.off(t,"focus",this._onFocus,this).off(t,"blur",this._onBlur,this).off(t,"mousedown",this._onMouseDown,this),this._map.off("focus",this._addHooks,this).off("blur",this._removeHooks,this)},_onMouseDown:function(){if(!this._focused){var i=e.body,n=e.documentElement,o=i.scrollTop||n.scrollTop,s=i.scrollLeft||n.scrollLeft;this._map._container.focus(),t.scrollTo(s,o)}},_onFocus:function(){this._focused=!0,this._map.fire("focus")},_onBlur:function(){this._focused=!1,this._map.fire("blur")},_setPanOffset:function(t){var e,i,n=this._panKeys={},o=this.keyCodes;for(e=0,i=o.left.length;i>e;e++)n[o.left[e]]=[-1*t,0];for(e=0,i=o.right.length;i>e;e++)n[o.right[e]]=[t,0];for(e=0,i=o.down.length;i>e;e++)n[o.down[e]]=[0,t];for(e=0,i=o.up.length;i>e;e++)n[o.up[e]]=[0,-1*t]},_setZoomOffset:function(t){var e,i,n=this._zoomKeys={},o=this.keyCodes;for(e=0,i=o.zoomIn.length;i>e;e++)n[o.zoomIn[e]]=t;for(e=0,i=o.zoomOut.length;i>e;e++)n[o.zoomOut[e]]=-t},_addHooks:function(){o.DomEvent.on(e,"keydown",this._onKeyDown,this)},_removeHooks:function(){o.DomEvent.off(e,"keydown",this._onKeyDown,this)},_onKeyDown:function(t){var e=t.keyCode,i=this._map;if(e in this._panKeys){if(i._panAnim&&i._panAnim._inProgress)return;i.panBy(this._panKeys[e]),i.options.maxBounds&&i.panInsideBounds(i.options.maxBounds)}else{if(!(e in this._zoomKeys))return;i.setZoom(i.getZoom()+this._zoomKeys[e])}o.DomEvent.stop(t)}}),o.Map.addInitHook("addHandler","keyboard",o.Map.Keyboard),o.Handler.MarkerDrag=o.Handler.extend({initialize:function(t){this._marker=t},addHooks:function(){var t=this._marker._icon;this._draggable||(this._draggable=new o.Draggable(t,t)),this._draggable.on("dragstart",this._onDragStart,this).on("drag",this._onDrag,this).on("dragend",this._onDragEnd,this),this._draggable.enable(),o.DomUtil.addClass(this._marker._icon,"leaflet-marker-draggable")},removeHooks:function(){this._draggable.off("dragstart",this._onDragStart,this).off("drag",this._onDrag,this).off("dragend",this._onDragEnd,this),this._draggable.disable(),o.DomUtil.removeClass(this._marker._icon,"leaflet-marker-draggable")},moved:function(){return this._draggable&&this._draggable._moved},_onDragStart:function(){this._marker.closePopup().fire("movestart").fire("dragstart")},_onDrag:function(){var t=this._marker,e=t._shadow,i=o.DomUtil.getPosition(t._icon),n=t._map.layerPointToLatLng(i);e&&o.DomUtil.setPosition(e,i),t._latlng=n,t.fire("move",{latlng:n}).fire("drag")},_onDragEnd:function(t){this._marker.fire("moveend").fire("dragend",t)}}),o.Control=o.Class.extend({options:{position:"topright"},initialize:function(t){o.setOptions(this,t)},getPosition:function(){return this.options.position},setPosition:function(t){var e=this._map;return e&&e.removeControl(this),this.options.position=t,e&&e.addControl(this),this},getContainer:function(){return this._container},addTo:function(t){this._map=t;var e=this._container=this.onAdd(t),i=this.getPosition(),n=t._controlCorners[i];return o.DomUtil.addClass(e,"leaflet-control"),-1!==i.indexOf("bottom")?n.insertBefore(e,n.firstChild):n.appendChild(e),this},removeFrom:function(t){var e=this.getPosition(),i=t._controlCorners[e];return i.removeChild(this._container),this._map=null,this.onRemove&&this.onRemove(t),this},_refocusOnMap:function(){this._map&&this._map.getContainer().focus()}}),o.control=function(t){return new o.Control(t)},o.Map.include({addControl:function(t){return t.addTo(this),this},removeControl:function(t){return t.removeFrom(this),this},_initControlPos:function(){function t(t,s){var a=i+t+" "+i+s;e[t+s]=o.DomUtil.create("div",a,n)}var e=this._controlCorners={},i="leaflet-",n=this._controlContainer=o.DomUtil.create("div",i+"control-container",this._container);t("top","left"),t("top","right"),t("bottom","left"),t("bottom","right")},_clearControlPos:function(){this._container.removeChild(this._controlContainer)}}),o.Control.Zoom=o.Control.extend({options:{position:"topleft",zoomInText:"+",zoomInTitle:"Zoom in",zoomOutText:"-",zoomOutTitle:"Zoom out"},onAdd:function(t){var e="leaflet-control-zoom",i=o.DomUtil.create("div",e+" leaflet-bar");return this._map=t,this._zoomInButton=this._createButton(this.options.zoomInText,this.options.zoomInTitle,e+"-in",i,this._zoomIn,this),this._zoomOutButton=this._createButton(this.options.zoomOutText,this.options.zoomOutTitle,e+"-out",i,this._zoomOut,this),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),i},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},_zoomIn:function(t){this._map.zoomIn(t.shiftKey?3:1)},_zoomOut:function(t){this._map.zoomOut(t.shiftKey?3:1)},_createButton:function(t,e,i,n,s,a){var r=o.DomUtil.create("a",i,n);r.innerHTML=t,r.href="#",r.title=e;var h=o.DomEvent.stopPropagation;return o.DomEvent.on(r,"click",h).on(r,"mousedown",h).on(r,"dblclick",h).on(r,"click",o.DomEvent.preventDefault).on(r,"click",s,a).on(r,"click",this._refocusOnMap,a),r},_updateDisabled:function(){var t=this._map,e="leaflet-disabled";o.DomUtil.removeClass(this._zoomInButton,e),o.DomUtil.removeClass(this._zoomOutButton,e),t._zoom===t.getMinZoom()&&o.DomUtil.addClass(this._zoomOutButton,e),t._zoom===t.getMaxZoom()&&o.DomUtil.addClass(this._zoomInButton,e)}}),o.Map.mergeOptions({zoomControl:!0}),o.Map.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new o.Control.Zoom,this.addControl(this.zoomControl))}),o.control.zoom=function(t){return new o.Control.Zoom(t)},o.Control.Attribution=o.Control.extend({options:{position:"bottomright",prefix:'<a href="http://leafletjs.com" title="A JS library for interactive maps">Leaflet</a>'},initialize:function(t){o.setOptions(this,t),this._attributions={}},onAdd:function(t){this._container=o.DomUtil.create("div","leaflet-control-attribution"),o.DomEvent.disableClickPropagation(this._container);for(var e in t._layers)t._layers[e].getAttribution&&this.addAttribution(t._layers[e].getAttribution());return t.on("layeradd",this._onLayerAdd,this).on("layerremove",this._onLayerRemove,this),this._update(),this._container},onRemove:function(t){t.off("layeradd",this._onLayerAdd).off("layerremove",this._onLayerRemove)},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t?(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update(),this):void 0},removeAttribution:function(t){return t?(this._attributions[t]&&(this._attributions[t]--,this._update()),this):void 0},_update:function(){if(this._map){var t=[];for(var e in this._attributions)this._attributions[e]&&t.push(e);var i=[];this.options.prefix&&i.push(this.options.prefix),t.length&&i.push(t.join(", ")),this._container.innerHTML=i.join(" | ")}},_onLayerAdd:function(t){t.layer.getAttribution&&this.addAttribution(t.layer.getAttribution())},_onLayerRemove:function(t){t.layer.getAttribution&&this.removeAttribution(t.layer.getAttribution())}}),o.Map.mergeOptions({attributionControl:!0}),o.Map.addInitHook(function(){this.options.attributionControl&&(this.attributionControl=(new o.Control.Attribution).addTo(this))}),o.control.attribution=function(t){return new o.Control.Attribution(t)},o.Control.Scale=o.Control.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0,updateWhenIdle:!1},onAdd:function(t){this._map=t;var e="leaflet-control-scale",i=o.DomUtil.create("div",e),n=this.options;return this._addScales(n,e,i),t.on(n.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),i},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,e,i){t.metric&&(this._mScale=o.DomUtil.create("div",e+"-line",i)),t.imperial&&(this._iScale=o.DomUtil.create("div",e+"-line",i))},_update:function(){var t=this._map.getBounds(),e=t.getCenter().lat,i=6378137*Math.PI*Math.cos(e*Math.PI/180),n=i*(t.getNorthEast().lng-t.getSouthWest().lng)/180,o=this._map.getSize(),s=this.options,a=0;o.x>0&&(a=n*(s.maxWidth/o.x)),this._updateScales(s,a)},_updateScales:function(t,e){t.metric&&e&&this._updateMetric(e),t.imperial&&e&&this._updateImperial(e)},_updateMetric:function(t){var e=this._getRoundNum(t);this._mScale.style.width=this._getScaleWidth(e/t)+"px",this._mScale.innerHTML=1e3>e?e+" m":e/1e3+" km"},_updateImperial:function(t){var e,i,n,o=3.2808399*t,s=this._iScale;o>5280?(e=o/5280,i=this._getRoundNum(e),s.style.width=this._getScaleWidth(i/e)+"px",s.innerHTML=i+" mi"):(n=this._getRoundNum(o),s.style.width=this._getScaleWidth(n/o)+"px",s.innerHTML=n+" ft")},_getScaleWidth:function(t){return Math.round(this.options.maxWidth*t)-10},_getRoundNum:function(t){var e=Math.pow(10,(Math.floor(t)+"").length-1),i=t/e;return i=i>=10?10:i>=5?5:i>=3?3:i>=2?2:1,e*i}}),o.control.scale=function(t){return new o.Control.Scale(t)},o.Control.Layers=o.Control.extend({options:{collapsed:!0,position:"topright",autoZIndex:!0},initialize:function(t,e,i){o.setOptions(this,i),this._layers={},this._lastZIndex=0,this._handlingClick=!1;for(var n in t)this._addLayer(t[n],n);for(n in e)this._addLayer(e[n],n,!0)},onAdd:function(t){return this._initLayout(),this._update(),t.on("layeradd",this._onLayerChange,this).on("layerremove",this._onLayerChange,this),this._container},onRemove:function(t){t.off("layeradd",this._onLayerChange,this).off("layerremove",this._onLayerChange,this)},addBaseLayer:function(t,e){return this._addLayer(t,e),this._update(),this},addOverlay:function(t,e){return this._addLayer(t,e,!0),this._update(),this},removeLayer:function(t){var e=o.stamp(t);return delete this._layers[e],this._update(),this},_initLayout:function(){var t="leaflet-control-layers",e=this._container=o.DomUtil.create("div",t);e.setAttribute("aria-haspopup",!0),o.Browser.touch?o.DomEvent.on(e,"click",o.DomEvent.stopPropagation):o.DomEvent.disableClickPropagation(e).disableScrollPropagation(e);var i=this._form=o.DomUtil.create("form",t+"-list");if(this.options.collapsed){o.Browser.android||o.DomEvent.on(e,"mouseover",this._expand,this).on(e,"mouseout",this._collapse,this);var n=this._layersLink=o.DomUtil.create("a",t+"-toggle",e);n.href="#",n.title="Layers",o.Browser.touch?o.DomEvent.on(n,"click",o.DomEvent.stop).on(n,"click",this._expand,this):o.DomEvent.on(n,"focus",this._expand,this),o.DomEvent.on(i,"click",function(){setTimeout(o.bind(this._onInputClick,this),0)},this),this._map.on("click",this._collapse,this)}else this._expand();this._baseLayersList=o.DomUtil.create("div",t+"-base",i),this._separator=o.DomUtil.create("div",t+"-separator",i),this._overlaysList=o.DomUtil.create("div",t+"-overlays",i),e.appendChild(i)},_addLayer:function(t,e,i){var n=o.stamp(t);this._layers[n]={layer:t,name:e,overlay:i},this.options.autoZIndex&&t.setZIndex&&(this._lastZIndex++,t.setZIndex(this._lastZIndex))},_update:function(){if(this._container){this._baseLayersList.innerHTML="",this._overlaysList.innerHTML="";var t,e,i=!1,n=!1;for(t in this._layers)e=this._layers[t],this._addItem(e),n=n||e.overlay,i=i||!e.overlay;this._separator.style.display=n&&i?"":"none"}},_onLayerChange:function(t){var e=this._layers[o.stamp(t.layer)];if(e){this._handlingClick||this._update();var i=e.overlay?"layeradd"===t.type?"overlayadd":"overlayremove":"layeradd"===t.type?"baselayerchange":null;i&&this._map.fire(i,e)}},_createRadioElement:function(t,i){var n='<input type="radio" class="leaflet-control-layers-selector" name="'+t+'"';i&&(n+=' checked="checked"'),n+="/>";var o=e.createElement("div");return o.innerHTML=n,o.firstChild},_addItem:function(t){var i,n=e.createElement("label"),s=this._map.hasLayer(t.layer);t.overlay?(i=e.createElement("input"),i.type="checkbox",i.className="leaflet-control-layers-selector",i.defaultChecked=s):i=this._createRadioElement("leaflet-base-layers",s),i.layerId=o.stamp(t.layer),o.DomEvent.on(i,"click",this._onInputClick,this);var a=e.createElement("span");a.innerHTML=" "+t.name,n.appendChild(i),n.appendChild(a);var r=t.overlay?this._overlaysList:this._baseLayersList;return r.appendChild(n),n},_onInputClick:function(){var t,e,i,n=this._form.getElementsByTagName("input"),o=n.length;for(this._handlingClick=!0,t=0;o>t;t++)e=n[t],i=this._layers[e.layerId],e.checked&&!this._map.hasLayer(i.layer)?this._map.addLayer(i.layer):!e.checked&&this._map.hasLayer(i.layer)&&this._map.removeLayer(i.layer);this._handlingClick=!1,this._refocusOnMap()},_expand:function(){o.DomUtil.addClass(this._container,"leaflet-control-layers-expanded")},_collapse:function(){this._container.className=this._container.className.replace(" leaflet-control-layers-expanded","")}}),o.control.layers=function(t,e,i){return new o.Control.Layers(t,e,i)},o.PosAnimation=o.Class.extend({includes:o.Mixin.Events,run:function(t,e,i,n){this.stop(),this._el=t,this._inProgress=!0,this._newPos=e,this.fire("start"),t.style[o.DomUtil.TRANSITION]="all "+(i||.25)+"s cubic-bezier(0,0,"+(n||.5)+",1)",o.DomEvent.on(t,o.DomUtil.TRANSITION_END,this._onTransitionEnd,this),o.DomUtil.setPosition(t,e),o.Util.falseFn(t.offsetWidth),this._stepTimer=setInterval(o.bind(this._onStep,this),50)},stop:function(){this._inProgress&&(o.DomUtil.setPosition(this._el,this._getPos()),this._onTransitionEnd(),o.Util.falseFn(this._el.offsetWidth))},_onStep:function(){var t=this._getPos();return t?(this._el._leaflet_pos=t,void this.fire("step")):void this._onTransitionEnd()},_transformRe:/([-+]?(?:\d*\.)?\d+)\D*, ([-+]?(?:\d*\.)?\d+)\D*\)/,_getPos:function(){var e,i,n,s=this._el,a=t.getComputedStyle(s);if(o.Browser.any3d){if(n=a[o.DomUtil.TRANSFORM].match(this._transformRe),!n)return;e=parseFloat(n[1]),i=parseFloat(n[2])}else e=parseFloat(a.left),i=parseFloat(a.top);return new o.Point(e,i,!0)},_onTransitionEnd:function(){o.DomEvent.off(this._el,o.DomUtil.TRANSITION_END,this._onTransitionEnd,this),this._inProgress&&(this._inProgress=!1,this._el.style[o.DomUtil.TRANSITION]="",this._el._leaflet_pos=this._newPos,clearInterval(this._stepTimer),this.fire("step").fire("end"))}}),o.Map.include({setView:function(t,e,n){if(e=e===i?this._zoom:this._limitZoom(e),t=this._limitCenter(o.latLng(t),e,this.options.maxBounds),n=n||{},this._panAnim&&this._panAnim.stop(),this._loaded&&!n.reset&&n!==!0){n.animate!==i&&(n.zoom=o.extend({animate:n.animate},n.zoom),n.pan=o.extend({animate:n.animate},n.pan));var s=this._zoom!==e?this._tryAnimatedZoom&&this._tryAnimatedZoom(t,e,n.zoom):this._tryAnimatedPan(t,n.pan);if(s)return clearTimeout(this._sizeTimer),this}return this._resetView(t,e),this},panBy:function(t,e){if(t=o.point(t).round(),e=e||{},!t.x&&!t.y)return this;if(this._panAnim||(this._panAnim=new o.PosAnimation,this._panAnim.on({step:this._onPanTransitionStep,end:this._onPanTransitionEnd},this)),e.noMoveStart||this.fire("movestart"),e.animate!==!1){o.DomUtil.addClass(this._mapPane,"leaflet-pan-anim");var i=this._getMapPanePos().subtract(t);this._panAnim.run(this._mapPane,i,e.duration||.25,e.easeLinearity)}else this._rawPanBy(t),this.fire("move").fire("moveend");return this},_onPanTransitionStep:function(){this.fire("move")},_onPanTransitionEnd:function(){o.DomUtil.removeClass(this._mapPane,"leaflet-pan-anim"),this.fire("moveend")},_tryAnimatedPan:function(t,e){var i=this._getCenterOffset(t)._floor();return(e&&e.animate)===!0||this.getSize().contains(i)?(this.panBy(i,e),!0):!1}}),o.PosAnimation=o.DomUtil.TRANSITION?o.PosAnimation:o.PosAnimation.extend({run:function(t,e,i,n){this.stop(),this._el=t,this._inProgress=!0,this._duration=i||.25,this._easeOutPower=1/Math.max(n||.5,.2),this._startPos=o.DomUtil.getPosition(t),this._offset=e.subtract(this._startPos),this._startTime=+new Date,this.fire("start"),this._animate()},stop:function(){this._inProgress&&(this._step(),this._complete())},_animate:function(){this._animId=o.Util.requestAnimFrame(this._animate,this),this._step()},_step:function(){var t=+new Date-this._startTime,e=1e3*this._duration;e>t?this._runFrame(this._easeOut(t/e)):(this._runFrame(1),this._complete())},_runFrame:function(t){var e=this._startPos.add(this._offset.multiplyBy(t));o.DomUtil.setPosition(this._el,e),this.fire("step")},_complete:function(){o.Util.cancelAnimFrame(this._animId),this._inProgress=!1,this.fire("end")},_easeOut:function(t){return 1-Math.pow(1-t,this._easeOutPower)}}),o.Map.mergeOptions({zoomAnimation:!0,zoomAnimationThreshold:4}),o.DomUtil.TRANSITION&&o.Map.addInitHook(function(){this._zoomAnimated=this.options.zoomAnimation&&o.DomUtil.TRANSITION&&o.Browser.any3d&&!o.Browser.android23&&!o.Browser.mobileOpera,this._zoomAnimated&&o.DomEvent.on(this._mapPane,o.DomUtil.TRANSITION_END,this._catchTransitionEnd,this)}),o.Map.include(o.DomUtil.TRANSITION?{_catchTransitionEnd:function(t){this._animatingZoom&&t.propertyName.indexOf("transform")>=0&&this._onZoomTransitionEnd()},_nothingToAnimate:function(){return!this._container.getElementsByClassName("leaflet-zoom-animated").length},_tryAnimatedZoom:function(t,e,i){if(this._animatingZoom)return!0;if(i=i||{},!this._zoomAnimated||i.animate===!1||this._nothingToAnimate()||Math.abs(e-this._zoom)>this.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(e),o=this._getCenterOffset(t)._divideBy(1-1/n),s=this._getCenterLayerPoint()._add(o);return i.animate===!0||this.getSize().contains(o)?(this.fire("movestart").fire("zoomstart"),this._animateZoom(t,e,s,n,null,!0),!0):!1},_animateZoom:function(t,e,i,n,s,a,r){r||(this._animatingZoom=!0),o.DomUtil.addClass(this._mapPane,"leaflet-zoom-anim"),this._animateToCenter=t,this._animateToZoom=e,o.Draggable&&(o.Draggable._disabled=!0),o.Util.requestAnimFrame(function(){this.fire("zoomanim",{center:t,zoom:e,origin:i,scale:n,delta:s,backwards:a}),setTimeout(o.bind(this._onZoomTransitionEnd,this),250)},this)},_onZoomTransitionEnd:function(){this._animatingZoom&&(this._animatingZoom=!1,o.DomUtil.removeClass(this._mapPane,"leaflet-zoom-anim"),o.Util.requestAnimFrame(function(){this._resetView(this._animateToCenter,this._animateToZoom,!0,!0),o.Draggable&&(o.Draggable._disabled=!1)},this))}}:{}),o.TileLayer.include({_animateZoom:function(t){this._animating||(this._animating=!0,this._prepareBgBuffer());var e=this._bgBuffer,i=o.DomUtil.TRANSFORM,n=t.delta?o.DomUtil.getTranslateString(t.delta):e.style[i],s=o.DomUtil.getScaleString(t.scale,t.origin);e.style[i]=t.backwards?s+" "+n:n+" "+s},_endZoomAnim:function(){var t=this._tileContainer,e=this._bgBuffer;t.style.visibility="",t.parentNode.appendChild(t),o.Util.falseFn(e.offsetWidth);var i=this._map.getZoom();(i>this.options.maxZoom||i<this.options.minZoom)&&this._clearBgBuffer(),this._animating=!1},_clearBgBuffer:function(){var t=this._map;!t||t._animatingZoom||t.touchZoom._zooming||(this._bgBuffer.innerHTML="",this._bgBuffer.style[o.DomUtil.TRANSFORM]="")},_prepareBgBuffer:function(){var t=this._tileContainer,e=this._bgBuffer,i=this._getLoadedTilesPercentage(e),n=this._getLoadedTilesPercentage(t);return e&&i>.5&&.5>n?(t.style.visibility="hidden",void this._stopLoadingImages(t)):(e.style.visibility="hidden",e.style[o.DomUtil.TRANSFORM]="",this._tileContainer=e,e=this._bgBuffer=t,this._stopLoadingImages(e),void clearTimeout(this._clearBgBufferTimer))},_getLoadedTilesPercentage:function(t){var e,i,n=t.getElementsByTagName("img"),o=0;for(e=0,i=n.length;i>e;e++)n[e].complete&&o++;return o/i},_stopLoadingImages:function(t){var e,i,n,s=Array.prototype.slice.call(t.getElementsByTagName("img"));for(e=0,i=s.length;i>e;e++)n=s[e],n.complete||(n.onload=o.Util.falseFn,n.onerror=o.Util.falseFn,n.src=o.Util.emptyImageUrl,n.parentNode.removeChild(n))}}),o.Map.include({_defaultLocateOptions:{watch:!1,setView:!1,maxZoom:1/0,timeout:1e4,maximumAge:0,enableHighAccuracy:!1},locate:function(t){if(t=this._locateOptions=o.extend(this._defaultLocateOptions,t),!navigator.geolocation)return this._handleGeolocationError({code:0,message:"Geolocation not supported."}),this;var e=o.bind(this._handleGeolocationResponse,this),i=o.bind(this._handleGeolocationError,this);return t.watch?this._locationWatchId=navigator.geolocation.watchPosition(e,i,t):navigator.geolocation.getCurrentPosition(e,i,t),this},stopLocate:function(){return navigator.geolocation&&navigator.geolocation.clearWatch(this._locationWatchId),this._locateOptions&&(this._locateOptions.setView=!1),this},_handleGeolocationError:function(t){var e=t.code,i=t.message||(1===e?"permission denied":2===e?"position unavailable":"timeout");this._locateOptions.setView&&!this._loaded&&this.fitWorld(),this.fire("locationerror",{code:e,message:"Geolocation error: "+i+"."})},_handleGeolocationResponse:function(t){var e=t.coords.latitude,i=t.coords.longitude,n=new o.LatLng(e,i),s=180*t.coords.accuracy/40075017,a=s/Math.cos(o.LatLng.DEG_TO_RAD*e),r=o.latLngBounds([e-s,i-a],[e+s,i+a]),h=this._locateOptions;if(h.setView){var l=Math.min(this.getBoundsZoom(r),h.maxZoom);this.setView(n,l)}var u={latlng:n,bounds:r,timestamp:t.timestamp};for(var c in t.coords)"number"==typeof t.coords[c]&&(u[c]=t.coords[c]);this.fire("locationfound",u)}})}(window,document);
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/.classpath b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/.classpath
new file mode 100644
index 0000000..7a6fc25
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/.classpath
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<classpath>
+	<classpathentry kind="con" path="aQute.bnd.classpath.container"/>
+	<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8"/>
+	<classpathentry kind="src" output="bin" path="src"/>
+	<classpathentry kind="src" output="bin_test" path="test">
+		<attributes>
+			<attribute name="test" value="true"/>
+		</attributes>
+	</classpathentry>
+	<classpathentry kind="output" path="bin"/>
+</classpath>
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/.gitignore b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/.gitignore
new file mode 100644
index 0000000..c2b941a
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/.gitignore
@@ -0,0 +1,2 @@
+/bin_test/
+/generated/
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/.project b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/.project
new file mode 100644
index 0000000..c4aab33
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/.project
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<projectDescription>
+	<name>org.eclipse.sensinact.studio.webapp.outdoor</name>
+	<comment></comment>
+	<projects>
+	</projects>
+	<buildSpec>
+		<buildCommand>
+			<name>org.eclipse.jdt.core.javabuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+		<buildCommand>
+			<name>bndtools.core.bndbuilder</name>
+			<arguments>
+			</arguments>
+		</buildCommand>
+	</buildSpec>
+	<natures>
+		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>bndtools.core.bndnature</nature>
+	</natures>
+</projectDescription>
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/bnd.bnd b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/bnd.bnd
new file mode 100644
index 0000000..ffc3eec
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/bnd.bnd
@@ -0,0 +1,8 @@
+Bundle-Version: 1.0.0.SNAPSHOT
+-buildpath: \
+	osgi.cmpn,\
+	org.eclipse.sensinact.studio.http.services;version=project,\
+	org.restlet,\
+	osgi.annotation
+-includeresource.webapp: \
+	webapp=webapp
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/src/org/eclipse/sensinact/studio/webapp/outdoor/Startup.java b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/src/org/eclipse/sensinact/studio/webapp/outdoor/Startup.java
new file mode 100644
index 0000000..d29cbc7
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/src/org/eclipse/sensinact/studio/webapp/outdoor/Startup.java
@@ -0,0 +1,43 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.webapp.outdoor;
+
+import org.eclipse.sensinact.studio.http.services.server.RouteUtil;
+import org.eclipse.sensinact.studio.webapp.outdoor.content.OutdoorInit;
+import org.eclipse.sensinact.studio.webapp.outdoor.content.OutdoorResources;
+import org.osgi.service.component.annotations.Activate;
+import org.osgi.service.component.annotations.Component;
+import org.osgi.service.component.annotations.Deactivate;
+
+/**
+ * @author Etienne Gandrille
+ */
+@Component
+public class Startup{
+
+	public static final String INIT_PATH = "/webapp/outdoor/init";
+	public static final String STATIC_PATH = "/webapp/outdoor/static";
+	public static final String BUNDLE_PATHS[] = { INIT_PATH, STATIC_PATH };
+	private OutdoorResources outdoorResources;
+
+	@Activate
+	public void activate() {
+		outdoorResources = new OutdoorResources();
+		RouteUtil.attachRoute(INIT_PATH, OutdoorInit.class);
+		RouteUtil.attachRoute(STATIC_PATH, outdoorResources);
+	}
+
+	@Deactivate
+	public void deactivate() {
+		RouteUtil.attachRoute(INIT_PATH, OutdoorInit.class);
+		RouteUtil.attachRoute(STATIC_PATH, outdoorResources);
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/src/org/eclipse/sensinact/studio/webapp/outdoor/content/OutdoorInit.java b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/src/org/eclipse/sensinact/studio/webapp/outdoor/content/OutdoorInit.java
new file mode 100644
index 0000000..aa311ad
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/src/org/eclipse/sensinact/studio/webapp/outdoor/content/OutdoorInit.java
@@ -0,0 +1,66 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.webapp.outdoor.content;
+
+import org.eclipse.sensinact.studio.http.services.server.SensinactServerResource;
+import org.restlet.resource.Get;
+
+/**
+ * @author Etienne Gandrille
+ */
+public class OutdoorInit extends SensinactServerResource {
+
+	/** Location displayed when studio starts */
+	private static final LOCATION DEFAULT_LOCATION = LOCATION.CEA_GRENOBLE;
+
+	@Get
+	public String getValue(String params) {
+		return getDefaultLocation();
+	}
+	
+	public static String getDefaultLocation() {
+		return DEFAULT_LOCATION.toJSON();
+	}
+	
+	public enum LOCATION
+	{
+		SANTANDER("43.464304", "-3.810365", "13"), 
+		CEA_GRENOBLE("45.19954840972916", "5.702977180480957", "15"), 
+		MURCIA("37.98682789766166", "-1.1273860931396484", "13"),
+		PALERMO("38.16270754361624","13.309797048568726","13");
+		
+		private final String lat;
+		private final String lng;
+		private final String zoom;
+
+		private LOCATION(String lat, String lng, String zoom) {
+			this.lat = lat;
+			this.lng = lng;
+			this.zoom = zoom;
+		}
+		
+		public String toJSON() {
+			StringBuilder sb = new StringBuilder();
+			sb.append("{");
+			buildJSONAttribute(sb, "lat", lat);
+			sb.append(",");
+			buildJSONAttribute(sb, "lng", lng);
+			sb.append(",");
+			buildJSONAttribute(sb, "zoom", zoom);
+			sb.append("}");
+			return sb.toString();
+		}
+
+		private void buildJSONAttribute(StringBuilder sb, String key, String val) {
+			sb.append("\"").append(key).append("\"").append(":").append("\"").append(val).append("\"");
+		}
+	}
+}
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/src/org/eclipse/sensinact/studio/webapp/outdoor/content/OutdoorResources.java b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/src/org/eclipse/sensinact/studio/webapp/outdoor/content/OutdoorResources.java
new file mode 100644
index 0000000..8e7f0b0
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/src/org/eclipse/sensinact/studio/webapp/outdoor/content/OutdoorResources.java
@@ -0,0 +1,28 @@
+/**
+ * Copyright (c) 2019 CEA.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ *  Contributors:
+ *     CEA - initial API and implementation and/or initial documentation
+ */
+package org.eclipse.sensinact.studio.webapp.outdoor.content;
+
+import org.restlet.Application;
+import org.restlet.Restlet;
+import org.restlet.data.Reference;
+import org.restlet.resource.Directory;
+
+/**
+ * @author Nicolas Hili
+ * @since  Nov 19, 2014
+ */
+public class OutdoorResources extends Application {
+	@Override
+    public Restlet createInboundRoot() {
+    	Directory dir = new Directory(getContext(), new Reference(getClass().getClassLoader().getResource("/webapp")));
+    	return dir;
+    }
+}
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/src/org/eclipse/sensinact/studio/webapp/outdoor/package-info.java b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/src/org/eclipse/sensinact/studio/webapp/outdoor/package-info.java
new file mode 100644
index 0000000..232afc1
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/src/org/eclipse/sensinact/studio/webapp/outdoor/package-info.java
@@ -0,0 +1,3 @@
+@org.osgi.annotation.bundle.Export
+@org.osgi.annotation.versioning.Version("1.0")
+package org.eclipse.sensinact.studio.webapp.outdoor;
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/WEB-INF/web.xml b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/WEB-INF/web.xml
new file mode 100644
index 0000000..7bd5858
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/WEB-INF/web.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Copyright (c) 2020 - 2021 Kentyou.
+   All rights reserved. This program and the accompanying materials
+   are made available under the terms of the Eclipse Public License v1.0
+   which accompanies this distribution, and is available at
+   http://www.eclipse.org/legal/epl-v10.html
+  
+   Contributors:
+      Kentyou - initial API and implementation
+-->
+<web-app>
+	<welcome-file-list>
+		<welcome-file>outdoor.html</welcome-file> 
+	</welcome-file-list>
+</web-app> 
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/custom.css b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/custom.css
new file mode 100644
index 0000000..4516592
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/custom.css
@@ -0,0 +1,54 @@
+/*
+*   Copyright (c) 2020 - 2021 Kentyou.
+*   All rights reserved. This program and the accompanying materials
+*   are made available under the terms of the Eclipse Public License v1.0
+*   which accompanies this distribution, and is available at
+*   http://www.eclipse.org/legal/epl-v10.html
+*  
+*   Contributors:
+*      Kentyou - initial API and implementation
+*/
+html, body, #map {
+	height:100%;
+	margin:0px;
+	padding:0px;
+}
+
+#notif {
+    position: absolute;
+    bottom: 1em;
+    right: 1em;
+    padding: 1em;
+    background-color: #759D66;
+    border-radius: 10px;
+    min-width: 150px;
+    color: white;
+    text-align: center;
+    visibility: hidden;    
+}
+
+#image {
+    position: absolute;
+    top:0em;
+    right:0em;
+    background-color: grey;
+    width: 100%;
+    height: 100%;
+    visibility: hidden;    
+    text-align: center;
+}
+
+#image a img {
+  max-width:100%;
+  max-height: 100%;
+}
+
+object {
+  max-width:80%;
+  max-height: 80%;
+  text-align: center;
+}
+
+a {
+  text-decoration: none;
+}
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/bus-icon.png b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/bus-icon.png
new file mode 100644
index 0000000..6cecdc4
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/bus-icon.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/layers-2x.png b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/layers-2x.png
new file mode 100644
index 0000000..200c333
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/layers-2x.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/layers.png b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/layers.png
new file mode 100644
index 0000000..1a72e57
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/layers.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/less.jpg b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/less.jpg
new file mode 100644
index 0000000..36f08d6
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/less.jpg
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/marker-icon-2x.png b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/marker-icon-2x.png
new file mode 100644
index 0000000..88f9e50
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/marker-icon-2x.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/marker-icon.png b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/marker-icon.png
new file mode 100644
index 0000000..950edf2
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/marker-icon.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/marker-rectangle.png b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/marker-rectangle.png
new file mode 100644
index 0000000..823dc26
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/marker-rectangle.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/marker-shadow.png b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/marker-shadow.png
new file mode 100644
index 0000000..9fd2979
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/marker-shadow.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/moins_.png b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/moins_.png
new file mode 100644
index 0000000..1933e28
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/moins_.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/plus_.png b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/plus_.png
new file mode 100644
index 0000000..372951f
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/plus_.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/validation.png b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/validation.png
new file mode 100644
index 0000000..8a1e10b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/images/validation.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/leaflet.css b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/leaflet.css
new file mode 100644
index 0000000..d1b47a1
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/css/leaflet.css
@@ -0,0 +1,636 @@
+/* required styles */
+
+.leaflet-pane,
+.leaflet-tile,
+.leaflet-marker-icon,
+.leaflet-marker-shadow,
+.leaflet-tile-container,
+.leaflet-pane > svg,
+.leaflet-pane > canvas,
+.leaflet-zoom-box,
+.leaflet-image-layer,
+.leaflet-layer {
+	position: absolute;
+	left: 0;
+	top: 0;
+	}
+.leaflet-container {
+	overflow: hidden;
+	}
+.leaflet-tile,
+.leaflet-marker-icon,
+.leaflet-marker-shadow {
+	-webkit-user-select: none;
+	   -moz-user-select: none;
+	        user-select: none;
+	  -webkit-user-drag: none;
+	}
+/* Safari renders non-retina tile on retina better with this, but Chrome is worse */
+.leaflet-safari .leaflet-tile {
+	image-rendering: -webkit-optimize-contrast;
+	}
+/* hack that prevents hw layers "stretching" when loading new tiles */
+.leaflet-safari .leaflet-tile-container {
+	width: 1600px;
+	height: 1600px;
+	-webkit-transform-origin: 0 0;
+	}
+.leaflet-marker-icon,
+.leaflet-marker-shadow {
+	display: block;
+	}
+/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */
+/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */
+.leaflet-container .leaflet-overlay-pane svg,
+.leaflet-container .leaflet-marker-pane img,
+.leaflet-container .leaflet-shadow-pane img,
+.leaflet-container .leaflet-tile-pane img,
+.leaflet-container img.leaflet-image-layer {
+	max-width: none !important;
+	max-height: none !important;
+	}
+
+.leaflet-container.leaflet-touch-zoom {
+	-ms-touch-action: pan-x pan-y;
+	touch-action: pan-x pan-y;
+	}
+.leaflet-container.leaflet-touch-drag {
+	-ms-touch-action: pinch-zoom;
+	/* Fallback for FF which doesn't support pinch-zoom */
+	touch-action: none;
+	touch-action: pinch-zoom;
+}
+.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom {
+	-ms-touch-action: none;
+	touch-action: none;
+}
+.leaflet-container {
+	-webkit-tap-highlight-color: transparent;
+}
+.leaflet-container a {
+	-webkit-tap-highlight-color: rgba(51, 181, 229, 0.4);
+}
+.leaflet-tile {
+	filter: inherit;
+	visibility: hidden;
+	}
+.leaflet-tile-loaded {
+	visibility: inherit;
+	}
+.leaflet-zoom-box {
+	width: 0;
+	height: 0;
+	-moz-box-sizing: border-box;
+	     box-sizing: border-box;
+	z-index: 800;
+	}
+/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */
+.leaflet-overlay-pane svg {
+	-moz-user-select: none;
+	}
+
+.leaflet-pane         { z-index: 400; }
+
+.leaflet-tile-pane    { z-index: 200; }
+.leaflet-overlay-pane { z-index: 400; }
+.leaflet-shadow-pane  { z-index: 500; }
+.leaflet-marker-pane  { z-index: 600; }
+.leaflet-tooltip-pane   { z-index: 650; }
+.leaflet-popup-pane   { z-index: 700; }
+
+.leaflet-map-pane canvas { z-index: 100; }
+.leaflet-map-pane svg    { z-index: 200; }
+
+.leaflet-vml-shape {
+	width: 1px;
+	height: 1px;
+	}
+.lvml {
+	behavior: url(#default#VML);
+	display: inline-block;
+	position: absolute;
+	}
+
+
+/* control positioning */
+
+.leaflet-control {
+	position: relative;
+	z-index: 800;
+	pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
+	pointer-events: auto;
+	}
+.leaflet-top,
+.leaflet-bottom {
+	position: absolute;
+	z-index: 1000;
+	pointer-events: none;
+	}
+.leaflet-top {
+	top: 0;
+	}
+.leaflet-right {
+	right: 0;
+	}
+.leaflet-bottom {
+	bottom: 0;
+	}
+.leaflet-left {
+	left: 0;
+	}
+.leaflet-control {
+	float: left;
+	clear: both;
+	}
+.leaflet-right .leaflet-control {
+	float: right;
+	}
+.leaflet-top .leaflet-control {
+	margin-top: 10px;
+	}
+.leaflet-bottom .leaflet-control {
+	margin-bottom: 10px;
+	}
+.leaflet-left .leaflet-control {
+	margin-left: 10px;
+	}
+.leaflet-right .leaflet-control {
+	margin-right: 10px;
+	}
+
+
+/* zoom and fade animations */
+
+.leaflet-fade-anim .leaflet-tile {
+	will-change: opacity;
+	}
+.leaflet-fade-anim .leaflet-popup {
+	opacity: 0;
+	-webkit-transition: opacity 0.2s linear;
+	   -moz-transition: opacity 0.2s linear;
+	     -o-transition: opacity 0.2s linear;
+	        transition: opacity 0.2s linear;
+	}
+.leaflet-fade-anim .leaflet-map-pane .leaflet-popup {
+	opacity: 1;
+	}
+.leaflet-zoom-animated {
+	-webkit-transform-origin: 0 0;
+	    -ms-transform-origin: 0 0;
+	        transform-origin: 0 0;
+	}
+.leaflet-zoom-anim .leaflet-zoom-animated {
+	will-change: transform;
+	}
+.leaflet-zoom-anim .leaflet-zoom-animated {
+	-webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1);
+	   -moz-transition:    -moz-transform 0.25s cubic-bezier(0,0,0.25,1);
+	     -o-transition:      -o-transform 0.25s cubic-bezier(0,0,0.25,1);
+	        transition:         transform 0.25s cubic-bezier(0,0,0.25,1);
+	}
+.leaflet-zoom-anim .leaflet-tile,
+.leaflet-pan-anim .leaflet-tile {
+	-webkit-transition: none;
+	   -moz-transition: none;
+	     -o-transition: none;
+	        transition: none;
+	}
+
+.leaflet-zoom-anim .leaflet-zoom-hide {
+	visibility: hidden;
+	}
+
+
+/* cursors */
+
+.leaflet-interactive {
+	cursor: pointer;
+	}
+.leaflet-grab {
+	cursor: -webkit-grab;
+	cursor:    -moz-grab;
+	}
+.leaflet-crosshair,
+.leaflet-crosshair .leaflet-interactive {
+	cursor: crosshair;
+	}
+.leaflet-popup-pane,
+.leaflet-control {
+	cursor: auto;
+	}
+.leaflet-dragging .leaflet-grab,
+.leaflet-dragging .leaflet-grab .leaflet-interactive,
+.leaflet-dragging .leaflet-marker-draggable {
+	cursor: move;
+	cursor: -webkit-grabbing;
+	cursor:    -moz-grabbing;
+	}
+
+/* marker & overlays interactivity */
+.leaflet-marker-icon,
+.leaflet-marker-shadow,
+.leaflet-image-layer,
+.leaflet-pane > svg path,
+.leaflet-tile-container {
+	pointer-events: none;
+	}
+
+.leaflet-marker-icon.leaflet-interactive,
+.leaflet-image-layer.leaflet-interactive,
+.leaflet-pane > svg path.leaflet-interactive {
+	pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
+	pointer-events: auto;
+	}
+
+/* visual tweaks */
+
+.leaflet-container {
+	background: #ddd;
+	outline: 0;
+	}
+.leaflet-container a {
+	color: #0078A8;
+	}
+.leaflet-container a.leaflet-active {
+	outline: 2px solid orange;
+	}
+.leaflet-zoom-box {
+	border: 2px dotted #38f;
+	background: rgba(255,255,255,0.5);
+	}
+
+
+/* general typography */
+.leaflet-container {
+	font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
+	}
+
+
+/* general toolbar styles */
+
+.leaflet-bar {
+	box-shadow: 0 1px 5px rgba(0,0,0,0.65);
+	border-radius: 4px;
+	}
+.leaflet-bar a,
+.leaflet-bar a:hover {
+	background-color: #fff;
+	border-bottom: 1px solid #ccc;
+	width: 26px;
+	height: 26px;
+	line-height: 26px;
+	display: block;
+	text-align: center;
+	text-decoration: none;
+	color: black;
+	}
+.leaflet-bar a,
+.leaflet-control-layers-toggle {
+	background-position: 50% 50%;
+	background-repeat: no-repeat;
+	display: block;
+	}
+.leaflet-bar a:hover {
+	background-color: #f4f4f4;
+	}
+.leaflet-bar a:first-child {
+	border-top-left-radius: 4px;
+	border-top-right-radius: 4px;
+	}
+.leaflet-bar a:last-child {
+	border-bottom-left-radius: 4px;
+	border-bottom-right-radius: 4px;
+	border-bottom: none;
+	}
+.leaflet-bar a.leaflet-disabled {
+	cursor: default;
+	background-color: #f4f4f4;
+	color: #bbb;
+	}
+
+.leaflet-touch .leaflet-bar a {
+	width: 30px;
+	height: 30px;
+	line-height: 30px;
+	}
+.leaflet-touch .leaflet-bar a:first-child {
+	border-top-left-radius: 2px;
+	border-top-right-radius: 2px;
+	}
+.leaflet-touch .leaflet-bar a:last-child {
+	border-bottom-left-radius: 2px;
+	border-bottom-right-radius: 2px;
+	}
+
+/* zoom control */
+
+.leaflet-control-zoom-in,
+.leaflet-control-zoom-out {
+	font: bold 18px 'Lucida Console', Monaco, monospace;
+	text-indent: 1px;
+	}
+
+.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out  {
+	font-size: 22px;
+	}
+
+
+/* layers control */
+
+.leaflet-control-layers {
+	box-shadow: 0 1px 5px rgba(0,0,0,0.4);
+	background: #fff;
+	border-radius: 5px;
+	}
+.leaflet-control-layers-toggle {
+	background-image: url(images/layers.png);
+	width: 36px;
+	height: 36px;
+	}
+.leaflet-retina .leaflet-control-layers-toggle {
+	background-image: url(images/layers-2x.png);
+	background-size: 26px 26px;
+	}
+.leaflet-touch .leaflet-control-layers-toggle {
+	width: 44px;
+	height: 44px;
+	}
+.leaflet-control-layers .leaflet-control-layers-list,
+.leaflet-control-layers-expanded .leaflet-control-layers-toggle {
+	display: none;
+	}
+.leaflet-control-layers-expanded .leaflet-control-layers-list {
+	display: block;
+	position: relative;
+	}
+.leaflet-control-layers-expanded {
+	padding: 6px 10px 6px 6px;
+	color: #333;
+	background: #fff;
+	}
+.leaflet-control-layers-scrollbar {
+	overflow-y: scroll;
+	overflow-x: hidden;
+	padding-right: 5px;
+	}
+.leaflet-control-layers-selector {
+	margin-top: 2px;
+	position: relative;
+	top: 1px;
+	}
+.leaflet-control-layers label {
+	display: block;
+	}
+.leaflet-control-layers-separator {
+	height: 0;
+	border-top: 1px solid #ddd;
+	margin: 5px -10px 5px -6px;
+	}
+
+/* Default icon URLs */
+.leaflet-default-icon-path {
+	background-image: url(images/marker-icon.png);
+	}
+
+
+/* attribution and scale controls */
+
+.leaflet-container .leaflet-control-attribution {
+	background: #fff;
+	background: rgba(255, 255, 255, 0.7);
+	margin: 0;
+	}
+.leaflet-control-attribution,
+.leaflet-control-scale-line {
+	padding: 0 5px;
+	color: #333;
+	}
+.leaflet-control-attribution a {
+	text-decoration: none;
+	}
+.leaflet-control-attribution a:hover {
+	text-decoration: underline;
+	}
+.leaflet-container .leaflet-control-attribution,
+.leaflet-container .leaflet-control-scale {
+	font-size: 11px;
+	}
+.leaflet-left .leaflet-control-scale {
+	margin-left: 5px;
+	}
+.leaflet-bottom .leaflet-control-scale {
+	margin-bottom: 5px;
+	}
+.leaflet-control-scale-line {
+	border: 2px solid #777;
+	border-top: none;
+	line-height: 1.1;
+	padding: 2px 5px 1px;
+	font-size: 11px;
+	white-space: nowrap;
+	overflow: hidden;
+	-moz-box-sizing: border-box;
+	     box-sizing: border-box;
+
+	background: #fff;
+	background: rgba(255, 255, 255, 0.5);
+	}
+.leaflet-control-scale-line:not(:first-child) {
+	border-top: 2px solid #777;
+	border-bottom: none;
+	margin-top: -2px;
+	}
+.leaflet-control-scale-line:not(:first-child):not(:last-child) {
+	border-bottom: 2px solid #777;
+	}
+
+.leaflet-touch .leaflet-control-attribution,
+.leaflet-touch .leaflet-control-layers,
+.leaflet-touch .leaflet-bar {
+	box-shadow: none;
+	}
+.leaflet-touch .leaflet-control-layers,
+.leaflet-touch .leaflet-bar {
+	border: 2px solid rgba(0,0,0,0.2);
+	background-clip: padding-box;
+	}
+
+
+/* popup */
+
+.leaflet-popup {
+	position: absolute;
+	text-align: center;
+	margin-bottom: 20px;
+	}
+.leaflet-popup-content-wrapper {
+	padding: 1px;
+	text-align: left;
+	border-radius: 12px;
+	}
+.leaflet-popup-content {
+	margin: 13px 19px;
+	line-height: 1.4;
+	}
+.leaflet-popup-content p {
+	margin: 18px 0;
+	}
+.leaflet-popup-tip-container {
+	width: 40px;
+	height: 20px;
+	position: absolute;
+	left: 50%;
+	margin-left: -20px;
+	overflow: hidden;
+	pointer-events: none;
+	}
+.leaflet-popup-tip {
+	width: 17px;
+	height: 17px;
+	padding: 1px;
+
+	margin: -10px auto 0;
+
+	-webkit-transform: rotate(45deg);
+	   -moz-transform: rotate(45deg);
+	    -ms-transform: rotate(45deg);
+	     -o-transform: rotate(45deg);
+	        transform: rotate(45deg);
+	}
+.leaflet-popup-content-wrapper,
+.leaflet-popup-tip {
+	background: white;
+	color: #333;
+	box-shadow: 0 3px 14px rgba(0,0,0,0.4);
+	}
+.leaflet-container a.leaflet-popup-close-button {
+	position: absolute;
+	top: 0;
+	right: 0;
+	padding: 4px 4px 0 0;
+	border: none;
+	text-align: center;
+	width: 18px;
+	height: 14px;
+	font: 16px/14px Tahoma, Verdana, sans-serif;
+	color: #c3c3c3;
+	text-decoration: none;
+	font-weight: bold;
+	background: transparent;
+	}
+.leaflet-container a.leaflet-popup-close-button:hover {
+	color: #999;
+	}
+.leaflet-popup-scrolled {
+	overflow: auto;
+	border-bottom: 1px solid #ddd;
+	border-top: 1px solid #ddd;
+	}
+
+.leaflet-oldie .leaflet-popup-content-wrapper {
+	zoom: 1;
+	}
+.leaflet-oldie .leaflet-popup-tip {
+	width: 24px;
+	margin: 0 auto;
+
+	-ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)";
+	filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678);
+	}
+.leaflet-oldie .leaflet-popup-tip-container {
+	margin-top: -1px;
+	}
+
+.leaflet-oldie .leaflet-control-zoom,
+.leaflet-oldie .leaflet-control-layers,
+.leaflet-oldie .leaflet-popup-content-wrapper,
+.leaflet-oldie .leaflet-popup-tip {
+	border: 1px solid #999;
+	}
+
+
+/* div icon */
+
+.leaflet-div-icon {
+	background: #fff;
+	border: 1px solid #666;
+	}
+
+
+/* Tooltip */
+/* Base styles for the element that has a tooltip */
+.leaflet-tooltip {
+	position: absolute;
+	padding: 6px;
+	background-color: #fff;
+	border: 1px solid #fff;
+	border-radius: 3px;
+	color: #222;
+	white-space: nowrap;
+	-webkit-user-select: none;
+	-moz-user-select: none;
+	-ms-user-select: none;
+	user-select: none;
+	pointer-events: none;
+	box-shadow: 0 1px 3px rgba(0,0,0,0.4);
+	}
+.leaflet-tooltip.leaflet-clickable {
+	cursor: pointer;
+	pointer-events: auto;
+	}
+.leaflet-tooltip-top:before,
+.leaflet-tooltip-bottom:before,
+.leaflet-tooltip-left:before,
+.leaflet-tooltip-right:before {
+	position: absolute;
+	pointer-events: none;
+	border: 6px solid transparent;
+	background: transparent;
+	content: "";
+	}
+
+/* Directions */
+
+.leaflet-tooltip-bottom {
+	margin-top: 6px;
+}
+.leaflet-tooltip-top {
+	margin-top: -6px;
+}
+.leaflet-tooltip-bottom:before,
+.leaflet-tooltip-top:before {
+	left: 50%;
+	margin-left: -6px;
+	}
+.leaflet-tooltip-top:before {
+	bottom: 0;
+	margin-bottom: -12px;
+	border-top-color: #fff;
+	}
+.leaflet-tooltip-bottom:before {
+	top: 0;
+	margin-top: -12px;
+	margin-left: -6px;
+	border-bottom-color: #fff;
+	}
+.leaflet-tooltip-left {
+	margin-left: -6px;
+}
+.leaflet-tooltip-right {
+	margin-left: 6px;
+}
+.leaflet-tooltip-left:before,
+.leaflet-tooltip-right:before {
+	top: 50%;
+	margin-top: -6px;
+	}
+.leaflet-tooltip-left:before {
+	right: 0;
+	margin-right: -12px;
+	border-left-color: #fff;
+	}
+.leaflet-tooltip-right:before {
+	left: 0;
+	margin-left: -12px;
+	border-right-color: #fff;
+	}
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/images/cea4022etage2.png b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/images/cea4022etage2.png
new file mode 100644
index 0000000..9b5c69b
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/images/cea4022etage2.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/images/ceaptl.png b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/images/ceaptl.png
new file mode 100644
index 0000000..21c049e
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/images/ceaptl.png
Binary files differ
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/js/custom.js b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/js/custom.js
new file mode 100644
index 0000000..1d28258
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/js/custom.js
@@ -0,0 +1,334 @@
+/*
+*   Copyright (c) 2020 - 2021 Kentyou.
+*   All rights reserved. This program and the accompanying materials
+*   are made available under the terms of the Eclipse Public License v1.0
+*   which accompanies this distribution, and is available at
+*   http://www.eclipse.org/legal/epl-v10.html
+*  
+*   Contributors:
+*      Kentyou - initial API and implementation
+*/
+
+// For debug purpose, for the eclipse webview...
+function toStr(obj) {
+  var output="";
+  for(var i in obj) {
+    var v = obj[i];
+    output += i + ":" + v + "\n"
+  }
+  return output;
+}
+
+function initialization(){
+ try{
+   return eval('(' + synchronusGET("/webapp/outdoor/init") + ')');
+ } catch(err){
+   console.error(err);
+   var tmp = {};
+   
+   tmp["lat"] = 45.19954840972916;
+   tmp["lng"] = 5.702977180480957;
+   tmp["zoom"]= 15;
+   return tmp;
+ }
+}
+
+var init = initialization();
+
+var map = L.map('map',{maxZoom:25}).setView([init.lat,init.lng], init.zoom);
+var rawLayer = L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
+	maxZoom: 25,attribution: '&copy; <a href="http://osm.org/copyright">OpenStreetMap</a> contributors - <a href="#" onclick="window.location.reload()">reload</a>'
+});
+
+rawLayer.addTo(map);
+
+var markers = {};
+var icons = {};
+
+var defaultIcon = L.icon({
+    iconUrl: 'css/images/marker-icon.png',
+    iconSize: [25, 41],
+    iconAnchor: [13, 41],
+    popupAnchor: [0, -40],
+    shadowUrl: 'css/images/marker-shadow.png',
+    shadowSize: [41, 41],
+    shadowAnchor: [13, 41]
+});
+icons['default']=defaultIcon;
+
+var busStopIcon = L.icon({
+    iconUrl: 'css/images/bus-icon.png',
+    iconSize: [39, 39],
+    iconAnchor: [20, 41],
+    popupAnchor: [0, -40],
+    shadowUrl: 'css/images/marker-shadow.png',
+    shadowSize: [41, 41],
+    shadowAnchor: [20, 41]
+});
+icons['busStop']=busStopIcon;
+
+var userIcon = L.icon({
+    iconUrl: 'http://193.48.18.251/images/user.png',
+    iconSize: [39, 39],
+    iconAnchor: [20, 41],
+    popupAnchor: [0, -40],
+    shadowUrl: 'css/images/marker-shadow.png',
+    shadowSize: [41, 41],
+    shadowAnchor: [20, 41]
+});
+icons['user']=userIcon;
+
+var restaurantIcon = L.icon({
+    iconUrl: 'http://193.48.18.251/images/restaurant.png',
+    iconSize: [39, 39],
+    iconAnchor: [20, 41],
+    popupAnchor: [0, -40],
+    shadowUrl: 'css/images/marker-shadow.png',
+    shadowSize: [41, 41],
+    shadowAnchor: [20, 41]
+});
+icons['restaurant']=restaurantIcon;
+
+imageBounds4022 = [[45.19317,5.70630],[45.19350,5.70675]];
+imageBoundsPTL = [[45.19591,5.70564],[45.19555,5.70617]];
+
+var bat4022=L.imageOverlay('/webapp/outdoor/static/images/cea4022etage2.png', imageBounds4022);
+var batPTL=L.imageOverlay('/webapp/outdoor/static/images/ceaptl.png', imageBoundsPTL);
+
+bat4022.addTo(map);
+bat4022.setOpacity(0.0);
+
+batPTL.addTo(map);
+batPTL.setOpacity(0.0);
+
+map.on('zoomend', function(e) {
+    console.log(e.target._zoom);
+  if(e.target._zoom >= 20) {
+	bat4022.setOpacity(0.5);
+	batPTL.setOpacity(0.5);
+  }else {
+	bat4022.setOpacity(0.0);
+	batPTL.setOpacity(0.0);
+  }
+});
+
+function synchronusGET(url){
+    return $.ajax({
+        type: "GET",
+        url: url,
+        cache: false,
+        async: false
+    }).responseText;
+}
+
+function computeCoordinates(x, y) {
+    var point = L.point(x, y);
+    var latlng = map.containerPointToLatLng(point);
+    var lat = latlng.lat;
+    var lng = latlng.lng;
+    var latlngArray = new Array();
+    latlngArray[0] = lat;
+    latlngArray[1] = lng;
+    return latlngArray;
+}
+
+function updateDeviceLocation(lat, lng, deviceName, iconName) {
+
+	var markerCache = markers[deviceName]; 
+
+    if (markerCache === undefined) {
+        var iconObject = getIcon(iconName)
+		var content = "<p><b>" + deviceName + "</b></p><p> please wait during information refresh...</p>";
+		var marker = L.marker([lat, lng], {draggable:true, title:deviceName, icon:iconObject}).bindPopup(content,{maxWidth:600}).addTo(map);
+		marker.on('dragend', markerDrag);
+		marker.on('click',function(e) {updatePopupAtInit(e,deviceName);} );
+		markers[deviceName] = marker;
+    } else {
+    	markerCache.setLatLng(new L.latLng(lat, lng));
+    	markerCache.update();
+    }
+    return Boolean("true");
+}
+
+function updateDeviceIcon(deviceName, iconName) {	
+ try{        
+		var markerCache = markers[deviceName];
+		if (markerCache === undefined) {
+		    return Boolean("false");
+		}
+		var iconObject = getIcon(iconName)
+		markerCache.setIcon(iconObject);
+		markerCache.update();
+		return Boolean("true");
+    }catch(error){
+    	console.error(error);
+    }
+ }
+
+function getIcon(iconName) {
+	var ic; 
+	if(iconName!==undefined)
+    	ic = icons[iconName];
+    if (ic === undefined) 
+        return icons['default'];       
+    return ic;  
+}
+
+function deleteMarker(deviceName) {
+    var marker = markers[deviceName];
+    if (marker !== undefined) {
+      map.removeLayer(marker);
+      markers[deviceName] = undefined;
+    }
+    return Boolean("true");
+}
+
+
+function markerDrag(e) {
+  var text = e.target._popup._content;
+  var latlng = e.target._latlng;  
+  var deviceName = e.target.options.title;
+    
+  var marker = markers[deviceName];
+
+  $.ajax
+  ({
+      contentType : 'application/json',
+      type: "POST",
+      url: "/webapp/updatelocation/" + deviceName,
+      async: false,
+      data: JSON.stringify({"lat": latlng.lat, "lng": latlng.lng }),
+      error : function(resultat, statut, erreur) {
+          var oldLatLng = JSON.parse(resultat.responseText);
+          var oldLat = oldLatLng.lat;
+          var oldLng = oldLatLng.lng;
+          updateDeviceLocation(oldLat, oldLng, deviceName);
+          alert("The location of " + deviceName + " device is not updatable");
+      }
+  });
+}
+
+function updatePopupAtInit(e, deviceName) {
+  updatePopup(markers[deviceName].getPopup(), deviceName);
+}
+
+function updatePopupOnClick(deviceName) {
+  var popup = markers[deviceName].getPopup();
+  updatePopup(popup, deviceName);
+}
+
+function updatePopup(popup, deviceName) {
+  $.get("/webapp/deviceinfo/" + deviceName, function(data) {
+    popup.setContent(data);
+    popup.update();
+  });
+}
+
+function updatePopupOnClick(deviceName, serviceName) {
+   $.get("/webapp/deviceinfo/" + deviceName + "/" + serviceName, function(data) {
+    markers[deviceName].closePopup();
+    markers[deviceName].setPopupContent(data);
+    markers[deviceName].getPopup().update();
+    markers[deviceName].openPopup();
+  });
+}
+
+function performAction(gatewayName, deviceName, serviceName, resourceName) {
+  $.get("/webapp/performAction/" + gatewayName + "/" + deviceName + "/" + serviceName + "/" + resourceName, function(data) {
+    var result = JSON.parse(data);
+    var title = result.title
+    var message = result.message;
+    var status = result.status;
+    
+	if (status != "SUCCESS") {    
+    	var msg = '[' + status + ']' + ' ' + title + '\n\n' + message;
+    	alert(msg);
+    } else {
+      document.getElementById("notif").style.visibility = "visible";
+      window.setTimeout(function() {document.getElementById("notif").style.visibility = "hidden";}, 1000);
+    }
+  });
+}
+
+function showImage(imageUrl) {
+  var content = '<a href="#" onclick="closeImage();"><img src="' + imageUrl + '" /></a>';
+  document.getElementById("image").innerHTML = content;
+  document.getElementById("image").style.visibility = "visible";
+}
+
+function closeImage(imageUrl) {
+  document.getElementById("image").style.visibility = "hidden";
+}
+
+var geo = null;
+var geo_json = null;
+var geo_markers_arr = {};
+var geo_layers_arr = {};
+
+var plus = document.getElementById("plus");
+var plus_button = document.getElementById("plus_button");
+
+var less = document.getElementById("less");
+var less_button = document.getElementById("less_button");
+
+var geo_extra = document.getElementById("geo_extra");
+var geodef = document.getElementById("geodef");		
+
+var validator = document.getElementById("validator");
+var geodef_name = document.getElementById("geodef_name");
+var geo_markers = document.getElementById("geo_markers");
+
+plus_button.onclick=function(e){
+	less.style.display="table-cell";
+	plus.style.display="none";
+	geo_extra.style.display="flex";
+}
+
+less_button.onclick=function(e){
+	plus.style.display="table-cell";
+	less.style.display="none";
+	geo_extra.style.display="none";
+	geodef.value = '';
+}
+
+validator.onclick = function(e){
+	geo_json = JSON.parse(geodef.value);			   
+	var name = geodef_name.value;
+	var length = Object.keys(geo_markers_arr).length;
+	   
+	if(name===undefined || name==='')
+	    name = "GeoJSON_"+length;
+	   		
+	geodef_name.value = '';
+	geodef.value = '';
+
+	geo_markers_arr[name] = geo_json;
+	   			   
+	var block_to_insert = document.createElement( 'a' );
+	block_to_insert.ping = false;
+	block_to_insert.name = name;
+	block_to_insert.style="display:table-cell"
+	block_to_insert.type = "geoanchor";
+	block_to_insert.innerHTML = name ;
+	block_to_insert.onclick = function(e){
+		try{
+			var src = event.srcElement;
+	  		var enabled_ = (src.ping==='true');
+	   		var name_  = src.name;
+	   		if(enabled_){
+	   			 src.ping=false;
+	   			 src.type="geoanchor";
+				 geo_layers_arr[name_].clearLayers();
+				 geo_layers_arr[name_]=null;
+	   		} else {
+	   			 src.ping=true;
+	   			 src.type="geoanchor-enabled";
+	   			 geo_layers_arr[name_]= L.geoJSON(geo_markers_arr[name_]).addTo(map);
+	   		}			   		
+		} catch(err){
+			console.error(err);
+		}
+	} 			  
+	geo_markers.appendChild( block_to_insert ); 
+	   		   
+}
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/js/jquery-2.2.0.min.js b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/js/jquery-2.2.0.min.js
new file mode 100644
index 0000000..06ac263
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/js/jquery-2.2.0.min.js
@@ -0,0 +1,4 @@
+/*! jQuery v2.2.0 | (c) jQuery Foundation | jquery.org/license */
+!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=a.document,e=c.slice,f=c.concat,g=c.push,h=c.indexOf,i={},j=i.toString,k=i.hasOwnProperty,l={},m="2.2.0",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return e.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:e.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a){return n.each(this,a)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(e.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor()},push:g,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){var b=a&&a.toString();return!n.isArray(a)&&b-parseFloat(b)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!k.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?i[j.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=d.createElement("script"),b.text=a,d.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b){var c,d=0;if(s(a)){for(c=a.length;c>d;d++)if(b.call(a[d],d,a[d])===!1)break}else for(d in a)if(b.call(a[d],d,a[d])===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):g.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:h.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,e,g=0,h=[];if(s(a))for(d=a.length;d>g;g++)e=b(a[g],g,c),null!=e&&h.push(e);else for(g in a)e=b(a[g],g,c),null!=e&&h.push(e);return f.apply([],h)},guid:1,proxy:function(a,b){var c,d,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(d=e.call(arguments,2),f=function(){return a.apply(b||this,d.concat(e.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:l}),"function"==typeof Symbol&&(n.fn[Symbol.iterator]=c[Symbol.iterator]),n.each("Boolean Number String Function Array Date RegExp Object Error Symbol".split(" "),function(a,b){i["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=!!a&&"length"in a&&a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=ga(),z=ga(),A=ga(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+M+"))|)"+L+"*\\]",O=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+N+")*)|.*)\\)|)",P=new RegExp(L+"+","g"),Q=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),R=new RegExp("^"+L+"*,"+L+"*"),S=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),T=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),U=new RegExp(O),V=new RegExp("^"+M+"$"),W={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M+"|[*])"),ATTR:new RegExp("^"+N),PSEUDO:new RegExp("^"+O),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},X=/^(?:input|select|textarea|button)$/i,Y=/^h\d$/i,Z=/^[^{]+\{\s*\[native \w/,$=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,_=/[+~]/,aa=/'|\\/g,ba=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),ca=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},da=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(ea){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function fa(a,b,d,e){var f,h,j,k,l,o,r,s,w=b&&b.ownerDocument,x=b?b.nodeType:9;if(d=d||[],"string"!=typeof a||!a||1!==x&&9!==x&&11!==x)return d;if(!e&&((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,p)){if(11!==x&&(o=$.exec(a)))if(f=o[1]){if(9===x){if(!(j=b.getElementById(f)))return d;if(j.id===f)return d.push(j),d}else if(w&&(j=w.getElementById(f))&&t(b,j)&&j.id===f)return d.push(j),d}else{if(o[2])return H.apply(d,b.getElementsByTagName(a)),d;if((f=o[3])&&c.getElementsByClassName&&b.getElementsByClassName)return H.apply(d,b.getElementsByClassName(f)),d}if(c.qsa&&!A[a+" "]&&(!q||!q.test(a))){if(1!==x)w=b,s=a;else if("object"!==b.nodeName.toLowerCase()){(k=b.getAttribute("id"))?k=k.replace(aa,"\\$&"):b.setAttribute("id",k=u),r=g(a),h=r.length,l=V.test(k)?"#"+k:"[id='"+k+"']";while(h--)r[h]=l+" "+qa(r[h]);s=r.join(","),w=_.test(a)&&oa(b.parentNode)||b}if(s)try{return H.apply(d,w.querySelectorAll(s)),d}catch(y){}finally{k===u&&b.removeAttribute("id")}}}return i(a.replace(Q,"$1"),b,d,e)}function ga(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ha(a){return a[u]=!0,a}function ia(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function ja(a,b){var c=a.split("|"),e=c.length;while(e--)d.attrHandle[c[e]]=b}function ka(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function la(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function ma(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function na(a){return ha(function(b){return b=+b,ha(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function oa(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=fa.support={},f=fa.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=fa.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=n.documentElement,p=!f(n),(e=n.defaultView)&&e.top!==e&&(e.addEventListener?e.addEventListener("unload",da,!1):e.attachEvent&&e.attachEvent("onunload",da)),c.attributes=ia(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=ia(function(a){return a.appendChild(n.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=Z.test(n.getElementsByClassName),c.getById=ia(function(a){return o.appendChild(a).id=u,!n.getElementsByName||!n.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c?[c]:[]}},d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(ba,ca);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return"undefined"!=typeof b.getElementsByClassName&&p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=Z.test(n.querySelectorAll))&&(ia(function(a){o.appendChild(a).innerHTML="<a id='"+u+"'></a><select id='"+u+"-\r\\' msallowcapture=''><option selected=''></option></select>",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),ia(function(a){var b=n.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=Z.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&ia(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",O)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=Z.test(o.compareDocumentPosition),t=b||Z.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===n||a.ownerDocument===v&&t(v,a)?-1:b===n||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,g=[a],h=[b];if(!e||!f)return a===n?-1:b===n?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return ka(a,b);c=a;while(c=c.parentNode)g.unshift(c);c=b;while(c=c.parentNode)h.unshift(c);while(g[d]===h[d])d++;return d?ka(g[d],h[d]):g[d]===v?-1:h[d]===v?1:0},n):n},fa.matches=function(a,b){return fa(a,null,null,b)},fa.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(T,"='$1']"),c.matchesSelector&&p&&!A[b+" "]&&(!r||!r.test(b))&&(!q||!q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return fa(b,n,null,[a]).length>0},fa.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},fa.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},fa.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},fa.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=fa.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=fa.selectors={cacheLength:50,createPseudo:ha,match:W,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(ba,ca),a[3]=(a[3]||a[4]||a[5]||"").replace(ba,ca),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||fa.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&fa.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return W.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&U.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(ba,ca).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=fa.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(P," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h,t=!1;if(q){if(f){while(p){m=b;while(m=m[p])if(h?m.nodeName.toLowerCase()===r:1===m.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){m=q,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n&&j[2],m=n&&q.childNodes[n];while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if(1===m.nodeType&&++t&&m===b){k[a]=[w,n,t];break}}else if(s&&(m=b,l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),j=k[a]||[],n=j[0]===w&&j[1],t=n),t===!1)while(m=++n&&m&&m[p]||(t=n=0)||o.pop())if((h?m.nodeName.toLowerCase()===r:1===m.nodeType)&&++t&&(s&&(l=m[u]||(m[u]={}),k=l[m.uniqueID]||(l[m.uniqueID]={}),k[a]=[w,t]),m===b))break;return t-=e,t===d||t%d===0&&t/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||fa.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ha(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ha(function(a){var b=[],c=[],d=h(a.replace(Q,"$1"));return d[u]?ha(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ha(function(a){return function(b){return fa(a,b).length>0}}),contains:ha(function(a){return a=a.replace(ba,ca),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ha(function(a){return V.test(a||"")||fa.error("unsupported lang: "+a),a=a.replace(ba,ca).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Y.test(a.nodeName)},input:function(a){return X.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:na(function(){return[0]}),last:na(function(a,b){return[b-1]}),eq:na(function(a,b,c){return[0>c?c+b:c]}),even:na(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:na(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:na(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:na(function(a,b,c){for(var d=0>c?c+b:c;++d<b;)a.push(d);return a})}},d.pseudos.nth=d.pseudos.eq;for(b in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})d.pseudos[b]=la(b);for(b in{submit:!0,reset:!0})d.pseudos[b]=ma(b);function pa(){}pa.prototype=d.filters=d.pseudos,d.setFilters=new pa,g=fa.tokenize=function(a,b){var c,e,f,g,h,i,j,k=z[a+" "];if(k)return b?0:k.slice(0);h=a,i=[],j=d.preFilter;while(h){(!c||(e=R.exec(h)))&&(e&&(h=h.slice(e[0].length)||h),i.push(f=[])),c=!1,(e=S.exec(h))&&(c=e.shift(),f.push({value:c,type:e[0].replace(Q," ")}),h=h.slice(c.length));for(g in d.filter)!(e=W[g].exec(h))||j[g]&&!(e=j[g](e))||(c=e.shift(),f.push({value:c,type:g,matches:e}),h=h.slice(c.length));if(!c)break}return b?h.length:h?fa.error(a):z(a,i).slice(0)};function qa(a){for(var b=0,c=a.length,d="";c>b;b++)d+=a[b].value;return d}function ra(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j,k=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(j=b[u]||(b[u]={}),i=j[b.uniqueID]||(j[b.uniqueID]={}),(h=i[d])&&h[0]===w&&h[1]===f)return k[2]=h[2];if(i[d]=k,k[2]=a(b,c,g))return!0}}}function sa(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ta(a,b,c){for(var d=0,e=b.length;e>d;d++)fa(a,b[d],c);return c}function ua(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function va(a,b,c,d,e,f){return d&&!d[u]&&(d=va(d)),e&&!e[u]&&(e=va(e,f)),ha(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ta(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:ua(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=ua(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=ua(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function wa(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=ra(function(a){return a===b},h,!0),l=ra(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[ra(sa(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return va(i>1&&sa(m),i>1&&qa(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(Q,"$1"),c,e>i&&wa(a.slice(i,e)),f>e&&wa(a=a.slice(e)),f>e&&qa(a))}m.push(c)}return sa(m)}function xa(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,o,q,r=0,s="0",t=f&&[],u=[],v=j,x=f||e&&d.find.TAG("*",k),y=w+=null==v?1:Math.random()||.1,z=x.length;for(k&&(j=g===n||g||k);s!==z&&null!=(l=x[s]);s++){if(e&&l){o=0,g||l.ownerDocument===n||(m(l),h=!p);while(q=a[o++])if(q(l,g||n,h)){i.push(l);break}k&&(w=y)}c&&((l=!q&&l)&&r--,f&&t.push(l))}if(r+=s,c&&s!==r){o=0;while(q=b[o++])q(t,u,g,h);if(f){if(r>0)while(s--)t[s]||u[s]||(u[s]=F.call(i));u=ua(u)}H.apply(i,u),k&&!f&&u.length>0&&r+b.length>1&&fa.uniqueSort(i)}return k&&(w=y,j=v),t};return c?ha(f):f}return h=fa.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=wa(b[c]),f[u]?d.push(f):e.push(f);f=A(a,xa(e,d)),f.selector=a}return f},i=fa.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(ba,ca),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=W.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(ba,ca),_.test(j[0].type)&&oa(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&qa(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,!b||_.test(a)&&oa(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=ia(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),ia(function(a){return a.innerHTML="<a href='#'></a>","#"===a.firstChild.getAttribute("href")})||ja("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&ia(function(a){return a.innerHTML="<input/>",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||ja("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),ia(function(a){return null==a.getAttribute("disabled")})||ja(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),fa}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.uniqueSort=n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},v=function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c},w=n.expr.match.needsContext,x=/^<([\w-]+)\s*\/?>(?:<\/\1>|)$/,y=/^.[^:#\[\.,]*$/;function z(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(y.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return h.call(b,a)>-1!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(z(this,a||[],!1))},not:function(a){return this.pushStack(z(this,a||[],!0))},is:function(a){return!!z(this,"string"==typeof a&&w.test(a)?n(a):a||[],!1).length}});var A,B=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=n.fn.init=function(a,b,c){var e,f;if(!a)return this;if(c=c||A,"string"==typeof a){if(e="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:B.exec(a),!e||!e[1]&&b)return!b||b.jquery?(b||c).find(a):this.constructor(b).find(a);if(e[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(e[1],b&&b.nodeType?b.ownerDocument||b:d,!0)),x.test(e[1])&&n.isPlainObject(b))for(e in b)n.isFunction(this[e])?this[e](b[e]):this.attr(e,b[e]);return this}return f=d.getElementById(e[2]),f&&f.parentNode&&(this.length=1,this[0]=f),this.context=d,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?void 0!==c.ready?c.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};C.prototype=n.fn,A=n(d);var D=/^(?:parents|prev(?:Until|All))/,E={children:!0,contents:!0,next:!0,prev:!0};n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=w.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.uniqueSort(f):f)},index:function(a){return a?"string"==typeof a?h.call(n(a),this[0]):h.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.uniqueSort(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function F(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return u(a,"parentNode")},parentsUntil:function(a,b,c){return u(a,"parentNode",c)},next:function(a){return F(a,"nextSibling")},prev:function(a){return F(a,"previousSibling")},nextAll:function(a){return u(a,"nextSibling")},prevAll:function(a){return u(a,"previousSibling")},nextUntil:function(a,b,c){return u(a,"nextSibling",c)},prevUntil:function(a,b,c){return u(a,"previousSibling",c)},siblings:function(a){return v((a.parentNode||{}).firstChild,a)},children:function(a){return v(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(E[a]||n.uniqueSort(e),D.test(a)&&e.reverse()),this.pushStack(e)}});var G=/\S+/g;function H(a){var b={};return n.each(a.match(G)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?H(a):n.extend({},a);var b,c,d,e,f=[],g=[],h=-1,i=function(){for(e=a.once,d=b=!0;g.length;h=-1){c=g.shift();while(++h<f.length)f[h].apply(c[0],c[1])===!1&&a.stopOnFalse&&(h=f.length,c=!1)}a.memory||(c=!1),b=!1,e&&(f=c?[]:"")},j={add:function(){return f&&(c&&!b&&(h=f.length-1,g.push(c)),function d(b){n.each(b,function(b,c){n.isFunction(c)?a.unique&&j.has(c)||f.push(c):c&&c.length&&"string"!==n.type(c)&&d(c)})}(arguments),c&&!b&&i()),this},remove:function(){return n.each(arguments,function(a,b){var c;while((c=n.inArray(b,f,c))>-1)f.splice(c,1),h>=c&&h--}),this},has:function(a){return a?n.inArray(a,f)>-1:f.length>0},empty:function(){return f&&(f=[]),this},disable:function(){return e=g=[],f=c="",this},disabled:function(){return!f},lock:function(){return e=g=[],c||(f=c=""),this},locked:function(){return!!e},fireWith:function(a,c){return e||(c=c||[],c=[a,c.slice?c.slice():c],g.push(c),b||i()),this},fire:function(){return j.fireWith(this,arguments),this},fired:function(){return!!d}};return j},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().progress(c.notify).done(c.resolve).fail(c.reject):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=e.call(arguments),d=c.length,f=1!==d||a&&n.isFunction(a.promise)?d:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(d){b[a]=this,c[a]=arguments.length>1?e.call(arguments):d,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(d>1)for(i=new Array(d),j=new Array(d),k=new Array(d);d>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().progress(h(b,j,i)).done(h(b,k,c)).fail(g.reject):--f;return f||g.resolveWith(k,c),g.promise()}});var I;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(I.resolveWith(d,[n]),n.fn.triggerHandler&&(n(d).triggerHandler("ready"),n(d).off("ready"))))}});function J(){d.removeEventListener("DOMContentLoaded",J),a.removeEventListener("load",J),n.ready()}n.ready.promise=function(b){return I||(I=n.Deferred(),"complete"===d.readyState||"loading"!==d.readyState&&!d.documentElement.doScroll?a.setTimeout(n.ready):(d.addEventListener("DOMContentLoaded",J),a.addEventListener("load",J))),I.promise(b)},n.ready.promise();var K=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)K(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f},L=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function M(){this.expando=n.expando+M.uid++}M.uid=1,M.prototype={register:function(a,b){var c=b||{};return a.nodeType?a[this.expando]=c:Object.defineProperty(a,this.expando,{value:c,writable:!0,configurable:!0}),a[this.expando]},cache:function(a){if(!L(a))return{};var b=a[this.expando];return b||(b={},L(a)&&(a.nodeType?a[this.expando]=b:Object.defineProperty(a,this.expando,{value:b,configurable:!0}))),b},set:function(a,b,c){var d,e=this.cache(a);if("string"==typeof b)e[b]=c;else for(d in b)e[d]=b[d];return e},get:function(a,b){return void 0===b?this.cache(a):a[this.expando]&&a[this.expando][b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=a[this.expando];if(void 0!==f){if(void 0===b)this.register(a);else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in f?d=[b,e]:(d=e,d=d in f?[d]:d.match(G)||[])),c=d.length;while(c--)delete f[d[c]]}(void 0===b||n.isEmptyObject(f))&&(a.nodeType?a[this.expando]=void 0:delete a[this.expando])}},hasData:function(a){var b=a[this.expando];return void 0!==b&&!n.isEmptyObject(b)}};var N=new M,O=new M,P=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,Q=/[A-Z]/g;function R(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(Q,"-$&").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:P.test(c)?n.parseJSON(c):c}catch(e){}O.set(a,b,c);
+}else c=void 0;return c}n.extend({hasData:function(a){return O.hasData(a)||N.hasData(a)},data:function(a,b,c){return O.access(a,b,c)},removeData:function(a,b){O.remove(a,b)},_data:function(a,b,c){return N.access(a,b,c)},_removeData:function(a,b){N.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=O.get(f),1===f.nodeType&&!N.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),R(f,d,e[d])));N.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){O.set(this,a)}):K(this,function(b){var c,d;if(f&&void 0===b){if(c=O.get(f,a)||O.get(f,a.replace(Q,"-$&").toLowerCase()),void 0!==c)return c;if(d=n.camelCase(a),c=O.get(f,d),void 0!==c)return c;if(c=R(f,d,void 0),void 0!==c)return c}else d=n.camelCase(a),this.each(function(){var c=O.get(this,d);O.set(this,d,b),a.indexOf("-")>-1&&void 0!==c&&O.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){O.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=N.get(a,b),c&&(!d||n.isArray(c)?d=N.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return N.get(a,c)||N.access(a,c,{empty:n.Callbacks("once memory").add(function(){N.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.length<c?n.queue(this[0],a):void 0===b?this:this.each(function(){var c=n.queue(this,a,b);n._queueHooks(this,a),"fx"===a&&"inprogress"!==c[0]&&n.dequeue(this,a)})},dequeue:function(a){return this.each(function(){n.dequeue(this,a)})},clearQueue:function(a){return this.queue(a||"fx",[])},promise:function(a,b){var c,d=1,e=n.Deferred(),f=this,g=this.length,h=function(){--d||e.resolveWith(f,[f])};"string"!=typeof a&&(b=a,a=void 0),a=a||"fx";while(g--)c=N.get(f[g],a+"queueHooks"),c&&c.empty&&(d++,c.empty.add(h));return h(),e.promise(b)}});var S=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,T=new RegExp("^(?:([+-])=|)("+S+")([a-z%]*)$","i"),U=["Top","Right","Bottom","Left"],V=function(a,b){return a=b||a,"none"===n.css(a,"display")||!n.contains(a.ownerDocument,a)};function W(a,b,c,d){var e,f=1,g=20,h=d?function(){return d.cur()}:function(){return n.css(a,b,"")},i=h(),j=c&&c[3]||(n.cssNumber[b]?"":"px"),k=(n.cssNumber[b]||"px"!==j&&+i)&&T.exec(n.css(a,b));if(k&&k[3]!==j){j=j||k[3],c=c||[],k=+i||1;do f=f||".5",k/=f,n.style(a,b,k+j);while(f!==(f=h()/i)&&1!==f&&--g)}return c&&(k=+k||+i||0,e=c[1]?k+(c[1]+1)*c[2]:+c[2],d&&(d.unit=j,d.start=k,d.end=e)),e}var X=/^(?:checkbox|radio)$/i,Y=/<([\w:-]+)/,Z=/^$|\/(?:java|ecma)script/i,$={option:[1,"<select multiple='multiple'>","</select>"],thead:[1,"<table>","</table>"],col:[2,"<table><colgroup>","</colgroup></table>"],tr:[2,"<table><tbody>","</tbody></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:[0,"",""]};$.optgroup=$.option,$.tbody=$.tfoot=$.colgroup=$.caption=$.thead,$.th=$.td;function _(a,b){var c="undefined"!=typeof a.getElementsByTagName?a.getElementsByTagName(b||"*"):"undefined"!=typeof a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function aa(a,b){for(var c=0,d=a.length;d>c;c++)N.set(a[c],"globalEval",!b||N.get(b[c],"globalEval"))}var ba=/<|&#?\w+;/;function ca(a,b,c,d,e){for(var f,g,h,i,j,k,l=b.createDocumentFragment(),m=[],o=0,p=a.length;p>o;o++)if(f=a[o],f||0===f)if("object"===n.type(f))n.merge(m,f.nodeType?[f]:f);else if(ba.test(f)){g=g||l.appendChild(b.createElement("div")),h=(Y.exec(f)||["",""])[1].toLowerCase(),i=$[h]||$._default,g.innerHTML=i[1]+n.htmlPrefilter(f)+i[2],k=i[0];while(k--)g=g.lastChild;n.merge(m,g.childNodes),g=l.firstChild,g.textContent=""}else m.push(b.createTextNode(f));l.textContent="",o=0;while(f=m[o++])if(d&&n.inArray(f,d)>-1)e&&e.push(f);else if(j=n.contains(f.ownerDocument,f),g=_(l.appendChild(f),"script"),j&&aa(g),c){k=0;while(f=g[k++])Z.test(f.type||"")&&c.push(f)}return l}!function(){var a=d.createDocumentFragment(),b=a.appendChild(d.createElement("div")),c=d.createElement("input");c.setAttribute("type","radio"),c.setAttribute("checked","checked"),c.setAttribute("name","t"),b.appendChild(c),l.checkClone=b.cloneNode(!0).cloneNode(!0).lastChild.checked,b.innerHTML="<textarea>x</textarea>",l.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var da=/^key/,ea=/^(?:mouse|pointer|contextmenu|drag|drop)|click/,fa=/^([^.]*)(?:\.(.+)|)/;function ga(){return!0}function ha(){return!1}function ia(){try{return d.activeElement}catch(a){}}function ja(a,b,c,d,e,f){var g,h;if("object"==typeof b){"string"!=typeof c&&(d=d||c,c=void 0);for(h in b)ja(a,h,c,d,b[h],f);return a}if(null==d&&null==e?(e=c,d=c=void 0):null==e&&("string"==typeof c?(e=d,d=void 0):(e=d,d=c,c=void 0)),e===!1)e=ha;else if(!e)return this;return 1===f&&(g=e,e=function(a){return n().off(a),g.apply(this,arguments)},e.guid=g.guid||(g.guid=n.guid++)),a.each(function(){n.event.add(this,b,e,d,c)})}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return"undefined"!=typeof n&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(G)||[""],j=b.length;while(j--)h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=N.hasData(a)&&N.get(a);if(r&&(i=r.events)){b=(b||"").match(G)||[""],j=b.length;while(j--)if(h=fa.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&N.remove(a,"handle events")}},dispatch:function(a){a=n.event.fix(a);var b,c,d,f,g,h=[],i=e.call(arguments),j=(N.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.rnamespace||a.rnamespace.test(g.namespace))&&(a.handleObj=g,a.data=g.data,d=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==d&&(a.result=d)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&("click"!==a.type||isNaN(a.button)||a.button<1))for(;i!==this;i=i.parentNode||this)if(1===i.nodeType&&(i.disabled!==!0||"click"!==a.type)){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>-1:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h<b.length&&g.push({elem:this,handlers:b.slice(h)}),g},props:"altKey bubbles cancelable ctrlKey currentTarget detail eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(a,b){return null==a.which&&(a.which=null!=b.charCode?b.charCode:b.keyCode),a}},mouseHooks:{props:"button buttons clientX clientY offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(a,b){var c,e,f,g=b.button;return null==a.pageX&&null!=b.clientX&&(c=a.target.ownerDocument||d,e=c.documentElement,f=c.body,a.pageX=b.clientX+(e&&e.scrollLeft||f&&f.scrollLeft||0)-(e&&e.clientLeft||f&&f.clientLeft||0),a.pageY=b.clientY+(e&&e.scrollTop||f&&f.scrollTop||0)-(e&&e.clientTop||f&&f.clientTop||0)),a.which||void 0===g||(a.which=1&g?1:2&g?3:4&g?2:0),a}},fix:function(a){if(a[n.expando])return a;var b,c,e,f=a.type,g=a,h=this.fixHooks[f];h||(this.fixHooks[f]=h=ea.test(f)?this.mouseHooks:da.test(f)?this.keyHooks:{}),e=h.props?this.props.concat(h.props):this.props,a=new n.Event(g),b=e.length;while(b--)c=e[b],a[c]=g[c];return a.target||(a.target=d),3===a.target.nodeType&&(a.target=a.target.parentNode),h.filter?h.filter(a,g):a},special:{load:{noBubble:!0},focus:{trigger:function(){return this!==ia()&&this.focus?(this.focus(),!1):void 0},delegateType:"focusin"},blur:{trigger:function(){return this===ia()&&this.blur?(this.blur(),!1):void 0},delegateType:"focusout"},click:{trigger:function(){return"checkbox"===this.type&&this.click&&n.nodeName(this,"input")?(this.click(),!1):void 0},_default:function(a){return n.nodeName(a.target,"a")}},beforeunload:{postDispatch:function(a){void 0!==a.result&&a.originalEvent&&(a.originalEvent.returnValue=a.result)}}}},n.removeEvent=function(a,b,c){a.removeEventListener&&a.removeEventListener(b,c)},n.Event=function(a,b){return this instanceof n.Event?(a&&a.type?(this.originalEvent=a,this.type=a.type,this.isDefaultPrevented=a.defaultPrevented||void 0===a.defaultPrevented&&a.returnValue===!1?ga:ha):this.type=a,b&&n.extend(this,b),this.timeStamp=a&&a.timeStamp||n.now(),void(this[n.expando]=!0)):new n.Event(a,b)},n.Event.prototype={constructor:n.Event,isDefaultPrevented:ha,isPropagationStopped:ha,isImmediatePropagationStopped:ha,preventDefault:function(){var a=this.originalEvent;this.isDefaultPrevented=ga,a&&a.preventDefault()},stopPropagation:function(){var a=this.originalEvent;this.isPropagationStopped=ga,a&&a.stopPropagation()},stopImmediatePropagation:function(){var a=this.originalEvent;this.isImmediatePropagationStopped=ga,a&&a.stopImmediatePropagation(),this.stopPropagation()}},n.each({mouseenter:"mouseover",mouseleave:"mouseout",pointerenter:"pointerover",pointerleave:"pointerout"},function(a,b){n.event.special[a]={delegateType:b,bindType:b,handle:function(a){var c,d=this,e=a.relatedTarget,f=a.handleObj;return(!e||e!==d&&!n.contains(d,e))&&(a.type=f.origType,c=f.handler.apply(this,arguments),a.type=b),c}}}),n.fn.extend({on:function(a,b,c,d){return ja(this,a,b,c,d)},one:function(a,b,c,d){return ja(this,a,b,c,d,1)},off:function(a,b,c){var d,e;if(a&&a.preventDefault&&a.handleObj)return d=a.handleObj,n(a.delegateTarget).off(d.namespace?d.origType+"."+d.namespace:d.origType,d.selector,d.handler),this;if("object"==typeof a){for(e in a)this.off(e,b,a[e]);return this}return(b===!1||"function"==typeof b)&&(c=b,b=void 0),c===!1&&(c=ha),this.each(function(){n.event.remove(this,a,c,b)})}});var ka=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:-]+)[^>]*)\/>/gi,la=/<script|<style|<link/i,ma=/checked\s*(?:[^=]|=\s*.checked.)/i,na=/^true\/(.*)/,oa=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g;function pa(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a:a}function qa(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function ra(a){var b=na.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function sa(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(N.hasData(a)&&(f=N.access(a),g=N.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}O.hasData(a)&&(h=O.access(a),i=n.extend({},h),O.set(b,i))}}function ta(a,b){var c=b.nodeName.toLowerCase();"input"===c&&X.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}function ua(a,b,c,d){b=f.apply([],b);var e,g,h,i,j,k,m=0,o=a.length,p=o-1,q=b[0],r=n.isFunction(q);if(r||o>1&&"string"==typeof q&&!l.checkClone&&ma.test(q))return a.each(function(e){var f=a.eq(e);r&&(b[0]=q.call(this,e,f.html())),ua(f,b,c,d)});if(o&&(e=ca(b,a[0].ownerDocument,!1,a,d),g=e.firstChild,1===e.childNodes.length&&(e=g),g||d)){for(h=n.map(_(e,"script"),qa),i=h.length;o>m;m++)j=e,m!==p&&(j=n.clone(j,!0,!0),i&&n.merge(h,_(j,"script"))),c.call(a[m],j,m);if(i)for(k=h[h.length-1].ownerDocument,n.map(h,ra),m=0;i>m;m++)j=h[m],Z.test(j.type||"")&&!N.access(j,"globalEval")&&n.contains(k,j)&&(j.src?n._evalUrl&&n._evalUrl(j.src):n.globalEval(j.textContent.replace(oa,"")))}return a}function va(a,b,c){for(var d,e=b?n.filter(b,a):a,f=0;null!=(d=e[f]);f++)c||1!==d.nodeType||n.cleanData(_(d)),d.parentNode&&(c&&n.contains(d.ownerDocument,d)&&aa(_(d,"script")),d.parentNode.removeChild(d));return a}n.extend({htmlPrefilter:function(a){return a.replace(ka,"<$1></$2>")},clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(l.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=_(h),f=_(a),d=0,e=f.length;e>d;d++)ta(f[d],g[d]);if(b)if(c)for(f=f||_(a),g=g||_(h),d=0,e=f.length;e>d;d++)sa(f[d],g[d]);else sa(a,h);return g=_(h,"script"),g.length>0&&aa(g,!i&&_(a,"script")),h},cleanData:function(a){for(var b,c,d,e=n.event.special,f=0;void 0!==(c=a[f]);f++)if(L(c)){if(b=c[N.expando]){if(b.events)for(d in b.events)e[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);c[N.expando]=void 0}c[O.expando]&&(c[O.expando]=void 0)}}}),n.fn.extend({domManip:ua,detach:function(a){return va(this,a,!0)},remove:function(a){return va(this,a)},text:function(a){return K(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.appendChild(a)}})},prepend:function(){return ua(this,arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=pa(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return ua(this,arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(_(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return K(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!la.test(a)&&!$[(Y.exec(a)||["",""])[1].toLowerCase()]){a=n.htmlPrefilter(a);try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(_(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=[];return ua(this,arguments,function(b){var c=this.parentNode;n.inArray(this,a)<0&&(n.cleanData(_(this)),c&&c.replaceChild(b,this))},a)}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),f=e.length-1,h=0;f>=h;h++)c=h===f?this:this.clone(!0),n(e[h])[b](c),g.apply(d,c.get());return this.pushStack(d)}});var wa,xa={HTML:"block",BODY:"block"};function ya(a,b){var c=n(b.createElement(a)).appendTo(b.body),d=n.css(c[0],"display");return c.detach(),d}function za(a){var b=d,c=xa[a];return c||(c=ya(a,b),"none"!==c&&c||(wa=(wa||n("<iframe frameborder='0' width='0' height='0'/>")).appendTo(b.documentElement),b=wa[0].contentDocument,b.write(),b.close(),c=ya(a,b),wa.detach()),xa[a]=c),c}var Aa=/^margin/,Ba=new RegExp("^("+S+")(?!px)[a-z%]+$","i"),Ca=function(b){var c=b.ownerDocument.defaultView;return c.opener||(c=a),c.getComputedStyle(b)},Da=function(a,b,c,d){var e,f,g={};for(f in b)g[f]=a.style[f],a.style[f]=b[f];e=c.apply(a,d||[]);for(f in b)a.style[f]=g[f];return e},Ea=d.documentElement;!function(){var b,c,e,f,g=d.createElement("div"),h=d.createElement("div");if(h.style){h.style.backgroundClip="content-box",h.cloneNode(!0).style.backgroundClip="",l.clearCloneStyle="content-box"===h.style.backgroundClip,g.style.cssText="border:0;width:8px;height:0;top:0;left:-9999px;padding:0;margin-top:1px;position:absolute",g.appendChild(h);function i(){h.style.cssText="-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;position:relative;display:block;margin:auto;border:1px;padding:1px;top:1%;width:50%",h.innerHTML="",Ea.appendChild(g);var d=a.getComputedStyle(h);b="1%"!==d.top,f="2px"===d.marginLeft,c="4px"===d.width,h.style.marginRight="50%",e="4px"===d.marginRight,Ea.removeChild(g)}n.extend(l,{pixelPosition:function(){return i(),b},boxSizingReliable:function(){return null==c&&i(),c},pixelMarginRight:function(){return null==c&&i(),e},reliableMarginLeft:function(){return null==c&&i(),f},reliableMarginRight:function(){var b,c=h.appendChild(d.createElement("div"));return c.style.cssText=h.style.cssText="-webkit-box-sizing:content-box;box-sizing:content-box;display:block;margin:0;border:0;padding:0",c.style.marginRight=c.style.width="0",h.style.width="1px",Ea.appendChild(g),b=!parseFloat(a.getComputedStyle(c).marginRight),Ea.removeChild(g),h.removeChild(c),b}})}}();function Fa(a,b,c){var d,e,f,g,h=a.style;return c=c||Ca(a),c&&(g=c.getPropertyValue(b)||c[b],""!==g||n.contains(a.ownerDocument,a)||(g=n.style(a,b)),!l.pixelMarginRight()&&Ba.test(g)&&Aa.test(b)&&(d=h.width,e=h.minWidth,f=h.maxWidth,h.minWidth=h.maxWidth=h.width=g,g=c.width,h.width=d,h.minWidth=e,h.maxWidth=f)),void 0!==g?g+"":g}function Ga(a,b){return{get:function(){return a()?void delete this.get:(this.get=b).apply(this,arguments)}}}var Ha=/^(none|table(?!-c[ea]).+)/,Ia={position:"absolute",visibility:"hidden",display:"block"},Ja={letterSpacing:"0",fontWeight:"400"},Ka=["Webkit","O","Moz","ms"],La=d.createElement("div").style;function Ma(a){if(a in La)return a;var b=a[0].toUpperCase()+a.slice(1),c=Ka.length;while(c--)if(a=Ka[c]+b,a in La)return a}function Na(a,b,c){var d=T.exec(b);return d?Math.max(0,d[2]-(c||0))+(d[3]||"px"):b}function Oa(a,b,c,d,e){for(var f=c===(d?"border":"content")?4:"width"===b?1:0,g=0;4>f;f+=2)"margin"===c&&(g+=n.css(a,c+U[f],!0,e)),d?("content"===c&&(g-=n.css(a,"padding"+U[f],!0,e)),"margin"!==c&&(g-=n.css(a,"border"+U[f]+"Width",!0,e))):(g+=n.css(a,"padding"+U[f],!0,e),"padding"!==c&&(g+=n.css(a,"border"+U[f]+"Width",!0,e)));return g}function Pa(b,c,e){var f=!0,g="width"===c?b.offsetWidth:b.offsetHeight,h=Ca(b),i="border-box"===n.css(b,"boxSizing",!1,h);if(d.msFullscreenElement&&a.top!==a&&b.getClientRects().length&&(g=Math.round(100*b.getBoundingClientRect()[c])),0>=g||null==g){if(g=Fa(b,c,h),(0>g||null==g)&&(g=b.style[c]),Ba.test(g))return g;f=i&&(l.boxSizingReliable()||g===b.style[c]),g=parseFloat(g)||0}return g+Oa(b,c,e||(i?"border":"content"),f,h)+"px"}function Qa(a,b){for(var c,d,e,f=[],g=0,h=a.length;h>g;g++)d=a[g],d.style&&(f[g]=N.get(d,"olddisplay"),c=d.style.display,b?(f[g]||"none"!==c||(d.style.display=""),""===d.style.display&&V(d)&&(f[g]=N.access(d,"olddisplay",za(d.nodeName)))):(e=V(d),"none"===c&&e||N.set(d,"olddisplay",e?c:n.css(d,"display"))));for(g=0;h>g;g++)d=a[g],d.style&&(b&&"none"!==d.style.display&&""!==d.style.display||(d.style.display=b?f[g]||"":"none"));return a}n.extend({cssHooks:{opacity:{get:function(a,b){if(b){var c=Fa(a,"opacity");return""===c?"1":c}}}},cssNumber:{animationIterationCount:!0,columnCount:!0,fillOpacity:!0,flexGrow:!0,flexShrink:!0,fontWeight:!0,lineHeight:!0,opacity:!0,order:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":"cssFloat"},style:function(a,b,c,d){if(a&&3!==a.nodeType&&8!==a.nodeType&&a.style){var e,f,g,h=n.camelCase(b),i=a.style;return b=n.cssProps[h]||(n.cssProps[h]=Ma(h)||h),g=n.cssHooks[b]||n.cssHooks[h],void 0===c?g&&"get"in g&&void 0!==(e=g.get(a,!1,d))?e:i[b]:(f=typeof c,"string"===f&&(e=T.exec(c))&&e[1]&&(c=W(a,b,e),f="number"),null!=c&&c===c&&("number"===f&&(c+=e&&e[3]||(n.cssNumber[h]?"":"px")),l.clearCloneStyle||""!==c||0!==b.indexOf("background")||(i[b]="inherit"),g&&"set"in g&&void 0===(c=g.set(a,c,d))||(i[b]=c)),void 0)}},css:function(a,b,c,d){var e,f,g,h=n.camelCase(b);return b=n.cssProps[h]||(n.cssProps[h]=Ma(h)||h),g=n.cssHooks[b]||n.cssHooks[h],g&&"get"in g&&(e=g.get(a,!0,c)),void 0===e&&(e=Fa(a,b,d)),"normal"===e&&b in Ja&&(e=Ja[b]),""===c||c?(f=parseFloat(e),c===!0||isFinite(f)?f||0:e):e}}),n.each(["height","width"],function(a,b){n.cssHooks[b]={get:function(a,c,d){return c?Ha.test(n.css(a,"display"))&&0===a.offsetWidth?Da(a,Ia,function(){return Pa(a,b,d)}):Pa(a,b,d):void 0},set:function(a,c,d){var e,f=d&&Ca(a),g=d&&Oa(a,b,d,"border-box"===n.css(a,"boxSizing",!1,f),f);return g&&(e=T.exec(c))&&"px"!==(e[3]||"px")&&(a.style[b]=c,c=n.css(a,b)),Na(a,c,g)}}}),n.cssHooks.marginLeft=Ga(l.reliableMarginLeft,function(a,b){return b?(parseFloat(Fa(a,"marginLeft"))||a.getBoundingClientRect().left-Da(a,{marginLeft:0},function(){return a.getBoundingClientRect().left}))+"px":void 0}),n.cssHooks.marginRight=Ga(l.reliableMarginRight,function(a,b){return b?Da(a,{display:"inline-block"},Fa,[a,"marginRight"]):void 0}),n.each({margin:"",padding:"",border:"Width"},function(a,b){n.cssHooks[a+b]={expand:function(c){for(var d=0,e={},f="string"==typeof c?c.split(" "):[c];4>d;d++)e[a+U[d]+b]=f[d]||f[d-2]||f[0];return e}},Aa.test(a)||(n.cssHooks[a+b].set=Na)}),n.fn.extend({css:function(a,b){return K(this,function(a,b,c){var d,e,f={},g=0;if(n.isArray(b)){for(d=Ca(a),e=b.length;e>g;g++)f[b[g]]=n.css(a,b[g],!1,d);return f}return void 0!==c?n.style(a,b,c):n.css(a,b)},a,b,arguments.length>1)},show:function(){return Qa(this,!0)},hide:function(){return Qa(this)},toggle:function(a){return"boolean"==typeof a?a?this.show():this.hide():this.each(function(){V(this)?n(this).show():n(this).hide()})}});function Ra(a,b,c,d,e){return new Ra.prototype.init(a,b,c,d,e)}n.Tween=Ra,Ra.prototype={constructor:Ra,init:function(a,b,c,d,e,f){this.elem=a,this.prop=c,this.easing=e||n.easing._default,this.options=b,this.start=this.now=this.cur(),this.end=d,this.unit=f||(n.cssNumber[c]?"":"px")},cur:function(){var a=Ra.propHooks[this.prop];return a&&a.get?a.get(this):Ra.propHooks._default.get(this)},run:function(a){var b,c=Ra.propHooks[this.prop];return this.options.duration?this.pos=b=n.easing[this.easing](a,this.options.duration*a,0,1,this.options.duration):this.pos=b=a,this.now=(this.end-this.start)*b+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),c&&c.set?c.set(this):Ra.propHooks._default.set(this),this}},Ra.prototype.init.prototype=Ra.prototype,Ra.propHooks={_default:{get:function(a){var b;return 1!==a.elem.nodeType||null!=a.elem[a.prop]&&null==a.elem.style[a.prop]?a.elem[a.prop]:(b=n.css(a.elem,a.prop,""),b&&"auto"!==b?b:0)},set:function(a){n.fx.step[a.prop]?n.fx.step[a.prop](a):1!==a.elem.nodeType||null==a.elem.style[n.cssProps[a.prop]]&&!n.cssHooks[a.prop]?a.elem[a.prop]=a.now:n.style(a.elem,a.prop,a.now+a.unit)}}},Ra.propHooks.scrollTop=Ra.propHooks.scrollLeft={set:function(a){a.elem.nodeType&&a.elem.parentNode&&(a.elem[a.prop]=a.now)}},n.easing={linear:function(a){return a},swing:function(a){return.5-Math.cos(a*Math.PI)/2},_default:"swing"},n.fx=Ra.prototype.init,n.fx.step={};var Sa,Ta,Ua=/^(?:toggle|show|hide)$/,Va=/queueHooks$/;function Wa(){return a.setTimeout(function(){Sa=void 0}),Sa=n.now()}function Xa(a,b){var c,d=0,e={height:a};for(b=b?1:0;4>d;d+=2-b)c=U[d],e["margin"+c]=e["padding"+c]=a;return b&&(e.opacity=e.width=a),e}function Ya(a,b,c){for(var d,e=(_a.tweeners[b]||[]).concat(_a.tweeners["*"]),f=0,g=e.length;g>f;f++)if(d=e[f].call(c,b,a))return d}function Za(a,b,c){var d,e,f,g,h,i,j,k,l=this,m={},o=a.style,p=a.nodeType&&V(a),q=N.get(a,"fxshow");c.queue||(h=n._queueHooks(a,"fx"),null==h.unqueued&&(h.unqueued=0,i=h.empty.fire,h.empty.fire=function(){h.unqueued||i()}),h.unqueued++,l.always(function(){l.always(function(){h.unqueued--,n.queue(a,"fx").length||h.empty.fire()})})),1===a.nodeType&&("height"in b||"width"in b)&&(c.overflow=[o.overflow,o.overflowX,o.overflowY],j=n.css(a,"display"),k="none"===j?N.get(a,"olddisplay")||za(a.nodeName):j,"inline"===k&&"none"===n.css(a,"float")&&(o.display="inline-block")),c.overflow&&(o.overflow="hidden",l.always(function(){o.overflow=c.overflow[0],o.overflowX=c.overflow[1],o.overflowY=c.overflow[2]}));for(d in b)if(e=b[d],Ua.exec(e)){if(delete b[d],f=f||"toggle"===e,e===(p?"hide":"show")){if("show"!==e||!q||void 0===q[d])continue;p=!0}m[d]=q&&q[d]||n.style(a,d)}else j=void 0;if(n.isEmptyObject(m))"inline"===("none"===j?za(a.nodeName):j)&&(o.display=j);else{q?"hidden"in q&&(p=q.hidden):q=N.access(a,"fxshow",{}),f&&(q.hidden=!p),p?n(a).show():l.done(function(){n(a).hide()}),l.done(function(){var b;N.remove(a,"fxshow");for(b in m)n.style(a,b,m[b])});for(d in m)g=Ya(p?q[d]:0,d,l),d in q||(q[d]=g.start,p&&(g.end=g.start,g.start="width"===d||"height"===d?1:0))}}function $a(a,b){var c,d,e,f,g;for(c in a)if(d=n.camelCase(c),e=b[d],f=a[c],n.isArray(f)&&(e=f[1],f=a[c]=f[0]),c!==d&&(a[d]=f,delete a[c]),g=n.cssHooks[d],g&&"expand"in g){f=g.expand(f),delete a[d];for(c in f)c in a||(a[c]=f[c],b[c]=e)}else b[d]=e}function _a(a,b,c){var d,e,f=0,g=_a.prefilters.length,h=n.Deferred().always(function(){delete i.elem}),i=function(){if(e)return!1;for(var b=Sa||Wa(),c=Math.max(0,j.startTime+j.duration-b),d=c/j.duration||0,f=1-d,g=0,i=j.tweens.length;i>g;g++)j.tweens[g].run(f);return h.notifyWith(a,[j,f,c]),1>f&&i?c:(h.resolveWith(a,[j]),!1)},j=h.promise({elem:a,props:n.extend({},b),opts:n.extend(!0,{specialEasing:{},easing:n.easing._default},c),originalProperties:b,originalOptions:c,startTime:Sa||Wa(),duration:c.duration,tweens:[],createTween:function(b,c){var d=n.Tween(a,j.opts,b,c,j.opts.specialEasing[b]||j.opts.easing);return j.tweens.push(d),d},stop:function(b){var c=0,d=b?j.tweens.length:0;if(e)return this;for(e=!0;d>c;c++)j.tweens[c].run(1);return b?(h.notifyWith(a,[j,1,0]),h.resolveWith(a,[j,b])):h.rejectWith(a,[j,b]),this}}),k=j.props;for($a(k,j.opts.specialEasing);g>f;f++)if(d=_a.prefilters[f].call(j,a,k,j.opts))return n.isFunction(d.stop)&&(n._queueHooks(j.elem,j.opts.queue).stop=n.proxy(d.stop,d)),d;return n.map(k,Ya,j),n.isFunction(j.opts.start)&&j.opts.start.call(a,j),n.fx.timer(n.extend(i,{elem:a,anim:j,queue:j.opts.queue})),j.progress(j.opts.progress).done(j.opts.done,j.opts.complete).fail(j.opts.fail).always(j.opts.always)}n.Animation=n.extend(_a,{tweeners:{"*":[function(a,b){var c=this.createTween(a,b);return W(c.elem,a,T.exec(b),c),c}]},tweener:function(a,b){n.isFunction(a)?(b=a,a=["*"]):a=a.match(G);for(var c,d=0,e=a.length;e>d;d++)c=a[d],_a.tweeners[c]=_a.tweeners[c]||[],_a.tweeners[c].unshift(b)},prefilters:[Za],prefilter:function(a,b){b?_a.prefilters.unshift(a):_a.prefilters.push(a)}}),n.speed=function(a,b,c){var d=a&&"object"==typeof a?n.extend({},a):{complete:c||!c&&b||n.isFunction(a)&&a,duration:a,easing:c&&b||b&&!n.isFunction(b)&&b};return d.duration=n.fx.off?0:"number"==typeof d.duration?d.duration:d.duration in n.fx.speeds?n.fx.speeds[d.duration]:n.fx.speeds._default,(null==d.queue||d.queue===!0)&&(d.queue="fx"),d.old=d.complete,d.complete=function(){n.isFunction(d.old)&&d.old.call(this),d.queue&&n.dequeue(this,d.queue)},d},n.fn.extend({fadeTo:function(a,b,c,d){return this.filter(V).css("opacity",0).show().end().animate({opacity:b},a,c,d)},animate:function(a,b,c,d){var e=n.isEmptyObject(a),f=n.speed(b,c,d),g=function(){var b=_a(this,n.extend({},a),f);(e||N.get(this,"finish"))&&b.stop(!0)};return g.finish=g,e||f.queue===!1?this.each(g):this.queue(f.queue,g)},stop:function(a,b,c){var d=function(a){var b=a.stop;delete a.stop,b(c)};return"string"!=typeof a&&(c=b,b=a,a=void 0),b&&a!==!1&&this.queue(a||"fx",[]),this.each(function(){var b=!0,e=null!=a&&a+"queueHooks",f=n.timers,g=N.get(this);if(e)g[e]&&g[e].stop&&d(g[e]);else for(e in g)g[e]&&g[e].stop&&Va.test(e)&&d(g[e]);for(e=f.length;e--;)f[e].elem!==this||null!=a&&f[e].queue!==a||(f[e].anim.stop(c),b=!1,f.splice(e,1));(b||!c)&&n.dequeue(this,a)})},finish:function(a){return a!==!1&&(a=a||"fx"),this.each(function(){var b,c=N.get(this),d=c[a+"queue"],e=c[a+"queueHooks"],f=n.timers,g=d?d.length:0;for(c.finish=!0,n.queue(this,a,[]),e&&e.stop&&e.stop.call(this,!0),b=f.length;b--;)f[b].elem===this&&f[b].queue===a&&(f[b].anim.stop(!0),f.splice(b,1));for(b=0;g>b;b++)d[b]&&d[b].finish&&d[b].finish.call(this);delete c.finish})}}),n.each(["toggle","show","hide"],function(a,b){var c=n.fn[b];n.fn[b]=function(a,d,e){return null==a||"boolean"==typeof a?c.apply(this,arguments):this.animate(Xa(b,!0),a,d,e)}}),n.each({slideDown:Xa("show"),slideUp:Xa("hide"),slideToggle:Xa("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(a,b){n.fn[a]=function(a,c,d){return this.animate(b,a,c,d)}}),n.timers=[],n.fx.tick=function(){var a,b=0,c=n.timers;for(Sa=n.now();b<c.length;b++)a=c[b],a()||c[b]!==a||c.splice(b--,1);c.length||n.fx.stop(),Sa=void 0},n.fx.timer=function(a){n.timers.push(a),a()?n.fx.start():n.timers.pop()},n.fx.interval=13,n.fx.start=function(){Ta||(Ta=a.setInterval(n.fx.tick,n.fx.interval))},n.fx.stop=function(){a.clearInterval(Ta),Ta=null},n.fx.speeds={slow:600,fast:200,_default:400},n.fn.delay=function(b,c){return b=n.fx?n.fx.speeds[b]||b:b,c=c||"fx",this.queue(c,function(c,d){var e=a.setTimeout(c,b);d.stop=function(){a.clearTimeout(e)}})},function(){var a=d.createElement("input"),b=d.createElement("select"),c=b.appendChild(d.createElement("option"));a.type="checkbox",l.checkOn=""!==a.value,l.optSelected=c.selected,b.disabled=!0,l.optDisabled=!c.disabled,a=d.createElement("input"),a.value="t",a.type="radio",l.radioValue="t"===a.value}();var ab,bb=n.expr.attrHandle;n.fn.extend({attr:function(a,b){return K(this,n.attr,a,b,arguments.length>1)},removeAttr:function(a){return this.each(function(){n.removeAttr(this,a)})}}),n.extend({attr:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return"undefined"==typeof a.getAttribute?n.prop(a,b,c):(1===f&&n.isXMLDoc(a)||(b=b.toLowerCase(),e=n.attrHooks[b]||(n.expr.match.bool.test(b)?ab:void 0)),void 0!==c?null===c?void n.removeAttr(a,b):e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:(a.setAttribute(b,c+""),c):e&&"get"in e&&null!==(d=e.get(a,b))?d:(d=n.find.attr(a,b),null==d?void 0:d))},attrHooks:{type:{set:function(a,b){if(!l.radioValue&&"radio"===b&&n.nodeName(a,"input")){var c=a.value;return a.setAttribute("type",b),c&&(a.value=c),b}}}},removeAttr:function(a,b){var c,d,e=0,f=b&&b.match(G);if(f&&1===a.nodeType)while(c=f[e++])d=n.propFix[c]||c,n.expr.match.bool.test(c)&&(a[d]=!1),a.removeAttribute(c)}}),ab={set:function(a,b,c){return b===!1?n.removeAttr(a,c):a.setAttribute(c,c),c}},n.each(n.expr.match.bool.source.match(/\w+/g),function(a,b){var c=bb[b]||n.find.attr;bb[b]=function(a,b,d){var e,f;return d||(f=bb[b],bb[b]=e,e=null!=c(a,b,d)?b.toLowerCase():null,bb[b]=f),e}});var cb=/^(?:input|select|textarea|button)$/i,db=/^(?:a|area)$/i;n.fn.extend({prop:function(a,b){return K(this,n.prop,a,b,arguments.length>1)},removeProp:function(a){return this.each(function(){delete this[n.propFix[a]||a]})}}),n.extend({prop:function(a,b,c){var d,e,f=a.nodeType;if(3!==f&&8!==f&&2!==f)return 1===f&&n.isXMLDoc(a)||(b=n.propFix[b]||b,e=n.propHooks[b]),void 0!==c?e&&"set"in e&&void 0!==(d=e.set(a,c,b))?d:a[b]=c:e&&"get"in e&&null!==(d=e.get(a,b))?d:a[b];
+},propHooks:{tabIndex:{get:function(a){var b=n.find.attr(a,"tabindex");return b?parseInt(b,10):cb.test(a.nodeName)||db.test(a.nodeName)&&a.href?0:-1}}},propFix:{"for":"htmlFor","class":"className"}}),l.optSelected||(n.propHooks.selected={get:function(a){var b=a.parentNode;return b&&b.parentNode&&b.parentNode.selectedIndex,null}}),n.each(["tabIndex","readOnly","maxLength","cellSpacing","cellPadding","rowSpan","colSpan","useMap","frameBorder","contentEditable"],function(){n.propFix[this.toLowerCase()]=this});var eb=/[\t\r\n\f]/g;function fb(a){return a.getAttribute&&a.getAttribute("class")||""}n.fn.extend({addClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).addClass(a.call(this,b,fb(this)))});if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=fb(c),d=1===c.nodeType&&(" "+e+" ").replace(eb," ")){g=0;while(f=b[g++])d.indexOf(" "+f+" ")<0&&(d+=f+" ");h=n.trim(d),e!==h&&c.setAttribute("class",h)}}return this},removeClass:function(a){var b,c,d,e,f,g,h,i=0;if(n.isFunction(a))return this.each(function(b){n(this).removeClass(a.call(this,b,fb(this)))});if(!arguments.length)return this.attr("class","");if("string"==typeof a&&a){b=a.match(G)||[];while(c=this[i++])if(e=fb(c),d=1===c.nodeType&&(" "+e+" ").replace(eb," ")){g=0;while(f=b[g++])while(d.indexOf(" "+f+" ")>-1)d=d.replace(" "+f+" "," ");h=n.trim(d),e!==h&&c.setAttribute("class",h)}}return this},toggleClass:function(a,b){var c=typeof a;return"boolean"==typeof b&&"string"===c?b?this.addClass(a):this.removeClass(a):n.isFunction(a)?this.each(function(c){n(this).toggleClass(a.call(this,c,fb(this),b),b)}):this.each(function(){var b,d,e,f;if("string"===c){d=0,e=n(this),f=a.match(G)||[];while(b=f[d++])e.hasClass(b)?e.removeClass(b):e.addClass(b)}else(void 0===a||"boolean"===c)&&(b=fb(this),b&&N.set(this,"__className__",b),this.setAttribute&&this.setAttribute("class",b||a===!1?"":N.get(this,"__className__")||""))})},hasClass:function(a){var b,c,d=0;b=" "+a+" ";while(c=this[d++])if(1===c.nodeType&&(" "+fb(c)+" ").replace(eb," ").indexOf(b)>-1)return!0;return!1}});var gb=/\r/g;n.fn.extend({val:function(a){var b,c,d,e=this[0];{if(arguments.length)return d=n.isFunction(a),this.each(function(c){var e;1===this.nodeType&&(e=d?a.call(this,c,n(this).val()):a,null==e?e="":"number"==typeof e?e+="":n.isArray(e)&&(e=n.map(e,function(a){return null==a?"":a+""})),b=n.valHooks[this.type]||n.valHooks[this.nodeName.toLowerCase()],b&&"set"in b&&void 0!==b.set(this,e,"value")||(this.value=e))});if(e)return b=n.valHooks[e.type]||n.valHooks[e.nodeName.toLowerCase()],b&&"get"in b&&void 0!==(c=b.get(e,"value"))?c:(c=e.value,"string"==typeof c?c.replace(gb,""):null==c?"":c)}}}),n.extend({valHooks:{option:{get:function(a){return n.trim(a.value)}},select:{get:function(a){for(var b,c,d=a.options,e=a.selectedIndex,f="select-one"===a.type||0>e,g=f?null:[],h=f?e+1:d.length,i=0>e?h:f?e:0;h>i;i++)if(c=d[i],(c.selected||i===e)&&(l.optDisabled?!c.disabled:null===c.getAttribute("disabled"))&&(!c.parentNode.disabled||!n.nodeName(c.parentNode,"optgroup"))){if(b=n(c).val(),f)return b;g.push(b)}return g},set:function(a,b){var c,d,e=a.options,f=n.makeArray(b),g=e.length;while(g--)d=e[g],(d.selected=n.inArray(n.valHooks.option.get(d),f)>-1)&&(c=!0);return c||(a.selectedIndex=-1),f}}}}),n.each(["radio","checkbox"],function(){n.valHooks[this]={set:function(a,b){return n.isArray(b)?a.checked=n.inArray(n(a).val(),b)>-1:void 0}},l.checkOn||(n.valHooks[this].get=function(a){return null===a.getAttribute("value")?"on":a.value})});var hb=/^(?:focusinfocus|focusoutblur)$/;n.extend(n.event,{trigger:function(b,c,e,f){var g,h,i,j,l,m,o,p=[e||d],q=k.call(b,"type")?b.type:b,r=k.call(b,"namespace")?b.namespace.split("."):[];if(h=i=e=e||d,3!==e.nodeType&&8!==e.nodeType&&!hb.test(q+n.event.triggered)&&(q.indexOf(".")>-1&&(r=q.split("."),q=r.shift(),r.sort()),l=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=f?2:3,b.namespace=r.join("."),b.rnamespace=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=e),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},f||!o.trigger||o.trigger.apply(e,c)!==!1)){if(!f&&!o.noBubble&&!n.isWindow(e)){for(j=o.delegateType||q,hb.test(j+q)||(h=h.parentNode);h;h=h.parentNode)p.push(h),i=h;i===(e.ownerDocument||d)&&p.push(i.defaultView||i.parentWindow||a)}g=0;while((h=p[g++])&&!b.isPropagationStopped())b.type=g>1?j:o.bindType||q,m=(N.get(h,"events")||{})[b.type]&&N.get(h,"handle"),m&&m.apply(h,c),m=l&&h[l],m&&m.apply&&L(h)&&(b.result=m.apply(h,c),b.result===!1&&b.preventDefault());return b.type=q,f||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!L(e)||l&&n.isFunction(e[q])&&!n.isWindow(e)&&(i=e[l],i&&(e[l]=null),n.event.triggered=q,e[q](),n.event.triggered=void 0,i&&(e[l]=i)),b.result}},simulate:function(a,b,c){var d=n.extend(new n.Event,c,{type:a,isSimulated:!0});n.event.trigger(d,null,b),d.isDefaultPrevented()&&c.preventDefault()}}),n.fn.extend({trigger:function(a,b){return this.each(function(){n.event.trigger(a,b,this)})},triggerHandler:function(a,b){var c=this[0];return c?n.event.trigger(a,b,c,!0):void 0}}),n.each("blur focus focusin focusout load resize scroll unload click dblclick mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave change select submit keydown keypress keyup error contextmenu".split(" "),function(a,b){n.fn[b]=function(a,c){return arguments.length>0?this.on(b,null,a,c):this.trigger(b)}}),n.fn.extend({hover:function(a,b){return this.mouseenter(a).mouseleave(b||a)}}),l.focusin="onfocusin"in a,l.focusin||n.each({focus:"focusin",blur:"focusout"},function(a,b){var c=function(a){n.event.simulate(b,a.target,n.event.fix(a))};n.event.special[b]={setup:function(){var d=this.ownerDocument||this,e=N.access(d,b);e||d.addEventListener(a,c,!0),N.access(d,b,(e||0)+1)},teardown:function(){var d=this.ownerDocument||this,e=N.access(d,b)-1;e?N.access(d,b,e):(d.removeEventListener(a,c,!0),N.remove(d,b))}}});var ib=a.location,jb=n.now(),kb=/\?/;n.parseJSON=function(a){return JSON.parse(a+"")},n.parseXML=function(b){var c;if(!b||"string"!=typeof b)return null;try{c=(new a.DOMParser).parseFromString(b,"text/xml")}catch(d){c=void 0}return(!c||c.getElementsByTagName("parsererror").length)&&n.error("Invalid XML: "+b),c};var lb=/#.*$/,mb=/([?&])_=[^&]*/,nb=/^(.*?):[ \t]*([^\r\n]*)$/gm,ob=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,pb=/^(?:GET|HEAD)$/,qb=/^\/\//,rb={},sb={},tb="*/".concat("*"),ub=d.createElement("a");ub.href=ib.href;function vb(a){return function(b,c){"string"!=typeof b&&(c=b,b="*");var d,e=0,f=b.toLowerCase().match(G)||[];if(n.isFunction(c))while(d=f[e++])"+"===d[0]?(d=d.slice(1)||"*",(a[d]=a[d]||[]).unshift(c)):(a[d]=a[d]||[]).push(c)}}function wb(a,b,c,d){var e={},f=a===sb;function g(h){var i;return e[h]=!0,n.each(a[h]||[],function(a,h){var j=h(b,c,d);return"string"!=typeof j||f||e[j]?f?!(i=j):void 0:(b.dataTypes.unshift(j),g(j),!1)}),i}return g(b.dataTypes[0])||!e["*"]&&g("*")}function xb(a,b){var c,d,e=n.ajaxSettings.flatOptions||{};for(c in b)void 0!==b[c]&&((e[c]?a:d||(d={}))[c]=b[c]);return d&&n.extend(!0,a,d),a}function yb(a,b,c){var d,e,f,g,h=a.contents,i=a.dataTypes;while("*"===i[0])i.shift(),void 0===d&&(d=a.mimeType||b.getResponseHeader("Content-Type"));if(d)for(e in h)if(h[e]&&h[e].test(d)){i.unshift(e);break}if(i[0]in c)f=i[0];else{for(e in c){if(!i[0]||a.converters[e+" "+i[0]]){f=e;break}g||(g=e)}f=f||g}return f?(f!==i[0]&&i.unshift(f),c[f]):void 0}function zb(a,b,c,d){var e,f,g,h,i,j={},k=a.dataTypes.slice();if(k[1])for(g in a.converters)j[g.toLowerCase()]=a.converters[g];f=k.shift();while(f)if(a.responseFields[f]&&(c[a.responseFields[f]]=b),!i&&d&&a.dataFilter&&(b=a.dataFilter(b,a.dataType)),i=f,f=k.shift())if("*"===f)f=i;else if("*"!==i&&i!==f){if(g=j[i+" "+f]||j["* "+f],!g)for(e in j)if(h=e.split(" "),h[1]===f&&(g=j[i+" "+h[0]]||j["* "+h[0]])){g===!0?g=j[e]:j[e]!==!0&&(f=h[0],k.unshift(h[1]));break}if(g!==!0)if(g&&a["throws"])b=g(b);else try{b=g(b)}catch(l){return{state:"parsererror",error:g?l:"No conversion from "+i+" to "+f}}}return{state:"success",data:b}}n.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:ib.href,type:"GET",isLocal:ob.test(ib.protocol),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":tb,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/\bxml\b/,html:/\bhtml/,json:/\bjson\b/},responseFields:{xml:"responseXML",text:"responseText",json:"responseJSON"},converters:{"* text":String,"text html":!0,"text json":n.parseJSON,"text xml":n.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(a,b){return b?xb(xb(a,n.ajaxSettings),b):xb(n.ajaxSettings,a)},ajaxPrefilter:vb(rb),ajaxTransport:vb(sb),ajax:function(b,c){"object"==typeof b&&(c=b,b=void 0),c=c||{};var e,f,g,h,i,j,k,l,m=n.ajaxSetup({},c),o=m.context||m,p=m.context&&(o.nodeType||o.jquery)?n(o):n.event,q=n.Deferred(),r=n.Callbacks("once memory"),s=m.statusCode||{},t={},u={},v=0,w="canceled",x={readyState:0,getResponseHeader:function(a){var b;if(2===v){if(!h){h={};while(b=nb.exec(g))h[b[1].toLowerCase()]=b[2]}b=h[a.toLowerCase()]}return null==b?null:b},getAllResponseHeaders:function(){return 2===v?g:null},setRequestHeader:function(a,b){var c=a.toLowerCase();return v||(a=u[c]=u[c]||a,t[a]=b),this},overrideMimeType:function(a){return v||(m.mimeType=a),this},statusCode:function(a){var b;if(a)if(2>v)for(b in a)s[b]=[s[b],a[b]];else x.always(a[x.status]);return this},abort:function(a){var b=a||w;return e&&e.abort(b),z(0,b),this}};if(q.promise(x).complete=r.add,x.success=x.done,x.error=x.fail,m.url=((b||m.url||ib.href)+"").replace(lb,"").replace(qb,ib.protocol+"//"),m.type=c.method||c.type||m.method||m.type,m.dataTypes=n.trim(m.dataType||"*").toLowerCase().match(G)||[""],null==m.crossDomain){j=d.createElement("a");try{j.href=m.url,j.href=j.href,m.crossDomain=ub.protocol+"//"+ub.host!=j.protocol+"//"+j.host}catch(y){m.crossDomain=!0}}if(m.data&&m.processData&&"string"!=typeof m.data&&(m.data=n.param(m.data,m.traditional)),wb(rb,m,c,x),2===v)return x;k=n.event&&m.global,k&&0===n.active++&&n.event.trigger("ajaxStart"),m.type=m.type.toUpperCase(),m.hasContent=!pb.test(m.type),f=m.url,m.hasContent||(m.data&&(f=m.url+=(kb.test(f)?"&":"?")+m.data,delete m.data),m.cache===!1&&(m.url=mb.test(f)?f.replace(mb,"$1_="+jb++):f+(kb.test(f)?"&":"?")+"_="+jb++)),m.ifModified&&(n.lastModified[f]&&x.setRequestHeader("If-Modified-Since",n.lastModified[f]),n.etag[f]&&x.setRequestHeader("If-None-Match",n.etag[f])),(m.data&&m.hasContent&&m.contentType!==!1||c.contentType)&&x.setRequestHeader("Content-Type",m.contentType),x.setRequestHeader("Accept",m.dataTypes[0]&&m.accepts[m.dataTypes[0]]?m.accepts[m.dataTypes[0]]+("*"!==m.dataTypes[0]?", "+tb+"; q=0.01":""):m.accepts["*"]);for(l in m.headers)x.setRequestHeader(l,m.headers[l]);if(m.beforeSend&&(m.beforeSend.call(o,x,m)===!1||2===v))return x.abort();w="abort";for(l in{success:1,error:1,complete:1})x[l](m[l]);if(e=wb(sb,m,c,x)){if(x.readyState=1,k&&p.trigger("ajaxSend",[x,m]),2===v)return x;m.async&&m.timeout>0&&(i=a.setTimeout(function(){x.abort("timeout")},m.timeout));try{v=1,e.send(t,z)}catch(y){if(!(2>v))throw y;z(-1,y)}}else z(-1,"No Transport");function z(b,c,d,h){var j,l,t,u,w,y=c;2!==v&&(v=2,i&&a.clearTimeout(i),e=void 0,g=h||"",x.readyState=b>0?4:0,j=b>=200&&300>b||304===b,d&&(u=yb(m,x,d)),u=zb(m,u,x,j),j?(m.ifModified&&(w=x.getResponseHeader("Last-Modified"),w&&(n.lastModified[f]=w),w=x.getResponseHeader("etag"),w&&(n.etag[f]=w)),204===b||"HEAD"===m.type?y="nocontent":304===b?y="notmodified":(y=u.state,l=u.data,t=u.error,j=!t)):(t=y,(b||!y)&&(y="error",0>b&&(b=0))),x.status=b,x.statusText=(c||y)+"",j?q.resolveWith(o,[l,y,x]):q.rejectWith(o,[x,y,t]),x.statusCode(s),s=void 0,k&&p.trigger(j?"ajaxSuccess":"ajaxError",[x,m,j?l:t]),r.fireWith(o,[x,y]),k&&(p.trigger("ajaxComplete",[x,m]),--n.active||n.event.trigger("ajaxStop")))}return x},getJSON:function(a,b,c){return n.get(a,b,c,"json")},getScript:function(a,b){return n.get(a,void 0,b,"script")}}),n.each(["get","post"],function(a,b){n[b]=function(a,c,d,e){return n.isFunction(c)&&(e=e||d,d=c,c=void 0),n.ajax(n.extend({url:a,type:b,dataType:e,data:c,success:d},n.isPlainObject(a)&&a))}}),n._evalUrl=function(a){return n.ajax({url:a,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0})},n.fn.extend({wrapAll:function(a){var b;return n.isFunction(a)?this.each(function(b){n(this).wrapAll(a.call(this,b))}):(this[0]&&(b=n(a,this[0].ownerDocument).eq(0).clone(!0),this[0].parentNode&&b.insertBefore(this[0]),b.map(function(){var a=this;while(a.firstElementChild)a=a.firstElementChild;return a}).append(this)),this)},wrapInner:function(a){return n.isFunction(a)?this.each(function(b){n(this).wrapInner(a.call(this,b))}):this.each(function(){var b=n(this),c=b.contents();c.length?c.wrapAll(a):b.append(a)})},wrap:function(a){var b=n.isFunction(a);return this.each(function(c){n(this).wrapAll(b?a.call(this,c):a)})},unwrap:function(){return this.parent().each(function(){n.nodeName(this,"body")||n(this).replaceWith(this.childNodes)}).end()}}),n.expr.filters.hidden=function(a){return!n.expr.filters.visible(a)},n.expr.filters.visible=function(a){return a.offsetWidth>0||a.offsetHeight>0||a.getClientRects().length>0};var Ab=/%20/g,Bb=/\[\]$/,Cb=/\r?\n/g,Db=/^(?:submit|button|image|reset|file)$/i,Eb=/^(?:input|select|textarea|keygen)/i;function Fb(a,b,c,d){var e;if(n.isArray(b))n.each(b,function(b,e){c||Bb.test(a)?d(a,e):Fb(a+"["+("object"==typeof e&&null!=e?b:"")+"]",e,c,d)});else if(c||"object"!==n.type(b))d(a,b);else for(e in b)Fb(a+"["+e+"]",b[e],c,d)}n.param=function(a,b){var c,d=[],e=function(a,b){b=n.isFunction(b)?b():null==b?"":b,d[d.length]=encodeURIComponent(a)+"="+encodeURIComponent(b)};if(void 0===b&&(b=n.ajaxSettings&&n.ajaxSettings.traditional),n.isArray(a)||a.jquery&&!n.isPlainObject(a))n.each(a,function(){e(this.name,this.value)});else for(c in a)Fb(c,a[c],b,e);return d.join("&").replace(Ab,"+")},n.fn.extend({serialize:function(){return n.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var a=n.prop(this,"elements");return a?n.makeArray(a):this}).filter(function(){var a=this.type;return this.name&&!n(this).is(":disabled")&&Eb.test(this.nodeName)&&!Db.test(a)&&(this.checked||!X.test(a))}).map(function(a,b){var c=n(this).val();return null==c?null:n.isArray(c)?n.map(c,function(a){return{name:b.name,value:a.replace(Cb,"\r\n")}}):{name:b.name,value:c.replace(Cb,"\r\n")}}).get()}}),n.ajaxSettings.xhr=function(){try{return new a.XMLHttpRequest}catch(b){}};var Gb={0:200,1223:204},Hb=n.ajaxSettings.xhr();l.cors=!!Hb&&"withCredentials"in Hb,l.ajax=Hb=!!Hb,n.ajaxTransport(function(b){var c,d;return l.cors||Hb&&!b.crossDomain?{send:function(e,f){var g,h=b.xhr();if(h.open(b.type,b.url,b.async,b.username,b.password),b.xhrFields)for(g in b.xhrFields)h[g]=b.xhrFields[g];b.mimeType&&h.overrideMimeType&&h.overrideMimeType(b.mimeType),b.crossDomain||e["X-Requested-With"]||(e["X-Requested-With"]="XMLHttpRequest");for(g in e)h.setRequestHeader(g,e[g]);c=function(a){return function(){c&&(c=d=h.onload=h.onerror=h.onabort=h.onreadystatechange=null,"abort"===a?h.abort():"error"===a?"number"!=typeof h.status?f(0,"error"):f(h.status,h.statusText):f(Gb[h.status]||h.status,h.statusText,"text"!==(h.responseType||"text")||"string"!=typeof h.responseText?{binary:h.response}:{text:h.responseText},h.getAllResponseHeaders()))}},h.onload=c(),d=h.onerror=c("error"),void 0!==h.onabort?h.onabort=d:h.onreadystatechange=function(){4===h.readyState&&a.setTimeout(function(){c&&d()})},c=c("abort");try{h.send(b.hasContent&&b.data||null)}catch(i){if(c)throw i}},abort:function(){c&&c()}}:void 0}),n.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/\b(?:java|ecma)script\b/},converters:{"text script":function(a){return n.globalEval(a),a}}}),n.ajaxPrefilter("script",function(a){void 0===a.cache&&(a.cache=!1),a.crossDomain&&(a.type="GET")}),n.ajaxTransport("script",function(a){if(a.crossDomain){var b,c;return{send:function(e,f){b=n("<script>").prop({charset:a.scriptCharset,src:a.url}).on("load error",c=function(a){b.remove(),c=null,a&&f("error"===a.type?404:200,a.type)}),d.head.appendChild(b[0])},abort:function(){c&&c()}}}});var Ib=[],Jb=/(=)\?(?=&|$)|\?\?/;n.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var a=Ib.pop()||n.expando+"_"+jb++;return this[a]=!0,a}}),n.ajaxPrefilter("json jsonp",function(b,c,d){var e,f,g,h=b.jsonp!==!1&&(Jb.test(b.url)?"url":"string"==typeof b.data&&0===(b.contentType||"").indexOf("application/x-www-form-urlencoded")&&Jb.test(b.data)&&"data");return h||"jsonp"===b.dataTypes[0]?(e=b.jsonpCallback=n.isFunction(b.jsonpCallback)?b.jsonpCallback():b.jsonpCallback,h?b[h]=b[h].replace(Jb,"$1"+e):b.jsonp!==!1&&(b.url+=(kb.test(b.url)?"&":"?")+b.jsonp+"="+e),b.converters["script json"]=function(){return g||n.error(e+" was not called"),g[0]},b.dataTypes[0]="json",f=a[e],a[e]=function(){g=arguments},d.always(function(){void 0===f?n(a).removeProp(e):a[e]=f,b[e]&&(b.jsonpCallback=c.jsonpCallback,Ib.push(e)),g&&n.isFunction(f)&&f(g[0]),g=f=void 0}),"script"):void 0}),l.createHTMLDocument=function(){var a=d.implementation.createHTMLDocument("").body;return a.innerHTML="<form></form><form></form>",2===a.childNodes.length}(),n.parseHTML=function(a,b,c){if(!a||"string"!=typeof a)return null;"boolean"==typeof b&&(c=b,b=!1),b=b||(l.createHTMLDocument?d.implementation.createHTMLDocument(""):d);var e=x.exec(a),f=!c&&[];return e?[b.createElement(e[1])]:(e=ca([a],b,f),f&&f.length&&n(f).remove(),n.merge([],e.childNodes))};var Kb=n.fn.load;n.fn.load=function(a,b,c){if("string"!=typeof a&&Kb)return Kb.apply(this,arguments);var d,e,f,g=this,h=a.indexOf(" ");return h>-1&&(d=n.trim(a.slice(h)),a=a.slice(0,h)),n.isFunction(b)?(c=b,b=void 0):b&&"object"==typeof b&&(e="POST"),g.length>0&&n.ajax({url:a,type:e||"GET",dataType:"html",data:b}).done(function(a){f=arguments,g.html(d?n("<div>").append(n.parseHTML(a)).find(d):a)}).always(c&&function(a,b){g.each(function(){c.apply(g,f||[a.responseText,b,a])})}),this},n.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(a,b){n.fn[b]=function(a){return this.on(b,a)}}),n.expr.filters.animated=function(a){return n.grep(n.timers,function(b){return a===b.elem}).length};function Lb(a){return n.isWindow(a)?a:9===a.nodeType&&a.defaultView}n.offset={setOffset:function(a,b,c){var d,e,f,g,h,i,j,k=n.css(a,"position"),l=n(a),m={};"static"===k&&(a.style.position="relative"),h=l.offset(),f=n.css(a,"top"),i=n.css(a,"left"),j=("absolute"===k||"fixed"===k)&&(f+i).indexOf("auto")>-1,j?(d=l.position(),g=d.top,e=d.left):(g=parseFloat(f)||0,e=parseFloat(i)||0),n.isFunction(b)&&(b=b.call(a,c,n.extend({},h))),null!=b.top&&(m.top=b.top-h.top+g),null!=b.left&&(m.left=b.left-h.left+e),"using"in b?b.using.call(a,m):l.css(m)}},n.fn.extend({offset:function(a){if(arguments.length)return void 0===a?this:this.each(function(b){n.offset.setOffset(this,a,b)});var b,c,d=this[0],e={top:0,left:0},f=d&&d.ownerDocument;if(f)return b=f.documentElement,n.contains(b,d)?(e=d.getBoundingClientRect(),c=Lb(f),{top:e.top+c.pageYOffset-b.clientTop,left:e.left+c.pageXOffset-b.clientLeft}):e},position:function(){if(this[0]){var a,b,c=this[0],d={top:0,left:0};return"fixed"===n.css(c,"position")?b=c.getBoundingClientRect():(a=this.offsetParent(),b=this.offset(),n.nodeName(a[0],"html")||(d=a.offset()),d.top+=n.css(a[0],"borderTopWidth",!0)-a.scrollTop(),d.left+=n.css(a[0],"borderLeftWidth",!0)-a.scrollLeft()),{top:b.top-d.top-n.css(c,"marginTop",!0),left:b.left-d.left-n.css(c,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var a=this.offsetParent;while(a&&"static"===n.css(a,"position"))a=a.offsetParent;return a||Ea})}}),n.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(a,b){var c="pageYOffset"===b;n.fn[a]=function(d){return K(this,function(a,d,e){var f=Lb(a);return void 0===e?f?f[b]:a[d]:void(f?f.scrollTo(c?f.pageXOffset:e,c?e:f.pageYOffset):a[d]=e)},a,d,arguments.length)}}),n.each(["top","left"],function(a,b){n.cssHooks[b]=Ga(l.pixelPosition,function(a,c){return c?(c=Fa(a,b),Ba.test(c)?n(a).position()[b]+"px":c):void 0})}),n.each({Height:"height",Width:"width"},function(a,b){n.each({padding:"inner"+a,content:b,"":"outer"+a},function(c,d){n.fn[d]=function(d,e){var f=arguments.length&&(c||"boolean"!=typeof d),g=c||(d===!0||e===!0?"margin":"border");return K(this,function(b,c,d){var e;return n.isWindow(b)?b.document.documentElement["client"+a]:9===b.nodeType?(e=b.documentElement,Math.max(b.body["scroll"+a],e["scroll"+a],b.body["offset"+a],e["offset"+a],e["client"+a])):void 0===d?n.css(b,c,g):n.style(b,c,d,g)},b,f?d:void 0,f,null)}})}),n.fn.extend({bind:function(a,b,c){return this.on(a,null,b,c)},unbind:function(a,b){return this.off(a,null,b)},delegate:function(a,b,c,d){return this.on(b,a,c,d)},undelegate:function(a,b,c){return 1===arguments.length?this.off(a,"**"):this.off(b,a||"**",c)},size:function(){return this.length}}),n.fn.andSelf=n.fn.addBack,"function"==typeof define&&define.amd&&define("jquery",[],function(){return n});var Mb=a.jQuery,Nb=a.$;return n.noConflict=function(b){return a.$===n&&(a.$=Nb),b&&a.jQuery===n&&(a.jQuery=Mb),n},b||(a.jQuery=a.$=n),n});
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/js/leaflet-src.js b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/js/leaflet-src.js
new file mode 100644
index 0000000..1dd3923
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/js/leaflet-src.js
@@ -0,0 +1,13802 @@
+/* @preserve
+ * Leaflet 1.3.1+Detached: ba6f97fff8647e724e4dfe66d2ed7da11f908989.ba6f97f, a JS library for interactive maps. http://leafletjs.com
+ * (c) 2010-2017 Vladimir Agafonkin, (c) 2010-2011 CloudMade
+ */
+
+(function (global, factory) {
+	typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
+	typeof define === 'function' && define.amd ? define(['exports'], factory) :
+	(factory((global.L = {})));
+}(this, (function (exports) { 'use strict';
+
+var version = "1.3.1+HEAD.ba6f97f";
+
+/*
+ * @namespace Util
+ *
+ * Various utility functions, used by Leaflet internally.
+ */
+
+var freeze = Object.freeze;
+Object.freeze = function (obj) { return obj; };
+
+// @function extend(dest: Object, src?: Object): Object
+// Merges the properties of the `src` object (or multiple objects) into `dest` object and returns the latter. Has an `L.extend` shortcut.
+function extend(dest) {
+	var i, j, len, src;
+
+	for (j = 1, len = arguments.length; j < len; j++) {
+		src = arguments[j];
+		for (i in src) {
+			dest[i] = src[i];
+		}
+	}
+	return dest;
+}
+
+// @function create(proto: Object, properties?: Object): Object
+// Compatibility polyfill for [Object.create](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Object/create)
+var create = Object.create || (function () {
+	function F() {}
+	return function (proto) {
+		F.prototype = proto;
+		return new F();
+	};
+})();
+
+// @function bind(fn: Function, …): Function
+// Returns a new function bound to the arguments passed, like [Function.prototype.bind](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Function/bind).
+// Has a `L.bind()` shortcut.
+function bind(fn, obj) {
+	var slice = Array.prototype.slice;
+
+	if (fn.bind) {
+		return fn.bind.apply(fn, slice.call(arguments, 1));
+	}
+
+	var args = slice.call(arguments, 2);
+
+	return function () {
+		return fn.apply(obj, args.length ? args.concat(slice.call(arguments)) : arguments);
+	};
+}
+
+// @property lastId: Number
+// Last unique ID used by [`stamp()`](#util-stamp)
+var lastId = 0;
+
+// @function stamp(obj: Object): Number
+// Returns the unique ID of an object, assigning it one if it doesn't have it.
+function stamp(obj) {
+	/*eslint-disable */
+	obj._leaflet_id = obj._leaflet_id || ++lastId;
+	return obj._leaflet_id;
+	/* eslint-enable */
+}
+
+// @function throttle(fn: Function, time: Number, context: Object): Function
+// Returns a function which executes function `fn` with the given scope `context`
+// (so that the `this` keyword refers to `context` inside `fn`'s code). The function
+// `fn` will be called no more than one time per given amount of `time`. The arguments
+// received by the bound function will be any arguments passed when binding the
+// function, followed by any arguments passed when invoking the bound function.
+// Has an `L.throttle` shortcut.
+function throttle(fn, time, context) {
+	var lock, args, wrapperFn, later;
+
+	later = function () {
+		// reset lock and call if queued
+		lock = false;
+		if (args) {
+			wrapperFn.apply(context, args);
+			args = false;
+		}
+	};
+
+	wrapperFn = function () {
+		if (lock) {
+			// called too soon, queue to call later
+			args = arguments;
+
+		} else {
+			// call and lock until later
+			fn.apply(context, arguments);
+			setTimeout(later, time);
+			lock = true;
+		}
+	};
+
+	return wrapperFn;
+}
+
+// @function wrapNum(num: Number, range: Number[], includeMax?: Boolean): Number
+// Returns the number `num` modulo `range` in such a way so it lies within
+// `range[0]` and `range[1]`. The returned value will be always smaller than
+// `range[1]` unless `includeMax` is set to `true`.
+function wrapNum(x, range, includeMax) {
+	var max = range[1],
+	    min = range[0],
+	    d = max - min;
+	return x === max && includeMax ? x : ((x - min) % d + d) % d + min;
+}
+
+// @function falseFn(): Function
+// Returns a function which always returns `false`.
+function falseFn() { return false; }
+
+// @function formatNum(num: Number, digits?: Number): Number
+// Returns the number `num` rounded to `digits` decimals, or to 6 decimals by default.
+function formatNum(num, digits) {
+	var pow = Math.pow(10, (digits === undefined ? 6 : digits));
+	return Math.round(num * pow) / pow;
+}
+
+// @function trim(str: String): String
+// Compatibility polyfill for [String.prototype.trim](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/String/Trim)
+function trim(str) {
+	return str.trim ? str.trim() : str.replace(/^\s+|\s+$/g, '');
+}
+
+// @function splitWords(str: String): String[]
+// Trims and splits the string on whitespace and returns the array of parts.
+function splitWords(str) {
+	return trim(str).split(/\s+/);
+}
+
+// @function setOptions(obj: Object, options: Object): Object
+// Merges the given properties to the `options` of the `obj` object, returning the resulting options. See `Class options`. Has an `L.setOptions` shortcut.
+function setOptions(obj, options) {
+	if (!obj.hasOwnProperty('options')) {
+		obj.options = obj.options ? create(obj.options) : {};
+	}
+	for (var i in options) {
+		obj.options[i] = options[i];
+	}
+	return obj.options;
+}
+
+// @function getParamString(obj: Object, existingUrl?: String, uppercase?: Boolean): String
+// Converts an object into a parameter URL string, e.g. `{a: "foo", b: "bar"}`
+// translates to `'?a=foo&b=bar'`. If `existingUrl` is set, the parameters will
+// be appended at the end. If `uppercase` is `true`, the parameter names will
+// be uppercased (e.g. `'?A=foo&B=bar'`)
+function getParamString(obj, existingUrl, uppercase) {
+	var params = [];
+	for (var i in obj) {
+		params.push(encodeURIComponent(uppercase ? i.toUpperCase() : i) + '=' + encodeURIComponent(obj[i]));
+	}
+	return ((!existingUrl || existingUrl.indexOf('?') === -1) ? '?' : '&') + params.join('&');
+}
+
+var templateRe = /\{ *([\w_-]+) *\}/g;
+
+// @function template(str: String, data: Object): String
+// Simple templating facility, accepts a template string of the form `'Hello {a}, {b}'`
+// and a data object like `{a: 'foo', b: 'bar'}`, returns evaluated string
+// `('Hello foo, bar')`. You can also specify functions instead of strings for
+// data values — they will be evaluated passing `data` as an argument.
+function template(str, data) {
+	return str.replace(templateRe, function (str, key) {
+		var value = data[key];
+
+		if (value === undefined) {
+			throw new Error('No value provided for variable ' + str);
+
+		} else if (typeof value === 'function') {
+			value = value(data);
+		}
+		return value;
+	});
+}
+
+// @function isArray(obj): Boolean
+// Compatibility polyfill for [Array.isArray](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/isArray)
+var isArray = Array.isArray || function (obj) {
+	return (Object.prototype.toString.call(obj) === '[object Array]');
+};
+
+// @function indexOf(array: Array, el: Object): Number
+// Compatibility polyfill for [Array.prototype.indexOf](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf)
+function indexOf(array, el) {
+	for (var i = 0; i < array.length; i++) {
+		if (array[i] === el) { return i; }
+	}
+	return -1;
+}
+
+// @property emptyImageUrl: String
+// Data URI string containing a base64-encoded empty GIF image.
+// Used as a hack to free memory from unused images on WebKit-powered
+// mobile devices (by setting image `src` to this string).
+var emptyImageUrl = 'data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=';
+
+// inspired by http://paulirish.com/2011/requestanimationframe-for-smart-animating/
+
+function getPrefixed(name) {
+	return window['webkit' + name] || window['moz' + name] || window['ms' + name];
+}
+
+var lastTime = 0;
+
+// fallback for IE 7-8
+function timeoutDefer(fn) {
+	var time = +new Date(),
+	    timeToCall = Math.max(0, 16 - (time - lastTime));
+
+	lastTime = time + timeToCall;
+	return window.setTimeout(fn, timeToCall);
+}
+
+var requestFn = window.requestAnimationFrame || getPrefixed('RequestAnimationFrame') || timeoutDefer;
+var cancelFn = window.cancelAnimationFrame || getPrefixed('CancelAnimationFrame') ||
+		getPrefixed('CancelRequestAnimationFrame') || function (id) { window.clearTimeout(id); };
+
+// @function requestAnimFrame(fn: Function, context?: Object, immediate?: Boolean): Number
+// Schedules `fn` to be executed when the browser repaints. `fn` is bound to
+// `context` if given. When `immediate` is set, `fn` is called immediately if
+// the browser doesn't have native support for
+// [`window.requestAnimationFrame`](https://developer.mozilla.org/docs/Web/API/window/requestAnimationFrame),
+// otherwise it's delayed. Returns a request ID that can be used to cancel the request.
+function requestAnimFrame(fn, context, immediate) {
+	if (immediate && requestFn === timeoutDefer) {
+		fn.call(context);
+	} else {
+		return requestFn.call(window, bind(fn, context));
+	}
+}
+
+// @function cancelAnimFrame(id: Number): undefined
+// Cancels a previous `requestAnimFrame`. See also [window.cancelAnimationFrame](https://developer.mozilla.org/docs/Web/API/window/cancelAnimationFrame).
+function cancelAnimFrame(id) {
+	if (id) {
+		cancelFn.call(window, id);
+	}
+}
+
+
+var Util = (Object.freeze || Object)({
+	freeze: freeze,
+	extend: extend,
+	create: create,
+	bind: bind,
+	lastId: lastId,
+	stamp: stamp,
+	throttle: throttle,
+	wrapNum: wrapNum,
+	falseFn: falseFn,
+	formatNum: formatNum,
+	trim: trim,
+	splitWords: splitWords,
+	setOptions: setOptions,
+	getParamString: getParamString,
+	template: template,
+	isArray: isArray,
+	indexOf: indexOf,
+	emptyImageUrl: emptyImageUrl,
+	requestFn: requestFn,
+	cancelFn: cancelFn,
+	requestAnimFrame: requestAnimFrame,
+	cancelAnimFrame: cancelAnimFrame
+});
+
+// @class Class
+// @aka L.Class
+
+// @section
+// @uninheritable
+
+// Thanks to John Resig and Dean Edwards for inspiration!
+
+function Class() {}
+
+Class.extend = function (props) {
+
+	// @function extend(props: Object): Function
+	// [Extends the current class](#class-inheritance) given the properties to be included.
+	// Returns a Javascript function that is a class constructor (to be called with `new`).
+	var NewClass = function () {
+
+		// call the constructor
+		if (this.initialize) {
+			this.initialize.apply(this, arguments);
+		}
+
+		// call all constructor hooks
+		this.callInitHooks();
+	};
+
+	var parentProto = NewClass.__super__ = this.prototype;
+
+	var proto = create(parentProto);
+	proto.constructor = NewClass;
+
+	NewClass.prototype = proto;
+
+	// inherit parent's statics
+	for (var i in this) {
+		if (this.hasOwnProperty(i) && i !== 'prototype' && i !== '__super__') {
+			NewClass[i] = this[i];
+		}
+	}
+
+	// mix static properties into the class
+	if (props.statics) {
+		extend(NewClass, props.statics);
+		delete props.statics;
+	}
+
+	// mix includes into the prototype
+	if (props.includes) {
+		checkDeprecatedMixinEvents(props.includes);
+		extend.apply(null, [proto].concat(props.includes));
+		delete props.includes;
+	}
+
+	// merge options
+	if (proto.options) {
+		props.options = extend(create(proto.options), props.options);
+	}
+
+	// mix given properties into the prototype
+	extend(proto, props);
+
+	proto._initHooks = [];
+
+	// add method for calling all hooks
+	proto.callInitHooks = function () {
+
+		if (this._initHooksCalled) { return; }
+
+		if (parentProto.callInitHooks) {
+			parentProto.callInitHooks.call(this);
+		}
+
+		this._initHooksCalled = true;
+
+		for (var i = 0, len = proto._initHooks.length; i < len; i++) {
+			proto._initHooks[i].call(this);
+		}
+	};
+
+	return NewClass;
+};
+
+
+// @function include(properties: Object): this
+// [Includes a mixin](#class-includes) into the current class.
+Class.include = function (props) {
+	extend(this.prototype, props);
+	return this;
+};
+
+// @function mergeOptions(options: Object): this
+// [Merges `options`](#class-options) into the defaults of the class.
+Class.mergeOptions = function (options) {
+	extend(this.prototype.options, options);
+	return this;
+};
+
+// @function addInitHook(fn: Function): this
+// Adds a [constructor hook](#class-constructor-hooks) to the class.
+Class.addInitHook = function (fn) { // (Function) || (String, args...)
+	var args = Array.prototype.slice.call(arguments, 1);
+
+	var init = typeof fn === 'function' ? fn : function () {
+		this[fn].apply(this, args);
+	};
+
+	this.prototype._initHooks = this.prototype._initHooks || [];
+	this.prototype._initHooks.push(init);
+	return this;
+};
+
+function checkDeprecatedMixinEvents(includes) {
+	if (typeof L === 'undefined' || !L || !L.Mixin) { return; }
+
+	includes = isArray(includes) ? includes : [includes];
+
+	for (var i = 0; i < includes.length; i++) {
+		if (includes[i] === L.Mixin.Events) {
+			console.warn('Deprecated include of L.Mixin.Events: ' +
+				'this property will be removed in future releases, ' +
+				'please inherit from L.Evented instead.', new Error().stack);
+		}
+	}
+}
+
+/*
+ * @class Evented
+ * @aka L.Evented
+ * @inherits Class
+ *
+ * A set of methods shared between event-powered classes (like `Map` and `Marker`). Generally, events allow you to execute some function when something happens with an object (e.g. the user clicks on the map, causing the map to fire `'click'` event).
+ *
+ * @example
+ *
+ * ```js
+ * map.on('click', function(e) {
+ * 	alert(e.latlng);
+ * } );
+ * ```
+ *
+ * Leaflet deals with event listeners by reference, so if you want to add a listener and then remove it, define it as a function:
+ *
+ * ```js
+ * function onClick(e) { ... }
+ *
+ * map.on('click', onClick);
+ * map.off('click', onClick);
+ * ```
+ */
+
+var Events = {
+	/* @method on(type: String, fn: Function, context?: Object): this
+	 * Adds a listener function (`fn`) to a particular event type of the object. You can optionally specify the context of the listener (object the this keyword will point to). You can also pass several space-separated types (e.g. `'click dblclick'`).
+	 *
+	 * @alternative
+	 * @method on(eventMap: Object): this
+	 * Adds a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}`
+	 */
+	on: function (types, fn, context) {
+
+		// types can be a map of types/handlers
+		if (typeof types === 'object') {
+			for (var type in types) {
+				// we don't process space-separated events here for performance;
+				// it's a hot path since Layer uses the on(obj) syntax
+				this._on(type, types[type], fn);
+			}
+
+		} else {
+			// types can be a string of space-separated words
+			types = splitWords(types);
+
+			for (var i = 0, len = types.length; i < len; i++) {
+				this._on(types[i], fn, context);
+			}
+		}
+
+		return this;
+	},
+
+	/* @method off(type: String, fn?: Function, context?: Object): this
+	 * Removes a previously added listener function. If no function is specified, it will remove all the listeners of that particular event from the object. Note that if you passed a custom context to `on`, you must pass the same context to `off` in order to remove the listener.
+	 *
+	 * @alternative
+	 * @method off(eventMap: Object): this
+	 * Removes a set of type/listener pairs.
+	 *
+	 * @alternative
+	 * @method off: this
+	 * Removes all listeners to all events on the object.
+	 */
+	off: function (types, fn, context) {
+
+		if (!types) {
+			// clear all listeners if called without arguments
+			delete this._events;
+
+		} else if (typeof types === 'object') {
+			for (var type in types) {
+				this._off(type, types[type], fn);
+			}
+
+		} else {
+			types = splitWords(types);
+
+			for (var i = 0, len = types.length; i < len; i++) {
+				this._off(types[i], fn, context);
+			}
+		}
+
+		return this;
+	},
+
+	// attach listener (without syntactic sugar now)
+	_on: function (type, fn, context) {
+		this._events = this._events || {};
+
+		/* get/init listeners for type */
+		var typeListeners = this._events[type];
+		if (!typeListeners) {
+			typeListeners = [];
+			this._events[type] = typeListeners;
+		}
+
+		if (context === this) {
+			// Less memory footprint.
+			context = undefined;
+		}
+		var newListener = {fn: fn, ctx: context},
+		    listeners = typeListeners;
+
+		// check if fn already there
+		for (var i = 0, len = listeners.length; i < len; i++) {
+			if (listeners[i].fn === fn && listeners[i].ctx === context) {
+				return;
+			}
+		}
+
+		listeners.push(newListener);
+	},
+
+	_off: function (type, fn, context) {
+		var listeners,
+		    i,
+		    len;
+
+		if (!this._events) { return; }
+
+		listeners = this._events[type];
+
+		if (!listeners) {
+			return;
+		}
+
+		if (!fn) {
+			// Set all removed listeners to noop so they are not called if remove happens in fire
+			for (i = 0, len = listeners.length; i < len; i++) {
+				listeners[i].fn = falseFn;
+			}
+			// clear all listeners for a type if function isn't specified
+			delete this._events[type];
+			return;
+		}
+
+		if (context === this) {
+			context = undefined;
+		}
+
+		if (listeners) {
+
+			// find fn and remove it
+			for (i = 0, len = listeners.length; i < len; i++) {
+				var l = listeners[i];
+				if (l.ctx !== context) { continue; }
+				if (l.fn === fn) {
+
+					// set the removed listener to noop so that's not called if remove happens in fire
+					l.fn = falseFn;
+
+					if (this._firingCount) {
+						/* copy array in case events are being fired */
+						this._events[type] = listeners = listeners.slice();
+					}
+					listeners.splice(i, 1);
+
+					return;
+				}
+			}
+		}
+	},
+
+	// @method fire(type: String, data?: Object, propagate?: Boolean): this
+	// Fires an event of the specified type. You can optionally provide an data
+	// object — the first argument of the listener function will contain its
+	// properties. The event can optionally be propagated to event parents.
+	fire: function (type, data, propagate) {
+		if (!this.listens(type, propagate)) { return this; }
+
+		var event = extend({}, data, {
+			type: type,
+			target: this,
+			sourceTarget: data && data.sourceTarget || this
+		});
+
+		if (this._events) {
+			var listeners = this._events[type];
+
+			if (listeners) {
+				this._firingCount = (this._firingCount + 1) || 1;
+				for (var i = 0, len = listeners.length; i < len; i++) {
+					var l = listeners[i];
+					l.fn.call(l.ctx || this, event);
+				}
+
+				this._firingCount--;
+			}
+		}
+
+		if (propagate) {
+			// propagate the event to parents (set with addEventParent)
+			this._propagateEvent(event);
+		}
+
+		return this;
+	},
+
+	// @method listens(type: String): Boolean
+	// Returns `true` if a particular event type has any listeners attached to it.
+	listens: function (type, propagate) {
+		var listeners = this._events && this._events[type];
+		if (listeners && listeners.length) { return true; }
+
+		if (propagate) {
+			// also check parents for listeners if event propagates
+			for (var id in this._eventParents) {
+				if (this._eventParents[id].listens(type, propagate)) { return true; }
+			}
+		}
+		return false;
+	},
+
+	// @method once(…): this
+	// Behaves as [`on(…)`](#evented-on), except the listener will only get fired once and then removed.
+	once: function (types, fn, context) {
+
+		if (typeof types === 'object') {
+			for (var type in types) {
+				this.once(type, types[type], fn);
+			}
+			return this;
+		}
+
+		var handler = bind(function () {
+			this
+			    .off(types, fn, context)
+			    .off(types, handler, context);
+		}, this);
+
+		// add a listener that's executed once and removed after that
+		return this
+		    .on(types, fn, context)
+		    .on(types, handler, context);
+	},
+
+	// @method addEventParent(obj: Evented): this
+	// Adds an event parent - an `Evented` that will receive propagated events
+	addEventParent: function (obj) {
+		this._eventParents = this._eventParents || {};
+		this._eventParents[stamp(obj)] = obj;
+		return this;
+	},
+
+	// @method removeEventParent(obj: Evented): this
+	// Removes an event parent, so it will stop receiving propagated events
+	removeEventParent: function (obj) {
+		if (this._eventParents) {
+			delete this._eventParents[stamp(obj)];
+		}
+		return this;
+	},
+
+	_propagateEvent: function (e) {
+		for (var id in this._eventParents) {
+			this._eventParents[id].fire(e.type, extend({
+				layer: e.target,
+				propagatedFrom: e.target
+			}, e), true);
+		}
+	}
+};
+
+// aliases; we should ditch those eventually
+
+// @method addEventListener(…): this
+// Alias to [`on(…)`](#evented-on)
+Events.addEventListener = Events.on;
+
+// @method removeEventListener(…): this
+// Alias to [`off(…)`](#evented-off)
+
+// @method clearAllEventListeners(…): this
+// Alias to [`off()`](#evented-off)
+Events.removeEventListener = Events.clearAllEventListeners = Events.off;
+
+// @method addOneTimeEventListener(…): this
+// Alias to [`once(…)`](#evented-once)
+Events.addOneTimeEventListener = Events.once;
+
+// @method fireEvent(…): this
+// Alias to [`fire(…)`](#evented-fire)
+Events.fireEvent = Events.fire;
+
+// @method hasEventListeners(…): Boolean
+// Alias to [`listens(…)`](#evented-listens)
+Events.hasEventListeners = Events.listens;
+
+var Evented = Class.extend(Events);
+
+/*
+ * @class Point
+ * @aka L.Point
+ *
+ * Represents a point with `x` and `y` coordinates in pixels.
+ *
+ * @example
+ *
+ * ```js
+ * var point = L.point(200, 300);
+ * ```
+ *
+ * All Leaflet methods and options that accept `Point` objects also accept them in a simple Array form (unless noted otherwise), so these lines are equivalent:
+ *
+ * ```js
+ * map.panBy([200, 300]);
+ * map.panBy(L.point(200, 300));
+ * ```
+ *
+ * Note that `Point` does not inherit from Leafet's `Class` object,
+ * which means new classes can't inherit from it, and new methods
+ * can't be added to it with the `include` function.
+ */
+
+function Point(x, y, round) {
+	// @property x: Number; The `x` coordinate of the point
+	this.x = (round ? Math.round(x) : x);
+	// @property y: Number; The `y` coordinate of the point
+	this.y = (round ? Math.round(y) : y);
+}
+
+var trunc = Math.trunc || function (v) {
+	return v > 0 ? Math.floor(v) : Math.ceil(v);
+};
+
+Point.prototype = {
+
+	// @method clone(): Point
+	// Returns a copy of the current point.
+	clone: function () {
+		return new Point(this.x, this.y);
+	},
+
+	// @method add(otherPoint: Point): Point
+	// Returns the result of addition of the current and the given points.
+	add: function (point) {
+		// non-destructive, returns a new point
+		return this.clone()._add(toPoint(point));
+	},
+
+	_add: function (point) {
+		// destructive, used directly for performance in situations where it's safe to modify existing point
+		this.x += point.x;
+		this.y += point.y;
+		return this;
+	},
+
+	// @method subtract(otherPoint: Point): Point
+	// Returns the result of subtraction of the given point from the current.
+	subtract: function (point) {
+		return this.clone()._subtract(toPoint(point));
+	},
+
+	_subtract: function (point) {
+		this.x -= point.x;
+		this.y -= point.y;
+		return this;
+	},
+
+	// @method divideBy(num: Number): Point
+	// Returns the result of division of the current point by the given number.
+	divideBy: function (num) {
+		return this.clone()._divideBy(num);
+	},
+
+	_divideBy: function (num) {
+		this.x /= num;
+		this.y /= num;
+		return this;
+	},
+
+	// @method multiplyBy(num: Number): Point
+	// Returns the result of multiplication of the current point by the given number.
+	multiplyBy: function (num) {
+		return this.clone()._multiplyBy(num);
+	},
+
+	_multiplyBy: function (num) {
+		this.x *= num;
+		this.y *= num;
+		return this;
+	},
+
+	// @method scaleBy(scale: Point): Point
+	// Multiply each coordinate of the current point by each coordinate of
+	// `scale`. In linear algebra terms, multiply the point by the
+	// [scaling matrix](https://en.wikipedia.org/wiki/Scaling_%28geometry%29#Matrix_representation)
+	// defined by `scale`.
+	scaleBy: function (point) {
+		return new Point(this.x * point.x, this.y * point.y);
+	},
+
+	// @method unscaleBy(scale: Point): Point
+	// Inverse of `scaleBy`. Divide each coordinate of the current point by
+	// each coordinate of `scale`.
+	unscaleBy: function (point) {
+		return new Point(this.x / point.x, this.y / point.y);
+	},
+
+	// @method round(): Point
+	// Returns a copy of the current point with rounded coordinates.
+	round: function () {
+		return this.clone()._round();
+	},
+
+	_round: function () {
+		this.x = Math.round(this.x);
+		this.y = Math.round(this.y);
+		return this;
+	},
+
+	// @method floor(): Point
+	// Returns a copy of the current point with floored coordinates (rounded down).
+	floor: function () {
+		return this.clone()._floor();
+	},
+
+	_floor: function () {
+		this.x = Math.floor(this.x);
+		this.y = Math.floor(this.y);
+		return this;
+	},
+
+	// @method ceil(): Point
+	// Returns a copy of the current point with ceiled coordinates (rounded up).
+	ceil: function () {
+		return this.clone()._ceil();
+	},
+
+	_ceil: function () {
+		this.x = Math.ceil(this.x);
+		this.y = Math.ceil(this.y);
+		return this;
+	},
+
+	// @method trunc(): Point
+	// Returns a copy of the current point with truncated coordinates (rounded towards zero).
+	trunc: function () {
+		return this.clone()._trunc();
+	},
+
+	_trunc: function () {
+		this.x = trunc(this.x);
+		this.y = trunc(this.y);
+		return this;
+	},
+
+	// @method distanceTo(otherPoint: Point): Number
+	// Returns the cartesian distance between the current and the given points.
+	distanceTo: function (point) {
+		point = toPoint(point);
+
+		var x = point.x - this.x,
+		    y = point.y - this.y;
+
+		return Math.sqrt(x * x + y * y);
+	},
+
+	// @method equals(otherPoint: Point): Boolean
+	// Returns `true` if the given point has the same coordinates.
+	equals: function (point) {
+		point = toPoint(point);
+
+		return point.x === this.x &&
+		       point.y === this.y;
+	},
+
+	// @method contains(otherPoint: Point): Boolean
+	// Returns `true` if both coordinates of the given point are less than the corresponding current point coordinates (in absolute values).
+	contains: function (point) {
+		point = toPoint(point);
+
+		return Math.abs(point.x) <= Math.abs(this.x) &&
+		       Math.abs(point.y) <= Math.abs(this.y);
+	},
+
+	// @method toString(): String
+	// Returns a string representation of the point for debugging purposes.
+	toString: function () {
+		return 'Point(' +
+		        formatNum(this.x) + ', ' +
+		        formatNum(this.y) + ')';
+	}
+};
+
+// @factory L.point(x: Number, y: Number, round?: Boolean)
+// Creates a Point object with the given `x` and `y` coordinates. If optional `round` is set to true, rounds the `x` and `y` values.
+
+// @alternative
+// @factory L.point(coords: Number[])
+// Expects an array of the form `[x, y]` instead.
+
+// @alternative
+// @factory L.point(coords: Object)
+// Expects a plain object of the form `{x: Number, y: Number}` instead.
+function toPoint(x, y, round) {
+	if (x instanceof Point) {
+		return x;
+	}
+	if (isArray(x)) {
+		return new Point(x[0], x[1]);
+	}
+	if (x === undefined || x === null) {
+		return x;
+	}
+	if (typeof x === 'object' && 'x' in x && 'y' in x) {
+		return new Point(x.x, x.y);
+	}
+	return new Point(x, y, round);
+}
+
+/*
+ * @class Bounds
+ * @aka L.Bounds
+ *
+ * Represents a rectangular area in pixel coordinates.
+ *
+ * @example
+ *
+ * ```js
+ * var p1 = L.point(10, 10),
+ * p2 = L.point(40, 60),
+ * bounds = L.bounds(p1, p2);
+ * ```
+ *
+ * All Leaflet methods that accept `Bounds` objects also accept them in a simple Array form (unless noted otherwise), so the bounds example above can be passed like this:
+ *
+ * ```js
+ * otherBounds.intersects([[10, 10], [40, 60]]);
+ * ```
+ *
+ * Note that `Bounds` does not inherit from Leafet's `Class` object,
+ * which means new classes can't inherit from it, and new methods
+ * can't be added to it with the `include` function.
+ */
+
+function Bounds(a, b) {
+	if (!a) { return; }
+
+	var points = b ? [a, b] : a;
+
+	for (var i = 0, len = points.length; i < len; i++) {
+		this.extend(points[i]);
+	}
+}
+
+Bounds.prototype = {
+	// @method extend(point: Point): this
+	// Extends the bounds to contain the given point.
+	extend: function (point) { // (Point)
+		point = toPoint(point);
+
+		// @property min: Point
+		// The top left corner of the rectangle.
+		// @property max: Point
+		// The bottom right corner of the rectangle.
+		if (!this.min && !this.max) {
+			this.min = point.clone();
+			this.max = point.clone();
+		} else {
+			this.min.x = Math.min(point.x, this.min.x);
+			this.max.x = Math.max(point.x, this.max.x);
+			this.min.y = Math.min(point.y, this.min.y);
+			this.max.y = Math.max(point.y, this.max.y);
+		}
+		return this;
+	},
+
+	// @method getCenter(round?: Boolean): Point
+	// Returns the center point of the bounds.
+	getCenter: function (round) {
+		return new Point(
+		        (this.min.x + this.max.x) / 2,
+		        (this.min.y + this.max.y) / 2, round);
+	},
+
+	// @method getBottomLeft(): Point
+	// Returns the bottom-left point of the bounds.
+	getBottomLeft: function () {
+		return new Point(this.min.x, this.max.y);
+	},
+
+	// @method getTopRight(): Point
+	// Returns the top-right point of the bounds.
+	getTopRight: function () { // -> Point
+		return new Point(this.max.x, this.min.y);
+	},
+
+	// @method getTopLeft(): Point
+	// Returns the top-left point of the bounds (i.e. [`this.min`](#bounds-min)).
+	getTopLeft: function () {
+		return this.min; // left, top
+	},
+
+	// @method getBottomRight(): Point
+	// Returns the bottom-right point of the bounds (i.e. [`this.max`](#bounds-max)).
+	getBottomRight: function () {
+		return this.max; // right, bottom
+	},
+
+	// @method getSize(): Point
+	// Returns the size of the given bounds
+	getSize: function () {
+		return this.max.subtract(this.min);
+	},
+
+	// @method contains(otherBounds: Bounds): Boolean
+	// Returns `true` if the rectangle contains the given one.
+	// @alternative
+	// @method contains(point: Point): Boolean
+	// Returns `true` if the rectangle contains the given point.
+	contains: function (obj) {
+		var min, max;
+
+		if (typeof obj[0] === 'number' || obj instanceof Point) {
+			obj = toPoint(obj);
+		} else {
+			obj = toBounds(obj);
+		}
+
+		if (obj instanceof Bounds) {
+			min = obj.min;
+			max = obj.max;
+		} else {
+			min = max = obj;
+		}
+
+		return (min.x >= this.min.x) &&
+		       (max.x <= this.max.x) &&
+		       (min.y >= this.min.y) &&
+		       (max.y <= this.max.y);
+	},
+
+	// @method intersects(otherBounds: Bounds): Boolean
+	// Returns `true` if the rectangle intersects the given bounds. Two bounds
+	// intersect if they have at least one point in common.
+	intersects: function (bounds) { // (Bounds) -> Boolean
+		bounds = toBounds(bounds);
+
+		var min = this.min,
+		    max = this.max,
+		    min2 = bounds.min,
+		    max2 = bounds.max,
+		    xIntersects = (max2.x >= min.x) && (min2.x <= max.x),
+		    yIntersects = (max2.y >= min.y) && (min2.y <= max.y);
+
+		return xIntersects && yIntersects;
+	},
+
+	// @method overlaps(otherBounds: Bounds): Boolean
+	// Returns `true` if the rectangle overlaps the given bounds. Two bounds
+	// overlap if their intersection is an area.
+	overlaps: function (bounds) { // (Bounds) -> Boolean
+		bounds = toBounds(bounds);
+
+		var min = this.min,
+		    max = this.max,
+		    min2 = bounds.min,
+		    max2 = bounds.max,
+		    xOverlaps = (max2.x > min.x) && (min2.x < max.x),
+		    yOverlaps = (max2.y > min.y) && (min2.y < max.y);
+
+		return xOverlaps && yOverlaps;
+	},
+
+	isValid: function () {
+		return !!(this.min && this.max);
+	}
+};
+
+
+// @factory L.bounds(corner1: Point, corner2: Point)
+// Creates a Bounds object from two corners coordinate pairs.
+// @alternative
+// @factory L.bounds(points: Point[])
+// Creates a Bounds object from the given array of points.
+function toBounds(a, b) {
+	if (!a || a instanceof Bounds) {
+		return a;
+	}
+	return new Bounds(a, b);
+}
+
+/*
+ * @class LatLngBounds
+ * @aka L.LatLngBounds
+ *
+ * Represents a rectangular geographical area on a map.
+ *
+ * @example
+ *
+ * ```js
+ * var corner1 = L.latLng(40.712, -74.227),
+ * corner2 = L.latLng(40.774, -74.125),
+ * bounds = L.latLngBounds(corner1, corner2);
+ * ```
+ *
+ * All Leaflet methods that accept LatLngBounds objects also accept them in a simple Array form (unless noted otherwise), so the bounds example above can be passed like this:
+ *
+ * ```js
+ * map.fitBounds([
+ * 	[40.712, -74.227],
+ * 	[40.774, -74.125]
+ * ]);
+ * ```
+ *
+ * Caution: if the area crosses the antimeridian (often confused with the International Date Line), you must specify corners _outside_ the [-180, 180] degrees longitude range.
+ *
+ * Note that `LatLngBounds` does not inherit from Leafet's `Class` object,
+ * which means new classes can't inherit from it, and new methods
+ * can't be added to it with the `include` function.
+ */
+
+function LatLngBounds(corner1, corner2) { // (LatLng, LatLng) or (LatLng[])
+	if (!corner1) { return; }
+
+	var latlngs = corner2 ? [corner1, corner2] : corner1;
+
+	for (var i = 0, len = latlngs.length; i < len; i++) {
+		this.extend(latlngs[i]);
+	}
+}
+
+LatLngBounds.prototype = {
+
+	// @method extend(latlng: LatLng): this
+	// Extend the bounds to contain the given point
+
+	// @alternative
+	// @method extend(otherBounds: LatLngBounds): this
+	// Extend the bounds to contain the given bounds
+	extend: function (obj) {
+		var sw = this._southWest,
+		    ne = this._northEast,
+		    sw2, ne2;
+
+		if (obj instanceof LatLng) {
+			sw2 = obj;
+			ne2 = obj;
+
+		} else if (obj instanceof LatLngBounds) {
+			sw2 = obj._southWest;
+			ne2 = obj._northEast;
+
+			if (!sw2 || !ne2) { return this; }
+
+		} else {
+			return obj ? this.extend(toLatLng(obj) || toLatLngBounds(obj)) : this;
+		}
+
+		if (!sw && !ne) {
+			this._southWest = new LatLng(sw2.lat, sw2.lng);
+			this._northEast = new LatLng(ne2.lat, ne2.lng);
+		} else {
+			sw.lat = Math.min(sw2.lat, sw.lat);
+			sw.lng = Math.min(sw2.lng, sw.lng);
+			ne.lat = Math.max(ne2.lat, ne.lat);
+			ne.lng = Math.max(ne2.lng, ne.lng);
+		}
+
+		return this;
+	},
+
+	// @method pad(bufferRatio: Number): LatLngBounds
+	// Returns bounds created by extending or retracting the current bounds by a given ratio in each direction.
+	// For example, a ratio of 0.5 extends the bounds by 50% in each direction.
+	// Negative values will retract the bounds.
+	pad: function (bufferRatio) {
+		var sw = this._southWest,
+		    ne = this._northEast,
+		    heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio,
+		    widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio;
+
+		return new LatLngBounds(
+		        new LatLng(sw.lat - heightBuffer, sw.lng - widthBuffer),
+		        new LatLng(ne.lat + heightBuffer, ne.lng + widthBuffer));
+	},
+
+	// @method getCenter(): LatLng
+	// Returns the center point of the bounds.
+	getCenter: function () {
+		return new LatLng(
+		        (this._southWest.lat + this._northEast.lat) / 2,
+		        (this._southWest.lng + this._northEast.lng) / 2);
+	},
+
+	// @method getSouthWest(): LatLng
+	// Returns the south-west point of the bounds.
+	getSouthWest: function () {
+		return this._southWest;
+	},
+
+	// @method getNorthEast(): LatLng
+	// Returns the north-east point of the bounds.
+	getNorthEast: function () {
+		return this._northEast;
+	},
+
+	// @method getNorthWest(): LatLng
+	// Returns the north-west point of the bounds.
+	getNorthWest: function () {
+		return new LatLng(this.getNorth(), this.getWest());
+	},
+
+	// @method getSouthEast(): LatLng
+	// Returns the south-east point of the bounds.
+	getSouthEast: function () {
+		return new LatLng(this.getSouth(), this.getEast());
+	},
+
+	// @method getWest(): Number
+	// Returns the west longitude of the bounds
+	getWest: function () {
+		return this._southWest.lng;
+	},
+
+	// @method getSouth(): Number
+	// Returns the south latitude of the bounds
+	getSouth: function () {
+		return this._southWest.lat;
+	},
+
+	// @method getEast(): Number
+	// Returns the east longitude of the bounds
+	getEast: function () {
+		return this._northEast.lng;
+	},
+
+	// @method getNorth(): Number
+	// Returns the north latitude of the bounds
+	getNorth: function () {
+		return this._northEast.lat;
+	},
+
+	// @method contains(otherBounds: LatLngBounds): Boolean
+	// Returns `true` if the rectangle contains the given one.
+
+	// @alternative
+	// @method contains (latlng: LatLng): Boolean
+	// Returns `true` if the rectangle contains the given point.
+	contains: function (obj) { // (LatLngBounds) or (LatLng) -> Boolean
+		if (typeof obj[0] === 'number' || obj instanceof LatLng || 'lat' in obj) {
+			obj = toLatLng(obj);
+		} else {
+			obj = toLatLngBounds(obj);
+		}
+
+		var sw = this._southWest,
+		    ne = this._northEast,
+		    sw2, ne2;
+
+		if (obj instanceof LatLngBounds) {
+			sw2 = obj.getSouthWest();
+			ne2 = obj.getNorthEast();
+		} else {
+			sw2 = ne2 = obj;
+		}
+
+		return (sw2.lat >= sw.lat) && (ne2.lat <= ne.lat) &&
+		       (sw2.lng >= sw.lng) && (ne2.lng <= ne.lng);
+	},
+
+	// @method intersects(otherBounds: LatLngBounds): Boolean
+	// Returns `true` if the rectangle intersects the given bounds. Two bounds intersect if they have at least one point in common.
+	intersects: function (bounds) {
+		bounds = toLatLngBounds(bounds);
+
+		var sw = this._southWest,
+		    ne = this._northEast,
+		    sw2 = bounds.getSouthWest(),
+		    ne2 = bounds.getNorthEast(),
+
+		    latIntersects = (ne2.lat >= sw.lat) && (sw2.lat <= ne.lat),
+		    lngIntersects = (ne2.lng >= sw.lng) && (sw2.lng <= ne.lng);
+
+		return latIntersects && lngIntersects;
+	},
+
+	// @method overlaps(otherBounds: Bounds): Boolean
+	// Returns `true` if the rectangle overlaps the given bounds. Two bounds overlap if their intersection is an area.
+	overlaps: function (bounds) {
+		bounds = toLatLngBounds(bounds);
+
+		var sw = this._southWest,
+		    ne = this._northEast,
+		    sw2 = bounds.getSouthWest(),
+		    ne2 = bounds.getNorthEast(),
+
+		    latOverlaps = (ne2.lat > sw.lat) && (sw2.lat < ne.lat),
+		    lngOverlaps = (ne2.lng > sw.lng) && (sw2.lng < ne.lng);
+
+		return latOverlaps && lngOverlaps;
+	},
+
+	// @method toBBoxString(): String
+	// Returns a string with bounding box coordinates in a 'southwest_lng,southwest_lat,northeast_lng,northeast_lat' format. Useful for sending requests to web services that return geo data.
+	toBBoxString: function () {
+		return [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()].join(',');
+	},
+
+	// @method equals(otherBounds: LatLngBounds, maxMargin?: Number): Boolean
+	// Returns `true` if the rectangle is equivalent (within a small margin of error) to the given bounds. The margin of error can be overridden by setting `maxMargin` to a small number.
+	equals: function (bounds, maxMargin) {
+		if (!bounds) { return false; }
+
+		bounds = toLatLngBounds(bounds);
+
+		return this._southWest.equals(bounds.getSouthWest(), maxMargin) &&
+		       this._northEast.equals(bounds.getNorthEast(), maxMargin);
+	},
+
+	// @method isValid(): Boolean
+	// Returns `true` if the bounds are properly initialized.
+	isValid: function () {
+		return !!(this._southWest && this._northEast);
+	}
+};
+
+// TODO International date line?
+
+// @factory L.latLngBounds(corner1: LatLng, corner2: LatLng)
+// Creates a `LatLngBounds` object by defining two diagonally opposite corners of the rectangle.
+
+// @alternative
+// @factory L.latLngBounds(latlngs: LatLng[])
+// Creates a `LatLngBounds` object defined by the geographical points it contains. Very useful for zooming the map to fit a particular set of locations with [`fitBounds`](#map-fitbounds).
+function toLatLngBounds(a, b) {
+	if (a instanceof LatLngBounds) {
+		return a;
+	}
+	return new LatLngBounds(a, b);
+}
+
+/* @class LatLng
+ * @aka L.LatLng
+ *
+ * Represents a geographical point with a certain latitude and longitude.
+ *
+ * @example
+ *
+ * ```
+ * var latlng = L.latLng(50.5, 30.5);
+ * ```
+ *
+ * All Leaflet methods that accept LatLng objects also accept them in a simple Array form and simple object form (unless noted otherwise), so these lines are equivalent:
+ *
+ * ```
+ * map.panTo([50, 30]);
+ * map.panTo({lon: 30, lat: 50});
+ * map.panTo({lat: 50, lng: 30});
+ * map.panTo(L.latLng(50, 30));
+ * ```
+ *
+ * Note that `LatLng` does not inherit from Leafet's `Class` object,
+ * which means new classes can't inherit from it, and new methods
+ * can't be added to it with the `include` function.
+ */
+
+function LatLng(lat, lng, alt) {
+	if (isNaN(lat) || isNaN(lng)) {
+		throw new Error('Invalid LatLng object: (' + lat + ', ' + lng + ')');
+	}
+
+	// @property lat: Number
+	// Latitude in degrees
+	this.lat = +lat;
+
+	// @property lng: Number
+	// Longitude in degrees
+	this.lng = +lng;
+
+	// @property alt: Number
+	// Altitude in meters (optional)
+	if (alt !== undefined) {
+		this.alt = +alt;
+	}
+}
+
+LatLng.prototype = {
+	// @method equals(otherLatLng: LatLng, maxMargin?: Number): Boolean
+	// Returns `true` if the given `LatLng` point is at the same position (within a small margin of error). The margin of error can be overridden by setting `maxMargin` to a small number.
+	equals: function (obj, maxMargin) {
+		if (!obj) { return false; }
+
+		obj = toLatLng(obj);
+
+		var margin = Math.max(
+		        Math.abs(this.lat - obj.lat),
+		        Math.abs(this.lng - obj.lng));
+
+		return margin <= (maxMargin === undefined ? 1.0E-9 : maxMargin);
+	},
+
+	// @method toString(): String
+	// Returns a string representation of the point (for debugging purposes).
+	toString: function (precision) {
+		return 'LatLng(' +
+		        formatNum(this.lat, precision) + ', ' +
+		        formatNum(this.lng, precision) + ')';
+	},
+
+	// @method distanceTo(otherLatLng: LatLng): Number
+	// Returns the distance (in meters) to the given `LatLng` calculated using the [Spherical Law of Cosines](https://en.wikipedia.org/wiki/Spherical_law_of_cosines).
+	distanceTo: function (other) {
+		return Earth.distance(this, toLatLng(other));
+	},
+
+	// @method wrap(): LatLng
+	// Returns a new `LatLng` object with the longitude wrapped so it's always between -180 and +180 degrees.
+	wrap: function () {
+		return Earth.wrapLatLng(this);
+	},
+
+	// @method toBounds(sizeInMeters: Number): LatLngBounds
+	// Returns a new `LatLngBounds` object in which each boundary is `sizeInMeters/2` meters apart from the `LatLng`.
+	toBounds: function (sizeInMeters) {
+		var latAccuracy = 180 * sizeInMeters / 40075017,
+		    lngAccuracy = latAccuracy / Math.cos((Math.PI / 180) * this.lat);
+
+		return toLatLngBounds(
+		        [this.lat - latAccuracy, this.lng - lngAccuracy],
+		        [this.lat + latAccuracy, this.lng + lngAccuracy]);
+	},
+
+	clone: function () {
+		return new LatLng(this.lat, this.lng, this.alt);
+	}
+};
+
+
+
+// @factory L.latLng(latitude: Number, longitude: Number, altitude?: Number): LatLng
+// Creates an object representing a geographical point with the given latitude and longitude (and optionally altitude).
+
+// @alternative
+// @factory L.latLng(coords: Array): LatLng
+// Expects an array of the form `[Number, Number]` or `[Number, Number, Number]` instead.
+
+// @alternative
+// @factory L.latLng(coords: Object): LatLng
+// Expects an plain object of the form `{lat: Number, lng: Number}` or `{lat: Number, lng: Number, alt: Number}` instead.
+
+function toLatLng(a, b, c) {
+	if (a instanceof LatLng) {
+		return a;
+	}
+	if (isArray(a) && typeof a[0] !== 'object') {
+		if (a.length === 3) {
+			return new LatLng(a[0], a[1], a[2]);
+		}
+		if (a.length === 2) {
+			return new LatLng(a[0], a[1]);
+		}
+		return null;
+	}
+	if (a === undefined || a === null) {
+		return a;
+	}
+	if (typeof a === 'object' && 'lat' in a) {
+		return new LatLng(a.lat, 'lng' in a ? a.lng : a.lon, a.alt);
+	}
+	if (b === undefined) {
+		return null;
+	}
+	return new LatLng(a, b, c);
+}
+
+/*
+ * @namespace CRS
+ * @crs L.CRS.Base
+ * Object that defines coordinate reference systems for projecting
+ * geographical points into pixel (screen) coordinates and back (and to
+ * coordinates in other units for [WMS](https://en.wikipedia.org/wiki/Web_Map_Service) services). See
+ * [spatial reference system](http://en.wikipedia.org/wiki/Coordinate_reference_system).
+ *
+ * Leaflet defines the most usual CRSs by default. If you want to use a
+ * CRS not defined by default, take a look at the
+ * [Proj4Leaflet](https://github.com/kartena/Proj4Leaflet) plugin.
+ *
+ * Note that the CRS instances do not inherit from Leafet's `Class` object,
+ * and can't be instantiated. Also, new classes can't inherit from them,
+ * and methods can't be added to them with the `include` function.
+ */
+
+var CRS = {
+	// @method latLngToPoint(latlng: LatLng, zoom: Number): Point
+	// Projects geographical coordinates into pixel coordinates for a given zoom.
+	latLngToPoint: function (latlng, zoom) {
+		var projectedPoint = this.projection.project(latlng),
+		    scale = this.scale(zoom);
+
+		return this.transformation._transform(projectedPoint, scale);
+	},
+
+	// @method pointToLatLng(point: Point, zoom: Number): LatLng
+	// The inverse of `latLngToPoint`. Projects pixel coordinates on a given
+	// zoom into geographical coordinates.
+	pointToLatLng: function (point, zoom) {
+		var scale = this.scale(zoom),
+		    untransformedPoint = this.transformation.untransform(point, scale);
+
+		return this.projection.unproject(untransformedPoint);
+	},
+
+	// @method project(latlng: LatLng): Point
+	// Projects geographical coordinates into coordinates in units accepted for
+	// this CRS (e.g. meters for EPSG:3857, for passing it to WMS services).
+	project: function (latlng) {
+		return this.projection.project(latlng);
+	},
+
+	// @method unproject(point: Point): LatLng
+	// Given a projected coordinate returns the corresponding LatLng.
+	// The inverse of `project`.
+	unproject: function (point) {
+		return this.projection.unproject(point);
+	},
+
+	// @method scale(zoom: Number): Number
+	// Returns the scale used when transforming projected coordinates into
+	// pixel coordinates for a particular zoom. For example, it returns
+	// `256 * 2^zoom` for Mercator-based CRS.
+	scale: function (zoom) {
+		return 256 * Math.pow(2, zoom);
+	},
+
+	// @method zoom(scale: Number): Number
+	// Inverse of `scale()`, returns the zoom level corresponding to a scale
+	// factor of `scale`.
+	zoom: function (scale) {
+		return Math.log(scale / 256) / Math.LN2;
+	},
+
+	// @method getProjectedBounds(zoom: Number): Bounds
+	// Returns the projection's bounds scaled and transformed for the provided `zoom`.
+	getProjectedBounds: function (zoom) {
+		if (this.infinite) { return null; }
+
+		var b = this.projection.bounds,
+		    s = this.scale(zoom),
+		    min = this.transformation.transform(b.min, s),
+		    max = this.transformation.transform(b.max, s);
+
+		return new Bounds(min, max);
+	},
+
+	// @method distance(latlng1: LatLng, latlng2: LatLng): Number
+	// Returns the distance between two geographical coordinates.
+
+	// @property code: String
+	// Standard code name of the CRS passed into WMS services (e.g. `'EPSG:3857'`)
+	//
+	// @property wrapLng: Number[]
+	// An array of two numbers defining whether the longitude (horizontal) coordinate
+	// axis wraps around a given range and how. Defaults to `[-180, 180]` in most
+	// geographical CRSs. If `undefined`, the longitude axis does not wrap around.
+	//
+	// @property wrapLat: Number[]
+	// Like `wrapLng`, but for the latitude (vertical) axis.
+
+	// wrapLng: [min, max],
+	// wrapLat: [min, max],
+
+	// @property infinite: Boolean
+	// If true, the coordinate space will be unbounded (infinite in both axes)
+	infinite: false,
+
+	// @method wrapLatLng(latlng: LatLng): LatLng
+	// Returns a `LatLng` where lat and lng has been wrapped according to the
+	// CRS's `wrapLat` and `wrapLng` properties, if they are outside the CRS's bounds.
+	wrapLatLng: function (latlng) {
+		var lng = this.wrapLng ? wrapNum(latlng.lng, this.wrapLng, true) : latlng.lng,
+		    lat = this.wrapLat ? wrapNum(latlng.lat, this.wrapLat, true) : latlng.lat,
+		    alt = latlng.alt;
+
+		return new LatLng(lat, lng, alt);
+	},
+
+	// @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds
+	// Returns a `LatLngBounds` with the same size as the given one, ensuring
+	// that its center is within the CRS's bounds.
+	// Only accepts actual `L.LatLngBounds` instances, not arrays.
+	wrapLatLngBounds: function (bounds) {
+		var center = bounds.getCenter(),
+		    newCenter = this.wrapLatLng(center),
+		    latShift = center.lat - newCenter.lat,
+		    lngShift = center.lng - newCenter.lng;
+
+		if (latShift === 0 && lngShift === 0) {
+			return bounds;
+		}
+
+		var sw = bounds.getSouthWest(),
+		    ne = bounds.getNorthEast(),
+		    newSw = new LatLng(sw.lat - latShift, sw.lng - lngShift),
+		    newNe = new LatLng(ne.lat - latShift, ne.lng - lngShift);
+
+		return new LatLngBounds(newSw, newNe);
+	}
+};
+
+/*
+ * @namespace CRS
+ * @crs L.CRS.Earth
+ *
+ * Serves as the base for CRS that are global such that they cover the earth.
+ * Can only be used as the base for other CRS and cannot be used directly,
+ * since it does not have a `code`, `projection` or `transformation`. `distance()` returns
+ * meters.
+ */
+
+var Earth = extend({}, CRS, {
+	wrapLng: [-180, 180],
+
+	// Mean Earth Radius, as recommended for use by
+	// the International Union of Geodesy and Geophysics,
+	// see http://rosettacode.org/wiki/Haversine_formula
+	R: 6371000,
+
+	// distance between two geographical points using spherical law of cosines approximation
+	distance: function (latlng1, latlng2) {
+		var rad = Math.PI / 180,
+		    lat1 = latlng1.lat * rad,
+		    lat2 = latlng2.lat * rad,
+		    sinDLat = Math.sin((latlng2.lat - latlng1.lat) * rad / 2),
+		    sinDLon = Math.sin((latlng2.lng - latlng1.lng) * rad / 2),
+		    a = sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon,
+		    c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
+		return this.R * c;
+	}
+});
+
+/*
+ * @namespace Projection
+ * @projection L.Projection.SphericalMercator
+ *
+ * Spherical Mercator projection — the most common projection for online maps,
+ * used by almost all free and commercial tile providers. Assumes that Earth is
+ * a sphere. Used by the `EPSG:3857` CRS.
+ */
+
+var SphericalMercator = {
+
+	R: 6378137,
+	MAX_LATITUDE: 85.0511287798,
+
+	project: function (latlng) {
+		var d = Math.PI / 180,
+		    max = this.MAX_LATITUDE,
+		    lat = Math.max(Math.min(max, latlng.lat), -max),
+		    sin = Math.sin(lat * d);
+
+		return new Point(
+			this.R * latlng.lng * d,
+			this.R * Math.log((1 + sin) / (1 - sin)) / 2);
+	},
+
+	unproject: function (point) {
+		var d = 180 / Math.PI;
+
+		return new LatLng(
+			(2 * Math.atan(Math.exp(point.y / this.R)) - (Math.PI / 2)) * d,
+			point.x * d / this.R);
+	},
+
+	bounds: (function () {
+		var d = 6378137 * Math.PI;
+		return new Bounds([-d, -d], [d, d]);
+	})()
+};
+
+/*
+ * @class Transformation
+ * @aka L.Transformation
+ *
+ * Represents an affine transformation: a set of coefficients `a`, `b`, `c`, `d`
+ * for transforming a point of a form `(x, y)` into `(a*x + b, c*y + d)` and doing
+ * the reverse. Used by Leaflet in its projections code.
+ *
+ * @example
+ *
+ * ```js
+ * var transformation = L.transformation(2, 5, -1, 10),
+ * 	p = L.point(1, 2),
+ * 	p2 = transformation.transform(p), //  L.point(7, 8)
+ * 	p3 = transformation.untransform(p2); //  L.point(1, 2)
+ * ```
+ */
+
+
+// factory new L.Transformation(a: Number, b: Number, c: Number, d: Number)
+// Creates a `Transformation` object with the given coefficients.
+function Transformation(a, b, c, d) {
+	if (isArray(a)) {
+		// use array properties
+		this._a = a[0];
+		this._b = a[1];
+		this._c = a[2];
+		this._d = a[3];
+		return;
+	}
+	this._a = a;
+	this._b = b;
+	this._c = c;
+	this._d = d;
+}
+
+Transformation.prototype = {
+	// @method transform(point: Point, scale?: Number): Point
+	// Returns a transformed point, optionally multiplied by the given scale.
+	// Only accepts actual `L.Point` instances, not arrays.
+	transform: function (point, scale) { // (Point, Number) -> Point
+		return this._transform(point.clone(), scale);
+	},
+
+	// destructive transform (faster)
+	_transform: function (point, scale) {
+		scale = scale || 1;
+		point.x = scale * (this._a * point.x + this._b);
+		point.y = scale * (this._c * point.y + this._d);
+		return point;
+	},
+
+	// @method untransform(point: Point, scale?: Number): Point
+	// Returns the reverse transformation of the given point, optionally divided
+	// by the given scale. Only accepts actual `L.Point` instances, not arrays.
+	untransform: function (point, scale) {
+		scale = scale || 1;
+		return new Point(
+		        (point.x / scale - this._b) / this._a,
+		        (point.y / scale - this._d) / this._c);
+	}
+};
+
+// factory L.transformation(a: Number, b: Number, c: Number, d: Number)
+
+// @factory L.transformation(a: Number, b: Number, c: Number, d: Number)
+// Instantiates a Transformation object with the given coefficients.
+
+// @alternative
+// @factory L.transformation(coefficients: Array): Transformation
+// Expects an coefficients array of the form
+// `[a: Number, b: Number, c: Number, d: Number]`.
+
+function toTransformation(a, b, c, d) {
+	return new Transformation(a, b, c, d);
+}
+
+/*
+ * @namespace CRS
+ * @crs L.CRS.EPSG3857
+ *
+ * The most common CRS for online maps, used by almost all free and commercial
+ * tile providers. Uses Spherical Mercator projection. Set in by default in
+ * Map's `crs` option.
+ */
+
+var EPSG3857 = extend({}, Earth, {
+	code: 'EPSG:3857',
+	projection: SphericalMercator,
+
+	transformation: (function () {
+		var scale = 0.5 / (Math.PI * SphericalMercator.R);
+		return toTransformation(scale, 0.5, -scale, 0.5);
+	}())
+});
+
+var EPSG900913 = extend({}, EPSG3857, {
+	code: 'EPSG:900913'
+});
+
+// @namespace SVG; @section
+// There are several static functions which can be called without instantiating L.SVG:
+
+// @function create(name: String): SVGElement
+// Returns a instance of [SVGElement](https://developer.mozilla.org/docs/Web/API/SVGElement),
+// corresponding to the class name passed. For example, using 'line' will return
+// an instance of [SVGLineElement](https://developer.mozilla.org/docs/Web/API/SVGLineElement).
+function svgCreate(name) {
+	return document.createElementNS('http://www.w3.org/2000/svg', name);
+}
+
+// @function pointsToPath(rings: Point[], closed: Boolean): String
+// Generates a SVG path string for multiple rings, with each ring turning
+// into "M..L..L.." instructions
+function pointsToPath(rings, closed) {
+	var str = '',
+	i, j, len, len2, points, p;
+
+	for (i = 0, len = rings.length; i < len; i++) {
+		points = rings[i];
+
+		for (j = 0, len2 = points.length; j < len2; j++) {
+			p = points[j];
+			str += (j ? 'L' : 'M') + p.x + ' ' + p.y;
+		}
+
+		// closes the ring for polygons; "x" is VML syntax
+		str += closed ? (svg ? 'z' : 'x') : '';
+	}
+
+	// SVG complains about empty path strings
+	return str || 'M0 0';
+}
+
+/*
+ * @namespace Browser
+ * @aka L.Browser
+ *
+ * A namespace with static properties for browser/feature detection used by Leaflet internally.
+ *
+ * @example
+ *
+ * ```js
+ * if (L.Browser.ielt9) {
+ *   alert('Upgrade your browser, dude!');
+ * }
+ * ```
+ */
+
+var style$1 = document.documentElement.style;
+
+// @property ie: Boolean; `true` for all Internet Explorer versions (not Edge).
+var ie = 'ActiveXObject' in window;
+
+// @property ielt9: Boolean; `true` for Internet Explorer versions less than 9.
+var ielt9 = ie && !document.addEventListener;
+
+// @property edge: Boolean; `true` for the Edge web browser.
+var edge = 'msLaunchUri' in navigator && !('documentMode' in document);
+
+// @property webkit: Boolean;
+// `true` for webkit-based browsers like Chrome and Safari (including mobile versions).
+var webkit = userAgentContains('webkit');
+
+// @property android: Boolean
+// `true` for any browser running on an Android platform.
+var android = userAgentContains('android');
+
+// @property android23: Boolean; `true` for browsers running on Android 2 or Android 3.
+var android23 = userAgentContains('android 2') || userAgentContains('android 3');
+
+/* See https://stackoverflow.com/a/17961266 for details on detecting stock Android */
+var webkitVer = parseInt(/WebKit\/([0-9]+)|$/.exec(navigator.userAgent)[1], 10); // also matches AppleWebKit
+// @property androidStock: Boolean; `true` for the Android stock browser (i.e. not Chrome)
+var androidStock = android && userAgentContains('Google') && webkitVer < 537 && !('AudioNode' in window);
+
+// @property opera: Boolean; `true` for the Opera browser
+var opera = !!window.opera;
+
+// @property chrome: Boolean; `true` for the Chrome browser.
+var chrome = userAgentContains('chrome');
+
+// @property gecko: Boolean; `true` for gecko-based browsers like Firefox.
+var gecko = userAgentContains('gecko') && !webkit && !opera && !ie;
+
+// @property safari: Boolean; `true` for the Safari browser.
+var safari = !chrome && userAgentContains('safari');
+
+var phantom = userAgentContains('phantom');
+
+// @property opera12: Boolean
+// `true` for the Opera browser supporting CSS transforms (version 12 or later).
+var opera12 = 'OTransition' in style$1;
+
+// @property win: Boolean; `true` when the browser is running in a Windows platform
+var win = navigator.platform.indexOf('Win') === 0;
+
+// @property ie3d: Boolean; `true` for all Internet Explorer versions supporting CSS transforms.
+var ie3d = ie && ('transition' in style$1);
+
+// @property webkit3d: Boolean; `true` for webkit-based browsers supporting CSS transforms.
+var webkit3d = ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()) && !android23;
+
+// @property gecko3d: Boolean; `true` for gecko-based browsers supporting CSS transforms.
+var gecko3d = 'MozPerspective' in style$1;
+
+// @property any3d: Boolean
+// `true` for all browsers supporting CSS transforms.
+var any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d) && !opera12 && !phantom;
+
+// @property mobile: Boolean; `true` for all browsers running in a mobile device.
+var mobile = typeof orientation !== 'undefined' || userAgentContains('mobile');
+
+// @property mobileWebkit: Boolean; `true` for all webkit-based browsers in a mobile device.
+var mobileWebkit = mobile && webkit;
+
+// @property mobileWebkit3d: Boolean
+// `true` for all webkit-based browsers in a mobile device supporting CSS transforms.
+var mobileWebkit3d = mobile && webkit3d;
+
+// @property msPointer: Boolean
+// `true` for browsers implementing the Microsoft touch events model (notably IE10).
+var msPointer = !window.PointerEvent && window.MSPointerEvent;
+
+// @property pointer: Boolean
+// `true` for all browsers supporting [pointer events](https://msdn.microsoft.com/en-us/library/dn433244%28v=vs.85%29.aspx).
+var pointer = !!(window.PointerEvent || msPointer);
+
+// @property touch: Boolean
+// `true` for all browsers supporting [touch events](https://developer.mozilla.org/docs/Web/API/Touch_events).
+// This does not necessarily mean that the browser is running in a computer with
+// a touchscreen, it only means that the browser is capable of understanding
+// touch events.
+var touch = !window.L_NO_TOUCH && (pointer || 'ontouchstart' in window ||
+		(window.DocumentTouch && document instanceof window.DocumentTouch));
+
+// @property mobileOpera: Boolean; `true` for the Opera browser in a mobile device.
+var mobileOpera = mobile && opera;
+
+// @property mobileGecko: Boolean
+// `true` for gecko-based browsers running in a mobile device.
+var mobileGecko = mobile && gecko;
+
+// @property retina: Boolean
+// `true` for browsers on a high-resolution "retina" screen.
+var retina = (window.devicePixelRatio || (window.screen.deviceXDPI / window.screen.logicalXDPI)) > 1;
+
+
+// @property canvas: Boolean
+// `true` when the browser supports [`<canvas>`](https://developer.mozilla.org/docs/Web/API/Canvas_API).
+var canvas = (function () {
+	return !!document.createElement('canvas').getContext;
+}());
+
+// @property svg: Boolean
+// `true` when the browser supports [SVG](https://developer.mozilla.org/docs/Web/SVG).
+var svg = !!(document.createElementNS && svgCreate('svg').createSVGRect);
+
+// @property vml: Boolean
+// `true` if the browser supports [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language).
+var vml = !svg && (function () {
+	try {
+		var div = document.createElement('div');
+		div.innerHTML = '<v:shape adj="1"/>';
+
+		var shape = div.firstChild;
+		shape.style.behavior = 'url(#default#VML)';
+
+		return shape && (typeof shape.adj === 'object');
+
+	} catch (e) {
+		return false;
+	}
+}());
+
+
+function userAgentContains(str) {
+	return navigator.userAgent.toLowerCase().indexOf(str) >= 0;
+}
+
+
+var Browser = (Object.freeze || Object)({
+	ie: ie,
+	ielt9: ielt9,
+	edge: edge,
+	webkit: webkit,
+	android: android,
+	android23: android23,
+	androidStock: androidStock,
+	opera: opera,
+	chrome: chrome,
+	gecko: gecko,
+	safari: safari,
+	phantom: phantom,
+	opera12: opera12,
+	win: win,
+	ie3d: ie3d,
+	webkit3d: webkit3d,
+	gecko3d: gecko3d,
+	any3d: any3d,
+	mobile: mobile,
+	mobileWebkit: mobileWebkit,
+	mobileWebkit3d: mobileWebkit3d,
+	msPointer: msPointer,
+	pointer: pointer,
+	touch: touch,
+	mobileOpera: mobileOpera,
+	mobileGecko: mobileGecko,
+	retina: retina,
+	canvas: canvas,
+	svg: svg,
+	vml: vml
+});
+
+/*
+ * Extends L.DomEvent to provide touch support for Internet Explorer and Windows-based devices.
+ */
+
+
+var POINTER_DOWN =   msPointer ? 'MSPointerDown'   : 'pointerdown';
+var POINTER_MOVE =   msPointer ? 'MSPointerMove'   : 'pointermove';
+var POINTER_UP =     msPointer ? 'MSPointerUp'     : 'pointerup';
+var POINTER_CANCEL = msPointer ? 'MSPointerCancel' : 'pointercancel';
+var TAG_WHITE_LIST = ['INPUT', 'SELECT', 'OPTION'];
+
+var _pointers = {};
+var _pointerDocListener = false;
+
+// DomEvent.DoubleTap needs to know about this
+var _pointersCount = 0;
+
+// Provides a touch events wrapper for (ms)pointer events.
+// ref http://www.w3.org/TR/pointerevents/ https://www.w3.org/Bugs/Public/show_bug.cgi?id=22890
+
+function addPointerListener(obj, type, handler, id) {
+	if (type === 'touchstart') {
+		_addPointerStart(obj, handler, id);
+
+	} else if (type === 'touchmove') {
+		_addPointerMove(obj, handler, id);
+
+	} else if (type === 'touchend') {
+		_addPointerEnd(obj, handler, id);
+	}
+
+	return this;
+}
+
+function removePointerListener(obj, type, id) {
+	var handler = obj['_leaflet_' + type + id];
+
+	if (type === 'touchstart') {
+		obj.removeEventListener(POINTER_DOWN, handler, false);
+
+	} else if (type === 'touchmove') {
+		obj.removeEventListener(POINTER_MOVE, handler, false);
+
+	} else if (type === 'touchend') {
+		obj.removeEventListener(POINTER_UP, handler, false);
+		obj.removeEventListener(POINTER_CANCEL, handler, false);
+	}
+
+	return this;
+}
+
+function _addPointerStart(obj, handler, id) {
+	var onDown = bind(function (e) {
+		if (e.pointerType !== 'mouse' && e.MSPOINTER_TYPE_MOUSE && e.pointerType !== e.MSPOINTER_TYPE_MOUSE) {
+			// In IE11, some touch events needs to fire for form controls, or
+			// the controls will stop working. We keep a whitelist of tag names that
+			// need these events. For other target tags, we prevent default on the event.
+			if (TAG_WHITE_LIST.indexOf(e.target.tagName) < 0) {
+				preventDefault(e);
+			} else {
+				return;
+			}
+		}
+
+		_handlePointer(e, handler);
+	});
+
+	obj['_leaflet_touchstart' + id] = onDown;
+	obj.addEventListener(POINTER_DOWN, onDown, false);
+
+	// need to keep track of what pointers and how many are active to provide e.touches emulation
+	if (!_pointerDocListener) {
+		// we listen documentElement as any drags that end by moving the touch off the screen get fired there
+		document.documentElement.addEventListener(POINTER_DOWN, _globalPointerDown, true);
+		document.documentElement.addEventListener(POINTER_MOVE, _globalPointerMove, true);
+		document.documentElement.addEventListener(POINTER_UP, _globalPointerUp, true);
+		document.documentElement.addEventListener(POINTER_CANCEL, _globalPointerUp, true);
+
+		_pointerDocListener = true;
+	}
+}
+
+function _globalPointerDown(e) {
+	_pointers[e.pointerId] = e;
+	_pointersCount++;
+}
+
+function _globalPointerMove(e) {
+	if (_pointers[e.pointerId]) {
+		_pointers[e.pointerId] = e;
+	}
+}
+
+function _globalPointerUp(e) {
+	delete _pointers[e.pointerId];
+	_pointersCount--;
+}
+
+function _handlePointer(e, handler) {
+	e.touches = [];
+	for (var i in _pointers) {
+		e.touches.push(_pointers[i]);
+	}
+	e.changedTouches = [e];
+
+	handler(e);
+}
+
+function _addPointerMove(obj, handler, id) {
+	var onMove = function (e) {
+		// don't fire touch moves when mouse isn't down
+		if ((e.pointerType === e.MSPOINTER_TYPE_MOUSE || e.pointerType === 'mouse') && e.buttons === 0) { return; }
+
+		_handlePointer(e, handler);
+	};
+
+	obj['_leaflet_touchmove' + id] = onMove;
+	obj.addEventListener(POINTER_MOVE, onMove, false);
+}
+
+function _addPointerEnd(obj, handler, id) {
+	var onUp = function (e) {
+		_handlePointer(e, handler);
+	};
+
+	obj['_leaflet_touchend' + id] = onUp;
+	obj.addEventListener(POINTER_UP, onUp, false);
+	obj.addEventListener(POINTER_CANCEL, onUp, false);
+}
+
+/*
+ * Extends the event handling code with double tap support for mobile browsers.
+ */
+
+var _touchstart = msPointer ? 'MSPointerDown' : pointer ? 'pointerdown' : 'touchstart';
+var _touchend = msPointer ? 'MSPointerUp' : pointer ? 'pointerup' : 'touchend';
+var _pre = '_leaflet_';
+
+// inspired by Zepto touch code by Thomas Fuchs
+function addDoubleTapListener(obj, handler, id) {
+	var last, touch$$1,
+	    doubleTap = false,
+	    delay = 250;
+
+	function onTouchStart(e) {
+		var count;
+
+		if (pointer) {
+			if ((!edge) || e.pointerType === 'mouse') { return; }
+			count = _pointersCount;
+		} else {
+			count = e.touches.length;
+		}
+
+		if (count > 1) { return; }
+
+		var now = Date.now(),
+		    delta = now - (last || now);
+
+		touch$$1 = e.touches ? e.touches[0] : e;
+		doubleTap = (delta > 0 && delta <= delay);
+		last = now;
+	}
+
+	function onTouchEnd(e) {
+		if (doubleTap && !touch$$1.cancelBubble) {
+			if (pointer) {
+				if ((!edge) || e.pointerType === 'mouse') { return; }
+				// work around .type being readonly with MSPointer* events
+				var newTouch = {},
+				    prop, i;
+
+				for (i in touch$$1) {
+					prop = touch$$1[i];
+					newTouch[i] = prop && prop.bind ? prop.bind(touch$$1) : prop;
+				}
+				touch$$1 = newTouch;
+			}
+			touch$$1.type = 'dblclick';
+			handler(touch$$1);
+			last = null;
+		}
+	}
+
+	obj[_pre + _touchstart + id] = onTouchStart;
+	obj[_pre + _touchend + id] = onTouchEnd;
+	obj[_pre + 'dblclick' + id] = handler;
+
+	obj.addEventListener(_touchstart, onTouchStart, false);
+	obj.addEventListener(_touchend, onTouchEnd, false);
+
+	// On some platforms (notably, chrome<55 on win10 + touchscreen + mouse),
+	// the browser doesn't fire touchend/pointerup events but does fire
+	// native dblclicks. See #4127.
+	// Edge 14 also fires native dblclicks, but only for pointerType mouse, see #5180.
+	obj.addEventListener('dblclick', handler, false);
+
+	return this;
+}
+
+function removeDoubleTapListener(obj, id) {
+	var touchstart = obj[_pre + _touchstart + id],
+	    touchend = obj[_pre + _touchend + id],
+	    dblclick = obj[_pre + 'dblclick' + id];
+
+	obj.removeEventListener(_touchstart, touchstart, false);
+	obj.removeEventListener(_touchend, touchend, false);
+	if (!edge) {
+		obj.removeEventListener('dblclick', dblclick, false);
+	}
+
+	return this;
+}
+
+/*
+ * @namespace DomEvent
+ * Utility functions to work with the [DOM events](https://developer.mozilla.org/docs/Web/API/Event), used by Leaflet internally.
+ */
+
+// Inspired by John Resig, Dean Edwards and YUI addEvent implementations.
+
+// @function on(el: HTMLElement, types: String, fn: Function, context?: Object): this
+// Adds a listener function (`fn`) to a particular DOM event type of the
+// element `el`. You can optionally specify the context of the listener
+// (object the `this` keyword will point to). You can also pass several
+// space-separated types (e.g. `'click dblclick'`).
+
+// @alternative
+// @function on(el: HTMLElement, eventMap: Object, context?: Object): this
+// Adds a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}`
+function on(obj, types, fn, context) {
+
+	if (typeof types === 'object') {
+		for (var type in types) {
+			addOne(obj, type, types[type], fn);
+		}
+	} else {
+		types = splitWords(types);
+
+		for (var i = 0, len = types.length; i < len; i++) {
+			addOne(obj, types[i], fn, context);
+		}
+	}
+
+	return this;
+}
+
+var eventsKey = '_leaflet_events';
+
+// @function off(el: HTMLElement, types: String, fn: Function, context?: Object): this
+// Removes a previously added listener function.
+// Note that if you passed a custom context to on, you must pass the same
+// context to `off` in order to remove the listener.
+
+// @alternative
+// @function off(el: HTMLElement, eventMap: Object, context?: Object): this
+// Removes a set of type/listener pairs, e.g. `{click: onClick, mousemove: onMouseMove}`
+function off(obj, types, fn, context) {
+
+	if (typeof types === 'object') {
+		for (var type in types) {
+			removeOne(obj, type, types[type], fn);
+		}
+	} else if (types) {
+		types = splitWords(types);
+
+		for (var i = 0, len = types.length; i < len; i++) {
+			removeOne(obj, types[i], fn, context);
+		}
+	} else {
+		for (var j in obj[eventsKey]) {
+			removeOne(obj, j, obj[eventsKey][j]);
+		}
+		delete obj[eventsKey];
+	}
+
+	return this;
+}
+
+function addOne(obj, type, fn, context) {
+	var id = type + stamp(fn) + (context ? '_' + stamp(context) : '');
+
+	if (obj[eventsKey] && obj[eventsKey][id]) { return this; }
+
+	var handler = function (e) {
+		return fn.call(context || obj, e || window.event);
+	};
+
+	var originalHandler = handler;
+
+	if (pointer && type.indexOf('touch') === 0) {
+		// Needs DomEvent.Pointer.js
+		addPointerListener(obj, type, handler, id);
+
+	} else if (touch && (type === 'dblclick') && addDoubleTapListener &&
+	           !(pointer && chrome)) {
+		// Chrome >55 does not need the synthetic dblclicks from addDoubleTapListener
+		// See #5180
+		addDoubleTapListener(obj, handler, id);
+
+	} else if ('addEventListener' in obj) {
+
+		if (type === 'mousewheel') {
+			obj.addEventListener('onwheel' in obj ? 'wheel' : 'mousewheel', handler, false);
+
+		} else if ((type === 'mouseenter') || (type === 'mouseleave')) {
+			handler = function (e) {
+				e = e || window.event;
+				if (isExternalTarget(obj, e)) {
+					originalHandler(e);
+				}
+			};
+			obj.addEventListener(type === 'mouseenter' ? 'mouseover' : 'mouseout', handler, false);
+
+		} else {
+			if (type === 'click' && android) {
+				handler = function (e) {
+					filterClick(e, originalHandler);
+				};
+			}
+			obj.addEventListener(type, handler, false);
+		}
+
+	} else if ('attachEvent' in obj) {
+		obj.attachEvent('on' + type, handler);
+	}
+
+	obj[eventsKey] = obj[eventsKey] || {};
+	obj[eventsKey][id] = handler;
+}
+
+function removeOne(obj, type, fn, context) {
+
+	var id = type + stamp(fn) + (context ? '_' + stamp(context) : ''),
+	    handler = obj[eventsKey] && obj[eventsKey][id];
+
+	if (!handler) { return this; }
+
+	if (pointer && type.indexOf('touch') === 0) {
+		removePointerListener(obj, type, id);
+
+	} else if (touch && (type === 'dblclick') && removeDoubleTapListener &&
+	           !(pointer && chrome)) {
+		removeDoubleTapListener(obj, id);
+
+	} else if ('removeEventListener' in obj) {
+
+		if (type === 'mousewheel') {
+			obj.removeEventListener('onwheel' in obj ? 'wheel' : 'mousewheel', handler, false);
+
+		} else {
+			obj.removeEventListener(
+				type === 'mouseenter' ? 'mouseover' :
+				type === 'mouseleave' ? 'mouseout' : type, handler, false);
+		}
+
+	} else if ('detachEvent' in obj) {
+		obj.detachEvent('on' + type, handler);
+	}
+
+	obj[eventsKey][id] = null;
+}
+
+// @function stopPropagation(ev: DOMEvent): this
+// Stop the given event from propagation to parent elements. Used inside the listener functions:
+// ```js
+// L.DomEvent.on(div, 'click', function (ev) {
+// 	L.DomEvent.stopPropagation(ev);
+// });
+// ```
+function stopPropagation(e) {
+
+	if (e.stopPropagation) {
+		e.stopPropagation();
+	} else if (e.originalEvent) {  // In case of Leaflet event.
+		e.originalEvent._stopped = true;
+	} else {
+		e.cancelBubble = true;
+	}
+	skipped(e);
+
+	return this;
+}
+
+// @function disableScrollPropagation(el: HTMLElement): this
+// Adds `stopPropagation` to the element's `'mousewheel'` events (plus browser variants).
+function disableScrollPropagation(el) {
+	addOne(el, 'mousewheel', stopPropagation);
+	return this;
+}
+
+// @function disableClickPropagation(el: HTMLElement): this
+// Adds `stopPropagation` to the element's `'click'`, `'doubleclick'`,
+// `'mousedown'` and `'touchstart'` events (plus browser variants).
+function disableClickPropagation(el) {
+	on(el, 'mousedown touchstart dblclick', stopPropagation);
+	addOne(el, 'click', fakeStop);
+	return this;
+}
+
+// @function preventDefault(ev: DOMEvent): this
+// Prevents the default action of the DOM Event `ev` from happening (such as
+// following a link in the href of the a element, or doing a POST request
+// with page reload when a `<form>` is submitted).
+// Use it inside listener functions.
+function preventDefault(e) {
+	if (e.preventDefault) {
+		e.preventDefault();
+	} else {
+		e.returnValue = false;
+	}
+	return this;
+}
+
+// @function stop(ev: DOMEvent): this
+// Does `stopPropagation` and `preventDefault` at the same time.
+function stop(e) {
+	preventDefault(e);
+	stopPropagation(e);
+	return this;
+}
+
+// @function getMousePosition(ev: DOMEvent, container?: HTMLElement): Point
+// Gets normalized mouse position from a DOM event relative to the
+// `container` or to the whole page if not specified.
+function getMousePosition(e, container) {
+	if (!container) {
+		return new Point(e.clientX, e.clientY);
+	}
+
+	var rect = container.getBoundingClientRect();
+
+	var scaleX = rect.width / container.offsetWidth || 1;
+	var scaleY = rect.height / container.offsetHeight || 1;
+	return new Point(
+		e.clientX / scaleX - rect.left - container.clientLeft,
+		e.clientY / scaleY - rect.top - container.clientTop);
+}
+
+// Chrome on Win scrolls double the pixels as in other platforms (see #4538),
+// and Firefox scrolls device pixels, not CSS pixels
+var wheelPxFactor =
+	(win && chrome) ? 2 * window.devicePixelRatio :
+	gecko ? window.devicePixelRatio : 1;
+
+// @function getWheelDelta(ev: DOMEvent): Number
+// Gets normalized wheel delta from a mousewheel DOM event, in vertical
+// pixels scrolled (negative if scrolling down).
+// Events from pointing devices without precise scrolling are mapped to
+// a best guess of 60 pixels.
+function getWheelDelta(e) {
+	return (edge) ? e.wheelDeltaY / 2 : // Don't trust window-geometry-based delta
+	       (e.deltaY && e.deltaMode === 0) ? -e.deltaY / wheelPxFactor : // Pixels
+	       (e.deltaY && e.deltaMode === 1) ? -e.deltaY * 20 : // Lines
+	       (e.deltaY && e.deltaMode === 2) ? -e.deltaY * 60 : // Pages
+	       (e.deltaX || e.deltaZ) ? 0 :	// Skip horizontal/depth wheel events
+	       e.wheelDelta ? (e.wheelDeltaY || e.wheelDelta) / 2 : // Legacy IE pixels
+	       (e.detail && Math.abs(e.detail) < 32765) ? -e.detail * 20 : // Legacy Moz lines
+	       e.detail ? e.detail / -32765 * 60 : // Legacy Moz pages
+	       0;
+}
+
+var skipEvents = {};
+
+function fakeStop(e) {
+	// fakes stopPropagation by setting a special event flag, checked/reset with skipped(e)
+	skipEvents[e.type] = true;
+}
+
+function skipped(e) {
+	var events = skipEvents[e.type];
+	// reset when checking, as it's only used in map container and propagates outside of the map
+	skipEvents[e.type] = false;
+	return events;
+}
+
+// check if element really left/entered the event target (for mouseenter/mouseleave)
+function isExternalTarget(el, e) {
+
+	var related = e.relatedTarget;
+
+	if (!related) { return true; }
+
+	try {
+		while (related && (related !== el)) {
+			related = related.parentNode;
+		}
+	} catch (err) {
+		return false;
+	}
+	return (related !== el);
+}
+
+var lastClick;
+
+// this is a horrible workaround for a bug in Android where a single touch triggers two click events
+function filterClick(e, handler) {
+	var timeStamp = (e.timeStamp || (e.originalEvent && e.originalEvent.timeStamp)),
+	    elapsed = lastClick && (timeStamp - lastClick);
+
+	// are they closer together than 500ms yet more than 100ms?
+	// Android typically triggers them ~300ms apart while multiple listeners
+	// on the same event should be triggered far faster;
+	// or check if click is simulated on the element, and if it is, reject any non-simulated events
+
+	if ((elapsed && elapsed > 100 && elapsed < 500) || (e.target._simulatedClick && !e._simulated)) {
+		stop(e);
+		return;
+	}
+	lastClick = timeStamp;
+
+	handler(e);
+}
+
+
+
+
+var DomEvent = (Object.freeze || Object)({
+	on: on,
+	off: off,
+	stopPropagation: stopPropagation,
+	disableScrollPropagation: disableScrollPropagation,
+	disableClickPropagation: disableClickPropagation,
+	preventDefault: preventDefault,
+	stop: stop,
+	getMousePosition: getMousePosition,
+	getWheelDelta: getWheelDelta,
+	fakeStop: fakeStop,
+	skipped: skipped,
+	isExternalTarget: isExternalTarget,
+	addListener: on,
+	removeListener: off
+});
+
+/*
+ * @namespace DomUtil
+ *
+ * Utility functions to work with the [DOM](https://developer.mozilla.org/docs/Web/API/Document_Object_Model)
+ * tree, used by Leaflet internally.
+ *
+ * Most functions expecting or returning a `HTMLElement` also work for
+ * SVG elements. The only difference is that classes refer to CSS classes
+ * in HTML and SVG classes in SVG.
+ */
+
+
+// @property TRANSFORM: String
+// Vendor-prefixed transform style name (e.g. `'webkitTransform'` for WebKit).
+var TRANSFORM = testProp(
+	['transform', 'WebkitTransform', 'OTransform', 'MozTransform', 'msTransform']);
+
+// webkitTransition comes first because some browser versions that drop vendor prefix don't do
+// the same for the transitionend event, in particular the Android 4.1 stock browser
+
+// @property TRANSITION: String
+// Vendor-prefixed transition style name.
+var TRANSITION = testProp(
+	['webkitTransition', 'transition', 'OTransition', 'MozTransition', 'msTransition']);
+
+// @property TRANSITION_END: String
+// Vendor-prefixed transitionend event name.
+var TRANSITION_END =
+	TRANSITION === 'webkitTransition' || TRANSITION === 'OTransition' ? TRANSITION + 'End' : 'transitionend';
+
+
+// @function get(id: String|HTMLElement): HTMLElement
+// Returns an element given its DOM id, or returns the element itself
+// if it was passed directly.
+function get(id) {
+	return typeof id === 'string' ? document.getElementById(id) : id;
+}
+
+// @function getStyle(el: HTMLElement, styleAttrib: String): String
+// Returns the value for a certain style attribute on an element,
+// including computed values or values set through CSS.
+function getStyle(el, style) {
+	var value = el.style[style] || (el.currentStyle && el.currentStyle[style]);
+
+	if ((!value || value === 'auto') && document.defaultView) {
+		var css = document.defaultView.getComputedStyle(el, null);
+		value = css ? css[style] : null;
+	}
+	return value === 'auto' ? null : value;
+}
+
+// @function create(tagName: String, className?: String, container?: HTMLElement): HTMLElement
+// Creates an HTML element with `tagName`, sets its class to `className`, and optionally appends it to `container` element.
+function create$1(tagName, className, container) {
+	var el = document.createElement(tagName);
+	el.className = className || '';
+
+	if (container) {
+		container.appendChild(el);
+	}
+	return el;
+}
+
+// @function remove(el: HTMLElement)
+// Removes `el` from its parent element
+function remove(el) {
+	var parent = el.parentNode;
+	if (parent) {
+		parent.removeChild(el);
+	}
+}
+
+// @function empty(el: HTMLElement)
+// Removes all of `el`'s children elements from `el`
+function empty(el) {
+	while (el.firstChild) {
+		el.removeChild(el.firstChild);
+	}
+}
+
+// @function toFront(el: HTMLElement)
+// Makes `el` the last child of its parent, so it renders in front of the other children.
+function toFront(el) {
+	var parent = el.parentNode;
+	if (parent.lastChild !== el) {
+		parent.appendChild(el);
+	}
+}
+
+// @function toBack(el: HTMLElement)
+// Makes `el` the first child of its parent, so it renders behind the other children.
+function toBack(el) {
+	var parent = el.parentNode;
+	if (parent.firstChild !== el) {
+		parent.insertBefore(el, parent.firstChild);
+	}
+}
+
+// @function hasClass(el: HTMLElement, name: String): Boolean
+// Returns `true` if the element's class attribute contains `name`.
+function hasClass(el, name) {
+	if (el.classList !== undefined) {
+		return el.classList.contains(name);
+	}
+	var className = getClass(el);
+	return className.length > 0 && new RegExp('(^|\\s)' + name + '(\\s|$)').test(className);
+}
+
+// @function addClass(el: HTMLElement, name: String)
+// Adds `name` to the element's class attribute.
+function addClass(el, name) {
+	if (el.classList !== undefined) {
+		var classes = splitWords(name);
+		for (var i = 0, len = classes.length; i < len; i++) {
+			el.classList.add(classes[i]);
+		}
+	} else if (!hasClass(el, name)) {
+		var className = getClass(el);
+		setClass(el, (className ? className + ' ' : '') + name);
+	}
+}
+
+// @function removeClass(el: HTMLElement, name: String)
+// Removes `name` from the element's class attribute.
+function removeClass(el, name) {
+	if (el.classList !== undefined) {
+		el.classList.remove(name);
+	} else {
+		setClass(el, trim((' ' + getClass(el) + ' ').replace(' ' + name + ' ', ' ')));
+	}
+}
+
+// @function setClass(el: HTMLElement, name: String)
+// Sets the element's class.
+function setClass(el, name) {
+	if (el.className.baseVal === undefined) {
+		el.className = name;
+	} else {
+		// in case of SVG element
+		el.className.baseVal = name;
+	}
+}
+
+// @function getClass(el: HTMLElement): String
+// Returns the element's class.
+function getClass(el) {
+	return el.className.baseVal === undefined ? el.className : el.className.baseVal;
+}
+
+// @function setOpacity(el: HTMLElement, opacity: Number)
+// Set the opacity of an element (including old IE support).
+// `opacity` must be a number from `0` to `1`.
+function setOpacity(el, value) {
+	if ('opacity' in el.style) {
+		el.style.opacity = value;
+	} else if ('filter' in el.style) {
+		_setOpacityIE(el, value);
+	}
+}
+
+function _setOpacityIE(el, value) {
+	var filter = false,
+	    filterName = 'DXImageTransform.Microsoft.Alpha';
+
+	// filters collection throws an error if we try to retrieve a filter that doesn't exist
+	try {
+		filter = el.filters.item(filterName);
+	} catch (e) {
+		// don't set opacity to 1 if we haven't already set an opacity,
+		// it isn't needed and breaks transparent pngs.
+		if (value === 1) { return; }
+	}
+
+	value = Math.round(value * 100);
+
+	if (filter) {
+		filter.Enabled = (value !== 100);
+		filter.Opacity = value;
+	} else {
+		el.style.filter += ' progid:' + filterName + '(opacity=' + value + ')';
+	}
+}
+
+// @function testProp(props: String[]): String|false
+// Goes through the array of style names and returns the first name
+// that is a valid style name for an element. If no such name is found,
+// it returns false. Useful for vendor-prefixed styles like `transform`.
+function testProp(props) {
+	var style = document.documentElement.style;
+
+	for (var i = 0; i < props.length; i++) {
+		if (props[i] in style) {
+			return props[i];
+		}
+	}
+	return false;
+}
+
+// @function setTransform(el: HTMLElement, offset: Point, scale?: Number)
+// Resets the 3D CSS transform of `el` so it is translated by `offset` pixels
+// and optionally scaled by `scale`. Does not have an effect if the
+// browser doesn't support 3D CSS transforms.
+function setTransform(el, offset, scale) {
+	var pos = offset || new Point(0, 0);
+
+	el.style[TRANSFORM] =
+		(ie3d ?
+			'translate(' + pos.x + 'px,' + pos.y + 'px)' :
+			'translate3d(' + pos.x + 'px,' + pos.y + 'px,0)') +
+		(scale ? ' scale(' + scale + ')' : '');
+}
+
+// @function setPosition(el: HTMLElement, position: Point)
+// Sets the position of `el` to coordinates specified by `position`,
+// using CSS translate or top/left positioning depending on the browser
+// (used by Leaflet internally to position its layers).
+function setPosition(el, point) {
+
+	/*eslint-disable */
+	el._leaflet_pos = point;
+	/* eslint-enable */
+
+	if (any3d) {
+		setTransform(el, point);
+	} else {
+		el.style.left = point.x + 'px';
+		el.style.top = point.y + 'px';
+	}
+}
+
+// @function getPosition(el: HTMLElement): Point
+// Returns the coordinates of an element previously positioned with setPosition.
+function getPosition(el) {
+	// this method is only used for elements previously positioned using setPosition,
+	// so it's safe to cache the position for performance
+
+	return el._leaflet_pos || new Point(0, 0);
+}
+
+// @function disableTextSelection()
+// Prevents the user from generating `selectstart` DOM events, usually generated
+// when the user drags the mouse through a page with text. Used internally
+// by Leaflet to override the behaviour of any click-and-drag interaction on
+// the map. Affects drag interactions on the whole document.
+
+// @function enableTextSelection()
+// Cancels the effects of a previous [`L.DomUtil.disableTextSelection`](#domutil-disabletextselection).
+var disableTextSelection;
+var enableTextSelection;
+var _userSelect;
+if ('onselectstart' in document) {
+	disableTextSelection = function () {
+		on(window, 'selectstart', preventDefault);
+	};
+	enableTextSelection = function () {
+		off(window, 'selectstart', preventDefault);
+	};
+} else {
+	var userSelectProperty = testProp(
+		['userSelect', 'WebkitUserSelect', 'OUserSelect', 'MozUserSelect', 'msUserSelect']);
+
+	disableTextSelection = function () {
+		if (userSelectProperty) {
+			var style = document.documentElement.style;
+			_userSelect = style[userSelectProperty];
+			style[userSelectProperty] = 'none';
+		}
+	};
+	enableTextSelection = function () {
+		if (userSelectProperty) {
+			document.documentElement.style[userSelectProperty] = _userSelect;
+			_userSelect = undefined;
+		}
+	};
+}
+
+// @function disableImageDrag()
+// As [`L.DomUtil.disableTextSelection`](#domutil-disabletextselection), but
+// for `dragstart` DOM events, usually generated when the user drags an image.
+function disableImageDrag() {
+	on(window, 'dragstart', preventDefault);
+}
+
+// @function enableImageDrag()
+// Cancels the effects of a previous [`L.DomUtil.disableImageDrag`](#domutil-disabletextselection).
+function enableImageDrag() {
+	off(window, 'dragstart', preventDefault);
+}
+
+var _outlineElement;
+var _outlineStyle;
+// @function preventOutline(el: HTMLElement)
+// Makes the [outline](https://developer.mozilla.org/docs/Web/CSS/outline)
+// of the element `el` invisible. Used internally by Leaflet to prevent
+// focusable elements from displaying an outline when the user performs a
+// drag interaction on them.
+function preventOutline(element) {
+	while (element.tabIndex === -1) {
+		element = element.parentNode;
+	}
+	if (!element.style) { return; }
+	restoreOutline();
+	_outlineElement = element;
+	_outlineStyle = element.style.outline;
+	element.style.outline = 'none';
+	on(window, 'keydown', restoreOutline);
+}
+
+// @function restoreOutline()
+// Cancels the effects of a previous [`L.DomUtil.preventOutline`]().
+function restoreOutline() {
+	if (!_outlineElement) { return; }
+	_outlineElement.style.outline = _outlineStyle;
+	_outlineElement = undefined;
+	_outlineStyle = undefined;
+	off(window, 'keydown', restoreOutline);
+}
+
+
+var DomUtil = (Object.freeze || Object)({
+	TRANSFORM: TRANSFORM,
+	TRANSITION: TRANSITION,
+	TRANSITION_END: TRANSITION_END,
+	get: get,
+	getStyle: getStyle,
+	create: create$1,
+	remove: remove,
+	empty: empty,
+	toFront: toFront,
+	toBack: toBack,
+	hasClass: hasClass,
+	addClass: addClass,
+	removeClass: removeClass,
+	setClass: setClass,
+	getClass: getClass,
+	setOpacity: setOpacity,
+	testProp: testProp,
+	setTransform: setTransform,
+	setPosition: setPosition,
+	getPosition: getPosition,
+	disableTextSelection: disableTextSelection,
+	enableTextSelection: enableTextSelection,
+	disableImageDrag: disableImageDrag,
+	enableImageDrag: enableImageDrag,
+	preventOutline: preventOutline,
+	restoreOutline: restoreOutline
+});
+
+/*
+ * @class PosAnimation
+ * @aka L.PosAnimation
+ * @inherits Evented
+ * Used internally for panning animations, utilizing CSS3 Transitions for modern browsers and a timer fallback for IE6-9.
+ *
+ * @example
+ * ```js
+ * var fx = new L.PosAnimation();
+ * fx.run(el, [300, 500], 0.5);
+ * ```
+ *
+ * @constructor L.PosAnimation()
+ * Creates a `PosAnimation` object.
+ *
+ */
+
+var PosAnimation = Evented.extend({
+
+	// @method run(el: HTMLElement, newPos: Point, duration?: Number, easeLinearity?: Number)
+	// Run an animation of a given element to a new position, optionally setting
+	// duration in seconds (`0.25` by default) and easing linearity factor (3rd
+	// argument of the [cubic bezier curve](http://cubic-bezier.com/#0,0,.5,1),
+	// `0.5` by default).
+	run: function (el, newPos, duration, easeLinearity) {
+		this.stop();
+
+		this._el = el;
+		this._inProgress = true;
+		this._duration = duration || 0.25;
+		this._easeOutPower = 1 / Math.max(easeLinearity || 0.5, 0.2);
+
+		this._startPos = getPosition(el);
+		this._offset = newPos.subtract(this._startPos);
+		this._startTime = +new Date();
+
+		// @event start: Event
+		// Fired when the animation starts
+		this.fire('start');
+
+		this._animate();
+	},
+
+	// @method stop()
+	// Stops the animation (if currently running).
+	stop: function () {
+		if (!this._inProgress) { return; }
+
+		this._step(true);
+		this._complete();
+	},
+
+	_animate: function () {
+		// animation loop
+		this._animId = requestAnimFrame(this._animate, this);
+		this._step();
+	},
+
+	_step: function (round) {
+		var elapsed = (+new Date()) - this._startTime,
+		    duration = this._duration * 1000;
+
+		if (elapsed < duration) {
+			this._runFrame(this._easeOut(elapsed / duration), round);
+		} else {
+			this._runFrame(1);
+			this._complete();
+		}
+	},
+
+	_runFrame: function (progress, round) {
+		var pos = this._startPos.add(this._offset.multiplyBy(progress));
+		if (round) {
+			pos._round();
+		}
+		setPosition(this._el, pos);
+
+		// @event step: Event
+		// Fired continuously during the animation.
+		this.fire('step');
+	},
+
+	_complete: function () {
+		cancelAnimFrame(this._animId);
+
+		this._inProgress = false;
+		// @event end: Event
+		// Fired when the animation ends.
+		this.fire('end');
+	},
+
+	_easeOut: function (t) {
+		return 1 - Math.pow(1 - t, this._easeOutPower);
+	}
+});
+
+/*
+ * @class Map
+ * @aka L.Map
+ * @inherits Evented
+ *
+ * The central class of the API — it is used to create a map on a page and manipulate it.
+ *
+ * @example
+ *
+ * ```js
+ * // initialize the map on the "map" div with a given center and zoom
+ * var map = L.map('map', {
+ * 	center: [51.505, -0.09],
+ * 	zoom: 13
+ * });
+ * ```
+ *
+ */
+
+var Map = Evented.extend({
+
+	options: {
+		// @section Map State Options
+		// @option crs: CRS = L.CRS.EPSG3857
+		// The [Coordinate Reference System](#crs) to use. Don't change this if you're not
+		// sure what it means.
+		crs: EPSG3857,
+
+		// @option center: LatLng = undefined
+		// Initial geographic center of the map
+		center: undefined,
+
+		// @option zoom: Number = undefined
+		// Initial map zoom level
+		zoom: undefined,
+
+		// @option minZoom: Number = *
+		// Minimum zoom level of the map.
+		// If not specified and at least one `GridLayer` or `TileLayer` is in the map,
+		// the lowest of their `minZoom` options will be used instead.
+		minZoom: undefined,
+
+		// @option maxZoom: Number = *
+		// Maximum zoom level of the map.
+		// If not specified and at least one `GridLayer` or `TileLayer` is in the map,
+		// the highest of their `maxZoom` options will be used instead.
+		maxZoom: undefined,
+
+		// @option layers: Layer[] = []
+		// Array of layers that will be added to the map initially
+		layers: [],
+
+		// @option maxBounds: LatLngBounds = null
+		// When this option is set, the map restricts the view to the given
+		// geographical bounds, bouncing the user back if the user tries to pan
+		// outside the view. To set the restriction dynamically, use
+		// [`setMaxBounds`](#map-setmaxbounds) method.
+		maxBounds: undefined,
+
+		// @option renderer: Renderer = *
+		// The default method for drawing vector layers on the map. `L.SVG`
+		// or `L.Canvas` by default depending on browser support.
+		renderer: undefined,
+
+
+		// @section Animation Options
+		// @option zoomAnimation: Boolean = true
+		// Whether the map zoom animation is enabled. By default it's enabled
+		// in all browsers that support CSS3 Transitions except Android.
+		zoomAnimation: true,
+
+		// @option zoomAnimationThreshold: Number = 4
+		// Won't animate zoom if the zoom difference exceeds this value.
+		zoomAnimationThreshold: 4,
+
+		// @option fadeAnimation: Boolean = true
+		// Whether the tile fade animation is enabled. By default it's enabled
+		// in all browsers that support CSS3 Transitions except Android.
+		fadeAnimation: true,
+
+		// @option markerZoomAnimation: Boolean = true
+		// Whether markers animate their zoom with the zoom animation, if disabled
+		// they will disappear for the length of the animation. By default it's
+		// enabled in all browsers that support CSS3 Transitions except Android.
+		markerZoomAnimation: true,
+
+		// @option transform3DLimit: Number = 2^23
+		// Defines the maximum size of a CSS translation transform. The default
+		// value should not be changed unless a web browser positions layers in
+		// the wrong place after doing a large `panBy`.
+		transform3DLimit: 8388608, // Precision limit of a 32-bit float
+
+		// @section Interaction Options
+		// @option zoomSnap: Number = 1
+		// Forces the map's zoom level to always be a multiple of this, particularly
+		// right after a [`fitBounds()`](#map-fitbounds) or a pinch-zoom.
+		// By default, the zoom level snaps to the nearest integer; lower values
+		// (e.g. `0.5` or `0.1`) allow for greater granularity. A value of `0`
+		// means the zoom level will not be snapped after `fitBounds` or a pinch-zoom.
+		zoomSnap: 1,
+
+		// @option zoomDelta: Number = 1
+		// Controls how much the map's zoom level will change after a
+		// [`zoomIn()`](#map-zoomin), [`zoomOut()`](#map-zoomout), pressing `+`
+		// or `-` on the keyboard, or using the [zoom controls](#control-zoom).
+		// Values smaller than `1` (e.g. `0.5`) allow for greater granularity.
+		zoomDelta: 1,
+
+		// @option trackResize: Boolean = true
+		// Whether the map automatically handles browser window resize to update itself.
+		trackResize: true
+	},
+
+	initialize: function (id, options) { // (HTMLElement or String, Object)
+		options = setOptions(this, options);
+
+		this._initContainer(id);
+		this._initLayout();
+
+		// hack for https://github.com/Leaflet/Leaflet/issues/1980
+		this._onResize = bind(this._onResize, this);
+
+		this._initEvents();
+
+		if (options.maxBounds) {
+			this.setMaxBounds(options.maxBounds);
+		}
+
+		if (options.zoom !== undefined) {
+			this._zoom = this._limitZoom(options.zoom);
+		}
+
+		if (options.center && options.zoom !== undefined) {
+			this.setView(toLatLng(options.center), options.zoom, {reset: true});
+		}
+
+		this._handlers = [];
+		this._layers = {};
+		this._zoomBoundLayers = {};
+		this._sizeChanged = true;
+
+		this.callInitHooks();
+
+		// don't animate on browsers without hardware-accelerated transitions or old Android/Opera
+		this._zoomAnimated = TRANSITION && any3d && !mobileOpera &&
+				this.options.zoomAnimation;
+
+		// zoom transitions run with the same duration for all layers, so if one of transitionend events
+		// happens after starting zoom animation (propagating to the map pane), we know that it ended globally
+		if (this._zoomAnimated) {
+			this._createAnimProxy();
+			on(this._proxy, TRANSITION_END, this._catchTransitionEnd, this);
+		}
+
+		this._addLayers(this.options.layers);
+	},
+
+
+	// @section Methods for modifying map state
+
+	// @method setView(center: LatLng, zoom: Number, options?: Zoom/pan options): this
+	// Sets the view of the map (geographical center and zoom) with the given
+	// animation options.
+	setView: function (center, zoom, options) {
+
+		zoom = zoom === undefined ? this._zoom : this._limitZoom(zoom);
+		center = this._limitCenter(toLatLng(center), zoom, this.options.maxBounds);
+		options = options || {};
+
+		this._stop();
+
+		if (this._loaded && !options.reset && options !== true) {
+
+			if (options.animate !== undefined) {
+				options.zoom = extend({animate: options.animate}, options.zoom);
+				options.pan = extend({animate: options.animate, duration: options.duration}, options.pan);
+			}
+
+			// try animating pan or zoom
+			var moved = (this._zoom !== zoom) ?
+				this._tryAnimatedZoom && this._tryAnimatedZoom(center, zoom, options.zoom) :
+				this._tryAnimatedPan(center, options.pan);
+
+			if (moved) {
+				// prevent resize handler call, the view will refresh after animation anyway
+				clearTimeout(this._sizeTimer);
+				return this;
+			}
+		}
+
+		// animation didn't start, just reset the map view
+		this._resetView(center, zoom);
+
+		return this;
+	},
+
+	// @method setZoom(zoom: Number, options?: Zoom/pan options): this
+	// Sets the zoom of the map.
+	setZoom: function (zoom, options) {
+		if (!this._loaded) {
+			this._zoom = zoom;
+			return this;
+		}
+		return this.setView(this.getCenter(), zoom, {zoom: options});
+	},
+
+	// @method zoomIn(delta?: Number, options?: Zoom options): this
+	// Increases the zoom of the map by `delta` ([`zoomDelta`](#map-zoomdelta) by default).
+	zoomIn: function (delta, options) {
+		delta = delta || (any3d ? this.options.zoomDelta : 1);
+		return this.setZoom(this._zoom + delta, options);
+	},
+
+	// @method zoomOut(delta?: Number, options?: Zoom options): this
+	// Decreases the zoom of the map by `delta` ([`zoomDelta`](#map-zoomdelta) by default).
+	zoomOut: function (delta, options) {
+		delta = delta || (any3d ? this.options.zoomDelta : 1);
+		return this.setZoom(this._zoom - delta, options);
+	},
+
+	// @method setZoomAround(latlng: LatLng, zoom: Number, options: Zoom options): this
+	// Zooms the map while keeping a specified geographical point on the map
+	// stationary (e.g. used internally for scroll zoom and double-click zoom).
+	// @alternative
+	// @method setZoomAround(offset: Point, zoom: Number, options: Zoom options): this
+	// Zooms the map while keeping a specified pixel on the map (relative to the top-left corner) stationary.
+	setZoomAround: function (latlng, zoom, options) {
+		var scale = this.getZoomScale(zoom),
+		    viewHalf = this.getSize().divideBy(2),
+		    containerPoint = latlng instanceof Point ? latlng : this.latLngToContainerPoint(latlng),
+
+		    centerOffset = containerPoint.subtract(viewHalf).multiplyBy(1 - 1 / scale),
+		    newCenter = this.containerPointToLatLng(viewHalf.add(centerOffset));
+
+		return this.setView(newCenter, zoom, {zoom: options});
+	},
+
+	_getBoundsCenterZoom: function (bounds, options) {
+
+		options = options || {};
+		bounds = bounds.getBounds ? bounds.getBounds() : toLatLngBounds(bounds);
+
+		var paddingTL = toPoint(options.paddingTopLeft || options.padding || [0, 0]),
+		    paddingBR = toPoint(options.paddingBottomRight || options.padding || [0, 0]),
+
+		    zoom = this.getBoundsZoom(bounds, false, paddingTL.add(paddingBR));
+
+		zoom = (typeof options.maxZoom === 'number') ? Math.min(options.maxZoom, zoom) : zoom;
+
+		if (zoom === Infinity) {
+			return {
+				center: bounds.getCenter(),
+				zoom: zoom
+			};
+		}
+
+		var paddingOffset = paddingBR.subtract(paddingTL).divideBy(2),
+
+		    swPoint = this.project(bounds.getSouthWest(), zoom),
+		    nePoint = this.project(bounds.getNorthEast(), zoom),
+		    center = this.unproject(swPoint.add(nePoint).divideBy(2).add(paddingOffset), zoom);
+
+		return {
+			center: center,
+			zoom: zoom
+		};
+	},
+
+	// @method fitBounds(bounds: LatLngBounds, options?: fitBounds options): this
+	// Sets a map view that contains the given geographical bounds with the
+	// maximum zoom level possible.
+	fitBounds: function (bounds, options) {
+
+		bounds = toLatLngBounds(bounds);
+
+		if (!bounds.isValid()) {
+			throw new Error('Bounds are not valid.');
+		}
+
+		var target = this._getBoundsCenterZoom(bounds, options);
+		return this.setView(target.center, target.zoom, options);
+	},
+
+	// @method fitWorld(options?: fitBounds options): this
+	// Sets a map view that mostly contains the whole world with the maximum
+	// zoom level possible.
+	fitWorld: function (options) {
+		return this.fitBounds([[-90, -180], [90, 180]], options);
+	},
+
+	// @method panTo(latlng: LatLng, options?: Pan options): this
+	// Pans the map to a given center.
+	panTo: function (center, options) { // (LatLng)
+		return this.setView(center, this._zoom, {pan: options});
+	},
+
+	// @method panBy(offset: Point, options?: Pan options): this
+	// Pans the map by a given number of pixels (animated).
+	panBy: function (offset, options) {
+		offset = toPoint(offset).round();
+		options = options || {};
+
+		if (!offset.x && !offset.y) {
+			return this.fire('moveend');
+		}
+		// If we pan too far, Chrome gets issues with tiles
+		// and makes them disappear or appear in the wrong place (slightly offset) #2602
+		if (options.animate !== true && !this.getSize().contains(offset)) {
+			this._resetView(this.unproject(this.project(this.getCenter()).add(offset)), this.getZoom());
+			return this;
+		}
+
+		if (!this._panAnim) {
+			this._panAnim = new PosAnimation();
+
+			this._panAnim.on({
+				'step': this._onPanTransitionStep,
+				'end': this._onPanTransitionEnd
+			}, this);
+		}
+
+		// don't fire movestart if animating inertia
+		if (!options.noMoveStart) {
+			this.fire('movestart');
+		}
+
+		// animate pan unless animate: false specified
+		if (options.animate !== false) {
+			addClass(this._mapPane, 'leaflet-pan-anim');
+
+			var newPos = this._getMapPanePos().subtract(offset).round();
+			this._panAnim.run(this._mapPane, newPos, options.duration || 0.25, options.easeLinearity);
+		} else {
+			this._rawPanBy(offset);
+			this.fire('move').fire('moveend');
+		}
+
+		return this;
+	},
+
+	// @method flyTo(latlng: LatLng, zoom?: Number, options?: Zoom/pan options): this
+	// Sets the view of the map (geographical center and zoom) performing a smooth
+	// pan-zoom animation.
+	flyTo: function (targetCenter, targetZoom, options) {
+
+		options = options || {};
+		if (options.animate === false || !any3d) {
+			return this.setView(targetCenter, targetZoom, options);
+		}
+
+		this._stop();
+
+		var from = this.project(this.getCenter()),
+		    to = this.project(targetCenter),
+		    size = this.getSize(),
+		    startZoom = this._zoom;
+
+		targetCenter = toLatLng(targetCenter);
+		targetZoom = targetZoom === undefined ? startZoom : targetZoom;
+
+		var w0 = Math.max(size.x, size.y),
+		    w1 = w0 * this.getZoomScale(startZoom, targetZoom),
+		    u1 = (to.distanceTo(from)) || 1,
+		    rho = 1.42,
+		    rho2 = rho * rho;
+
+		function r(i) {
+			var s1 = i ? -1 : 1,
+			    s2 = i ? w1 : w0,
+			    t1 = w1 * w1 - w0 * w0 + s1 * rho2 * rho2 * u1 * u1,
+			    b1 = 2 * s2 * rho2 * u1,
+			    b = t1 / b1,
+			    sq = Math.sqrt(b * b + 1) - b;
+
+			    // workaround for floating point precision bug when sq = 0, log = -Infinite,
+			    // thus triggering an infinite loop in flyTo
+			    var log = sq < 0.000000001 ? -18 : Math.log(sq);
+
+			return log;
+		}
+
+		function sinh(n) { return (Math.exp(n) - Math.exp(-n)) / 2; }
+		function cosh(n) { return (Math.exp(n) + Math.exp(-n)) / 2; }
+		function tanh(n) { return sinh(n) / cosh(n); }
+
+		var r0 = r(0);
+
+		function w(s) { return w0 * (cosh(r0) / cosh(r0 + rho * s)); }
+		function u(s) { return w0 * (cosh(r0) * tanh(r0 + rho * s) - sinh(r0)) / rho2; }
+
+		function easeOut(t) { return 1 - Math.pow(1 - t, 1.5); }
+
+		var start = Date.now(),
+		    S = (r(1) - r0) / rho,
+		    duration = options.duration ? 1000 * options.duration : 1000 * S * 0.8;
+
+		function frame() {
+			var t = (Date.now() - start) / duration,
+			    s = easeOut(t) * S;
+
+			if (t <= 1) {
+				this._flyToFrame = requestAnimFrame(frame, this);
+
+				this._move(
+					this.unproject(from.add(to.subtract(from).multiplyBy(u(s) / u1)), startZoom),
+					this.getScaleZoom(w0 / w(s), startZoom),
+					{flyTo: true});
+
+			} else {
+				this
+					._move(targetCenter, targetZoom)
+					._moveEnd(true);
+			}
+		}
+
+		this._moveStart(true, options.noMoveStart);
+
+		frame.call(this);
+		return this;
+	},
+
+	// @method flyToBounds(bounds: LatLngBounds, options?: fitBounds options): this
+	// Sets the view of the map with a smooth animation like [`flyTo`](#map-flyto),
+	// but takes a bounds parameter like [`fitBounds`](#map-fitbounds).
+	flyToBounds: function (bounds, options) {
+		var target = this._getBoundsCenterZoom(bounds, options);
+		return this.flyTo(target.center, target.zoom, options);
+	},
+
+	// @method setMaxBounds(bounds: Bounds): this
+	// Restricts the map view to the given bounds (see the [maxBounds](#map-maxbounds) option).
+	setMaxBounds: function (bounds) {
+		bounds = toLatLngBounds(bounds);
+
+		if (!bounds.isValid()) {
+			this.options.maxBounds = null;
+			return this.off('moveend', this._panInsideMaxBounds);
+		} else if (this.options.maxBounds) {
+			this.off('moveend', this._panInsideMaxBounds);
+		}
+
+		this.options.maxBounds = bounds;
+
+		if (this._loaded) {
+			this._panInsideMaxBounds();
+		}
+
+		return this.on('moveend', this._panInsideMaxBounds);
+	},
+
+	// @method setMinZoom(zoom: Number): this
+	// Sets the lower limit for the available zoom levels (see the [minZoom](#map-minzoom) option).
+	setMinZoom: function (zoom) {
+		var oldZoom = this.options.minZoom;
+		this.options.minZoom = zoom;
+
+		if (this._loaded && oldZoom !== zoom) {
+			this.fire('zoomlevelschange');
+
+			if (this.getZoom() < this.options.minZoom) {
+				return this.setZoom(zoom);
+			}
+		}
+
+		return this;
+	},
+
+	// @method setMaxZoom(zoom: Number): this
+	// Sets the upper limit for the available zoom levels (see the [maxZoom](#map-maxzoom) option).
+	setMaxZoom: function (zoom) {
+		var oldZoom = this.options.maxZoom;
+		this.options.maxZoom = zoom;
+
+		if (this._loaded && oldZoom !== zoom) {
+			this.fire('zoomlevelschange');
+
+			if (this.getZoom() > this.options.maxZoom) {
+				return this.setZoom(zoom);
+			}
+		}
+
+		return this;
+	},
+
+	// @method panInsideBounds(bounds: LatLngBounds, options?: Pan options): this
+	// Pans the map to the closest view that would lie inside the given bounds (if it's not already), controlling the animation using the options specific, if any.
+	panInsideBounds: function (bounds, options) {
+		this._enforcingBounds = true;
+		var center = this.getCenter(),
+		    newCenter = this._limitCenter(center, this._zoom, toLatLngBounds(bounds));
+
+		if (!center.equals(newCenter)) {
+			this.panTo(newCenter, options);
+		}
+
+		this._enforcingBounds = false;
+		return this;
+	},
+
+	// @method invalidateSize(options: Zoom/pan options): this
+	// Checks if the map container size changed and updates the map if so —
+	// call it after you've changed the map size dynamically, also animating
+	// pan by default. If `options.pan` is `false`, panning will not occur.
+	// If `options.debounceMoveend` is `true`, it will delay `moveend` event so
+	// that it doesn't happen often even if the method is called many
+	// times in a row.
+
+	// @alternative
+	// @method invalidateSize(animate: Boolean): this
+	// Checks if the map container size changed and updates the map if so —
+	// call it after you've changed the map size dynamically, also animating
+	// pan by default.
+	invalidateSize: function (options) {
+		if (!this._loaded) { return this; }
+
+		options = extend({
+			animate: false,
+			pan: true
+		}, options === true ? {animate: true} : options);
+
+		var oldSize = this.getSize();
+		this._sizeChanged = true;
+		this._lastCenter = null;
+
+		var newSize = this.getSize(),
+		    oldCenter = oldSize.divideBy(2).round(),
+		    newCenter = newSize.divideBy(2).round(),
+		    offset = oldCenter.subtract(newCenter);
+
+		if (!offset.x && !offset.y) { return this; }
+
+		if (options.animate && options.pan) {
+			this.panBy(offset);
+
+		} else {
+			if (options.pan) {
+				this._rawPanBy(offset);
+			}
+
+			this.fire('move');
+
+			if (options.debounceMoveend) {
+				clearTimeout(this._sizeTimer);
+				this._sizeTimer = setTimeout(bind(this.fire, this, 'moveend'), 200);
+			} else {
+				this.fire('moveend');
+			}
+		}
+
+		// @section Map state change events
+		// @event resize: ResizeEvent
+		// Fired when the map is resized.
+		return this.fire('resize', {
+			oldSize: oldSize,
+			newSize: newSize
+		});
+	},
+
+	// @section Methods for modifying map state
+	// @method stop(): this
+	// Stops the currently running `panTo` or `flyTo` animation, if any.
+	stop: function () {
+		this.setZoom(this._limitZoom(this._zoom));
+		if (!this.options.zoomSnap) {
+			this.fire('viewreset');
+		}
+		return this._stop();
+	},
+
+	// @section Geolocation methods
+	// @method locate(options?: Locate options): this
+	// Tries to locate the user using the Geolocation API, firing a [`locationfound`](#map-locationfound)
+	// event with location data on success or a [`locationerror`](#map-locationerror) event on failure,
+	// and optionally sets the map view to the user's location with respect to
+	// detection accuracy (or to the world view if geolocation failed).
+	// Note that, if your page doesn't use HTTPS, this method will fail in
+	// modern browsers ([Chrome 50 and newer](https://sites.google.com/a/chromium.org/dev/Home/chromium-security/deprecating-powerful-features-on-insecure-origins))
+	// See `Locate options` for more details.
+	locate: function (options) {
+
+		options = this._locateOptions = extend({
+			timeout: 10000,
+			watch: false
+			// setView: false
+			// maxZoom: <Number>
+			// maximumAge: 0
+			// enableHighAccuracy: false
+		}, options);
+
+		if (!('geolocation' in navigator)) {
+			this._handleGeolocationError({
+				code: 0,
+				message: 'Geolocation not supported.'
+			});
+			return this;
+		}
+
+		var onResponse = bind(this._handleGeolocationResponse, this),
+		    onError = bind(this._handleGeolocationError, this);
+
+		if (options.watch) {
+			this._locationWatchId =
+			        navigator.geolocation.watchPosition(onResponse, onError, options);
+		} else {
+			navigator.geolocation.getCurrentPosition(onResponse, onError, options);
+		}
+		return this;
+	},
+
+	// @method stopLocate(): this
+	// Stops watching location previously initiated by `map.locate({watch: true})`
+	// and aborts resetting the map view if map.locate was called with
+	// `{setView: true}`.
+	stopLocate: function () {
+		if (navigator.geolocation && navigator.geolocation.clearWatch) {
+			navigator.geolocation.clearWatch(this._locationWatchId);
+		}
+		if (this._locateOptions) {
+			this._locateOptions.setView = false;
+		}
+		return this;
+	},
+
+	_handleGeolocationError: function (error) {
+		var c = error.code,
+		    message = error.message ||
+		            (c === 1 ? 'permission denied' :
+		            (c === 2 ? 'position unavailable' : 'timeout'));
+
+		if (this._locateOptions.setView && !this._loaded) {
+			this.fitWorld();
+		}
+
+		// @section Location events
+		// @event locationerror: ErrorEvent
+		// Fired when geolocation (using the [`locate`](#map-locate) method) failed.
+		this.fire('locationerror', {
+			code: c,
+			message: 'Geolocation error: ' + message + '.'
+		});
+	},
+
+	_handleGeolocationResponse: function (pos) {
+		var lat = pos.coords.latitude,
+		    lng = pos.coords.longitude,
+		    latlng = new LatLng(lat, lng),
+		    bounds = latlng.toBounds(pos.coords.accuracy),
+		    options = this._locateOptions;
+
+		if (options.setView) {
+			var zoom = this.getBoundsZoom(bounds);
+			this.setView(latlng, options.maxZoom ? Math.min(zoom, options.maxZoom) : zoom);
+		}
+
+		var data = {
+			latlng: latlng,
+			bounds: bounds,
+			timestamp: pos.timestamp
+		};
+
+		for (var i in pos.coords) {
+			if (typeof pos.coords[i] === 'number') {
+				data[i] = pos.coords[i];
+			}
+		}
+
+		// @event locationfound: LocationEvent
+		// Fired when geolocation (using the [`locate`](#map-locate) method)
+		// went successfully.
+		this.fire('locationfound', data);
+	},
+
+	// TODO Appropriate docs section?
+	// @section Other Methods
+	// @method addHandler(name: String, HandlerClass: Function): this
+	// Adds a new `Handler` to the map, given its name and constructor function.
+	addHandler: function (name, HandlerClass) {
+		if (!HandlerClass) { return this; }
+
+		var handler = this[name] = new HandlerClass(this);
+
+		this._handlers.push(handler);
+
+		if (this.options[name]) {
+			handler.enable();
+		}
+
+		return this;
+	},
+
+	// @method remove(): this
+	// Destroys the map and clears all related event listeners.
+	remove: function () {
+
+		this._initEvents(true);
+
+		if (this._containerId !== this._container._leaflet_id) {
+			throw new Error('Map container is being reused by another instance');
+		}
+
+		try {
+			// throws error in IE6-8
+			delete this._container._leaflet_id;
+			delete this._containerId;
+		} catch (e) {
+			/*eslint-disable */
+			this._container._leaflet_id = undefined;
+			/* eslint-enable */
+			this._containerId = undefined;
+		}
+
+		if (this._locationWatchId !== undefined) {
+			this.stopLocate();
+		}
+
+		this._stop();
+
+		remove(this._mapPane);
+
+		if (this._clearControlPos) {
+			this._clearControlPos();
+		}
+
+		this._clearHandlers();
+
+		if (this._loaded) {
+			// @section Map state change events
+			// @event unload: Event
+			// Fired when the map is destroyed with [remove](#map-remove) method.
+			this.fire('unload');
+		}
+
+		var i;
+		for (i in this._layers) {
+			this._layers[i].remove();
+		}
+		for (i in this._panes) {
+			remove(this._panes[i]);
+		}
+
+		this._layers = [];
+		this._panes = [];
+		delete this._mapPane;
+		delete this._renderer;
+
+		return this;
+	},
+
+	// @section Other Methods
+	// @method createPane(name: String, container?: HTMLElement): HTMLElement
+	// Creates a new [map pane](#map-pane) with the given name if it doesn't exist already,
+	// then returns it. The pane is created as a child of `container`, or
+	// as a child of the main map pane if not set.
+	createPane: function (name, container) {
+		var className = 'leaflet-pane' + (name ? ' leaflet-' + name.replace('Pane', '') + '-pane' : ''),
+		    pane = create$1('div', className, container || this._mapPane);
+
+		if (name) {
+			this._panes[name] = pane;
+		}
+		return pane;
+	},
+
+	// @section Methods for Getting Map State
+
+	// @method getCenter(): LatLng
+	// Returns the geographical center of the map view
+	getCenter: function () {
+		this._checkIfLoaded();
+
+		if (this._lastCenter && !this._moved()) {
+			return this._lastCenter;
+		}
+		return this.layerPointToLatLng(this._getCenterLayerPoint());
+	},
+
+	// @method getZoom(): Number
+	// Returns the current zoom level of the map view
+	getZoom: function () {
+		return this._zoom;
+	},
+
+	// @method getBounds(): LatLngBounds
+	// Returns the geographical bounds visible in the current map view
+	getBounds: function () {
+		var bounds = this.getPixelBounds(),
+		    sw = this.unproject(bounds.getBottomLeft()),
+		    ne = this.unproject(bounds.getTopRight());
+
+		return new LatLngBounds(sw, ne);
+	},
+
+	// @method getMinZoom(): Number
+	// Returns the minimum zoom level of the map (if set in the `minZoom` option of the map or of any layers), or `0` by default.
+	getMinZoom: function () {
+		return this.options.minZoom === undefined ? this._layersMinZoom || 0 : this.options.minZoom;
+	},
+
+	// @method getMaxZoom(): Number
+	// Returns the maximum zoom level of the map (if set in the `maxZoom` option of the map or of any layers).
+	getMaxZoom: function () {
+		return this.options.maxZoom === undefined ?
+			(this._layersMaxZoom === undefined ? Infinity : this._layersMaxZoom) :
+			this.options.maxZoom;
+	},
+
+	// @method getBoundsZoom(bounds: LatLngBounds, inside?: Boolean): Number
+	// Returns the maximum zoom level on which the given bounds fit to the map
+	// view in its entirety. If `inside` (optional) is set to `true`, the method
+	// instead returns the minimum zoom level on which the map view fits into
+	// the given bounds in its entirety.
+	getBoundsZoom: function (bounds, inside, padding) { // (LatLngBounds[, Boolean, Point]) -> Number
+		bounds = toLatLngBounds(bounds);
+		padding = toPoint(padding || [0, 0]);
+
+		var zoom = this.getZoom() || 0,
+		    min = this.getMinZoom(),
+		    max = this.getMaxZoom(),
+		    nw = bounds.getNorthWest(),
+		    se = bounds.getSouthEast(),
+		    size = this.getSize().subtract(padding),
+		    boundsSize = toBounds(this.project(se, zoom), this.project(nw, zoom)).getSize(),
+		    snap = any3d ? this.options.zoomSnap : 1,
+		    scalex = size.x / boundsSize.x,
+		    scaley = size.y / boundsSize.y,
+		    scale = inside ? Math.max(scalex, scaley) : Math.min(scalex, scaley);
+
+		zoom = this.getScaleZoom(scale, zoom);
+
+		if (snap) {
+			zoom = Math.round(zoom / (snap / 100)) * (snap / 100); // don't jump if within 1% of a snap level
+			zoom = inside ? Math.ceil(zoom / snap) * snap : Math.floor(zoom / snap) * snap;
+		}
+
+		return Math.max(min, Math.min(max, zoom));
+	},
+
+	// @method getSize(): Point
+	// Returns the current size of the map container (in pixels).
+	getSize: function () {
+		if (!this._size || this._sizeChanged) {
+			this._size = new Point(
+				this._container.clientWidth || 0,
+				this._container.clientHeight || 0);
+
+			this._sizeChanged = false;
+		}
+		return this._size.clone();
+	},
+
+	// @method getPixelBounds(): Bounds
+	// Returns the bounds of the current map view in projected pixel
+	// coordinates (sometimes useful in layer and overlay implementations).
+	getPixelBounds: function (center, zoom) {
+		var topLeftPoint = this._getTopLeftPoint(center, zoom);
+		return new Bounds(topLeftPoint, topLeftPoint.add(this.getSize()));
+	},
+
+	// TODO: Check semantics - isn't the pixel origin the 0,0 coord relative to
+	// the map pane? "left point of the map layer" can be confusing, specially
+	// since there can be negative offsets.
+	// @method getPixelOrigin(): Point
+	// Returns the projected pixel coordinates of the top left point of
+	// the map layer (useful in custom layer and overlay implementations).
+	getPixelOrigin: function () {
+		this._checkIfLoaded();
+		return this._pixelOrigin;
+	},
+
+	// @method getPixelWorldBounds(zoom?: Number): Bounds
+	// Returns the world's bounds in pixel coordinates for zoom level `zoom`.
+	// If `zoom` is omitted, the map's current zoom level is used.
+	getPixelWorldBounds: function (zoom) {
+		return this.options.crs.getProjectedBounds(zoom === undefined ? this.getZoom() : zoom);
+	},
+
+	// @section Other Methods
+
+	// @method getPane(pane: String|HTMLElement): HTMLElement
+	// Returns a [map pane](#map-pane), given its name or its HTML element (its identity).
+	getPane: function (pane) {
+		return typeof pane === 'string' ? this._panes[pane] : pane;
+	},
+
+	// @method getPanes(): Object
+	// Returns a plain object containing the names of all [panes](#map-pane) as keys and
+	// the panes as values.
+	getPanes: function () {
+		return this._panes;
+	},
+
+	// @method getContainer: HTMLElement
+	// Returns the HTML element that contains the map.
+	getContainer: function () {
+		return this._container;
+	},
+
+
+	// @section Conversion Methods
+
+	// @method getZoomScale(toZoom: Number, fromZoom: Number): Number
+	// Returns the scale factor to be applied to a map transition from zoom level
+	// `fromZoom` to `toZoom`. Used internally to help with zoom animations.
+	getZoomScale: function (toZoom, fromZoom) {
+		// TODO replace with universal implementation after refactoring projections
+		var crs = this.options.crs;
+		fromZoom = fromZoom === undefined ? this._zoom : fromZoom;
+		return crs.scale(toZoom) / crs.scale(fromZoom);
+	},
+
+	// @method getScaleZoom(scale: Number, fromZoom: Number): Number
+	// Returns the zoom level that the map would end up at, if it is at `fromZoom`
+	// level and everything is scaled by a factor of `scale`. Inverse of
+	// [`getZoomScale`](#map-getZoomScale).
+	getScaleZoom: function (scale, fromZoom) {
+		var crs = this.options.crs;
+		fromZoom = fromZoom === undefined ? this._zoom : fromZoom;
+		var zoom = crs.zoom(scale * crs.scale(fromZoom));
+		return isNaN(zoom) ? Infinity : zoom;
+	},
+
+	// @method project(latlng: LatLng, zoom: Number): Point
+	// Projects a geographical coordinate `LatLng` according to the projection
+	// of the map's CRS, then scales it according to `zoom` and the CRS's
+	// `Transformation`. The result is pixel coordinate relative to
+	// the CRS origin.
+	project: function (latlng, zoom) {
+		zoom = zoom === undefined ? this._zoom : zoom;
+		return this.options.crs.latLngToPoint(toLatLng(latlng), zoom);
+	},
+
+	// @method unproject(point: Point, zoom: Number): LatLng
+	// Inverse of [`project`](#map-project).
+	unproject: function (point, zoom) {
+		zoom = zoom === undefined ? this._zoom : zoom;
+		return this.options.crs.pointToLatLng(toPoint(point), zoom);
+	},
+
+	// @method layerPointToLatLng(point: Point): LatLng
+	// Given a pixel coordinate relative to the [origin pixel](#map-getpixelorigin),
+	// returns the corresponding geographical coordinate (for the current zoom level).
+	layerPointToLatLng: function (point) {
+		var projectedPoint = toPoint(point).add(this.getPixelOrigin());
+		return this.unproject(projectedPoint);
+	},
+
+	// @method latLngToLayerPoint(latlng: LatLng): Point
+	// Given a geographical coordinate, returns the corresponding pixel coordinate
+	// relative to the [origin pixel](#map-getpixelorigin).
+	latLngToLayerPoint: function (latlng) {
+		var projectedPoint = this.project(toLatLng(latlng))._round();
+		return projectedPoint._subtract(this.getPixelOrigin());
+	},
+
+	// @method wrapLatLng(latlng: LatLng): LatLng
+	// Returns a `LatLng` where `lat` and `lng` has been wrapped according to the
+	// map's CRS's `wrapLat` and `wrapLng` properties, if they are outside the
+	// CRS's bounds.
+	// By default this means longitude is wrapped around the dateline so its
+	// value is between -180 and +180 degrees.
+	wrapLatLng: function (latlng) {
+		return this.options.crs.wrapLatLng(toLatLng(latlng));
+	},
+
+	// @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds
+	// Returns a `LatLngBounds` with the same size as the given one, ensuring that
+	// its center is within the CRS's bounds.
+	// By default this means the center longitude is wrapped around the dateline so its
+	// value is between -180 and +180 degrees, and the majority of the bounds
+	// overlaps the CRS's bounds.
+	wrapLatLngBounds: function (latlng) {
+		return this.options.crs.wrapLatLngBounds(toLatLngBounds(latlng));
+	},
+
+	// @method distance(latlng1: LatLng, latlng2: LatLng): Number
+	// Returns the distance between two geographical coordinates according to
+	// the map's CRS. By default this measures distance in meters.
+	distance: function (latlng1, latlng2) {
+		return this.options.crs.distance(toLatLng(latlng1), toLatLng(latlng2));
+	},
+
+	// @method containerPointToLayerPoint(point: Point): Point
+	// Given a pixel coordinate relative to the map container, returns the corresponding
+	// pixel coordinate relative to the [origin pixel](#map-getpixelorigin).
+	containerPointToLayerPoint: function (point) { // (Point)
+		return toPoint(point).subtract(this._getMapPanePos());
+	},
+
+	// @method layerPointToContainerPoint(point: Point): Point
+	// Given a pixel coordinate relative to the [origin pixel](#map-getpixelorigin),
+	// returns the corresponding pixel coordinate relative to the map container.
+	layerPointToContainerPoint: function (point) { // (Point)
+		return toPoint(point).add(this._getMapPanePos());
+	},
+
+	// @method containerPointToLatLng(point: Point): LatLng
+	// Given a pixel coordinate relative to the map container, returns
+	// the corresponding geographical coordinate (for the current zoom level).
+	containerPointToLatLng: function (point) {
+		var layerPoint = this.containerPointToLayerPoint(toPoint(point));
+		return this.layerPointToLatLng(layerPoint);
+	},
+
+	// @method latLngToContainerPoint(latlng: LatLng): Point
+	// Given a geographical coordinate, returns the corresponding pixel coordinate
+	// relative to the map container.
+	latLngToContainerPoint: function (latlng) {
+		return this.layerPointToContainerPoint(this.latLngToLayerPoint(toLatLng(latlng)));
+	},
+
+	// @method mouseEventToContainerPoint(ev: MouseEvent): Point
+	// Given a MouseEvent object, returns the pixel coordinate relative to the
+	// map container where the event took place.
+	mouseEventToContainerPoint: function (e) {
+		return getMousePosition(e, this._container);
+	},
+
+	// @method mouseEventToLayerPoint(ev: MouseEvent): Point
+	// Given a MouseEvent object, returns the pixel coordinate relative to
+	// the [origin pixel](#map-getpixelorigin) where the event took place.
+	mouseEventToLayerPoint: function (e) {
+		return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(e));
+	},
+
+	// @method mouseEventToLatLng(ev: MouseEvent): LatLng
+	// Given a MouseEvent object, returns geographical coordinate where the
+	// event took place.
+	mouseEventToLatLng: function (e) { // (MouseEvent)
+		return this.layerPointToLatLng(this.mouseEventToLayerPoint(e));
+	},
+
+
+	// map initialization methods
+
+	_initContainer: function (id) {
+		var container = this._container = get(id);
+
+		if (!container) {
+			throw new Error('Map container not found.');
+		} else if (container._leaflet_id) {
+			throw new Error('Map container is already initialized.');
+		}
+
+		on(container, 'scroll', this._onScroll, this);
+		this._containerId = stamp(container);
+	},
+
+	_initLayout: function () {
+		var container = this._container;
+
+		this._fadeAnimated = this.options.fadeAnimation && any3d;
+
+		addClass(container, 'leaflet-container' +
+			(touch ? ' leaflet-touch' : '') +
+			(retina ? ' leaflet-retina' : '') +
+			(ielt9 ? ' leaflet-oldie' : '') +
+			(safari ? ' leaflet-safari' : '') +
+			(this._fadeAnimated ? ' leaflet-fade-anim' : ''));
+
+		var position = getStyle(container, 'position');
+
+		if (position !== 'absolute' && position !== 'relative' && position !== 'fixed') {
+			container.style.position = 'relative';
+		}
+
+		this._initPanes();
+
+		if (this._initControlPos) {
+			this._initControlPos();
+		}
+	},
+
+	_initPanes: function () {
+		var panes = this._panes = {};
+		this._paneRenderers = {};
+
+		// @section
+		//
+		// Panes are DOM elements used to control the ordering of layers on the map. You
+		// can access panes with [`map.getPane`](#map-getpane) or
+		// [`map.getPanes`](#map-getpanes) methods. New panes can be created with the
+		// [`map.createPane`](#map-createpane) method.
+		//
+		// Every map has the following default panes that differ only in zIndex.
+		//
+		// @pane mapPane: HTMLElement = 'auto'
+		// Pane that contains all other map panes
+
+		this._mapPane = this.createPane('mapPane', this._container);
+		setPosition(this._mapPane, new Point(0, 0));
+
+		// @pane tilePane: HTMLElement = 200
+		// Pane for `GridLayer`s and `TileLayer`s
+		this.createPane('tilePane');
+		// @pane overlayPane: HTMLElement = 400
+		// Pane for vectors (`Path`s, like `Polyline`s and `Polygon`s), `ImageOverlay`s and `VideoOverlay`s
+		this.createPane('shadowPane');
+		// @pane shadowPane: HTMLElement = 500
+		// Pane for overlay shadows (e.g. `Marker` shadows)
+		this.createPane('overlayPane');
+		// @pane markerPane: HTMLElement = 600
+		// Pane for `Icon`s of `Marker`s
+		this.createPane('markerPane');
+		// @pane tooltipPane: HTMLElement = 650
+		// Pane for `Tooltip`s.
+		this.createPane('tooltipPane');
+		// @pane popupPane: HTMLElement = 700
+		// Pane for `Popup`s.
+		this.createPane('popupPane');
+
+		if (!this.options.markerZoomAnimation) {
+			addClass(panes.markerPane, 'leaflet-zoom-hide');
+			addClass(panes.shadowPane, 'leaflet-zoom-hide');
+		}
+	},
+
+
+	// private methods that modify map state
+
+	// @section Map state change events
+	_resetView: function (center, zoom) {
+		setPosition(this._mapPane, new Point(0, 0));
+
+		var loading = !this._loaded;
+		this._loaded = true;
+		zoom = this._limitZoom(zoom);
+
+		this.fire('viewprereset');
+
+		var zoomChanged = this._zoom !== zoom;
+		this
+			._moveStart(zoomChanged, false)
+			._move(center, zoom)
+			._moveEnd(zoomChanged);
+
+		// @event viewreset: Event
+		// Fired when the map needs to redraw its content (this usually happens
+		// on map zoom or load). Very useful for creating custom overlays.
+		this.fire('viewreset');
+
+		// @event load: Event
+		// Fired when the map is initialized (when its center and zoom are set
+		// for the first time).
+		if (loading) {
+			this.fire('load');
+		}
+	},
+
+	_moveStart: function (zoomChanged, noMoveStart) {
+		// @event zoomstart: Event
+		// Fired when the map zoom is about to change (e.g. before zoom animation).
+		// @event movestart: Event
+		// Fired when the view of the map starts changing (e.g. user starts dragging the map).
+		if (zoomChanged) {
+			this.fire('zoomstart');
+		}
+		if (!noMoveStart) {
+			this.fire('movestart');
+		}
+		return this;
+	},
+
+	_move: function (center, zoom, data) {
+		if (zoom === undefined) {
+			zoom = this._zoom;
+		}
+		var zoomChanged = this._zoom !== zoom;
+
+		this._zoom = zoom;
+		this._lastCenter = center;
+		this._pixelOrigin = this._getNewPixelOrigin(center);
+
+		// @event zoom: Event
+		// Fired repeatedly during any change in zoom level, including zoom
+		// and fly animations.
+		if (zoomChanged || (data && data.pinch)) {	// Always fire 'zoom' if pinching because #3530
+			this.fire('zoom', data);
+		}
+
+		// @event move: Event
+		// Fired repeatedly during any movement of the map, including pan and
+		// fly animations.
+		return this.fire('move', data);
+	},
+
+	_moveEnd: function (zoomChanged) {
+		// @event zoomend: Event
+		// Fired when the map has changed, after any animations.
+		if (zoomChanged) {
+			this.fire('zoomend');
+		}
+
+		// @event moveend: Event
+		// Fired when the center of the map stops changing (e.g. user stopped
+		// dragging the map).
+		return this.fire('moveend');
+	},
+
+	_stop: function () {
+		cancelAnimFrame(this._flyToFrame);
+		if (this._panAnim) {
+			this._panAnim.stop();
+		}
+		return this;
+	},
+
+	_rawPanBy: function (offset) {
+		setPosition(this._mapPane, this._getMapPanePos().subtract(offset));
+	},
+
+	_getZoomSpan: function () {
+		return this.getMaxZoom() - this.getMinZoom();
+	},
+
+	_panInsideMaxBounds: function () {
+		if (!this._enforcingBounds) {
+			this.panInsideBounds(this.options.maxBounds);
+		}
+	},
+
+	_checkIfLoaded: function () {
+		if (!this._loaded) {
+			throw new Error('Set map center and zoom first.');
+		}
+	},
+
+	// DOM event handling
+
+	// @section Interaction events
+	_initEvents: function (remove$$1) {
+		this._targets = {};
+		this._targets[stamp(this._container)] = this;
+
+		var onOff = remove$$1 ? off : on;
+
+		// @event click: MouseEvent
+		// Fired when the user clicks (or taps) the map.
+		// @event dblclick: MouseEvent
+		// Fired when the user double-clicks (or double-taps) the map.
+		// @event mousedown: MouseEvent
+		// Fired when the user pushes the mouse button on the map.
+		// @event mouseup: MouseEvent
+		// Fired when the user releases the mouse button on the map.
+		// @event mouseover: MouseEvent
+		// Fired when the mouse enters the map.
+		// @event mouseout: MouseEvent
+		// Fired when the mouse leaves the map.
+		// @event mousemove: MouseEvent
+		// Fired while the mouse moves over the map.
+		// @event contextmenu: MouseEvent
+		// Fired when the user pushes the right mouse button on the map, prevents
+		// default browser context menu from showing if there are listeners on
+		// this event. Also fired on mobile when the user holds a single touch
+		// for a second (also called long press).
+		// @event keypress: KeyboardEvent
+		// Fired when the user presses a key from the keyboard while the map is focused.
+		onOff(this._container, 'click dblclick mousedown mouseup ' +
+			'mouseover mouseout mousemove contextmenu keypress', this._handleDOMEvent, this);
+
+		if (this.options.trackResize) {
+			onOff(window, 'resize', this._onResize, this);
+		}
+
+		if (any3d && this.options.transform3DLimit) {
+			(remove$$1 ? this.off : this.on).call(this, 'moveend', this._onMoveEnd);
+		}
+	},
+
+	_onResize: function () {
+		cancelAnimFrame(this._resizeRequest);
+		this._resizeRequest = requestAnimFrame(
+		        function () { this.invalidateSize({debounceMoveend: true}); }, this);
+	},
+
+	_onScroll: function () {
+		this._container.scrollTop  = 0;
+		this._container.scrollLeft = 0;
+	},
+
+	_onMoveEnd: function () {
+		var pos = this._getMapPanePos();
+		if (Math.max(Math.abs(pos.x), Math.abs(pos.y)) >= this.options.transform3DLimit) {
+			// https://bugzilla.mozilla.org/show_bug.cgi?id=1203873 but Webkit also have
+			// a pixel offset on very high values, see: http://jsfiddle.net/dg6r5hhb/
+			this._resetView(this.getCenter(), this.getZoom());
+		}
+	},
+
+	_findEventTargets: function (e, type) {
+		var targets = [],
+		    target,
+		    isHover = type === 'mouseout' || type === 'mouseover',
+		    src = e.target || e.srcElement,
+		    dragging = false;
+
+		while (src) {
+			target = this._targets[stamp(src)];
+			if (target && (type === 'click' || type === 'preclick') && !e._simulated && this._draggableMoved(target)) {
+				// Prevent firing click after you just dragged an object.
+				dragging = true;
+				break;
+			}
+			if (target && target.listens(type, true)) {
+				if (isHover && !isExternalTarget(src, e)) { break; }
+				targets.push(target);
+				if (isHover) { break; }
+			}
+			if (src === this._container) { break; }
+			src = src.parentNode;
+		}
+		if (!targets.length && !dragging && !isHover && isExternalTarget(src, e)) {
+			targets = [this];
+		}
+		return targets;
+	},
+
+	_handleDOMEvent: function (e) {
+		if (!this._loaded || skipped(e)) { return; }
+
+		var type = e.type;
+
+		if (type === 'mousedown' || type === 'keypress') {
+			// prevents outline when clicking on keyboard-focusable element
+			preventOutline(e.target || e.srcElement);
+		}
+
+		this._fireDOMEvent(e, type);
+	},
+
+	_mouseEvents: ['click', 'dblclick', 'mouseover', 'mouseout', 'contextmenu'],
+
+	_fireDOMEvent: function (e, type, targets) {
+
+		if (e.type === 'click') {
+			// Fire a synthetic 'preclick' event which propagates up (mainly for closing popups).
+			// @event preclick: MouseEvent
+			// Fired before mouse click on the map (sometimes useful when you
+			// want something to happen on click before any existing click
+			// handlers start running).
+			var synth = extend({}, e);
+			synth.type = 'preclick';
+			this._fireDOMEvent(synth, synth.type, targets);
+		}
+
+		if (e._stopped) { return; }
+
+		// Find the layer the event is propagating from and its parents.
+		targets = (targets || []).concat(this._findEventTargets(e, type));
+
+		if (!targets.length) { return; }
+
+		var target = targets[0];
+		if (type === 'contextmenu' && target.listens(type, true)) {
+			preventDefault(e);
+		}
+
+		var data = {
+			originalEvent: e
+		};
+
+		if (e.type !== 'keypress') {
+			var isMarker = target.getLatLng && (!target._radius || target._radius <= 10);
+			data.containerPoint = isMarker ?
+				this.latLngToContainerPoint(target.getLatLng()) : this.mouseEventToContainerPoint(e);
+			data.layerPoint = this.containerPointToLayerPoint(data.containerPoint);
+			data.latlng = isMarker ? target.getLatLng() : this.layerPointToLatLng(data.layerPoint);
+		}
+
+		for (var i = 0; i < targets.length; i++) {
+			targets[i].fire(type, data, true);
+			if (data.originalEvent._stopped ||
+				(targets[i].options.bubblingMouseEvents === false && indexOf(this._mouseEvents, type) !== -1)) { return; }
+		}
+	},
+
+	_draggableMoved: function (obj) {
+		obj = obj.dragging && obj.dragging.enabled() ? obj : this;
+		return (obj.dragging && obj.dragging.moved()) || (this.boxZoom && this.boxZoom.moved());
+	},
+
+	_clearHandlers: function () {
+		for (var i = 0, len = this._handlers.length; i < len; i++) {
+			this._handlers[i].disable();
+		}
+	},
+
+	// @section Other Methods
+
+	// @method whenReady(fn: Function, context?: Object): this
+	// Runs the given function `fn` when the map gets initialized with
+	// a view (center and zoom) and at least one layer, or immediately
+	// if it's already initialized, optionally passing a function context.
+	whenReady: function (callback, context) {
+		if (this._loaded) {
+			callback.call(context || this, {target: this});
+		} else {
+			this.on('load', callback, context);
+		}
+		return this;
+	},
+
+
+	// private methods for getting map state
+
+	_getMapPanePos: function () {
+		return getPosition(this._mapPane) || new Point(0, 0);
+	},
+
+	_moved: function () {
+		var pos = this._getMapPanePos();
+		return pos && !pos.equals([0, 0]);
+	},
+
+	_getTopLeftPoint: function (center, zoom) {
+		var pixelOrigin = center && zoom !== undefined ?
+			this._getNewPixelOrigin(center, zoom) :
+			this.getPixelOrigin();
+		return pixelOrigin.subtract(this._getMapPanePos());
+	},
+
+	_getNewPixelOrigin: function (center, zoom) {
+		var viewHalf = this.getSize()._divideBy(2);
+		return this.project(center, zoom)._subtract(viewHalf)._add(this._getMapPanePos())._round();
+	},
+
+	_latLngToNewLayerPoint: function (latlng, zoom, center) {
+		var topLeft = this._getNewPixelOrigin(center, zoom);
+		return this.project(latlng, zoom)._subtract(topLeft);
+	},
+
+	_latLngBoundsToNewLayerBounds: function (latLngBounds, zoom, center) {
+		var topLeft = this._getNewPixelOrigin(center, zoom);
+		return toBounds([
+			this.project(latLngBounds.getSouthWest(), zoom)._subtract(topLeft),
+			this.project(latLngBounds.getNorthWest(), zoom)._subtract(topLeft),
+			this.project(latLngBounds.getSouthEast(), zoom)._subtract(topLeft),
+			this.project(latLngBounds.getNorthEast(), zoom)._subtract(topLeft)
+		]);
+	},
+
+	// layer point of the current center
+	_getCenterLayerPoint: function () {
+		return this.containerPointToLayerPoint(this.getSize()._divideBy(2));
+	},
+
+	// offset of the specified place to the current center in pixels
+	_getCenterOffset: function (latlng) {
+		return this.latLngToLayerPoint(latlng).subtract(this._getCenterLayerPoint());
+	},
+
+	// adjust center for view to get inside bounds
+	_limitCenter: function (center, zoom, bounds) {
+
+		if (!bounds) { return center; }
+
+		var centerPoint = this.project(center, zoom),
+		    viewHalf = this.getSize().divideBy(2),
+		    viewBounds = new Bounds(centerPoint.subtract(viewHalf), centerPoint.add(viewHalf)),
+		    offset = this._getBoundsOffset(viewBounds, bounds, zoom);
+
+		// If offset is less than a pixel, ignore.
+		// This prevents unstable projections from getting into
+		// an infinite loop of tiny offsets.
+		if (offset.round().equals([0, 0])) {
+			return center;
+		}
+
+		return this.unproject(centerPoint.add(offset), zoom);
+	},
+
+	// adjust offset for view to get inside bounds
+	_limitOffset: function (offset, bounds) {
+		if (!bounds) { return offset; }
+
+		var viewBounds = this.getPixelBounds(),
+		    newBounds = new Bounds(viewBounds.min.add(offset), viewBounds.max.add(offset));
+
+		return offset.add(this._getBoundsOffset(newBounds, bounds));
+	},
+
+	// returns offset needed for pxBounds to get inside maxBounds at a specified zoom
+	_getBoundsOffset: function (pxBounds, maxBounds, zoom) {
+		var projectedMaxBounds = toBounds(
+		        this.project(maxBounds.getNorthEast(), zoom),
+		        this.project(maxBounds.getSouthWest(), zoom)
+		    ),
+		    minOffset = projectedMaxBounds.min.subtract(pxBounds.min),
+		    maxOffset = projectedMaxBounds.max.subtract(pxBounds.max),
+
+		    dx = this._rebound(minOffset.x, -maxOffset.x),
+		    dy = this._rebound(minOffset.y, -maxOffset.y);
+
+		return new Point(dx, dy);
+	},
+
+	_rebound: function (left, right) {
+		return left + right > 0 ?
+			Math.round(left - right) / 2 :
+			Math.max(0, Math.ceil(left)) - Math.max(0, Math.floor(right));
+	},
+
+	_limitZoom: function (zoom) {
+		var min = this.getMinZoom(),
+		    max = this.getMaxZoom(),
+		    snap = any3d ? this.options.zoomSnap : 1;
+		if (snap) {
+			zoom = Math.round(zoom / snap) * snap;
+		}
+		return Math.max(min, Math.min(max, zoom));
+	},
+
+	_onPanTransitionStep: function () {
+		this.fire('move');
+	},
+
+	_onPanTransitionEnd: function () {
+		removeClass(this._mapPane, 'leaflet-pan-anim');
+		this.fire('moveend');
+	},
+
+	_tryAnimatedPan: function (center, options) {
+		// difference between the new and current centers in pixels
+		var offset = this._getCenterOffset(center)._trunc();
+
+		// don't animate too far unless animate: true specified in options
+		if ((options && options.animate) !== true && !this.getSize().contains(offset)) { return false; }
+
+		this.panBy(offset, options);
+
+		return true;
+	},
+
+	_createAnimProxy: function () {
+
+		var proxy = this._proxy = create$1('div', 'leaflet-proxy leaflet-zoom-animated');
+		this._panes.mapPane.appendChild(proxy);
+
+		this.on('zoomanim', function (e) {
+			var prop = TRANSFORM,
+			    transform = this._proxy.style[prop];
+
+			setTransform(this._proxy, this.project(e.center, e.zoom), this.getZoomScale(e.zoom, 1));
+
+			// workaround for case when transform is the same and so transitionend event is not fired
+			if (transform === this._proxy.style[prop] && this._animatingZoom) {
+				this._onZoomTransitionEnd();
+			}
+		}, this);
+
+		this.on('load moveend', function () {
+			var c = this.getCenter(),
+			    z = this.getZoom();
+			setTransform(this._proxy, this.project(c, z), this.getZoomScale(z, 1));
+		}, this);
+
+		this._on('unload', this._destroyAnimProxy, this);
+	},
+
+	_destroyAnimProxy: function () {
+		remove(this._proxy);
+		delete this._proxy;
+	},
+
+	_catchTransitionEnd: function (e) {
+		if (this._animatingZoom && e.propertyName.indexOf('transform') >= 0) {
+			this._onZoomTransitionEnd();
+		}
+	},
+
+	_nothingToAnimate: function () {
+		return !this._container.getElementsByClassName('leaflet-zoom-animated').length;
+	},
+
+	_tryAnimatedZoom: function (center, zoom, options) {
+
+		if (this._animatingZoom) { return true; }
+
+		options = options || {};
+
+		// don't animate if disabled, not supported or zoom difference is too large
+		if (!this._zoomAnimated || options.animate === false || this._nothingToAnimate() ||
+		        Math.abs(zoom - this._zoom) > this.options.zoomAnimationThreshold) { return false; }
+
+		// offset is the pixel coords of the zoom origin relative to the current center
+		var scale = this.getZoomScale(zoom),
+		    offset = this._getCenterOffset(center)._divideBy(1 - 1 / scale);
+
+		// don't animate if the zoom origin isn't within one screen from the current center, unless forced
+		if (options.animate !== true && !this.getSize().contains(offset)) { return false; }
+
+		requestAnimFrame(function () {
+			this
+			    ._moveStart(true, false)
+			    ._animateZoom(center, zoom, true);
+		}, this);
+
+		return true;
+	},
+
+	_animateZoom: function (center, zoom, startAnim, noUpdate) {
+		if (!this._mapPane) { return; }
+
+		if (startAnim) {
+			this._animatingZoom = true;
+
+			// remember what center/zoom to set after animation
+			this._animateToCenter = center;
+			this._animateToZoom = zoom;
+
+			addClass(this._mapPane, 'leaflet-zoom-anim');
+		}
+
+		// @event zoomanim: ZoomAnimEvent
+		// Fired on every frame of a zoom animation
+		this.fire('zoomanim', {
+			center: center,
+			zoom: zoom,
+			noUpdate: noUpdate
+		});
+
+		// Work around webkit not firing 'transitionend', see https://github.com/Leaflet/Leaflet/issues/3689, 2693
+		setTimeout(bind(this._onZoomTransitionEnd, this), 250);
+	},
+
+	_onZoomTransitionEnd: function () {
+		if (!this._animatingZoom) { return; }
+
+		if (this._mapPane) {
+			removeClass(this._mapPane, 'leaflet-zoom-anim');
+		}
+
+		this._animatingZoom = false;
+
+		this._move(this._animateToCenter, this._animateToZoom);
+
+		// This anim frame should prevent an obscure iOS webkit tile loading race condition.
+		requestAnimFrame(function () {
+			this._moveEnd(true);
+		}, this);
+	}
+});
+
+// @section
+
+// @factory L.map(id: String, options?: Map options)
+// Instantiates a map object given the DOM ID of a `<div>` element
+// and optionally an object literal with `Map options`.
+//
+// @alternative
+// @factory L.map(el: HTMLElement, options?: Map options)
+// Instantiates a map object given an instance of a `<div>` HTML element
+// and optionally an object literal with `Map options`.
+function createMap(id, options) {
+	return new Map(id, options);
+}
+
+/*
+ * @class Control
+ * @aka L.Control
+ * @inherits Class
+ *
+ * L.Control is a base class for implementing map controls. Handles positioning.
+ * All other controls extend from this class.
+ */
+
+var Control = Class.extend({
+	// @section
+	// @aka Control options
+	options: {
+		// @option position: String = 'topright'
+		// The position of the control (one of the map corners). Possible values are `'topleft'`,
+		// `'topright'`, `'bottomleft'` or `'bottomright'`
+		position: 'topright'
+	},
+
+	initialize: function (options) {
+		setOptions(this, options);
+	},
+
+	/* @section
+	 * Classes extending L.Control will inherit the following methods:
+	 *
+	 * @method getPosition: string
+	 * Returns the position of the control.
+	 */
+	getPosition: function () {
+		return this.options.position;
+	},
+
+	// @method setPosition(position: string): this
+	// Sets the position of the control.
+	setPosition: function (position) {
+		var map = this._map;
+
+		if (map) {
+			map.removeControl(this);
+		}
+
+		this.options.position = position;
+
+		if (map) {
+			map.addControl(this);
+		}
+
+		return this;
+	},
+
+	// @method getContainer: HTMLElement
+	// Returns the HTMLElement that contains the control.
+	getContainer: function () {
+		return this._container;
+	},
+
+	// @method addTo(map: Map): this
+	// Adds the control to the given map.
+	addTo: function (map) {
+		this.remove();
+		this._map = map;
+
+		var container = this._container = this.onAdd(map),
+		    pos = this.getPosition(),
+		    corner = map._controlCorners[pos];
+
+		addClass(container, 'leaflet-control');
+
+		if (pos.indexOf('bottom') !== -1) {
+			corner.insertBefore(container, corner.firstChild);
+		} else {
+			corner.appendChild(container);
+		}
+
+		return this;
+	},
+
+	// @method remove: this
+	// Removes the control from the map it is currently active on.
+	remove: function () {
+		if (!this._map) {
+			return this;
+		}
+
+		remove(this._container);
+
+		if (this.onRemove) {
+			this.onRemove(this._map);
+		}
+
+		this._map = null;
+
+		return this;
+	},
+
+	_refocusOnMap: function (e) {
+		// if map exists and event is not a keyboard event
+		if (this._map && e && e.screenX > 0 && e.screenY > 0) {
+			this._map.getContainer().focus();
+		}
+	}
+});
+
+var control = function (options) {
+	return new Control(options);
+};
+
+/* @section Extension methods
+ * @uninheritable
+ *
+ * Every control should extend from `L.Control` and (re-)implement the following methods.
+ *
+ * @method onAdd(map: Map): HTMLElement
+ * Should return the container DOM element for the control and add listeners on relevant map events. Called on [`control.addTo(map)`](#control-addTo).
+ *
+ * @method onRemove(map: Map)
+ * Optional method. Should contain all clean up code that removes the listeners previously added in [`onAdd`](#control-onadd). Called on [`control.remove()`](#control-remove).
+ */
+
+/* @namespace Map
+ * @section Methods for Layers and Controls
+ */
+Map.include({
+	// @method addControl(control: Control): this
+	// Adds the given control to the map
+	addControl: function (control) {
+		control.addTo(this);
+		return this;
+	},
+
+	// @method removeControl(control: Control): this
+	// Removes the given control from the map
+	removeControl: function (control) {
+		control.remove();
+		return this;
+	},
+
+	_initControlPos: function () {
+		var corners = this._controlCorners = {},
+		    l = 'leaflet-',
+		    container = this._controlContainer =
+		            create$1('div', l + 'control-container', this._container);
+
+		function createCorner(vSide, hSide) {
+			var className = l + vSide + ' ' + l + hSide;
+
+			corners[vSide + hSide] = create$1('div', className, container);
+		}
+
+		createCorner('top', 'left');
+		createCorner('top', 'right');
+		createCorner('bottom', 'left');
+		createCorner('bottom', 'right');
+	},
+
+	_clearControlPos: function () {
+		for (var i in this._controlCorners) {
+			remove(this._controlCorners[i]);
+		}
+		remove(this._controlContainer);
+		delete this._controlCorners;
+		delete this._controlContainer;
+	}
+});
+
+/*
+ * @class Control.Layers
+ * @aka L.Control.Layers
+ * @inherits Control
+ *
+ * The layers control gives users the ability to switch between different base layers and switch overlays on/off (check out the [detailed example](http://leafletjs.com/examples/layers-control/)). Extends `Control`.
+ *
+ * @example
+ *
+ * ```js
+ * var baseLayers = {
+ * 	"Mapbox": mapbox,
+ * 	"OpenStreetMap": osm
+ * };
+ *
+ * var overlays = {
+ * 	"Marker": marker,
+ * 	"Roads": roadsLayer
+ * };
+ *
+ * L.control.layers(baseLayers, overlays).addTo(map);
+ * ```
+ *
+ * The `baseLayers` and `overlays` parameters are object literals with layer names as keys and `Layer` objects as values:
+ *
+ * ```js
+ * {
+ *     "<someName1>": layer1,
+ *     "<someName2>": layer2
+ * }
+ * ```
+ *
+ * The layer names can contain HTML, which allows you to add additional styling to the items:
+ *
+ * ```js
+ * {"<img src='my-layer-icon' /> <span class='my-layer-item'>My Layer</span>": myLayer}
+ * ```
+ */
+
+var Layers = Control.extend({
+	// @section
+	// @aka Control.Layers options
+	options: {
+		// @option collapsed: Boolean = true
+		// If `true`, the control will be collapsed into an icon and expanded on mouse hover or touch.
+		collapsed: true,
+		position: 'topright',
+
+		// @option autoZIndex: Boolean = true
+		// If `true`, the control will assign zIndexes in increasing order to all of its layers so that the order is preserved when switching them on/off.
+		autoZIndex: true,
+
+		// @option hideSingleBase: Boolean = false
+		// If `true`, the base layers in the control will be hidden when there is only one.
+		hideSingleBase: false,
+
+		// @option sortLayers: Boolean = false
+		// Whether to sort the layers. When `false`, layers will keep the order
+		// in which they were added to the control.
+		sortLayers: false,
+
+		// @option sortFunction: Function = *
+		// A [compare function](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Array/sort)
+		// that will be used for sorting the layers, when `sortLayers` is `true`.
+		// The function receives both the `L.Layer` instances and their names, as in
+		// `sortFunction(layerA, layerB, nameA, nameB)`.
+		// By default, it sorts layers alphabetically by their name.
+		sortFunction: function (layerA, layerB, nameA, nameB) {
+			return nameA < nameB ? -1 : (nameB < nameA ? 1 : 0);
+		}
+	},
+
+	initialize: function (baseLayers, overlays, options) {
+		setOptions(this, options);
+
+		this._layerControlInputs = [];
+		this._layers = [];
+		this._lastZIndex = 0;
+		this._handlingClick = false;
+
+		for (var i in baseLayers) {
+			this._addLayer(baseLayers[i], i);
+		}
+
+		for (i in overlays) {
+			this._addLayer(overlays[i], i, true);
+		}
+	},
+
+	onAdd: function (map) {
+		this._initLayout();
+		this._update();
+
+		this._map = map;
+		map.on('zoomend', this._checkDisabledLayers, this);
+
+		for (var i = 0; i < this._layers.length; i++) {
+			this._layers[i].layer.on('add remove', this._onLayerChange, this);
+		}
+
+		return this._container;
+	},
+
+	addTo: function (map) {
+		Control.prototype.addTo.call(this, map);
+		// Trigger expand after Layers Control has been inserted into DOM so that is now has an actual height.
+		return this._expandIfNotCollapsed();
+	},
+
+	onRemove: function () {
+		this._map.off('zoomend', this._checkDisabledLayers, this);
+
+		for (var i = 0; i < this._layers.length; i++) {
+			this._layers[i].layer.off('add remove', this._onLayerChange, this);
+		}
+	},
+
+	// @method addBaseLayer(layer: Layer, name: String): this
+	// Adds a base layer (radio button entry) with the given name to the control.
+	addBaseLayer: function (layer, name) {
+		this._addLayer(layer, name);
+		return (this._map) ? this._update() : this;
+	},
+
+	// @method addOverlay(layer: Layer, name: String): this
+	// Adds an overlay (checkbox entry) with the given name to the control.
+	addOverlay: function (layer, name) {
+		this._addLayer(layer, name, true);
+		return (this._map) ? this._update() : this;
+	},
+
+	// @method removeLayer(layer: Layer): this
+	// Remove the given layer from the control.
+	removeLayer: function (layer) {
+		layer.off('add remove', this._onLayerChange, this);
+
+		var obj = this._getLayer(stamp(layer));
+		if (obj) {
+			this._layers.splice(this._layers.indexOf(obj), 1);
+		}
+		return (this._map) ? this._update() : this;
+	},
+
+	// @method expand(): this
+	// Expand the control container if collapsed.
+	expand: function () {
+		addClass(this._container, 'leaflet-control-layers-expanded');
+		this._form.style.height = null;
+		var acceptableHeight = this._map.getSize().y - (this._container.offsetTop + 50);
+		if (acceptableHeight < this._form.clientHeight) {
+			addClass(this._form, 'leaflet-control-layers-scrollbar');
+			this._form.style.height = acceptableHeight + 'px';
+		} else {
+			removeClass(this._form, 'leaflet-control-layers-scrollbar');
+		}
+		this._checkDisabledLayers();
+		return this;
+	},
+
+	// @method collapse(): this
+	// Collapse the control container if expanded.
+	collapse: function () {
+		removeClass(this._container, 'leaflet-control-layers-expanded');
+		return this;
+	},
+
+	_initLayout: function () {
+		var className = 'leaflet-control-layers',
+		    container = this._container = create$1('div', className),
+		    collapsed = this.options.collapsed;
+
+		// makes this work on IE touch devices by stopping it from firing a mouseout event when the touch is released
+		container.setAttribute('aria-haspopup', true);
+
+		disableClickPropagation(container);
+		disableScrollPropagation(container);
+
+		var form = this._form = create$1('form', className + '-list');
+
+		if (collapsed) {
+			this._map.on('click', this.collapse, this);
+
+			if (!android) {
+				on(container, {
+					mouseenter: this.expand,
+					mouseleave: this.collapse
+				}, this);
+			}
+		}
+
+		var link = this._layersLink = create$1('a', className + '-toggle', container);
+		link.href = '#';
+		link.title = 'Layers';
+
+		if (touch) {
+			on(link, 'click', stop);
+			on(link, 'click', this.expand, this);
+		} else {
+			on(link, 'focus', this.expand, this);
+		}
+
+		if (!collapsed) {
+			this.expand();
+		}
+
+		this._baseLayersList = create$1('div', className + '-base', form);
+		this._separator = create$1('div', className + '-separator', form);
+		this._overlaysList = create$1('div', className + '-overlays', form);
+
+		container.appendChild(form);
+	},
+
+	_getLayer: function (id) {
+		for (var i = 0; i < this._layers.length; i++) {
+
+			if (this._layers[i] && stamp(this._layers[i].layer) === id) {
+				return this._layers[i];
+			}
+		}
+	},
+
+	_addLayer: function (layer, name, overlay) {
+		if (this._map) {
+			layer.on('add remove', this._onLayerChange, this);
+		}
+
+		this._layers.push({
+			layer: layer,
+			name: name,
+			overlay: overlay
+		});
+
+		if (this.options.sortLayers) {
+			this._layers.sort(bind(function (a, b) {
+				return this.options.sortFunction(a.layer, b.layer, a.name, b.name);
+			}, this));
+		}
+
+		if (this.options.autoZIndex && layer.setZIndex) {
+			this._lastZIndex++;
+			layer.setZIndex(this._lastZIndex);
+		}
+
+		this._expandIfNotCollapsed();
+	},
+
+	_update: function () {
+		if (!this._container) { return this; }
+
+		empty(this._baseLayersList);
+		empty(this._overlaysList);
+
+		this._layerControlInputs = [];
+		var baseLayersPresent, overlaysPresent, i, obj, baseLayersCount = 0;
+
+		for (i = 0; i < this._layers.length; i++) {
+			obj = this._layers[i];
+			this._addItem(obj);
+			overlaysPresent = overlaysPresent || obj.overlay;
+			baseLayersPresent = baseLayersPresent || !obj.overlay;
+			baseLayersCount += !obj.overlay ? 1 : 0;
+		}
+
+		// Hide base layers section if there's only one layer.
+		if (this.options.hideSingleBase) {
+			baseLayersPresent = baseLayersPresent && baseLayersCount > 1;
+			this._baseLayersList.style.display = baseLayersPresent ? '' : 'none';
+		}
+
+		this._separator.style.display = overlaysPresent && baseLayersPresent ? '' : 'none';
+
+		return this;
+	},
+
+	_onLayerChange: function (e) {
+		if (!this._handlingClick) {
+			this._update();
+		}
+
+		var obj = this._getLayer(stamp(e.target));
+
+		// @namespace Map
+		// @section Layer events
+		// @event baselayerchange: LayersControlEvent
+		// Fired when the base layer is changed through the [layer control](#control-layers).
+		// @event overlayadd: LayersControlEvent
+		// Fired when an overlay is selected through the [layer control](#control-layers).
+		// @event overlayremove: LayersControlEvent
+		// Fired when an overlay is deselected through the [layer control](#control-layers).
+		// @namespace Control.Layers
+		var type = obj.overlay ?
+			(e.type === 'add' ? 'overlayadd' : 'overlayremove') :
+			(e.type === 'add' ? 'baselayerchange' : null);
+
+		if (type) {
+			this._map.fire(type, obj);
+		}
+	},
+
+	// IE7 bugs out if you create a radio dynamically, so you have to do it this hacky way (see http://bit.ly/PqYLBe)
+	_createRadioElement: function (name, checked) {
+
+		var radioHtml = '<input type="radio" class="leaflet-control-layers-selector" name="' +
+				name + '"' + (checked ? ' checked="checked"' : '') + '/>';
+
+		var radioFragment = document.createElement('div');
+		radioFragment.innerHTML = radioHtml;
+
+		return radioFragment.firstChild;
+	},
+
+	_addItem: function (obj) {
+		var label = document.createElement('label'),
+		    checked = this._map.hasLayer(obj.layer),
+		    input;
+
+		if (obj.overlay) {
+			input = document.createElement('input');
+			input.type = 'checkbox';
+			input.className = 'leaflet-control-layers-selector';
+			input.defaultChecked = checked;
+		} else {
+			input = this._createRadioElement('leaflet-base-layers', checked);
+		}
+
+		this._layerControlInputs.push(input);
+		input.layerId = stamp(obj.layer);
+
+		on(input, 'click', this._onInputClick, this);
+
+		var name = document.createElement('span');
+		name.innerHTML = ' ' + obj.name;
+
+		// Helps from preventing layer control flicker when checkboxes are disabled
+		// https://github.com/Leaflet/Leaflet/issues/2771
+		var holder = document.createElement('div');
+
+		label.appendChild(holder);
+		holder.appendChild(input);
+		holder.appendChild(name);
+
+		var container = obj.overlay ? this._overlaysList : this._baseLayersList;
+		container.appendChild(label);
+
+		this._checkDisabledLayers();
+		return label;
+	},
+
+	_onInputClick: function () {
+		var inputs = this._layerControlInputs,
+		    input, layer;
+		var addedLayers = [],
+		    removedLayers = [];
+
+		this._handlingClick = true;
+
+		for (var i = inputs.length - 1; i >= 0; i--) {
+			input = inputs[i];
+			layer = this._getLayer(input.layerId).layer;
+
+			if (input.checked) {
+				addedLayers.push(layer);
+			} else if (!input.checked) {
+				removedLayers.push(layer);
+			}
+		}
+
+		// Bugfix issue 2318: Should remove all old layers before readding new ones
+		for (i = 0; i < removedLayers.length; i++) {
+			if (this._map.hasLayer(removedLayers[i])) {
+				this._map.removeLayer(removedLayers[i]);
+			}
+		}
+		for (i = 0; i < addedLayers.length; i++) {
+			if (!this._map.hasLayer(addedLayers[i])) {
+				this._map.addLayer(addedLayers[i]);
+			}
+		}
+
+		this._handlingClick = false;
+
+		this._refocusOnMap();
+	},
+
+	_checkDisabledLayers: function () {
+		var inputs = this._layerControlInputs,
+		    input,
+		    layer,
+		    zoom = this._map.getZoom();
+
+		for (var i = inputs.length - 1; i >= 0; i--) {
+			input = inputs[i];
+			layer = this._getLayer(input.layerId).layer;
+			input.disabled = (layer.options.minZoom !== undefined && zoom < layer.options.minZoom) ||
+			                 (layer.options.maxZoom !== undefined && zoom > layer.options.maxZoom);
+
+		}
+	},
+
+	_expandIfNotCollapsed: function () {
+		if (this._map && !this.options.collapsed) {
+			this.expand();
+		}
+		return this;
+	},
+
+	_expand: function () {
+		// Backward compatibility, remove me in 1.1.
+		return this.expand();
+	},
+
+	_collapse: function () {
+		// Backward compatibility, remove me in 1.1.
+		return this.collapse();
+	}
+
+});
+
+
+// @factory L.control.layers(baselayers?: Object, overlays?: Object, options?: Control.Layers options)
+// Creates an attribution control with the given layers. Base layers will be switched with radio buttons, while overlays will be switched with checkboxes. Note that all base layers should be passed in the base layers object, but only one should be added to the map during map instantiation.
+var layers = function (baseLayers, overlays, options) {
+	return new Layers(baseLayers, overlays, options);
+};
+
+/*
+ * @class Control.Zoom
+ * @aka L.Control.Zoom
+ * @inherits Control
+ *
+ * A basic zoom control with two buttons (zoom in and zoom out). It is put on the map by default unless you set its [`zoomControl` option](#map-zoomcontrol) to `false`. Extends `Control`.
+ */
+
+var Zoom = Control.extend({
+	// @section
+	// @aka Control.Zoom options
+	options: {
+		position: 'topleft',
+
+		// @option zoomInText: String = '+'
+		// The text set on the 'zoom in' button.
+		zoomInText: '+',
+
+		// @option zoomInTitle: String = 'Zoom in'
+		// The title set on the 'zoom in' button.
+		zoomInTitle: 'Zoom in',
+
+		// @option zoomOutText: String = '&#x2212;'
+		// The text set on the 'zoom out' button.
+		zoomOutText: '&#x2212;',
+
+		// @option zoomOutTitle: String = 'Zoom out'
+		// The title set on the 'zoom out' button.
+		zoomOutTitle: 'Zoom out'
+	},
+
+	onAdd: function (map) {
+		var zoomName = 'leaflet-control-zoom',
+		    container = create$1('div', zoomName + ' leaflet-bar'),
+		    options = this.options;
+
+		this._zoomInButton  = this._createButton(options.zoomInText, options.zoomInTitle,
+		        zoomName + '-in',  container, this._zoomIn);
+		this._zoomOutButton = this._createButton(options.zoomOutText, options.zoomOutTitle,
+		        zoomName + '-out', container, this._zoomOut);
+
+		this._updateDisabled();
+		map.on('zoomend zoomlevelschange', this._updateDisabled, this);
+
+		return container;
+	},
+
+	onRemove: function (map) {
+		map.off('zoomend zoomlevelschange', this._updateDisabled, this);
+	},
+
+	disable: function () {
+		this._disabled = true;
+		this._updateDisabled();
+		return this;
+	},
+
+	enable: function () {
+		this._disabled = false;
+		this._updateDisabled();
+		return this;
+	},
+
+	_zoomIn: function (e) {
+		if (!this._disabled && this._map._zoom < this._map.getMaxZoom()) {
+			this._map.zoomIn(this._map.options.zoomDelta * (e.shiftKey ? 3 : 1));
+		}
+	},
+
+	_zoomOut: function (e) {
+		if (!this._disabled && this._map._zoom > this._map.getMinZoom()) {
+			this._map.zoomOut(this._map.options.zoomDelta * (e.shiftKey ? 3 : 1));
+		}
+	},
+
+	_createButton: function (html, title, className, container, fn) {
+		var link = create$1('a', className, container);
+		link.innerHTML = html;
+		link.href = '#';
+		link.title = title;
+
+		/*
+		 * Will force screen readers like VoiceOver to read this as "Zoom in - button"
+		 */
+		link.setAttribute('role', 'button');
+		link.setAttribute('aria-label', title);
+
+		disableClickPropagation(link);
+		on(link, 'click', stop);
+		on(link, 'click', fn, this);
+		on(link, 'click', this._refocusOnMap, this);
+
+		return link;
+	},
+
+	_updateDisabled: function () {
+		var map = this._map,
+		    className = 'leaflet-disabled';
+
+		removeClass(this._zoomInButton, className);
+		removeClass(this._zoomOutButton, className);
+
+		if (this._disabled || map._zoom === map.getMinZoom()) {
+			addClass(this._zoomOutButton, className);
+		}
+		if (this._disabled || map._zoom === map.getMaxZoom()) {
+			addClass(this._zoomInButton, className);
+		}
+	}
+});
+
+// @namespace Map
+// @section Control options
+// @option zoomControl: Boolean = true
+// Whether a [zoom control](#control-zoom) is added to the map by default.
+Map.mergeOptions({
+	zoomControl: true
+});
+
+Map.addInitHook(function () {
+	if (this.options.zoomControl) {
+		this.zoomControl = new Zoom();
+		this.addControl(this.zoomControl);
+	}
+});
+
+// @namespace Control.Zoom
+// @factory L.control.zoom(options: Control.Zoom options)
+// Creates a zoom control
+var zoom = function (options) {
+	return new Zoom(options);
+};
+
+/*
+ * @class Control.Scale
+ * @aka L.Control.Scale
+ * @inherits Control
+ *
+ * A simple scale control that shows the scale of the current center of screen in metric (m/km) and imperial (mi/ft) systems. Extends `Control`.
+ *
+ * @example
+ *
+ * ```js
+ * L.control.scale().addTo(map);
+ * ```
+ */
+
+var Scale = Control.extend({
+	// @section
+	// @aka Control.Scale options
+	options: {
+		position: 'bottomleft',
+
+		// @option maxWidth: Number = 100
+		// Maximum width of the control in pixels. The width is set dynamically to show round values (e.g. 100, 200, 500).
+		maxWidth: 100,
+
+		// @option metric: Boolean = True
+		// Whether to show the metric scale line (m/km).
+		metric: true,
+
+		// @option imperial: Boolean = True
+		// Whether to show the imperial scale line (mi/ft).
+		imperial: true
+
+		// @option updateWhenIdle: Boolean = false
+		// If `true`, the control is updated on [`moveend`](#map-moveend), otherwise it's always up-to-date (updated on [`move`](#map-move)).
+	},
+
+	onAdd: function (map) {
+		var className = 'leaflet-control-scale',
+		    container = create$1('div', className),
+		    options = this.options;
+
+		this._addScales(options, className + '-line', container);
+
+		map.on(options.updateWhenIdle ? 'moveend' : 'move', this._update, this);
+		map.whenReady(this._update, this);
+
+		return container;
+	},
+
+	onRemove: function (map) {
+		map.off(this.options.updateWhenIdle ? 'moveend' : 'move', this._update, this);
+	},
+
+	_addScales: function (options, className, container) {
+		if (options.metric) {
+			this._mScale = create$1('div', className, container);
+		}
+		if (options.imperial) {
+			this._iScale = create$1('div', className, container);
+		}
+	},
+
+	_update: function () {
+		var map = this._map,
+		    y = map.getSize().y / 2;
+
+		var maxMeters = map.distance(
+			map.containerPointToLatLng([0, y]),
+			map.containerPointToLatLng([this.options.maxWidth, y]));
+
+		this._updateScales(maxMeters);
+	},
+
+	_updateScales: function (maxMeters) {
+		if (this.options.metric && maxMeters) {
+			this._updateMetric(maxMeters);
+		}
+		if (this.options.imperial && maxMeters) {
+			this._updateImperial(maxMeters);
+		}
+	},
+
+	_updateMetric: function (maxMeters) {
+		var meters = this._getRoundNum(maxMeters),
+		    label = meters < 1000 ? meters + ' m' : (meters / 1000) + ' km';
+
+		this._updateScale(this._mScale, label, meters / maxMeters);
+	},
+
+	_updateImperial: function (maxMeters) {
+		var maxFeet = maxMeters * 3.2808399,
+		    maxMiles, miles, feet;
+
+		if (maxFeet > 5280) {
+			maxMiles = maxFeet / 5280;
+			miles = this._getRoundNum(maxMiles);
+			this._updateScale(this._iScale, miles + ' mi', miles / maxMiles);
+
+		} else {
+			feet = this._getRoundNum(maxFeet);
+			this._updateScale(this._iScale, feet + ' ft', feet / maxFeet);
+		}
+	},
+
+	_updateScale: function (scale, text, ratio) {
+		scale.style.width = Math.round(this.options.maxWidth * ratio) + 'px';
+		scale.innerHTML = text;
+	},
+
+	_getRoundNum: function (num) {
+		var pow10 = Math.pow(10, (Math.floor(num) + '').length - 1),
+		    d = num / pow10;
+
+		d = d >= 10 ? 10 :
+		    d >= 5 ? 5 :
+		    d >= 3 ? 3 :
+		    d >= 2 ? 2 : 1;
+
+		return pow10 * d;
+	}
+});
+
+
+// @factory L.control.scale(options?: Control.Scale options)
+// Creates an scale control with the given options.
+var scale = function (options) {
+	return new Scale(options);
+};
+
+/*
+ * @class Control.Attribution
+ * @aka L.Control.Attribution
+ * @inherits Control
+ *
+ * The attribution control allows you to display attribution data in a small text box on a map. It is put on the map by default unless you set its [`attributionControl` option](#map-attributioncontrol) to `false`, and it fetches attribution texts from layers with the [`getAttribution` method](#layer-getattribution) automatically. Extends Control.
+ */
+
+var Attribution = Control.extend({
+	// @section
+	// @aka Control.Attribution options
+	options: {
+		position: 'bottomright',
+
+		// @option prefix: String = 'Leaflet'
+		// The HTML text shown before the attributions. Pass `false` to disable.
+		prefix: '<a href="http://leafletjs.com" title="A JS library for interactive maps">Leaflet</a>'
+	},
+
+	initialize: function (options) {
+		setOptions(this, options);
+
+		this._attributions = {};
+	},
+
+	onAdd: function (map) {
+		map.attributionControl = this;
+		this._container = create$1('div', 'leaflet-control-attribution');
+		disableClickPropagation(this._container);
+
+		// TODO ugly, refactor
+		for (var i in map._layers) {
+			if (map._layers[i].getAttribution) {
+				this.addAttribution(map._layers[i].getAttribution());
+			}
+		}
+
+		this._update();
+
+		return this._container;
+	},
+
+	// @method setPrefix(prefix: String): this
+	// Sets the text before the attributions.
+	setPrefix: function (prefix) {
+		this.options.prefix = prefix;
+		this._update();
+		return this;
+	},
+
+	// @method addAttribution(text: String): this
+	// Adds an attribution text (e.g. `'Vector data &copy; Mapbox'`).
+	addAttribution: function (text) {
+		if (!text) { return this; }
+
+		if (!this._attributions[text]) {
+			this._attributions[text] = 0;
+		}
+		this._attributions[text]++;
+
+		this._update();
+
+		return this;
+	},
+
+	// @method removeAttribution(text: String): this
+	// Removes an attribution text.
+	removeAttribution: function (text) {
+		if (!text) { return this; }
+
+		if (this._attributions[text]) {
+			this._attributions[text]--;
+			this._update();
+		}
+
+		return this;
+	},
+
+	_update: function () {
+		if (!this._map) { return; }
+
+		var attribs = [];
+
+		for (var i in this._attributions) {
+			if (this._attributions[i]) {
+				attribs.push(i);
+			}
+		}
+
+		var prefixAndAttribs = [];
+
+		if (this.options.prefix) {
+			prefixAndAttribs.push(this.options.prefix);
+		}
+		if (attribs.length) {
+			prefixAndAttribs.push(attribs.join(', '));
+		}
+
+		this._container.innerHTML = prefixAndAttribs.join(' | ');
+	}
+});
+
+// @namespace Map
+// @section Control options
+// @option attributionControl: Boolean = true
+// Whether a [attribution control](#control-attribution) is added to the map by default.
+Map.mergeOptions({
+	attributionControl: true
+});
+
+Map.addInitHook(function () {
+	if (this.options.attributionControl) {
+		new Attribution().addTo(this);
+	}
+});
+
+// @namespace Control.Attribution
+// @factory L.control.attribution(options: Control.Attribution options)
+// Creates an attribution control.
+var attribution = function (options) {
+	return new Attribution(options);
+};
+
+Control.Layers = Layers;
+Control.Zoom = Zoom;
+Control.Scale = Scale;
+Control.Attribution = Attribution;
+
+control.layers = layers;
+control.zoom = zoom;
+control.scale = scale;
+control.attribution = attribution;
+
+/*
+	L.Handler is a base class for handler classes that are used internally to inject
+	interaction features like dragging to classes like Map and Marker.
+*/
+
+// @class Handler
+// @aka L.Handler
+// Abstract class for map interaction handlers
+
+var Handler = Class.extend({
+	initialize: function (map) {
+		this._map = map;
+	},
+
+	// @method enable(): this
+	// Enables the handler
+	enable: function () {
+		if (this._enabled) { return this; }
+
+		this._enabled = true;
+		this.addHooks();
+		return this;
+	},
+
+	// @method disable(): this
+	// Disables the handler
+	disable: function () {
+		if (!this._enabled) { return this; }
+
+		this._enabled = false;
+		this.removeHooks();
+		return this;
+	},
+
+	// @method enabled(): Boolean
+	// Returns `true` if the handler is enabled
+	enabled: function () {
+		return !!this._enabled;
+	}
+
+	// @section Extension methods
+	// Classes inheriting from `Handler` must implement the two following methods:
+	// @method addHooks()
+	// Called when the handler is enabled, should add event hooks.
+	// @method removeHooks()
+	// Called when the handler is disabled, should remove the event hooks added previously.
+});
+
+// @section There is static function which can be called without instantiating L.Handler:
+// @function addTo(map: Map, name: String): this
+// Adds a new Handler to the given map with the given name.
+Handler.addTo = function (map, name) {
+	map.addHandler(name, this);
+	return this;
+};
+
+var Mixin = {Events: Events};
+
+/*
+ * @class Draggable
+ * @aka L.Draggable
+ * @inherits Evented
+ *
+ * A class for making DOM elements draggable (including touch support).
+ * Used internally for map and marker dragging. Only works for elements
+ * that were positioned with [`L.DomUtil.setPosition`](#domutil-setposition).
+ *
+ * @example
+ * ```js
+ * var draggable = new L.Draggable(elementToDrag);
+ * draggable.enable();
+ * ```
+ */
+
+var START = touch ? 'touchstart mousedown' : 'mousedown';
+var END = {
+	mousedown: 'mouseup',
+	touchstart: 'touchend',
+	pointerdown: 'touchend',
+	MSPointerDown: 'touchend'
+};
+var MOVE = {
+	mousedown: 'mousemove',
+	touchstart: 'touchmove',
+	pointerdown: 'touchmove',
+	MSPointerDown: 'touchmove'
+};
+
+
+var Draggable = Evented.extend({
+
+	options: {
+		// @section
+		// @aka Draggable options
+		// @option clickTolerance: Number = 3
+		// The max number of pixels a user can shift the mouse pointer during a click
+		// for it to be considered a valid click (as opposed to a mouse drag).
+		clickTolerance: 3
+	},
+
+	// @constructor L.Draggable(el: HTMLElement, dragHandle?: HTMLElement, preventOutline?: Boolean, options?: Draggable options)
+	// Creates a `Draggable` object for moving `el` when you start dragging the `dragHandle` element (equals `el` itself by default).
+	initialize: function (element, dragStartTarget, preventOutline$$1, options) {
+		setOptions(this, options);
+
+		this._element = element;
+		this._dragStartTarget = dragStartTarget || element;
+		this._preventOutline = preventOutline$$1;
+	},
+
+	// @method enable()
+	// Enables the dragging ability
+	enable: function () {
+		if (this._enabled) { return; }
+
+		on(this._dragStartTarget, START, this._onDown, this);
+
+		this._enabled = true;
+	},
+
+	// @method disable()
+	// Disables the dragging ability
+	disable: function () {
+		if (!this._enabled) { return; }
+
+		// If we're currently dragging this draggable,
+		// disabling it counts as first ending the drag.
+		if (Draggable._dragging === this) {
+			this.finishDrag();
+		}
+
+		off(this._dragStartTarget, START, this._onDown, this);
+
+		this._enabled = false;
+		this._moved = false;
+	},
+
+	_onDown: function (e) {
+		// Ignore simulated events, since we handle both touch and
+		// mouse explicitly; otherwise we risk getting duplicates of
+		// touch events, see #4315.
+		// Also ignore the event if disabled; this happens in IE11
+		// under some circumstances, see #3666.
+		if (e._simulated || !this._enabled) { return; }
+
+		this._moved = false;
+
+		if (hasClass(this._element, 'leaflet-zoom-anim')) { return; }
+
+		if (Draggable._dragging || e.shiftKey || ((e.which !== 1) && (e.button !== 1) && !e.touches)) { return; }
+		Draggable._dragging = this;  // Prevent dragging multiple objects at once.
+
+		if (this._preventOutline) {
+			preventOutline(this._element);
+		}
+
+		disableImageDrag();
+		disableTextSelection();
+
+		if (this._moving) { return; }
+
+		// @event down: Event
+		// Fired when a drag is about to start.
+		this.fire('down');
+
+		var first = e.touches ? e.touches[0] : e;
+
+		this._startPoint = new Point(first.clientX, first.clientY);
+
+		on(document, MOVE[e.type], this._onMove, this);
+		on(document, END[e.type], this._onUp, this);
+	},
+
+	_onMove: function (e) {
+		// Ignore simulated events, since we handle both touch and
+		// mouse explicitly; otherwise we risk getting duplicates of
+		// touch events, see #4315.
+		// Also ignore the event if disabled; this happens in IE11
+		// under some circumstances, see #3666.
+		if (e._simulated || !this._enabled) { return; }
+
+		if (e.touches && e.touches.length > 1) {
+			this._moved = true;
+			return;
+		}
+
+		var first = (e.touches && e.touches.length === 1 ? e.touches[0] : e),
+		    newPoint = new Point(first.clientX, first.clientY),
+		    offset = newPoint.subtract(this._startPoint);
+
+		if (!offset.x && !offset.y) { return; }
+		if (Math.abs(offset.x) + Math.abs(offset.y) < this.options.clickTolerance) { return; }
+
+		preventDefault(e);
+
+		if (!this._moved) {
+			// @event dragstart: Event
+			// Fired when a drag starts
+			this.fire('dragstart');
+
+			this._moved = true;
+			this._startPos = getPosition(this._element).subtract(offset);
+
+			addClass(document.body, 'leaflet-dragging');
+
+			this._lastTarget = e.target || e.srcElement;
+			// IE and Edge do not give the <use> element, so fetch it
+			// if necessary
+			if ((window.SVGElementInstance) && (this._lastTarget instanceof SVGElementInstance)) {
+				this._lastTarget = this._lastTarget.correspondingUseElement;
+			}
+			addClass(this._lastTarget, 'leaflet-drag-target');
+		}
+
+		this._newPos = this._startPos.add(offset);
+		this._moving = true;
+
+		cancelAnimFrame(this._animRequest);
+		this._lastEvent = e;
+		this._animRequest = requestAnimFrame(this._updatePosition, this, true);
+	},
+
+	_updatePosition: function () {
+		var e = {originalEvent: this._lastEvent};
+
+		// @event predrag: Event
+		// Fired continuously during dragging *before* each corresponding
+		// update of the element's position.
+		this.fire('predrag', e);
+		setPosition(this._element, this._newPos);
+
+		// @event drag: Event
+		// Fired continuously during dragging.
+		this.fire('drag', e);
+	},
+
+	_onUp: function (e) {
+		// Ignore simulated events, since we handle both touch and
+		// mouse explicitly; otherwise we risk getting duplicates of
+		// touch events, see #4315.
+		// Also ignore the event if disabled; this happens in IE11
+		// under some circumstances, see #3666.
+		if (e._simulated || !this._enabled) { return; }
+		this.finishDrag();
+	},
+
+	finishDrag: function () {
+		removeClass(document.body, 'leaflet-dragging');
+
+		if (this._lastTarget) {
+			removeClass(this._lastTarget, 'leaflet-drag-target');
+			this._lastTarget = null;
+		}
+
+		for (var i in MOVE) {
+			off(document, MOVE[i], this._onMove, this);
+			off(document, END[i], this._onUp, this);
+		}
+
+		enableImageDrag();
+		enableTextSelection();
+
+		if (this._moved && this._moving) {
+			// ensure drag is not fired after dragend
+			cancelAnimFrame(this._animRequest);
+
+			// @event dragend: DragEndEvent
+			// Fired when the drag ends.
+			this.fire('dragend', {
+				distance: this._newPos.distanceTo(this._startPos)
+			});
+		}
+
+		this._moving = false;
+		Draggable._dragging = false;
+	}
+
+});
+
+/*
+ * @namespace LineUtil
+ *
+ * Various utility functions for polyline points processing, used by Leaflet internally to make polylines lightning-fast.
+ */
+
+// Simplify polyline with vertex reduction and Douglas-Peucker simplification.
+// Improves rendering performance dramatically by lessening the number of points to draw.
+
+// @function simplify(points: Point[], tolerance: Number): Point[]
+// Dramatically reduces the number of points in a polyline while retaining
+// its shape and returns a new array of simplified points, using the
+// [Douglas-Peucker algorithm](http://en.wikipedia.org/wiki/Douglas-Peucker_algorithm).
+// Used for a huge performance boost when processing/displaying Leaflet polylines for
+// each zoom level and also reducing visual noise. tolerance affects the amount of
+// simplification (lesser value means higher quality but slower and with more points).
+// Also released as a separated micro-library [Simplify.js](http://mourner.github.com/simplify-js/).
+function simplify(points, tolerance) {
+	if (!tolerance || !points.length) {
+		return points.slice();
+	}
+
+	var sqTolerance = tolerance * tolerance;
+
+	    // stage 1: vertex reduction
+	    points = _reducePoints(points, sqTolerance);
+
+	    // stage 2: Douglas-Peucker simplification
+	    points = _simplifyDP(points, sqTolerance);
+
+	return points;
+}
+
+// @function pointToSegmentDistance(p: Point, p1: Point, p2: Point): Number
+// Returns the distance between point `p` and segment `p1` to `p2`.
+function pointToSegmentDistance(p, p1, p2) {
+	return Math.sqrt(_sqClosestPointOnSegment(p, p1, p2, true));
+}
+
+// @function closestPointOnSegment(p: Point, p1: Point, p2: Point): Number
+// Returns the closest point from a point `p` on a segment `p1` to `p2`.
+function closestPointOnSegment(p, p1, p2) {
+	return _sqClosestPointOnSegment(p, p1, p2);
+}
+
+// Douglas-Peucker simplification, see http://en.wikipedia.org/wiki/Douglas-Peucker_algorithm
+function _simplifyDP(points, sqTolerance) {
+
+	var len = points.length,
+	    ArrayConstructor = typeof Uint8Array !== undefined + '' ? Uint8Array : Array,
+	    markers = new ArrayConstructor(len);
+
+	    markers[0] = markers[len - 1] = 1;
+
+	_simplifyDPStep(points, markers, sqTolerance, 0, len - 1);
+
+	var i,
+	    newPoints = [];
+
+	for (i = 0; i < len; i++) {
+		if (markers[i]) {
+			newPoints.push(points[i]);
+		}
+	}
+
+	return newPoints;
+}
+
+function _simplifyDPStep(points, markers, sqTolerance, first, last) {
+
+	var maxSqDist = 0,
+	index, i, sqDist;
+
+	for (i = first + 1; i <= last - 1; i++) {
+		sqDist = _sqClosestPointOnSegment(points[i], points[first], points[last], true);
+
+		if (sqDist > maxSqDist) {
+			index = i;
+			maxSqDist = sqDist;
+		}
+	}
+
+	if (maxSqDist > sqTolerance) {
+		markers[index] = 1;
+
+		_simplifyDPStep(points, markers, sqTolerance, first, index);
+		_simplifyDPStep(points, markers, sqTolerance, index, last);
+	}
+}
+
+// reduce points that are too close to each other to a single point
+function _reducePoints(points, sqTolerance) {
+	var reducedPoints = [points[0]];
+
+	for (var i = 1, prev = 0, len = points.length; i < len; i++) {
+		if (_sqDist(points[i], points[prev]) > sqTolerance) {
+			reducedPoints.push(points[i]);
+			prev = i;
+		}
+	}
+	if (prev < len - 1) {
+		reducedPoints.push(points[len - 1]);
+	}
+	return reducedPoints;
+}
+
+var _lastCode;
+
+// @function clipSegment(a: Point, b: Point, bounds: Bounds, useLastCode?: Boolean, round?: Boolean): Point[]|Boolean
+// Clips the segment a to b by rectangular bounds with the
+// [Cohen-Sutherland algorithm](https://en.wikipedia.org/wiki/Cohen%E2%80%93Sutherland_algorithm)
+// (modifying the segment points directly!). Used by Leaflet to only show polyline
+// points that are on the screen or near, increasing performance.
+function clipSegment(a, b, bounds, useLastCode, round) {
+	var codeA = useLastCode ? _lastCode : _getBitCode(a, bounds),
+	    codeB = _getBitCode(b, bounds),
+
+	    codeOut, p, newCode;
+
+	    // save 2nd code to avoid calculating it on the next segment
+	    _lastCode = codeB;
+
+	while (true) {
+		// if a,b is inside the clip window (trivial accept)
+		if (!(codeA | codeB)) {
+			return [a, b];
+		}
+
+		// if a,b is outside the clip window (trivial reject)
+		if (codeA & codeB) {
+			return false;
+		}
+
+		// other cases
+		codeOut = codeA || codeB;
+		p = _getEdgeIntersection(a, b, codeOut, bounds, round);
+		newCode = _getBitCode(p, bounds);
+
+		if (codeOut === codeA) {
+			a = p;
+			codeA = newCode;
+		} else {
+			b = p;
+			codeB = newCode;
+		}
+	}
+}
+
+function _getEdgeIntersection(a, b, code, bounds, round) {
+	var dx = b.x - a.x,
+	    dy = b.y - a.y,
+	    min = bounds.min,
+	    max = bounds.max,
+	    x, y;
+
+	if (code & 8) { // top
+		x = a.x + dx * (max.y - a.y) / dy;
+		y = max.y;
+
+	} else if (code & 4) { // bottom
+		x = a.x + dx * (min.y - a.y) / dy;
+		y = min.y;
+
+	} else if (code & 2) { // right
+		x = max.x;
+		y = a.y + dy * (max.x - a.x) / dx;
+
+	} else if (code & 1) { // left
+		x = min.x;
+		y = a.y + dy * (min.x - a.x) / dx;
+	}
+
+	return new Point(x, y, round);
+}
+
+function _getBitCode(p, bounds) {
+	var code = 0;
+
+	if (p.x < bounds.min.x) { // left
+		code |= 1;
+	} else if (p.x > bounds.max.x) { // right
+		code |= 2;
+	}
+
+	if (p.y < bounds.min.y) { // bottom
+		code |= 4;
+	} else if (p.y > bounds.max.y) { // top
+		code |= 8;
+	}
+
+	return code;
+}
+
+// square distance (to avoid unnecessary Math.sqrt calls)
+function _sqDist(p1, p2) {
+	var dx = p2.x - p1.x,
+	    dy = p2.y - p1.y;
+	return dx * dx + dy * dy;
+}
+
+// return closest point on segment or distance to that point
+function _sqClosestPointOnSegment(p, p1, p2, sqDist) {
+	var x = p1.x,
+	    y = p1.y,
+	    dx = p2.x - x,
+	    dy = p2.y - y,
+	    dot = dx * dx + dy * dy,
+	    t;
+
+	if (dot > 0) {
+		t = ((p.x - x) * dx + (p.y - y) * dy) / dot;
+
+		if (t > 1) {
+			x = p2.x;
+			y = p2.y;
+		} else if (t > 0) {
+			x += dx * t;
+			y += dy * t;
+		}
+	}
+
+	dx = p.x - x;
+	dy = p.y - y;
+
+	return sqDist ? dx * dx + dy * dy : new Point(x, y);
+}
+
+
+// @function isFlat(latlngs: LatLng[]): Boolean
+// Returns true if `latlngs` is a flat array, false is nested.
+function isFlat(latlngs) {
+	return !isArray(latlngs[0]) || (typeof latlngs[0][0] !== 'object' && typeof latlngs[0][0] !== 'undefined');
+}
+
+function _flat(latlngs) {
+	console.warn('Deprecated use of _flat, please use L.LineUtil.isFlat instead.');
+	return isFlat(latlngs);
+}
+
+
+var LineUtil = (Object.freeze || Object)({
+	simplify: simplify,
+	pointToSegmentDistance: pointToSegmentDistance,
+	closestPointOnSegment: closestPointOnSegment,
+	clipSegment: clipSegment,
+	_getEdgeIntersection: _getEdgeIntersection,
+	_getBitCode: _getBitCode,
+	_sqClosestPointOnSegment: _sqClosestPointOnSegment,
+	isFlat: isFlat,
+	_flat: _flat
+});
+
+/*
+ * @namespace PolyUtil
+ * Various utility functions for polygon geometries.
+ */
+
+/* @function clipPolygon(points: Point[], bounds: Bounds, round?: Boolean): Point[]
+ * Clips the polygon geometry defined by the given `points` by the given bounds (using the [Sutherland-Hodgman algorithm](https://en.wikipedia.org/wiki/Sutherland%E2%80%93Hodgman_algorithm)).
+ * Used by Leaflet to only show polygon points that are on the screen or near, increasing
+ * performance. Note that polygon points needs different algorithm for clipping
+ * than polyline, so there's a separate method for it.
+ */
+function clipPolygon(points, bounds, round) {
+	var clippedPoints,
+	    edges = [1, 4, 2, 8],
+	    i, j, k,
+	    a, b,
+	    len, edge, p;
+
+	for (i = 0, len = points.length; i < len; i++) {
+		points[i]._code = _getBitCode(points[i], bounds);
+	}
+
+	// for each edge (left, bottom, right, top)
+	for (k = 0; k < 4; k++) {
+		edge = edges[k];
+		clippedPoints = [];
+
+		for (i = 0, len = points.length, j = len - 1; i < len; j = i++) {
+			a = points[i];
+			b = points[j];
+
+			// if a is inside the clip window
+			if (!(a._code & edge)) {
+				// if b is outside the clip window (a->b goes out of screen)
+				if (b._code & edge) {
+					p = _getEdgeIntersection(b, a, edge, bounds, round);
+					p._code = _getBitCode(p, bounds);
+					clippedPoints.push(p);
+				}
+				clippedPoints.push(a);
+
+			// else if b is inside the clip window (a->b enters the screen)
+			} else if (!(b._code & edge)) {
+				p = _getEdgeIntersection(b, a, edge, bounds, round);
+				p._code = _getBitCode(p, bounds);
+				clippedPoints.push(p);
+			}
+		}
+		points = clippedPoints;
+	}
+
+	return points;
+}
+
+
+var PolyUtil = (Object.freeze || Object)({
+	clipPolygon: clipPolygon
+});
+
+/*
+ * @namespace Projection
+ * @section
+ * Leaflet comes with a set of already defined Projections out of the box:
+ *
+ * @projection L.Projection.LonLat
+ *
+ * Equirectangular, or Plate Carree projection — the most simple projection,
+ * mostly used by GIS enthusiasts. Directly maps `x` as longitude, and `y` as
+ * latitude. Also suitable for flat worlds, e.g. game maps. Used by the
+ * `EPSG:4326` and `Simple` CRS.
+ */
+
+var LonLat = {
+	project: function (latlng) {
+		return new Point(latlng.lng, latlng.lat);
+	},
+
+	unproject: function (point) {
+		return new LatLng(point.y, point.x);
+	},
+
+	bounds: new Bounds([-180, -90], [180, 90])
+};
+
+/*
+ * @namespace Projection
+ * @projection L.Projection.Mercator
+ *
+ * Elliptical Mercator projection — more complex than Spherical Mercator. Takes into account that Earth is a geoid, not a perfect sphere. Used by the EPSG:3395 CRS.
+ */
+
+var Mercator = {
+	R: 6378137,
+	R_MINOR: 6356752.314245179,
+
+	bounds: new Bounds([-20037508.34279, -15496570.73972], [20037508.34279, 18764656.23138]),
+
+	project: function (latlng) {
+		var d = Math.PI / 180,
+		    r = this.R,
+		    y = latlng.lat * d,
+		    tmp = this.R_MINOR / r,
+		    e = Math.sqrt(1 - tmp * tmp),
+		    con = e * Math.sin(y);
+
+		var ts = Math.tan(Math.PI / 4 - y / 2) / Math.pow((1 - con) / (1 + con), e / 2);
+		y = -r * Math.log(Math.max(ts, 1E-10));
+
+		return new Point(latlng.lng * d * r, y);
+	},
+
+	unproject: function (point) {
+		var d = 180 / Math.PI,
+		    r = this.R,
+		    tmp = this.R_MINOR / r,
+		    e = Math.sqrt(1 - tmp * tmp),
+		    ts = Math.exp(-point.y / r),
+		    phi = Math.PI / 2 - 2 * Math.atan(ts);
+
+		for (var i = 0, dphi = 0.1, con; i < 15 && Math.abs(dphi) > 1e-7; i++) {
+			con = e * Math.sin(phi);
+			con = Math.pow((1 - con) / (1 + con), e / 2);
+			dphi = Math.PI / 2 - 2 * Math.atan(ts * con) - phi;
+			phi += dphi;
+		}
+
+		return new LatLng(phi * d, point.x * d / r);
+	}
+};
+
+/*
+ * @class Projection
+
+ * An object with methods for projecting geographical coordinates of the world onto
+ * a flat surface (and back). See [Map projection](http://en.wikipedia.org/wiki/Map_projection).
+
+ * @property bounds: Bounds
+ * The bounds (specified in CRS units) where the projection is valid
+
+ * @method project(latlng: LatLng): Point
+ * Projects geographical coordinates into a 2D point.
+ * Only accepts actual `L.LatLng` instances, not arrays.
+
+ * @method unproject(point: Point): LatLng
+ * The inverse of `project`. Projects a 2D point into a geographical location.
+ * Only accepts actual `L.Point` instances, not arrays.
+
+ * Note that the projection instances do not inherit from Leafet's `Class` object,
+ * and can't be instantiated. Also, new classes can't inherit from them,
+ * and methods can't be added to them with the `include` function.
+
+ */
+
+
+
+
+var index = (Object.freeze || Object)({
+	LonLat: LonLat,
+	Mercator: Mercator,
+	SphericalMercator: SphericalMercator
+});
+
+/*
+ * @namespace CRS
+ * @crs L.CRS.EPSG3395
+ *
+ * Rarely used by some commercial tile providers. Uses Elliptical Mercator projection.
+ */
+var EPSG3395 = extend({}, Earth, {
+	code: 'EPSG:3395',
+	projection: Mercator,
+
+	transformation: (function () {
+		var scale = 0.5 / (Math.PI * Mercator.R);
+		return toTransformation(scale, 0.5, -scale, 0.5);
+	}())
+});
+
+/*
+ * @namespace CRS
+ * @crs L.CRS.EPSG4326
+ *
+ * A common CRS among GIS enthusiasts. Uses simple Equirectangular projection.
+ *
+ * Leaflet 1.0.x complies with the [TMS coordinate scheme for EPSG:4326](https://wiki.osgeo.org/wiki/Tile_Map_Service_Specification#global-geodetic),
+ * which is a breaking change from 0.7.x behaviour.  If you are using a `TileLayer`
+ * with this CRS, ensure that there are two 256x256 pixel tiles covering the
+ * whole earth at zoom level zero, and that the tile coordinate origin is (-180,+90),
+ * or (-180,-90) for `TileLayer`s with [the `tms` option](#tilelayer-tms) set.
+ */
+
+var EPSG4326 = extend({}, Earth, {
+	code: 'EPSG:4326',
+	projection: LonLat,
+	transformation: toTransformation(1 / 180, 1, -1 / 180, 0.5)
+});
+
+/*
+ * @namespace CRS
+ * @crs L.CRS.Simple
+ *
+ * A simple CRS that maps longitude and latitude into `x` and `y` directly.
+ * May be used for maps of flat surfaces (e.g. game maps). Note that the `y`
+ * axis should still be inverted (going from bottom to top). `distance()` returns
+ * simple euclidean distance.
+ */
+
+var Simple = extend({}, CRS, {
+	projection: LonLat,
+	transformation: toTransformation(1, 0, -1, 0),
+
+	scale: function (zoom) {
+		return Math.pow(2, zoom);
+	},
+
+	zoom: function (scale) {
+		return Math.log(scale) / Math.LN2;
+	},
+
+	distance: function (latlng1, latlng2) {
+		var dx = latlng2.lng - latlng1.lng,
+		    dy = latlng2.lat - latlng1.lat;
+
+		return Math.sqrt(dx * dx + dy * dy);
+	},
+
+	infinite: true
+});
+
+CRS.Earth = Earth;
+CRS.EPSG3395 = EPSG3395;
+CRS.EPSG3857 = EPSG3857;
+CRS.EPSG900913 = EPSG900913;
+CRS.EPSG4326 = EPSG4326;
+CRS.Simple = Simple;
+
+/*
+ * @class Layer
+ * @inherits Evented
+ * @aka L.Layer
+ * @aka ILayer
+ *
+ * A set of methods from the Layer base class that all Leaflet layers use.
+ * Inherits all methods, options and events from `L.Evented`.
+ *
+ * @example
+ *
+ * ```js
+ * var layer = L.Marker(latlng).addTo(map);
+ * layer.addTo(map);
+ * layer.remove();
+ * ```
+ *
+ * @event add: Event
+ * Fired after the layer is added to a map
+ *
+ * @event remove: Event
+ * Fired after the layer is removed from a map
+ */
+
+
+var Layer = Evented.extend({
+
+	// Classes extending `L.Layer` will inherit the following options:
+	options: {
+		// @option pane: String = 'overlayPane'
+		// By default the layer will be added to the map's [overlay pane](#map-overlaypane). Overriding this option will cause the layer to be placed on another pane by default.
+		pane: 'overlayPane',
+
+		// @option attribution: String = null
+		// String to be shown in the attribution control, describes the layer data, e.g. "© Mapbox".
+		attribution: null,
+
+		bubblingMouseEvents: true
+	},
+
+	/* @section
+	 * Classes extending `L.Layer` will inherit the following methods:
+	 *
+	 * @method addTo(map: Map|LayerGroup): this
+	 * Adds the layer to the given map or layer group.
+	 */
+	addTo: function (map) {
+		map.addLayer(this);
+		return this;
+	},
+
+	// @method remove: this
+	// Removes the layer from the map it is currently active on.
+	remove: function () {
+		return this.removeFrom(this._map || this._mapToAdd);
+	},
+
+	// @method removeFrom(map: Map): this
+	// Removes the layer from the given map
+	removeFrom: function (obj) {
+		if (obj) {
+			obj.removeLayer(this);
+		}
+		return this;
+	},
+
+	// @method getPane(name? : String): HTMLElement
+	// Returns the `HTMLElement` representing the named pane on the map. If `name` is omitted, returns the pane for this layer.
+	getPane: function (name) {
+		return this._map.getPane(name ? (this.options[name] || name) : this.options.pane);
+	},
+
+	addInteractiveTarget: function (targetEl) {
+		this._map._targets[stamp(targetEl)] = this;
+		return this;
+	},
+
+	removeInteractiveTarget: function (targetEl) {
+		delete this._map._targets[stamp(targetEl)];
+		return this;
+	},
+
+	// @method getAttribution: String
+	// Used by the `attribution control`, returns the [attribution option](#gridlayer-attribution).
+	getAttribution: function () {
+		return this.options.attribution;
+	},
+
+	_layerAdd: function (e) {
+		var map = e.target;
+
+		// check in case layer gets added and then removed before the map is ready
+		if (!map.hasLayer(this)) { return; }
+
+		this._map = map;
+		this._zoomAnimated = map._zoomAnimated;
+
+		if (this.getEvents) {
+			var events = this.getEvents();
+			map.on(events, this);
+			this.once('remove', function () {
+				map.off(events, this);
+			}, this);
+		}
+
+		this.onAdd(map);
+
+		if (this.getAttribution && map.attributionControl) {
+			map.attributionControl.addAttribution(this.getAttribution());
+		}
+
+		this.fire('add');
+		map.fire('layeradd', {layer: this});
+	}
+});
+
+/* @section Extension methods
+ * @uninheritable
+ *
+ * Every layer should extend from `L.Layer` and (re-)implement the following methods.
+ *
+ * @method onAdd(map: Map): this
+ * Should contain code that creates DOM elements for the layer, adds them to `map panes` where they should belong and puts listeners on relevant map events. Called on [`map.addLayer(layer)`](#map-addlayer).
+ *
+ * @method onRemove(map: Map): this
+ * Should contain all clean up code that removes the layer's elements from the DOM and removes listeners previously added in [`onAdd`](#layer-onadd). Called on [`map.removeLayer(layer)`](#map-removelayer).
+ *
+ * @method getEvents(): Object
+ * This optional method should return an object like `{ viewreset: this._reset }` for [`addEventListener`](#evented-addeventlistener). The event handlers in this object will be automatically added and removed from the map with your layer.
+ *
+ * @method getAttribution(): String
+ * This optional method should return a string containing HTML to be shown on the `Attribution control` whenever the layer is visible.
+ *
+ * @method beforeAdd(map: Map): this
+ * Optional method. Called on [`map.addLayer(layer)`](#map-addlayer), before the layer is added to the map, before events are initialized, without waiting until the map is in a usable state. Use for early initialization only.
+ */
+
+
+/* @namespace Map
+ * @section Layer events
+ *
+ * @event layeradd: LayerEvent
+ * Fired when a new layer is added to the map.
+ *
+ * @event layerremove: LayerEvent
+ * Fired when some layer is removed from the map
+ *
+ * @section Methods for Layers and Controls
+ */
+Map.include({
+	// @method addLayer(layer: Layer): this
+	// Adds the given layer to the map
+	addLayer: function (layer) {
+		if (!layer._layerAdd) {
+			throw new Error('The provided object is not a Layer.');
+		}
+
+		var id = stamp(layer);
+		if (this._layers[id]) { return this; }
+		this._layers[id] = layer;
+
+		layer._mapToAdd = this;
+
+		if (layer.beforeAdd) {
+			layer.beforeAdd(this);
+		}
+
+		this.whenReady(layer._layerAdd, layer);
+
+		return this;
+	},
+
+	// @method removeLayer(layer: Layer): this
+	// Removes the given layer from the map.
+	removeLayer: function (layer) {
+		var id = stamp(layer);
+
+		if (!this._layers[id]) { return this; }
+
+		if (this._loaded) {
+			layer.onRemove(this);
+		}
+
+		if (layer.getAttribution && this.attributionControl) {
+			this.attributionControl.removeAttribution(layer.getAttribution());
+		}
+
+		delete this._layers[id];
+
+		if (this._loaded) {
+			this.fire('layerremove', {layer: layer});
+			layer.fire('remove');
+		}
+
+		layer._map = layer._mapToAdd = null;
+
+		return this;
+	},
+
+	// @method hasLayer(layer: Layer): Boolean
+	// Returns `true` if the given layer is currently added to the map
+	hasLayer: function (layer) {
+		return !!layer && (stamp(layer) in this._layers);
+	},
+
+	/* @method eachLayer(fn: Function, context?: Object): this
+	 * Iterates over the layers of the map, optionally specifying context of the iterator function.
+	 * ```
+	 * map.eachLayer(function(layer){
+	 *     layer.bindPopup('Hello');
+	 * });
+	 * ```
+	 */
+	eachLayer: function (method, context) {
+		for (var i in this._layers) {
+			method.call(context, this._layers[i]);
+		}
+		return this;
+	},
+
+	_addLayers: function (layers) {
+		layers = layers ? (isArray(layers) ? layers : [layers]) : [];
+
+		for (var i = 0, len = layers.length; i < len; i++) {
+			this.addLayer(layers[i]);
+		}
+	},
+
+	_addZoomLimit: function (layer) {
+		if (isNaN(layer.options.maxZoom) || !isNaN(layer.options.minZoom)) {
+			this._zoomBoundLayers[stamp(layer)] = layer;
+			this._updateZoomLevels();
+		}
+	},
+
+	_removeZoomLimit: function (layer) {
+		var id = stamp(layer);
+
+		if (this._zoomBoundLayers[id]) {
+			delete this._zoomBoundLayers[id];
+			this._updateZoomLevels();
+		}
+	},
+
+	_updateZoomLevels: function () {
+		var minZoom = Infinity,
+		    maxZoom = -Infinity,
+		    oldZoomSpan = this._getZoomSpan();
+
+		for (var i in this._zoomBoundLayers) {
+			var options = this._zoomBoundLayers[i].options;
+
+			minZoom = options.minZoom === undefined ? minZoom : Math.min(minZoom, options.minZoom);
+			maxZoom = options.maxZoom === undefined ? maxZoom : Math.max(maxZoom, options.maxZoom);
+		}
+
+		this._layersMaxZoom = maxZoom === -Infinity ? undefined : maxZoom;
+		this._layersMinZoom = minZoom === Infinity ? undefined : minZoom;
+
+		// @section Map state change events
+		// @event zoomlevelschange: Event
+		// Fired when the number of zoomlevels on the map is changed due
+		// to adding or removing a layer.
+		if (oldZoomSpan !== this._getZoomSpan()) {
+			this.fire('zoomlevelschange');
+		}
+
+		if (this.options.maxZoom === undefined && this._layersMaxZoom && this.getZoom() > this._layersMaxZoom) {
+			this.setZoom(this._layersMaxZoom);
+		}
+		if (this.options.minZoom === undefined && this._layersMinZoom && this.getZoom() < this._layersMinZoom) {
+			this.setZoom(this._layersMinZoom);
+		}
+	}
+});
+
+/*
+ * @class LayerGroup
+ * @aka L.LayerGroup
+ * @inherits Layer
+ *
+ * Used to group several layers and handle them as one. If you add it to the map,
+ * any layers added or removed from the group will be added/removed on the map as
+ * well. Extends `Layer`.
+ *
+ * @example
+ *
+ * ```js
+ * L.layerGroup([marker1, marker2])
+ * 	.addLayer(polyline)
+ * 	.addTo(map);
+ * ```
+ */
+
+var LayerGroup = Layer.extend({
+
+	initialize: function (layers, options) {
+		setOptions(this, options);
+
+		this._layers = {};
+
+		var i, len;
+
+		if (layers) {
+			for (i = 0, len = layers.length; i < len; i++) {
+				this.addLayer(layers[i]);
+			}
+		}
+	},
+
+	// @method addLayer(layer: Layer): this
+	// Adds the given layer to the group.
+	addLayer: function (layer) {
+		var id = this.getLayerId(layer);
+
+		this._layers[id] = layer;
+
+		if (this._map) {
+			this._map.addLayer(layer);
+		}
+
+		return this;
+	},
+
+	// @method removeLayer(layer: Layer): this
+	// Removes the given layer from the group.
+	// @alternative
+	// @method removeLayer(id: Number): this
+	// Removes the layer with the given internal ID from the group.
+	removeLayer: function (layer) {
+		var id = layer in this._layers ? layer : this.getLayerId(layer);
+
+		if (this._map && this._layers[id]) {
+			this._map.removeLayer(this._layers[id]);
+		}
+
+		delete this._layers[id];
+
+		return this;
+	},
+
+	// @method hasLayer(layer: Layer): Boolean
+	// Returns `true` if the given layer is currently added to the group.
+	// @alternative
+	// @method hasLayer(id: Number): Boolean
+	// Returns `true` if the given internal ID is currently added to the group.
+	hasLayer: function (layer) {
+		return !!layer && (layer in this._layers || this.getLayerId(layer) in this._layers);
+	},
+
+	// @method clearLayers(): this
+	// Removes all the layers from the group.
+	clearLayers: function () {
+		return this.eachLayer(this.removeLayer, this);
+	},
+
+	// @method invoke(methodName: String, …): this
+	// Calls `methodName` on every layer contained in this group, passing any
+	// additional parameters. Has no effect if the layers contained do not
+	// implement `methodName`.
+	invoke: function (methodName) {
+		var args = Array.prototype.slice.call(arguments, 1),
+		    i, layer;
+
+		for (i in this._layers) {
+			layer = this._layers[i];
+
+			if (layer[methodName]) {
+				layer[methodName].apply(layer, args);
+			}
+		}
+
+		return this;
+	},
+
+	onAdd: function (map) {
+		this.eachLayer(map.addLayer, map);
+	},
+
+	onRemove: function (map) {
+		this.eachLayer(map.removeLayer, map);
+	},
+
+	// @method eachLayer(fn: Function, context?: Object): this
+	// Iterates over the layers of the group, optionally specifying context of the iterator function.
+	// ```js
+	// group.eachLayer(function (layer) {
+	// 	layer.bindPopup('Hello');
+	// });
+	// ```
+	eachLayer: function (method, context) {
+		for (var i in this._layers) {
+			method.call(context, this._layers[i]);
+		}
+		return this;
+	},
+
+	// @method getLayer(id: Number): Layer
+	// Returns the layer with the given internal ID.
+	getLayer: function (id) {
+		return this._layers[id];
+	},
+
+	// @method getLayers(): Layer[]
+	// Returns an array of all the layers added to the group.
+	getLayers: function () {
+		var layers = [];
+		this.eachLayer(layers.push, layers);
+		return layers;
+	},
+
+	// @method setZIndex(zIndex: Number): this
+	// Calls `setZIndex` on every layer contained in this group, passing the z-index.
+	setZIndex: function (zIndex) {
+		return this.invoke('setZIndex', zIndex);
+	},
+
+	// @method getLayerId(layer: Layer): Number
+	// Returns the internal ID for a layer
+	getLayerId: function (layer) {
+		return stamp(layer);
+	}
+});
+
+
+// @factory L.layerGroup(layers?: Layer[], options?: Object)
+// Create a layer group, optionally given an initial set of layers and an `options` object.
+var layerGroup = function (layers, options) {
+	return new LayerGroup(layers, options);
+};
+
+/*
+ * @class FeatureGroup
+ * @aka L.FeatureGroup
+ * @inherits LayerGroup
+ *
+ * Extended `LayerGroup` that makes it easier to do the same thing to all its member layers:
+ *  * [`bindPopup`](#layer-bindpopup) binds a popup to all of the layers at once (likewise with [`bindTooltip`](#layer-bindtooltip))
+ *  * Events are propagated to the `FeatureGroup`, so if the group has an event
+ * handler, it will handle events from any of the layers. This includes mouse events
+ * and custom events.
+ *  * Has `layeradd` and `layerremove` events
+ *
+ * @example
+ *
+ * ```js
+ * L.featureGroup([marker1, marker2, polyline])
+ * 	.bindPopup('Hello world!')
+ * 	.on('click', function() { alert('Clicked on a member of the group!'); })
+ * 	.addTo(map);
+ * ```
+ */
+
+var FeatureGroup = LayerGroup.extend({
+
+	addLayer: function (layer) {
+		if (this.hasLayer(layer)) {
+			return this;
+		}
+
+		layer.addEventParent(this);
+
+		LayerGroup.prototype.addLayer.call(this, layer);
+
+		// @event layeradd: LayerEvent
+		// Fired when a layer is added to this `FeatureGroup`
+		return this.fire('layeradd', {layer: layer});
+	},
+
+	removeLayer: function (layer) {
+		if (!this.hasLayer(layer)) {
+			return this;
+		}
+		if (layer in this._layers) {
+			layer = this._layers[layer];
+		}
+
+		layer.removeEventParent(this);
+
+		LayerGroup.prototype.removeLayer.call(this, layer);
+
+		// @event layerremove: LayerEvent
+		// Fired when a layer is removed from this `FeatureGroup`
+		return this.fire('layerremove', {layer: layer});
+	},
+
+	// @method setStyle(style: Path options): this
+	// Sets the given path options to each layer of the group that has a `setStyle` method.
+	setStyle: function (style) {
+		return this.invoke('setStyle', style);
+	},
+
+	// @method bringToFront(): this
+	// Brings the layer group to the top of all other layers
+	bringToFront: function () {
+		return this.invoke('bringToFront');
+	},
+
+	// @method bringToBack(): this
+	// Brings the layer group to the back of all other layers
+	bringToBack: function () {
+		return this.invoke('bringToBack');
+	},
+
+	// @method getBounds(): LatLngBounds
+	// Returns the LatLngBounds of the Feature Group (created from bounds and coordinates of its children).
+	getBounds: function () {
+		var bounds = new LatLngBounds();
+
+		for (var id in this._layers) {
+			var layer = this._layers[id];
+			bounds.extend(layer.getBounds ? layer.getBounds() : layer.getLatLng());
+		}
+		return bounds;
+	}
+});
+
+// @factory L.featureGroup(layers: Layer[])
+// Create a feature group, optionally given an initial set of layers.
+var featureGroup = function (layers) {
+	return new FeatureGroup(layers);
+};
+
+/*
+ * @class Icon
+ * @aka L.Icon
+ *
+ * Represents an icon to provide when creating a marker.
+ *
+ * @example
+ *
+ * ```js
+ * var myIcon = L.icon({
+ *     iconUrl: 'my-icon.png',
+ *     iconRetinaUrl: 'my-icon@2x.png',
+ *     iconSize: [38, 95],
+ *     iconAnchor: [22, 94],
+ *     popupAnchor: [-3, -76],
+ *     shadowUrl: 'my-icon-shadow.png',
+ *     shadowRetinaUrl: 'my-icon-shadow@2x.png',
+ *     shadowSize: [68, 95],
+ *     shadowAnchor: [22, 94]
+ * });
+ *
+ * L.marker([50.505, 30.57], {icon: myIcon}).addTo(map);
+ * ```
+ *
+ * `L.Icon.Default` extends `L.Icon` and is the blue icon Leaflet uses for markers by default.
+ *
+ */
+
+var Icon = Class.extend({
+
+	/* @section
+	 * @aka Icon options
+	 *
+	 * @option iconUrl: String = null
+	 * **(required)** The URL to the icon image (absolute or relative to your script path).
+	 *
+	 * @option iconRetinaUrl: String = null
+	 * The URL to a retina sized version of the icon image (absolute or relative to your
+	 * script path). Used for Retina screen devices.
+	 *
+	 * @option iconSize: Point = null
+	 * Size of the icon image in pixels.
+	 *
+	 * @option iconAnchor: Point = null
+	 * The coordinates of the "tip" of the icon (relative to its top left corner). The icon
+	 * will be aligned so that this point is at the marker's geographical location. Centered
+	 * by default if size is specified, also can be set in CSS with negative margins.
+	 *
+	 * @option popupAnchor: Point = [0, 0]
+	 * The coordinates of the point from which popups will "open", relative to the icon anchor.
+	 *
+	 * @option tooltipAnchor: Point = [0, 0]
+	 * The coordinates of the point from which tooltips will "open", relative to the icon anchor.
+	 *
+	 * @option shadowUrl: String = null
+	 * The URL to the icon shadow image. If not specified, no shadow image will be created.
+	 *
+	 * @option shadowRetinaUrl: String = null
+	 *
+	 * @option shadowSize: Point = null
+	 * Size of the shadow image in pixels.
+	 *
+	 * @option shadowAnchor: Point = null
+	 * The coordinates of the "tip" of the shadow (relative to its top left corner) (the same
+	 * as iconAnchor if not specified).
+	 *
+	 * @option className: String = ''
+	 * A custom class name to assign to both icon and shadow images. Empty by default.
+	 */
+
+	options: {
+		popupAnchor: [0, 0],
+		tooltipAnchor: [0, 0],
+	},
+
+	initialize: function (options) {
+		setOptions(this, options);
+	},
+
+	// @method createIcon(oldIcon?: HTMLElement): HTMLElement
+	// Called internally when the icon has to be shown, returns a `<img>` HTML element
+	// styled according to the options.
+	createIcon: function (oldIcon) {
+		return this._createIcon('icon', oldIcon);
+	},
+
+	// @method createShadow(oldIcon?: HTMLElement): HTMLElement
+	// As `createIcon`, but for the shadow beneath it.
+	createShadow: function (oldIcon) {
+		return this._createIcon('shadow', oldIcon);
+	},
+
+	_createIcon: function (name, oldIcon) {
+		var src = this._getIconUrl(name);
+
+		if (!src) {
+			if (name === 'icon') {
+				throw new Error('iconUrl not set in Icon options (see the docs).');
+			}
+			return null;
+		}
+
+		var img = this._createImg(src, oldIcon && oldIcon.tagName === 'IMG' ? oldIcon : null);
+		this._setIconStyles(img, name);
+
+		return img;
+	},
+
+	_setIconStyles: function (img, name) {
+		var options = this.options;
+		var sizeOption = options[name + 'Size'];
+
+		if (typeof sizeOption === 'number') {
+			sizeOption = [sizeOption, sizeOption];
+		}
+
+		var size = toPoint(sizeOption),
+		    anchor = toPoint(name === 'shadow' && options.shadowAnchor || options.iconAnchor ||
+		            size && size.divideBy(2, true));
+
+		img.className = 'leaflet-marker-' + name + ' ' + (options.className || '');
+
+		if (anchor) {
+			img.style.marginLeft = (-anchor.x) + 'px';
+			img.style.marginTop  = (-anchor.y) + 'px';
+		}
+
+		if (size) {
+			img.style.width  = size.x + 'px';
+			img.style.height = size.y + 'px';
+		}
+	},
+
+	_createImg: function (src, el) {
+		el = el || document.createElement('img');
+		el.src = src;
+		return el;
+	},
+
+	_getIconUrl: function (name) {
+		return retina && this.options[name + 'RetinaUrl'] || this.options[name + 'Url'];
+	}
+});
+
+
+// @factory L.icon(options: Icon options)
+// Creates an icon instance with the given options.
+function icon(options) {
+	return new Icon(options);
+}
+
+/*
+ * @miniclass Icon.Default (Icon)
+ * @aka L.Icon.Default
+ * @section
+ *
+ * A trivial subclass of `Icon`, represents the icon to use in `Marker`s when
+ * no icon is specified. Points to the blue marker image distributed with Leaflet
+ * releases.
+ *
+ * In order to customize the default icon, just change the properties of `L.Icon.Default.prototype.options`
+ * (which is a set of `Icon options`).
+ *
+ * If you want to _completely_ replace the default icon, override the
+ * `L.Marker.prototype.options.icon` with your own icon instead.
+ */
+
+var IconDefault = Icon.extend({
+
+	options: {
+		iconUrl:       'marker-icon.png',
+		iconRetinaUrl: 'marker-icon-2x.png',
+		shadowUrl:     'marker-shadow.png',
+		iconSize:    [25, 41],
+		iconAnchor:  [12, 41],
+		popupAnchor: [1, -34],
+		tooltipAnchor: [16, -28],
+		shadowSize:  [41, 41]
+	},
+
+	_getIconUrl: function (name) {
+		if (!IconDefault.imagePath) {	// Deprecated, backwards-compatibility only
+			IconDefault.imagePath = this._detectIconPath();
+		}
+
+		// @option imagePath: String
+		// `Icon.Default` will try to auto-detect the location of the
+		// blue icon images. If you are placing these images in a non-standard
+		// way, set this option to point to the right path.
+		return (this.options.imagePath || IconDefault.imagePath) + Icon.prototype._getIconUrl.call(this, name);
+	},
+
+	_detectIconPath: function () {
+		var el = create$1('div',  'leaflet-default-icon-path', document.body);
+		var path = getStyle(el, 'background-image') ||
+		           getStyle(el, 'backgroundImage');	// IE8
+
+		document.body.removeChild(el);
+
+		if (path === null || path.indexOf('url') !== 0) {
+			path = '';
+		} else {
+			path = path.replace(/^url\(["']?/, '').replace(/marker-icon\.png["']?\)$/, '');
+		}
+
+		return path;
+	}
+});
+
+/*
+ * L.Handler.MarkerDrag is used internally by L.Marker to make the markers draggable.
+ */
+
+
+/* @namespace Marker
+ * @section Interaction handlers
+ *
+ * Interaction handlers are properties of a marker instance that allow you to control interaction behavior in runtime, enabling or disabling certain features such as dragging (see `Handler` methods). Example:
+ *
+ * ```js
+ * marker.dragging.disable();
+ * ```
+ *
+ * @property dragging: Handler
+ * Marker dragging handler (by both mouse and touch). Only valid when the marker is on the map (Otherwise set [`marker.options.draggable`](#marker-draggable)).
+ */
+
+var MarkerDrag = Handler.extend({
+	initialize: function (marker) {
+		this._marker = marker;
+	},
+
+	addHooks: function () {
+		var icon = this._marker._icon;
+
+		if (!this._draggable) {
+			this._draggable = new Draggable(icon, icon, true);
+		}
+
+		this._draggable.on({
+			dragstart: this._onDragStart,
+			predrag: this._onPreDrag,
+			drag: this._onDrag,
+			dragend: this._onDragEnd
+		}, this).enable();
+
+		addClass(icon, 'leaflet-marker-draggable');
+	},
+
+	removeHooks: function () {
+		this._draggable.off({
+			dragstart: this._onDragStart,
+			predrag: this._onPreDrag,
+			drag: this._onDrag,
+			dragend: this._onDragEnd
+		}, this).disable();
+
+		if (this._marker._icon) {
+			removeClass(this._marker._icon, 'leaflet-marker-draggable');
+		}
+	},
+
+	moved: function () {
+		return this._draggable && this._draggable._moved;
+	},
+
+	_adjustPan: function (e) {
+		var marker = this._marker,
+		    map = marker._map,
+		    speed = this._marker.options.autoPanSpeed,
+		    padding = this._marker.options.autoPanPadding,
+		    iconPos = L.DomUtil.getPosition(marker._icon),
+		    bounds = map.getPixelBounds(),
+		    origin = map.getPixelOrigin();
+
+		var panBounds = toBounds(
+			bounds.min._subtract(origin).add(padding),
+			bounds.max._subtract(origin).subtract(padding)
+		);
+
+		if (!panBounds.contains(iconPos)) {
+			// Compute incremental movement
+			var movement = toPoint(
+				(Math.max(panBounds.max.x, iconPos.x) - panBounds.max.x) / (bounds.max.x - panBounds.max.x) -
+				(Math.min(panBounds.min.x, iconPos.x) - panBounds.min.x) / (bounds.min.x - panBounds.min.x),
+
+				(Math.max(panBounds.max.y, iconPos.y) - panBounds.max.y) / (bounds.max.y - panBounds.max.y) -
+				(Math.min(panBounds.min.y, iconPos.y) - panBounds.min.y) / (bounds.min.y - panBounds.min.y)
+			).multiplyBy(speed);
+
+			map.panBy(movement, {animate: false});
+
+			this._draggable._newPos._add(movement);
+			this._draggable._startPos._add(movement);
+
+			L.DomUtil.setPosition(marker._icon, this._draggable._newPos);
+			this._onDrag(e);
+
+			this._panRequest = requestAnimFrame(this._adjustPan.bind(this, e));
+		}
+	},
+
+	_onDragStart: function () {
+		// @section Dragging events
+		// @event dragstart: Event
+		// Fired when the user starts dragging the marker.
+
+		// @event movestart: Event
+		// Fired when the marker starts moving (because of dragging).
+
+		this._oldLatLng = this._marker.getLatLng();
+		this._marker
+		    .closePopup()
+		    .fire('movestart')
+		    .fire('dragstart');
+	},
+
+	_onPreDrag: function (e) {
+		if (this._marker.options.autoPan) {
+			cancelAnimFrame(this._panRequest);
+			this._panRequest = requestAnimFrame(this._adjustPan.bind(this, e));
+		}
+	},
+
+	_onDrag: function (e) {
+		var marker = this._marker,
+		    shadow = marker._shadow,
+		iconPos = getPosition(marker._icon),
+		    latlng = marker._map.layerPointToLatLng(iconPos);
+
+		// update shadow position
+		if (shadow) {
+			setPosition(shadow, iconPos);
+		}
+
+		marker._latlng = latlng;
+		e.latlng = latlng;
+		e.oldLatLng = this._oldLatLng;
+
+		// @event drag: Event
+		// Fired repeatedly while the user drags the marker.
+		marker
+		    .fire('move', e)
+		    .fire('drag', e);
+	},
+
+	_onDragEnd: function (e) {
+		// @event dragend: DragEndEvent
+		// Fired when the user stops dragging the marker.
+
+		 cancelAnimFrame(this._panRequest);
+
+		// @event moveend: Event
+		// Fired when the marker stops moving (because of dragging).
+		delete this._oldLatLng;
+		this._marker
+		    .fire('moveend')
+		    .fire('dragend', e);
+	}
+});
+
+/*
+ * @class Marker
+ * @inherits Interactive layer
+ * @aka L.Marker
+ * L.Marker is used to display clickable/draggable icons on the map. Extends `Layer`.
+ *
+ * @example
+ *
+ * ```js
+ * L.marker([50.5, 30.5]).addTo(map);
+ * ```
+ */
+
+var Marker = Layer.extend({
+
+	// @section
+	// @aka Marker options
+	options: {
+		// @option icon: Icon = *
+		// Icon instance to use for rendering the marker.
+		// See [Icon documentation](#L.Icon) for details on how to customize the marker icon.
+		// If not specified, a common instance of `L.Icon.Default` is used.
+		icon: new IconDefault(),
+
+		// Option inherited from "Interactive layer" abstract class
+		interactive: true,
+
+		// @option draggable: Boolean = false
+		// Whether the marker is draggable with mouse/touch or not.
+		draggable: false,
+
+		// @option autoPan: Boolean = false
+		// Set it to `true` if you want the map to do panning animation when marker hits the edges.
+		autoPan: false,
+
+		// @option autoPanPadding: Point = Point(50, 50)
+		// Equivalent of setting both top left and bottom right autopan padding to the same value.
+		autoPanPadding: [50, 50],
+
+		// @option autoPanSpeed: Number = 10
+		// Number of pixels the map should move by.
+		autoPanSpeed: 10,
+
+		// @option keyboard: Boolean = true
+		// Whether the marker can be tabbed to with a keyboard and clicked by pressing enter.
+		keyboard: true,
+
+		// @option title: String = ''
+		// Text for the browser tooltip that appear on marker hover (no tooltip by default).
+		title: '',
+
+		// @option alt: String = ''
+		// Text for the `alt` attribute of the icon image (useful for accessibility).
+		alt: '',
+
+		// @option zIndexOffset: Number = 0
+		// By default, marker images zIndex is set automatically based on its latitude. Use this option if you want to put the marker on top of all others (or below), specifying a high value like `1000` (or high negative value, respectively).
+		zIndexOffset: 0,
+
+		// @option opacity: Number = 1.0
+		// The opacity of the marker.
+		opacity: 1,
+
+		// @option riseOnHover: Boolean = false
+		// If `true`, the marker will get on top of others when you hover the mouse over it.
+		riseOnHover: false,
+
+		// @option riseOffset: Number = 250
+		// The z-index offset used for the `riseOnHover` feature.
+		riseOffset: 250,
+
+		// @option pane: String = 'markerPane'
+		// `Map pane` where the markers icon will be added.
+		pane: 'markerPane',
+
+		// @option bubblingMouseEvents: Boolean = false
+		// When `true`, a mouse event on this marker will trigger the same event on the map
+		// (unless [`L.DomEvent.stopPropagation`](#domevent-stoppropagation) is used).
+		bubblingMouseEvents: false
+	},
+
+	/* @section
+	 *
+	 * In addition to [shared layer methods](#Layer) like `addTo()` and `remove()` and [popup methods](#Popup) like bindPopup() you can also use the following methods:
+	 */
+
+	initialize: function (latlng, options) {
+		setOptions(this, options);
+		this._latlng = toLatLng(latlng);
+	},
+
+	onAdd: function (map) {
+		this._zoomAnimated = this._zoomAnimated && map.options.markerZoomAnimation;
+
+		if (this._zoomAnimated) {
+			map.on('zoomanim', this._animateZoom, this);
+		}
+
+		this._initIcon();
+		this.update();
+	},
+
+	onRemove: function (map) {
+		if (this.dragging && this.dragging.enabled()) {
+			this.options.draggable = true;
+			this.dragging.removeHooks();
+		}
+		delete this.dragging;
+
+		if (this._zoomAnimated) {
+			map.off('zoomanim', this._animateZoom, this);
+		}
+
+		this._removeIcon();
+		this._removeShadow();
+	},
+
+	getEvents: function () {
+		return {
+			zoom: this.update,
+			viewreset: this.update
+		};
+	},
+
+	// @method getLatLng: LatLng
+	// Returns the current geographical position of the marker.
+	getLatLng: function () {
+		return this._latlng;
+	},
+
+	// @method setLatLng(latlng: LatLng): this
+	// Changes the marker position to the given point.
+	setLatLng: function (latlng) {
+		var oldLatLng = this._latlng;
+		this._latlng = toLatLng(latlng);
+		this.update();
+
+		// @event move: Event
+		// Fired when the marker is moved via [`setLatLng`](#marker-setlatlng) or by [dragging](#marker-dragging). Old and new coordinates are included in event arguments as `oldLatLng`, `latlng`.
+		return this.fire('move', {oldLatLng: oldLatLng, latlng: this._latlng});
+	},
+
+	// @method setZIndexOffset(offset: Number): this
+	// Changes the [zIndex offset](#marker-zindexoffset) of the marker.
+	setZIndexOffset: function (offset) {
+		this.options.zIndexOffset = offset;
+		return this.update();
+	},
+
+	// @method setIcon(icon: Icon): this
+	// Changes the marker icon.
+	setIcon: function (icon) {
+
+		this.options.icon = icon;
+
+		if (this._map) {
+			this._initIcon();
+			this.update();
+		}
+
+		if (this._popup) {
+			this.bindPopup(this._popup, this._popup.options);
+		}
+
+		return this;
+	},
+
+	getElement: function () {
+		return this._icon;
+	},
+
+	update: function () {
+
+		if (this._icon && this._map) {
+			var pos = this._map.latLngToLayerPoint(this._latlng).round();
+			this._setPos(pos);
+		}
+
+		return this;
+	},
+
+	_initIcon: function () {
+		var options = this.options,
+		    classToAdd = 'leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide');
+
+		var icon = options.icon.createIcon(this._icon),
+		    addIcon = false;
+
+		// if we're not reusing the icon, remove the old one and init new one
+		if (icon !== this._icon) {
+			if (this._icon) {
+				this._removeIcon();
+			}
+			addIcon = true;
+
+			if (options.title) {
+				icon.title = options.title;
+			}
+
+			if (icon.tagName === 'IMG') {
+				icon.alt = options.alt || '';
+			}
+		}
+
+		addClass(icon, classToAdd);
+
+		if (options.keyboard) {
+			icon.tabIndex = '0';
+		}
+
+		this._icon = icon;
+
+		if (options.riseOnHover) {
+			this.on({
+				mouseover: this._bringToFront,
+				mouseout: this._resetZIndex
+			});
+		}
+
+		var newShadow = options.icon.createShadow(this._shadow),
+		    addShadow = false;
+
+		if (newShadow !== this._shadow) {
+			this._removeShadow();
+			addShadow = true;
+		}
+
+		if (newShadow) {
+			addClass(newShadow, classToAdd);
+			newShadow.alt = '';
+		}
+		this._shadow = newShadow;
+
+
+		if (options.opacity < 1) {
+			this._updateOpacity();
+		}
+
+
+		if (addIcon) {
+			this.getPane().appendChild(this._icon);
+		}
+		this._initInteraction();
+		if (newShadow && addShadow) {
+			this.getPane('shadowPane').appendChild(this._shadow);
+		}
+	},
+
+	_removeIcon: function () {
+		if (this.options.riseOnHover) {
+			this.off({
+				mouseover: this._bringToFront,
+				mouseout: this._resetZIndex
+			});
+		}
+
+		remove(this._icon);
+		this.removeInteractiveTarget(this._icon);
+
+		this._icon = null;
+	},
+
+	_removeShadow: function () {
+		if (this._shadow) {
+			remove(this._shadow);
+		}
+		this._shadow = null;
+	},
+
+	_setPos: function (pos) {
+		setPosition(this._icon, pos);
+
+		if (this._shadow) {
+			setPosition(this._shadow, pos);
+		}
+
+		this._zIndex = pos.y + this.options.zIndexOffset;
+
+		this._resetZIndex();
+	},
+
+	_updateZIndex: function (offset) {
+		this._icon.style.zIndex = this._zIndex + offset;
+	},
+
+	_animateZoom: function (opt) {
+		var pos = this._map._latLngToNewLayerPoint(this._latlng, opt.zoom, opt.center).round();
+
+		this._setPos(pos);
+	},
+
+	_initInteraction: function () {
+
+		if (!this.options.interactive) { return; }
+
+		addClass(this._icon, 'leaflet-interactive');
+
+		this.addInteractiveTarget(this._icon);
+
+		if (MarkerDrag) {
+			var draggable = this.options.draggable;
+			if (this.dragging) {
+				draggable = this.dragging.enabled();
+				this.dragging.disable();
+			}
+
+			this.dragging = new MarkerDrag(this);
+
+			if (draggable) {
+				this.dragging.enable();
+			}
+		}
+	},
+
+	// @method setOpacity(opacity: Number): this
+	// Changes the opacity of the marker.
+	setOpacity: function (opacity) {
+		this.options.opacity = opacity;
+		if (this._map) {
+			this._updateOpacity();
+		}
+
+		return this;
+	},
+
+	_updateOpacity: function () {
+		var opacity = this.options.opacity;
+
+		setOpacity(this._icon, opacity);
+
+		if (this._shadow) {
+			setOpacity(this._shadow, opacity);
+		}
+	},
+
+	_bringToFront: function () {
+		this._updateZIndex(this.options.riseOffset);
+	},
+
+	_resetZIndex: function () {
+		this._updateZIndex(0);
+	},
+
+	_getPopupAnchor: function () {
+		return this.options.icon.options.popupAnchor;
+	},
+
+	_getTooltipAnchor: function () {
+		return this.options.icon.options.tooltipAnchor;
+	}
+});
+
+
+// factory L.marker(latlng: LatLng, options? : Marker options)
+
+// @factory L.marker(latlng: LatLng, options? : Marker options)
+// Instantiates a Marker object given a geographical point and optionally an options object.
+function marker(latlng, options) {
+	return new Marker(latlng, options);
+}
+
+/*
+ * @class Path
+ * @aka L.Path
+ * @inherits Interactive layer
+ *
+ * An abstract class that contains options and constants shared between vector
+ * overlays (Polygon, Polyline, Circle). Do not use it directly. Extends `Layer`.
+ */
+
+var Path = Layer.extend({
+
+	// @section
+	// @aka Path options
+	options: {
+		// @option stroke: Boolean = true
+		// Whether to draw stroke along the path. Set it to `false` to disable borders on polygons or circles.
+		stroke: true,
+
+		// @option color: String = '#3388ff'
+		// Stroke color
+		color: '#3388ff',
+
+		// @option weight: Number = 3
+		// Stroke width in pixels
+		weight: 3,
+
+		// @option opacity: Number = 1.0
+		// Stroke opacity
+		opacity: 1,
+
+		// @option lineCap: String= 'round'
+		// A string that defines [shape to be used at the end](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-linecap) of the stroke.
+		lineCap: 'round',
+
+		// @option lineJoin: String = 'round'
+		// A string that defines [shape to be used at the corners](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-linejoin) of the stroke.
+		lineJoin: 'round',
+
+		// @option dashArray: String = null
+		// A string that defines the stroke [dash pattern](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-dasharray). Doesn't work on `Canvas`-powered layers in [some old browsers](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/setLineDash#Browser_compatibility).
+		dashArray: null,
+
+		// @option dashOffset: String = null
+		// A string that defines the [distance into the dash pattern to start the dash](https://developer.mozilla.org/docs/Web/SVG/Attribute/stroke-dashoffset). Doesn't work on `Canvas`-powered layers in [some old browsers](https://developer.mozilla.org/docs/Web/API/CanvasRenderingContext2D/setLineDash#Browser_compatibility).
+		dashOffset: null,
+
+		// @option fill: Boolean = depends
+		// Whether to fill the path with color. Set it to `false` to disable filling on polygons or circles.
+		fill: false,
+
+		// @option fillColor: String = *
+		// Fill color. Defaults to the value of the [`color`](#path-color) option
+		fillColor: null,
+
+		// @option fillOpacity: Number = 0.2
+		// Fill opacity.
+		fillOpacity: 0.2,
+
+		// @option fillRule: String = 'evenodd'
+		// A string that defines [how the inside of a shape](https://developer.mozilla.org/docs/Web/SVG/Attribute/fill-rule) is determined.
+		fillRule: 'evenodd',
+
+		// className: '',
+
+		// Option inherited from "Interactive layer" abstract class
+		interactive: true,
+
+		// @option bubblingMouseEvents: Boolean = true
+		// When `true`, a mouse event on this path will trigger the same event on the map
+		// (unless [`L.DomEvent.stopPropagation`](#domevent-stoppropagation) is used).
+		bubblingMouseEvents: true
+	},
+
+	beforeAdd: function (map) {
+		// Renderer is set here because we need to call renderer.getEvents
+		// before this.getEvents.
+		this._renderer = map.getRenderer(this);
+	},
+
+	onAdd: function () {
+		this._renderer._initPath(this);
+		this._reset();
+		this._renderer._addPath(this);
+	},
+
+	onRemove: function () {
+		this._renderer._removePath(this);
+	},
+
+	// @method redraw(): this
+	// Redraws the layer. Sometimes useful after you changed the coordinates that the path uses.
+	redraw: function () {
+		if (this._map) {
+			this._renderer._updatePath(this);
+		}
+		return this;
+	},
+
+	// @method setStyle(style: Path options): this
+	// Changes the appearance of a Path based on the options in the `Path options` object.
+	setStyle: function (style) {
+		setOptions(this, style);
+		if (this._renderer) {
+			this._renderer._updateStyle(this);
+		}
+		return this;
+	},
+
+	// @method bringToFront(): this
+	// Brings the layer to the top of all path layers.
+	bringToFront: function () {
+		if (this._renderer) {
+			this._renderer._bringToFront(this);
+		}
+		return this;
+	},
+
+	// @method bringToBack(): this
+	// Brings the layer to the bottom of all path layers.
+	bringToBack: function () {
+		if (this._renderer) {
+			this._renderer._bringToBack(this);
+		}
+		return this;
+	},
+
+	getElement: function () {
+		return this._path;
+	},
+
+	_reset: function () {
+		// defined in child classes
+		this._project();
+		this._update();
+	},
+
+	_clickTolerance: function () {
+		// used when doing hit detection for Canvas layers
+		return (this.options.stroke ? this.options.weight / 2 : 0) + this._renderer.options.tolerance;
+	}
+});
+
+/*
+ * @class CircleMarker
+ * @aka L.CircleMarker
+ * @inherits Path
+ *
+ * A circle of a fixed size with radius specified in pixels. Extends `Path`.
+ */
+
+var CircleMarker = Path.extend({
+
+	// @section
+	// @aka CircleMarker options
+	options: {
+		fill: true,
+
+		// @option radius: Number = 10
+		// Radius of the circle marker, in pixels
+		radius: 10
+	},
+
+	initialize: function (latlng, options) {
+		setOptions(this, options);
+		this._latlng = toLatLng(latlng);
+		this._radius = this.options.radius;
+	},
+
+	// @method setLatLng(latLng: LatLng): this
+	// Sets the position of a circle marker to a new location.
+	setLatLng: function (latlng) {
+		this._latlng = toLatLng(latlng);
+		this.redraw();
+		return this.fire('move', {latlng: this._latlng});
+	},
+
+	// @method getLatLng(): LatLng
+	// Returns the current geographical position of the circle marker
+	getLatLng: function () {
+		return this._latlng;
+	},
+
+	// @method setRadius(radius: Number): this
+	// Sets the radius of a circle marker. Units are in pixels.
+	setRadius: function (radius) {
+		this.options.radius = this._radius = radius;
+		return this.redraw();
+	},
+
+	// @method getRadius(): Number
+	// Returns the current radius of the circle
+	getRadius: function () {
+		return this._radius;
+	},
+
+	setStyle : function (options) {
+		var radius = options && options.radius || this._radius;
+		Path.prototype.setStyle.call(this, options);
+		this.setRadius(radius);
+		return this;
+	},
+
+	_project: function () {
+		this._point = this._map.latLngToLayerPoint(this._latlng);
+		this._updateBounds();
+	},
+
+	_updateBounds: function () {
+		var r = this._radius,
+		    r2 = this._radiusY || r,
+		    w = this._clickTolerance(),
+		    p = [r + w, r2 + w];
+		this._pxBounds = new Bounds(this._point.subtract(p), this._point.add(p));
+	},
+
+	_update: function () {
+		if (this._map) {
+			this._updatePath();
+		}
+	},
+
+	_updatePath: function () {
+		this._renderer._updateCircle(this);
+	},
+
+	_empty: function () {
+		return this._radius && !this._renderer._bounds.intersects(this._pxBounds);
+	},
+
+	// Needed by the `Canvas` renderer for interactivity
+	_containsPoint: function (p) {
+		return p.distanceTo(this._point) <= this._radius + this._clickTolerance();
+	}
+});
+
+
+// @factory L.circleMarker(latlng: LatLng, options?: CircleMarker options)
+// Instantiates a circle marker object given a geographical point, and an optional options object.
+function circleMarker(latlng, options) {
+	return new CircleMarker(latlng, options);
+}
+
+/*
+ * @class Circle
+ * @aka L.Circle
+ * @inherits CircleMarker
+ *
+ * A class for drawing circle overlays on a map. Extends `CircleMarker`.
+ *
+ * It's an approximation and starts to diverge from a real circle closer to poles (due to projection distortion).
+ *
+ * @example
+ *
+ * ```js
+ * L.circle([50.5, 30.5], {radius: 200}).addTo(map);
+ * ```
+ */
+
+var Circle = CircleMarker.extend({
+
+	initialize: function (latlng, options, legacyOptions) {
+		if (typeof options === 'number') {
+			// Backwards compatibility with 0.7.x factory (latlng, radius, options?)
+			options = extend({}, legacyOptions, {radius: options});
+		}
+		setOptions(this, options);
+		this._latlng = toLatLng(latlng);
+
+		if (isNaN(this.options.radius)) { throw new Error('Circle radius cannot be NaN'); }
+
+		// @section
+		// @aka Circle options
+		// @option radius: Number; Radius of the circle, in meters.
+		this._mRadius = this.options.radius;
+	},
+
+	// @method setRadius(radius: Number): this
+	// Sets the radius of a circle. Units are in meters.
+	setRadius: function (radius) {
+		this._mRadius = radius;
+		return this.redraw();
+	},
+
+	// @method getRadius(): Number
+	// Returns the current radius of a circle. Units are in meters.
+	getRadius: function () {
+		return this._mRadius;
+	},
+
+	// @method getBounds(): LatLngBounds
+	// Returns the `LatLngBounds` of the path.
+	getBounds: function () {
+		var half = [this._radius, this._radiusY || this._radius];
+
+		return new LatLngBounds(
+			this._map.layerPointToLatLng(this._point.subtract(half)),
+			this._map.layerPointToLatLng(this._point.add(half)));
+	},
+
+	setStyle: Path.prototype.setStyle,
+
+	_project: function () {
+
+		var lng = this._latlng.lng,
+		    lat = this._latlng.lat,
+		    map = this._map,
+		    crs = map.options.crs;
+
+		if (crs.distance === Earth.distance) {
+			var d = Math.PI / 180,
+			    latR = (this._mRadius / Earth.R) / d,
+			    top = map.project([lat + latR, lng]),
+			    bottom = map.project([lat - latR, lng]),
+			    p = top.add(bottom).divideBy(2),
+			    lat2 = map.unproject(p).lat,
+			    lngR = Math.acos((Math.cos(latR * d) - Math.sin(lat * d) * Math.sin(lat2 * d)) /
+			            (Math.cos(lat * d) * Math.cos(lat2 * d))) / d;
+
+			if (isNaN(lngR) || lngR === 0) {
+				lngR = latR / Math.cos(Math.PI / 180 * lat); // Fallback for edge case, #2425
+			}
+
+			this._point = p.subtract(map.getPixelOrigin());
+			this._radius = isNaN(lngR) ? 0 : p.x - map.project([lat2, lng - lngR]).x;
+			this._radiusY = p.y - top.y;
+
+		} else {
+			var latlng2 = crs.unproject(crs.project(this._latlng).subtract([this._mRadius, 0]));
+
+			this._point = map.latLngToLayerPoint(this._latlng);
+			this._radius = this._point.x - map.latLngToLayerPoint(latlng2).x;
+		}
+
+		this._updateBounds();
+	}
+});
+
+// @factory L.circle(latlng: LatLng, options?: Circle options)
+// Instantiates a circle object given a geographical point, and an options object
+// which contains the circle radius.
+// @alternative
+// @factory L.circle(latlng: LatLng, radius: Number, options?: Circle options)
+// Obsolete way of instantiating a circle, for compatibility with 0.7.x code.
+// Do not use in new applications or plugins.
+function circle(latlng, options, legacyOptions) {
+	return new Circle(latlng, options, legacyOptions);
+}
+
+/*
+ * @class Polyline
+ * @aka L.Polyline
+ * @inherits Path
+ *
+ * A class for drawing polyline overlays on a map. Extends `Path`.
+ *
+ * @example
+ *
+ * ```js
+ * // create a red polyline from an array of LatLng points
+ * var latlngs = [
+ * 	[45.51, -122.68],
+ * 	[37.77, -122.43],
+ * 	[34.04, -118.2]
+ * ];
+ *
+ * var polyline = L.polyline(latlngs, {color: 'red'}).addTo(map);
+ *
+ * // zoom the map to the polyline
+ * map.fitBounds(polyline.getBounds());
+ * ```
+ *
+ * You can also pass a multi-dimensional array to represent a `MultiPolyline` shape:
+ *
+ * ```js
+ * // create a red polyline from an array of arrays of LatLng points
+ * var latlngs = [
+ * 	[[45.51, -122.68],
+ * 	 [37.77, -122.43],
+ * 	 [34.04, -118.2]],
+ * 	[[40.78, -73.91],
+ * 	 [41.83, -87.62],
+ * 	 [32.76, -96.72]]
+ * ];
+ * ```
+ */
+
+
+var Polyline = Path.extend({
+
+	// @section
+	// @aka Polyline options
+	options: {
+		// @option smoothFactor: Number = 1.0
+		// How much to simplify the polyline on each zoom level. More means
+		// better performance and smoother look, and less means more accurate representation.
+		smoothFactor: 1.0,
+
+		// @option noClip: Boolean = false
+		// Disable polyline clipping.
+		noClip: false
+	},
+
+	initialize: function (latlngs, options) {
+		setOptions(this, options);
+		this._setLatLngs(latlngs);
+	},
+
+	// @method getLatLngs(): LatLng[]
+	// Returns an array of the points in the path, or nested arrays of points in case of multi-polyline.
+	getLatLngs: function () {
+		return this._latlngs;
+	},
+
+	// @method setLatLngs(latlngs: LatLng[]): this
+	// Replaces all the points in the polyline with the given array of geographical points.
+	setLatLngs: function (latlngs) {
+		this._setLatLngs(latlngs);
+		return this.redraw();
+	},
+
+	// @method isEmpty(): Boolean
+	// Returns `true` if the Polyline has no LatLngs.
+	isEmpty: function () {
+		return !this._latlngs.length;
+	},
+
+	// @method closestLayerPoint: Point
+	// Returns the point closest to `p` on the Polyline.
+	closestLayerPoint: function (p) {
+		var minDistance = Infinity,
+		    minPoint = null,
+		    closest = _sqClosestPointOnSegment,
+		    p1, p2;
+
+		for (var j = 0, jLen = this._parts.length; j < jLen; j++) {
+			var points = this._parts[j];
+
+			for (var i = 1, len = points.length; i < len; i++) {
+				p1 = points[i - 1];
+				p2 = points[i];
+
+				var sqDist = closest(p, p1, p2, true);
+
+				if (sqDist < minDistance) {
+					minDistance = sqDist;
+					minPoint = closest(p, p1, p2);
+				}
+			}
+		}
+		if (minPoint) {
+			minPoint.distance = Math.sqrt(minDistance);
+		}
+		return minPoint;
+	},
+
+	// @method getCenter(): LatLng
+	// Returns the center ([centroid](http://en.wikipedia.org/wiki/Centroid)) of the polyline.
+	getCenter: function () {
+		// throws error when not yet added to map as this center calculation requires projected coordinates
+		if (!this._map) {
+			throw new Error('Must add layer to map before using getCenter()');
+		}
+
+		var i, halfDist, segDist, dist, p1, p2, ratio,
+		    points = this._rings[0],
+		    len = points.length;
+
+		if (!len) { return null; }
+
+		// polyline centroid algorithm; only uses the first ring if there are multiple
+
+		for (i = 0, halfDist = 0; i < len - 1; i++) {
+			halfDist += points[i].distanceTo(points[i + 1]) / 2;
+		}
+
+		// The line is so small in the current view that all points are on the same pixel.
+		if (halfDist === 0) {
+			return this._map.layerPointToLatLng(points[0]);
+		}
+
+		for (i = 0, dist = 0; i < len - 1; i++) {
+			p1 = points[i];
+			p2 = points[i + 1];
+			segDist = p1.distanceTo(p2);
+			dist += segDist;
+
+			if (dist > halfDist) {
+				ratio = (dist - halfDist) / segDist;
+				return this._map.layerPointToLatLng([
+					p2.x - ratio * (p2.x - p1.x),
+					p2.y - ratio * (p2.y - p1.y)
+				]);
+			}
+		}
+	},
+
+	// @method getBounds(): LatLngBounds
+	// Returns the `LatLngBounds` of the path.
+	getBounds: function () {
+		return this._bounds;
+	},
+
+	// @method addLatLng(latlng: LatLng, latlngs? LatLng[]): this
+	// Adds a given point to the polyline. By default, adds to the first ring of
+	// the polyline in case of a multi-polyline, but can be overridden by passing
+	// a specific ring as a LatLng array (that you can earlier access with [`getLatLngs`](#polyline-getlatlngs)).
+	addLatLng: function (latlng, latlngs) {
+		latlngs = latlngs || this._defaultShape();
+		latlng = toLatLng(latlng);
+		latlngs.push(latlng);
+		this._bounds.extend(latlng);
+		return this.redraw();
+	},
+
+	_setLatLngs: function (latlngs) {
+		this._bounds = new LatLngBounds();
+		this._latlngs = this._convertLatLngs(latlngs);
+	},
+
+	_defaultShape: function () {
+		return isFlat(this._latlngs) ? this._latlngs : this._latlngs[0];
+	},
+
+	// recursively convert latlngs input into actual LatLng instances; calculate bounds along the way
+	_convertLatLngs: function (latlngs) {
+		var result = [],
+		    flat = isFlat(latlngs);
+
+		for (var i = 0, len = latlngs.length; i < len; i++) {
+			if (flat) {
+				result[i] = toLatLng(latlngs[i]);
+				this._bounds.extend(result[i]);
+			} else {
+				result[i] = this._convertLatLngs(latlngs[i]);
+			}
+		}
+
+		return result;
+	},
+
+	_project: function () {
+		var pxBounds = new Bounds();
+		this._rings = [];
+		this._projectLatlngs(this._latlngs, this._rings, pxBounds);
+
+		var w = this._clickTolerance(),
+		    p = new Point(w, w);
+
+		if (this._bounds.isValid() && pxBounds.isValid()) {
+			pxBounds.min._subtract(p);
+			pxBounds.max._add(p);
+			this._pxBounds = pxBounds;
+		}
+	},
+
+	// recursively turns latlngs into a set of rings with projected coordinates
+	_projectLatlngs: function (latlngs, result, projectedBounds) {
+		var flat = latlngs[0] instanceof LatLng,
+		    len = latlngs.length,
+		    i, ring;
+
+		if (flat) {
+			ring = [];
+			for (i = 0; i < len; i++) {
+				ring[i] = this._map.latLngToLayerPoint(latlngs[i]);
+				projectedBounds.extend(ring[i]);
+			}
+			result.push(ring);
+		} else {
+			for (i = 0; i < len; i++) {
+				this._projectLatlngs(latlngs[i], result, projectedBounds);
+			}
+		}
+	},
+
+	// clip polyline by renderer bounds so that we have less to render for performance
+	_clipPoints: function () {
+		var bounds = this._renderer._bounds;
+
+		this._parts = [];
+		if (!this._pxBounds || !this._pxBounds.intersects(bounds)) {
+			return;
+		}
+
+		if (this.options.noClip) {
+			this._parts = this._rings;
+			return;
+		}
+
+		var parts = this._parts,
+		    i, j, k, len, len2, segment, points;
+
+		for (i = 0, k = 0, len = this._rings.length; i < len; i++) {
+			points = this._rings[i];
+
+			for (j = 0, len2 = points.length; j < len2 - 1; j++) {
+				segment = clipSegment(points[j], points[j + 1], bounds, j, true);
+
+				if (!segment) { continue; }
+
+				parts[k] = parts[k] || [];
+				parts[k].push(segment[0]);
+
+				// if segment goes out of screen, or it's the last one, it's the end of the line part
+				if ((segment[1] !== points[j + 1]) || (j === len2 - 2)) {
+					parts[k].push(segment[1]);
+					k++;
+				}
+			}
+		}
+	},
+
+	// simplify each clipped part of the polyline for performance
+	_simplifyPoints: function () {
+		var parts = this._parts,
+		    tolerance = this.options.smoothFactor;
+
+		for (var i = 0, len = parts.length; i < len; i++) {
+			parts[i] = simplify(parts[i], tolerance);
+		}
+	},
+
+	_update: function () {
+		if (!this._map) { return; }
+
+		this._clipPoints();
+		this._simplifyPoints();
+		this._updatePath();
+	},
+
+	_updatePath: function () {
+		this._renderer._updatePoly(this);
+	},
+
+	// Needed by the `Canvas` renderer for interactivity
+	_containsPoint: function (p, closed) {
+		var i, j, k, len, len2, part,
+		    w = this._clickTolerance();
+
+		if (!this._pxBounds || !this._pxBounds.contains(p)) { return false; }
+
+		// hit detection for polylines
+		for (i = 0, len = this._parts.length; i < len; i++) {
+			part = this._parts[i];
+
+			for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) {
+				if (!closed && (j === 0)) { continue; }
+
+				if (pointToSegmentDistance(p, part[k], part[j]) <= w) {
+					return true;
+				}
+			}
+		}
+		return false;
+	}
+});
+
+// @factory L.polyline(latlngs: LatLng[], options?: Polyline options)
+// Instantiates a polyline object given an array of geographical points and
+// optionally an options object. You can create a `Polyline` object with
+// multiple separate lines (`MultiPolyline`) by passing an array of arrays
+// of geographic points.
+function polyline(latlngs, options) {
+	return new Polyline(latlngs, options);
+}
+
+// Retrocompat. Allow plugins to support Leaflet versions before and after 1.1.
+Polyline._flat = _flat;
+
+/*
+ * @class Polygon
+ * @aka L.Polygon
+ * @inherits Polyline
+ *
+ * A class for drawing polygon overlays on a map. Extends `Polyline`.
+ *
+ * Note that points you pass when creating a polygon shouldn't have an additional last point equal to the first one — it's better to filter out such points.
+ *
+ *
+ * @example
+ *
+ * ```js
+ * // create a red polygon from an array of LatLng points
+ * var latlngs = [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]];
+ *
+ * var polygon = L.polygon(latlngs, {color: 'red'}).addTo(map);
+ *
+ * // zoom the map to the polygon
+ * map.fitBounds(polygon.getBounds());
+ * ```
+ *
+ * You can also pass an array of arrays of latlngs, with the first array representing the outer shape and the other arrays representing holes in the outer shape:
+ *
+ * ```js
+ * var latlngs = [
+ *   [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]], // outer ring
+ *   [[37.29, -108.58],[40.71, -108.58],[40.71, -102.50],[37.29, -102.50]] // hole
+ * ];
+ * ```
+ *
+ * Additionally, you can pass a multi-dimensional array to represent a MultiPolygon shape.
+ *
+ * ```js
+ * var latlngs = [
+ *   [ // first polygon
+ *     [[37, -109.05],[41, -109.03],[41, -102.05],[37, -102.04]], // outer ring
+ *     [[37.29, -108.58],[40.71, -108.58],[40.71, -102.50],[37.29, -102.50]] // hole
+ *   ],
+ *   [ // second polygon
+ *     [[41, -111.03],[45, -111.04],[45, -104.05],[41, -104.05]]
+ *   ]
+ * ];
+ * ```
+ */
+
+var Polygon = Polyline.extend({
+
+	options: {
+		fill: true
+	},
+
+	isEmpty: function () {
+		return !this._latlngs.length || !this._latlngs[0].length;
+	},
+
+	getCenter: function () {
+		// throws error when not yet added to map as this center calculation requires projected coordinates
+		if (!this._map) {
+			throw new Error('Must add layer to map before using getCenter()');
+		}
+
+		var i, j, p1, p2, f, area, x, y, center,
+		    points = this._rings[0],
+		    len = points.length;
+
+		if (!len) { return null; }
+
+		// polygon centroid algorithm; only uses the first ring if there are multiple
+
+		area = x = y = 0;
+
+		for (i = 0, j = len - 1; i < len; j = i++) {
+			p1 = points[i];
+			p2 = points[j];
+
+			f = p1.y * p2.x - p2.y * p1.x;
+			x += (p1.x + p2.x) * f;
+			y += (p1.y + p2.y) * f;
+			area += f * 3;
+		}
+
+		if (area === 0) {
+			// Polygon is so small that all points are on same pixel.
+			center = points[0];
+		} else {
+			center = [x / area, y / area];
+		}
+		return this._map.layerPointToLatLng(center);
+	},
+
+	_convertLatLngs: function (latlngs) {
+		var result = Polyline.prototype._convertLatLngs.call(this, latlngs),
+		    len = result.length;
+
+		// remove last point if it equals first one
+		if (len >= 2 && result[0] instanceof LatLng && result[0].equals(result[len - 1])) {
+			result.pop();
+		}
+		return result;
+	},
+
+	_setLatLngs: function (latlngs) {
+		Polyline.prototype._setLatLngs.call(this, latlngs);
+		if (isFlat(this._latlngs)) {
+			this._latlngs = [this._latlngs];
+		}
+	},
+
+	_defaultShape: function () {
+		return isFlat(this._latlngs[0]) ? this._latlngs[0] : this._latlngs[0][0];
+	},
+
+	_clipPoints: function () {
+		// polygons need a different clipping algorithm so we redefine that
+
+		var bounds = this._renderer._bounds,
+		    w = this.options.weight,
+		    p = new Point(w, w);
+
+		// increase clip padding by stroke width to avoid stroke on clip edges
+		bounds = new Bounds(bounds.min.subtract(p), bounds.max.add(p));
+
+		this._parts = [];
+		if (!this._pxBounds || !this._pxBounds.intersects(bounds)) {
+			return;
+		}
+
+		if (this.options.noClip) {
+			this._parts = this._rings;
+			return;
+		}
+
+		for (var i = 0, len = this._rings.length, clipped; i < len; i++) {
+			clipped = clipPolygon(this._rings[i], bounds, true);
+			if (clipped.length) {
+				this._parts.push(clipped);
+			}
+		}
+	},
+
+	_updatePath: function () {
+		this._renderer._updatePoly(this, true);
+	},
+
+	// Needed by the `Canvas` renderer for interactivity
+	_containsPoint: function (p) {
+		var inside = false,
+		    part, p1, p2, i, j, k, len, len2;
+
+		if (!this._pxBounds.contains(p)) { return false; }
+
+		// ray casting algorithm for detecting if point is in polygon
+		for (i = 0, len = this._parts.length; i < len; i++) {
+			part = this._parts[i];
+
+			for (j = 0, len2 = part.length, k = len2 - 1; j < len2; k = j++) {
+				p1 = part[j];
+				p2 = part[k];
+
+				if (((p1.y > p.y) !== (p2.y > p.y)) && (p.x < (p2.x - p1.x) * (p.y - p1.y) / (p2.y - p1.y) + p1.x)) {
+					inside = !inside;
+				}
+			}
+		}
+
+		// also check if it's on polygon stroke
+		return inside || Polyline.prototype._containsPoint.call(this, p, true);
+	}
+
+});
+
+
+// @factory L.polygon(latlngs: LatLng[], options?: Polyline options)
+function polygon(latlngs, options) {
+	return new Polygon(latlngs, options);
+}
+
+/*
+ * @class GeoJSON
+ * @aka L.GeoJSON
+ * @inherits FeatureGroup
+ *
+ * Represents a GeoJSON object or an array of GeoJSON objects. Allows you to parse
+ * GeoJSON data and display it on the map. Extends `FeatureGroup`.
+ *
+ * @example
+ *
+ * ```js
+ * L.geoJSON(data, {
+ * 	style: function (feature) {
+ * 		return {color: feature.properties.color};
+ * 	}
+ * }).bindPopup(function (layer) {
+ * 	return layer.feature.properties.description;
+ * }).addTo(map);
+ * ```
+ */
+
+var GeoJSON = FeatureGroup.extend({
+
+	/* @section
+	 * @aka GeoJSON options
+	 *
+	 * @option pointToLayer: Function = *
+	 * A `Function` defining how GeoJSON points spawn Leaflet layers. It is internally
+	 * called when data is added, passing the GeoJSON point feature and its `LatLng`.
+	 * The default is to spawn a default `Marker`:
+	 * ```js
+	 * function(geoJsonPoint, latlng) {
+	 * 	return L.marker(latlng);
+	 * }
+	 * ```
+	 *
+	 * @option style: Function = *
+	 * A `Function` defining the `Path options` for styling GeoJSON lines and polygons,
+	 * called internally when data is added.
+	 * The default value is to not override any defaults:
+	 * ```js
+	 * function (geoJsonFeature) {
+	 * 	return {}
+	 * }
+	 * ```
+	 *
+	 * @option onEachFeature: Function = *
+	 * A `Function` that will be called once for each created `Feature`, after it has
+	 * been created and styled. Useful for attaching events and popups to features.
+	 * The default is to do nothing with the newly created layers:
+	 * ```js
+	 * function (feature, layer) {}
+	 * ```
+	 *
+	 * @option filter: Function = *
+	 * A `Function` that will be used to decide whether to include a feature or not.
+	 * The default is to include all features:
+	 * ```js
+	 * function (geoJsonFeature) {
+	 * 	return true;
+	 * }
+	 * ```
+	 * Note: dynamically changing the `filter` option will have effect only on newly
+	 * added data. It will _not_ re-evaluate already included features.
+	 *
+	 * @option coordsToLatLng: Function = *
+	 * A `Function` that will be used for converting GeoJSON coordinates to `LatLng`s.
+	 * The default is the `coordsToLatLng` static method.
+	 */
+
+	initialize: function (geojson, options) {
+		setOptions(this, options);
+
+		this._layers = {};
+
+		if (geojson) {
+			this.addData(geojson);
+		}
+	},
+
+	// @method addData( <GeoJSON> data ): this
+	// Adds a GeoJSON object to the layer.
+	addData: function (geojson) {
+		var features = isArray(geojson) ? geojson : geojson.features,
+		    i, len, feature;
+
+		if (features) {
+			for (i = 0, len = features.length; i < len; i++) {
+				// only add this if geometry or geometries are set and not null
+				feature = features[i];
+				if (feature.geometries || feature.geometry || feature.features || feature.coordinates) {
+					this.addData(feature);
+				}
+			}
+			return this;
+		}
+
+		var options = this.options;
+
+		if (options.filter && !options.filter(geojson)) { return this; }
+
+		var layer = geometryToLayer(geojson, options);
+		if (!layer) {
+			return this;
+		}
+		layer.feature = asFeature(geojson);
+
+		layer.defaultOptions = layer.options;
+		this.resetStyle(layer);
+
+		if (options.onEachFeature) {
+			options.onEachFeature(geojson, layer);
+		}
+
+		return this.addLayer(layer);
+	},
+
+	// @method resetStyle( <Path> layer ): this
+	// Resets the given vector layer's style to the original GeoJSON style, useful for resetting style after hover events.
+	resetStyle: function (layer) {
+		// reset any custom styles
+		layer.options = extend({}, layer.defaultOptions);
+		this._setLayerStyle(layer, this.options.style);
+		return this;
+	},
+
+	// @method setStyle( <Function> style ): this
+	// Changes styles of GeoJSON vector layers with the given style function.
+	setStyle: function (style) {
+		return this.eachLayer(function (layer) {
+			this._setLayerStyle(layer, style);
+		}, this);
+	},
+
+	_setLayerStyle: function (layer, style) {
+		if (typeof style === 'function') {
+			style = style(layer.feature);
+		}
+		if (layer.setStyle) {
+			layer.setStyle(style);
+		}
+	}
+});
+
+// @section
+// There are several static functions which can be called without instantiating L.GeoJSON:
+
+// @function geometryToLayer(featureData: Object, options?: GeoJSON options): Layer
+// Creates a `Layer` from a given GeoJSON feature. Can use a custom
+// [`pointToLayer`](#geojson-pointtolayer) and/or [`coordsToLatLng`](#geojson-coordstolatlng)
+// functions if provided as options.
+function geometryToLayer(geojson, options) {
+
+	var geometry = geojson.type === 'Feature' ? geojson.geometry : geojson,
+	    coords = geometry ? geometry.coordinates : null,
+	    layers = [],
+	    pointToLayer = options && options.pointToLayer,
+	    _coordsToLatLng = options && options.coordsToLatLng || coordsToLatLng,
+	    latlng, latlngs, i, len;
+
+	if (!coords && !geometry) {
+		return null;
+	}
+
+	switch (geometry.type) {
+	case 'Point':
+		latlng = _coordsToLatLng(coords);
+		return pointToLayer ? pointToLayer(geojson, latlng) : new Marker(latlng);
+
+	case 'MultiPoint':
+		for (i = 0, len = coords.length; i < len; i++) {
+			latlng = _coordsToLatLng(coords[i]);
+			layers.push(pointToLayer ? pointToLayer(geojson, latlng) : new Marker(latlng));
+		}
+		return new FeatureGroup(layers);
+
+	case 'LineString':
+	case 'MultiLineString':
+		latlngs = coordsToLatLngs(coords, geometry.type === 'LineString' ? 0 : 1, _coordsToLatLng);
+		return new Polyline(latlngs, options);
+
+	case 'Polygon':
+	case 'MultiPolygon':
+		latlngs = coordsToLatLngs(coords, geometry.type === 'Polygon' ? 1 : 2, _coordsToLatLng);
+		return new Polygon(latlngs, options);
+
+	case 'GeometryCollection':
+		for (i = 0, len = geometry.geometries.length; i < len; i++) {
+			var layer = geometryToLayer({
+				geometry: geometry.geometries[i],
+				type: 'Feature',
+				properties: geojson.properties
+			}, options);
+
+			if (layer) {
+				layers.push(layer);
+			}
+		}
+		return new FeatureGroup(layers);
+
+	default:
+		throw new Error('Invalid GeoJSON object.');
+	}
+}
+
+// @function coordsToLatLng(coords: Array): LatLng
+// Creates a `LatLng` object from an array of 2 numbers (longitude, latitude)
+// or 3 numbers (longitude, latitude, altitude) used in GeoJSON for points.
+function coordsToLatLng(coords) {
+	return new LatLng(coords[1], coords[0], coords[2]);
+}
+
+// @function coordsToLatLngs(coords: Array, levelsDeep?: Number, coordsToLatLng?: Function): Array
+// Creates a multidimensional array of `LatLng`s from a GeoJSON coordinates array.
+// `levelsDeep` specifies the nesting level (0 is for an array of points, 1 for an array of arrays of points, etc., 0 by default).
+// Can use a custom [`coordsToLatLng`](#geojson-coordstolatlng) function.
+function coordsToLatLngs(coords, levelsDeep, _coordsToLatLng) {
+	var latlngs = [];
+
+	for (var i = 0, len = coords.length, latlng; i < len; i++) {
+		latlng = levelsDeep ?
+			coordsToLatLngs(coords[i], levelsDeep - 1, _coordsToLatLng) :
+			(_coordsToLatLng || coordsToLatLng)(coords[i]);
+
+		latlngs.push(latlng);
+	}
+
+	return latlngs;
+}
+
+// @function latLngToCoords(latlng: LatLng, precision?: Number): Array
+// Reverse of [`coordsToLatLng`](#geojson-coordstolatlng)
+function latLngToCoords(latlng, precision) {
+	precision = typeof precision === 'number' ? precision : 6;
+	return latlng.alt !== undefined ?
+		[formatNum(latlng.lng, precision), formatNum(latlng.lat, precision), formatNum(latlng.alt, precision)] :
+		[formatNum(latlng.lng, precision), formatNum(latlng.lat, precision)];
+}
+
+// @function latLngsToCoords(latlngs: Array, levelsDeep?: Number, closed?: Boolean): Array
+// Reverse of [`coordsToLatLngs`](#geojson-coordstolatlngs)
+// `closed` determines whether the first point should be appended to the end of the array to close the feature, only used when `levelsDeep` is 0. False by default.
+function latLngsToCoords(latlngs, levelsDeep, closed, precision) {
+	var coords = [];
+
+	for (var i = 0, len = latlngs.length; i < len; i++) {
+		coords.push(levelsDeep ?
+			latLngsToCoords(latlngs[i], levelsDeep - 1, closed, precision) :
+			latLngToCoords(latlngs[i], precision));
+	}
+
+	if (!levelsDeep && closed) {
+		coords.push(coords[0]);
+	}
+
+	return coords;
+}
+
+function getFeature(layer, newGeometry) {
+	return layer.feature ?
+		extend({}, layer.feature, {geometry: newGeometry}) :
+		asFeature(newGeometry);
+}
+
+// @function asFeature(geojson: Object): Object
+// Normalize GeoJSON geometries/features into GeoJSON features.
+function asFeature(geojson) {
+	if (geojson.type === 'Feature' || geojson.type === 'FeatureCollection') {
+		return geojson;
+	}
+
+	return {
+		type: 'Feature',
+		properties: {},
+		geometry: geojson
+	};
+}
+
+var PointToGeoJSON = {
+	toGeoJSON: function (precision) {
+		return getFeature(this, {
+			type: 'Point',
+			coordinates: latLngToCoords(this.getLatLng(), precision)
+		});
+	}
+};
+
+// @namespace Marker
+// @method toGeoJSON(): Object
+// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the marker (as a GeoJSON `Point` Feature).
+Marker.include(PointToGeoJSON);
+
+// @namespace CircleMarker
+// @method toGeoJSON(): Object
+// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the circle marker (as a GeoJSON `Point` Feature).
+Circle.include(PointToGeoJSON);
+CircleMarker.include(PointToGeoJSON);
+
+
+// @namespace Polyline
+// @method toGeoJSON(): Object
+// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the polyline (as a GeoJSON `LineString` or `MultiLineString` Feature).
+Polyline.include({
+	toGeoJSON: function (precision) {
+		var multi = !isFlat(this._latlngs);
+
+		var coords = latLngsToCoords(this._latlngs, multi ? 1 : 0, false, precision);
+
+		return getFeature(this, {
+			type: (multi ? 'Multi' : '') + 'LineString',
+			coordinates: coords
+		});
+	}
+});
+
+// @namespace Polygon
+// @method toGeoJSON(): Object
+// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the polygon (as a GeoJSON `Polygon` or `MultiPolygon` Feature).
+Polygon.include({
+	toGeoJSON: function (precision) {
+		var holes = !isFlat(this._latlngs),
+		    multi = holes && !isFlat(this._latlngs[0]);
+
+		var coords = latLngsToCoords(this._latlngs, multi ? 2 : holes ? 1 : 0, true, precision);
+
+		if (!holes) {
+			coords = [coords];
+		}
+
+		return getFeature(this, {
+			type: (multi ? 'Multi' : '') + 'Polygon',
+			coordinates: coords
+		});
+	}
+});
+
+
+// @namespace LayerGroup
+LayerGroup.include({
+	toMultiPoint: function (precision) {
+		var coords = [];
+
+		this.eachLayer(function (layer) {
+			coords.push(layer.toGeoJSON(precision).geometry.coordinates);
+		});
+
+		return getFeature(this, {
+			type: 'MultiPoint',
+			coordinates: coords
+		});
+	},
+
+	// @method toGeoJSON(): Object
+	// Returns a [`GeoJSON`](http://en.wikipedia.org/wiki/GeoJSON) representation of the layer group (as a GeoJSON `FeatureCollection`, `GeometryCollection`, or `MultiPoint`).
+	toGeoJSON: function (precision) {
+
+		var type = this.feature && this.feature.geometry && this.feature.geometry.type;
+
+		if (type === 'MultiPoint') {
+			return this.toMultiPoint(precision);
+		}
+
+		var isGeometryCollection = type === 'GeometryCollection',
+		    jsons = [];
+
+		this.eachLayer(function (layer) {
+			if (layer.toGeoJSON) {
+				var json = layer.toGeoJSON(precision);
+				if (isGeometryCollection) {
+					jsons.push(json.geometry);
+				} else {
+					var feature = asFeature(json);
+					// Squash nested feature collections
+					if (feature.type === 'FeatureCollection') {
+						jsons.push.apply(jsons, feature.features);
+					} else {
+						jsons.push(feature);
+					}
+				}
+			}
+		});
+
+		if (isGeometryCollection) {
+			return getFeature(this, {
+				geometries: jsons,
+				type: 'GeometryCollection'
+			});
+		}
+
+		return {
+			type: 'FeatureCollection',
+			features: jsons
+		};
+	}
+});
+
+// @namespace GeoJSON
+// @factory L.geoJSON(geojson?: Object, options?: GeoJSON options)
+// Creates a GeoJSON layer. Optionally accepts an object in
+// [GeoJSON format](http://geojson.org/geojson-spec.html) to display on the map
+// (you can alternatively add it later with `addData` method) and an `options` object.
+function geoJSON(geojson, options) {
+	return new GeoJSON(geojson, options);
+}
+
+// Backward compatibility.
+var geoJson = geoJSON;
+
+/*
+ * @class ImageOverlay
+ * @aka L.ImageOverlay
+ * @inherits Interactive layer
+ *
+ * Used to load and display a single image over specific bounds of the map. Extends `Layer`.
+ *
+ * @example
+ *
+ * ```js
+ * var imageUrl = 'http://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg',
+ * 	imageBounds = [[40.712216, -74.22655], [40.773941, -74.12544]];
+ * L.imageOverlay(imageUrl, imageBounds).addTo(map);
+ * ```
+ */
+
+var ImageOverlay = Layer.extend({
+
+	// @section
+	// @aka ImageOverlay options
+	options: {
+		// @option opacity: Number = 1.0
+		// The opacity of the image overlay.
+		opacity: 1,
+
+		// @option alt: String = ''
+		// Text for the `alt` attribute of the image (useful for accessibility).
+		alt: '',
+
+		// @option interactive: Boolean = false
+		// If `true`, the image overlay will emit [mouse events](#interactive-layer) when clicked or hovered.
+		interactive: false,
+
+		// @option crossOrigin: Boolean = false
+		// If true, the image will have its crossOrigin attribute set to ''. This is needed if you want to access image pixel data.
+		crossOrigin: false,
+
+		// @option errorOverlayUrl: String = ''
+		// URL to the overlay image to show in place of the overlay that failed to load.
+		errorOverlayUrl: '',
+
+		// @option zIndex: Number = 1
+		// The explicit [zIndex](https://developer.mozilla.org/docs/Web/CSS/CSS_Positioning/Understanding_z_index) of the tile layer.
+		zIndex: 1,
+
+		// @option className: String = ''
+		// A custom class name to assign to the image. Empty by default.
+		className: '',
+	},
+
+	initialize: function (url, bounds, options) { // (String, LatLngBounds, Object)
+		this._url = url;
+		this._bounds = toLatLngBounds(bounds);
+
+		setOptions(this, options);
+	},
+
+	onAdd: function () {
+		if (!this._image) {
+			this._initImage();
+
+			if (this.options.opacity < 1) {
+				this._updateOpacity();
+			}
+		}
+
+		if (this.options.interactive) {
+			addClass(this._image, 'leaflet-interactive');
+			this.addInteractiveTarget(this._image);
+		}
+
+		this.getPane().appendChild(this._image);
+		this._reset();
+	},
+
+	onRemove: function () {
+		remove(this._image);
+		if (this.options.interactive) {
+			this.removeInteractiveTarget(this._image);
+		}
+	},
+
+	// @method setOpacity(opacity: Number): this
+	// Sets the opacity of the overlay.
+	setOpacity: function (opacity) {
+		this.options.opacity = opacity;
+
+		if (this._image) {
+			this._updateOpacity();
+		}
+		return this;
+	},
+
+	setStyle: function (styleOpts) {
+		if (styleOpts.opacity) {
+			this.setOpacity(styleOpts.opacity);
+		}
+		return this;
+	},
+
+	// @method bringToFront(): this
+	// Brings the layer to the top of all overlays.
+	bringToFront: function () {
+		if (this._map) {
+			toFront(this._image);
+		}
+		return this;
+	},
+
+	// @method bringToBack(): this
+	// Brings the layer to the bottom of all overlays.
+	bringToBack: function () {
+		if (this._map) {
+			toBack(this._image);
+		}
+		return this;
+	},
+
+	// @method setUrl(url: String): this
+	// Changes the URL of the image.
+	setUrl: function (url) {
+		this._url = url;
+
+		if (this._image) {
+			this._image.src = url;
+		}
+		return this;
+	},
+
+	// @method setBounds(bounds: LatLngBounds): this
+	// Update the bounds that this ImageOverlay covers
+	setBounds: function (bounds) {
+		this._bounds = toLatLngBounds(bounds);
+
+		if (this._map) {
+			this._reset();
+		}
+		return this;
+	},
+
+	getEvents: function () {
+		var events = {
+			zoom: this._reset,
+			viewreset: this._reset
+		};
+
+		if (this._zoomAnimated) {
+			events.zoomanim = this._animateZoom;
+		}
+
+		return events;
+	},
+
+	// @method: setZIndex(value: Number) : this
+	// Changes the [zIndex](#imageoverlay-zindex) of the image overlay.
+	setZIndex: function (value) {
+		this.options.zIndex = value;
+		this._updateZIndex();
+		return this;
+	},
+
+	// @method getBounds(): LatLngBounds
+	// Get the bounds that this ImageOverlay covers
+	getBounds: function () {
+		return this._bounds;
+	},
+
+	// @method getElement(): HTMLElement
+	// Returns the instance of [`HTMLImageElement`](https://developer.mozilla.org/docs/Web/API/HTMLImageElement)
+	// used by this overlay.
+	getElement: function () {
+		return this._image;
+	},
+
+	_initImage: function () {
+		var wasElementSupplied = this._url.tagName === 'IMG';
+		var img = this._image = wasElementSupplied ? this._url : create$1('img');
+
+		addClass(img, 'leaflet-image-layer');
+		if (this._zoomAnimated) { addClass(img, 'leaflet-zoom-animated'); }
+		if (this.options.className) { addClass(img, this.options.className); }
+
+		img.onselectstart = falseFn;
+		img.onmousemove = falseFn;
+
+		// @event load: Event
+		// Fired when the ImageOverlay layer has loaded its image
+		img.onload = bind(this.fire, this, 'load');
+		img.onerror = bind(this._overlayOnError, this, 'error');
+
+		if (this.options.crossOrigin) {
+			img.crossOrigin = '';
+		}
+
+		if (this.options.zIndex) {
+			this._updateZIndex();
+		}
+
+		if (wasElementSupplied) {
+			this._url = img.src;
+			return;
+		}
+
+		img.src = this._url;
+		img.alt = this.options.alt;
+	},
+
+	_animateZoom: function (e) {
+		var scale = this._map.getZoomScale(e.zoom),
+		    offset = this._map._latLngBoundsToNewLayerBounds(this._bounds, e.zoom, e.center).min;
+
+		setTransform(this._image, offset, scale);
+	},
+
+	_reset: function () {
+		var image = this._image,
+		    bounds = new Bounds(
+		        this._map.latLngToLayerPoint(this._bounds.getNorthWest()),
+		        this._map.latLngToLayerPoint(this._bounds.getSouthEast())),
+		    size = bounds.getSize();
+
+		setPosition(image, bounds.min);
+
+		image.style.width  = size.x + 'px';
+		image.style.height = size.y + 'px';
+	},
+
+	_updateOpacity: function () {
+		setOpacity(this._image, this.options.opacity);
+	},
+
+	_updateZIndex: function () {
+		if (this._image && this.options.zIndex !== undefined && this.options.zIndex !== null) {
+			this._image.style.zIndex = this.options.zIndex;
+		}
+	},
+
+	_overlayOnError: function () {
+		// @event error: Event
+		// Fired when the ImageOverlay layer has loaded its image
+		this.fire('error');
+
+		var errorUrl = this.options.errorOverlayUrl;
+		if (errorUrl && this._url !== errorUrl) {
+			this._url = errorUrl;
+			this._image.src = errorUrl;
+		}
+	}
+});
+
+// @factory L.imageOverlay(imageUrl: String, bounds: LatLngBounds, options?: ImageOverlay options)
+// Instantiates an image overlay object given the URL of the image and the
+// geographical bounds it is tied to.
+var imageOverlay = function (url, bounds, options) {
+	return new ImageOverlay(url, bounds, options);
+};
+
+/*
+ * @class VideoOverlay
+ * @aka L.VideoOverlay
+ * @inherits ImageOverlay
+ *
+ * Used to load and display a video player over specific bounds of the map. Extends `ImageOverlay`.
+ *
+ * A video overlay uses the [`<video>`](https://developer.mozilla.org/docs/Web/HTML/Element/video)
+ * HTML5 element.
+ *
+ * @example
+ *
+ * ```js
+ * var videoUrl = 'https://www.mapbox.com/bites/00188/patricia_nasa.webm',
+ * 	videoBounds = [[ 32, -130], [ 13, -100]];
+ * L.VideoOverlay(videoUrl, videoBounds ).addTo(map);
+ * ```
+ */
+
+var VideoOverlay = ImageOverlay.extend({
+
+	// @section
+	// @aka VideoOverlay options
+	options: {
+		// @option autoplay: Boolean = true
+		// Whether the video starts playing automatically when loaded.
+		autoplay: true,
+
+		// @option loop: Boolean = true
+		// Whether the video will loop back to the beginning when played.
+		loop: true
+	},
+
+	_initImage: function () {
+		var wasElementSupplied = this._url.tagName === 'VIDEO';
+		var vid = this._image = wasElementSupplied ? this._url : create$1('video');
+
+		addClass(vid, 'leaflet-image-layer');
+		if (this._zoomAnimated) { addClass(vid, 'leaflet-zoom-animated'); }
+
+		vid.onselectstart = falseFn;
+		vid.onmousemove = falseFn;
+
+		// @event load: Event
+		// Fired when the video has finished loading the first frame
+		vid.onloadeddata = bind(this.fire, this, 'load');
+
+		if (wasElementSupplied) {
+			var sourceElements = vid.getElementsByTagName('source');
+			var sources = [];
+			for (var j = 0; j < sourceElements.length; j++) {
+				sources.push(sourceElements[j].src);
+			}
+
+			this._url = (sourceElements.length > 0) ? sources : [vid.src];
+			return;
+		}
+
+		if (!isArray(this._url)) { this._url = [this._url]; }
+
+		vid.autoplay = !!this.options.autoplay;
+		vid.loop = !!this.options.loop;
+		for (var i = 0; i < this._url.length; i++) {
+			var source = create$1('source');
+			source.src = this._url[i];
+			vid.appendChild(source);
+		}
+	}
+
+	// @method getElement(): HTMLVideoElement
+	// Returns the instance of [`HTMLVideoElement`](https://developer.mozilla.org/docs/Web/API/HTMLVideoElement)
+	// used by this overlay.
+});
+
+
+// @factory L.videoOverlay(video: String|Array|HTMLVideoElement, bounds: LatLngBounds, options?: VideoOverlay options)
+// Instantiates an image overlay object given the URL of the video (or array of URLs, or even a video element) and the
+// geographical bounds it is tied to.
+
+function videoOverlay(video, bounds, options) {
+	return new VideoOverlay(video, bounds, options);
+}
+
+/*
+ * @class DivOverlay
+ * @inherits Layer
+ * @aka L.DivOverlay
+ * Base model for L.Popup and L.Tooltip. Inherit from it for custom popup like plugins.
+ */
+
+// @namespace DivOverlay
+var DivOverlay = Layer.extend({
+
+	// @section
+	// @aka DivOverlay options
+	options: {
+		// @option offset: Point = Point(0, 7)
+		// The offset of the popup position. Useful to control the anchor
+		// of the popup when opening it on some overlays.
+		offset: [0, 7],
+
+		// @option className: String = ''
+		// A custom CSS class name to assign to the popup.
+		className: '',
+
+		// @option pane: String = 'popupPane'
+		// `Map pane` where the popup will be added.
+		pane: 'popupPane'
+	},
+
+	initialize: function (options, source) {
+		setOptions(this, options);
+
+		this._source = source;
+	},
+
+	onAdd: function (map) {
+		this._zoomAnimated = map._zoomAnimated;
+
+		if (!this._container) {
+			this._initLayout();
+		}
+
+		if (map._fadeAnimated) {
+			setOpacity(this._container, 0);
+		}
+
+		clearTimeout(this._removeTimeout);
+		this.getPane().appendChild(this._container);
+		this.update();
+
+		if (map._fadeAnimated) {
+			setOpacity(this._container, 1);
+		}
+
+		this.bringToFront();
+	},
+
+	onRemove: function (map) {
+		if (map._fadeAnimated) {
+			setOpacity(this._container, 0);
+			this._removeTimeout = setTimeout(bind(remove, undefined, this._container), 200);
+		} else {
+			remove(this._container);
+		}
+	},
+
+	// @namespace Popup
+	// @method getLatLng: LatLng
+	// Returns the geographical point of popup.
+	getLatLng: function () {
+		return this._latlng;
+	},
+
+	// @method setLatLng(latlng: LatLng): this
+	// Sets the geographical point where the popup will open.
+	setLatLng: function (latlng) {
+		this._latlng = toLatLng(latlng);
+		if (this._map) {
+			this._updatePosition();
+			this._adjustPan();
+		}
+		return this;
+	},
+
+	// @method getContent: String|HTMLElement
+	// Returns the content of the popup.
+	getContent: function () {
+		return this._content;
+	},
+
+	// @method setContent(htmlContent: String|HTMLElement|Function): this
+	// Sets the HTML content of the popup. If a function is passed the source layer will be passed to the function. The function should return a `String` or `HTMLElement` to be used in the popup.
+	setContent: function (content) {
+		this._content = content;
+		this.update();
+		return this;
+	},
+
+	// @method getElement: String|HTMLElement
+	// Alias for [getContent()](#popup-getcontent)
+	getElement: function () {
+		return this._container;
+	},
+
+	// @method update: null
+	// Updates the popup content, layout and position. Useful for updating the popup after something inside changed, e.g. image loaded.
+	update: function () {
+		if (!this._map) { return; }
+
+		this._container.style.visibility = 'hidden';
+
+		this._updateContent();
+		this._updateLayout();
+		this._updatePosition();
+
+		this._container.style.visibility = '';
+
+		this._adjustPan();
+	},
+
+	getEvents: function () {
+		var events = {
+			zoom: this._updatePosition,
+			viewreset: this._updatePosition
+		};
+
+		if (this._zoomAnimated) {
+			events.zoomanim = this._animateZoom;
+		}
+		return events;
+	},
+
+	// @method isOpen: Boolean
+	// Returns `true` when the popup is visible on the map.
+	isOpen: function () {
+		return !!this._map && this._map.hasLayer(this);
+	},
+
+	// @method bringToFront: this
+	// Brings this popup in front of other popups (in the same map pane).
+	bringToFront: function () {
+		if (this._map) {
+			toFront(this._container);
+		}
+		return this;
+	},
+
+	// @method bringToBack: this
+	// Brings this popup to the back of other popups (in the same map pane).
+	bringToBack: function () {
+		if (this._map) {
+			toBack(this._container);
+		}
+		return this;
+	},
+
+	_updateContent: function () {
+		if (!this._content) { return; }
+
+		var node = this._contentNode;
+		var content = (typeof this._content === 'function') ? this._content(this._source || this) : this._content;
+
+		if (typeof content === 'string') {
+			node.innerHTML = content;
+		} else {
+			while (node.hasChildNodes()) {
+				node.removeChild(node.firstChild);
+			}
+			node.appendChild(content);
+		}
+		this.fire('contentupdate');
+	},
+
+	_updatePosition: function () {
+		if (!this._map) { return; }
+
+		var pos = this._map.latLngToLayerPoint(this._latlng),
+		    offset = toPoint(this.options.offset),
+		    anchor = this._getAnchor();
+
+		if (this._zoomAnimated) {
+			setPosition(this._container, pos.add(anchor));
+		} else {
+			offset = offset.add(pos).add(anchor);
+		}
+
+		var bottom = this._containerBottom = -offset.y,
+		    left = this._containerLeft = -Math.round(this._containerWidth / 2) + offset.x;
+
+		// bottom position the popup in case the height of the popup changes (images loading etc)
+		this._container.style.bottom = bottom + 'px';
+		this._container.style.left = left + 'px';
+	},
+
+	_getAnchor: function () {
+		return [0, 0];
+	}
+
+});
+
+/*
+ * @class Popup
+ * @inherits DivOverlay
+ * @aka L.Popup
+ * Used to open popups in certain places of the map. Use [Map.openPopup](#map-openpopup) to
+ * open popups while making sure that only one popup is open at one time
+ * (recommended for usability), or use [Map.addLayer](#map-addlayer) to open as many as you want.
+ *
+ * @example
+ *
+ * If you want to just bind a popup to marker click and then open it, it's really easy:
+ *
+ * ```js
+ * marker.bindPopup(popupContent).openPopup();
+ * ```
+ * Path overlays like polylines also have a `bindPopup` method.
+ * Here's a more complicated way to open a popup on a map:
+ *
+ * ```js
+ * var popup = L.popup()
+ * 	.setLatLng(latlng)
+ * 	.setContent('<p>Hello world!<br />This is a nice popup.</p>')
+ * 	.openOn(map);
+ * ```
+ */
+
+
+// @namespace Popup
+var Popup = DivOverlay.extend({
+
+	// @section
+	// @aka Popup options
+	options: {
+		// @option maxWidth: Number = 300
+		// Max width of the popup, in pixels.
+		maxWidth: 300,
+
+		// @option minWidth: Number = 50
+		// Min width of the popup, in pixels.
+		minWidth: 50,
+
+		// @option maxHeight: Number = null
+		// If set, creates a scrollable container of the given height
+		// inside a popup if its content exceeds it.
+		maxHeight: null,
+
+		// @option autoPan: Boolean = true
+		// Set it to `false` if you don't want the map to do panning animation
+		// to fit the opened popup.
+		autoPan: true,
+
+		// @option autoPanPaddingTopLeft: Point = null
+		// The margin between the popup and the top left corner of the map
+		// view after autopanning was performed.
+		autoPanPaddingTopLeft: null,
+
+		// @option autoPanPaddingBottomRight: Point = null
+		// The margin between the popup and the bottom right corner of the map
+		// view after autopanning was performed.
+		autoPanPaddingBottomRight: null,
+
+		// @option autoPanPadding: Point = Point(5, 5)
+		// Equivalent of setting both top left and bottom right autopan padding to the same value.
+		autoPanPadding: [5, 5],
+
+		// @option keepInView: Boolean = false
+		// Set it to `true` if you want to prevent users from panning the popup
+		// off of the screen while it is open.
+		keepInView: false,
+
+		// @option closeButton: Boolean = true
+		// Controls the presence of a close button in the popup.
+		closeButton: true,
+
+		// @option autoClose: Boolean = true
+		// Set it to `false` if you want to override the default behavior of
+		// the popup closing when another popup is opened.
+		autoClose: true,
+
+		// @option closeOnEscapeKey: Boolean = true
+		// Set it to `false` if you want to override the default behavior of
+		// the ESC key for closing of the popup.
+		closeOnEscapeKey: true,
+
+		// @option closeOnClick: Boolean = *
+		// Set it if you want to override the default behavior of the popup closing when user clicks
+		// on the map. Defaults to the map's [`closePopupOnClick`](#map-closepopuponclick) option.
+
+		// @option className: String = ''
+		// A custom CSS class name to assign to the popup.
+		className: ''
+	},
+
+	// @namespace Popup
+	// @method openOn(map: Map): this
+	// Adds the popup to the map and closes the previous one. The same as `map.openPopup(popup)`.
+	openOn: function (map) {
+		map.openPopup(this);
+		return this;
+	},
+
+	onAdd: function (map) {
+		DivOverlay.prototype.onAdd.call(this, map);
+
+		// @namespace Map
+		// @section Popup events
+		// @event popupopen: PopupEvent
+		// Fired when a popup is opened in the map
+		map.fire('popupopen', {popup: this});
+
+		if (this._source) {
+			// @namespace Layer
+			// @section Popup events
+			// @event popupopen: PopupEvent
+			// Fired when a popup bound to this layer is opened
+			this._source.fire('popupopen', {popup: this}, true);
+			// For non-path layers, we toggle the popup when clicking
+			// again the layer, so prevent the map to reopen it.
+			if (!(this._source instanceof Path)) {
+				this._source.on('preclick', stopPropagation);
+			}
+		}
+	},
+
+	onRemove: function (map) {
+		DivOverlay.prototype.onRemove.call(this, map);
+
+		// @namespace Map
+		// @section Popup events
+		// @event popupclose: PopupEvent
+		// Fired when a popup in the map is closed
+		map.fire('popupclose', {popup: this});
+
+		if (this._source) {
+			// @namespace Layer
+			// @section Popup events
+			// @event popupclose: PopupEvent
+			// Fired when a popup bound to this layer is closed
+			this._source.fire('popupclose', {popup: this}, true);
+			if (!(this._source instanceof Path)) {
+				this._source.off('preclick', stopPropagation);
+			}
+		}
+	},
+
+	getEvents: function () {
+		var events = DivOverlay.prototype.getEvents.call(this);
+
+		if (this.options.closeOnClick !== undefined ? this.options.closeOnClick : this._map.options.closePopupOnClick) {
+			events.preclick = this._close;
+		}
+
+		if (this.options.keepInView) {
+			events.moveend = this._adjustPan;
+		}
+
+		return events;
+	},
+
+	_close: function () {
+		if (this._map) {
+			this._map.closePopup(this);
+		}
+	},
+
+	_initLayout: function () {
+		var prefix = 'leaflet-popup',
+		    container = this._container = create$1('div',
+			prefix + ' ' + (this.options.className || '') +
+			' leaflet-zoom-animated');
+
+		var wrapper = this._wrapper = create$1('div', prefix + '-content-wrapper', container);
+		this._contentNode = create$1('div', prefix + '-content', wrapper);
+
+		disableClickPropagation(wrapper);
+		disableScrollPropagation(this._contentNode);
+		on(wrapper, 'contextmenu', stopPropagation);
+
+		this._tipContainer = create$1('div', prefix + '-tip-container', container);
+		this._tip = create$1('div', prefix + '-tip', this._tipContainer);
+
+		if (this.options.closeButton) {
+			var closeButton = this._closeButton = create$1('a', prefix + '-close-button', container);
+			closeButton.href = '#close';
+			closeButton.innerHTML = '&#215;';
+
+			on(closeButton, 'click', this._onCloseButtonClick, this);
+		}
+	},
+
+	_updateLayout: function () {
+		var container = this._contentNode,
+		    style = container.style;
+
+		style.width = '';
+		style.whiteSpace = 'nowrap';
+
+		var width = container.offsetWidth;
+		width = Math.min(width, this.options.maxWidth);
+		width = Math.max(width, this.options.minWidth);
+
+		style.width = (width + 1) + 'px';
+		style.whiteSpace = '';
+
+		style.height = '';
+
+		var height = container.offsetHeight,
+		    maxHeight = this.options.maxHeight,
+		    scrolledClass = 'leaflet-popup-scrolled';
+
+		if (maxHeight && height > maxHeight) {
+			style.height = maxHeight + 'px';
+			addClass(container, scrolledClass);
+		} else {
+			removeClass(container, scrolledClass);
+		}
+
+		this._containerWidth = this._container.offsetWidth;
+	},
+
+	_animateZoom: function (e) {
+		var pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center),
+		    anchor = this._getAnchor();
+		setPosition(this._container, pos.add(anchor));
+	},
+
+	_adjustPan: function () {
+		if (!this.options.autoPan || (this._map._panAnim && this._map._panAnim._inProgress)) { return; }
+
+		var map = this._map,
+		    marginBottom = parseInt(getStyle(this._container, 'marginBottom'), 10) || 0,
+		    containerHeight = this._container.offsetHeight + marginBottom,
+		    containerWidth = this._containerWidth,
+		    layerPos = new Point(this._containerLeft, -containerHeight - this._containerBottom);
+
+		layerPos._add(getPosition(this._container));
+
+		var containerPos = map.layerPointToContainerPoint(layerPos),
+		    padding = toPoint(this.options.autoPanPadding),
+		    paddingTL = toPoint(this.options.autoPanPaddingTopLeft || padding),
+		    paddingBR = toPoint(this.options.autoPanPaddingBottomRight || padding),
+		    size = map.getSize(),
+		    dx = 0,
+		    dy = 0;
+
+		if (containerPos.x + containerWidth + paddingBR.x > size.x) { // right
+			dx = containerPos.x + containerWidth - size.x + paddingBR.x;
+		}
+		if (containerPos.x - dx - paddingTL.x < 0) { // left
+			dx = containerPos.x - paddingTL.x;
+		}
+		if (containerPos.y + containerHeight + paddingBR.y > size.y) { // bottom
+			dy = containerPos.y + containerHeight - size.y + paddingBR.y;
+		}
+		if (containerPos.y - dy - paddingTL.y < 0) { // top
+			dy = containerPos.y - paddingTL.y;
+		}
+
+		// @namespace Map
+		// @section Popup events
+		// @event autopanstart: Event
+		// Fired when the map starts autopanning when opening a popup.
+		if (dx || dy) {
+			map
+			    .fire('autopanstart')
+			    .panBy([dx, dy]);
+		}
+	},
+
+	_onCloseButtonClick: function (e) {
+		this._close();
+		stop(e);
+	},
+
+	_getAnchor: function () {
+		// Where should we anchor the popup on the source layer?
+		return toPoint(this._source && this._source._getPopupAnchor ? this._source._getPopupAnchor() : [0, 0]);
+	}
+
+});
+
+// @namespace Popup
+// @factory L.popup(options?: Popup options, source?: Layer)
+// Instantiates a `Popup` object given an optional `options` object that describes its appearance and location and an optional `source` object that is used to tag the popup with a reference to the Layer to which it refers.
+var popup = function (options, source) {
+	return new Popup(options, source);
+};
+
+
+/* @namespace Map
+ * @section Interaction Options
+ * @option closePopupOnClick: Boolean = true
+ * Set it to `false` if you don't want popups to close when user clicks the map.
+ */
+Map.mergeOptions({
+	closePopupOnClick: true
+});
+
+
+// @namespace Map
+// @section Methods for Layers and Controls
+Map.include({
+	// @method openPopup(popup: Popup): this
+	// Opens the specified popup while closing the previously opened (to make sure only one is opened at one time for usability).
+	// @alternative
+	// @method openPopup(content: String|HTMLElement, latlng: LatLng, options?: Popup options): this
+	// Creates a popup with the specified content and options and opens it in the given point on a map.
+	openPopup: function (popup, latlng, options) {
+		if (!(popup instanceof Popup)) {
+			popup = new Popup(options).setContent(popup);
+		}
+
+		if (latlng) {
+			popup.setLatLng(latlng);
+		}
+
+		if (this.hasLayer(popup)) {
+			return this;
+		}
+
+		if (this._popup && this._popup.options.autoClose) {
+			this.closePopup();
+		}
+
+		this._popup = popup;
+		return this.addLayer(popup);
+	},
+
+	// @method closePopup(popup?: Popup): this
+	// Closes the popup previously opened with [openPopup](#map-openpopup) (or the given one).
+	closePopup: function (popup) {
+		if (!popup || popup === this._popup) {
+			popup = this._popup;
+			this._popup = null;
+		}
+		if (popup) {
+			this.removeLayer(popup);
+		}
+		return this;
+	}
+});
+
+/*
+ * @namespace Layer
+ * @section Popup methods example
+ *
+ * All layers share a set of methods convenient for binding popups to it.
+ *
+ * ```js
+ * var layer = L.Polygon(latlngs).bindPopup('Hi There!').addTo(map);
+ * layer.openPopup();
+ * layer.closePopup();
+ * ```
+ *
+ * Popups will also be automatically opened when the layer is clicked on and closed when the layer is removed from the map or another popup is opened.
+ */
+
+// @section Popup methods
+Layer.include({
+
+	// @method bindPopup(content: String|HTMLElement|Function|Popup, options?: Popup options): this
+	// Binds a popup to the layer with the passed `content` and sets up the
+	// necessary event listeners. If a `Function` is passed it will receive
+	// the layer as the first argument and should return a `String` or `HTMLElement`.
+	bindPopup: function (content, options) {
+
+		if (content instanceof Popup) {
+			setOptions(content, options);
+			this._popup = content;
+			content._source = this;
+		} else {
+			if (!this._popup || options) {
+				this._popup = new Popup(options, this);
+			}
+			this._popup.setContent(content);
+		}
+
+		if (!this._popupHandlersAdded) {
+			this.on({
+				click: this._openPopup,
+				keypress: this._onKeyPress,
+				remove: this.closePopup,
+				move: this._movePopup
+			});
+			this._popupHandlersAdded = true;
+		}
+
+		return this;
+	},
+
+	// @method unbindPopup(): this
+	// Removes the popup previously bound with `bindPopup`.
+	unbindPopup: function () {
+		if (this._popup) {
+			this.off({
+				click: this._openPopup,
+				keypress: this._onKeyPress,
+				remove: this.closePopup,
+				move: this._movePopup
+			});
+			this._popupHandlersAdded = false;
+			this._popup = null;
+		}
+		return this;
+	},
+
+	// @method openPopup(latlng?: LatLng): this
+	// Opens the bound popup at the specified `latlng` or at the default popup anchor if no `latlng` is passed.
+	openPopup: function (layer, latlng) {
+		if (!(layer instanceof Layer)) {
+			latlng = layer;
+			layer = this;
+		}
+
+		if (layer instanceof FeatureGroup) {
+			for (var id in this._layers) {
+				layer = this._layers[id];
+				break;
+			}
+		}
+
+		if (!latlng) {
+			latlng = layer.getCenter ? layer.getCenter() : layer.getLatLng();
+		}
+
+		if (this._popup && this._map) {
+			// set popup source to this layer
+			this._popup._source = layer;
+
+			// update the popup (content, layout, ect...)
+			this._popup.update();
+
+			// open the popup on the map
+			this._map.openPopup(this._popup, latlng);
+		}
+
+		return this;
+	},
+
+	// @method closePopup(): this
+	// Closes the popup bound to this layer if it is open.
+	closePopup: function () {
+		if (this._popup) {
+			this._popup._close();
+		}
+		return this;
+	},
+
+	// @method togglePopup(): this
+	// Opens or closes the popup bound to this layer depending on its current state.
+	togglePopup: function (target) {
+		if (this._popup) {
+			if (this._popup._map) {
+				this.closePopup();
+			} else {
+				this.openPopup(target);
+			}
+		}
+		return this;
+	},
+
+	// @method isPopupOpen(): boolean
+	// Returns `true` if the popup bound to this layer is currently open.
+	isPopupOpen: function () {
+		return (this._popup ? this._popup.isOpen() : false);
+	},
+
+	// @method setPopupContent(content: String|HTMLElement|Popup): this
+	// Sets the content of the popup bound to this layer.
+	setPopupContent: function (content) {
+		if (this._popup) {
+			this._popup.setContent(content);
+		}
+		return this;
+	},
+
+	// @method getPopup(): Popup
+	// Returns the popup bound to this layer.
+	getPopup: function () {
+		return this._popup;
+	},
+
+	_openPopup: function (e) {
+		var layer = e.layer || e.target;
+
+		if (!this._popup) {
+			return;
+		}
+
+		if (!this._map) {
+			return;
+		}
+
+		// prevent map click
+		stop(e);
+
+		// if this inherits from Path its a vector and we can just
+		// open the popup at the new location
+		if (layer instanceof Path) {
+			this.openPopup(e.layer || e.target, e.latlng);
+			return;
+		}
+
+		// otherwise treat it like a marker and figure out
+		// if we should toggle it open/closed
+		if (this._map.hasLayer(this._popup) && this._popup._source === layer) {
+			this.closePopup();
+		} else {
+			this.openPopup(layer, e.latlng);
+		}
+	},
+
+	_movePopup: function (e) {
+		this._popup.setLatLng(e.latlng);
+	},
+
+	_onKeyPress: function (e) {
+		if (e.originalEvent.keyCode === 13) {
+			this._openPopup(e);
+		}
+	}
+});
+
+/*
+ * @class Tooltip
+ * @inherits DivOverlay
+ * @aka L.Tooltip
+ * Used to display small texts on top of map layers.
+ *
+ * @example
+ *
+ * ```js
+ * marker.bindTooltip("my tooltip text").openTooltip();
+ * ```
+ * Note about tooltip offset. Leaflet takes two options in consideration
+ * for computing tooltip offsetting:
+ * - the `offset` Tooltip option: it defaults to [0, 0], and it's specific to one tooltip.
+ *   Add a positive x offset to move the tooltip to the right, and a positive y offset to
+ *   move it to the bottom. Negatives will move to the left and top.
+ * - the `tooltipAnchor` Icon option: this will only be considered for Marker. You
+ *   should adapt this value if you use a custom icon.
+ */
+
+
+// @namespace Tooltip
+var Tooltip = DivOverlay.extend({
+
+	// @section
+	// @aka Tooltip options
+	options: {
+		// @option pane: String = 'tooltipPane'
+		// `Map pane` where the tooltip will be added.
+		pane: 'tooltipPane',
+
+		// @option offset: Point = Point(0, 0)
+		// Optional offset of the tooltip position.
+		offset: [0, 0],
+
+		// @option direction: String = 'auto'
+		// Direction where to open the tooltip. Possible values are: `right`, `left`,
+		// `top`, `bottom`, `center`, `auto`.
+		// `auto` will dynamically switch between `right` and `left` according to the tooltip
+		// position on the map.
+		direction: 'auto',
+
+		// @option permanent: Boolean = false
+		// Whether to open the tooltip permanently or only on mouseover.
+		permanent: false,
+
+		// @option sticky: Boolean = false
+		// If true, the tooltip will follow the mouse instead of being fixed at the feature center.
+		sticky: false,
+
+		// @option interactive: Boolean = false
+		// If true, the tooltip will listen to the feature events.
+		interactive: false,
+
+		// @option opacity: Number = 0.9
+		// Tooltip container opacity.
+		opacity: 0.9
+	},
+
+	onAdd: function (map) {
+		DivOverlay.prototype.onAdd.call(this, map);
+		this.setOpacity(this.options.opacity);
+
+		// @namespace Map
+		// @section Tooltip events
+		// @event tooltipopen: TooltipEvent
+		// Fired when a tooltip is opened in the map.
+		map.fire('tooltipopen', {tooltip: this});
+
+		if (this._source) {
+			// @namespace Layer
+			// @section Tooltip events
+			// @event tooltipopen: TooltipEvent
+			// Fired when a tooltip bound to this layer is opened.
+			this._source.fire('tooltipopen', {tooltip: this}, true);
+		}
+	},
+
+	onRemove: function (map) {
+		DivOverlay.prototype.onRemove.call(this, map);
+
+		// @namespace Map
+		// @section Tooltip events
+		// @event tooltipclose: TooltipEvent
+		// Fired when a tooltip in the map is closed.
+		map.fire('tooltipclose', {tooltip: this});
+
+		if (this._source) {
+			// @namespace Layer
+			// @section Tooltip events
+			// @event tooltipclose: TooltipEvent
+			// Fired when a tooltip bound to this layer is closed.
+			this._source.fire('tooltipclose', {tooltip: this}, true);
+		}
+	},
+
+	getEvents: function () {
+		var events = DivOverlay.prototype.getEvents.call(this);
+
+		if (touch && !this.options.permanent) {
+			events.preclick = this._close;
+		}
+
+		return events;
+	},
+
+	_close: function () {
+		if (this._map) {
+			this._map.closeTooltip(this);
+		}
+	},
+
+	_initLayout: function () {
+		var prefix = 'leaflet-tooltip',
+		    className = prefix + ' ' + (this.options.className || '') + ' leaflet-zoom-' + (this._zoomAnimated ? 'animated' : 'hide');
+
+		this._contentNode = this._container = create$1('div', className);
+	},
+
+	_updateLayout: function () {},
+
+	_adjustPan: function () {},
+
+	_setPosition: function (pos) {
+		var map = this._map,
+		    container = this._container,
+		    centerPoint = map.latLngToContainerPoint(map.getCenter()),
+		    tooltipPoint = map.layerPointToContainerPoint(pos),
+		    direction = this.options.direction,
+		    tooltipWidth = container.offsetWidth,
+		    tooltipHeight = container.offsetHeight,
+		    offset = toPoint(this.options.offset),
+		    anchor = this._getAnchor();
+
+		if (direction === 'top') {
+			pos = pos.add(toPoint(-tooltipWidth / 2 + offset.x, -tooltipHeight + offset.y + anchor.y, true));
+		} else if (direction === 'bottom') {
+			pos = pos.subtract(toPoint(tooltipWidth / 2 - offset.x, -offset.y, true));
+		} else if (direction === 'center') {
+			pos = pos.subtract(toPoint(tooltipWidth / 2 + offset.x, tooltipHeight / 2 - anchor.y + offset.y, true));
+		} else if (direction === 'right' || direction === 'auto' && tooltipPoint.x < centerPoint.x) {
+			direction = 'right';
+			pos = pos.add(toPoint(offset.x + anchor.x, anchor.y - tooltipHeight / 2 + offset.y, true));
+		} else {
+			direction = 'left';
+			pos = pos.subtract(toPoint(tooltipWidth + anchor.x - offset.x, tooltipHeight / 2 - anchor.y - offset.y, true));
+		}
+
+		removeClass(container, 'leaflet-tooltip-right');
+		removeClass(container, 'leaflet-tooltip-left');
+		removeClass(container, 'leaflet-tooltip-top');
+		removeClass(container, 'leaflet-tooltip-bottom');
+		addClass(container, 'leaflet-tooltip-' + direction);
+		setPosition(container, pos);
+	},
+
+	_updatePosition: function () {
+		var pos = this._map.latLngToLayerPoint(this._latlng);
+		this._setPosition(pos);
+	},
+
+	setOpacity: function (opacity) {
+		this.options.opacity = opacity;
+
+		if (this._container) {
+			setOpacity(this._container, opacity);
+		}
+	},
+
+	_animateZoom: function (e) {
+		var pos = this._map._latLngToNewLayerPoint(this._latlng, e.zoom, e.center);
+		this._setPosition(pos);
+	},
+
+	_getAnchor: function () {
+		// Where should we anchor the tooltip on the source layer?
+		return toPoint(this._source && this._source._getTooltipAnchor && !this.options.sticky ? this._source._getTooltipAnchor() : [0, 0]);
+	}
+
+});
+
+// @namespace Tooltip
+// @factory L.tooltip(options?: Tooltip options, source?: Layer)
+// Instantiates a Tooltip object given an optional `options` object that describes its appearance and location and an optional `source` object that is used to tag the tooltip with a reference to the Layer to which it refers.
+var tooltip = function (options, source) {
+	return new Tooltip(options, source);
+};
+
+// @namespace Map
+// @section Methods for Layers and Controls
+Map.include({
+
+	// @method openTooltip(tooltip: Tooltip): this
+	// Opens the specified tooltip.
+	// @alternative
+	// @method openTooltip(content: String|HTMLElement, latlng: LatLng, options?: Tooltip options): this
+	// Creates a tooltip with the specified content and options and open it.
+	openTooltip: function (tooltip, latlng, options) {
+		if (!(tooltip instanceof Tooltip)) {
+			tooltip = new Tooltip(options).setContent(tooltip);
+		}
+
+		if (latlng) {
+			tooltip.setLatLng(latlng);
+		}
+
+		if (this.hasLayer(tooltip)) {
+			return this;
+		}
+
+		return this.addLayer(tooltip);
+	},
+
+	// @method closeTooltip(tooltip?: Tooltip): this
+	// Closes the tooltip given as parameter.
+	closeTooltip: function (tooltip) {
+		if (tooltip) {
+			this.removeLayer(tooltip);
+		}
+		return this;
+	}
+
+});
+
+/*
+ * @namespace Layer
+ * @section Tooltip methods example
+ *
+ * All layers share a set of methods convenient for binding tooltips to it.
+ *
+ * ```js
+ * var layer = L.Polygon(latlngs).bindTooltip('Hi There!').addTo(map);
+ * layer.openTooltip();
+ * layer.closeTooltip();
+ * ```
+ */
+
+// @section Tooltip methods
+Layer.include({
+
+	// @method bindTooltip(content: String|HTMLElement|Function|Tooltip, options?: Tooltip options): this
+	// Binds a tooltip to the layer with the passed `content` and sets up the
+	// necessary event listeners. If a `Function` is passed it will receive
+	// the layer as the first argument and should return a `String` or `HTMLElement`.
+	bindTooltip: function (content, options) {
+
+		if (content instanceof Tooltip) {
+			setOptions(content, options);
+			this._tooltip = content;
+			content._source = this;
+		} else {
+			if (!this._tooltip || options) {
+				this._tooltip = new Tooltip(options, this);
+			}
+			this._tooltip.setContent(content);
+
+		}
+
+		this._initTooltipInteractions();
+
+		if (this._tooltip.options.permanent && this._map && this._map.hasLayer(this)) {
+			this.openTooltip();
+		}
+
+		return this;
+	},
+
+	// @method unbindTooltip(): this
+	// Removes the tooltip previously bound with `bindTooltip`.
+	unbindTooltip: function () {
+		if (this._tooltip) {
+			this._initTooltipInteractions(true);
+			this.closeTooltip();
+			this._tooltip = null;
+		}
+		return this;
+	},
+
+	_initTooltipInteractions: function (remove$$1) {
+		if (!remove$$1 && this._tooltipHandlersAdded) { return; }
+		var onOff = remove$$1 ? 'off' : 'on',
+		    events = {
+			remove: this.closeTooltip,
+			move: this._moveTooltip
+		    };
+		if (!this._tooltip.options.permanent) {
+			events.mouseover = this._openTooltip;
+			events.mouseout = this.closeTooltip;
+			if (this._tooltip.options.sticky) {
+				events.mousemove = this._moveTooltip;
+			}
+			if (touch) {
+				events.click = this._openTooltip;
+			}
+		} else {
+			events.add = this._openTooltip;
+		}
+		this[onOff](events);
+		this._tooltipHandlersAdded = !remove$$1;
+	},
+
+	// @method openTooltip(latlng?: LatLng): this
+	// Opens the bound tooltip at the specified `latlng` or at the default tooltip anchor if no `latlng` is passed.
+	openTooltip: function (layer, latlng) {
+		if (!(layer instanceof Layer)) {
+			latlng = layer;
+			layer = this;
+		}
+
+		if (layer instanceof FeatureGroup) {
+			for (var id in this._layers) {
+				layer = this._layers[id];
+				break;
+			}
+		}
+
+		if (!latlng) {
+			latlng = layer.getCenter ? layer.getCenter() : layer.getLatLng();
+		}
+
+		if (this._tooltip && this._map) {
+
+			// set tooltip source to this layer
+			this._tooltip._source = layer;
+
+			// update the tooltip (content, layout, ect...)
+			this._tooltip.update();
+
+			// open the tooltip on the map
+			this._map.openTooltip(this._tooltip, latlng);
+
+			// Tooltip container may not be defined if not permanent and never
+			// opened.
+			if (this._tooltip.options.interactive && this._tooltip._container) {
+				addClass(this._tooltip._container, 'leaflet-clickable');
+				this.addInteractiveTarget(this._tooltip._container);
+			}
+		}
+
+		return this;
+	},
+
+	// @method closeTooltip(): this
+	// Closes the tooltip bound to this layer if it is open.
+	closeTooltip: function () {
+		if (this._tooltip) {
+			this._tooltip._close();
+			if (this._tooltip.options.interactive && this._tooltip._container) {
+				removeClass(this._tooltip._container, 'leaflet-clickable');
+				this.removeInteractiveTarget(this._tooltip._container);
+			}
+		}
+		return this;
+	},
+
+	// @method toggleTooltip(): this
+	// Opens or closes the tooltip bound to this layer depending on its current state.
+	toggleTooltip: function (target) {
+		if (this._tooltip) {
+			if (this._tooltip._map) {
+				this.closeTooltip();
+			} else {
+				this.openTooltip(target);
+			}
+		}
+		return this;
+	},
+
+	// @method isTooltipOpen(): boolean
+	// Returns `true` if the tooltip bound to this layer is currently open.
+	isTooltipOpen: function () {
+		return this._tooltip.isOpen();
+	},
+
+	// @method setTooltipContent(content: String|HTMLElement|Tooltip): this
+	// Sets the content of the tooltip bound to this layer.
+	setTooltipContent: function (content) {
+		if (this._tooltip) {
+			this._tooltip.setContent(content);
+		}
+		return this;
+	},
+
+	// @method getTooltip(): Tooltip
+	// Returns the tooltip bound to this layer.
+	getTooltip: function () {
+		return this._tooltip;
+	},
+
+	_openTooltip: function (e) {
+		var layer = e.layer || e.target;
+
+		if (!this._tooltip || !this._map) {
+			return;
+		}
+		this.openTooltip(layer, this._tooltip.options.sticky ? e.latlng : undefined);
+	},
+
+	_moveTooltip: function (e) {
+		var latlng = e.latlng, containerPoint, layerPoint;
+		if (this._tooltip.options.sticky && e.originalEvent) {
+			containerPoint = this._map.mouseEventToContainerPoint(e.originalEvent);
+			layerPoint = this._map.containerPointToLayerPoint(containerPoint);
+			latlng = this._map.layerPointToLatLng(layerPoint);
+		}
+		this._tooltip.setLatLng(latlng);
+	}
+});
+
+/*
+ * @class DivIcon
+ * @aka L.DivIcon
+ * @inherits Icon
+ *
+ * Represents a lightweight icon for markers that uses a simple `<div>`
+ * element instead of an image. Inherits from `Icon` but ignores the `iconUrl` and shadow options.
+ *
+ * @example
+ * ```js
+ * var myIcon = L.divIcon({className: 'my-div-icon'});
+ * // you can set .my-div-icon styles in CSS
+ *
+ * L.marker([50.505, 30.57], {icon: myIcon}).addTo(map);
+ * ```
+ *
+ * By default, it has a 'leaflet-div-icon' CSS class and is styled as a little white square with a shadow.
+ */
+
+var DivIcon = Icon.extend({
+	options: {
+		// @section
+		// @aka DivIcon options
+		iconSize: [12, 12], // also can be set through CSS
+
+		// iconAnchor: (Point),
+		// popupAnchor: (Point),
+
+		// @option html: String = ''
+		// Custom HTML code to put inside the div element, empty by default.
+		html: false,
+
+		// @option bgPos: Point = [0, 0]
+		// Optional relative position of the background, in pixels
+		bgPos: null,
+
+		className: 'leaflet-div-icon'
+	},
+
+	createIcon: function (oldIcon) {
+		var div = (oldIcon && oldIcon.tagName === 'DIV') ? oldIcon : document.createElement('div'),
+		    options = this.options;
+
+		div.innerHTML = options.html !== false ? options.html : '';
+
+		if (options.bgPos) {
+			var bgPos = toPoint(options.bgPos);
+			div.style.backgroundPosition = (-bgPos.x) + 'px ' + (-bgPos.y) + 'px';
+		}
+		this._setIconStyles(div, 'icon');
+
+		return div;
+	},
+
+	createShadow: function () {
+		return null;
+	}
+});
+
+// @factory L.divIcon(options: DivIcon options)
+// Creates a `DivIcon` instance with the given options.
+function divIcon(options) {
+	return new DivIcon(options);
+}
+
+Icon.Default = IconDefault;
+
+/*
+ * @class GridLayer
+ * @inherits Layer
+ * @aka L.GridLayer
+ *
+ * Generic class for handling a tiled grid of HTML elements. This is the base class for all tile layers and replaces `TileLayer.Canvas`.
+ * GridLayer can be extended to create a tiled grid of HTML elements like `<canvas>`, `<img>` or `<div>`. GridLayer will handle creating and animating these DOM elements for you.
+ *
+ *
+ * @section Synchronous usage
+ * @example
+ *
+ * To create a custom layer, extend GridLayer and implement the `createTile()` method, which will be passed a `Point` object with the `x`, `y`, and `z` (zoom level) coordinates to draw your tile.
+ *
+ * ```js
+ * var CanvasLayer = L.GridLayer.extend({
+ *     createTile: function(coords){
+ *         // create a <canvas> element for drawing
+ *         var tile = L.DomUtil.create('canvas', 'leaflet-tile');
+ *
+ *         // setup tile width and height according to the options
+ *         var size = this.getTileSize();
+ *         tile.width = size.x;
+ *         tile.height = size.y;
+ *
+ *         // get a canvas context and draw something on it using coords.x, coords.y and coords.z
+ *         var ctx = tile.getContext('2d');
+ *
+ *         // return the tile so it can be rendered on screen
+ *         return tile;
+ *     }
+ * });
+ * ```
+ *
+ * @section Asynchronous usage
+ * @example
+ *
+ * Tile creation can also be asynchronous, this is useful when using a third-party drawing library. Once the tile is finished drawing it can be passed to the `done()` callback.
+ *
+ * ```js
+ * var CanvasLayer = L.GridLayer.extend({
+ *     createTile: function(coords, done){
+ *         var error;
+ *
+ *         // create a <canvas> element for drawing
+ *         var tile = L.DomUtil.create('canvas', 'leaflet-tile');
+ *
+ *         // setup tile width and height according to the options
+ *         var size = this.getTileSize();
+ *         tile.width = size.x;
+ *         tile.height = size.y;
+ *
+ *         // draw something asynchronously and pass the tile to the done() callback
+ *         setTimeout(function() {
+ *             done(error, tile);
+ *         }, 1000);
+ *
+ *         return tile;
+ *     }
+ * });
+ * ```
+ *
+ * @section
+ */
+
+
+var GridLayer = Layer.extend({
+
+	// @section
+	// @aka GridLayer options
+	options: {
+		// @option tileSize: Number|Point = 256
+		// Width and height of tiles in the grid. Use a number if width and height are equal, or `L.point(width, height)` otherwise.
+		tileSize: 256,
+
+		// @option opacity: Number = 1.0
+		// Opacity of the tiles. Can be used in the `createTile()` function.
+		opacity: 1,
+
+		// @option updateWhenIdle: Boolean = (depends)
+		// Load new tiles only when panning ends.
+		// `true` by default on mobile browsers, in order to avoid too many requests and keep smooth navigation.
+		// `false` otherwise in order to display new tiles _during_ panning, since it is easy to pan outside the
+		// [`keepBuffer`](#gridlayer-keepbuffer) option in desktop browsers.
+		updateWhenIdle: mobile,
+
+		// @option updateWhenZooming: Boolean = true
+		// By default, a smooth zoom animation (during a [touch zoom](#map-touchzoom) or a [`flyTo()`](#map-flyto)) will update grid layers every integer zoom level. Setting this option to `false` will update the grid layer only when the smooth animation ends.
+		updateWhenZooming: true,
+
+		// @option updateInterval: Number = 200
+		// Tiles will not update more than once every `updateInterval` milliseconds when panning.
+		updateInterval: 200,
+
+		// @option zIndex: Number = 1
+		// The explicit zIndex of the tile layer.
+		zIndex: 1,
+
+		// @option bounds: LatLngBounds = undefined
+		// If set, tiles will only be loaded inside the set `LatLngBounds`.
+		bounds: null,
+
+		// @option minZoom: Number = 0
+		// The minimum zoom level down to which this layer will be displayed (inclusive).
+		minZoom: 0,
+
+		// @option maxZoom: Number = undefined
+		// The maximum zoom level up to which this layer will be displayed (inclusive).
+		maxZoom: undefined,
+
+		// @option maxNativeZoom: Number = undefined
+		// Maximum zoom number the tile source has available. If it is specified,
+		// the tiles on all zoom levels higher than `maxNativeZoom` will be loaded
+		// from `maxNativeZoom` level and auto-scaled.
+		maxNativeZoom: undefined,
+
+		// @option minNativeZoom: Number = undefined
+		// Minimum zoom number the tile source has available. If it is specified,
+		// the tiles on all zoom levels lower than `minNativeZoom` will be loaded
+		// from `minNativeZoom` level and auto-scaled.
+		minNativeZoom: undefined,
+
+		// @option noWrap: Boolean = false
+		// Whether the layer is wrapped around the antimeridian. If `true`, the
+		// GridLayer will only be displayed once at low zoom levels. Has no
+		// effect when the [map CRS](#map-crs) doesn't wrap around. Can be used
+		// in combination with [`bounds`](#gridlayer-bounds) to prevent requesting
+		// tiles outside the CRS limits.
+		noWrap: false,
+
+		// @option pane: String = 'tilePane'
+		// `Map pane` where the grid layer will be added.
+		pane: 'tilePane',
+
+		// @option className: String = ''
+		// A custom class name to assign to the tile layer. Empty by default.
+		className: '',
+
+		// @option keepBuffer: Number = 2
+		// When panning the map, keep this many rows and columns of tiles before unloading them.
+		keepBuffer: 2
+	},
+
+	initialize: function (options) {
+		setOptions(this, options);
+	},
+
+	onAdd: function () {
+		this._initContainer();
+
+		this._levels = {};
+		this._tiles = {};
+
+		this._resetView();
+		this._update();
+	},
+
+	beforeAdd: function (map) {
+		map._addZoomLimit(this);
+	},
+
+	onRemove: function (map) {
+		this._removeAllTiles();
+		remove(this._container);
+		map._removeZoomLimit(this);
+		this._container = null;
+		this._tileZoom = undefined;
+	},
+
+	// @method bringToFront: this
+	// Brings the tile layer to the top of all tile layers.
+	bringToFront: function () {
+		if (this._map) {
+			toFront(this._container);
+			this._setAutoZIndex(Math.max);
+		}
+		return this;
+	},
+
+	// @method bringToBack: this
+	// Brings the tile layer to the bottom of all tile layers.
+	bringToBack: function () {
+		if (this._map) {
+			toBack(this._container);
+			this._setAutoZIndex(Math.min);
+		}
+		return this;
+	},
+
+	// @method getContainer: HTMLElement
+	// Returns the HTML element that contains the tiles for this layer.
+	getContainer: function () {
+		return this._container;
+	},
+
+	// @method setOpacity(opacity: Number): this
+	// Changes the [opacity](#gridlayer-opacity) of the grid layer.
+	setOpacity: function (opacity) {
+		this.options.opacity = opacity;
+		this._updateOpacity();
+		return this;
+	},
+
+	// @method setZIndex(zIndex: Number): this
+	// Changes the [zIndex](#gridlayer-zindex) of the grid layer.
+	setZIndex: function (zIndex) {
+		this.options.zIndex = zIndex;
+		this._updateZIndex();
+
+		return this;
+	},
+
+	// @method isLoading: Boolean
+	// Returns `true` if any tile in the grid layer has not finished loading.
+	isLoading: function () {
+		return this._loading;
+	},
+
+	// @method redraw: this
+	// Causes the layer to clear all the tiles and request them again.
+	redraw: function () {
+		if (this._map) {
+			this._removeAllTiles();
+			this._update();
+		}
+		return this;
+	},
+
+	getEvents: function () {
+		var events = {
+			viewprereset: this._invalidateAll,
+			viewreset: this._resetView,
+			zoom: this._resetView,
+			moveend: this._onMoveEnd
+		};
+
+		if (!this.options.updateWhenIdle) {
+			// update tiles on move, but not more often than once per given interval
+			if (!this._onMove) {
+				this._onMove = throttle(this._onMoveEnd, this.options.updateInterval, this);
+			}
+
+			events.move = this._onMove;
+		}
+
+		if (this._zoomAnimated) {
+			events.zoomanim = this._animateZoom;
+		}
+
+		return events;
+	},
+
+	// @section Extension methods
+	// Layers extending `GridLayer` shall reimplement the following method.
+	// @method createTile(coords: Object, done?: Function): HTMLElement
+	// Called only internally, must be overridden by classes extending `GridLayer`.
+	// Returns the `HTMLElement` corresponding to the given `coords`. If the `done` callback
+	// is specified, it must be called when the tile has finished loading and drawing.
+	createTile: function () {
+		return document.createElement('div');
+	},
+
+	// @section
+	// @method getTileSize: Point
+	// Normalizes the [tileSize option](#gridlayer-tilesize) into a point. Used by the `createTile()` method.
+	getTileSize: function () {
+		var s = this.options.tileSize;
+		return s instanceof Point ? s : new Point(s, s);
+	},
+
+	_updateZIndex: function () {
+		if (this._container && this.options.zIndex !== undefined && this.options.zIndex !== null) {
+			this._container.style.zIndex = this.options.zIndex;
+		}
+	},
+
+	_setAutoZIndex: function (compare) {
+		// go through all other layers of the same pane, set zIndex to max + 1 (front) or min - 1 (back)
+
+		var layers = this.getPane().children,
+		    edgeZIndex = -compare(-Infinity, Infinity); // -Infinity for max, Infinity for min
+
+		for (var i = 0, len = layers.length, zIndex; i < len; i++) {
+
+			zIndex = layers[i].style.zIndex;
+
+			if (layers[i] !== this._container && zIndex) {
+				edgeZIndex = compare(edgeZIndex, +zIndex);
+			}
+		}
+
+		if (isFinite(edgeZIndex)) {
+			this.options.zIndex = edgeZIndex + compare(-1, 1);
+			this._updateZIndex();
+		}
+	},
+
+	_updateOpacity: function () {
+		if (!this._map) { return; }
+
+		// IE doesn't inherit filter opacity properly, so we're forced to set it on tiles
+		if (ielt9) { return; }
+
+		setOpacity(this._container, this.options.opacity);
+
+		var now = +new Date(),
+		    nextFrame = false,
+		    willPrune = false;
+
+		for (var key in this._tiles) {
+			var tile = this._tiles[key];
+			if (!tile.current || !tile.loaded) { continue; }
+
+			var fade = Math.min(1, (now - tile.loaded) / 200);
+
+			setOpacity(tile.el, fade);
+			if (fade < 1) {
+				nextFrame = true;
+			} else {
+				if (tile.active) {
+					willPrune = true;
+				} else {
+					this._onOpaqueTile(tile);
+				}
+				tile.active = true;
+			}
+		}
+
+		if (willPrune && !this._noPrune) { this._pruneTiles(); }
+
+		if (nextFrame) {
+			cancelAnimFrame(this._fadeFrame);
+			this._fadeFrame = requestAnimFrame(this._updateOpacity, this);
+		}
+	},
+
+	_onOpaqueTile: falseFn,
+
+	_initContainer: function () {
+		if (this._container) { return; }
+
+		this._container = create$1('div', 'leaflet-layer ' + (this.options.className || ''));
+		this._updateZIndex();
+
+		if (this.options.opacity < 1) {
+			this._updateOpacity();
+		}
+
+		this.getPane().appendChild(this._container);
+	},
+
+	_updateLevels: function () {
+
+		var zoom = this._tileZoom,
+		    maxZoom = this.options.maxZoom;
+
+		if (zoom === undefined) { return undefined; }
+
+		for (var z in this._levels) {
+			if (this._levels[z].el.children.length || z === zoom) {
+				this._levels[z].el.style.zIndex = maxZoom - Math.abs(zoom - z);
+				this._onUpdateLevel(z);
+			} else {
+				remove(this._levels[z].el);
+				this._removeTilesAtZoom(z);
+				this._onRemoveLevel(z);
+				delete this._levels[z];
+			}
+		}
+
+		var level = this._levels[zoom],
+		    map = this._map;
+
+		if (!level) {
+			level = this._levels[zoom] = {};
+
+			level.el = create$1('div', 'leaflet-tile-container leaflet-zoom-animated', this._container);
+			level.el.style.zIndex = maxZoom;
+
+			level.origin = map.project(map.unproject(map.getPixelOrigin()), zoom).round();
+			level.zoom = zoom;
+
+			this._setZoomTransform(level, map.getCenter(), map.getZoom());
+
+			// force the browser to consider the newly added element for transition
+			falseFn(level.el.offsetWidth);
+
+			this._onCreateLevel(level);
+		}
+
+		this._level = level;
+
+		return level;
+	},
+
+	_onUpdateLevel: falseFn,
+
+	_onRemoveLevel: falseFn,
+
+	_onCreateLevel: falseFn,
+
+	_pruneTiles: function () {
+		if (!this._map) {
+			return;
+		}
+
+		var key, tile;
+
+		var zoom = this._map.getZoom();
+		if (zoom > this.options.maxZoom ||
+			zoom < this.options.minZoom) {
+			this._removeAllTiles();
+			return;
+		}
+
+		for (key in this._tiles) {
+			tile = this._tiles[key];
+			tile.retain = tile.current;
+		}
+
+		for (key in this._tiles) {
+			tile = this._tiles[key];
+			if (tile.current && !tile.active) {
+				var coords = tile.coords;
+				if (!this._retainParent(coords.x, coords.y, coords.z, coords.z - 5)) {
+					this._retainChildren(coords.x, coords.y, coords.z, coords.z + 2);
+				}
+			}
+		}
+
+		for (key in this._tiles) {
+			if (!this._tiles[key].retain) {
+				this._removeTile(key);
+			}
+		}
+	},
+
+	_removeTilesAtZoom: function (zoom) {
+		for (var key in this._tiles) {
+			if (this._tiles[key].coords.z !== zoom) {
+				continue;
+			}
+			this._removeTile(key);
+		}
+	},
+
+	_removeAllTiles: function () {
+		for (var key in this._tiles) {
+			this._removeTile(key);
+		}
+	},
+
+	_invalidateAll: function () {
+		for (var z in this._levels) {
+			remove(this._levels[z].el);
+			this._onRemoveLevel(z);
+			delete this._levels[z];
+		}
+		this._removeAllTiles();
+
+		this._tileZoom = undefined;
+	},
+
+	_retainParent: function (x, y, z, minZoom) {
+		var x2 = Math.floor(x / 2),
+		    y2 = Math.floor(y / 2),
+		    z2 = z - 1,
+		    coords2 = new Point(+x2, +y2);
+		coords2.z = +z2;
+
+		var key = this._tileCoordsToKey(coords2),
+		    tile = this._tiles[key];
+
+		if (tile && tile.active) {
+			tile.retain = true;
+			return true;
+
+		} else if (tile && tile.loaded) {
+			tile.retain = true;
+		}
+
+		if (z2 > minZoom) {
+			return this._retainParent(x2, y2, z2, minZoom);
+		}
+
+		return false;
+	},
+
+	_retainChildren: function (x, y, z, maxZoom) {
+
+		for (var i = 2 * x; i < 2 * x + 2; i++) {
+			for (var j = 2 * y; j < 2 * y + 2; j++) {
+
+				var coords = new Point(i, j);
+				coords.z = z + 1;
+
+				var key = this._tileCoordsToKey(coords),
+				    tile = this._tiles[key];
+
+				if (tile && tile.active) {
+					tile.retain = true;
+					continue;
+
+				} else if (tile && tile.loaded) {
+					tile.retain = true;
+				}
+
+				if (z + 1 < maxZoom) {
+					this._retainChildren(i, j, z + 1, maxZoom);
+				}
+			}
+		}
+	},
+
+	_resetView: function (e) {
+		var animating = e && (e.pinch || e.flyTo);
+		this._setView(this._map.getCenter(), this._map.getZoom(), animating, animating);
+	},
+
+	_animateZoom: function (e) {
+		this._setView(e.center, e.zoom, true, e.noUpdate);
+	},
+
+	_clampZoom: function (zoom) {
+		var options = this.options;
+
+		if (undefined !== options.minNativeZoom && zoom < options.minNativeZoom) {
+			return options.minNativeZoom;
+		}
+
+		if (undefined !== options.maxNativeZoom && options.maxNativeZoom < zoom) {
+			return options.maxNativeZoom;
+		}
+
+		return zoom;
+	},
+
+	_setView: function (center, zoom, noPrune, noUpdate) {
+		var tileZoom = this._clampZoom(Math.round(zoom));
+		if ((this.options.maxZoom !== undefined && tileZoom > this.options.maxZoom) ||
+		    (this.options.minZoom !== undefined && tileZoom < this.options.minZoom)) {
+			tileZoom = undefined;
+		}
+
+		var tileZoomChanged = this.options.updateWhenZooming && (tileZoom !== this._tileZoom);
+
+		if (!noUpdate || tileZoomChanged) {
+
+			this._tileZoom = tileZoom;
+
+			if (this._abortLoading) {
+				this._abortLoading();
+			}
+
+			this._updateLevels();
+			this._resetGrid();
+
+			if (tileZoom !== undefined) {
+				this._update(center);
+			}
+
+			if (!noPrune) {
+				this._pruneTiles();
+			}
+
+			// Flag to prevent _updateOpacity from pruning tiles during
+			// a zoom anim or a pinch gesture
+			this._noPrune = !!noPrune;
+		}
+
+		this._setZoomTransforms(center, zoom);
+	},
+
+	_setZoomTransforms: function (center, zoom) {
+		for (var i in this._levels) {
+			this._setZoomTransform(this._levels[i], center, zoom);
+		}
+	},
+
+	_setZoomTransform: function (level, center, zoom) {
+		var scale = this._map.getZoomScale(zoom, level.zoom),
+		    translate = level.origin.multiplyBy(scale)
+		        .subtract(this._map._getNewPixelOrigin(center, zoom)).round();
+
+		if (any3d) {
+			setTransform(level.el, translate, scale);
+		} else {
+			setPosition(level.el, translate);
+		}
+	},
+
+	_resetGrid: function () {
+		var map = this._map,
+		    crs = map.options.crs,
+		    tileSize = this._tileSize = this.getTileSize(),
+		    tileZoom = this._tileZoom;
+
+		var bounds = this._map.getPixelWorldBounds(this._tileZoom);
+		if (bounds) {
+			this._globalTileRange = this._pxBoundsToTileRange(bounds);
+		}
+
+		this._wrapX = crs.wrapLng && !this.options.noWrap && [
+			Math.floor(map.project([0, crs.wrapLng[0]], tileZoom).x / tileSize.x),
+			Math.ceil(map.project([0, crs.wrapLng[1]], tileZoom).x / tileSize.y)
+		];
+		this._wrapY = crs.wrapLat && !this.options.noWrap && [
+			Math.floor(map.project([crs.wrapLat[0], 0], tileZoom).y / tileSize.x),
+			Math.ceil(map.project([crs.wrapLat[1], 0], tileZoom).y / tileSize.y)
+		];
+	},
+
+	_onMoveEnd: function () {
+		if (!this._map || this._map._animatingZoom) { return; }
+
+		this._update();
+	},
+
+	_getTiledPixelBounds: function (center) {
+		var map = this._map,
+		    mapZoom = map._animatingZoom ? Math.max(map._animateToZoom, map.getZoom()) : map.getZoom(),
+		    scale = map.getZoomScale(mapZoom, this._tileZoom),
+		    pixelCenter = map.project(center, this._tileZoom).floor(),
+		    halfSize = map.getSize().divideBy(scale * 2);
+
+		return new Bounds(pixelCenter.subtract(halfSize), pixelCenter.add(halfSize));
+	},
+
+	// Private method to load tiles in the grid's active zoom level according to map bounds
+	_update: function (center) {
+		var map = this._map;
+		if (!map) { return; }
+		var zoom = this._clampZoom(map.getZoom());
+
+		if (center === undefined) { center = map.getCenter(); }
+		if (this._tileZoom === undefined) { return; }	// if out of minzoom/maxzoom
+
+		var pixelBounds = this._getTiledPixelBounds(center),
+		    tileRange = this._pxBoundsToTileRange(pixelBounds),
+		    tileCenter = tileRange.getCenter(),
+		    queue = [],
+		    margin = this.options.keepBuffer,
+		    noPruneRange = new Bounds(tileRange.getBottomLeft().subtract([margin, -margin]),
+		                              tileRange.getTopRight().add([margin, -margin]));
+
+		// Sanity check: panic if the tile range contains Infinity somewhere.
+		if (!(isFinite(tileRange.min.x) &&
+		      isFinite(tileRange.min.y) &&
+		      isFinite(tileRange.max.x) &&
+		      isFinite(tileRange.max.y))) { throw new Error('Attempted to load an infinite number of tiles'); }
+
+		for (var key in this._tiles) {
+			var c = this._tiles[key].coords;
+			if (c.z !== this._tileZoom || !noPruneRange.contains(new Point(c.x, c.y))) {
+				this._tiles[key].current = false;
+			}
+		}
+
+		// _update just loads more tiles. If the tile zoom level differs too much
+		// from the map's, let _setView reset levels and prune old tiles.
+		if (Math.abs(zoom - this._tileZoom) > 1) { this._setView(center, zoom); return; }
+
+		// create a queue of coordinates to load tiles from
+		for (var j = tileRange.min.y; j <= tileRange.max.y; j++) {
+			for (var i = tileRange.min.x; i <= tileRange.max.x; i++) {
+				var coords = new Point(i, j);
+				coords.z = this._tileZoom;
+
+				if (!this._isValidTile(coords)) { continue; }
+
+				var tile = this._tiles[this._tileCoordsToKey(coords)];
+				if (tile) {
+					tile.current = true;
+				} else {
+					queue.push(coords);
+				}
+			}
+		}
+
+		// sort tile queue to load tiles in order of their distance to center
+		queue.sort(function (a, b) {
+			return a.distanceTo(tileCenter) - b.distanceTo(tileCenter);
+		});
+
+		if (queue.length !== 0) {
+			// if it's the first batch of tiles to load
+			if (!this._loading) {
+				this._loading = true;
+				// @event loading: Event
+				// Fired when the grid layer starts loading tiles.
+				this.fire('loading');
+			}
+
+			// create DOM fragment to append tiles in one batch
+			var fragment = document.createDocumentFragment();
+
+			for (i = 0; i < queue.length; i++) {
+				this._addTile(queue[i], fragment);
+			}
+
+			this._level.el.appendChild(fragment);
+		}
+	},
+
+	_isValidTile: function (coords) {
+		var crs = this._map.options.crs;
+
+		if (!crs.infinite) {
+			// don't load tile if it's out of bounds and not wrapped
+			var bounds = this._globalTileRange;
+			if ((!crs.wrapLng && (coords.x < bounds.min.x || coords.x > bounds.max.x)) ||
+			    (!crs.wrapLat && (coords.y < bounds.min.y || coords.y > bounds.max.y))) { return false; }
+		}
+
+		if (!this.options.bounds) { return true; }
+
+		// don't load tile if it doesn't intersect the bounds in options
+		var tileBounds = this._tileCoordsToBounds(coords);
+		return toLatLngBounds(this.options.bounds).overlaps(tileBounds);
+	},
+
+	_keyToBounds: function (key) {
+		return this._tileCoordsToBounds(this._keyToTileCoords(key));
+	},
+
+	_tileCoordsToNwSe: function (coords) {
+		var map = this._map,
+		    tileSize = this.getTileSize(),
+		    nwPoint = coords.scaleBy(tileSize),
+		    sePoint = nwPoint.add(tileSize),
+		    nw = map.unproject(nwPoint, coords.z),
+		    se = map.unproject(sePoint, coords.z);
+		return [nw, se];
+	},
+
+	// converts tile coordinates to its geographical bounds
+	_tileCoordsToBounds: function (coords) {
+		var bp = this._tileCoordsToNwSe(coords),
+		    bounds = new LatLngBounds(bp[0], bp[1]);
+
+		if (!this.options.noWrap) {
+			bounds = this._map.wrapLatLngBounds(bounds);
+		}
+		return bounds;
+	},
+	// converts tile coordinates to key for the tile cache
+	_tileCoordsToKey: function (coords) {
+		return coords.x + ':' + coords.y + ':' + coords.z;
+	},
+
+	// converts tile cache key to coordinates
+	_keyToTileCoords: function (key) {
+		var k = key.split(':'),
+		    coords = new Point(+k[0], +k[1]);
+		coords.z = +k[2];
+		return coords;
+	},
+
+	_removeTile: function (key) {
+		var tile = this._tiles[key];
+		if (!tile) { return; }
+
+		// Cancels any pending http requests associated with the tile
+		// unless we're on Android's stock browser,
+		// see https://github.com/Leaflet/Leaflet/issues/137
+		if (!androidStock) {
+			tile.el.setAttribute('src', emptyImageUrl);
+		}
+		remove(tile.el);
+
+		delete this._tiles[key];
+
+		// @event tileunload: TileEvent
+		// Fired when a tile is removed (e.g. when a tile goes off the screen).
+		this.fire('tileunload', {
+			tile: tile.el,
+			coords: this._keyToTileCoords(key)
+		});
+	},
+
+	_initTile: function (tile) {
+		addClass(tile, 'leaflet-tile');
+
+		var tileSize = this.getTileSize();
+		tile.style.width = tileSize.x + 'px';
+		tile.style.height = tileSize.y + 'px';
+
+		tile.onselectstart = falseFn;
+		tile.onmousemove = falseFn;
+
+		// update opacity on tiles in IE7-8 because of filter inheritance problems
+		if (ielt9 && this.options.opacity < 1) {
+			setOpacity(tile, this.options.opacity);
+		}
+
+		// without this hack, tiles disappear after zoom on Chrome for Android
+		// https://github.com/Leaflet/Leaflet/issues/2078
+		if (android && !android23) {
+			tile.style.WebkitBackfaceVisibility = 'hidden';
+		}
+	},
+
+	_addTile: function (coords, container) {
+		var tilePos = this._getTilePos(coords),
+		    key = this._tileCoordsToKey(coords);
+
+		var tile = this.createTile(this._wrapCoords(coords), bind(this._tileReady, this, coords));
+
+		this._initTile(tile);
+
+		// if createTile is defined with a second argument ("done" callback),
+		// we know that tile is async and will be ready later; otherwise
+		if (this.createTile.length < 2) {
+			// mark tile as ready, but delay one frame for opacity animation to happen
+			requestAnimFrame(bind(this._tileReady, this, coords, null, tile));
+		}
+
+		setPosition(tile, tilePos);
+
+		// save tile in cache
+		this._tiles[key] = {
+			el: tile,
+			coords: coords,
+			current: true
+		};
+
+		container.appendChild(tile);
+		// @event tileloadstart: TileEvent
+		// Fired when a tile is requested and starts loading.
+		this.fire('tileloadstart', {
+			tile: tile,
+			coords: coords
+		});
+	},
+
+	_tileReady: function (coords, err, tile) {
+		if (!this._map) { return; }
+
+		if (err) {
+			// @event tileerror: TileErrorEvent
+			// Fired when there is an error loading a tile.
+			this.fire('tileerror', {
+				error: err,
+				tile: tile,
+				coords: coords
+			});
+		}
+
+		var key = this._tileCoordsToKey(coords);
+
+		tile = this._tiles[key];
+		if (!tile) { return; }
+
+		tile.loaded = +new Date();
+		if (this._map._fadeAnimated) {
+			setOpacity(tile.el, 0);
+			cancelAnimFrame(this._fadeFrame);
+			this._fadeFrame = requestAnimFrame(this._updateOpacity, this);
+		} else {
+			tile.active = true;
+			this._pruneTiles();
+		}
+
+		if (!err) {
+			addClass(tile.el, 'leaflet-tile-loaded');
+
+			// @event tileload: TileEvent
+			// Fired when a tile loads.
+			this.fire('tileload', {
+				tile: tile.el,
+				coords: coords
+			});
+		}
+
+		if (this._noTilesToLoad()) {
+			this._loading = false;
+			// @event load: Event
+			// Fired when the grid layer loaded all visible tiles.
+			this.fire('load');
+
+			if (ielt9 || !this._map._fadeAnimated) {
+				requestAnimFrame(this._pruneTiles, this);
+			} else {
+				// Wait a bit more than 0.2 secs (the duration of the tile fade-in)
+				// to trigger a pruning.
+				setTimeout(bind(this._pruneTiles, this), 250);
+			}
+		}
+	},
+
+	_getTilePos: function (coords) {
+		return coords.scaleBy(this.getTileSize()).subtract(this._level.origin);
+	},
+
+	_wrapCoords: function (coords) {
+		var newCoords = new Point(
+			this._wrapX ? wrapNum(coords.x, this._wrapX) : coords.x,
+			this._wrapY ? wrapNum(coords.y, this._wrapY) : coords.y);
+		newCoords.z = coords.z;
+		return newCoords;
+	},
+
+	_pxBoundsToTileRange: function (bounds) {
+		var tileSize = this.getTileSize();
+		return new Bounds(
+			bounds.min.unscaleBy(tileSize).floor(),
+			bounds.max.unscaleBy(tileSize).ceil().subtract([1, 1]));
+	},
+
+	_noTilesToLoad: function () {
+		for (var key in this._tiles) {
+			if (!this._tiles[key].loaded) { return false; }
+		}
+		return true;
+	}
+});
+
+// @factory L.gridLayer(options?: GridLayer options)
+// Creates a new instance of GridLayer with the supplied options.
+function gridLayer(options) {
+	return new GridLayer(options);
+}
+
+/*
+ * @class TileLayer
+ * @inherits GridLayer
+ * @aka L.TileLayer
+ * Used to load and display tile layers on the map. Extends `GridLayer`.
+ *
+ * @example
+ *
+ * ```js
+ * L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png?{foo}', {foo: 'bar'}).addTo(map);
+ * ```
+ *
+ * @section URL template
+ * @example
+ *
+ * A string of the following form:
+ *
+ * ```
+ * 'http://{s}.somedomain.com/blabla/{z}/{x}/{y}{r}.png'
+ * ```
+ *
+ * `{s}` means one of the available subdomains (used sequentially to help with browser parallel requests per domain limitation; subdomain values are specified in options; `a`, `b` or `c` by default, can be omitted), `{z}` — zoom level, `{x}` and `{y}` — tile coordinates. `{r}` can be used to add "&commat;2x" to the URL to load retina tiles.
+ *
+ * You can use custom keys in the template, which will be [evaluated](#util-template) from TileLayer options, like this:
+ *
+ * ```
+ * L.tileLayer('http://{s}.somedomain.com/{foo}/{z}/{x}/{y}.png', {foo: 'bar'});
+ * ```
+ */
+
+
+var TileLayer = GridLayer.extend({
+
+	// @section
+	// @aka TileLayer options
+	options: {
+		// @option minZoom: Number = 0
+		// The minimum zoom level down to which this layer will be displayed (inclusive).
+		minZoom: 0,
+
+		// @option maxZoom: Number = 18
+		// The maximum zoom level up to which this layer will be displayed (inclusive).
+		maxZoom: 18,
+
+		// @option subdomains: String|String[] = 'abc'
+		// Subdomains of the tile service. Can be passed in the form of one string (where each letter is a subdomain name) or an array of strings.
+		subdomains: 'abc',
+
+		// @option errorTileUrl: String = ''
+		// URL to the tile image to show in place of the tile that failed to load.
+		errorTileUrl: '',
+
+		// @option zoomOffset: Number = 0
+		// The zoom number used in tile URLs will be offset with this value.
+		zoomOffset: 0,
+
+		// @option tms: Boolean = false
+		// If `true`, inverses Y axis numbering for tiles (turn this on for [TMS](https://en.wikipedia.org/wiki/Tile_Map_Service) services).
+		tms: false,
+
+		// @option zoomReverse: Boolean = false
+		// If set to true, the zoom number used in tile URLs will be reversed (`maxZoom - zoom` instead of `zoom`)
+		zoomReverse: false,
+
+		// @option detectRetina: Boolean = false
+		// If `true` and user is on a retina display, it will request four tiles of half the specified size and a bigger zoom level in place of one to utilize the high resolution.
+		detectRetina: false,
+
+		// @option crossOrigin: Boolean = false
+		// If true, all tiles will have their crossOrigin attribute set to ''. This is needed if you want to access tile pixel data.
+		crossOrigin: false
+	},
+
+	initialize: function (url, options) {
+
+		this._url = url;
+
+		options = setOptions(this, options);
+
+		// detecting retina displays, adjusting tileSize and zoom levels
+		if (options.detectRetina && retina && options.maxZoom > 0) {
+
+			options.tileSize = Math.floor(options.tileSize / 2);
+
+			if (!options.zoomReverse) {
+				options.zoomOffset++;
+				options.maxZoom--;
+			} else {
+				options.zoomOffset--;
+				options.minZoom++;
+			}
+
+			options.minZoom = Math.max(0, options.minZoom);
+		}
+
+		if (typeof options.subdomains === 'string') {
+			options.subdomains = options.subdomains.split('');
+		}
+
+		// for https://github.com/Leaflet/Leaflet/issues/137
+		if (!android) {
+			this.on('tileunload', this._onTileRemove);
+		}
+	},
+
+	// @method setUrl(url: String, noRedraw?: Boolean): this
+	// Updates the layer's URL template and redraws it (unless `noRedraw` is set to `true`).
+	setUrl: function (url, noRedraw) {
+		this._url = url;
+
+		if (!noRedraw) {
+			this.redraw();
+		}
+		return this;
+	},
+
+	// @method createTile(coords: Object, done?: Function): HTMLElement
+	// Called only internally, overrides GridLayer's [`createTile()`](#gridlayer-createtile)
+	// to return an `<img>` HTML element with the appropriate image URL given `coords`. The `done`
+	// callback is called when the tile has been loaded.
+	createTile: function (coords, done) {
+		var tile = document.createElement('img');
+
+		on(tile, 'load', bind(this._tileOnLoad, this, done, tile));
+		on(tile, 'error', bind(this._tileOnError, this, done, tile));
+
+		if (this.options.crossOrigin) {
+			tile.crossOrigin = '';
+		}
+
+		/*
+		 Alt tag is set to empty string to keep screen readers from reading URL and for compliance reasons
+		 http://www.w3.org/TR/WCAG20-TECHS/H67
+		*/
+		tile.alt = '';
+
+		/*
+		 Set role="presentation" to force screen readers to ignore this
+		 https://www.w3.org/TR/wai-aria/roles#textalternativecomputation
+		*/
+		tile.setAttribute('role', 'presentation');
+
+		tile.src = this.getTileUrl(coords);
+
+		return tile;
+	},
+
+	// @section Extension methods
+	// @uninheritable
+	// Layers extending `TileLayer` might reimplement the following method.
+	// @method getTileUrl(coords: Object): String
+	// Called only internally, returns the URL for a tile given its coordinates.
+	// Classes extending `TileLayer` can override this function to provide custom tile URL naming schemes.
+	getTileUrl: function (coords) {
+		var data = {
+			r: retina ? '@2x' : '',
+			s: this._getSubdomain(coords),
+			x: coords.x,
+			y: coords.y,
+			z: this._getZoomForUrl()
+		};
+		if (this._map && !this._map.options.crs.infinite) {
+			var invertedY = this._globalTileRange.max.y - coords.y;
+			if (this.options.tms) {
+				data['y'] = invertedY;
+			}
+			data['-y'] = invertedY;
+		}
+
+		return template(this._url, extend(data, this.options));
+	},
+
+	_tileOnLoad: function (done, tile) {
+		// For https://github.com/Leaflet/Leaflet/issues/3332
+		if (ielt9) {
+			setTimeout(bind(done, this, null, tile), 0);
+		} else {
+			done(null, tile);
+		}
+	},
+
+	_tileOnError: function (done, tile, e) {
+		var errorUrl = this.options.errorTileUrl;
+		if (errorUrl && tile.getAttribute('src') !== errorUrl) {
+			tile.src = errorUrl;
+		}
+		done(e, tile);
+	},
+
+	_onTileRemove: function (e) {
+		e.tile.onload = null;
+	},
+
+	_getZoomForUrl: function () {
+		var zoom = this._tileZoom,
+		maxZoom = this.options.maxZoom,
+		zoomReverse = this.options.zoomReverse,
+		zoomOffset = this.options.zoomOffset;
+
+		if (zoomReverse) {
+			zoom = maxZoom - zoom;
+		}
+
+		return zoom + zoomOffset;
+	},
+
+	_getSubdomain: function (tilePoint) {
+		var index = Math.abs(tilePoint.x + tilePoint.y) % this.options.subdomains.length;
+		return this.options.subdomains[index];
+	},
+
+	// stops loading all tiles in the background layer
+	_abortLoading: function () {
+		var i, tile;
+		for (i in this._tiles) {
+			if (this._tiles[i].coords.z !== this._tileZoom) {
+				tile = this._tiles[i].el;
+
+				tile.onload = falseFn;
+				tile.onerror = falseFn;
+
+				if (!tile.complete) {
+					tile.src = emptyImageUrl;
+					remove(tile);
+					delete this._tiles[i];
+				}
+			}
+		}
+	}
+});
+
+
+// @factory L.tilelayer(urlTemplate: String, options?: TileLayer options)
+// Instantiates a tile layer object given a `URL template` and optionally an options object.
+
+function tileLayer(url, options) {
+	return new TileLayer(url, options);
+}
+
+/*
+ * @class TileLayer.WMS
+ * @inherits TileLayer
+ * @aka L.TileLayer.WMS
+ * Used to display [WMS](https://en.wikipedia.org/wiki/Web_Map_Service) services as tile layers on the map. Extends `TileLayer`.
+ *
+ * @example
+ *
+ * ```js
+ * var nexrad = L.tileLayer.wms("http://mesonet.agron.iastate.edu/cgi-bin/wms/nexrad/n0r.cgi", {
+ * 	layers: 'nexrad-n0r-900913',
+ * 	format: 'image/png',
+ * 	transparent: true,
+ * 	attribution: "Weather data © 2012 IEM Nexrad"
+ * });
+ * ```
+ */
+
+var TileLayerWMS = TileLayer.extend({
+
+	// @section
+	// @aka TileLayer.WMS options
+	// If any custom options not documented here are used, they will be sent to the
+	// WMS server as extra parameters in each request URL. This can be useful for
+	// [non-standard vendor WMS parameters](http://docs.geoserver.org/stable/en/user/services/wms/vendor.html).
+	defaultWmsParams: {
+		service: 'WMS',
+		request: 'GetMap',
+
+		// @option layers: String = ''
+		// **(required)** Comma-separated list of WMS layers to show.
+		layers: '',
+
+		// @option styles: String = ''
+		// Comma-separated list of WMS styles.
+		styles: '',
+
+		// @option format: String = 'image/jpeg'
+		// WMS image format (use `'image/png'` for layers with transparency).
+		format: 'image/jpeg',
+
+		// @option transparent: Boolean = false
+		// If `true`, the WMS service will return images with transparency.
+		transparent: false,
+
+		// @option version: String = '1.1.1'
+		// Version of the WMS service to use
+		version: '1.1.1'
+	},
+
+	options: {
+		// @option crs: CRS = null
+		// Coordinate Reference System to use for the WMS requests, defaults to
+		// map CRS. Don't change this if you're not sure what it means.
+		crs: null,
+
+		// @option uppercase: Boolean = false
+		// If `true`, WMS request parameter keys will be uppercase.
+		uppercase: false
+	},
+
+	initialize: function (url, options) {
+
+		this._url = url;
+
+		var wmsParams = extend({}, this.defaultWmsParams);
+
+		// all keys that are not TileLayer options go to WMS params
+		for (var i in options) {
+			if (!(i in this.options)) {
+				wmsParams[i] = options[i];
+			}
+		}
+
+		options = setOptions(this, options);
+
+		var realRetina = options.detectRetina && retina ? 2 : 1;
+		var tileSize = this.getTileSize();
+		wmsParams.width = tileSize.x * realRetina;
+		wmsParams.height = tileSize.y * realRetina;
+
+		this.wmsParams = wmsParams;
+	},
+
+	onAdd: function (map) {
+
+		this._crs = this.options.crs || map.options.crs;
+		this._wmsVersion = parseFloat(this.wmsParams.version);
+
+		var projectionKey = this._wmsVersion >= 1.3 ? 'crs' : 'srs';
+		this.wmsParams[projectionKey] = this._crs.code;
+
+		TileLayer.prototype.onAdd.call(this, map);
+	},
+
+	getTileUrl: function (coords) {
+
+		var tileBounds = this._tileCoordsToNwSe(coords),
+		    crs = this._crs,
+		    bounds = toBounds(crs.project(tileBounds[0]), crs.project(tileBounds[1])),
+		    min = bounds.min,
+		    max = bounds.max,
+		    bbox = (this._wmsVersion >= 1.3 && this._crs === EPSG4326 ?
+		    [min.y, min.x, max.y, max.x] :
+		    [min.x, min.y, max.x, max.y]).join(','),
+		url = L.TileLayer.prototype.getTileUrl.call(this, coords);
+		return url +
+			getParamString(this.wmsParams, url, this.options.uppercase) +
+			(this.options.uppercase ? '&BBOX=' : '&bbox=') + bbox;
+	},
+
+	// @method setParams(params: Object, noRedraw?: Boolean): this
+	// Merges an object with the new parameters and re-requests tiles on the current screen (unless `noRedraw` was set to true).
+	setParams: function (params, noRedraw) {
+
+		extend(this.wmsParams, params);
+
+		if (!noRedraw) {
+			this.redraw();
+		}
+
+		return this;
+	}
+});
+
+
+// @factory L.tileLayer.wms(baseUrl: String, options: TileLayer.WMS options)
+// Instantiates a WMS tile layer object given a base URL of the WMS service and a WMS parameters/options object.
+function tileLayerWMS(url, options) {
+	return new TileLayerWMS(url, options);
+}
+
+TileLayer.WMS = TileLayerWMS;
+tileLayer.wms = tileLayerWMS;
+
+/*
+ * @class Renderer
+ * @inherits Layer
+ * @aka L.Renderer
+ *
+ * Base class for vector renderer implementations (`SVG`, `Canvas`). Handles the
+ * DOM container of the renderer, its bounds, and its zoom animation.
+ *
+ * A `Renderer` works as an implicit layer group for all `Path`s - the renderer
+ * itself can be added or removed to the map. All paths use a renderer, which can
+ * be implicit (the map will decide the type of renderer and use it automatically)
+ * or explicit (using the [`renderer`](#path-renderer) option of the path).
+ *
+ * Do not use this class directly, use `SVG` and `Canvas` instead.
+ *
+ * @event update: Event
+ * Fired when the renderer updates its bounds, center and zoom, for example when
+ * its map has moved
+ */
+
+var Renderer = Layer.extend({
+
+	// @section
+	// @aka Renderer options
+	options: {
+		// @option padding: Number = 0.1
+		// How much to extend the clip area around the map view (relative to its size)
+		// e.g. 0.1 would be 10% of map view in each direction
+		padding: 0.1,
+
+		// @option tolerance: Number = 0
+		// How much to extend click tolerance round a path/object on the map
+		tolerance : 0
+	},
+
+	initialize: function (options) {
+		setOptions(this, options);
+		stamp(this);
+		this._layers = this._layers || {};
+	},
+
+	onAdd: function () {
+		if (!this._container) {
+			this._initContainer(); // defined by renderer implementations
+
+			if (this._zoomAnimated) {
+				addClass(this._container, 'leaflet-zoom-animated');
+			}
+		}
+
+		this.getPane().appendChild(this._container);
+		this._update();
+		this.on('update', this._updatePaths, this);
+	},
+
+	onRemove: function () {
+		this.off('update', this._updatePaths, this);
+		this._destroyContainer();
+	},
+
+	getEvents: function () {
+		var events = {
+			viewreset: this._reset,
+			zoom: this._onZoom,
+			moveend: this._update,
+			zoomend: this._onZoomEnd
+		};
+		if (this._zoomAnimated) {
+			events.zoomanim = this._onAnimZoom;
+		}
+		return events;
+	},
+
+	_onAnimZoom: function (ev) {
+		this._updateTransform(ev.center, ev.zoom);
+	},
+
+	_onZoom: function () {
+		this._updateTransform(this._map.getCenter(), this._map.getZoom());
+	},
+
+	_updateTransform: function (center, zoom) {
+		var scale = this._map.getZoomScale(zoom, this._zoom),
+		    position = getPosition(this._container),
+		    viewHalf = this._map.getSize().multiplyBy(0.5 + this.options.padding),
+		    currentCenterPoint = this._map.project(this._center, zoom),
+		    destCenterPoint = this._map.project(center, zoom),
+		    centerOffset = destCenterPoint.subtract(currentCenterPoint),
+
+		    topLeftOffset = viewHalf.multiplyBy(-scale).add(position).add(viewHalf).subtract(centerOffset);
+
+		if (any3d) {
+			setTransform(this._container, topLeftOffset, scale);
+		} else {
+			setPosition(this._container, topLeftOffset);
+		}
+	},
+
+	_reset: function () {
+		this._update();
+		this._updateTransform(this._center, this._zoom);
+
+		for (var id in this._layers) {
+			this._layers[id]._reset();
+		}
+	},
+
+	_onZoomEnd: function () {
+		for (var id in this._layers) {
+			this._layers[id]._project();
+		}
+	},
+
+	_updatePaths: function () {
+		for (var id in this._layers) {
+			this._layers[id]._update();
+		}
+	},
+
+	_update: function () {
+		// Update pixel bounds of renderer container (for positioning/sizing/clipping later)
+		// Subclasses are responsible of firing the 'update' event.
+		var p = this.options.padding,
+		    size = this._map.getSize(),
+		    min = this._map.containerPointToLayerPoint(size.multiplyBy(-p)).round();
+
+		this._bounds = new Bounds(min, min.add(size.multiplyBy(1 + p * 2)).round());
+
+		this._center = this._map.getCenter();
+		this._zoom = this._map.getZoom();
+	}
+});
+
+/*
+ * @class Canvas
+ * @inherits Renderer
+ * @aka L.Canvas
+ *
+ * Allows vector layers to be displayed with [`<canvas>`](https://developer.mozilla.org/docs/Web/API/Canvas_API).
+ * Inherits `Renderer`.
+ *
+ * Due to [technical limitations](http://caniuse.com/#search=canvas), Canvas is not
+ * available in all web browsers, notably IE8, and overlapping geometries might
+ * not display properly in some edge cases.
+ *
+ * @example
+ *
+ * Use Canvas by default for all paths in the map:
+ *
+ * ```js
+ * var map = L.map('map', {
+ * 	renderer: L.canvas()
+ * });
+ * ```
+ *
+ * Use a Canvas renderer with extra padding for specific vector geometries:
+ *
+ * ```js
+ * var map = L.map('map');
+ * var myRenderer = L.canvas({ padding: 0.5 });
+ * var line = L.polyline( coordinates, { renderer: myRenderer } );
+ * var circle = L.circle( center, { renderer: myRenderer } );
+ * ```
+ */
+
+var Canvas = Renderer.extend({
+	getEvents: function () {
+		var events = Renderer.prototype.getEvents.call(this);
+		events.viewprereset = this._onViewPreReset;
+		return events;
+	},
+
+	_onViewPreReset: function () {
+		// Set a flag so that a viewprereset+moveend+viewreset only updates&redraws once
+		this._postponeUpdatePaths = true;
+	},
+
+	onAdd: function () {
+		Renderer.prototype.onAdd.call(this);
+
+		// Redraw vectors since canvas is cleared upon removal,
+		// in case of removing the renderer itself from the map.
+		this._draw();
+	},
+
+	_initContainer: function () {
+		var container = this._container = document.createElement('canvas');
+
+		on(container, 'mousemove', throttle(this._onMouseMove, 32, this), this);
+		on(container, 'click dblclick mousedown mouseup contextmenu', this._onClick, this);
+		on(container, 'mouseout', this._handleMouseOut, this);
+
+		this._ctx = container.getContext('2d');
+	},
+
+	_destroyContainer: function () {
+		delete this._ctx;
+		remove(this._container);
+		off(this._container);
+		delete this._container;
+	},
+
+	_updatePaths: function () {
+		if (this._postponeUpdatePaths) { return; }
+
+		var layer;
+		this._redrawBounds = null;
+		for (var id in this._layers) {
+			layer = this._layers[id];
+			layer._update();
+		}
+		this._redraw();
+	},
+
+	_update: function () {
+		if (this._map._animatingZoom && this._bounds) { return; }
+
+		this._drawnLayers = {};
+
+		Renderer.prototype._update.call(this);
+
+		var b = this._bounds,
+		    container = this._container,
+		    size = b.getSize(),
+		    m = retina ? 2 : 1;
+
+		setPosition(container, b.min);
+
+		// set canvas size (also clearing it); use double size on retina
+		container.width = m * size.x;
+		container.height = m * size.y;
+		container.style.width = size.x + 'px';
+		container.style.height = size.y + 'px';
+
+		if (retina) {
+			this._ctx.scale(2, 2);
+		}
+
+		// translate so we use the same path coordinates after canvas element moves
+		this._ctx.translate(-b.min.x, -b.min.y);
+
+		// Tell paths to redraw themselves
+		this.fire('update');
+	},
+
+	_reset: function () {
+		Renderer.prototype._reset.call(this);
+
+		if (this._postponeUpdatePaths) {
+			this._postponeUpdatePaths = false;
+			this._updatePaths();
+		}
+	},
+
+	_initPath: function (layer) {
+		this._updateDashArray(layer);
+		this._layers[stamp(layer)] = layer;
+
+		var order = layer._order = {
+			layer: layer,
+			prev: this._drawLast,
+			next: null
+		};
+		if (this._drawLast) { this._drawLast.next = order; }
+		this._drawLast = order;
+		this._drawFirst = this._drawFirst || this._drawLast;
+	},
+
+	_addPath: function (layer) {
+		this._requestRedraw(layer);
+	},
+
+	_removePath: function (layer) {
+		var order = layer._order;
+		var next = order.next;
+		var prev = order.prev;
+
+		if (next) {
+			next.prev = prev;
+		} else {
+			this._drawLast = prev;
+		}
+		if (prev) {
+			prev.next = next;
+		} else {
+			this._drawFirst = next;
+		}
+
+		delete layer._order;
+
+		delete this._layers[L.stamp(layer)];
+
+		this._requestRedraw(layer);
+	},
+
+	_updatePath: function (layer) {
+		// Redraw the union of the layer's old pixel
+		// bounds and the new pixel bounds.
+		this._extendRedrawBounds(layer);
+		layer._project();
+		layer._update();
+		// The redraw will extend the redraw bounds
+		// with the new pixel bounds.
+		this._requestRedraw(layer);
+	},
+
+	_updateStyle: function (layer) {
+		this._updateDashArray(layer);
+		this._requestRedraw(layer);
+	},
+
+	_updateDashArray: function (layer) {
+		if (layer.options.dashArray) {
+			var parts = layer.options.dashArray.split(','),
+			    dashArray = [],
+			    i;
+			for (i = 0; i < parts.length; i++) {
+				dashArray.push(Number(parts[i]));
+			}
+			layer.options._dashArray = dashArray;
+		}
+	},
+
+	_requestRedraw: function (layer) {
+		if (!this._map) { return; }
+
+		this._extendRedrawBounds(layer);
+		this._redrawRequest = this._redrawRequest || requestAnimFrame(this._redraw, this);
+	},
+
+	_extendRedrawBounds: function (layer) {
+		if (layer._pxBounds) {
+			var padding = (layer.options.weight || 0) + 1;
+			this._redrawBounds = this._redrawBounds || new Bounds();
+			this._redrawBounds.extend(layer._pxBounds.min.subtract([padding, padding]));
+			this._redrawBounds.extend(layer._pxBounds.max.add([padding, padding]));
+		}
+	},
+
+	_redraw: function () {
+		this._redrawRequest = null;
+
+		if (this._redrawBounds) {
+			this._redrawBounds.min._floor();
+			this._redrawBounds.max._ceil();
+		}
+
+		this._clear(); // clear layers in redraw bounds
+		this._draw(); // draw layers
+
+		this._redrawBounds = null;
+	},
+
+	_clear: function () {
+		var bounds = this._redrawBounds;
+		if (bounds) {
+			var size = bounds.getSize();
+			this._ctx.clearRect(bounds.min.x, bounds.min.y, size.x, size.y);
+		} else {
+			this._ctx.clearRect(0, 0, this._container.width, this._container.height);
+		}
+	},
+
+	_draw: function () {
+		var layer, bounds = this._redrawBounds;
+		this._ctx.save();
+		if (bounds) {
+			var size = bounds.getSize();
+			this._ctx.beginPath();
+			this._ctx.rect(bounds.min.x, bounds.min.y, size.x, size.y);
+			this._ctx.clip();
+		}
+
+		this._drawing = true;
+
+		for (var order = this._drawFirst; order; order = order.next) {
+			layer = order.layer;
+			if (!bounds || (layer._pxBounds && layer._pxBounds.intersects(bounds))) {
+				layer._updatePath();
+			}
+		}
+
+		this._drawing = false;
+
+		this._ctx.restore();  // Restore state before clipping.
+	},
+
+	_updatePoly: function (layer, closed) {
+		if (!this._drawing) { return; }
+
+		var i, j, len2, p,
+		    parts = layer._parts,
+		    len = parts.length,
+		    ctx = this._ctx;
+
+		if (!len) { return; }
+
+		this._drawnLayers[layer._leaflet_id] = layer;
+
+		ctx.beginPath();
+
+		for (i = 0; i < len; i++) {
+			for (j = 0, len2 = parts[i].length; j < len2; j++) {
+				p = parts[i][j];
+				ctx[j ? 'lineTo' : 'moveTo'](p.x, p.y);
+			}
+			if (closed) {
+				ctx.closePath();
+			}
+		}
+
+		this._fillStroke(ctx, layer);
+
+		// TODO optimization: 1 fill/stroke for all features with equal style instead of 1 for each feature
+	},
+
+	_updateCircle: function (layer) {
+
+		if (!this._drawing || layer._empty()) { return; }
+
+		var p = layer._point,
+		    ctx = this._ctx,
+		    r = Math.max(Math.round(layer._radius), 1),
+		    s = (Math.max(Math.round(layer._radiusY), 1) || r) / r;
+
+		this._drawnLayers[layer._leaflet_id] = layer;
+
+		if (s !== 1) {
+			ctx.save();
+			ctx.scale(1, s);
+		}
+
+		ctx.beginPath();
+		ctx.arc(p.x, p.y / s, r, 0, Math.PI * 2, false);
+
+		if (s !== 1) {
+			ctx.restore();
+		}
+
+		this._fillStroke(ctx, layer);
+	},
+
+	_fillStroke: function (ctx, layer) {
+		var options = layer.options;
+
+		if (options.fill) {
+			ctx.globalAlpha = options.fillOpacity;
+			ctx.fillStyle = options.fillColor || options.color;
+			ctx.fill(options.fillRule || 'evenodd');
+		}
+
+		if (options.stroke && options.weight !== 0) {
+			if (ctx.setLineDash) {
+				ctx.setLineDash(layer.options && layer.options._dashArray || []);
+			}
+			ctx.globalAlpha = options.opacity;
+			ctx.lineWidth = options.weight;
+			ctx.strokeStyle = options.color;
+			ctx.lineCap = options.lineCap;
+			ctx.lineJoin = options.lineJoin;
+			ctx.stroke();
+		}
+	},
+
+	// Canvas obviously doesn't have mouse events for individual drawn objects,
+	// so we emulate that by calculating what's under the mouse on mousemove/click manually
+
+	_onClick: function (e) {
+		var point = this._map.mouseEventToLayerPoint(e), layer, clickedLayer;
+
+		for (var order = this._drawFirst; order; order = order.next) {
+			layer = order.layer;
+			if (layer.options.interactive && layer._containsPoint(point) && !this._map._draggableMoved(layer)) {
+				clickedLayer = layer;
+			}
+		}
+		if (clickedLayer)  {
+			fakeStop(e);
+			this._fireEvent([clickedLayer], e);
+		}
+	},
+
+	_onMouseMove: function (e) {
+		if (!this._map || this._map.dragging.moving() || this._map._animatingZoom) { return; }
+
+		var point = this._map.mouseEventToLayerPoint(e);
+		this._handleMouseHover(e, point);
+	},
+
+
+	_handleMouseOut: function (e) {
+		var layer = this._hoveredLayer;
+		if (layer) {
+			// if we're leaving the layer, fire mouseout
+			removeClass(this._container, 'leaflet-interactive');
+			this._fireEvent([layer], e, 'mouseout');
+			this._hoveredLayer = null;
+		}
+	},
+
+	_handleMouseHover: function (e, point) {
+		var layer, candidateHoveredLayer;
+
+		for (var order = this._drawFirst; order; order = order.next) {
+			layer = order.layer;
+			if (layer.options.interactive && layer._containsPoint(point)) {
+				candidateHoveredLayer = layer;
+			}
+		}
+
+		if (candidateHoveredLayer !== this._hoveredLayer) {
+			this._handleMouseOut(e);
+
+			if (candidateHoveredLayer) {
+				addClass(this._container, 'leaflet-interactive'); // change cursor
+				this._fireEvent([candidateHoveredLayer], e, 'mouseover');
+				this._hoveredLayer = candidateHoveredLayer;
+			}
+		}
+
+		if (this._hoveredLayer) {
+			this._fireEvent([this._hoveredLayer], e);
+		}
+	},
+
+	_fireEvent: function (layers, e, type) {
+		this._map._fireDOMEvent(e, type || e.type, layers);
+	},
+
+	_bringToFront: function (layer) {
+		var order = layer._order;
+		var next = order.next;
+		var prev = order.prev;
+
+		if (next) {
+			next.prev = prev;
+		} else {
+			// Already last
+			return;
+		}
+		if (prev) {
+			prev.next = next;
+		} else if (next) {
+			// Update first entry unless this is the
+			// single entry
+			this._drawFirst = next;
+		}
+
+		order.prev = this._drawLast;
+		this._drawLast.next = order;
+
+		order.next = null;
+		this._drawLast = order;
+
+		this._requestRedraw(layer);
+	},
+
+	_bringToBack: function (layer) {
+		var order = layer._order;
+		var next = order.next;
+		var prev = order.prev;
+
+		if (prev) {
+			prev.next = next;
+		} else {
+			// Already first
+			return;
+		}
+		if (next) {
+			next.prev = prev;
+		} else if (prev) {
+			// Update last entry unless this is the
+			// single entry
+			this._drawLast = prev;
+		}
+
+		order.prev = null;
+
+		order.next = this._drawFirst;
+		this._drawFirst.prev = order;
+		this._drawFirst = order;
+
+		this._requestRedraw(layer);
+	}
+});
+
+// @factory L.canvas(options?: Renderer options)
+// Creates a Canvas renderer with the given options.
+function canvas$1(options) {
+	return canvas ? new Canvas(options) : null;
+}
+
+/*
+ * Thanks to Dmitry Baranovsky and his Raphael library for inspiration!
+ */
+
+
+var vmlCreate = (function () {
+	try {
+		document.namespaces.add('lvml', 'urn:schemas-microsoft-com:vml');
+		return function (name) {
+			return document.createElement('<lvml:' + name + ' class="lvml">');
+		};
+	} catch (e) {
+		return function (name) {
+			return document.createElement('<' + name + ' xmlns="urn:schemas-microsoft.com:vml" class="lvml">');
+		};
+	}
+})();
+
+
+/*
+ * @class SVG
+ *
+ * Although SVG is not available on IE7 and IE8, these browsers support [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language), and the SVG renderer will fall back to VML in this case.
+ *
+ * VML was deprecated in 2012, which means VML functionality exists only for backwards compatibility
+ * with old versions of Internet Explorer.
+ */
+
+// mixin to redefine some SVG methods to handle VML syntax which is similar but with some differences
+var vmlMixin = {
+
+	_initContainer: function () {
+		this._container = create$1('div', 'leaflet-vml-container');
+	},
+
+	_update: function () {
+		if (this._map._animatingZoom) { return; }
+		Renderer.prototype._update.call(this);
+		this.fire('update');
+	},
+
+	_initPath: function (layer) {
+		var container = layer._container = vmlCreate('shape');
+
+		addClass(container, 'leaflet-vml-shape ' + (this.options.className || ''));
+
+		container.coordsize = '1 1';
+
+		layer._path = vmlCreate('path');
+		container.appendChild(layer._path);
+
+		this._updateStyle(layer);
+		this._layers[stamp(layer)] = layer;
+	},
+
+	_addPath: function (layer) {
+		var container = layer._container;
+		this._container.appendChild(container);
+
+		if (layer.options.interactive) {
+			layer.addInteractiveTarget(container);
+		}
+	},
+
+	_removePath: function (layer) {
+		var container = layer._container;
+		remove(container);
+		layer.removeInteractiveTarget(container);
+		delete this._layers[stamp(layer)];
+	},
+
+	_updateStyle: function (layer) {
+		var stroke = layer._stroke,
+		    fill = layer._fill,
+		    options = layer.options,
+		    container = layer._container;
+
+		container.stroked = !!options.stroke;
+		container.filled = !!options.fill;
+
+		if (options.stroke) {
+			if (!stroke) {
+				stroke = layer._stroke = vmlCreate('stroke');
+			}
+			container.appendChild(stroke);
+			stroke.weight = options.weight + 'px';
+			stroke.color = options.color;
+			stroke.opacity = options.opacity;
+
+			if (options.dashArray) {
+				stroke.dashStyle = isArray(options.dashArray) ?
+				    options.dashArray.join(' ') :
+				    options.dashArray.replace(/( *, *)/g, ' ');
+			} else {
+				stroke.dashStyle = '';
+			}
+			stroke.endcap = options.lineCap.replace('butt', 'flat');
+			stroke.joinstyle = options.lineJoin;
+
+		} else if (stroke) {
+			container.removeChild(stroke);
+			layer._stroke = null;
+		}
+
+		if (options.fill) {
+			if (!fill) {
+				fill = layer._fill = vmlCreate('fill');
+			}
+			container.appendChild(fill);
+			fill.color = options.fillColor || options.color;
+			fill.opacity = options.fillOpacity;
+
+		} else if (fill) {
+			container.removeChild(fill);
+			layer._fill = null;
+		}
+	},
+
+	_updateCircle: function (layer) {
+		var p = layer._point.round(),
+		    r = Math.round(layer._radius),
+		    r2 = Math.round(layer._radiusY || r);
+
+		this._setPath(layer, layer._empty() ? 'M0 0' :
+			'AL ' + p.x + ',' + p.y + ' ' + r + ',' + r2 + ' 0,' + (65535 * 360));
+	},
+
+	_setPath: function (layer, path) {
+		layer._path.v = path;
+	},
+
+	_bringToFront: function (layer) {
+		toFront(layer._container);
+	},
+
+	_bringToBack: function (layer) {
+		toBack(layer._container);
+	}
+};
+
+var create$2 = vml ? vmlCreate : svgCreate;
+
+/*
+ * @class SVG
+ * @inherits Renderer
+ * @aka L.SVG
+ *
+ * Allows vector layers to be displayed with [SVG](https://developer.mozilla.org/docs/Web/SVG).
+ * Inherits `Renderer`.
+ *
+ * Due to [technical limitations](http://caniuse.com/#search=svg), SVG is not
+ * available in all web browsers, notably Android 2.x and 3.x.
+ *
+ * Although SVG is not available on IE7 and IE8, these browsers support
+ * [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language)
+ * (a now deprecated technology), and the SVG renderer will fall back to VML in
+ * this case.
+ *
+ * @example
+ *
+ * Use SVG by default for all paths in the map:
+ *
+ * ```js
+ * var map = L.map('map', {
+ * 	renderer: L.svg()
+ * });
+ * ```
+ *
+ * Use a SVG renderer with extra padding for specific vector geometries:
+ *
+ * ```js
+ * var map = L.map('map');
+ * var myRenderer = L.svg({ padding: 0.5 });
+ * var line = L.polyline( coordinates, { renderer: myRenderer } );
+ * var circle = L.circle( center, { renderer: myRenderer } );
+ * ```
+ */
+
+var SVG = Renderer.extend({
+
+	getEvents: function () {
+		var events = Renderer.prototype.getEvents.call(this);
+		events.zoomstart = this._onZoomStart;
+		return events;
+	},
+
+	_initContainer: function () {
+		this._container = create$2('svg');
+
+		// makes it possible to click through svg root; we'll reset it back in individual paths
+		this._container.setAttribute('pointer-events', 'none');
+
+		this._rootGroup = create$2('g');
+		this._container.appendChild(this._rootGroup);
+	},
+
+	_destroyContainer: function () {
+		remove(this._container);
+		off(this._container);
+		delete this._container;
+		delete this._rootGroup;
+		delete this._svgSize;
+	},
+
+	_onZoomStart: function () {
+		// Drag-then-pinch interactions might mess up the center and zoom.
+		// In this case, the easiest way to prevent this is re-do the renderer
+		//   bounds and padding when the zooming starts.
+		this._update();
+	},
+
+	_update: function () {
+		if (this._map._animatingZoom && this._bounds) { return; }
+
+		Renderer.prototype._update.call(this);
+
+		var b = this._bounds,
+		    size = b.getSize(),
+		    container = this._container;
+
+		// set size of svg-container if changed
+		if (!this._svgSize || !this._svgSize.equals(size)) {
+			this._svgSize = size;
+			container.setAttribute('width', size.x);
+			container.setAttribute('height', size.y);
+		}
+
+		// movement: update container viewBox so that we don't have to change coordinates of individual layers
+		setPosition(container, b.min);
+		container.setAttribute('viewBox', [b.min.x, b.min.y, size.x, size.y].join(' '));
+
+		this.fire('update');
+	},
+
+	// methods below are called by vector layers implementations
+
+	_initPath: function (layer) {
+		var path = layer._path = create$2('path');
+
+		// @namespace Path
+		// @option className: String = null
+		// Custom class name set on an element. Only for SVG renderer.
+		if (layer.options.className) {
+			addClass(path, layer.options.className);
+		}
+
+		if (layer.options.interactive) {
+			addClass(path, 'leaflet-interactive');
+		}
+
+		this._updateStyle(layer);
+		this._layers[stamp(layer)] = layer;
+	},
+
+	_addPath: function (layer) {
+		if (!this._rootGroup) { this._initContainer(); }
+		this._rootGroup.appendChild(layer._path);
+		layer.addInteractiveTarget(layer._path);
+	},
+
+	_removePath: function (layer) {
+		remove(layer._path);
+		layer.removeInteractiveTarget(layer._path);
+		delete this._layers[stamp(layer)];
+	},
+
+	_updatePath: function (layer) {
+		layer._project();
+		layer._update();
+	},
+
+	_updateStyle: function (layer) {
+		var path = layer._path,
+		    options = layer.options;
+
+		if (!path) { return; }
+
+		if (options.stroke) {
+			path.setAttribute('stroke', options.color);
+			path.setAttribute('stroke-opacity', options.opacity);
+			path.setAttribute('stroke-width', options.weight);
+			path.setAttribute('stroke-linecap', options.lineCap);
+			path.setAttribute('stroke-linejoin', options.lineJoin);
+
+			if (options.dashArray) {
+				path.setAttribute('stroke-dasharray', options.dashArray);
+			} else {
+				path.removeAttribute('stroke-dasharray');
+			}
+
+			if (options.dashOffset) {
+				path.setAttribute('stroke-dashoffset', options.dashOffset);
+			} else {
+				path.removeAttribute('stroke-dashoffset');
+			}
+		} else {
+			path.setAttribute('stroke', 'none');
+		}
+
+		if (options.fill) {
+			path.setAttribute('fill', options.fillColor || options.color);
+			path.setAttribute('fill-opacity', options.fillOpacity);
+			path.setAttribute('fill-rule', options.fillRule || 'evenodd');
+		} else {
+			path.setAttribute('fill', 'none');
+		}
+	},
+
+	_updatePoly: function (layer, closed) {
+		this._setPath(layer, pointsToPath(layer._parts, closed));
+	},
+
+	_updateCircle: function (layer) {
+		var p = layer._point,
+		    r = Math.max(Math.round(layer._radius), 1),
+		    r2 = Math.max(Math.round(layer._radiusY), 1) || r,
+		    arc = 'a' + r + ',' + r2 + ' 0 1,0 ';
+
+		// drawing a circle with two half-arcs
+		var d = layer._empty() ? 'M0 0' :
+			'M' + (p.x - r) + ',' + p.y +
+			arc + (r * 2) + ',0 ' +
+			arc + (-r * 2) + ',0 ';
+
+		this._setPath(layer, d);
+	},
+
+	_setPath: function (layer, path) {
+		layer._path.setAttribute('d', path);
+	},
+
+	// SVG does not have the concept of zIndex so we resort to changing the DOM order of elements
+	_bringToFront: function (layer) {
+		toFront(layer._path);
+	},
+
+	_bringToBack: function (layer) {
+		toBack(layer._path);
+	}
+});
+
+if (vml) {
+	SVG.include(vmlMixin);
+}
+
+// @namespace SVG
+// @factory L.svg(options?: Renderer options)
+// Creates a SVG renderer with the given options.
+function svg$1(options) {
+	return svg || vml ? new SVG(options) : null;
+}
+
+Map.include({
+	// @namespace Map; @method getRenderer(layer: Path): Renderer
+	// Returns the instance of `Renderer` that should be used to render the given
+	// `Path`. It will ensure that the `renderer` options of the map and paths
+	// are respected, and that the renderers do exist on the map.
+	getRenderer: function (layer) {
+		// @namespace Path; @option renderer: Renderer
+		// Use this specific instance of `Renderer` for this path. Takes
+		// precedence over the map's [default renderer](#map-renderer).
+		var renderer = layer.options.renderer || this._getPaneRenderer(layer.options.pane) || this.options.renderer || this._renderer;
+
+		if (!renderer) {
+			// @namespace Map; @option preferCanvas: Boolean = false
+			// Whether `Path`s should be rendered on a `Canvas` renderer.
+			// By default, all `Path`s are rendered in a `SVG` renderer.
+			renderer = this._renderer = (this.options.preferCanvas && canvas$1()) || svg$1();
+		}
+
+		if (!this.hasLayer(renderer)) {
+			this.addLayer(renderer);
+		}
+		return renderer;
+	},
+
+	_getPaneRenderer: function (name) {
+		if (name === 'overlayPane' || name === undefined) {
+			return false;
+		}
+
+		var renderer = this._paneRenderers[name];
+		if (renderer === undefined) {
+			renderer = (SVG && svg$1({pane: name})) || (Canvas && canvas$1({pane: name}));
+			this._paneRenderers[name] = renderer;
+		}
+		return renderer;
+	}
+});
+
+/*
+ * L.Rectangle extends Polygon and creates a rectangle when passed a LatLngBounds object.
+ */
+
+/*
+ * @class Rectangle
+ * @aka L.Rectangle
+ * @inherits Polygon
+ *
+ * A class for drawing rectangle overlays on a map. Extends `Polygon`.
+ *
+ * @example
+ *
+ * ```js
+ * // define rectangle geographical bounds
+ * var bounds = [[54.559322, -5.767822], [56.1210604, -3.021240]];
+ *
+ * // create an orange rectangle
+ * L.rectangle(bounds, {color: "#ff7800", weight: 1}).addTo(map);
+ *
+ * // zoom the map to the rectangle bounds
+ * map.fitBounds(bounds);
+ * ```
+ *
+ */
+
+
+var Rectangle = Polygon.extend({
+	initialize: function (latLngBounds, options) {
+		Polygon.prototype.initialize.call(this, this._boundsToLatLngs(latLngBounds), options);
+	},
+
+	// @method setBounds(latLngBounds: LatLngBounds): this
+	// Redraws the rectangle with the passed bounds.
+	setBounds: function (latLngBounds) {
+		return this.setLatLngs(this._boundsToLatLngs(latLngBounds));
+	},
+
+	_boundsToLatLngs: function (latLngBounds) {
+		latLngBounds = toLatLngBounds(latLngBounds);
+		return [
+			latLngBounds.getSouthWest(),
+			latLngBounds.getNorthWest(),
+			latLngBounds.getNorthEast(),
+			latLngBounds.getSouthEast()
+		];
+	}
+});
+
+
+// @factory L.rectangle(latLngBounds: LatLngBounds, options?: Polyline options)
+function rectangle(latLngBounds, options) {
+	return new Rectangle(latLngBounds, options);
+}
+
+SVG.create = create$2;
+SVG.pointsToPath = pointsToPath;
+
+GeoJSON.geometryToLayer = geometryToLayer;
+GeoJSON.coordsToLatLng = coordsToLatLng;
+GeoJSON.coordsToLatLngs = coordsToLatLngs;
+GeoJSON.latLngToCoords = latLngToCoords;
+GeoJSON.latLngsToCoords = latLngsToCoords;
+GeoJSON.getFeature = getFeature;
+GeoJSON.asFeature = asFeature;
+
+/*
+ * L.Handler.BoxZoom is used to add shift-drag zoom interaction to the map
+ * (zoom to a selected bounding box), enabled by default.
+ */
+
+// @namespace Map
+// @section Interaction Options
+Map.mergeOptions({
+	// @option boxZoom: Boolean = true
+	// Whether the map can be zoomed to a rectangular area specified by
+	// dragging the mouse while pressing the shift key.
+	boxZoom: true
+});
+
+var BoxZoom = Handler.extend({
+	initialize: function (map) {
+		this._map = map;
+		this._container = map._container;
+		this._pane = map._panes.overlayPane;
+		this._resetStateTimeout = 0;
+		map.on('unload', this._destroy, this);
+	},
+
+	addHooks: function () {
+		on(this._container, 'mousedown', this._onMouseDown, this);
+	},
+
+	removeHooks: function () {
+		off(this._container, 'mousedown', this._onMouseDown, this);
+	},
+
+	moved: function () {
+		return this._moved;
+	},
+
+	_destroy: function () {
+		remove(this._pane);
+		delete this._pane;
+	},
+
+	_resetState: function () {
+		this._resetStateTimeout = 0;
+		this._moved = false;
+	},
+
+	_clearDeferredResetState: function () {
+		if (this._resetStateTimeout !== 0) {
+			clearTimeout(this._resetStateTimeout);
+			this._resetStateTimeout = 0;
+		}
+	},
+
+	_onMouseDown: function (e) {
+		if (!e.shiftKey || ((e.which !== 1) && (e.button !== 1))) { return false; }
+
+		// Clear the deferred resetState if it hasn't executed yet, otherwise it
+		// will interrupt the interaction and orphan a box element in the container.
+		this._clearDeferredResetState();
+		this._resetState();
+
+		disableTextSelection();
+		disableImageDrag();
+
+		this._startPoint = this._map.mouseEventToContainerPoint(e);
+
+		on(document, {
+			contextmenu: stop,
+			mousemove: this._onMouseMove,
+			mouseup: this._onMouseUp,
+			keydown: this._onKeyDown
+		}, this);
+	},
+
+	_onMouseMove: function (e) {
+		if (!this._moved) {
+			this._moved = true;
+
+			this._box = create$1('div', 'leaflet-zoom-box', this._container);
+			addClass(this._container, 'leaflet-crosshair');
+
+			this._map.fire('boxzoomstart');
+		}
+
+		this._point = this._map.mouseEventToContainerPoint(e);
+
+		var bounds = new Bounds(this._point, this._startPoint),
+		    size = bounds.getSize();
+
+		setPosition(this._box, bounds.min);
+
+		this._box.style.width  = size.x + 'px';
+		this._box.style.height = size.y + 'px';
+	},
+
+	_finish: function () {
+		if (this._moved) {
+			remove(this._box);
+			removeClass(this._container, 'leaflet-crosshair');
+		}
+
+		enableTextSelection();
+		enableImageDrag();
+
+		off(document, {
+			contextmenu: stop,
+			mousemove: this._onMouseMove,
+			mouseup: this._onMouseUp,
+			keydown: this._onKeyDown
+		}, this);
+	},
+
+	_onMouseUp: function (e) {
+		if ((e.which !== 1) && (e.button !== 1)) { return; }
+
+		this._finish();
+
+		if (!this._moved) { return; }
+		// Postpone to next JS tick so internal click event handling
+		// still see it as "moved".
+		this._clearDeferredResetState();
+		this._resetStateTimeout = setTimeout(bind(this._resetState, this), 0);
+
+		var bounds = new LatLngBounds(
+		        this._map.containerPointToLatLng(this._startPoint),
+		        this._map.containerPointToLatLng(this._point));
+
+		this._map
+			.fitBounds(bounds)
+			.fire('boxzoomend', {boxZoomBounds: bounds});
+	},
+
+	_onKeyDown: function (e) {
+		if (e.keyCode === 27) {
+			this._finish();
+		}
+	}
+});
+
+// @section Handlers
+// @property boxZoom: Handler
+// Box (shift-drag with mouse) zoom handler.
+Map.addInitHook('addHandler', 'boxZoom', BoxZoom);
+
+/*
+ * L.Handler.DoubleClickZoom is used to handle double-click zoom on the map, enabled by default.
+ */
+
+// @namespace Map
+// @section Interaction Options
+
+Map.mergeOptions({
+	// @option doubleClickZoom: Boolean|String = true
+	// Whether the map can be zoomed in by double clicking on it and
+	// zoomed out by double clicking while holding shift. If passed
+	// `'center'`, double-click zoom will zoom to the center of the
+	//  view regardless of where the mouse was.
+	doubleClickZoom: true
+});
+
+var DoubleClickZoom = Handler.extend({
+	addHooks: function () {
+		this._map.on('dblclick', this._onDoubleClick, this);
+	},
+
+	removeHooks: function () {
+		this._map.off('dblclick', this._onDoubleClick, this);
+	},
+
+	_onDoubleClick: function (e) {
+		var map = this._map,
+		    oldZoom = map.getZoom(),
+		    delta = map.options.zoomDelta,
+		    zoom = e.originalEvent.shiftKey ? oldZoom - delta : oldZoom + delta;
+
+		if (map.options.doubleClickZoom === 'center') {
+			map.setZoom(zoom);
+		} else {
+			map.setZoomAround(e.containerPoint, zoom);
+		}
+	}
+});
+
+// @section Handlers
+//
+// Map properties include interaction handlers that allow you to control
+// interaction behavior in runtime, enabling or disabling certain features such
+// as dragging or touch zoom (see `Handler` methods). For example:
+//
+// ```js
+// map.doubleClickZoom.disable();
+// ```
+//
+// @property doubleClickZoom: Handler
+// Double click zoom handler.
+Map.addInitHook('addHandler', 'doubleClickZoom', DoubleClickZoom);
+
+/*
+ * L.Handler.MapDrag is used to make the map draggable (with panning inertia), enabled by default.
+ */
+
+// @namespace Map
+// @section Interaction Options
+Map.mergeOptions({
+	// @option dragging: Boolean = true
+	// Whether the map be draggable with mouse/touch or not.
+	dragging: true,
+
+	// @section Panning Inertia Options
+	// @option inertia: Boolean = *
+	// If enabled, panning of the map will have an inertia effect where
+	// the map builds momentum while dragging and continues moving in
+	// the same direction for some time. Feels especially nice on touch
+	// devices. Enabled by default unless running on old Android devices.
+	inertia: !android23,
+
+	// @option inertiaDeceleration: Number = 3000
+	// The rate with which the inertial movement slows down, in pixels/second².
+	inertiaDeceleration: 3400, // px/s^2
+
+	// @option inertiaMaxSpeed: Number = Infinity
+	// Max speed of the inertial movement, in pixels/second.
+	inertiaMaxSpeed: Infinity, // px/s
+
+	// @option easeLinearity: Number = 0.2
+	easeLinearity: 0.2,
+
+	// TODO refactor, move to CRS
+	// @option worldCopyJump: Boolean = false
+	// With this option enabled, the map tracks when you pan to another "copy"
+	// of the world and seamlessly jumps to the original one so that all overlays
+	// like markers and vector layers are still visible.
+	worldCopyJump: false,
+
+	// @option maxBoundsViscosity: Number = 0.0
+	// If `maxBounds` is set, this option will control how solid the bounds
+	// are when dragging the map around. The default value of `0.0` allows the
+	// user to drag outside the bounds at normal speed, higher values will
+	// slow down map dragging outside bounds, and `1.0` makes the bounds fully
+	// solid, preventing the user from dragging outside the bounds.
+	maxBoundsViscosity: 0.0
+});
+
+var Drag = Handler.extend({
+	addHooks: function () {
+		if (!this._draggable) {
+			var map = this._map;
+
+			this._draggable = new Draggable(map._mapPane, map._container);
+
+			this._draggable.on({
+				dragstart: this._onDragStart,
+				drag: this._onDrag,
+				dragend: this._onDragEnd
+			}, this);
+
+			this._draggable.on('predrag', this._onPreDragLimit, this);
+			if (map.options.worldCopyJump) {
+				this._draggable.on('predrag', this._onPreDragWrap, this);
+				map.on('zoomend', this._onZoomEnd, this);
+
+				map.whenReady(this._onZoomEnd, this);
+			}
+		}
+		addClass(this._map._container, 'leaflet-grab leaflet-touch-drag');
+		this._draggable.enable();
+		this._positions = [];
+		this._times = [];
+	},
+
+	removeHooks: function () {
+		removeClass(this._map._container, 'leaflet-grab');
+		removeClass(this._map._container, 'leaflet-touch-drag');
+		this._draggable.disable();
+	},
+
+	moved: function () {
+		return this._draggable && this._draggable._moved;
+	},
+
+	moving: function () {
+		return this._draggable && this._draggable._moving;
+	},
+
+	_onDragStart: function () {
+		var map = this._map;
+
+		map._stop();
+		if (this._map.options.maxBounds && this._map.options.maxBoundsViscosity) {
+			var bounds = toLatLngBounds(this._map.options.maxBounds);
+
+			this._offsetLimit = toBounds(
+				this._map.latLngToContainerPoint(bounds.getNorthWest()).multiplyBy(-1),
+				this._map.latLngToContainerPoint(bounds.getSouthEast()).multiplyBy(-1)
+					.add(this._map.getSize()));
+
+			this._viscosity = Math.min(1.0, Math.max(0.0, this._map.options.maxBoundsViscosity));
+		} else {
+			this._offsetLimit = null;
+		}
+
+		map
+		    .fire('movestart')
+		    .fire('dragstart');
+
+		if (map.options.inertia) {
+			this._positions = [];
+			this._times = [];
+		}
+	},
+
+	_onDrag: function (e) {
+		if (this._map.options.inertia) {
+			var time = this._lastTime = +new Date(),
+			    pos = this._lastPos = this._draggable._absPos || this._draggable._newPos;
+
+			this._positions.push(pos);
+			this._times.push(time);
+
+			this._prunePositions(time);
+		}
+
+		this._map
+		    .fire('move', e)
+		    .fire('drag', e);
+	},
+
+	_prunePositions: function (time) {
+		while (this._positions.length > 1 && time - this._times[0] > 50) {
+			this._positions.shift();
+			this._times.shift();
+		}
+	},
+
+	_onZoomEnd: function () {
+		var pxCenter = this._map.getSize().divideBy(2),
+		    pxWorldCenter = this._map.latLngToLayerPoint([0, 0]);
+
+		this._initialWorldOffset = pxWorldCenter.subtract(pxCenter).x;
+		this._worldWidth = this._map.getPixelWorldBounds().getSize().x;
+	},
+
+	_viscousLimit: function (value, threshold) {
+		return value - (value - threshold) * this._viscosity;
+	},
+
+	_onPreDragLimit: function () {
+		if (!this._viscosity || !this._offsetLimit) { return; }
+
+		var offset = this._draggable._newPos.subtract(this._draggable._startPos);
+
+		var limit = this._offsetLimit;
+		if (offset.x < limit.min.x) { offset.x = this._viscousLimit(offset.x, limit.min.x); }
+		if (offset.y < limit.min.y) { offset.y = this._viscousLimit(offset.y, limit.min.y); }
+		if (offset.x > limit.max.x) { offset.x = this._viscousLimit(offset.x, limit.max.x); }
+		if (offset.y > limit.max.y) { offset.y = this._viscousLimit(offset.y, limit.max.y); }
+
+		this._draggable._newPos = this._draggable._startPos.add(offset);
+	},
+
+	_onPreDragWrap: function () {
+		// TODO refactor to be able to adjust map pane position after zoom
+		var worldWidth = this._worldWidth,
+		    halfWidth = Math.round(worldWidth / 2),
+		    dx = this._initialWorldOffset,
+		    x = this._draggable._newPos.x,
+		    newX1 = (x - halfWidth + dx) % worldWidth + halfWidth - dx,
+		    newX2 = (x + halfWidth + dx) % worldWidth - halfWidth - dx,
+		    newX = Math.abs(newX1 + dx) < Math.abs(newX2 + dx) ? newX1 : newX2;
+
+		this._draggable._absPos = this._draggable._newPos.clone();
+		this._draggable._newPos.x = newX;
+	},
+
+	_onDragEnd: function (e) {
+		var map = this._map,
+		    options = map.options,
+
+		    noInertia = !options.inertia || this._times.length < 2;
+
+		map.fire('dragend', e);
+
+		if (noInertia) {
+			map.fire('moveend');
+
+		} else {
+			this._prunePositions(+new Date());
+
+			var direction = this._lastPos.subtract(this._positions[0]),
+			    duration = (this._lastTime - this._times[0]) / 1000,
+			    ease = options.easeLinearity,
+
+			    speedVector = direction.multiplyBy(ease / duration),
+			    speed = speedVector.distanceTo([0, 0]),
+
+			    limitedSpeed = Math.min(options.inertiaMaxSpeed, speed),
+			    limitedSpeedVector = speedVector.multiplyBy(limitedSpeed / speed),
+
+			    decelerationDuration = limitedSpeed / (options.inertiaDeceleration * ease),
+			    offset = limitedSpeedVector.multiplyBy(-decelerationDuration / 2).round();
+
+			if (!offset.x && !offset.y) {
+				map.fire('moveend');
+
+			} else {
+				offset = map._limitOffset(offset, map.options.maxBounds);
+
+				requestAnimFrame(function () {
+					map.panBy(offset, {
+						duration: decelerationDuration,
+						easeLinearity: ease,
+						noMoveStart: true,
+						animate: true
+					});
+				});
+			}
+		}
+	}
+});
+
+// @section Handlers
+// @property dragging: Handler
+// Map dragging handler (by both mouse and touch).
+Map.addInitHook('addHandler', 'dragging', Drag);
+
+/*
+ * L.Map.Keyboard is handling keyboard interaction with the map, enabled by default.
+ */
+
+// @namespace Map
+// @section Keyboard Navigation Options
+Map.mergeOptions({
+	// @option keyboard: Boolean = true
+	// Makes the map focusable and allows users to navigate the map with keyboard
+	// arrows and `+`/`-` keys.
+	keyboard: true,
+
+	// @option keyboardPanDelta: Number = 80
+	// Amount of pixels to pan when pressing an arrow key.
+	keyboardPanDelta: 80
+});
+
+var Keyboard = Handler.extend({
+
+	keyCodes: {
+		left:    [37],
+		right:   [39],
+		down:    [40],
+		up:      [38],
+		zoomIn:  [187, 107, 61, 171],
+		zoomOut: [189, 109, 54, 173]
+	},
+
+	initialize: function (map) {
+		this._map = map;
+
+		this._setPanDelta(map.options.keyboardPanDelta);
+		this._setZoomDelta(map.options.zoomDelta);
+	},
+
+	addHooks: function () {
+		var container = this._map._container;
+
+		// make the container focusable by tabbing
+		if (container.tabIndex <= 0) {
+			container.tabIndex = '0';
+		}
+
+		on(container, {
+			focus: this._onFocus,
+			blur: this._onBlur,
+			mousedown: this._onMouseDown
+		}, this);
+
+		this._map.on({
+			focus: this._addHooks,
+			blur: this._removeHooks
+		}, this);
+	},
+
+	removeHooks: function () {
+		this._removeHooks();
+
+		off(this._map._container, {
+			focus: this._onFocus,
+			blur: this._onBlur,
+			mousedown: this._onMouseDown
+		}, this);
+
+		this._map.off({
+			focus: this._addHooks,
+			blur: this._removeHooks
+		}, this);
+	},
+
+	_onMouseDown: function () {
+		if (this._focused) { return; }
+
+		var body = document.body,
+		    docEl = document.documentElement,
+		    top = body.scrollTop || docEl.scrollTop,
+		    left = body.scrollLeft || docEl.scrollLeft;
+
+		this._map._container.focus();
+
+		window.scrollTo(left, top);
+	},
+
+	_onFocus: function () {
+		this._focused = true;
+		this._map.fire('focus');
+	},
+
+	_onBlur: function () {
+		this._focused = false;
+		this._map.fire('blur');
+	},
+
+	_setPanDelta: function (panDelta) {
+		var keys = this._panKeys = {},
+		    codes = this.keyCodes,
+		    i, len;
+
+		for (i = 0, len = codes.left.length; i < len; i++) {
+			keys[codes.left[i]] = [-1 * panDelta, 0];
+		}
+		for (i = 0, len = codes.right.length; i < len; i++) {
+			keys[codes.right[i]] = [panDelta, 0];
+		}
+		for (i = 0, len = codes.down.length; i < len; i++) {
+			keys[codes.down[i]] = [0, panDelta];
+		}
+		for (i = 0, len = codes.up.length; i < len; i++) {
+			keys[codes.up[i]] = [0, -1 * panDelta];
+		}
+	},
+
+	_setZoomDelta: function (zoomDelta) {
+		var keys = this._zoomKeys = {},
+		    codes = this.keyCodes,
+		    i, len;
+
+		for (i = 0, len = codes.zoomIn.length; i < len; i++) {
+			keys[codes.zoomIn[i]] = zoomDelta;
+		}
+		for (i = 0, len = codes.zoomOut.length; i < len; i++) {
+			keys[codes.zoomOut[i]] = -zoomDelta;
+		}
+	},
+
+	_addHooks: function () {
+		on(document, 'keydown', this._onKeyDown, this);
+	},
+
+	_removeHooks: function () {
+		off(document, 'keydown', this._onKeyDown, this);
+	},
+
+	_onKeyDown: function (e) {
+		if (e.altKey || e.ctrlKey || e.metaKey) { return; }
+
+		var key = e.keyCode,
+		    map = this._map,
+		    offset;
+
+		if (key in this._panKeys) {
+
+			if (map._panAnim && map._panAnim._inProgress) { return; }
+
+			offset = this._panKeys[key];
+			if (e.shiftKey) {
+				offset = toPoint(offset).multiplyBy(3);
+			}
+
+			map.panBy(offset);
+
+			if (map.options.maxBounds) {
+				map.panInsideBounds(map.options.maxBounds);
+			}
+
+		} else if (key in this._zoomKeys) {
+			map.setZoom(map.getZoom() + (e.shiftKey ? 3 : 1) * this._zoomKeys[key]);
+
+		} else if (key === 27 && map._popup && map._popup.options.closeOnEscapeKey) {
+			map.closePopup();
+
+		} else {
+			return;
+		}
+
+		stop(e);
+	}
+});
+
+// @section Handlers
+// @section Handlers
+// @property keyboard: Handler
+// Keyboard navigation handler.
+Map.addInitHook('addHandler', 'keyboard', Keyboard);
+
+/*
+ * L.Handler.ScrollWheelZoom is used by L.Map to enable mouse scroll wheel zoom on the map.
+ */
+
+// @namespace Map
+// @section Interaction Options
+Map.mergeOptions({
+	// @section Mousewheel options
+	// @option scrollWheelZoom: Boolean|String = true
+	// Whether the map can be zoomed by using the mouse wheel. If passed `'center'`,
+	// it will zoom to the center of the view regardless of where the mouse was.
+	scrollWheelZoom: true,
+
+	// @option wheelDebounceTime: Number = 40
+	// Limits the rate at which a wheel can fire (in milliseconds). By default
+	// user can't zoom via wheel more often than once per 40 ms.
+	wheelDebounceTime: 40,
+
+	// @option wheelPxPerZoomLevel: Number = 60
+	// How many scroll pixels (as reported by [L.DomEvent.getWheelDelta](#domevent-getwheeldelta))
+	// mean a change of one full zoom level. Smaller values will make wheel-zooming
+	// faster (and vice versa).
+	wheelPxPerZoomLevel: 60
+});
+
+var ScrollWheelZoom = Handler.extend({
+	addHooks: function () {
+		on(this._map._container, 'mousewheel', this._onWheelScroll, this);
+
+		this._delta = 0;
+	},
+
+	removeHooks: function () {
+		off(this._map._container, 'mousewheel', this._onWheelScroll, this);
+	},
+
+	_onWheelScroll: function (e) {
+		var delta = getWheelDelta(e);
+
+		var debounce = this._map.options.wheelDebounceTime;
+
+		this._delta += delta;
+		this._lastMousePos = this._map.mouseEventToContainerPoint(e);
+
+		if (!this._startTime) {
+			this._startTime = +new Date();
+		}
+
+		var left = Math.max(debounce - (+new Date() - this._startTime), 0);
+
+		clearTimeout(this._timer);
+		this._timer = setTimeout(bind(this._performZoom, this), left);
+
+		stop(e);
+	},
+
+	_performZoom: function () {
+		var map = this._map,
+		    zoom = map.getZoom(),
+		    snap = this._map.options.zoomSnap || 0;
+
+		map._stop(); // stop panning and fly animations if any
+
+		// map the delta with a sigmoid function to -4..4 range leaning on -1..1
+		var d2 = this._delta / (this._map.options.wheelPxPerZoomLevel * 4),
+		    d3 = 4 * Math.log(2 / (1 + Math.exp(-Math.abs(d2)))) / Math.LN2,
+		    d4 = snap ? Math.ceil(d3 / snap) * snap : d3,
+		    delta = map._limitZoom(zoom + (this._delta > 0 ? d4 : -d4)) - zoom;
+
+		this._delta = 0;
+		this._startTime = null;
+
+		if (!delta) { return; }
+
+		if (map.options.scrollWheelZoom === 'center') {
+			map.setZoom(zoom + delta);
+		} else {
+			map.setZoomAround(this._lastMousePos, zoom + delta);
+		}
+	}
+});
+
+// @section Handlers
+// @property scrollWheelZoom: Handler
+// Scroll wheel zoom handler.
+Map.addInitHook('addHandler', 'scrollWheelZoom', ScrollWheelZoom);
+
+/*
+ * L.Map.Tap is used to enable mobile hacks like quick taps and long hold.
+ */
+
+// @namespace Map
+// @section Interaction Options
+Map.mergeOptions({
+	// @section Touch interaction options
+	// @option tap: Boolean = true
+	// Enables mobile hacks for supporting instant taps (fixing 200ms click
+	// delay on iOS/Android) and touch holds (fired as `contextmenu` events).
+	tap: true,
+
+	// @option tapTolerance: Number = 15
+	// The max number of pixels a user can shift his finger during touch
+	// for it to be considered a valid tap.
+	tapTolerance: 15
+});
+
+var Tap = Handler.extend({
+	addHooks: function () {
+		on(this._map._container, 'touchstart', this._onDown, this);
+	},
+
+	removeHooks: function () {
+		off(this._map._container, 'touchstart', this._onDown, this);
+	},
+
+	_onDown: function (e) {
+		if (!e.touches) { return; }
+
+		preventDefault(e);
+
+		this._fireClick = true;
+
+		// don't simulate click or track longpress if more than 1 touch
+		if (e.touches.length > 1) {
+			this._fireClick = false;
+			clearTimeout(this._holdTimeout);
+			return;
+		}
+
+		var first = e.touches[0],
+		    el = first.target;
+
+		this._startPos = this._newPos = new Point(first.clientX, first.clientY);
+
+		// if touching a link, highlight it
+		if (el.tagName && el.tagName.toLowerCase() === 'a') {
+			addClass(el, 'leaflet-active');
+		}
+
+		// simulate long hold but setting a timeout
+		this._holdTimeout = setTimeout(bind(function () {
+			if (this._isTapValid()) {
+				this._fireClick = false;
+				this._onUp();
+				this._simulateEvent('contextmenu', first);
+			}
+		}, this), 1000);
+
+		this._simulateEvent('mousedown', first);
+
+		on(document, {
+			touchmove: this._onMove,
+			touchend: this._onUp
+		}, this);
+	},
+
+	_onUp: function (e) {
+		clearTimeout(this._holdTimeout);
+
+		off(document, {
+			touchmove: this._onMove,
+			touchend: this._onUp
+		}, this);
+
+		if (this._fireClick && e && e.changedTouches) {
+
+			var first = e.changedTouches[0],
+			    el = first.target;
+
+			if (el && el.tagName && el.tagName.toLowerCase() === 'a') {
+				removeClass(el, 'leaflet-active');
+			}
+
+			this._simulateEvent('mouseup', first);
+
+			// simulate click if the touch didn't move too much
+			if (this._isTapValid()) {
+				this._simulateEvent('click', first);
+			}
+		}
+	},
+
+	_isTapValid: function () {
+		return this._newPos.distanceTo(this._startPos) <= this._map.options.tapTolerance;
+	},
+
+	_onMove: function (e) {
+		var first = e.touches[0];
+		this._newPos = new Point(first.clientX, first.clientY);
+		this._simulateEvent('mousemove', first);
+	},
+
+	_simulateEvent: function (type, e) {
+		var simulatedEvent = document.createEvent('MouseEvents');
+
+		simulatedEvent._simulated = true;
+		e.target._simulatedClick = true;
+
+		simulatedEvent.initMouseEvent(
+		        type, true, true, window, 1,
+		        e.screenX, e.screenY,
+		        e.clientX, e.clientY,
+		        false, false, false, false, 0, null);
+
+		e.target.dispatchEvent(simulatedEvent);
+	}
+});
+
+// @section Handlers
+// @property tap: Handler
+// Mobile touch hacks (quick tap and touch hold) handler.
+if (touch && !pointer) {
+	Map.addInitHook('addHandler', 'tap', Tap);
+}
+
+/*
+ * L.Handler.TouchZoom is used by L.Map to add pinch zoom on supported mobile browsers.
+ */
+
+// @namespace Map
+// @section Interaction Options
+Map.mergeOptions({
+	// @section Touch interaction options
+	// @option touchZoom: Boolean|String = *
+	// Whether the map can be zoomed by touch-dragging with two fingers. If
+	// passed `'center'`, it will zoom to the center of the view regardless of
+	// where the touch events (fingers) were. Enabled for touch-capable web
+	// browsers except for old Androids.
+	touchZoom: touch && !android23,
+
+	// @option bounceAtZoomLimits: Boolean = true
+	// Set it to false if you don't want the map to zoom beyond min/max zoom
+	// and then bounce back when pinch-zooming.
+	bounceAtZoomLimits: true
+});
+
+var TouchZoom = Handler.extend({
+	addHooks: function () {
+		addClass(this._map._container, 'leaflet-touch-zoom');
+		on(this._map._container, 'touchstart', this._onTouchStart, this);
+	},
+
+	removeHooks: function () {
+		removeClass(this._map._container, 'leaflet-touch-zoom');
+		off(this._map._container, 'touchstart', this._onTouchStart, this);
+	},
+
+	_onTouchStart: function (e) {
+		var map = this._map;
+		if (!e.touches || e.touches.length !== 2 || map._animatingZoom || this._zooming) { return; }
+
+		var p1 = map.mouseEventToContainerPoint(e.touches[0]),
+		    p2 = map.mouseEventToContainerPoint(e.touches[1]);
+
+		this._centerPoint = map.getSize()._divideBy(2);
+		this._startLatLng = map.containerPointToLatLng(this._centerPoint);
+		if (map.options.touchZoom !== 'center') {
+			this._pinchStartLatLng = map.containerPointToLatLng(p1.add(p2)._divideBy(2));
+		}
+
+		this._startDist = p1.distanceTo(p2);
+		this._startZoom = map.getZoom();
+
+		this._moved = false;
+		this._zooming = true;
+
+		map._stop();
+
+		on(document, 'touchmove', this._onTouchMove, this);
+		on(document, 'touchend', this._onTouchEnd, this);
+
+		preventDefault(e);
+	},
+
+	_onTouchMove: function (e) {
+		if (!e.touches || e.touches.length !== 2 || !this._zooming) { return; }
+
+		var map = this._map,
+		    p1 = map.mouseEventToContainerPoint(e.touches[0]),
+		    p2 = map.mouseEventToContainerPoint(e.touches[1]),
+		    scale = p1.distanceTo(p2) / this._startDist;
+
+		this._zoom = map.getScaleZoom(scale, this._startZoom);
+
+		if (!map.options.bounceAtZoomLimits && (
+			(this._zoom < map.getMinZoom() && scale < 1) ||
+			(this._zoom > map.getMaxZoom() && scale > 1))) {
+			this._zoom = map._limitZoom(this._zoom);
+		}
+
+		if (map.options.touchZoom === 'center') {
+			this._center = this._startLatLng;
+			if (scale === 1) { return; }
+		} else {
+			// Get delta from pinch to center, so centerLatLng is delta applied to initial pinchLatLng
+			var delta = p1._add(p2)._divideBy(2)._subtract(this._centerPoint);
+			if (scale === 1 && delta.x === 0 && delta.y === 0) { return; }
+			this._center = map.unproject(map.project(this._pinchStartLatLng, this._zoom).subtract(delta), this._zoom);
+		}
+
+		if (!this._moved) {
+			map._moveStart(true, false);
+			this._moved = true;
+		}
+
+		cancelAnimFrame(this._animRequest);
+
+		var moveFn = bind(map._move, map, this._center, this._zoom, {pinch: true, round: false});
+		this._animRequest = requestAnimFrame(moveFn, this, true);
+
+		preventDefault(e);
+	},
+
+	_onTouchEnd: function () {
+		if (!this._moved || !this._zooming) {
+			this._zooming = false;
+			return;
+		}
+
+		this._zooming = false;
+		cancelAnimFrame(this._animRequest);
+
+		off(document, 'touchmove', this._onTouchMove);
+		off(document, 'touchend', this._onTouchEnd);
+
+		// Pinch updates GridLayers' levels only when zoomSnap is off, so zoomSnap becomes noUpdate.
+		if (this._map.options.zoomAnimation) {
+			this._map._animateZoom(this._center, this._map._limitZoom(this._zoom), true, this._map.options.zoomSnap);
+		} else {
+			this._map._resetView(this._center, this._map._limitZoom(this._zoom));
+		}
+	}
+});
+
+// @section Handlers
+// @property touchZoom: Handler
+// Touch zoom handler.
+Map.addInitHook('addHandler', 'touchZoom', TouchZoom);
+
+Map.BoxZoom = BoxZoom;
+Map.DoubleClickZoom = DoubleClickZoom;
+Map.Drag = Drag;
+Map.Keyboard = Keyboard;
+Map.ScrollWheelZoom = ScrollWheelZoom;
+Map.Tap = Tap;
+Map.TouchZoom = TouchZoom;
+
+// misc
+
+var oldL = window.L;
+function noConflict() {
+	window.L = oldL;
+	return this;
+}
+
+// Always export us to window global (see #2364)
+window.L = exports;
+
+Object.freeze = freeze;
+
+exports.version = version;
+exports.noConflict = noConflict;
+exports.Control = Control;
+exports.control = control;
+exports.Browser = Browser;
+exports.Evented = Evented;
+exports.Mixin = Mixin;
+exports.Util = Util;
+exports.Class = Class;
+exports.Handler = Handler;
+exports.extend = extend;
+exports.bind = bind;
+exports.stamp = stamp;
+exports.setOptions = setOptions;
+exports.DomEvent = DomEvent;
+exports.DomUtil = DomUtil;
+exports.PosAnimation = PosAnimation;
+exports.Draggable = Draggable;
+exports.LineUtil = LineUtil;
+exports.PolyUtil = PolyUtil;
+exports.Point = Point;
+exports.point = toPoint;
+exports.Bounds = Bounds;
+exports.bounds = toBounds;
+exports.Transformation = Transformation;
+exports.transformation = toTransformation;
+exports.Projection = index;
+exports.LatLng = LatLng;
+exports.latLng = toLatLng;
+exports.LatLngBounds = LatLngBounds;
+exports.latLngBounds = toLatLngBounds;
+exports.CRS = CRS;
+exports.GeoJSON = GeoJSON;
+exports.geoJSON = geoJSON;
+exports.geoJson = geoJson;
+exports.Layer = Layer;
+exports.LayerGroup = LayerGroup;
+exports.layerGroup = layerGroup;
+exports.FeatureGroup = FeatureGroup;
+exports.featureGroup = featureGroup;
+exports.ImageOverlay = ImageOverlay;
+exports.imageOverlay = imageOverlay;
+exports.VideoOverlay = VideoOverlay;
+exports.videoOverlay = videoOverlay;
+exports.DivOverlay = DivOverlay;
+exports.Popup = Popup;
+exports.popup = popup;
+exports.Tooltip = Tooltip;
+exports.tooltip = tooltip;
+exports.Icon = Icon;
+exports.icon = icon;
+exports.DivIcon = DivIcon;
+exports.divIcon = divIcon;
+exports.Marker = Marker;
+exports.marker = marker;
+exports.TileLayer = TileLayer;
+exports.tileLayer = tileLayer;
+exports.GridLayer = GridLayer;
+exports.gridLayer = gridLayer;
+exports.SVG = SVG;
+exports.svg = svg$1;
+exports.Renderer = Renderer;
+exports.Canvas = Canvas;
+exports.canvas = canvas$1;
+exports.Path = Path;
+exports.CircleMarker = CircleMarker;
+exports.circleMarker = circleMarker;
+exports.Circle = Circle;
+exports.circle = circle;
+exports.Polyline = Polyline;
+exports.polyline = polyline;
+exports.Polygon = Polygon;
+exports.polygon = polygon;
+exports.Rectangle = Rectangle;
+exports.rectangle = rectangle;
+exports.Map = Map;
+exports.map = createMap;
+
+})));
+//# sourceMappingURL=leaflet-src.js.map
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/js/leaflet.js b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/js/leaflet.js
new file mode 100644
index 0000000..764fbb8
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/js/leaflet.js
@@ -0,0 +1,5 @@
+/* @preserve
+ * Leaflet 1.3.1+Detached: ba6f97fff8647e724e4dfe66d2ed7da11f908989.ba6f97f, a JS library for interactive maps. http://leafletjs.com
+ * (c) 2010-2017 Vladimir Agafonkin, (c) 2010-2011 CloudMade
+ */
+!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports):"function"==typeof define&&define.amd?define(["exports"],i):i(t.L={})}(this,function(t){"use strict";function i(t){var i,e,n,o;for(e=1,n=arguments.length;e<n;e++){o=arguments[e];for(i in o)t[i]=o[i]}return t}function e(t,i){var e=Array.prototype.slice;if(t.bind)return t.bind.apply(t,e.call(arguments,1));var n=e.call(arguments,2);return function(){return t.apply(i,n.length?n.concat(e.call(arguments)):arguments)}}function n(t){return t._leaflet_id=t._leaflet_id||++ti,t._leaflet_id}function o(t,i,e){var n,o,s,r;return r=function(){n=!1,o&&(s.apply(e,o),o=!1)},s=function(){n?o=arguments:(t.apply(e,arguments),setTimeout(r,i),n=!0)}}function s(t,i,e){var n=i[1],o=i[0],s=n-o;return t===n&&e?t:((t-o)%s+s)%s+o}function r(){return!1}function a(t,i){var e=Math.pow(10,void 0===i?6:i);return Math.round(t*e)/e}function h(t){return t.trim?t.trim():t.replace(/^\s+|\s+$/g,"")}function u(t){return h(t).split(/\s+/)}function l(t,i){t.hasOwnProperty("options")||(t.options=t.options?Qt(t.options):{});for(var e in i)t.options[e]=i[e];return t.options}function c(t,i,e){var n=[];for(var o in t)n.push(encodeURIComponent(e?o.toUpperCase():o)+"="+encodeURIComponent(t[o]));return(i&&-1!==i.indexOf("?")?"&":"?")+n.join("&")}function _(t,i){return t.replace(ii,function(t,e){var n=i[e];if(void 0===n)throw new Error("No value provided for variable "+t);return"function"==typeof n&&(n=n(i)),n})}function d(t,i){for(var e=0;e<t.length;e++)if(t[e]===i)return e;return-1}function p(t){return window["webkit"+t]||window["moz"+t]||window["ms"+t]}function m(t){var i=+new Date,e=Math.max(0,16-(i-oi));return oi=i+e,window.setTimeout(t,e)}function f(t,i,n){if(!n||si!==m)return si.call(window,e(t,i));t.call(i)}function g(t){t&&ri.call(window,t)}function v(){}function y(t){if("undefined"!=typeof L&&L&&L.Mixin){t=ei(t)?t:[t];for(var i=0;i<t.length;i++)t[i]===L.Mixin.Events&&console.warn("Deprecated include of L.Mixin.Events: this property will be removed in future releases, please inherit from L.Evented instead.",(new Error).stack)}}function x(t,i,e){this.x=e?Math.round(t):t,this.y=e?Math.round(i):i}function w(t,i,e){return t instanceof x?t:ei(t)?new x(t[0],t[1]):void 0===t||null===t?t:"object"==typeof t&&"x"in t&&"y"in t?new x(t.x,t.y):new x(t,i,e)}function P(t,i){if(t)for(var e=i?[t,i]:t,n=0,o=e.length;n<o;n++)this.extend(e[n])}function b(t,i){return!t||t instanceof P?t:new P(t,i)}function T(t,i){if(t)for(var e=i?[t,i]:t,n=0,o=e.length;n<o;n++)this.extend(e[n])}function z(t,i){return t instanceof T?t:new T(t,i)}function M(t,i,e){if(isNaN(t)||isNaN(i))throw new Error("Invalid LatLng object: ("+t+", "+i+")");this.lat=+t,this.lng=+i,void 0!==e&&(this.alt=+e)}function C(t,i,e){return t instanceof M?t:ei(t)&&"object"!=typeof t[0]?3===t.length?new M(t[0],t[1],t[2]):2===t.length?new M(t[0],t[1]):null:void 0===t||null===t?t:"object"==typeof t&&"lat"in t?new M(t.lat,"lng"in t?t.lng:t.lon,t.alt):void 0===i?null:new M(t,i,e)}function Z(t,i,e,n){if(ei(t))return this._a=t[0],this._b=t[1],this._c=t[2],void(this._d=t[3]);this._a=t,this._b=i,this._c=e,this._d=n}function S(t,i,e,n){return new Z(t,i,e,n)}function E(t){return document.createElementNS("http://www.w3.org/2000/svg",t)}function k(t,i){var e,n,o,s,r,a,h="";for(e=0,o=t.length;e<o;e++){for(n=0,s=(r=t[e]).length;n<s;n++)a=r[n],h+=(n?"L":"M")+a.x+" "+a.y;h+=i?Xi?"z":"x":""}return h||"M0 0"}function A(t){return navigator.userAgent.toLowerCase().indexOf(t)>=0}function I(t,i,e,n){return"touchstart"===i?O(t,e,n):"touchmove"===i?W(t,e,n):"touchend"===i&&H(t,e,n),this}function B(t,i,e){var n=t["_leaflet_"+i+e];return"touchstart"===i?t.removeEventListener(Qi,n,!1):"touchmove"===i?t.removeEventListener(te,n,!1):"touchend"===i&&(t.removeEventListener(ie,n,!1),t.removeEventListener(ee,n,!1)),this}function O(t,i,n){var o=e(function(t){if("mouse"!==t.pointerType&&t.MSPOINTER_TYPE_MOUSE&&t.pointerType!==t.MSPOINTER_TYPE_MOUSE){if(!(ne.indexOf(t.target.tagName)<0))return;$(t)}j(t,i)});t["_leaflet_touchstart"+n]=o,t.addEventListener(Qi,o,!1),se||(document.documentElement.addEventListener(Qi,R,!0),document.documentElement.addEventListener(te,D,!0),document.documentElement.addEventListener(ie,N,!0),document.documentElement.addEventListener(ee,N,!0),se=!0)}function R(t){oe[t.pointerId]=t,re++}function D(t){oe[t.pointerId]&&(oe[t.pointerId]=t)}function N(t){delete oe[t.pointerId],re--}function j(t,i){t.touches=[];for(var e in oe)t.touches.push(oe[e]);t.changedTouches=[t],i(t)}function W(t,i,e){var n=function(t){(t.pointerType!==t.MSPOINTER_TYPE_MOUSE&&"mouse"!==t.pointerType||0!==t.buttons)&&j(t,i)};t["_leaflet_touchmove"+e]=n,t.addEventListener(te,n,!1)}function H(t,i,e){var n=function(t){j(t,i)};t["_leaflet_touchend"+e]=n,t.addEventListener(ie,n,!1),t.addEventListener(ee,n,!1)}function F(t,i,e){function n(t){var i;if(Ui){if(!Pi||"mouse"===t.pointerType)return;i=re}else i=t.touches.length;if(!(i>1)){var e=Date.now(),n=e-(s||e);r=t.touches?t.touches[0]:t,a=n>0&&n<=h,s=e}}function o(t){if(a&&!r.cancelBubble){if(Ui){if(!Pi||"mouse"===t.pointerType)return;var e,n,o={};for(n in r)e=r[n],o[n]=e&&e.bind?e.bind(r):e;r=o}r.type="dblclick",i(r),s=null}}var s,r,a=!1,h=250;return t[ue+ae+e]=n,t[ue+he+e]=o,t[ue+"dblclick"+e]=i,t.addEventListener(ae,n,!1),t.addEventListener(he,o,!1),t.addEventListener("dblclick",i,!1),this}function U(t,i){var e=t[ue+ae+i],n=t[ue+he+i],o=t[ue+"dblclick"+i];return t.removeEventListener(ae,e,!1),t.removeEventListener(he,n,!1),Pi||t.removeEventListener("dblclick",o,!1),this}function V(t,i,e,n){if("object"==typeof i)for(var o in i)G(t,o,i[o],e);else for(var s=0,r=(i=u(i)).length;s<r;s++)G(t,i[s],e,n);return this}function q(t,i,e,n){if("object"==typeof i)for(var o in i)K(t,o,i[o],e);else if(i)for(var s=0,r=(i=u(i)).length;s<r;s++)K(t,i[s],e,n);else{for(var a in t[le])K(t,a,t[le][a]);delete t[le]}return this}function G(t,i,e,o){var s=i+n(e)+(o?"_"+n(o):"");if(t[le]&&t[le][s])return this;var r=function(i){return e.call(o||t,i||window.event)},a=r;Ui&&0===i.indexOf("touch")?I(t,i,r,s):!Vi||"dblclick"!==i||!F||Ui&&Si?"addEventListener"in t?"mousewheel"===i?t.addEventListener("onwheel"in t?"wheel":"mousewheel",r,!1):"mouseenter"===i||"mouseleave"===i?(r=function(i){i=i||window.event,ot(t,i)&&a(i)},t.addEventListener("mouseenter"===i?"mouseover":"mouseout",r,!1)):("click"===i&&Ti&&(r=function(t){st(t,a)}),t.addEventListener(i,r,!1)):"attachEvent"in t&&t.attachEvent("on"+i,r):F(t,r,s),t[le]=t[le]||{},t[le][s]=r}function K(t,i,e,o){var s=i+n(e)+(o?"_"+n(o):""),r=t[le]&&t[le][s];if(!r)return this;Ui&&0===i.indexOf("touch")?B(t,i,s):!Vi||"dblclick"!==i||!U||Ui&&Si?"removeEventListener"in t?"mousewheel"===i?t.removeEventListener("onwheel"in t?"wheel":"mousewheel",r,!1):t.removeEventListener("mouseenter"===i?"mouseover":"mouseleave"===i?"mouseout":i,r,!1):"detachEvent"in t&&t.detachEvent("on"+i,r):U(t,s),t[le][s]=null}function Y(t){return t.stopPropagation?t.stopPropagation():t.originalEvent?t.originalEvent._stopped=!0:t.cancelBubble=!0,nt(t),this}function X(t){return G(t,"mousewheel",Y),this}function J(t){return V(t,"mousedown touchstart dblclick",Y),G(t,"click",et),this}function $(t){return t.preventDefault?t.preventDefault():t.returnValue=!1,this}function Q(t){return $(t),Y(t),this}function tt(t,i){if(!i)return new x(t.clientX,t.clientY);var e=i.getBoundingClientRect(),n=e.width/i.offsetWidth||1,o=e.height/i.offsetHeight||1;return new x(t.clientX/n-e.left-i.clientLeft,t.clientY/o-e.top-i.clientTop)}function it(t){return Pi?t.wheelDeltaY/2:t.deltaY&&0===t.deltaMode?-t.deltaY/ce:t.deltaY&&1===t.deltaMode?20*-t.deltaY:t.deltaY&&2===t.deltaMode?60*-t.deltaY:t.deltaX||t.deltaZ?0:t.wheelDelta?(t.wheelDeltaY||t.wheelDelta)/2:t.detail&&Math.abs(t.detail)<32765?20*-t.detail:t.detail?t.detail/-32765*60:0}function et(t){_e[t.type]=!0}function nt(t){var i=_e[t.type];return _e[t.type]=!1,i}function ot(t,i){var e=i.relatedTarget;if(!e)return!0;try{for(;e&&e!==t;)e=e.parentNode}catch(t){return!1}return e!==t}function st(t,i){var e=t.timeStamp||t.originalEvent&&t.originalEvent.timeStamp,n=pi&&e-pi;n&&n>100&&n<500||t.target._simulatedClick&&!t._simulated?Q(t):(pi=e,i(t))}function rt(t){return"string"==typeof t?document.getElementById(t):t}function at(t,i){var e=t.style[i]||t.currentStyle&&t.currentStyle[i];if((!e||"auto"===e)&&document.defaultView){var n=document.defaultView.getComputedStyle(t,null);e=n?n[i]:null}return"auto"===e?null:e}function ht(t,i,e){var n=document.createElement(t);return n.className=i||"",e&&e.appendChild(n),n}function ut(t){var i=t.parentNode;i&&i.removeChild(t)}function lt(t){for(;t.firstChild;)t.removeChild(t.firstChild)}function ct(t){var i=t.parentNode;i.lastChild!==t&&i.appendChild(t)}function _t(t){var i=t.parentNode;i.firstChild!==t&&i.insertBefore(t,i.firstChild)}function dt(t,i){if(void 0!==t.classList)return t.classList.contains(i);var e=gt(t);return e.length>0&&new RegExp("(^|\\s)"+i+"(\\s|$)").test(e)}function pt(t,i){if(void 0!==t.classList)for(var e=u(i),n=0,o=e.length;n<o;n++)t.classList.add(e[n]);else if(!dt(t,i)){var s=gt(t);ft(t,(s?s+" ":"")+i)}}function mt(t,i){void 0!==t.classList?t.classList.remove(i):ft(t,h((" "+gt(t)+" ").replace(" "+i+" "," ")))}function ft(t,i){void 0===t.className.baseVal?t.className=i:t.className.baseVal=i}function gt(t){return void 0===t.className.baseVal?t.className:t.className.baseVal}function vt(t,i){"opacity"in t.style?t.style.opacity=i:"filter"in t.style&&yt(t,i)}function yt(t,i){var e=!1,n="DXImageTransform.Microsoft.Alpha";try{e=t.filters.item(n)}catch(t){if(1===i)return}i=Math.round(100*i),e?(e.Enabled=100!==i,e.Opacity=i):t.style.filter+=" progid:"+n+"(opacity="+i+")"}function xt(t){for(var i=document.documentElement.style,e=0;e<t.length;e++)if(t[e]in i)return t[e];return!1}function wt(t,i,e){var n=i||new x(0,0);t.style[pe]=(Oi?"translate("+n.x+"px,"+n.y+"px)":"translate3d("+n.x+"px,"+n.y+"px,0)")+(e?" scale("+e+")":"")}function Lt(t,i){t._leaflet_pos=i,Ni?wt(t,i):(t.style.left=i.x+"px",t.style.top=i.y+"px")}function Pt(t){return t._leaflet_pos||new x(0,0)}function bt(){V(window,"dragstart",$)}function Tt(){q(window,"dragstart",$)}function zt(t){for(;-1===t.tabIndex;)t=t.parentNode;t.style&&(Mt(),ve=t,ye=t.style.outline,t.style.outline="none",V(window,"keydown",Mt))}function Mt(){ve&&(ve.style.outline=ye,ve=void 0,ye=void 0,q(window,"keydown",Mt))}function Ct(t,i){if(!i||!t.length)return t.slice();var e=i*i;return t=kt(t,e),t=St(t,e)}function Zt(t,i,e){return Math.sqrt(Rt(t,i,e,!0))}function St(t,i){var e=t.length,n=new(typeof Uint8Array!=void 0+""?Uint8Array:Array)(e);n[0]=n[e-1]=1,Et(t,n,i,0,e-1);var o,s=[];for(o=0;o<e;o++)n[o]&&s.push(t[o]);return s}function Et(t,i,e,n,o){var s,r,a,h=0;for(r=n+1;r<=o-1;r++)(a=Rt(t[r],t[n],t[o],!0))>h&&(s=r,h=a);h>e&&(i[s]=1,Et(t,i,e,n,s),Et(t,i,e,s,o))}function kt(t,i){for(var e=[t[0]],n=1,o=0,s=t.length;n<s;n++)Ot(t[n],t[o])>i&&(e.push(t[n]),o=n);return o<s-1&&e.push(t[s-1]),e}function At(t,i,e,n,o){var s,r,a,h=n?Se:Bt(t,e),u=Bt(i,e);for(Se=u;;){if(!(h|u))return[t,i];if(h&u)return!1;a=Bt(r=It(t,i,s=h||u,e,o),e),s===h?(t=r,h=a):(i=r,u=a)}}function It(t,i,e,n,o){var s,r,a=i.x-t.x,h=i.y-t.y,u=n.min,l=n.max;return 8&e?(s=t.x+a*(l.y-t.y)/h,r=l.y):4&e?(s=t.x+a*(u.y-t.y)/h,r=u.y):2&e?(s=l.x,r=t.y+h*(l.x-t.x)/a):1&e&&(s=u.x,r=t.y+h*(u.x-t.x)/a),new x(s,r,o)}function Bt(t,i){var e=0;return t.x<i.min.x?e|=1:t.x>i.max.x&&(e|=2),t.y<i.min.y?e|=4:t.y>i.max.y&&(e|=8),e}function Ot(t,i){var e=i.x-t.x,n=i.y-t.y;return e*e+n*n}function Rt(t,i,e,n){var o,s=i.x,r=i.y,a=e.x-s,h=e.y-r,u=a*a+h*h;return u>0&&((o=((t.x-s)*a+(t.y-r)*h)/u)>1?(s=e.x,r=e.y):o>0&&(s+=a*o,r+=h*o)),a=t.x-s,h=t.y-r,n?a*a+h*h:new x(s,r)}function Dt(t){return!ei(t[0])||"object"!=typeof t[0][0]&&void 0!==t[0][0]}function Nt(t){return console.warn("Deprecated use of _flat, please use L.LineUtil.isFlat instead."),Dt(t)}function jt(t,i,e){var n,o,s,r,a,h,u,l,c,_=[1,4,2,8];for(o=0,u=t.length;o<u;o++)t[o]._code=Bt(t[o],i);for(r=0;r<4;r++){for(l=_[r],n=[],o=0,s=(u=t.length)-1;o<u;s=o++)a=t[o],h=t[s],a._code&l?h._code&l||((c=It(h,a,l,i,e))._code=Bt(c,i),n.push(c)):(h._code&l&&((c=It(h,a,l,i,e))._code=Bt(c,i),n.push(c)),n.push(a));t=n}return t}function Wt(t,i){var e,n,o,s,r="Feature"===t.type?t.geometry:t,a=r?r.coordinates:null,h=[],u=i&&i.pointToLayer,l=i&&i.coordsToLatLng||Ht;if(!a&&!r)return null;switch(r.type){case"Point":return e=l(a),u?u(t,e):new Xe(e);case"MultiPoint":for(o=0,s=a.length;o<s;o++)e=l(a[o]),h.push(u?u(t,e):new Xe(e));return new qe(h);case"LineString":case"MultiLineString":return n=Ft(a,"LineString"===r.type?0:1,l),new tn(n,i);case"Polygon":case"MultiPolygon":return n=Ft(a,"Polygon"===r.type?1:2,l),new en(n,i);case"GeometryCollection":for(o=0,s=r.geometries.length;o<s;o++){var c=Wt({geometry:r.geometries[o],type:"Feature",properties:t.properties},i);c&&h.push(c)}return new qe(h);default:throw new Error("Invalid GeoJSON object.")}}function Ht(t){return new M(t[1],t[0],t[2])}function Ft(t,i,e){for(var n,o=[],s=0,r=t.length;s<r;s++)n=i?Ft(t[s],i-1,e):(e||Ht)(t[s]),o.push(n);return o}function Ut(t,i){return i="number"==typeof i?i:6,void 0!==t.alt?[a(t.lng,i),a(t.lat,i),a(t.alt,i)]:[a(t.lng,i),a(t.lat,i)]}function Vt(t,i,e,n){for(var o=[],s=0,r=t.length;s<r;s++)o.push(i?Vt(t[s],i-1,e,n):Ut(t[s],n));return!i&&e&&o.push(o[0]),o}function qt(t,e){return t.feature?i({},t.feature,{geometry:e}):Gt(e)}function Gt(t){return"Feature"===t.type||"FeatureCollection"===t.type?t:{type:"Feature",properties:{},geometry:t}}function Kt(t,i){return new nn(t,i)}function Yt(t,i){return new dn(t,i)}function Xt(t){return Yi?new fn(t):null}function Jt(t){return Xi||Ji?new xn(t):null}var $t=Object.freeze;Object.freeze=function(t){return t};var Qt=Object.create||function(){function t(){}return function(i){return t.prototype=i,new t}}(),ti=0,ii=/\{ *([\w_-]+) *\}/g,ei=Array.isArray||function(t){return"[object Array]"===Object.prototype.toString.call(t)},ni="data:image/gif;base64,R0lGODlhAQABAAD/ACwAAAAAAQABAAACADs=",oi=0,si=window.requestAnimationFrame||p("RequestAnimationFrame")||m,ri=window.cancelAnimationFrame||p("CancelAnimationFrame")||p("CancelRequestAnimationFrame")||function(t){window.clearTimeout(t)},ai=(Object.freeze||Object)({freeze:$t,extend:i,create:Qt,bind:e,lastId:ti,stamp:n,throttle:o,wrapNum:s,falseFn:r,formatNum:a,trim:h,splitWords:u,setOptions:l,getParamString:c,template:_,isArray:ei,indexOf:d,emptyImageUrl:ni,requestFn:si,cancelFn:ri,requestAnimFrame:f,cancelAnimFrame:g});v.extend=function(t){var e=function(){this.initialize&&this.initialize.apply(this,arguments),this.callInitHooks()},n=e.__super__=this.prototype,o=Qt(n);o.constructor=e,e.prototype=o;for(var s in this)this.hasOwnProperty(s)&&"prototype"!==s&&"__super__"!==s&&(e[s]=this[s]);return t.statics&&(i(e,t.statics),delete t.statics),t.includes&&(y(t.includes),i.apply(null,[o].concat(t.includes)),delete t.includes),o.options&&(t.options=i(Qt(o.options),t.options)),i(o,t),o._initHooks=[],o.callInitHooks=function(){if(!this._initHooksCalled){n.callInitHooks&&n.callInitHooks.call(this),this._initHooksCalled=!0;for(var t=0,i=o._initHooks.length;t<i;t++)o._initHooks[t].call(this)}},e},v.include=function(t){return i(this.prototype,t),this},v.mergeOptions=function(t){return i(this.prototype.options,t),this},v.addInitHook=function(t){var i=Array.prototype.slice.call(arguments,1),e="function"==typeof t?t:function(){this[t].apply(this,i)};return this.prototype._initHooks=this.prototype._initHooks||[],this.prototype._initHooks.push(e),this};var hi={on:function(t,i,e){if("object"==typeof t)for(var n in t)this._on(n,t[n],i);else for(var o=0,s=(t=u(t)).length;o<s;o++)this._on(t[o],i,e);return this},off:function(t,i,e){if(t)if("object"==typeof t)for(var n in t)this._off(n,t[n],i);else for(var o=0,s=(t=u(t)).length;o<s;o++)this._off(t[o],i,e);else delete this._events;return this},_on:function(t,i,e){this._events=this._events||{};var n=this._events[t];n||(n=[],this._events[t]=n),e===this&&(e=void 0);for(var o={fn:i,ctx:e},s=n,r=0,a=s.length;r<a;r++)if(s[r].fn===i&&s[r].ctx===e)return;s.push(o)},_off:function(t,i,e){var n,o,s;if(this._events&&(n=this._events[t]))if(i){if(e===this&&(e=void 0),n)for(o=0,s=n.length;o<s;o++){var a=n[o];if(a.ctx===e&&a.fn===i)return a.fn=r,this._firingCount&&(this._events[t]=n=n.slice()),void n.splice(o,1)}}else{for(o=0,s=n.length;o<s;o++)n[o].fn=r;delete this._events[t]}},fire:function(t,e,n){if(!this.listens(t,n))return this;var o=i({},e,{type:t,target:this,sourceTarget:e&&e.sourceTarget||this});if(this._events){var s=this._events[t];if(s){this._firingCount=this._firingCount+1||1;for(var r=0,a=s.length;r<a;r++){var h=s[r];h.fn.call(h.ctx||this,o)}this._firingCount--}}return n&&this._propagateEvent(o),this},listens:function(t,i){var e=this._events&&this._events[t];if(e&&e.length)return!0;if(i)for(var n in this._eventParents)if(this._eventParents[n].listens(t,i))return!0;return!1},once:function(t,i,n){if("object"==typeof t){for(var o in t)this.once(o,t[o],i);return this}var s=e(function(){this.off(t,i,n).off(t,s,n)},this);return this.on(t,i,n).on(t,s,n)},addEventParent:function(t){return this._eventParents=this._eventParents||{},this._eventParents[n(t)]=t,this},removeEventParent:function(t){return this._eventParents&&delete this._eventParents[n(t)],this},_propagateEvent:function(t){for(var e in this._eventParents)this._eventParents[e].fire(t.type,i({layer:t.target,propagatedFrom:t.target},t),!0)}};hi.addEventListener=hi.on,hi.removeEventListener=hi.clearAllEventListeners=hi.off,hi.addOneTimeEventListener=hi.once,hi.fireEvent=hi.fire,hi.hasEventListeners=hi.listens;var ui=v.extend(hi),li=Math.trunc||function(t){return t>0?Math.floor(t):Math.ceil(t)};x.prototype={clone:function(){return new x(this.x,this.y)},add:function(t){return this.clone()._add(w(t))},_add:function(t){return this.x+=t.x,this.y+=t.y,this},subtract:function(t){return this.clone()._subtract(w(t))},_subtract:function(t){return this.x-=t.x,this.y-=t.y,this},divideBy:function(t){return this.clone()._divideBy(t)},_divideBy:function(t){return this.x/=t,this.y/=t,this},multiplyBy:function(t){return this.clone()._multiplyBy(t)},_multiplyBy:function(t){return this.x*=t,this.y*=t,this},scaleBy:function(t){return new x(this.x*t.x,this.y*t.y)},unscaleBy:function(t){return new x(this.x/t.x,this.y/t.y)},round:function(){return this.clone()._round()},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this},floor:function(){return this.clone()._floor()},_floor:function(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this},ceil:function(){return this.clone()._ceil()},_ceil:function(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this},trunc:function(){return this.clone()._trunc()},_trunc:function(){return this.x=li(this.x),this.y=li(this.y),this},distanceTo:function(t){var i=(t=w(t)).x-this.x,e=t.y-this.y;return Math.sqrt(i*i+e*e)},equals:function(t){return(t=w(t)).x===this.x&&t.y===this.y},contains:function(t){return t=w(t),Math.abs(t.x)<=Math.abs(this.x)&&Math.abs(t.y)<=Math.abs(this.y)},toString:function(){return"Point("+a(this.x)+", "+a(this.y)+")"}},P.prototype={extend:function(t){return t=w(t),this.min||this.max?(this.min.x=Math.min(t.x,this.min.x),this.max.x=Math.max(t.x,this.max.x),this.min.y=Math.min(t.y,this.min.y),this.max.y=Math.max(t.y,this.max.y)):(this.min=t.clone(),this.max=t.clone()),this},getCenter:function(t){return new x((this.min.x+this.max.x)/2,(this.min.y+this.max.y)/2,t)},getBottomLeft:function(){return new x(this.min.x,this.max.y)},getTopRight:function(){return new x(this.max.x,this.min.y)},getTopLeft:function(){return this.min},getBottomRight:function(){return this.max},getSize:function(){return this.max.subtract(this.min)},contains:function(t){var i,e;return(t="number"==typeof t[0]||t instanceof x?w(t):b(t))instanceof P?(i=t.min,e=t.max):i=e=t,i.x>=this.min.x&&e.x<=this.max.x&&i.y>=this.min.y&&e.y<=this.max.y},intersects:function(t){t=b(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>=i.x&&n.x<=e.x,r=o.y>=i.y&&n.y<=e.y;return s&&r},overlaps:function(t){t=b(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>i.x&&n.x<e.x,r=o.y>i.y&&n.y<e.y;return s&&r},isValid:function(){return!(!this.min||!this.max)}},T.prototype={extend:function(t){var i,e,n=this._southWest,o=this._northEast;if(t instanceof M)i=t,e=t;else{if(!(t instanceof T))return t?this.extend(C(t)||z(t)):this;if(i=t._southWest,e=t._northEast,!i||!e)return this}return n||o?(n.lat=Math.min(i.lat,n.lat),n.lng=Math.min(i.lng,n.lng),o.lat=Math.max(e.lat,o.lat),o.lng=Math.max(e.lng,o.lng)):(this._southWest=new M(i.lat,i.lng),this._northEast=new M(e.lat,e.lng)),this},pad:function(t){var i=this._southWest,e=this._northEast,n=Math.abs(i.lat-e.lat)*t,o=Math.abs(i.lng-e.lng)*t;return new T(new M(i.lat-n,i.lng-o),new M(e.lat+n,e.lng+o))},getCenter:function(){return new M((this._southWest.lat+this._northEast.lat)/2,(this._southWest.lng+this._northEast.lng)/2)},getSouthWest:function(){return this._southWest},getNorthEast:function(){return this._northEast},getNorthWest:function(){return new M(this.getNorth(),this.getWest())},getSouthEast:function(){return new M(this.getSouth(),this.getEast())},getWest:function(){return this._southWest.lng},getSouth:function(){return this._southWest.lat},getEast:function(){return this._northEast.lng},getNorth:function(){return this._northEast.lat},contains:function(t){t="number"==typeof t[0]||t instanceof M||"lat"in t?C(t):z(t);var i,e,n=this._southWest,o=this._northEast;return t instanceof T?(i=t.getSouthWest(),e=t.getNorthEast()):i=e=t,i.lat>=n.lat&&e.lat<=o.lat&&i.lng>=n.lng&&e.lng<=o.lng},intersects:function(t){t=z(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>=i.lat&&n.lat<=e.lat,r=o.lng>=i.lng&&n.lng<=e.lng;return s&&r},overlaps:function(t){t=z(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>i.lat&&n.lat<e.lat,r=o.lng>i.lng&&n.lng<e.lng;return s&&r},toBBoxString:function(){return[this.getWest(),this.getSouth(),this.getEast(),this.getNorth()].join(",")},equals:function(t,i){return!!t&&(t=z(t),this._southWest.equals(t.getSouthWest(),i)&&this._northEast.equals(t.getNorthEast(),i))},isValid:function(){return!(!this._southWest||!this._northEast)}},M.prototype={equals:function(t,i){return!!t&&(t=C(t),Math.max(Math.abs(this.lat-t.lat),Math.abs(this.lng-t.lng))<=(void 0===i?1e-9:i))},toString:function(t){return"LatLng("+a(this.lat,t)+", "+a(this.lng,t)+")"},distanceTo:function(t){return _i.distance(this,C(t))},wrap:function(){return _i.wrapLatLng(this)},toBounds:function(t){var i=180*t/40075017,e=i/Math.cos(Math.PI/180*this.lat);return z([this.lat-i,this.lng-e],[this.lat+i,this.lng+e])},clone:function(){return new M(this.lat,this.lng,this.alt)}};var ci={latLngToPoint:function(t,i){var e=this.projection.project(t),n=this.scale(i);return this.transformation._transform(e,n)},pointToLatLng:function(t,i){var e=this.scale(i),n=this.transformation.untransform(t,e);return this.projection.unproject(n)},project:function(t){return this.projection.project(t)},unproject:function(t){return this.projection.unproject(t)},scale:function(t){return 256*Math.pow(2,t)},zoom:function(t){return Math.log(t/256)/Math.LN2},getProjectedBounds:function(t){if(this.infinite)return null;var i=this.projection.bounds,e=this.scale(t);return new P(this.transformation.transform(i.min,e),this.transformation.transform(i.max,e))},infinite:!1,wrapLatLng:function(t){var i=this.wrapLng?s(t.lng,this.wrapLng,!0):t.lng;return new M(this.wrapLat?s(t.lat,this.wrapLat,!0):t.lat,i,t.alt)},wrapLatLngBounds:function(t){var i=t.getCenter(),e=this.wrapLatLng(i),n=i.lat-e.lat,o=i.lng-e.lng;if(0===n&&0===o)return t;var s=t.getSouthWest(),r=t.getNorthEast();return new T(new M(s.lat-n,s.lng-o),new M(r.lat-n,r.lng-o))}},_i=i({},ci,{wrapLng:[-180,180],R:6371e3,distance:function(t,i){var e=Math.PI/180,n=t.lat*e,o=i.lat*e,s=Math.sin((i.lat-t.lat)*e/2),r=Math.sin((i.lng-t.lng)*e/2),a=s*s+Math.cos(n)*Math.cos(o)*r*r,h=2*Math.atan2(Math.sqrt(a),Math.sqrt(1-a));return this.R*h}}),di={R:6378137,MAX_LATITUDE:85.0511287798,project:function(t){var i=Math.PI/180,e=this.MAX_LATITUDE,n=Math.max(Math.min(e,t.lat),-e),o=Math.sin(n*i);return new x(this.R*t.lng*i,this.R*Math.log((1+o)/(1-o))/2)},unproject:function(t){var i=180/Math.PI;return new M((2*Math.atan(Math.exp(t.y/this.R))-Math.PI/2)*i,t.x*i/this.R)},bounds:function(){var t=6378137*Math.PI;return new P([-t,-t],[t,t])}()};Z.prototype={transform:function(t,i){return this._transform(t.clone(),i)},_transform:function(t,i){return i=i||1,t.x=i*(this._a*t.x+this._b),t.y=i*(this._c*t.y+this._d),t},untransform:function(t,i){return i=i||1,new x((t.x/i-this._b)/this._a,(t.y/i-this._d)/this._c)}};var pi,mi,fi,gi,vi=i({},_i,{code:"EPSG:3857",projection:di,transformation:function(){var t=.5/(Math.PI*di.R);return S(t,.5,-t,.5)}()}),yi=i({},vi,{code:"EPSG:900913"}),xi=document.documentElement.style,wi="ActiveXObject"in window,Li=wi&&!document.addEventListener,Pi="msLaunchUri"in navigator&&!("documentMode"in document),bi=A("webkit"),Ti=A("android"),zi=A("android 2")||A("android 3"),Mi=parseInt(/WebKit\/([0-9]+)|$/.exec(navigator.userAgent)[1],10),Ci=Ti&&A("Google")&&Mi<537&&!("AudioNode"in window),Zi=!!window.opera,Si=A("chrome"),Ei=A("gecko")&&!bi&&!Zi&&!wi,ki=!Si&&A("safari"),Ai=A("phantom"),Ii="OTransition"in xi,Bi=0===navigator.platform.indexOf("Win"),Oi=wi&&"transition"in xi,Ri="WebKitCSSMatrix"in window&&"m11"in new window.WebKitCSSMatrix&&!zi,Di="MozPerspective"in xi,Ni=!window.L_DISABLE_3D&&(Oi||Ri||Di)&&!Ii&&!Ai,ji="undefined"!=typeof orientation||A("mobile"),Wi=ji&&bi,Hi=ji&&Ri,Fi=!window.PointerEvent&&window.MSPointerEvent,Ui=!(!window.PointerEvent&&!Fi),Vi=!window.L_NO_TOUCH&&(Ui||"ontouchstart"in window||window.DocumentTouch&&document instanceof window.DocumentTouch),qi=ji&&Zi,Gi=ji&&Ei,Ki=(window.devicePixelRatio||window.screen.deviceXDPI/window.screen.logicalXDPI)>1,Yi=!!document.createElement("canvas").getContext,Xi=!(!document.createElementNS||!E("svg").createSVGRect),Ji=!Xi&&function(){try{var t=document.createElement("div");t.innerHTML='<v:shape adj="1"/>';var i=t.firstChild;return i.style.behavior="url(#default#VML)",i&&"object"==typeof i.adj}catch(t){return!1}}(),$i=(Object.freeze||Object)({ie:wi,ielt9:Li,edge:Pi,webkit:bi,android:Ti,android23:zi,androidStock:Ci,opera:Zi,chrome:Si,gecko:Ei,safari:ki,phantom:Ai,opera12:Ii,win:Bi,ie3d:Oi,webkit3d:Ri,gecko3d:Di,any3d:Ni,mobile:ji,mobileWebkit:Wi,mobileWebkit3d:Hi,msPointer:Fi,pointer:Ui,touch:Vi,mobileOpera:qi,mobileGecko:Gi,retina:Ki,canvas:Yi,svg:Xi,vml:Ji}),Qi=Fi?"MSPointerDown":"pointerdown",te=Fi?"MSPointerMove":"pointermove",ie=Fi?"MSPointerUp":"pointerup",ee=Fi?"MSPointerCancel":"pointercancel",ne=["INPUT","SELECT","OPTION"],oe={},se=!1,re=0,ae=Fi?"MSPointerDown":Ui?"pointerdown":"touchstart",he=Fi?"MSPointerUp":Ui?"pointerup":"touchend",ue="_leaflet_",le="_leaflet_events",ce=Bi&&Si?2*window.devicePixelRatio:Ei?window.devicePixelRatio:1,_e={},de=(Object.freeze||Object)({on:V,off:q,stopPropagation:Y,disableScrollPropagation:X,disableClickPropagation:J,preventDefault:$,stop:Q,getMousePosition:tt,getWheelDelta:it,fakeStop:et,skipped:nt,isExternalTarget:ot,addListener:V,removeListener:q}),pe=xt(["transform","WebkitTransform","OTransform","MozTransform","msTransform"]),me=xt(["webkitTransition","transition","OTransition","MozTransition","msTransition"]),fe="webkitTransition"===me||"OTransition"===me?me+"End":"transitionend";if("onselectstart"in document)mi=function(){V(window,"selectstart",$)},fi=function(){q(window,"selectstart",$)};else{var ge=xt(["userSelect","WebkitUserSelect","OUserSelect","MozUserSelect","msUserSelect"]);mi=function(){if(ge){var t=document.documentElement.style;gi=t[ge],t[ge]="none"}},fi=function(){ge&&(document.documentElement.style[ge]=gi,gi=void 0)}}var ve,ye,xe=(Object.freeze||Object)({TRANSFORM:pe,TRANSITION:me,TRANSITION_END:fe,get:rt,getStyle:at,create:ht,remove:ut,empty:lt,toFront:ct,toBack:_t,hasClass:dt,addClass:pt,removeClass:mt,setClass:ft,getClass:gt,setOpacity:vt,testProp:xt,setTransform:wt,setPosition:Lt,getPosition:Pt,disableTextSelection:mi,enableTextSelection:fi,disableImageDrag:bt,enableImageDrag:Tt,preventOutline:zt,restoreOutline:Mt}),we=ui.extend({run:function(t,i,e,n){this.stop(),this._el=t,this._inProgress=!0,this._duration=e||.25,this._easeOutPower=1/Math.max(n||.5,.2),this._startPos=Pt(t),this._offset=i.subtract(this._startPos),this._startTime=+new Date,this.fire("start"),this._animate()},stop:function(){this._inProgress&&(this._step(!0),this._complete())},_animate:function(){this._animId=f(this._animate,this),this._step()},_step:function(t){var i=+new Date-this._startTime,e=1e3*this._duration;i<e?this._runFrame(this._easeOut(i/e),t):(this._runFrame(1),this._complete())},_runFrame:function(t,i){var e=this._startPos.add(this._offset.multiplyBy(t));i&&e._round(),Lt(this._el,e),this.fire("step")},_complete:function(){g(this._animId),this._inProgress=!1,this.fire("end")},_easeOut:function(t){return 1-Math.pow(1-t,this._easeOutPower)}}),Le=ui.extend({options:{crs:vi,center:void 0,zoom:void 0,minZoom:void 0,maxZoom:void 0,layers:[],maxBounds:void 0,renderer:void 0,zoomAnimation:!0,zoomAnimationThreshold:4,fadeAnimation:!0,markerZoomAnimation:!0,transform3DLimit:8388608,zoomSnap:1,zoomDelta:1,trackResize:!0},initialize:function(t,i){i=l(this,i),this._initContainer(t),this._initLayout(),this._onResize=e(this._onResize,this),this._initEvents(),i.maxBounds&&this.setMaxBounds(i.maxBounds),void 0!==i.zoom&&(this._zoom=this._limitZoom(i.zoom)),i.center&&void 0!==i.zoom&&this.setView(C(i.center),i.zoom,{reset:!0}),this._handlers=[],this._layers={},this._zoomBoundLayers={},this._sizeChanged=!0,this.callInitHooks(),this._zoomAnimated=me&&Ni&&!qi&&this.options.zoomAnimation,this._zoomAnimated&&(this._createAnimProxy(),V(this._proxy,fe,this._catchTransitionEnd,this)),this._addLayers(this.options.layers)},setView:function(t,e,n){return e=void 0===e?this._zoom:this._limitZoom(e),t=this._limitCenter(C(t),e,this.options.maxBounds),n=n||{},this._stop(),this._loaded&&!n.reset&&!0!==n&&(void 0!==n.animate&&(n.zoom=i({animate:n.animate},n.zoom),n.pan=i({animate:n.animate,duration:n.duration},n.pan)),this._zoom!==e?this._tryAnimatedZoom&&this._tryAnimatedZoom(t,e,n.zoom):this._tryAnimatedPan(t,n.pan))?(clearTimeout(this._sizeTimer),this):(this._resetView(t,e),this)},setZoom:function(t,i){return this._loaded?this.setView(this.getCenter(),t,{zoom:i}):(this._zoom=t,this)},zoomIn:function(t,i){return t=t||(Ni?this.options.zoomDelta:1),this.setZoom(this._zoom+t,i)},zoomOut:function(t,i){return t=t||(Ni?this.options.zoomDelta:1),this.setZoom(this._zoom-t,i)},setZoomAround:function(t,i,e){var n=this.getZoomScale(i),o=this.getSize().divideBy(2),s=(t instanceof x?t:this.latLngToContainerPoint(t)).subtract(o).multiplyBy(1-1/n),r=this.containerPointToLatLng(o.add(s));return this.setView(r,i,{zoom:e})},_getBoundsCenterZoom:function(t,i){i=i||{},t=t.getBounds?t.getBounds():z(t);var e=w(i.paddingTopLeft||i.padding||[0,0]),n=w(i.paddingBottomRight||i.padding||[0,0]),o=this.getBoundsZoom(t,!1,e.add(n));if((o="number"==typeof i.maxZoom?Math.min(i.maxZoom,o):o)===1/0)return{center:t.getCenter(),zoom:o};var s=n.subtract(e).divideBy(2),r=this.project(t.getSouthWest(),o),a=this.project(t.getNorthEast(),o);return{center:this.unproject(r.add(a).divideBy(2).add(s),o),zoom:o}},fitBounds:function(t,i){if(!(t=z(t)).isValid())throw new Error("Bounds are not valid.");var e=this._getBoundsCenterZoom(t,i);return this.setView(e.center,e.zoom,i)},fitWorld:function(t){return this.fitBounds([[-90,-180],[90,180]],t)},panTo:function(t,i){return this.setView(t,this._zoom,{pan:i})},panBy:function(t,i){if(t=w(t).round(),i=i||{},!t.x&&!t.y)return this.fire("moveend");if(!0!==i.animate&&!this.getSize().contains(t))return this._resetView(this.unproject(this.project(this.getCenter()).add(t)),this.getZoom()),this;if(this._panAnim||(this._panAnim=new we,this._panAnim.on({step:this._onPanTransitionStep,end:this._onPanTransitionEnd},this)),i.noMoveStart||this.fire("movestart"),!1!==i.animate){pt(this._mapPane,"leaflet-pan-anim");var e=this._getMapPanePos().subtract(t).round();this._panAnim.run(this._mapPane,e,i.duration||.25,i.easeLinearity)}else this._rawPanBy(t),this.fire("move").fire("moveend");return this},flyTo:function(t,i,e){function n(t){var i=(g*g-m*m+(t?-1:1)*x*x*v*v)/(2*(t?g:m)*x*v),e=Math.sqrt(i*i+1)-i;return e<1e-9?-18:Math.log(e)}function o(t){return(Math.exp(t)-Math.exp(-t))/2}function s(t){return(Math.exp(t)+Math.exp(-t))/2}function r(t){return o(t)/s(t)}function a(t){return m*(s(w)/s(w+y*t))}function h(t){return m*(s(w)*r(w+y*t)-o(w))/x}function u(t){return 1-Math.pow(1-t,1.5)}function l(){var e=(Date.now()-L)/b,n=u(e)*P;e<=1?(this._flyToFrame=f(l,this),this._move(this.unproject(c.add(_.subtract(c).multiplyBy(h(n)/v)),p),this.getScaleZoom(m/a(n),p),{flyTo:!0})):this._move(t,i)._moveEnd(!0)}if(!1===(e=e||{}).animate||!Ni)return this.setView(t,i,e);this._stop();var c=this.project(this.getCenter()),_=this.project(t),d=this.getSize(),p=this._zoom;t=C(t),i=void 0===i?p:i;var m=Math.max(d.x,d.y),g=m*this.getZoomScale(p,i),v=_.distanceTo(c)||1,y=1.42,x=y*y,w=n(0),L=Date.now(),P=(n(1)-w)/y,b=e.duration?1e3*e.duration:1e3*P*.8;return this._moveStart(!0,e.noMoveStart),l.call(this),this},flyToBounds:function(t,i){var e=this._getBoundsCenterZoom(t,i);return this.flyTo(e.center,e.zoom,i)},setMaxBounds:function(t){return(t=z(t)).isValid()?(this.options.maxBounds&&this.off("moveend",this._panInsideMaxBounds),this.options.maxBounds=t,this._loaded&&this._panInsideMaxBounds(),this.on("moveend",this._panInsideMaxBounds)):(this.options.maxBounds=null,this.off("moveend",this._panInsideMaxBounds))},setMinZoom:function(t){var i=this.options.minZoom;return this.options.minZoom=t,this._loaded&&i!==t&&(this.fire("zoomlevelschange"),this.getZoom()<this.options.minZoom)?this.setZoom(t):this},setMaxZoom:function(t){var i=this.options.maxZoom;return this.options.maxZoom=t,this._loaded&&i!==t&&(this.fire("zoomlevelschange"),this.getZoom()>this.options.maxZoom)?this.setZoom(t):this},panInsideBounds:function(t,i){this._enforcingBounds=!0;var e=this.getCenter(),n=this._limitCenter(e,this._zoom,z(t));return e.equals(n)||this.panTo(n,i),this._enforcingBounds=!1,this},invalidateSize:function(t){if(!this._loaded)return this;t=i({animate:!1,pan:!0},!0===t?{animate:!0}:t);var n=this.getSize();this._sizeChanged=!0,this._lastCenter=null;var o=this.getSize(),s=n.divideBy(2).round(),r=o.divideBy(2).round(),a=s.subtract(r);return a.x||a.y?(t.animate&&t.pan?this.panBy(a):(t.pan&&this._rawPanBy(a),this.fire("move"),t.debounceMoveend?(clearTimeout(this._sizeTimer),this._sizeTimer=setTimeout(e(this.fire,this,"moveend"),200)):this.fire("moveend")),this.fire("resize",{oldSize:n,newSize:o})):this},stop:function(){return this.setZoom(this._limitZoom(this._zoom)),this.options.zoomSnap||this.fire("viewreset"),this._stop()},locate:function(t){if(t=this._locateOptions=i({timeout:1e4,watch:!1},t),!("geolocation"in navigator))return this._handleGeolocationError({code:0,message:"Geolocation not supported."}),this;var n=e(this._handleGeolocationResponse,this),o=e(this._handleGeolocationError,this);return t.watch?this._locationWatchId=navigator.geolocation.watchPosition(n,o,t):navigator.geolocation.getCurrentPosition(n,o,t),this},stopLocate:function(){return navigator.geolocation&&navigator.geolocation.clearWatch&&navigator.geolocation.clearWatch(this._locationWatchId),this._locateOptions&&(this._locateOptions.setView=!1),this},_handleGeolocationError:function(t){var i=t.code,e=t.message||(1===i?"permission denied":2===i?"position unavailable":"timeout");this._locateOptions.setView&&!this._loaded&&this.fitWorld(),this.fire("locationerror",{code:i,message:"Geolocation error: "+e+"."})},_handleGeolocationResponse:function(t){var i=new M(t.coords.latitude,t.coords.longitude),e=i.toBounds(t.coords.accuracy),n=this._locateOptions;if(n.setView){var o=this.getBoundsZoom(e);this.setView(i,n.maxZoom?Math.min(o,n.maxZoom):o)}var s={latlng:i,bounds:e,timestamp:t.timestamp};for(var r in t.coords)"number"==typeof t.coords[r]&&(s[r]=t.coords[r]);this.fire("locationfound",s)},addHandler:function(t,i){if(!i)return this;var e=this[t]=new i(this);return this._handlers.push(e),this.options[t]&&e.enable(),this},remove:function(){if(this._initEvents(!0),this._containerId!==this._container._leaflet_id)throw new Error("Map container is being reused by another instance");try{delete this._container._leaflet_id,delete this._containerId}catch(t){this._container._leaflet_id=void 0,this._containerId=void 0}void 0!==this._locationWatchId&&this.stopLocate(),this._stop(),ut(this._mapPane),this._clearControlPos&&this._clearControlPos(),this._clearHandlers(),this._loaded&&this.fire("unload");var t;for(t in this._layers)this._layers[t].remove();for(t in this._panes)ut(this._panes[t]);return this._layers=[],this._panes=[],delete this._mapPane,delete this._renderer,this},createPane:function(t,i){var e=ht("div","leaflet-pane"+(t?" leaflet-"+t.replace("Pane","")+"-pane":""),i||this._mapPane);return t&&(this._panes[t]=e),e},getCenter:function(){return this._checkIfLoaded(),this._lastCenter&&!this._moved()?this._lastCenter:this.layerPointToLatLng(this._getCenterLayerPoint())},getZoom:function(){return this._zoom},getBounds:function(){var t=this.getPixelBounds();return new T(this.unproject(t.getBottomLeft()),this.unproject(t.getTopRight()))},getMinZoom:function(){return void 0===this.options.minZoom?this._layersMinZoom||0:this.options.minZoom},getMaxZoom:function(){return void 0===this.options.maxZoom?void 0===this._layersMaxZoom?1/0:this._layersMaxZoom:this.options.maxZoom},getBoundsZoom:function(t,i,e){t=z(t),e=w(e||[0,0]);var n=this.getZoom()||0,o=this.getMinZoom(),s=this.getMaxZoom(),r=t.getNorthWest(),a=t.getSouthEast(),h=this.getSize().subtract(e),u=b(this.project(a,n),this.project(r,n)).getSize(),l=Ni?this.options.zoomSnap:1,c=h.x/u.x,_=h.y/u.y,d=i?Math.max(c,_):Math.min(c,_);return n=this.getScaleZoom(d,n),l&&(n=Math.round(n/(l/100))*(l/100),n=i?Math.ceil(n/l)*l:Math.floor(n/l)*l),Math.max(o,Math.min(s,n))},getSize:function(){return this._size&&!this._sizeChanged||(this._size=new x(this._container.clientWidth||0,this._container.clientHeight||0),this._sizeChanged=!1),this._size.clone()},getPixelBounds:function(t,i){var e=this._getTopLeftPoint(t,i);return new P(e,e.add(this.getSize()))},getPixelOrigin:function(){return this._checkIfLoaded(),this._pixelOrigin},getPixelWorldBounds:function(t){return this.options.crs.getProjectedBounds(void 0===t?this.getZoom():t)},getPane:function(t){return"string"==typeof t?this._panes[t]:t},getPanes:function(){return this._panes},getContainer:function(){return this._container},getZoomScale:function(t,i){var e=this.options.crs;return i=void 0===i?this._zoom:i,e.scale(t)/e.scale(i)},getScaleZoom:function(t,i){var e=this.options.crs;i=void 0===i?this._zoom:i;var n=e.zoom(t*e.scale(i));return isNaN(n)?1/0:n},project:function(t,i){return i=void 0===i?this._zoom:i,this.options.crs.latLngToPoint(C(t),i)},unproject:function(t,i){return i=void 0===i?this._zoom:i,this.options.crs.pointToLatLng(w(t),i)},layerPointToLatLng:function(t){var i=w(t).add(this.getPixelOrigin());return this.unproject(i)},latLngToLayerPoint:function(t){return this.project(C(t))._round()._subtract(this.getPixelOrigin())},wrapLatLng:function(t){return this.options.crs.wrapLatLng(C(t))},wrapLatLngBounds:function(t){return this.options.crs.wrapLatLngBounds(z(t))},distance:function(t,i){return this.options.crs.distance(C(t),C(i))},containerPointToLayerPoint:function(t){return w(t).subtract(this._getMapPanePos())},layerPointToContainerPoint:function(t){return w(t).add(this._getMapPanePos())},containerPointToLatLng:function(t){var i=this.containerPointToLayerPoint(w(t));return this.layerPointToLatLng(i)},latLngToContainerPoint:function(t){return this.layerPointToContainerPoint(this.latLngToLayerPoint(C(t)))},mouseEventToContainerPoint:function(t){return tt(t,this._container)},mouseEventToLayerPoint:function(t){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(t))},mouseEventToLatLng:function(t){return this.layerPointToLatLng(this.mouseEventToLayerPoint(t))},_initContainer:function(t){var i=this._container=rt(t);if(!i)throw new Error("Map container not found.");if(i._leaflet_id)throw new Error("Map container is already initialized.");V(i,"scroll",this._onScroll,this),this._containerId=n(i)},_initLayout:function(){var t=this._container;this._fadeAnimated=this.options.fadeAnimation&&Ni,pt(t,"leaflet-container"+(Vi?" leaflet-touch":"")+(Ki?" leaflet-retina":"")+(Li?" leaflet-oldie":"")+(ki?" leaflet-safari":"")+(this._fadeAnimated?" leaflet-fade-anim":""));var i=at(t,"position");"absolute"!==i&&"relative"!==i&&"fixed"!==i&&(t.style.position="relative"),this._initPanes(),this._initControlPos&&this._initControlPos()},_initPanes:function(){var t=this._panes={};this._paneRenderers={},this._mapPane=this.createPane("mapPane",this._container),Lt(this._mapPane,new x(0,0)),this.createPane("tilePane"),this.createPane("shadowPane"),this.createPane("overlayPane"),this.createPane("markerPane"),this.createPane("tooltipPane"),this.createPane("popupPane"),this.options.markerZoomAnimation||(pt(t.markerPane,"leaflet-zoom-hide"),pt(t.shadowPane,"leaflet-zoom-hide"))},_resetView:function(t,i){Lt(this._mapPane,new x(0,0));var e=!this._loaded;this._loaded=!0,i=this._limitZoom(i),this.fire("viewprereset");var n=this._zoom!==i;this._moveStart(n,!1)._move(t,i)._moveEnd(n),this.fire("viewreset"),e&&this.fire("load")},_moveStart:function(t,i){return t&&this.fire("zoomstart"),i||this.fire("movestart"),this},_move:function(t,i,e){void 0===i&&(i=this._zoom);var n=this._zoom!==i;return this._zoom=i,this._lastCenter=t,this._pixelOrigin=this._getNewPixelOrigin(t),(n||e&&e.pinch)&&this.fire("zoom",e),this.fire("move",e)},_moveEnd:function(t){return t&&this.fire("zoomend"),this.fire("moveend")},_stop:function(){return g(this._flyToFrame),this._panAnim&&this._panAnim.stop(),this},_rawPanBy:function(t){Lt(this._mapPane,this._getMapPanePos().subtract(t))},_getZoomSpan:function(){return this.getMaxZoom()-this.getMinZoom()},_panInsideMaxBounds:function(){this._enforcingBounds||this.panInsideBounds(this.options.maxBounds)},_checkIfLoaded:function(){if(!this._loaded)throw new Error("Set map center and zoom first.")},_initEvents:function(t){this._targets={},this._targets[n(this._container)]=this;var i=t?q:V;i(this._container,"click dblclick mousedown mouseup mouseover mouseout mousemove contextmenu keypress",this._handleDOMEvent,this),this.options.trackResize&&i(window,"resize",this._onResize,this),Ni&&this.options.transform3DLimit&&(t?this.off:this.on).call(this,"moveend",this._onMoveEnd)},_onResize:function(){g(this._resizeRequest),this._resizeRequest=f(function(){this.invalidateSize({debounceMoveend:!0})},this)},_onScroll:function(){this._container.scrollTop=0,this._container.scrollLeft=0},_onMoveEnd:function(){var t=this._getMapPanePos();Math.max(Math.abs(t.x),Math.abs(t.y))>=this.options.transform3DLimit&&this._resetView(this.getCenter(),this.getZoom())},_findEventTargets:function(t,i){for(var e,o=[],s="mouseout"===i||"mouseover"===i,r=t.target||t.srcElement,a=!1;r;){if((e=this._targets[n(r)])&&("click"===i||"preclick"===i)&&!t._simulated&&this._draggableMoved(e)){a=!0;break}if(e&&e.listens(i,!0)){if(s&&!ot(r,t))break;if(o.push(e),s)break}if(r===this._container)break;r=r.parentNode}return o.length||a||s||!ot(r,t)||(o=[this]),o},_handleDOMEvent:function(t){if(this._loaded&&!nt(t)){var i=t.type;"mousedown"!==i&&"keypress"!==i||zt(t.target||t.srcElement),this._fireDOMEvent(t,i)}},_mouseEvents:["click","dblclick","mouseover","mouseout","contextmenu"],_fireDOMEvent:function(t,e,n){if("click"===t.type){var o=i({},t);o.type="preclick",this._fireDOMEvent(o,o.type,n)}if(!t._stopped&&(n=(n||[]).concat(this._findEventTargets(t,e))).length){var s=n[0];"contextmenu"===e&&s.listens(e,!0)&&$(t);var r={originalEvent:t};if("keypress"!==t.type){var a=s.getLatLng&&(!s._radius||s._radius<=10);r.containerPoint=a?this.latLngToContainerPoint(s.getLatLng()):this.mouseEventToContainerPoint(t),r.layerPoint=this.containerPointToLayerPoint(r.containerPoint),r.latlng=a?s.getLatLng():this.layerPointToLatLng(r.layerPoint)}for(var h=0;h<n.length;h++)if(n[h].fire(e,r,!0),r.originalEvent._stopped||!1===n[h].options.bubblingMouseEvents&&-1!==d(this._mouseEvents,e))return}},_draggableMoved:function(t){return(t=t.dragging&&t.dragging.enabled()?t:this).dragging&&t.dragging.moved()||this.boxZoom&&this.boxZoom.moved()},_clearHandlers:function(){for(var t=0,i=this._handlers.length;t<i;t++)this._handlers[t].disable()},whenReady:function(t,i){return this._loaded?t.call(i||this,{target:this}):this.on("load",t,i),this},_getMapPanePos:function(){return Pt(this._mapPane)||new x(0,0)},_moved:function(){var t=this._getMapPanePos();return t&&!t.equals([0,0])},_getTopLeftPoint:function(t,i){return(t&&void 0!==i?this._getNewPixelOrigin(t,i):this.getPixelOrigin()).subtract(this._getMapPanePos())},_getNewPixelOrigin:function(t,i){var e=this.getSize()._divideBy(2);return this.project(t,i)._subtract(e)._add(this._getMapPanePos())._round()},_latLngToNewLayerPoint:function(t,i,e){var n=this._getNewPixelOrigin(e,i);return this.project(t,i)._subtract(n)},_latLngBoundsToNewLayerBounds:function(t,i,e){var n=this._getNewPixelOrigin(e,i);return b([this.project(t.getSouthWest(),i)._subtract(n),this.project(t.getNorthWest(),i)._subtract(n),this.project(t.getSouthEast(),i)._subtract(n),this.project(t.getNorthEast(),i)._subtract(n)])},_getCenterLayerPoint:function(){return this.containerPointToLayerPoint(this.getSize()._divideBy(2))},_getCenterOffset:function(t){return this.latLngToLayerPoint(t).subtract(this._getCenterLayerPoint())},_limitCenter:function(t,i,e){if(!e)return t;var n=this.project(t,i),o=this.getSize().divideBy(2),s=new P(n.subtract(o),n.add(o)),r=this._getBoundsOffset(s,e,i);return r.round().equals([0,0])?t:this.unproject(n.add(r),i)},_limitOffset:function(t,i){if(!i)return t;var e=this.getPixelBounds(),n=new P(e.min.add(t),e.max.add(t));return t.add(this._getBoundsOffset(n,i))},_getBoundsOffset:function(t,i,e){var n=b(this.project(i.getNorthEast(),e),this.project(i.getSouthWest(),e)),o=n.min.subtract(t.min),s=n.max.subtract(t.max);return new x(this._rebound(o.x,-s.x),this._rebound(o.y,-s.y))},_rebound:function(t,i){return t+i>0?Math.round(t-i)/2:Math.max(0,Math.ceil(t))-Math.max(0,Math.floor(i))},_limitZoom:function(t){var i=this.getMinZoom(),e=this.getMaxZoom(),n=Ni?this.options.zoomSnap:1;return n&&(t=Math.round(t/n)*n),Math.max(i,Math.min(e,t))},_onPanTransitionStep:function(){this.fire("move")},_onPanTransitionEnd:function(){mt(this._mapPane,"leaflet-pan-anim"),this.fire("moveend")},_tryAnimatedPan:function(t,i){var e=this._getCenterOffset(t)._trunc();return!(!0!==(i&&i.animate)&&!this.getSize().contains(e))&&(this.panBy(e,i),!0)},_createAnimProxy:function(){var t=this._proxy=ht("div","leaflet-proxy leaflet-zoom-animated");this._panes.mapPane.appendChild(t),this.on("zoomanim",function(t){var i=pe,e=this._proxy.style[i];wt(this._proxy,this.project(t.center,t.zoom),this.getZoomScale(t.zoom,1)),e===this._proxy.style[i]&&this._animatingZoom&&this._onZoomTransitionEnd()},this),this.on("load moveend",function(){var t=this.getCenter(),i=this.getZoom();wt(this._proxy,this.project(t,i),this.getZoomScale(i,1))},this),this._on("unload",this._destroyAnimProxy,this)},_destroyAnimProxy:function(){ut(this._proxy),delete this._proxy},_catchTransitionEnd:function(t){this._animatingZoom&&t.propertyName.indexOf("transform")>=0&&this._onZoomTransitionEnd()},_nothingToAnimate:function(){return!this._container.getElementsByClassName("leaflet-zoom-animated").length},_tryAnimatedZoom:function(t,i,e){if(this._animatingZoom)return!0;if(e=e||{},!this._zoomAnimated||!1===e.animate||this._nothingToAnimate()||Math.abs(i-this._zoom)>this.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(i),o=this._getCenterOffset(t)._divideBy(1-1/n);return!(!0!==e.animate&&!this.getSize().contains(o))&&(f(function(){this._moveStart(!0,!1)._animateZoom(t,i,!0)},this),!0)},_animateZoom:function(t,i,n,o){this._mapPane&&(n&&(this._animatingZoom=!0,this._animateToCenter=t,this._animateToZoom=i,pt(this._mapPane,"leaflet-zoom-anim")),this.fire("zoomanim",{center:t,zoom:i,noUpdate:o}),setTimeout(e(this._onZoomTransitionEnd,this),250))},_onZoomTransitionEnd:function(){this._animatingZoom&&(this._mapPane&&mt(this._mapPane,"leaflet-zoom-anim"),this._animatingZoom=!1,this._move(this._animateToCenter,this._animateToZoom),f(function(){this._moveEnd(!0)},this))}}),Pe=v.extend({options:{position:"topright"},initialize:function(t){l(this,t)},getPosition:function(){return this.options.position},setPosition:function(t){var i=this._map;return i&&i.removeControl(this),this.options.position=t,i&&i.addControl(this),this},getContainer:function(){return this._container},addTo:function(t){this.remove(),this._map=t;var i=this._container=this.onAdd(t),e=this.getPosition(),n=t._controlCorners[e];return pt(i,"leaflet-control"),-1!==e.indexOf("bottom")?n.insertBefore(i,n.firstChild):n.appendChild(i),this},remove:function(){return this._map?(ut(this._container),this.onRemove&&this.onRemove(this._map),this._map=null,this):this},_refocusOnMap:function(t){this._map&&t&&t.screenX>0&&t.screenY>0&&this._map.getContainer().focus()}}),be=function(t){return new Pe(t)};Le.include({addControl:function(t){return t.addTo(this),this},removeControl:function(t){return t.remove(),this},_initControlPos:function(){function t(t,o){var s=e+t+" "+e+o;i[t+o]=ht("div",s,n)}var i=this._controlCorners={},e="leaflet-",n=this._controlContainer=ht("div",e+"control-container",this._container);t("top","left"),t("top","right"),t("bottom","left"),t("bottom","right")},_clearControlPos:function(){for(var t in this._controlCorners)ut(this._controlCorners[t]);ut(this._controlContainer),delete this._controlCorners,delete this._controlContainer}});var Te=Pe.extend({options:{collapsed:!0,position:"topright",autoZIndex:!0,hideSingleBase:!1,sortLayers:!1,sortFunction:function(t,i,e,n){return e<n?-1:n<e?1:0}},initialize:function(t,i,e){l(this,e),this._layerControlInputs=[],this._layers=[],this._lastZIndex=0,this._handlingClick=!1;for(var n in t)this._addLayer(t[n],n);for(n in i)this._addLayer(i[n],n,!0)},onAdd:function(t){this._initLayout(),this._update(),this._map=t,t.on("zoomend",this._checkDisabledLayers,this);for(var i=0;i<this._layers.length;i++)this._layers[i].layer.on("add remove",this._onLayerChange,this);return this._container},addTo:function(t){return Pe.prototype.addTo.call(this,t),this._expandIfNotCollapsed()},onRemove:function(){this._map.off("zoomend",this._checkDisabledLayers,this);for(var t=0;t<this._layers.length;t++)this._layers[t].layer.off("add remove",this._onLayerChange,this)},addBaseLayer:function(t,i){return this._addLayer(t,i),this._map?this._update():this},addOverlay:function(t,i){return this._addLayer(t,i,!0),this._map?this._update():this},removeLayer:function(t){t.off("add remove",this._onLayerChange,this);var i=this._getLayer(n(t));return i&&this._layers.splice(this._layers.indexOf(i),1),this._map?this._update():this},expand:function(){pt(this._container,"leaflet-control-layers-expanded"),this._form.style.height=null;var t=this._map.getSize().y-(this._container.offsetTop+50);return t<this._form.clientHeight?(pt(this._form,"leaflet-control-layers-scrollbar"),this._form.style.height=t+"px"):mt(this._form,"leaflet-control-layers-scrollbar"),this._checkDisabledLayers(),this},collapse:function(){return mt(this._container,"leaflet-control-layers-expanded"),this},_initLayout:function(){var t="leaflet-control-layers",i=this._container=ht("div",t),e=this.options.collapsed;i.setAttribute("aria-haspopup",!0),J(i),X(i);var n=this._form=ht("form",t+"-list");e&&(this._map.on("click",this.collapse,this),Ti||V(i,{mouseenter:this.expand,mouseleave:this.collapse},this));var o=this._layersLink=ht("a",t+"-toggle",i);o.href="#",o.title="Layers",Vi?(V(o,"click",Q),V(o,"click",this.expand,this)):V(o,"focus",this.expand,this),e||this.expand(),this._baseLayersList=ht("div",t+"-base",n),this._separator=ht("div",t+"-separator",n),this._overlaysList=ht("div",t+"-overlays",n),i.appendChild(n)},_getLayer:function(t){for(var i=0;i<this._layers.length;i++)if(this._layers[i]&&n(this._layers[i].layer)===t)return this._layers[i]},_addLayer:function(t,i,n){this._map&&t.on("add remove",this._onLayerChange,this),this._layers.push({layer:t,name:i,overlay:n}),this.options.sortLayers&&this._layers.sort(e(function(t,i){return this.options.sortFunction(t.layer,i.layer,t.name,i.name)},this)),this.options.autoZIndex&&t.setZIndex&&(this._lastZIndex++,t.setZIndex(this._lastZIndex)),this._expandIfNotCollapsed()},_update:function(){if(!this._container)return this;lt(this._baseLayersList),lt(this._overlaysList),this._layerControlInputs=[];var t,i,e,n,o=0;for(e=0;e<this._layers.length;e++)n=this._layers[e],this._addItem(n),i=i||n.overlay,t=t||!n.overlay,o+=n.overlay?0:1;return this.options.hideSingleBase&&(t=t&&o>1,this._baseLayersList.style.display=t?"":"none"),this._separator.style.display=i&&t?"":"none",this},_onLayerChange:function(t){this._handlingClick||this._update();var i=this._getLayer(n(t.target)),e=i.overlay?"add"===t.type?"overlayadd":"overlayremove":"add"===t.type?"baselayerchange":null;e&&this._map.fire(e,i)},_createRadioElement:function(t,i){var e='<input type="radio" class="leaflet-control-layers-selector" name="'+t+'"'+(i?' checked="checked"':"")+"/>",n=document.createElement("div");return n.innerHTML=e,n.firstChild},_addItem:function(t){var i,e=document.createElement("label"),o=this._map.hasLayer(t.layer);t.overlay?((i=document.createElement("input")).type="checkbox",i.className="leaflet-control-layers-selector",i.defaultChecked=o):i=this._createRadioElement("leaflet-base-layers",o),this._layerControlInputs.push(i),i.layerId=n(t.layer),V(i,"click",this._onInputClick,this);var s=document.createElement("span");s.innerHTML=" "+t.name;var r=document.createElement("div");return e.appendChild(r),r.appendChild(i),r.appendChild(s),(t.overlay?this._overlaysList:this._baseLayersList).appendChild(e),this._checkDisabledLayers(),e},_onInputClick:function(){var t,i,e=this._layerControlInputs,n=[],o=[];this._handlingClick=!0;for(var s=e.length-1;s>=0;s--)t=e[s],i=this._getLayer(t.layerId).layer,t.checked?n.push(i):t.checked||o.push(i);for(s=0;s<o.length;s++)this._map.hasLayer(o[s])&&this._map.removeLayer(o[s]);for(s=0;s<n.length;s++)this._map.hasLayer(n[s])||this._map.addLayer(n[s]);this._handlingClick=!1,this._refocusOnMap()},_checkDisabledLayers:function(){for(var t,i,e=this._layerControlInputs,n=this._map.getZoom(),o=e.length-1;o>=0;o--)t=e[o],i=this._getLayer(t.layerId).layer,t.disabled=void 0!==i.options.minZoom&&n<i.options.minZoom||void 0!==i.options.maxZoom&&n>i.options.maxZoom},_expandIfNotCollapsed:function(){return this._map&&!this.options.collapsed&&this.expand(),this},_expand:function(){return this.expand()},_collapse:function(){return this.collapse()}}),ze=Pe.extend({options:{position:"topleft",zoomInText:"+",zoomInTitle:"Zoom in",zoomOutText:"&#x2212;",zoomOutTitle:"Zoom out"},onAdd:function(t){var i="leaflet-control-zoom",e=ht("div",i+" leaflet-bar"),n=this.options;return this._zoomInButton=this._createButton(n.zoomInText,n.zoomInTitle,i+"-in",e,this._zoomIn),this._zoomOutButton=this._createButton(n.zoomOutText,n.zoomOutTitle,i+"-out",e,this._zoomOut),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),e},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},disable:function(){return this._disabled=!0,this._updateDisabled(),this},enable:function(){return this._disabled=!1,this._updateDisabled(),this},_zoomIn:function(t){!this._disabled&&this._map._zoom<this._map.getMaxZoom()&&this._map.zoomIn(this._map.options.zoomDelta*(t.shiftKey?3:1))},_zoomOut:function(t){!this._disabled&&this._map._zoom>this._map.getMinZoom()&&this._map.zoomOut(this._map.options.zoomDelta*(t.shiftKey?3:1))},_createButton:function(t,i,e,n,o){var s=ht("a",e,n);return s.innerHTML=t,s.href="#",s.title=i,s.setAttribute("role","button"),s.setAttribute("aria-label",i),J(s),V(s,"click",Q),V(s,"click",o,this),V(s,"click",this._refocusOnMap,this),s},_updateDisabled:function(){var t=this._map,i="leaflet-disabled";mt(this._zoomInButton,i),mt(this._zoomOutButton,i),(this._disabled||t._zoom===t.getMinZoom())&&pt(this._zoomOutButton,i),(this._disabled||t._zoom===t.getMaxZoom())&&pt(this._zoomInButton,i)}});Le.mergeOptions({zoomControl:!0}),Le.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new ze,this.addControl(this.zoomControl))});var Me=Pe.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0},onAdd:function(t){var i=ht("div","leaflet-control-scale"),e=this.options;return this._addScales(e,"leaflet-control-scale-line",i),t.on(e.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),i},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,i,e){t.metric&&(this._mScale=ht("div",i,e)),t.imperial&&(this._iScale=ht("div",i,e))},_update:function(){var t=this._map,i=t.getSize().y/2,e=t.distance(t.containerPointToLatLng([0,i]),t.containerPointToLatLng([this.options.maxWidth,i]));this._updateScales(e)},_updateScales:function(t){this.options.metric&&t&&this._updateMetric(t),this.options.imperial&&t&&this._updateImperial(t)},_updateMetric:function(t){var i=this._getRoundNum(t),e=i<1e3?i+" m":i/1e3+" km";this._updateScale(this._mScale,e,i/t)},_updateImperial:function(t){var i,e,n,o=3.2808399*t;o>5280?(i=o/5280,e=this._getRoundNum(i),this._updateScale(this._iScale,e+" mi",e/i)):(n=this._getRoundNum(o),this._updateScale(this._iScale,n+" ft",n/o))},_updateScale:function(t,i,e){t.style.width=Math.round(this.options.maxWidth*e)+"px",t.innerHTML=i},_getRoundNum:function(t){var i=Math.pow(10,(Math.floor(t)+"").length-1),e=t/i;return e=e>=10?10:e>=5?5:e>=3?3:e>=2?2:1,i*e}}),Ce=Pe.extend({options:{position:"bottomright",prefix:'<a href="http://leafletjs.com" title="A JS library for interactive maps">Leaflet</a>'},initialize:function(t){l(this,t),this._attributions={}},onAdd:function(t){t.attributionControl=this,this._container=ht("div","leaflet-control-attribution"),J(this._container);for(var i in t._layers)t._layers[i].getAttribution&&this.addAttribution(t._layers[i].getAttribution());return this._update(),this._container},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t?(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update(),this):this},removeAttribution:function(t){return t?(this._attributions[t]&&(this._attributions[t]--,this._update()),this):this},_update:function(){if(this._map){var t=[];for(var i in this._attributions)this._attributions[i]&&t.push(i);var e=[];this.options.prefix&&e.push(this.options.prefix),t.length&&e.push(t.join(", ")),this._container.innerHTML=e.join(" | ")}}});Le.mergeOptions({attributionControl:!0}),Le.addInitHook(function(){this.options.attributionControl&&(new Ce).addTo(this)});Pe.Layers=Te,Pe.Zoom=ze,Pe.Scale=Me,Pe.Attribution=Ce,be.layers=function(t,i,e){return new Te(t,i,e)},be.zoom=function(t){return new ze(t)},be.scale=function(t){return new Me(t)},be.attribution=function(t){return new Ce(t)};var Ze=v.extend({initialize:function(t){this._map=t},enable:function(){return this._enabled?this:(this._enabled=!0,this.addHooks(),this)},disable:function(){return this._enabled?(this._enabled=!1,this.removeHooks(),this):this},enabled:function(){return!!this._enabled}});Ze.addTo=function(t,i){return t.addHandler(i,this),this};var Se,Ee={Events:hi},ke=Vi?"touchstart mousedown":"mousedown",Ae={mousedown:"mouseup",touchstart:"touchend",pointerdown:"touchend",MSPointerDown:"touchend"},Ie={mousedown:"mousemove",touchstart:"touchmove",pointerdown:"touchmove",MSPointerDown:"touchmove"},Be=ui.extend({options:{clickTolerance:3},initialize:function(t,i,e,n){l(this,n),this._element=t,this._dragStartTarget=i||t,this._preventOutline=e},enable:function(){this._enabled||(V(this._dragStartTarget,ke,this._onDown,this),this._enabled=!0)},disable:function(){this._enabled&&(Be._dragging===this&&this.finishDrag(),q(this._dragStartTarget,ke,this._onDown,this),this._enabled=!1,this._moved=!1)},_onDown:function(t){if(!t._simulated&&this._enabled&&(this._moved=!1,!dt(this._element,"leaflet-zoom-anim")&&!(Be._dragging||t.shiftKey||1!==t.which&&1!==t.button&&!t.touches||(Be._dragging=this,this._preventOutline&&zt(this._element),bt(),mi(),this._moving)))){this.fire("down");var i=t.touches?t.touches[0]:t;this._startPoint=new x(i.clientX,i.clientY),V(document,Ie[t.type],this._onMove,this),V(document,Ae[t.type],this._onUp,this)}},_onMove:function(t){if(!t._simulated&&this._enabled)if(t.touches&&t.touches.length>1)this._moved=!0;else{var i=t.touches&&1===t.touches.length?t.touches[0]:t,e=new x(i.clientX,i.clientY).subtract(this._startPoint);(e.x||e.y)&&(Math.abs(e.x)+Math.abs(e.y)<this.options.clickTolerance||($(t),this._moved||(this.fire("dragstart"),this._moved=!0,this._startPos=Pt(this._element).subtract(e),pt(document.body,"leaflet-dragging"),this._lastTarget=t.target||t.srcElement,window.SVGElementInstance&&this._lastTarget instanceof SVGElementInstance&&(this._lastTarget=this._lastTarget.correspondingUseElement),pt(this._lastTarget,"leaflet-drag-target")),this._newPos=this._startPos.add(e),this._moving=!0,g(this._animRequest),this._lastEvent=t,this._animRequest=f(this._updatePosition,this,!0)))}},_updatePosition:function(){var t={originalEvent:this._lastEvent};this.fire("predrag",t),Lt(this._element,this._newPos),this.fire("drag",t)},_onUp:function(t){!t._simulated&&this._enabled&&this.finishDrag()},finishDrag:function(){mt(document.body,"leaflet-dragging"),this._lastTarget&&(mt(this._lastTarget,"leaflet-drag-target"),this._lastTarget=null);for(var t in Ie)q(document,Ie[t],this._onMove,this),q(document,Ae[t],this._onUp,this);Tt(),fi(),this._moved&&this._moving&&(g(this._animRequest),this.fire("dragend",{distance:this._newPos.distanceTo(this._startPos)})),this._moving=!1,Be._dragging=!1}}),Oe=(Object.freeze||Object)({simplify:Ct,pointToSegmentDistance:Zt,closestPointOnSegment:function(t,i,e){return Rt(t,i,e)},clipSegment:At,_getEdgeIntersection:It,_getBitCode:Bt,_sqClosestPointOnSegment:Rt,isFlat:Dt,_flat:Nt}),Re=(Object.freeze||Object)({clipPolygon:jt}),De={project:function(t){return new x(t.lng,t.lat)},unproject:function(t){return new M(t.y,t.x)},bounds:new P([-180,-90],[180,90])},Ne={R:6378137,R_MINOR:6356752.314245179,bounds:new P([-20037508.34279,-15496570.73972],[20037508.34279,18764656.23138]),project:function(t){var i=Math.PI/180,e=this.R,n=t.lat*i,o=this.R_MINOR/e,s=Math.sqrt(1-o*o),r=s*Math.sin(n),a=Math.tan(Math.PI/4-n/2)/Math.pow((1-r)/(1+r),s/2);return n=-e*Math.log(Math.max(a,1e-10)),new x(t.lng*i*e,n)},unproject:function(t){for(var i,e=180/Math.PI,n=this.R,o=this.R_MINOR/n,s=Math.sqrt(1-o*o),r=Math.exp(-t.y/n),a=Math.PI/2-2*Math.atan(r),h=0,u=.1;h<15&&Math.abs(u)>1e-7;h++)i=s*Math.sin(a),i=Math.pow((1-i)/(1+i),s/2),a+=u=Math.PI/2-2*Math.atan(r*i)-a;return new M(a*e,t.x*e/n)}},je=(Object.freeze||Object)({LonLat:De,Mercator:Ne,SphericalMercator:di}),We=i({},_i,{code:"EPSG:3395",projection:Ne,transformation:function(){var t=.5/(Math.PI*Ne.R);return S(t,.5,-t,.5)}()}),He=i({},_i,{code:"EPSG:4326",projection:De,transformation:S(1/180,1,-1/180,.5)}),Fe=i({},ci,{projection:De,transformation:S(1,0,-1,0),scale:function(t){return Math.pow(2,t)},zoom:function(t){return Math.log(t)/Math.LN2},distance:function(t,i){var e=i.lng-t.lng,n=i.lat-t.lat;return Math.sqrt(e*e+n*n)},infinite:!0});ci.Earth=_i,ci.EPSG3395=We,ci.EPSG3857=vi,ci.EPSG900913=yi,ci.EPSG4326=He,ci.Simple=Fe;var Ue=ui.extend({options:{pane:"overlayPane",attribution:null,bubblingMouseEvents:!0},addTo:function(t){return t.addLayer(this),this},remove:function(){return this.removeFrom(this._map||this._mapToAdd)},removeFrom:function(t){return t&&t.removeLayer(this),this},getPane:function(t){return this._map.getPane(t?this.options[t]||t:this.options.pane)},addInteractiveTarget:function(t){return this._map._targets[n(t)]=this,this},removeInteractiveTarget:function(t){return delete this._map._targets[n(t)],this},getAttribution:function(){return this.options.attribution},_layerAdd:function(t){var i=t.target;if(i.hasLayer(this)){if(this._map=i,this._zoomAnimated=i._zoomAnimated,this.getEvents){var e=this.getEvents();i.on(e,this),this.once("remove",function(){i.off(e,this)},this)}this.onAdd(i),this.getAttribution&&i.attributionControl&&i.attributionControl.addAttribution(this.getAttribution()),this.fire("add"),i.fire("layeradd",{layer:this})}}});Le.include({addLayer:function(t){if(!t._layerAdd)throw new Error("The provided object is not a Layer.");var i=n(t);return this._layers[i]?this:(this._layers[i]=t,t._mapToAdd=this,t.beforeAdd&&t.beforeAdd(this),this.whenReady(t._layerAdd,t),this)},removeLayer:function(t){var i=n(t);return this._layers[i]?(this._loaded&&t.onRemove(this),t.getAttribution&&this.attributionControl&&this.attributionControl.removeAttribution(t.getAttribution()),delete this._layers[i],this._loaded&&(this.fire("layerremove",{layer:t}),t.fire("remove")),t._map=t._mapToAdd=null,this):this},hasLayer:function(t){return!!t&&n(t)in this._layers},eachLayer:function(t,i){for(var e in this._layers)t.call(i,this._layers[e]);return this},_addLayers:function(t){for(var i=0,e=(t=t?ei(t)?t:[t]:[]).length;i<e;i++)this.addLayer(t[i])},_addZoomLimit:function(t){!isNaN(t.options.maxZoom)&&isNaN(t.options.minZoom)||(this._zoomBoundLayers[n(t)]=t,this._updateZoomLevels())},_removeZoomLimit:function(t){var i=n(t);this._zoomBoundLayers[i]&&(delete this._zoomBoundLayers[i],this._updateZoomLevels())},_updateZoomLevels:function(){var t=1/0,i=-1/0,e=this._getZoomSpan();for(var n in this._zoomBoundLayers){var o=this._zoomBoundLayers[n].options;t=void 0===o.minZoom?t:Math.min(t,o.minZoom),i=void 0===o.maxZoom?i:Math.max(i,o.maxZoom)}this._layersMaxZoom=i===-1/0?void 0:i,this._layersMinZoom=t===1/0?void 0:t,e!==this._getZoomSpan()&&this.fire("zoomlevelschange"),void 0===this.options.maxZoom&&this._layersMaxZoom&&this.getZoom()>this._layersMaxZoom&&this.setZoom(this._layersMaxZoom),void 0===this.options.minZoom&&this._layersMinZoom&&this.getZoom()<this._layersMinZoom&&this.setZoom(this._layersMinZoom)}});var Ve=Ue.extend({initialize:function(t,i){l(this,i),this._layers={};var e,n;if(t)for(e=0,n=t.length;e<n;e++)this.addLayer(t[e])},addLayer:function(t){var i=this.getLayerId(t);return this._layers[i]=t,this._map&&this._map.addLayer(t),this},removeLayer:function(t){var i=t in this._layers?t:this.getLayerId(t);return this._map&&this._layers[i]&&this._map.removeLayer(this._layers[i]),delete this._layers[i],this},hasLayer:function(t){return!!t&&(t in this._layers||this.getLayerId(t)in this._layers)},clearLayers:function(){return this.eachLayer(this.removeLayer,this)},invoke:function(t){var i,e,n=Array.prototype.slice.call(arguments,1);for(i in this._layers)(e=this._layers[i])[t]&&e[t].apply(e,n);return this},onAdd:function(t){this.eachLayer(t.addLayer,t)},onRemove:function(t){this.eachLayer(t.removeLayer,t)},eachLayer:function(t,i){for(var e in this._layers)t.call(i,this._layers[e]);return this},getLayer:function(t){return this._layers[t]},getLayers:function(){var t=[];return this.eachLayer(t.push,t),t},setZIndex:function(t){return this.invoke("setZIndex",t)},getLayerId:function(t){return n(t)}}),qe=Ve.extend({addLayer:function(t){return this.hasLayer(t)?this:(t.addEventParent(this),Ve.prototype.addLayer.call(this,t),this.fire("layeradd",{layer:t}))},removeLayer:function(t){return this.hasLayer(t)?(t in this._layers&&(t=this._layers[t]),t.removeEventParent(this),Ve.prototype.removeLayer.call(this,t),this.fire("layerremove",{layer:t})):this},setStyle:function(t){return this.invoke("setStyle",t)},bringToFront:function(){return this.invoke("bringToFront")},bringToBack:function(){return this.invoke("bringToBack")},getBounds:function(){var t=new T;for(var i in this._layers){var e=this._layers[i];t.extend(e.getBounds?e.getBounds():e.getLatLng())}return t}}),Ge=v.extend({options:{popupAnchor:[0,0],tooltipAnchor:[0,0]},initialize:function(t){l(this,t)},createIcon:function(t){return this._createIcon("icon",t)},createShadow:function(t){return this._createIcon("shadow",t)},_createIcon:function(t,i){var e=this._getIconUrl(t);if(!e){if("icon"===t)throw new Error("iconUrl not set in Icon options (see the docs).");return null}var n=this._createImg(e,i&&"IMG"===i.tagName?i:null);return this._setIconStyles(n,t),n},_setIconStyles:function(t,i){var e=this.options,n=e[i+"Size"];"number"==typeof n&&(n=[n,n]);var o=w(n),s=w("shadow"===i&&e.shadowAnchor||e.iconAnchor||o&&o.divideBy(2,!0));t.className="leaflet-marker-"+i+" "+(e.className||""),s&&(t.style.marginLeft=-s.x+"px",t.style.marginTop=-s.y+"px"),o&&(t.style.width=o.x+"px",t.style.height=o.y+"px")},_createImg:function(t,i){return i=i||document.createElement("img"),i.src=t,i},_getIconUrl:function(t){return Ki&&this.options[t+"RetinaUrl"]||this.options[t+"Url"]}}),Ke=Ge.extend({options:{iconUrl:"marker-icon.png",iconRetinaUrl:"marker-icon-2x.png",shadowUrl:"marker-shadow.png",iconSize:[25,41],iconAnchor:[12,41],popupAnchor:[1,-34],tooltipAnchor:[16,-28],shadowSize:[41,41]},_getIconUrl:function(t){return Ke.imagePath||(Ke.imagePath=this._detectIconPath()),(this.options.imagePath||Ke.imagePath)+Ge.prototype._getIconUrl.call(this,t)},_detectIconPath:function(){var t=ht("div","leaflet-default-icon-path",document.body),i=at(t,"background-image")||at(t,"backgroundImage");return document.body.removeChild(t),i=null===i||0!==i.indexOf("url")?"":i.replace(/^url\(["']?/,"").replace(/marker-icon\.png["']?\)$/,"")}}),Ye=Ze.extend({initialize:function(t){this._marker=t},addHooks:function(){var t=this._marker._icon;this._draggable||(this._draggable=new Be(t,t,!0)),this._draggable.on({dragstart:this._onDragStart,predrag:this._onPreDrag,drag:this._onDrag,dragend:this._onDragEnd},this).enable(),pt(t,"leaflet-marker-draggable")},removeHooks:function(){this._draggable.off({dragstart:this._onDragStart,predrag:this._onPreDrag,drag:this._onDrag,dragend:this._onDragEnd},this).disable(),this._marker._icon&&mt(this._marker._icon,"leaflet-marker-draggable")},moved:function(){return this._draggable&&this._draggable._moved},_adjustPan:function(t){var i=this._marker,e=i._map,n=this._marker.options.autoPanSpeed,o=this._marker.options.autoPanPadding,s=L.DomUtil.getPosition(i._icon),r=e.getPixelBounds(),a=e.getPixelOrigin(),h=b(r.min._subtract(a).add(o),r.max._subtract(a).subtract(o));if(!h.contains(s)){var u=w((Math.max(h.max.x,s.x)-h.max.x)/(r.max.x-h.max.x)-(Math.min(h.min.x,s.x)-h.min.x)/(r.min.x-h.min.x),(Math.max(h.max.y,s.y)-h.max.y)/(r.max.y-h.max.y)-(Math.min(h.min.y,s.y)-h.min.y)/(r.min.y-h.min.y)).multiplyBy(n);e.panBy(u,{animate:!1}),this._draggable._newPos._add(u),this._draggable._startPos._add(u),L.DomUtil.setPosition(i._icon,this._draggable._newPos),this._onDrag(t),this._panRequest=f(this._adjustPan.bind(this,t))}},_onDragStart:function(){this._oldLatLng=this._marker.getLatLng(),this._marker.closePopup().fire("movestart").fire("dragstart")},_onPreDrag:function(t){this._marker.options.autoPan&&(g(this._panRequest),this._panRequest=f(this._adjustPan.bind(this,t)))},_onDrag:function(t){var i=this._marker,e=i._shadow,n=Pt(i._icon),o=i._map.layerPointToLatLng(n);e&&Lt(e,n),i._latlng=o,t.latlng=o,t.oldLatLng=this._oldLatLng,i.fire("move",t).fire("drag",t)},_onDragEnd:function(t){g(this._panRequest),delete this._oldLatLng,this._marker.fire("moveend").fire("dragend",t)}}),Xe=Ue.extend({options:{icon:new Ke,interactive:!0,draggable:!1,autoPan:!1,autoPanPadding:[50,50],autoPanSpeed:10,keyboard:!0,title:"",alt:"",zIndexOffset:0,opacity:1,riseOnHover:!1,riseOffset:250,pane:"markerPane",bubblingMouseEvents:!1},initialize:function(t,i){l(this,i),this._latlng=C(t)},onAdd:function(t){this._zoomAnimated=this._zoomAnimated&&t.options.markerZoomAnimation,this._zoomAnimated&&t.on("zoomanim",this._animateZoom,this),this._initIcon(),this.update()},onRemove:function(t){this.dragging&&this.dragging.enabled()&&(this.options.draggable=!0,this.dragging.removeHooks()),delete this.dragging,this._zoomAnimated&&t.off("zoomanim",this._animateZoom,this),this._removeIcon(),this._removeShadow()},getEvents:function(){return{zoom:this.update,viewreset:this.update}},getLatLng:function(){return this._latlng},setLatLng:function(t){var i=this._latlng;return this._latlng=C(t),this.update(),this.fire("move",{oldLatLng:i,latlng:this._latlng})},setZIndexOffset:function(t){return this.options.zIndexOffset=t,this.update()},setIcon:function(t){return this.options.icon=t,this._map&&(this._initIcon(),this.update()),this._popup&&this.bindPopup(this._popup,this._popup.options),this},getElement:function(){return this._icon},update:function(){if(this._icon&&this._map){var t=this._map.latLngToLayerPoint(this._latlng).round();this._setPos(t)}return this},_initIcon:function(){var t=this.options,i="leaflet-zoom-"+(this._zoomAnimated?"animated":"hide"),e=t.icon.createIcon(this._icon),n=!1;e!==this._icon&&(this._icon&&this._removeIcon(),n=!0,t.title&&(e.title=t.title),"IMG"===e.tagName&&(e.alt=t.alt||"")),pt(e,i),t.keyboard&&(e.tabIndex="0"),this._icon=e,t.riseOnHover&&this.on({mouseover:this._bringToFront,mouseout:this._resetZIndex});var o=t.icon.createShadow(this._shadow),s=!1;o!==this._shadow&&(this._removeShadow(),s=!0),o&&(pt(o,i),o.alt=""),this._shadow=o,t.opacity<1&&this._updateOpacity(),n&&this.getPane().appendChild(this._icon),this._initInteraction(),o&&s&&this.getPane("shadowPane").appendChild(this._shadow)},_removeIcon:function(){this.options.riseOnHover&&this.off({mouseover:this._bringToFront,mouseout:this._resetZIndex}),ut(this._icon),this.removeInteractiveTarget(this._icon),this._icon=null},_removeShadow:function(){this._shadow&&ut(this._shadow),this._shadow=null},_setPos:function(t){Lt(this._icon,t),this._shadow&&Lt(this._shadow,t),this._zIndex=t.y+this.options.zIndexOffset,this._resetZIndex()},_updateZIndex:function(t){this._icon.style.zIndex=this._zIndex+t},_animateZoom:function(t){var i=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center).round();this._setPos(i)},_initInteraction:function(){if(this.options.interactive&&(pt(this._icon,"leaflet-interactive"),this.addInteractiveTarget(this._icon),Ye)){var t=this.options.draggable;this.dragging&&(t=this.dragging.enabled(),this.dragging.disable()),this.dragging=new Ye(this),t&&this.dragging.enable()}},setOpacity:function(t){return this.options.opacity=t,this._map&&this._updateOpacity(),this},_updateOpacity:function(){var t=this.options.opacity;vt(this._icon,t),this._shadow&&vt(this._shadow,t)},_bringToFront:function(){this._updateZIndex(this.options.riseOffset)},_resetZIndex:function(){this._updateZIndex(0)},_getPopupAnchor:function(){return this.options.icon.options.popupAnchor},_getTooltipAnchor:function(){return this.options.icon.options.tooltipAnchor}}),Je=Ue.extend({options:{stroke:!0,color:"#3388ff",weight:3,opacity:1,lineCap:"round",lineJoin:"round",dashArray:null,dashOffset:null,fill:!1,fillColor:null,fillOpacity:.2,fillRule:"evenodd",interactive:!0,bubblingMouseEvents:!0},beforeAdd:function(t){this._renderer=t.getRenderer(this)},onAdd:function(){this._renderer._initPath(this),this._reset(),this._renderer._addPath(this)},onRemove:function(){this._renderer._removePath(this)},redraw:function(){return this._map&&this._renderer._updatePath(this),this},setStyle:function(t){return l(this,t),this._renderer&&this._renderer._updateStyle(this),this},bringToFront:function(){return this._renderer&&this._renderer._bringToFront(this),this},bringToBack:function(){return this._renderer&&this._renderer._bringToBack(this),this},getElement:function(){return this._path},_reset:function(){this._project(),this._update()},_clickTolerance:function(){return(this.options.stroke?this.options.weight/2:0)+this._renderer.options.tolerance}}),$e=Je.extend({options:{fill:!0,radius:10},initialize:function(t,i){l(this,i),this._latlng=C(t),this._radius=this.options.radius},setLatLng:function(t){return this._latlng=C(t),this.redraw(),this.fire("move",{latlng:this._latlng})},getLatLng:function(){return this._latlng},setRadius:function(t){return this.options.radius=this._radius=t,this.redraw()},getRadius:function(){return this._radius},setStyle:function(t){var i=t&&t.radius||this._radius;return Je.prototype.setStyle.call(this,t),this.setRadius(i),this},_project:function(){this._point=this._map.latLngToLayerPoint(this._latlng),this._updateBounds()},_updateBounds:function(){var t=this._radius,i=this._radiusY||t,e=this._clickTolerance(),n=[t+e,i+e];this._pxBounds=new P(this._point.subtract(n),this._point.add(n))},_update:function(){this._map&&this._updatePath()},_updatePath:function(){this._renderer._updateCircle(this)},_empty:function(){return this._radius&&!this._renderer._bounds.intersects(this._pxBounds)},_containsPoint:function(t){return t.distanceTo(this._point)<=this._radius+this._clickTolerance()}}),Qe=$e.extend({initialize:function(t,e,n){if("number"==typeof e&&(e=i({},n,{radius:e})),l(this,e),this._latlng=C(t),isNaN(this.options.radius))throw new Error("Circle radius cannot be NaN");this._mRadius=this.options.radius},setRadius:function(t){return this._mRadius=t,this.redraw()},getRadius:function(){return this._mRadius},getBounds:function(){var t=[this._radius,this._radiusY||this._radius];return new T(this._map.layerPointToLatLng(this._point.subtract(t)),this._map.layerPointToLatLng(this._point.add(t)))},setStyle:Je.prototype.setStyle,_project:function(){var t=this._latlng.lng,i=this._latlng.lat,e=this._map,n=e.options.crs;if(n.distance===_i.distance){var o=Math.PI/180,s=this._mRadius/_i.R/o,r=e.project([i+s,t]),a=e.project([i-s,t]),h=r.add(a).divideBy(2),u=e.unproject(h).lat,l=Math.acos((Math.cos(s*o)-Math.sin(i*o)*Math.sin(u*o))/(Math.cos(i*o)*Math.cos(u*o)))/o;(isNaN(l)||0===l)&&(l=s/Math.cos(Math.PI/180*i)),this._point=h.subtract(e.getPixelOrigin()),this._radius=isNaN(l)?0:h.x-e.project([u,t-l]).x,this._radiusY=h.y-r.y}else{var c=n.unproject(n.project(this._latlng).subtract([this._mRadius,0]));this._point=e.latLngToLayerPoint(this._latlng),this._radius=this._point.x-e.latLngToLayerPoint(c).x}this._updateBounds()}}),tn=Je.extend({options:{smoothFactor:1,noClip:!1},initialize:function(t,i){l(this,i),this._setLatLngs(t)},getLatLngs:function(){return this._latlngs},setLatLngs:function(t){return this._setLatLngs(t),this.redraw()},isEmpty:function(){return!this._latlngs.length},closestLayerPoint:function(t){for(var i,e,n=1/0,o=null,s=Rt,r=0,a=this._parts.length;r<a;r++)for(var h=this._parts[r],u=1,l=h.length;u<l;u++){var c=s(t,i=h[u-1],e=h[u],!0);c<n&&(n=c,o=s(t,i,e))}return o&&(o.distance=Math.sqrt(n)),o},getCenter:function(){if(!this._map)throw new Error("Must add layer to map before using getCenter()");var t,i,e,n,o,s,r,a=this._rings[0],h=a.length;if(!h)return null;for(t=0,i=0;t<h-1;t++)i+=a[t].distanceTo(a[t+1])/2;if(0===i)return this._map.layerPointToLatLng(a[0]);for(t=0,n=0;t<h-1;t++)if(o=a[t],s=a[t+1],e=o.distanceTo(s),(n+=e)>i)return r=(n-i)/e,this._map.layerPointToLatLng([s.x-r*(s.x-o.x),s.y-r*(s.y-o.y)])},getBounds:function(){return this._bounds},addLatLng:function(t,i){return i=i||this._defaultShape(),t=C(t),i.push(t),this._bounds.extend(t),this.redraw()},_setLatLngs:function(t){this._bounds=new T,this._latlngs=this._convertLatLngs(t)},_defaultShape:function(){return Dt(this._latlngs)?this._latlngs:this._latlngs[0]},_convertLatLngs:function(t){for(var i=[],e=Dt(t),n=0,o=t.length;n<o;n++)e?(i[n]=C(t[n]),this._bounds.extend(i[n])):i[n]=this._convertLatLngs(t[n]);return i},_project:function(){var t=new P;this._rings=[],this._projectLatlngs(this._latlngs,this._rings,t);var i=this._clickTolerance(),e=new x(i,i);this._bounds.isValid()&&t.isValid()&&(t.min._subtract(e),t.max._add(e),this._pxBounds=t)},_projectLatlngs:function(t,i,e){var n,o,s=t[0]instanceof M,r=t.length;if(s){for(o=[],n=0;n<r;n++)o[n]=this._map.latLngToLayerPoint(t[n]),e.extend(o[n]);i.push(o)}else for(n=0;n<r;n++)this._projectLatlngs(t[n],i,e)},_clipPoints:function(){var t=this._renderer._bounds;if(this._parts=[],this._pxBounds&&this._pxBounds.intersects(t))if(this.options.noClip)this._parts=this._rings;else{var i,e,n,o,s,r,a,h=this._parts;for(i=0,n=0,o=this._rings.length;i<o;i++)for(e=0,s=(a=this._rings[i]).length;e<s-1;e++)(r=At(a[e],a[e+1],t,e,!0))&&(h[n]=h[n]||[],h[n].push(r[0]),r[1]===a[e+1]&&e!==s-2||(h[n].push(r[1]),n++))}},_simplifyPoints:function(){for(var t=this._parts,i=this.options.smoothFactor,e=0,n=t.length;e<n;e++)t[e]=Ct(t[e],i)},_update:function(){this._map&&(this._clipPoints(),this._simplifyPoints(),this._updatePath())},_updatePath:function(){this._renderer._updatePoly(this)},_containsPoint:function(t,i){var e,n,o,s,r,a,h=this._clickTolerance();if(!this._pxBounds||!this._pxBounds.contains(t))return!1;for(e=0,s=this._parts.length;e<s;e++)for(n=0,o=(r=(a=this._parts[e]).length)-1;n<r;o=n++)if((i||0!==n)&&Zt(t,a[o],a[n])<=h)return!0;return!1}});tn._flat=Nt;var en=tn.extend({options:{fill:!0},isEmpty:function(){return!this._latlngs.length||!this._latlngs[0].length},getCenter:function(){if(!this._map)throw new Error("Must add layer to map before using getCenter()");var t,i,e,n,o,s,r,a,h,u=this._rings[0],l=u.length;if(!l)return null;for(s=r=a=0,t=0,i=l-1;t<l;i=t++)e=u[t],n=u[i],o=e.y*n.x-n.y*e.x,r+=(e.x+n.x)*o,a+=(e.y+n.y)*o,s+=3*o;return h=0===s?u[0]:[r/s,a/s],this._map.layerPointToLatLng(h)},_convertLatLngs:function(t){var i=tn.prototype._convertLatLngs.call(this,t),e=i.length;return e>=2&&i[0]instanceof M&&i[0].equals(i[e-1])&&i.pop(),i},_setLatLngs:function(t){tn.prototype._setLatLngs.call(this,t),Dt(this._latlngs)&&(this._latlngs=[this._latlngs])},_defaultShape:function(){return Dt(this._latlngs[0])?this._latlngs[0]:this._latlngs[0][0]},_clipPoints:function(){var t=this._renderer._bounds,i=this.options.weight,e=new x(i,i);if(t=new P(t.min.subtract(e),t.max.add(e)),this._parts=[],this._pxBounds&&this._pxBounds.intersects(t))if(this.options.noClip)this._parts=this._rings;else for(var n,o=0,s=this._rings.length;o<s;o++)(n=jt(this._rings[o],t,!0)).length&&this._parts.push(n)},_updatePath:function(){this._renderer._updatePoly(this,!0)},_containsPoint:function(t){var i,e,n,o,s,r,a,h,u=!1;if(!this._pxBounds.contains(t))return!1;for(o=0,a=this._parts.length;o<a;o++)for(s=0,r=(h=(i=this._parts[o]).length)-1;s<h;r=s++)e=i[s],n=i[r],e.y>t.y!=n.y>t.y&&t.x<(n.x-e.x)*(t.y-e.y)/(n.y-e.y)+e.x&&(u=!u);return u||tn.prototype._containsPoint.call(this,t,!0)}}),nn=qe.extend({initialize:function(t,i){l(this,i),this._layers={},t&&this.addData(t)},addData:function(t){var i,e,n,o=ei(t)?t:t.features;if(o){for(i=0,e=o.length;i<e;i++)((n=o[i]).geometries||n.geometry||n.features||n.coordinates)&&this.addData(n);return this}var s=this.options;if(s.filter&&!s.filter(t))return this;var r=Wt(t,s);return r?(r.feature=Gt(t),r.defaultOptions=r.options,this.resetStyle(r),s.onEachFeature&&s.onEachFeature(t,r),this.addLayer(r)):this},resetStyle:function(t){return t.options=i({},t.defaultOptions),this._setLayerStyle(t,this.options.style),this},setStyle:function(t){return this.eachLayer(function(i){this._setLayerStyle(i,t)},this)},_setLayerStyle:function(t,i){"function"==typeof i&&(i=i(t.feature)),t.setStyle&&t.setStyle(i)}}),on={toGeoJSON:function(t){return qt(this,{type:"Point",coordinates:Ut(this.getLatLng(),t)})}};Xe.include(on),Qe.include(on),$e.include(on),tn.include({toGeoJSON:function(t){var i=!Dt(this._latlngs),e=Vt(this._latlngs,i?1:0,!1,t);return qt(this,{type:(i?"Multi":"")+"LineString",coordinates:e})}}),en.include({toGeoJSON:function(t){var i=!Dt(this._latlngs),e=i&&!Dt(this._latlngs[0]),n=Vt(this._latlngs,e?2:i?1:0,!0,t);return i||(n=[n]),qt(this,{type:(e?"Multi":"")+"Polygon",coordinates:n})}}),Ve.include({toMultiPoint:function(t){var i=[];return this.eachLayer(function(e){i.push(e.toGeoJSON(t).geometry.coordinates)}),qt(this,{type:"MultiPoint",coordinates:i})},toGeoJSON:function(t){var i=this.feature&&this.feature.geometry&&this.feature.geometry.type;if("MultiPoint"===i)return this.toMultiPoint(t);var e="GeometryCollection"===i,n=[];return this.eachLayer(function(i){if(i.toGeoJSON){var o=i.toGeoJSON(t);if(e)n.push(o.geometry);else{var s=Gt(o);"FeatureCollection"===s.type?n.push.apply(n,s.features):n.push(s)}}}),e?qt(this,{geometries:n,type:"GeometryCollection"}):{type:"FeatureCollection",features:n}}});var sn=Kt,rn=Ue.extend({options:{opacity:1,alt:"",interactive:!1,crossOrigin:!1,errorOverlayUrl:"",zIndex:1,className:""},initialize:function(t,i,e){this._url=t,this._bounds=z(i),l(this,e)},onAdd:function(){this._image||(this._initImage(),this.options.opacity<1&&this._updateOpacity()),this.options.interactive&&(pt(this._image,"leaflet-interactive"),this.addInteractiveTarget(this._image)),this.getPane().appendChild(this._image),this._reset()},onRemove:function(){ut(this._image),this.options.interactive&&this.removeInteractiveTarget(this._image)},setOpacity:function(t){return this.options.opacity=t,this._image&&this._updateOpacity(),this},setStyle:function(t){return t.opacity&&this.setOpacity(t.opacity),this},bringToFront:function(){return this._map&&ct(this._image),this},bringToBack:function(){return this._map&&_t(this._image),this},setUrl:function(t){return this._url=t,this._image&&(this._image.src=t),this},setBounds:function(t){return this._bounds=z(t),this._map&&this._reset(),this},getEvents:function(){var t={zoom:this._reset,viewreset:this._reset};return this._zoomAnimated&&(t.zoomanim=this._animateZoom),t},setZIndex:function(t){return this.options.zIndex=t,this._updateZIndex(),this},getBounds:function(){return this._bounds},getElement:function(){return this._image},_initImage:function(){var t="IMG"===this._url.tagName,i=this._image=t?this._url:ht("img");pt(i,"leaflet-image-layer"),this._zoomAnimated&&pt(i,"leaflet-zoom-animated"),this.options.className&&pt(i,this.options.className),i.onselectstart=r,i.onmousemove=r,i.onload=e(this.fire,this,"load"),i.onerror=e(this._overlayOnError,this,"error"),this.options.crossOrigin&&(i.crossOrigin=""),this.options.zIndex&&this._updateZIndex(),t?this._url=i.src:(i.src=this._url,i.alt=this.options.alt)},_animateZoom:function(t){var i=this._map.getZoomScale(t.zoom),e=this._map._latLngBoundsToNewLayerBounds(this._bounds,t.zoom,t.center).min;wt(this._image,e,i)},_reset:function(){var t=this._image,i=new P(this._map.latLngToLayerPoint(this._bounds.getNorthWest()),this._map.latLngToLayerPoint(this._bounds.getSouthEast())),e=i.getSize();Lt(t,i.min),t.style.width=e.x+"px",t.style.height=e.y+"px"},_updateOpacity:function(){vt(this._image,this.options.opacity)},_updateZIndex:function(){this._image&&void 0!==this.options.zIndex&&null!==this.options.zIndex&&(this._image.style.zIndex=this.options.zIndex)},_overlayOnError:function(){this.fire("error");var t=this.options.errorOverlayUrl;t&&this._url!==t&&(this._url=t,this._image.src=t)}}),an=rn.extend({options:{autoplay:!0,loop:!0},_initImage:function(){var t="VIDEO"===this._url.tagName,i=this._image=t?this._url:ht("video");if(pt(i,"leaflet-image-layer"),this._zoomAnimated&&pt(i,"leaflet-zoom-animated"),i.onselectstart=r,i.onmousemove=r,i.onloadeddata=e(this.fire,this,"load"),t){for(var n=i.getElementsByTagName("source"),o=[],s=0;s<n.length;s++)o.push(n[s].src);this._url=n.length>0?o:[i.src]}else{ei(this._url)||(this._url=[this._url]),i.autoplay=!!this.options.autoplay,i.loop=!!this.options.loop;for(var a=0;a<this._url.length;a++){var h=ht("source");h.src=this._url[a],i.appendChild(h)}}}}),hn=Ue.extend({options:{offset:[0,7],className:"",pane:"popupPane"},initialize:function(t,i){l(this,t),this._source=i},onAdd:function(t){this._zoomAnimated=t._zoomAnimated,this._container||this._initLayout(),t._fadeAnimated&&vt(this._container,0),clearTimeout(this._removeTimeout),this.getPane().appendChild(this._container),this.update(),t._fadeAnimated&&vt(this._container,1),this.bringToFront()},onRemove:function(t){t._fadeAnimated?(vt(this._container,0),this._removeTimeout=setTimeout(e(ut,void 0,this._container),200)):ut(this._container)},getLatLng:function(){return this._latlng},setLatLng:function(t){return this._latlng=C(t),this._map&&(this._updatePosition(),this._adjustPan()),this},getContent:function(){return this._content},setContent:function(t){return this._content=t,this.update(),this},getElement:function(){return this._container},update:function(){this._map&&(this._container.style.visibility="hidden",this._updateContent(),this._updateLayout(),this._updatePosition(),this._container.style.visibility="",this._adjustPan())},getEvents:function(){var t={zoom:this._updatePosition,viewreset:this._updatePosition};return this._zoomAnimated&&(t.zoomanim=this._animateZoom),t},isOpen:function(){return!!this._map&&this._map.hasLayer(this)},bringToFront:function(){return this._map&&ct(this._container),this},bringToBack:function(){return this._map&&_t(this._container),this},_updateContent:function(){if(this._content){var t=this._contentNode,i="function"==typeof this._content?this._content(this._source||this):this._content;if("string"==typeof i)t.innerHTML=i;else{for(;t.hasChildNodes();)t.removeChild(t.firstChild);t.appendChild(i)}this.fire("contentupdate")}},_updatePosition:function(){if(this._map){var t=this._map.latLngToLayerPoint(this._latlng),i=w(this.options.offset),e=this._getAnchor();this._zoomAnimated?Lt(this._container,t.add(e)):i=i.add(t).add(e);var n=this._containerBottom=-i.y,o=this._containerLeft=-Math.round(this._containerWidth/2)+i.x;this._container.style.bottom=n+"px",this._container.style.left=o+"px"}},_getAnchor:function(){return[0,0]}}),un=hn.extend({options:{maxWidth:300,minWidth:50,maxHeight:null,autoPan:!0,autoPanPaddingTopLeft:null,autoPanPaddingBottomRight:null,autoPanPadding:[5,5],keepInView:!1,closeButton:!0,autoClose:!0,closeOnEscapeKey:!0,className:""},openOn:function(t){return t.openPopup(this),this},onAdd:function(t){hn.prototype.onAdd.call(this,t),t.fire("popupopen",{popup:this}),this._source&&(this._source.fire("popupopen",{popup:this},!0),this._source instanceof Je||this._source.on("preclick",Y))},onRemove:function(t){hn.prototype.onRemove.call(this,t),t.fire("popupclose",{popup:this}),this._source&&(this._source.fire("popupclose",{popup:this},!0),this._source instanceof Je||this._source.off("preclick",Y))},getEvents:function(){var t=hn.prototype.getEvents.call(this);return(void 0!==this.options.closeOnClick?this.options.closeOnClick:this._map.options.closePopupOnClick)&&(t.preclick=this._close),this.options.keepInView&&(t.moveend=this._adjustPan),t},_close:function(){this._map&&this._map.closePopup(this)},_initLayout:function(){var t="leaflet-popup",i=this._container=ht("div",t+" "+(this.options.className||"")+" leaflet-zoom-animated"),e=this._wrapper=ht("div",t+"-content-wrapper",i);if(this._contentNode=ht("div",t+"-content",e),J(e),X(this._contentNode),V(e,"contextmenu",Y),this._tipContainer=ht("div",t+"-tip-container",i),this._tip=ht("div",t+"-tip",this._tipContainer),this.options.closeButton){var n=this._closeButton=ht("a",t+"-close-button",i);n.href="#close",n.innerHTML="&#215;",V(n,"click",this._onCloseButtonClick,this)}},_updateLayout:function(){var t=this._contentNode,i=t.style;i.width="",i.whiteSpace="nowrap";var e=t.offsetWidth;e=Math.min(e,this.options.maxWidth),e=Math.max(e,this.options.minWidth),i.width=e+1+"px",i.whiteSpace="",i.height="";var n=t.offsetHeight,o=this.options.maxHeight;o&&n>o?(i.height=o+"px",pt(t,"leaflet-popup-scrolled")):mt(t,"leaflet-popup-scrolled"),this._containerWidth=this._container.offsetWidth},_animateZoom:function(t){var i=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center),e=this._getAnchor();Lt(this._container,i.add(e))},_adjustPan:function(){if(!(!this.options.autoPan||this._map._panAnim&&this._map._panAnim._inProgress)){var t=this._map,i=parseInt(at(this._container,"marginBottom"),10)||0,e=this._container.offsetHeight+i,n=this._containerWidth,o=new x(this._containerLeft,-e-this._containerBottom);o._add(Pt(this._container));var s=t.layerPointToContainerPoint(o),r=w(this.options.autoPanPadding),a=w(this.options.autoPanPaddingTopLeft||r),h=w(this.options.autoPanPaddingBottomRight||r),u=t.getSize(),l=0,c=0;s.x+n+h.x>u.x&&(l=s.x+n-u.x+h.x),s.x-l-a.x<0&&(l=s.x-a.x),s.y+e+h.y>u.y&&(c=s.y+e-u.y+h.y),s.y-c-a.y<0&&(c=s.y-a.y),(l||c)&&t.fire("autopanstart").panBy([l,c])}},_onCloseButtonClick:function(t){this._close(),Q(t)},_getAnchor:function(){return w(this._source&&this._source._getPopupAnchor?this._source._getPopupAnchor():[0,0])}});Le.mergeOptions({closePopupOnClick:!0}),Le.include({openPopup:function(t,i,e){return t instanceof un||(t=new un(e).setContent(t)),i&&t.setLatLng(i),this.hasLayer(t)?this:(this._popup&&this._popup.options.autoClose&&this.closePopup(),this._popup=t,this.addLayer(t))},closePopup:function(t){return t&&t!==this._popup||(t=this._popup,this._popup=null),t&&this.removeLayer(t),this}}),Ue.include({bindPopup:function(t,i){return t instanceof un?(l(t,i),this._popup=t,t._source=this):(this._popup&&!i||(this._popup=new un(i,this)),this._popup.setContent(t)),this._popupHandlersAdded||(this.on({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!0),this},unbindPopup:function(){return this._popup&&(this.off({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!1,this._popup=null),this},openPopup:function(t,i){if(t instanceof Ue||(i=t,t=this),t instanceof qe)for(var e in this._layers){t=this._layers[e];break}return i||(i=t.getCenter?t.getCenter():t.getLatLng()),this._popup&&this._map&&(this._popup._source=t,this._popup.update(),this._map.openPopup(this._popup,i)),this},closePopup:function(){return this._popup&&this._popup._close(),this},togglePopup:function(t){return this._popup&&(this._popup._map?this.closePopup():this.openPopup(t)),this},isPopupOpen:function(){return!!this._popup&&this._popup.isOpen()},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},getPopup:function(){return this._popup},_openPopup:function(t){var i=t.layer||t.target;this._popup&&this._map&&(Q(t),i instanceof Je?this.openPopup(t.layer||t.target,t.latlng):this._map.hasLayer(this._popup)&&this._popup._source===i?this.closePopup():this.openPopup(i,t.latlng))},_movePopup:function(t){this._popup.setLatLng(t.latlng)},_onKeyPress:function(t){13===t.originalEvent.keyCode&&this._openPopup(t)}});var ln=hn.extend({options:{pane:"tooltipPane",offset:[0,0],direction:"auto",permanent:!1,sticky:!1,interactive:!1,opacity:.9},onAdd:function(t){hn.prototype.onAdd.call(this,t),this.setOpacity(this.options.opacity),t.fire("tooltipopen",{tooltip:this}),this._source&&this._source.fire("tooltipopen",{tooltip:this},!0)},onRemove:function(t){hn.prototype.onRemove.call(this,t),t.fire("tooltipclose",{tooltip:this}),this._source&&this._source.fire("tooltipclose",{tooltip:this},!0)},getEvents:function(){var t=hn.prototype.getEvents.call(this);return Vi&&!this.options.permanent&&(t.preclick=this._close),t},_close:function(){this._map&&this._map.closeTooltip(this)},_initLayout:function(){var t="leaflet-tooltip "+(this.options.className||"")+" leaflet-zoom-"+(this._zoomAnimated?"animated":"hide");this._contentNode=this._container=ht("div",t)},_updateLayout:function(){},_adjustPan:function(){},_setPosition:function(t){var i=this._map,e=this._container,n=i.latLngToContainerPoint(i.getCenter()),o=i.layerPointToContainerPoint(t),s=this.options.direction,r=e.offsetWidth,a=e.offsetHeight,h=w(this.options.offset),u=this._getAnchor();"top"===s?t=t.add(w(-r/2+h.x,-a+h.y+u.y,!0)):"bottom"===s?t=t.subtract(w(r/2-h.x,-h.y,!0)):"center"===s?t=t.subtract(w(r/2+h.x,a/2-u.y+h.y,!0)):"right"===s||"auto"===s&&o.x<n.x?(s="right",t=t.add(w(h.x+u.x,u.y-a/2+h.y,!0))):(s="left",t=t.subtract(w(r+u.x-h.x,a/2-u.y-h.y,!0))),mt(e,"leaflet-tooltip-right"),mt(e,"leaflet-tooltip-left"),mt(e,"leaflet-tooltip-top"),mt(e,"leaflet-tooltip-bottom"),pt(e,"leaflet-tooltip-"+s),Lt(e,t)},_updatePosition:function(){var t=this._map.latLngToLayerPoint(this._latlng);this._setPosition(t)},setOpacity:function(t){this.options.opacity=t,this._container&&vt(this._container,t)},_animateZoom:function(t){var i=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center);this._setPosition(i)},_getAnchor:function(){return w(this._source&&this._source._getTooltipAnchor&&!this.options.sticky?this._source._getTooltipAnchor():[0,0])}});Le.include({openTooltip:function(t,i,e){return t instanceof ln||(t=new ln(e).setContent(t)),i&&t.setLatLng(i),this.hasLayer(t)?this:this.addLayer(t)},closeTooltip:function(t){return t&&this.removeLayer(t),this}}),Ue.include({bindTooltip:function(t,i){return t instanceof ln?(l(t,i),this._tooltip=t,t._source=this):(this._tooltip&&!i||(this._tooltip=new ln(i,this)),this._tooltip.setContent(t)),this._initTooltipInteractions(),this._tooltip.options.permanent&&this._map&&this._map.hasLayer(this)&&this.openTooltip(),this},unbindTooltip:function(){return this._tooltip&&(this._initTooltipInteractions(!0),this.closeTooltip(),this._tooltip=null),this},_initTooltipInteractions:function(t){if(t||!this._tooltipHandlersAdded){var i=t?"off":"on",e={remove:this.closeTooltip,move:this._moveTooltip};this._tooltip.options.permanent?e.add=this._openTooltip:(e.mouseover=this._openTooltip,e.mouseout=this.closeTooltip,this._tooltip.options.sticky&&(e.mousemove=this._moveTooltip),Vi&&(e.click=this._openTooltip)),this[i](e),this._tooltipHandlersAdded=!t}},openTooltip:function(t,i){if(t instanceof Ue||(i=t,t=this),t instanceof qe)for(var e in this._layers){t=this._layers[e];break}return i||(i=t.getCenter?t.getCenter():t.getLatLng()),this._tooltip&&this._map&&(this._tooltip._source=t,this._tooltip.update(),this._map.openTooltip(this._tooltip,i),this._tooltip.options.interactive&&this._tooltip._container&&(pt(this._tooltip._container,"leaflet-clickable"),this.addInteractiveTarget(this._tooltip._container))),this},closeTooltip:function(){return this._tooltip&&(this._tooltip._close(),this._tooltip.options.interactive&&this._tooltip._container&&(mt(this._tooltip._container,"leaflet-clickable"),this.removeInteractiveTarget(this._tooltip._container))),this},toggleTooltip:function(t){return this._tooltip&&(this._tooltip._map?this.closeTooltip():this.openTooltip(t)),this},isTooltipOpen:function(){return this._tooltip.isOpen()},setTooltipContent:function(t){return this._tooltip&&this._tooltip.setContent(t),this},getTooltip:function(){return this._tooltip},_openTooltip:function(t){var i=t.layer||t.target;this._tooltip&&this._map&&this.openTooltip(i,this._tooltip.options.sticky?t.latlng:void 0)},_moveTooltip:function(t){var i,e,n=t.latlng;this._tooltip.options.sticky&&t.originalEvent&&(i=this._map.mouseEventToContainerPoint(t.originalEvent),e=this._map.containerPointToLayerPoint(i),n=this._map.layerPointToLatLng(e)),this._tooltip.setLatLng(n)}});var cn=Ge.extend({options:{iconSize:[12,12],html:!1,bgPos:null,className:"leaflet-div-icon"},createIcon:function(t){var i=t&&"DIV"===t.tagName?t:document.createElement("div"),e=this.options;if(i.innerHTML=!1!==e.html?e.html:"",e.bgPos){var n=w(e.bgPos);i.style.backgroundPosition=-n.x+"px "+-n.y+"px"}return this._setIconStyles(i,"icon"),i},createShadow:function(){return null}});Ge.Default=Ke;var _n=Ue.extend({options:{tileSize:256,opacity:1,updateWhenIdle:ji,updateWhenZooming:!0,updateInterval:200,zIndex:1,bounds:null,minZoom:0,maxZoom:void 0,maxNativeZoom:void 0,minNativeZoom:void 0,noWrap:!1,pane:"tilePane",className:"",keepBuffer:2},initialize:function(t){l(this,t)},onAdd:function(){this._initContainer(),this._levels={},this._tiles={},this._resetView(),this._update()},beforeAdd:function(t){t._addZoomLimit(this)},onRemove:function(t){this._removeAllTiles(),ut(this._container),t._removeZoomLimit(this),this._container=null,this._tileZoom=void 0},bringToFront:function(){return this._map&&(ct(this._container),this._setAutoZIndex(Math.max)),this},bringToBack:function(){return this._map&&(_t(this._container),this._setAutoZIndex(Math.min)),this},getContainer:function(){return this._container},setOpacity:function(t){return this.options.opacity=t,this._updateOpacity(),this},setZIndex:function(t){return this.options.zIndex=t,this._updateZIndex(),this},isLoading:function(){return this._loading},redraw:function(){return this._map&&(this._removeAllTiles(),this._update()),this},getEvents:function(){var t={viewprereset:this._invalidateAll,viewreset:this._resetView,zoom:this._resetView,moveend:this._onMoveEnd};return this.options.updateWhenIdle||(this._onMove||(this._onMove=o(this._onMoveEnd,this.options.updateInterval,this)),t.move=this._onMove),this._zoomAnimated&&(t.zoomanim=this._animateZoom),t},createTile:function(){return document.createElement("div")},getTileSize:function(){var t=this.options.tileSize;return t instanceof x?t:new x(t,t)},_updateZIndex:function(){this._container&&void 0!==this.options.zIndex&&null!==this.options.zIndex&&(this._container.style.zIndex=this.options.zIndex)},_setAutoZIndex:function(t){for(var i,e=this.getPane().children,n=-t(-1/0,1/0),o=0,s=e.length;o<s;o++)i=e[o].style.zIndex,e[o]!==this._container&&i&&(n=t(n,+i));isFinite(n)&&(this.options.zIndex=n+t(-1,1),this._updateZIndex())},_updateOpacity:function(){if(this._map&&!Li){vt(this._container,this.options.opacity);var t=+new Date,i=!1,e=!1;for(var n in this._tiles){var o=this._tiles[n];if(o.current&&o.loaded){var s=Math.min(1,(t-o.loaded)/200);vt(o.el,s),s<1?i=!0:(o.active?e=!0:this._onOpaqueTile(o),o.active=!0)}}e&&!this._noPrune&&this._pruneTiles(),i&&(g(this._fadeFrame),this._fadeFrame=f(this._updateOpacity,this))}},_onOpaqueTile:r,_initContainer:function(){this._container||(this._container=ht("div","leaflet-layer "+(this.options.className||"")),this._updateZIndex(),this.options.opacity<1&&this._updateOpacity(),this.getPane().appendChild(this._container))},_updateLevels:function(){var t=this._tileZoom,i=this.options.maxZoom;if(void 0!==t){for(var e in this._levels)this._levels[e].el.children.length||e===t?(this._levels[e].el.style.zIndex=i-Math.abs(t-e),this._onUpdateLevel(e)):(ut(this._levels[e].el),this._removeTilesAtZoom(e),this._onRemoveLevel(e),delete this._levels[e]);var n=this._levels[t],o=this._map;return n||((n=this._levels[t]={}).el=ht("div","leaflet-tile-container leaflet-zoom-animated",this._container),n.el.style.zIndex=i,n.origin=o.project(o.unproject(o.getPixelOrigin()),t).round(),n.zoom=t,this._setZoomTransform(n,o.getCenter(),o.getZoom()),n.el.offsetWidth,this._onCreateLevel(n)),this._level=n,n}},_onUpdateLevel:r,_onRemoveLevel:r,_onCreateLevel:r,_pruneTiles:function(){if(this._map){var t,i,e=this._map.getZoom();if(e>this.options.maxZoom||e<this.options.minZoom)this._removeAllTiles();else{for(t in this._tiles)(i=this._tiles[t]).retain=i.current;for(t in this._tiles)if((i=this._tiles[t]).current&&!i.active){var n=i.coords;this._retainParent(n.x,n.y,n.z,n.z-5)||this._retainChildren(n.x,n.y,n.z,n.z+2)}for(t in this._tiles)this._tiles[t].retain||this._removeTile(t)}}},_removeTilesAtZoom:function(t){for(var i in this._tiles)this._tiles[i].coords.z===t&&this._removeTile(i)},_removeAllTiles:function(){for(var t in this._tiles)this._removeTile(t)},_invalidateAll:function(){for(var t in this._levels)ut(this._levels[t].el),this._onRemoveLevel(t),delete this._levels[t];this._removeAllTiles(),this._tileZoom=void 0},_retainParent:function(t,i,e,n){var o=Math.floor(t/2),s=Math.floor(i/2),r=e-1,a=new x(+o,+s);a.z=+r;var h=this._tileCoordsToKey(a),u=this._tiles[h];return u&&u.active?(u.retain=!0,!0):(u&&u.loaded&&(u.retain=!0),r>n&&this._retainParent(o,s,r,n))},_retainChildren:function(t,i,e,n){for(var o=2*t;o<2*t+2;o++)for(var s=2*i;s<2*i+2;s++){var r=new x(o,s);r.z=e+1;var a=this._tileCoordsToKey(r),h=this._tiles[a];h&&h.active?h.retain=!0:(h&&h.loaded&&(h.retain=!0),e+1<n&&this._retainChildren(o,s,e+1,n))}},_resetView:function(t){var i=t&&(t.pinch||t.flyTo);this._setView(this._map.getCenter(),this._map.getZoom(),i,i)},_animateZoom:function(t){this._setView(t.center,t.zoom,!0,t.noUpdate)},_clampZoom:function(t){var i=this.options;return void 0!==i.minNativeZoom&&t<i.minNativeZoom?i.minNativeZoom:void 0!==i.maxNativeZoom&&i.maxNativeZoom<t?i.maxNativeZoom:t},_setView:function(t,i,e,n){var o=this._clampZoom(Math.round(i));(void 0!==this.options.maxZoom&&o>this.options.maxZoom||void 0!==this.options.minZoom&&o<this.options.minZoom)&&(o=void 0);var s=this.options.updateWhenZooming&&o!==this._tileZoom;n&&!s||(this._tileZoom=o,this._abortLoading&&this._abortLoading(),this._updateLevels(),this._resetGrid(),void 0!==o&&this._update(t),e||this._pruneTiles(),this._noPrune=!!e),this._setZoomTransforms(t,i)},_setZoomTransforms:function(t,i){for(var e in this._levels)this._setZoomTransform(this._levels[e],t,i)},_setZoomTransform:function(t,i,e){var n=this._map.getZoomScale(e,t.zoom),o=t.origin.multiplyBy(n).subtract(this._map._getNewPixelOrigin(i,e)).round();Ni?wt(t.el,o,n):Lt(t.el,o)},_resetGrid:function(){var t=this._map,i=t.options.crs,e=this._tileSize=this.getTileSize(),n=this._tileZoom,o=this._map.getPixelWorldBounds(this._tileZoom);o&&(this._globalTileRange=this._pxBoundsToTileRange(o)),this._wrapX=i.wrapLng&&!this.options.noWrap&&[Math.floor(t.project([0,i.wrapLng[0]],n).x/e.x),Math.ceil(t.project([0,i.wrapLng[1]],n).x/e.y)],this._wrapY=i.wrapLat&&!this.options.noWrap&&[Math.floor(t.project([i.wrapLat[0],0],n).y/e.x),Math.ceil(t.project([i.wrapLat[1],0],n).y/e.y)]},_onMoveEnd:function(){this._map&&!this._map._animatingZoom&&this._update()},_getTiledPixelBounds:function(t){var i=this._map,e=i._animatingZoom?Math.max(i._animateToZoom,i.getZoom()):i.getZoom(),n=i.getZoomScale(e,this._tileZoom),o=i.project(t,this._tileZoom).floor(),s=i.getSize().divideBy(2*n);return new P(o.subtract(s),o.add(s))},_update:function(t){var i=this._map;if(i){var e=this._clampZoom(i.getZoom());if(void 0===t&&(t=i.getCenter()),void 0!==this._tileZoom){var n=this._getTiledPixelBounds(t),o=this._pxBoundsToTileRange(n),s=o.getCenter(),r=[],a=this.options.keepBuffer,h=new P(o.getBottomLeft().subtract([a,-a]),o.getTopRight().add([a,-a]));if(!(isFinite(o.min.x)&&isFinite(o.min.y)&&isFinite(o.max.x)&&isFinite(o.max.y)))throw new Error("Attempted to load an infinite number of tiles");for(var u in this._tiles){var l=this._tiles[u].coords;l.z===this._tileZoom&&h.contains(new x(l.x,l.y))||(this._tiles[u].current=!1)}if(Math.abs(e-this._tileZoom)>1)this._setView(t,e);else{for(var c=o.min.y;c<=o.max.y;c++)for(var _=o.min.x;_<=o.max.x;_++){var d=new x(_,c);if(d.z=this._tileZoom,this._isValidTile(d)){var p=this._tiles[this._tileCoordsToKey(d)];p?p.current=!0:r.push(d)}}if(r.sort(function(t,i){return t.distanceTo(s)-i.distanceTo(s)}),0!==r.length){this._loading||(this._loading=!0,this.fire("loading"));var m=document.createDocumentFragment();for(_=0;_<r.length;_++)this._addTile(r[_],m);this._level.el.appendChild(m)}}}}},_isValidTile:function(t){var i=this._map.options.crs;if(!i.infinite){var e=this._globalTileRange;if(!i.wrapLng&&(t.x<e.min.x||t.x>e.max.x)||!i.wrapLat&&(t.y<e.min.y||t.y>e.max.y))return!1}if(!this.options.bounds)return!0;var n=this._tileCoordsToBounds(t);return z(this.options.bounds).overlaps(n)},_keyToBounds:function(t){return this._tileCoordsToBounds(this._keyToTileCoords(t))},_tileCoordsToNwSe:function(t){var i=this._map,e=this.getTileSize(),n=t.scaleBy(e),o=n.add(e);return[i.unproject(n,t.z),i.unproject(o,t.z)]},_tileCoordsToBounds:function(t){var i=this._tileCoordsToNwSe(t),e=new T(i[0],i[1]);return this.options.noWrap||(e=this._map.wrapLatLngBounds(e)),e},_tileCoordsToKey:function(t){return t.x+":"+t.y+":"+t.z},_keyToTileCoords:function(t){var i=t.split(":"),e=new x(+i[0],+i[1]);return e.z=+i[2],e},_removeTile:function(t){var i=this._tiles[t];i&&(Ci||i.el.setAttribute("src",ni),ut(i.el),delete this._tiles[t],this.fire("tileunload",{tile:i.el,coords:this._keyToTileCoords(t)}))},_initTile:function(t){pt(t,"leaflet-tile");var i=this.getTileSize();t.style.width=i.x+"px",t.style.height=i.y+"px",t.onselectstart=r,t.onmousemove=r,Li&&this.options.opacity<1&&vt(t,this.options.opacity),Ti&&!zi&&(t.style.WebkitBackfaceVisibility="hidden")},_addTile:function(t,i){var n=this._getTilePos(t),o=this._tileCoordsToKey(t),s=this.createTile(this._wrapCoords(t),e(this._tileReady,this,t));this._initTile(s),this.createTile.length<2&&f(e(this._tileReady,this,t,null,s)),Lt(s,n),this._tiles[o]={el:s,coords:t,current:!0},i.appendChild(s),this.fire("tileloadstart",{tile:s,coords:t})},_tileReady:function(t,i,n){if(this._map){i&&this.fire("tileerror",{error:i,tile:n,coords:t});var o=this._tileCoordsToKey(t);(n=this._tiles[o])&&(n.loaded=+new Date,this._map._fadeAnimated?(vt(n.el,0),g(this._fadeFrame),this._fadeFrame=f(this._updateOpacity,this)):(n.active=!0,this._pruneTiles()),i||(pt(n.el,"leaflet-tile-loaded"),this.fire("tileload",{tile:n.el,coords:t})),this._noTilesToLoad()&&(this._loading=!1,this.fire("load"),Li||!this._map._fadeAnimated?f(this._pruneTiles,this):setTimeout(e(this._pruneTiles,this),250)))}},_getTilePos:function(t){return t.scaleBy(this.getTileSize()).subtract(this._level.origin)},_wrapCoords:function(t){var i=new x(this._wrapX?s(t.x,this._wrapX):t.x,this._wrapY?s(t.y,this._wrapY):t.y);return i.z=t.z,i},_pxBoundsToTileRange:function(t){var i=this.getTileSize();return new P(t.min.unscaleBy(i).floor(),t.max.unscaleBy(i).ceil().subtract([1,1]))},_noTilesToLoad:function(){for(var t in this._tiles)if(!this._tiles[t].loaded)return!1;return!0}}),dn=_n.extend({options:{minZoom:0,maxZoom:18,subdomains:"abc",errorTileUrl:"",zoomOffset:0,tms:!1,zoomReverse:!1,detectRetina:!1,crossOrigin:!1},initialize:function(t,i){this._url=t,(i=l(this,i)).detectRetina&&Ki&&i.maxZoom>0&&(i.tileSize=Math.floor(i.tileSize/2),i.zoomReverse?(i.zoomOffset--,i.minZoom++):(i.zoomOffset++,i.maxZoom--),i.minZoom=Math.max(0,i.minZoom)),"string"==typeof i.subdomains&&(i.subdomains=i.subdomains.split("")),Ti||this.on("tileunload",this._onTileRemove)},setUrl:function(t,i){return this._url=t,i||this.redraw(),this},createTile:function(t,i){var n=document.createElement("img");return V(n,"load",e(this._tileOnLoad,this,i,n)),V(n,"error",e(this._tileOnError,this,i,n)),this.options.crossOrigin&&(n.crossOrigin=""),n.alt="",n.setAttribute("role","presentation"),n.src=this.getTileUrl(t),n},getTileUrl:function(t){var e={r:Ki?"@2x":"",s:this._getSubdomain(t),x:t.x,y:t.y,z:this._getZoomForUrl()};if(this._map&&!this._map.options.crs.infinite){var n=this._globalTileRange.max.y-t.y;this.options.tms&&(e.y=n),e["-y"]=n}return _(this._url,i(e,this.options))},_tileOnLoad:function(t,i){Li?setTimeout(e(t,this,null,i),0):t(null,i)},_tileOnError:function(t,i,e){var n=this.options.errorTileUrl;n&&i.getAttribute("src")!==n&&(i.src=n),t(e,i)},_onTileRemove:function(t){t.tile.onload=null},_getZoomForUrl:function(){var t=this._tileZoom,i=this.options.maxZoom,e=this.options.zoomReverse,n=this.options.zoomOffset;return e&&(t=i-t),t+n},_getSubdomain:function(t){var i=Math.abs(t.x+t.y)%this.options.subdomains.length;return this.options.subdomains[i]},_abortLoading:function(){var t,i;for(t in this._tiles)this._tiles[t].coords.z!==this._tileZoom&&((i=this._tiles[t].el).onload=r,i.onerror=r,i.complete||(i.src=ni,ut(i),delete this._tiles[t]))}}),pn=dn.extend({defaultWmsParams:{service:"WMS",request:"GetMap",layers:"",styles:"",format:"image/jpeg",transparent:!1,version:"1.1.1"},options:{crs:null,uppercase:!1},initialize:function(t,e){this._url=t;var n=i({},this.defaultWmsParams);for(var o in e)o in this.options||(n[o]=e[o]);var s=(e=l(this,e)).detectRetina&&Ki?2:1,r=this.getTileSize();n.width=r.x*s,n.height=r.y*s,this.wmsParams=n},onAdd:function(t){this._crs=this.options.crs||t.options.crs,this._wmsVersion=parseFloat(this.wmsParams.version);var i=this._wmsVersion>=1.3?"crs":"srs";this.wmsParams[i]=this._crs.code,dn.prototype.onAdd.call(this,t)},getTileUrl:function(t){var i=this._tileCoordsToNwSe(t),e=this._crs,n=b(e.project(i[0]),e.project(i[1])),o=n.min,s=n.max,r=(this._wmsVersion>=1.3&&this._crs===He?[o.y,o.x,s.y,s.x]:[o.x,o.y,s.x,s.y]).join(","),a=L.TileLayer.prototype.getTileUrl.call(this,t);return a+c(this.wmsParams,a,this.options.uppercase)+(this.options.uppercase?"&BBOX=":"&bbox=")+r},setParams:function(t,e){return i(this.wmsParams,t),e||this.redraw(),this}});dn.WMS=pn,Yt.wms=function(t,i){return new pn(t,i)};var mn=Ue.extend({options:{padding:.1,tolerance:0},initialize:function(t){l(this,t),n(this),this._layers=this._layers||{}},onAdd:function(){this._container||(this._initContainer(),this._zoomAnimated&&pt(this._container,"leaflet-zoom-animated")),this.getPane().appendChild(this._container),this._update(),this.on("update",this._updatePaths,this)},onRemove:function(){this.off("update",this._updatePaths,this),this._destroyContainer()},getEvents:function(){var t={viewreset:this._reset,zoom:this._onZoom,moveend:this._update,zoomend:this._onZoomEnd};return this._zoomAnimated&&(t.zoomanim=this._onAnimZoom),t},_onAnimZoom:function(t){this._updateTransform(t.center,t.zoom)},_onZoom:function(){this._updateTransform(this._map.getCenter(),this._map.getZoom())},_updateTransform:function(t,i){var e=this._map.getZoomScale(i,this._zoom),n=Pt(this._container),o=this._map.getSize().multiplyBy(.5+this.options.padding),s=this._map.project(this._center,i),r=this._map.project(t,i).subtract(s),a=o.multiplyBy(-e).add(n).add(o).subtract(r);Ni?wt(this._container,a,e):Lt(this._container,a)},_reset:function(){this._update(),this._updateTransform(this._center,this._zoom);for(var t in this._layers)this._layers[t]._reset()},_onZoomEnd:function(){for(var t in this._layers)this._layers[t]._project()},_updatePaths:function(){for(var t in this._layers)this._layers[t]._update()},_update:function(){var t=this.options.padding,i=this._map.getSize(),e=this._map.containerPointToLayerPoint(i.multiplyBy(-t)).round();this._bounds=new P(e,e.add(i.multiplyBy(1+2*t)).round()),this._center=this._map.getCenter(),this._zoom=this._map.getZoom()}}),fn=mn.extend({getEvents:function(){var t=mn.prototype.getEvents.call(this);return t.viewprereset=this._onViewPreReset,t},_onViewPreReset:function(){this._postponeUpdatePaths=!0},onAdd:function(){mn.prototype.onAdd.call(this),this._draw()},_initContainer:function(){var t=this._container=document.createElement("canvas");V(t,"mousemove",o(this._onMouseMove,32,this),this),V(t,"click dblclick mousedown mouseup contextmenu",this._onClick,this),V(t,"mouseout",this._handleMouseOut,this),this._ctx=t.getContext("2d")},_destroyContainer:function(){delete this._ctx,ut(this._container),q(this._container),delete this._container},_updatePaths:function(){if(!this._postponeUpdatePaths){this._redrawBounds=null;for(var t in this._layers)this._layers[t]._update();this._redraw()}},_update:function(){if(!this._map._animatingZoom||!this._bounds){this._drawnLayers={},mn.prototype._update.call(this);var t=this._bounds,i=this._container,e=t.getSize(),n=Ki?2:1;Lt(i,t.min),i.width=n*e.x,i.height=n*e.y,i.style.width=e.x+"px",i.style.height=e.y+"px",Ki&&this._ctx.scale(2,2),this._ctx.translate(-t.min.x,-t.min.y),this.fire("update")}},_reset:function(){mn.prototype._reset.call(this),this._postponeUpdatePaths&&(this._postponeUpdatePaths=!1,this._updatePaths())},_initPath:function(t){this._updateDashArray(t),this._layers[n(t)]=t;var i=t._order={layer:t,prev:this._drawLast,next:null};this._drawLast&&(this._drawLast.next=i),this._drawLast=i,this._drawFirst=this._drawFirst||this._drawLast},_addPath:function(t){this._requestRedraw(t)},_removePath:function(t){var i=t._order,e=i.next,n=i.prev;e?e.prev=n:this._drawLast=n,n?n.next=e:this._drawFirst=e,delete t._order,delete this._layers[L.stamp(t)],this._requestRedraw(t)},_updatePath:function(t){this._extendRedrawBounds(t),t._project(),t._update(),this._requestRedraw(t)},_updateStyle:function(t){this._updateDashArray(t),this._requestRedraw(t)},_updateDashArray:function(t){if(t.options.dashArray){var i,e=t.options.dashArray.split(","),n=[];for(i=0;i<e.length;i++)n.push(Number(e[i]));t.options._dashArray=n}},_requestRedraw:function(t){this._map&&(this._extendRedrawBounds(t),this._redrawRequest=this._redrawRequest||f(this._redraw,this))},_extendRedrawBounds:function(t){if(t._pxBounds){var i=(t.options.weight||0)+1;this._redrawBounds=this._redrawBounds||new P,this._redrawBounds.extend(t._pxBounds.min.subtract([i,i])),this._redrawBounds.extend(t._pxBounds.max.add([i,i]))}},_redraw:function(){this._redrawRequest=null,this._redrawBounds&&(this._redrawBounds.min._floor(),this._redrawBounds.max._ceil()),this._clear(),this._draw(),this._redrawBounds=null},_clear:function(){var t=this._redrawBounds;if(t){var i=t.getSize();this._ctx.clearRect(t.min.x,t.min.y,i.x,i.y)}else this._ctx.clearRect(0,0,this._container.width,this._container.height)},_draw:function(){var t,i=this._redrawBounds;if(this._ctx.save(),i){var e=i.getSize();this._ctx.beginPath(),this._ctx.rect(i.min.x,i.min.y,e.x,e.y),this._ctx.clip()}this._drawing=!0;for(var n=this._drawFirst;n;n=n.next)t=n.layer,(!i||t._pxBounds&&t._pxBounds.intersects(i))&&t._updatePath();this._drawing=!1,this._ctx.restore()},_updatePoly:function(t,i){if(this._drawing){var e,n,o,s,r=t._parts,a=r.length,h=this._ctx;if(a){for(this._drawnLayers[t._leaflet_id]=t,h.beginPath(),e=0;e<a;e++){for(n=0,o=r[e].length;n<o;n++)s=r[e][n],h[n?"lineTo":"moveTo"](s.x,s.y);i&&h.closePath()}this._fillStroke(h,t)}}},_updateCircle:function(t){if(this._drawing&&!t._empty()){var i=t._point,e=this._ctx,n=Math.max(Math.round(t._radius),1),o=(Math.max(Math.round(t._radiusY),1)||n)/n;this._drawnLayers[t._leaflet_id]=t,1!==o&&(e.save(),e.scale(1,o)),e.beginPath(),e.arc(i.x,i.y/o,n,0,2*Math.PI,!1),1!==o&&e.restore(),this._fillStroke(e,t)}},_fillStroke:function(t,i){var e=i.options;e.fill&&(t.globalAlpha=e.fillOpacity,t.fillStyle=e.fillColor||e.color,t.fill(e.fillRule||"evenodd")),e.stroke&&0!==e.weight&&(t.setLineDash&&t.setLineDash(i.options&&i.options._dashArray||[]),t.globalAlpha=e.opacity,t.lineWidth=e.weight,t.strokeStyle=e.color,t.lineCap=e.lineCap,t.lineJoin=e.lineJoin,t.stroke())},_onClick:function(t){for(var i,e,n=this._map.mouseEventToLayerPoint(t),o=this._drawFirst;o;o=o.next)(i=o.layer).options.interactive&&i._containsPoint(n)&&!this._map._draggableMoved(i)&&(e=i);e&&(et(t),this._fireEvent([e],t))},_onMouseMove:function(t){if(this._map&&!this._map.dragging.moving()&&!this._map._animatingZoom){var i=this._map.mouseEventToLayerPoint(t);this._handleMouseHover(t,i)}},_handleMouseOut:function(t){var i=this._hoveredLayer;i&&(mt(this._container,"leaflet-interactive"),this._fireEvent([i],t,"mouseout"),this._hoveredLayer=null)},_handleMouseHover:function(t,i){for(var e,n,o=this._drawFirst;o;o=o.next)(e=o.layer).options.interactive&&e._containsPoint(i)&&(n=e);n!==this._hoveredLayer&&(this._handleMouseOut(t),n&&(pt(this._container,"leaflet-interactive"),this._fireEvent([n],t,"mouseover"),this._hoveredLayer=n)),this._hoveredLayer&&this._fireEvent([this._hoveredLayer],t)},_fireEvent:function(t,i,e){this._map._fireDOMEvent(i,e||i.type,t)},_bringToFront:function(t){var i=t._order,e=i.next,n=i.prev;e&&(e.prev=n,n?n.next=e:e&&(this._drawFirst=e),i.prev=this._drawLast,this._drawLast.next=i,i.next=null,this._drawLast=i,this._requestRedraw(t))},_bringToBack:function(t){var i=t._order,e=i.next,n=i.prev;n&&(n.next=e,e?e.prev=n:n&&(this._drawLast=n),i.prev=null,i.next=this._drawFirst,this._drawFirst.prev=i,this._drawFirst=i,this._requestRedraw(t))}}),gn=function(){try{return document.namespaces.add("lvml","urn:schemas-microsoft-com:vml"),function(t){return document.createElement("<lvml:"+t+' class="lvml">')}}catch(t){return function(t){return document.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}}(),vn={_initContainer:function(){this._container=ht("div","leaflet-vml-container")},_update:function(){this._map._animatingZoom||(mn.prototype._update.call(this),this.fire("update"))},_initPath:function(t){var i=t._container=gn("shape");pt(i,"leaflet-vml-shape "+(this.options.className||"")),i.coordsize="1 1",t._path=gn("path"),i.appendChild(t._path),this._updateStyle(t),this._layers[n(t)]=t},_addPath:function(t){var i=t._container;this._container.appendChild(i),t.options.interactive&&t.addInteractiveTarget(i)},_removePath:function(t){var i=t._container;ut(i),t.removeInteractiveTarget(i),delete this._layers[n(t)]},_updateStyle:function(t){var i=t._stroke,e=t._fill,n=t.options,o=t._container;o.stroked=!!n.stroke,o.filled=!!n.fill,n.stroke?(i||(i=t._stroke=gn("stroke")),o.appendChild(i),i.weight=n.weight+"px",i.color=n.color,i.opacity=n.opacity,n.dashArray?i.dashStyle=ei(n.dashArray)?n.dashArray.join(" "):n.dashArray.replace(/( *, *)/g," "):i.dashStyle="",i.endcap=n.lineCap.replace("butt","flat"),i.joinstyle=n.lineJoin):i&&(o.removeChild(i),t._stroke=null),n.fill?(e||(e=t._fill=gn("fill")),o.appendChild(e),e.color=n.fillColor||n.color,e.opacity=n.fillOpacity):e&&(o.removeChild(e),t._fill=null)},_updateCircle:function(t){var i=t._point.round(),e=Math.round(t._radius),n=Math.round(t._radiusY||e);this._setPath(t,t._empty()?"M0 0":"AL "+i.x+","+i.y+" "+e+","+n+" 0,23592600")},_setPath:function(t,i){t._path.v=i},_bringToFront:function(t){ct(t._container)},_bringToBack:function(t){_t(t._container)}},yn=Ji?gn:E,xn=mn.extend({getEvents:function(){var t=mn.prototype.getEvents.call(this);return t.zoomstart=this._onZoomStart,t},_initContainer:function(){this._container=yn("svg"),this._container.setAttribute("pointer-events","none"),this._rootGroup=yn("g"),this._container.appendChild(this._rootGroup)},_destroyContainer:function(){ut(this._container),q(this._container),delete this._container,delete this._rootGroup,delete this._svgSize},_onZoomStart:function(){this._update()},_update:function(){if(!this._map._animatingZoom||!this._bounds){mn.prototype._update.call(this);var t=this._bounds,i=t.getSize(),e=this._container;this._svgSize&&this._svgSize.equals(i)||(this._svgSize=i,e.setAttribute("width",i.x),e.setAttribute("height",i.y)),Lt(e,t.min),e.setAttribute("viewBox",[t.min.x,t.min.y,i.x,i.y].join(" ")),this.fire("update")}},_initPath:function(t){var i=t._path=yn("path");t.options.className&&pt(i,t.options.className),t.options.interactive&&pt(i,"leaflet-interactive"),this._updateStyle(t),this._layers[n(t)]=t},_addPath:function(t){this._rootGroup||this._initContainer(),this._rootGroup.appendChild(t._path),t.addInteractiveTarget(t._path)},_removePath:function(t){ut(t._path),t.removeInteractiveTarget(t._path),delete this._layers[n(t)]},_updatePath:function(t){t._project(),t._update()},_updateStyle:function(t){var i=t._path,e=t.options;i&&(e.stroke?(i.setAttribute("stroke",e.color),i.setAttribute("stroke-opacity",e.opacity),i.setAttribute("stroke-width",e.weight),i.setAttribute("stroke-linecap",e.lineCap),i.setAttribute("stroke-linejoin",e.lineJoin),e.dashArray?i.setAttribute("stroke-dasharray",e.dashArray):i.removeAttribute("stroke-dasharray"),e.dashOffset?i.setAttribute("stroke-dashoffset",e.dashOffset):i.removeAttribute("stroke-dashoffset")):i.setAttribute("stroke","none"),e.fill?(i.setAttribute("fill",e.fillColor||e.color),i.setAttribute("fill-opacity",e.fillOpacity),i.setAttribute("fill-rule",e.fillRule||"evenodd")):i.setAttribute("fill","none"))},_updatePoly:function(t,i){this._setPath(t,k(t._parts,i))},_updateCircle:function(t){var i=t._point,e=Math.max(Math.round(t._radius),1),n="a"+e+","+(Math.max(Math.round(t._radiusY),1)||e)+" 0 1,0 ",o=t._empty()?"M0 0":"M"+(i.x-e)+","+i.y+n+2*e+",0 "+n+2*-e+",0 ";this._setPath(t,o)},_setPath:function(t,i){t._path.setAttribute("d",i)},_bringToFront:function(t){ct(t._path)},_bringToBack:function(t){_t(t._path)}});Ji&&xn.include(vn),Le.include({getRenderer:function(t){var i=t.options.renderer||this._getPaneRenderer(t.options.pane)||this.options.renderer||this._renderer;return i||(i=this._renderer=this.options.preferCanvas&&Xt()||Jt()),this.hasLayer(i)||this.addLayer(i),i},_getPaneRenderer:function(t){if("overlayPane"===t||void 0===t)return!1;var i=this._paneRenderers[t];return void 0===i&&(i=xn&&Jt({pane:t})||fn&&Xt({pane:t}),this._paneRenderers[t]=i),i}});var wn=en.extend({initialize:function(t,i){en.prototype.initialize.call(this,this._boundsToLatLngs(t),i)},setBounds:function(t){return this.setLatLngs(this._boundsToLatLngs(t))},_boundsToLatLngs:function(t){return t=z(t),[t.getSouthWest(),t.getNorthWest(),t.getNorthEast(),t.getSouthEast()]}});xn.create=yn,xn.pointsToPath=k,nn.geometryToLayer=Wt,nn.coordsToLatLng=Ht,nn.coordsToLatLngs=Ft,nn.latLngToCoords=Ut,nn.latLngsToCoords=Vt,nn.getFeature=qt,nn.asFeature=Gt,Le.mergeOptions({boxZoom:!0});var Ln=Ze.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane,this._resetStateTimeout=0,t.on("unload",this._destroy,this)},addHooks:function(){V(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){q(this._container,"mousedown",this._onMouseDown,this)},moved:function(){return this._moved},_destroy:function(){ut(this._pane),delete this._pane},_resetState:function(){this._resetStateTimeout=0,this._moved=!1},_clearDeferredResetState:function(){0!==this._resetStateTimeout&&(clearTimeout(this._resetStateTimeout),this._resetStateTimeout=0)},_onMouseDown:function(t){if(!t.shiftKey||1!==t.which&&1!==t.button)return!1;this._clearDeferredResetState(),this._resetState(),mi(),bt(),this._startPoint=this._map.mouseEventToContainerPoint(t),V(document,{contextmenu:Q,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseMove:function(t){this._moved||(this._moved=!0,this._box=ht("div","leaflet-zoom-box",this._container),pt(this._container,"leaflet-crosshair"),this._map.fire("boxzoomstart")),this._point=this._map.mouseEventToContainerPoint(t);var i=new P(this._point,this._startPoint),e=i.getSize();Lt(this._box,i.min),this._box.style.width=e.x+"px",this._box.style.height=e.y+"px"},_finish:function(){this._moved&&(ut(this._box),mt(this._container,"leaflet-crosshair")),fi(),Tt(),q(document,{contextmenu:Q,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseUp:function(t){if((1===t.which||1===t.button)&&(this._finish(),this._moved)){this._clearDeferredResetState(),this._resetStateTimeout=setTimeout(e(this._resetState,this),0);var i=new T(this._map.containerPointToLatLng(this._startPoint),this._map.containerPointToLatLng(this._point));this._map.fitBounds(i).fire("boxzoomend",{boxZoomBounds:i})}},_onKeyDown:function(t){27===t.keyCode&&this._finish()}});Le.addInitHook("addHandler","boxZoom",Ln),Le.mergeOptions({doubleClickZoom:!0});var Pn=Ze.extend({addHooks:function(){this._map.on("dblclick",this._onDoubleClick,this)},removeHooks:function(){this._map.off("dblclick",this._onDoubleClick,this)},_onDoubleClick:function(t){var i=this._map,e=i.getZoom(),n=i.options.zoomDelta,o=t.originalEvent.shiftKey?e-n:e+n;"center"===i.options.doubleClickZoom?i.setZoom(o):i.setZoomAround(t.containerPoint,o)}});Le.addInitHook("addHandler","doubleClickZoom",Pn),Le.mergeOptions({dragging:!0,inertia:!zi,inertiaDeceleration:3400,inertiaMaxSpeed:1/0,easeLinearity:.2,worldCopyJump:!1,maxBoundsViscosity:0});var bn=Ze.extend({addHooks:function(){if(!this._draggable){var t=this._map;this._draggable=new Be(t._mapPane,t._container),this._draggable.on({dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this),this._draggable.on("predrag",this._onPreDragLimit,this),t.options.worldCopyJump&&(this._draggable.on("predrag",this._onPreDragWrap,this),t.on("zoomend",this._onZoomEnd,this),t.whenReady(this._onZoomEnd,this))}pt(this._map._container,"leaflet-grab leaflet-touch-drag"),this._draggable.enable(),this._positions=[],this._times=[]},removeHooks:function(){mt(this._map._container,"leaflet-grab"),mt(this._map._container,"leaflet-touch-drag"),this._draggable.disable()},moved:function(){return this._draggable&&this._draggable._moved},moving:function(){return this._draggable&&this._draggable._moving},_onDragStart:function(){var t=this._map;if(t._stop(),this._map.options.maxBounds&&this._map.options.maxBoundsViscosity){var i=z(this._map.options.maxBounds);this._offsetLimit=b(this._map.latLngToContainerPoint(i.getNorthWest()).multiplyBy(-1),this._map.latLngToContainerPoint(i.getSouthEast()).multiplyBy(-1).add(this._map.getSize())),this._viscosity=Math.min(1,Math.max(0,this._map.options.maxBoundsViscosity))}else this._offsetLimit=null;t.fire("movestart").fire("dragstart"),t.options.inertia&&(this._positions=[],this._times=[])},_onDrag:function(t){if(this._map.options.inertia){var i=this._lastTime=+new Date,e=this._lastPos=this._draggable._absPos||this._draggable._newPos;this._positions.push(e),this._times.push(i),this._prunePositions(i)}this._map.fire("move",t).fire("drag",t)},_prunePositions:function(t){for(;this._positions.length>1&&t-this._times[0]>50;)this._positions.shift(),this._times.shift()},_onZoomEnd:function(){var t=this._map.getSize().divideBy(2),i=this._map.latLngToLayerPoint([0,0]);this._initialWorldOffset=i.subtract(t).x,this._worldWidth=this._map.getPixelWorldBounds().getSize().x},_viscousLimit:function(t,i){return t-(t-i)*this._viscosity},_onPreDragLimit:function(){if(this._viscosity&&this._offsetLimit){var t=this._draggable._newPos.subtract(this._draggable._startPos),i=this._offsetLimit;t.x<i.min.x&&(t.x=this._viscousLimit(t.x,i.min.x)),t.y<i.min.y&&(t.y=this._viscousLimit(t.y,i.min.y)),t.x>i.max.x&&(t.x=this._viscousLimit(t.x,i.max.x)),t.y>i.max.y&&(t.y=this._viscousLimit(t.y,i.max.y)),this._draggable._newPos=this._draggable._startPos.add(t)}},_onPreDragWrap:function(){var t=this._worldWidth,i=Math.round(t/2),e=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-i+e)%t+i-e,s=(n+i+e)%t-i-e,r=Math.abs(o+e)<Math.abs(s+e)?o:s;this._draggable._absPos=this._draggable._newPos.clone(),this._draggable._newPos.x=r},_onDragEnd:function(t){var i=this._map,e=i.options,n=!e.inertia||this._times.length<2;if(i.fire("dragend",t),n)i.fire("moveend");else{this._prunePositions(+new Date);var o=this._lastPos.subtract(this._positions[0]),s=(this._lastTime-this._times[0])/1e3,r=e.easeLinearity,a=o.multiplyBy(r/s),h=a.distanceTo([0,0]),u=Math.min(e.inertiaMaxSpeed,h),l=a.multiplyBy(u/h),c=u/(e.inertiaDeceleration*r),_=l.multiplyBy(-c/2).round();_.x||_.y?(_=i._limitOffset(_,i.options.maxBounds),f(function(){i.panBy(_,{duration:c,easeLinearity:r,noMoveStart:!0,animate:!0})})):i.fire("moveend")}}});Le.addInitHook("addHandler","dragging",bn),Le.mergeOptions({keyboard:!0,keyboardPanDelta:80});var Tn=Ze.extend({keyCodes:{left:[37],right:[39],down:[40],up:[38],zoomIn:[187,107,61,171],zoomOut:[189,109,54,173]},initialize:function(t){this._map=t,this._setPanDelta(t.options.keyboardPanDelta),this._setZoomDelta(t.options.zoomDelta)},addHooks:function(){var t=this._map._container;t.tabIndex<=0&&(t.tabIndex="0"),V(t,{focus:this._onFocus,blur:this._onBlur,mousedown:this._onMouseDown},this),this._map.on({focus:this._addHooks,blur:this._removeHooks},this)},removeHooks:function(){this._removeHooks(),q(this._map._container,{focus:this._onFocus,blur:this._onBlur,mousedown:this._onMouseDown},this),this._map.off({focus:this._addHooks,blur:this._removeHooks},this)},_onMouseDown:function(){if(!this._focused){var t=document.body,i=document.documentElement,e=t.scrollTop||i.scrollTop,n=t.scrollLeft||i.scrollLeft;this._map._container.focus(),window.scrollTo(n,e)}},_onFocus:function(){this._focused=!0,this._map.fire("focus")},_onBlur:function(){this._focused=!1,this._map.fire("blur")},_setPanDelta:function(t){var i,e,n=this._panKeys={},o=this.keyCodes;for(i=0,e=o.left.length;i<e;i++)n[o.left[i]]=[-1*t,0];for(i=0,e=o.right.length;i<e;i++)n[o.right[i]]=[t,0];for(i=0,e=o.down.length;i<e;i++)n[o.down[i]]=[0,t];for(i=0,e=o.up.length;i<e;i++)n[o.up[i]]=[0,-1*t]},_setZoomDelta:function(t){var i,e,n=this._zoomKeys={},o=this.keyCodes;for(i=0,e=o.zoomIn.length;i<e;i++)n[o.zoomIn[i]]=t;for(i=0,e=o.zoomOut.length;i<e;i++)n[o.zoomOut[i]]=-t},_addHooks:function(){V(document,"keydown",this._onKeyDown,this)},_removeHooks:function(){q(document,"keydown",this._onKeyDown,this)},_onKeyDown:function(t){if(!(t.altKey||t.ctrlKey||t.metaKey)){var i,e=t.keyCode,n=this._map;if(e in this._panKeys){if(n._panAnim&&n._panAnim._inProgress)return;i=this._panKeys[e],t.shiftKey&&(i=w(i).multiplyBy(3)),n.panBy(i),n.options.maxBounds&&n.panInsideBounds(n.options.maxBounds)}else if(e in this._zoomKeys)n.setZoom(n.getZoom()+(t.shiftKey?3:1)*this._zoomKeys[e]);else{if(27!==e||!n._popup||!n._popup.options.closeOnEscapeKey)return;n.closePopup()}Q(t)}}});Le.addInitHook("addHandler","keyboard",Tn),Le.mergeOptions({scrollWheelZoom:!0,wheelDebounceTime:40,wheelPxPerZoomLevel:60});var zn=Ze.extend({addHooks:function(){V(this._map._container,"mousewheel",this._onWheelScroll,this),this._delta=0},removeHooks:function(){q(this._map._container,"mousewheel",this._onWheelScroll,this)},_onWheelScroll:function(t){var i=it(t),n=this._map.options.wheelDebounceTime;this._delta+=i,this._lastMousePos=this._map.mouseEventToContainerPoint(t),this._startTime||(this._startTime=+new Date);var o=Math.max(n-(+new Date-this._startTime),0);clearTimeout(this._timer),this._timer=setTimeout(e(this._performZoom,this),o),Q(t)},_performZoom:function(){var t=this._map,i=t.getZoom(),e=this._map.options.zoomSnap||0;t._stop();var n=this._delta/(4*this._map.options.wheelPxPerZoomLevel),o=4*Math.log(2/(1+Math.exp(-Math.abs(n))))/Math.LN2,s=e?Math.ceil(o/e)*e:o,r=t._limitZoom(i+(this._delta>0?s:-s))-i;this._delta=0,this._startTime=null,r&&("center"===t.options.scrollWheelZoom?t.setZoom(i+r):t.setZoomAround(this._lastMousePos,i+r))}});Le.addInitHook("addHandler","scrollWheelZoom",zn),Le.mergeOptions({tap:!0,tapTolerance:15});var Mn=Ze.extend({addHooks:function(){V(this._map._container,"touchstart",this._onDown,this)},removeHooks:function(){q(this._map._container,"touchstart",this._onDown,this)},_onDown:function(t){if(t.touches){if($(t),this._fireClick=!0,t.touches.length>1)return this._fireClick=!1,void clearTimeout(this._holdTimeout);var i=t.touches[0],n=i.target;this._startPos=this._newPos=new x(i.clientX,i.clientY),n.tagName&&"a"===n.tagName.toLowerCase()&&pt(n,"leaflet-active"),this._holdTimeout=setTimeout(e(function(){this._isTapValid()&&(this._fireClick=!1,this._onUp(),this._simulateEvent("contextmenu",i))},this),1e3),this._simulateEvent("mousedown",i),V(document,{touchmove:this._onMove,touchend:this._onUp},this)}},_onUp:function(t){if(clearTimeout(this._holdTimeout),q(document,{touchmove:this._onMove,touchend:this._onUp},this),this._fireClick&&t&&t.changedTouches){var i=t.changedTouches[0],e=i.target;e&&e.tagName&&"a"===e.tagName.toLowerCase()&&mt(e,"leaflet-active"),this._simulateEvent("mouseup",i),this._isTapValid()&&this._simulateEvent("click",i)}},_isTapValid:function(){return this._newPos.distanceTo(this._startPos)<=this._map.options.tapTolerance},_onMove:function(t){var i=t.touches[0];this._newPos=new x(i.clientX,i.clientY),this._simulateEvent("mousemove",i)},_simulateEvent:function(t,i){var e=document.createEvent("MouseEvents");e._simulated=!0,i.target._simulatedClick=!0,e.initMouseEvent(t,!0,!0,window,1,i.screenX,i.screenY,i.clientX,i.clientY,!1,!1,!1,!1,0,null),i.target.dispatchEvent(e)}});Vi&&!Ui&&Le.addInitHook("addHandler","tap",Mn),Le.mergeOptions({touchZoom:Vi&&!zi,bounceAtZoomLimits:!0});var Cn=Ze.extend({addHooks:function(){pt(this._map._container,"leaflet-touch-zoom"),V(this._map._container,"touchstart",this._onTouchStart,this)},removeHooks:function(){mt(this._map._container,"leaflet-touch-zoom"),q(this._map._container,"touchstart",this._onTouchStart,this)},_onTouchStart:function(t){var i=this._map;if(t.touches&&2===t.touches.length&&!i._animatingZoom&&!this._zooming){var e=i.mouseEventToContainerPoint(t.touches[0]),n=i.mouseEventToContainerPoint(t.touches[1]);this._centerPoint=i.getSize()._divideBy(2),this._startLatLng=i.containerPointToLatLng(this._centerPoint),"center"!==i.options.touchZoom&&(this._pinchStartLatLng=i.containerPointToLatLng(e.add(n)._divideBy(2))),this._startDist=e.distanceTo(n),this._startZoom=i.getZoom(),this._moved=!1,this._zooming=!0,i._stop(),V(document,"touchmove",this._onTouchMove,this),V(document,"touchend",this._onTouchEnd,this),$(t)}},_onTouchMove:function(t){if(t.touches&&2===t.touches.length&&this._zooming){var i=this._map,n=i.mouseEventToContainerPoint(t.touches[0]),o=i.mouseEventToContainerPoint(t.touches[1]),s=n.distanceTo(o)/this._startDist;if(this._zoom=i.getScaleZoom(s,this._startZoom),!i.options.bounceAtZoomLimits&&(this._zoom<i.getMinZoom()&&s<1||this._zoom>i.getMaxZoom()&&s>1)&&(this._zoom=i._limitZoom(this._zoom)),"center"===i.options.touchZoom){if(this._center=this._startLatLng,1===s)return}else{var r=n._add(o)._divideBy(2)._subtract(this._centerPoint);if(1===s&&0===r.x&&0===r.y)return;this._center=i.unproject(i.project(this._pinchStartLatLng,this._zoom).subtract(r),this._zoom)}this._moved||(i._moveStart(!0,!1),this._moved=!0),g(this._animRequest);var a=e(i._move,i,this._center,this._zoom,{pinch:!0,round:!1});this._animRequest=f(a,this,!0),$(t)}},_onTouchEnd:function(){this._moved&&this._zooming?(this._zooming=!1,g(this._animRequest),q(document,"touchmove",this._onTouchMove),q(document,"touchend",this._onTouchEnd),this._map.options.zoomAnimation?this._map._animateZoom(this._center,this._map._limitZoom(this._zoom),!0,this._map.options.zoomSnap):this._map._resetView(this._center,this._map._limitZoom(this._zoom))):this._zooming=!1}});Le.addInitHook("addHandler","touchZoom",Cn),Le.BoxZoom=Ln,Le.DoubleClickZoom=Pn,Le.Drag=bn,Le.Keyboard=Tn,Le.ScrollWheelZoom=zn,Le.Tap=Mn,Le.TouchZoom=Cn;var Zn=window.L;window.L=t,Object.freeze=$t,t.version="1.3.1+HEAD.ba6f97f",t.noConflict=function(){return window.L=Zn,this},t.Control=Pe,t.control=be,t.Browser=$i,t.Evented=ui,t.Mixin=Ee,t.Util=ai,t.Class=v,t.Handler=Ze,t.extend=i,t.bind=e,t.stamp=n,t.setOptions=l,t.DomEvent=de,t.DomUtil=xe,t.PosAnimation=we,t.Draggable=Be,t.LineUtil=Oe,t.PolyUtil=Re,t.Point=x,t.point=w,t.Bounds=P,t.bounds=b,t.Transformation=Z,t.transformation=S,t.Projection=je,t.LatLng=M,t.latLng=C,t.LatLngBounds=T,t.latLngBounds=z,t.CRS=ci,t.GeoJSON=nn,t.geoJSON=Kt,t.geoJson=sn,t.Layer=Ue,t.LayerGroup=Ve,t.layerGroup=function(t,i){return new Ve(t,i)},t.FeatureGroup=qe,t.featureGroup=function(t){return new qe(t)},t.ImageOverlay=rn,t.imageOverlay=function(t,i,e){return new rn(t,i,e)},t.VideoOverlay=an,t.videoOverlay=function(t,i,e){return new an(t,i,e)},t.DivOverlay=hn,t.Popup=un,t.popup=function(t,i){return new un(t,i)},t.Tooltip=ln,t.tooltip=function(t,i){return new ln(t,i)},t.Icon=Ge,t.icon=function(t){return new Ge(t)},t.DivIcon=cn,t.divIcon=function(t){return new cn(t)},t.Marker=Xe,t.marker=function(t,i){return new Xe(t,i)},t.TileLayer=dn,t.tileLayer=Yt,t.GridLayer=_n,t.gridLayer=function(t){return new _n(t)},t.SVG=xn,t.svg=Jt,t.Renderer=mn,t.Canvas=fn,t.canvas=Xt,t.Path=Je,t.CircleMarker=$e,t.circleMarker=function(t,i){return new $e(t,i)},t.Circle=Qe,t.circle=function(t,i,e){return new Qe(t,i,e)},t.Polyline=tn,t.polyline=function(t,i){return new tn(t,i)},t.Polygon=en,t.polygon=function(t,i){return new en(t,i)},t.Rectangle=wn,t.rectangle=function(t,i){return new wn(t,i)},t.Map=Le,t.map=function(t,i){return new Le(t,i)}});
\ No newline at end of file
diff --git a/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/outdoor.html b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/outdoor.html
new file mode 100644
index 0000000..ce0e3ef
--- /dev/null
+++ b/bnd/org.eclipse.sensinact.studio.webapp.outdoor/webapp/outdoor.html
@@ -0,0 +1,74 @@
+<!--
+   Copyright (c) 2020 - 2021 Kentyou.
+   All rights reserved. This program and the accompanying materials
+   are made available under the terms of the Eclipse Public License v1.0
+   which accompanies this distribution, and is available at
+   http://www.eclipse.org/legal/epl-v10.html
+  
+   Contributors:
+      Kentyou - initial API and implementation
+-->
+<!DOCTYPE html>
+<html lang="en">
+	<head>
+		<meta charset="utf-8">
+		<meta name="viewport" content="width=device-width, initial-scale=1.0">
+
+		<title>Outdoor Map</title>
+		<link rel="stylesheet" href="css/leaflet.css" />
+		<link rel="stylesheet" href="css/custom.css" />
+		<style>
+			a[type=geoanchor] {
+			  background-color: #F79F81;
+			  color: gray;
+			  padding: 6px 10px;
+			  margin-left: 2px;
+			  border: none;
+			  border-radius: 4px;
+			  cursor: pointer;
+			  float: left;
+			}
+			
+			a[type=geoanchor-enabled] {
+			  background-color: #F79F81;
+			  color: white;
+			  padding: 6px 10px;
+			  margin-left: 2px;
+			  border: none;
+			  border-radius: 4px;
+			  cursor: pointer;
+			  float: left;
+			}
+			
+			a[type=geoanchor]:hover,a[type=geoanchor-enabled]:hover {
+			  background-color: #F5D0A9;
+			}
+	</style>
+	</head>
+	<body>
+		<div id="map" style="display:flex"></div>
+		<div id="geo_markers" style="display:table-row"></div>
+		<div style="display:table-row">
+		    <div id="plus" style="width:50%;left:5px;display:table-cell;">
+		        <a id="plus_button"><image src="css/images/plus_.png" style="width:20px;height:20px;"/></a>
+		    </div>
+		    <div id="less" style="width:50%;left:5px;display:none;">
+		        <a id="less_button"><image src="css/images/moins_.png" style="width:20px;height:20px;"/></a>
+		    </div>
+		</div>
+		<div id="geo_extra" style="display:none;">
+			<div style="display:inline">
+				<input id="geodef_name" type="text" style="width:80%"/>			
+				<a id="validator"><image src="css/images/validation.png" style="width:20px;height:20px;"/></a>
+			</div>
+			<div style="display:inline">
+				<textarea id="geodef" rows="5" cols="150"></textarea>
+			</div>
+		</div>
+		<div id="notif"><a href="javascript:window.location.reload()">reload view</a></div>
+		<div id="image"></div>
+		<script src="js/jquery-2.2.0.min.js"></script>
+		<script src="js/leaflet.js"></script>
+		<script src="js/custom.js"></script>
+	</body>
+</html>
diff --git a/bnd/settings.gradle b/bnd/settings.gradle
new file mode 100644
index 0000000..8872fbc
--- /dev/null
+++ b/bnd/settings.gradle
@@ -0,0 +1,13 @@
+pluginManagement {
+  plugins {
+    id 'biz.aQute.bnd.workspace' version bnd_version
+  }
+  repositories {
+    maven { url bnd_snapshots }
+    mavenCentral()
+    gradlePluginPortal()
+  }
+}
+plugins {
+  id 'biz.aQute.bnd.workspace'
+}