diff --git a/.github/stale.yml b/.github/stale.yml new file mode 100644 index 00000000000..9cbd495b143 --- /dev/null +++ b/.github/stale.yml @@ -0,0 +1,15 @@ +# Number of days of inactivity before an issue becomes stale +daysUntilStale: 10 +# Don't close isssues or pulls +daysUntilClose: false +# Issues with these labels will never be considered stale +exemptLabels: + - Resolution/Postponed +# Label to use when marking an issue as stale +staleLabel: Resolution/Stale +# Comment to post when marking an issue as stale. Set to `false` to disable +markComment: > + This issue has been automatically marked as stale because it has not had + recent activity. +# Comment to post when closing a stale issue. Set to `false` to disable +closeComment: false diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.annotations/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.annotations/pom.xml index 4a903cf6cca..01ea40d9da0 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.annotations/pom.xml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.annotations/pom.xml @@ -22,13 +22,13 @@ apimgt-extensions org.wso2.carbon.devicemgt - 3.0.217-SNAPSHOT + 3.1.34-SNAPSHOT ../pom.xml 4.0.0 org.wso2.carbon.apimgt.annotations - 3.0.217-SNAPSHOT + 3.1.34-SNAPSHOT bundle WSO2 Carbon - API Management Annotations WSO2 Carbon - API Management Custom Annotation Module diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/pom.xml index 7f1c19bc737..c6969f29b14 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/pom.xml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension.api/pom.xml @@ -21,12 +21,12 @@ apimgt-extensions org.wso2.carbon.devicemgt - 3.0.217-SNAPSHOT + 3.1.34-SNAPSHOT ../pom.xml 4.0.0 - 3.0.217-SNAPSHOT + 3.1.34-SNAPSHOT org.wso2.carbon.apimgt.application.extension.api war WSO2 Carbon - API Application Management API diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/pom.xml index fdb9f1a0166..2194b0ae8a8 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/pom.xml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/pom.xml @@ -22,12 +22,12 @@ apimgt-extensions org.wso2.carbon.devicemgt - 3.0.217-SNAPSHOT + 3.1.34-SNAPSHOT ../pom.xml 4.0.0 - 3.0.217-SNAPSHOT + 3.1.34-SNAPSHOT org.wso2.carbon.apimgt.application.extension bundle WSO2 Carbon - API Application Management diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderServiceImpl.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderServiceImpl.java index 7f3def1ccda..487177ed613 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderServiceImpl.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.application.extension/src/main/java/org/wso2/carbon/apimgt/application/extension/APIManagementProviderServiceImpl.java @@ -129,6 +129,7 @@ public class APIManagementProviderServiceImpl implements APIManagementProviderSe for (APIInfo apiInfo : apiList.getList()) { String id = apiInfo.getProvider().replace("@", "-AT-") + "-" + apiInfo.getName() + "-" + apiInfo.getVersion(); + id = id.replace(" ", "+"); boolean subscriptionExist = false; if (subscriptionList.getList() != null && subscriptionList.getList().size() > 0) { for (Subscription subs : subscriptionList.getList()) { diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/pom.xml index 8acc92772d6..aa8d4afcd2d 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/pom.xml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/pom.xml @@ -21,13 +21,13 @@ apimgt-extensions org.wso2.carbon.devicemgt - 3.0.217-SNAPSHOT + 3.1.34-SNAPSHOT ../pom.xml 4.0.0 org.wso2.carbon.apimgt.handlers - 3.0.217-SNAPSHOT + 3.1.34-SNAPSHOT bundle WSO2 Carbon - API Security Handler Component WSO2 Carbon - API Management Security Handler Module @@ -140,4 +140,4 @@ - \ No newline at end of file + diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/iot-api-config.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/iot-api-config.xml index ed61a4a1151..bb8e00495de 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/iot-api-config.xml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/main/resources/iot-api-config.xml @@ -29,7 +29,7 @@ admin - https://${iot.keymanager.host}:${iot.keymanager.https.port}/client-registration/v0.11/register + https://${iot.keymanager.host}:${iot.keymanager.https.port}/client-registration/v0.12/register https://${iot.keymanager.host}:${iot.keymanager.https.port}/oauth2/token diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/java/org/wso2/carbon/apimgt/handlers/IOTServerConfigurationTest.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/java/org/wso2/carbon/apimgt/handlers/IOTServerConfigurationTest.java index 84ebc863659..1b7a88dd3b4 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/java/org/wso2/carbon/apimgt/handlers/IOTServerConfigurationTest.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/java/org/wso2/carbon/apimgt/handlers/IOTServerConfigurationTest.java @@ -47,7 +47,7 @@ public class IOTServerConfigurationTest extends BaseAPIHandlerTest { Assert.assertEquals(serverConfiguration.getUsername(), "testuser"); Assert.assertEquals(serverConfiguration.getPassword(), "testuserpwd"); Assert.assertEquals(serverConfiguration.getDynamicClientRegistrationEndpoint(), - "https://${iot.keymanager.host}:${iot.keymanager.https.port}/client-registration/v0.11/register"); + "https://${iot.keymanager.host}:${iot.keymanager.https.port}/client-registration/v0.12/register"); Assert.assertEquals(serverConfiguration.getOauthTokenEndpoint(), "https://${iot.keymanager.host}:${iot.keymanager.https.port}/oauth2/token"); Assert.assertEquals(serverConfiguration.getApis().size(), 1); @@ -87,7 +87,7 @@ public class IOTServerConfigurationTest extends BaseAPIHandlerTest { Assert.assertEquals(serverConfiguration.getPassword(), "testuserpwd"); Assert.assertEquals(serverConfiguration.getDynamicClientRegistrationEndpoint(), "https://" + TestUtils.IOT_KEYMANAGER_HOST + ":" + TestUtils.IOT_KEYMANAGER_PORT - + "/client-registration/v0.11/register"); + + "/client-registration/v0.12/register"); Assert.assertEquals(serverConfiguration.getOauthTokenEndpoint(), "https://" + TestUtils.IOT_KEYMANAGER_HOST + ":" + TestUtils.IOT_KEYMANAGER_PORT + "/oauth2/token"); diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/resources/carbon-home/repository/conf/iot-api-config-invalid-xml.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/resources/carbon-home/repository/conf/iot-api-config-invalid-xml.xml index b7519e99ac3..25110b26a67 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/resources/carbon-home/repository/conf/iot-api-config-invalid-xml.xml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/resources/carbon-home/repository/conf/iot-api-config-invalid-xml.xml @@ -29,7 +29,7 @@ testuserpwd - https://${iot.keymanager.host}:${iot.keymanager.https.port}/client-registration/v0.11/register + https://${iot.keymanager.host}:${iot.keymanager.https.port}/client-registration/v0.12/register https://${iot.keymanager.host}:${iot.keymanager.https.port}/oauth2/token diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/resources/carbon-home/repository/conf/iot-api-config-invalid.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/resources/carbon-home/repository/conf/iot-api-config-invalid.xml index 9951e7b98e3..67ffc7fd8c8 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/resources/carbon-home/repository/conf/iot-api-config-invalid.xml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/resources/carbon-home/repository/conf/iot-api-config-invalid.xml @@ -29,7 +29,7 @@ testuserpwd - https://${iot.keymanager.host}:${iot.keymanager.https.port}/client-registration/v0.11/register + https://${iot.keymanager.host}:${iot.keymanager.https.port}/client-registration/v0.12/register https://${iot.keymanager.host}:${iot.keymanager.https.port}/oauth2/token diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/resources/carbon-home/repository/conf/iot-api-config.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/resources/carbon-home/repository/conf/iot-api-config.xml index fcb53bd009e..73af43c45f9 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/resources/carbon-home/repository/conf/iot-api-config.xml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.handlers/src/test/resources/carbon-home/repository/conf/iot-api-config.xml @@ -29,7 +29,7 @@ testuserpwd - https://${iot.keymanager.host}:${iot.keymanager.https.port}/client-registration/v0.11/register + https://${iot.keymanager.host}:${iot.keymanager.https.port}/client-registration/v0.12/register https://${iot.keymanager.host}:${iot.keymanager.https.port}/oauth2/token diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/pom.xml index cf751f15953..7fb37938edc 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/pom.xml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/pom.xml @@ -13,13 +13,13 @@ apimgt-extensions org.wso2.carbon.devicemgt - 3.0.217-SNAPSHOT + 3.1.34-SNAPSHOT ../pom.xml 4.0.0 org.wso2.carbon.apimgt.integration.client - 3.0.217-SNAPSHOT + 3.1.34-SNAPSHOT bundle WSO2 Carbon - API Management Integration Client WSO2 Carbon - API Management Integration Client @@ -72,10 +72,20 @@ javax.xml, org.wso2.carbon.base, javax.net.ssl, + org.apache.commons.lang, + android.util;resolution:=optional, + javax.annotation;resolution:=optional, + javax.net;resolution:=optional, + javax.security.auth.x500;resolution:=optional, + javax.crypto;resolution:=optional, + javax.crypto.spec;resolution:=optional jsr311-api, - feign-jaxrs + feign-jaxrs, + feign-okhttp, + okhttp, + okio @@ -110,6 +120,18 @@ + + com.squareup.okhttp3 + okhttp + + + com.squareup.okio + okio + + + io.github.openfeign + feign-okhttp + org.wso2.carbon org.wso2.carbon.logging diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/OAuthRequestInterceptor.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/OAuthRequestInterceptor.java index b4bc9106869..4bf28755094 100755 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/OAuthRequestInterceptor.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/OAuthRequestInterceptor.java @@ -22,6 +22,7 @@ import feign.auth.BasicAuthRequestInterceptor; import feign.gson.GsonDecoder; import feign.gson.GsonEncoder; import feign.jaxrs.JAXRSContract; +import feign.okhttp.OkHttpClient; import feign.slf4j.Slf4jLogger; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -65,8 +66,9 @@ public class OAuthRequestInterceptor implements RequestInterceptor { public OAuthRequestInterceptor() { String username = APIMConfigReader.getInstance().getConfig().getUsername(); String password = APIMConfigReader.getInstance().getConfig().getPassword(); - dcrClient = Feign.builder().client(Utils.getSSLClient()).logger(new Slf4jLogger()).logLevel( - Logger.Level.FULL).requestInterceptor(new BasicAuthRequestInterceptor(username, password)) + dcrClient = Feign.builder().client(new OkHttpClient(Utils.getSSLClient())).logger(new Slf4jLogger()) + .logLevel(Logger.Level.FULL).requestInterceptor(new BasicAuthRequestInterceptor(username, + password)) .contract(new JAXRSContract()).encoder(new GsonEncoder()).decoder(new GsonDecoder()) .target(DCRClient.class, Utils.replaceProperties( APIMConfigReader.getInstance().getConfig().getDcrEndpoint())); diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/publisher/PublisherClient.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/publisher/PublisherClient.java index 5ce49b7e83a..3887d59c661 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/publisher/PublisherClient.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/publisher/PublisherClient.java @@ -22,6 +22,7 @@ import feign.Logger; import feign.RequestInterceptor; import feign.gson.GsonDecoder; import feign.gson.GsonEncoder; +import feign.okhttp.OkHttpClient; import feign.slf4j.Slf4jLogger; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -35,12 +36,13 @@ import org.wso2.carbon.core.util.Utils; public class PublisherClient { private static final Log log = LogFactory.getLog(PublisherClient.class); - private APIsApi api = null; - private APIDocumentApi document = null; - private ApplicationsApi application = null; - private EnvironmentsApi environments = null; - private SubscriptionsApi subscriptions = null; - private TiersApi tiers = null; + private APIIndividualApi api = null; + private APICollectionApi apis = null; + private DocumentIndividualApi document = null; + private ApplicationIndividualApi application = null; + private EnvironmentCollectionApi environments = null; + private SubscriptionCollectionApi subscriptions = null; + private ThrottlingTierCollectionApi tiers = null; /** @@ -48,41 +50,47 @@ public class PublisherClient { * */ public PublisherClient(RequestInterceptor requestInterceptor) { - Feign.Builder builder = Feign.builder().client( - org.wso2.carbon.apimgt.integration.client.util.Utils.getSSLClient()).logger(new Slf4jLogger()) + Feign.Builder builder = Feign.builder().client(new OkHttpClient( + org.wso2.carbon.apimgt.integration.client.util.Utils.getSSLClient())).logger(new + Slf4jLogger()) .logLevel(Logger.Level.FULL) .requestInterceptor(requestInterceptor).encoder(new GsonEncoder()).decoder(new GsonDecoder()); String basePath = Utils.replaceSystemProperty(APIMConfigReader.getInstance().getConfig().getPublisherEndpoint()); - api = builder.target(APIsApi.class, basePath); - document = builder.target(APIDocumentApi.class, basePath); - application = builder.target(ApplicationsApi.class, basePath); - environments = builder.target(EnvironmentsApi.class, basePath); - subscriptions = builder.target(SubscriptionsApi.class, basePath); - tiers = builder.target(TiersApi.class, basePath); + api = builder.target(APIIndividualApi.class, basePath); + apis = builder.target(APICollectionApi.class, basePath); + document = builder.target(DocumentIndividualApi.class, basePath); + application = builder.target(ApplicationIndividualApi.class, basePath); + environments = builder.target(EnvironmentCollectionApi.class, basePath); + subscriptions = builder.target(SubscriptionCollectionApi.class, basePath); + tiers = builder.target(ThrottlingTierCollectionApi.class, basePath); } - public APIsApi getApi() { + public APIIndividualApi getApi() { return api; } - public APIDocumentApi getDocument() { + public APICollectionApi getApis() { + return apis; + } + + public DocumentIndividualApi getDocument() { return document; } - public ApplicationsApi getApplication() { + public ApplicationIndividualApi getApplication() { return application; } - public EnvironmentsApi getEnvironments() { + public EnvironmentCollectionApi getEnvironments() { return environments; } - public SubscriptionsApi getSubscriptions() { + public SubscriptionCollectionApi getSubscriptions() { return subscriptions; } - public TiersApi getTiers() { + public ThrottlingTierCollectionApi getTiers() { return tiers; } } diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/store/StoreClient.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/store/StoreClient.java index 19633fa009d..db751f204e8 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/store/StoreClient.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/store/StoreClient.java @@ -24,6 +24,7 @@ import feign.RequestInterceptor; import feign.Retryer; import feign.gson.GsonDecoder; import feign.gson.GsonEncoder; +import feign.okhttp.OkHttpClient; import feign.slf4j.Slf4jLogger; import org.apache.commons.logging.LogFactory; import org.wso2.carbon.apimgt.integration.client.configs.APIMConfigReader; @@ -52,8 +53,9 @@ public class StoreClient { public StoreClient(RequestInterceptor requestInterceptor) { - Feign.Builder builder = Feign.builder().client( - org.wso2.carbon.apimgt.integration.client.util.Utils.getSSLClient()).logger(new Slf4jLogger()) + Feign.Builder builder = Feign.builder().client(new OkHttpClient( + org.wso2.carbon.apimgt.integration.client.util.Utils.getSSLClient())).logger(new + Slf4jLogger()) .logLevel(Logger.Level.FULL) .requestInterceptor(requestInterceptor).encoder(new GsonEncoder()).decoder(new GsonDecoder()); String basePath = Utils.replaceSystemProperty(APIMConfigReader.getInstance().getConfig().getStoreEndpoint()); diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/util/Utils.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/util/Utils.java index 3474d836bd3..85004efd691 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/util/Utils.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.client/src/main/java/org/wso2/carbon/apimgt/integration/client/util/Utils.java @@ -18,24 +18,38 @@ package org.wso2.carbon.apimgt.integration.client.util; +import okhttp3.OkHttpClient; +import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.base.ServerConfiguration; -import feign.Client; - -import javax.net.ssl.*; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocketFactory; +import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; +import javax.net.ssl.X509TrustManager; import java.io.FileInputStream; -import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStream; -import java.security.*; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.ProxySelector; +import java.net.SocketAddress; +import java.net.URI; +import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; +import java.security.NoSuchAlgorithmException; +import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; +import java.util.ArrayList; +import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; -import feign.Logger; -import feign.Request; -import feign.Response; -import org.apache.commons.logging.Log; -import org.apache.commons.logging.LogFactory; -import org.wso2.carbon.base.ServerConfiguration; public class Utils { @@ -57,6 +71,10 @@ public class Utils { private static final String SSLV3 = "SSLv3"; + private static final String DEFAULT_HOST = "localhost"; + + private static final String DEFAULT_HOST_IP = "127.0.0.1"; + //This method is only used if the mb features are within DAS. public static String replaceProperties(String text) { @@ -73,17 +91,68 @@ public class Utils { return text; } - public static Client getSSLClient() { - boolean isIgnoreHostnameVerification = Boolean.parseBoolean(System.getProperty("org.wso2.ignoreHostnameVerification")); - if(isIgnoreHostnameVerification) { - return new Client.Default(getSimpleTrustedSSLSocketFactory(), new HostnameVerifier() { - @Override - public boolean verify(String s, SSLSession sslSession) { - return true; + public static OkHttpClient getSSLClient() { + + boolean isIgnoreHostnameVerification = Boolean.parseBoolean(System.getProperty("org.wso2" + + ".ignoreHostnameVerification")); + OkHttpClient okHttpClient; + final String proxyHost = System.getProperty("http.proxyHost"); + final String proxyPort = System.getProperty("http.proxyPort"); + final String nonProxyHostsValue = System.getProperty("http.nonProxyHosts"); + + final ProxySelector proxySelector = new ProxySelector() { + @Override + public java.util.List select(URI uri) { + List proxyList = new ArrayList<>(); + String host = uri.getHost(); + + if (!StringUtils.isEmpty(host)) { + if (host.startsWith(DEFAULT_HOST_IP) || host.startsWith(DEFAULT_HOST) || StringUtils + .isEmpty(nonProxyHostsValue) || StringUtils.contains(nonProxyHostsValue, host) || + StringUtils.isEmpty(proxyHost) || StringUtils.isEmpty(proxyPort)) { + proxyList.add(Proxy.NO_PROXY); + } else { + proxyList.add(new Proxy(Proxy.Type.HTTP, + new InetSocketAddress(proxyHost, Integer.parseInt(proxyPort)))); + } + } else { + log.error("Host is null. Host could not be empty or null"); } - }); + return proxyList; + } + + @Override + public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { + throw new UnsupportedOperationException("Not supported yet."); + } + }; + + X509TrustManager trustAllCerts = new X509TrustManager() { + public java.security.cert.X509Certificate[] getAcceptedIssuers() { + return new java.security.cert.X509Certificate[0]; + } + public void checkClientTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + public void checkServerTrusted( + java.security.cert.X509Certificate[] certs, String authType) { + } + }; + if(isIgnoreHostnameVerification) { + okHttpClient = new OkHttpClient.Builder() + .sslSocketFactory(getSimpleTrustedSSLSocketFactory(), trustAllCerts) + .hostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String s, SSLSession sslSession) { + return true; + } + }).proxySelector(proxySelector).build(); + return okHttpClient; }else { - return new Client.Default(getTrustedSSLSocketFactory(), null); + SSLSocketFactory trustedSSLSocketFactory = getTrustedSSLSocketFactory(); + okHttpClient = new OkHttpClient.Builder().sslSocketFactory(trustedSSLSocketFactory) + .proxySelector(proxySelector).build(); + return okHttpClient; } } diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/pom.xml index d0c406c0ff3..c76eff78383 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/pom.xml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/pom.xml @@ -13,13 +13,13 @@ apimgt-extensions org.wso2.carbon.devicemgt - 3.0.217-SNAPSHOT + 3.1.34-SNAPSHOT ../pom.xml 4.0.0 org.wso2.carbon.apimgt.integration.generated.client - 3.0.217-SNAPSHOT + 3.1.34-SNAPSHOT bundle WSO2 Carbon - API Management Integration Generated Client WSO2 Carbon - API Management Integration Client diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/src/main/resources/publisher-api.yaml b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/src/main/resources/publisher-api.yaml index e2d97583426..b2068857a76 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/src/main/resources/publisher-api.yaml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/src/main/resources/publisher-api.yaml @@ -1,15 +1,15 @@ + swagger: '2.0' ###################################################### # Prolog ###################################################### info: - version: "0.10.0" + version: "0.12.0" title: "WSO2 API Manager - Publisher API" description: | - This document specifies a **RESTful API** for WSO2 **API Manager** - Publisher. - - It is written with [swagger 2](http://swagger.io/). + This specifies a **RESTful API** for WSO2 **API Manager** - Publisher. + Please see [full swagger definition](https://raw.githubusercontent.com/wso2/carbon-apimgt/v6.1.66/components/apimgt/org.wso2.carbon.apimgt.rest.api.publisher/src/main/resources/publisher-api.yaml) of the API which is written using [swagger 2.0](http://swagger.io/) specification. contact: name: "WSO2" url: "http://wso2.com/products/api-manager/" @@ -33,7 +33,7 @@ host: apis.wso2.com # The base path of the API. # Will be prefixed to all paths. -basePath: /api/am/publisher/v0.10 +basePath: /api/am/publisher/v0.12 # The following media types can be passed as input in message bodies of the API. # The actual media type must be specified in the Content-Type header field of the request. @@ -84,6 +84,15 @@ x-wso2-security: roles: admin name: apim:subscription_block key: apim:subscription_block + - description: "" + roles: admin + name: apim:mediation_policy_view + key: apim:mediation_policy_view + - description: "" + roles: admin + name: apim:api_workflow + key: apim:api_workflow + ###################################################### # The "API Collection" resource APIs @@ -96,12 +105,17 @@ paths: #----------------------------------------------------- get: x-scope: apim:api_view - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" http://127.0.0.1:9763/api/am/publisher/v0.10/apis" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" https://localhost:9443/api/am/publisher/v0.12/apis" + x-wso2-request: | + GET https://localhost:9443/api/am/publisher/v0.12/apis + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"previous\": \"\",\n \"list\": [\n {\n \"provider\": \"admin\",\n \"version\": \"1.0.0\",\n \"description\": \"This sample API provides Account Status Validation\",\n \"name\": \"AccountVal\",\n \"context\": \"/account\",\n \"id\": \"2e81f147-c8a8-4f68-b4f0-69e0e7510b01\",\n \"status\": \"PUBLISHED\"\n },\n {\n \"provider\": \"admin\",\n \"version\": \"1.0.0\",\n \"description\": null,\n \"name\": \"api1\",\n \"context\": \"/api1\",\n \"id\": \"3e22d2fb-277a-4e9e-8c7e-1c0f7f73960e\",\n \"status\": \"PUBLISHED\"\n }\n ],\n \"next\": \"\",\n \"count\": 2\n}" summary: | - Get all APIs + Retrieve/Search APIs description: | - Get a list of available APIs qualifying under a given search condition. + This operation provides you a list of available APIs qualifying under a given search condition. + + Each retrieved API is represented with a minimal amount of attributes. If you want to get complete details of an API, you need to use **Get details of an API** operation. parameters: - $ref : '#/parameters/limit' - $ref : '#/parameters/offset' @@ -110,20 +124,27 @@ paths: description: | **Search condition**. - You can search in attributes by using an **"attribute:"** modifier. + You can search in attributes by using an **":"** modifier. + + Eg. + "provider:wso2" will match an API if the provider of the API is exactly "wso2". + + Additionally you can use wildcards. - Eg. "provider:wso2" will match an API if the provider of the API contains "wso2". + Eg. + "provider:wso2*" will match an API if the provider of the API starts with "wso2". Supported attribute modifiers are [**version, context, status, description, subcontext, doc, provider**] - If no advanced attribute modifier has been specified, search will match the - given query string against API Name. + If no advanced attribute modifier has been specified, the API names containing + the search term will be returned as a result. + type: string - $ref : "#/parameters/Accept" - $ref : "#/parameters/If-None-Match" tags: - - APIs + - API (Collection) responses: 200: description: | @@ -137,12 +158,12 @@ paths: type: string ETag: description: | - Entity Tag of the response resource. Used by caches, or in conditional requests. + Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future). type: string 304: description: | Not Modified. - Empty body because the client has already the latest version of the requested resource. + Empty body because the client has already the latest version of the requested resource (Will be supported in future). 406: description: | Not Acceptable. @@ -151,16 +172,18 @@ paths: $ref: '#/definitions/Error' #----------------------------------------------------- -# Create a new API +# Create a new API -API (Individual) #----------------------------------------------------- post: x-scope: apim:api_create - x-wso2-curl: "curl -H \"Authorization: Bearer 40e486e50ce43407181fb4c570d2cac7\" -H \"Content-Type: application/json\" -X POST -d @data.json http://127.0.0.1:9763/api/am/publisher/v0.10/apis" - x-wso2-request: "{\n \"sequences\": [],\n \"tiers\": [\n \"Bronze\",\n \"Gold\"\n ],\n \"thumbnailUrl\": null,\n \"visibility\": \"PUBLIC\",\n \"visibleRoles\": [],\n \"visibleTenants\": [],\n \"cacheTimeout\": 300,\n \"endpointConfig\": \"{\\\"production_endpoints\\\":{\\\"url\\\":\\\" http://ws.cdyne.com/phoneverify/phoneverify.asmx\\\",\\\"config\\\":null},\\\"endpoint_type\\\":\\\"http\\\"}\",\n \"subscriptionAvailability\": null,\n \"subscriptionAvailableTenants\": [],\n \"destinationStatsEnabled\": \"Disabled\",\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"\\/*\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"responses\\\":{\\\"200\\\":{\\\"description\\\":\\\"OK\\\"}}}}},\\\"x-wso2-security\\\":{\\\"apim\\\":{\\\"x-wso2-scopes\\\":[]}},\\\"swagger\\\":\\\"2.0\\\",\\\"info\\\":{\\\"title\\\":\\\"PhoneVerification\\\",\\\"description\\\":\\\"Verify a phone number\\\",\\\"contact\\\":{\\\"email\\\":\\\"xx@ee.com\\\",\\\"name\\\":\\\"xx\\\"},\\\"version\\\":\\\"1.0.0\\\"}}\",\n \"responseCaching\": \"Disabled\",\n \"isDefaultVersion\": true,\n \"gatewayEnvironments\": \"Production and Sandbox\",\n \"businessInformation\": {\n \"technicalOwner\": \"xx\",\n \"technicalOwnerEmail\": \"ggg@ww.com\",\n \"businessOwner\": \"xx\",\n \"businessOwnerEmail\": \"xx@ee.com\"\n },\n \"transport\": [\n \"http\",\n \"https\"\n ],\n \"tags\": [\n \"phone\",\n \"multimedia\",\n \"mobile\"\n ],\n \"provider\": \"admin\",\n \"version\": \"1.0.0\",\n \"description\": \"Verify a phone number\",\n \"name\": \"PhoneVerification\",\n \"context\": \"/phoneverify\"\n}" - x-wso2-response: "HTTP/1.1 201 Created\nLocation: http://localhost:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b\nContent-Type: application/json\n\n{\n \"sequences\": [],\n \"tiers\": [\n \"Bronze\",\n \"Gold\"\n ],\n \"thumbnailUrl\": null,\n \"visibility\": \"PUBLIC\",\n \"visibleRoles\": [],\n \"visibleTenants\": [],\n \"cacheTimeout\": 300,\n \"endpointConfig\": \"{\\\"production_endpoints\\\":{\\\"url\\\":\\\" http://ws.cdyne.com/phoneverify/phoneverify.asmx\\\",\\\"config\\\":null},\\\"endpoint_type\\\":\\\"http\\\"}\",\n \"subscriptionAvailability\": null,\n \"subscriptionAvailableTenants\": [],\n \"destinationStatsEnabled\": \"Disabled\",\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"\\/*\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"responses\\\":{\\\"200\\\":{\\\"description\\\":\\\"OK\\\"}}}}},\\\"x-wso2-security\\\":{\\\"apim\\\":{\\\"x-wso2-scopes\\\":[]}},\\\"swagger\\\":\\\"2.0\\\",\\\"info\\\":{\\\"title\\\":\\\"PhoneVerification\\\",\\\"description\\\":\\\"Verify a phone number\\\",\\\"contact\\\":{\\\"email\\\":\\\"xx@ee.com\\\",\\\"name\\\":\\\"xx\\\"},\\\"version\\\":\\\"1.0.0\\\"}}\",\n \"responseCaching\": \"Disabled\",\n \"isDefaultVersion\": true,\n \"gatewayEnvironments\": \"Production and Sandbox\",\n \"businessInformation\": {\n \"technicalOwner\": \"xx\",\n \"technicalOwnerEmail\": \"ggg@ww.com\",\n \"businessOwner\": \"xx\",\n \"businessOwnerEmail\": \"xx@ee.com\"\n },\n \"transport\": [\n \"http\",\n \"https\"\n ],\n \"tags\": [\n \"phone\",\n \"multimedia\",\n \"mobile\"\n ],\n \"provider\": \"admin\",\n \"version\": \"1.0.0\",\n \"description\": \"Verify a phone number\",\n \"name\": \"PhoneVerification\",\n \"context\": \"/phoneverify\",\n \"id\": \"890a4f4d-09eb-4877-a323-57f6ce2ed79b\",\n \"status\": \"CREATED\"\n}" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -H \"Content-Type: application/json\" -X POST -d @data.json https://localhost:9443/api/am/publisher/v0.12/apis" + x-wso2-request: "POST https://localhost:9443/api/am/publisher/v0.12/apis\nAuthorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\n\n{\r\n \"name\": \"PizzaShackAPI\",\r\n \"description\": \"This document describe a RESTFul API for Pizza Shack online pizza delivery store.\\r\\n\",\r\n \"context\": \"/pizzashack\",\r\n \"version\": \"1.0.0\",\r\n \"provider\": \"admin\",\r\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"/order\\\":{\\\"post\\\":{\\\"x-auth-type\\\":\\\"Application & Application User\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"description\\\":\\\"Create a new Order\\\",\\\"parameters\\\":[{\\\"schema\\\":{\\\"$ref\\\":\\\"#/definitions/Order\\\"},\\\"description\\\":\\\"Order object that needs to be added\\\",\\\"name\\\":\\\"body\\\",\\\"required\\\":true,\\\"in\\\":\\\"body\\\"}],\\\"responses\\\":{\\\"201\\\":{\\\"headers\\\":{\\\"Location\\\":{\\\"description\\\":\\\"The URL of the newly created resource.\\\",\\\"type\\\":\\\"string\\\"}},\\\"schema\\\":{\\\"$ref\\\":\\\"#/definitions/Order\\\"},\\\"description\\\":\\\"Created.\\\"}}}},\\\"/menu\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application & Application User\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"description\\\":\\\"Return a list of available menu items\\\",\\\"parameters\\\":[],\\\"responses\\\":{\\\"200\\\":{\\\"headers\\\":{},\\\"schema\\\":{\\\"title\\\":\\\"Menu\\\",\\\"properties\\\":{\\\"list\\\":{\\\"items\\\":{\\\"$ref\\\":\\\"#/definitions/MenuItem\\\"},\\\"type\\\":\\\"array\\\"}},\\\"type\\\":\\\"object\\\"},\\\"description\\\":\\\"OK.\\\"}}}}},\\\"schemes\\\":[\\\"https\\\"],\\\"produces\\\":[\\\"application/json\\\"],\\\"swagger\\\":\\\"2.0\\\",\\\"definitions\\\":{\\\"MenuItem\\\":{\\\"title\\\":\\\"Pizza menu Item\\\",\\\"properties\\\":{\\\"price\\\":{\\\"type\\\":\\\"string\\\"},\\\"description\\\":{\\\"type\\\":\\\"string\\\"},\\\"name\\\":{\\\"type\\\":\\\"string\\\"},\\\"image\\\":{\\\"type\\\":\\\"string\\\"}},\\\"required\\\":[\\\"name\\\"]},\\\"Order\\\":{\\\"title\\\":\\\"Pizza Order\\\",\\\"properties\\\":{\\\"customerName\\\":{\\\"type\\\":\\\"string\\\"},\\\"delivered\\\":{\\\"type\\\":\\\"boolean\\\"},\\\"address\\\":{\\\"type\\\":\\\"string\\\"},\\\"pizzaType\\\":{\\\"type\\\":\\\"string\\\"},\\\"creditCardNumber\\\":{\\\"type\\\":\\\"string\\\"},\\\"quantity\\\":{\\\"type\\\":\\\"number\\\"},\\\"orderId\\\":{\\\"type\\\":\\\"string\\\"}},\\\"required\\\":[\\\"orderId\\\"]}},\\\"consumes\\\":[\\\"application/json\\\"],\\\"info\\\":{\\\"title\\\":\\\"PizzaShackAPI\\\",\\\"description\\\":\\\"This document describe a RESTFul API for Pizza Shack online pizza delivery store.\\\\n\\\",\\\"license\\\":{\\\"name\\\":\\\"Apache 2.0\\\",\\\"url\\\":\\\"http://www.apache.org/licenses/LICENSE-2.0.html\\\"},\\\"contact\\\":{\\\"email\\\":\\\"architecture@pizzashack.com\\\",\\\"name\\\":\\\"John Doe\\\",\\\"url\\\":\\\"http://www.pizzashack.com\\\"},\\\"version\\\":\\\"1.0.0\\\"}}\",\r\n \"wsdlUri\": null,\r\n \"status\": \"PUBLISHED\",\r\n \"responseCaching\": \"Disabled\",\r\n \"cacheTimeout\": 300,\r\n \"destinationStatsEnabled\": false,\r\n \"isDefaultVersion\": false,\r\n \"type\": \"HTTP\",\r\n \"transport\": [\r\n \"http\",\r\n \"https\"\r\n ],\r\n \"tags\": [\"pizza\"],\r\n \"tiers\": [\"Unlimited\"],\r\n \"maxTps\": {\r\n \"sandbox\": 5000,\r\n \"production\": 1000\r\n },\r\n \"visibility\": \"PUBLIC\",\r\n \"visibleRoles\": [],\\r\n \"endpointConfig\": \"{\\\"production_endpoints\\\":{\\\"url\\\":\\\"https://localhost:9443/am/sample/pizzashack/v1/api/\\\",\\\"config\\\":null},\\\"sandbox_endpoints\\\":{\\\"url\\\":\\\"https://localhost:9443/am/sample/pizzashack/v1/api/\\\",\\\"config\\\":null},\\\"endpoint_type\\\":\\\"http\\\"}\",\r\n \"endpointSecurity\": {\r\n \"username\": \"user\",\r\n \"type\": \"basic\",\r\n \"password\": \"pass\"\r\n },\r\n \"gatewayEnvironments\": \"Production and Sandbox\",\r\n \"sequences\": [{\"name\":\"json_validator\",\"type\": \"in\"},{\"name\":\"log_out_message\",\"type\": \"out\"}],\r\n \"subscriptionAvailability\": null,\r\n \"subscriptionAvailableTenants\": [],\r\n \"businessInformation\": {\r\n \"businessOwnerEmail\": \"marketing@pizzashack.com\",\r\n \"technicalOwnerEmail\": \"architecture@pizzashack.com\",\r\n \"technicalOwner\": \"John Doe\",\r\n \"businessOwner\": \"Jane Roe\"\r\n },\r\n \"corsConfiguration\": {\r\n \"accessControlAllowOrigins\": [\"*\"],\r\n \"accessControlAllowHeaders\": [\r\n \"authorization\",\r\n \"Access-Control-Allow-Origin\",\r\n \"Content-Type\",\r\n \"SOAPAction\"\r\n ],\r\n \"accessControlAllowMethods\": [\r\n \"GET\",\r\n \"PUT\",\r\n \"POST\",\r\n \"DELETE\",\r\n \"PATCH\",\r\n \"OPTIONS\"\r\n ],\r\n \"accessControlAllowCredentials\": false,\r\n \"corsConfigurationEnabled\": false\r\n }\r\n}" + x-wso2-response: "HTTP/1.1 201 Created\nLocation: https://localhost:9443/api/am/publisher/v0.12/apis/7a2298c4-c905-403f-8fac-38c73301631f\nContent-Type: application/json\n\n{\r\n \"id\": \"7a2298c4-c905-403f-8fac-38c73301631f\",\r\n \"name\": \"PizzaShackAPI\",\r\n \"description\": \"This document describe a RESTFul API for Pizza Shack online pizza delivery store.\\r\\n\",\r\n \"context\": \"/pizzashack\",\r\n \"version\": \"1.0.0\",\r\n \"provider\": \"admin\",\r\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"/order\\\":{\\\"post\\\":{\\\"x-auth-type\\\":\\\"Application & Application User\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"description\\\":\\\"Create a new Order\\\",\\\"parameters\\\":[{\\\"schema\\\":{\\\"$ref\\\":\\\"#/definitions/Order\\\"},\\\"description\\\":\\\"Order object that needs to be added\\\",\\\"name\\\":\\\"body\\\",\\\"required\\\":true,\\\"in\\\":\\\"body\\\"}],\\\"responses\\\":{\\\"201\\\":{\\\"headers\\\":{\\\"Location\\\":{\\\"description\\\":\\\"The URL of the newly created resource.\\\",\\\"type\\\":\\\"string\\\"}},\\\"schema\\\":{\\\"$ref\\\":\\\"#/definitions/Order\\\"},\\\"description\\\":\\\"Created.\\\"}}}},\\\"/menu\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application & Application User\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"description\\\":\\\"Return a list of available menu items\\\",\\\"parameters\\\":[],\\\"responses\\\":{\\\"200\\\":{\\\"headers\\\":{},\\\"schema\\\":{\\\"title\\\":\\\"Menu\\\",\\\"properties\\\":{\\\"list\\\":{\\\"items\\\":{\\\"$ref\\\":\\\"#/definitions/MenuItem\\\"},\\\"type\\\":\\\"array\\\"}},\\\"type\\\":\\\"object\\\"},\\\"description\\\":\\\"OK.\\\"}}}}},\\\"schemes\\\":[\\\"https\\\"],\\\"produces\\\":[\\\"application/json\\\"],\\\"swagger\\\":\\\"2.0\\\",\\\"definitions\\\":{\\\"MenuItem\\\":{\\\"title\\\":\\\"Pizza menu Item\\\",\\\"properties\\\":{\\\"price\\\":{\\\"type\\\":\\\"string\\\"},\\\"description\\\":{\\\"type\\\":\\\"string\\\"},\\\"name\\\":{\\\"type\\\":\\\"string\\\"},\\\"image\\\":{\\\"type\\\":\\\"string\\\"}},\\\"required\\\":[\\\"name\\\"]},\\\"Order\\\":{\\\"title\\\":\\\"Pizza Order\\\",\\\"properties\\\":{\\\"customerName\\\":{\\\"type\\\":\\\"string\\\"},\\\"delivered\\\":{\\\"type\\\":\\\"boolean\\\"},\\\"address\\\":{\\\"type\\\":\\\"string\\\"},\\\"pizzaType\\\":{\\\"type\\\":\\\"string\\\"},\\\"creditCardNumber\\\":{\\\"type\\\":\\\"string\\\"},\\\"quantity\\\":{\\\"type\\\":\\\"number\\\"},\\\"orderId\\\":{\\\"type\\\":\\\"integer\\\"}},\\\"required\\\":[\\\"orderId\\\"]}},\\\"consumes\\\":[\\\"application/json\\\"],\\\"info\\\":{\\\"title\\\":\\\"PizzaShackAPI\\\",\\\"description\\\":\\\"This document describe a RESTFul API for Pizza Shack online pizza delivery store.\\\\n\\\",\\\"license\\\":{\\\"name\\\":\\\"Apache 2.0\\\",\\\"url\\\":\\\"http://www.apache.org/licenses/LICENSE-2.0.html\\\"},\\\"contact\\\":{\\\"email\\\":\\\"architecture@pizzashack.com\\\",\\\"name\\\":\\\"John Doe\\\",\\\"url\\\":\\\"http://www.pizzashack.com\\\"},\\\"version\\\":\\\"1.0.0\\\"}}\",\r\n \"wsdlUri\": null,\r\n \"responseCaching\": \"Disabled\",\r\n \"cacheTimeout\": 300,\r\n \"destinationStatsEnabled\": null,\r\n \"isDefaultVersion\": false,\r\n \"type\": \"HTTP\",\r\n \"transport\": [\r\n \"http\",\r\n \"https\"\r\n ],\r\n \"tags\": [\"pizza\"],\r\n \"tiers\": [\"Unlimited\"],\r\n \"maxTps\": {\r\n \"sandbox\": 5000,\r\n \"production\": 1000\r\n },\r\n \"thumbnailUri\": null,\r\n \"visibility\": \"PUBLIC\",\r\n \"visibleRoles\": [],\\r\n \"endpointConfig\": \"{\\\"production_endpoints\\\":{\\\"url\\\":\\\"https://localhost:9443/am/sample/pizzashack/v1/api/\\\",\\\"config\\\":null},\\\"sandbox_endpoints\\\":{\\\"url\\\":\\\"https://localhost:9443/am/sample/pizzashack/v1/api/\\\",\\\"config\\\":null},\\\"endpoint_type\\\":\\\"http\\\"}\",\r\n \"endpointSecurity\": {\r\n \"username\": \"user\",\r\n \"type\": \"basic\",\r\n \"password\": \"pass\"\r\n },\r\n \"gatewayEnvironments\": \"Production and Sandbox\",\r\n \"sequences\": [{\"name\":\"json_validator\",\"type\":\"in\",\"id\":\"142ece76-b208-4aab-b29a-f382045ed066\",\"shared\":false},{\"name\":\"log_out_message\",\"type\":\"out\",\"id\":\"b3527be8-95e6-41e0-8097-3276987b7d4b\",\"shared\":false}],\r\n \"subscriptionAvailability\": null,\r\n \"subscriptionAvailableTenants\": [],\r\n \"businessInformation\": {\r\n \"businessOwnerEmail\": \"marketing@pizzashack.com\",\r\n \"technicalOwnerEmail\": \"architecture@pizzashack.com\",\r\n \"technicalOwner\": \"John Doe\",\r\n \"businessOwner\": \"Jane Roe\"\r\n },\r\n \"corsConfiguration\": {\r\n \"accessControlAllowOrigins\": [\"*\"],\r\n \"accessControlAllowHeaders\": [\r\n \"authorization\",\r\n \"Access-Control-Allow-Origin\",\r\n \"Content-Type\",\r\n \"SOAPAction\"\r\n ],\r\n \"accessControlAllowMethods\": [\r\n \"GET\",\r\n \"PUT\",\r\n \"POST\",\r\n \"DELETE\",\r\n \"PATCH\",\r\n \"OPTIONS\"\r\n ],\r\n \"accessControlAllowCredentials\": false,\r\n \"corsConfigurationEnabled\": false\r\n }\r\n}" summary: Create a new API description: | - Create a new API + This operation can be used to create a new API specifying the details of the API in the payload. The new API will be in `CREATED` state. + + There is a special capability for a user who has `APIM Admin` permission such that he can create APIs on behalf of other users. For that he can to specify `"provider" : "some_other_user"` in the payload so that the API's creator will be shown as `some_other_user` in the UI. parameters: - in: body name: body @@ -170,8 +193,9 @@ paths: schema: $ref: '#/definitions/API' - $ref: '#/parameters/Content-Type' + - $ref: '#/parameters/Authorization' tags: - - APIs + - API (Individual) responses: 201: description: | @@ -189,9 +213,13 @@ paths: description: | The content type of the body. type: string + Authorization: + description: | + The brearer token. + type: string ETag: description: | - Entity Tag of the response resource. Used by caches, or in conditional request + Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future). type: string 400: description: | @@ -216,18 +244,21 @@ paths: #----------------------------------------------------- get: x-scope: apim:api_view - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" http://127.0.0.1:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b" - x-wso2-response: "HTTP/1.1 200 OK\nDate: Mon, 22 Feb 2016 13:27:08 GMT\nContent-Type: application/json\nTransfer-Encoding: chunked\nServer: WSO2 Carbon Server\n\n{\n \"sequences\": [],\n \"tiers\": [\n \"Bronze\",\n \"Gold\"\n ],\n \"thumbnailUrl\": null,\n \"visibility\": \"PUBLIC\",\n \"visibleRoles\": [],\n \"visibleTenants\": [],\n \"cacheTimeout\": 300,\n \"endpointConfig\": \"{\\\"production_endpoints\\\":{\\\"url\\\":\\\" http://ws.cdyne.com/phoneverify/phoneverify.asmx\\\",\\\"config\\\":null},\\\"endpoint_type\\\":\\\"http\\\"}\",\n \"subscriptionAvailability\": null,\n \"subscriptionAvailableTenants\": [],\n \"destinationStatsEnabled\": \"Disabled\",\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"\\/*\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"responses\\\":{\\\"200\\\":{\\\"description\\\":\\\"OK\\\"}}}}},\\\"x-wso2-security\\\":{\\\"apim\\\":{\\\"x-wso2-scopes\\\":[]}},\\\"swagger\\\":\\\"2.0\\\",\\\"info\\\":{\\\"title\\\":\\\"PhoneVerification\\\",\\\"description\\\":\\\"Verify a phone number\\\",\\\"contact\\\":{\\\"email\\\":\\\"xx@ee.com\\\",\\\"name\\\":\\\"xx\\\"},\\\"version\\\":\\\"1.0.0\\\"}}\",\n \"responseCaching\": \"Disabled\",\n \"isDefaultVersion\": false,\n \"gatewayEnvironments\": \"Production and Sandbox\",\n \"businessInformation\": {\n \"technicalOwner\": \"xx\",\n \"technicalOwnerEmail\": \"ggg@ww.com\",\n \"businessOwner\": \"xx\",\n \"businessOwnerEmail\": \"xx@ee.com\"\n },\n \"transport\": [\n \"http\",\n \"https\"\n ],\n \"tags\": [\n \"phone\",\n \"multimedia\",\n \"mobile\"\n ],\n \"provider\": \"admin\",\n \"version\": \"1.0.0\",\n \"description\": \"Verify a phone number\",\n \"name\": \"PhoneVerification\",\n \"context\": \"/phoneverify\",\n \"id\": \"890a4f4d-09eb-4877-a323-57f6ce2ed79b\",\n \"status\": \"PUBLISHED\"\n}" - summary: Get API details + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" https://localhost:9443/api/am/publisher/v0.12/apis/7a2298c4-c905-403f-8fac-38c73301631f" + x-wso2-request: | + GET https://localhost:9443/api/am/publisher/v0.12/apis/7a2298c4-c905-403f-8fac-38c73301631f + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\r\n \"id\": \"7a2298c4-c905-403f-8fac-38c73301631f\",\r\n \"name\": \"PizzaShackAPI\",\r\n \"description\": \"This document describe a RESTFul API for Pizza Shack online pizza delivery store.\\r\\n\",\r\n \"context\": \"/pizzashack\",\r\n \"version\": \"1.0.0\",\r\n \"provider\": \"admin\",\r\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"/order\\\":{\\\"post\\\":{\\\"x-auth-type\\\":\\\"Application & Application User\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"description\\\":\\\"Create a new Order\\\",\\\"parameters\\\":[{\\\"schema\\\":{\\\"$ref\\\":\\\"#/definitions/Order\\\"},\\\"description\\\":\\\"Order object that needs to be added\\\",\\\"name\\\":\\\"body\\\",\\\"required\\\":true,\\\"in\\\":\\\"body\\\"}],\\\"responses\\\":{\\\"201\\\":{\\\"headers\\\":{\\\"Location\\\":{\\\"description\\\":\\\"The URL of the newly created resource.\\\",\\\"type\\\":\\\"string\\\"}},\\\"schema\\\":{\\\"$ref\\\":\\\"#/definitions/Order\\\"},\\\"description\\\":\\\"Created.\\\"}}}},\\\"/menu\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application & Application User\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"description\\\":\\\"Return a list of available menu items\\\",\\\"parameters\\\":[],\\\"responses\\\":{\\\"200\\\":{\\\"headers\\\":{},\\\"schema\\\":{\\\"title\\\":\\\"Menu\\\",\\\"properties\\\":{\\\"list\\\":{\\\"items\\\":{\\\"$ref\\\":\\\"#/definitions/MenuItem\\\"},\\\"type\\\":\\\"array\\\"}},\\\"type\\\":\\\"object\\\"},\\\"description\\\":\\\"OK.\\\"}}}}},\\\"schemes\\\":[\\\"https\\\"],\\\"produces\\\":[\\\"application/json\\\"],\\\"swagger\\\":\\\"2.0\\\",\\\"definitions\\\":{\\\"MenuItem\\\":{\\\"title\\\":\\\"Pizza menu Item\\\",\\\"properties\\\":{\\\"price\\\":{\\\"type\\\":\\\"string\\\"},\\\"description\\\":{\\\"type\\\":\\\"string\\\"},\\\"name\\\":{\\\"type\\\":\\\"string\\\"},\\\"image\\\":{\\\"type\\\":\\\"string\\\"}},\\\"required\\\":[\\\"name\\\"]},\\\"Order\\\":{\\\"title\\\":\\\"Pizza Order\\\",\\\"properties\\\":{\\\"customerName\\\":{\\\"type\\\":\\\"string\\\"},\\\"delivered\\\":{\\\"type\\\":\\\"boolean\\\"},\\\"address\\\":{\\\"type\\\":\\\"string\\\"},\\\"pizzaType\\\":{\\\"type\\\":\\\"string\\\"},\\\"creditCardNumber\\\":{\\\"type\\\":\\\"string\\\"},\\\"quantity\\\":{\\\"type\\\":\\\"number\\\"},\\\"orderId\\\":{\\\"type\\\":\\\"string\\\"}},\\\"required\\\":[\\\"orderId\\\"]}},\\\"consumes\\\":[\\\"application/json\\\"],\\\"info\\\":{\\\"title\\\":\\\"PizzaShackAPI\\\",\\\"description\\\":\\\"This document describe a RESTFul API for Pizza Shack online pizza delivery store.\\\\n\\\",\\\"license\\\":{\\\"name\\\":\\\"Apache 2.0\\\",\\\"url\\\":\\\"http://www.apache.org/licenses/LICENSE-2.0.html\\\"},\\\"contact\\\":{\\\"email\\\":\\\"architecture@pizzashack.com\\\",\\\"name\\\":\\\"John Doe\\\",\\\"url\\\":\\\"http://www.pizzashack.com\\\"},\\\"version\\\":\\\"1.0.0\\\"}}\",\r\n \"wsdlUri\": null,\r\n \"status\": \"CREATED\",\r\n \"responseCaching\": \"Disabled\",\r\n \"cacheTimeout\": 300,\r\n \"destinationStatsEnabled\": null,\r\n \"isDefaultVersion\": false,\r\n \"type\": \"HTTP\",\r\n \"transport\": [\r\n \"http\",\r\n \"https\"\r\n ],\r\n \"tags\": [\"pizza\"],\r\n \"tiers\": [\"Unlimited\"],\r\n \"maxTps\": {\r\n \"sandbox\": 5000,\r\n \"production\": 1000\r\n },\r\n \"thumbnailUri\": null,\r\n \"visibility\": \"PUBLIC\",\r\n \"visibleRoles\": [],\\r\n \"endpointConfig\": \"{\\\"production_endpoints\\\":{\\\"url\\\":\\\"https://localhost:9443/am/sample/pizzashack/v1/api/\\\",\\\"config\\\":null},\\\"sandbox_endpoints\\\":{\\\"url\\\":\\\"https://localhost:9443/am/sample/pizzashack/v1/api/\\\",\\\"config\\\":null},\\\"endpoint_type\\\":\\\"http\\\"}\",\r\n \"endpointSecurity\": {\r\n \"username\": \"user\",\r\n \"type\": \"basic\",\r\n \"password\": \"pass\"\r\n },\r\n \"gatewayEnvironments\": \"Production and Sandbox\",\r\n \"sequences\": [],\r\n \"subscriptionAvailability\": null,\r\n \"subscriptionAvailableTenants\": [],\r\n \"businessInformation\": {\r\n \"businessOwnerEmail\": \"marketing@pizzashack.com\",\r\n \"technicalOwnerEmail\": \"architecture@pizzashack.com\",\r\n \"technicalOwner\": \"John Doe\",\r\n \"businessOwner\": \"Jane Roe\"\r\n },\r\n \"corsConfiguration\": {\r\n \"accessControlAllowOrigins\": [\"*\"],\r\n \"accessControlAllowHeaders\": [\r\n \"authorization\",\r\n \"Access-Control-Allow-Origin\",\r\n \"Content-Type\",\r\n \"SOAPAction\"\r\n ],\r\n \"accessControlAllowMethods\": [\r\n \"GET\",\r\n \"PUT\",\r\n \"POST\",\r\n \"DELETE\",\r\n \"PATCH\",\r\n \"OPTIONS\"\r\n ],\r\n \"accessControlAllowCredentials\": false,\r\n \"corsConfigurationEnabled\": false\r\n }\r\n}" + summary: Get details of an API description: | - Get details of an API + Using this operation, you can retrieve complete details of a single API. You need to provide the Id of the API to retrive it. parameters: - $ref: '#/parameters/apiId' - $ref: '#/parameters/Accept' - $ref: '#/parameters/If-None-Match' - $ref: '#/parameters/If-Modified-Since' tags: - - APIs + - API (Individual) responses: 200: description: | @@ -240,19 +271,19 @@ paths: type: string ETag: description: | - Entity Tag of the response resource. Used by caches, or in conditional requests. + Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future). type: string Last-Modified: description: | Date and time the resource has been modifed the last time. - Used by caches, or in conditional requests. + Used by caches, or in conditional requests (Will be supported in future). type: string schema: $ref: '#/definitions/API' 304: description: | Not Modified. - Empty body because the client has already the latest version of the requested resource. + Empty body because the client has already the latest version of the requested resource (Will be supported in future). 404: description: | Not Found. @@ -271,12 +302,13 @@ paths: #----------------------------------------------------- put: x-scope: apim:api_create - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -H \"Content-Type: application/json\" -X PUT -d @data.json http://127.0.0.1:9763/api/am/publisher/v0.10/apis/6fb74674-4ab8-4b52-9886-f9a376985060" - x-wso2-request: "{\n \"sequences\": [],\n \"tiers\": [\n \"Bronze\",\n \"Gold\"\n ],\n \"thumbnailUrl\": null,\n \"visibility\": \"PUBLIC\",\n \"visibleRoles\": [],\n \"visibleTenants\": [],\n \"cacheTimeout\": 300,\n \"endpointConfig\": \"{\\\"production_endpoints\\\":{\\\"url\\\":\\\" http://ws.cdyne.com/phoneverify/phoneverify.asmx\\\",\\\"config\\\":null},\\\"endpoint_type\\\":\\\"http\\\"}\",\n \"subscriptionAvailability\": null,\n \"subscriptionAvailableTenants\": [],\n \"destinationStatsEnabled\": \"Disabled\",\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"\\/*\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"responses\\\":{\\\"200\\\":{\\\"description\\\":\\\"OK\\\"}}}}},\\\"x-wso2-security\\\":{\\\"apim\\\":{\\\"x-wso2-scopes\\\":[]}},\\\"swagger\\\":\\\"2.0\\\",\\\"info\\\":{\\\"title\\\":\\\"PhoneVerification\\\",\\\"description\\\":\\\"Verify a phone number\\\",\\\"contact\\\":{\\\"email\\\":\\\"xx@ee.com\\\",\\\"name\\\":\\\"xx\\\"},\\\"version\\\":\\\"2.0.0\\\"}}\",\n \"responseCaching\": \"Disabled\",\n \"isDefaultVersion\": false,\n \"gatewayEnvironments\": \"Production and Sandbox\",\n \"businessInformation\": {\n \"technicalOwner\": \"xx\",\n \"technicalOwnerEmail\": \"ggg@ww.com\",\n \"businessOwner\": \"xx\",\n \"businessOwnerEmail\": \"xx@ee.com\"\n },\n \"transport\": [\n \"http\",\n \"https\"\n ],\n \"tags\": [\n \"phone\",\n \"multimedia\",\n \"verification\",\n \"mobile\"\n ],\n \"provider\": \"admin\",\n \"version\": \"2.0.0\",\n \"description\": \"Use this API to verify a phone number\",\n \"name\": \"PhoneVerification\",\n \"context\": \"/phoneverify\",\n \"id\": \"6fb74674-4ab8-4b52-9886-f9a376985060\",\n \"status\": \"CREATED\"\n}" - x-wso2-response: "HTTP/1.1 200 OK\nDate: Mon, 22 Feb 2016 13:31:35 GMT\nContent-Type: application/json\nTransfer-Encoding: chunked\nServer: WSO2 Carbon Server\n\n{\n \"sequences\": [],\n \"tiers\": [\n \"Bronze\",\n \"Gold\"\n ],\n \"thumbnailUrl\": null,\n \"visibility\": \"PUBLIC\",\n \"visibleRoles\": [],\n \"visibleTenants\": [],\n \"cacheTimeout\": 300,\n \"endpointConfig\": \"{\\\"production_endpoints\\\":{\\\"url\\\":\\\" http://ws.cdyne.com/phoneverify/phoneverify.asmx\\\",\\\"config\\\":null},\\\"endpoint_type\\\":\\\"http\\\"}\",\n \"subscriptionAvailability\": null,\n \"subscriptionAvailableTenants\": [],\n \"destinationStatsEnabled\": \"Disabled\",\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"\\/*\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"responses\\\":{\\\"200\\\":{\\\"description\\\":\\\"OK\\\"}}}}},\\\"x-wso2-security\\\":{\\\"apim\\\":{\\\"x-wso2-scopes\\\":[]}},\\\"swagger\\\":\\\"2.0\\\",\\\"info\\\":{\\\"title\\\":\\\"PhoneVerification\\\",\\\"description\\\":\\\"Verify a phone number\\\",\\\"contact\\\":{\\\"email\\\":\\\"xx@ee.com\\\",\\\"name\\\":\\\"xx\\\"},\\\"version\\\":\\\"2.0.0\\\"}}\",\n \"responseCaching\": \"Disabled\",\n \"isDefaultVersion\": false,\n \"gatewayEnvironments\": \"Production and Sandbox\",\n \"businessInformation\": {\n \"technicalOwner\": \"xx\",\n \"technicalOwnerEmail\": \"ggg@ww.com\",\n \"businessOwner\": \"xx\",\n \"businessOwnerEmail\": \"xx@ee.com\"\n },\n \"transport\": [\n \"http\",\n \"https\"\n ],\n \"tags\": [\n \"phone\",\n \"multimedia\",\n \"verification\",\n \"mobile\"\n ],\n \"provider\": \"admin\",\n \"version\": \"2.0.0\",\n \"description\": \"Use this API to verify a phone number\",\n \"name\": \"PhoneVerification\",\n \"context\": \"/phoneverify\",\n \"id\": \"6fb74674-4ab8-4b52-9886-f9a376985060\",\n \"status\": \"CREATED\"\n}" - summary: Update an existing API + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -H \"Content-Type: application/json\" -X PUT -d @data.json https://localhost:9443/api/am/publisher/v0.12/apis/7a2298c4-c905-403f-8fac-38c73301631f" + x-wso2-request: "PUT https://localhost:9443/api/am/publisher/v0.12/apis/7a2298c4-c905-403f-8fac-38c73301631f\nAuthorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\nContent-Type: application/json\n\n{\r\n \"id\": \"7a2298c4-c905-403f-8fac-38c73301631f\",\r\n \"name\": \"PizzaShackAPI\",\r\n \"description\": \"This document describe a RESTFul API for Pizza Shack online pizza delivery store.\\r\\n\",\r\n \"context\": \"/pizzashack\",\r\n \"version\": \"1.0.0\",\r\n \"provider\": \"admin\",\r\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"/order\\\":{\\\"post\\\":{\\\"x-auth-type\\\":\\\"Application & Application User\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"description\\\":\\\"Create a new Order\\\",\\\"parameters\\\":[{\\\"schema\\\":{\\\"$ref\\\":\\\"#/definitions/Order\\\"},\\\"description\\\":\\\"Order object that needs to be added\\\",\\\"name\\\":\\\"body\\\",\\\"required\\\":true,\\\"in\\\":\\\"body\\\"}],\\\"responses\\\":{\\\"201\\\":{\\\"headers\\\":{\\\"Location\\\":{\\\"description\\\":\\\"The URL of the newly created resource.\\\",\\\"type\\\":\\\"string\\\"}},\\\"schema\\\":{\\\"$ref\\\":\\\"#/definitions/Order\\\"},\\\"description\\\":\\\"Created.\\\"}}}},\\\"/menu\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application & Application User\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"description\\\":\\\"Return a list of available menu items\\\",\\\"parameters\\\":[],\\\"responses\\\":{\\\"200\\\":{\\\"headers\\\":{},\\\"schema\\\":{\\\"title\\\":\\\"Menu\\\",\\\"properties\\\":{\\\"list\\\":{\\\"items\\\":{\\\"$ref\\\":\\\"#/definitions/MenuItem\\\"},\\\"type\\\":\\\"array\\\"}},\\\"type\\\":\\\"object\\\"},\\\"description\\\":\\\"OK.\\\"}}}}},\\\"schemes\\\":[\\\"https\\\"],\\\"produces\\\":[\\\"application/json\\\"],\\\"swagger\\\":\\\"2.0\\\",\\\"definitions\\\":{\\\"MenuItem\\\":{\\\"title\\\":\\\"Pizza menu Item\\\",\\\"properties\\\":{\\\"price\\\":{\\\"type\\\":\\\"string\\\"},\\\"description\\\":{\\\"type\\\":\\\"string\\\"},\\\"name\\\":{\\\"type\\\":\\\"string\\\"},\\\"image\\\":{\\\"type\\\":\\\"string\\\"}},\\\"required\\\":[\\\"name\\\"]},\\\"Order\\\":{\\\"title\\\":\\\"Pizza Order\\\",\\\"properties\\\":{\\\"customerName\\\":{\\\"type\\\":\\\"string\\\"},\\\"delivered\\\":{\\\"type\\\":\\\"boolean\\\"},\\\"address\\\":{\\\"type\\\":\\\"string\\\"},\\\"pizzaType\\\":{\\\"type\\\":\\\"string\\\"},\\\"creditCardNumber\\\":{\\\"type\\\":\\\"string\\\"},\\\"quantity\\\":{\\\"type\\\":\\\"number\\\"},\\\"orderId\\\":{\\\"type\\\":\\\"integer\\\"}},\\\"required\\\":[\\\"orderId\\\"]}},\\\"consumes\\\":[\\\"application/json\\\"],\\\"info\\\":{\\\"title\\\":\\\"PizzaShackAPI\\\",\\\"description\\\":\\\"This document describe a RESTFul API for Pizza Shack online pizza delivery store.\\\\n\\\",\\\"license\\\":{\\\"name\\\":\\\"Apache 2.0\\\",\\\"url\\\":\\\"http://www.apache.org/licenses/LICENSE-2.0.html\\\"},\\\"contact\\\":{\\\"email\\\":\\\"architecture@pizzashack.com\\\",\\\"name\\\":\\\"John Doe\\\",\\\"url\\\":\\\"http://www.pizzashack.com\\\"},\\\"version\\\":\\\"1.0.0\\\"}}\",\r\n \"wsdlUri\": null,\r\n \"status\": \"CREATED\",\r\n \"responseCaching\": \"Disabled\",\r\n \"cacheTimeout\": 300,\r\n \"destinationStatsEnabled\": null,\r\n \"isDefaultVersion\": false,\r\n \"type\": \"HTTP\",\r\n \"transport\": [\r\n \"https\"\r\n ],\r\n \"tags\": [\"pizza\",\"chicken\"],\r\n \"tiers\": [\"Unlimited\"],\r\n \"maxTps\": {\r\n \"sandbox\": 500,\r\n \"production\": 100\r\n },\r\n \"thumbnailUri\": null,\r\n \"visibility\": \"PUBLIC\",\r\n \"visibleRoles\": [],\\r\n \"endpointConfig\": \"{\\\"production_endpoints\\\":{\\\"url\\\":\\\"https://localhost:9443/am/sample/pizzashack/v1/api/\\\",\\\"config\\\":null},\\\"sandbox_endpoints\\\":{\\\"url\\\":\\\"https://localhost:9443/am/sample/pizzashack/v1/api/\\\",\\\"config\\\":null},\\\"endpoint_type\\\":\\\"http\\\"}\",\r\n \"endpointSecurity\": {\r\n \"username\": \"user\",\r\n \"type\": \"basic\",\r\n \"password\": \"pass\"\r\n },\r\n \"gatewayEnvironments\": \"Production and Sandbox\",\r\n \"sequences\": [{\"name\":\"json_validator\",\"type\": \"in\"},{\"name\":\"log_out_message\",\"type\": \"out\"}],\r\n \"subscriptionAvailability\": null,\r\n \"subscriptionAvailableTenants\": [],\r\n \"businessInformation\": {\r\n \"businessOwnerEmail\": \"marketing@pizzashack.com\",\r\n \"technicalOwnerEmail\": \"architecture@pizzashack.com\",\r\n \"technicalOwner\": \"John Doe\",\r\n \"businessOwner\": \"Jane Roe\"\r\n },\r\n \"corsConfiguration\": {\r\n \"accessControlAllowOrigins\": [\"*\"],\r\n \"accessControlAllowHeaders\": [\r\n \"authorization\",\r\n \"Access-Control-Allow-Origin\",\r\n \"Content-Type\",\r\n \"SOAPAction\"\r\n ],\r\n \"accessControlAllowMethods\": [\r\n \"GET\",\r\n \"PUT\",\r\n \"POST\",\r\n \"DELETE\",\r\n \"PATCH\",\r\n \"OPTIONS\"\r\n ],\r\n \"accessControlAllowCredentials\": false,\r\n \"corsConfigurationEnabled\": false\r\n }\r\n}" + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\r\n \"id\": \"7a2298c4-c905-403f-8fac-38c73301631f\",\r\n \"name\": \"PizzaShackAPI\",\r\n \"description\": \"This document describe a RESTFul API for Pizza Shack online pizza delivery store.\\r\\n\",\r\n \"context\": \"/pizzashack\",\r\n \"version\": \"1.0.0\",\r\n \"provider\": \"admin\",\r\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"/order\\\":{\\\"post\\\":{\\\"x-auth-type\\\":\\\"Application & Application User\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"description\\\":\\\"Create a new Order\\\",\\\"parameters\\\":[{\\\"schema\\\":{\\\"$ref\\\":\\\"#/definitions/Order\\\"},\\\"description\\\":\\\"Order object that needs to be added\\\",\\\"name\\\":\\\"body\\\",\\\"required\\\":true,\\\"in\\\":\\\"body\\\"}],\\\"responses\\\":{\\\"201\\\":{\\\"headers\\\":{\\\"Location\\\":{\\\"description\\\":\\\"The URL of the newly created resource.\\\",\\\"type\\\":\\\"string\\\"}},\\\"schema\\\":{\\\"$ref\\\":\\\"#/definitions/Order\\\"},\\\"description\\\":\\\"Created.\\\"}}}},\\\"/menu\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application & Application User\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"description\\\":\\\"Return a list of available menu items\\\",\\\"parameters\\\":[],\\\"responses\\\":{\\\"200\\\":{\\\"headers\\\":{},\\\"schema\\\":{\\\"title\\\":\\\"Menu\\\",\\\"properties\\\":{\\\"list\\\":{\\\"items\\\":{\\\"$ref\\\":\\\"#/definitions/MenuItem\\\"},\\\"type\\\":\\\"array\\\"}},\\\"type\\\":\\\"object\\\"},\\\"description\\\":\\\"OK.\\\"}}}}},\\\"schemes\\\":[\\\"https\\\"],\\\"produces\\\":[\\\"application/json\\\"],\\\"swagger\\\":\\\"2.0\\\",\\\"definitions\\\":{\\\"MenuItem\\\":{\\\"title\\\":\\\"Pizza menu Item\\\",\\\"properties\\\":{\\\"price\\\":{\\\"type\\\":\\\"string\\\"},\\\"description\\\":{\\\"type\\\":\\\"string\\\"},\\\"name\\\":{\\\"type\\\":\\\"string\\\"},\\\"image\\\":{\\\"type\\\":\\\"string\\\"}},\\\"required\\\":[\\\"name\\\"]},\\\"Order\\\":{\\\"title\\\":\\\"Pizza Order\\\",\\\"properties\\\":{\\\"customerName\\\":{\\\"type\\\":\\\"string\\\"},\\\"delivered\\\":{\\\"type\\\":\\\"boolean\\\"},\\\"address\\\":{\\\"type\\\":\\\"string\\\"},\\\"pizzaType\\\":{\\\"type\\\":\\\"string\\\"},\\\"creditCardNumber\\\":{\\\"type\\\":\\\"string\\\"},\\\"quantity\\\":{\\\"type\\\":\\\"number\\\"},\\\"orderId\\\":{\\\"type\\\":\\\"string\\\"}},\\\"required\\\":[\\\"orderId\\\"]}},\\\"consumes\\\":[\\\"application/json\\\"],\\\"info\\\":{\\\"title\\\":\\\"PizzaShackAPI\\\",\\\"description\\\":\\\"This document describe a RESTFul API for Pizza Shack online pizza delivery store.\\\\n\\\",\\\"license\\\":{\\\"name\\\":\\\"Apache 2.0\\\",\\\"url\\\":\\\"http://www.apache.org/licenses/LICENSE-2.0.html\\\"},\\\"contact\\\":{\\\"email\\\":\\\"architecture@pizzashack.com\\\",\\\"name\\\":\\\"John Doe\\\",\\\"url\\\":\\\"http://www.pizzashack.com\\\"},\\\"version\\\":\\\"1.0.0\\\"}}\",\r\n \"wsdlUri\": null,\r\n \"status\": \"CREATED\",\r\n \"responseCaching\": \"Disabled\",\r\n \"cacheTimeout\": 300,\r\n \"destinationStatsEnabled\": null,\r\n \"isDefaultVersion\": false,\r\n \"type\": \"HTTP\",\r\n \"transport\": [\"https\"],\r\n \"tags\": [\r\n \"chicken\",\r\n \"pizza\"\r\n ],\r\n \"tiers\": [\"Unlimited\"],\r\n \"maxTps\": {\r\n \"sandbox\": 500,\r\n \"production\": 100\r\n },\r\n \"thumbnailUri\": null,\r\n \"visibility\": \"PUBLIC\",\r\n \"visibleRoles\": [],\\r\n \"endpointConfig\": \"{\\\"production_endpoints\\\":{\\\"url\\\":\\\"https://localhost:9443/am/sample/pizzashack/v1/api/\\\",\\\"config\\\":null},\\\"sandbox_endpoints\\\":{\\\"url\\\":\\\"https://localhost:9443/am/sample/pizzashack/v1/api/\\\",\\\"config\\\":null},\\\"endpoint_type\\\":\\\"http\\\"}\",\r\n \"endpointSecurity\": {\r\n \"username\": \"user\",\r\n \"type\": \"basic\",\r\n \"password\": \"pass\"\r\n },\r\n \"gatewayEnvironments\": \"Production and Sandbox\",\r\n \"sequences\": [{\"name\":\"json_validator\",\"type\":\"in\",\"id\":\"142ece76-b208-4aab-b29a-f382045ed066\",\"shared\":false},{\"name\":\"log_out_message\",\"type\":\"out\",\"id\":\"b3527be8-95e6-41e0-8097-3276987b7d4b\",\"shared\":false}],\r\n \"subscriptionAvailability\": null,\r\n \"subscriptionAvailableTenants\": [],\r\n \"businessInformation\": {\r\n \"businessOwnerEmail\": \"marketing@pizzashack.com\",\r\n \"technicalOwnerEmail\": \"architecture@pizzashack.com\",\r\n \"technicalOwner\": \"John Doe\",\r\n \"businessOwner\": \"Jane Roe\"\r\n },\r\n \"corsConfiguration\": {\r\n \"accessControlAllowOrigins\": [\"*\"],\r\n \"accessControlAllowHeaders\": [\r\n \"authorization\",\r\n \"Access-Control-Allow-Origin\",\r\n \"Content-Type\",\r\n \"SOAPAction\"\r\n ],\r\n \"accessControlAllowMethods\": [\r\n \"GET\",\r\n \"PUT\",\r\n \"POST\",\r\n \"DELETE\",\r\n \"PATCH\",\r\n \"OPTIONS\"\r\n ],\r\n \"accessControlAllowCredentials\": false,\r\n \"corsConfigurationEnabled\": false\r\n }\r\n}" + summary: Update an API description: | - Update an existing API + This operation can be used to update an existing API. + But the properties `name`, `version`, `context`, `provider`, `state` will not be changed by this operation. parameters: - $ref: '#/parameters/apiId' - in: body @@ -290,7 +322,7 @@ paths: - $ref: '#/parameters/If-Match' - $ref: '#/parameters/If-Unmodified-Since' tags: - - APIs + - API (Individual) responses: 200: description: | @@ -309,12 +341,12 @@ paths: type: string ETag: description: | - Entity Tag of the response resource. Used by caches, or in conditional request. + Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future). type: string Last-Modified: description: | Date and time the resource has been modifed the last time. - Used by caches, or in conditional requests. + Used by caches, or in conditional requests (Will be supported in future). type: string 400: description: | @@ -346,17 +378,20 @@ paths: #----------------------------------------------------- delete: x-scope: apim:api_create - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -X DELETE http://127.0.0.1:9763/api/am/publisher/v0.10/apis/6fb74674-4ab8-4b52-9886-f9a376985060" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -X DELETE https://localhost:9443/api/am/publisher/v0.12/apis/6fb74674-4ab8-4b52-9886-f9a376985060" + x-wso2-request: | + DELETE https://localhost:9443/api/am/publisher/v0.12/apis/6fb74674-4ab8-4b52-9886-f9a376985060 + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 x-wso2-response: "HTTP/1.1 200 OK" - summary: Delete API + summary: Delete an API description: | - Delete an existing API + This operation can be used to delete an existing API proving the Id of the API. parameters: - $ref: '#/parameters/apiId' - $ref: '#/parameters/If-Match' - $ref: '#/parameters/If-Unmodified-Since' tags: - - APIs + - API (Individual) responses: 200: description: | @@ -391,18 +426,21 @@ paths: #----------------------------------------------------- get: x-scope: apim:api_view - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" http://127.0.0.1:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/swagger" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" https://localhost:9443/api/am/publisher/v0.12/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/swagger" + x-wso2-request: | + GET https://localhost:9443/api/am/publisher/v0.12/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/swagger + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\nContent-Length: 329\n\n{\n \"paths\": {\"/*\": {\"get\": {\n \"x-auth-type\": \"Application\",\n \"x-throttling-tier\": \"Unlimited\",\n \"responses\": {\"200\": {\"description\": \"OK\"}}\n }}},\n \"x-wso2-security\": {\"apim\": {\"x-wso2-scopes\": []}},\n \"swagger\": \"2.0\",\n \"info\": {\n \"title\": \"PhoneVerification\",\n \"description\": \"Verify a phone number\",\n \"contact\": {\n \"email\": \"xx@ee.com\",\n \"name\": \"xx\"\n },\n \"version\": \"1.0.0\"\n }\n}" - summary: Get API Definition + summary: Get swagger definition description: | - Get the swagger of an API + This operation can be used to retrieve the swagger definition of an API. parameters: - $ref: '#/parameters/apiId' - $ref: '#/parameters/Accept' - $ref: '#/parameters/If-None-Match' - $ref: '#/parameters/If-Modified-Since' tags: - - APIs + - API (Individual) responses: 200: description: | @@ -415,17 +453,17 @@ paths: type: string ETag: description: | - Entity Tag of the response resource. Used by caches, or in conditional requests. + Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future). type: string Last-Modified: description: | Date and time the resource has been modifed the last time. - Used by caches, or in conditional requests. + Used by caches, or in conditional requests (Will be supported in future). type: string 304: description: | Not Modified. - Empty body because the client has already the latest version of the requested resource. + Empty body because the client has already the latest version of the requested resource (Will be supported in future). 404: description: | Not Found. @@ -446,12 +484,22 @@ paths: consumes: - multipart/form-data x-scope: apim:api_create - x-wso2-curl: "curl -k -H \"Authorization:Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -F apiDefinition=\"{\\\"paths\\\":{\\\"\\/*\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"responses\\\":{\\\"200\\\":{\\\"description\\\":\\\"OK\\\"}}}}},\\\"x-wso2-security\\\":{\\\"apim\\\":{\\\"x-wso2-scopes\\\":[]}},\\\"swagger\\\":\\\"2.0\\\",\\\"info\\\":{\\\"title\\\":\\\"PhoneVerification\\\",\\\"description\\\":\\\"Verify a phone number\\\",\\\"contact\\\":{\\\"email\\\":\\\"xx@ee.com\\\",\\\"name\\\":\\\"xx\\\"},\\\"version\\\":\\\"1.0.0\\\"}}\" -X PUT \"http://127.0.0.1:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/swagger\"" - x-wso2-request: "{\n \"paths\": {\n \"\\/*\": {\n \"get\": {\n \"x-auth-type\": \"Application\",\n \"x-throttling-tier\": \"Unlimited\",\n \"responses\": {\n \"200\": {\n \"description\": \"OK\"\n }\n }\n }\n }\n },\n \"x-wso2-security\": {\n \"apim\": {\n \"x-wso2-scopes\": []\n }\n },\n \"swagger\": \"2.0\",\n \"info\": {\n \"title\": \"PhoneVerification\",\n \"description\": \"Verify a phone number\",\n \"contact\": {\n \"email\": \"xx@ee.com\",\n \"name\": \"xx\"\n },\n \"version\": \"1.0.0\"\n }\n}" + x-wso2-curl: "curl -k -H \"Authorization:Bearer 5311eca3-8ac8-354e-ab36-7e2fdd6a4013\" -F apiDefinition=\"{\\\"paths\\\":{\\\"\\/*\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"responses\\\":{\\\"200\\\":{\\\"description\\\":\\\"OK\\\"}}}}},\\\"x-wso2-security\\\":{\\\"apim\\\":{\\\"x-wso2-scopes\\\":[]}},\\\"swagger\\\":\\\"2.0\\\",\\\"info\\\":{\\\"title\\\":\\\"PhoneVerification\\\",\\\"description\\\":\\\"Verify a phone number\\\",\\\"contact\\\":{\\\"email\\\":\\\"xx@ee.com\\\",\\\"name\\\":\\\"xx\\\"},\\\"version\\\":\\\"1.0.0\\\"}}\" -X PUT \"https://localhost:9443/api/am/publisher/v0.12/apis/8848faaa-7fd1-478a-baa2-48a4ebb92c98/swagger\"" + x-wso2-request: | + PUT https://localhost:9443/api/am/publisher/v0.12/apis/8848faaa-7fd1-478a-baa2-48a4ebb92c98/swagger + Authorization:Bearer 5311eca3-8ac8-354e-ab36-7e2fdd6a4013 + Content-Length: 477 + Content-Type: multipart/form-data; boundary=------------------------4f51e636c0003d99 + + --------------------------4f51e636c0003d99 + Content-Disposition: form-data; name="apiDefinition" + + {"paths":{"\/*":{"get":{"x-auth-type":"Application","x-throttling-tier":"Unlimited","responses":{"200":{"description":"OK"}}}}},"x-wso2-security":{"apim":{"x-wso2-scopes":[]}},"swagger":"2.0","info":{"title":"PhoneVerification","description":"Verify a phone number","contact":{"email":"xx@ee.com","name":"xx"},"version":"1.0.0"}} + --------------------------4f51e636c0003d99-- x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"paths\": {\"/*\": {\"get\": {\n \"x-auth-type\": \"Application\",\n \"x-throttling-tier\": \"Unlimited\",\n \"responses\": {\"200\": {\"description\": \"OK\"}}\n }}},\n \"x-wso2-security\": {\"apim\": {\"x-wso2-scopes\": []}},\n \"swagger\": \"2.0\",\n \"info\": {\n \"title\": \"PhoneVerification\",\n \"description\": \"Verify a phone number\",\n \"contact\": {\n \"email\": \"xx@ee.com\",\n \"name\": \"xx\"\n },\n \"version\": \"1.0.0\"\n }\n}" - summary: Update API Definition + summary: Update swagger definition description: | - Update an existing swagger definition of an API + This operation can be used to update the swagger definition of an existing API. Swagger definition to be updated is passed as a form data parameter `apiDefinition`. parameters: - $ref: '#/parameters/apiId' - in: formData @@ -463,7 +511,7 @@ paths: - $ref: '#/parameters/If-Match' - $ref: '#/parameters/If-Unmodified-Since' tags: - - APIs + - API (Individual) responses: 200: description: | @@ -480,12 +528,12 @@ paths: type: string ETag: description: | - Entity Tag of the response resource. Used by caches, or in conditional request. + Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future). type: string Last-Modified: description: | Date and time the resource has been modifed the last time. - Used by caches, or in conditional requests. + Used by caches, or in conditional requests (Will be supported in future). type: string 400: description: | @@ -522,18 +570,21 @@ paths: #------------------------------------------------------------------------------------------------- get: x-scope: apim:api_view - x-wso2-curl: "curl -H \"Authorization: Bearer d34baf74-3f02-3929-814e-88b27f750ba9\" http://127.0.0.1:9763/api/am/publisher/v0.10/apis/29c9ec3d-f590-467e-83e6-96d43517080f/thumbnail > image.jpg" + x-wso2-curl: "curl -k -H \"Authorization: Bearer d34baf74-3f02-3929-814e-88b27f750ba9\" https://localhost:9443/api/am/publisher/v0.12/apis/29c9ec3d-f590-467e-83e6-96d43517080f/thumbnail > image.jpg" + x-wso2-request: | + GET https://localhost:9443/api/am/publisher/v0.12/apis/29c9ec3d-f590-467e-83e6-96d43517080f/thumbnail + Authorization: Bearer d34baf74-3f02-3929-814e-88b27f750ba9 x-wso2-response: "HTTP/1.1 200 OK\r\nContent-Type: image/jpeg\r\n\r\n[image content]" - summary: Get the thumbnail image + summary: Get thumbnail image description: | - Downloads a thumbnail image of an API + This operation can be used to download a thumbnail image of an API. parameters: - $ref: '#/parameters/apiId' - $ref: '#/parameters/Accept' - $ref: '#/parameters/If-None-Match' - $ref: '#/parameters/If-Modified-Since' tags: - - APIs + - API (Individual) responses: 200: description: | @@ -547,17 +598,17 @@ paths: ETag: description: | Entity Tag of the response resource. - Used by caches, or in conditional requests. + Used by caches, or in conditional requests (Will be supported in future). type: string Last-Modified: description: | Date and time the resource has been modifed the last time. - Used by caches, or in conditional reuquests. + Used by caches, or in conditional requests (Will be supported in future). type: string 304: description: | Not Modified. - Empty body because the client has already the latest version of the requested resource. + Empty body because the client has already the latest version of the requested resource (Will be supported in future). 404: description: | Not Found. @@ -578,11 +629,24 @@ paths: consumes: - multipart/form-data x-scope: apim:api_create - x-wso2-curl: "curl -X POST -H \"Authorization: Bearer d34baf74-3f02-3929-814e-88b27f750ba9\" http://127.0.0.1:9763/api/am/publisher/v0.10/apis/29c9ec3d-f590-467e-83e6-96d43517080f/thumbnail -F file=@image.jpg" - x-wso2-response: "HTTP/1.1 201 Created\r\nLocation: http://localhost:9763/api/am/publisher/v0.10/apis/29c9ec3d-f590-467e-83e6-96d43517080f/thumbnail\r\nContent-Type: application/json\r\n\r\n{\r\n \"relativePath\": \"/apis/29c9ec3d-f590-467e-83e6-96d43517080f/thumbnail\",\r\n \"mediaType\": \"image/jpeg\"\r\n}" + x-wso2-curl: "curl -X POST -H \"Authorization: Bearer d34baf74-3f02-3929-814e-88b27f750ba9\" https://localhost:9443/api/am/publisher/v0.12/apis/29c9ec3d-f590-467e-83e6-96d43517080f/thumbnail -F file=@image.jpg" + x-wso2-request: | + POST https://localhost:9443/api/am/publisher/v0.12/apis/8848faaa-7fd1-478a-baa2-48a4ebb92c98/thumbnail + Authorization: Bearer d34baf74-3f02-3929-814e-88b27f750ba9 + Content-Type: multipart/form-data; boundary=------------------------5e542e0e5b50e1e4 + Content-Length: 18333 + + --------------------------5e542e0e5b50e1e4 + Content-Disposition: form-data; name="file"; filename="image.jpg" + Content-Type: image/jpeg + + [image content] + + --------------------------5e542e0e5b50e1e4-- + x-wso2-response: "HTTP/1.1 201 Created\r\nLocation: https://localhost:9443/api/am/publisher/v0.12/apis/8848faaa-7fd1-478a-baa2-48a4ebb92c98/thumbnail\r\nContent-Type: application/json\r\n\r\n{\r\n \"relativePath\": \"/apis/8848faaa-7fd1-478a-baa2-48a4ebb92c98/thumbnail\",\r\n \"mediaType\": \"image/jpeg\"\r\n}" summary: Upload a thumbnail image description: | - Upload a thumbnail image to an API. + This operation can be used to upload a thumbnail image of an API. The thumbnail to be uploaded should be given as a form data parameter `file`. parameters: - $ref: '#/parameters/apiId' - in: formData @@ -594,7 +658,7 @@ paths: - $ref: '#/parameters/If-Match' - $ref: '#/parameters/If-Unmodified-Since' tags: - - APIs + - API (Individual) responses: 200: description: | @@ -614,12 +678,12 @@ paths: ETag: description: | Entity Tag of the response resource. - Used by caches, or in conditional request. + Used by caches, or in conditional requests (Will be supported in future). type: string Last-Modified: description: | Date and time the resource has been modifed the last time. - Used by caches, or in conditional reuquests. + Used by caches, or in conditional requests (Will be supported in future). type: string 400: description: | @@ -650,11 +714,14 @@ paths: #----------------------------------------------------- post: x-scope: apim:api_create - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -X POST \"http://127.0.0.1:9763/api/am/publisher/v0.10/apis/copy-api?apiId=890a4f4d-09eb-4877-a323-57f6ce2ed79b&newVersion=2.0.0\"" - x-wso2-response: "HTTP/1.1 201 Created\nLocation: http://localhost:9763/api/am/publisher/v0.10/apis/6fb74674-4ab8-4b52-9886-f9a376985060\nContent-Type: application/json\n\n{\n \"sequences\": [],\n \"tiers\": [\n \"Bronze\",\n \"Gold\"\n ],\n \"thumbnailUrl\": null,\n \"visibility\": \"PUBLIC\",\n \"visibleRoles\": [],\n \"visibleTenants\": [],\n \"cacheTimeout\": 300,\n \"endpointConfig\": \"{\\\"production_endpoints\\\":{\\\"url\\\":\\\" http://ws.cdyne.com/phoneverify/phoneverify.asmx\\\",\\\"config\\\":null},\\\"endpoint_type\\\":\\\"http\\\"}\",\n \"subscriptionAvailability\": null,\n \"subscriptionAvailableTenants\": [],\n \"destinationStatsEnabled\": \"Disabled\",\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"\\/*\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"responses\\\":{\\\"200\\\":{\\\"description\\\":\\\"OK\\\"}}}}},\\\"x-wso2-security\\\":{\\\"apim\\\":{\\\"x-wso2-scopes\\\":[]}},\\\"swagger\\\":\\\"2.0\\\",\\\"info\\\":{\\\"title\\\":\\\"PhoneVerification\\\",\\\"description\\\":\\\"Verify a phone number\\\",\\\"contact\\\":{\\\"email\\\":\\\"xx@ee.com\\\",\\\"name\\\":\\\"xx\\\"},\\\"version\\\":\\\"2.0.0\\\"}}\",\n \"responseCaching\": \"Disabled\",\n \"isDefaultVersion\": true,\n \"gatewayEnvironments\": \"Production and Sandbox\",\n \"businessInformation\": {\n \"technicalOwner\": \"xx\",\n \"technicalOwnerEmail\": \"ggg@ww.com\",\n \"businessOwner\": \"xx\",\n \"businessOwnerEmail\": \"xx@ee.com\"\n },\n \"transport\": [\n \"http\",\n \"https\"\n ],\n \"tags\": [\n \"phone\",\n \"multimedia\",\n \"mobile\"\n ],\n \"provider\": \"admin\",\n \"version\": \"2.0.0\",\n \"description\": \"Verify a phone number\",\n \"name\": \"PhoneVerification\",\n \"context\": \"/phoneverify\",\n \"id\": \"6fb74674-4ab8-4b52-9886-f9a376985060\",\n \"status\": \"CREATED\"\n}" - summary: Copy API + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -X POST \"https://localhost:9443/api/am/publisher/v0.12/apis/copy-api?apiId=890a4f4d-09eb-4877-a323-57f6ce2ed79b&newVersion=2.0.0\"" + x-wso2-request: | + POST https://localhost:9443/api/am/publisher/v0.12/apis/copy-api?apiId=890a4f4d-09eb-4877-a323-57f6ce2ed79b&newVersion=2.0.0 + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 + x-wso2-response: "HTTP/1.1 201 Created\nLocation: https://localhost:9443/api/am/publisher/v0.12/apis/25a84fc9-38c0-4578-95e8-29fb6b1c4771\nContent-Type: application/json\n\n{\r\n \"id\": \"25a84fc9-38c0-4578-95e8-29fb6b1c4771\",\r\n \"name\": \"PizzaShackAPI\",\r\n \"description\": \"This document describe a RESTFul API for Pizza Shack online pizza delivery store.\\r\\n\",\r\n \"context\": \"/pizzashack\",\r\n \"version\": \"2.0.0\",\r\n \"provider\": \"admin\",\r\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"\\\\/order\\\":{\\\"post\\\":{\\\"x-auth-type\\\":\\\"Application & Application User\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"description\\\":\\\"Create a new Order\\\",\\\"parameters\\\":[{\\\"schema\\\":{\\\"$ref\\\":\\\"#\\\\/definitions\\\\/Order\\\"},\\\"description\\\":\\\"Order object that needs to be added\\\",\\\"name\\\":\\\"body\\\",\\\"required\\\":true,\\\"in\\\":\\\"body\\\"}],\\\"responses\\\":{\\\"201\\\":{\\\"schema\\\":{\\\"$ref\\\":\\\"#\\\\/definitions\\\\/Order\\\"},\\\"headers\\\":{\\\"Location\\\":{\\\"description\\\":\\\"The URL of the newly created resource.\\\",\\\"type\\\":\\\"string\\\"}},\\\"description\\\":\\\"Created.\\\"}}}},\\\"\\\\/menu\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application & Application User\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"description\\\":\\\"Return a list of available menu items\\\",\\\"parameters\\\":[],\\\"responses\\\":{\\\"200\\\":{\\\"schema\\\":{\\\"title\\\":\\\"Menu\\\",\\\"properties\\\":{\\\"list\\\":{\\\"items\\\":{\\\"$ref\\\":\\\"#\\\\/definitions\\\\/MenuItem\\\"},\\\"type\\\":\\\"array\\\"}},\\\"type\\\":\\\"object\\\"},\\\"headers\\\":{},\\\"description\\\":\\\"OK.\\\"}}}}},\\\"schemes\\\":[\\\"https\\\"],\\\"produces\\\":[\\\"application\\\\/json\\\"],\\\"swagger\\\":\\\"2.0\\\",\\\"definitions\\\":{\\\"MenuItem\\\":{\\\"title\\\":\\\"Pizza menu Item\\\",\\\"properties\\\":{\\\"price\\\":{\\\"type\\\":\\\"string\\\"},\\\"description\\\":{\\\"type\\\":\\\"string\\\"},\\\"name\\\":{\\\"type\\\":\\\"string\\\"},\\\"image\\\":{\\\"type\\\":\\\"string\\\"}},\\\"required\\\":[\\\"name\\\"]},\\\"Order\\\":{\\\"title\\\":\\\"Pizza Order\\\",\\\"properties\\\":{\\\"customerName\\\":{\\\"type\\\":\\\"string\\\"},\\\"delivered\\\":{\\\"type\\\":\\\"boolean\\\"},\\\"pizzaType\\\":{\\\"type\\\":\\\"string\\\"},\\\"address\\\":{\\\"type\\\":\\\"string\\\"},\\\"creditCardNumber\\\":{\\\"type\\\":\\\"string\\\"},\\\"quantity\\\":{\\\"type\\\":\\\"number\\\"},\\\"orderId\\\":{\\\"type\\\":\\\"string\\\"}},\\\"required\\\":[\\\"orderId\\\"]}},\\\"consumes\\\":[\\\"application\\\\/json\\\"],\\\"info\\\":{\\\"title\\\":\\\"PizzaShackAPI\\\",\\\"description\\\":\\\"This document describe a RESTFul API for Pizza Shack online pizza delivery store.\\\\n\\\",\\\"license\\\":{\\\"name\\\":\\\"Apache 2.0\\\",\\\"url\\\":\\\"http:\\\\/\\\\/www.apache.org\\\\/licenses\\\\/LICENSE-2.0.html\\\"},\\\"contact\\\":{\\\"email\\\":\\\"architecture@pizzashack.com\\\",\\\"name\\\":\\\"John Doe\\\",\\\"url\\\":\\\"http:\\\\/\\\\/www.pizzashack.com\\\"},\\\"version\\\":\\\"2.0.0\\\"}}\",\r\n \"wsdlUri\": null,\r\n \"status\": \"CREATED\",\r\n \"responseCaching\": \"Disabled\",\r\n \"cacheTimeout\": 300,\r\n \"destinationStatsEnabled\": null,\r\n \"isDefaultVersion\": false,\r\n \"type\": \"HTTP\",\r\n \"transport\": [\"https\"],\r\n \"tags\": [\r\n \"chicken\",\r\n \"pizza\"\r\n ],\r\n \"tiers\": [\"Unlimited\"],\r\n \"maxTps\": {\r\n \"sandbox\": 500,\r\n \"production\": 100\r\n },\r\n \"thumbnailUri\": null,\r\n \"visibility\": \"PUBLIC\",\r\n \"visibleRoles\": [],\\r\n \"endpointConfig\": \"{\\\"production_endpoints\\\":{\\\"url\\\":\\\"https://localhost:9443/am/sample/pizzashack/v1/api/\\\",\\\"config\\\":null},\\\"sandbox_endpoints\\\":{\\\"url\\\":\\\"https://localhost:9443/am/sample/pizzashack/v1/api/\\\",\\\"config\\\":null},\\\"endpoint_type\\\":\\\"http\\\"}\",\r\n \"endpointSecurity\": {\r\n \"username\": \"user\",\r\n \"type\": \"basic\",\r\n \"password\": \"pass\"\r\n },\r\n \"gatewayEnvironments\": \"Production and Sandbox\",\r\n \"sequences\": [],\r\n \"subscriptionAvailability\": null,\r\n \"subscriptionAvailableTenants\": [],\r\n \"businessInformation\": {\r\n \"businessOwnerEmail\": \"marketing@pizzashack.com\",\r\n \"technicalOwnerEmail\": \"architecture@pizzashack.com\",\r\n \"technicalOwner\": \"John Doe\",\r\n \"businessOwner\": \"Jane Roe\"\r\n },\r\n \"corsConfiguration\": {\r\n \"accessControlAllowOrigins\": [\"*\"],\r\n \"accessControlAllowHeaders\": [\r\n \"authorization\",\r\n \"Access-Control-Allow-Origin\",\r\n \"Content-Type\",\r\n \"SOAPAction\"\r\n ],\r\n \"accessControlAllowMethods\": [\r\n \"GET\",\r\n \"PUT\",\r\n \"POST\",\r\n \"DELETE\",\r\n \"PATCH\",\r\n \"OPTIONS\"\r\n ],\r\n \"accessControlAllowCredentials\": false,\r\n \"corsConfigurationEnabled\": false\r\n }\r\n}" + summary: Create a new API version description: | - Create a new API by copying an existing API + This operation can be used to create a new version of an existing API. The new version is specified as `newVersion` query parameter. New API will be in `CREATED` state. parameters: - name: newVersion description: Version of the new API. @@ -663,7 +730,7 @@ paths: required: true - $ref: '#/parameters/apiId-Q' tags: - - APIs + - API (Individual) responses: 201: description: | @@ -684,6 +751,9 @@ paths: description: | Not Found. API to copy does not exist. + 401: + description: | + Unauthenticated request. schema: $ref: '#/definitions/Error' @@ -697,11 +767,18 @@ paths: #----------------------------------------------------- post: x-scope: apim:api_publish - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -X POST \"http://127.0.0.1:9763/api/am/publisher/v0.10/apis/change-lifecycle?apiId=890a4f4d-09eb-4877-a323-57f6ce2ed79b&action=Publish\"" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -X POST \"https://localhost:9443/api/am/publisher/v0.12/apis/change-lifecycle?apiId=890a4f4d-09eb-4877-a323-57f6ce2ed79b&action=Publish\"" + x-wso2-request: | + POST https://localhost:9443/api/am/publisher/v0.12/apis/change-lifecycle?apiId=890a4f4d-09eb-4877-a323-57f6ce2ed79b&action=Publish + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 x-wso2-response: "HTTP/1.1 200 OK" summary: Change API Status description: | - Change the lifecycle of an API + This operation is used to change the lifecycle of an API. Eg: Publish an API which is in `CREATED` state. In order to change the lifecycle, we need to provide the lifecycle `action` as a query parameter. + + For example, to Publish an API, `action` should be `Publish`. Note that the `Re-publish` action is available only after calling `Block`. + + Some actions supports providing additional paramters which should be provided as `lifecycleChecklist` parameter. Please see parameters table for more information. parameters: - name: action description: | @@ -724,23 +801,23 @@ paths: - name: lifecycleChecklist description: | - You can specify additional checklist items by using an **"attribute:"** modifier. - - Eg: "Deprecate Old Versions:true" will deprecate older versions of a particular API when it is promoted to - Published state from Created state. Multiple checklist items can be given in "attribute1:true, attribute2:false" - format. - Supported checklist items are as follows. 1. **Deprecate Old Versions**: Setting this to true will deprecate older versions of a particular API when it is promoted to Published state from Created state. 2. **Require Re-Subscription**: If you set this to true, users need to re subscribe to the API although they may have subscribed to an older version. + You can specify additional checklist items by using an **"attribute:"** modifier. + + Eg: "Deprecate Old Versions:true" will deprecate older versions of a particular API when it is promoted to Published state from Created state. Multiple checklist items can be given in "attribute1:true, attribute2:false" format. + + **Sample CURL :** curl -k -H "Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8" -X POST "https://localhost:9443/api/am/publisher/v0.12/apis/change-lifecycle?apiId=890a4f4d-09eb-4877-a323-57f6ce2ed79b&action=Publish&lifecycleChecklist=Deprecate Old Versions:true,Require Re-Subscription:true" + type: string in: query - $ref: '#/parameters/apiId-Q' - $ref: '#/parameters/If-Match' - $ref: '#/parameters/If-Unmodified-Since' tags: - - APIs + - API (Individual) responses: 200: description: | @@ -749,12 +826,12 @@ paths: headers: ETag: description: | - Entity Tag of the changed API. Used by caches, or in conditional request. + Entity Tag of the changed API. Used by caches, or in conditional requests (Will be supported in future). type: string Last-Modified: description: | Date and time the API lifecycle has been modified the last time. - Used by caches, or in conditional requests. + Used by caches, or in conditional requests (Will be supported in future). type: string 400: description: | @@ -785,11 +862,14 @@ paths: #----------------------------------------------------- get: x-scope: apim:api_view - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" \"http://127.0.0.1:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents\"" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" \"https://localhost:9443/api/am/publisher/v0.12/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents\"" + x-wso2-request: | + GET https://localhost:9443/api/am/publisher/v0.12/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"previous\": \"\",\n \"list\": [\n {\n \"visibility\": \"API_LEVEL\",\n \"sourceType\": \"INLINE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"documentId\": \"0bcb7f05-599d-4e1a-adce-5cb89bfe58d5\",\n \"summary\": \"This is a sample documentation for v1.0.0\",\n \"name\": \"PhoneVerification API Documentation\",\n \"type\": \"HOWTO\"\n },\n {\n \"visibility\": \"API_LEVEL\",\n \"sourceType\": \"URL\",\n \"sourceUrl\": \"http://wiki.cdyne.com/index.php/Phone_Verification\",\n \"otherTypeName\": null,\n \"documentId\": \"4145df31-04f1-440c-8d08-68952874622c\",\n \"summary\": \"This is the URL for online documentation\",\n \"name\": \"Online Documentation\",\n \"type\": \"SAMPLES\"\n }\n ],\n \"next\": \"\",\n \"count\": 2\n}" - summary: Get API Documents + summary: Get a list of documents of an API description: | - Get a list of documents belonging to an API. + This operation can be used to retrive a list of documents belonging to an API by providing the id of the API. parameters: - $ref: '#/parameters/apiId' - $ref: '#/parameters/limit' @@ -797,7 +877,7 @@ paths: - $ref: '#/parameters/Accept' - $ref: '#/parameters/If-None-Match' tags: - - API Document + - Document (Collection) responses: 200: description: | @@ -812,12 +892,12 @@ paths: type: string ETag: description: | - Entity Tag of the response resource. Used by caches, or in conditional requests. + Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future). type: string 304: description: | Not Modified. - Empty body because the client has already the latest version of the requested resource. + Empty body because the client has already the latest version of the requested resource (Will be supported in future). 404: description: | Not Found. @@ -836,12 +916,12 @@ paths: #----------------------------------------------------- post: x-scope: apim:api_create - x-wso2-curl: "curl -H \"Authorization: Bearer cdcc8cf6016ed10620edf3a1d3c5ef2b\" -H \"Content-Type: application/json\" -X POST -d @data.json \"http://127.0.0.1:9763/api/am/publisher/v0.10/apis/96077508-fd01-4fae-bc64-5de0e2baf43c/documents\"" - x-wso2-request: "{\n \"visibility\": \"API_LEVEL\",\n \"sourceType\": \"INLINE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"summary\": \"This is a sample documentation\",\n \"name\": \"Introduction to PhoneVerification API\",\n \"type\": \"HOWTO\"\n}" - x-wso2-response: "HTTP/1.1 201 Created\nLocation: http://localhost:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/ffd5790d-b7a9-4cb6-b76a-f8b83ecdd058\nContent-Type: application/json\n\n{\n \"visibility\": \"API_LEVEL\",\n \"sourceType\": \"INLINE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"documentId\": \"ffd5790d-b7a9-4cb6-b76a-f8b83ecdd058\",\n \"summary\": \"This is a sample documentation\",\n \"name\": \"Introduction to PhoneVerification API\",\n \"type\": \"HOWTO\"\n}" - summary: Add a new document + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -H \"Content-Type: application/json\" -X POST -d @data.json \"https://localhost:9443/api/am/publisher/v0.12/apis/96077508-fd01-4fae-bc64-5de0e2baf43c/documents\"" + x-wso2-request: "POST https://localhost:9443/api/am/publisher/v0.12/apis/96077508-fd01-4fae-bc64-5de0e2baf43c/documents\nAuthorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\nContent-Type: application/json\n\n{\n \"visibility\": \"API_LEVEL\",\n \"sourceType\": \"INLINE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"summary\": \"This is a sample documentation\",\n \"name\": \"Introduction to PhoneVerification API\",\n \"type\": \"HOWTO\"\n}" + x-wso2-response: "HTTP/1.1 201 Created\nLocation: https://localhost:9443/api/am/publisher/v0.12/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/ffd5790d-b7a9-4cb6-b76a-f8b83ecdd058\nContent-Type: application/json\n\n{\n \"visibility\": \"API_LEVEL\",\n \"sourceType\": \"INLINE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"documentId\": \"ffd5790d-b7a9-4cb6-b76a-f8b83ecdd058\",\n \"summary\": \"This is a sample documentation\",\n \"name\": \"Introduction to PhoneVerification API\",\n \"type\": \"HOWTO\"\n}" + summary: Add a new document to an API description: | - Add a new document to an API + This operation can be used to add a new documentation to an API. This operation only adds the metadata of a document. To add the actual content we need to use **Upload the content of an API document ** API once we obtain a document Id by this operation. parameters: - $ref: '#/parameters/apiId' - in: body @@ -853,7 +933,7 @@ paths: $ref: '#/definitions/Document' - $ref: '#/parameters/Content-Type' tags: - - API Document + - Document (Collection) responses: 201: description: | @@ -874,7 +954,7 @@ paths: ETag: description: | Entity Tag of the response resource. - Used by caches, or in conditional request. + Used by caches, or in conditional requests (Will be supported in future). type: string 400: description: | @@ -897,11 +977,14 @@ paths: #----------------------------------------------------- get: x-scope: apim:api_view - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" \"http://127.0.0.1:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/0bcb7f05-599d-4e1a-adce-5cb89bfe58d5\"" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" \"https://localhost:9443/api/am/publisher/v0.12/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/0bcb7f05-599d-4e1a-adce-5cb89bfe58d5\"" + x-wso2-request: | + GET https://localhost:9443/api/am/publisher/v0.12/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/0bcb7f05-599d-4e1a-adce-5cb89bfe58d5 + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"visibility\": \"API_LEVEL\",\n \"sourceType\": \"INLINE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"documentId\": \"0bcb7f05-599d-4e1a-adce-5cb89bfe58d5\",\n \"summary\": \"This is a sample documentation\",\n \"name\": \"PhoneVerification API Documentation\",\n \"type\": \"HOWTO\"\n}" - summary: Get an API Document + summary: Get a document of an API description: | - Get a particular document associated with an API. + This operation can be used to retrieve a particular document's metadata associated with an API. parameters: - $ref: '#/parameters/apiId' - $ref: '#/parameters/documentId' @@ -909,7 +992,7 @@ paths: - $ref: '#/parameters/If-None-Match' - $ref: '#/parameters/If-Modified-Since' tags: - - API Document + - Document (Individual) responses: 200: description: | @@ -925,17 +1008,17 @@ paths: ETag: description: | Entity Tag of the response resource. - Used by caches, or in conditional requests. + Used by caches, or in conditional requests (Will be supported in future). type: string Last-Modified: description: | Date and time the resource has been modifed the last time. - Used by caches, or in conditional reuquests. + Used by caches, or in conditional requests (Will be supported in future). type: string 304: description: | Not Modified. - Empty body because the client has already the latest version of the requested resource. + Empty body because the client has already the latest version of the requested resource (Will be supported in future). 404: description: | Not Found. @@ -954,12 +1037,12 @@ paths: #----------------------------------------------------- put: x-scope: apim:api_create - x-wso2-curl: "curl -k -H \"Authorization:Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -H \"Content-Type: application/json\" -X PUT -d data.json \"http://127.0.0.1:9763/api/am/publisher/v0.10/apis/96077508-fd01-4fae-bc64-5de0e2baf43c/documents/0bcb7f05-599d-4e1a-adce-5cb89bfe58d5\"" - x-wso2-request: "{\n \"visibility\": \"API_LEVEL\",\n \"sourceType\": \"INLINE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"documentId\": \"0bcb7f05-599d-4e1a-adce-5cb89bfe58d5\",\n \"summary\": \"This is a sample documentation for v1.0.0\",\n \"name\": \"PhoneVerification API Documentation\",\n \"type\": \"HOWTO\"\n}" + x-wso2-curl: "curl -k -H \"Authorization:Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -H \"Content-Type: application/json\" -X PUT -d data.json \"https://localhost:9443/api/am/publisher/v0.12/apis/96077508-fd01-4fae-bc64-5de0e2baf43c/documents/0bcb7f05-599d-4e1a-adce-5cb89bfe58d5\"" + x-wso2-request: "PUT https://localhost:9443/api/am/publisher/v0.12/apis/96077508-fd01-4fae-bc64-5de0e2baf43c/documents/0bcb7f05-599d-4e1a-adce-5cb89bfe58d5\nAuthorization:Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\nContent-Type: application/json\n\n{\n \"visibility\": \"API_LEVEL\",\n \"sourceType\": \"INLINE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"documentId\": \"0bcb7f05-599d-4e1a-adce-5cb89bfe58d5\",\n \"summary\": \"This is a sample documentation for v1.0.0\",\n \"name\": \"PhoneVerification API Documentation\",\n \"type\": \"HOWTO\"\n}" x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"visibility\": \"API_LEVEL\",\n \"sourceType\": \"INLINE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"documentId\": \"0bcb7f05-599d-4e1a-adce-5cb89bfe58d5\",\n \"summary\": \"This is a sample documentation for v1.0.0\",\n \"name\": \"PhoneVerification API Documentation\",\n \"type\": \"HOWTO\"\n}" - summary: Update an API Document + summary: Update a document of an API description: | - Update document details. + This operation can be used to update metadata of an API's document. parameters: - $ref: '#/parameters/apiId' - $ref: '#/parameters/documentId' @@ -974,7 +1057,7 @@ paths: - $ref: '#/parameters/If-Match' - $ref: '#/parameters/If-Unmodified-Since' tags: - - API Document + - Document (Individual) responses: 200: description: | @@ -994,12 +1077,12 @@ paths: ETag: description: | Entity Tag of the response resource. - Used by caches, or in conditional request. + Used by caches, or in conditional requests (Will be supported in future). type: string Last-Modified: description: | Date and time the resource has been modifed the last time. - Used by caches, or in conditional reuquests. + Used by caches, or in conditional requests (Will be supported in future). type: string 400: description: | @@ -1025,18 +1108,21 @@ paths: #----------------------------------------------------- delete: x-scope: apim:api_create - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -X DELETE http://127.0.0.1:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/ffd5790d-b7a9-4cb6-b76a-f8b83ecdd058" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -X DELETE https://localhost:9443/api/am/publisher/v0.12/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/ffd5790d-b7a9-4cb6-b76a-f8b83ecdd058" + x-wso2-request: | + DELETE https://localhost:9443/api/am/publisher/v0.12/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/ffd5790d-b7a9-4cb6-b76a-f8b83ecdd058 + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 x-wso2-response: "HTTP/1.1 200 OK" - summary: Delete an API Document + summary: Delete a document of an API description: | - Delete a document of an API + This operation can be used to delete a document associated with an API. parameters: - $ref: '#/parameters/apiId' - $ref: '#/parameters/documentId' - $ref: '#/parameters/If-Match' - $ref: '#/parameters/If-Unmodified-Since' tags: - - API Document + - Document (Individual) responses: 200: description: | @@ -1066,11 +1152,25 @@ paths: #------------------------------------------------------------------------------------------------- get: x-scope: apim:api_view - x-wso2-curl: "curl -k -H \"Authorization:Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" \"http://127.0.0.1:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/daf732d3-bda2-46da-b381-2c39d901ea61/content\" > sample.pdf" + x-wso2-curl: "curl -k -H \"Authorization:Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" \"https://localhost:9443/api/am/publisher/v0.12/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/daf732d3-bda2-46da-b381-2c39d901ea61/content\" > sample.pdf" + x-wso2-request: | + GET https://localhost:9443/api/am/publisher/v0.12/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/daf732d3-bda2-46da-b381-2c39d901ea61/content + Authorization:Bearer b0982cd2aacd463ff5f63cd5ebe58f4a x-wso2-response: "HTTP/1.1 200 OK\nContent-Disposition: attachment; filename=\"sample.pdf\"\nContent-Type: application/octet-stream\nContent-Length: 7802\n\n%PDF-1.4\n%äüöß\n2 0 obj\n<>\nstream\n..\n>>\nstartxref\n7279\n%%EOF" - summary: Get document content + summary: Get the content of an API document description: | - Downloads a FILE type document/get the inline content or source url of a certain document. + This operation can be used to retrive the content of an API's document. + + The document can be of 3 types. In each cases responses are different. + + 1. **Inline type**: + The content of the document will be retrieved in `text/plain` content type + + _Sample cURL_ : `curl -k -H "Authorization:Bearer 579f0af4-37be-35c7-81a4-f1f1e9ee7c51" -F inlineContent=@"docs.txt" -X POST "https://localhost:9443/api/am/publisher/v0.12/apis/995a4972-3178-4b17-a374-756e0e19127c/documents/43c2bcce-60e7-405f-bc36-e39c0c5e189e/content` + 2. **FILE type**: + The file will be downloaded with the related content type (eg. `application/pdf`) + 3. **URL type**: + The client will recieve the URL of the document as the Location header with the response with - `303 See Other` parameters: - $ref: '#/parameters/apiId' - $ref: '#/parameters/documentId' @@ -1078,7 +1178,7 @@ paths: - $ref: '#/parameters/If-None-Match' - $ref: '#/parameters/If-Modified-Since' tags: - - API Document + - Document (Individual) responses: 200: description: | @@ -1092,12 +1192,12 @@ paths: ETag: description: | Entity Tag of the response resource. - Used by caches, or in conditional requests. + Used by caches, or in conditional requests (Will be supported in future). type: string Last-Modified: description: | Date and time the resource has been modifed the last time. - Used by caches, or in conditional reuquests. + Used by caches, or in conditional requests (Will be supported in future). type: string 303: description: | @@ -1111,7 +1211,7 @@ paths: 304: description: | Not Modified. - Empty body because the client has already the latest version of the requested resource. + Empty body because the client has already the latest version of the requested resource (Will be supported in future). 404: description: | Not Found. @@ -1132,16 +1232,29 @@ paths: consumes: - multipart/form-data x-scope: apim:api_create - x-wso2-curl: "curl -k -H \"Authorization:Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -F file=@\"sample.pdf\" -X POST \"http://127.0.0.1:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/daf732d3-bda2-46da-b381-2c39d901ea61/content\"" - x-wso2-response: "HTTP/1.1 201 Created\nLocation: http://localhost:9763/api/am/publisher/v0.10/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/daf732d3-bda2-46da-b381-2c39d901ea61/content\nContent-Type: application/json\n\n{\n \"visibility\":\"API_LEVEL\",\n \"sourceType\":\"FILE\",\n \"sourceUrl\":null,\n \"otherTypeName\":null,\n \"documentId\":\"daf732d3-bda2-46da-b381-2c39d901ea61\",\n \"summary\":\"This is a sample documentation pdf\",\n \"name\":\"Introduction to PhoneVerification API PDF\",\n \"type\":\"HOWTO\"\n}" - summary: Update API document content. + x-wso2-curl: "curl -k -H \"Authorization:Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -F file=@\"sample.pdf\" -X POST \"https://localhost:9443/api/am/publisher/v0.12/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/daf732d3-bda2-46da-b381-2c39d901ea61/content\"" + x-wso2-request: | + POST https://localhost:9443/api/am/publisher/v0.12/apis/8848faaa-7fd1-478a-baa2-48a4ebb92c98/documents/b3a79270-02bb-4e39-9ac1-90ce8f6c84af/content + Authorization:Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 + Content-Length: 8004 + Content-Type: multipart/form-data; boundary=------------------------7b9a53f1ffa452b9 + + --------------------------7b9a53f1ffa452b9 + Content-Disposition: form-data; name="file"; filename="sample.pdf" + Content-Type: application/octet-stream + + [file content] + + --------------------------7b9a53f1ffa452b9-- + x-wso2-response: "HTTP/1.1 201 Created\nLocation: https://localhost:9443/api/am/publisher/v0.12/apis/8848faaa-7fd1-478a-baa2-48a4ebb92c98/documents/b3a79270-02bb-4e39-9ac1-90ce8f6c84af/content\nContent-Type: application/json\n\n{\n \"visibility\":\"API_LEVEL\",\n \"sourceType\":\"FILE\",\n \"sourceUrl\":null,\n \"otherTypeName\":null,\n \"documentId\":\"daf732d3-bda2-46da-b381-2c39d901ea61\",\n \"summary\":\"This is a sample documentation pdf\",\n \"name\":\"Introduction to PhoneVerification API PDF\",\n \"type\":\"HOWTO\"\n}" + summary: Upload the content of an API document description: | - Upload a file to a document or add inline content to the document. + Thid operation can be used to upload a file or add inline content to an API document. - Document's source type should be **FILE** in order to upload a file to the document using **file** parameter. - Document's source type should be **INLINE** in order to add inline content to the document using **inlineContent** parameter. - - Only one of **file** or **inlineContent** can be specified at one time. + **IMPORTANT:** + * Either **file** or **inlineContent** form data parameters should be specified at one time. + * Document's source type should be **FILE** in order to upload a file to the document using **file** parameter. + * Document's source type should be **INLINE** in order to add inline content to the document using **inlineContent** parameter. parameters: - $ref: '#/parameters/apiId' - $ref: '#/parameters/documentId' @@ -1159,7 +1272,7 @@ paths: - $ref: '#/parameters/If-Match' - $ref: '#/parameters/If-Unmodified-Since' tags: - - API Document + - Document (Individual) responses: 200: description: | @@ -1179,12 +1292,137 @@ paths: ETag: description: | Entity Tag of the response resource. - Used by caches, or in conditional request. + Used by caches, or in conditional requests (Will be supported in future). + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional requests (Will be supported in future). + type: string + 400: + description: | + Bad Request. + Invalid request or validation error. + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + The resource to be updated does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + + ##pp +###################################################### +# The "specific mediation policy" resource APIs +###################################################### + '/apis/{apiId}/policies/mediation': + + #----------------------------------------------------------------------------------------- + # Retrieving the list of all API specific mediation sequences under a given search condition + #----------------------------------------------------------------------------------------- + get: + x-scope: apim:api_view + x-wso2-curl: "curl -k -H \"Authorization: Bearer fb2a0784-f60c-3276-8fde-5b0f70e61ecc\" https://localhost:9443/api/am/publisher/v0.12/apis/40082986-6488-4b86-801a-b0b069d4588c/policies/mediation" + x-wso2-request: "GET https://localhost:9443/api/am/publisher/v0.12/apis/40082986-6488-4b86-801a-b0b069d4588c/policies/mediation\r\nAuthorization: Bearer fb2a0784-f60c-3276-8fde-5b0f70e61ecc" + x-wso2-response: "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{\r\n \"count\": 1,\r\n \"next\": null,\r\n \"previous\": null,\r\n \"list\": [ {\r\n \"name\": \"add_custom_header_fault\",\r\n \"id\": \"6460d7e6-4272-4e3a-9879-437228d83123\",\r\n \"type\": \"fault\"\r\n }]\r\n}" + summary: | + Get all mediation policies of an API + description: | + This operation provides you a list of available mediation policies of an API. + parameters: + - $ref: '#/parameters/apiId' + - $ref : '#/parameters/limit' + - $ref : '#/parameters/offset' + - name : query + in: query + description: "-Not supported yet-" + type: string + - $ref : "#/parameters/Accept" + - $ref : "#/parameters/If-None-Match" + tags: + - Mediation Policy (Collection) + responses: + 200: + description: | + OK. + List of qualifying APIs is returned. + schema: + $ref: '#/definitions/mediationList' + headers: + Content-Type: + description: The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future). + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource (Will be supported in future). + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +#---------------------------------------------------------------------------- +# Upload an API specific mediation policy +#---------------------------------------------------------------------------- + post: + x-scope: apim:api_create + x-wso2-curl: "curl -k -H \"Authorization: Bearer 6cea3696-0151-3282-bf79-a0c4db6f308a\" -H \"Content-Type: application/json\" -X POST -d @data.json \"https://localhost:9443/api/am/publisher/v0.12/apis/40082986-6488-4b86-801a-b0b069d4588c/policies/mediation\"" + x-wso2-request: "POST https://localhost:9443/api/am/publisher/v0.12/apis/40082986-6488-4b86-801a-b0b069d4588c/policies/mediation\r\nContent-Type: application/json\r\nAuthorization: Bearer 6cea3696-0151-3282-bf79-a0c4db6f308a\r\n\r\n{\r\n \"name\": \"add_custom_header_fault\",\r\n \"type\": \"fault\",\r\n \"config\": \"\\n \\n<\\/sequence>\\n\"\r\n}" + x-wso2-response: "HTTP/1.1 201 Created\r\nLocation: https://localhost:9443/api/am/publisher/v0.12/registry/resource/_system/governance/apimgt/applicationdata/provider/admin/hello/1.0.0/fault/add_custom_header_fault.xml\r\nContent-Type: application/json\r\n\r\n{ \r\n \"id\":\"624b9f7d-bfaf-484b-94cc-e84491f5d725\",\r\n \"name\":\"add_custom_header_fault\",\r\n \"type\":\"fault\",\r\n \"config\":\"\\n \\n\\n\"\r\n}" + summary: Add an API specific mediation policy + description: | + This operation can be used to add an API specifc mediation policy. + parameters: + - in: body + name: body + description: mediation policy to upload + required: true + schema: + $ref: '#/definitions/Mediation' + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/Content-Type' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + tags: + - Mediation Policy (Collection) + responses: + 200: + description: | + OK. + mediation policy uploaded + schema: + $ref : '#/definitions/Mediation' + headers: + Location: + description: | + The URL of the uploaded thumbnail image of the API. + type: string + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional requests (Will be supported in future). type: string Last-Modified: description: | Date and time the resource has been modifed the last time. - Used by caches, or in conditional reuquests. + Used by caches, or in conditional requests (Will be supported in future). type: string 400: description: | @@ -1205,6 +1443,324 @@ paths: schema: $ref: '#/definitions/Error' +###################################################### +# The "Individual API specific mediation sequence" resource +###################################################### + /apis/{apiId}/policies/mediation/{mediationPolicyId}: + +#----------------------------------------------------- +# Retrieve a particular API specific mediation squence +#----------------------------------------------------- + get: + x-scope: apim:api_view + x-wso2-curl: "curl -k -H \"Authorization: Bearer 5aa0acc0-0ce3-3a0b-8cc8-db5ef696ee23\" https://localhost:9443/api/am/publisher/v0.12/apis/40082986-6488-4b86-801a-b0b069d4588c/policies/mediation/624b9f7d-bfaf-484b-94cc-e84491f5d725" + x-wso2-request: "GET https://localhost:9443/api/am/publisher/v0.12/apis/40082986-6488-4b86-801a-b0b069d4588c/policies/mediation/624b9f7d-bfaf-484b-94cc-e84491f5d725\r\nAuthorization: Bearer 5aa0acc0-0ce3-3a0b-8cc8-db5ef696ee23" + x-wso2-response: "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{\r\n \"id\": \"624b9f7d-bfaf-484b-94cc-e84491f5d725\",\r\n \"name\": \"add_custom_header_fault\",\r\n \"type\": \"fault\",\r\n \"config\": \"\\n \\n<\\/sequence>\\n\"\r\n}" + summary: Get an API specific mediation policy + description: | + This operation can be used to retrieve a particular API specific mediation policy. + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/mediationPolicyId' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + - $ref: '#/parameters/If-Modified-Since' + tags: + - Mediation Policy (Individual) + responses: + 200: + description: | + OK. + Mediation policy returned. + schema: + $ref: '#/definitions/Mediation' + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. + Used by caches, or in conditional requests (Will be supported in future). + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional requests (Will be supported in future). + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource (Will be supported in future). + 404: + description: | + Not Found. + Requested Document does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + +#----------------------------------------------------- +# Delete the mediation policy +#----------------------------------------------------- + delete: + x-scope: apim:api_create + x-wso2-curl: "curl -k -H \"Authorization: Bearer fb2a0784-f60c-3276-8fde-5b0f70e61ecc\" -X DELETE https://localhost:9443/api/am/publisher/v0.12/apis/40082986-6488-4b86-801a-b0b069d4588c/policies/mediation/60f5146d-1774-405d-86b3-9b040ac266d5" + x-wso2-request: "DELETE https://localhost:9443/api/am/publisher/v0.12/apis/40082986-6488-4b86-801a-b0b069d4588c/policies/mediation/60f5146d-1774-405d-86b3-9b040ac266d5\r\nAuthorization: Bearer fb2a0784-f60c-3276-8fde-5b0f70e61ecc" + x-wso2-response: "HTTP/1.1 200 OK" + summary: Delete an API specific mediation policy + description: | + This operation can be used to delete an existing API specific mediation policy providing the Id of the API and the Id of the mediation policy. + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/mediationPolicyId' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + tags: + - Mediation Policy (Individual) + responses: + 200: + description: | + OK. + Resource successfully deleted. + 403: + description: | + Forbidden. + The request must be conditional but no condition has been specified. + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + Resource to be deleted does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + +#----------------------------------------------------- +# Update the a mediation policy +#----------------------------------------------------- + put: + x-scope: apim:api_create + x-wso2-curl: "curl -k -H \"Authorization: Bearer 9e41fae2-3ada-3dd1-8f12-2077202f4285\" -H \"Content-Type: application/json\" -X PUT -d @data.json https://localhost:9443/api/am/publisher/v0.12/apis/40082986-6488-4b86-801a-b0b069d4588c/policies/mediation/820fdcf7-7258-42b5-809e-674b893644d1" + x-wso2-request: "PUT https://localhost:9443/api/am/publisher/v0.12/apis/40082986-6488-4b86-801a-b0b069d4588c/policies/mediation/820fdcf7-7258-42b5-809e-674b893644d1\r\nContent-Type: application/json\r\nAuthorization: Bearer 9e41fae2-3ada-3dd1-8f12-2077202f4285\r\n\r\n{\r\n \"name\": \"add_custom_header_fault\",\r\n \"type\": \"fault\",\r\n \"config\": \"\\n \\n<\\/sequence>\\n\"\r\n}" + x-wso2-response: "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{\r\n \"id\": \"a7365481-5b3f-463c-a646-a498895ac210\",\r\n \"name\": \"add_custom_header_fault\",\r\n \"type\": \"fault\",\r\n \"config\": \"\\n \\n<\\/sequence>\\n\"\r\n}" + summary: Update an API specific mediation policy + description: | + This operation can be used to update an existing mediation policy of an API. + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/mediationPolicyId' + - in: body + name: body + description: | + Mediation policy object that needs to be updated + required: true + schema: + $ref: '#/definitions/Mediation' + - $ref: '#/parameters/Content-Type' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + tags: + - Mediation Policy (Individual) + responses: + 200: + description: | + OK. + Successful response with updated API object + schema: + $ref: '#/definitions/Mediation' + headers: + Location: + description: | + The URL of the newly created resource. + type: string + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future). + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional requests (Will be supported in future). + type: string + 400: + description: | + Bad Request. + Invalid request or validation error + schema: + $ref: '#/definitions/Error' + 403: + description: | + Forbidden. + The request must be conditional but no condition has been specified. + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + The resource to be updated does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + +###################################################### +# The wsdl Resource +###################################################### + /apis/{apiId}/wsdl: + +#----------------------------------------------------- +# Retrieve the details about a certain wsdl +#----------------------------------------------------- + get: + x-scope: apim:api_view + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" \"https://localhost:9443/api/am/publisher/v0.12/apis/7f82f6b0-2667-441e-af23-c0fc44cf3a17/wsdl\"" + x-wso2-request: | + GET https://localhost:9443/api/am/publisher/v0.12/apis/7f82f6b0-2667-441e-af23-c0fc44cf3a17/wsdl + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 + x-wso2-response: "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{\r\n \"name\": \"admin--hello1.0.0.wsdl\",\r\n \"wsdlDefinition\": \"\\n \\n \\n <\\/part>\\n <\\/message>\\n \\n \\n <\\/part>\\n <\\/message>\\n \\n \\n \\n <\\/input>\\n \\n <\\/output>\\n <\\/operation>\\n <\\/portType>\\n \\n \\n \\n \\n \\n \\n <\\/input>\\n \\n \\n <\\/output>\\n <\\/operation>\\n <\\/binding>\\n \\nWSDL File for HelloService<\\/documentation>\\n \\n \\n <\\/port>\\n <\\/service>\\n<\\/definitions>\"\r\n}" + summary: Get the WSDL of an API + description: | + This operation can be used to retrieve the WSDL definition of an API. + parameters: + - $ref: '#/parameters/apiId' + - $ref: '#/parameters/Accept' + - $ref: '#/parameters/If-None-Match' + - $ref: '#/parameters/If-Modified-Since' + tags: + - Wsdl (Individual) + responses: + 200: + description: | + OK. + Requested WSDL DTO object belongs to the API + schema: + $ref: '#/definitions/Wsdl' + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future). + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional requests (Will be supported in future). + type: string + + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource (Will be supported in future). + 404: + description: | + Not Found. + Requested API does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' +#----------------------------------------------------- +# Add a wsdl to the registry +#----------------------------------------------------- + post: + x-scope: apim:api_create + x-wso2-curl: "curl -k -H \"Authorization:Bearer 5311eca3-8ac8-354e-ab36-7e2fdd6a4013\" -H \"Content-Type: application/json\" -X POST -d @data.json \"https://localhost:9443/api/am/publisher/v0.12/apis/af3f96da-9ccf-463f-8cee-13ec8530a9cd/wsdl\"" + x-wso2-request: "POST https://localhost:9443/api/am/publisher/v0.12/apis/af3f96da-9ccf-463f-8cee-13ec8530a9cd/wsdl\r\nContent-Type: application/json\r\nAuthorization: Bearer 7d237cab-7011-3f81-b384-24d03e750873\r\n\r\n{\r\n \"name\": \"admin--PizzaShackAPI1.0.0.wsdl\",\r\n \"wsdlDefinition\": \"\\n \\n \\n <\\/part>\\n <\\/message>\\n \\n \\n <\\/part>\\n <\\/message>\\n \\n \\n \\n <\\/input>\\n \\n <\\/output>\\n <\\/operation>\\n <\\/portType>\\n \\n \\n \\n \\n \\n \\n <\\/input>\\n \\n \\n <\\/output>\\n <\\/operation>\\n <\\/binding>\\n \\nWSDL File for HelloService<\\/documentation>\\n \\n \\n <\\/port>\\n <\\/service>\\n<\\/definitions>\"\r\n}" + x-wso2-response: "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{\r\n \"name\": \"admin--PizzaShackAPI1.0.0.wsdl\",\r\n \"wsdlDefinition\": \"\\n \\n \\n <\\/part>\\n <\\/message>\\n \\n \\n <\\/part>\\n <\\/message>\\n \\n \\n \\n <\\/input>\\n \\n <\\/output>\\n <\\/operation>\\n <\\/portType>\\n \\n \\n \\n \\n \\n \\n <\\/input>\\n \\n \\n <\\/output>\\n <\\/operation>\\n <\\/binding>\\n \\nWSDL File for HelloService<\\/documentation>\\n \\n \\n <\\/port>\\n <\\/service>\\n<\\/definitions>\"\r\n}" + summary: Add a WSDL to an API + description: | + This operation can be used to add a WSDL definition to an existing API. + parameters: + - $ref: '#/parameters/apiId' + - in: body + name: body + description: | + JSON payload including WSDL definition that needs to be added + required: true + schema: + $ref: '#/definitions/Wsdl' + - $ref: '#/parameters/Content-Type' + - $ref: '#/parameters/If-Match' + - $ref: '#/parameters/If-Unmodified-Since' + tags: + - Wsdl (Individual) + responses: + 200: + description: | + OK. + Successful response with updated wsdl definition + headers: + Location: + description: | + The URL of the newly created resource. + type: string + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future). + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional requests (Will be supported in future). + type: string + 400: + description: | + Bad Request. + Invalid request or validation error + schema: + $ref: '#/definitions/Error' + 403: + description: | + Forbidden. + The request must be conditional but no condition has been specified. + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + The resource to be updated does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + + ###################################################### # The "Individual Application" resource APIs ###################################################### @@ -1215,18 +1771,21 @@ paths: #----------------------------------------------------- get: x-scope: apim:api_create - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" http://127.0.0.1:9763/api/am/publisher/v0.10/applications/896658a0-b4ee-4535-bbfa-806c894a4015" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" https://localhost:9443/api/am/publisher/v0.12/applications/896658a0-b4ee-4535-bbfa-806c894a4015" + x-wso2-request: | + GET https://localhost:9443/api/am/publisher/v0.12/applications/896658a0-b4ee-4535-bbfa-806c894a4015 + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"groupId\": \"\",\n \"subscriber\": \"admin\",\n \"throttlingTier\": \"Unlimited\",\n \"applicationId\": \"896658a0-b4ee-4535-bbfa-806c894a4015\",\n \"description\": null,\n \"name\": \"DefaultApplication\"\n}" - summary: Get Application + summary: Get details of an application description: | - Get application details + This operation can be used to retrieve details of an individual application specifying the application id in the URI. parameters: - $ref: '#/parameters/applicationId' - $ref: '#/parameters/Accept' - $ref: '#/parameters/If-None-Match' - $ref: '#/parameters/If-Modified-Since' tags: - - Applications + - Application (Individual) responses: 200: description: | @@ -1241,17 +1800,17 @@ paths: type: string ETag: description: | - Entity Tag of the response resource. Used by caches, or in conditional requests. + Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future). type: string Last-Modified: description: | Date and time the resource has been modifed the last time. - Used by caches, or in conditional reuquests. + Used by caches, or in conditional requests (Will be supported in future). type: string 304: description: | Not Modified. - Empty body because the client has already the latest version of the requested resource. + Empty body because the client has already the latest version of the requested resource (Will be supported in future). 404: description: | Not Found. @@ -1275,13 +1834,20 @@ paths: #----------------------------------------------------- get: x-scope: apim:subscription_view - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" \"http://127.0.0.1:9763/api/am/publisher/v0.10/subscriptions?apiId=890a4f4d-09eb-4877-a323-57f6ce2ed79b\"" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" \"https://localhost:9443/api/am/publisher/v0.12/subscriptions?apiId=890a4f4d-09eb-4877-a323-57f6ce2ed79b\"" + x-wso2-request: | + GET https://localhost:9443/api/am/publisher/v0.12/subscriptions?apiId=890a4f4d-09eb-4877-a323-57f6ce2ed79b + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n \n{\n \"previous\": \"\",\n \"list\": [\n {\n \"subscriptionId\": \"64eca60b-2e55-4c38-8603-e9e6bad7d809\",\n \"tier\": \"Gold\",\n \"apiIdentifier\": \"admin-PhoneVerification-1.0.0\",\n \"applicationId\": \"896658a0-b4ee-4535-bbfa-806c894a4015\",\n \"status\": \"UNBLOCKED\"\n },\n {\n \"subscriptionId\": \"7ac22c34-8745-4cfe-91e0-262c50b2f2e3\",\n \"tier\": \"Gold\",\n \"apiIdentifier\": \"admin-PhoneVerification-1.0.0\",\n \"applicationId\": \"367a2361-8db5-4140-8133-c6c8dc7fa0c4\",\n \"status\": \"UNBLOCKED\"\n }\n ],\n \"next\": \"\",\n \"count\": 2\n}" - summary: Get All Subscriptions + summary: Get all Subscriptions description: | - Get subscription list. - The API Identifier and corresponding Application Identifier - the subscriptions of which are to be returned are passed as parameters. + This operation can be used to retrieve a list of subscriptions of the user associated with the provided access token. This operation is capable of + + 1. Retrieving all subscriptions for the user's APIs. + `GET https://localhost:9443/api/am/publisher/v0.12/subscriptions` + + 2. Retrieving subscriptions for a specific API. + `GET https://localhost:9443/api/am/publisher/v0.12/subscriptions?apiId=c43a325c-260b-4302-81cb-768eafaa3aed` parameters: - $ref: '#/parameters/apiId-Q' - $ref: '#/parameters/limit' @@ -1289,7 +1855,7 @@ paths: - $ref: '#/parameters/Accept' - $ref: '#/parameters/If-None-Match' tags: - - Subscriptions + - Subscription (Collection) responses: 200: description: | @@ -1305,12 +1871,12 @@ paths: ETag: description: | Entity Tag of the response resource. - Used by caches, or in conditional requests. + Used by caches, or in conditional requests (Will be supported in future). type: string 304: description: | Not Modified. - Empty body because the client has already the latest version of the requested resource. + Empty body because the client has already the latest version of the requested resource (Will be supported in future). 406: description: | Not Acceptable. The requested media type is not supported @@ -1327,39 +1893,42 @@ paths: #----------------------------------------------------- get: x-scope: apim:subscription_view - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" http://127.0.0.1:9763/api/am/publisher/v0.10/subscriptions/64eca60b-2e55-4c38-8603-e9e6bad7d809" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" https://localhost:9443/api/am/publisher/v0.12/subscriptions/64eca60b-2e55-4c38-8603-e9e6bad7d809" + x-wso2-request: | + GET https://localhost:9443/api/am/publisher/v0.12/subscriptions/64eca60b-2e55-4c38-8603-e9e6bad7d809 + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"subscriptionId\": \"64eca60b-2e55-4c38-8603-e9e6bad7d809\",\n \"tier\": \"Gold\",\n \"apiIdentifier\": \"admin-PhoneVerification-1.0.0\",\n \"applicationId\": \"896658a0-b4ee-4535-bbfa-806c894a4015\",\n \"status\": \"UNBLOCKED\"\n}" - summary: Get a Subscription + summary: Get details of a subscription description: | - Get subscription details + This operation can be used to get details of a single subscription. parameters: - $ref: '#/parameters/subscriptionId' - $ref: '#/parameters/Accept' - $ref: '#/parameters/If-None-Match' - $ref: '#/parameters/If-Modified-Since' tags: - - Subscriptions + - Subscription (Individual) responses: 200: description: | OK. Subscription returned schema: - $ref: '#/definitions/Subscription' + $ref: '#/definitions/ExtendedSubscription' headers: Content-Type: description: The content type of the body. type: string ETag: - description: 'Entity Tag of the response resource. Used by caches, or in conditional requests.' + description: 'Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future).' type: string Last-Modified: - description: 'Date and time the resource has been modifed the last time. Used by caches, or in conditional reuquests.' + description: 'Date and time the resource has been modifed the last time. Used by caches, or in conditional requests (Will be supported in future).' type: string '304': description: | Not Modified. - Empty body because the client has already the latest version of the requested resource. + Empty body because the client has already the latest version of the requested resource (Will be supported in future). '404': description: | Not Found. @@ -1377,9 +1946,17 @@ paths: #----------------------------------------------------- post: x-scope: apim:subscription_block - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -X POST \"http://127.0.0.1:9763/api/am/publisher/v0.10/subscriptions/block-subscription?subscriptionId=64eca60b-2e55-4c38-8603-e9e6bad7d809&blockState=PROD_ONLY_BLOCKED\"" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -X POST \"https://localhost:9443/api/am/publisher/v0.12/subscriptions/block-subscription?subscriptionId=64eca60b-2e55-4c38-8603-e9e6bad7d809&blockState=PROD_ONLY_BLOCKED\"" + x-wso2-request: | + POST https://localhost:9443/api/am/publisher/v0.12/subscriptions/block-subscription?subscriptionId=64eca60b-2e55-4c38-8603-e9e6bad7d809&blockState=PROD_ONLY_BLOCKED + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n \n{\n \"subscriptionId\": \"64eca60b-2e55-4c38-8603-e9e6bad7d809\",\n \"tier\": \"Gold\",\n \"apiIdentifier\": \"admin-PhoneVerification-1.0.0\",\n \"applicationId\": \"896658a0-b4ee-4535-bbfa-806c894a4015\",\n \"status\": \"PROD_ONLY_BLOCKED\"\n}" summary: Block a subscription + description: | + This operation can be used to block a subscription. Along with the request, `blockState` must be specified as a query parameter. + + 1. `BLOCKED` : Subscription is completely blocked for both Production and Sandbox environments. + 2. `PROD_ONLY_BLOCKED` : Subscription is blocked for Production environment only. parameters: - $ref: '#/parameters/subscriptionId-Q' - name: blockState @@ -1393,10 +1970,8 @@ paths: - PROD_ONLY_BLOCKED - $ref: '#/parameters/If-Match' - $ref: '#/parameters/If-Unmodified-Since' - description: | - Block a subscription. tags: - - Subscriptions + - Subscription (Individual) responses: 200: description: | @@ -1406,12 +1981,12 @@ paths: ETag: description: | Entity Tag of the blocked subscription. - Used by caches, or in conditional request. + Used by caches, or in conditional requests (Will be supported in future). type: string Last-Modified: description: | Date and time the subscription has been blocked. - Used by caches, or in conditional requests. + Used by caches, or in conditional requests (Will be supported in future). type: string 400: description: | @@ -1442,7 +2017,10 @@ paths: #----------------------------------------------------- post: x-scope: apim:subscription_block - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -X POST \"http://127.0.0.1:9763/api/am/publisher/v0.10/subscriptions/unblock-subscription?subscriptionId=64eca60b-2e55-4c38-8603-e9e6bad7d809\"" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -X POST \"https://localhost:9443/api/am/publisher/v0.12/subscriptions/unblock-subscription?subscriptionId=64eca60b-2e55-4c38-8603-e9e6bad7d809\"" + x-wso2-request: | + POST https://localhost:9443/api/am/publisher/v0.12/subscriptions/unblock-subscription?subscriptionId=64eca60b-2e55-4c38-8603-e9e6bad7d809 + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8` x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"subscriptionId\": \"64eca60b-2e55-4c38-8603-e9e6bad7d809\",\n \"tier\": \"Gold\",\n \"apiIdentifier\": \"admin-PhoneVerification-1.0.0\",\n \"applicationId\": \"896658a0-b4ee-4535-bbfa-806c894a4015\",\n \"status\": \"UNBLOCKED\"\n} " summary: Unblock a Subscription parameters: @@ -1450,9 +2028,9 @@ paths: - $ref: '#/parameters/If-Match' - $ref: '#/parameters/If-Unmodified-Since' description: | - Unblock a subscription. + This operation can be used to unblock a subscription specifying the subscription Id. The subscription will be fully unblocked after performing this operation. tags: - - Subscriptions + - Subscription (Individual) responses: 200: description: | @@ -1462,12 +2040,12 @@ paths: ETag: description: | Entity Tag of the unblocked subscription. - Used by caches, or in conditional request. + Used by caches, or in conditional requests (Will be supported in future). type: string Last-Modified: description: | Date and time the subscription has been unblocked. - Used by caches, or in conditional requests. + Used by caches, or in conditional requests (Will be supported in future). type: string 400: description: | @@ -1498,11 +2076,14 @@ paths: #----------------------------------------------------- get: x-scope: apim:tier_view - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" http://127.0.0.1:9763/api/am/publisher/v0.10/tiers/api" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" https://localhost:9443/api/am/publisher/v0.12/tiers/api" + x-wso2-request: | + GET https://localhost:9443/api/am/publisher/v0.12/tiers/api + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n\n{\n \"previous\": \"\",\n \"list\": [\n {\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 1,\n \"description\": \"Allows 1 request(s) per minute.\",\n \"name\": \"Bronze\",\n \"attributes\": {}\n },\n {\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 20,\n \"description\": \"Allows 20 request(s) per minute.\",\n \"name\": \"Gold\",\n \"attributes\": {}\n },\n {\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 5,\n \"description\": \"Allows 5 request(s) per minute.\",\n \"name\": \"Silver\",\n \"attributes\": {}\n },\n {\n \"unitTime\": 0,\n \"tierPlan\": null,\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 0,\n \"description\": \"Allows unlimited requests\",\n \"name\": \"Unlimited\",\n \"attributes\": {}\n }\n ],\n \"next\": \"\",\n \"count\": 4\n}" - summary: List Tiers + summary: Get all tiers description: | - Get available tiers + This operation can be used to list the available tiers for a given tier level. Tier level should be specified as a path parameter and should be one of `api`, `application` and `resource`. parameters: - $ref: '#/parameters/limit' - $ref: '#/parameters/offset' @@ -1510,7 +2091,7 @@ paths: - $ref: '#/parameters/Accept' - $ref: '#/parameters/If-None-Match' tags: - - Tiers + - Throttling Tier (Collection) responses: 200: description: | @@ -1525,12 +2106,12 @@ paths: ETag: description: | Entity Tag of the response resource. - Used by caches, or in conditional requests. + Used by caches, or in conditional requests (Will be supported in future). type: string 304: description: | Not Modified. - Empty body because the client has already the latest version of the requested resource. + Empty body because the client has already the latest version of the requested resource (Will be supported in future). 406: description: | Not Acceptable. @@ -1543,12 +2124,16 @@ paths: #----------------------------------------------------- post: x-scope: apim:tier_manage - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -H \"Content-Type: application/json\" -X POST -d @data.json \"http://127.0.0.1:9763/api/am/publisher/v0.10/tiers/api\"" - x-wso2-request: "{\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 5,\n \"description\": \"Allows 5 request(s) per minute.\",\n \"name\": \"Low\",\n \"attributes\": {\n \"a\":10,\n \"b\":30\n }\n}" - x-wso2-response: "HTTP/1.1 201 Created\nLocation: http://localhost:9763/api/am/publisher/v0.10/tiers/Low\nContent-Type: application/json\n\n{\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 5,\n \"description\": \"Allows 5 request(s) per minute.\",\n \"name\": \"Low\",\n \"attributes\": {\n \"b\": \"30\",\n \"a\": \"10\"\n }\n}" - summary: Add a new Tier + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -H \"Content-Type: application/json\" -X POST -d @data.json \"https://localhost:9443/api/am/publisher/v0.12/tiers/api\"" + x-wso2-request: "POST https://localhost:9443/api/am/publisher/v0.12/tiers/api\nAuthorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\nContent-Type: application/json\n\n{\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 5,\n \"description\": \"Allows 5 request(s) per minute.\",\n \"name\": \"Low\",\n \"attributes\": {\n \"a\":10,\n \"b\":30\n }\n}" + x-wso2-response: "HTTP/1.1 201 Created\nLocation: https://localhost:9443/api/am/publisher/v0.12/tiers/Low\nContent-Type: application/json\n\n{\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 5,\n \"description\": \"Allows 5 request(s) per minute.\",\n \"name\": \"Low\",\n \"attributes\": {\n \"b\": \"30\",\n \"a\": \"10\"\n }\n}" + summary: Create a Tier description: | - Add a new tier + This operation can be used to create a new throttling tier. The only supported tier level is `api` tiers. + `POST https://localhost:9443/api/am/publisher/v0.12/tiers/api` + + **IMPORTANT:** + * This is only effective when Advanced Throttling is disabled in the Server. If enabled, we need to use Admin REST API for throttling tiers modification related operations. parameters: - in: body name: body @@ -1557,10 +2142,10 @@ paths: required: true schema: $ref: '#/definitions/Tier' - - $ref: '#/parameters/tierLevel' + - $ref: '#/parameters/tierLevel-A' - $ref: '#/parameters/Content-Type' tags: - - Tiers + - Throttling Tier (Collection) responses: 201: description: | @@ -1604,11 +2189,16 @@ paths: #----------------------------------------------------- get: x-scope: apim:tier_view - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" http://127.0.0.1:9763/api/am/publisher/v0.10/tiers/api/Bronze" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" https://localhost:9443/api/am/publisher/v0.12/tiers/api/Bronze" + x-wso2-request: | + GET https://localhost:9443/api/am/publisher/v0.12/tiers/api/Bronze + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 1,\n \"description\": \"Allows 1 request(s) per minute.\",\n \"name\": \"Bronze\",\n \"attributes\": {}\n}" - summary: Get a Tier + summary: Get details of a tier description: | - Get tier details + This operation can be used to retrieve details of a single tier by specifying the tier level and tier name. + Note that the scope of the API is mandatory while retreiving the access token with the following cURL command : `curl -k -d \"grant_type=password&username=username&password=password&scope=apim:tier_view\" -H \"Authorization: Basic \" https://localhost:8243/token`. + You will receive the access token as the response, for example `"access_token":"8644c013-7ff1-3217-b150-d7b92cae6be7"`. parameters: - $ref: '#/parameters/tierName' - $ref: '#/parameters/tierLevel' @@ -1616,7 +2206,7 @@ paths: - $ref: '#/parameters/If-None-Match' - $ref: '#/parameters/If-Modified-Since' tags: - - Tiers + - Throttling Tier (Individual) responses: 200: description: | @@ -1632,17 +2222,17 @@ paths: ETag: description: | Entity Tag of the response resource. - Used by caches, or in conditional requests. + Used by caches, or in conditional requests (Will be supported in future). type: string Last-Modified: description: | Date and time the resource has been modifed the last time. - Used by caches, or in conditional reuquests. + Used by caches, or in conditional requests (Will be supported in future). type: string 304: description: | Not Modified. - Empty body because the client has already the latest version of the requested resource. + Empty body because the client has already the latest version of the requested resource (Will be supported in future). 404: description: | Not Found. @@ -1661,12 +2251,16 @@ paths: #----------------------------------------------------- put: x-scope: apim:tier_manage - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -H \"Content-Type: application/json\" -X PUT -d @data.json \"http://127.0.0.1:9763/api/am/publisher/v0.10/tiers/api/Low\"" - x-wso2-request: "{\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 10,\n \"description\": \"Allows 10 request(s) per minute.\",\n \"name\": \"Low\",\n \"attributes\": {\n \"a\": \"30\",\n \"b\": \"10\",\n \"c\": \"20\"\n }\n}\n" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -H \"Content-Type: application/json\" -X PUT -d @data.json \"https://localhost:9443/api/am/publisher/v0.12/tiers/api/Low\"" + x-wso2-request: "PUT https://localhost:9443/api/am/publisher/v0.12/tiers/api/Low\nAuthorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\nContent-Type: application/json\n\n{\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 10,\n \"description\": \"Allows 10 request(s) per minute.\",\n \"name\": \"Low\",\n \"attributes\": {\n \"a\": \"30\",\n \"b\": \"10\",\n \"c\": \"20\"\n }\n}\n" x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"tierLevel\": \"api\",\n \"stopOnQuotaReach\": true,\n \"requestCount\": 10,\n \"description\": \"Allows 10 request(s) per minute.\",\n \"name\": \"Low\",\n \"attributes\": {\n \"b\": \"10\",\n \"c\": \"20\",\n \"a\": \"30\"\n }\n}" summary: Update a Tier description: | - Update tier details + This operation can be used to update an existing tier. The only supported tier level is `api` tiers. + `PUT https://localhost:9443/api/am/publisher/v0.12/tiers/api/Low` + + **IMPORTANT:** + * This is only effective when Advanced Throttling is disabled in the Server. If enabled, we need to use Admin REST API for throttling tiers modification related operations. parameters: - $ref: '#/parameters/tierName' - in: body @@ -1676,12 +2270,12 @@ paths: required: true schema: $ref: '#/definitions/Tier' - - $ref: '#/parameters/tierLevel' + - $ref: '#/parameters/tierLevel-A' - $ref: '#/parameters/Content-Type' - $ref: '#/parameters/If-Match' - $ref: '#/parameters/If-Unmodified-Since' tags: - - Tiers + - Throttling Tier (Individual) responses: 200: description: | @@ -1701,12 +2295,12 @@ paths: ETag: description: | Entity Tag of the response resource. - Used by caches, or in conditional request. + Used by caches, or in conditional requests (Will be supported in future). type: string Last-Modified: description: | Date and time the resource has been modifed the last time. - Used by caches, or in conditional reuquests. + Used by caches, or in conditional requests (Will be supported in future). type: string 400: description: | @@ -1732,18 +2326,25 @@ paths: #----------------------------------------------------- delete: x-scope: apim:tier_manage - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -X POST \"http://127.0.0.1:9763/api/am/publisher/v0.10/tiers/api/Low\"" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -X DELETE \"https://localhost:9443/api/am/publisher/v0.12/tiers/api/Low\"" + x-wso2-request: | + DELETE https://localhost:9443/api/am/publisher/v0.12/tiers/api/Low + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 x-wso2-response: "HTTP/1.1 200 OK" summary: Delete a Tier description: | - Remove a tier + This operation can be used to delete an existing tier. The only supported tier level is `api` tiers. + `DELETE https://localhost:9443/api/am/publisher/v0.12/tiers/api/Low` + + **IMPORTANT:** + * This is only effective when Advanced Throttling is disabled in the Server. If enabled, we need to use Admin REST API for throttling tiers modification related operations. parameters: - $ref: '#/parameters/tierName' - - $ref: '#/parameters/tierLevel' + - $ref: '#/parameters/tierLevel-A' - $ref: '#/parameters/If-Match' - $ref: '#/parameters/If-Unmodified-Since' tags: - - Tiers + - Throttling Tier (Individual) responses: 200: description: | @@ -1772,12 +2373,12 @@ paths: #----------------------------------------------------- post: x-scope: apim:tier_manage - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" -H \"Content-Type: application/json\" -X POST -d @data.json \"http://127.0.0.1:9763/api/am/publisher/v0.10/tiers/update-permission?tierName=Bronze&tierLevel=api\"" - x-wso2-request: "{\n \"permissionType\":\"deny\",\n \"roles\": [\"Internal/everyone\",\"admin\"]\n}" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -H \"Content-Type: application/json\" -X POST -d @data.json \"https://localhost:9443/api/am/publisher/v0.12/tiers/update-permission?tierName=Bronze&tierLevel=api\"" + x-wso2-request: "POST https://localhost:9443/api/am/publisher/v0.12/tiers/update-permission?tierName=Bronze&tierLevel=api\nAuthorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\nContent-Type: application/json\n\n{\n \"permissionType\":\"deny\",\n \"roles\": [\"Internal/everyone\",\"admin\"]\n}" x-wso2-response: "HTTP/1.1 200 OK" - summary: Update Tier Permission + summary: Update tier permission description: | - Update tier permission + This operation can be used to update tier permissions which controls access for the particular tier based on the subscribers' roles. parameters: - $ref: '#/parameters/tierName-Q' - $ref: '#/parameters/tierLevel-Q' @@ -1788,7 +2389,7 @@ paths: schema: $ref: '#/definitions/TierPermission' tags: - - Tiers + - Throttling Tier (Individual) responses: 200: description: | @@ -1802,12 +2403,12 @@ paths: ETag: description: | Entity Tag of the modified tier. - Used by caches, or in conditional request. + Used by caches, or in conditional requests (Will be supported in future). type: string Last-Modified: description: | Date and time the tier has been modified. - Used by caches, or in conditional requests. + Used by caches, or in conditional requests (Will be supported in future). type: string 400: description: | @@ -1845,19 +2446,18 @@ paths: #----------------------------------------------------- get: x-scope: apim:api_view - x-wso2-curl: "curl -H \"Authorization: Bearer b0982cd2aacd463ff5f63cd5ebe58f4a\" \"http://127.0.0.1:9763/api/am/publisher/v0.10/environments\"" - x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"list\": [ {\n \"showInApiConsole\": true,\n \"serverUrl\": \"https://192.168.56.1:9444//services/\",\n \"endpoints\": {\n \"http\": \"http://192.168.56.1:8281\",\n \"https\": \"https://192.168.56.1:8244\"\n },\n \"name\": \"Production and Sandbox\",\n \"type\": \"hybrid\"\n }],\n \"count\": 1\n}" - summary: Get gateway environments + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" \"https://localhost:9443/api/am/publisher/v0.12/environments\"" + x-wso2-request: | + GET https://localhost:9443/api/am/publisher/v0.12/environments + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"list\": [ {\n \"showInApiConsole\": true,\n \"serverUrl\": \"https://localhost:9443/services/\",\n \"endpoints\": {\n \"http\": \"http://localhost:8280\",\n \"https\": \"https://localhost:8243\"\n },\n \"name\": \"Production and Sandbox\",\n \"type\": \"hybrid\"\n }],\n \"count\": 1\n}" + summary: Get all gateway environments description: | - Get a list of gateway environments configured previously. + This operation can be used to retrieve the list of gateway environments available. parameters: - - in: query - name: apiId - description: | - Will return environment list for the provided API. - type: string + - $ref: '#/parameters/apiId-Q' tags: - - Environments + - Environment (Collection) responses: 200: description: | @@ -1873,18 +2473,124 @@ paths: ETag: description: | Entity Tag of the response resource. - Used by caches, or in conditional requests. + Used by caches, or in conditional requests (Will be supported in future). type: string 304: description: | Not Modified. - Empty body because the client has already the latest version of the requested resource. + Empty body because the client has already the latest version of the requested resource (Will be supported in future). 404: description: | Not Found. Requested API does not exist. schema: $ref: '#/definitions/Error' + /policies/mediation: + +#----------------------------------------------------------------------------------------- +# Retrieving the list of all global mediation sequences under a given search condition +#----------------------------------------------------------------------------------------- + get: + x-scope: apim:mediation_policy_view + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" https://localhost:9443/api/am/publisher/v0.12/policies/mediation" + x-wso2-request: | + GET https://localhost:9443/api/am/publisher/v0.12/policies/mediation + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 + x-wso2-response: "HTTP/1.1 200 OK\r\nContent-Type: application/json\r\n\r\n{\r\n \"count\": 10,\r\n \"next\": null,\r\n \"previous\": null,\r\n \"list\": [\r\n {\r\n \"name\": \"debug_json_fault\",\r\n \"id\": \"563de8f3-dd1d-4ec7-afc2-d158c663ed34\",\r\n \"type\": \"fault\"\r\n },\r\n {\r\n \"name\": \"json_fault\",\r\n \"id\": \"f9c36f4d-a2b6-41e7-b311-d358a47916be\",\r\n \"type\": \"fault\"\r\n },\r\n {\r\n \"name\": \"json_to_xml_in_message\",\r\n \"id\": \"3921225b-7918-4b95-a851-22c4e4e3e911\",\r\n \"type\": \"in\"\r\n },\r\n {\r\n \"name\": \"debug_in_flow\",\r\n \"id\": \"2bc15f93-4455-4763-89b8-83600fb9d731\",\r\n \"type\": \"in\"\r\n },\r\n {\r\n \"name\": \"log_in_message\",\r\n \"id\": \"4d287cca-76ab-44ca-b22e-919fc27c50e3\",\r\n \"type\": \"in\"\r\n },\r\n {\r\n \"name\": \"preserve_accept_header\",\r\n \"id\": \"3776b215-b3bc-40b6-bdcb-06efa7de64be\",\r\n \"type\": \"in\"\r\n },\r\n {\r\n \"name\": \"xml_to_json_in_message\",\r\n \"id\": \"50ac2002-769e-4f90-8549-6d0248dff7d2\",\r\n \"type\": \"in\"\r\n },\r\n {\r\n \"name\": \"xml_to_json_out_message\",\r\n \"id\": \"2af75853-ed75-4d25-81aa-0ebbeca691ea\",\r\n \"type\": \"out\"\r\n },\r\n {\r\n \"name\": \"json_to_xml_out_message\",\r\n \"id\": \"d9fa3ffc-f6b6-4171-ab97-eb44196cb66e\",\r\n \"type\": \"out\"\r\n },\r\n {\r\n \"name\": \"debug_out_flow\",\r\n \"id\": \"260b7701-4071-46bd-9b66-900ac6fffed6\",\r\n \"type\": \"out\"\r\n },\r\n {\r\n \"name\": \"apply_accept_header\",\r\n \"id\": \"15c17c2f-33e3-4c37-a262-04dfa49983a4\",\r\n \"type\": \"out\"\r\n },\r\n {\r\n \"name\": \"log_out_message\",\r\n \"id\": \"d37dca41-c048-492a-82cf-9a2292c6fff0\",\r\n \"type\": \"out\"\r\n }\r\n ]\r\n}" + summary: | + Get all global level mediation policies + description: | + This operation provides you a list of available all global level mediation policies. + parameters: + - $ref : '#/parameters/limit' + - $ref : '#/parameters/offset' + - name : query + in: query + description: "-Not supported yet-" + type: string + - $ref : "#/parameters/Accept" + - $ref : "#/parameters/If-None-Match" + tags: + - Mediation Policy (Collection) + responses: + 200: + description: | + OK. + List of mediation policies is returned. + schema: + $ref: '#/definitions/mediationList' + headers: + Content-Type: + description: The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future). + type: string + 304: + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource (Will be supported in future). + 406: + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' + + + +###################################################### +# The "Workflow approval" resource API +###################################################### + /workflows/update-workflow-status: + +#------------------------------------------------------------------- +# Resume the workflow by approving or rejecting the workflow request +#------------------------------------------------------------------- + post: + x-scope: apim:api_workflow + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -H \"Content-Type: application/json\" -X POST -d @data.json \"https://localhost:9443/api/am/publisher/v0.12/workflows/update-workflow-status?workflowReferenceId=56e3a170-a7a7-45f8-b051-7e43a58a67e1\"" + x-wso2-request: "POST https://localhost:9443/api/am/publisher/v0.12/workflows/update-workflow-status?workflowReferenceId=56e3a170-a7a7-45f8-b051-7e43a58a67e1\nAuthorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\nContent-Type: application/json\n\n{\n \"status\" : \"APPROVED\",\n \"attributes\" : {\n \"apiCurrentState\": \"Created\",\n \"apiLCAction\": \"Publish\",\n \"apiName\":\"APIname\",\n \"apiVersion\" : \"1.0.0\",\n \"apiProvider\" : \"admin\",\n \"invoker\": \"admin\"\n }\n}" + x-wso2-response: "HTTP/1.1 200 OK" + summary: Update workflow status + description: | + This operation can be used to approve or reject a workflow task. + parameters: + - $ref: '#/parameters/workflowReferenceId-Q' + - in: body + name: body + description: | + Workflow event that need to be updated + required: true + schema: + $ref: '#/definitions/Workflow' + tags: + - Workflows (Individual) + responses: + 200: + description: | + OK. + Workflow request information is returned. + schema: + $ref: '#/definitions/Workflow' + headers: + Content-Type: + description: | + The content type of the body. + type: string + 400: + description: | + Bad Request. + Invalid request or validation error. + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + Workflow for the given reference in not found. + schema: + $ref: '#/definitions/Error' ###################################################### # Parameters - required by some of the APIs above ###################################################### @@ -1896,11 +2602,12 @@ parameters: name: apiId in: path description: | - **API ID** consisting of the **UUID** of the API. + **API ID** consisting of the **UUID** of the API. Using the **UUID** in the API call is recommended. The combination of the provider of the API, name of the API and the version is also accepted as a valid API ID. Should be formatted as **provider-name-version**. required: true type: string + x-encoded: true # API Identifier # Specified as part of the query string @@ -1908,11 +2615,12 @@ parameters: name: apiId in: query description: | - **API ID** consisting of the **UUID** of the API. + **API ID** consisting of the **UUID** of the API. Using the **UUID** in the API call is recommended. The combination of the provider of the API, name of the API and the version is also accepted as a valid API I. Should be formatted as **provider-name-version**. required: true type: string + x-encoded: true # Document Identifier @@ -1921,7 +2629,7 @@ parameters: name: documentId in: path description: | - **Document Identifier** + Document Identifier required: true type: string @@ -1945,6 +2653,18 @@ parameters: required: true type: string +# Mediation policy identifier +# Specified as part of the path expression + mediationPolicyId: + name: mediationPolicyId + in: path + description: | + Mediation policy Id + required: true + type: string + + + # Subscription Identifier # Specified as part of the query string subscriptionId-Q: @@ -1989,6 +2709,18 @@ parameters: - resource required: true +# Tier Type +# Specified as part of the path expression + tierLevel-A: + name: tierLevel + in: path + description: | + List API or Application or Resource type tiers. + type: string + enum: + - api + required: true + # Tier Type # Specified as part of the query string tierLevel-Q: @@ -2029,8 +2761,8 @@ parameters: name: Accept in: header description: | - Media types acceptable for the response. Default is JSON. - default: JSON + Media types acceptable for the response. Default is application/json. + default: application/json type: string # The HTTP Content-Type header @@ -2038,8 +2770,17 @@ parameters: name: Content-Type in: header description: | - Media type of the entity in the body. Default is JSON. - default: JSON + Media type of the entity in the body. Default is application/json. + default: application/json + required: true + type : string + +# The HTTP Authorization header + Authorization: + name: Authorization + in: header + description: | + Holds the bearer token for apis that require authentication. required: true type : string @@ -2050,7 +2791,7 @@ parameters: in: header description: | Validator for conditional requests; based on the ETag of the formerly retrieved - variant of the resourec. + variant of the resource (Will be supported in future). type : string # The HTTP If-Modified-Since header @@ -2060,7 +2801,7 @@ parameters: in: header description: | Validator for conditional requests; based on Last Modified header of the - formerly retrieved variant of the resource. + formerly retrieved variant of the resource (Will be supported in future). type: string # The HTTP If-Match header @@ -2069,7 +2810,7 @@ parameters: name: If-Match in: header description: | - Validator for conditional requests; based on ETag. + Validator for conditional requests; based on ETag (Will be supported in future). type: string # The HTTP If-Unmodified-Since header @@ -2078,7 +2819,18 @@ parameters: name: If-Unmodified-Since in: header description: | - Validator for conditional requests; based on Last Modified header. + Validator for conditional requests; based on Last Modified header (Will be supported in future). + type: string + + +# Workflow reference ID +# Specified as part of the path expression + workflowReferenceId-Q: + name: workflowReferenceId + in: query + description: | + Workflow reference id + required: true type: string ###################################################### @@ -2113,6 +2865,17 @@ definitions: type: array items: $ref: '#/definitions/APIInfo' + pagination: + properties: + offset: + type: integer + example: 12 + limit: + type: integer + example: 25 + total: + type: integer + example: 1290 #----------------------------------------------------- # The API Info resource @@ -2143,6 +2906,9 @@ definitions: status: type: string example: CREATED + thumbnailUri: + type: string + example: /apis/01234567-0123-0123-0123-012345678901/thumbnail #----------------------------------------------------- # The API resource @@ -2153,12 +2919,12 @@ definitions: - name - context - version - - apiDefinition - tiers - isDefaultVersion - transport - endpointConfig - visibility + - type properties: id: type: string @@ -2167,15 +2933,19 @@ definitions: example: 01234567-0123-0123-0123-012345678901 name: type: string + description: Name of the API example: CalculatorAPI description: type: string + description: A brief description about the API example: A calculator API that supports basic operations context: type: string + description: A string that represents the context of the user's request example: CalculatorAPI version: type: string + description: The version of the API example: 1.0.0 provider: description: | @@ -2186,6 +2956,7 @@ definitions: description: | Swagger definition of the API which contains details about URI templates and scopes type: string + example: "{\"paths\":{\"/substract\":{\"get\":{\"x-auth-type\":\"Application & Application User\",\"x-throttling-tier\":\"Unlimited\",\"parameters\":[{\"name\":\"x\",\"required\":true,\"type\":\"string\",\"in\":\"query\"},{\"name\":\"y\",\"required\":true,\"type\":\"string\",\"in\":\"query\"}],\"responses\":{\"200\":{}}}},\"/add\":{\"get\":{\"x-auth-type\":\"Application & Application User\",\"x-throttling-tier\":\"Unlimited\",\"parameters\":[{\"name\":\"x\",\"required\":true,\"type\":\"string\",\"in\":\"query\"},{\"name\":\"y\",\"required\":true,\"type\":\"string\",\"in\":\"query\"}],\"responses\":{\"200\":{}}}}},\"swagger\":\"2.0\",\"info\":{\"title\":\"CalculatorAPI\",\"version\":\"1.0.0\"}}" wsdlUri: description: | WSDL URL if the API is based on a WSDL endpoint @@ -2193,6 +2964,7 @@ definitions: example: "http://www.webservicex.com/globalweather.asmx?wsdl" status: type: string + description: This describes in which status of the lifecycle the API is example: CREATED responseCaching: type: string @@ -2206,6 +2978,14 @@ definitions: isDefaultVersion: type: boolean example: false + type: + type: string + description: The transport to be set. Accepted values are HTTP, WS + enum: + - HTTP + - WS + example: HTTP + default: HTTP transport: description: | Supported transports for the API (http and/or https). @@ -2215,14 +2995,20 @@ definitions: example: ["http","https"] tags: type: array + description: Search keywords related to the API items: type: string example: ["substract","add"] tiers: type: array + description: The subscription tiers selected for the particular API items: type: string example: ["Unlimited"] + apiLevelPolicy: + description: The policy selected for the particular API + type: string + example: "Unlimited" maxTps: properties: production: @@ -2238,6 +3024,7 @@ definitions: example: "/apis/01234567-0123-0123-0123-012345678901/thumbnail" visibility: type: string + description: The visibility level of the API. Accepts one of the following. PUBLIC, PRIVATE, RESTRICTED OR CONTROLLED. enum: - PUBLIC - PRIVATE @@ -2246,22 +3033,19 @@ definitions: example: PUBLIC visibleRoles: type: array - items: - type: string - example: [] - visibleTenants: - type: array + description: The user roles that are able to access the API items: type: string example: [] endpointConfig: type: string - example: "{\"production_endpoints\":{\"url\":\"http://localhost:9763/am/sample/calculator/v1/api\",\"config\":null},\"implementation_status\":\"managed\",\"endpoint_type\":\"http\"}" + example: "{\"production_endpoints\":{\"url\":\"https://localhost:9443/am/sample/pizzashack/v1/api/\",\"config\":{\"suspendErrorCode\":\"101000\",\"suspendDuration\":\"2000\",\"suspendMaxDuration\":\"3\",\"factor\":\"2\",\"retryErroCode\":\"101000\",\"retryTimeOut\":\"4\",\"retryDelay\":\"1000\",\"actionSelect\":\"fault\",\"actionDuration\":\"3000\"}},\"sandbox_endpoints\":{\"url\":\"https://localhost:9443/am/sample/pizzashack/v1/api/\",\"config\":null},\"endpoint_type\":\"http\"}" endpointSecurity: properties: type: type: string example: basic + description: Accepts one of the following, basic or digest. enum: - basic - digest @@ -2283,6 +3067,7 @@ definitions: example: [] subscriptionAvailability: type: string + description: The subscription availability. Accepts one of the following. current_tenant, all_tenants or specific_tenants. enum: - current_tenant - all_tenants @@ -2292,7 +3077,25 @@ definitions: type: array items: type: string - example: [] + example: ["tenant1", "tenant2"] + additionalProperties: + type: object + description : Map of custom properties of API + accessControl: + type: string + description: | + Is the API is restricted to certain set of publishers or creators or is it visible to all the + publishers and creators. If the accessControl restriction is none, this API can be modified by all the + publishers and creators, if not it can only be viewable/modifiable by certain set of publishers and creators, + based on the restriction. enum: + - NONE + - RESTRICTED + accessControlRoles: + type: array + description: The user roles that are able to view/modify as API publisher or creator. + items: + type: string + example: [admin] businessInformation: properties: businessOwner: @@ -2439,6 +3242,102 @@ definitions: example: API_LEVEL #----------------------------------------------------- +# The Mediation List resource +#----------------------------------------------------- + mediationList: + title: Mediation List + properties: + count: + type: integer + description: | + Number of mediation sequences returned. + example: 1 + next: + type: string + description: | + Link to the next subset of sequences qualified. + Empty if no more sequences are to be returned. + example: "" + previous: + type: string + description: | + Link to the previous subset of sequences qualified. + Empty if current subset is the first subset returned. + example: "" + list: + type: array + items: + $ref: '#/definitions/MediationInfo' + +#----------------------------------------------------- +# The MediationInfo resource +#----------------------------------------------------- + MediationInfo: + title: MediationInfo + required: + - name + - type + - id + properties: + name: + type: string + example: json_fault.xml + id: + type: string + example: 01234567-0123-0123-0123-012345678901 + type: + type: string + enum: + - in + - out + - fault + example: in +#----------------------------------------------------- +# The Mediation resource +#----------------------------------------------------- + Mediation: + title: Mediation + required: + - name + - type + - config + properties: + id: + type: string + example: 01234567-0123-0123-0123-012345678901 + name: + type: string + example: json_fault.xml + type: + type: string + enum: + - in + - out + - fault + example: in + config: + type: string + example: ' + + + + ' + +#----------------------------------------------------- +# The MediationInfo resource +#----------------------------------------------------- + Wsdl: + title: Wsdl + required: + - name + properties: + name: + type: string + example: admin--calculatorAPI2.0.wsdl + wsdlDefinition: + type: string + + # The Tier List resource #----------------------------------------------------- TierList: @@ -2607,6 +3506,20 @@ definitions: - REJECTED example: UNBLOCKED +#----------------------------------------------------- +# The Extended Subscription resource +#----------------------------------------------------- + ExtendedSubscription: + title: Subscription with Ext. Workflow Reference + required: + - workflowId + allOf: + - $ref: '#/definitions/Subscription' + - properties: + workflowId: + type: string + example: 01234567-0123-0123-0123-012345678901 + #----------------------------------------------------- # The Sequence resource #----------------------------------------------------- @@ -2618,12 +3531,15 @@ definitions: name: type: string example: log_in_message - config: - type: string - example: "" type: type: string example: in + id: + type: string + example: 69ea3fa6-55c6-472e-896d-e449dd34a824 + shared: + type: boolean + example: true #----------------------------------------------------- # The Error resource @@ -2692,7 +3608,7 @@ definitions: example: hybrid serverUrl: type: string - example: "https://localhost:9443//services/" + example: "https://localhost:9443/services/" showInApiConsole: type: boolean example: true @@ -2729,7 +3645,7 @@ definitions: https: type: string description: HTTPS environment URL - example: "https://localhost:8244" + example: "https://localhost:8243" #----------------------------------------------------- # The File Information resource @@ -2744,4 +3660,32 @@ definitions: mediaType: type: string description: media-type of the file - example: "image/jpeg" \ No newline at end of file + example: "image/jpeg" + + +#----------------------------------------------------- +# The workflow response resource +#----------------------------------------------------- + Workflow: + title: workflow + required: + - status + properties: + status: + description: | + This attribute declares whether this workflow task is approved or rejected. + type: string + enum: + - APPROVED + - REJECTED + example: APPROVED + attributes: + description: | + Custom attributes to complete the workflow task + type: object + additionalProperties: + type: string + example: {} + description: + type: string + example: "Approve workflow request." \ No newline at end of file diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/src/main/resources/store-api.yaml b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/src/main/resources/store-api.yaml index 43c19533b7d..a57b96d4abd 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/src/main/resources/store-api.yaml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.integration.generated.client/src/main/resources/store-api.yaml @@ -1,19 +1,34 @@ +# Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +# +# 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 +# +# http://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. +################################################################################ + swagger: '2.0' ###################################################### # Prolog ###################################################### info: - version: "0.11.0" + version: "0.12.0" title: "WSO2 API Manager - Store" description: | This specifies a **RESTful API** for WSO2 **API Manager** - Store. - - Please see [full swagger definition](https://raw.githubusercontent.com/wso2/carbon-apimgt/v6.0.4/components/apimgt/org.wso2.carbon.apimgt.rest.api.store/src/main/resources/store-api.yaml) of the API which is written using [swagger 2.0](http://swagger.io/) specification. + + Please see [full swagger definition](https://raw.githubusercontent.com/wso2/carbon-apimgt/v6.1.66/components/apimgt/org.wso2.carbon.apimgt.rest.api.store/src/main/resources/store-api.yaml) of the API which is written using [swagger 2.0](http://swagger.io/) specification. contact: name: "WSO2" url: "http://wso2.com/products/api-manager/" email: "architecture@wso2.com" - license: + license: name: "Apache 2.0" url: "http://www.apache.org/licenses/LICENSE-2.0.html" @@ -22,7 +37,7 @@ info: ###################################################### # The schemes supported by the API -schemes: +schemes: - https # The domain of the API. @@ -32,23 +47,23 @@ host: apis.wso2.com # The base path of the API. # Will be prefixed to all paths. -basePath: /api/am/store/v0.11 +basePath: /api/am/store/v0.12 # The following media types can be passed as input in message bodies of the API. # The actual media type must be specified in the Content-Type header field of the request. # The default is json, i.e. the Content-Type header is not needed to # be set, but supporting it serves extensibility. -consumes: +consumes: - application/json # The following media types may be passed as output in message bodies of the API. # The media type(s) consumable by the requestor is specified in the Accept header field -# of the corresponding request. -# The actual media type returned will be specfied in the Content-Type header field +# of the corresponding request. +# The actual media type returned will be specfied in the Content-Type header field # of the of the response. # The default of the Accept header is json, i.e. there is not needed to # set the value, but supporting it serves extensibility. -produces: +produces: - application/json x-wso2-security: @@ -66,20 +81,21 @@ paths: /apis: #----------------------------------------------------- -# Retrieving the list of all APIs qualifying under a given search condition +# Retrieving the list of all APIs qualifying under a given search condition #----------------------------------------------------- get: - x-wso2-curl: "curl https://127.0.0.1:9443/api/am/store/v0.11/apis" + x-wso2-curl: "curl https://localhost:9443/api/am/store/v0.12/apis" + x-wso2-curl-tenant: "curl -k -H \"X-WSO2-Tenant:test.com\" https://localhost:9443/api/am/store/v0.12/apis" x-wso2-request: | - GET https://127.0.0.1:9443/api/am/store/v0.11/apis + GET https://localhost:9443/api/am/store/v0.12/apis x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"previous\": \"\",\n \"list\": [\n {\n \"provider\": \"admin\",\n \"version\": \"1.0.0\",\n \"description\": \"This API provide Account Status Validation.\",\n \"status\": \"PUBLISHED\",\n \"name\": \"AccountVal\",\n \"context\": \"/account/1.0.0\",\n \"id\": \"2e81f147-c8a8-4f68-b4f0-69e0e7510b01\"\n },\n {\n \"provider\": \"admin\",\n \"version\": \"1.0.0\",\n \"description\": null,\n \"status\": \"PUBLISHED\",\n \"name\": \"api1\",\n \"context\": \"/api1/1.0.0\",\n \"id\": \"3e22d2fb-277a-4e9e-8c7e-1c0f7f73960e\"\n },\n {\n \"provider\": \"admin\",\n \"version\": \"2.0.0\",\n \"description\": \"Verify a phone number\",\n \"status\": \"PUBLISHED\",\n \"name\": \"PhoneVerification\",\n \"context\": \"/phoneverify/2.0.0\",\n \"id\": \"c43a325c-260b-4302-81cb-768eafaa3aed\"\n }\n ],\n \"count\": 3,\n \"next\": \"\"\n}" summary: | Retrieve/Search APIs description: | This operation provides you a list of available APIs qualifying under a given search condition. - + Each retrieved API is represented with a minimal amount of attributes. If you want to get complete details of an API, you need to use **Get details of an API** operation. - + This operation supports retriving APIs of other tenants. The required tenant domain need to be specified as a header `X-WSO2-Tenant`. If not specified super tenant's APIs will be retrieved. If you used an Authorization header, the user's tenant associated with the access token will be used. **NOTE:** @@ -109,7 +125,7 @@ paths: If no advanced attribute modifier has been specified, search will match the given query string against API Name. - + type: string - $ref : "#/parameters/Accept" - $ref : "#/parameters/If-None-Match" @@ -150,17 +166,18 @@ paths: # Retrieve the details of an API definition #----------------------------------------------------- get: - x-wso2-curl: "curl https://127.0.0.1:9443/api/am/store/v0.11/apis/c43a325c-260b-4302-81cb-768eafaa3aed" + x-wso2-curl: "curl https://localhost:9443/api/am/store/v0.12/apis/c43a325c-260b-4302-81cb-768eafaa3aed" + x-wso2-curl-tenant: "curl -k -H \"X-WSO2-Tenant:test.com\" https://localhost:9443/api/am/store/v0.12/apis/c43a325c-260b-4302-81cb-768eafaa3aed" x-wso2-request: | - GET https://127.0.0.1:9443/api/am/store/v0.11/apis/c43a325c-260b-4302-81cb-768eafaa3aed - x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\r\n \"thumbnailUrl\": null,\r\n \"tiers\": [\"Unlimited\"],\r\n \"businessInformation\": {\r\n \"technicalOwner\": \"John Doe\",\r\n \"technicalOwnerEmail\": \"architecture@pizzashack.com\",\r\n \"businessOwner\": \"Jane Roe\",\r\n \"businessOwnerEmail\": \"marketing@pizzashack.com\"\r\n },\r\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"/order\\\":{\\\"post\\\":{\\\"x-auth-type\\\":\\\"Application & Application User\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"description\\\":\\\"Create a new Order\\\",\\\"parameters\\\":[{\\\"schema\\\":{\\\"$ref\\\":\\\"#/definitions/Order\\\"},\\\"description\\\":\\\"Order object that needs to be added\\\",\\\"name\\\":\\\"body\\\",\\\"required\\\":true,\\\"in\\\":\\\"body\\\"}],\\\"responses\\\":{\\\"201\\\":{\\\"headers\\\":{\\\"Location\\\":{\\\"description\\\":\\\"The URL of the newly created resource.\\\",\\\"type\\\":\\\"string\\\"},\\\"Content-Type\\\":{\\\"description\\\":\\\"The content type of the body.\\\",\\\"type\\\":\\\"string\\\"}},\\\"schema\\\":{\\\"$ref\\\":\\\"#/definitions/Order\\\"},\\\"description\\\":\\\"Created. Successful response with the newly created object as entity in the body. Location header contains URL of newly created entity.\\\"}}}},\\\"/order/{orderId}\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application & Application User\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"description\\\":\\\"Get details of an Order\\\",\\\"parameters\\\":[{\\\"description\\\":\\\"Order Id\\\",\\\"name\\\":\\\"orderId\\\",\\\"format\\\":\\\"integer\\\",\\\"type\\\":\\\"number\\\",\\\"required\\\":true,\\\"in\\\":\\\"path\\\"}],\\\"responses\\\":{\\\"200\\\":{\\\"schema\\\":{\\\"$ref\\\":\\\"#/definitions/Order\\\"},\\\"headers\\\":{},\\\"description\\\":\\\"OK Requested Order will be returned\\\"}}}}},\\\"schemes\\\":[\\\"https\\\"],\\\"produces\\\":[\\\"application/json\\\"],\\\"swagger\\\":\\\"2.0\\\",\\\"definitions\\\":{\\\"Order\\\":{\\\"title\\\":\\\"Pizza Order\\\",\\\"properties\\\":{\\\"customerName\\\":{\\\"type\\\":\\\"string\\\"},\\\"delivered\\\":{\\\"type\\\":\\\"boolean\\\"},\\\"address\\\":{\\\"type\\\":\\\"string\\\"},\\\"pizzaType\\\":{\\\"type\\\":\\\"string\\\"},\\\"creditCardNumber\\\":{\\\"type\\\":\\\"string\\\"},\\\"quantity\\\":{\\\"type\\\":\\\"number\\\"},\\\"orderId\\\":{\\\"type\\\":\\\"integer\\\"}},\\\"required\\\":[\\\"orderId\\\"]}},\\\"consumes\\\":[\\\"application/json\\\"],\\\"info\\\":{\\\"title\\\":\\\"PizzaShackAPI\\\",\\\"description\\\":\\\"This document describe a RESTFul API for Pizza Shack online pizza delivery store.\\\\n\\\",\\\"license\\\":{\\\"name\\\":\\\"Apache 2.0\\\",\\\"url\\\":\\\"http://www.apache.org/licenses/LICENSE-2.0.html\\\"},\\\"contact\\\":{\\\"email\\\":\\\"architecture@pizzashack.com\\\",\\\"name\\\":\\\"John Doe\\\",\\\"url\\\":\\\"http://www.pizzashack.com\\\"},\\\"version\\\":\\\"1.0.0\\\"}}\",\r\n \"wsdlUri\": null,\r\n \"isDefaultVersion\": false,\r\n \"endpointURLs\": [ {\r\n \"environmentName\": \"Production and Sandbox\",\r\n \"environmentType\": \"hybrid\",\r\n \"environmentURLs\": {\r\n \"http\": \"http://10.100.7.77:8280//pizzashack/1.0.0\",\r\n \"https\": \"https://10.100.7.77:8243//pizzashack/1.0.0\"\r\n }\r\n }],\r\n \"transport\": [\r\n \"http\",\r\n \"https\"\r\n ],\r\n \"tags\": [\"pizza\"],\r\n \"version\": \"1.0.0\",\r\n \"description\": \"This document describe a RESTFul API for Pizza Shack online pizza delivery store.\\r\\n\",\r\n \"provider\": \"admin\",\r\n \"name\": \"PizzaShackAPI\",\r\n \"context\": \"/pizzashack/1.0.0\",\r\n \"id\": \"8848faaa-7fd1-478a-baa2-48a4ebb92c98\",\r\n \"status\": \"PUBLISHED\"\r\n} " + GET https://localhost:9443/api/am/store/v0.12/apis/c43a325c-260b-4302-81cb-768eafaa3aed + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\r\n \"thumbnailUrl\": null,\r\n \"tiers\": [\"Unlimited\"],\r\n \"businessInformation\": {\r\n \"technicalOwner\": \"John Doe\",\r\n \"technicalOwnerEmail\": \"architecture@pizzashack.com\",\r\n \"businessOwner\": \"Jane Roe\",\r\n \"businessOwnerEmail\": \"marketing@pizzashack.com\"\r\n },\r\n \"apiDefinition\": \"{\\\"paths\\\":{\\\"/order\\\":{\\\"post\\\":{\\\"x-auth-type\\\":\\\"Application & Application User\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"description\\\":\\\"Create a new Order\\\",\\\"parameters\\\":[{\\\"schema\\\":{\\\"$ref\\\":\\\"#/definitions/Order\\\"},\\\"description\\\":\\\"Order object that needs to be added\\\",\\\"name\\\":\\\"body\\\",\\\"required\\\":true,\\\"in\\\":\\\"body\\\"}],\\\"responses\\\":{\\\"201\\\":{\\\"headers\\\":{\\\"Location\\\":{\\\"description\\\":\\\"The URL of the newly created resource.\\\",\\\"type\\\":\\\"string\\\"},\\\"Content-Type\\\":{\\\"description\\\":\\\"The content type of the body.\\\",\\\"type\\\":\\\"string\\\"}},\\\"schema\\\":{\\\"$ref\\\":\\\"#/definitions/Order\\\"},\\\"description\\\":\\\"Created. Successful response with the newly created object as entity in the body. Location header contains URL of newly created entity.\\\"}}}},\\\"/order/{orderId}\\\":{\\\"get\\\":{\\\"x-auth-type\\\":\\\"Application & Application User\\\",\\\"x-throttling-tier\\\":\\\"Unlimited\\\",\\\"description\\\":\\\"Get details of an Order\\\",\\\"parameters\\\":[{\\\"description\\\":\\\"Order Id\\\",\\\"name\\\":\\\"orderId\\\",\\\"format\\\":\\\"string\\\",\\\"type\\\":\\\"string\\\",\\\"required\\\":true,\\\"in\\\":\\\"path\\\"}],\\\"responses\\\":{\\\"200\\\":{\\\"schema\\\":{\\\"$ref\\\":\\\"#/definitions/Order\\\"},\\\"headers\\\":{},\\\"description\\\":\\\"OK Requested Order will be returned\\\"}}}}},\\\"schemes\\\":[\\\"https\\\"],\\\"produces\\\":[\\\"application/json\\\"],\\\"swagger\\\":\\\"2.0\\\",\\\"definitions\\\":{\\\"Order\\\":{\\\"title\\\":\\\"Pizza Order\\\",\\\"properties\\\":{\\\"customerName\\\":{\\\"type\\\":\\\"string\\\"},\\\"delivered\\\":{\\\"type\\\":\\\"boolean\\\"},\\\"address\\\":{\\\"type\\\":\\\"string\\\"},\\\"pizzaType\\\":{\\\"type\\\":\\\"string\\\"},\\\"creditCardNumber\\\":{\\\"type\\\":\\\"string\\\"},\\\"quantity\\\":{\\\"type\\\":\\\"number\\\"},\\\"orderId\\\":{\\\"type\\\":\\\"string\\\"}},\\\"required\\\":[\\\"orderId\\\"]}},\\\"consumes\\\":[\\\"application/json\\\"],\\\"info\\\":{\\\"title\\\":\\\"PizzaShackAPI\\\",\\\"description\\\":\\\"This document describe a RESTFul API for Pizza Shack online pizza delivery store.\\\\n\\\",\\\"license\\\":{\\\"name\\\":\\\"Apache 2.0\\\",\\\"url\\\":\\\"http://www.apache.org/licenses/LICENSE-2.0.html\\\"},\\\"contact\\\":{\\\"email\\\":\\\"architecture@pizzashack.com\\\",\\\"name\\\":\\\"John Doe\\\",\\\"url\\\":\\\"http://www.pizzashack.com\\\"},\\\"version\\\":\\\"1.0.0\\\"}}\",\r\n \"wsdlUri\": null,\r\n \"isDefaultVersion\": false,\r\n \"endpointURLs\": [ {\r\n \"environmentName\": \"Production and Sandbox\",\r\n \"environmentType\": \"hybrid\",\r\n \"environmentURLs\": {\r\n \"http\": \"http://localhost:8280//pizzashack/1.0.0\",\r\n \"https\": \"https://localhost:8243//pizzashack/1.0.0\"\r\n }\r\n }],\r\n \"transport\": [\r\n \"http\",\r\n \"https\"\r\n ],\r\n \"tags\": [\"pizza\"],\r\n \"version\": \"1.0.0\",\r\n \"description\": \"This document describe a RESTFul API for Pizza Shack online pizza delivery store.\\r\\n\",\r\n \"provider\": \"admin\",\r\n \"name\": \"PizzaShackAPI\",\r\n \"context\": \"/pizzashack/1.0.0\",\r\n \"id\": \"8848faaa-7fd1-478a-baa2-48a4ebb92c98\",\r\n \"status\": \"PUBLISHED\"\r\n} " summary: | Get details of an API description: | Using this operation, you can retrieve complete details of a single API. You need to provide the Id of the API to retrive it. - + `X-WSO2-Tenant` header can be used to retrive an API of a different tenant domain. If not specified super tenant will be used. If Authorization header is present in the request, the user's tenant associated with the access token will be used. - + **NOTE:** * This operation does not require an Authorization header by default. But if it is provided, it will be validated and checked for permissions of the user, hence you may be able to see APIs which are restricted for special permissions/roles. \n parameters: @@ -183,7 +200,7 @@ paths: type: string ETag: description: | - Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future). + Entity Tag of the response resource. Used by caches, or in conditional requests. type: string Last-Modified: description: | @@ -195,7 +212,7 @@ paths: 304: description: | Not Modified. - Empty body because the client has already the latest version of the requested resource (Will be supported in future). + Empty body because the client has already the latest version of the requested resource. 404: description: | Not Found. @@ -216,16 +233,17 @@ paths: #----------------------------------------------------- get: x-wso2-request: | - GET https://127.0.0.1:9443/api/am/store/v0.11/apis/c43a325c-260b-4302-81cb-768eafaa3aed/swagger - x-wso2-curl: "curl https://127.0.0.1:9443/api/am/store/v0.11/apis/c43a325c-260b-4302-81cb-768eafaa3aed/swagger" + GET https://localhost:9443/api/am/store/v0.12/apis/c43a325c-260b-4302-81cb-768eafaa3aed/swagger + x-wso2-curl: "curl https://localhost:9443/api/am/store/v0.12/apis/c43a325c-260b-4302-81cb-768eafaa3aed/swagger" + x-wso2-curl-tenant: "curl -k -H \"X-WSO2-Tenant:test.com\" https://localhost:9443/api/am/store/v0.12/apis/c43a325c-260b-4302-81cb-768eafaa3aed/swagger" x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"paths\": {\"/*\": {\"get\": {\n \"x-auth-type\": \"Application\",\n \"x-throttling-tier\": \"Unlimited\",\n \"responses\": {\"200\": {\"description\": \"OK\"}}\n }}},\n \"x-wso2-security\": {\"apim\": {\"x-wso2-scopes\": []}},\n \"swagger\": \"2.0\",\n \"info\": {\n \"title\": \"PhoneVerification\",\n \"description\": \"Verify a phone number\",\n \"contact\": {\n \"email\": \"xx@ee.com\",\n \"name\": \"xx\"\n },\n \"version\": \"2.0.0\"\n }\n}\n" summary: | Get swagger definition description: | You can use this operation to retrieve the swagger definition of an API. - + `X-WSO2-Tenant` header can be used to retrive the swagger definition an API of a different tenant domain. If not specified super tenant will be used. If Authorization header is present in the request, the user's tenant associated with the access token will be used. - + **NOTE:** * This operation does not require an Authorization header by default. But in order to see a restricted API's swagger definition, you need to provide Authorization header. parameters: @@ -248,7 +266,7 @@ paths: type: string ETag: description: | - Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future). + Entity Tag of the response resource. Used by caches, or in conditional requests. type: string Last-Modified: description: | @@ -258,7 +276,7 @@ paths: 304: description: | Not Modified. - Empty body because the client has already the latest version of the requested resource (Will be supported in future). + Empty body because the client has already the latest version of the requested resource. 404: description: | Not Found. @@ -279,9 +297,10 @@ paths: post: x-scope: apim:subscribe x-wso2-request: | - GET https://127.0.0.1:9443/api/am/store/v0.11/apis/generate-sdk - x-wso2-curl: "curl https://127.0.0.1:9443/api/am/store/v0.11/apis/generate-sdk" - x-wso2-response: "HTTP/1.1 200 OK \n Content-Disposition: attachment; filename=\"PizzaShackAPI_1.0.0_java.zip\" \n Date: Wed, 12 Oct 2016 11:10:49 GMT \n Content-Type: application/zip \n Transfer-Encoding: chunked \n Server: WSO2 Carbon Server" + POST https://localhost:9443/api/am/store/v0.12/apis/generate-sdk?apiId=e93fb282-b456-48fc-8981-003fb89086ae&language=java + Authorization: Bearer 2e29904b-f3b0-366e-ba13-b469abedd88e + x-wso2-curl: "curl -k -H \"Authorization: Bearer 2e29904b-f3b0-366e-ba13-b469abedd88e\" -X POST 'https://localhost:9443/api/am/store/v0.12/apis/generate-sdk?apiId=5721d128-76d0-4cb9-b300-2bd9578beddb&language=java' > PizzaAPI_Java_SDK.zip" + x-wso2-response: "HTTP/1.1 200 OK \nContent-Disposition: attachment; filename=\"PizzaShackAPI_1.0.0_java.zip\"\nContent-Type: application/zip\n\n[zip content]" summary: | Generate SDK for an API description: | @@ -331,16 +350,17 @@ paths: #----------------------------------------------------- get: x-wso2-request: | - GET https://127.0.0.1:9443/api/am/store/v0.11/apis/c43a325c-260b-4302-81cb-768eafaa3aed/documents - x-wso2-curl: "curl https://127.0.0.1:9443/api/am/store/v0.11/apis/c43a325c-260b-4302-81cb-768eafaa3aed/documents" + GET https://localhost:9443/api/am/store/v0.12/apis/c43a325c-260b-4302-81cb-768eafaa3aed/documents + x-wso2-curl: "curl https://localhost:9443/api/am/store/v0.12/apis/c43a325c-260b-4302-81cb-768eafaa3aed/documents" + x-wso2-curl-tenant: "curl -k -H \"X-WSO2-Tenant:test.com\" https://localhost:9443/api/am/store/v0.12/apis/c43a325c-260b-4302-81cb-768eafaa3aed/documents" x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"previous\": \"\",\n \"list\": [\n {\n \"sourceType\": \"INLINE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"documentId\": \"850a4f34-db2c-4d23-9d85-3f95fbfb082c\",\n \"summary\": \"This is a sample documentation for v1.0.0\",\n \"name\": \"PhoneVerification API Documentation\",\n \"type\": \"HOWTO\"\n },\n {\n \"sourceType\": \"URL\",\n \"sourceUrl\": \"http://wiki.cdyne.com/index.php/Phone_Verification\",\n \"otherTypeName\": null,\n \"documentId\": \"98e18be8-5861-43c7-ba26-8cbbccd3a76f\",\n \"summary\": \"This is the URL for online documentation\",\n \"name\": \"Online Documentation\",\n \"type\": \"SAMPLES\"\n },\n {\n \"sourceType\": \"FILE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"documentId\": \"b66451ff-c6c2-4f6a-b91d-3821dc119b04\",\n \"summary\": \"This is a sample documentation pdf\",\n \"name\": \"Introduction to PhoneVerification API PDF\",\n \"type\": \"HOWTO\"\n }\n ],\n \"count\": 3,\n \"next\": \"\"\n}" summary: | Get a list of documents of an API description: | This operation can be used to retrive a list of documents belonging to an API by providing the id of the API. - + `X-WSO2-Tenant` header can be used to retrive documents of an API that belongs to a different tenant domain. If not specified super tenant will be used. If Authorization header is present in the request, the user's tenant associated with the access token will be used. - + **NOTE:** * This operation does not require an Authorization header by default. But in order to see a restricted API's documents, you need to provide Authorization header. parameters: @@ -395,18 +415,19 @@ paths: #----------------------------------------------------- get: x-wso2-request: | - GET https://127.0.0.1:9443/api/am/store/v0.11/apis/c43a325c-260b-4302-81cb-768eafaa3aed/documents/850a4f34-db2c-4d23-9d85-3f95fbfb082c - x-wso2-curl: "curl \"https://127.0.0.1:9443/api/am/store/v0.11/apis/c43a325c-260b-4302-81cb-768eafaa3aed/documents/850a4f34-db2c-4d23-9d85-3f95fbfb082c\"" + GET https://localhost:9443/api/am/store/v0.12/apis/c43a325c-260b-4302-81cb-768eafaa3aed/documents/850a4f34-db2c-4d23-9d85-3f95fbfb082c + x-wso2-curl: "curl \"https://localhost:9443/api/am/store/v0.12/apis/c43a325c-260b-4302-81cb-768eafaa3aed/documents/850a4f34-db2c-4d23-9d85-3f95fbfb082c\"" + x-wso2-curl-tenant: "curl -k -H \"X-WSO2-Tenant:test.com\" https://localhost:9443/api/am/store/v0.12/apis/c43a325c-260b-4302-81cb-768eafaa3aed/documents/850a4f34-db2c-4d23-9d85-3f95fbfb082c" x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"sourceType\": \"INLINE\",\n \"sourceUrl\": null,\n \"otherTypeName\": null,\n \"documentId\": \"850a4f34-db2c-4d23-9d85-3f95fbfb082c\",\n \"summary\": \"This is a sample documentation for v1.0.0\",\n \"name\": \"PhoneVerification API Documentation\",\n \"type\": \"HOWTO\"\n}" summary: | Get a document of an API description: | This operation can be used to retrieve a particular document's metadata associated with an API. - + `X-WSO2-Tenant` header can be used to retrive a document of an API that belongs to a different tenant domain. If not specified super tenant will be used. If Authorization header is present in the request, the user's tenant associated with the access token will be used. **NOTE:** - * This operation does not require an Authorization header by default. But in order to see a restricted API's document, you need to provide Authorization header. + * This operation does not require an Authorization header by default. But in order to see a restricted API's document, you need to provide Authorization header. parameters: - $ref: '#/parameters/apiId' - $ref: '#/parameters/documentId' @@ -431,7 +452,7 @@ paths: ETag: description: | Entity Tag of the response resource. - Used by caches, or in conditional requests (Will be supported in future). + Used by caches, or in conditional requests. type: string Last-Modified: description: | @@ -441,7 +462,7 @@ paths: 304: description: | Not Modified. - Empty body because the client has already the latest version of the requested resource (Will be supported in future). + Empty body because the client has already the latest version of the requested resource. 404: description: | Not Found. @@ -467,28 +488,29 @@ paths: #------------------------------------------------------------------------------------------------- get: x-wso2-request: | - GET https://127.0.0.1:9443/api/am/store/v0.11/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/0bcb7f05-599d-4e1a-adce-5cb89bfe58d5/content - x-wso2-curl: "curl \"https://127.0.0.1:9443/api/am/store/v0.11/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/0bcb7f05-599d-4e1a-adce-5cb89bfe58d5/content\" > sample.pdf" + GET https://localhost:9443/api/am/store/v0.12/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/0bcb7f05-599d-4e1a-adce-5cb89bfe58d5/content + x-wso2-curl: "curl \"https://localhost:9443/api/am/store/v0.12/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/0bcb7f05-599d-4e1a-adce-5cb89bfe58d5/content\" > sample.pdf" + x-wso2-curl-tenant: "curl -k -H \"X-WSO2-Tenant:test.com\" \"https://localhost:9443/api/am/store/v0.12/apis/890a4f4d-09eb-4877-a323-57f6ce2ed79b/documents/0bcb7f05-599d-4e1a-adce-5cb89bfe58d5/content\" > sample.pdf" x-wso2-response: "HTTP/1.1 200 OK\nContent-Disposition: attachment; filename=\"sample.pdf\"\nContent-Type: application/octet-stream\nContent-Length: 7802\n\n%PDF-1.4\n%äüöß\n2 0 obj\n<>\nstream\n..\n>>\nstartxref\n7279\n%%EOF" summary: | Get the content of an API document description: | This operation can be used to retrive the content of an API's document. - + The document can be of 3 types. In each cases responses are different. - + 1. **Inline type**: The content of the document will be retrieved in `text/plain` content type - 2. **FILE type**: + 2. **FILE type**: The file will be downloaded with the related content type (eg. `application/pdf`) 3. **URL type**: The client will recieve the URL of the document as the Location header with the response with - `303 See Other` - + `X-WSO2-Tenant` header can be used to retrive the content of a document of an API that belongs to a different tenant domain. If not specified super tenant will be used. If Authorization header is present in the request, the user's tenant associated with the access token will be used. **NOTE:** - * This operation does not require an Authorization header by default. But in order to see a restricted API's document content, you need to provide Authorization header. + * This operation does not require an Authorization header by default. But in order to see a restricted API's document content, you need to provide Authorization header. parameters: - $ref: '#/parameters/apiId' - $ref: '#/parameters/documentId' @@ -511,7 +533,7 @@ paths: ETag: description: | Entity Tag of the response resource. - Used by caches, or in conditional requests (Will be supported in future). + Used by caches, or in conditional requests. type: string Last-Modified: description: | @@ -530,7 +552,7 @@ paths: 304: description: | Not Modified. - Empty body because the client has already the latest version of the requested resource (Will be supported in future). + Empty body because the client has already the latest version of the requested resource. 404: description: | Not Found. @@ -554,15 +576,18 @@ paths: #------------------------------------------------------------------------------------------------- get: x-wso2-request: | - GET https://127.0.0.1:9443/api/am/store/v0.11/apis/e93fb282-b456-48fc-8981-003fb89086ae/thumbnail - x-wso2-curl: "curl https://127.0.0.1:9443/api/am/store/v0.11/apis/e93fb282-b456-48fc-8981-003fb89086ae/thumbnail > image.jpg" + GET https://localhost:9443/api/am/store/v0.12/apis/e93fb282-b456-48fc-8981-003fb89086ae/thumbnail + x-wso2-curl: "curl https://localhost:9443/api/am/store/v0.12/apis/e93fb282-b456-48fc-8981-003fb89086ae/thumbnail > image.jpg" + x-wso2-curl-tenant: "curl -k -H \"X-WSO2-Tenant:test.com\" https://localhost:9443/api/am/store/v0.12/apis/e93fb282-b456-48fc-8981-003fb89086ae/thumbnail > image.jpg" x-wso2-response: "HTTP/1.1 200 OK\r\nContent-Type: image/jpeg\r\n\r\n[image content]" summary: Get thumbnail image description: | This operation can be used to download a thumbnail image of an API. - + + `X-WSO2-Tenant` header can be used to retrive a thumbnail of an API that belongs to a different tenant domain. If not specified super tenant will be used. If Authorization header is present in the request, the user's tenant associated with the access token will be used. + **NOTE:** - * This operation does not require an Authorization header by default. But in order to see a restricted API's thumbnail, you need to provide Authorization header. + * This operation does not require an Authorization header by default. But in order to see a restricted API's thumbnail, you need to provide Authorization header. parameters: - $ref: '#/parameters/apiId' - $ref: '#/parameters/requestedTenant' @@ -584,7 +609,7 @@ paths: ETag: description: | Entity Tag of the response resource. - Used by caches, or in conditional requests (Will be supported in future). + Used by caches, or in conditional requests. type: string Last-Modified: description: | @@ -594,7 +619,7 @@ paths: 304: description: | Not Modified. - Empty body because the client has already the latest version of the requested resource (Will be supported in future). + Empty body because the client has already the latest version of the requested resource. 404: description: | Not Found. @@ -619,9 +644,9 @@ paths: get: x-scope: apim:subscribe x-wso2-request: | - GET https://127.0.0.1:9443/api/am/store/v0.11/applications + GET https://localhost:9443/api/am/store/v0.12/applications Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 - x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" \"https://127.0.0.1:9443/api/am/store/v0.11/applications\"" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" \"https://localhost:9443/api/am/store/v0.12/applications\"" x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"previous\": \"\",\n \"list\": [\n {\n \"groupId\": \"\",\n \"subscriber\": \"admin\",\n \"throttlingTier\": \"Unlimited\",\n \"applicationId\": \"367a2361-8db5-4140-8133-c6c8dc7fa0c4\",\n \"description\": \"\",\n \"status\": \"APPROVED\",\n \"name\": \"app1\"\n },\n {\n \"groupId\": \"\",\n \"subscriber\": \"admin\",\n \"throttlingTier\": \"Unlimited\",\n \"applicationId\": \"896658a0-b4ee-4535-bbfa-806c894a4015\",\n \"description\": null,\n \"status\": \"APPROVED\",\n \"name\": \"DefaultApplication\"\n }\n ],\n \"count\": 2,\n \"next\": \"\"\n}" summary: | Retrieve/Search applications @@ -686,9 +711,9 @@ paths: #----------------------------------------------------- post: x-scope: apim:subscribe - x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -H \"Content-Type: application/json\" -X POST -d @data.json \"https://127.0.0.1:9443/api/am/store/v0.11/applications\"" - x-wso2-request: "POST https://127.0.0.1:9443/api/am/store/v0.11/applications\nAuthorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\n\n{\n \"throttlingTier\": \"Unlimited\",\n \"description\": \"sample app description\",\n \"name\": \"sampleapp\",\n \"callbackUrl\": \"http://my.server.com/callback\"\n}" - x-wso2-response: "HTTP/1.1 201 Created\nLocation: https://localhost:9443/api/am/store/v0.11/applications/c30f3a6e-ffa4-4ae7-afce-224d1f820524\nContent-Type: application/json\n\n{\n \"groupId\": null,\n \"callbackUrl\": \"http://my.server.com/callback\",\n \"subscriber\": \"admin\",\n \"throttlingTier\": \"Unlimited\",\n \"applicationId\": \"c30f3a6e-ffa4-4ae7-afce-224d1f820524\",\n \"description\": \"sample app description\",\n \"status\": \"APPROVED\",\n \"name\": \"sampleapp\",\n \"keys\": []\n}" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -H \"Content-Type: application/json\" -X POST -d @data.json \"https://localhost:9443/api/am/store/v0.12/applications\"" + x-wso2-request: "POST https://localhost:9443/api/am/store/v0.12/applications\nAuthorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\n\n{\n \"throttlingTier\": \"Unlimited\",\n \"description\": \"sample app description\",\n \"name\": \"sampleapp\",\n \"callbackUrl\": \"http://my.server.com/callback\"\n}" + x-wso2-response: "HTTP/1.1 201 Created\nLocation: https://localhost:9443/api/am/store/v0.12/applications/c30f3a6e-ffa4-4ae7-afce-224d1f820524\nContent-Type: application/json\n\n{\n \"groupId\": null,\n \"callbackUrl\": \"http://my.server.com/callback\",\n \"subscriber\": \"admin\",\n \"throttlingTier\": \"Unlimited\",\n \"applicationId\": \"c30f3a6e-ffa4-4ae7-afce-224d1f820524\",\n \"description\": \"sample app description\",\n \"status\": \"APPROVED\",\n \"name\": \"sampleapp\",\n \"keys\": []\n}" summary: | Create a new application description: | @@ -754,9 +779,9 @@ paths: #----------------------------------------------------- get: x-scope: apim:subscribe - x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" \"https://127.0.0.1:9443/api/am/store/v0.11/applications/896658a0-b4ee-4535-bbfa-806c894a4015\"" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" \"https://localhost:9443/api/am/store/v0.12/applications/896658a0-b4ee-4535-bbfa-806c894a4015\"" x-wso2-request: | - GET https://127.0.0.1:9443/api/am/store/v0.11/applications/896658a0-b4ee-4535-bbfa-806c894a4015 + GET https://localhost:9443/api/am/store/v0.12/applications/896658a0-b4ee-4535-bbfa-806c894a4015 Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"groupId\": \"\",\n \"callbackUrl\": null,\n \"subscriber\": \"admin\",\n \"throttlingTier\": \"Unlimited\",\n \"applicationId\": \"896658a0-b4ee-4535-bbfa-806c894a4015\",\n \"description\": null,\n \"status\": \"APPROVED\",\n \"name\": \"DefaultApplication\",\n \"keys\": [ {\n \"consumerKey\": \"AVoREWiB16kY_GTIzscl40GYYZQa\",\n \"consumerSecret\": \"KXQxmS8W3xDvvJH4AfR6xrhKIeIa\",\n \"keyState\": \"COMPLETED\",\n \"keyType\": \"PRODUCTION\",\n \"supportedGrantTypes\": null,\n \"token\": {\n \"validityTime\": 3600,\n \"accessToken\": \"3887da6d111f0429c6dff47a46e87209\",\n \"tokenScopes\": [\n \"am_application_scope\",\n \"default\"\n ]\n }\n }]\n}" summary: | @@ -784,7 +809,7 @@ paths: type: string ETag: description: | - Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future). + Entity Tag of the response resource. Used by caches, or in conditional requests. type: string Last-Modified: description: | @@ -794,7 +819,7 @@ paths: 304: description: | Not Modified. - Empty body because the client has already the latest version of the requested resource (Will be supported in future). + Empty body because the client has already the latest version of the requested resource. 404: description: | Not Found. @@ -813,8 +838,8 @@ paths: #----------------------------------------------------- put: x-scope: apim:subscribe - x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -H \"Content-Type: application/json\" -X PUT -d @data.json \"https://127.0.0.1:9443/api/am/store/v0.11/applications/c30f3a6e-ffa4-4ae7-afce-224d1f820524\"" - x-wso2-request: "PUT https://127.0.0.1:9443/api/am/store/v0.11/applications/c30f3a6e-ffa4-4ae7-afce-224d1f820524\nAuthorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\n\n{\n \"callbackUrl\": \"\",\n \"throttlingTier\": \"Bronze\",\n \"description\": \"sample app description updated\",\n \"name\": \"sampleapp\"\n}" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -H \"Content-Type: application/json\" -X PUT -d @data.json \"https://localhost:9443/api/am/store/v0.12/applications/c30f3a6e-ffa4-4ae7-afce-224d1f820524\"" + x-wso2-request: "PUT https://localhost:9443/api/am/store/v0.12/applications/c30f3a6e-ffa4-4ae7-afce-224d1f820524\nAuthorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\n\n{\n \"callbackUrl\": \"\",\n \"throttlingTier\": \"Bronze\",\n \"description\": \"sample app description updated\",\n \"name\": \"sampleapp\"\n}" x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"groupId\": null,\n \"callbackUrl\": \"\",\n \"subscriber\": \"admin\",\n \"throttlingTier\": \"Bronze\",\n \"applicationId\": \"c30f3a6e-ffa4-4ae7-afce-224d1f820524\",\n \"description\": \"sample app description updated\",\n \"status\": \"APPROVED\",\n \"name\": \"sampleapp\",\n \"keys\": []\n}" summary: | Update an application @@ -852,7 +877,7 @@ paths: type: string ETag: description: | - Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future). + Entity Tag of the response resource. Used by caches, or in conditional requests. type: string Last-Modified: description: | @@ -874,7 +899,7 @@ paths: 412: description: | Precondition Failed. - The request has not been performed because one of the preconditions is not met (Will be supported in future). + The request has not been performed because one of the preconditions is not met. schema: $ref: '#/definitions/Error' @@ -883,9 +908,9 @@ paths: #----------------------------------------------------- delete: x-scope: apim:subscribe - x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -X DELETE \"https://127.0.0.1:9443/api/am/store/v0.11/applications/367a2361-8db5-4140-8133-c6c8dc7fa0c4\"" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -X DELETE \"https://localhost:9443/api/am/store/v0.12/applications/367a2361-8db5-4140-8133-c6c8dc7fa0c4\"" x-wso2-request: | - DELETE https://127.0.0.1:9443/api/am/store/v0.11/applications/367a2361-8db5-4140-8133-c6c8dc7fa0c4 + DELETE https://localhost:9443/api/am/store/v0.12/applications/367a2361-8db5-4140-8133-c6c8dc7fa0c4 Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 x-wso2-response: "HTTP/1.1 200 OK" summary: | @@ -912,10 +937,126 @@ paths: 412: description: | Precondition Failed. - The request has not been performed because one of the preconditions is not met (Will be supported in future). + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + +###################################################### +# The "Application Keys of a Given Type" resource APIs +###################################################### + '/applications/{applicationId}/keys/{keyType}': + +#----------------------------------------------------------- +# Retrieve key details of a given type (PRODUCTION/SANDBOX) +#----------------------------------------------------------- + get: + x-scope: apim:subscribe + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" \"https://localhost:9443/api/am/store/v0.12/applications/896658a0-b4ee-4535-bbfa-806c894a4015/keys/PRODUCTION\"" + x-wso2-request: | + GET https://localhost:9443/api/am/store/v0.12/applications/896658a0-b4ee-4535-bbfa-806c894a4015/keys/PRODUCTION + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n {\n \"consumerKey\": \"QwEtRHd4NJkcFuRUfAT5af8XEEoa\",\n \"consumerSecret\": \"7Fairfeu321ENjOR9w2xgJl3i70a\",\n \"supportedGrantTypes\": [\n \"refresh_token\",\n \"urn:ietf:params:oauth:grant-type:saml2-bearer\",\n \"password\",\n \"client_credentials\",\n \"iwa:ntlm\"\n ],\n \"callbackUrl\": \"http://sample/com/callback\",\n \"keyState\": \"COMPLETED\",\n \"keyType\": \"PRODUCTION\"}\n" + summary: | + Get key details of a given type + description: | + This operation can be used to retrieve key details of an individual application specifying the key type in the URI. + parameters: + - $ref: '#/parameters/applicationId' + - $ref: '#/parameters/keyType' + - $ref: '#/parameters/groupId' + - $ref: '#/parameters/Accept' + tags: + - Application (Individual) + - Application Keys + responses: + 200: + description: | + OK. + Application key details returned. + schema: + $ref: '#/definitions/ApplicationKey' + headers: + Content-Type: + description: | + The content type of the body. + type: string + 404: + description: | + Not Found. + Requested application does not exist. + schema: + $ref: '#/definitions/Error' + 406: + description: | + Not Acceptable. + The requested media type is not supported schema: $ref: '#/definitions/Error' +#----------------------------------------------------- +# Update grant types and callback url of an application +#----------------------------------------------------- + put: + x-scope: apim:subscribe + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -H \"Content-Type: application/json\" -X PUT -d @data.json \"https://localhost:9443/api/am/store/v0.12/applications/c30f3a6e-ffa4-4ae7-afce-224d1f820524/keys/SANDBOX\"" + x-wso2-request: | + PUT https://localhost:9443/api/am/store/v0.12/applications/896658a0-b4ee-4535-bbfa-806c894a4015/keys/SANDBOX + Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 + { + "supportedGrantTypes": [ + "refresh_token", + "urn:ietf:params:oauth:grant-type:saml2-bearer", + "password", + "client_credentials", + "iwa:ntlm" + ], + "callbackUrl": "http://sample/com/callback" + } + x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n {\n \"consumerKey\": \"QwEtRHd4NJkcFuRUfAT5af8XEEoa\",\n \"consumerSecret\": \"7Fairfeu321ENjOR9w2xgJl3i70a\",\n \"supportedGrantTypes\": [\n \"refresh_token\",\n \"urn:ietf:params:oauth:grant-type:saml2-bearer\",\n \"password\",\n \"client_credentials\",\n \"iwa:ntlm\"\n ],\n \"callbackUrl\": \"http://sample/com/callback\",\n \"keyState\": \"COMPLETED\",\n \"keyType\": \"PRODUCTION\"}\n" + summary: | + Update grant types and callback url of an application + description: | + This operation can be used to update grant types and callback url of an application. (Consumer Key and Consumer Secret are ignored) Upon succesfull you will retrieve the updated key details as the response. + parameters: + - $ref: '#/parameters/applicationId' + - $ref: '#/parameters/keyType' + - in: body + name: body + description: | + Grant types/Callback URL update request object + required: true + schema: + $ref: '#/definitions/ApplicationKey' + tags: + - Application (Individual) + - Application Keys + responses: + 200: + description: | + Ok. + Grant types or/and callback url is/are updated. + schema: + $ref: '#/definitions/ApplicationKey' + 400: + description: | + Bad Request. + Invalid request or validation error + schema: + $ref: '#/definitions/Error' + 404: + description: | + Not Found. + The resource to be updated does not exist. + schema: + $ref: '#/definitions/Error' + 412: + description: | + Precondition Failed. + The request has not been performed because one of the preconditions is not met. + schema: + $ref: '#/definitions/Error' + + ###################################################### # The "Generate Keys" Processing Function resource API ###################################################### @@ -926,8 +1067,8 @@ paths: #----------------------------------------------------- post: x-scope: apim:subscribe - x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -H \"Content-Type: application/json\" -X POST -d @data.json \"https://127.0.0.1:9443/api/am/store/v0.11/applications/generate-keys?applicationId=c30f3a6e-ffa4-4ae7-afce-224d1f820524\"" - x-wso2-request: "POST https://127.0.0.1:9443/api/am/store/v0.11/applications/generate-keys?applicationId=c30f3a6e-ffa4-4ae7-afce-224d1f820524\nAuthorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\n\n{\n \"validityTime\": \"3600\",\n \"keyType\": \"PRODUCTION\",\n \"accessAllowDomains\": [\"ALL\"\n ]\n}" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -H \"Content-Type: application/json\" -X POST -d @data.json \"https://localhost:9443/api/am/store/v0.12/applications/generate-keys?applicationId=c30f3a6e-ffa4-4ae7-afce-224d1f820524\"" + x-wso2-request: "POST https://localhost:9443/api/am/store/v0.12/applications/generate-keys?applicationId=c30f3a6e-ffa4-4ae7-afce-224d1f820524\nAuthorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\n\n{\n \"validityTime\": \"3600\",\n \"keyType\": \"PRODUCTION\",\n \"accessAllowDomains\": [\"ALL\"\n ]\n}" x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"consumerSecret\": \"8V7DDKtKGtuG_9GDjaOJ5sijdX0a\",\n \"consumerKey\": \"LOFL8He72MSGVil4SS_bsh9O8MQa\",\n \"keyState\": \"APPROVED\",\n \"keyType\": \"PRODUCTION\",\n \"supportedGrantTypes\": [\n \"urn:ietf:params:oauth:grant-type:saml2-bearer\",\n \"iwa:ntlm\",\n \"refresh_token\",\n \"client_credentials\",\n \"password\"\n ],\n \"token\": {\n \"validityTime\": 3600,\n \"accessToken\": \"fd2cdc4906fbc162e033d57f85a71c21\",\n \"tokenScopes\": [\n \"am_application_scope\",\n \"default\"\n ]\n }\n}" summary: | Generate keys for application @@ -987,6 +1128,96 @@ paths: The request has not been performed because one of the preconditions is not met (Will be supported in future). schema: $ref: '#/definitions/Error' + '/applications/scopes/{applicationId}': + get: + x-scope: 'apim:subscribe' + x-wso2-request: |- + GET https://127.0.0.1:9443/api/am/store/v0.12/applications/scopes/896658a0-b4ee-4535-bbfa-806c894a4015 + Authorization: Beareraa0ddec1ac656744234477f20fafcb0d + x-wso2-curl: 'curl -k -H "Authorization: Bearer aa0ddec1ac656744234477f20fafcb0d" "https://127.0.0.1:9443/api/am/store/v0.12/applications/scopes/896658a0-b4ee-4535-bbfa-806c894a4015"' + x-wso2-response: |- + HTTP/1.1 200 OK + Content-Type: application/json + + { + "groupId": "", + "callbackUrl": null, + "subscriber": "admin", + "throttlingTier": "Unlimited", + "applicationId": "896658a0-b4ee-4535-bbfa-806c894a4015", + "description": null, + "status": "APPROVED", + "name": "DefaultApplication", + "keys": [ { + "consumerKey": "AVoREWiB16kY_GTIzscl40GYYZQa", + "consumerSecret": "KXQxmS8W3xDvvJH4AfR6xrhKIeIa", + "keyState": "COMPLETED", + "keyType": "PRODUCTION", + "supportedGrantTypes": null, + "token": { + "validityTime": 3600, + "accessToken": "3887da6d111f0429c6dff47a46e87209", + "tokenScopes": [ + "am_application_scope", + "default" + ] + } + }] + } + summary: | + Get scopes associated with a particular application based on subscribed APIs + description: | + Get scopes associated with a particular application based on subscribed APIs + parameters: + - $ref: '#/parameters/applicationId' + - $ref: '#/parameters/filterByUserRoles' + - $ref: '#/parameters/If-None-Match' + - $ref: '#/parameters/If-Modified-Since' + tags: + - Application (Individual) + responses: + '200': + description: | + OK. + Scope returned. + schema: + $ref: '#/definitions/ScopeList' + headers: + Content-Type: + description: | + The content type of the body. + type: string + ETag: + description: | + Entity Tag of the response resource. Used by caches, or in conditional requests. + type: string + Last-Modified: + description: | + Date and time the resource has been modifed the last time. + Used by caches, or in conditional reuquests. + type: string + '304': + description: | + Not Modified. + Empty body because the client has already the latest version of the requested resource. + '401': + description: | + Un authorized. + The user is not authorized to view the application . + schema: + $ref: '#/definitions/Error' + '404': + description: | + Not Found. + Requested application does not exist. + schema: + $ref: '#/definitions/Error' + '406': + description: | + Not Acceptable. + The requested media type is not supported + schema: + $ref: '#/definitions/Error' ###################################################### # The "Subscription Collection" resource APIs @@ -998,22 +1229,22 @@ paths: #----------------------------------------------------- get: x-scope: apim:subscribe - x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" \"https://127.0.0.1:9443/api/am/store/v0.11/subscriptions?apiId=c43a325c-260b-4302-81cb-768eafaa3aed\"" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" \"https://localhost:9443/api/am/store/v0.12/subscriptions?apiId=c43a325c-260b-4302-81cb-768eafaa3aed\"" x-wso2-request: | - GET https://127.0.0.1:9443/api/am/store/v0.11/subscriptions?apiId=c43a325c-260b-4302-81cb-768eafaa3aed + GET https://localhost:9443/api/am/store/v0.12/subscriptions?apiId=c43a325c-260b-4302-81cb-768eafaa3aed Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"previous\": \"\",\n \"list\": [\n {\n \"tier\": \"Bronze\",\n \"subscriptionId\": \"03b8ef2b-5ae5-41f5-968e-52fa7fbd5d33\",\n \"apiIdentifier\": \"admin-PhoneVerification-2.0.0\",\n \"applicationId\": \"896658a0-b4ee-4535-bbfa-806c894a4015\",\n \"status\": \"UNBLOCKED\"\n },\n {\n \"tier\": \"Bronze\",\n \"subscriptionId\": \"5ed42650-9f5e-4dd4-94f3-3f09f1b17354\",\n \"apiIdentifier\": \"admin-PhoneVerification-2.0.0\",\n \"applicationId\": \"846118a5-3b25-4c22-a983-2d0278936f09\",\n \"status\": \"UNBLOCKED\"\n }\n ],\n \"count\": 2,\n \"next\": \"\"\n}" summary: | Get all subscriptions description: | This operation can be used to retrieve a list of subscriptions of the user associated with the provided access token. This operation is capable of - + 1. Retrieving applications which are subscibed to a specific API. - `GET https://127.0.0.1:9443/api/am/store/v0.11/subscriptions?apiId=c43a325c-260b-4302-81cb-768eafaa3aed` - + `GET https://localhost:9443/api/am/store/v0.12/subscriptions?apiId=c43a325c-260b-4302-81cb-768eafaa3aed` + 2. Retrieving APIs which are subscribed by a specific application. - `GET https://127.0.0.1:9443/api/am/store/v0.11/subscriptions?applicationId=c43a325c-260b-4302-81cb-768eafaa3aed` - + `GET https://localhost:9443/api/am/store/v0.12/subscriptions?applicationId=c43a325c-260b-4302-81cb-768eafaa3aed` + **IMPORTANT:** * It is mandatory to provide either **apiId** or **applicationId**. parameters: @@ -1058,9 +1289,9 @@ paths: #----------------------------------------------------- post: x-scope: apim:subscribe - x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -H \"Content-Type: application/json\" -X POST -d @data.json \"https://127.0.0.1:9443/api/am/store/v0.11/subscriptions\"" - x-wso2-request: "POST https://127.0.0.1:9443/api/am/store/v0.11/subscriptions\nAuthorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\n\n{\n \"tier\": \"Gold\",\n \"apiIdentifier\": \"c43a325c-260b-4302-81cb-768eafaa3aed\",\n \"applicationId\": \"c30f3a6e-ffa4-4ae7-afce-224d1f820524\"\n}" - x-wso2-response: "HTTP/1.1 201 Created\nLocation: https://localhost:9443/api/am/store/v0.11/subscriptions/5b65808c-cdf2-43e1-a695-de63e3ad0ae9\nContent-Type: application/json\n\n{\n \"tier\": \"Gold\",\n \"subscriptionId\": \"5b65808c-cdf2-43e1-a695-de63e3ad0ae9\",\n \"apiIdentifier\": \"admin-PhoneVerification-2.0.0\",\n \"applicationId\": \"c30f3a6e-ffa4-4ae7-afce-224d1f820524\",\n \"status\": \"UNBLOCKED\"\n}" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -H \"Content-Type: application/json\" -X POST -d @data.json \"https://localhost:9443/api/am/store/v0.12/subscriptions\"" + x-wso2-request: "POST https://localhost:9443/api/am/store/v0.12/subscriptions\nAuthorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\n\n{\n \"tier\": \"Gold\",\n \"apiIdentifier\": \"c43a325c-260b-4302-81cb-768eafaa3aed\",\n \"applicationId\": \"c30f3a6e-ffa4-4ae7-afce-224d1f820524\"\n}" + x-wso2-response: "HTTP/1.1 201 Created\nLocation: https://localhost:9443/api/am/store/v0.12/subscriptions/5b65808c-cdf2-43e1-a695-de63e3ad0ae9\nContent-Type: application/json\n\n{\n \"tier\": \"Gold\",\n \"subscriptionId\": \"5b65808c-cdf2-43e1-a695-de63e3ad0ae9\",\n \"apiIdentifier\": \"admin-PhoneVerification-2.0.0\",\n \"applicationId\": \"c30f3a6e-ffa4-4ae7-afce-224d1f820524\",\n \"status\": \"UNBLOCKED\"\n}" summary: | Add a new subscription description: | @@ -1117,9 +1348,9 @@ paths: #----------------------------------------------------- post: x-scope: apim:subscribe - x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -H \"Content-Type: application/json\" -X POST -d @data.json \"https://127.0.0.1:9443/api/am/store/v0.11/subscriptions/multiple\"" - x-wso2-request: "POST https://127.0.0.1:9443/api/am/store/v0.11/subscriptions/multiple\nAuthorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\n\n{\n \"tier\": \"Gold\",\n \"apiIdentifier\": \"c43a325c-260b-4302-81cb-768eafaa3aed\",\n \"applicationId\": \"c30f3a6e-ffa4-4ae7-afce-224d1f820524\"\n}" - x-wso2-response: "HTTP/1.1 201 Created\nLocation: https://localhost:9443/api/am/store/v0.11/subscriptions/5b65808c-cdf2-43e1-a695-de63e3ad0ae9\nContent-Type: application/json\n\n{\n \"tier\": \"Gold\",\n \"subscriptionId\": \"5b65808c-cdf2-43e1-a695-de63e3ad0ae9\",\n \"apiIdentifier\": \"admin-PhoneVerification-2.0.0\",\n \"applicationId\": \"c30f3a6e-ffa4-4ae7-afce-224d1f820524\",\n \"status\": \"UNBLOCKED\"\n}" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -H \"Content-Type: application/json\" -X POST -d @data.json \"https://localhost:9443/api/am/store/v0.12/subscriptions/multiple\"" + x-wso2-request: "POST https://localhost:9443/api/am/store/v0.12/subscriptions/multiple\nAuthorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\n\n{\n \"tier\": \"Gold\",\n \"apiIdentifier\": \"c43a325c-260b-4302-81cb-768eafaa3aed\",\n \"applicationId\": \"c30f3a6e-ffa4-4ae7-afce-224d1f820524\"\n}" + x-wso2-response: "HTTP/1.1 201 Created\nLocation: https://localhost:9443/api/am/store/v0.12/subscriptions/5b65808c-cdf2-43e1-a695-de63e3ad0ae9\nContent-Type: application/json\n\n{\n \"tier\": \"Gold\",\n \"subscriptionId\": \"5b65808c-cdf2-43e1-a695-de63e3ad0ae9\",\n \"apiIdentifier\": \"admin-PhoneVerification-2.0.0\",\n \"applicationId\": \"c30f3a6e-ffa4-4ae7-afce-224d1f820524\",\n \"status\": \"UNBLOCKED\"\n}" summary: | Add new subscriptions description: | @@ -1165,7 +1396,7 @@ paths: description: | Unsupported media type. The entity of the request was in a not supported format. - + ###################################################### # The "Individual Subscription" resource APIs ###################################################### @@ -1176,9 +1407,9 @@ paths: #----------------------------------------------------- get: x-scope: apim:subscribe - x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" \"https://127.0.0.1:9443/api/am/store/v0.11/subscriptions/5b65808c-cdf2-43e1-a695-de63e3ad0ae9\"" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" \"https://localhost:9443/api/am/store/v0.12/subscriptions/5b65808c-cdf2-43e1-a695-de63e3ad0ae9\"" x-wso2-request: | - GET https://127.0.0.1:9443/api/am/store/v0.11/subscriptions/5b65808c-cdf2-43e1-a695-de63e3ad0ae9 + GET https://localhost:9443/api/am/store/v0.12/subscriptions/5b65808c-cdf2-43e1-a695-de63e3ad0ae9 Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8 x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"tier\": \"Gold\",\n \"subscriptionId\": \"5b65808c-cdf2-43e1-a695-de63e3ad0ae9\",\n \"apiIdentifier\": \"admin-PhoneVerification-2.0.0\",\n \"applicationId\": \"c30f3a6e-ffa4-4ae7-afce-224d1f820524\",\n \"status\": \"UNBLOCKED\"\n}" summary: | @@ -1205,7 +1436,7 @@ paths: type: string ETag: description: | - Entity Tag of the response resource. Used by caches, or in conditional requests (Will be supported in future). + Entity Tag of the response resource. Used by caches, or in conditional requests. type: string Last-Modified: description: | @@ -1214,7 +1445,7 @@ paths: '304': description: | Not Modified. - Empty body because the client has already the latest version of the requested resource (Will be supported in future). + Empty body because the client has already the latest version of the requested resource. '404': description: | Not Found. @@ -1227,9 +1458,9 @@ paths: #----------------------------------------------------- delete: x-scope: apim:subscribe - x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -X DELETE \"https://127.0.0.1:9443/api/am/store/v0.11/subscriptions/5b65808c-cdf2-43e1-a695-de63e3ad0ae9\"" + x-wso2-curl: "curl -k -H \"Authorization: Bearer ae4eae22-3f65-387b-a171-d37eaa366fa8\" -X DELETE \"https://localhost:9443/api/am/store/v0.12/subscriptions/5b65808c-cdf2-43e1-a695-de63e3ad0ae9\"" x-wso2-request: | - DELETE https://127.0.0.1:9443/api/am/store/v0.11/subscriptions/5b65808c-cdf2-43e1-a695-de63e3ad0ae9 + DELETE https://localhost:9443/api/am/store/v0.12/subscriptions/5b65808c-cdf2-43e1-a695-de63e3ad0ae9 x-wso2-response: "HTTP/1.1 200 OK" summary: | Remove a subscription @@ -1255,7 +1486,7 @@ paths: 412: description: | Precondition Failed. - The request has not been performed because one of the preconditions is not met (Will be supported in future). + The request has not been performed because one of the preconditions is not met. schema: $ref: '#/definitions/Error' @@ -1268,15 +1499,18 @@ paths: # Retrieve the list of all available tiers #----------------------------------------------------- get: - x-wso2-curl: "curl \"https://127.0.0.1:9443/api/am/store/v0.11/tiers/api\"" + x-wso2-curl: "curl \"https://localhost:9443/api/am/store/v0.12/tiers/api\"" x-wso2-request: | - GET https://127.0.0.1:9443/api/am/store/v0.11/tiers/api + GET https://localhost:9443/api/am/store/v0.12/tiers/api + x-wso2-curl-tenant: "curl -k -H \"X-WSO2-Tenant:test.com\" https://localhost:9443/api/am/store/v0.12/tiers/api" x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"previous\": \"\",\n \"list\": [\n {\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"stopOnQuotaReach\": true,\n \"tierLevel\": \"api\",\n \"requestCount\": 1,\n \"description\": \"Allows 1 request(s) per minute.\",\n \"name\": \"Bronze\",\n \"attributes\": {}\n },\n {\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"stopOnQuotaReach\": true,\n \"tierLevel\": \"api\",\n \"requestCount\": 20,\n \"description\": \"Allows 20 request(s) per minute.\",\n \"name\": \"Gold\",\n \"attributes\": {}\n },\n {\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"stopOnQuotaReach\": true,\n \"tierLevel\": \"api\",\n \"requestCount\": 5,\n \"description\": \"Allows 5 request(s) per minute.\",\n \"name\": \"Silver\",\n \"attributes\": {}\n },\n {\n \"unitTime\": 0,\n \"tierPlan\": null,\n \"stopOnQuotaReach\": true,\n \"tierLevel\": \"api\",\n \"requestCount\": 0,\n \"description\": \"Allows unlimited requests\",\n \"name\": \"Unlimited\",\n \"attributes\": {}\n }\n ],\n \"count\": 4,\n \"next\": \"\"\n}" summary: | Get available tiers description: | This operation can be used to retrieve all the tiers available for the provided tier level. Tier level should be specified as a path parameter and should be one of `api` and `application`. - + + `X-WSO2-Tenant` header can be used to retrive tiers that belongs to a different tenant domain. If not specified super tenant will be used. If Authorization header is present in the request, the user's tenant associated with the access token will be used. + **NOTE**: * API tiers are the ones that is available during subscription of an application to an API. Hence they are also called subscription tiers and are same as the subscription policies in Admin REST API. parameters: @@ -1326,14 +1560,17 @@ paths: # Retrieve a certain tier #----------------------------------------------------- get: - x-wso2-curl: "curl \"https://127.0.0.1:9443/api/am/store/v0.11/tiers/api/Bronze\"" + x-wso2-curl: "curl \"https://localhost:9443/api/am/store/v0.12/tiers/api/Bronze\"" x-wso2-request: | - GET https://127.0.0.1:9443/api/am/store/v0.11/tiers/api/Bronze + GET https://localhost:9443/api/am/store/v0.12/tiers/api/Bronze + x-wso2-curl-tenant: "curl -k -H \"X-WSO2-Tenant:test.com\" https://localhost:9443/api/am/store/v0.12/tiers/api/Bronze" x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"unitTime\": 60000,\n \"tierPlan\": \"FREE\",\n \"stopOnQuotaReach\": true,\n \"tierLevel\": \"api\",\n \"requestCount\": 1,\n \"description\": \"Allows 1 request(s) per minute.\",\n \"name\": \"Bronze\",\n \"attributes\": {}\n}" summary: | Get details of a tier description: | This operation can be used to retrieve details of a single tier by specifying the tier level and tier name. + + `X-WSO2-Tenant` header can be used to retrive tiers that belongs to a different tenant domain. If not specified super tenant will be used. If Authorization header is present in the request, the user's tenant associated with the access token will be used. parameters: - $ref: '#/parameters/tierName' - $ref: '#/parameters/tierLevel' @@ -1391,14 +1628,20 @@ paths: # Retrieve the list of tags qualifying under a search condition #----------------------------------------------------- get: - x-wso2-curl: "curl \"https://127.0.0.1:9443/api/am/store/v0.11/tags\"" + x-wso2-curl: "curl \"https://localhost:9443/api/am/store/v0.12/tags\"" x-wso2-request: | - GET https://127.0.0.1:9443/api/am/store/v0.11/tags + GET https://localhost:9443/api/am/store/v0.12/tags + x-wso2-curl-tenant: "curl -k -H \"X-WSO2-Tenant:test.com\" https://localhost:9443/api/am/store/v0.12/tags" x-wso2-response: "HTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"previous\": \"\",\n \"list\": [\n {\n \"weight\": 1,\n \"name\": \"mobile\"\n },\n {\n \"weight\": 1,\n \"name\": \"multimedia\"\n },\n {\n \"weight\": 1,\n \"name\": \"phone\"\n }\n ],\n \"count\": 3,\n \"next\": \"\"\n}" summary: | Get all tags description: | This operation can be used to retrieve a list of tags that are already added to APIs. + + `X-WSO2-Tenant` header can be used to retrive tags that belongs to a different tenant domain. If not specified super tenant will be used. If Authorization header is present in the request, the user's tenant associated with the access token will be used. + + **NOTE:** + * This operation does not require an Authorization header by default. But in order to see a restricted API's tags, you need to provide Authorization header. parameters: - $ref: '#/parameters/limit' - $ref: '#/parameters/offset' @@ -1461,11 +1704,12 @@ parameters: name: apiId in: path description: | - **API ID** consisting of the **UUID** of the API. + **API ID** consisting of the **UUID** of the API. Using the **UUID** in the API call is recommended. The combination of the provider of the API, name of the API and the version is also accepted as a valid API ID. Should be formatted as **provider-name-version**. required: true type: string + x-encoded: true # API Identifier # Specified as part of the query string @@ -1473,11 +1717,12 @@ parameters: name: apiId in: query description: | - **API ID** consisting of the **UUID** of the API. + **API ID** consisting of the **UUID** of the API. Using the **UUID** in the API call is recommended. The combination of the provider of the API, name of the API and the version is also accepted as a valid API I. Should be formatted as **provider-name-version**. required: true type: string + x-encoded: true # API Identifier # Specified as part of the path expression @@ -1510,6 +1755,16 @@ parameters: required: true type: string +# Filter By user roles +# Specified as part of the query string + filterByUserRoles: + name: filterByUserRoles + in: query + description : | + Filter user by roles. + required : false + type: boolean + # Application Identifier # Specified as part of the query string applicationId-Q: @@ -1583,6 +1838,19 @@ parameters: default: 0 type: integer +# Application Key Type +# Specified as part of the path expression + keyType: + name: keyType + in: path + description: | + **Application Key Type** standing for the type of the keys (i.e. Production or Sandbox). + required: true + type: string + enum: + - PRODUCTION + - SANDBOX + # The HTTP Accept header Accept: name: Accept @@ -1609,7 +1877,7 @@ parameters: in: header description: | Validator for conditional requests; based on the ETag of the formerly retrieved - variant of the resourec. + variant of the resource. type : string # The HTTP If-Modified-Since header @@ -1619,7 +1887,7 @@ parameters: in: header description: | Validator for conditional requests; based on Last Modified header of the - formerly retrieved variant of the resource. + formerly retrieved variant of the resource (Will be supported in future). type: string # The HTTP If-Match header @@ -1637,7 +1905,7 @@ parameters: name: If-Unmodified-Since in: header description: | - Validator for conditional requests; based on Last Modified header. + Validator for conditional requests; based on Last Modified header (Will be supported in future). type: string ###################################################### @@ -1672,7 +1940,17 @@ definitions: type: array items: $ref: '#/definitions/APIInfo' - + pagination: + properties: + offset: + type: integer + example: 12 + limit: + type: integer + example: 25 + total: + type: integer + example: 1290 #----------------------------------------------------- # The API Info resource #----------------------------------------------------- @@ -1702,7 +1980,13 @@ definitions: status: type: string example: PUBLISHED - + thumbnailUri: + type: string + example: /apis/01234567-0123-0123-0123-012345678901/thumbnail + scopes: + type: array + items: + $ref: '#/definitions/ScopeInfo' #----------------------------------------------------- # The API resource #----------------------------------------------------- @@ -1723,15 +2007,19 @@ definitions: example: 01234567-0123-0123-0123-012345678901 name: type: string + description: Name of the API example: CalculatorAPI description: type: string + description: A brief description about the API example: A calculator API that supports basic operations context: type: string + description: A string that represents thecontext of the user's request example: CalculatorAPI version: type: string + description: The version of the API example: 1.0.0 provider: description: | @@ -1742,7 +2030,7 @@ definitions: description: | Swagger definition of the API which contains details about URI templates and scopes type: string - example: "{\"paths\":{\"/substract\":{\"get\":{\"x-auth-type\":\"Application & Application User\",\"x-throttling-tier\":\"Unlimited\",\"parameters\":[{\"name\":\"x\",\"required\":true,\"type\":\"string\",\"in\":\"query\"},{\"name\":\"y\",\"required\":true,\"type\":\"string\",\"in\":\"query\"}],\"responses\":{\"200\":{}}}},\"/add\":{\"get\":{\"x-auth-type\":\"Application & Application User\",\"x-throttling-tier\":\"Unlimited\",\"parameters\":[{\"name\":\"x\",\"required\":true,\"type\":\"string\",\"in\":\"query\"},{\"name\":\"y\",\"required\":true,\"type\":\"string\",\"in\":\"query\"}],\"responses\":{\"200\":{}}}}},\"swagger\":\"2.0\",\"info\":{\"title\":\"CalculatorAPI\",\"version\":\"1.0.0\"}}" + example: "{'paths':{'/substract':{'get':{'x-auth-type':'Application & Application User','x-throttling-tier':'Unlimited','parameters':[{'name':'x','required':true,'type':'string','in':'query'},{'name':'y','required':true,'type':'string','in':'query'}],'responses':{'200':{}}}},'/add':{'get':{'x-auth-type':'Application & Application User','x-throttling-tier':'Unlimited','parameters':[{'name':'x','required':true,'type':'string','in':'query'},{'name':'y','required':true,'type':'string','in':'query'}],'responses':{'200':{}}}}},'swagger':'2.0','info':{'title':'CalculatorAPI','version':'1.0.0'}}" wsdlUri: description: | WSDL URL if the API is based on a WSDL endpoint @@ -1750,6 +2038,7 @@ definitions: example: "http://www.webservicex.com/globalweather.asmx?wsdl" status: type: string + description: This describes in which status of the lifecycle the API is. example: PUBLISHED isDefaultVersion: type: boolean @@ -1763,17 +2052,26 @@ definitions: example: ["http","https"] tags: type: array + description: Search keywords related to the API items: type: string example: ["substract","add"] tiers: type: array + description: The subscription tiers selected for the particular API items: type: string example: ["Unlimited"] thumbnailUrl: type: string example: "" + additionalProperties: + description: | + Custom(user defined) properties of API + type: object + additionalProperties: + type: string + example: {} endpointURLs: type: array items: @@ -1789,11 +2087,11 @@ definitions: http: type: string description: HTTP environment URL - example: "http://192.168.56.1:8280/phoneverify/1.0.0" + example: "http://localhost:8280/phoneverify/1.0.0" https: type: string description: HTTPS environment URL - example: "https://192.168.56.1:8243/phoneverify/1.0.0" + example: "https://localhost:8243/phoneverify/1.0.0" businessInformation: properties: businessOwner: @@ -2062,7 +2360,8 @@ definitions: even if the request count exceeded within a unit time type: boolean example: true - + TierPermissions: + $ref: '#/definitions/TierPermissionInfo' #----------------------------------------------------- # The Subscription List resource #----------------------------------------------------- @@ -2103,13 +2402,16 @@ definitions: properties: subscriptionId: type: string - example: 01234567-0123-0123-0123-012345678901 + description: The UUID of the subscription + example: faae5fcc-cbae-40c4-bf43-89931630d313 applicationId: type: string - example: 01234567-0123-0123-0123-012345678901 + description: The UUID of the application + example: b3ade481-30b0-4b38-9a67-498a40873a6d apiIdentifier: type: string - example: 01234567-0123-0123-0123-012345678901 + description: The unique identifier of the API. + example: admin-PizzaShackAPI-1.0.0 tier: type: string example: Unlimited @@ -2123,6 +2425,7 @@ definitions: - REJECTED example: UNBLOCKED + #----------------------------------------------------- # The Tag resource #----------------------------------------------------- @@ -2244,29 +2547,37 @@ definitions: properties: consumerKey: type: string - description: Consumer key of the application + description: The consumer key associated with the application and identifying the client example: vYDoc9s7IgAFdkSyNDaswBX7ejoa consumerSecret: type: string - description: Consumer secret of the application + description: The client secret that is used to authenticate the client with the authentication server example: TIDlOFkpzB7WjufO3OJUhy1fsvAa supportedGrantTypes: type: array items: type: string - description: Supported grant types for the application + description: The grant types that are supported by the application example: ["client_credentials","password"] + callbackUrl: + type: string + description: Callback URL + example: "http://sample.com/callback/url" keyState: type: string - description: State of the key generation of the application + description: Describes the state of the key generation. example: APPROVED keyType: - description: Key type + description: Describes to which endpoint the key belongs type: string enum: - PRODUCTION - SANDBOX example: PRODUCTION + groupId: + type: string + description: Application group id (if any). + example: 02 token: $ref: '#/definitions/Token' @@ -2289,6 +2600,12 @@ definitions: validityTime: type: string example: 3600 + supportedGrantTypes: + type: array + items: + type: string + description: The grant types that are supported by the application + example: ["client_credentials","password"] callbackUrl: type: string description: Callback URL @@ -2306,6 +2623,71 @@ definitions: description: Allowed scopes for the access token example: ["am_application_scope","default"] +#----------------------------------------------------- +# Scope Info resource +#----------------------------------------------------- + ScopeInfo: + title: API Scope info object with scope details + properties: + key: + type: string + example: admin_scope + name: + type: string + example: admin scope + roles: + type: array + items: + type: string + description: Allowed roles for the scope + example: ["manager","developer"] + +#----------------------------------------------------- +# Tier Permission Info resource +#----------------------------------------------------- + TierPermissionInfo: + title: Tier Permission info object with tier permission details + properties: + type: + type: string + enum: + - allow + - deny + roles: + type: array + items: + type: string + description: roles for this permission + example: ["manager","developer"] + + ApplicationScope : + title: Scope of the APIs + properties: + key: + type: string + description: Key of scope + example: apim:fileread + name: + type: string + description: Name of the scope + example: apim file read + roles : + type: string + description: Roles scope is bounded to + example : admin, role1 + description: + type: string + description: Description of the scope + + ScopeList : + title : Scope list + properties: + list : + type : array + items: + $ref: '#/definitions/ApplicationScope' + + #----------------------------------------------------- # END-OF-FILE #----------------------------------------------------- \ No newline at end of file diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/pom.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/pom.xml index 7bd0d2c6665..51bb5ed8867 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/pom.xml +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/pom.xml @@ -22,13 +22,13 @@ apimgt-extensions org.wso2.carbon.devicemgt - 3.0.217-SNAPSHOT + 3.1.34-SNAPSHOT ../pom.xml 4.0.0 org.wso2.carbon.apimgt.webapp.publisher - 3.0.217-SNAPSHOT + 3.1.34-SNAPSHOT bundle WSO2 Carbon - API Management Webapp Publisher WSO2 Carbon - API Management Webapp Publisher diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java index 4bb54d5ac15..2fe35e472bf 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/main/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceImpl.java @@ -50,10 +50,10 @@ public class APIPublisherServiceImpl implements APIPublisherService { PublisherClient publisherClient = APIPublisherDataHolder.getInstance().getIntegrationClientService() .getPublisherClient(); API api = getAPI(apiConfig); - APIList apiList = publisherClient.getApi().apisGet(100, 0, "name:" + api.getName(), CONTENT_TYPE, null); + APIList apiList = publisherClient.getApis().apisGet(100, 0, "name:" + api.getName(), CONTENT_TYPE, null); if (!isExist(api, apiList)) { - api = publisherClient.getApi().apisPost(api, CONTENT_TYPE); + api = publisherClient.getApi().apisPost(api, CONTENT_TYPE, null); if (CREATED_STATUS.equals(api.getStatus())) { publisherClient.getApi().apisChangeLifecyclePost(PUBLISH_ACTION, api.getId(), null, null, null); } diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceTest.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceTest.java index 87d27c5e524..f5f38676535 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceTest.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/java/org/wso2/carbon/apimgt/webapp/publisher/APIPublisherServiceTest.java @@ -27,7 +27,8 @@ import org.wso2.carbon.apimgt.integration.client.OAuthRequestInterceptor; import org.wso2.carbon.apimgt.integration.client.model.OAuthApplication; import org.wso2.carbon.apimgt.integration.client.publisher.PublisherClient; import org.wso2.carbon.apimgt.integration.client.service.IntegrationClientService; -import org.wso2.carbon.apimgt.integration.generated.client.publisher.api.APIsApi; +import org.wso2.carbon.apimgt.integration.generated.client.publisher.api.APICollectionApi; +import org.wso2.carbon.apimgt.integration.generated.client.publisher.api.APIIndividualApi; import org.wso2.carbon.apimgt.integration.generated.client.publisher.model.API; import org.wso2.carbon.apimgt.integration.generated.client.publisher.model.APIInfo; import org.wso2.carbon.apimgt.integration.generated.client.publisher.model.APIList; @@ -35,7 +36,8 @@ import org.wso2.carbon.apimgt.webapp.publisher.config.WebappPublisherConfig; import org.wso2.carbon.apimgt.webapp.publisher.dto.ApiScope; import org.wso2.carbon.apimgt.webapp.publisher.exception.APIManagerPublisherException; import org.wso2.carbon.apimgt.webapp.publisher.internal.APIPublisherDataHolder; -import org.wso2.carbon.apimgt.webapp.publisher.utils.MockApi; +import org.wso2.carbon.apimgt.webapp.publisher.utils.MockAPICollectionApi; +import org.wso2.carbon.apimgt.webapp.publisher.utils.MockAPIIndividualApi; import org.wso2.carbon.apimgt.webapp.publisher.utils.TestUtils; import java.lang.reflect.Field; @@ -61,6 +63,12 @@ public class APIPublisherServiceTest extends BaseAPIPublisherTest { APIManagerPublisherException { APIConfig apiConfig = new APIConfig(); setApiConfigs(apiConfig, "testAPI-0"); + PublisherClient publisherClient = APIPublisherDataHolder.getInstance().getIntegrationClientService(). + getPublisherClient(); + APICollectionApi collectionApi = Mockito.mock(MockAPICollectionApi.class, Mockito.CALLS_REAL_METHODS); + APIIndividualApi apIsApi = Mockito.mock(MockAPIIndividualApi.class, Mockito.CALLS_REAL_METHODS); + doReturn(collectionApi).when(publisherClient).getApis(); + doReturn(apIsApi).when(publisherClient).getApi(); apiPublisherService.publishAPI(apiConfig); } @@ -77,11 +85,13 @@ public class APIPublisherServiceTest extends BaseAPIPublisherTest { PublisherClient publisherClient = APIPublisherDataHolder.getInstance().getIntegrationClientService(). getPublisherClient(); doReturn(publisherClient).when(integrationClientService).getPublisherClient(); - APIsApi apIsApi = Mockito.mock(MockApi.class, Mockito.CALLS_REAL_METHODS); + APIIndividualApi apIsApi = Mockito.mock(MockAPIIndividualApi.class, Mockito.CALLS_REAL_METHODS); + APICollectionApi collectionApi = Mockito.mock(MockAPICollectionApi.class, Mockito.CALLS_REAL_METHODS); + doReturn(collectionApi).when(publisherClient).getApis(); doReturn(apIsApi).when(publisherClient).getApi(); API api = Mockito.mock(API.class, Mockito.CALLS_REAL_METHODS); api.setStatus("CREATED"); - doReturn(api).when(apIsApi).apisPost(Mockito.any(), Mockito.anyString()); + doReturn(api).when(apIsApi).apisPost(Mockito.any(), Mockito.anyString(), Mockito.anyString()); apiPublisherService.publishAPI(apiConfig); } @@ -97,18 +107,18 @@ public class APIPublisherServiceTest extends BaseAPIPublisherTest { PublisherClient publisherClient = APIPublisherDataHolder.getInstance().getIntegrationClientService(). getPublisherClient(); doReturn(publisherClient).when(integrationClientService).getPublisherClient(); - APIsApi apIsApi = Mockito.mock(MockApi.class, Mockito.CALLS_REAL_METHODS); + APIIndividualApi apIsApi = Mockito.mock(MockAPIIndividualApi.class, Mockito.CALLS_REAL_METHODS); + APICollectionApi collectionApi = Mockito.mock(MockAPICollectionApi.class, Mockito.CALLS_REAL_METHODS); + doReturn(collectionApi).when(publisherClient).getApis(); doReturn(apIsApi).when(publisherClient).getApi(); API api = Mockito.mock(API.class, Mockito.CALLS_REAL_METHODS); api.setStatus("CREATED"); - doReturn(api).when(apIsApi).apisPost(Mockito.any(), Mockito.anyString()); + doReturn(api).when(apIsApi).apisPost(Mockito.any(), Mockito.anyString(), Mockito.anyString()); APIList apiList = Mockito.mock(APIList.class, Mockito.CALLS_REAL_METHODS); APIInfo apiInfo = new APIInfo(); List apiInfoList = new ArrayList<>(); apiInfoList.add(apiInfo); apiList.list(apiInfoList); - doReturn(apiList).when(apIsApi).apisGet(Mockito.anyInt(), Mockito.anyInt(), - Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); doReturn(api).when(apIsApi).apisApiIdPut(Mockito.anyString(), Mockito.any(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); apiPublisherService.publishAPI(apiConfig); @@ -126,11 +136,13 @@ public class APIPublisherServiceTest extends BaseAPIPublisherTest { PublisherClient publisherClient = APIPublisherDataHolder.getInstance().getIntegrationClientService(). getPublisherClient(); doReturn(publisherClient).when(integrationClientService).getPublisherClient(); - APIsApi apIsApi = Mockito.mock(MockApi.class, Mockito.CALLS_REAL_METHODS); + APIIndividualApi apIsApi = Mockito.mock(MockAPIIndividualApi.class, Mockito.CALLS_REAL_METHODS); + APICollectionApi collectionApi = Mockito.mock(MockAPICollectionApi.class, Mockito.CALLS_REAL_METHODS); + doReturn(collectionApi).when(publisherClient).getApis(); doReturn(apIsApi).when(publisherClient).getApi(); API api = Mockito.mock(API.class, Mockito.CALLS_REAL_METHODS); api.setStatus("CREATED"); - doReturn(api).when(apIsApi).apisPost(Mockito.any(), Mockito.anyString()); + doReturn(api).when(apIsApi).apisPost(Mockito.any(), Mockito.anyString(), Mockito.anyString()); APIList apiList = Mockito.mock(APIList.class, Mockito.CALLS_REAL_METHODS); APIInfo apiInfo = new APIInfo(); apiInfo.setName("testAPI-3"); @@ -139,8 +151,6 @@ public class APIPublisherServiceTest extends BaseAPIPublisherTest { List apiInfoList = new ArrayList<>(); apiInfoList.add(apiInfo); apiList.list(apiInfoList); - doReturn(apiList).when(apIsApi).apisGet(Mockito.anyInt(), Mockito.anyInt(), - Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); doReturn(api).when(apIsApi).apisApiIdPut(Mockito.anyString(), Mockito.any(), Mockito.anyString(), Mockito.anyString(), Mockito.anyString()); apiConfig.setSharedWithAllTenants(false); diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/java/org/wso2/carbon/apimgt/webapp/publisher/BaseAPIPublisherTest.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/java/org/wso2/carbon/apimgt/webapp/publisher/BaseAPIPublisherTest.java index 229d11a9702..dd2d111c340 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/java/org/wso2/carbon/apimgt/webapp/publisher/BaseAPIPublisherTest.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/java/org/wso2/carbon/apimgt/webapp/publisher/BaseAPIPublisherTest.java @@ -26,9 +26,9 @@ import org.wso2.carbon.apimgt.integration.client.IntegrationClientServiceImpl; import org.wso2.carbon.apimgt.integration.client.internal.APIIntegrationClientDataHolder; import org.wso2.carbon.apimgt.integration.client.publisher.PublisherClient; import org.wso2.carbon.apimgt.integration.client.service.IntegrationClientService; -import org.wso2.carbon.apimgt.integration.generated.client.publisher.api.APIsApi; +import org.wso2.carbon.apimgt.integration.generated.client.publisher.api.APIIndividualApi; import org.wso2.carbon.apimgt.webapp.publisher.internal.APIPublisherDataHolder; -import org.wso2.carbon.apimgt.webapp.publisher.utils.MockApi; +import org.wso2.carbon.apimgt.webapp.publisher.utils.MockAPIIndividualApi; import org.wso2.carbon.base.MultitenantConstants; import org.wso2.carbon.context.PrivilegedCarbonContext; import org.wso2.carbon.context.internal.OSGiDataHolder; @@ -87,7 +87,7 @@ public abstract class BaseAPIPublisherTest { PublisherClient publisherClient = Mockito.mock(PublisherClient.class, Mockito.CALLS_REAL_METHODS); doReturn(publisherClient).when(integrationClientService).getPublisherClient(); - APIsApi api = new MockApi(); + APIIndividualApi api = new MockAPIIndividualApi(); Field field = PublisherClient.class.getDeclaredField("api"); field.setAccessible(true); field.set(publisherClient, api); diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/java/org/wso2/carbon/apimgt/webapp/publisher/utils/MockAPICollectionApi.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/java/org/wso2/carbon/apimgt/webapp/publisher/utils/MockAPICollectionApi.java new file mode 100644 index 00000000000..f13c43a953f --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/java/org/wso2/carbon/apimgt/webapp/publisher/utils/MockAPICollectionApi.java @@ -0,0 +1,32 @@ +/* +* Copyright (c) 2017, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. +* +* WSO2 Inc. licenses this file to you 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 +* +* http://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. +*/ +package org.wso2.carbon.apimgt.webapp.publisher.utils; + +import org.wso2.carbon.apimgt.integration.generated.client.publisher.api.APICollectionApi; +import org.wso2.carbon.apimgt.integration.generated.client.publisher.model.APIList; + +/** + * Class to create MockApi for testing. + */ +public class MockAPICollectionApi implements APICollectionApi { + + @Override + public APIList apisGet(Integer limit, Integer offset, String query, String accept, String ifNoneMatch) { + return null; + } +} diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/java/org/wso2/carbon/apimgt/webapp/publisher/utils/MockApi.java b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/java/org/wso2/carbon/apimgt/webapp/publisher/utils/MockAPIIndividualApi.java similarity index 86% rename from components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/java/org/wso2/carbon/apimgt/webapp/publisher/utils/MockApi.java rename to components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/java/org/wso2/carbon/apimgt/webapp/publisher/utils/MockAPIIndividualApi.java index f9e22de3e8d..9e8260a8517 100644 --- a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/java/org/wso2/carbon/apimgt/webapp/publisher/utils/MockApi.java +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/java/org/wso2/carbon/apimgt/webapp/publisher/utils/MockAPIIndividualApi.java @@ -17,9 +17,9 @@ */ package org.wso2.carbon.apimgt.webapp.publisher.utils; -import org.wso2.carbon.apimgt.integration.generated.client.publisher.api.APIsApi; +import feign.Param; +import org.wso2.carbon.apimgt.integration.generated.client.publisher.api.APIIndividualApi; import org.wso2.carbon.apimgt.integration.generated.client.publisher.model.API; -import org.wso2.carbon.apimgt.integration.generated.client.publisher.model.APIList; import org.wso2.carbon.apimgt.integration.generated.client.publisher.model.FileInfo; import java.io.File; @@ -27,7 +27,7 @@ import java.io.File; /** * Class to create MockApi for testing. */ -public class MockApi implements APIsApi { +public class MockAPIIndividualApi implements APIIndividualApi { @Override public void apisApiIdDelete(String apiId, String ifMatch, String ifUnmodifiedSince) { @@ -75,12 +75,8 @@ public class MockApi implements APIsApi { } @Override - public APIList apisGet(Integer limit, Integer offset, String query, String accept, String ifNoneMatch) { - return null; - } - - @Override - public API apisPost(API body, String contentType) { + public API apisPost(API body, @Param("contentType") String contentType, @Param("authorization") String authorization) { return new API(); } + } diff --git a/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/resources/carbon-home/repository/conf/carbon.xml b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/resources/carbon-home/repository/conf/carbon.xml new file mode 100644 index 00000000000..f24ee57be23 --- /dev/null +++ b/components/apimgt-extensions/org.wso2.carbon.apimgt.webapp.publisher/src/test/resources/carbon-home/repository/conf/carbon.xml @@ -0,0 +1,656 @@ + + + + + + + + + ${product.name} + + + ${product.key} + + + ${product.version} + + + + + + + + + local:/${carbon.context}/services/ + + + + + + + ${default.server.role} + + + + + + + org.wso2.carbon + + + / + + + + + + + + + 15 + + + + + + + + + 0 + + + + + 9999 + + 11111 + + + + + + 10389 + + 8000 + + + + + + 10500 + + + + + + + org.wso2.carbon.tomcat.jndi.CarbonJavaURLContextFactory + + + + + + + + + java + + + + + + + + + + false + + + false + + + 600 + + + + false + + + + + + + + 30 + + + + + + + + + 15 + + + + + + ${carbon.home}/repository/deployment/server/ + + + 15 + + + ${carbon.home}/repository/conf/axis2/axis2.xml + + + 30000 + + + ${carbon.home}/repository/deployment/client/ + + ${carbon.home}/repository/conf/axis2/axis2_client.xml + + true + + + + + + + + + + admin + Default Administrator Role + + + user + Default User Role + + + + + + + + + + + + ${carbon.home}/repository/resources/security/wso2carbon.jks + + JKS + + wso2carbon + + wso2carbon + + wso2carbon + + + + + + ${carbon.home}/repository/resources/security/client-truststore.jks + + JKS + + wso2carbon + + + + + + + + + + + + + + + + + + + UserManager + + + false + + + + + + + ${carbon.home}/tmp/work + + + + + + true + + + 10 + + + 30 + + + + + + 100 + + + + keystore + certificate + * + + org.wso2.carbon.ui.transports.fileupload.AnyFileUploadExecutor + + + + + jarZip + + org.wso2.carbon.ui.transports.fileupload.JarZipUploadExecutor + + + + dbs + + org.wso2.carbon.ui.transports.fileupload.DBSFileUploadExecutor + + + + tools + + org.wso2.carbon.ui.transports.fileupload.ToolsFileUploadExecutor + + + + toolsAny + + org.wso2.carbon.ui.transports.fileupload.ToolsAnyFileUploadExecutor + + + + + + + info + org.wso2.carbon.core.transports.util.InfoProcessor + + + wsdl + org.wso2.carbon.core.transports.util.Wsdl11Processor + + + wsdl2 + org.wso2.carbon.core.transports.util.Wsdl20Processor + + + xsd + org.wso2.carbon.core.transports.util.XsdProcessor + + + + + + false + false + true + svn + http://svnrepo.example.com/repos/ + username + password + true + + + + + + + + + + + + + + + ${require.carbon.servlet} + + + + + true + + + + + + + default repository + ${p2.repo.url} + + + + + + + + true + + + + + + true + + diff --git a/components/apimgt-extensions/pom.xml b/components/apimgt-extensions/pom.xml index 059a9bc00c4..06747b53842 100644 --- a/components/apimgt-extensions/pom.xml +++ b/components/apimgt-extensions/pom.xml @@ -22,13 +22,13 @@ org.wso2.carbon.devicemgt carbon-devicemgt - 3.0.217-SNAPSHOT + 3.1.34-SNAPSHOT ../../pom.xml 4.0.0 apimgt-extensions - 3.0.217-SNAPSHOT + 3.1.34-SNAPSHOT pom WSO2 Carbon - API Management Extensions Component http://wso2.org diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.api/pom.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.api/pom.xml index b16ca5081b4..89067020852 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.api/pom.xml +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.api/pom.xml @@ -22,7 +22,7 @@ certificate-mgt org.wso2.carbon.devicemgt - 3.0.217-SNAPSHOT + 3.1.34-SNAPSHOT ../pom.xml diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/pom.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/pom.xml index 24b95a8453b..a9b3d9bd2ff 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/pom.xml +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.api/pom.xml @@ -22,7 +22,7 @@ certificate-mgt org.wso2.carbon.devicemgt - 3.0.217-SNAPSHOT + 3.1.34-SNAPSHOT ../pom.xml diff --git a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/pom.xml b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/pom.xml index 053d08e1d30..ba0d7533c98 100644 --- a/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/pom.xml +++ b/components/certificate-mgt/org.wso2.carbon.certificate.mgt.cert.admin.v09.api/pom.xml @@ -1,7 +1,7 @@ {{#zone "bottomJs"}} {{js "js/moment.min.js"}} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.realtime.analytics-view/public/js/device-stats.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.realtime.analytics-view/public/js/device-stats.js index be1f1e7c0c5..e84224d15aa 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.realtime.analytics-view/public/js/device-stats.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.default.device.type.realtime.analytics-view/public/js/device-stats.js @@ -48,6 +48,15 @@ function connect(target) { } $("#time-mode").text("Real Time Mode"); }; + ws.onerror = function (webSocketData) { + var websocketURL = webSocketData.currentTarget.url; + websocketURL = websocketURL.replace("wss://","https://"); + var uriParts = websocketURL.split("/"); + websocketURL = uriParts[0] + "//" + uriParts[2]; + var errorMsg = $("#websocker-onerror").html(); + errorMsg = errorMsg.replace(new RegExp('\\$webSocketURL', 'g'), websocketURL); + $("#div-chart").html("
" + errorMsg + "
"); + }; } } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.operation-bar/public/js/operation-bar.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.operation-bar/public/js/operation-bar.js index a892a32ff88..8d1a9475be7 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.operation-bar/public/js/operation-bar.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.operation-bar/public/js/operation-bar.js @@ -52,22 +52,21 @@ function submitForm(formId) { uriencodedQueryStr += prefix + input.attr("id") + "=" + input.val(); } else if (input.data("param-type") == "form") { var prefix = (uriencodedFormStr == "") ? "" : "&"; - if (input.attr("type") == "checkbox" || input.attr("type") == "radio"){ - - if (isItemSelected == undefined){ + if (input.attr("type") == "checkbox" || input.attr("type") == "radio") { + if (isItemSelected == undefined) { isItemSelected = false; } - if (input.is(':checked')){ + if (input.is(':checked')) { isItemSelected = true; uriencodedFormStr += prefix + input.attr("name") + "=" + input.val(); } - }else{ + } else { uriencodedFormStr += prefix + input.attr("id") + "=" + input.val(); } } }); - if (isItemSelected === false){ + if (isItemSelected === false) { title.html("Please Select One Option"); statusIcon.attr("class", defaultStatusClasses + " fw-error"); $(modalPopupContent).html(content.html()); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/listing.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/listing.hbs index b51e7f0eb87..cd41dc37f57 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/listing.hbs +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.types.listing/listing.hbs @@ -43,7 +43,7 @@

No device type is available to be displayed.

- diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/public/js/device-view.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/public/js/device-view.js index cedfb8bdc9c..7cce058c69e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/public/js/device-view.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.view/public/js/device-view.js @@ -145,7 +145,7 @@ function loadOperationsLog(update) { $(row.child()).removeClass('log-data-row'); tr.removeClass('shown'); } else { - invokerUtil.get(uri,(payload) => { + invokerUtil.get(uri, function (payload) { //update the parent status var payloadObject = JSON.parse(payload); if ( payloadObject["activityStatus"][0]["status"] != rowData["status"] ) { @@ -157,7 +157,7 @@ function loadOperationsLog(update) { tr.find('i.fw-down').removeClass('fw-down').addClass('fw-up'); $(row.child()).addClass('log-data-row'); tr.addClass('shown'); - },(error) => { + },function(error) { },contentType); } @@ -178,19 +178,17 @@ function loadOperationsLog(update) { responseMsg = activityStatus['0'].responses['0'].response; } - Object.entries(activityStatus).forEach( - ([key, entry]) => { - logStream += '
' + - '
' + - '
' + - '' + ((responseMsg == null) ? entry.status : responseMsg) + '
' + - '
' + - '
' + - '
' + entry.updatedTimestamp + '
' + - '
' + - '
'; - } - ); + $. each (payload.activityStatus, function (key, entry) { + logStream += '
' + + '
' + + '
' + + '' + entry.status + '
' + + '
' + + '
' + + '
' + entry.updatedTimestamp + '
' + + '
' + + '
'; + }); logStream += ''; return logStream; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.effective-policy.view/public/js/view.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.effective-policy.view/public/js/view.js index bb11a38d267..a2b2e27b941 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.effective-policy.view/public/js/view.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.effective-policy.view/public/js/view.js @@ -27,31 +27,29 @@ var displayPolicy = function (policyPayloadObj) { $("#policy-action").text(policyPayloadObj.compliance.toUpperCase()); $("#policy-description").text(policyPayloadObj["description"]); var policyStatus = "Active"; - if (policyPayloadObj["active"] == true && policyPayloadObj["updated"] == true) { + if (policyPayloadObj["active"] === true && policyPayloadObj["updated"] === true) { policyStatus = ' Active/Updated
'; - } else if (policyPayloadObj["active"] == true && policyPayloadObj["updated"] == false) { + } else if (policyPayloadObj["active"] === true && policyPayloadObj["updated"] === false) { policyStatus = ' Active'; - } else if (policyPayloadObj["active"] == false && policyPayloadObj["updated"] == true) { + } else if (policyPayloadObj["active"] === false && policyPayloadObj["updated"] === true) { policyStatus = ' Inactive/Updated'; - } else if (policyPayloadObj["active"] == false && policyPayloadObj["updated"] == false) { + } else if (policyPayloadObj["active"] === false && policyPayloadObj["updated"] === false) { policyStatus = ' Inactive'; } $("#policy-status").html(policyStatus); - if (policyPayloadObj.users == null) { + if (!policyPayloadObj.users) { $("#policy-users").text("NONE"); - } - else if (policyPayloadObj.users.length > 0) { + } else if (policyPayloadObj.users.length > 0) { $("#policy-users").text(policyPayloadObj.users.toString().split(",").join(", ")); } else { $("#users-row").addClass("hidden"); } - if (policyPayloadObj.deviceGroups == null) { + if (!policyPayloadObj.deviceGroups) { $("#policy-groups").text("NONE"); } else if (policyPayloadObj.deviceGroups.length > 0) { - debugger; var deviceGroups = policyPayloadObj.deviceGroups; var assignedGroups = []; for (var index in deviceGroups) { @@ -60,14 +58,11 @@ var displayPolicy = function (policyPayloadObj) { } } $("#policy-groups").text(assignedGroups.toString().split(",").join(", ")); - } else { - $("#policy-groups").text("NONE"); } - if (policyPayloadObj.roles == null) { + if (!policyPayloadObj.roles) { $("#policy-roles").text("NONE"); - } - else if (policyPayloadObj.roles.length > 0) { + } else if (policyPayloadObj.roles.length > 0) { $("#policy-roles").text(policyPayloadObj.roles.toString().split(",").join(", ")); } else { $("#roles-row").addClass("hidden"); @@ -131,7 +126,7 @@ $(document).ready(function () { "/api/device-mgt/v1.0" + "/policies/effective-policy/" + getParameterByName("type") + "/" + getParameterByName("id"), // on success function (data, textStatus, jqXHR) { - if (jqXHR.status == 200 && data) { + if (jqXHR.status === 200 && data) { policyPayloadObj = JSON.parse(data); displayPolicy(policyPayloadObj); } diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.footer/footer.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.footer/footer.hbs index 2df360ab3a4..2a6e296cc4b 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.footer/footer.hbs +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.footer/footer.hbs @@ -17,8 +17,8 @@ }} {{#zone "footer"}}

- - WSO2 IoT Server{{#unless isCloud}} 3.1.0{{/unless}} | © , + + WSO2 IoT Server{{#unless isCloud}} 3.2.0{{/unless}} | © , Inc. All Rights Reserved.

{{/zone}} \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/geo-dashboard.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/geo-dashboard.hbs index 151a91e9fd6..e2a5018d80d 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/geo-dashboard.hbs +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/geo-dashboard.hbs @@ -521,10 +521,10 @@

{{#if geoServicesEnabled}}
Speed km/h
-
Heading
- - - + + + + {{/if}} @@ -736,6 +736,7 @@ var geoLocationLink = $(".initGeoLocationLink"); if (geoLocationLink) { geoLocationLink.on('click', function () { + loadGeoFencing(); initializeGeoLocation({{geoServicesEnabled}}); }); geoPublicUri = $("#geo-charts").data("geo-public-uri"); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/geo-dashboard.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/geo-dashboard.js index 1fcfd20d1cf..de15fc40e46 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/geo-dashboard.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/geo-dashboard.js @@ -17,7 +17,6 @@ */ function onRequest(context) { - var log = new Log("geo-dashboard.js"); var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"]; var viewModel = {}; @@ -41,14 +40,14 @@ function onRequest(context) { wsEndpoint = devicemgtProps["wssURL"].replace("https", "wss") + "/secured-websocket/"; } } else { - tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username + "@" + context.user.domain,"default", {}); + tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username + "@" + + context.user.domain, "default", {}); if (tokenPair) { token = tokenPair.accessToken; - wsEndpoint = devicemgtProps["wssURL"].replace("https", "wss") + "/secured-websocket/t/"+context.user.domain+"/"; + wsEndpoint = devicemgtProps["wssURL"].replace("https", "wss") + "/secured-websocket/t/" + + context.user.domain + "/"; } - } - } viewModel.device = device; viewModel.wsToken = token; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/public/js/app.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/public/js/app.js index 9c9632f3df1..805ec7a3ab4 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/public/js/app.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/public/js/app.js @@ -46,7 +46,8 @@ function initialLoad(geoFencingEnabled) { } function initializeMap() { - if (typeof(map) !== 'undefined') { + ///map.zoomControl is added to fix UI loading issue on Safari + if (typeof(map) !== 'undefined' && map.zoomControl != null) { map.remove(); } if (document.getElementById('map') == null) { @@ -121,10 +122,10 @@ function processAfterInitializationMap(geoFencingEnabled) { }; map.addControl(L.control.fullscreen({position: 'bottomright'})); - geoAlertsBar = L.control.geoAlerts({position: 'topright'}); - if (geoFencingEnabled) { - map.addControl(geoAlertsBar); - } + // geoAlertsBar = L.control.geoAlerts({position: 'topright'}); + // if (geoFencingEnabled) { + // map.addControl(geoAlertsBar); + // } groupedOverlays = { "Web Map Service layers": {} @@ -255,7 +256,7 @@ function focusOnSpatialObject(objectId) { // TODO: check the map._layersMaxZoom and set the zoom level accordingly spatialObject.marker.openPopup(); - getAlertsHistory(deviceType, deviceId, new Date($('#timeFromCal').val()).getTime(), new Date($('#timeToCal').val()).getTime()); + // getAlertsHistory(deviceType, deviceId, new Date($('#timeFromCal').val()).getTime(), new Date($('#timeToCal').val()).getTime()); spatialObject.drawPath(); if (speedGraphControl) { setTimeout(function () { @@ -434,11 +435,11 @@ function drawSpatialObject() { return true; } - if (geoFencingEnabled) { - var alertsFromDate = new Date(); - alertsFromDate.setHours(alertsFromDate.getHours() - 24); //last 24 hours - getAlertsHistory(deviceType, deviceId, alertsFromDate.valueOf(), toDate.valueOf()); - } + // if (geoFencingEnabled) { + // var alertsFromDate = new Date(); + // alertsFromDate.setHours(alertsFromDate.getHours() - 24); //last 24 hours + // getAlertsHistory(deviceType, deviceId, alertsFromDate.valueOf(), toDate.valueOf()); + // } setTimeout(function () { map.invalidateSize(); @@ -512,7 +513,7 @@ function focusOnHistorySpatialObject(objectId, timeFrom, timeTo) { // TODO: check the map._layersMaxZoom and set the zoom level accordingly spatialObject.marker.openPopup(); - getAlertsHistory(deviceType, deviceId, new Date($('#timeFromCal').val()).getTime(), new Date($('#timeToCal').val()).getTime()); + // getAlertsHistory(deviceType, deviceId, new Date($('#timeFromCal').val()).getTime(), new Date($('#timeToCal').val()).getTime()); spatialObject.drawPath(); if (speedGraphControl) { setTimeout(function () { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/public/js/geo_fencing.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/public/js/geo_fencing.js index 5996dbcac35..182a9a1baa3 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/public/js/geo_fencing.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/public/js/geo_fencing.js @@ -23,10 +23,9 @@ var drawnItems; var lastId; var controlDiv; -loadGeoFencing(); - function loadGeoFencing() { - if (map == null) { + ///map.zoomControl is added to fix UI loading issue on Safari + if (map == null || map.zoomControl == null) { setTimeout(loadGeoFencing, 1000); // give everything some time to render } else { map.on('draw:created', function (e) { @@ -40,30 +39,30 @@ function loadGeoFencing() { function openTools(id) { lastId = id; - if (drawControl) { - try{ - map.removeControl(drawControl); - } catch(e) { - console.log("error: " + e.message); - } - console.log("removed drawControl"); + if (drawControl) { + try{ + map.removeControl(drawControl); + } catch(e) { + console.log("error: " + e.message); + } + console.log("removed drawControl"); } if (removeAllControl) { - try { - map.removeControl(removeAllControl); - } catch(e) { - console.log("error: " + e.message); - } - console.log("removed removeAllControl"); + try { + map.removeControl(removeAllControl); + } catch(e) { + console.log("error: " + e.message); + } + console.log("removed removeAllControl"); } if (drawnItems) { - try{ - map.removeLayer(drawnItems); - console.log("removing layer"); - } catch(e) { - console.log("error: " + e.message); - } - console.log("removed drawnItems"); + try{ + map.removeLayer(drawnItems); + console.log("removing layer"); + } catch(e) { + console.log("error: " + e.message); + } + console.log("removed drawnItems"); } closeAll(); @@ -85,7 +84,7 @@ function openTools(id) { drawnItems.clearLayers(); if(id == "Prediction"){ $('#predictionResults').animate({width: ['toggle','swing']},200); - toggeled = false; + toggeled = false; } }); @@ -109,7 +108,7 @@ function openTools(id) { // Initialise the FeatureGroup to store editable layers drawnItems = new L.FeatureGroup(); map.addLayer(drawnItems); - + if (id=="WithIn") { // Initialise the draw control and pass it the FeatureGroup of editable layers drawControl = new L.Control.Draw({ @@ -140,30 +139,30 @@ function openTools(id) { } else if (id=="Exit") { // Initialise the draw control and pass it the FeatureGroup of editable layers drawControl = new L.Control.Draw({ - draw: { - polygon: { - allowIntersection: false, // Restricts shapes to simple polygons - drawError: { - color: '#e1e100', // Color the shape will turn when intersects - message: 'Oh snap! you can\'t draw that!' // Message that will show when intersect - }, - shapeOptions: { - color: '#ff0043' - } - }, - rectangle: { - shapeOptions: { - color: '#002bff' - } - }, - polyline: false, - circle: false, // Turns off this drawing tool - marker: false // Markers are not applicable for within geo fencing - }, - edit: { - featureGroup: drawnItems - } - }); + draw: { + polygon: { + allowIntersection: false, // Restricts shapes to simple polygons + drawError: { + color: '#e1e100', // Color the shape will turn when intersects + message: 'Oh snap! you can\'t draw that!' // Message that will show when intersect + }, + shapeOptions: { + color: '#ff0043' + } + }, + rectangle: { + shapeOptions: { + color: '#002bff' + } + }, + polyline: false, + circle: false, // Turns off this drawing tool + marker: false // Markers are not applicable for within geo fencing + }, + edit: { + featureGroup: drawnItems + } + }); } else if(id=="Stationery"){ // Initialise the draw control and pass it the FeatureGroup of editable layers drawControl = new L.Control.Draw({ @@ -221,9 +220,9 @@ function openTools(id) { } }, marker: { - shapeOptions: { - color: '#ff0043' - } + shapeOptions: { + color: '#ff0043' + } } }, edit: { @@ -231,16 +230,16 @@ function openTools(id) { } }); } else if (id =="Prediction") { - drawControl = new L.Control.Draw({ + drawControl = new L.Control.Draw({ draw: { polygon: false, rectangle: false, polyline: false, circle: false, marker: { - shapeOptions: { - color: '#ff0043' - } + shapeOptions: { + color: '#ff0043' + } } }, edit: { @@ -267,10 +266,10 @@ function createPopup(layer,id) { popupTemplate.find('#addTrafficAlert').attr('leaflet_id', layer._leaflet_id); //console.log(">>got here " + id + " " + popupTemplate.find('#addTrafficAlert') + " " + layer._leaflet_id); } else if (id=="Prediction") { - getPrediction(layer._leaflet_id); - return; + getPrediction(layer._leaflet_id); + return; } - + popupTemplate.find('.exportGeoJson').attr('leaflet_id', layer._leaflet_id); popupTemplate.find('.editGeoJson').attr('leaflet_id', layer._leaflet_id); @@ -363,9 +362,9 @@ function viewFence(geoFenceElement,id) { color: '#ff0043' }; geometryShape= new L.circle([geoJson.coordinates[1],geoJson.coordinates[0]], geoJson.radius,circleOptions); - // var marker=new L.marker([geoJson.coordinates[1],geoJson.coordinates[0]]); + // var marker=new L.marker([geoJson.coordinates[1],geoJson.coordinates[0]]); map.addLayer(geometryShape); - // map.addLayer(marker); + // map.addLayer(marker); } else if (geoJson.type=="Polygon") { geoJson.coordinates[0].pop(); // popout the last coordinate set(lat,lng pair) due to circular chain var leafletLatLngs = []; @@ -494,4 +493,3 @@ function viewFenceByData(geoJson, queryName, areaName, stationeryTime, id) { } closeAll(); } - diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/public/js/geo_remote.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/public/js/geo_remote.js index e5894ceee10..136e4554532 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/public/js/geo_remote.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/public/js/geo_remote.js @@ -248,7 +248,6 @@ function setWithinAlert(leafletId) { var data = { 'parseData': JSON.stringify({ 'geoFenceGeoJSON': selectedAreaGeoJson, - 'executionPlanName': createExecutionPlanName(queryName, "WithIn", deviceId), 'areaName': areaName, 'deviceId': deviceId }), @@ -281,7 +280,7 @@ function setWithinAlert(leafletId) { responseHandler, function (xhr) { responseHandler(xhr.responseText, xhr.statusText, xhr); }); - viewFenceByData(selectedAreaGeoJson, queryName, areaName, null, 'Within'); + viewFenceByData(selectedAreaGeoJson, queryName, areaName, null, 'WithIn'); } } @@ -307,7 +306,6 @@ function setExitAlert(leafletId) { var data = { 'parseData': JSON.stringify({ 'geoFenceGeoJSON': selectedAreaGeoJson, - 'executionPlanName': createExecutionPlanName(queryName, "Exit", deviceId), 'areaName': areaName, 'deviceId': deviceId }), @@ -379,7 +377,6 @@ function setStationeryAlert(leafletId) { var data = { 'parseData': JSON.stringify({ 'geoFenceGeoJSON': selectedProcessedAreaGeoJson, - 'executionPlanName': createExecutionPlanName(queryName, "Stationery", deviceId), 'stationeryName': stationeryName, 'stationeryTime': time, 'fluctuationRadius': fluctuationRadius @@ -414,7 +411,7 @@ function setStationeryAlert(leafletId) { responseHandler, function (xhr) { responseHandler(xhr.responseText, xhr.statusText, xhr); }); - viewFenceByData(selectedProcessedAreaGeoJson, queryName, areaName, time, 'Stationery'); + viewFenceByData(selectedProcessedAreaGeoJson, queryName, stationeryName, time, 'Stationery'); } @@ -492,7 +489,6 @@ function setTrafficAlert(leafletId) { var data = { 'parseData': JSON.stringify({ 'geoFenceGeoJSON': selectedProcessedAreaGeoJson, - 'executionPlanName': createExecutionPlanName(queryName, "Traffic", deviceId), 'areaName': areaName }), 'executionPlan': 'Traffic', @@ -563,8 +559,8 @@ function getAlertsHistory(deviceType, deviceId, timeFrom, timeTo) { if (val.values) { val = val.values; } - var msg = deviceType.charAt(0).toUpperCase() + deviceType.slice(1) + - " " + deviceId + " " + val.information.replace("Alerts: ,", "") + " - " + timeSince(val.timeStamp); + var msg = val.information.replace("Alerts: ,", "").charAt(0).toUpperCase() + + val.information.replace("Alerts: ,", "").slice(1) + " - " + timeSince(val.timeStamp); switch (val.state) { case "NORMAL": return; @@ -634,21 +630,6 @@ function setProximityAlert() { } } -// TODO:this is not a remote call , move this to application.js -function createExecutionPlanName(queryName, id, deviceId) { - - if (id == "WithIn") { - return 'Geo-ExecutionPlan-Within' + (queryName ? '_' + queryName : '') + "---" + (deviceId ? '_' + deviceId : '') + '_alert'; // TODO: value of the `queryName` can't be empty, because it will cause name conflicts in CEP, have to do validation(check not empty String) - } else if (id == "Exit") { - return 'Geo-ExecutionPlan-Exit' + (queryName ? '_' + queryName : '') + "---" + (deviceId ? '_' + deviceId : '') + '_alert'; // TODO: value of the `queryName` can't be empty, because it will cause name conflicts in CEP, have to do validation(check not empty String) - } else if (id == "Stationery") { - return 'Geo-ExecutionPlan-Stationery' + (queryName ? '_' + queryName : '') + "---" + (deviceId ? '_' + deviceId : '') + '_alert'; // TODO: value of the `queryName` can't be empty, because it will cause name conflicts in CEP, have to do validation(check not empty String) - } else if (id == "Traffic") { - return 'Geo-ExecutionPlan-Traffic' + (queryName ? '_' + queryName : '') + '_alert'; // TODO: value of the `queryName` can't be empty, because it will cause name conflicts in CEP, have to do validation(check not empty String) - } - -} - // TODO:this is not a remote call , move this to application.js function closeAll() { $('.modal').modal('hide'); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/public/js/websocket.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/public/js/websocket.js index fbecf66217f..5bc0c3d8a1e 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/public/js/websocket.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-dashboard/public/js/websocket.js @@ -78,7 +78,7 @@ function initializeGeoLocation(geoFencingEnabled) { geoPublicUri = geoCharts.data("geo-public-uri"); webSocketURL = wsEndPoint + "iot.per.device.stream.geo.FusedSpatialEvent/1.0.0?" + "deviceId=" + deviceId + "&deviceType=" + deviceType + "&websocketToken=" + wsToken; - alertWebSocketURL = wsEndPoint + "iot.per.device.stream.geo.AlertsNotifications/1.0.0?" + alertWebSocketURL = wsEndPoint + "iot.per.device.stream.geo.AlertNotifications/1.0.0?" + "deviceId=" + deviceId + "&deviceType=" + deviceType + "&websocketToken=" + wsToken; $("#proximity_alert").hide(); @@ -214,7 +214,7 @@ SpatialObject.prototype.update = function (geoJSON) { this.popupTemplate.find('#information').html(this.information); this.popupTemplate.find('#speed').html(Math.round(this.speed * 10) / 10); - this.popupTemplate.find('#heading').html(angleToHeading(this.heading)); + // this.popupTemplate.find('#heading').html(angleToHeading(this.heading)); this.marker.setPopupContent(this.popupTemplate.html()) }; @@ -561,7 +561,7 @@ var webSocketOnAlertMessage = function processMessage(message) { var json = $.parseJSON(message.data); if (json.messageType == "Alert") { processAlertMessage(json); - }else { + } else { console.log("Message type not supported."); } } @@ -571,7 +571,11 @@ var webSocketOnAlertClose = function (e) { }; var webSocketOnAlertError = function (e) { - noty({text: 'Something went wrong when trying to connect to ' + alertWebSocketURL + '', type: 'error'}); + var wsURL = alertWebSocketURL; + wsURL = wsURL.replace("wss://","https://"); + var uriParts = wsURL.split("/"); + wsURL = uriParts[0] + "//" + uriParts[2]; + noty({text: 'Something went wrong when trying to connect to ' + wsURL + '', type: 'error'}); }; var webSocketSpatialOnOpen = function () { @@ -598,7 +602,11 @@ var webSocketSpatialOnClose = function (e) { }; var webSocketSpatialOnError = function (err) { - noty({text: 'Something went wrong when trying to connect to ' + webSocketURL + '', type: 'error'}); + var wsURL = webSocketURL; + wsURL = wsURL.replace("wss://","https://"); + var uriParts = wsURL.split("/"); + wsURL = uriParts[0] + "//" + uriParts[2]; + noty({text: 'Something went wrong when trying to connect to ' + wsURL + '', type: 'error'}); }; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/geo-devices.hbs b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/geo-devices.hbs index 2d6476ee0d9..63a861940d4 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/geo-devices.hbs +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/geo-devices.hbs @@ -27,11 +27,833 @@ {{css "css/leaflet.awesome-markers.css" combine=false}} {{/zone}} +
+
+
+
+ +
+ + + +
+
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + +
+
+
+

ID

+
+
Information
+

+
+
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+

ID

+ +
+
Information
+ +

+
+
+ +
+
+

ID

+
+
Severity
+ +

+
+
+
Information
+ +

+
+
+ +
+
+
+ + + Name of the selected area(e.g. colombo) +
+
+
+
+ +
+
+ +
+
+ Export +
+
+
+
+
+
+
+
+ + + Name of the selected area(e.g. colombo) +
+
+
+
+ +
+
+ +
+
+ Export +
+
+
+
+
+
+
+
+
+ + + Name of the selected area(e.g. colombo) + + + + + + +
+
+
+
+ +
+
+ +
+
+ Export +
+
+
+
+
+
+
+
+ + + Name of the selected area(e.g. colombo) +
+
+
+
+ +
+
+ +
+
+ Export +
+
+
+
+
+
{{#zone "bottomJs" }} @@ -39,6 +861,7 @@ {{js "js/leaflet/leaflet.markercluster.js" }} {{js "js/leaflet/L.Control.Locate.js" }} {{js "js/leaflet/L.Control.Focus.js" }} + {{js "js/leaflet/L.Control.GeoAlerts.js" }} {{js "js/leaflet/leaflet.groupedlayercontrol.js" }} {{js "js/leaflet/Leaflet.fullscreen.min.js" }} {{js "js/leaflet/Marker.Rotate.js" }} @@ -47,9 +870,30 @@ {{js "js/typeahead.bundle.min.js" }} {{js "js/geo_remote.js" }} {{js "js/app.js" }} + + {{!js "js/jquery/jquery-ui.min.js" }} + + + {{js "js/firstTemp.js" }} + + + {{js "js/d3/d3.min.js" }} + {{js "js/d3/c3.min.js" }} + {{js "js/application_options.js" }} + {{js "js/secondTemp.js" }} + + {{js "js/show_alert_in_map.js" }} + + {{js "js/websocket.js" }} + {{js "js/geo_fencing.js" }} + {{/zone}} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/geo-devices.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/geo-devices.js new file mode 100644 index 00000000000..eddb14ea91b --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/geo-devices.js @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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 + * + * http://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. + */ + +function onRequest(context) { + + var log = new Log("geo-devices.js"); + var devicemgtProps = require("/app/modules/conf-reader/main.js")["conf"]; + var viewModel = {}; + var carbonServer = require("carbon").server; + var device = context.unit.params.device; + var constants = require("/app/modules/constants.js"); + var wsEndpoint = null; + var jwtService = carbonServer.osgiService( + 'org.wso2.carbon.identity.jwt.client.extension.service.JWTClientManagerService'); + var jwtClient = jwtService.getJWTClient(); + var encodedClientKeys = session.get(constants["ENCODED_TENANT_BASED_WEB_SOCKET_CLIENT_CREDENTIALS"]); + var tokenPair = null; + var token = ""; + if (encodedClientKeys) { + var tokenUtil = require("/app/modules/oauth/token-handler-utils.js")["utils"]; + var resp = tokenUtil.decode(encodedClientKeys).split(":"); + if (context.user.domain == "carbon.super") { + tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username,"default", {}); + if (tokenPair) { + token = tokenPair.accessToken; + wsEndpoint = devicemgtProps["wssURL"].replace("https", "wss") + "/secured-websocket/"; + } + } else { + tokenPair = jwtClient.getAccessToken(resp[0], resp[1], context.user.username + "@" + context.user.domain,"default", {}); + if (tokenPair) { + token = tokenPair.accessToken; + wsEndpoint = devicemgtProps["wssURL"].replace("https", "wss") + "/secured-websocket/t/"+context.user.domain+"/"; + } + + } + + } + viewModel.device = device; + viewModel.wsToken = token; + viewModel.wsEndpoint = wsEndpoint; + viewModel.geoServicesEnabled = devicemgtProps.serverConfig.geoLocationConfiguration.enabled; + return viewModel; +} \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/assets/html_templates/modal/proximity_alert.html b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/assets/html_templates/modal/proximity_alert.html new file mode 100644 index 00000000000..a24b4291c66 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/assets/html_templates/modal/proximity_alert.html @@ -0,0 +1,95 @@ + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/assets/html_templates/modal/traffic_point.html b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/assets/html_templates/modal/traffic_point.html new file mode 100644 index 00000000000..834cd47b4a3 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/assets/html_templates/modal/traffic_point.html @@ -0,0 +1,106 @@ + + + + + + + + + + + + + + + + + + diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/assets/html_templates/view_fence_popup.html b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/assets/html_templates/view_fence_popup.html new file mode 100644 index 00000000000..0314ef5a037 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/assets/html_templates/view_fence_popup.html @@ -0,0 +1,52 @@ + + + + + + + + +
+

+
+
+ + +
+
+
+
+

+
+
+ + +
+
+
+
+

+
+
+
Stationery time(Seconds)N/A
+ + +
+
+
+ + \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/conf/alerts/Geo-ExecutionPlan-Exit_alert.siddhiql b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/conf/alerts/Geo-ExecutionPlan-Exit_alert.siddhiql new file mode 100644 index 00000000000..53902ccfe5c --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/conf/alerts/Geo-ExecutionPlan-Exit_alert.siddhiql @@ -0,0 +1,20 @@ +/* Enter a unique ExecutionPlan */ +@Plan:name('$executionPlanName') + +/* Enter a unique description for ExecutionPlan */ +-- @Plan:description('ExecutionPlan') + +/* define streams/tables and write queries here ... */ + +@Import('org.wso2.geo.StandardSpatialEvents:1.0.0') +define stream dataIn (id string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string); + +@Export('org.wso2.geo.ProcessedSpatialEvents:1.0.0') +define stream dataOut (id string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string, state string, information string); + +from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")==false and id == "$deviceId"]#geodashboard:subscribe() +select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "ALERTED" as state, "This device is in $areaName restricted area!!!" as information +insert into dataOut; +from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")!=false and id == "$deviceId"] +select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "NORMAL" as state, "" as information +insert into dataOut; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/conf/alerts/Geo-ExecutionPlan-Proximity_alert.siddhiql b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/conf/alerts/Geo-ExecutionPlan-Proximity_alert.siddhiql new file mode 100644 index 00000000000..fb64720391a --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/conf/alerts/Geo-ExecutionPlan-Proximity_alert.siddhiql @@ -0,0 +1,140 @@ +/* Enter a unique ExecutionPlan */ +@Plan:name('Geo-ExecutionPlan-Proximity_alert') + +/* Enter a unique description for ExecutionPlan */ +-- @Plan:description('ExecutionPlan') + +/* define streams/tables and write queries here ... */ + +@Import('org.wso2.geo.StandardSpatialEvents:1.0.0') +define stream dataIn (id string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, eventId string ); + +@Export('org.wso2.geo.ProcessedSpatialEvents:1.0.0') +define stream dataOut ( id string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, eventId string, state string, information string ); + +@IndexBy('id') +define table ProximityTable(id string, timeStamp long); + +@IndexBy('id') +define table AlertsTable(id string , proximityWith string, eventId string); + +from dataIn#geodashboard:subscribe() +select id, latitude, longitude, timeStamp, type, speed, heading, eventId +insert into initialStream; + +from initialStream[type == 'STOP'] +select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "" as proximityInfo ,"false" as isProximity +insert into dataOutStream; + +from initialStream[type != 'STOP'] +select * +insert into objectInitialStream; + +from objectInitialStream#geo:proximity(id,longitude,latitude, $proximityDistance) +select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith +insert into proxymityStream; + +from proxymityStream[AlertsTable.id == proxymityStream.id in AlertsTable] +select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith,true as inAlertTable +insert into innerStreamOne; + +from proxymityStream[not(AlertsTable.id == proxymityStream.id in AlertsTable)] +select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith,false as inAlertTable +insert into innerStreamOne; + +from proxymityStream[AlertsTable.id == proxymityStream.proximityWith in AlertsTable] +select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith,true as inAlertTable +insert into innerStreamSeven; + +from proxymityStream[not(AlertsTable.id == proxymityStream.proximityWith in AlertsTable)] +select id, latitude, longitude, timeStamp, type, speed, heading, eventId,inCloseProximity,proximityWith,false as inAlertTable +insert into innerStreamSeven; + +from innerStreamOne[inCloseProximity == true AND not(inAlertTable)] +select id,str:concat(",",proximityWith) as proximityWith , eventId +insert into AlertsTable; + +from innerStreamSeven[inCloseProximity == true AND not(inAlertTable)] +select proximityWith as id,str:concat(",",id) as proximityWith , eventId +insert into AlertsTable; + +from innerStreamOne[innerStreamOne.inCloseProximity == true AND inAlertTable]#window.length(0) join AlertsTable +on innerStreamOne.id == AlertsTable.id +select innerStreamOne.id as id, str:concat(",", innerStreamOne.proximityWith, AlertsTable.proximityWith) as proximityWith, innerStreamOne.eventId as eventId +insert into updateStream; + +from innerStreamSeven[innerStreamSeven.inCloseProximity == true AND inAlertTable]#window.length(0) join AlertsTable +on innerStreamSeven.proximityWith == AlertsTable.id +select innerStreamSeven.proximityWith as id, str:concat(",", innerStreamSeven.id, AlertsTable.proximityWith) as proximityWith, innerStreamSeven.eventId as eventId +insert into updateStream; + +from innerStreamOne[innerStreamOne.inCloseProximity == false AND inAlertTable]#window.length(0) join AlertsTable +on innerStreamOne.id == AlertsTable.id +select innerStreamOne.id as id, str:replaceAll(AlertsTable.proximityWith, str:concat(",", innerStreamOne.proximityWith), "") as proximityWith, innerStreamOne.eventId as eventId +insert into updateStream; + +from innerStreamSeven[innerStreamSeven.inCloseProximity == false AND inAlertTable]#window.length(0) join AlertsTable +on innerStreamSeven.proximityWith == AlertsTable.id +select innerStreamSeven.proximityWith as id, str:replaceAll(AlertsTable.proximityWith, str:concat(",", innerStreamSeven.id), "") as proximityWith, innerStreamSeven.eventId as eventId +insert into updateStream; + +from updateStream +select * +update AlertsTable + on id== AlertsTable.id; + +from updateStream[proximityWith == ""] +delete AlertsTable + on id== AlertsTable.id; + +from objectInitialStream[AlertsTable.id == objectInitialStream.id in AlertsTable] +select id, latitude, longitude, timeStamp, type, speed, heading, eventId, true as inAlertTable +insert into publishStream; + +from objectInitialStream[not(AlertsTable.id == objectInitialStream.id in AlertsTable)] +select id, latitude, longitude, timeStamp, type, speed, heading, eventId, false as inAlertTable +insert into publishStream; + +from publishStream[inAlertTable == true]#window.length(0) join AlertsTable +on publishStream.id== AlertsTable.id +select publishStream.id as id, publishStream.latitude as latitude, publishStream.longitude as longitude, publishStream.timeStamp as timeStamp, publishStream.type as type, publishStream.speed as speed, publishStream.heading as heading, publishStream.eventId as eventId, AlertsTable.proximityWith as proximityInfo +insert into innerStreamTwo; + +from publishStream[inAlertTable == false] +delete ProximityTable on ProximityTable.id==id; + +from publishStream[inAlertTable == false] +select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "" as proximityInfo ,"false" as isProximity +insert into dataOutStream; + +from innerStreamTwo[ProximityTable.id == innerStreamTwo.id in ProximityTable] +insert into innerStreamThree; + +from innerStreamThree#window.length(0) join ProximityTable +on innerStreamThree.id == ProximityTable.id +select innerStreamThree.id , innerStreamThree.latitude, innerStreamThree.longitude,innerStreamThree.timeStamp, innerStreamThree.type, innerStreamThree.speed, innerStreamThree.heading ,innerStreamThree.eventId, ProximityTable.timeStamp as storedTime, innerStreamThree.proximityInfo as proximityInfo +insert into innerStreamFour; + +from innerStreamFour[(timeStamp - storedTime) >= $proximityTime] +select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,proximityInfo,"true" as isProximity +insert into dataOutStream; + +from innerStreamFour[(timeStamp - storedTime) < $proximityTime] +select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , proximityInfo ,"false" as isProximity +insert into dataOutStream; + +from innerStreamTwo[not(ProximityTable.id == innerStreamTwo.id in ProximityTable)] +select innerStreamTwo.id, innerStreamTwo.timeStamp +insert into ProximityTable; + +from innerStreamTwo[not(ProximityTable.id == innerStreamTwo.id in ProximityTable)] +select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "" as proximityInfo ,"false" as isProximity +insert into dataOutStream; + +from dataOutStream[isProximity == 'true'] +select id, latitude, longitude, timeStamp, type, speed, heading, eventId,"WARNING" as state,str:concat("Proximity with "," ",proximityInfo) as information +insert into dataOut; + +from dataOutStream[isProximity == 'false'] +select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,"NORMAL" as state,"" as information +insert into dataOut; \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/conf/alerts/Geo-ExecutionPlan-Speed_alert.siddhiql b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/conf/alerts/Geo-ExecutionPlan-Speed_alert.siddhiql new file mode 100644 index 00000000000..65dad468d5e --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/conf/alerts/Geo-ExecutionPlan-Speed_alert.siddhiql @@ -0,0 +1,20 @@ +/* Enter a unique ExecutionPlan */ +@Plan:name('Geo-ExecutionPlan-Speed---$deviceId_alert') + +/* Enter a unique description for ExecutionPlan */ +-- @Plan:description('ExecutionPlan') + +/* define streams/tables and write queries here ... */ + +@Import('org.wso2.geo.StandardSpatialEvents:1.0.0') +define stream dataIn (id string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, eventId string); + +@Export('org.wso2.geo.ProcessedSpatialEvents:1.0.0') +define stream dataOut (id string, latitude double, longitude double, timeStamp long, type string, speed float, heading float, eventId string, state string, information string); + +from dataIn[speed >= $speedAlertValue and id == "$deviceId"]#geodashboard:subscribe() +select id , latitude, longitude,timeStamp, type ,speed, heading ,eventId , "ALERTED" as state, "This device movement is not normal!!" as information +insert into dataOut; +from dataIn[speed < $speedAlertValue and id == "$deviceId"] +select id , latitude, longitude,timeStamp, type ,speed, heading ,eventId , "NORMAL" as state, "This device movement is normal" as information +insert into dataOut; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/conf/alerts/Geo-ExecutionPlan-Stationery_alert.siddhiql b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/conf/alerts/Geo-ExecutionPlan-Stationery_alert.siddhiql new file mode 100644 index 00000000000..46bfbfe2e35 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/conf/alerts/Geo-ExecutionPlan-Stationery_alert.siddhiql @@ -0,0 +1,89 @@ +/* Enter a unique ExecutionPlan */ +@Plan:name('$executionPlanName') + +/* Enter a unique description for ExecutionPlan */ +-- @Plan:description('ExecutionPlan') + +/* define streams/tables and write queries here ... */ + +@Import('org.wso2.geo.StandardSpatialEvents:1.0.0') +define stream dataIn (id string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string); + + +@Export('org.wso2.geo.ProcessedSpatialEvents:1.0.0') +define stream dataOut (id string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string, state string, information string); + +@IndexBy('id') +define table StationeryTable(id string, timeStamp long); + +@IndexBy('id') +define table AlertsTable(id string, stationary bool); + +from dataIn#geodashboard:subscribe() +select id, latitude, longitude, timeStamp, type, speed, heading, eventId,geo:within(longitude,latitude,"$geoFenceGeoJSON") as isWithin +insert into innerStreamOne; + +from innerStreamOne[isWithin == false] +delete StationeryTable on StationeryTable.id==id; + +from innerStreamOne[isWithin == false] +select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "false" as isStationary +insert into dataOutStream; + +from innerStreamOne[isWithin == true]#geo:stationary(id,longitude,latitude, $fluctuationRadius) +select id, latitude, longitude, timeStamp, type, speed, heading, eventId,stationary +insert into innerStreamTwo; + +from innerStreamTwo[innerStreamTwo.stationary == true] +select innerStreamTwo.id, innerStreamTwo.stationary +insert into AlertsTable; + +from innerStreamTwo[innerStreamTwo.stationary == false] +delete AlertsTable on AlertsTable.id==id; + +from innerStreamTwo[innerStreamTwo.stationary == false] +delete StationeryTable on StationeryTable.id==id; + +from innerStreamOne[isWithin == true AND not(AlertsTable.id == innerStreamOne.id in AlertsTable)] +select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "false" as isStationary +insert into dataOutStream; + +from innerStreamOne[isWithin == true AND AlertsTable.id == innerStreamOne.id in AlertsTable] +insert into innerStreamThree; + +from innerStreamThree#window.length(0) join AlertsTable +on innerStreamThree.id == AlertsTable.id +select innerStreamThree.id , innerStreamThree.latitude, innerStreamThree.longitude,innerStreamThree.timeStamp, innerStreamThree.type, innerStreamThree.speed, innerStreamThree.heading ,innerStreamThree.eventId +insert into innerStreamFour; + +from innerStreamFour[not(StationeryTable.id == innerStreamFour.id in StationeryTable)] +select innerStreamFour.id, innerStreamFour.timeStamp +insert into StationeryTable; + +from innerStreamOne[isWithin == true AND not(StationeryTable.id == innerStreamOne.id in StationeryTable)] +select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "false" as isStationary +insert into dataOutStream; + +from innerStreamOne[isWithin == true AND StationeryTable.id == innerStreamOne.id in StationeryTable] +insert into innerStreamFive; + +from innerStreamFive#window.length(0) join StationeryTable +on innerStreamFive.id == StationeryTable.id +select innerStreamFive.id , innerStreamFive.latitude, innerStreamFive.longitude,innerStreamFive.timeStamp, innerStreamFive.type, innerStreamFive.speed, innerStreamFive.heading ,innerStreamFive.eventId, StationeryTable.timeStamp as storedTime +insert into innerStreamSix; + +from innerStreamSix[(timeStamp - storedTime) >= $stationeryTime] +select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,"true" as isStationary +insert into dataOutStream; + +from innerStreamSix[(timeStamp - storedTime) < $stationeryTime] +select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,"false" as isStationary +insert into dataOutStream; + +from dataOutStream[isStationary == 'true'] +select id ,latitude, longitude,timeStamp, type, speed, heading ,eventId ,"ALERTED" as state, "This device is in $stationeryName area!!!" as information +insert into dataOut; + +from dataOutStream[isStationary == 'false'] +select id , latitude, longitude,timeStamp, type, speed, heading ,eventId ,"NORMAL" as state,"" as information +insert into dataOut; \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/conf/alerts/Geo-ExecutionPlan-Traffic_alert.siddhiql b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/conf/alerts/Geo-ExecutionPlan-Traffic_alert.siddhiql new file mode 100644 index 00000000000..5e6bb5b1a8e --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/conf/alerts/Geo-ExecutionPlan-Traffic_alert.siddhiql @@ -0,0 +1,17 @@ +/* Enter a unique ExecutionPlan */ +@Plan:name('$executionPlanName') + +/* Enter a unique description for ExecutionPlan */ +-- @Plan:description('ExecutionPlan') + +/* define streams/tables and write queries here ... */ + +@Import('rawGeoStream:1.0.0') +define stream dataIn (id string, timeStamp long, geometry string, state string, information string); + +@Export('AlertsNotifications:1.0.0') +define stream dataOut (id string, state string, information string, timeStamp long, latitude double, longitude double); + +from dataIn[geo:intersects(geometry, "$geoFenceGeoJSON")==true and geodashboard:needToNotify(id, str:concat(information, state), "sendFirst") == true and id == $deviceId] +select id, state, str:concat("Traffic alert in $areaName. State: ", state, " ", information) as information, timeStamp, 0.0 as latitude, 0.0 as longitude +insert into dataOut \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/conf/alerts/Geo-ExecutionPlan-Within_alert.siddhiql b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/conf/alerts/Geo-ExecutionPlan-Within_alert.siddhiql new file mode 100644 index 00000000000..b58fd59e334 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/conf/alerts/Geo-ExecutionPlan-Within_alert.siddhiql @@ -0,0 +1,20 @@ +/* Enter a unique ExecutionPlan */ +@Plan:name('$executionPlanName') + +/* Enter a unique description for ExecutionPlan */ +-- @Plan:description('ExecutionPlan') + +/* define streams/tables and write queries here ... */ + +@Import('org.wso2.geo.StandardSpatialEvents:1.0.0') +define stream dataIn (id string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string); + +@Export('org.wso2.geo.ProcessedSpatialEvents:1.0.0') +define stream dataOut (id string, latitude double, longitude double, timeStamp long, type string ,speed float, heading float, eventId string, state string, information string); + +from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")==true and id == "$deviceId"]#geodashboard:subscribe() +select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "ALERTED" as state, "This device is in $areaName restricted area!!!" as information +insert into dataOut; +from dataIn[geo:within(longitude,latitude,"$geoFenceGeoJSON")!=true and id == "$deviceId"] +select id , latitude, longitude,timeStamp, type, speed, heading ,eventId , "NORMAL" as state, "" as information +insert into dataOut; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/css/app.css b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/css/app.css index 086e80f550d..2cfec651d35 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/css/app.css +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/css/app.css @@ -128,6 +128,25 @@ input[type="radio"], input[type="checkbox"] { padding: 5px 10px; } +.tab-actions .action-btn.filter.geo-alert { + padding: 10px 15px; + background-color: #ebebeb; + float: left; + cursor: pointer; + position: relative; + margin-left: 10px; + margin-bottom: 10px; +} + +.tab-actions .action-btn.filter.geo-tools { + padding: 10px 15px; + background-color: #ebebeb; + float: right; + cursor: pointer; + position: relative; + margin-left: 10px; + margin-bottom: 10px; +} /* diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/app.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/app.js index 5ef3beeadb2..de2b1ec9a47 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/app.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/app.js @@ -33,16 +33,22 @@ var map; var geoClusters; var markersLayer = new L.LayerGroup(); var popupContent; +var clusterLat; +var clusterLong; +var lastSeen; +var geoFencingEnabled; var zoomLevel = 15; var tileSet = "https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"; var attribution = "© OpenStreetMap contributors"; -function initialLoad() { +function initialLoad(geoFencingEnabled) { + window.geoFencingEnabled = geoFencingEnabled; if (document.getElementById('map') == null) { setTimeout(initialLoad, 500); // give everything some time to render } else { initializeMap(); + processAfterInitializationMap(); $("#loading").hide(); } } @@ -65,6 +71,7 @@ function initializeMap() { maxNativeZoom: 18 }); L.tileLayer(tileSet, {attribution: attribution}).addTo(map); + markersLayer.clearLayers(); markersLayer.addTo(map); showMarkersOnChange(); @@ -86,6 +93,39 @@ function initializeMap() { $("a[href='#left_side_pannel']").trigger('click'); } +function processAfterInitializationMap() { + attributionControl = L.control({ + position: "bottomright" + }); + attributionControl.onAdd = function (map) { + var div = L.DomUtil.create("div", "leaflet-control-attribution"); + div.innerHTML = "Attribution"; + return div; + }; + map.addControl(L.control.fullscreen({position: 'bottomright'})); + + geoAlertsBar = L.control.geoAlerts({position: 'topright'}); + if (geoFencingEnabled) { + map.addControl(geoAlertsBar); + } + + groupedOverlays = { + "Web Map Service layers": {} + }; + + layerControl = L.control.groupedLayers(baseLayers, groupedOverlays, { + collapsed: true, + position: 'bottomleft' + }).addTo(map); + + if (geoFencingEnabled) { + var alertsFromDate = new Date(); + var toDate = new Date(); + alertsFromDate.setHours(alertsFromDate.getHours() - 24); //last 24 hours + getAlertsHistory(alertsFromDate.valueOf(), toDate.valueOf()); + }; +} + var showMarkesOnZoomEnd = function (zoomLevel) { if(map.getZoom()===zoomLevel){ @@ -99,7 +139,7 @@ var showMarkersOnChange=function(){ var minLat = bounds._southWest.lat; var minLong = bounds._southWest.lng; var zoom = map.getZoom(); - var backEndUrl = '/api/device-mgt/v1.0/geo-services/1.0.0/stats/deviceLocations'+ + var backEndUrl = '/api/device-mgt/v1.0/geo-services/1.0.0/stats/device-locations'+ '?'+'&minLat='+minLat+'&maxLat='+maxLat+'&minLong='+minLong+ '&maxLong='+maxLong+'&zoom='+zoom; markersLayer.clearLayers(); @@ -127,14 +167,17 @@ function geoGridControl(){ geoClusterMarker(count,cluster.coordinates.latitude,cluster.coordinates.longitude, cluster.southWestBound.latitude, cluster.northEastBound.latitude,cluster.southWestBound.longitude,cluster.northEastBound.longitude, - cluster.deviceIdentification,cluster.deviceType); + cluster.deviceIdentification,cluster.deviceType, cluster.lastSeen); } } } function geoClusterMarker(count, clusterLat, clusterLong, minLat, maxLat, minLong, maxLong,deviceIdentification, - deviceType) { + deviceType, lastSeen) { + window.clusterLat = clusterLat; + window.clusterLong = clusterLong; + window.lastSeen = lastSeen; var deviceMarker = L.AwesomeMarkers.icon({ icon: ' ', markerColor: 'blue' @@ -180,17 +223,32 @@ function handleMarkerEvents(event,extra_data,marker) { } -var devicePopupManagement= function(deviceName, deviceType, deviceIdentifier,deviceStatus,deviceOwner){ +var devicePopupManagement= function(deviceName, deviceType, deviceIdentifier,deviceStatus,deviceOwner) { + if (!geoFencingEnabled) { + var deviceMgtUrl = "/devicemgt/device/"; + var html1 = '
'; + var html2 = '

' + '' + deviceName + '' + '

'; + var html3 = '

' + 'Type : ' + deviceType + '

'; + var html4 = '

' + 'Status : ' + deviceStatus + '

'; + var html5 = '

' + 'Owner : ' + deviceOwner + '

'; + var html6 = '
'; + var html = html1 + html2 + html3 + html4 + html5 + html6; + return html; + } + + var popupTemplate = $('#markerPopup'); + var fromDate = new Date(); + fromDate.setHours(fromDate.getHours() - 2); + var toDate = new Date(); + var tableData = getAnalyticsData(deviceIdentifier,deviceType,fromDate.valueOf(),toDate.valueOf()); + var data = tableData[tableData.length-1]; - var deviceMgtUrl= "/devicemgt/device/"; - var html1='
'; - var html2 = '

'+'' + deviceName + ''+'

' ; - var html3 = '

'+'Type : '+ deviceType+'

'; - var html4 = '

'+'Status : '+deviceStatus+'

'; - var html5 = '

'+ 'Owner : ' + deviceOwner + '

'; - var html6='
'; - var html=html1+html2+html3+html4+html5+html6; - return html; + popupTemplate.find('#objectId').html(deviceIdentifier); + popupTemplate.find('#information').html(data.values.information); + popupTemplate.find('#speed').html(Math.round(data.values.speed * 10) / 10); + popupTemplate.find('#heading').html(angleToHeading(data.values.heading)); + + return popupTemplate.html(); }; var devicePopupContentBackEndCall = function(type,deviceIdentification,marker,callback){ @@ -212,3 +270,196 @@ var successCallBackDeviceDetails=function(device){ popupContent = devicePopupManagement(deviceName,deviceType,deviceIdentifier,deviceStatus,deviceOwner); } + +function getAnalyticsData(deviceId, deviceType, timeFrom, timeTo) { + var tableData = []; + var serviceUrl = '/api/device-mgt/v1.0/geo-services/stats/' + deviceType + '/' + deviceId + '?from=' + timeFrom + '&to=' + timeTo; + invokerUtil.get(serviceUrl, + function (data) { + if(data === "") { + showCurrentLocation(deviceId, deviceType, tableData); + } + tableData = JSON.parse(data); + if (tableData.length === 0) { + showCurrentLocation(deviceId, deviceType, tableData); + } + }, function (message) { + showCurrentLocation(deviceId, deviceType, tableData); + }); + return tableData; +} + +function showRecentAlertsHistory() { + if (geoFencingEnabled) { + var alertsFromDate = new Date(); + var toDate = new Date(); + alertsFromDate.setHours(alertsFromDate.getHours() - 2); //last 24 hours + getAlertsHistory(alertsFromDate.valueOf(), toDate.valueOf()); + } + + if (speedGraphControl) { + setTimeout(function () { + createChart(); + chart.load({columns: [0]}); //TODO: Somehow get device speed history here + }, 100); + } + + noty({text: "Showing last two hours geo history", type: "information"}); +} + +function showAlertsHistory(timeFrom, timeTo) { + if (!timeFrom) { + notifyError('No start time provided to show history. Please provide a suitable value' + timeFrom); + } else if (!timeTo) { + notifyError('No end time provided to show history. Please provide a suitable value' + timeTo); + } else { + $('#dateRangePopup').dialog('close'); + disableRealTime(); + isBatchModeOn = true; + getAlertsHistory(new Date($('#timeFromCal').val()).getTime(), new Date($('#timeToCal').val()).getTime()); + + if (speedGraphControl) { + setTimeout(function () { + createChart(); + chart.load({columns: [0]}); //TODO: Somehow get device speed history here + }, 100); + } + } +} + +function createGeoToolListItem(link, text, icon, menuRoot, alert) { + var listItem = $("
", { class: 'action-btn filter'}).appendTo(menuRoot); + var anchor = $("", {href: link, text: ' ' + text}).appendTo(listItem); + if (alert == 'Exit') { + anchor.attr('data-toggle', 'modal'); + anchor.attr('data-target', '#modalExit'); + } else if (alert == 'Within') { + anchor.attr('data-toggle', 'modal'); + anchor.attr('data-target', '#modalWithin'); + } else if (alert == 'Stationery') { + anchor.attr('data-toggle', 'modal'); + anchor.attr('data-target', '#modalStationery'); + } else if (alert == 'Speed') { + anchor.attr('data-toggle', 'modal'); + anchor.attr('data-target', '#modalSpeed'); + } + $("", {class: icon}).prependTo(anchor); + return listItem; +} + +var chart; +function createChart() { + chart = c3.generate({ + bindto: '#chart_div', + data: { + columns: [ + ['speed'] + ] + }, + subchart: { + show: true + }, + axis: { + y: { + label: { + text: 'Speed', + position: 'outer-middle' + } + } + }, + legend: { + show: false + } + }); +} + +function notifyError(message) { + noty({text: message, type: "error"}); +} + +function enableRealTime(geoFencingEnabled) { + $("#realTimeShow").hide(); + $(".geo-alert").show(); + isBatchModeOn = false; + initializeGeoLocation(geoFencingEnabled); +} + +function disableRealTime(){ + $(".geo-alert").hide(); + $("#realTimeShow").show(); +} + +function showCurrentLocation(deviceId, deviceType, tableData){ + var location = {}; + location.latitude = clusterLat; + location.longitude = clusterLong; + location.updatedTime = lastSeen; + location.id = deviceId; + location.values = {}; + location.values.id = deviceId; + location.values.information = "Last seen " + timeSince(new Date(location.updatedTime)); + location.values.notify = false; + location.values.speed = 0; + location.values.heading = 0; + location.values.state = "NORMAL"; + location.values.longitude = location.longitude; + location.values.latitude = location.latitude; + location.timestamp = location.updatedTime; + location.values.timeStamp = location.updatedTime; + location.values.type = deviceType; + location._version = "1.0.0"; + tableData.push(location); +} + +function formatDate(date) { + var hours = date.getHours(); + var minutes = date.getMinutes(); + var ampm = hours >= 12 ? 'pm' : 'am'; + hours = hours % 12; + hours = hours ? hours : 12; // the hour '0' should be '12' + minutes = minutes < 10 ? '0' + minutes : minutes; + var strTime = hours + ':' + minutes + ' ' + ampm; + return date.getDate() + "/" + date.getMonth() + 1 + "/" + date.getFullYear() + " " + strTime; +} + +function timeSince(date) { + if (!date) { + return "time is unknown"; + } + + var seconds = Math.floor((new Date() - date) / 1000); + var intervalType; + + var interval = Math.floor(seconds / 31536000); + if (interval >= 1) { + intervalType = 'year'; + } else { + interval = Math.floor(seconds / 2592000); + if (interval >= 1) { + intervalType = 'month'; + } else { + interval = Math.floor(seconds / 86400); + if (interval >= 1) { + intervalType = 'day'; + } else { + interval = Math.floor(seconds / 3600); + if (interval >= 1) { + intervalType = "hour"; + } else { + interval = Math.floor(seconds / 60); + if (interval >= 1) { + intervalType = "minute"; + } else { + interval = seconds; + intervalType = "second"; + } + } + } + } + } + + if (interval > 1 || interval === 0) { + intervalType += 's'; + } + return interval + ' ' + intervalType + ' ago'; +} \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/application_options.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/application_options.js new file mode 100644 index 00000000000..2ca6536b452 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/application_options.js @@ -0,0 +1,77 @@ +/* + * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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 + * + * http://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. + */ +var ApplicationOptions = { + colors: { + states: { + NORMAL: 'blue', + WARNING: 'blue', + OFFLINE: 'grey', + ALERTED: 'red', + UNKNOWN: 'black' + }, + application: { + header: 'grey' + } + }, + constance:{ + CEP_WEB_SOCKET_OUTPUT_ADAPTOR_NAME: 'iot.per.device.stream.geo.FusedSpatialEvent', + CEP_ON_ALERT_WEB_SOCKET_OUTPUT_ADAPTOR_NAME: 'org.wso2.geo.AlertsNotifications', + CEP_Traffic_STREAM_WEB_SOCKET_OUTPUT_ADAPTOR_NAME: 'DefaultWebsocketOutputAdaptorOnTrafficStream', + CEP_WEB_SOCKET_OUTPUT_ADAPTOR_WEBAPP_NAME: 'secured-websocket', + TENANT_INDEX: 't', + COLON : ':', + PATH_SEPARATOR : '/', + VERSION: '1.0.0', + SPEED_HISTORY_COUNT: 20, + NOTIFY_INFO_TIMEOUT: 1000, + NOTIFY_SUCCESS_TIMEOUT: 1000, + NOTIFY_WARNING_TIMEOUT: 3000, + NOTIFY_DANGER_TIMEOUT: 5000 + }, + messages:{ + app:{ + + } + }, + leaflet: { + iconUrls: { + //TODO path needs to be changed + normalMovingIcon: '/img/markers/object-types/default/moving/alerted.png', + alertedMovingIcon: '/img/markers/moving/arrow_alerted.png', + offlineMovingIcon: '/img/markers/moving/arrow_offline.png', + warningMovingIcon: '/img/markers/moving/arrow_warning.png', + defaultMovingIcon: '/img/markers/moving/arrow_normal.png', + + normalNonMovingIcon: '/img/markers/non_moving/dot_normal.png', + alertedNonMovingIcon: '/img/markers/non_moving/dot_alerted.png', + offlineNonMovingIcon: '/img/markers/non_moving/dot_offline.png', + warningNonMovingIcon: '/img/markers/non_moving/dot_warning.png', + defaultNonMovingIcon: '/img/markers/non_moving/dot_normal.png', + + normalPlaceIcon: '/img/markers/places/marker-icon.png', + alertedPlaceIcon: '/img/markers/places/redMarker.png', + offlinePlaceIcon: '/img/markers/places/ashMarker.png', + warningPlaceIcon: '/img/markers/places/pinkMarker.png', + defaultPlaceIcon: '/img/markers/places/marker-icon.png', + + defaultIcon: '/img/markers/moving/default_icons/marker-icon.png', + resizeIcon: '/img/markers/resize.png', + stopIcon: '/img/markers/stopIcon.png' + } + } +}; diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/d3/C3_LICENSE b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/d3/C3_LICENSE new file mode 100644 index 00000000000..29ce9cb0ad5 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/d3/C3_LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 Masayuki Tanaka + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/d3/D3_LICENSE b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/d3/D3_LICENSE new file mode 100644 index 00000000000..83013469b98 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/d3/D3_LICENSE @@ -0,0 +1,26 @@ +Copyright (c) 2010-2014, Michael Bostock +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +* Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +* Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +* The name Michael Bostock may not be used to endorse or promote products + derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL MICHAEL BOSTOCK BE LIABLE FOR ANY DIRECT, +INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, +BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING +NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, +EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/d3/c3.min.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/d3/c3.min.js new file mode 100644 index 00000000000..cdbf2d5a555 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/d3/c3.min.js @@ -0,0 +1,4 @@ +!function(a){"use strict";function b(a){var b=this.internal=new c(this);b.loadConfig(a),b.init(),function d(a,b,c){for(var e in a)b[e]=a[e].bind(c),Object.keys(a[e]).length>0&&d(a[e],b[e],c)}(e,this,this)}function c(b){var c=this;c.d3=a.d3?a.d3:"undefined"!=typeof require?require("d3"):void 0,c.api=b,c.config=c.getDefaultConfig(),c.data={},c.cache={},c.axes={}}function d(a,b){function c(a,b){a.attr("transform",function(a){return"translate("+Math.ceil(b(a)+s)+", 0)"})}function d(a,b){a.attr("transform",function(a){return"translate(0,"+Math.ceil(b(a))+")"})}function e(a){var b=a[0],c=a[a.length-1];return c>b?[b,c]:[c,b]}function f(a){var b,c,d=[];if(a.ticks)return a.ticks.apply(a,k);for(c=a.domain(),b=Math.ceil(c[0]);b0&&d[0]>0&&d.unshift(d[0]-(d[1]-d[0])),d}function g(){var a,c=m.copy();return b&&(a=m.domain(),c.domain([a[0],a[1]-1])),c}function h(a){return j?j(a):a}function i(i){i.each(function(){function i(a){var b=m(a)+s;return B[0]=0&&C.select(this).style("display",b%z?"none":"block")})}else A.svg.selectAll("."+h.axisX+" .tick text").style("display","block");!D.axis_rotated&&D.axis_x_tick_rotate&&A.rotateTickText(A.axes.x,b.axisX,D.axis_x_tick_rotate),m=A.generateDrawArea?A.generateDrawArea(E,!1):void 0,n=A.generateDrawBar?A.generateDrawBar(F):void 0,o=A.generateDrawLine?A.generateDrawLine(G,!1):void 0,p=A.generateXYForText(F,!0),q=A.generateXYForText(F,!1),A.subY.domain(A.y.domain()),A.subY2.domain(A.y2.domain()),A.tooltip.style("display","none"),A.updateXgridFocus(),B.select("text."+h.text+"."+h.empty).attr("x",A.width/2).attr("y",A.height/2).text(D.data_empty_label_text).transition().style("opacity",I.length?0:1),A.redrawGrid(r,c),A.redrawRegion(r),A.redrawBar(t),A.redrawLine(t),A.redrawArea(t),D.point_show&&A.redrawCircle(),A.hasDataLabel()&&A.redrawText(t),A.redrawArc&&A.redrawArc(r,t,i),A.redrawSubchart&&A.redrawSubchart(d,b,r,t,E,F,G),B.selectAll("."+h.selectedCircles).filter(A.isBarType.bind(A)).selectAll("circle").remove(),D.interaction_enabled&&A.redrawEventRect(),C.transition().duration(r).each(function(){var b=[];A.addTransitionForBar(b,n),A.addTransitionForLine(b,o),A.addTransitionForArea(b,m),D.point_show&&A.addTransitionForCircle(b,K,L),A.addTransitionForText(b,p,q,a.flow),A.addTransitionForRegion(b),A.addTransitionForGrid(b),a.flow&&(v=A.generateWait(),b.forEach(function(a){v.add(a)}),w=A.generateFlow({targets:I,flow:a.flow,duration:r,drawBar:n,drawLine:o,drawArea:m,cx:K,cy:L,xv:J,xForText:p,yForText:q}))}).call(v||function(){},w||function(){}),A.mapToIds(A.data.targets).forEach(function(a){A.withoutFadeIn[a]=!0}),A.updateZoom&&A.updateZoom()},f.updateAndRedraw=function(a){var b,c=this,d=c.config;a=a||{},a.withTransition=s(a,"withTransition",!0),a.withTransform=s(a,"withTransform",!1),a.withLegend=s(a,"withLegend",!1),a.withUpdateXDomain=!0,a.withUpdateOrgXDomain=!0,a.withTransitionForExit=!1,a.withTransitionForTransform=s(a,"withTransitionForTransform",a.withTransition),c.updateSizes(),a.withLegend&&d.legend_show||(b=c.generateAxisTransitions(a.withTransitionForAxis?d.transition_duration:0),c.updateScales(),c.updateSvgSize(),c.transformAll(a.withTransitionForTransform,b)),c.redraw(a,b)},f.isTimeSeries=function(){return"timeseries"===this.config.axis_x_type},f.isCategorized=function(){return this.config.axis_x_type.indexOf("categor")>=0},f.isCustomX=function(){var a=this,b=a.config;return!a.isTimeSeries()&&(b.data_x||r(b.data_xs))},f.getTranslate=function(a){var b,c,d=this,e=d.config;return"main"===a?(b=o(d.margin.left),c=o(d.margin.top)):"context"===a?(b=o(d.margin2.left),c=o(d.margin2.top)):"legend"===a?(b=d.margin3.left,c=d.margin3.top):"x"===a?(b=0,c=e.axis_rotated?0:d.height):"y"===a?(b=0,c=e.axis_rotated?d.height:0):"y2"===a?(b=e.axis_rotated?0:d.width,c=e.axis_rotated?1:0):"subx"===a?(b=0,c=e.axis_rotated?0:d.height2):"arc"===a&&(b=d.arcWidth/2,c=d.arcHeight/2),"translate("+b+","+c+")"},f.initialOpacity=function(a){return null!==a.value&&this.withoutFadeIn[a.id]?1:0},f.opacityForCircle=function(a){var b=this;return i(a.value)?b.isScatterType(a)?.5:1:0},f.opacityForText=function(){return this.hasDataLabel()?1:0},f.xx=function(a){return a?this.x(a.x):null},f.xv=function(a){var b=this;return Math.ceil(b.x(b.isTimeSeries()?b.parseDate(a.value):a.value))},f.yv=function(a){var b=this,c=a.axis&&"y2"===a.axis?b.y2:b.y;return Math.ceil(c(a.value))},f.subxx=function(a){return a?this.subX(a.x):null},f.transformMain=function(a,b){var c,d,e,f=this;b&&b.axisX?c=b.axisX:(c=f.main.select("."+h.axisX),a&&(c=c.transition())),b&&b.axisY?d=b.axisY:(d=f.main.select("."+h.axisY),a&&(d=d.transition())),b&&b.axisY2?e=b.axisY2:(e=f.main.select("."+h.axisY2),a&&(e=e.transition())),(a?f.main.transition():f.main).attr("transform",f.getTranslate("main")),c.attr("transform",f.getTranslate("x")),d.attr("transform",f.getTranslate("y")),e.attr("transform",f.getTranslate("y2")),f.main.select("."+h.chartArcs).attr("transform",f.getTranslate("arc"))},f.transformAll=function(a,b){var c=this;c.transformMain(a,b),c.config.subchart_show&&c.transformContext(a,b),c.legend&&c.transformLegend(a)},f.updateSvgSize=function(){var a=this;a.svg.attr("width",a.currentWidth).attr("height",a.currentHeight),a.svg.select("#"+a.clipId).select("rect").attr("width",a.width).attr("height",a.height),a.svg.select("#"+a.clipIdForXAxis).select("rect").attr("x",a.getXAxisClipX.bind(a)).attr("y",a.getXAxisClipY.bind(a)).attr("width",a.getXAxisClipWidth.bind(a)).attr("height",a.getXAxisClipHeight.bind(a)),a.svg.select("#"+a.clipIdForYAxis).select("rect").attr("x",a.getYAxisClipX.bind(a)).attr("y",a.getYAxisClipY.bind(a)).attr("width",a.getYAxisClipWidth.bind(a)).attr("height",a.getYAxisClipHeight.bind(a)),a.svg.select("."+h.zoomRect).attr("width",a.width).attr("height",a.height),a.selectChart.style("max-height",a.currentHeight+"px")},f.updateDimension=function(){var a=this;a.config.axis_rotated?(a.axes.x.call(a.xAxis),a.axes.subx.call(a.subXAxis)):(a.axes.y.call(a.yAxis),a.axes.y2.call(a.y2Axis)),a.updateSizes(),a.updateScales(),a.updateSvgSize(),a.transformAll(!1)},f.observeInserted=function(b){var c=this,d=new MutationObserver(function(e){e.forEach(function(e){if("childList"===e.type&&e.previousSibling){d.disconnect();var f=a.setInterval(function(){b.node().parentNode&&(a.clearInterval(f),c.updateDimension(),c.redraw({withTransform:!0,withUpdateXDomain:!0,withUpdateOrgXDomain:!0,withTransition:!1,withTransitionForTransform:!1,withLegend:!0}),b.transition().style("opacity",1))},10)}})});d.observe(b.node(),{attributes:!0,childList:!0,characterData:!0})},f.generateResize=function(){function a(){b.forEach(function(a){a()})}var b=[];return a.add=function(a){b.push(a)},a},f.endall=function(a,b){var c=0;a.each(function(){++c}).each("end",function(){--c||b.apply(this,arguments)})},f.generateWait=function(){var a=[],b=function(b,c){var d=setInterval(function(){var b=0;a.forEach(function(a){if(a.empty())return void(b+=1);try{a.transition()}catch(c){b+=1}}),b===a.length&&(clearInterval(d),c&&c())},10)};return b.add=function(b){a.push(b)},b},f.parseDate=function(b){var c,d=this;return c=b instanceof Date?b:"number"==typeof b?new Date(b):d.dataTimeFormat(d.config.data_xFormat).parse(b),(!c||isNaN(+c))&&a.console.error("Failed to parse x '"+b+"' to Date object"),c},f.getDefaultConfig=function(){var a={bindto:"#chart",size_width:void 0,size_height:void 0,padding_left:void 0,padding_right:void 0,padding_top:void 0,padding_bottom:void 0,zoom_enabled:!1,zoom_extent:void 0,zoom_privileged:!1,zoom_onzoom:function(){},interaction_enabled:!0,onmouseover:function(){},onmouseout:function(){},onresize:function(){},onresized:function(){},transition_duration:350,data_x:void 0,data_xs:{},data_xFormat:"%Y-%m-%d",data_xLocaltime:!0,data_idConverter:function(a){return a},data_names:{},data_classes:{},data_groups:[],data_axes:{},data_type:void 0,data_types:{},data_labels:{},data_order:"desc",data_regions:{},data_color:void 0,data_colors:{},data_hide:!1,data_filter:void 0,data_selection_enabled:!1,data_selection_grouped:!1,data_selection_isselectable:function(){return!0},data_selection_multiple:!0,data_onclick:function(){},data_onmouseover:function(){},data_onmouseout:function(){},data_onselected:function(){},data_onunselected:function(){},data_ondragstart:function(){},data_ondragend:function(){},data_url:void 0,data_json:void 0,data_rows:void 0,data_columns:void 0,data_mimeType:void 0,data_keys:void 0,data_empty_label_text:"",subchart_show:!1,subchart_size_height:60,subchart_onbrush:function(){},color_pattern:[],color_threshold:{},legend_show:!0,legend_position:"bottom",legend_inset_anchor:"top-left",legend_inset_x:10,legend_inset_y:0,legend_inset_step:void 0,legend_item_onclick:void 0,legend_item_onmouseover:void 0,legend_item_onmouseout:void 0,legend_equally:!1,axis_rotated:!1,axis_x_show:!0,axis_x_type:"indexed",axis_x_localtime:!0,axis_x_categories:[],axis_x_tick_centered:!1,axis_x_tick_format:void 0,axis_x_tick_culling:{},axis_x_tick_culling_max:10,axis_x_tick_count:void 0,axis_x_tick_fit:!0,axis_x_tick_values:null,axis_x_tick_rotate:void 0,axis_x_tick_outer:!0,axis_x_max:null,axis_x_min:null,axis_x_padding:{},axis_x_height:void 0,axis_x_default:void 0,axis_x_label:{},axis_y_show:!0,axis_y_max:void 0,axis_y_min:void 0,axis_y_center:void 0,axis_y_label:{},axis_y_tick_format:void 0,axis_y_tick_outer:!0,axis_y_padding:void 0,axis_y_ticks:10,axis_y2_show:!1,axis_y2_max:void 0,axis_y2_min:void 0,axis_y2_center:void 0,axis_y2_label:{},axis_y2_tick_format:void 0,axis_y2_tick_outer:!0,axis_y2_padding:void 0,axis_y2_ticks:10,grid_x_show:!1,grid_x_type:"tick",grid_x_lines:[],grid_y_show:!1,grid_y_lines:[],grid_y_ticks:10,grid_focus_show:!0,point_show:!0,point_r:2.5,point_focus_expand_enabled:!0,point_focus_expand_r:void 0,point_select_r:void 0,line_connect_null:!1,bar_width:void 0,bar_width_ratio:.6,bar_width_max:void 0,bar_zerobased:!0,area_zerobased:!0,pie_label_show:!0,pie_label_format:void 0,pie_label_threshold:.05,pie_sort:!0,pie_expand:!0,gauge_label_show:!0,gauge_label_format:void 0,gauge_expand:!0,gauge_min:0,gauge_max:100,gauge_units:void 0,gauge_width:void 0,donut_label_show:!0,donut_label_format:void 0,donut_label_threshold:.05,donut_width:void 0,donut_sort:!0,donut_expand:!0,donut_title:"",regions:[],tooltip_show:!0,tooltip_grouped:!0,tooltip_format_title:void 0,tooltip_format_name:void 0,tooltip_format_value:void 0,tooltip_contents:function(a,b,c,d){return this.getTooltipContent?this.getTooltipContent(a,b,c,d):""},tooltip_init_show:!1,tooltip_init_x:0,tooltip_init_position:{top:"0px",left:"50px"}};return Object.keys(this.additionalConfig).forEach(function(b){a[b]=this.additionalConfig[b]},this),a},f.additionalConfig={},f.loadConfig=function(a){function b(){var a=d.shift();return a&&c&&"object"==typeof c&&a in c?(c=c[a],b()):a?void 0:c}var c,d,e,f=this.config;Object.keys(f).forEach(function(g){c=a,d=g.split("_"),e=b(),m(e)&&(f[g]=e)})},f.getScale=function(a,b,c){return(c?this.d3.time.scale():this.d3.scale.linear()).range([a,b])},f.getX=function(a,b,c,d){var e,f=this,g=f.getScale(a,b,f.isTimeSeries()),h=c?g.domain(c):g;f.isCategorized()?(d=d||function(){return 0},g=function(a,b){var c=h(a)+d(a);return b?c:Math.ceil(c)}):g=function(a,b){var c=h(a);return b?c:Math.ceil(c)};for(e in h)g[e]=h[e];return g.orgDomain=function(){return h.domain()},f.isCategorized()&&(g.domain=function(a){return arguments.length?(h.domain(a),g):(a=this.orgDomain(),[a[0],a[1]+1])}),g},f.getY=function(a,b,c){var d=this.getScale(a,b);return c&&d.domain(c),d},f.getYScale=function(a){return"y2"===this.getAxisId(a)?this.y2:this.y},f.getSubYScale=function(a){return"y2"===this.getAxisId(a)?this.subY2:this.subY},f.updateScales=function(){var a=this,b=a.config,c=!a.x;a.xMin=b.axis_rotated?1:0,a.xMax=b.axis_rotated?a.height:a.width,a.yMin=b.axis_rotated?0:a.height,a.yMax=b.axis_rotated?a.width:1,a.subXMin=a.xMin,a.subXMax=a.xMax,a.subYMin=b.axis_rotated?0:a.height2,a.subYMax=b.axis_rotated?a.width2:1,a.x=a.getX(a.xMin,a.xMax,c?void 0:a.x.orgDomain(),function(){return a.xAxis.tickOffset()}),a.y=a.getY(a.yMin,a.yMax,c?void 0:a.y.domain()),a.y2=a.getY(a.yMin,a.yMax,c?void 0:a.y2.domain()),a.subX=a.getX(a.xMin,a.xMax,a.orgXDomain,function(b){return b%1?0:a.subXAxis.tickOffset()}),a.subY=a.getY(a.subYMin,a.subYMax,c?void 0:a.subY.domain()),a.subY2=a.getY(a.subYMin,a.subYMax,c?void 0:a.subY2.domain()),a.xAxisTickFormat=a.getXAxisTickFormat(),a.xAxisTickValues=b.axis_x_tick_values?b.axis_x_tick_values:c?void 0:a.xAxis.tickValues(),a.xAxis=a.getXAxis(a.x,a.xOrient,a.xAxisTickFormat,a.xAxisTickValues),a.subXAxis=a.getXAxis(a.subX,a.subXOrient,a.xAxisTickFormat,a.xAxisTickValues),a.yAxis=a.getYAxis(a.y,a.yOrient,b.axis_y_tick_format,b.axis_y_ticks),a.y2Axis=a.getYAxis(a.y2,a.y2Orient,b.axis_y2_tick_format,b.axis_y2_ticks),c||(a.brush&&a.brush.scale(a.subX),b.zoom_enabled&&a.zoom.scale(a.x)),a.updateArc&&a.updateArc()},f.getYDomainMin=function(a){var b,c,d,e,f,g,h=this,i=h.config,j=h.mapToIds(a),k=h.getValuesAsIdKeyed(a);if(i.data_groups.length>0)for(g=h.hasNegativeValueInTargets(a),b=0;b=0}),0!==e.length)for(d=e[0],g&&k[d]&&k[d].forEach(function(a,b){k[d][b]=0>a?a:0}),c=1;c0||(k[d][b]+=+a)});return h.d3.min(Object.keys(k).map(function(a){return h.d3.min(k[a])}))},f.getYDomainMax=function(a){var b,c,d,e,f,g,h=this,i=h.config,j=h.mapToIds(a),k=h.getValuesAsIdKeyed(a);if(i.data_groups.length>0)for(g=h.hasPositiveValueInTargets(a),b=0;b=0}),0!==e.length)for(d=e[0],g&&k[d]&&k[d].forEach(function(a,b){k[d][b]=a>0?a:0}),c=1;c+a||(k[d][b]+=+a)});return h.d3.max(Object.keys(k).map(function(a){return h.d3.max(k[a])}))},f.getYDomain=function(a,b){var c,d,e,f,g,h,j,k,l,m,n=this,o=n.config,q=a.filter(function(a){return n.getAxisId(a.id)===b}),r="y2"===b?o.axis_y2_min:o.axis_y_min,s="y2"===b?o.axis_y2_max:o.axis_y_max,t=i(r)?r:n.getYDomainMin(q),u=i(s)?s:n.getYDomainMax(q),v="y2"===b?o.axis_y2_center:o.axis_y_center,w=n.hasType("bar",q)&&o.bar_zerobased||n.hasType("area",q)&&o.area_zerobased,x=n.hasDataLabel()&&o.axis_rotated,y=n.hasDataLabel()&&!o.axis_rotated;return 0===q.length?"y2"===b?n.y2.domain():n.y.domain():(t===u&&(0>t?u=0:t=0),l=t>=0&&u>=0,m=0>=t&&0>=u,w&&(l&&(t=0),m&&(u=0)),c=Math.abs(u-t),d=e=f=.1*c,v&&(g=Math.max(Math.abs(t),Math.abs(u)),u=g-v,t=v-g),x?(h=n.getDataLabelLength(t,u,b,"width"),j=p(n.y.range()),k=[h[0]/j,h[1]/j],e+=c*(k[1]/(1-k[0]-k[1])),f+=c*(k[0]/(1-k[0]-k[1]))):y&&(h=n.getDataLabelLength(t,u,b,"height"),e+=h[1],f+=h[0]),"y"===b&&o.axis_y_padding&&(e=n.getAxisPadding(o.axis_y_padding,"top",d,c),f=n.getAxisPadding(o.axis_y_padding,"bottom",d,c)),"y2"===b&&o.axis_y2_padding&&(e=n.getAxisPadding(o.axis_y2_padding,"top",d,c),f=n.getAxisPadding(o.axis_y2_padding,"bottom",d,c)),w&&(l&&(f=t),m&&(e=-u)),[t-f,u+e])},f.getXDomainMin=function(a){var b=this,c=b.config;return c.axis_x_min?b.isTimeSeries()?this.parseDate(c.axis_x_min):c.axis_x_min:b.d3.min(a,function(a){return b.d3.min(a.values,function(a){return a.x})})},f.getXDomainMax=function(a){var b=this,c=b.config;return c.axis_x_max?b.isTimeSeries()?this.parseDate(c.axis_x_max):c.axis_x_max:b.d3.max(a,function(a){return b.d3.max(a.values,function(a){return a.x})})},f.getXDomainPadding=function(a){var b,c,d,e,f=this,g=f.config,h=this.getEdgeX(a),j=h[1]-h[0];return f.isCategorized()?c=0:f.hasType("bar",a)?(b=f.getMaxDataCount(),c=b>1?j/(b-1)/2:.5):c=.01*j,"object"==typeof g.axis_x_padding&&r(g.axis_x_padding)?(d=i(g.axis_x_padding.left)?g.axis_x_padding.left:c,e=i(g.axis_x_padding.right)?g.axis_x_padding.right:c):d=e="number"==typeof g.axis_x_padding?g.axis_x_padding:c,{left:d,right:e}},f.getXDomain=function(a){var b=this,c=[b.getXDomainMin(a),b.getXDomainMax(a)],d=c[0],e=c[1],f=b.getXDomainPadding(a),g=0,h=0;return d-e!==0||b.isCategorized()||(d=b.isTimeSeries()?new Date(.5*d.getTime()):-.5,e=b.isTimeSeries()?new Date(1.5*e.getTime()):.5),(d||0===d)&&(g=b.isTimeSeries()?new Date(d.getTime()-f.left):d-f.left),(e||0===e)&&(h=b.isTimeSeries()?new Date(e.getTime()+f.right):e+f.right),[g,h]},f.updateXDomain=function(a,b,c,d){var e=this,f=e.config;return c&&(e.x.domain(d?d:e.d3.extent(e.getXDomain(a))),e.orgXDomain=e.x.domain(),f.zoom_enabled&&e.zoom.scale(e.x).updateScaleExtent(),e.subX.domain(e.x.domain()),e.brush&&e.brush.scale(e.subX)),b&&(e.x.domain(d?d:!e.brush||e.brush.empty()?e.orgXDomain:e.brush.extent()),f.zoom_enabled&&e.zoom.scale(e.x).updateScaleExtent()),e.x.domain()},f.isX=function(a){var b=this,c=b.config;return c.data_x&&a===c.data_x||r(c.data_xs)&&t(c.data_xs,a)},f.isNotX=function(a){return!this.isX(a)},f.getXKey=function(a){var b=this,c=b.config;return c.data_x?c.data_x:r(c.data_xs)?c.data_xs[a]:null},f.getXValuesOfXKey=function(a,b){var c,d=this,e=b&&r(b)?d.mapToIds(b):[];return e.forEach(function(b){d.getXKey(b)===a&&(c=d.data.xs[b])}),c},f.getXValue=function(a,b){var c=this;return a in c.data.xs&&c.data.xs[a]&&i(c.data.xs[a][b])?c.data.xs[a][b]:b},f.getOtherTargetXs=function(){var a=this,b=Object.keys(a.data.xs);return b.length?a.data.xs[b[0]]:null},f.getOtherTargetX=function(a){var b=this.getOtherTargetXs();return b&&a1},f.isMultipleX=function(){var a=this,b=a.config;return r(b.data_xs)&&a.hasMultipleX(b.data_xs)},f.addName=function(a){var b,c=this;return a&&(b=c.config.data_names[a.id],a.name=b?b:a.id),a},f.getValueOnIndex=function(a,b){var c=a.filter(function(a){return a.index===b});return c.length?c[0]:null},f.updateTargetX=function(a,b){var c=this;a.forEach(function(a){a.values.forEach(function(d,e){d.x=c.generateTargetX(b[e],a.id,e)}),c.data.xs[a.id]=b})},f.updateTargetXs=function(a,b){var c=this;a.forEach(function(a){b[a.id]&&c.updateTargetX([a],b[a.id])})},f.generateTargetX=function(a,b,c){var d,e=this;return d=e.isTimeSeries()?e.parseDate(a?a:e.getXValue(b,c)):e.isCustomX()&&!e.isCategorized()?i(a)?+a:e.getXValue(b,c):c},f.cloneTarget=function(a){return{id:a.id,id_org:a.id_org,values:a.values.map(function(a){return{x:a.x,value:a.value,id:a.id}})}},f.getPrevX=function(a){var b=this,c=b.getValueOnIndex(b.data.targets[0].values,a-1);return c?c.x:null},f.getNextX=function(a){var b=this,c=b.getValueOnIndex(b.data.targets[0].values,a+1);return c?c.x:null},f.getMaxDataCount=function(){var a=this;return a.d3.max(a.data.targets,function(a){return a.values.length})},f.getMaxDataCountTarget=function(a){var b,c=a.length,d=0;return c>1?a.forEach(function(a){a.values.length>d&&(b=a,d=a.values.length)}):b=c?a[0]:null,b},f.getEdgeX=function(a){var b,c,d=this.getMaxDataCountTarget(a);return d?(b=d.values[0],c=d.values[d.values.length-1],[b.x,c.x]):[0,0]},f.mapToIds=function(a){return a.map(function(a){return a.id})},f.mapToTargetIds=function(a){var b=this;return a?k(a)?[a]:a:b.mapToIds(b.data.targets)},f.hasTarget=function(a,b){var c,d=this.mapToIds(a);for(c=0;ca})},f.hasPositiveValueInTargets=function(a){return this.checkValueInTargets(a,function(a){return a>0})},f.isOrderDesc=function(){var a=this.config;return a.data_order&&"desc"===a.data_order.toLowerCase()},f.isOrderAsc=function(){var a=this.config;return a.data_order&&"asc"===a.data_order.toLowerCase()},f.orderTargets=function(a){var b=this,c=b.config,d=b.isOrderAsc(),e=b.isOrderDesc();return d||e?a.sort(function(a,b){var c=function(a,b){return a+Math.abs(b.value)},e=a.values.reduce(c,0),f=b.values.reduce(c,0);return d?f-e:e-f}):j(c.data_order)&&a.sort(c.data_order),a +},f.filterSameX=function(a,b){return this.d3.merge(a.map(function(a){return a.values})).filter(function(a){return a.x-b===0})},f.filterRemoveNull=function(a){return a.filter(function(a){return i(a.value)})},f.hasDataLabel=function(){var a=this.config;return"boolean"==typeof a.data_labels&&a.data_labels?!0:"object"==typeof a.data_labels&&r(a.data_labels)?!0:!1},f.getDataLabelLength=function(a,b,c,d){var e=this,f=[0,0],g=1.3;return e.selectChart.select("svg").selectAll(".dummy").data([a,b]).enter().append("text").text(function(a){return e.formatByAxisId(c)(a)}).each(function(a,b){f[b]=this.getBoundingClientRect()[d]*g}).remove(),f},f.isNoneArc=function(a){return this.hasTarget(this.data.targets,a.id)},f.isArc=function(a){return"data"in a&&this.hasTarget(this.data.targets,a.data.id)},f.findSameXOfValues=function(a,b){var c,d=a[b].x,e=[];for(c=b-1;c>=0&&d===a[c].x;c--)e.push(a[c]);for(c=b;c0?h=i:g=i,h-g===1||0===g&&0===h?(e=[],(a[g].x||0===a[g].x)&&(e=e.concat(f.findSameXOfValues(a,g))),(a[h].x||0===a[h].x)&&(e=e.concat(f.findSameXOfValues(a,h))),f.findClosest(e,b)):f.findClosestOfValues(a,b,g,h)},f.findClosestFromTargets=function(a,b){var c,d=this;return c=a.map(function(a){return d.findClosestOfValues(a.values,b)}),d.findClosest(c,b)},f.findClosest=function(a,b){var c,d,e=this;return a.forEach(function(a){var f=e.dist(a,b);(c>f||!c)&&(c=f,d=a)}),d},f.dist=function(a,b){var c=this,d=c.config,e="y"===c.getAxisId(a.id)?c.y:c.y2,f=d.axis_rotated?1:0,g=d.axis_rotated?0:1;return Math.pow(c.x(a.x)-b[f],2)+Math.pow(e(a.value)-b[g],2)},f.convertUrlToData=function(a,b,c,d){var e=this,f=b?b:"csv";e.d3.xhr(a,function(a,b){var g;g="json"===f?e.convertJsonToData(JSON.parse(b.response),c):e.convertCsvToData(b.response),d.call(e,g)})},f.convertCsvToData=function(a){var b,c=this.d3,d=c.csv.parseRows(a);return 1===d.length?(b=[{}],d[0].forEach(function(a){b[0][a]=null})):b=c.csv.parse(a),b},f.convertJsonToData=function(a,b){var c,d,e=this,f=[];return b?(c=b.value,b.x&&(c.push(b.x),e.config.data_x=b.x),f.push(c),a.forEach(function(a){var b=[];c.forEach(function(c){var d=l(a[c])?null:a[c];b.push(d)}),f.push(b)}),d=e.convertRowsToData(f)):(Object.keys(a).forEach(function(b){f.push([b].concat(a[b]))}),d=e.convertColumnsToData(f)),d},f.convertRowsToData=function(a){var b,c,d=a[0],e={},f=[];for(b=1;b=0?d.data.xs[c]=(b&&d.data.xs[c]?d.data.xs[c]:[]).concat(a.map(function(a){return a[f]}).filter(i).map(function(a,b){return d.generateTargetX(a,c,b)})):e.data_x?d.data.xs[c]=d.getOtherTargetXs():r(e.data_xs)&&(d.data.xs[c]=d.getXValuesOfXKey(f,d.data.targets)):d.data.xs[c]=a.map(function(a,b){return b})}),f.forEach(function(a){if(!d.data.xs[a])throw new Error('x is not defined for id = "'+a+'".')}),c=f.map(function(b,c){var f=e.data_idConverter(b);return{id:f,id_org:b,values:a.map(function(a,g){var h=d.getXKey(b),i=a[h],j=d.generateTargetX(i,b,g);return d.isCustomX()&&d.isCategorized()&&0===c&&i&&(0===g&&(e.axis_x_categories=[]),e.axis_x_categories.push(i)),(l(a[b])||d.data.xs[b].length<=g)&&(j=void 0),{x:j,value:null===a[b]||isNaN(a[b])?null:+a[b],id:f}}).filter(function(a){return m(a.x)})}}),c.forEach(function(a){var b;a.values=a.values.sort(function(a,b){var c=a.x||0===a.x?a.x:1/0,d=b.x||0===b.x?b.x:1/0;return c-d}),b=0,a.values.forEach(function(a){a.index=b++}),d.data.xs[a.id].sort(function(a,b){return a-b})}),e.data_type&&d.setTargetType(d.mapToIds(c).filter(function(a){return!(a in e.data_types)}),e.data_type),c.forEach(function(a){d.addCache(a.id_org,a)}),c},f.load=function(a,b){var c=this;a&&(b.filter&&(a=a.filter(b.filter)),(b.type||b.types)&&a.forEach(function(a){c.setTargetType(a.id,b.types?b.types[a.id]:b.type)}),c.data.targets.forEach(function(b){for(var c=0;ce?0:e},g=function(a){var b=h.getPrevX(a.index),c=h.data.xs[a.id][a.index];return(h.x(c)+h.x(b?b:c))/2}),b=i.axis_rotated?0:g,c=i.axis_rotated?g:0,d=i.axis_rotated?h.width:f,e=i.axis_rotated?f:h.height),a.attr("class",h.classEvent.bind(h)).attr("x",b).attr("y",c).attr("width",d).attr("height",e)},f.generateEventRectsForSingleX=function(a){var b=this,c=b.d3,d=b.config;a.append("rect").attr("class",b.classEvent.bind(b)).style("cursor",d.data_selection_enabled&&d.data_selection_grouped?"pointer":null).on("mouseover",function(a){var c,e,f=a.index;b.dragging||b.hasArcType()||(c=b.data.targets.map(function(a){return b.addName(b.getValueOnIndex(a.values,f))}),e=[],Object.keys(d.data_names).forEach(function(a){for(var b=0;b0?c:320},f.getCurrentPaddingTop=function(){var a=this.config;return i(a.padding_top)?a.padding_top:0},f.getCurrentPaddingBottom=function(){var a=this.config;return i(a.padding_bottom)?a.padding_bottom:0},f.getCurrentPaddingLeft=function(){var a=this,b=a.config;return i(b.padding_left)?b.padding_left:b.axis_rotated?b.axis_x_show?Math.max(n(a.getAxisWidthByAxisId("x")),40):1:b.axis_y_show?n(a.getAxisWidthByAxisId("y")):1},f.getCurrentPaddingRight=function(){var a=this,b=a.config,c=10,d=a.isLegendRight?a.getLegendWidth()+20:0;return i(b.padding_right)?b.padding_right+1:b.axis_rotated?c+d:(b.axis_y2_show?n(a.getAxisWidthByAxisId("y2")):c)+d},f.getParentRectValue=function(a){for(var b,c=this.selectChart.node();c&&"BODY"!==c.tagName&&!(b=c.getBoundingClientRect()[a]);)c=c.parentNode;return b},f.getParentWidth=function(){return this.getParentRectValue("width")},f.getParentHeight=function(){var a=this.selectChart.style("height");return a.indexOf("px")>0?+a.replace("px",""):0},f.getSvgLeft=function(){var a=this,b=a.config,c=b.axis_rotated?h.axisX:h.axisY,d=a.main.select("."+c).node(),e=d?d.getBoundingClientRect():{right:0},f=a.selectChart.node().getBoundingClientRect(),g=a.hasArcType(),i=e.right-f.left-(g?0:a.getCurrentPaddingLeft());return i>0?i:0},f.getAxisWidthByAxisId=function(a){var b=this,c=b.getAxisLabelPositionById(a);return c.isInner?20+b.getMaxTickWidth(a):40+b.getMaxTickWidth(a)},f.getHorizontalAxisHeight=function(a){var b=this,c=b.config;return"x"!==a||c.axis_x_show?"x"===a&&c.axis_x_height?c.axis_x_height:"y"!==a||c.axis_y_show?"y2"!==a||c.axis_y2_show?(b.getAxisLabelPositionById(a).isInner?30:40)+("y2"===a?-10:0):b.rotated_padding_top:!c.legend_show||b.isLegendRight||b.isLegendInset?1:10:0},f.getEventRectWidth=function(){var a,b,c,d,e,f,g=this,h=g.getMaxDataCountTarget(g.data.targets);return h?(a=h.values[0],b=h.values[h.values.length-1],c=g.x(b.x)-g.x(a.x),0===c?g.config.axis_rotated?g.height:g.width:(d=g.getMaxDataCount(),e=g.hasType("bar")?(d-(g.isCategorized()?.25:1))/d:1,f=d>1?c*e/(d-1):c,1>f?1:f)):0},f.getShapeIndices=function(a){var b,c,d=this,e=d.config,f={},g=0;return d.filterTargetsToShow(d.data.targets.filter(a,d)).forEach(function(a){for(b=0;b=0&&(j+=h(c.values[g].value)-i)}),j}},f.getInterpolate=function(a){var b=this;return b.isSplineType(a)?"cardinal":b.isStepType(a)?"step-after":"linear"},f.initLine=function(){var a=this;a.main.select("."+h.chart).append("g").attr("class",h.chartLines)},f.updateTargetsForLine=function(a){var b,c,d=this,e=d.config,f=d.classChartLine.bind(d),g=d.classLines.bind(d),i=d.classAreas.bind(d),j=d.classCircles.bind(d);b=d.main.select("."+h.chartLines).selectAll("."+h.chartLine).data(a).attr("class",f),c=b.enter().append("g").attr("class",f).style("opacity",0).style("pointer-events","none"),c.append("g").attr("class",g),c.append("g").attr("class",i),c.append("g").attr("class",function(a){return d.generateClass(h.selectedCircles,a.id)}),c.append("g").attr("class",j).style("cursor",function(a){return e.data_selection_isselectable(a)?"pointer":null}),a.forEach(function(a){d.main.selectAll("."+h.selectedCircles+d.getTargetSelectorSuffix(a.id)).selectAll("."+h.selectedCircle).each(function(b){b.value=a.values[b.index].value})})},f.redrawLine=function(a){var b=this;b.mainLine=b.main.selectAll("."+h.lines).selectAll("."+h.line).data(b.lineData.bind(b)),b.mainLine.enter().append("path").attr("class",b.classLine.bind(b)).style("stroke",b.color),b.mainLine.style("opacity",b.initialOpacity.bind(b)).attr("transform",null),b.mainLine.exit().transition().duration(a).style("opacity",0).remove()},f.addTransitionForLine=function(a,b){var c=this;a.push(c.mainLine.transition().attr("d",b).style("stroke",c.color).style("opacity",1))},f.generateDrawLine=function(a,b){var c=this,d=c.config,e=c.d3.svg.line(),f=c.generateGetLinePoint(a,b),g=b?c.getSubYScale:c.getYScale,h=function(a){return(b?c.subxx:c.xx).call(c,a)},i=function(a,b){return d.data_groups.length>0?f(a,b)[0][1]:g.call(c,a.id)(a.value)};return e=d.axis_rotated?e.x(i).y(h):e.x(h).y(i),d.line_connect_null||(e=e.defined(function(a){return null!=a.value})),function(a){var f,h=d.line_connect_null?c.filterRemoveNull(a.values):a.values,i=b?c.x:c.subX,j=g.call(c,a.id),k=0,l=0;return c.isLineType(a)?f=d.data_regions[a.id]?c.lineWithRegions(h,i,j,d.data_regions[a.id]):e.interpolate(c.getInterpolate(a))(h):(h[0]&&(k=i(h[0].x),l=j(h[0].value)),f=d.axis_rotated?"M "+l+" "+k:"M "+k+" "+l),f?f:"M 0 0"}},f.generateGetLinePoint=function(a,b){var c=this,d=c.config,e=a.__max__+1,f=c.getShapeX(0,e,a,!!b),g=c.getShapeY(!!b),h=c.getShapeOffset(c.isLineType,a,!!b),i=b?c.getSubYScale:c.getYScale;return function(a,b){var e=i.call(c,a.id)(0),j=h(a,b)||e,k=f(a),l=g(a);return d.axis_rotated&&(0l||a.value<0&&l>e)&&(l=e),[[k,l-(e-j)]]}},f.lineWithRegions=function(a,b,c,d){function e(a,b){var c;for(c=0;c=g;g+=q)w+=h(a[f-1],a[f],g,p);v=a[f].x}return w},f.redrawArea=function(a){var b=this,c=b.d3;b.mainArea=b.main.selectAll("."+h.areas).selectAll("."+h.area).data(b.lineData.bind(b)),b.mainArea.enter().append("path").attr("class",b.classArea.bind(b)).style("fill",b.color).style("opacity",function(){return b.orgAreaOpacity=+c.select(this).style("opacity"),0}),b.mainArea.style("opacity",b.orgAreaOpacity),b.mainArea.exit().transition().duration(a).style("opacity",0).remove()},f.addTransitionForArea=function(a,b){var c=this;a.push(c.mainArea.transition().attr("d",b).style("fill",c.color).style("opacity",c.orgAreaOpacity))},f.generateDrawArea=function(a,b){var c=this,d=c.config,e=c.d3.svg.area(),f=c.generateGetAreaPoint(a,b),g=b?c.getSubYScale:c.getYScale,h=function(a){return(b?c.subxx:c.xx).call(c,a)},i=function(a,b){return d.data_groups.length>0?f(a,b)[0][1]:g.call(c,a.id)(0)},j=function(a,b){return d.data_groups.length>0?f(a,b)[1][1]:g.call(c,a.id)(a.value)};return e=d.axis_rotated?e.x0(i).x1(j).y(h):e.x(h).y0(i).y1(j),d.line_connect_null||(e=e.defined(function(a){return null!==a.value})),function(a){var b,f=d.line_connect_null?c.filterRemoveNull(a.values):a.values,g=0,h=0;return c.isAreaType(a)?b=e.interpolate(c.getInterpolate(a))(f):(f[0]&&(g=c.x(f[0].x),h=c.getYScale(a.id)(f[0].value)),b=d.axis_rotated?"M "+h+" "+g:"M "+g+" "+h),b?b:"M 0 0"}},f.generateGetAreaPoint=function(a,b){var c=this,d=c.config,e=a.__max__+1,f=c.getShapeX(0,e,a,!!b),g=c.getShapeY(!!b),h=c.getShapeOffset(c.isAreaType,a,!!b),i=b?c.getSubYScale:c.getYScale;return function(a,b){var e=i.call(c,a.id)(0),j=h(a,b)||e,k=f(a),l=g(a);return d.axis_rotated&&(0l||a.value<0&&l>e)&&(l=e),[[k,j],[k,l-(e-j)]]}},f.redrawCircle=function(){var a=this;a.mainCircle=a.main.selectAll("."+h.circles).selectAll("."+h.circle).data(a.lineOrScatterData.bind(a)),a.mainCircle.enter().append("circle").attr("class",a.classCircle.bind(a)).attr("r",a.pointR.bind(a)).style("fill",a.color),a.mainCircle.style("opacity",a.initialOpacity.bind(a)),a.mainCircle.exit().remove()},f.addTransitionForCircle=function(a,b,c){var d=this;a.push(d.mainCircle.transition().style("opacity",d.opacityForCircle.bind(d)).style("fill",d.color).attr("cx",b).attr("cy",c)),a.push(d.main.selectAll("."+h.selectedCircle).transition().attr("cx",b).attr("cy",c))},f.circleX=function(a){return a.x||0===a.x?this.x(a.x):null},f.circleY=function(a,b){var c=this,d=c.getShapeIndices(c.isLineType),e=c.generateGetLinePoint(d);return c.config.data_groups.length>0?e(a,b)[0][1]:c.getYScale(a.id)(a.value)},f.getCircles=function(a,b){var c=this;return(b?c.main.selectAll("."+h.circles+c.getTargetSelectorSuffix(b)):c.main).selectAll("."+h.circle+(i(a)?"-"+a:""))},f.expandCircles=function(a,b){var c=this,d=c.pointExpandedR.bind(c);c.getCircles(a,b).classed(h.EXPANDED,!0).attr("r",d)},f.unexpandCircles=function(a){var b=this,c=b.pointR.bind(b);b.getCircles(a).filter(function(){return b.d3.select(this).classed(h.EXPANDED)}).classed(h.EXPANDED,!1).attr("r",c)},f.pointR=function(a){var b=this,c=b.config;return c.point_show&&!b.isStepType(a)?j(c.point_r)?c.point_r(a):c.point_r:0},f.pointExpandedR=function(a){var b=this,c=b.config;return c.point_focus_expand_enabled?c.point_focus_expand_r?c.point_focus_expand_r:1.75*b.pointR(a):b.pointR(a)},f.pointSelectR=function(a){var b=this,c=b.config;return c.point_select_r?c.point_select_r:4*b.pointR(a)},f.isWithinCircle=function(a,b){var c=this.d3,d=c.mouse(a),e=c.select(a),f=1*e.attr("cx"),g=1*e.attr("cy");return Math.sqrt(Math.pow(f-d[0],2)+Math.pow(g-d[1],2))d.bar_width_max?d.bar_width_max:e},f.getBars=function(a){var b=this;return b.main.selectAll("."+h.bar+(i(a)?"-"+a:""))},f.expandBars=function(a){var b=this;b.getBars(a).classed(h.EXPANDED,!0)},f.unexpandBars=function(a){var b=this;b.getBars(a).classed(h.EXPANDED,!1)},f.generateDrawBar=function(a,b){var c=this,d=c.config,e=c.generateGetBarPoints(a,b);return function(a,b){var c=e(a,b),f=d.axis_rotated?1:0,g=d.axis_rotated?0:1,h="M "+c[0][f]+","+c[0][g]+" L"+c[1][f]+","+c[1][g]+" L"+c[2][f]+","+c[2][g]+" L"+c[3][f]+","+c[3][g]+" z";return h}},f.generateGetBarPoints=function(a,b){var c=this,d=a.__max__+1,e=c.getBarW(c.xAxis,d),f=c.getShapeX(e,d,a,!!b),g=c.getShapeY(!!b),h=c.getShapeOffset(c.isBarType,a,!!b),i=b?c.getSubYScale:c.getYScale;return function(a,b){var d=i.call(c,a.id)(0),j=h(a,b)||d,k=f(a),l=g(a);return c.config.axis_rotated&&(0l||a.value<0&&l>d)&&(l=d),[[k,j],[k,l-(d-j)],[k+e,l-(d-j)],[k+e,j]]}},f.isWithinBar=function(a){var b=this.d3,c=b.mouse(a),d=a.getBoundingClientRect(),e=a.pathSegList.getItem(0),f=a.pathSegList.getItem(1),g=e.x,h=Math.min(e.y,f.y),i=d.width,j=d.height,k=2,l=g-k,m=g+i+k,n=h+j+k,o=h-k;return lf.width?f.width-g.width:d},f.getYForText=function(a,b,c){var d,e=this,f=c.getBoundingClientRect();return d=e.config.axis_rotated?(a[0][0]+a[2][0]+.6*f.height)/2:a[2][1]+(b.value<0?f.height:e.isBarType(b)?-3:-6),d=0||!(b.id in d)&&"line"===a)&&(e=!0)}),e},f.hasArcType=function(a){return this.hasType("pie",a)||this.hasType("donut",a)||this.hasType("gauge",a)},f.isLineType=function(a){var b=this.config,c=k(a)?a:a.id;return!b.data_types[c]||["line","spline","area","area-spline","step","area-step"].indexOf(b.data_types[c])>=0},f.isStepType=function(a){var b=k(a)?a:a.id;return["step","area-step"].indexOf(this.config.data_types[b])>=0},f.isSplineType=function(a){var b=k(a)?a:a.id;return["spline","area-spline"].indexOf(this.config.data_types[b])>=0},f.isAreaType=function(a){var b=k(a)?a:a.id;return["area","area-spline","area-step"].indexOf(this.config.data_types[b])>=0},f.isBarType=function(a){var b=k(a)?a:a.id;return"bar"===this.config.data_types[b]},f.isScatterType=function(a){var b=k(a)?a:a.id;return"scatter"===this.config.data_types[b]},f.isPieType=function(a){var b=k(a)?a:a.id;return"pie"===this.config.data_types[b]},f.isGaugeType=function(a){var b=k(a)?a:a.id;return"gauge"===this.config.data_types[b]},f.isDonutType=function(a){var b=k(a)?a:a.id;return"donut"===this.config.data_types[b]},f.isArcType=function(a){return this.isPieType(a)||this.isDonutType(a)||this.isGaugeType(a)},f.lineData=function(a){return this.isLineType(a)?[a]:[]},f.arcData=function(a){return this.isArcType(a.data)?[a]:[]},f.barData=function(a){return this.isBarType(a)?a.values:[]},f.lineOrScatterData=function(a){return this.isLineType(a)||this.isScatterType(a)?a.values:[]},f.barOrLineData=function(a){return this.isBarType(a)||this.isLineType(a)?a.values:[]},f.initGrid=function(){var a=this,b=a.config,c=a.d3;a.grid=a.main.append("g").attr("clip-path",a.clipPath).attr("class",h.grid),b.grid_x_show&&a.grid.append("g").attr("class",h.xgrids),b.grid_y_show&&a.grid.append("g").attr("class",h.ygrids),a.grid.append("g").attr("class",h.xgridLines),a.grid.append("g").attr("class",h.ygridLines),b.grid_focus_show&&a.grid.append("g").attr("class",h.xgridFocus).append("line").attr("class",h.xgridFocus),a.xgrid=c.selectAll([]),a.xgridLines=c.selectAll([])},f.updateXGrid=function(a){var b=this,c=b.config,d=b.d3,e=b.generateGridData(c.grid_x_type,b.x),f=b.isCategorized()?b.xAxis.tickOffset():0;b.xgridAttr=c.axis_rotated?{x1:0,x2:b.width,y1:function(a){return b.x(a)-f},y2:function(a){return b.x(a)-f}}:{x1:function(a){return b.x(a)+f},x2:function(a){return b.x(a)+f},y1:0,y2:b.height},b.xgrid=b.main.select("."+h.xgrids).selectAll("."+h.xgrid).data(e),b.xgrid.enter().append("line").attr("class",h.xgrid),a||b.xgrid.attr(b.xgridAttr).style("opacity",function(){return+d.select(this).attr(c.axis_rotated?"y1":"x1")===(c.axis_rotated?b.height:0)?0:1}),b.xgrid.exit().remove()},f.updateYGrid=function(){var a=this,b=a.config;a.ygrid=a.main.select("."+h.ygrids).selectAll("."+h.ygrid).data(a.y.ticks(b.grid_y_ticks)),a.ygrid.enter().append("line").attr("class",h.ygrid),a.ygrid.attr("x1",b.axis_rotated?a.y:0).attr("x2",b.axis_rotated?a.y:a.width).attr("y1",b.axis_rotated?0:a.y).attr("y2",b.axis_rotated?a.height:a.y),a.ygrid.exit().remove(),a.smoothLines(a.ygrid,"grid")},f.redrawGrid=function(a,b){var c,d,e,f=this,g=f.main,i=f.config;g.select("line."+h.xgridFocus).style("visibility","hidden"),i.grid_x_show&&f.updateXGrid(),f.xgridLines=g.select("."+h.xgridLines).selectAll("."+h.xgridLine).data(i.grid_x_lines),c=f.xgridLines.enter().append("g").attr("class",function(a){return h.xgridLine+(a.class?" "+a.class:"")}),c.append("line").style("opacity",0),c.append("text").attr("text-anchor","end").attr("transform",i.axis_rotated?"":"rotate(-90)").attr("dx",i.axis_rotated?0:-f.margin.top).attr("dy",-5).style("opacity",0),f.xgridLines.exit().transition().duration(a).style("opacity",0).remove(),b&&i.grid_y_show&&f.updateYGrid(),b&&(f.ygridLines=g.select("."+h.ygridLines).selectAll("."+h.ygridLine).data(i.grid_y_lines),d=f.ygridLines.enter().append("g").attr("class",function(a){return h.ygridLine+(a.class?" "+a.class:"")}),d.append("line").style("opacity",0),d.append("text").attr("text-anchor","end").attr("transform",i.axis_rotated?"rotate(-90)":"").attr("dx",i.axis_rotated?0:-f.margin.top).attr("dy",-5).style("opacity",0),e=f.yv.bind(f),f.ygridLines.select("line").transition().duration(a).attr("x1",i.axis_rotated?e:0).attr("x2",i.axis_rotated?e:f.width).attr("y1",i.axis_rotated?0:e).attr("y2",i.axis_rotated?f.height:e).style("opacity",1),f.ygridLines.select("text").transition().duration(a).attr("x",i.axis_rotated?0:f.width).attr("y",e).text(function(a){return a.text}).style("opacity",1),f.ygridLines.exit().transition().duration(a).style("opacity",0).remove())},f.addTransitionForGrid=function(a){var b=this,c=b.config,d=b.xv.bind(b);a.push(b.xgridLines.select("line").transition().attr("x1",c.axis_rotated?0:d).attr("x2",c.axis_rotated?b.width:d).attr("y1",c.axis_rotated?d:b.margin.top).attr("y2",c.axis_rotated?d:b.height).style("opacity",1)),a.push(b.xgridLines.select("text").transition().attr("x",c.axis_rotated?b.width:0).attr("y",d).text(function(a){return a.text}).style("opacity",1))},f.showXGridFocus=function(a){var b=this,c=b.config,d=a.filter(function(a){return a&&i(a.value)}),e=b.main.selectAll("line."+h.xgridFocus),f=b.xx.bind(b);c.tooltip_show&&(b.hasType("scatter")||b.hasArcType()||(e.style("visibility","visible").data([d[0]]).attr(c.axis_rotated?"y1":"x1",f).attr(c.axis_rotated?"y2":"x2",f),b.smoothLines(e,"grid")))},f.hideXGridFocus=function(){this.main.select("line."+h.xgridFocus).style("visibility","hidden")},f.updateXgridFocus=function(){var a=this,b=a.config;a.main.select("line."+h.xgridFocus).attr("x1",b.axis_rotated?0:-10).attr("x2",b.axis_rotated?a.width:-10).attr("y1",b.axis_rotated?-10:0).attr("y2",b.axis_rotated?-10:a.height)},f.generateGridData=function(a,b){var c,d,e,f,g=this,i=[],j=g.main.select("."+h.axisX).selectAll(".tick").size();if("year"===a)for(c=g.getXDomain(),d=c[0].getFullYear(),e=c[1].getFullYear(),f=d;e>=f;f++)i.push(new Date(f+"-01-01 00:00:00")); +else i=b.ticks(10),i.length>j&&(i=i.filter(function(a){return(""+a).indexOf(".")<0}));return i},f.getGridFilterToRemove=function(a){return a?function(b){var c=!1;return[].concat(a).forEach(function(d){("value"in d&&b.value===a.value||"class"in d&&b.class===a.class)&&(c=!0)}),c}:function(){return!0}},f.removeGridLines=function(a,b){var c=this,d=c.config,e=c.getGridFilterToRemove(a),f=function(a){return!e(a)},g=b?h.xgridLines:h.ygridLines,i=b?h.xgridLine:h.ygridLine;c.main.select("."+g).selectAll("."+i).filter(e).transition().duration(d.transition_duration).style("opacity",0).remove(),b?d.grid_x_lines=d.grid_x_lines.filter(f):d.grid_y_lines=d.grid_y_lines.filter(f)},f.initTooltip=function(){var a,b=this,c=b.config;if(b.tooltip=b.selectChart.style("position","relative").append("div").style("position","absolute").style("pointer-events","none").style("z-index","10").style("display","none"),c.tooltip_init_show){if(b.isTimeSeries()&&k(c.tooltip_init_x)){for(c.tooltip_init_x=b.parseDate(c.tooltip_init_x),a=0;a"+(g||0===g?""+g+"":"")),j=o(a[f].name),i=p(a[f].value,a[f].ratio,a[f].id,a[f].index),k=l.levelColor?l.levelColor(a[f].value):d(a[f].id),e+="",e+=""+j+"",e+=""+i+"",e+="");return e+""},f.showTooltip=function(a,b){var c,d,e,f,g,h,j,k=this,l=k.config,m=k.hasArcType(),n=a.filter(function(a){return a&&i(a.value)});0!==n.length&&l.tooltip_show&&(k.tooltip.html(l.tooltip_contents.call(k,a,k.getXAxisTickFormat(),k.getYFormat(m),k.color)).style("display","block"),c=k.tooltip.property("offsetWidth"),d=k.tooltip.property("offsetHeight"),m?(f=k.width/2+b[0],h=k.height/2+b[1]+20):(l.axis_rotated?(e=k.getSvgLeft(),f=e+b[0]+100,g=f+c,j=k.getCurrentWidth()-k.getCurrentPaddingRight(),h=k.x(n[0].x)+20):(e=k.getSvgLeft(),f=e+k.getCurrentPaddingLeft()+k.x(n[0].x)+20,g=f+c,j=e+k.getCurrentWidth()-k.getCurrentPaddingRight(),h=b[1]+15),g>j&&(f-=g-j),h+d>k.getCurrentHeight()&&h>d+30&&(h-=d+30)),k.tooltip.style("top",h+"px").style("left",f+"px"))},f.hideTooltip=function(){this.tooltip.style("display","none")},f.initLegend=function(){var a=this;a.legend=a.svg.append("g").attr("transform",a.getTranslate("legend")),a.config.legend_show||(a.legend.style("visibility","hidden"),a.hiddenLegendIds=a.mapToIds(a.data.targets)),a.updateLegend(a.mapToIds(a.data.targets),{withTransform:!1,withTransitionForTransform:!1,withTransition:!1})},f.updateSizeForLegend=function(a,b){var c=this,d=c.config,e={top:c.isLegendTop?c.getCurrentPaddingTop()+d.legend_inset_y+5.5:c.currentHeight-a-c.getCurrentPaddingBottom()-d.legend_inset_y,left:c.isLegendLeft?c.getCurrentPaddingLeft()+d.legend_inset_x+.5:c.currentWidth-b-c.getCurrentPaddingRight()-d.legend_inset_x+.5};c.margin3={top:c.isLegendRight?0:c.isLegendInset?e.top:c.currentHeight-a,right:0/0,bottom:0,left:c.isLegendRight?c.currentWidth-b:c.isLegendInset?e.left:0}},f.transformLegend=function(a){var b=this;(a?b.legend.transition():b.legend).attr("transform",b.getTranslate("legend"))},f.updateLegendStep=function(a){this.legendStep=a},f.updateLegendItemWidth=function(a){this.legendItemWidth=a},f.updateLegendItemHeight=function(a){this.legendItemHeight=a},f.getLegendWidth=function(){var a=this;return a.config.legend_show?a.isLegendRight||a.isLegendInset?a.legendItemWidth*(a.legendStep+1):a.currentWidth:0},f.getLegendHeight=function(){var a=this,b=a.config,c=0;return b.legend_show&&(c=a.isLegendRight?a.currentHeight:a.isLegendInset?b.legend_inset_step?Math.max(20,a.legendItemHeight)*(b.legend_inset_step+1):a.height:Math.max(20,a.legendItemHeight)*(a.legendStep+1)),c},f.opacityForLegend=function(a){var b=this;return a.classed(h.legendItemHidden)?b.legendOpacityForHidden:1},f.opacityForUnfocusedLegend=function(a){var b=this;return a.classed(h.legendItemHidden)?b.legendOpacityForHidden:.3},f.toggleFocusLegend=function(a,b){var c=this;c.legend.selectAll("."+h.legendItem).transition().duration(100).style("opacity",function(d){var e=c.d3.select(this);return a&&d!==a?b?c.opacityForUnfocusedLegend(e):c.opacityForLegend(e):b?c.opacityForLegend(e):c.opacityForUnfocusedLegend(e)})},f.revertLegend=function(){var a=this,b=a.d3;a.legend.selectAll("."+h.legendItem).transition().duration(100).style("opacity",function(){return a.opacityForLegend(b.select(this))})},f.showLegend=function(a){var b=this,c=b.config;c.legend_show||(c.legend_show=!0,b.legend.style("visibility","visible")),b.removeHiddenLegendIds(a),b.legend.selectAll(b.selectorLegends(a)).style("visibility","visible").transition().style("opacity",function(){return b.opacityForLegend(b.d3.select(this))})},f.hideLegend=function(a){var b=this,c=b.config;c.legend_show&&q(a)&&(c.legend_show=!1,b.legend.style("visibility","hidden")),b.addHiddenLegendIds(a),b.legend.selectAll(b.selectorLegends(a)).style("opacity",0).style("visibility","hidden")},f.updateLegend=function(a,b,c){function d(b,c,d){function e(a,b){b||(f=(m-A-l)/2,z>f&&(f=(m-l)/2,A=0,G++)),F[a]=G,E[G]=t.isLegendInset?10:f,B[a]=A,A+=l}var f,g,i=t.getTextRect(b.textContent,h.legendItem),j=10*Math.ceil((i.width+w)/10),k=10*Math.ceil((i.height+v)/10),l=t.isLegendRight||t.isLegendInset?k:j,m=t.isLegendRight||t.isLegendInset?t.getLegendHeight():t.getLegendWidth();return d&&(A=0,G=0,x=0,y=0),u.legend_show&&!t.isLegendToShow(c)?void(C[c]=D[c]=F[c]=B[c]=0):(C[c]=j,D[c]=k,(!x||j>=x)&&(x=j),(!y||k>=y)&&(y=k),g=t.isLegendRight||t.isLegendInset?y:x,void(u.legend_equally?(Object.keys(C).forEach(function(a){C[a]=x}),Object.keys(D).forEach(function(a){D[a]=y}),f=(m-g*a.length)/2,z>f?(A=0,G=0,a.forEach(function(a){e(a)})):e(c,!0)):e(c)))}var e,f,g,i,j,k,l,n,o,p,q,r,t=this,u=t.config,v=4,w=36,x=0,y=0,z=10,A=0,B={},C={},D={},E=[0],F={},G=0,H=t.legend.selectAll("."+h.legendItemFocused).size();b=b||{},n=s(b,"withTransition",!0),o=s(b,"withTransitionForTransform",!0),t.isLegendRight?(e=function(a){return x*F[a]},i=function(a){return E[F[a]]+B[a]}):t.isLegendInset?(e=function(a){return x*F[a]+10},i=function(a){return E[F[a]]+B[a]}):(e=function(a){return E[F[a]]+B[a]},i=function(a){return y*F[a]}),f=function(a,b){return e(a,b)+14},j=function(a,b){return i(a,b)+9},g=function(a,b){return e(a,b)-4},k=function(a,b){return i(a,b)-7},l=t.legend.selectAll("."+h.legendItem).data(a).enter().append("g").attr("class",function(a){return t.generateClass(h.legendItem,a)}).style("visibility",function(a){return t.isLegendToShow(a)?"visible":"hidden"}).style("cursor","pointer").on("click",function(a){u.legend_item_onclick?u.legend_item_onclick.call(t,a):t.api.toggle(a)}).on("mouseover",function(a){t.d3.select(this).classed(h.legendItemFocused,!0),t.transiting||t.api.focus(a),u.legend_item_onmouseover&&u.legend_item_onmouseover.call(t,a)}).on("mouseout",function(a){t.d3.select(this).classed(h.legendItemFocused,!1),t.transiting||t.api.revert(),u.legend_item_onmouseout&&u.legend_item_onmouseout.call(t,a)}),l.append("text").text(function(a){return m(u.data_names[a])?u.data_names[a]:a}).each(function(a,b){d(this,a,0===b)}).style("pointer-events","none").attr("x",t.isLegendRight||t.isLegendInset?f:-200).attr("y",t.isLegendRight||t.isLegendInset?-200:j),l.append("rect").attr("class",h.legendItemEvent).style("fill-opacity",0).attr("x",t.isLegendRight||t.isLegendInset?g:-200).attr("y",t.isLegendRight||t.isLegendInset?-200:k),l.append("rect").attr("class",h.legendItemTile).style("pointer-events","none").style("fill",t.color).attr("x",t.isLegendRight||t.isLegendInset?f:-200).attr("y",t.isLegendRight||t.isLegendInset?-200:i).attr("width",10).attr("height",10),t.isLegendInset&&0!==x&&t.legend.insert("g","."+h.legendItem).attr("class",h.legendBackground).append("rect").attr("height",t.getLegendHeight()-10).attr("width",x*(G+1)+10),p=t.legend.selectAll("text").data(a).text(function(a){return m(u.data_names[a])?u.data_names[a]:a}).each(function(a,b){d(this,a,0===b)}),(n?p.transition():p).attr("x",f).attr("y",j),q=t.legend.selectAll("rect."+h.legendItemEvent).data(a),(n?q.transition():q).attr("width",function(a){return C[a]}).attr("height",function(a){return D[a]}).attr("x",g).attr("y",k),r=t.legend.selectAll("rect."+h.legendItemTile).data(a),(n?r.transition():r).style("fill",t.color).attr("x",e).attr("y",i),t.legend.selectAll("."+h.legendItem).classed(h.legendItemHidden,function(a){return!t.isTargetToShow(a)}).transition().style("opacity",function(a){var b=t.d3.select(this);return t.isTargetToShow(a)?!H||b.classed(h.legendItemFocused)?t.opacityForLegend(b):t.opacityForUnfocusedLegend(b):t.legendOpacityForHidden}),t.updateLegendItemWidth(x),t.updateLegendItemHeight(y),t.updateLegendStep(G),t.updateSizes(),t.updateScales(),t.updateSvgSize(),t.transformAll(o,c)},f.initAxis=function(){var a=this,b=a.config,c=a.main;a.axes.x=c.append("g").attr("class",h.axis+" "+h.axisX).attr("clip-path",a.clipPathForXAxis).attr("transform",a.getTranslate("x")).style("visibility",b.axis_x_show?"visible":"hidden"),a.axes.x.append("text").attr("class",h.axisXLabel).attr("transform",b.axis_rotated?"rotate(-90)":"").style("text-anchor",a.textAnchorForXAxisLabel.bind(a)),a.axes.y=c.append("g").attr("class",h.axis+" "+h.axisY).attr("clip-path",a.clipPathForYAxis).attr("transform",a.getTranslate("y")).style("visibility",b.axis_y_show?"visible":"hidden"),a.axes.y.append("text").attr("class",h.axisYLabel).attr("transform",b.axis_rotated?"":"rotate(-90)").style("text-anchor",a.textAnchorForYAxisLabel.bind(a)),a.axes.y2=c.append("g").attr("class",h.axis+" "+h.axisY2).attr("transform",a.getTranslate("y2")).style("visibility",b.axis_y2_show?"visible":"hidden"),a.axes.y2.append("text").attr("class",h.axisY2Label).attr("transform",b.axis_rotated?"":"rotate(-90)").style("text-anchor",a.textAnchorForY2AxisLabel.bind(a))},f.getXAxis=function(a,b,c,e){var f=this,g=f.config,h=d(f.d3,f.isCategorized()).scale(a).orient(b);return h.tickFormat(c).tickValues(e),f.isCategorized()?(h.tickCentered(g.axis_x_tick_centered),q(g.axis_x_tick_culling)&&(g.axis_x_tick_culling=!1)):h.tickOffset=function(){var a=f.getEdgeX(f.data.targets),b=f.x(a[1])-f.x(a[0]),c=b?b:g.axis_rotated?f.height:f.width;return c/f.getMaxDataCount()/2},h},f.getYAxis=function(a,b,c,e){return d(this.d3).scale(a).orient(b).tickFormat(c).ticks(e)},f.getAxisId=function(a){var b=this.config;return a in b.data_axes?b.data_axes[a]:"y"},f.getXAxisTickFormat=function(){var a=this,b=a.config,c=a.isTimeSeries()?a.defaultAxisTimeFormat:a.isCategorized()?a.categoryName:function(a){return 0>a?a.toFixed(0):a};return b.axis_x_tick_format&&(j(b.axis_x_tick_format)?c=b.axis_x_tick_format:a.isTimeSeries()&&(c=function(c){return c?a.axisTimeFormat(b.axis_x_tick_format)(c):""})),j(c)?function(b){return c.call(a,b)}:c},f.getAxisLabelOptionByAxisId=function(a){var b,c=this,d=c.config;return"y"===a?b=d.axis_y_label:"y2"===a?b=d.axis_y2_label:"x"===a&&(b=d.axis_x_label),b},f.getAxisLabelText=function(a){var b=this.getAxisLabelOptionByAxisId(a);return k(b)?b:b?b.text:null},f.setAxisLabelText=function(a,b){var c=this,d=c.config,e=c.getAxisLabelOptionByAxisId(a);k(e)?"y"===a?d.axis_y_label=b:"y2"===a?d.axis_y2_label=b:"x"===a&&(d.axis_x_label=b):e&&(e.text=b)},f.getAxisLabelPosition=function(a,b){var c=this.getAxisLabelOptionByAxisId(a),d=c&&"object"==typeof c&&c.position?c.position:b;return{isInner:d.indexOf("inner")>=0,isOuter:d.indexOf("outer")>=0,isLeft:d.indexOf("left")>=0,isCenter:d.indexOf("center")>=0,isRight:d.indexOf("right")>=0,isTop:d.indexOf("top")>=0,isMiddle:d.indexOf("middle")>=0,isBottom:d.indexOf("bottom")>=0}},f.getXAxisLabelPosition=function(){return this.getAxisLabelPosition("x",this.config.axis_rotated?"inner-top":"inner-right")},f.getYAxisLabelPosition=function(){return this.getAxisLabelPosition("y",this.config.axis_rotated?"inner-right":"inner-top")},f.getY2AxisLabelPosition=function(){return this.getAxisLabelPosition("y2",this.config.axis_rotated?"inner-right":"inner-top")},f.getAxisLabelPositionById=function(a){return"y2"===a?this.getY2AxisLabelPosition():"y"===a?this.getYAxisLabelPosition():this.getXAxisLabelPosition()},f.textForXAxisLabel=function(){return this.getAxisLabelText("x")},f.textForYAxisLabel=function(){return this.getAxisLabelText("y")},f.textForY2AxisLabel=function(){return this.getAxisLabelText("y2")},f.xForAxisLabel=function(a,b){var c=this;return a?b.isLeft?0:b.isCenter?c.width/2:c.width:b.isBottom?-c.height:b.isMiddle?-c.height/2:0},f.dxForAxisLabel=function(a,b){return a?b.isLeft?"0.5em":b.isRight?"-0.5em":"0":b.isTop?"-0.5em":b.isBottom?"0.5em":"0"},f.textAnchorForAxisLabel=function(a,b){return a?b.isLeft?"start":b.isCenter?"middle":"end":b.isBottom?"start":b.isMiddle?"middle":"end"},f.xForXAxisLabel=function(){return this.xForAxisLabel(!this.config.axis_rotated,this.getXAxisLabelPosition())},f.xForYAxisLabel=function(){return this.xForAxisLabel(this.config.axis_rotated,this.getYAxisLabelPosition())},f.xForY2AxisLabel=function(){return this.xForAxisLabel(this.config.axis_rotated,this.getY2AxisLabelPosition())},f.dxForXAxisLabel=function(){return this.dxForAxisLabel(!this.config.axis_rotated,this.getXAxisLabelPosition())},f.dxForYAxisLabel=function(){return this.dxForAxisLabel(this.config.axis_rotated,this.getYAxisLabelPosition())},f.dxForY2AxisLabel=function(){return this.dxForAxisLabel(this.config.axis_rotated,this.getY2AxisLabelPosition())},f.dyForXAxisLabel=function(){var a=this,b=a.config,c=a.getXAxisLabelPosition();return b.axis_rotated?c.isInner?"1.2em":-25-a.getMaxTickWidth("x"):c.isInner?"-0.5em":b.axis_x_height?b.axis_x_height-10:"3em"},f.dyForYAxisLabel=function(){var a=this,b=a.getYAxisLabelPosition();return a.config.axis_rotated?b.isInner?"-0.5em":"3em":b.isInner?"1.2em":-20-a.getMaxTickWidth("y")},f.dyForY2AxisLabel=function(){var a=this,b=a.getY2AxisLabelPosition();return a.config.axis_rotated?b.isInner?"1.2em":"-2.2em":b.isInner?"-0.5em":30+this.getMaxTickWidth("y2")},f.textAnchorForXAxisLabel=function(){var a=this;return a.textAnchorForAxisLabel(!a.config.axis_rotated,a.getXAxisLabelPosition())},f.textAnchorForYAxisLabel=function(){var a=this;return a.textAnchorForAxisLabel(a.config.axis_rotated,a.getYAxisLabelPosition())},f.textAnchorForY2AxisLabel=function(){var a=this;return a.textAnchorForAxisLabel(a.config.axis_rotated,a.getY2AxisLabelPosition())},f.xForRotatedTickText=function(a){return 10*Math.sin(Math.PI*(a/180))},f.yForRotatedTickText=function(a){return 11.5-2.5*(a/15)},f.rotateTickText=function(a,b,c){a.selectAll(".tick text").style("text-anchor","start"),b.selectAll(".tick text").attr("y",this.yForRotatedTickText(c)).attr("x",this.xForRotatedTickText(c)).attr("transform","rotate("+c+")")},f.getMaxTickWidth=function(a){var b,c,d,e=this,f=e.config,g=0;return e.svg&&(b=e.filterTargetsToShow(e.data.targets),"y"===a?(c=e.y.copy().domain(e.getYDomain(b,"y")),d=e.getYAxis(c,e.yOrient,f.axis_y_tick_format,f.axis_y_ticks)):"y2"===a?(c=e.y2.copy().domain(e.getYDomain(b,"y2")),d=e.getYAxis(c,e.y2Orient,f.axis_y2_tick_format,f.axis_y2_ticks)):(c=e.x.copy().domain(e.getXDomain(b)),d=e.getXAxis(c,e.xOrient,e.getXAxisTickFormat(),f.axis_x_tick_values?f.axis_x_tick_values:e.xAxis.tickValues())),e.main.append("g").call(d).each(function(){e.d3.select(this).selectAll("text").each(function(){var a=this.getBoundingClientRect();g=g?e.currentMaxTickWidth:g,e.currentMaxTickWidth},f.updateAxisLabels=function(a){var b=this,c=b.main.select("."+h.axisX+" ."+h.axisXLabel),d=b.main.select("."+h.axisY+" ."+h.axisYLabel),e=b.main.select("."+h.axisY2+" ."+h.axisY2Label);(a?c.transition():c).attr("x",b.xForXAxisLabel.bind(b)).attr("dx",b.dxForXAxisLabel.bind(b)).attr("dy",b.dyForXAxisLabel.bind(b)).text(b.textForXAxisLabel.bind(b)),(a?d.transition():d).attr("x",b.xForYAxisLabel.bind(b)).attr("dx",b.dxForYAxisLabel.bind(b)).attr("dy",b.dyForYAxisLabel.bind(b)).text(b.textForYAxisLabel.bind(b)),(a?e.transition():e).attr("x",b.xForY2AxisLabel.bind(b)).attr("dx",b.dxForY2AxisLabel.bind(b)).attr("dy",b.dyForY2AxisLabel.bind(b)).text(b.textForY2AxisLabel.bind(b))},f.getAxisPadding=function(a,b,c,d){var e="ratio"===a.unit?d:1;return i(a[b])?a[b]*e:c},f.generateTickValues=function(a,b){var c,d,e,f,g,h,i,k=this,l=a;if(b)if(c=j(b)?b():b,1===c)l=[a[0]];else if(2===c)l=[a[0],a[a.length-1]];else if(c>2){for(f=c-2,d=a[0],e=a[a.length-1],g=(e-d)/(f+1),l=[d],h=0;f>h;h++)i=+d+g*(h+1),l.push(k.isTimeSeries()?new Date(i):i);l.push(e)}return k.isTimeSeries()||(l=l.sort(function(a,b){return a-b})),l},f.generateAxisTransitions=function(a){var b=this,c=b.axes;return{axisX:a?c.x.transition().duration(a):c.x,axisY:a?c.y.transition().duration(a):c.y,axisY2:a?c.y2.transition().duration(a):c.y2,axisSubX:a?c.subx.transition().duration(a):c.subx}},f.redrawAxis=function(a,b){var c=this;c.axes.x.style("opacity",b?0:1),c.axes.y.style("opacity",b?0:1),c.axes.y2.style("opacity",b?0:1),c.axes.subx.style("opacity",b?0:1),a.axisX.call(c.xAxis),a.axisY.call(c.yAxis),a.axisY2.call(c.y2Axis),a.axisSubX.call(c.subXAxis)},f.getClipPath=function(b){var c=a.navigator.appVersion.toLowerCase().indexOf("msie 9.")>=0;return"url("+(c?"":document.URL.split("#")[0])+"#"+b+")"},f.getAxisClipX=function(a){return a?-31:-(this.margin.left-1)},f.getAxisClipY=function(a){return a?-20:-4},f.getXAxisClipX=function(){var a=this;return a.getAxisClipX(!a.config.axis_rotated)},f.getXAxisClipY=function(){var a=this;return a.getAxisClipY(!a.config.axis_rotated)},f.getYAxisClipX=function(){var a=this;return a.getAxisClipX(a.config.axis_rotated)},f.getYAxisClipY=function(){var a=this;return a.getAxisClipY(a.config.axis_rotated)},f.getAxisClipWidth=function(a){var b=this;return a?b.width+2+30+30:b.margin.left+20},f.getAxisClipHeight=function(a){var b=this,c=b.config;return a?(c.axis_x_height?c.axis_x_height:0)+80:b.height+8},f.getXAxisClipWidth=function(){var a=this;return a.getAxisClipWidth(!a.config.axis_rotated)},f.getXAxisClipHeight=function(){var a=this;return a.getAxisClipHeight(!a.config.axis_rotated)},f.getYAxisClipWidth=function(){var a=this;return a.getAxisClipWidth(a.config.axis_rotated)},f.getYAxisClipHeight=function(){var a=this;return a.getAxisClipHeight(a.config.axis_rotated)},f.initPie=function(){var a=this,b=a.d3,c=a.config;a.pie=b.layout.pie().value(function(a){return a.values.reduce(function(a,b){return a+b.value},0)}),c.data_order&&c.pie_sort&&c.donut_sort||a.pie.sort(null)},f.updateRadius=function(){var a=this,b=a.config,c=b.gauge_width||b.donut_width;a.radiusExpanded=Math.min(a.arcWidth,a.arcHeight)/2,a.radius=.95*a.radiusExpanded,a.innerRadiusRatio=c?(a.radius-c)/a.radius:.6,a.innerRadius=a.hasType("donut")||a.hasType("gauge")?a.radius*a.innerRadiusRatio:0},f.updateArc=function(){var a=this;a.svgArc=a.getSvgArc(),a.svgArcExpanded=a.getSvgArcExpanded(),a.svgArcExpandedSub=a.getSvgArcExpanded(.98)},f.updateAngle=function(a){var b=this,c=b.config,d=!1,e=0;if(b.pie(b.filterTargetsToShow(b.data.targets)).sort(b.descByStartAngle).forEach(function(b){d||b.data.id!==a.data.id||(d=!0,a=b,a.index=e),e++}),isNaN(a.endAngle)&&(a.endAngle=a.startAngle),b.isGaugeType(a.data)){var f=c.gauge_min,g=c.gauge_max,h=Math.abs(f)+g,i=Math.PI/h;a.startAngle=-1*(Math.PI/2)+i*Math.abs(f),a.endAngle=a.startAngle+i*(a.value>g?g:a.value)}return d?a:null},f.getSvgArc=function(){var a=this,b=a.d3.svg.arc().outerRadius(a.radius).innerRadius(a.innerRadius),c=function(c,d){var e;return d?b(c):(e=a.updateAngle(c),e?b(e):"M 0 0")};return c.centroid=b.centroid,c},f.getSvgArcExpanded=function(a){var b=this,c=b.d3.svg.arc().outerRadius(b.radiusExpanded*(a?a:1)).innerRadius(b.innerRadius);return function(a){var d=b.updateAngle(a);return d?c(d):"M 0 0"}},f.getArc=function(a,b,c){return c||this.isArcType(a.data)?this.svgArc(a,b):"M 0 0"},f.transformForArcLabel=function(a){var b,c,d,e,f,g=this,h=g.updateAngle(a),i="";return h&&!g.hasType("gauge")&&(b=this.svgArc.centroid(h),c=isNaN(b[0])?0:b[0],d=isNaN(b[1])?0:b[1],e=Math.sqrt(c*c+d*d),f=g.radius&&e?(36/g.radius>.375?1.175-36/g.radius:.8)*g.radius/e:0,i="translate("+c*f+","+d*f+")"),i},f.getArcRatio=function(a){var b=this,c=b.hasType("gauge")?Math.PI:2*Math.PI;return a?(a.endAngle-a.startAngle)/c:null},f.convertToArcData=function(a){return this.addName({id:a.data.id,value:a.value,ratio:this.getArcRatio(a),index:a.index})},f.textForArcLabel=function(a){var b,c,d,e,f=this;return f.shouldShowArcLabel()?(b=f.updateAngle(a),c=b?b.value:null,d=f.getArcRatio(b),f.hasType("gauge")||f.meetsArcLabelThreshold(d)?(e=f.getArcLabelFormat(),e?e(c,d):f.defaultArcValueFormat(c,d)):""):""},f.expandArc=function(a,b){var c=this,d=c.svg.selectAll("."+h.chartArc+c.selectorTarget(a)),e=c.svg.selectAll("."+h.arc).filter(function(b){return b.data.id!==a});c.shouldExpand(a)&&d.selectAll("path").transition().duration(50).attr("d",c.svgArcExpanded).transition().duration(100).attr("d",c.svgArcExpandedSub).each(function(a){c.isDonutType(a.data)}),b||e.style("opacity",.3)},f.unexpandArc=function(a){var b=this,c=b.svg.selectAll("."+h.chartArc+b.selectorTarget(a));c.selectAll("path."+h.arc).transition().duration(50).attr("d",b.svgArc),b.svg.selectAll("."+h.arc).style("opacity",1)},f.shouldExpand=function(a){var b=this,c=b.config;return b.isDonutType(a)&&c.donut_expand||b.isGaugeType(a)&&c.gauge_expand||b.isPieType(a)&&c.pie_expand},f.shouldShowArcLabel=function(){var a=this,b=a.config,c=!0;return a.hasType("donut")?c=b.donut_label_show:a.hasType("pie")&&(c=b.pie_label_show),c},f.meetsArcLabelThreshold=function(a){var b=this,c=b.config,d=b.hasType("donut")?c.donut_label_threshold:c.pie_label_threshold;return a>=d},f.getArcLabelFormat=function(){var a=this,b=a.config,c=b.pie_label_format;return a.hasType("gauge")?c=b.gauge_label_format:a.hasType("donut")&&(c=b.donut_label_format),c},f.getArcTitle=function(){var a=this;return a.hasType("donut")?a.config.donut_title:""},f.descByStartAngle=function(a,b){return a.startAngle-b.startAngle},f.updateTargetsForArc=function(a){var b,c,d=this,e=d.main,f=d.classChartArc.bind(d),g=d.classArcs.bind(d);b=e.select("."+h.chartArcs).selectAll("."+h.chartArc).data(d.pie(a)).attr("class",f),c=b.enter().append("g").attr("class",f),c.append("g").attr("class",g),c.append("text").attr("dy",d.hasType("gauge")?"-0.35em":".35em").style("opacity",0).style("text-anchor","middle").style("pointer-events","none")},f.initArc=function(){var a=this;a.arcs=a.main.select("."+h.chart).append("g").attr("class",h.chartArcs).attr("transform",a.getTranslate("arc")),a.arcs.append("text").attr("class",h.chartArcsTitle).style("text-anchor","middle").text(a.getArcTitle())},f.redrawArc=function(a,b,c){var d,e=this,f=e.d3,g=e.config,i=e.main;d=i.selectAll("."+h.arcs).selectAll("."+h.arc).data(e.arcData.bind(e)),d.enter().append("path").attr("class",e.classArc.bind(e)).style("fill",function(a){return e.color(a.data)}).style("cursor",function(a){return g.data_selection_isselectable(a)?"pointer":null}).style("opacity",0).each(function(a){e.isGaugeType(a.data)&&(a.startAngle=a.endAngle=-1*(Math.PI/2)),this._current=a}).on("mouseover",function(a){var b,c;e.transiting||(b=e.updateAngle(a),c=e.convertToArcData(b),e.expandArc(b.data.id),e.toggleFocusLegend(b.data.id,!0),e.config.data_onmouseover(c,this))}).on("mousemove",function(a){var b=e.updateAngle(a),c=e.convertToArcData(b),d=[c];e.showTooltip(d,f.mouse(this))}).on("mouseout",function(a){var b,c;e.transiting||(b=e.updateAngle(a),c=e.convertToArcData(b),e.unexpandArc(b.data.id),e.revertLegend(),e.hideTooltip(),e.config.data_onmouseout(c,this))}).on("click",function(a,b){var c,d;e.toggleShape&&(c=e.updateAngle(a),d=e.convertToArcData(c),e.toggleShape(this,d,b))}),d.attr("transform",function(a){return!e.isGaugeType(a.data)&&c?"scale(0)":""}).style("opacity",function(a){return a===this._current?0:1}).each(function(){e.transiting=!0}).transition().duration(a).attrTween("d",function(a){var b,c=e.updateAngle(a);return c?(isNaN(this._current.endAngle)&&(this._current.endAngle=this._current.startAngle),b=f.interpolate(this._current,c),this._current=b(0),function(a){return e.getArc(b(a),!0)}):function(){return"M 0 0"}}).attr("transform",c?"scale(1)":"").style("fill",function(a){return e.levelColor?e.levelColor(a.data.values[0].value):e.color(a.data.id)}).style("opacity",1).call(e.endall,function(){e.transiting=!1}),d.exit().transition().duration(b).style("opacity",0).remove(),i.selectAll("."+h.chartArc).select("text").style("opacity",0).attr("class",function(a){return e.isGaugeType(a.data)?h.gaugeValue:""}).text(e.textForArcLabel.bind(e)).attr("transform",e.transformForArcLabel.bind(e)).transition().duration(a).style("opacity",function(a){return e.isTargetToShow(a.data.id)&&e.isArcType(a.data)?1:0}),i.select("."+h.chartArcsTitle).style("opacity",e.hasType("donut")||e.hasType("gauge")?1:0)},f.initGauge=function(){var a=this,b=a.config,c=a.arcs;a.hasType("gauge")&&(c.append("path").attr("class",h.chartArcsBackground).attr("d",function(){var c={data:[{value:b.gauge_max}],startAngle:-1*(Math.PI/2),endAngle:Math.PI/2};return a.getArc(c,!0,!0)}),c.append("text").attr("dy",".75em").attr("class",h.chartArcsGaugeUnit).style("text-anchor","middle").style("pointer-events","none").text(b.gauge_label_show?b.gauge_units:""),c.append("text").attr("dx",-1*(a.innerRadius+(a.radius-a.innerRadius)/2)+"px").attr("dy","1.2em").attr("class",h.chartArcsGaugeMin).style("text-anchor","middle").style("pointer-events","none").text(b.gauge_label_show?b.gauge_min:""),c.append("text").attr("dx",a.innerRadius+(a.radius-a.innerRadius)/2+"px").attr("dy","1.2em").attr("class",h.chartArcsGaugeMax).style("text-anchor","middle").style("pointer-events","none").text(b.gauge_label_show?b.gauge_max:""))},f.initRegion=function(){var a=this;a.main.append("g").attr("clip-path",a.clipPath).attr("class",h.regions)},f.redrawRegion=function(a){var b=this,c=b.config;b.mainRegion=b.main.select("."+h.regions).selectAll("."+h.region).data(c.regions),b.mainRegion.enter().append("g").attr("class",b.classRegion.bind(b)).append("rect").style("fill-opacity",0),b.mainRegion.exit().transition().duration(a).style("opacity",0).remove()},f.addTransitionForRegion=function(a){var b=this,c=b.regionX.bind(b),d=b.regionY.bind(b),e=b.regionWidth.bind(b),f=b.regionHeight.bind(b);a.push(b.mainRegion.selectAll("rect").transition().attr("x",c).attr("y",d).attr("width",e).attr("height",f).style("fill-opacity",function(a){return i(a.opacity)?a.opacity:.1}))},f.regionX=function(a){var b,c=this,d=c.config,e="y"===a.axis?c.y:c.y2;return b="y"===a.axis||"y2"===a.axis?d.axis_rotated?"start"in a?e(a.start):0:0:d.axis_rotated?0:"start"in a?c.x(c.isTimeSeries()?c.parseDate(a.start):a.start):0},f.regionY=function(a){var b,c=this,d=c.config,e="y"===a.axis?c.y:c.y2;return b="y"===a.axis||"y2"===a.axis?d.axis_rotated?0:"end"in a?e(a.end):0:d.axis_rotated?"start"in a?c.x(c.isTimeSeries()?c.parseDate(a.start):a.start):0:0},f.regionWidth=function(a){var b,c=this,d=c.config,e=c.regionX(a),f="y"===a.axis?c.y:c.y2;return b="y"===a.axis||"y2"===a.axis?d.axis_rotated?"end"in a?f(a.end):c.width:c.width:d.axis_rotated?c.width:"end"in a?c.x(c.isTimeSeries()?c.parseDate(a.end):a.end):c.width,e>b?0:b-e},f.regionHeight=function(a){var b,c=this,d=c.config,e=this.regionY(a),f="y"===a.axis?c.y:c.y2;return b="y"===a.axis||"y2"===a.axis?d.axis_rotated?c.height:"start"in a?f(a.start):c.height:d.axis_rotated?"end"in a?c.x(c.isTimeSeries()?c.parseDate(a.end):a.end):c.height:c.height,e>b?0:b-e},f.isRegionOnX=function(a){return!a.axis||"x"===a.axis},f.drag=function(a){var b,c,d,e,f,g,i,j,k=this,l=k.config,m=k.main,n=k.d3;k.hasArcType()||l.data_selection_enabled&&(!l.zoom_enabled||k.zoom.altDomain)&&l.data_selection_multiple&&(b=k.dragStart[0],c=k.dragStart[1],d=a[0],e=a[1],f=Math.min(b,d),g=Math.max(b,d),i=l.data_selection_grouped?k.margin.top:Math.min(c,e),j=l.data_selection_grouped?k.height:Math.max(c,e),m.select("."+h.dragarea).attr("x",f).attr("y",i).attr("width",g-f).attr("height",j-i),m.selectAll("."+h.shapes).selectAll("."+h.shape).filter(function(a){return l.data_selection_isselectable(a)}).each(function(a,b){var c,d,e,l,m,o,p=n.select(this),q=p.classed(h.SELECTED),r=p.classed(h.INCLUDED),s=!1;if(p.classed(h.circle))c=1*p.attr("cx"),d=1*p.attr("cy"),m=k.togglePoint,s=c>f&&g>c&&d>i&&j>d;else{if(!p.classed(h.bar))return;o=u(this),c=o.x,d=o.y,e=o.width,l=o.height,m=k.toggleBar,s=!(c>g||f>c+e||d>j||i>d+l)}s^r&&(p.classed(h.INCLUDED,!r),p.classed(h.SELECTED,!q),m.call(k,!q,p,a,b))}))},f.dragstart=function(a){var b=this,c=b.config;b.hasArcType()||c.data_selection_enabled&&(b.dragStart=a,b.main.select("."+h.chart).append("rect").attr("class",h.dragarea).style("opacity",.1),b.dragging=!0,b.config.data_ondragstart())},f.dragend=function(){var a=this,b=a.config;a.hasArcType()||b.data_selection_enabled&&(a.main.select("."+h.dragarea).transition().duration(100).style("opacity",0).remove(),a.main.selectAll("."+h.shape).classed(h.INCLUDED,!1),a.dragging=!1,a.config.data_ondragend())},f.selectPoint=function(a,b,c){var d=this,e=d.config,f=(e.axis_rotated?d.circleY:d.circleX).bind(d),g=(e.axis_rotated?d.circleX:d.circleY).bind(d),i=d.pointSelectR.bind(d);e.data_onselected.call(d.api,b,a.node()),d.main.select("."+h.selectedCircles+d.getTargetSelectorSuffix(b.id)).selectAll("."+h.selectedCircle+"-"+c).data([b]).enter().append("circle").attr("class",function(){return d.generateClass(h.selectedCircle,c)}).attr("cx",f).attr("cy",g).attr("stroke",function(){return d.color(b)}).attr("r",function(a){return 1.4*d.pointSelectR(a)}).transition().duration(100).attr("r",i)},f.unselectPoint=function(a,b,c){var d=this;d.config.data_onunselected(b,a.node()),d.main.select("."+h.selectedCircles+d.getTargetSelectorSuffix(b.id)).selectAll("."+h.selectedCircle+"-"+c).transition().duration(100).attr("r",0).remove()},f.togglePoint=function(a,b,c,d){a?this.selectPoint(b,c,d):this.unselectPoint(b,c,d)},f.selectBar=function(a,b){var c=this;c.config.data_onselected.call(c,b,a.node()),a.transition().duration(100).style("fill",function(){return c.d3.rgb(c.color(b)).brighter(.75)})},f.unselectBar=function(a,b){var c=this;c.config.data_onunselected.call(c,b,a.node()),a.transition().duration(100).style("fill",function(){return c.color(b)})},f.toggleBar=function(a,b,c,d){a?this.selectBar(b,c,d):this.unselectBar(b,c,d)},f.toggleArc=function(a,b,c,d){this.toggleBar(a,b,c.data,d)},f.getToggle=function(a){var b=this;return"circle"===a.nodeName?b.togglePoint:b.d3.select(a).classed(h.bar)?b.toggleBar:b.toggleArc},f.toggleShape=function(a,b,c){var d,e,f=this,g=f.d3,i=f.config,j=g.select(a),k=j.classed(h.SELECTED);"circle"===a.nodeName?(d=f.isWithinCircle(a,1.5*f.pointSelectR(b)),e=f.togglePoint):"path"===a.nodeName&&(j.classed(h.bar)?(d=f.isWithinBar(a),e=f.toggleBar):(d=!0,e=f.toggleArc)),(i.data_selection_grouped||d)&&(i.data_selection_enabled&&i.data_selection_isselectable(b)&&(i.data_selection_multiple||f.main.selectAll("."+h.shapes+(i.data_selection_grouped?f.getTargetSelectorSuffix(b.id):"")).selectAll("."+h.shape).each(function(a,b){var c=g.select(this);c.classed(h.SELECTED)&&e.call(f,!1,c.classed(h.SELECTED,!1),a,b)}),j.classed(h.SELECTED,!k),e.call(f,!k,j,b,c)),f.config.data_onclick.call(f.api,b,a))},f.initBrush=function(){var a=this,b=a.d3;a.brush=b.svg.brush().on("brush",function(){a.redrawForBrush()}),a.brush.update=function(){return a.context&&a.context.select("."+h.brush).call(this),this +},a.brush.scale=function(b){return a.config.axis_rotated?this.y(b):this.x(b)}},f.initSubchart=function(){var a=this,b=a.config,c=a.context=a.svg.append("g").attr("transform",a.getTranslate("context"));b.subchart_show||c.style("visibility","hidden"),c.append("g").attr("clip-path",a.clipPath).attr("class",h.chart),c.select("."+h.chart).append("g").attr("class",h.chartBars),c.select("."+h.chart).append("g").attr("class",h.chartLines),c.append("g").attr("clip-path",a.clipPath).attr("class",h.brush).call(a.brush).selectAll("rect").attr(b.axis_rotated?"width":"height",b.axis_rotated?a.width2:a.height2),a.axes.subx=c.append("g").attr("class",h.axisX).attr("transform",a.getTranslate("subx")).attr("clip-path",b.axis_rotated?"":a.clipPathForXAxis)},f.updateTargetsForSubchart=function(a){var b,c,d,e,f=this,g=f.context,i=f.config,j=f.classChartBar.bind(f),k=f.classBars.bind(f),l=f.classChartLine.bind(f),m=f.classLines.bind(f),n=f.classAreas.bind(f);i.subchart_show&&(e=g.select("."+h.chartBars).selectAll("."+h.chartBar).data(a).attr("class",j),d=e.enter().append("g").style("opacity",0).attr("class",j),d.append("g").attr("class",k),c=g.select("."+h.chartLines).selectAll("."+h.chartLine).data(a).attr("class",l),b=c.enter().append("g").style("opacity",0).attr("class",l),b.append("g").attr("class",m),b.append("g").attr("class",n))},f.redrawSubchart=function(a,b,c,d,e,f,g){var i,j,k,l,m,n,o=this,p=o.d3,q=o.context,r=o.config,s=o.barData.bind(o),t=o.lineData.bind(o),u=o.classBar.bind(o),v=o.classLine.bind(o),w=o.classArea.bind(o),x=o.initialOpacity.bind(o);r.subchart_show&&(p.event&&"zoom"===p.event.type&&o.brush.extent(o.x.orgDomain()).update(),a&&(!r.axis_rotated&&r.axis_x_tick_rotate&&o.rotateTickText(o.axes.subx,b.axisSubX,r.axis_x_tick_rotate),o.brush.empty()||o.brush.extent(o.x.orgDomain()).update(),l=o.generateDrawArea(e,!0),m=o.generateDrawBar(f,!0),n=o.generateDrawLine(g,!0),k=q.selectAll("."+h.bars).selectAll("."+h.bar).data(s),k.enter().append("path").attr("class",u).style("stroke","none").style("fill",o.color),k.style("opacity",x).transition().duration(c).attr("d",m).style("opacity",1),k.exit().transition().duration(c).style("opacity",0).remove(),i=q.selectAll("."+h.lines).selectAll("."+h.line).data(t),i.enter().append("path").attr("class",v).style("stroke",o.color),i.style("opacity",x).transition().duration(c).attr("d",n).style("opacity",1),i.exit().transition().duration(c).style("opacity",0).remove(),j=q.selectAll("."+h.areas).selectAll("."+h.area).data(t),j.enter().append("path").attr("class",w).style("fill",o.color).style("opacity",function(){return o.orgAreaOpacity=+p.select(this).style("opacity"),0}),j.style("opacity",0).transition().duration(c).attr("d",l).style("fill",o.color).style("opacity",o.orgAreaOpacity),j.exit().transition().duration(d).style("opacity",0).remove()))},f.redrawForBrush=function(){var a=this,b=a.x;a.redraw({withTransition:!1,withY:!1,withSubchart:!1,withUpdateXDomain:!0}),a.config.subchart_onbrush.call(a.api,b.orgDomain())},f.transformContext=function(a,b){var c,d=this;b&&b.axisSubX?c=b.axisSubX:(c=d.context.select("."+h.axisX),a&&(c=c.transition())),d.context.attr("transform",d.getTranslate("context")),c.attr("transform",d.getTranslate("subx"))},f.initZoom=function(){var a=this,b=a.d3,c=a.config;a.zoom=b.behavior.zoom().on("zoomstart",function(){a.zoom.altDomain=b.event.sourceEvent.altKey?a.x.orgDomain():null}).on("zoom",function(){a.redrawForZoom.call(a)}),a.zoom.scale=function(a){return c.axis_rotated?this.y(a):this.x(a)},a.zoom.orgScaleExtent=function(){var b=c.zoom_extent?c.zoom_extent:[1,10];return[b[0],Math.max(a.getMaxDataCount()/b[1],b[1])]},a.zoom.updateScaleExtent=function(){var b=p(a.x.orgDomain())/p(a.orgXDomain),c=this.orgScaleExtent();return this.scaleExtent([c[0]*b,c[1]*b]),this}},f.updateZoom=function(){var a=this,b=a.config.zoom_enabled?a.zoom:function(){};a.main.select("."+h.zoomRect).call(b),a.main.selectAll("."+h.eventRect).call(b)},f.redrawForZoom=function(){var a=this,b=a.d3,c=a.config,d=a.zoom,e=a.x,f=a.orgXDomain;if(c.zoom_enabled&&0!==a.filterTargetsToShow(a.data.targets).length){if("mousemove"===b.event.sourceEvent.type&&d.altDomain)return e.domain(d.altDomain),void d.scale(e).updateScaleExtent();a.isCategorized()&&e.orgDomain()[0]===f[0]&&e.domain([f[0]-1e-10,e.orgDomain()[1]]),a.redraw({withTransition:!1,withY:!1,withSubchart:!1}),"mousemove"===b.event.sourceEvent.type&&(a.cancelClick=!0),c.zoom_onzoom.call(a.api,e.orgDomain())}},f.generateColor=function(){var a=this,b=a.config,c=a.d3,d=b.data_colors,e=r(b.color_pattern)?b.color_pattern:c.scale.category10().range(),f=b.data_color,g=[];return function(a){var b,c=a.id||a;return d[c]instanceof Function?b=d[c](a):d[c]?b=d[c]:(g.indexOf(c)<0&&g.push(c),b=e[g.indexOf(c)%e.length],d[c]=b),f instanceof Function?f(b,a):b}},f.generateLevelColor=function(){var a=this,b=a.config,c=b.color_pattern,d=b.color_threshold,e="value"===d.unit,f=d.values&&d.values.length?d.values:[],g=d.max||100;return r(b.color_threshold)?function(a){var b,d,h=c[c.length-1];for(b=0;b0},s=f.getOption=function(a,b,c){return m(a[b])?a[b]:c},t=f.hasValue=function(a,b){var c=!1;return Object.keys(a).forEach(function(d){a[d]===b&&(c=!0)}),c},u=f.getPathBox=function(a){var b=a.getBoundingClientRect(),c=[a.pathSegList.getItem(0),a.pathSegList.getItem(1)],d=c[0].x,e=Math.min(c[0].y,c[1].y);return{x:d,y:e,width:b.width,height:b.height}};e.focus=function(a){function b(a){c.filterTargetsToShow(a).transition().duration(100).style("opacity",1)}var c=this.internal,d=c.svg.selectAll(c.selectorTarget(a)),e=d.filter(c.isNoneArc.bind(c)),f=d.filter(c.isArc.bind(c));this.revert(),this.defocus(),b(e.classed(h.focused,!0)),b(f),c.hasArcType()&&c.expandArc(a,!0),c.toggleFocusLegend(a,!0)},e.defocus=function(a){function b(a){c.filterTargetsToShow(a).transition().duration(100).style("opacity",.3)}var c=this.internal,d=c.svg.selectAll(c.selectorTarget(a)),e=d.filter(c.isNoneArc.bind(c)),f=d.filter(c.isArc.bind(c));this.revert(),b(e.classed(h.focused,!1)),b(f),c.hasArcType()&&c.unexpandArc(a),c.toggleFocusLegend(a,!1)},e.revert=function(a){function b(a){c.filterTargetsToShow(a).transition().duration(100).style("opacity",1)}var c=this.internal,d=c.svg.selectAll(c.selectorTarget(a)),e=d.filter(c.isNoneArc.bind(c)),f=d.filter(c.isArc.bind(c));b(e.classed(h.focused,!1)),b(f),c.hasArcType()&&c.unexpandArc(a),c.revertLegend()},e.show=function(a,b){var c=this.internal;a=c.mapToTargetIds(a),b=b||{},c.removeHiddenTargetIds(a),c.svg.selectAll(c.selectorTargets(a)).transition().style("opacity",1),b.withLegend&&c.showLegend(a),c.redraw({withUpdateOrgXDomain:!0,withUpdateXDomain:!0,withLegend:!0})},e.hide=function(a,b){var c=this.internal;a=c.mapToTargetIds(a),b=b||{},c.addHiddenTargetIds(a),c.svg.selectAll(c.selectorTargets(a)).transition().style("opacity",0),b.withLegend&&c.hideLegend(a),c.redraw({withUpdateOrgXDomain:!0,withUpdateXDomain:!0,withLegend:!0})},e.toggle=function(a){var b=this.internal;b.isTargetToShow(a)?this.hide(a):this.show(a)},e.zoom=function(){},e.zoom.enable=function(a){var b=this.internal;b.config.zoom_enabled=a,b.updateAndRedraw()},e.unzoom=function(){var a=this.internal;a.brush.clear().update(),a.redraw({withUpdateXDomain:!0})},e.load=function(a){var b=this.internal,c=b.config;return a.xs&&b.addXs(a.xs),"classes"in a&&Object.keys(a.classes).forEach(function(b){c.data_classes[b]=a.classes[b]}),"categories"in a&&b.isCategorized()&&(c.axis_x_categories=a.categories),"cacheIds"in a&&b.hasCaches(a.cacheIds)?void b.load(b.getCaches(a.cacheIds),a.done):void("unload"in a?b.unload(b.mapToTargetIds("boolean"==typeof a.unload&&a.unload?null:a.unload),function(){b.loadFromArgs(a)}):b.loadFromArgs(a))},e.unload=function(a){var b=this.internal;a=a||{},b.unload(b.mapToTargetIds(a.ids),function(){b.redraw({withUpdateOrgXDomain:!0,withUpdateXDomain:!0,withLegend:!0}),a.done&&a.done()})},e.flow=function(a){var b,c,d,e,f,g,h,j,k=this.internal,l=[],n=k.getMaxDataCount(),o=0,p=0;if(a.json)c=k.convertJsonToData(a.json,a.keys);else if(a.rows)c=k.convertRowsToData(a.rows);else{if(!a.columns)return;c=k.convertColumnsToData(a.columns)}b=k.convertDataToTargets(c,!0),k.data.targets.forEach(function(a){var c,d,e=!1;for(c=0;cd;d++)b[c].values[d].index=p+d,k.isTimeSeries()||(b[c].values[d].x=p+d);a.values=a.values.concat(b[c].values),b.splice(c,1);break}e||l.push(a.id)}),k.data.targets.forEach(function(a){var b,c;for(b=0;bc;c++)a.values.push({id:a.id,index:p+c,x:k.isTimeSeries()?k.getOtherTargetX(p+c):p+c,value:null})}),k.data.targets.length&&b.forEach(function(a){var b,c=[];for(b=k.data.targets[0].values[0].index;p>b;b++)c.push({id:a.id,index:b,x:k.isTimeSeries()?k.getOtherTargetX(b):b,value:null});a.values.forEach(function(a){a.index+=p,k.isTimeSeries()||(a.x+=p)}),a.values=c.concat(a.values)}),k.data.targets=k.data.targets.concat(b),d=k.getMaxDataCount(),f=k.data.targets[0],g=f.values[0],m(a.to)?(o=0,j=k.isTimeSeries()?k.parseDate(a.to):a.to,f.values.forEach(function(a){a.x1?f.values[f.values.length-1].x-g.x:g.x-k.getXDomain(k.data.targets)[0]:1,e=[g.x-h,g.x],k.updateXDomain(null,!0,!0,e)),k.updateTargets(k.data.targets),k.redraw({flow:{index:g.index,length:o,duration:i(a.duration)?a.duration:k.config.transition_duration,done:a.done,orgDataCount:n},withLegend:!0,withTransition:n>1})},f.generateFlow=function(a){var b=this,c=b.config,d=b.d3;return function(){var e,f,g,i=a.targets,j=a.flow,k=a.drawBar,l=a.drawLine,m=a.drawArea,n=a.cx,o=a.cy,q=a.xv,r=a.xForText,s=a.yForText,t=a.duration,u=1,v=j.index,w=j.length,x=b.getValueOnIndex(b.data.targets[0].values,v),y=b.getValueOnIndex(b.data.targets[0].values,v+w),z=b.x.domain(),A=j.duration||t,B=j.done||function(){},C=b.generateWait(),D=b.xgrid||d.selectAll([]),E=b.xgridLines||d.selectAll([]),F=b.mainRegion||d.selectAll([]),G=b.mainText||d.selectAll([]),H=b.mainBar||d.selectAll([]),I=b.mainLine||d.selectAll([]),J=b.mainArea||d.selectAll([]),K=b.mainCircle||d.selectAll([]);b.data.targets.forEach(function(a){a.values.splice(0,w)}),g=b.updateXDomain(i,!0,!0),b.updateXGrid&&b.updateXGrid(!0),j.orgDataCount?e=1===j.orgDataCount||x.x===y.x?b.x(z[0])-b.x(g[0]):b.isTimeSeries()?b.x(z[0])-b.x(g[0]):b.x(x.x)-b.x(y.x):1!==b.data.targets[0].values.length?e=b.x(z[0])-b.x(g[0]):b.isTimeSeries()?(x=b.getValueOnIndex(b.data.targets[0].values,0),y=b.getValueOnIndex(b.data.targets[0].values,b.data.targets[0].values.length-1),e=b.x(x.x)-b.x(y.x)):e=p(g)/2,u=p(z)/p(g),f="translate("+e+",0) scale("+u+",1)",d.transition().ease("linear").duration(A).each(function(){C.add(b.axes.x.transition().call(b.xAxis)),C.add(H.transition().attr("transform",f)),C.add(I.transition().attr("transform",f)),C.add(J.transition().attr("transform",f)),C.add(K.transition().attr("transform",f)),C.add(G.transition().attr("transform",f)),C.add(F.filter(b.isRegionOnX).transition().attr("transform",f)),C.add(D.transition().attr("transform",f)),C.add(E.transition().attr("transform",f))}).call(C,function(){var a,d=[],e=[],f=[];if(w){for(a=0;w>a;a++)d.push("."+h.shape+"-"+(v+a)),e.push("."+h.text+"-"+(v+a)),f.push("."+h.eventRect+"-"+(v+a));b.svg.selectAll("."+h.shapes).selectAll(d).remove(),b.svg.selectAll("."+h.texts).selectAll(e).remove(),b.svg.selectAll("."+h.eventRects).selectAll(f).remove(),b.svg.select("."+h.xgrid).remove()}D.attr("transform",null).attr(b.xgridAttr),E.attr("transform",null),E.select("line").attr("x1",c.axis_rotated?0:q).attr("x2",c.axis_rotated?b.width:q),E.select("text").attr("x",c.axis_rotated?b.width:0).attr("y",q),H.attr("transform",null).attr("d",k),I.attr("transform",null).attr("d",l),J.attr("transform",null).attr("d",m),K.attr("transform",null).attr("cx",n).attr("cy",o),G.attr("transform",null).attr("x",r).attr("y",s).style("fill-opacity",b.opacityForText.bind(b)),F.attr("transform",null),F.select("rect").filter(b.isRegionOnX).attr("x",b.regionX.bind(b)).attr("width",b.regionWidth.bind(b)),b.updateEventRect(),B()})}},e.selected=function(a){var b=this.internal,c=b.d3;return c.merge(b.main.selectAll("."+h.shapes+b.getTargetSelectorSuffix(a)).selectAll("."+h.shape).filter(function(){return c.select(this).classed(h.SELECTED)}).map(function(a){return a.map(function(a){var b=a.__data__;return b.data?b.data:b})}))},e.select=function(a,b,c){var d=this.internal,e=d.d3,f=d.config;f.data_selection_enabled&&d.main.selectAll("."+h.shapes).selectAll("."+h.shape).each(function(g,i){var j=e.select(this),k=g.data?g.data.id:g.id,l=d.getToggle(this).bind(d),n=f.data_selection_grouped||!a||a.indexOf(k)>=0,o=!b||b.indexOf(i)>=0,p=j.classed(h.SELECTED);j.classed(h.line)||j.classed(h.area)||(n&&o?f.data_selection_isselectable(g)&&!p&&l(!0,j.classed(h.SELECTED,!0),g,i):m(c)&&c&&p&&l(!1,j.classed(h.SELECTED,!1),g,i))})},e.unselect=function(a,b){var c=this.internal,d=c.d3,e=c.config;e.data_selection_enabled&&c.main.selectAll("."+h.shapes).selectAll("."+h.shape).each(function(f,g){var i=d.select(this),j=f.data?f.data.id:f.id,k=c.getToggle(this).bind(c),l=e.data_selection_grouped||!a||a.indexOf(j)>=0,m=!b||b.indexOf(g)>=0,n=i.classed(h.SELECTED);i.classed(h.line)||i.classed(h.area)||l&&m&&e.data_selection_isselectable(f)&&n&&k(!1,i.classed(h.SELECTED,!1),f,g)})},e.transform=function(a,b){var c=this.internal,d=["pie","donut"].indexOf(a)>=0?{withTransform:!0}:null;c.transformTo(b,a,d)},f.transformTo=function(a,b,c){var d=this,e=!d.hasArcType(),f=c||{withTransitionForAxis:e};f.withTransitionForTransform=!1,d.transiting=!1,d.setTargetType(a,b),d.updateAndRedraw(f)},e.groups=function(a){var b=this.internal,c=b.config;return l(a)?c.data_groups:(c.data_groups=a,b.redraw(),c.data_groups)},e.xgrids=function(a){var b=this.internal,c=b.config;return a?(c.grid_x_lines=a,b.redraw(),c.grid_x_lines):c.grid_x_lines},e.xgrids.add=function(a){var b=this.internal;return this.xgrids(b.config.grid_x_lines.concat(a?a:[]))},e.xgrids.remove=function(a){var b=this.internal;b.removeGridLines(a,!0)},e.ygrids=function(a){var b=this.internal,c=b.config;return a?(c.grid_y_lines=a,b.redraw(),c.grid_y_lines):c.grid_y_lines},e.ygrids.add=function(a){var b=this.internal;return this.ygrids(b.config.grid_y_lines.concat(a?a:[]))},e.ygrids.remove=function(a){var b=this.internal;b.removeGridLines(a,!1)},e.regions=function(a){var b=this.internal,c=b.config;return a?(c.regions=a,b.redraw(),c.regions):c.regions},e.regions.add=function(a){var b=this.internal,c=b.config;return a?(c.regions=c.regions.concat(a),b.redraw(),c.regions):c.regions},e.regions.remove=function(a){var b,c,d,e=this.internal,f=e.config;return a=a||{},b=e.getOption(a,"duration",f.transition_duration),c=e.getOption(a,"classes",[h.region]),d=e.main.select("."+h.regions).selectAll(c.map(function(a){return"."+a})),(b?d.transition().duration(b):d).style("opacity",0).remove(),f.regions=f.regions.filter(function(a){var b=!1;return a.class?(a.class.split(" ").forEach(function(a){c.indexOf(a)>=0&&(b=!0)}),!b):!0}),f.regions},e.data=function(){},e.data.get=function(a){var b=this.data.getAsTarget(a);return m(b)?b.values.map(function(a){return a.value}):void 0},e.data.getAsTarget=function(a){var b=this.data.targets.filter(function(b){return b.id===a});return b.length>0?b[0]:void 0},e.data.names=function(a){var b=this.internal,c=b.config;return arguments.length?(Object.keys(a).forEach(function(b){c.data_names[b]=a[b]}),b.redraw({withLegend:!0}),c.data_names):c.data_names},e.data.colors=function(a){var b=this.internal,c=b.config;return arguments.length?(Object.keys(a).forEach(function(b){c.data_colors[b]=a[b]}),b.redraw({withLegend:!0}),c.data_colors):c.data_colors},e.category=function(a,b){var c=this.internal,d=c.config;return arguments.length>1&&(d.axis_x_categories[a]=b,c.redraw()),d.axis_x_categories[a]},e.categories=function(a){var b=this.internal,c=b.config;return arguments.length?(c.axis_x_categories=a,b.redraw(),c.axis_x_categories):c.axis_x_categories},e.color=function(a){var b=this.internal;return b.color(a)},e.x=function(a){var b=this.internal;return arguments.length&&(b.updateTargetX(b.data.targets,a),b.redraw({withUpdateOrgXDomain:!0,withUpdateXDomain:!0})),b.data.xs},e.xs=function(a){var b=this.internal;return arguments.length&&(b.updateTargetXs(b.data.targets,a),b.redraw({withUpdateOrgXDomain:!0,withUpdateXDomain:!0})),b.data.xs},e.axis=function(){},e.axis.labels=function(a){var b=this.internal;arguments.length&&(Object.keys(a).forEach(function(c){b.setAxisLabelText(c,a[c])}),b.updateAxisLabels())},e.axis.max=function(a){var b=this.internal,c=b.config;arguments.length&&("object"==typeof a?(i(a.x)&&(c.axis_x_max=a.x),i(a.y)&&(c.axis_y_max=a.y),i(a.y2)&&(c.axis_y2_max=a.y2)):c.axis_y_max=c.axis_y2_max=a,b.redraw({withUpdateOrgXDomain:!0,withUpdateXDomain:!0}))},e.axis.min=function(a){var b=this.internal,c=b.config;arguments.length&&("object"==typeof a?(i(a.x)&&(c.axis_x_min=a.x),i(a.y)&&(c.axis_y_min=a.y),i(a.y2)&&(c.axis_y2_min=a.y2)):c.axis_y_min=c.axis_y2_min=a,b.redraw({withUpdateOrgXDomain:!0,withUpdateXDomain:!0}))},e.axis.range=function(a){arguments.length&&(m(a.max)&&this.axis.max(a.max),m(a.min)&&this.axis.min(a.min))},e.legend=function(){},e.legend.show=function(a){var b=this.internal;b.showLegend(b.mapToTargetIds(a)),b.updateAndRedraw({withLegend:!0})},e.legend.hide=function(a){var b=this.internal;b.hideLegend(b.mapToTargetIds(a)),b.updateAndRedraw({withLegend:!0})},e.resize=function(a){var b=this.internal,c=b.config;c.size_width=a?a.width:null,c.size_height=a?a.height:null,this.flush()},e.flush=function(){var a=this.internal;a.updateAndRedraw({withLegend:!0,withTransition:!1,withTransitionForTransform:!1})},e.destroy=function(){var b=this.internal;b.data.targets=void 0,b.data.xs={},b.selectChart.classed("c3",!1).html(""),a.onresize=null},"function"==typeof define&&define.amd?define("c3",["d3"],g):"undefined"!=typeof exports&&"undefined"!=typeof module?module.exports=g:a.c3=g}(window); \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/d3/d3.min.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/d3/d3.min.js new file mode 100644 index 00000000000..88550ae5124 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/d3/d3.min.js @@ -0,0 +1,5 @@ +!function(){function n(n,t){return t>n?-1:n>t?1:n>=t?0:0/0}function t(n){return null!=n&&!isNaN(n)}function e(n){return{left:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)<0?r=i+1:u=i}return r},right:function(t,e,r,u){for(arguments.length<3&&(r=0),arguments.length<4&&(u=t.length);u>r;){var i=r+u>>>1;n(t[i],e)>0?u=i:r=i+1}return r}}}function r(n){return n.length}function u(n){for(var t=1;n*t%1;)t*=10;return t}function i(n,t){try{for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}catch(r){n.prototype=t}}function o(){}function a(n){return ia+n in this}function c(n){return n=ia+n,n in this&&delete this[n]}function s(){var n=[];return this.forEach(function(t){n.push(t)}),n}function l(){var n=0;for(var t in this)t.charCodeAt(0)===oa&&++n;return n}function f(){for(var n in this)if(n.charCodeAt(0)===oa)return!1;return!0}function h(){}function g(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function p(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.substring(1);for(var e=0,r=aa.length;r>e;++e){var u=aa[e]+t;if(u in n)return u}}function v(){}function d(){}function m(n){function t(){for(var t,r=e,u=-1,i=r.length;++ue;e++)for(var u,i=n[e],o=0,a=i.length;a>o;o++)(u=i[o])&&t(u,o,e);return n}function U(n){return sa(n,da),n}function j(n){var t,e;return function(r,u,i){var o,a=n[i].update,c=a.length;for(i!=e&&(e=i,t=0),u>=t&&(t=u+1);!(o=a[t])&&++t0&&(n=n.substring(0,a));var s=ya.get(n);return s&&(n=s,c=Y),a?t?u:r:t?v:i}function O(n,t){return function(e){var r=Zo.event;Zo.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{Zo.event=r}}}function Y(n,t){var e=O(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function I(){var n=".dragsuppress-"+ ++Ma,t="click"+n,e=Zo.select(Wo).on("touchmove"+n,y).on("dragstart"+n,y).on("selectstart"+n,y);if(xa){var r=Bo.style,u=r[xa];r[xa]="none"}return function(i){function o(){e.on(t,null)}e.on(n,null),xa&&(r[xa]=u),i&&(e.on(t,function(){y(),o()},!0),setTimeout(o,0))}}function Z(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>_a&&(Wo.scrollX||Wo.scrollY)){e=Zo.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();_a=!(u.f||u.e),e.remove()}return _a?(r.x=t.pageX,r.y=t.pageY):(r.x=t.clientX,r.y=t.clientY),r=r.matrixTransform(n.getScreenCTM().inverse()),[r.x,r.y]}var i=n.getBoundingClientRect();return[t.clientX-i.left-n.clientLeft,t.clientY-i.top-n.clientTop]}function V(){return Zo.event.changedTouches[0].identifier}function X(){return Zo.event.target}function $(){return Wo}function B(n){return n>0?1:0>n?-1:0}function W(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function J(n){return n>1?0:-1>n?ba:Math.acos(n)}function G(n){return n>1?Sa:-1>n?-Sa:Math.asin(n)}function K(n){return((n=Math.exp(n))-1/n)/2}function Q(n){return((n=Math.exp(n))+1/n)/2}function nt(n){return((n=Math.exp(2*n))-1)/(n+1)}function tt(n){return(n=Math.sin(n/2))*n}function et(){}function rt(n,t,e){return this instanceof rt?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof rt?new rt(n.h,n.s,n.l):mt(""+n,yt,rt):new rt(n,t,e)}function ut(n,t,e){function r(n){return n>360?n-=360:0>n&&(n+=360),60>n?i+(o-i)*n/60:180>n?o:240>n?i+(o-i)*(240-n)/60:i}function u(n){return Math.round(255*r(n))}var i,o;return n=isNaN(n)?0:(n%=360)<0?n+360:n,t=isNaN(t)?0:0>t?0:t>1?1:t,e=0>e?0:e>1?1:e,o=.5>=e?e*(1+t):e+t-e*t,i=2*e-o,new gt(u(n+120),u(n),u(n-120))}function it(n,t,e){return this instanceof it?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof it?new it(n.h,n.c,n.l):n instanceof at?st(n.l,n.a,n.b):st((n=xt((n=Zo.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new it(n,t,e)}function ot(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new at(e,Math.cos(n*=Aa)*t,Math.sin(n)*t)}function at(n,t,e){return this instanceof at?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof at?new at(n.l,n.a,n.b):n instanceof it?ot(n.l,n.c,n.h):xt((n=gt(n)).r,n.g,n.b):new at(n,t,e)}function ct(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=lt(u)*ja,r=lt(r)*Ha,i=lt(i)*Fa,new gt(ht(3.2404542*u-1.5371385*r-.4985314*i),ht(-.969266*u+1.8760108*r+.041556*i),ht(.0556434*u-.2040259*r+1.0572252*i))}function st(n,t,e){return n>0?new it(Math.atan2(e,t)*Ca,Math.sqrt(t*t+e*e),n):new it(0/0,0/0,n)}function lt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function ft(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function ht(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function gt(n,t,e){return this instanceof gt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof gt?new gt(n.r,n.g,n.b):mt(""+n,gt,ut):new gt(n,t,e)}function pt(n){return new gt(n>>16,255&n>>8,255&n)}function vt(n){return pt(n)+""}function dt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function mt(n,t,e){var r,u,i,o=0,a=0,c=0;if(r=/([a-z]+)\((.*)\)/i.exec(n))switch(u=r[2].split(","),r[1]){case"hsl":return e(parseFloat(u[0]),parseFloat(u[1])/100,parseFloat(u[2])/100);case"rgb":return t(_t(u[0]),_t(u[1]),_t(u[2]))}return(i=Ia.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.substring(1),16))||(4===n.length?(o=(3840&i)>>4,o=o>>4|o,a=240&i,a=a>>4|a,c=15&i,c=c<<4|c):7===n.length&&(o=(16711680&i)>>16,a=(65280&i)>>8,c=255&i)),t(o,a,c))}function yt(n,t,e){var r,u,i=Math.min(n/=255,t/=255,e/=255),o=Math.max(n,t,e),a=o-i,c=(o+i)/2;return a?(u=.5>c?a/(o+i):a/(2-o-i),r=n==o?(t-e)/a+(e>t?6:0):t==o?(e-n)/a+2:(n-t)/a+4,r*=60):(r=0/0,u=c>0&&1>c?0:r),new rt(r,u,c)}function xt(n,t,e){n=Mt(n),t=Mt(t),e=Mt(e);var r=ft((.4124564*n+.3575761*t+.1804375*e)/ja),u=ft((.2126729*n+.7151522*t+.072175*e)/Ha),i=ft((.0193339*n+.119192*t+.9503041*e)/Fa);return at(116*u-16,500*(r-u),200*(u-i))}function Mt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function _t(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function bt(n){return"function"==typeof n?n:function(){return n}}function wt(n){return n}function St(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),kt(t,e,n,r)}}function kt(n,t,e,r){function u(){var n,t=c.status;if(!t&&c.responseText||t>=200&&300>t||304===t){try{n=e.call(i,c)}catch(r){return o.error.call(i,r),void 0}o.load.call(i,n)}else o.error.call(i,c)}var i={},o=Zo.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,s=null;return!Wo.XDomainRequest||"withCredentials"in c||!/^(http(s)?:)?\/\//.test(n)||(c=new XDomainRequest),"onload"in c?c.onload=c.onerror=u:c.onreadystatechange=function(){c.readyState>3&&u()},c.onprogress=function(n){var t=Zo.event;Zo.event=n;try{o.progress.call(i,c)}finally{Zo.event=t}},i.header=function(n,t){return n=(n+"").toLowerCase(),arguments.length<2?a[n]:(null==t?delete a[n]:a[n]=t+"",i)},i.mimeType=function(n){return arguments.length?(t=null==n?null:n+"",i):t},i.responseType=function(n){return arguments.length?(s=n,i):s},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(Xo(arguments)))}}),i.send=function(e,r,u){if(2===arguments.length&&"function"==typeof r&&(u=r,r=null),c.open(e,n,!0),null==t||"accept"in a||(a.accept=t+",*/*"),c.setRequestHeader)for(var l in a)c.setRequestHeader(l,a[l]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=s&&(c.responseType=s),null!=u&&i.on("error",u).on("load",function(n){u(null,n)}),o.beforesend.call(i,c),c.send(null==r?null:r),i},i.abort=function(){return c.abort(),i},Zo.rebind(i,o,"on"),null==r?i:i.get(Et(r))}function Et(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function At(){var n=Ct(),t=Nt()-n;t>24?(isFinite(t)&&(clearTimeout($a),$a=setTimeout(At,t)),Xa=0):(Xa=1,Wa(At))}function Ct(){var n=Date.now();for(Ba=Za;Ba;)n>=Ba.t&&(Ba.f=Ba.c(n-Ba.t)),Ba=Ba.n;return n}function Nt(){for(var n,t=Za,e=1/0;t;)t.f?t=n?n.n=t.n:Za=t.n:(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Tt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r?function(n){for(var t=n.length,u=[],i=0,o=r[0];t>0&&o>0;)u.push(n.substring(t-=o,t+o)),o=r[i=(i+1)%r.length];return u.reverse().join(e)}:wt;return function(n){var e=Ga.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"",c=e[4]||"",s=e[5],l=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1;switch(h&&(h=+h.substring(1)),(s||"0"===r&&"="===o)&&(s=r="0",o="=",f&&(l-=Math.floor((l-1)/4))),g){case"n":f=!0,g="g";break;case"%":p=100,d="%",g="f";break;case"p":p=100,d="%",g="r";break;case"b":case"o":case"x":case"X":"#"===c&&(v="0"+g.toLowerCase());case"c":case"d":m=!0,h=0;break;case"s":p=-1,g="r"}"$"===c&&(v=u[0],d=u[1]),"r"!=g||h||(g="g"),null!=h&&("g"==g?h=Math.max(1,Math.min(21,h)):("e"==g||"f"==g)&&(h=Math.max(0,Math.min(20,h)))),g=Ka.get(g)||qt;var y=s&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):a;if(0>p){var c=Zo.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x=n.lastIndexOf("."),M=0>x?n:n.substring(0,x),_=0>x?"":t+n.substring(x+1);!s&&f&&(M=i(M));var b=v.length+M.length+_.length+(y?0:u.length),w=l>b?new Array(b=l-b+1).join(r):"";return y&&(M=i(w+M)),u+=v,n=M+_,("<"===o?u+n+w:">"===o?w+u+n:"^"===o?w.substring(0,b>>=1)+u+n+w.substring(b):u+(y?n:w+n))+e}}}function qt(n){return n+""}function Rt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Dt(n,t,e){function r(t){var e=n(t),r=i(e,1);return r-t>t-e?e:r}function u(e){return t(e=n(new nc(e-1)),1),e}function i(n,e){return t(n=new nc(+n),e),n}function o(n,r,i){var o=u(n),a=[];if(i>1)for(;r>o;)e(o)%i||a.push(new Date(+o)),t(o,1);else for(;r>o;)a.push(new Date(+o)),t(o,1);return a}function a(n,t,e){try{nc=Rt;var r=new Rt;return r._=n,o(r,t,e)}finally{nc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Pt(n);return c.floor=c,c.round=Pt(r),c.ceil=Pt(u),c.offset=Pt(i),c.range=a,n}function Pt(n){return function(t,e){try{nc=Rt;var r=new Rt;return r._=t,n(r,e)._}finally{nc=Date}}}function Ut(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++aa;){if(r>=s)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=N[o in ec?t.charAt(a++):o],!i||(r=i(n,e,r))<0)return-1}else if(u!=e.charCodeAt(r++))return-1}return r}function r(n,t,e){b.lastIndex=0;var r=b.exec(t.substring(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){M.lastIndex=0;var r=M.exec(t.substring(e));return r?(n.w=_.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.substring(e));return r?(n.m=A.get(r[0].toLowerCase()),e+r[0].length):-1}function o(n,t,e){S.lastIndex=0;var r=S.exec(t.substring(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,C.c.toString(),t,r)}function c(n,t,r){return e(n,C.x.toString(),t,r)}function s(n,t,r){return e(n,C.X.toString(),t,r)}function l(n,t,e){var r=x.get(t.substring(e,e+=2).toLowerCase());return null==r?-1:(n.p=r,e)}var f=n.dateTime,h=n.date,g=n.time,p=n.periods,v=n.days,d=n.shortDays,m=n.months,y=n.shortMonths;t.utc=function(n){function e(n){try{nc=Rt;var t=new nc;return t._=n,r(t)}finally{nc=Date}}var r=t(n);return e.parse=function(n){try{nc=Rt;var t=r.parse(n);return t&&t._}finally{nc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=re;var x=Zo.map(),M=Ht(v),_=Ft(v),b=Ht(d),w=Ft(d),S=Ht(m),k=Ft(m),E=Ht(y),A=Ft(y);p.forEach(function(n,t){x.set(n.toLowerCase(),t)});var C={a:function(n){return d[n.getDay()]},A:function(n){return v[n.getDay()]},b:function(n){return y[n.getMonth()]},B:function(n){return m[n.getMonth()]},c:t(f),d:function(n,t){return jt(n.getDate(),t,2)},e:function(n,t){return jt(n.getDate(),t,2)},H:function(n,t){return jt(n.getHours(),t,2)},I:function(n,t){return jt(n.getHours()%12||12,t,2)},j:function(n,t){return jt(1+Qa.dayOfYear(n),t,3)},L:function(n,t){return jt(n.getMilliseconds(),t,3)},m:function(n,t){return jt(n.getMonth()+1,t,2)},M:function(n,t){return jt(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return jt(n.getSeconds(),t,2)},U:function(n,t){return jt(Qa.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return jt(Qa.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return jt(n.getFullYear()%100,t,2)},Y:function(n,t){return jt(n.getFullYear()%1e4,t,4)},Z:te,"%":function(){return"%"}},N={a:r,A:u,b:i,B:o,c:a,d:Wt,e:Wt,H:Gt,I:Gt,j:Jt,L:ne,m:Bt,M:Kt,p:l,S:Qt,U:Yt,w:Ot,W:It,x:c,X:s,y:Vt,Y:Zt,Z:Xt,"%":ee};return t}function jt(n,t,e){var r=0>n?"-":"",u=(r?-n:n)+"",i=u.length;return r+(e>i?new Array(e-i+1).join(t)+u:u)}function Ht(n){return new RegExp("^(?:"+n.map(Zo.requote).join("|")+")","i")}function Ft(n){for(var t=new o,e=-1,r=n.length;++e68?1900:2e3)}function Bt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Wt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function Jt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function Gt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function Kt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function Qt(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ne(n,t,e){rc.lastIndex=0;var r=rc.exec(t.substring(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function te(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=~~(ua(t)/60),u=ua(t)%60;return e+jt(r,"0",2)+jt(u,"0",2)}function ee(n,t,e){uc.lastIndex=0;var r=uc.exec(t.substring(e,e+1));return r?e+r[0].length:-1}function re(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,c=Math.cos(t),s=Math.sin(t),l=i*s,f=u*c+l*Math.cos(a),h=l*o*Math.sin(a);lc.add(Math.atan2(h,f)),r=n,u=c,i=s}var t,e,r,u,i;fc.point=function(o,a){fc.point=n,r=(t=o)*Aa,u=Math.cos(a=(e=a)*Aa/2+ba/4),i=Math.sin(a)},fc.lineEnd=function(){n(t,e)}}function le(n){var t=n[0],e=n[1],r=Math.cos(e);return[r*Math.cos(t),r*Math.sin(t),Math.sin(e)]}function fe(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function he(n,t){return[n[1]*t[2]-n[2]*t[1],n[2]*t[0]-n[0]*t[2],n[0]*t[1]-n[1]*t[0]]}function ge(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function pe(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function ve(n){var t=Math.sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);n[0]/=t,n[1]/=t,n[2]/=t}function de(n){return[Math.atan2(n[1],n[0]),G(n[2])]}function me(n,t){return ua(n[0]-t[0])a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new Ee(e,n,null,!0),s=new Ee(e,null,c,!1);c.o=s,i.push(c),o.push(s),c=new Ee(r,n,null,!1),s=new Ee(r,null,c,!0),c.o=s,i.push(c),o.push(s)}}),o.sort(t),ke(i),ke(o),i.length){for(var a=0,c=e,s=o.length;s>a;++a)o[a].e=c=!c;for(var l,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;l=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,s=l.length;s>a;++a)u.point((f=l[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){l=g.p.z;for(var a=l.length-1;a>=0;--a)u.point((f=l[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,l=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ke(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r0){for(_||(i.polygonStart(),_=!0),i.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Ce))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:s,polygonStart:function(){y.point=l,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=s,g=Zo.merge(g);var n=Le(m,p);g.length?(_||(i.polygonStart(),_=!0),Se(g,ze,n,e,i)):n&&(_||(i.polygonStart(),_=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),_&&(i.polygonEnd(),_=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},x=Ne(),M=t(x),_=!1;return y}}function Ce(n){return n.length>1}function Ne(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:v,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function ze(n,t){return((n=n.x)[0]<0?n[1]-Sa-ka:Sa-n[1])-((t=t.x)[0]<0?t[1]-Sa-ka:Sa-t[1])}function Le(n,t){var e=n[0],r=n[1],u=[Math.sin(e),-Math.cos(e),0],i=0,o=0;lc.reset();for(var a=0,c=t.length;c>a;++a){var s=t[a],l=s.length;if(l)for(var f=s[0],h=f[0],g=f[1]/2+ba/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===l&&(d=0),n=s[d];var m=n[0],y=n[1]/2+ba/4,x=Math.sin(y),M=Math.cos(y),_=m-h,b=_>=0?1:-1,w=b*_,S=w>ba,k=p*x;if(lc.add(Math.atan2(k*b*Math.sin(w),v*M+k*Math.cos(w))),i+=S?_+b*wa:_,S^h>=e^m>=e){var E=he(le(f),le(n));ve(E);var A=he(u,E);ve(A);var C=(S^_>=0?-1:1)*G(A[2]);(r>C||r===C&&(E[0]||E[1]))&&(o+=S^_>=0?1:-1)}if(!d++)break;h=m,p=x,v=M,f=n}}return(-ka>i||ka>i&&0>lc)^1&o}function Te(n){var t,e=0/0,r=0/0,u=0/0;return{lineStart:function(){n.lineStart(),t=1},point:function(i,o){var a=i>0?ba:-ba,c=ua(i-e);ua(c-ba)0?Sa:-Sa),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=ba&&(ua(e-u)ka?Math.atan((Math.sin(t)*(i=Math.cos(r))*Math.sin(e)-Math.sin(r)*(u=Math.cos(t))*Math.sin(n))/(u*i*o)):(t+r)/2}function Re(n,t,e,r){var u;if(null==n)u=e*Sa,r.point(-ba,u),r.point(0,u),r.point(ba,u),r.point(ba,0),r.point(ba,-u),r.point(0,-u),r.point(-ba,-u),r.point(-ba,0),r.point(-ba,u);else if(ua(n[0]-t[0])>ka){var i=n[0]i}function e(n){var e,i,c,s,l;return{lineStart:function(){s=c=!1,l=1},point:function(f,h){var g,p=[f,h],v=t(f,h),d=o?v?0:u(f,h):v?u(f+(0>f?ba:-ba),h):0;if(!e&&(s=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(me(e,g)||me(p,g))&&(p[0]+=ka,p[1]+=ka,v=t(p[0],p[1]))),v!==c)l=0,v?(n.lineStart(),g=r(p,e),n.point(g[0],g[1])):(g=r(e,p),n.point(g[0],g[1]),n.lineEnd()),e=g;else if(a&&e&&o^v){var m;d&i||!(m=r(p,e,!0))||(l=0,o?(n.lineStart(),n.point(m[0][0],m[0][1]),n.point(m[1][0],m[1][1]),n.lineEnd()):(n.point(m[1][0],m[1][1]),n.lineEnd(),n.lineStart(),n.point(m[0][0],m[0][1])))}!v||e&&me(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return l|(s&&c)<<1}}}function r(n,t,e){var r=le(n),u=le(t),o=[1,0,0],a=he(r,u),c=fe(a,a),s=a[0],l=c-s*s;if(!l)return!e&&n;var f=i*c/l,h=-i*s/l,g=he(o,a),p=pe(o,f),v=pe(a,h);ge(p,v);var d=g,m=fe(p,d),y=fe(d,d),x=m*m-y*(fe(p,p)-1);if(!(0>x)){var M=Math.sqrt(x),_=pe(d,(-m-M)/y);if(ge(_,p),_=de(_),!e)return _;var b,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(b=w,w=S,S=b);var A=S-w,C=ua(A-ba)A;if(!C&&k>E&&(b=k,k=E,E=b),N?C?k+E>0^_[1]<(ua(_[0]-w)ba^(w<=_[0]&&_[0]<=S)){var z=pe(d,(-m+M)/y);return ge(z,p),[_,de(z)]}}}function u(t,e){var r=o?n:ba-n,u=0;return-r>t?u|=1:t>r&&(u|=2),-r>e?u|=4:e>r&&(u|=8),u}var i=Math.cos(n),o=i>0,a=ua(i)>ka,c=sr(n,6*Aa);return Ae(t,e,c,o?[0,-n]:[-ba,n-ba])}function Pe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,s=o.y,l=a.x,f=a.y,h=0,g=1,p=l-c,v=f-s;if(i=n-c,p||!(i>0)){if(i/=p,0>p){if(h>i)return;g>i&&(g=i)}else if(p>0){if(i>g)return;i>h&&(h=i)}if(i=e-c,p||!(0>i)){if(i/=p,0>p){if(i>g)return;i>h&&(h=i)}else if(p>0){if(h>i)return;g>i&&(g=i)}if(i=t-s,v||!(i>0)){if(i/=v,0>v){if(h>i)return;g>i&&(g=i)}else if(v>0){if(i>g)return;i>h&&(h=i)}if(i=r-s,v||!(0>i)){if(i/=v,0>v){if(i>g)return;i>h&&(h=i)}else if(v>0){if(h>i)return;g>i&&(g=i)}return h>0&&(u.a={x:c+h*p,y:s+h*v}),1>g&&(u.b={x:c+g*p,y:s+g*v}),u}}}}}}function Ue(n,t,e,r){function u(r,u){return ua(r[0]-n)0?0:3:ua(r[0]-e)0?2:1:ua(r[1]-t)0?1:0:u>0?3:2}function i(n,t){return o(n.x,t.x)}function o(n,t){var e=u(n,1),r=u(t,1);return e!==r?e-r:0===e?t[1]-n[1]:1===e?n[0]-t[0]:2===e?n[1]-t[1]:t[0]-n[0]}return function(a){function c(n){for(var t=0,e=d.length,r=n[1],u=0;e>u;++u)for(var i,o=1,a=d[u],c=a.length,s=a[0];c>o;++o)i=a[o],s[1]<=r?i[1]>r&&W(s,i,n)>0&&++t:i[1]<=r&&W(s,i,n)<0&&--t,s=i;return 0!==t}function s(i,a,c,s){var l=0,f=0;if(null==i||(l=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do s.point(0===l||3===l?n:e,l>1?r:t);while((l=(l+c+4)%4)!==f)}else s.point(a[0],a[1])}function l(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){l(n,t)&&a.point(n,t)}function h(){N.point=p,d&&d.push(m=[]),S=!0,w=!1,_=b=0/0}function g(){v&&(p(y,x),M&&w&&A.rejoin(),v.push(A.buffer())),N.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-kc,Math.min(kc,n)),t=Math.max(-kc,Math.min(kc,t));var e=l(n,t);if(d&&m.push([n,t]),S)y=n,x=t,M=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:_,y:b},b:{x:n,y:t}};C(r)?(w||(a.lineStart(),a.point(r.a.x,r.a.y)),a.point(r.b.x,r.b.y),e||a.lineEnd(),k=!1):e&&(a.lineStart(),a.point(n,t),k=!1)}_=n,b=t,w=e}var v,d,m,y,x,M,_,b,w,S,k,E=a,A=Ne(),C=Pe(n,t,e,r),N={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=Zo.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),s(null,null,1,a),a.lineEnd()),u&&Se(v,i,t,s,a),a.polygonEnd()),v=d=m=null}};return N}}function je(n,t){function e(e,r){return e=n(e,r),t(e[0],e[1])}return n.invert&&t.invert&&(e.invert=function(e,r){return e=t.invert(e,r),e&&n.invert(e[0],e[1])}),e}function He(n){var t=0,e=ba/3,r=tr(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*ba/180,e=n[1]*ba/180):[180*(t/ba),180*(e/ba)]},u}function Fe(n,t){function e(n,t){var e=Math.sqrt(i-2*u*Math.sin(t))/u;return[e*Math.sin(n*=u),o-e*Math.cos(n)]}var r=Math.sin(n),u=(r+Math.sin(t))/2,i=1+r*(2*u-r),o=Math.sqrt(i)/u;return e.invert=function(n,t){var e=o-t;return[Math.atan2(n,e)/u,G((i-(n*n+e*e)*u*u)/(2*u))]},e}function Oe(){function n(n,t){Ac+=u*n-r*t,r=n,u=t}var t,e,r,u;Tc.point=function(i,o){Tc.point=n,t=r=i,e=u=o},Tc.lineEnd=function(){n(t,e)}}function Ye(n,t){Cc>n&&(Cc=n),n>zc&&(zc=n),Nc>t&&(Nc=t),t>Lc&&(Lc=t)}function Ie(){function n(n,t){o.push("M",n,",",t,i)}function t(n,t){o.push("M",n,",",t),a.point=e}function e(n,t){o.push("L",n,",",t)}function r(){a.point=n}function u(){o.push("Z")}var i=Ze(4.5),o=[],a={point:n,lineStart:function(){a.point=t},lineEnd:r,polygonStart:function(){a.lineEnd=u},polygonEnd:function(){a.lineEnd=r,a.point=n},pointRadius:function(n){return i=Ze(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Ze(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function Ve(n,t){pc+=n,vc+=t,++dc}function Xe(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);mc+=o*(t+n)/2,yc+=o*(e+r)/2,xc+=o,Ve(t=n,e=r)}var t,e;Rc.point=function(r,u){Rc.point=n,Ve(t=r,e=u)}}function $e(){Rc.point=Ve}function Be(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);mc+=o*(r+n)/2,yc+=o*(u+t)/2,xc+=o,o=u*n-r*t,Mc+=o*(r+n),_c+=o*(u+t),bc+=3*o,Ve(r=n,u=t)}var t,e,r,u;Rc.point=function(i,o){Rc.point=n,Ve(t=r=i,e=u=o)},Rc.lineEnd=function(){n(t,e)}}function We(n){function t(t,e){n.moveTo(t,e),n.arc(t,e,o,0,wa)}function e(t,e){n.moveTo(t,e),a.point=r}function r(t,e){n.lineTo(t,e)}function u(){a.point=t}function i(){n.closePath()}var o=4.5,a={point:t,lineStart:function(){a.point=e},lineEnd:u,polygonStart:function(){a.lineEnd=i},polygonEnd:function(){a.lineEnd=u,a.point=t},pointRadius:function(n){return o=n,a},result:v};return a}function Je(n){function t(n){return(a?r:e)(n)}function e(t){return Qe(t,function(e,r){e=n(e,r),t.point(e[0],e[1])})}function r(t){function e(e,r){e=n(e,r),t.point(e[0],e[1])}function r(){x=0/0,S.point=i,t.lineStart()}function i(e,r){var i=le([e,r]),o=n(e,r);u(x,M,y,_,b,w,x=o[0],M=o[1],y=e,_=i[0],b=i[1],w=i[2],a,t),t.point(x,M)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=s,S.lineEnd=l}function s(n,t){i(f=n,h=t),g=x,p=M,v=_,d=b,m=w,S.point=i}function l(){u(x,M,y,_,b,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,x,M,_,b,w,S={point:e,lineStart:r,lineEnd:o,polygonStart:function(){t.polygonStart(),S.lineStart=c},polygonEnd:function(){t.polygonEnd(),S.lineStart=r}};return S}function u(t,e,r,a,c,s,l,f,h,g,p,v,d,m){var y=l-t,x=f-e,M=y*y+x*x;if(M>4*i&&d--){var _=a+g,b=c+p,w=s+v,S=Math.sqrt(_*_+b*b+w*w),k=Math.asin(w/=S),E=ua(ua(w)-1)i||ua((y*z+x*L)/M-.5)>.3||o>a*g+c*p+s*v)&&(u(t,e,r,a,c,s,C,N,E,_/=S,b/=S,w,d,m),m.point(C,N),u(C,N,E,_,b,w,l,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Aa),a=16; +return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function Ge(n){var t=Je(function(t,e){return n([t*Ca,e*Ca])});return function(n){return er(t(n))}}function Ke(n){this.stream=n}function Qe(n,t){return{point:t,sphere:function(){n.sphere()},lineStart:function(){n.lineStart()},lineEnd:function(){n.lineEnd()},polygonStart:function(){n.polygonStart()},polygonEnd:function(){n.polygonEnd()}}}function nr(n){return tr(function(){return n})()}function tr(n){function t(n){return n=a(n[0]*Aa,n[1]*Aa),[n[0]*h+c,s-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(s-n[1])/h),n&&[n[0]*Ca,n[1]*Ca]}function r(){a=je(o=ir(m,y,x),i);var n=i(v,d);return c=g-n[0]*h,s=p+n[1]*h,u()}function u(){return l&&(l.valid=!1,l=null),t}var i,o,a,c,s,l,f=Je(function(n,t){return n=i(n,t),[n[0]*h+c,s-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,x=0,M=Sc,_=wt,b=null,w=null;return t.stream=function(n){return l&&(l.valid=!1),l=er(M(o,f(_(n)))),l.valid=!0,l},t.clipAngle=function(n){return arguments.length?(M=null==n?(b=n,Sc):De((b=+n)*Aa),u()):b},t.clipExtent=function(n){return arguments.length?(w=n,_=n?Ue(n[0][0],n[0][1],n[1][0],n[1][1]):wt,u()):w},t.scale=function(n){return arguments.length?(h=+n,r()):h},t.translate=function(n){return arguments.length?(g=+n[0],p=+n[1],r()):[g,p]},t.center=function(n){return arguments.length?(v=n[0]%360*Aa,d=n[1]%360*Aa,r()):[v*Ca,d*Ca]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Aa,y=n[1]%360*Aa,x=n.length>2?n[2]%360*Aa:0,r()):[m*Ca,y*Ca,x*Ca]},Zo.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function er(n){return Qe(n,function(t,e){n.point(t*Aa,e*Aa)})}function rr(n,t){return[n,t]}function ur(n,t){return[n>ba?n-wa:-ba>n?n+wa:n,t]}function ir(n,t,e){return n?t||e?je(ar(n),cr(t,e)):ar(n):t||e?cr(t,e):ur}function or(n){return function(t,e){return t+=n,[t>ba?t-wa:-ba>t?t+wa:t,e]}}function ar(n){var t=or(n);return t.invert=or(-n),t}function cr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*r+a*u;return[Math.atan2(c*i-l*o,a*r-s*u),G(l*i+c*o)]}var r=Math.cos(n),u=Math.sin(n),i=Math.cos(t),o=Math.sin(t);return e.invert=function(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,s=Math.sin(t),l=s*i-c*o;return[Math.atan2(c*i+s*o,a*r+l*u),G(l*r-a*u)]},e}function sr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=lr(e,u),i=lr(e,i),(o>0?i>u:u>i)&&(u+=o*wa)):(u=n+o*wa,i=n-.5*c);for(var s,l=u;o>0?l>i:i>l;l-=c)a.point((s=de([e,-r*Math.cos(l),-r*Math.sin(l)]))[0],s[1])}}function lr(n,t){var e=le(t);e[0]-=n,ve(e);var r=J(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-ka)%(2*Math.PI)}function fr(n,t,e){var r=Zo.range(n,t-ka,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function hr(n,t,e){var r=Zo.range(n,t-ka,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function gr(n){return n.source}function pr(n){return n.target}function vr(n,t,e,r){var u=Math.cos(t),i=Math.sin(t),o=Math.cos(r),a=Math.sin(r),c=u*Math.cos(n),s=u*Math.sin(n),l=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(tt(r-t)+u*o*tt(e-n))),g=1/Math.sin(h),p=h?function(n){var t=Math.sin(n*=h)*g,e=Math.sin(h-n)*g,r=e*c+t*l,u=e*s+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Ca,Math.atan2(o,Math.sqrt(r*r+u*u))*Ca]}:function(){return[n*Ca,t*Ca]};return p.distance=h,p}function dr(){function n(n,u){var i=Math.sin(u*=Aa),o=Math.cos(u),a=ua((n*=Aa)-t),c=Math.cos(a);Dc+=Math.atan2(Math.sqrt((a=o*Math.sin(a))*a+(a=r*i-e*o*c)*a),e*i+r*o*c),t=n,e=i,r=o}var t,e,r;Pc.point=function(u,i){t=u*Aa,e=Math.sin(i*=Aa),r=Math.cos(i),Pc.point=n},Pc.lineEnd=function(){Pc.point=Pc.lineEnd=v}}function mr(n,t){function e(t,e){var r=Math.cos(t),u=Math.cos(e),i=n(r*u);return[i*u*Math.sin(t),i*Math.sin(e)]}return e.invert=function(n,e){var r=Math.sqrt(n*n+e*e),u=t(r),i=Math.sin(u),o=Math.cos(u);return[Math.atan2(n*i,r*o),Math.asin(r&&e*i/r)]},e}function yr(n,t){function e(n,t){o>0?-Sa+ka>t&&(t=-Sa+ka):t>Sa-ka&&(t=Sa-ka);var e=o/Math.pow(u(t),i);return[e*Math.sin(i*n),o-e*Math.cos(i*n)]}var r=Math.cos(n),u=function(n){return Math.tan(ba/4+n/2)},i=n===t?Math.sin(n):Math.log(r/Math.cos(t))/Math.log(u(t)/u(n)),o=r*Math.pow(u(n),i)/i;return i?(e.invert=function(n,t){var e=o-t,r=B(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-Sa]},e):Mr}function xr(n,t){function e(n,t){var e=i-t;return[e*Math.sin(u*n),i-e*Math.cos(u*n)]}var r=Math.cos(n),u=n===t?Math.sin(n):(r-Math.cos(t))/(t-n),i=r/u+n;return ua(u)u;u++){for(;r>1&&W(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function Er(n,t){return n[0]-t[0]||n[1]-t[1]}function Ar(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Cr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],s=e[1],l=t[1]-c,f=r[1]-s,h=(a*(c-s)-f*(u-i))/(f*o-a*l);return[u+h*o,c+h*l]}function Nr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function zr(){Gr(this),this.edge=this.site=this.circle=null}function Lr(n){var t=Bc.pop()||new zr;return t.site=n,t}function Tr(n){Yr(n),Vc.remove(n),Bc.push(n),Gr(n)}function qr(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Tr(n);for(var c=i;c.circle&&ua(e-c.circle.x)l;++l)s=a[l],c=a[l-1],Br(s.edge,c.site,s.site,u);c=a[0],s=a[f-1],s.edge=Xr(c.site,s.site,null,u),Or(c),Or(s)}function Rr(n){for(var t,e,r,u,i=n.x,o=n.y,a=Vc._;a;)if(r=Dr(a,o)-i,r>ka)a=a.L;else{if(u=i-Pr(a,o),!(u>ka)){r>-ka?(t=a.P,e=a):u>-ka?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Lr(n);if(Vc.insert(t,c),t||e){if(t===e)return Yr(t),e=Lr(t.site),Vc.insert(c,e),c.edge=e.edge=Xr(t.site,c.site),Or(t),Or(e),void 0;if(!e)return c.edge=Xr(t.site,c.site),void 0;Yr(t),Yr(e);var s=t.site,l=s.x,f=s.y,h=n.x-l,g=n.y-f,p=e.site,v=p.x-l,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,x=v*v+d*d,M={x:(d*y-g*x)/m+l,y:(h*x-v*y)/m+f};Br(e.edge,s,p,M),c.edge=Xr(s,n,null,M),e.edge=Xr(n,p,null,M),Or(t),Or(e)}}function Dr(n,t){var e=n.site,r=e.x,u=e.y,i=u-t;if(!i)return r;var o=n.P;if(!o)return-1/0;e=o.site;var a=e.x,c=e.y,s=c-t;if(!s)return a;var l=a-r,f=1/i-1/s,h=l/s;return f?(-h+Math.sqrt(h*h-2*f*(l*l/(-2*s)-c+s/2+u-i/2)))/f+r:(r+a)/2}function Pr(n,t){var e=n.N;if(e)return Dr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Ur(n){this.site=n,this.edges=[]}function jr(n){for(var t,e,r,u,i,o,a,c,s,l,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=Zc,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)l=a[o].end(),r=l.x,u=l.y,s=a[++o%c].start(),t=s.x,e=s.y,(ua(r-t)>ka||ua(u-e)>ka)&&(a.splice(o,0,new Wr($r(i.site,l,ua(r-f)ka?{x:f,y:ua(t-f)ka?{x:ua(e-p)ka?{x:h,y:ua(t-h)ka?{x:ua(e-g)=-Ea)){var g=c*c+s*s,p=l*l+f*f,v=(f*g-s*p)/h,d=(c*p-l*g)/h,f=d+a,m=Wc.pop()||new Fr;m.arc=n,m.site=u,m.x=v+o,m.y=f+Math.sqrt(v*v+d*d),m.cy=f,n.circle=m;for(var y=null,x=$c._;x;)if(m.yd||d>=a)return;if(h>p){if(i){if(i.y>=s)return}else i={x:d,y:c};e={x:d,y:s}}else{if(i){if(i.yr||r>1)if(h>p){if(i){if(i.y>=s)return}else i={x:(c-u)/r,y:c};e={x:(s-u)/r,y:s}}else{if(i){if(i.yg){if(i){if(i.x>=a)return}else i={x:o,y:r*o+u};e={x:a,y:r*a+u}}else{if(i){if(i.xi&&(u=t.substring(i,u),a[o]?a[o]+=u:a[++o]=u),(e=e[0])===(r=r[0])?a[o]?a[o]+=r:a[++o]=r:(a[++o]=null,c.push({i:o,x:lu(e,r)})),i=Kc.lastIndex;return ir;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function hu(n,t){for(var e,r=Zo.interpolators.length;--r>=0&&!(e=Zo.interpolators[r](n,t)););return e}function gu(n,t){var e,r=[],u=[],i=n.length,o=t.length,a=Math.min(n.length,t.length);for(e=0;a>e;++e)r.push(hu(n[e],t[e]));for(;i>e;++e)u[e]=n[e];for(;o>e;++e)u[e]=t[e];return function(n){for(e=0;a>e;++e)u[e]=r[e](n);return u}}function pu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function vu(n){return function(t){return 1-n(1-t)}}function du(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function mu(n){return n*n}function yu(n){return n*n*n}function xu(n){if(0>=n)return 0;if(n>=1)return 1;var t=n*n,e=t*n;return 4*(.5>n?e:3*(n-t)+e-.75)}function Mu(n){return function(t){return Math.pow(t,n)}}function _u(n){return 1-Math.cos(n*Sa)}function bu(n){return Math.pow(2,10*(n-1))}function wu(n){return 1-Math.sqrt(1-n*n)}function Su(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/wa*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*wa/t)}}function ku(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function Eu(n){return 1/2.75>n?7.5625*n*n:2/2.75>n?7.5625*(n-=1.5/2.75)*n+.75:2.5/2.75>n?7.5625*(n-=2.25/2.75)*n+.9375:7.5625*(n-=2.625/2.75)*n+.984375}function Au(n,t){n=Zo.hcl(n),t=Zo.hcl(t);var e=n.h,r=n.c,u=n.l,i=t.h-e,o=t.c-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.c:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ot(e+i*n,r+o*n,u+a*n)+""}}function Cu(n,t){n=Zo.hsl(n),t=Zo.hsl(t);var e=n.h,r=n.s,u=n.l,i=t.h-e,o=t.s-r,a=t.l-u;return isNaN(o)&&(o=0,r=isNaN(r)?t.s:r),isNaN(i)?(i=0,e=isNaN(e)?t.h:e):i>180?i-=360:-180>i&&(i+=360),function(n){return ut(e+i*n,r+o*n,u+a*n)+""}}function Nu(n,t){n=Zo.lab(n),t=Zo.lab(t);var e=n.l,r=n.a,u=n.b,i=t.l-e,o=t.a-r,a=t.b-u;return function(n){return ct(e+i*n,r+o*n,u+a*n)+""}}function zu(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Lu(n){var t=[n.a,n.b],e=[n.c,n.d],r=qu(t),u=Tu(t,e),i=qu(Ru(e,t,-u))||0;t[0]*e[1]180?l+=360:l-s>180&&(s+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:lu(s,l)})):l&&r.push(r.pop()+"rotate("+l+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:lu(f,h)}):h&&r.push(r.pop()+"skewX("+h+")"),g[0]!=p[0]||g[1]!=p[1]?(e=r.push(r.pop()+"scale(",null,",",null,")"),u.push({i:e-4,x:lu(g[0],p[0])},{i:e-2,x:lu(g[1],p[1])})):(1!=p[0]||1!=p[1])&&r.push(r.pop()+"scale("+p+")"),e=u.length,function(n){for(var t,i=-1;++i=0;)e.push(u[r])}function Bu(n,t){for(var e=[n],r=[];null!=(n=e.pop());)if(r.push(n),(i=n.children)&&(u=i.length))for(var u,i,o=-1;++oe;++e)(t=n[e][1])>u&&(r=e,u=t);return r}function ii(n){return n.reduce(oi,0)}function oi(n,t){return n+t[1]}function ai(n,t){return ci(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function ci(n,t){for(var e=-1,r=+n[0],u=(n[1]-r)/t,i=[];++e<=t;)i[e]=u*e+r;return i}function si(n){return[Zo.min(n),Zo.max(n)]}function li(n,t){return n.value-t.value}function fi(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function hi(n,t){n._pack_next=t,t._pack_prev=n}function gi(n,t){var e=t.x-n.x,r=t.y-n.y,u=n.r+t.r;return.999*u*u>e*e+r*r}function pi(n){function t(n){l=Math.min(n.x-n.r,l),f=Math.max(n.x+n.r,f),h=Math.min(n.y-n.r,h),g=Math.max(n.y+n.r,g)}if((e=n.children)&&(s=e.length)){var e,r,u,i,o,a,c,s,l=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(vi),r=e[0],r.x=-r.r,r.y=0,t(r),s>1&&(u=e[1],u.x=u.r,u.y=0,t(u),s>2))for(i=e[2],yi(r,u,i),t(i),fi(r,i),r._pack_prev=i,fi(i,u),u=r._pack_next,o=3;s>o;o++){yi(r,u,i=e[o]);var p=0,v=1,d=1;for(a=u._pack_next;a!==u;a=a._pack_next,v++)if(gi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!gi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.ro;o++)i=e[o],i.x-=m,i.y-=y,x=Math.max(x,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=x,e.forEach(di)}}function vi(n){n._pack_next=n._pack_prev=n}function di(n){delete n._pack_next,delete n._pack_prev}function mi(n,t,e,r){var u=n.children;if(n.x=t+=r*n.x,n.y=e+=r*n.y,n.r*=r,u)for(var i=-1,o=u.length;++i=0;)t=u[i],t.z+=e,t.m+=e,e+=t.s+(r+=t.c)}function Si(n,t,e){return n.a.parent===t.parent?n.a:e}function ki(n){return 1+Zo.max(n,function(n){return n.y})}function Ei(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Ai(n){var t=n.children;return t&&t.length?Ai(t[0]):n}function Ci(n){var t,e=n.children;return e&&(t=e.length)?Ci(e[t-1]):n}function Ni(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function zi(n,t){var e=n.x+t[3],r=n.y+t[0],u=n.dx-t[1]-t[3],i=n.dy-t[0]-t[2];return 0>u&&(e+=u/2,u=0),0>i&&(r+=i/2,i=0),{x:e,y:r,dx:u,dy:i}}function Li(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ti(n){return n.rangeExtent?n.rangeExtent():Li(n.range())}function qi(n,t,e,r){var u=e(n[0],n[1]),i=r(t[0],t[1]);return function(n){return i(u(n))}}function Ri(n,t){var e,r=0,u=n.length-1,i=n[r],o=n[u];return i>o&&(e=r,r=u,u=e,e=i,i=o,o=e),n[r]=t.floor(i),n[u]=t.ceil(o),n}function Di(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:ss}function Pi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Pi:qi,c=r?Uu:Pu;return o=u(n,t,c,e),a=u(t,n,c,hu),i}function i(n){return o(n)}var o,a;return i.invert=function(n){return a(n)},i.domain=function(t){return arguments.length?(n=t.map(Number),u()):n},i.range=function(n){return arguments.length?(t=n,u()):t},i.rangeRound=function(n){return i.range(n).interpolate(zu)},i.clamp=function(n){return arguments.length?(r=n,u()):r},i.interpolate=function(n){return arguments.length?(e=n,u()):e},i.ticks=function(t){return Oi(n,t)},i.tickFormat=function(t,e){return Yi(n,t,e)},i.nice=function(t){return Hi(n,t),u()},i.copy=function(){return Ui(n,t,e,r)},u()}function ji(n,t){return Zo.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Hi(n,t){return Ri(n,Di(Fi(n,t)[2]))}function Fi(n,t){null==t&&(t=10);var e=Li(n),r=e[1]-e[0],u=Math.pow(10,Math.floor(Math.log(r/t)/Math.LN10)),i=t/r*u;return.15>=i?u*=10:.35>=i?u*=5:.75>=i&&(u*=2),e[0]=Math.ceil(e[0]/u)*u,e[1]=Math.floor(e[1]/u)*u+.5*u,e[2]=u,e}function Oi(n,t){return Zo.range.apply(Zo,Fi(n,t))}function Yi(n,t,e){var r=Fi(n,t);if(e){var u=Ga.exec(e);if(u.shift(),"s"===u[8]){var i=Zo.formatPrefix(Math.max(ua(r[0]),ua(r[1])));return u[7]||(u[7]="."+Ii(i.scale(r[2]))),u[8]="f",e=Zo.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Zi(u[8],r)),e=u.join("")}else e=",."+Ii(r[2])+"f";return Zo.format(e)}function Ii(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Zi(n,t){var e=Ii(t[2]);return n in ls?Math.abs(e-Ii(Math.max(ua(t[0]),ua(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Vi(n,t,e,r){function u(n){return(e?Math.log(0>n?0:n):-Math.log(n>0?0:-n))/Math.log(t)}function i(n){return e?Math.pow(t,n):-Math.pow(t,-n)}function o(t){return n(u(t))}return o.invert=function(t){return i(n.invert(t))},o.domain=function(t){return arguments.length?(e=t[0]>=0,n.domain((r=t.map(Number)).map(u)),o):r},o.base=function(e){return arguments.length?(t=+e,n.domain(r.map(u)),o):t},o.nice=function(){var t=Ri(r.map(u),e?Math:hs);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Li(r),o=[],a=n[0],c=n[1],s=Math.floor(u(a)),l=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(l-s)){if(e){for(;l>s;s++)for(var h=1;f>h;h++)o.push(i(s)*h);o.push(i(s))}else for(o.push(i(s));s++0;h--)o.push(i(s)*h);for(s=0;o[s]c;l--);o=o.slice(s,l)}return o},o.tickFormat=function(n,t){if(!arguments.length)return fs;arguments.length<2?t=fs:"function"!=typeof t&&(t=Zo.format(t));var r,a=Math.max(.1,n/o.ticks().length),c=e?(r=1e-12,Math.ceil):(r=-1e-12,Math.floor);return function(n){return n/i(c(u(n)+r))<=a?t(n):""}},o.copy=function(){return Vi(n.copy(),t,e,r)},ji(o,n)}function Xi(n,t,e){function r(t){return n(u(t))}var u=$i(t),i=$i(1/t);return r.invert=function(t){return i(n.invert(t))},r.domain=function(t){return arguments.length?(n.domain((e=t.map(Number)).map(u)),r):e},r.ticks=function(n){return Oi(e,n)},r.tickFormat=function(n,t){return Yi(e,n,t)},r.nice=function(n){return r.domain(Hi(e,n))},r.exponent=function(o){return arguments.length?(u=$i(t=o),i=$i(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Xi(n.copy(),t,e)},ji(r,n)}function $i(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Bi(n,t){function e(e){return i[((u.get(e)||("range"===t.t?u.set(e,n.push(e)):0/0))-1)%i.length]}function r(t,e){return Zo.range(n.length).map(function(n){return t+e*n})}var u,i,a;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new o;for(var i,a=-1,c=r.length;++an?[0/0,0/0]:[n>0?o[n-1]:e[0],nt?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return Ji(n,t,e)},u()}function Gi(n,t){function e(e){return e>=e?t[Zo.bisect(n,e)]:void 0}return e.domain=function(t){return arguments.length?(n=t,e):n},e.range=function(n){return arguments.length?(t=n,e):t},e.invertExtent=function(e){return e=t.indexOf(e),[n[e-1],n[e]]},e.copy=function(){return Gi(n,t)},e}function Ki(n){function t(n){return+n}return t.invert=t,t.domain=t.range=function(e){return arguments.length?(n=e.map(t),t):n},t.ticks=function(t){return Oi(n,t)},t.tickFormat=function(t,e){return Yi(n,t,e)},t.copy=function(){return Ki(n)},t}function Qi(n){return n.innerRadius}function no(n){return n.outerRadius}function to(n){return n.startAngle}function eo(n){return n.endAngle}function ro(n){function t(t){function o(){s.push("M",i(n(l),a))}for(var c,s=[],l=[],f=-1,h=t.length,g=bt(e),p=bt(r);++f1&&u.push("H",r[0]),u.join("")}function ao(n){for(var t=0,e=n.length,r=n[0],u=[r[0],",",r[1]];++t1){a=t[1],i=n[c],c++,r+="C"+(u[0]+o[0])+","+(u[1]+o[1])+","+(i[0]-a[0])+","+(i[1]-a[1])+","+i[0]+","+i[1];for(var s=2;s9&&(u=3*t/Math.sqrt(u),o[a]=u*e,o[a+1]=u*r));for(a=-1;++a<=c;)u=(n[Math.min(c,a+1)][0]-n[Math.max(0,a-1)][0])/(6*(1+o[a]*o[a])),i.push([u||0,o[a]*u||0]);return i}function So(n){return n.length<3?uo(n):n[0]+ho(n,wo(n))}function ko(n){for(var t,e,r,u=-1,i=n.length;++ue?s():(u.active=e,i.event&&i.event.start.call(n,l,t),i.tween.forEach(function(e,r){(r=r.call(n,l,t))&&v.push(r)}),Zo.timer(function(){return p.c=c(r||1)?we:c,1},0,a),void 0)}function c(r){if(u.active!==e)return s();for(var o=r/g,a=f(o),c=v.length;c>0;)v[--c].call(n,a); +return o>=1?(i.event&&i.event.end.call(n,l,t),s()):void 0}function s(){return--u.count?delete u[e]:delete n.__transition__,1}var l=n.__data__,f=i.ease,h=i.delay,g=i.duration,p=Ba,v=[];return p.t=h+a,r>=h?o(r-h):(p.c=o,void 0)},0,a)}}function Uo(n,t){n.attr("transform",function(n){return"translate("+t(n)+",0)"})}function jo(n,t){n.attr("transform",function(n){return"translate(0,"+t(n)+")"})}function Ho(n){return n.toISOString()}function Fo(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=Zo.bisect(Us,u);return i==Us.length?[t.year,Fi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Us[i-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=Oo(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Oo(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Li(r.domain()),i=null==n?u(e,10):"number"==typeof n?u(e,n):!n.range&&[{range:n},t];return i&&(n=i[0],t=i[1]),n.range(e[0],Oo(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Fo(n.copy(),t,e)},ji(r,n)}function Oo(n){return new Date(n)}function Yo(n){return JSON.parse(n.responseText)}function Io(n){var t=$o.createRange();return t.selectNode($o.body),t.createContextualFragment(n.responseText)}var Zo={version:"3.4.11"};Date.now||(Date.now=function(){return+new Date});var Vo=[].slice,Xo=function(n){return Vo.call(n)},$o=document,Bo=$o.documentElement,Wo=window;try{Xo(Bo.childNodes)[0].nodeType}catch(Jo){Xo=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{$o.createElement("div").style.setProperty("opacity",0,"")}catch(Go){var Ko=Wo.Element.prototype,Qo=Ko.setAttribute,na=Ko.setAttributeNS,ta=Wo.CSSStyleDeclaration.prototype,ea=ta.setProperty;Ko.setAttribute=function(n,t){Qo.call(this,n,t+"")},Ko.setAttributeNS=function(n,t,e){na.call(this,n,t,e+"")},ta.setProperty=function(n,t,e){ea.call(this,n,t+"",e)}}Zo.ascending=n,Zo.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},Zo.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=e);)e=void 0;for(;++ur&&(e=r)}else{for(;++u=e);)e=void 0;for(;++ur&&(e=r)}return e},Zo.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=e);)e=void 0;for(;++ue&&(e=r)}else{for(;++u=e);)e=void 0;for(;++ue&&(e=r)}return e},Zo.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i=e);)e=u=void 0;for(;++ir&&(e=r),r>u&&(u=r))}else{for(;++i=e);)e=void 0;for(;++ir&&(e=r),r>u&&(u=r))}return[e,u]},Zo.sum=function(n,t){var e,r=0,u=n.length,i=-1;if(1===arguments.length)for(;++i1&&(e=e.map(r)),e=e.filter(t),e.length?Zo.quantile(e.sort(n),.5):void 0};var ra=e(n);Zo.bisectLeft=ra.left,Zo.bisect=Zo.bisectRight=ra.right,Zo.bisector=function(t){return e(1===t.length?function(e,r){return n(t(e),r)}:t)},Zo.shuffle=function(n){for(var t,e,r=n.length;r;)e=0|Math.random()*r--,t=n[r],n[r]=n[e],n[e]=t;return n},Zo.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},Zo.pairs=function(n){for(var t,e=0,r=n.length-1,u=n[0],i=new Array(0>r?0:r);r>e;)i[e]=[t=u,u=n[++e]];return i},Zo.zip=function(){if(!(u=arguments.length))return[];for(var n=-1,t=Zo.min(arguments,r),e=new Array(t);++n=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var ua=Math.abs;Zo.range=function(n,t,e){if(arguments.length<3&&(e=1,arguments.length<2&&(t=n,n=0)),1/0===(t-n)/e)throw new Error("infinite range");var r,i=[],o=u(ua(e)),a=-1;if(n*=o,t*=o,e*=o,0>e)for(;(r=n+e*++a)>t;)i.push(r/o);else for(;(r=n+e*++a)=i.length)return r?r.call(u,a):e?a.sort(e):a;for(var s,l,f,h,g=-1,p=a.length,v=i[c++],d=new o;++g=i.length)return n;var r=[],u=a[e++];return n.forEach(function(n,u){r.push({key:n,values:t(u,e)})}),u?r.sort(function(n,t){return u(n.key,t.key)}):r}var e,r,u={},i=[],a=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(Zo.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return a[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},Zo.set=function(n){var t=new h;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},i(h,{has:a,add:function(n){return this[ia+n]=!0,n},remove:function(n){return n=ia+n,n in this&&delete this[n]},values:s,size:l,empty:f,forEach:function(n){for(var t in this)t.charCodeAt(0)===oa&&n.call(this,t.substring(1))}}),Zo.behavior={},Zo.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r=0&&(r=n.substring(e+1),n=n.substring(0,e)),n)return arguments.length<2?this[n].on(r):this[n].on(r,t);if(2===arguments.length){if(null==t)for(n in this)this.hasOwnProperty(n)&&this[n].on(r,null);return this}},Zo.event=null,Zo.requote=function(n){return n.replace(ca,"\\$&")};var ca=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,sa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},la=function(n,t){return t.querySelector(n)},fa=function(n,t){return t.querySelectorAll(n)},ha=Bo.matches||Bo[p(Bo,"matchesSelector")],ga=function(n,t){return ha.call(n,t)};"function"==typeof Sizzle&&(la=function(n,t){return Sizzle(n,t)[0]||null},fa=Sizzle,ga=Sizzle.matchesSelector),Zo.selection=function(){return ma};var pa=Zo.selection.prototype=[];pa.select=function(n){var t,e,r,u,i=[];n=b(n);for(var o=-1,a=this.length;++o=0&&(e=n.substring(0,t),n=n.substring(t+1)),va.hasOwnProperty(e)?{space:va[e],local:n}:n}},pa.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=Zo.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(S(t,n[t]));return this}return this.each(S(n,t))},pa.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=A(n)).length,u=-1;if(t=e.classList){for(;++ur){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(z(e,n[e],t));return this}if(2>r)return Wo.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(z(n,t,e))},pa.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(L(t,n[t]));return this}return this.each(L(n,t))},pa.text=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.textContent=null==t?"":t}:null==n?function(){this.textContent=""}:function(){this.textContent=n}):this.node().textContent},pa.html=function(n){return arguments.length?this.each("function"==typeof n?function(){var t=n.apply(this,arguments);this.innerHTML=null==t?"":t}:null==n?function(){this.innerHTML=""}:function(){this.innerHTML=n}):this.node().innerHTML},pa.append=function(n){return n=T(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},pa.insert=function(n,t){return n=T(n),t=b(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},pa.remove=function(){return this.each(function(){var n=this.parentNode;n&&n.removeChild(this)})},pa.data=function(n,t){function e(n,e){var r,u,i,a=n.length,f=e.length,h=Math.min(a,f),g=new Array(f),p=new Array(f),v=new Array(a);if(t){var d,m=new o,y=new o,x=[];for(r=-1;++rr;++r)p[r]=q(e[r]);for(;a>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),s.push(g),l.push(v)}var r,u,i=-1,a=this.length;if(!arguments.length){for(n=new Array(a=(r=this[0]).length);++ii;i++){u.push(t=[]),t.parentNode=(e=this[i]).parentNode;for(var a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return _(u)},pa.order=function(){for(var n=-1,t=this.length;++n=0;)(e=r[u])&&(i&&i!==e.nextSibling&&i.parentNode.insertBefore(e,i),i=e);return this},pa.sort=function(n){n=D.apply(this,arguments);for(var t=-1,e=this.length;++tn;n++)for(var e=this[n],r=0,u=e.length;u>r;r++){var i=e[r];if(i)return i}return null},pa.size=function(){var n=0;return this.each(function(){++n}),n};var da=[];Zo.selection.enter=U,Zo.selection.enter.prototype=da,da.append=pa.append,da.empty=pa.empty,da.node=pa.node,da.call=pa.call,da.size=pa.size,da.select=function(n){for(var t,e,r,u,i,o=[],a=-1,c=this.length;++ar){if("string"!=typeof n){2>r&&(t=!1);for(e in n)this.each(F(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(F(n,t,e))};var ya=Zo.map({mouseenter:"mouseover",mouseleave:"mouseout"});ya.forEach(function(n){"on"+n in $o&&ya.remove(n)});var xa="onselectstart"in $o?null:p(Bo.style,"userSelect"),Ma=0;Zo.mouse=function(n){return Z(n,x())};var _a=/WebKit/.test(Wo.navigator.userAgent)?-1:0;Zo.touches=function(n,t){return arguments.length<2&&(t=x().touches),t?Xo(t).map(function(t){var e=Z(n,t);return e.identifier=t.identifier,e}):[]},Zo.behavior.drag=function(){function n(){this.on("mousedown.drag",u).on("touchstart.drag",i)}function t(n,t,u,i,o){return function(){function a(){var n,e,r=t(h,v);r&&(n=r[0]-x[0],e=r[1]-x[1],p|=n|e,x=r,g({type:"drag",x:r[0]+s[0],y:r[1]+s[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&Zo.event.target===f),g({type:"dragend"}))}var s,l=this,f=Zo.event.target,h=l.parentNode,g=e.of(l,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=Zo.select(u()).on(i+d,a).on(o+d,c),y=I(),x=t(h,v);r?(s=r.apply(l,arguments),s=[s.x-x[0],s.y-x[1]]):s=[0,0],g({type:"dragstart"})}}var e=M(n,"drag","dragstart","dragend"),r=null,u=t(v,Zo.mouse,$,"mousemove","mouseup"),i=t(V,Zo.touch,X,"touchmove","touchend");return n.origin=function(t){return arguments.length?(r=t,n):r},Zo.rebind(n,e,"on")};var ba=Math.PI,wa=2*ba,Sa=ba/2,ka=1e-6,Ea=ka*ka,Aa=ba/180,Ca=180/ba,Na=Math.SQRT2,za=2,La=4;Zo.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=Q(v),o=i/(za*h)*(e*nt(Na*t+v)-K(v));return[r+o*s,u+o*l,i*e/Q(Na*t+v)]}return[r+n*s,u+n*l,i*Math.exp(Na*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],s=o-r,l=a-u,f=s*s+l*l,h=Math.sqrt(f),g=(c*c-i*i+La*f)/(2*i*za*h),p=(c*c-i*i-La*f)/(2*c*za*h),v=Math.log(Math.sqrt(g*g+1)-g),d=Math.log(Math.sqrt(p*p+1)-p),m=d-v,y=(m||Math.log(c/i))/Na;return e.duration=1e3*y,e},Zo.behavior.zoom=function(){function n(n){n.on(A,s).on(Ra+".zoom",f).on("dblclick.zoom",h).on(z,l)}function t(n){return[(n[0]-S.x)/S.k,(n[1]-S.y)/S.k]}function e(n){return[n[0]*S.k+S.x,n[1]*S.k+S.y]}function r(n){S.k=Math.max(E[0],Math.min(E[1],n))}function u(n,t){t=e(t),S.x+=n[0]-t[0],S.y+=n[1]-t[1]}function i(){_&&_.domain(x.range().map(function(n){return(n-S.x)/S.k}).map(x.invert)),w&&w.domain(b.range().map(function(n){return(n-S.y)/S.k}).map(b.invert))}function o(n){n({type:"zoomstart"})}function a(n){i(),n({type:"zoom",scale:S.k,translate:[S.x,S.y]})}function c(n){n({type:"zoomend"})}function s(){function n(){l=1,u(Zo.mouse(r),h),a(s)}function e(){f.on(C,null).on(N,null),g(l&&Zo.event.target===i),c(s)}var r=this,i=Zo.event.target,s=L.of(r,arguments),l=0,f=Zo.select(Wo).on(C,n).on(N,e),h=t(Zo.mouse(r)),g=I();H.call(r),o(s)}function l(){function n(){var n=Zo.touches(g);return h=S.k,n.forEach(function(n){n.identifier in v&&(v[n.identifier]=t(n))}),n}function e(){var t=Zo.event.target;Zo.select(t).on(M,i).on(_,f),b.push(t);for(var e=Zo.event.changedTouches,o=0,c=e.length;c>o;++o)v[e[o].identifier]=null;var s=n(),l=Date.now();if(1===s.length){if(500>l-m){var h=s[0],g=v[h.identifier];r(2*S.k),u(h,g),y(),a(p)}m=l}else if(s.length>1){var h=s[0],x=s[1],w=h[0]-x[0],k=h[1]-x[1];d=w*w+k*k}}function i(){for(var n,t,e,i,o=Zo.touches(g),c=0,s=o.length;s>c;++c,i=null)if(e=o[c],i=v[e.identifier]){if(t)break;n=e,t=i}if(i){var l=(l=e[0]-n[0])*l+(l=e[1]-n[1])*l,f=d&&Math.sqrt(l/d);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*h)}m=null,u(n,t),a(p)}function f(){if(Zo.event.touches.length){for(var t=Zo.event.changedTouches,e=0,r=t.length;r>e;++e)delete v[t[e].identifier];for(var u in v)return void n()}Zo.selectAll(b).on(x,null),w.on(A,s).on(z,l),k(),c(p)}var h,g=this,p=L.of(g,arguments),v={},d=0,x=".zoom-"+Zo.event.changedTouches[0].identifier,M="touchmove"+x,_="touchend"+x,b=[],w=Zo.select(g).on(A,null).on(z,e),k=I();H.call(g),e(),o(p)}function f(){var n=L.of(this,arguments);d?clearTimeout(d):(g=t(p=v||Zo.mouse(this)),H.call(this),o(n)),d=setTimeout(function(){d=null,c(n)},50),y(),r(Math.pow(2,.002*Ta())*S.k),u(p,g),a(n)}function h(){var n=L.of(this,arguments),e=Zo.mouse(this),i=t(e),s=Math.log(S.k)/Math.LN2;o(n),r(Math.pow(2,Zo.event.shiftKey?Math.ceil(s)-1:Math.floor(s)+1)),u(e,i),a(n),c(n)}var g,p,v,d,m,x,_,b,w,S={x:0,y:0,k:1},k=[960,500],E=qa,A="mousedown.zoom",C="mousemove.zoom",N="mouseup.zoom",z="touchstart.zoom",L=M(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=L.of(this,arguments),t=S;Ss?Zo.select(this).transition().each("start.zoom",function(){S=this.__chart__||{x:0,y:0,k:1},o(n)}).tween("zoom:zoom",function(){var e=k[0],r=k[1],u=e/2,i=r/2,o=Zo.interpolateZoom([(u-S.x)/S.k,(i-S.y)/S.k,e/S.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),c=e/r[2];this.__chart__=S={x:u-r[0]*c,y:i-r[1]*c,k:c},a(n)}}).each("end.zoom",function(){c(n)}):(this.__chart__=S,o(n),a(n),c(n))})},n.translate=function(t){return arguments.length?(S={x:+t[0],y:+t[1],k:S.k},i(),n):[S.x,S.y]},n.scale=function(t){return arguments.length?(S={x:S.x,y:S.y,k:+t},i(),n):S.k},n.scaleExtent=function(t){return arguments.length?(E=null==t?qa:[+t[0],+t[1]],n):E},n.center=function(t){return arguments.length?(v=t&&[+t[0],+t[1]],n):v},n.size=function(t){return arguments.length?(k=t&&[+t[0],+t[1]],n):k},n.x=function(t){return arguments.length?(_=t,x=t.copy(),S={x:0,y:0,k:1},n):_},n.y=function(t){return arguments.length?(w=t,b=t.copy(),S={x:0,y:0,k:1},n):w},Zo.rebind(n,L,"on")};var Ta,qa=[0,1/0],Ra="onwheel"in $o?(Ta=function(){return-Zo.event.deltaY*(Zo.event.deltaMode?120:1)},"wheel"):"onmousewheel"in $o?(Ta=function(){return Zo.event.wheelDelta},"mousewheel"):(Ta=function(){return-Zo.event.detail},"MozMousePixelScroll");Zo.color=et,et.prototype.toString=function(){return this.rgb()+""},Zo.hsl=rt;var Da=rt.prototype=new et;Da.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new rt(this.h,this.s,this.l/n)},Da.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new rt(this.h,this.s,n*this.l)},Da.rgb=function(){return ut(this.h,this.s,this.l)},Zo.hcl=it;var Pa=it.prototype=new et;Pa.brighter=function(n){return new it(this.h,this.c,Math.min(100,this.l+Ua*(arguments.length?n:1)))},Pa.darker=function(n){return new it(this.h,this.c,Math.max(0,this.l-Ua*(arguments.length?n:1)))},Pa.rgb=function(){return ot(this.h,this.c,this.l).rgb()},Zo.lab=at;var Ua=18,ja=.95047,Ha=1,Fa=1.08883,Oa=at.prototype=new et;Oa.brighter=function(n){return new at(Math.min(100,this.l+Ua*(arguments.length?n:1)),this.a,this.b)},Oa.darker=function(n){return new at(Math.max(0,this.l-Ua*(arguments.length?n:1)),this.a,this.b)},Oa.rgb=function(){return ct(this.l,this.a,this.b)},Zo.rgb=gt;var Ya=gt.prototype=new et;Ya.brighter=function(n){n=Math.pow(.7,arguments.length?n:1);var t=this.r,e=this.g,r=this.b,u=30;return t||e||r?(t&&u>t&&(t=u),e&&u>e&&(e=u),r&&u>r&&(r=u),new gt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new gt(u,u,u)},Ya.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new gt(n*this.r,n*this.g,n*this.b)},Ya.hsl=function(){return yt(this.r,this.g,this.b)},Ya.toString=function(){return"#"+dt(this.r)+dt(this.g)+dt(this.b)};var Ia=Zo.map({aliceblue:15792383,antiquewhite:16444375,aqua:65535,aquamarine:8388564,azure:15794175,beige:16119260,bisque:16770244,black:0,blanchedalmond:16772045,blue:255,blueviolet:9055202,brown:10824234,burlywood:14596231,cadetblue:6266528,chartreuse:8388352,chocolate:13789470,coral:16744272,cornflowerblue:6591981,cornsilk:16775388,crimson:14423100,cyan:65535,darkblue:139,darkcyan:35723,darkgoldenrod:12092939,darkgray:11119017,darkgreen:25600,darkgrey:11119017,darkkhaki:12433259,darkmagenta:9109643,darkolivegreen:5597999,darkorange:16747520,darkorchid:10040012,darkred:9109504,darksalmon:15308410,darkseagreen:9419919,darkslateblue:4734347,darkslategray:3100495,darkslategrey:3100495,darkturquoise:52945,darkviolet:9699539,deeppink:16716947,deepskyblue:49151,dimgray:6908265,dimgrey:6908265,dodgerblue:2003199,firebrick:11674146,floralwhite:16775920,forestgreen:2263842,fuchsia:16711935,gainsboro:14474460,ghostwhite:16316671,gold:16766720,goldenrod:14329120,gray:8421504,green:32768,greenyellow:11403055,grey:8421504,honeydew:15794160,hotpink:16738740,indianred:13458524,indigo:4915330,ivory:16777200,khaki:15787660,lavender:15132410,lavenderblush:16773365,lawngreen:8190976,lemonchiffon:16775885,lightblue:11393254,lightcoral:15761536,lightcyan:14745599,lightgoldenrodyellow:16448210,lightgray:13882323,lightgreen:9498256,lightgrey:13882323,lightpink:16758465,lightsalmon:16752762,lightseagreen:2142890,lightskyblue:8900346,lightslategray:7833753,lightslategrey:7833753,lightsteelblue:11584734,lightyellow:16777184,lime:65280,limegreen:3329330,linen:16445670,magenta:16711935,maroon:8388608,mediumaquamarine:6737322,mediumblue:205,mediumorchid:12211667,mediumpurple:9662683,mediumseagreen:3978097,mediumslateblue:8087790,mediumspringgreen:64154,mediumturquoise:4772300,mediumvioletred:13047173,midnightblue:1644912,mintcream:16121850,mistyrose:16770273,moccasin:16770229,navajowhite:16768685,navy:128,oldlace:16643558,olive:8421376,olivedrab:7048739,orange:16753920,orangered:16729344,orchid:14315734,palegoldenrod:15657130,palegreen:10025880,paleturquoise:11529966,palevioletred:14381203,papayawhip:16773077,peachpuff:16767673,peru:13468991,pink:16761035,plum:14524637,powderblue:11591910,purple:8388736,red:16711680,rosybrown:12357519,royalblue:4286945,saddlebrown:9127187,salmon:16416882,sandybrown:16032864,seagreen:3050327,seashell:16774638,sienna:10506797,silver:12632256,skyblue:8900331,slateblue:6970061,slategray:7372944,slategrey:7372944,snow:16775930,springgreen:65407,steelblue:4620980,tan:13808780,teal:32896,thistle:14204888,tomato:16737095,turquoise:4251856,violet:15631086,wheat:16113331,white:16777215,whitesmoke:16119285,yellow:16776960,yellowgreen:10145074});Ia.forEach(function(n,t){Ia.set(n,pt(t))}),Zo.functor=bt,Zo.xhr=St(wt),Zo.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=kt(n,t,null==e?r:u(e),i);return o.row=function(n){return arguments.length?o.response(null==(e=n)?r:u(n)):e},o}function r(n){return e.parse(n.responseText)}function u(n){return function(t){return e.parse(t.responseText,n)}}function i(t){return t.map(o).join(n)}function o(n){return a.test(n)?'"'+n.replace(/\"/g,'""')+'"':n}var a=new RegExp('["'+n+"\n]"),c=n.charCodeAt(0);return e.parse=function(n,t){var r;return e.parseRows(n,function(n,e){if(r)return r(n,e-1);var u=new Function("d","return {"+n.map(function(n,t){return JSON.stringify(n)+": d["+t+"]"}).join(",")+"}");r=t?function(n,e){return t(u(n),e)}:u})},e.parseRows=function(n,t){function e(){if(l>=s)return o;if(u)return u=!1,i;var t=l;if(34===n.charCodeAt(t)){for(var e=t;e++l;){var r=n.charCodeAt(l++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(l)&&(++l,++a);else if(r!==c)continue;return n.substring(t,l-a)}return n.substring(t)}for(var r,u,i={},o={},a=[],s=n.length,l=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();(!t||(h=t(h,f++)))&&a.push(h)}return a},e.format=function(t){if(Array.isArray(t[0]))return e.formatRows(t);var r=new h,u=[];return t.forEach(function(n){for(var t in n)r.has(t)||u.push(r.add(t))}),[u.map(o).join(n)].concat(t.map(function(t){return u.map(function(n){return o(t[n])}).join(n)})).join("\n")},e.formatRows=function(n){return n.map(i).join("\n")},e},Zo.csv=Zo.dsv(",","text/csv"),Zo.tsv=Zo.dsv(" ","text/tab-separated-values"),Zo.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=x().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return Z(n,r)};var Za,Va,Xa,$a,Ba,Wa=Wo[p(Wo,"requestAnimationFrame")]||function(n){setTimeout(n,17)};Zo.timer=function(n,t,e){var r=arguments.length;2>r&&(t=0),3>r&&(e=Date.now());var u=e+t,i={c:n,t:u,f:!1,n:null};Va?Va.n=i:Za=i,Va=i,Xa||($a=clearTimeout($a),Xa=1,Wa(At))},Zo.timer.flush=function(){Ct(),Nt()},Zo.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var Ja=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Lt);Zo.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=Zo.round(n,zt(n,t))),e=1+Math.floor(1e-12+Math.log(n)/Math.LN10),e=Math.max(-24,Math.min(24,3*Math.floor((e-1)/3)))),Ja[8+e/3]};var Ga=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,Ka=Zo.map({b:function(n){return n.toString(2)},c:function(n){return String.fromCharCode(n)},o:function(n){return n.toString(8)},x:function(n){return n.toString(16)},X:function(n){return n.toString(16).toUpperCase()},g:function(n,t){return n.toPrecision(t)},e:function(n,t){return n.toExponential(t)},f:function(n,t){return n.toFixed(t)},r:function(n,t){return(n=Zo.round(n,zt(n,t))).toFixed(Math.max(0,Math.min(20,zt(n*(1+1e-15),t))))}}),Qa=Zo.time={},nc=Date;Rt.prototype={getDate:function(){return this._.getUTCDate()},getDay:function(){return this._.getUTCDay()},getFullYear:function(){return this._.getUTCFullYear()},getHours:function(){return this._.getUTCHours()},getMilliseconds:function(){return this._.getUTCMilliseconds()},getMinutes:function(){return this._.getUTCMinutes()},getMonth:function(){return this._.getUTCMonth()},getSeconds:function(){return this._.getUTCSeconds()},getTime:function(){return this._.getTime()},getTimezoneOffset:function(){return 0},valueOf:function(){return this._.valueOf()},setDate:function(){tc.setUTCDate.apply(this._,arguments)},setDay:function(){tc.setUTCDay.apply(this._,arguments)},setFullYear:function(){tc.setUTCFullYear.apply(this._,arguments)},setHours:function(){tc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){tc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){tc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){tc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){tc.setUTCSeconds.apply(this._,arguments)},setTime:function(){tc.setTime.apply(this._,arguments)}};var tc=Date.prototype;Qa.year=Dt(function(n){return n=Qa.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),Qa.years=Qa.year.range,Qa.years.utc=Qa.year.utc.range,Qa.day=Dt(function(n){var t=new nc(2e3,0);return t.setFullYear(n.getFullYear(),n.getMonth(),n.getDate()),t},function(n,t){n.setDate(n.getDate()+t)},function(n){return n.getDate()-1}),Qa.days=Qa.day.range,Qa.days.utc=Qa.day.utc.range,Qa.dayOfYear=function(n){var t=Qa.year(n);return Math.floor((n-t-6e4*(n.getTimezoneOffset()-t.getTimezoneOffset()))/864e5)},["sunday","monday","tuesday","wednesday","thursday","friday","saturday"].forEach(function(n,t){t=7-t;var e=Qa[n]=Dt(function(n){return(n=Qa.day(n)).setDate(n.getDate()-(n.getDay()+t)%7),n},function(n,t){n.setDate(n.getDate()+7*Math.floor(t))},function(n){var e=Qa.year(n).getDay();return Math.floor((Qa.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});Qa[n+"s"]=e.range,Qa[n+"s"].utc=e.utc.range,Qa[n+"OfYear"]=function(n){var e=Qa.year(n).getDay();return Math.floor((Qa.dayOfYear(n)+(e+t)%7)/7)}}),Qa.week=Qa.sunday,Qa.weeks=Qa.sunday.range,Qa.weeks.utc=Qa.sunday.utc.range,Qa.weekOfYear=Qa.sundayOfYear;var ec={"-":"",_:" ",0:"0"},rc=/^\s*\d+/,uc=/^%/;Zo.locale=function(n){return{numberFormat:Tt(n),timeFormat:Ut(n)}};var ic=Zo.locale({decimal:".",thousands:",",grouping:[3],currency:["$",""],dateTime:"%a %b %e %X %Y",date:"%m/%d/%Y",time:"%H:%M:%S",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Zo.format=ic.numberFormat,Zo.geo={},ue.prototype={s:0,t:0,add:function(n){ie(n,this.t,oc),ie(oc.s,this.s,this),this.s?this.t+=oc.t:this.s=oc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var oc=new ue;Zo.geo.stream=function(n,t){n&&ac.hasOwnProperty(n.type)?ac[n.type](n,t):oe(n,t)};var ac={Feature:function(n,t){oe(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++rn?4*ba+n:n,fc.lineStart=fc.lineEnd=fc.point=v}};Zo.geo.bounds=function(){function n(n,t){x.push(M=[l=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=le([t*Aa,e*Aa]);if(m){var u=he(m,r),i=[u[1],-u[0],0],o=he(i,u);ve(o),o=de(o);var c=t-p,s=c>0?1:-1,v=o[0]*Ca*s,d=ua(c)>180;if(d^(v>s*p&&s*t>v)){var y=o[1]*Ca;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>s*p&&s*t>v)){var y=-o[1]*Ca;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t):h>=l?(l>t&&(l=t),t>h&&(h=t)):t>p?a(l,t)>a(l,h)&&(h=t):a(t,h)>a(l,h)&&(l=t)}else n(t,e);m=r,p=t}function e(){_.point=t}function r(){M[0]=l,M[1]=h,_.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=ua(r)>180?r+(r>0?360:-360):r}else v=n,d=e;fc.point(n,e),t(n,e)}function i(){fc.lineStart()}function o(){u(v,d),fc.lineEnd(),ua(y)>ka&&(l=-(h=180)),M[0]=l,M[1]=h,m=null}function a(n,t){return(t-=n)<0?t+360:t}function c(n,t){return n[0]-t[0]}function s(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:nlc?(l=-(h=180),f=-(g=90)):y>ka?g=90:-ka>y&&(f=-90),M[0]=l,M[1]=h}};return function(n){g=h=-(l=f=1/0),x=[],Zo.geo.stream(n,_);var t=x.length;if(t){x.sort(c);for(var e,r=1,u=x[0],i=[u];t>r;++r)e=x[r],s(e[0],u)||s(e[1],u)?(a(u[0],e[1])>a(u[0],u[1])&&(u[1]=e[1]),a(e[0],u[1])>a(u[0],u[1])&&(u[0]=e[0])):i.push(u=e); +for(var o,e,p=-1/0,t=i.length-1,r=0,u=i[t];t>=r;u=e,++r)e=i[r],(o=a(u[1],e[0]))>p&&(p=o,l=e[0],h=u[1])}return x=M=null,1/0===l||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[l,f],[h,g]]}}(),Zo.geo.centroid=function(n){hc=gc=pc=vc=dc=mc=yc=xc=Mc=_c=bc=0,Zo.geo.stream(n,wc);var t=Mc,e=_c,r=bc,u=t*t+e*e+r*r;return Ea>u&&(t=mc,e=yc,r=xc,ka>gc&&(t=pc,e=vc,r=dc),u=t*t+e*e+r*r,Ea>u)?[0/0,0/0]:[Math.atan2(e,t)*Ca,G(r/Math.sqrt(u))*Ca]};var hc,gc,pc,vc,dc,mc,yc,xc,Mc,_c,bc,wc={sphere:v,point:ye,lineStart:Me,lineEnd:_e,polygonStart:function(){wc.lineStart=be},polygonEnd:function(){wc.lineStart=Me}},Sc=Ae(we,Te,Re,[-ba,-ba/2]),kc=1e9;Zo.geo.clipExtent=function(){var n,t,e,r,u,i,o={stream:function(n){return u&&(u.valid=!1),u=i(n),u.valid=!0,u},extent:function(a){return arguments.length?(i=Ue(n=+a[0][0],t=+a[0][1],e=+a[1][0],r=+a[1][1]),u&&(u.valid=!1,u=null),o):[[n,t],[e,r]]}};return o.extent([[0,0],[960,500]])},(Zo.geo.conicEqualArea=function(){return He(Fe)}).raw=Fe,Zo.geo.albers=function(){return Zo.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},Zo.geo.albersUsa=function(){function n(n){var i=n[0],o=n[1];return t=null,e(i,o),t||(r(i,o),t)||u(i,o),t}var t,e,r,u,i=Zo.geo.albers(),o=Zo.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=Zo.geo.conicEqualArea().rotate([157,0]).center([-3,19.9]).parallels([8,18]),c={point:function(n,e){t=[n,e]}};return n.invert=function(n){var t=i.scale(),e=i.translate(),r=(n[0]-e[0])/t,u=(n[1]-e[1])/t;return(u>=.12&&.234>u&&r>=-.425&&-.214>r?o:u>=.166&&.234>u&&r>=-.214&&-.115>r?a:i).invert(n)},n.stream=function(n){var t=i.stream(n),e=o.stream(n),r=a.stream(n);return{point:function(n,u){t.point(n,u),e.point(n,u),r.point(n,u)},sphere:function(){t.sphere(),e.sphere(),r.sphere()},lineStart:function(){t.lineStart(),e.lineStart(),r.lineStart()},lineEnd:function(){t.lineEnd(),e.lineEnd(),r.lineEnd()},polygonStart:function(){t.polygonStart(),e.polygonStart(),r.polygonStart()},polygonEnd:function(){t.polygonEnd(),e.polygonEnd(),r.polygonEnd()}}},n.precision=function(t){return arguments.length?(i.precision(t),o.precision(t),a.precision(t),n):i.precision()},n.scale=function(t){return arguments.length?(i.scale(t),o.scale(.35*t),a.scale(t),n.translate(i.translate())):i.scale()},n.translate=function(t){if(!arguments.length)return i.translate();var s=i.scale(),l=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[l-.455*s,f-.238*s],[l+.455*s,f+.238*s]]).stream(c).point,r=o.translate([l-.307*s,f+.201*s]).clipExtent([[l-.425*s+ka,f+.12*s+ka],[l-.214*s-ka,f+.234*s-ka]]).stream(c).point,u=a.translate([l-.205*s,f+.212*s]).clipExtent([[l-.214*s+ka,f+.166*s+ka],[l-.115*s-ka,f+.234*s-ka]]).stream(c).point,n},n.scale(1070)};var Ec,Ac,Cc,Nc,zc,Lc,Tc={point:v,lineStart:v,lineEnd:v,polygonStart:function(){Ac=0,Tc.lineStart=Oe},polygonEnd:function(){Tc.lineStart=Tc.lineEnd=Tc.point=v,Ec+=ua(Ac/2)}},qc={point:Ye,lineStart:v,lineEnd:v,polygonStart:v,polygonEnd:v},Rc={point:Ve,lineStart:Xe,lineEnd:$e,polygonStart:function(){Rc.lineStart=Be},polygonEnd:function(){Rc.point=Ve,Rc.lineStart=Xe,Rc.lineEnd=$e}};Zo.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),Zo.geo.stream(n,o)),i.result()}function t(){return o=null,n}var e,r,u,i,o,a=4.5;return n.area=function(n){return Ec=0,Zo.geo.stream(n,u(Tc)),Ec},n.centroid=function(n){return pc=vc=dc=mc=yc=xc=Mc=_c=bc=0,Zo.geo.stream(n,u(Rc)),bc?[Mc/bc,_c/bc]:xc?[mc/xc,yc/xc]:dc?[pc/dc,vc/dc]:[0/0,0/0]},n.bounds=function(n){return zc=Lc=-(Cc=Nc=1/0),Zo.geo.stream(n,u(qc)),[[Cc,Nc],[zc,Lc]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||Ge(n):wt,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new Ie:new We(n),"function"!=typeof a&&i.pointRadius(a),t()):r},n.pointRadius=function(t){return arguments.length?(a="function"==typeof t?t:(i.pointRadius(+t),+t),n):a},n.projection(Zo.geo.albersUsa()).context(null)},Zo.geo.transform=function(n){return{stream:function(t){var e=new Ke(t);for(var r in n)e[r]=n[r];return e}}},Ke.prototype={point:function(n,t){this.stream.point(n,t)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}},Zo.geo.projection=nr,Zo.geo.projectionMutator=tr,(Zo.geo.equirectangular=function(){return nr(rr)}).raw=rr.invert=rr,Zo.geo.rotation=function(n){function t(t){return t=n(t[0]*Aa,t[1]*Aa),t[0]*=Ca,t[1]*=Ca,t}return n=ir(n[0]%360*Aa,n[1]*Aa,n.length>2?n[2]*Aa:0),t.invert=function(t){return t=n.invert(t[0]*Aa,t[1]*Aa),t[0]*=Ca,t[1]*=Ca,t},t},ur.invert=rr,Zo.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=ir(-n[0]*Aa,-n[1]*Aa,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Ca,n[1]*=Ca}}),{type:"Polygon",coordinates:[u]}}var t,e,r=[0,0],u=6;return n.origin=function(t){return arguments.length?(r=t,n):r},n.angle=function(r){return arguments.length?(e=sr((t=+r)*Aa,u*Aa),n):t},n.precision=function(r){return arguments.length?(e=sr(t*Aa,(u=+r)*Aa),n):u},n.angle(90)},Zo.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Aa,u=n[1]*Aa,i=t[1]*Aa,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),s=Math.cos(u),l=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=s*l-c*f*a)*e),c*l+s*f*a)},Zo.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return Zo.range(Math.ceil(i/d)*d,u,d).map(h).concat(Zo.range(Math.ceil(s/m)*m,c,m).map(g)).concat(Zo.range(Math.ceil(r/p)*p,e,p).filter(function(n){return ua(n%d)>ka}).map(l)).concat(Zo.range(Math.ceil(a/v)*v,o,v).filter(function(n){return ua(n%m)>ka}).map(f))}var e,r,u,i,o,a,c,s,l,f,h,g,p=10,v=p,d=90,m=360,y=2.5;return n.lines=function(){return t().map(function(n){return{type:"LineString",coordinates:n}})},n.outline=function(){return{type:"Polygon",coordinates:[h(i).concat(g(c).slice(1),h(u).reverse().slice(1),g(s).reverse().slice(1))]}},n.extent=function(t){return arguments.length?n.majorExtent(t).minorExtent(t):n.minorExtent()},n.majorExtent=function(t){return arguments.length?(i=+t[0][0],u=+t[1][0],s=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),s>c&&(t=s,s=c,c=t),n.precision(y)):[[i,s],[u,c]]},n.minorExtent=function(t){return arguments.length?(r=+t[0][0],e=+t[1][0],a=+t[0][1],o=+t[1][1],r>e&&(t=r,r=e,e=t),a>o&&(t=a,a=o,o=t),n.precision(y)):[[r,a],[e,o]]},n.step=function(t){return arguments.length?n.majorStep(t).minorStep(t):n.minorStep()},n.majorStep=function(t){return arguments.length?(d=+t[0],m=+t[1],n):[d,m]},n.minorStep=function(t){return arguments.length?(p=+t[0],v=+t[1],n):[p,v]},n.precision=function(t){return arguments.length?(y=+t,l=fr(a,o,90),f=hr(r,e,y),h=fr(s,c,90),g=hr(i,u,y),n):y},n.majorExtent([[-180,-90+ka],[180,90-ka]]).minorExtent([[-180,-80-ka],[180,80+ka]])},Zo.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=gr,u=pr;return n.distance=function(){return Zo.geo.distance(t||r.apply(this,arguments),e||u.apply(this,arguments))},n.source=function(e){return arguments.length?(r=e,t="function"==typeof e?null:e,n):r},n.target=function(t){return arguments.length?(u=t,e="function"==typeof t?null:t,n):u},n.precision=function(){return arguments.length?n:0},n},Zo.geo.interpolate=function(n,t){return vr(n[0]*Aa,n[1]*Aa,t[0]*Aa,t[1]*Aa)},Zo.geo.length=function(n){return Dc=0,Zo.geo.stream(n,Pc),Dc};var Dc,Pc={sphere:v,point:v,lineStart:dr,lineEnd:v,polygonStart:v,polygonEnd:v},Uc=mr(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(Zo.geo.azimuthalEqualArea=function(){return nr(Uc)}).raw=Uc;var jc=mr(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},wt);(Zo.geo.azimuthalEquidistant=function(){return nr(jc)}).raw=jc,(Zo.geo.conicConformal=function(){return He(yr)}).raw=yr,(Zo.geo.conicEquidistant=function(){return He(xr)}).raw=xr;var Hc=mr(function(n){return 1/n},Math.atan);(Zo.geo.gnomonic=function(){return nr(Hc)}).raw=Hc,Mr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-Sa]},(Zo.geo.mercator=function(){return _r(Mr)}).raw=Mr;var Fc=mr(function(){return 1},Math.asin);(Zo.geo.orthographic=function(){return nr(Fc)}).raw=Fc;var Oc=mr(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(Zo.geo.stereographic=function(){return nr(Oc)}).raw=Oc,br.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-Sa]},(Zo.geo.transverseMercator=function(){var n=_r(br),t=n.center,e=n.rotate;return n.center=function(n){return n?t([-n[1],n[0]]):(n=t(),[n[1],-n[0]])},n.rotate=function(n){return n?e([n[0],n[1],n.length>2?n[2]+90:90]):(n=e(),[n[0],n[1],n[2]-90])},e([0,0,90])}).raw=br,Zo.geom={},Zo.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=bt(e),i=bt(r),o=n.length,a=[],c=[];for(t=0;o>t;t++)a.push([+u.call(this,n[t],t),+i.call(this,n[t],t),t]);for(a.sort(Er),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var s=kr(a),l=kr(c),f=l[0]===s[0],h=l[l.length-1]===s[s.length-1],g=[];for(t=s.length-1;t>=0;--t)g.push(n[a[s[t]][2]]);for(t=+f;t=r&&s.x<=i&&s.y>=u&&s.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];l.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/ka)*ka,y:Math.round(o(n,t)/ka)*ka,i:t}})}var r=wr,u=Sr,i=r,o=u,a=Jc;return n?t(n):(t.links=function(n){return tu(e(n)).edges.filter(function(n){return n.l&&n.r}).map(function(t){return{source:n[t.l.i],target:n[t.r.i]}})},t.triangles=function(n){var t=[];return tu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Hr),c=-1,s=a.length,l=a[s-1].edge,f=l.l===o?l.r:l.l;++c=s,h=r>=l,g=(h<<1)+f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=ou()),f?u=s:a=s,h?o=l:c=l,i(n,t,e,r,u,o,a,c)}var l,f,h,g,p,v,d,m,y,x=bt(a),M=bt(c);if(null!=t)v=t,d=e,m=r,y=u;else if(m=y=-(v=d=1/0),f=[],h=[],p=n.length,o)for(g=0;p>g;++g)l=n[g],l.xm&&(m=l.x),l.y>y&&(y=l.y),f.push(l.x),h.push(l.y);else for(g=0;p>g;++g){var _=+x(l=n[g],g),b=+M(l,g);v>_&&(v=_),d>b&&(d=b),_>m&&(m=_),b>y&&(y=b),f.push(_),h.push(b)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=ou();if(k.add=function(n){i(k,n,+x(n,++g),+M(n,g),v,d,m,y)},k.visit=function(n){au(n,k,v,d,m,y)},g=-1,null==t){for(;++g=0?n.substring(0,t):n,r=t>=0?n.substring(t+1):"in";return e=ns.get(e)||Qc,r=ts.get(r)||wt,pu(r(e.apply(null,Vo.call(arguments,1))))},Zo.interpolateHcl=Au,Zo.interpolateHsl=Cu,Zo.interpolateLab=Nu,Zo.interpolateRound=zu,Zo.transform=function(n){var t=$o.createElementNS(Zo.ns.prefix.svg,"g");return(Zo.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Lu(e?e.matrix:es)})(n)},Lu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var es={a:1,b:0,c:0,d:1,e:0,f:0};Zo.interpolateTransform=Du,Zo.layout={},Zo.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/d){if(p>c){var s=t.charge/c;n.px-=i*s,n.py-=o*s}return!0}if(t.point&&c&&p>c){var s=t.pointCharge/c;n.px-=i*s,n.py-=o*s}}return!t.charge}}function t(n){n.px=Zo.event.x,n.py=Zo.event.y,a.resume()}var e,r,u,i,o,a={},c=Zo.dispatch("start","tick","end"),s=[1,1],l=.9,f=rs,h=us,g=-30,p=is,v=.1,d=.64,m=[],y=[];return a.tick=function(){if((r*=.99)<.005)return c.end({type:"end",alpha:r=0}),!0;var t,e,a,f,h,p,d,x,M,_=m.length,b=y.length;for(e=0;b>e;++e)a=y[e],f=a.source,h=a.target,x=h.x-f.x,M=h.y-f.y,(p=x*x+M*M)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,x*=p,M*=p,h.x-=x*(d=f.weight/(h.weight+f.weight)),h.y-=M*d,f.x+=x*(d=1-d),f.y+=M*d);if((d=r*v)&&(x=s[0]/2,M=s[1]/2,e=-1,d))for(;++e<_;)a=m[e],a.x+=(x-a.x)*d,a.y+=(M-a.y)*d;if(g)for(Vu(t=Zo.geom.quadtree(m),r,o),e=-1;++e<_;)(a=m[e]).fixed||t.visit(n(a));for(e=-1;++e<_;)a=m[e],a.fixed?(a.x=a.px,a.y=a.py):(a.x-=(a.px-(a.px=a.x))*l,a.y-=(a.py-(a.py=a.y))*l);c.tick({type:"tick",alpha:r})},a.nodes=function(n){return arguments.length?(m=n,a):m},a.links=function(n){return arguments.length?(y=n,a):y},a.size=function(n){return arguments.length?(s=n,a):s},a.linkDistance=function(n){return arguments.length?(f="function"==typeof n?n:+n,a):f},a.distance=a.linkDistance,a.linkStrength=function(n){return arguments.length?(h="function"==typeof n?n:+n,a):h},a.friction=function(n){return arguments.length?(l=+n,a):l},a.charge=function(n){return arguments.length?(g="function"==typeof n?n:+n,a):g},a.chargeDistance=function(n){return arguments.length?(p=n*n,a):Math.sqrt(p)},a.gravity=function(n){return arguments.length?(v=+n,a):v},a.theta=function(n){return arguments.length?(d=n*n,a):Math.sqrt(d)},a.alpha=function(n){return arguments.length?(n=+n,r?r=n>0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),Zo.timer(a.tick)),a):r},a.start=function(){function n(n,r){if(!e){for(e=new Array(c),a=0;c>a;++a)e[a]=[];for(a=0;s>a;++a){var u=y[a];e[u.source.index].push(u.target),e[u.target.index].push(u.source)}}for(var i,o=e[t],a=-1,s=o.length;++at;++t)(r=m[t]).index=t,r.weight=0;for(t=0;l>t;++t)r=y[t],"number"==typeof r.source&&(r.source=m[r.source]),"number"==typeof r.target&&(r.target=m[r.target]),++r.source.weight,++r.target.weight;for(t=0;c>t;++t)r=m[t],isNaN(r.x)&&(r.x=n("x",p)),isNaN(r.y)&&(r.y=n("y",v)),isNaN(r.px)&&(r.px=r.x),isNaN(r.py)&&(r.py=r.y);if(u=[],"function"==typeof f)for(t=0;l>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;l>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;l>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;l>t;++t)i[t]=h;if(o=[],"function"==typeof g)for(t=0;c>t;++t)o[t]=+g.call(this,m[t],t);else for(t=0;c>t;++t)o[t]=g;return a.resume()},a.resume=function(){return a.alpha(.1)},a.stop=function(){return a.alpha(0)},a.drag=function(){return e||(e=Zo.behavior.drag().origin(wt).on("dragstart.force",Ou).on("drag.force",t).on("dragend.force",Yu)),arguments.length?(this.on("mouseover.force",Iu).on("mouseout.force",Zu).call(e),void 0):e},Zo.rebind(a,c,"on")};var rs=20,us=1,is=1/0;Zo.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(s=e.call(n,i,i.depth))&&(c=s.length)){for(var c,s,l;--c>=0;)o.push(l=s[c]),l.parent=i,l.depth=i.depth+1;r&&(i.value=0),i.children=s}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Bu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=Gu,e=Wu,r=Ju;return n.sort=function(e){return arguments.length?(t=e,n):t},n.children=function(t){return arguments.length?(e=t,n):e},n.value=function(t){return arguments.length?(r=t,n):r},n.revalue=function(t){return r&&($u(t,function(n){n.children&&(n.value=0)}),Bu(t,function(t){var e;t.children||(t.value=+r.call(n,t,t.depth)||0),(e=t.parent)&&(e.value+=t.value)})),t},n},Zo.layout.partition=function(){function n(t,e,r,u){var i=t.children;if(t.x=e,t.y=t.depth*u,t.dx=r,t.dy=u,i&&(o=i.length)){var o,a,c,s=-1;for(r=t.value?r/t.value:0;++sg;++g)for(u.call(n,s[0][g],p=v[g],l[0][g][1]),h=1;d>h;++h)u.call(n,s[h][g],p+=l[h-1][g][1],l[h][g][1]);return a}var t=wt,e=ei,r=ri,u=ti,i=Qu,o=ni;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:as.get(t)||ei,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:cs.get(t)||ri,n):r},n.x=function(t){return arguments.length?(i=t,n):i},n.y=function(t){return arguments.length?(o=t,n):o},n.out=function(t){return arguments.length?(u=t,n):u},n};var as=Zo.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(ui),i=n.map(ii),o=Zo.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,s=[],l=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],s.push(e)):(c+=i[e],l.push(e));return l.reverse().concat(s)},reverse:function(n){return Zo.range(n.length).reverse()},"default":ei}),cs=Zo.map({silhouette:function(n){var t,e,r,u=n.length,i=n[0].length,o=[],a=0,c=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];r>a&&(a=r),o.push(r)}for(e=0;i>e;++e)c[e]=(a-o[e])/2;return c},wiggle:function(n){var t,e,r,u,i,o,a,c,s,l=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=s=0,e=1;h>e;++e){for(t=0,u=0;l>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];l>t;++t){for(r=0,o=(n[t][e][1]-n[t][e-1][1])/(2*a);t>r;++r)o+=(n[r][e][1]-n[r][e-1][1])/a;i+=o*n[t][e][1]}g[e]=c-=u?i/u*a:0,s>c&&(s=c)}for(e=0;h>e;++e)g[e]-=s;return g},expand:function(n){var t,e,r,u=n.length,i=n[0].length,o=1/u,a=[];for(e=0;i>e;++e){for(t=0,r=0;u>t;t++)r+=n[t][e][1];if(r)for(t=0;u>t;t++)n[t][e][1]/=r;else for(t=0;u>t;t++)n[t][e][1]=o}for(e=0;i>e;++e)a[e]=0;return a},zero:ri});Zo.layout.histogram=function(){function n(n,i){for(var o,a,c=[],s=n.map(e,this),l=r.call(this,s,i),f=u.call(this,l,s,i),i=-1,h=s.length,g=f.length-1,p=t?1:1/h;++i0)for(i=-1;++i=l[0]&&a<=l[1]&&(o=c[Zo.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=si,u=ai;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=bt(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return ci(n,t)}:bt(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},Zo.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],s=u[1],l=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Bu(a,function(n){n.r=+l(n.value)}),Bu(a,pi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/s))/2;Bu(a,function(n){n.r+=f}),Bu(a,pi),Bu(a,function(n){n.r-=f})}return mi(a,c/2,s/2,t?1:1/Math.max(2*a.r/c,2*a.r/s)),o}var t,e=Zo.layout.hierarchy().sort(li),r=0,u=[1,1];return n.size=function(t){return arguments.length?(u=t,n):u},n.radius=function(e){return arguments.length?(t=null==e||"function"==typeof e?e:+e,n):t},n.padding=function(t){return arguments.length?(r=+t,n):r},Xu(n,e)},Zo.layout.tree=function(){function n(n,u){var l=o.call(this,n,u),f=l[0],h=t(f);if(Bu(h,e),h.parent.m=-h.z,$u(h,r),s)$u(f,i);else{var g=f,p=f,v=f;$u(f,function(n){n.xp.x&&(p=n),n.depth>v.depth&&(v=n)});var d=a(g,p)/2-g.x,m=c[0]/(p.x+a(p,g)/2+d),y=c[1]/(v.depth||1);$u(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return l}function t(n){for(var t,e={A:null,children:[n]},r=[e];null!=(t=r.pop());)for(var u,i=t.children,o=0,a=i.length;a>o;++o)r.push((i[o]=u={_:i[o],parent:t,children:(u=i[o].children)&&u.slice()||[],A:null,a:null,z:0,m:0,c:0,s:0,t:null,i:o}).a=u);return e.children[0]}function e(n){var t=n.children,e=n.parent.children,r=n.i?e[n.i-1]:null;if(t.length){wi(n);var i=(t[0].z+t[t.length-1].z)/2;r?(n.z=r.z+a(n._,r._),n.m=n.z-i):n.z=i}else r&&(n.z=r.z+a(n._,r._));n.parent.A=u(n,r,n.parent.A||e[0])}function r(n){n._.x=n.z+n.parent.m,n.m+=n.parent.m}function u(n,t,e){if(t){for(var r,u=n,i=n,o=t,c=u.parent.children[0],s=u.m,l=i.m,f=o.m,h=c.m;o=_i(o),u=Mi(u),o&&u;)c=Mi(c),i=_i(i),i.a=n,r=o.z+f-u.z-s+a(o._,u._),r>0&&(bi(Si(o,n,e),n,r),s+=r,l+=r),f+=o.m,s+=u.m,h+=c.m,l+=i.m;o&&!_i(i)&&(i.t=o,i.m+=f-l),u&&!Mi(c)&&(c.t=u,c.m+=s-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=Zo.layout.hierarchy().sort(null).value(null),a=xi,c=[1,1],s=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(s=null==(c=t)?i:null,n):s?null:c},n.nodeSize=function(t){return arguments.length?(s=null==(c=t)?null:i,n):s?c:null},Xu(n,o)},Zo.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],s=0;Bu(c,function(n){var t=n.children;t&&t.length?(n.x=Ei(t),n.y=ki(t)):(n.x=o?s+=e(n,o):0,n.y=0,o=n)});var l=Ai(c),f=Ci(c),h=l.x-e(l,f)/2,g=f.x+e(f,l)/2;return Bu(c,u?function(n){n.x=(n.x-c.x)*r[0],n.y=(c.y-n.y)*r[1]}:function(n){n.x=(n.x-h)/(g-h)*r[0],n.y=(1-(c.y?n.y/c.y:1))*r[1]}),a}var t=Zo.layout.hierarchy().sort(null).value(null),e=xi,r=[1,1],u=!1;return n.separation=function(t){return arguments.length?(e=t,n):e},n.size=function(t){return arguments.length?(u=null==(r=t),n):u?null:r},n.nodeSize=function(t){return arguments.length?(u=null!=(r=t),n):u?r:null},Xu(n,t)},Zo.layout.treemap=function(){function n(n,t){for(var e,r,u=-1,i=n.length;++ut?0:t),e.area=isNaN(r)||0>=r?0:r}function t(e){var i=e.children;if(i&&i.length){var o,a,c,s=f(e),l=[],h=i.slice(),p=1/0,v="slice"===g?s.dx:"dice"===g?s.dy:"slice-dice"===g?1&e.depth?s.dy:s.dx:Math.min(s.dx,s.dy);for(n(h,s.dx*s.dy/e.value),l.area=0;(c=h.length)>0;)l.push(o=h[c-1]),l.area+=o.area,"squarify"!==g||(a=r(l,v))<=p?(h.pop(),p=a):(l.area-=l.pop().area,u(l,v,s,!1),v=Math.min(s.dx,s.dy),l.length=l.area=0,p=1/0);l.length&&(u(l,v,s,!0),l.length=l.area=0),i.forEach(t)}}function e(t){var r=t.children;if(r&&r.length){var i,o=f(t),a=r.slice(),c=[];for(n(a,o.dx*o.dy/t.value),c.area=0;i=a.pop();)c.push(i),c.area+=i.area,null!=i.z&&(u(c,i.z?o.dx:o.dy,o,!a.length),c.length=c.area=0);r.forEach(e)}}function r(n,t){for(var e,r=n.area,u=0,i=1/0,o=-1,a=n.length;++oe&&(i=e),e>u&&(u=e));return r*=r,t*=t,r?Math.max(t*u*p/r,r/(t*i*p)):1/0}function u(n,t,e,r){var u,i=-1,o=n.length,a=e.x,s=e.y,l=t?c(n.area/t):0;if(t==e.dx){for((r||l>e.dy)&&(l=e.dy);++ie.dx)&&(l=e.dx);++ie&&(t=1),1>e&&(n=0),function(){var e,r,u;do e=2*Math.random()-1,r=2*Math.random()-1,u=e*e+r*r;while(!u||u>1);return n+t*e*Math.sqrt(-2*Math.log(u)/u)}},logNormal:function(){var n=Zo.random.normal.apply(Zo,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=Zo.random.irwinHall(n);return function(){return t()/n}},irwinHall:function(n){return function(){for(var t=0,e=0;n>e;e++)t+=Math.random();return t}}},Zo.scale={};var ss={floor:wt,ceil:wt};Zo.scale.linear=function(){return Ui([0,1],[0,1],hu,!1)};var ls={s:1,g:1,p:1,r:1,e:1};Zo.scale.log=function(){return Vi(Zo.scale.linear().domain([0,1]),10,!0,[1,10])};var fs=Zo.format(".0e"),hs={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};Zo.scale.pow=function(){return Xi(Zo.scale.linear(),1,[0,1])},Zo.scale.sqrt=function(){return Zo.scale.pow().exponent(.5)},Zo.scale.ordinal=function(){return Bi([],{t:"range",a:[[]]})},Zo.scale.category10=function(){return Zo.scale.ordinal().range(gs)},Zo.scale.category20=function(){return Zo.scale.ordinal().range(ps)},Zo.scale.category20b=function(){return Zo.scale.ordinal().range(vs)},Zo.scale.category20c=function(){return Zo.scale.ordinal().range(ds)};var gs=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(vt),ps=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(vt),vs=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(vt),ds=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(vt);Zo.scale.quantile=function(){return Wi([],[])},Zo.scale.quantize=function(){return Ji(0,1,[0,1])},Zo.scale.threshold=function(){return Gi([.5],[0,1])},Zo.scale.identity=function(){return Ki([0,1])},Zo.svg={},Zo.svg.arc=function(){function n(){var n=t.apply(this,arguments),i=e.apply(this,arguments),o=r.apply(this,arguments)+ms,a=u.apply(this,arguments)+ms,c=(o>a&&(c=o,o=a,a=c),a-o),s=ba>c?"0":"1",l=Math.cos(o),f=Math.sin(o),h=Math.cos(a),g=Math.sin(a); +return c>=ys?n?"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"M0,"+n+"A"+n+","+n+" 0 1,0 0,"+-n+"A"+n+","+n+" 0 1,0 0,"+n+"Z":"M0,"+i+"A"+i+","+i+" 0 1,1 0,"+-i+"A"+i+","+i+" 0 1,1 0,"+i+"Z":n?"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L"+n*h+","+n*g+"A"+n+","+n+" 0 "+s+",0 "+n*l+","+n*f+"Z":"M"+i*l+","+i*f+"A"+i+","+i+" 0 "+s+",1 "+i*h+","+i*g+"L0,0"+"Z"}var t=Qi,e=no,r=to,u=eo;return n.innerRadius=function(e){return arguments.length?(t=bt(e),n):t},n.outerRadius=function(t){return arguments.length?(e=bt(t),n):e},n.startAngle=function(t){return arguments.length?(r=bt(t),n):r},n.endAngle=function(t){return arguments.length?(u=bt(t),n):u},n.centroid=function(){var n=(t.apply(this,arguments)+e.apply(this,arguments))/2,i=(r.apply(this,arguments)+u.apply(this,arguments))/2+ms;return[Math.cos(i)*n,Math.sin(i)*n]},n};var ms=-Sa,ys=wa-ka;Zo.svg.line=function(){return ro(wt)};var xs=Zo.map({linear:uo,"linear-closed":io,step:oo,"step-before":ao,"step-after":co,basis:po,"basis-open":vo,"basis-closed":mo,bundle:yo,cardinal:fo,"cardinal-open":so,"cardinal-closed":lo,monotone:So});xs.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var Ms=[0,2/3,1/3,0],_s=[0,1/3,2/3,0],bs=[0,1/6,2/3,1/6];Zo.svg.line.radial=function(){var n=ro(ko);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},ao.reverse=co,co.reverse=ao,Zo.svg.area=function(){return Eo(wt)},Zo.svg.area.radial=function(){var n=Eo(ko);return n.radius=n.x,delete n.x,n.innerRadius=n.x0,delete n.x0,n.outerRadius=n.x1,delete n.x1,n.angle=n.y,delete n.y,n.startAngle=n.y0,delete n.y0,n.endAngle=n.y1,delete n.y1,n},Zo.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),s=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,s)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,s.r,s.p0)+r(s.r,s.p1,s.a1-s.a0)+u(s.r,s.p1,c.r,c.p0))+"Z"}function t(n,t,e,r){var u=t.call(n,e,r),i=a.call(n,u,r),o=c.call(n,u,r)+ms,l=s.call(n,u,r)+ms;return{r:i,a0:o,a1:l,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(l),i*Math.sin(l)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>ba)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=gr,o=pr,a=Ao,c=to,s=eo;return n.radius=function(t){return arguments.length?(a=bt(t),n):a},n.source=function(t){return arguments.length?(i=bt(t),n):i},n.target=function(t){return arguments.length?(o=bt(t),n):o},n.startAngle=function(t){return arguments.length?(c=bt(t),n):c},n.endAngle=function(t){return arguments.length?(s=bt(t),n):s},n},Zo.svg.diagonal=function(){function n(n,u){var i=t.call(this,n,u),o=e.call(this,n,u),a=(i.y+o.y)/2,c=[i,{x:i.x,y:a},{x:o.x,y:a},o];return c=c.map(r),"M"+c[0]+"C"+c[1]+" "+c[2]+" "+c[3]}var t=gr,e=pr,r=Co;return n.source=function(e){return arguments.length?(t=bt(e),n):t},n.target=function(t){return arguments.length?(e=bt(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},Zo.svg.diagonal.radial=function(){var n=Zo.svg.diagonal(),t=Co,e=n.projection;return n.projection=function(n){return arguments.length?e(No(t=n)):t},n},Zo.svg.symbol=function(){function n(n,r){return(ws.get(t.call(this,n,r))||To)(e.call(this,n,r))}var t=Lo,e=zo;return n.type=function(e){return arguments.length?(t=bt(e),n):t},n.size=function(t){return arguments.length?(e=bt(t),n):e},n};var ws=Zo.map({circle:To,cross:function(n){var t=Math.sqrt(n/5)/2;return"M"+-3*t+","+-t+"H"+-t+"V"+-3*t+"H"+t+"V"+-t+"H"+3*t+"V"+t+"H"+t+"V"+3*t+"H"+-t+"V"+t+"H"+-3*t+"Z"},diamond:function(n){var t=Math.sqrt(n/(2*As)),e=t*As;return"M0,"+-t+"L"+e+",0"+" 0,"+t+" "+-e+",0"+"Z"},square:function(n){var t=Math.sqrt(n)/2;return"M"+-t+","+-t+"L"+t+","+-t+" "+t+","+t+" "+-t+","+t+"Z"},"triangle-down":function(n){var t=Math.sqrt(n/Es),e=t*Es/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/Es),e=t*Es/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});Zo.svg.symbolTypes=ws.keys();var Ss,ks,Es=Math.sqrt(3),As=Math.tan(30*Aa),Cs=[],Ns=0;Cs.call=pa.call,Cs.empty=pa.empty,Cs.node=pa.node,Cs.size=pa.size,Zo.transition=function(n){return arguments.length?Ss?n.transition():n:ma.transition()},Zo.transition.prototype=Cs,Cs.select=function(n){var t,e,r,u=this.id,i=[];n=b(n);for(var o=-1,a=this.length;++oi;i++){u.push(t=[]);for(var e=this[i],a=0,c=e.length;c>a;a++)(r=e[a])&&n.call(r,r.__data__,a,i)&&t.push(r)}return qo(u,this.id)},Cs.tween=function(n,t){var e=this.id;return arguments.length<2?this.node().__transition__[e].tween.get(n):P(this,null==t?function(t){t.__transition__[e].tween.remove(n)}:function(r){r.__transition__[e].tween.set(n,t)})},Cs.attr=function(n,t){function e(){this.removeAttribute(a)}function r(){this.removeAttributeNS(a.space,a.local)}function u(n){return null==n?e:(n+="",function(){var t,e=this.getAttribute(a);return e!==n&&(t=o(e,n),function(n){this.setAttribute(a,t(n))})})}function i(n){return null==n?r:(n+="",function(){var t,e=this.getAttributeNS(a.space,a.local);return e!==n&&(t=o(e,n),function(n){this.setAttributeNS(a.space,a.local,t(n))})})}if(arguments.length<2){for(t in n)this.attr(t,n[t]);return this}var o="transform"==n?Du:hu,a=Zo.ns.qualify(n);return Ro(this,"attr."+n,t,a.local?i:u)},Cs.attrTween=function(n,t){function e(n,e){var r=t.call(this,n,e,this.getAttribute(u));return r&&function(n){this.setAttribute(u,r(n))}}function r(n,e){var r=t.call(this,n,e,this.getAttributeNS(u.space,u.local));return r&&function(n){this.setAttributeNS(u.space,u.local,r(n))}}var u=Zo.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Cs.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=Wo.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=hu(u,t),function(t){this.style.setProperty(n,r(t),e)})})}var i=arguments.length;if(3>i){if("string"!=typeof n){2>i&&(t="");for(e in n)this.style(e,n[e],t);return this}e=""}return Ro(this,"style."+n,t,u)},Cs.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,Wo.getComputedStyle(this,null).getPropertyValue(n));return i&&function(t){this.style.setProperty(n,i(t),e)}}return arguments.length<3&&(e=""),this.tween("style."+n,r)},Cs.text=function(n){return Ro(this,"text",n,Do)},Cs.remove=function(){return this.each("end.transition",function(){var n;this.__transition__.count<2&&(n=this.parentNode)&&n.removeChild(this)})},Cs.ease=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].ease:("function"!=typeof n&&(n=Zo.ease.apply(Zo,arguments)),P(this,function(e){e.__transition__[t].ease=n}))},Cs.delay=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].delay:P(this,"function"==typeof n?function(e,r,u){e.__transition__[t].delay=+n.call(e,e.__data__,r,u)}:(n=+n,function(e){e.__transition__[t].delay=n}))},Cs.duration=function(n){var t=this.id;return arguments.length<1?this.node().__transition__[t].duration:P(this,"function"==typeof n?function(e,r,u){e.__transition__[t].duration=Math.max(1,n.call(e,e.__data__,r,u))}:(n=Math.max(1,n),function(e){e.__transition__[t].duration=n}))},Cs.each=function(n,t){var e=this.id;if(arguments.length<2){var r=ks,u=Ss;Ss=e,P(this,function(t,r,u){ks=t.__transition__[e],n.call(t,t.__data__,r,u)}),ks=r,Ss=u}else P(this,function(r){var u=r.__transition__[e];(u.event||(u.event=Zo.dispatch("start","end"))).on(n,t)});return this},Cs.transition=function(){for(var n,t,e,r,u=this.id,i=++Ns,o=[],a=0,c=this.length;c>a;a++){o.push(n=[]);for(var t=this[a],s=0,l=t.length;l>s;s++)(e=t[s])&&(r=Object.create(e.__transition__[u]),r.delay+=r.duration,Po(e,s,i,r)),n.push(e)}return qo(o,i)},Zo.svg.axis=function(){function n(n){n.each(function(){var n,s=Zo.select(this),l=this.__chart__||e,f=this.__chart__=e.copy(),h=null==c?f.ticks?f.ticks.apply(f,a):f.domain():c,g=null==t?f.tickFormat?f.tickFormat.apply(f,a):wt:t,p=s.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",ka),d=Zo.transition(p.exit()).style("opacity",ka).remove(),m=Zo.transition(p.order()).style("opacity",1),y=Ti(f),x=s.selectAll(".domain").data([0]),M=(x.enter().append("path").attr("class","domain"),Zo.transition(x));v.append("line"),v.append("text");var _=v.select("line"),b=m.select("line"),w=p.select("text").text(g),S=v.select("text"),k=m.select("text");switch(r){case"bottom":n=Uo,_.attr("y2",u),S.attr("y",Math.max(u,0)+o),b.attr("x2",0).attr("y2",u),k.attr("x",0).attr("y",Math.max(u,0)+o),w.attr("dy",".71em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+i+"V0H"+y[1]+"V"+i);break;case"top":n=Uo,_.attr("y2",-u),S.attr("y",-(Math.max(u,0)+o)),b.attr("x2",0).attr("y2",-u),k.attr("x",0).attr("y",-(Math.max(u,0)+o)),w.attr("dy","0em").style("text-anchor","middle"),M.attr("d","M"+y[0]+","+-i+"V0H"+y[1]+"V"+-i);break;case"left":n=jo,_.attr("x2",-u),S.attr("x",-(Math.max(u,0)+o)),b.attr("x2",-u).attr("y2",0),k.attr("x",-(Math.max(u,0)+o)).attr("y",0),w.attr("dy",".32em").style("text-anchor","end"),M.attr("d","M"+-i+","+y[0]+"H0V"+y[1]+"H"+-i);break;case"right":n=jo,_.attr("x2",u),S.attr("x",Math.max(u,0)+o),b.attr("x2",u).attr("y2",0),k.attr("x",Math.max(u,0)+o).attr("y",0),w.attr("dy",".32em").style("text-anchor","start"),M.attr("d","M"+i+","+y[0]+"H0V"+y[1]+"H"+i)}if(f.rangeBand){var E=f,A=E.rangeBand()/2;l=f=function(n){return E(n)+A}}else l.rangeBand?l=f:d.call(n,f);v.call(n,l),m.call(n,f)})}var t,e=Zo.scale.linear(),r=zs,u=6,i=6,o=3,a=[10],c=null;return n.scale=function(t){return arguments.length?(e=t,n):e},n.orient=function(t){return arguments.length?(r=t in Ls?t+"":zs,n):r},n.ticks=function(){return arguments.length?(a=arguments,n):a},n.tickValues=function(t){return arguments.length?(c=t,n):c},n.tickFormat=function(e){return arguments.length?(t=e,n):t},n.tickSize=function(t){var e=arguments.length;return e?(u=+t,i=+arguments[e-1],n):u},n.innerTickSize=function(t){return arguments.length?(u=+t,n):u},n.outerTickSize=function(t){return arguments.length?(i=+t,n):i},n.tickPadding=function(t){return arguments.length?(o=+t,n):o},n.tickSubdivide=function(){return arguments.length&&n},n};var zs="bottom",Ls={top:1,right:1,bottom:1,left:1};Zo.svg.brush=function(){function n(i){i.each(function(){var i=Zo.select(this).style("pointer-events","all").style("-webkit-tap-highlight-color","rgba(0,0,0,0)").on("mousedown.brush",u).on("touchstart.brush",u),o=i.selectAll(".background").data([0]);o.enter().append("rect").attr("class","background").style("visibility","hidden").style("cursor","crosshair"),i.selectAll(".extent").data([0]).enter().append("rect").attr("class","extent").style("cursor","move");var a=i.selectAll(".resize").data(p,wt);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Ts[n]}).append("rect").attr("x",function(n){return/[ew]$/.test(n)?-3:null}).attr("y",function(n){return/^[ns]/.test(n)?-3:null}).attr("width",6).attr("height",6).style("visibility","hidden"),a.style("display",n.empty()?"none":null);var l,f=Zo.transition(i),h=Zo.transition(o);c&&(l=Ti(c),h.attr("x",l[0]).attr("width",l[1]-l[0]),e(f)),s&&(l=Ti(s),h.attr("y",l[0]).attr("height",l[1]-l[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+l[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",l[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",l[1]-l[0])}function r(n){n.select(".extent").attr("y",f[0]),n.selectAll(".extent,.e>rect,.w>rect").attr("height",f[1]-f[0])}function u(){function u(){32==Zo.event.keyCode&&(C||(x=null,z[0]-=l[1],z[1]-=f[1],C=2),y())}function p(){32==Zo.event.keyCode&&2==C&&(z[0]+=l[1],z[1]+=f[1],C=0,y())}function v(){var n=Zo.mouse(_),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),C||(Zo.event.altKey?(x||(x=[(l[0]+l[1])/2,(f[0]+f[1])/2]),z[0]=l[+(n[0]p?(u=r,r=p):u=p),v[0]!=r||v[1]!=u?(e?o=null:i=null,v[0]=r,v[1]=u,!0):void 0}function m(){v(),S.style("pointer-events","all").selectAll(".resize").style("display",n.empty()?"none":null),Zo.select("body").style("cursor",null),L.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),N(),w({type:"brushend"})}var x,M,_=this,b=Zo.select(Zo.event.target),w=a.of(_,arguments),S=Zo.select(_),k=b.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&s,C=b.classed("extent"),N=I(),z=Zo.mouse(_),L=Zo.select(Wo).on("keydown.brush",u).on("keyup.brush",p);if(Zo.event.changedTouches?L.on("touchmove.brush",v).on("touchend.brush",m):L.on("mousemove.brush",v).on("mouseup.brush",m),S.interrupt().selectAll("*").interrupt(),C)z[0]=l[0]-z[0],z[1]=f[0]-z[1];else if(k){var T=+/w$/.test(k),q=+/^n/.test(k);M=[l[1-T]-z[0],f[1-q]-z[1]],z[0]=l[T],z[1]=f[q]}else Zo.event.altKey&&(x=z.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),Zo.select("body").style("cursor",b.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=M(n,"brushstart","brush","brushend"),c=null,s=null,l=[0,0],f=[0,0],h=!0,g=!0,p=qs[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:l,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,Ss?Zo.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,l=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=gu(l,t.x),r=gu(f,t.y);return i=o=null,function(u){l=t.x=e(u),f=t.y=r(u),n({type:"brush",mode:"resize"})}}).each("end.brush",function(){i=t.i,o=t.j,n({type:"brush",mode:"resize"}),n({type:"brushend"})}):(n({type:"brushstart"}),n({type:"brush",mode:"resize"}),n({type:"brushend"}))})},n.x=function(t){return arguments.length?(c=t,p=qs[!c<<1|!s],n):c},n.y=function(t){return arguments.length?(s=t,p=qs[!c<<1|!s],n):s},n.clamp=function(t){return arguments.length?(c&&s?(h=!!t[0],g=!!t[1]):c?h=!!t:s&&(g=!!t),n):c&&s?[h,g]:c?h:s?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],s&&(e=e[0],r=r[0]),i=[e,r],c.invert&&(e=c(e),r=c(r)),e>r&&(h=e,e=r,r=h),(e!=l[0]||r!=l[1])&&(l=[e,r])),s&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],s.invert&&(u=s(u),a=s(a)),u>a&&(h=u,u=a,a=h),(u!=f[0]||a!=f[1])&&(f=[u,a])),n):(c&&(i?(e=i[0],r=i[1]):(e=l[0],r=l[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),s&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],s.invert&&(u=s.invert(u),a=s.invert(a)),u>a&&(h=u,u=a,a=h))),c&&s?[[e,u],[r,a]]:c?[e,r]:s&&[u,a])},n.clear=function(){return n.empty()||(l=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&l[0]==l[1]||!!s&&f[0]==f[1]},Zo.rebind(n,a,"on")};var Ts={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},qs=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Rs=Qa.format=ic.timeFormat,Ds=Rs.utc,Ps=Ds("%Y-%m-%dT%H:%M:%S.%LZ");Rs.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Ho:Ps,Ho.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Ho.toString=Ps.toString,Qa.second=Dt(function(n){return new nc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),Qa.seconds=Qa.second.range,Qa.seconds.utc=Qa.second.utc.range,Qa.minute=Dt(function(n){return new nc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),Qa.minutes=Qa.minute.range,Qa.minutes.utc=Qa.minute.utc.range,Qa.hour=Dt(function(n){var t=n.getTimezoneOffset()/60;return new nc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),Qa.hours=Qa.hour.range,Qa.hours.utc=Qa.hour.utc.range,Qa.month=Dt(function(n){return n=Qa.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),Qa.months=Qa.month.range,Qa.months.utc=Qa.month.utc.range;var Us=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],js=[[Qa.second,1],[Qa.second,5],[Qa.second,15],[Qa.second,30],[Qa.minute,1],[Qa.minute,5],[Qa.minute,15],[Qa.minute,30],[Qa.hour,1],[Qa.hour,3],[Qa.hour,6],[Qa.hour,12],[Qa.day,1],[Qa.day,2],[Qa.week,1],[Qa.month,1],[Qa.month,3],[Qa.year,1]],Hs=Rs.multi([[".%L",function(n){return n.getMilliseconds()}],[":%S",function(n){return n.getSeconds()}],["%I:%M",function(n){return n.getMinutes()}],["%I %p",function(n){return n.getHours()}],["%a %d",function(n){return n.getDay()&&1!=n.getDate()}],["%b %d",function(n){return 1!=n.getDate()}],["%B",function(n){return n.getMonth()}],["%Y",we]]),Fs={range:function(n,t,e){return Zo.range(Math.ceil(n/e)*e,+t,e).map(Oo)},floor:wt,ceil:wt};js.year=Qa.year,Qa.scale=function(){return Fo(Zo.scale.linear(),js,Hs)};var Os=js.map(function(n){return[n[0].utc,n[1]]}),Ys=Ds.multi([[".%L",function(n){return n.getUTCMilliseconds()}],[":%S",function(n){return n.getUTCSeconds()}],["%I:%M",function(n){return n.getUTCMinutes()}],["%I %p",function(n){return n.getUTCHours()}],["%a %d",function(n){return n.getUTCDay()&&1!=n.getUTCDate()}],["%b %d",function(n){return 1!=n.getUTCDate()}],["%B",function(n){return n.getUTCMonth()}],["%Y",we]]);Os.year=Qa.year.utc,Qa.scale.utc=function(){return Fo(Zo.scale.linear(),Os,Ys)},Zo.text=St(function(n){return n.responseText}),Zo.json=function(n,t){return kt(n,"application/json",Yo,t)},Zo.html=function(n,t){return kt(n,"text/html",Io,t)},Zo.xml=St(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(Zo):"object"==typeof module&&module.exports&&(module.exports=Zo),this.d3=Zo}(); \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/firstTemp.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/firstTemp.js new file mode 100644 index 00000000000..4956d676ae0 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/firstTemp.js @@ -0,0 +1,26 @@ +/* + * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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 + * + * http://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. + */ + +$(function() { + $("#timeFromCal").datepicker({ + orientation: 'top' + }); + $("#timeToCal").datepicker({ + orientation: 'top' + }); +}); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_exit_fence.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_exit_fence.js new file mode 100644 index 00000000000..db134b4fa4a --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_exit_fence.js @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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 + * + * http://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. + */ + +function initializeExit() { + $(".removeGeoFence").tooltip(); + $("#exit-alert > tbody").empty(); + var serverUrl = "/api/device-mgt/v1.0/geo-services/alerts/Exit"; + invokerUtil.get(serverUrl, function (response) { + if (response) { + response = JSON.parse(response); + } + if (response && response.length) { + $(".fence-not-exist").hide(); + $("#exit-alert").show(); + for (var index in response) { + var alertBean = response[index]; + $("#exit-alert > tbody").append( + "" + alertBean.areaName + "" + + "" + alertBean.queryName + "" + formatDate(new Date(alertBean.createdTime)) + "" + + ""); + } + } else { + $(".fence-not-exist").show(); + $("#exit-alert").hide(); + } + $('.viewGeoFenceRow td:not(:last-child)').click(function () { + viewFence(this.parentElement,'Exit'); + }); + }); +} +initializeExit(); \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_fencing.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_fencing.js new file mode 100644 index 00000000000..4eb89817e14 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_fencing.js @@ -0,0 +1,570 @@ +/* + * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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 + * + * http://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. + */ + +var drawControl; +var speedGraphControl; +var removeAllControl; +var drawnItems; +var lastId; +var controlDiv; +var deleteLayers; +var deleteLayersCount; + +loadGeoFencing(); + +function loadGeoFencing() { + if (map == null) { + setTimeout(loadGeoFencing, 1000); // give everything some time to render + } else { + map.on('draw:created', function (e) { + var type = e.layerType, layer = e.layer; + drawnItems.addLayer(layer); + createPopup(layer,lastId); + }); + } +} + +function openTools(id) { + lastId = id; + if (drawControl) { + try{ + map.removeControl(drawControl); + } catch(e) { + console.log("error: " + e.message); + } + } + if (removeAllControl) { + try { + map.removeControl(removeAllControl); + } catch(e) { + console.log("error: " + e.message); + } + } + if (drawnItems) { + try{ + map.removeLayer(drawnItems); + console.log("removing layer"); + } catch(e) { + console.log("error: " + e.message); + } + } + + closeAll(); + noty({text: "Please draw the required area on the map", type: "information"}); + + L.Control.RemoveAll = L.Control.extend( + { + options: { + position: 'topleft' + }, + onAdd: function (map) { + controlDiv = L.DomUtil.create('div', 'leaflet-draw-toolbar leaflet-bar'); + L.DomEvent + .addListener(controlDiv, 'click', L.DomEvent.stopPropagation) + .addListener(controlDiv, 'click', L.DomEvent.preventDefault) + .addListener(controlDiv, 'click', function () { + controlDiv.remove(); + drawControl.removeFrom(map); + drawnItems.clearLayers(); + if(id == "Prediction"){ + $('#predictionResults').animate({width: ['toggle','swing']},200); + toggeled = false; + } + }); + + var controlUI = L.DomUtil.create('a', 'fa fa-times fa-lg drawControlCloseButton', controlDiv); + $(controlUI).css("background-image", "none"); // Remove default control icon + // TODO: bad usage of .hover() use CSS instead + $(controlUI).mouseenter(function () { + $(this).css("color", "red"); + }).mouseleave(function () { + $(this).css("color", "black") + }); + + controlUI.title = 'Close drawer tools'; + controlUI.href = '#'; + return controlDiv; + } + }); + removeAllControl = new L.Control.RemoveAll(); + map.addControl(removeAllControl); + + // Initialise the FeatureGroup to store editable layers + drawnItems = new L.FeatureGroup(); + map.addLayer(drawnItems); + + if (id=="WithIn") { + // Initialise the draw control and pass it the FeatureGroup of editable layers + drawControl = new L.Control.Draw({ + draw: { + polygon: { + allowIntersection: false, // Restricts shapes to simple polygons + drawError: { + color: '#002bff', // Color the shape will turn when intersects + message: 'Oh snap! you can\'t draw that!' // Message that will show when intersect + }, + shapeOptions: { + color: '#002bff' + } + }, + rectangle: { + shapeOptions: { + color: '#002bff' + } + }, + polyline: false, + circle: false, // Turns off this drawing tool + marker: false // Markers are not applicable for within geo fencing + }, + edit: { + featureGroup: drawnItems + } + }); + } else if (id=="Exit") { + // Initialise the draw control and pass it the FeatureGroup of editable layers + drawControl = new L.Control.Draw({ + draw: { + polygon: { + allowIntersection: false, // Restricts shapes to simple polygons + drawError: { + color: '#ff0043', // Color the shape will turn when intersects + message: 'Oh snap! you can\'t draw that!' // Message that will show when intersect + }, + shapeOptions: { + color: '#ff0043' + } + }, + rectangle: { + shapeOptions: { + color: '#ff0043' + } + }, + polyline: false, + circle: false, // Turns off this drawing tool + marker: false // Markers are not applicable for within geo fencing + }, + edit: { + featureGroup: drawnItems + } + }); + } else if(id=="Stationery"){ + // Initialise the draw control and pass it the FeatureGroup of editable layers + drawControl = new L.Control.Draw({ + draw: { + polygon: { + allowIntersection: false, // Restricts shapes to simple polygons + drawError: { + color: '#e1e100', // Color the shape will turn when intersects + message: 'Oh snap! you can\'t draw that!' // Message that will show when intersect + }, + shapeOptions: { + color: '#e1e100' + } + }, + rectangle: { + shapeOptions: { + color: '#e1e100' + } + }, + polyline: false, + circle: { + shapeOptions: { + color: '#e1e100' + } + }, + marker: false // Markers are not applicable for within geo fencing + }, + edit: { + featureGroup: drawnItems + } + }); + } else if (id=="Traffic") { + // Initialise the draw control and pass it the FeatureGroup of editable layers + drawControl = new L.Control.Draw({ + draw: { + polygon: { + allowIntersection: false, // Restricts shapes to simple polygons + drawError: { + color: '#e1e100', // Color the shape will turn when intersects + message: 'Oh snap! you can\'t draw that!' // Message that will show when intersect + }, + shapeOptions: { + color: '#ff0043' + } + }, + rectangle: { + shapeOptions: { + color: '#002bff' + } + }, + polyline: false, + circle: { + shapeOptions: { + color: '#ff0043' + } + }, + marker: { + shapeOptions: { + color: '#ff0043' + } + } + }, + edit: { + featureGroup: drawnItems + } + }); + } else if (id =="Prediction") { + drawControl = new L.Control.Draw({ + draw: { + polygon: false, + rectangle: false, + polyline: false, + circle: false, + marker: { + shapeOptions: { + color: '#ff0043' + } + } + }, + edit: { + featureGroup: drawnItems + } + }); + console.log("prediction tool opened"); + } + map.addControl(drawControl); + map.on('draw:created', function (e) { + var type = e.layerType, layer = e.layer; + drawnItems.addLayer(layer); + createPopup(layer,lastId); + }); +} + +function createPopup(layer,id) { + if (id=="WithIn") { + var popupTemplate = $('#setWithinAlert'); + popupTemplate.find('#addWithinAlert').attr('leaflet_id', layer._leaflet_id); + } else if (id=="Exit") { + var popupTemplate = $('#setExitAlert'); + popupTemplate.find('#addExitAlert').attr('leaflet_id', layer._leaflet_id); + } else if (id=="Stationery") { + var popupTemplate = $('#setStationeryAlert'); + popupTemplate.find('#addStationeryAlert').attr('leaflet_id', layer._leaflet_id); + } else if (id=="Traffic") { + var popupTemplate = $('#setTrafficAlert'); + popupTemplate.find('#addTrafficAlert').attr('leaflet_id', layer._leaflet_id); + } else if (id=="Prediction") { + getPrediction(layer._leaflet_id); + return; + } + + popupTemplate.find('.exportGeoJson').attr('leaflet_id', layer._leaflet_id); + popupTemplate.find('.editGeoJson').attr('leaflet_id', layer._leaflet_id); + + layer.bindPopup(popupTemplate.html(), {closeOnClick: false, closeButton: false}).openPopup(); + + $(layer._popup._container.childNodes[0]).css("background", "rgba(255,255,255,0.8)"); +} + +function toggleSpeedGraph() { + if (speedGraphControl) { + try { + map.removeControl(speedGraphControl); + speedGraphControl = null; + } catch (e) { + console.log("error: " + e.message); + } + } else { + speedGraphControl = new L.control.speedChart({'position' : 'topright'}); + map.addControl(speedGraphControl); + } +} + +function closeTools(leafletId) { + map.removeLayer(map._layers[leafletId]); + map.removeControl(drawControl); + controlDiv.remove(); +} + +/* Export selected area on the map as a json encoded geoJson standard file, no back-end calls simple HTML5 trick ;) */ +function exportToGeoJSON(element, content) { + // HTML5 features has been used here + var geoJsonData = 'data:application/json;charset=utf-8,' + encodeURIComponent(content); + // TODO: replace closest() by using persistence id for templates, template id prefixed by unique id(i.e leaflet_id) + var fileName = $(element).closest('form').attr('area-name') || 'geoJson'; + var link = document.createElement("a"); + link.download = fileName + '.json'; // Use the fence name given by the user as the file name of the JSON file; + link.href = geoJsonData; + document.body.appendChild(link); + link.click(); + document.body.removeChild(link); + delete link; +} + +$(function () { + $("#importGeoJsonFile").change(function () { + var importedFile = this.files[0]; + var reader = new FileReader(); + reader.readAsText(importedFile); + reader.onload = function (e) { + $("#enterGeoJson").text(e.target.result.toString()); + }; + }); +}); +function importGeoJson() { + var updatedGeoJson; + updatedGeoJson = $('#enterGeoJson').val(); + updateDrawing(updatedGeoJson); +} + +function updateDrawing(updatedGeoJson) { + updatedGeoJson = JSON.parse(updatedGeoJson); + // Pop the last LatLng pair because according to the geoJSON standard it use complete round LatLng set to store polygon coordinates + updatedGeoJson.geometry.coordinates[0].pop(); + var leafletLatLngs = []; + $.each(updatedGeoJson.geometry.coordinates[0], function (idx, pItem) { + leafletLatLngs.push({lat: pItem[1], lng: pItem[0]}); + }); + var polygon = new L.Polygon(leafletLatLngs); + polygon.editing.enable(); + map.addLayer(polygon); + createPopup(polygon); + closeAll(); +} + +var prevLayers = []; +function clearPrevLayers() { + for(var i =0; i < prevLayers.length; i++) { + var prevLayer = prevLayers[i]; + map.removeLayer(prevLayer); + } + prevLayers.length = 0; +} + +function viewFence(geoFenceElement,id) { + if (deleteLayers && !deleteLayersCount) { + clearPrevLayers(); + deleteLayersCount = true; + deleteLayers = false; + } + var geoJson = $(geoFenceElement).attr('data-geoJson'); + var matchResults = /(?:"geoFenceGeoJSON"):"{(.*)}"/g.exec(geoJson); + if (matchResults && matchResults.length > 1) { + geoJson = "{" + matchResults[1] + "}"; + } + geoJson = JSON.parse(geoJson.replace(/'/g, '"')); + var queryName = $(geoFenceElement).attr('data-queryName'); + var areaName = $(geoFenceElement).attr('data-areaName'); + var geometryShape; + var circleOptions = {color: null}; + var polygonOptions = {color: null}; + + if (id == "Exit") { + circleOptions.color = '#ff0043'; + polygonOptions.color = '#ff0043'; + } else if (id == "WithIn") { + circleOptions.color = '#002bff'; + polygonOptions.color = '#002bff'; + } else { + circleOptions.color = '#e1e100'; + polygonOptions.color = '#e1e100'; + } + + if (geoJson.type=="Point") { + geometryShape= new L.circle([geoJson.coordinates[1],geoJson.coordinates[0]], geoJson.radius,circleOptions); + map.addLayer(geometryShape); + prevLayers.push(geometryShape); + } else if (geoJson.type=="Polygon") { + geoJson.coordinates[0].pop(); // popout the last coordinate set(lat,lng pair) due to circular chain + var leafletLatLngs = []; + $.each(geoJson.coordinates[0], function (idx, pItem) { + leafletLatLngs.push({lat: pItem[1], lng: pItem[0]}); + }); + geometryShape = new L.Polygon(leafletLatLngs,polygonOptions); + map.addLayer(geometryShape); + prevLayers.push(geometryShape); + } + + var geoPublicUri = $("#geo-charts").data("geo-public-uri"); + + if (id=="Stationery") { + + var stationeryTime=$(geoFenceElement).attr('data-stationeryTime'); + $('#templateLoader').load(geoPublicUri + "/assets/html_templates/view_fence_popup.html #viewStationeryAlert", function () { + var popupTemplate = $('#templateLoader').find('#viewStationeryAlert'); + popupTemplate.find('#exportGeoJson').attr('leaflet_id', geometryShape._leaflet_id); + popupTemplate.find('#hideViewFence').attr('leaflet_id', geometryShape._leaflet_id); + popupTemplate.find('#viewAreaName').html(areaName); + popupTemplate.find('#stationaryAlertForm').attr('area-name', areaName); + popupTemplate.find('#stationaryAlertForm').attr('query-name', queryName); + popupTemplate.find('#viewAreaTime').html(stationeryTime); + geometryShape.bindPopup(popupTemplate.html(), {closeButton: true}).openPopup(); + $(geometryShape._popup._container.childNodes[0]).css("background", "rgba(255,255,255,0.8)"); + + }); + } else if (id=="WithIn") { + + $('#templateLoader').load(geoPublicUri + "/assets/html_templates/view_fence_popup.html #viewWithinAlert", function () { + var popupTemplate = $('#templateLoader').find('#viewWithinAlert'); + popupTemplate.find('#exportGeoJson').attr('leaflet_id', geometryShape._leaflet_id); + popupTemplate.find('#hideViewFence').attr('leaflet_id', geometryShape._leaflet_id); + popupTemplate.find('#viewAreaName').html(areaName); + popupTemplate.find('#withinAlertForm').attr('area-name', areaName); + popupTemplate.find('#withinAlertForm').attr('query-name', queryName); + geometryShape.bindPopup(popupTemplate.html(), {closeButton: true}).openPopup(); + $(geometryShape._popup._container.childNodes[0]).css("background", "rgba(255,255,255,0.8)"); + }); + } else if (id=="Exit") { + + $('#templateLoader').load(geoPublicUri + "/assets/html_templates/view_fence_popup.html #viewExitAlert", function () { + var popupTemplate = $('#templateLoader').find('#viewExitAlert'); + popupTemplate.find('#exportGeoJson').attr('leaflet_id', geometryShape._leaflet_id); + popupTemplate.find('#hideViewFence').attr('leaflet_id', geometryShape._leaflet_id); + popupTemplate.find('#viewAreaName').html(areaName); + popupTemplate.find('#exitAlertForm').attr('area-name', areaName); + popupTemplate.find('#exitAlertForm').attr('query-name', queryName); + geometryShape.bindPopup(popupTemplate.html(), {closeButton: true}).openPopup(); + $(geometryShape._popup._container.childNodes[0]).css("background", "rgba(255,255,255,0.8)"); + }); + } + closeAll(); +} + +// view all defined fence areas of a particular alert type +function viewAll(id) { + deleteLayers = true; + deleteLayersCount = false; + + var table = null; + if (id == "Exit") { + table = $("#exit-alert > tbody"); + } else if (id == "WithIn") { + table = $("#within-alert > tbody"); + } else { + table = $("#stationary-alert-table > tbody"); + } + + table.find('tr').each(function (i, el) { + viewFence(this,id); + }); +} + +// View all defined fence areas of all alert types +function viewAllFences() { + deleteLayers = true; + deleteLayersCount = false; + initializeExit(); + initializeWithin(); + initStationaryAlert(); + initializeSpeed(); + + var table = $("#exit-alert > tbody"); + table.find('tr').each(function (i, el) { + viewFence(this,'Exit'); + }); + table = $("#within-alert > tbody"); + table.find('tr').each(function (i, el) { + viewFence(this,'WithIn'); + }); + table = $("#stationary-alert-table > tbody"); + table.find('tr').each(function (i, el) { + viewFence(this,'Stationery'); + }); +} + +function viewFenceByData(geoJson, queryName, areaName, stationeryTime, id) { + var matchResults = /(?:"geoFenceGeoJSON"):"{(.*)}"/g.exec(geoJson); + if (matchResults && matchResults.length > 1) { + geoJson = "{" + matchResults[1] + "}"; + } + geoJson = JSON.parse(geoJson.replace(/'/g, '"')); + var geometryShape; + + var circleOptions = {color: null}; + var polygonOptions = {color: null}; + + if (id == "Exit") { + circleOptions.color = '#ff0043'; + polygonOptions.color = '#ff0043'; + } else if (id == "WithIn") { + circleOptions.color = '#002bff'; + polygonOptions.color = '#002bff'; + } else { + circleOptions.color = '#e1e100'; + polygonOptions.color = '#e1e100'; + } + + if (geoJson.type=="Point") { + + geometryShape= new L.circle([geoJson.coordinates[1],geoJson.coordinates[0]], geoJson.radius,circleOptions); + // var marker=new L.marker([geoJson.coordinates[1],geoJson.coordinates[0]]); + map.addLayer(geometryShape); + // map.addLayer(marker); + } else if (geoJson.type=="Polygon") { + geoJson.coordinates[0].pop(); // popout the last coordinate set(lat,lng pair) due to circular chain + var leafletLatLngs = []; + $.each(geoJson.coordinates[0], function (idx, pItem) { + leafletLatLngs.push({lat: pItem[1], lng: pItem[0]}); + }); + geometryShape = new L.Polygon(leafletLatLngs,polygonOptions); + map.addLayer(geometryShape); + } + + var geoPublicUri = $("#geo-charts").data("geo-public-uri"); + + if (id=="Stationery") { + + $('#templateLoader').load(geoPublicUri + "/assets/html_templates/view_fence_popup.html #viewStationeryAlert", function () { + var popupTemplate = $('#templateLoader').find('#viewStationeryAlert'); + popupTemplate.find('#exportGeoJson').attr('leaflet_id', geometryShape._leaflet_id); + popupTemplate.find('#hideViewFence').attr('leaflet_id', geometryShape._leaflet_id); + popupTemplate.find('#viewAreaTime').html(stationeryTime); + geometryShape.bindPopup(popupTemplate.html(), {closeButton: true}).openPopup(); + // transparent the layer .leaflet-popup-content-wrapper + $(geometryShape._popup._container.childNodes[0]).css("background", "rgba(255,255,255,0.8)"); + + }); + } else if (id=="WithIn") { + + $('#templateLoader').load(geoPublicUri + "/assets/html_templates/view_fence_popup.html #viewWithinAlert", function () { + var popupTemplate = $('#templateLoader').find('#viewWithinAlert'); + popupTemplate.find('#exportGeoJson').attr('leaflet_id', geometryShape._leaflet_id); + popupTemplate.find('#hideViewFence').attr('leaflet_id', geometryShape._leaflet_id); + popupTemplate.find('#viewAreaName').html(areaName); + popupTemplate.find('#withinAlertForm').attr('area-name', areaName); + popupTemplate.find('#withinAlertForm').attr('query-name', queryName); + geometryShape.bindPopup(popupTemplate.html(), {closeButton: true}).openPopup(); + // transparent the layer .leaflet-popup-content-wrapper + $(geometryShape._popup._container.childNodes[0]).css("background", "rgba(255,255,255,0.8)"); + }); + } else if (id=="Exit") { + + $('#templateLoader').load(geoPublicUri + "/assets/html_templates/view_fence_popup.html #viewExitAlert", function () { + var popupTemplate = $('#templateLoader').find('#viewExitAlert'); + popupTemplate.find('#exportGeoJson').attr('leaflet_id', geometryShape._leaflet_id); + popupTemplate.find('#hideViewFence').attr('leaflet_id', geometryShape._leaflet_id); + popupTemplate.find('#viewAreaName').html(areaName); + popupTemplate.find('#exitAlertForm').attr('area-name', areaName); + popupTemplate.find('#exitAlertForm').attr('query-name', queryName); + geometryShape.bindPopup(popupTemplate.html(), {closeButton: true}).openPopup(); + // transparent the layer .leaflet-popup-content-wrapper + $(geometryShape._popup._container.childNodes[0]).css("background", "rgba(255,255,255,0.8)"); + }); + } + closeAll(); +} \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_proximity.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_proximity.js new file mode 100644 index 00000000000..ead593168c9 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_proximity.js @@ -0,0 +1,88 @@ +/* + * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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 + * + * http://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. + */ + +var centerLocation = new L.LatLng(6.999833130825296, 79.99855044297874); +var resizeIconLocation = new L.LatLng(6.99847, 80.14412); +var proximityMap = L.map("proximityMap", { + zoom: 10, + center: centerLocation, + zoomControl: false, + attributionControl: false, + maxZoom: 20 + }); +var proximityDistance = $("#proximityDistance"); + +var serverUrl = "/api/device-mgt/v1.0/geo-services/alerts/Proximity"; +invokerUtil.get(serverUrl, function (response) { + response = JSON.parse(response); + proximityDistance.val(response.proximityDistance); + $("#proximityTime").val(response.proximityTime); +}); + +L.grid({ + redraw: 'move' + }).addTo(proximityMap); + +proximityMap.scrollWheelZoom.disable(); + +var marker = L.marker(centerLocation).setIcon(normalMovingIcon); + +marker.addTo(proximityMap); + +var resizeIcon = L.icon({ + iconUrl: ApplicationOptions.leaflet.iconUrls.resizeIcon, + iconAnchor: [24, 24] +}); + +var resizeMarker = L.marker(resizeIconLocation, {icon: resizeIcon, draggable: 'true'}).addTo(proximityMap); +resizeMarker.on('drag', updateRuler); + +var measureLine = new L.Polyline( + [centerLocation, resizeIconLocation ], + { color: "black", opacity: 0.5, stroke: true }); + +proximityMap.addLayer(measureLine); +measureLine._path.setAttribute("class", 'measuring-line-for-look'); + +var options = { + minWidth: 50, + autoPan: false, + closeButton: true, // should the popups have a close option? + displayTotalDistance: true, + displayPartialDistance: false, + className: 'measuring-label-tooltip' /*css label class name*/ +}; + +var initialDistance = centerLocation.distanceTo(resizeIconLocation); + +var measureCircle = L.circle(centerLocation, initialDistance).addTo(proximityMap); + +function updateRuler(e) { + var target = e.target; + resizeIconLocation = target.getLatLng(); + measureLine.setLatLngs([centerLocation, resizeIconLocation]); + setDistancePopup(centerLocation, resizeIconLocation) +} + +function setDistancePopup(startLatLng, endLatLng) { + var centerPos = new L.LatLng((startLatLng.lat + endLatLng.lat) / 2, + (startLatLng.lng + endLatLng.lng) / 2), + distance = startLatLng.distanceTo(endLatLng); + proximityDistance.val(distance.toFixed(2)); + measureCircle.setRadius(distance); +} diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_remote.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_remote.js index 4b65d266d6c..ce78a0a66b8 100644 --- a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_remote.js +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_remote.js @@ -1,5 +1,5 @@ /* - * Copyright (c) 2016, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. * * WSO2 Inc. licenses this file to you under the Apache License, * Version 2.0 (the "License"); you may not use this file except @@ -91,8 +91,481 @@ function getTileServers() { }); } +function addWmsEndPoint() { + serviceName = $('#serviceName').val(); + layers = $('#layers').val(); + wmsVersion = $('#wmsVersion').val(); + serviceEndPoint = $('#serviceEndPoint').val(); + outputFormat = $('#outputFormat').val(); + var validated = false; + + if (serviceName === undefined || serviceName == "" || serviceName == null) { + var message = "Service Provider name cannot be empty."; + noty({text: '' + message + '', type: 'error'}); + } + + if (validated) { + wmsLayer = L.tileLayer.wms(serviceEndPoint, { + layers: layers.split(','), + format: outputFormat ? outputFormat : 'image/png', + version: wmsVersion, + transparent: true, + opacity: 0.4 + }); + + layerControl.addOverlay(wmsLayer, serviceName, "Web Map Service layers"); + map.addLayer(wmsLayer); + + var data = { + 'serviceName': serviceName, + 'layers': layers, + 'wmsVersion': wmsVersion, + 'serviceEndPoint': serviceEndPoint, + 'outputFormat': outputFormat + }; + var serverUrl = "/api/controllers/wms_endpoints"; + // TODO: If failure happens notify user about the error message + $.post(serverUrl, data, function (response) { + noty({ + text: '' + response + '', + type: 'success' + }); + closeAll(); + }); + } + + +} + +function loadWms() { + // For refference {"wmsServerId" : 1, "serviceUrl" : "http://{s}.somedomain.com/blabla/{z}/{x}/{y}.png", "name" : "Sample server URL", "layers" : "asdsad,sd,adasd,asd", "version" : "1.0.2", "format" : "sadasda/asdas"} + $.getJSON("/api/controllers/wms_endpoints?serverId=all", function (data) { + $.each(data, function (key, val) { + + wmsLayer = L.tileLayer.wms(val.SERVICEURL, { + layers: val.LAYERS.split(','), + format: val.FORMAT ? val.FORMAT : 'image/png', + version: val.VERSION, + transparent: true, + opacity: 0.4 + }); + layerControl.addOverlay(wmsLayer, val.NAME, "Web Map Service layers"); + }); + }); +} + +function setSpeedAlert() { + //TODO: get the device Id from the URL + var speedAlertValue = $("#speedAlertValue").val(); + + if (!speedAlertValue) { + var message = "Speed cannot be empty."; + noty({text: message, type: 'error'}); + } else { + data = { + 'parseData': JSON.stringify({ + 'speedAlertValue': speedAlertValue, + 'deviceId': deviceId}), // parseKey : parseValue pair , this key pair is replace with the key in the template file + 'executionPlan': 'Speed', + 'customName': null, + 'cepAction': 'edit', + 'deviceId': deviceId + }; + var serviceUrl = '/api/device-mgt/v1.0/geo-services/alerts/Speed'; + var responseHandler = function (data, textStatus, xhr) { + closeAll(); + if (xhr.status == 200) { + noty({text: 'Successfully added alert', type: 'success'}); + } else { + var ptrn = /(?:)(.*)(?:<\/am\:description>)/g; + var result = (ptrn.exec(data)); + var errorTxt; + if (result) { + errorTxt = result.length > 1 ? result[1] : data; + } else { + errorTxt = data; + } + noty({text: textStatus + ' : ' + errorTxt, type: 'error'}); + } + }; + invokerUtil.put(serviceUrl, + data, + responseHandler, function (xhr) { + responseHandler(xhr.responseText, xhr.statusText, xhr); + }); + } + + +} +var lastToolLeafletId = null; + +function setWithinAlert(leafletId) { + /* + * TODO: replace double quote to single quote because of a conflict when deploying execution plan in CEP + * this is against JSON standards so has been re-replaced when getting the data from governance registry + * (look in get_alerts for .replace() method) + * */ + var selectedAreaGeoJson = JSON.stringify(map._layers[leafletId].toGeoJSON().geometry).replace(/"/g, "'"); + var areaName = $("#withinAlertAreaName").val(); + var queryName = areaName; + + + if (areaName == null || areaName === undefined || areaName == "") { + var message = "Area Name cannot be empty."; + noty({text: message, type: 'error'}); + } else if ($.trim(areaName).indexOf(" ") > -1) { + var message = "Area Name cannot contain spaces."; + noty({text: message, type: 'error'}); + } else { + areaName = $.trim(areaName); + var data = { + 'parseData': JSON.stringify({ + 'geoFenceGeoJSON': selectedAreaGeoJson, + 'areaName': areaName, + 'deviceId': deviceId + }), + 'executionPlan': 'Within', + 'customName': areaName, // TODO: fix , When template copies there can be two queryName and areaName id elements in the DOM + 'queryName': queryName, + 'cepAction': 'deploy', + 'deviceId': deviceId + }; + + var serviceUrl = '/api/device-mgt/v1.0/geo-services/alerts/Within'; + var responseHandler = function (data, textStatus, xhr) { + closeTools(leafletId); + if (xhr.status == 200) { + noty({text: 'Successfully added alert', type: 'success'}); + } else { + var ptrn = /(?:)(.*)(?:<\/am\:description>)/g; + var errorTxt; + var result = (ptrn.exec(data)); + if (result) { + errorTxt = result.length > 1 ? result[1] : data; + } else { + errorTxt = data; + } + noty({text: textStatus + ' : ' + errorTxt, type: 'error'}); + } + }; + invokerUtil.post(serviceUrl, + data, + responseHandler, function (xhr) { + responseHandler(xhr.responseText, xhr.statusText, xhr); + }); + viewFenceByData(selectedAreaGeoJson, queryName, areaName, null, 'WithIn'); + } +} + +function setExitAlert(leafletId) { + /* + * TODO: replace double quote to single quote because of a conflict when deploying execution plan in CEP + * this is against JSON standards so has been re-replaced when getting the data from governance registry + * (look in get_alerts for .replace() method) + * */ + var selectedAreaGeoJson = JSON.stringify(map._layers[leafletId].toGeoJSON().geometry).replace(/"/g, "'"); + var areaName = $("#exitAlertAreaName").val(); + var queryName = areaName; + + + if (areaName == null || areaName === undefined || areaName == "") { + var message = "Area Name cannot be empty."; + noty({text: message, type: 'error'}); + } else if ($.trim(areaName).indexOf(" ") > -1) { + var message = "Area Name cannot contain spaces."; + noty({text: message, type: 'error'}); + } else { + areaName = $.trim(areaName); + var data = { + 'parseData': JSON.stringify({ + 'geoFenceGeoJSON': selectedAreaGeoJson, + 'areaName': areaName, + 'deviceId': deviceId + }), + 'executionPlan': 'Exit', + 'customName': areaName, // TODO: fix , When template copies there can be two queryName and areaName id elements in the DOM + 'queryName': queryName, + 'cepAction': 'deploy', + 'deviceId': deviceId + }; + + var serviceUrl = '/api/device-mgt/v1.0/geo-services/alerts/Exit'; + var responseHandler = function (data, textStatus, xhr) { + closeTools(leafletId); + if (xhr.status == 200) { + noty({text: 'Successfully added alert', type: 'success'}); + } else { + var ptrn = /(?:)(.*)(?:<\/am\:description>)/g; + var errorTxt; + var result = (ptrn.exec(data)); + if (result) { + errorTxt = result.length > 1 ? result[1] : data; + } else { + errorTxt = data; + } + noty({text: textStatus + ' : ' + errorTxt, type: 'error'}); + } + }; + invokerUtil.post(serviceUrl, + data, + responseHandler, function (xhr) { + responseHandler(xhr.responseText, xhr.statusText, xhr); + }); + viewFenceByData(selectedAreaGeoJson, queryName, areaName, null, 'Exit'); + } +} + +function setStationeryAlert(leafletId) { + + var selectedAreaGeoJson = map._layers[leafletId].toGeoJSON().geometry; + + //if a circle is drawn adding radius for the object + if (selectedAreaGeoJson.type == "Point") { + + var radius = map._layers[leafletId]._mRadius; + selectedAreaGeoJson["radius"] = radius; + } + + var selectedProcessedAreaGeoJson = JSON.stringify(selectedAreaGeoJson).replace(/"/g, "'"); + + var stationeryName = $("#stationaryAlertAreaName").val(); + var queryName = stationeryName; + var fluctuationRadius = $("#fRadius").val(); + var time = $("#time").val(); + + if (stationeryName == null || stationeryName === undefined || stationeryName == "") { + var message = "Stationery Name cannot be empty."; + noty({text: message, type: 'error'}); + } else if ($.trim(stationeryName).indexOf(" ") > -1) { + var message = "Stationery Name cannot contain spaces."; + noty({text: message, type: 'error'}); + } else if (fluctuationRadius == null || fluctuationRadius === undefined || fluctuationRadius == "") { + var message = "Fluctuation Radius cannot be empty."; + noty({text: message, type: 'error'}); + } else if (time == null || time === undefined || time == "") { + var message = "Time cannot be empty."; + noty({text: message, type: 'error'}); + } else { + stationeryName = $.trim(stationeryName); + var data = { + 'parseData': JSON.stringify({ + 'geoFenceGeoJSON': selectedProcessedAreaGeoJson, + 'stationeryName': stationeryName, + 'stationeryTime': time, + 'fluctuationRadius': fluctuationRadius + }), + 'stationeryTime': time, + 'fluctuationRadius': fluctuationRadius, + 'executionPlan': 'Stationery', + 'customName': stationeryName, // TODO: fix , When template copies there can be two queryName and areaName id elements in the DOM + 'queryName': queryName, + 'cepAction': 'deploy', + 'deviceId': deviceId + }; + var serviceUrl = '/api/device-mgt/v1.0/geo-services/alerts/Stationery'; + var responseHandler = function (data, textStatus, xhr) { + closeTools(leafletId); + if (xhr.status == 200) { + noty({text: 'Successfully added alert', type: 'success'}); + } else { + var ptrn = /(?:)(.*)(?:<\/am\:description>)/g; + var errorTxt; + var result = (ptrn.exec(data)); + if (result) { + errorTxt = result.length > 1 ? result[1] : data; + } else { + errorTxt = data; + } + noty({text: textStatus + ' : ' + errorTxt, type: 'error'}); + } + }; + invokerUtil.post(serviceUrl, + data, + responseHandler, function (xhr) { + responseHandler(xhr.responseText, xhr.statusText, xhr); + }); + viewFenceByData(selectedProcessedAreaGeoJson, queryName, stationeryName, time, 'Stationery'); + } + + +} + +var toggeled = false; + +function setTrafficAlert(leafletId) { + /* + * TODO: replace double quote to single quote because of a conflict when deploying execution plan in CEP + * this is against JSON standards so has been re-replaced when getting the data from governance registry + * (look in get_alerts for .replace() method) + * */ + var selectedAreaGeoJson = map._layers[leafletId].toGeoJSON().geometry; + + //if a circle is drawn adding radius for the object + if (selectedAreaGeoJson.type == "Point") { + + var radius = map._layers[leafletId]._mRadius; + selectedAreaGeoJson["radius"] = radius; + } + + var selectedProcessedAreaGeoJson = JSON.stringify(selectedAreaGeoJson).replace(/"/g, "'"); + + var areaName = $("#trafficAlertAreaName").val(); + var queryName = areaName; + //var time = $("#time").val(); + + if (areaName == null || areaName === undefined || areaName == "") { + var message = "Area Name cannot be empty."; + noty({text: message, type: 'error'}); + } else if ($.trim(areaName).indexOf(" ") > -1) { + var message = "Area Name cannot contain spaces."; + noty({text: message, type: 'error'}); + } else { + areaName = $.trim(areaName); + var data = { + 'parseData': JSON.stringify({ + 'geoFenceGeoJSON': selectedProcessedAreaGeoJson, + 'areaName': areaName + }), + 'executionPlan': 'Traffic', + 'customName': areaName, // TODO: fix , When template copies there can be two queryName and areaName id elements in the DOM + 'queryName': queryName, + 'cepAction': 'deploy', + 'deviceId': deviceId + }; + + var serviceUrl = '/api/device-mgt/v1.0/geo-services/alerts/Traffic'; + var responseHandler = function (data, textStatus, xhr) { + closeTools(leafletId); + if (xhr.status == 200) { + noty({text: 'Successfully added alert', type: 'success'}); + } else { + var ptrn = /(?:)(.*)(?:<\/am\:description>)/g; + var errorTxt; + var result = (ptrn.exec(data)); + if (result) { + errorTxt = result.length > 1 ? result[1] : data; + } else { + errorTxt = data; + } + noty({text: textStatus + ' : ' + errorTxt, type: 'error'}); + } + }; + invokerUtil.post(serviceUrl, + data, + responseHandler, function (xhr) { + responseHandler(xhr.responseText, xhr.statusText, xhr); + }); + } +} + +function removeGeoFence(geoFenceElement, id) { + var queryName = $(geoFenceElement).attr('data-queryName'); + var areaName = $(geoFenceElement).attr('data-areaName'); + + var serviceUrl = '/api/device-mgt/v1.0/geo-services/alerts/' + id + '?queryName=' + + queryName; + invokerUtil.delete(serviceUrl, function (response) { + noty({ + text: 'Successfully removed ' + id + ' alert', + type: 'success' + }); + closeAll(); + }, + function (xhr) { + noty({ + text: 'Could not remove ' + id + ' alert', + type: 'error' + }) + }); +} + + +function getAlertsHistory(timeFrom, timeTo) { + var timeRange = ''; + if (timeFrom && timeTo) { + timeRange = '?from=' + timeFrom + '&to=' + timeTo; + } + var serviceUrl = '/api/device-mgt/v1.0/geo-services/alerts/history' + timeRange; + invokerUtil.get(serviceUrl, + function (data) { + geoAlertsBar.clearAllAlerts(); + var alerts = JSON.parse(data); + $.each(alerts, function (key, val) { + if (val.values) { + val = val.values; + } + var msg = val.information.replace("Alerts: ,", "").charAt(0).toUpperCase() + + val.information.replace("Alerts: ,", "").slice(1) + " - " + timeSince(val.timeStamp); + switch (val.state) { + case "NORMAL": + return; + case "WARNING": + geoAlertsBar.addAlert('warn', msg, val); + break; + case "ALERTED": + geoAlertsBar.addAlert('danger', msg, val); + break; + case "OFFLINE": + geoAlertsBar.addAlert('info', msg, val); + break; + } + }); + }, function (message) { + }); +} + + +function setProximityAlert() { + + var proximityDistance = $("#proximityDistance").val(); + var proximityTime = $("#proximityTime").val(); + + if (proximityDistance == null || proximityDistance === undefined || proximityDistance == "") { + var message = "Proximity distance cannot be empty."; + noty({text: message, type: 'error'}); + } else if (proximityTime == null || proximityTime === undefined || proximityTime == "") { + var message = "Proximity Time cannot be empty."; + noty({text: message, type: 'error'}); + } else { + var data = { + 'parseData': JSON.stringify({ + 'proximityTime': proximityTime, + 'proximityDistance': proximityDistance + }), + 'proximityTime': proximityTime, + 'proximityDistance': proximityDistance, + 'executionPlan': 'Proximity', + 'customName': null, + 'cepAction': 'edit', + 'deviceId': deviceId + }; + var serviceUrl = '/api/device-mgt/v1.0/geo-services/alerts/Proximity'; + var responseHandler = function (data, textStatus, xhr) { + closeAll(); + if (xhr.status == 200) { + noty({text: 'Successfully added alert', type: 'success'}); + } else { + var ptrn = /(?:)(.*)(?:<\/am\:description>)/g; + var errorTxt; + var result = (ptrn.exec(data)); + if (result) { + errorTxt = result.length > 1 ? result[1] : data; + } else { + errorTxt = data; + } + noty({text: textStatus + ' : ' + errorTxt, type: 'error'}); + } + }; + invokerUtil.put(serviceUrl, + data, + responseHandler, function (xhr) { + responseHandler(xhr.responseText, xhr.statusText, xhr); + }); + + } +} // TODO:this is not a remote call , move this to application.js function closeAll() { diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_speed.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_speed.js new file mode 100644 index 00000000000..905da718d9d --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_speed.js @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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 + * + * http://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. + */ + +function initializeSpeed() { + var serverUrl = "/api/device-mgt/v1.0/geo-services/alerts/Speed"; + // var serverUrl = "/portal/store/carbon.super/fs/gadget/geo-dashboard/controllers/get_alerts.jag?executionPlanType=Speed&deviceId=" + deviceId; + invokerUtil.get(serverUrl, function (response) { + response = JSON.parse(response); + if (response) { + $("#speedAlertValue").val(response.speedLimit); + } + }); +} +initializeSpeed(); diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_stationary.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_stationary.js new file mode 100644 index 00000000000..60facead220 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_stationary.js @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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 + * + * http://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. + */ + +function initStationaryAlert() { + // var serverUrl = "/portal/store/carbon.super/fs/gadget/geo-dashboard/controllers/get_alerts.jag?executionPlanType=Stationery&deviceId=" + deviceId; + var serverUrl = "/api/device-mgt/v1.0/geo-services/alerts/Stationery"; + + $(".removeGeoFence").tooltip(); + $("#stationary-alert-table > tbody").empty(); + invokerUtil.get(serverUrl, function (response) { + if (response) { + response = JSON.parse(response); + } + if (response && response.length) { + $(".fence-not-exist").hide(); + $("#stationary-alert-table").show(); + for (var index in response) { + var alert = response[index]; + $("#stationary-alert-table > tbody").append( + "" + + "" + alert.areaName + "" + alert.stationaryTime + "" + alert.fluctuationRadius + + "" + alert.queryName + "" + formatDate(new Date(alert.createdTime)) + "") + } + } else { + $(".fence-not-exist").show(); + $("#stationary-alert-table").hide(); + } + $('.viewGeoFenceRow td:not(:last-child)').click(function () { + viewFence(this.parentElement,'Stationery'); + }); + }); +} +initStationaryAlert(); \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_within.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_within.js new file mode 100644 index 00000000000..dd875c52e2d --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/geo_within.js @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2018, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you 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 + * + * http://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. + */ + +function initializeWithin() { + $(".removeGeoFence").tooltip(); + $("#within-alert > tbody").empty(); + var serverUrl = "/api/device-mgt/v1.0/geo-services/alerts/Within"; + invokerUtil.get(serverUrl, function (response) { + if (response) { + response = JSON.parse(response); + } + if (response && response.length) { + $(".fence-not-exist").hide(); + $("#within-alert").show(); + for (var index in response) { + var alertBean = response[index]; + $("#within-alert > tbody").append( + "" + alertBean.areaName + "" + + "" + alertBean.queryName + "" + formatDate(new Date(alertBean.createdTime)) + "" + + ""); + } + } else{ + $(".fence-not-exist").show(); + $("#within-alert").hide(); + } + $('.viewGeoFenceRow td:not(:last-child)').click(function () { + viewFence(this.parentElement,'WithIn'); + }); + }); +} +initializeWithin(); \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/jquery/bootstrap-datepicker.min.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/jquery/bootstrap-datepicker.min.js new file mode 100644 index 00000000000..f26d0d86747 --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/jquery/bootstrap-datepicker.min.js @@ -0,0 +1,8 @@ +/*! + * Datepicker for Bootstrap v1.4.0 (https://github.com/eternicode/bootstrap-datepicker) + * + * Copyright 2012 Stefan Petre + * Improvements by Andrew Rowls + * Licensed under the Apache License v2.0 (http://www.apache.org/licenses/LICENSE-2.0) + */ +!function(a,b){function c(){return new Date(Date.UTC.apply(Date,arguments))}function d(){var a=new Date;return c(a.getFullYear(),a.getMonth(),a.getDate())}function e(a,b){return a.getUTCFullYear()===b.getUTCFullYear()&&a.getUTCMonth()===b.getUTCMonth()&&a.getUTCDate()===b.getUTCDate()}function f(a){return function(){return this[a].apply(this,arguments)}}function g(b,c){function d(a,b){return b.toLowerCase()}var e,f=a(b).data(),g={},h=new RegExp("^"+c.toLowerCase()+"([A-Z])");c=new RegExp("^"+c.toLowerCase());for(var i in f)c.test(i)&&(e=i.replace(h,d),g[e]=f[i]);return g}function h(b){var c={};if(p[b]||(b=b.split("-")[0],p[b])){var d=p[b];return a.each(o,function(a,b){b in d&&(c[b]=d[b])}),c}}var i=function(){var b={get:function(a){return this.slice(a)[0]},contains:function(a){for(var b=a&&a.valueOf(),c=0,d=this.length;d>c;c++)if(this[c].valueOf()===b)return c;return-1},remove:function(a){this.splice(a,1)},replace:function(b){b&&(a.isArray(b)||(b=[b]),this.clear(),this.push.apply(this,b))},clear:function(){this.length=0},copy:function(){var a=new i;return a.replace(this),a}};return function(){var c=[];return c.push.apply(c,arguments),a.extend(c,b),c}}(),j=function(b,c){this._process_options(c),this.dates=new i,this.viewDate=this.o.defaultViewDate,this.focusDate=null,this.element=a(b),this.isInline=!1,this.isInput=this.element.is("input"),this.component=this.element.hasClass("date")?this.element.find(".add-on, .input-group-addon, .btn"):!1,this.hasInput=this.component&&this.element.find("input").length,this.component&&0===this.component.length&&(this.component=!1),this.picker=a(q.template),this._buildEvents(),this._attachEvents(),this.isInline?this.picker.addClass("datepicker-inline").appendTo(this.element):this.picker.addClass("datepicker-dropdown dropdown-menu"),this.o.rtl&&this.picker.addClass("datepicker-rtl"),this.viewMode=this.o.startView,this.o.calendarWeeks&&this.picker.find("tfoot .today, tfoot .clear").attr("colspan",function(a,b){return parseInt(b)+1}),this._allow_update=!1,this.setStartDate(this._o.startDate),this.setEndDate(this._o.endDate),this.setDaysOfWeekDisabled(this.o.daysOfWeekDisabled),this.setDatesDisabled(this.o.datesDisabled),this.fillDow(),this.fillMonths(),this._allow_update=!0,this.update(),this.showMode(),this.isInline&&this.show()};j.prototype={constructor:j,_process_options:function(e){this._o=a.extend({},this._o,e);var f=this.o=a.extend({},this._o),g=f.language;switch(p[g]||(g=g.split("-")[0],p[g]||(g=n.language)),f.language=g,f.startView){case 2:case"decade":f.startView=2;break;case 1:case"year":f.startView=1;break;default:f.startView=0}switch(f.minViewMode){case 1:case"months":f.minViewMode=1;break;case 2:case"years":f.minViewMode=2;break;default:f.minViewMode=0}f.startView=Math.max(f.startView,f.minViewMode),f.multidate!==!0&&(f.multidate=Number(f.multidate)||!1,f.multidate!==!1&&(f.multidate=Math.max(0,f.multidate))),f.multidateSeparator=String(f.multidateSeparator),f.weekStart%=7,f.weekEnd=(f.weekStart+6)%7;var h=q.parseFormat(f.format);if(f.startDate!==-1/0&&(f.startDate=f.startDate?f.startDate instanceof Date?this._local_to_utc(this._zero_time(f.startDate)):q.parseDate(f.startDate,h,f.language):-1/0),1/0!==f.endDate&&(f.endDate=f.endDate?f.endDate instanceof Date?this._local_to_utc(this._zero_time(f.endDate)):q.parseDate(f.endDate,h,f.language):1/0),f.daysOfWeekDisabled=f.daysOfWeekDisabled||[],a.isArray(f.daysOfWeekDisabled)||(f.daysOfWeekDisabled=f.daysOfWeekDisabled.split(/[,\s]*/)),f.daysOfWeekDisabled=a.map(f.daysOfWeekDisabled,function(a){return parseInt(a,10)}),f.datesDisabled=f.datesDisabled||[],!a.isArray(f.datesDisabled)){var i=[];i.push(q.parseDate(f.datesDisabled,h,f.language)),f.datesDisabled=i}f.datesDisabled=a.map(f.datesDisabled,function(a){return q.parseDate(a,h,f.language)});var j=String(f.orientation).toLowerCase().split(/\s+/g),k=f.orientation.toLowerCase();if(j=a.grep(j,function(a){return/^auto|left|right|top|bottom$/.test(a)}),f.orientation={x:"auto",y:"auto"},k&&"auto"!==k)if(1===j.length)switch(j[0]){case"top":case"bottom":f.orientation.y=j[0];break;case"left":case"right":f.orientation.x=j[0]}else k=a.grep(j,function(a){return/^left|right$/.test(a)}),f.orientation.x=k[0]||"auto",k=a.grep(j,function(a){return/^top|bottom$/.test(a)}),f.orientation.y=k[0]||"auto";else;if(f.defaultViewDate){var l=f.defaultViewDate.year||(new Date).getFullYear(),m=f.defaultViewDate.month||0,o=f.defaultViewDate.day||1;f.defaultViewDate=c(l,m,o)}else f.defaultViewDate=d();f.showOnFocus=f.showOnFocus!==b?f.showOnFocus:!0},_events:[],_secondaryEvents:[],_applyEvents:function(a){for(var c,d,e,f=0;fe?(this.picker.addClass("datepicker-orient-right"),n=k.left+m-b):this.picker.addClass("datepicker-orient-left");var p,q,r=this.o.orientation.y;if("auto"===r&&(p=-g+o-c,q=g+f-(o+l+c),r=Math.max(p,q)===q?"top":"bottom"),this.picker.addClass("datepicker-orient-"+r),"top"===r?o+=l:o-=c+parseInt(this.picker.css("padding-top")),this.o.rtl){var s=e-(n+m);this.picker.css({top:o,right:s,zIndex:j})}else this.picker.css({top:o,left:n,zIndex:j});return this},_allow_update:!0,update:function(){if(!this._allow_update)return this;var b=this.dates.copy(),c=[],d=!1;return arguments.length?(a.each(arguments,a.proxy(function(a,b){b instanceof Date&&(b=this._local_to_utc(b)),c.push(b)},this)),d=!0):(c=this.isInput?this.element.val():this.element.data("date")||this.element.find("input").val(),c=c&&this.o.multidate?c.split(this.o.multidateSeparator):[c],delete this.element.data().date),c=a.map(c,a.proxy(function(a){return q.parseDate(a,this.o.format,this.o.language)},this)),c=a.grep(c,a.proxy(function(a){return athis.o.endDate||!a},this),!0),this.dates.replace(c),this.dates.length?this.viewDate=new Date(this.dates.get(-1)):this.viewDatethis.o.endDate&&(this.viewDate=new Date(this.o.endDate)),d?this.setValue():c.length&&String(b)!==String(this.dates)&&this._trigger("changeDate"),!this.dates.length&&b.length&&this._trigger("clearDate"),this.fill(),this},fillDow:function(){var a=this.o.weekStart,b="";if(this.o.calendarWeeks){this.picker.find(".datepicker-days thead tr:first-child .datepicker-switch").attr("colspan",function(a,b){return parseInt(b)+1});var c=' ';b+=c}for(;a'+p[this.o.language].daysMin[a++%7]+"";b+="",this.picker.find(".datepicker-days thead").append(b)},fillMonths:function(){for(var a="",b=0;12>b;)a+=''+p[this.o.language].monthsShort[b++]+"";this.picker.find(".datepicker-months td").html(a)},setRange:function(b){b&&b.length?this.range=a.map(b,function(a){return a.valueOf()}):delete this.range,this.fill()},getClassNames:function(b){var c=[],d=this.viewDate.getUTCFullYear(),f=this.viewDate.getUTCMonth(),g=new Date;return b.getUTCFullYear()d||b.getUTCFullYear()===d&&b.getUTCMonth()>f)&&c.push("new"),this.focusDate&&b.valueOf()===this.focusDate.valueOf()&&c.push("focused"),this.o.todayHighlight&&b.getUTCFullYear()===g.getFullYear()&&b.getUTCMonth()===g.getMonth()&&b.getUTCDate()===g.getDate()&&c.push("today"),-1!==this.dates.contains(b)&&c.push("active"),(b.valueOf()this.o.endDate||-1!==a.inArray(b.getUTCDay(),this.o.daysOfWeekDisabled))&&c.push("disabled"),this.o.datesDisabled.length>0&&a.grep(this.o.datesDisabled,function(a){return e(b,a)}).length>0&&c.push("disabled","disabled-date"),this.range&&(b>this.range[0]&&b"),this.o.calendarWeeks)){var u=new Date(+n+(this.o.weekStart-n.getUTCDay()-7)%7*864e5),v=new Date(Number(u)+(11-u.getUTCDay())%7*864e5),w=new Date(Number(w=c(v.getUTCFullYear(),0,1))+(11-w.getUTCDay())%7*864e5),x=(v-w)/864e5/7+1;t.push(''+x+"")}if(s=this.getClassNames(n),s.push("day"),this.o.beforeShowDay!==a.noop){var y=this.o.beforeShowDay(this._utc_to_local(n));y===b?y={}:"boolean"==typeof y?y={enabled:y}:"string"==typeof y&&(y={classes:y}),y.enabled===!1&&s.push("disabled"),y.classes&&(s=s.concat(y.classes.split(/\s+/))),y.tooltip&&(d=y.tooltip)}s=a.unique(s),t.push('"+n.getUTCDate()+""),d=null,n.getUTCDay()===this.o.weekEnd&&t.push(""),n.setUTCDate(n.getUTCDate()+1)}this.picker.find(".datepicker-days tbody").empty().append(t.join(""));var z=this.picker.find(".datepicker-months").find("th:eq(1)").text(f).end().find("span").removeClass("active");if(a.each(this.dates,function(a,b){b.getUTCFullYear()===f&&z.eq(b.getUTCMonth()).addClass("active")}),(h>f||f>j)&&z.addClass("disabled"),f===h&&z.slice(0,i).addClass("disabled"),f===j&&z.slice(k+1).addClass("disabled"),this.o.beforeShowMonth!==a.noop){var A=this;a.each(z,function(b,c){if(!a(c).hasClass("disabled")){var d=new Date(f,b,1),e=A.o.beforeShowMonth(d);e===!1&&a(c).addClass("disabled")}})}t="",f=10*parseInt(f/10,10);var B=this.picker.find(".datepicker-years").find("th:eq(1)").text(f+"-"+(f+9)).end().find("td");f-=1;for(var C,D=a.map(this.dates,function(a){return a.getUTCFullYear()}),E=-1;11>E;E++)C=["year"],-1===E?C.push("old"):10===E&&C.push("new"),-1!==a.inArray(f,D)&&C.push("active"),(h>f||f>j)&&C.push("disabled"),t+=''+f+"",f+=1;B.html(t)}},updateNavArrows:function(){if(this._allow_update){var a=new Date(this.viewDate),b=a.getUTCFullYear(),c=a.getUTCMonth();switch(this.viewMode){case 0:this.picker.find(".prev").css(this.o.startDate!==-1/0&&b<=this.o.startDate.getUTCFullYear()&&c<=this.o.startDate.getUTCMonth()?{visibility:"hidden"}:{visibility:"visible"}),this.picker.find(".next").css(1/0!==this.o.endDate&&b>=this.o.endDate.getUTCFullYear()&&c>=this.o.endDate.getUTCMonth()?{visibility:"hidden"}:{visibility:"visible"});break;case 1:case 2:this.picker.find(".prev").css(this.o.startDate!==-1/0&&b<=this.o.startDate.getUTCFullYear()?{visibility:"hidden"}:{visibility:"visible"}),this.picker.find(".next").css(1/0!==this.o.endDate&&b>=this.o.endDate.getUTCFullYear()?{visibility:"hidden"}:{visibility:"visible"})}}},click:function(b){b.preventDefault();var d,e,f,g=a(b.target).closest("span, td, th");if(1===g.length)switch(g[0].nodeName.toLowerCase()){case"th":switch(g[0].className){case"datepicker-switch":this.showMode(1);break;case"prev":case"next":var h=q.modes[this.viewMode].navStep*("prev"===g[0].className?-1:1);switch(this.viewMode){case 0:this.viewDate=this.moveMonth(this.viewDate,h),this._trigger("changeMonth",this.viewDate);break;case 1:case 2:this.viewDate=this.moveYear(this.viewDate,h),1===this.viewMode&&this._trigger("changeYear",this.viewDate)}this.fill();break;case"today":var i=new Date;i=c(i.getFullYear(),i.getMonth(),i.getDate(),0,0,0),this.showMode(-2);var j="linked"===this.o.todayBtn?null:"view";this._setDate(i,j);break;case"clear":this.clearDates()}break;case"span":g.hasClass("disabled")||(this.viewDate.setUTCDate(1),g.hasClass("month")?(f=1,e=g.parent().find("span").index(g),d=this.viewDate.getUTCFullYear(),this.viewDate.setUTCMonth(e),this._trigger("changeMonth",this.viewDate),1===this.o.minViewMode&&this._setDate(c(d,e,f))):(f=1,e=0,d=parseInt(g.text(),10)||0,this.viewDate.setUTCFullYear(d),this._trigger("changeYear",this.viewDate),2===this.o.minViewMode&&this._setDate(c(d,e,f))),this.showMode(-1),this.fill());break;case"td":g.hasClass("day")&&!g.hasClass("disabled")&&(f=parseInt(g.text(),10)||1,d=this.viewDate.getUTCFullYear(),e=this.viewDate.getUTCMonth(),g.hasClass("old")?0===e?(e=11,d-=1):e-=1:g.hasClass("new")&&(11===e?(e=0,d+=1):e+=1),this._setDate(c(d,e,f)))}this.picker.is(":visible")&&this._focused_from&&a(this._focused_from).focus(),delete this._focused_from},_toggle_multidate:function(a){var b=this.dates.contains(a);if(a||this.dates.clear(),-1!==b?(this.o.multidate===!0||this.o.multidate>1||this.o.toggleActive)&&this.dates.remove(b):this.o.multidate===!1?(this.dates.clear(),this.dates.push(a)):this.dates.push(a),"number"==typeof this.o.multidate)for(;this.dates.length>this.o.multidate;)this.dates.remove(0)},_setDate:function(a,b){b&&"date"!==b||this._toggle_multidate(a&&new Date(a)),b&&"view"!==b||(this.viewDate=a&&new Date(a)),this.fill(),this.setValue(),b&&"view"===b||this._trigger("changeDate");var c;this.isInput?c=this.element:this.component&&(c=this.element.find("input")),c&&c.change(),!this.o.autoclose||b&&"date"!==b||this.hide()},moveMonth:function(a,c){if(!a)return b;if(!c)return a;var d,e,f=new Date(a.valueOf()),g=f.getUTCDate(),h=f.getUTCMonth(),i=Math.abs(c);if(c=c>0?1:-1,1===i)e=-1===c?function(){return f.getUTCMonth()===h}:function(){return f.getUTCMonth()!==d},d=h+c,f.setUTCMonth(d),(0>d||d>11)&&(d=(d+12)%12);else{for(var j=0;i>j;j++)f=this.moveMonth(f,c);d=f.getUTCMonth(),f.setUTCDate(g),e=function(){return d!==f.getUTCMonth()}}for(;e();)f.setUTCDate(--g),f.setUTCMonth(d);return f},moveYear:function(a,b){return this.moveMonth(a,12*b)},dateWithinRange:function(a){return a>=this.o.startDate&&a<=this.o.endDate},keydown:function(a){if(!this.picker.is(":visible"))return void(27===a.keyCode&&this.show());var b,c,e,f=!1,g=this.focusDate||this.viewDate;switch(a.keyCode){case 27:this.focusDate?(this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill()):this.hide(),a.preventDefault();break;case 37:case 39:if(!this.o.keyboardNavigation)break;b=37===a.keyCode?-1:1,a.ctrlKey?(c=this.moveYear(this.dates.get(-1)||d(),b),e=this.moveYear(g,b),this._trigger("changeYear",this.viewDate)):a.shiftKey?(c=this.moveMonth(this.dates.get(-1)||d(),b),e=this.moveMonth(g,b),this._trigger("changeMonth",this.viewDate)):(c=new Date(this.dates.get(-1)||d()),c.setUTCDate(c.getUTCDate()+b),e=new Date(g),e.setUTCDate(g.getUTCDate()+b)),this.dateWithinRange(e)&&(this.focusDate=this.viewDate=e,this.setValue(),this.fill(),a.preventDefault());break;case 38:case 40:if(!this.o.keyboardNavigation)break;b=38===a.keyCode?-1:1,a.ctrlKey?(c=this.moveYear(this.dates.get(-1)||d(),b),e=this.moveYear(g,b),this._trigger("changeYear",this.viewDate)):a.shiftKey?(c=this.moveMonth(this.dates.get(-1)||d(),b),e=this.moveMonth(g,b),this._trigger("changeMonth",this.viewDate)):(c=new Date(this.dates.get(-1)||d()),c.setUTCDate(c.getUTCDate()+7*b),e=new Date(g),e.setUTCDate(g.getUTCDate()+7*b)),this.dateWithinRange(e)&&(this.focusDate=this.viewDate=e,this.setValue(),this.fill(),a.preventDefault());break;case 32:break;case 13:g=this.focusDate||this.dates.get(-1)||this.viewDate,this.o.keyboardNavigation&&(this._toggle_multidate(g),f=!0),this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.setValue(),this.fill(),this.picker.is(":visible")&&(a.preventDefault(),"function"==typeof a.stopPropagation?a.stopPropagation():a.cancelBubble=!0,this.o.autoclose&&this.hide());break;case 9:this.focusDate=null,this.viewDate=this.dates.get(-1)||this.viewDate,this.fill(),this.hide()}if(f){this._trigger(this.dates.length?"changeDate":"clearDate");var h;this.isInput?h=this.element:this.component&&(h=this.element.find("input")),h&&h.change()}},showMode:function(a){a&&(this.viewMode=Math.max(this.o.minViewMode,Math.min(2,this.viewMode+a))),this.picker.children("div").hide().filter(".datepicker-"+q.modes[this.viewMode].clsName).css("display","block"),this.updateNavArrows()}};var k=function(b,c){this.element=a(b),this.inputs=a.map(c.inputs,function(a){return a.jquery?a[0]:a}),delete c.inputs,m.call(a(this.inputs),c).bind("changeDate",a.proxy(this.dateUpdated,this)),this.pickers=a.map(this.inputs,function(b){return a(b).data("datepicker")}),this.updateDates()};k.prototype={updateDates:function(){this.dates=a.map(this.pickers,function(a){return a.getUTCDate()}),this.updateRanges()},updateRanges:function(){var b=a.map(this.dates,function(a){return a.valueOf()});a.each(this.pickers,function(a,c){c.setRange(b)})},dateUpdated:function(b){if(!this.updating){this.updating=!0;var c=a(b.target).data("datepicker"),d=c.getUTCDate(),e=a.inArray(b.target,this.inputs),f=e-1,g=e+1,h=this.inputs.length;if(-1!==e){if(a.each(this.pickers,function(a,b){b.getUTCDate()||b.setUTCDate(d)}),d=0&&dthis.dates[g])for(;h>g&&d>this.dates[g];)this.pickers[g++].setUTCDate(d);this.updateDates(),delete this.updating}}},remove:function(){a.map(this.pickers,function(a){a.remove()}),delete this.element.data().datepicker}};var l=a.fn.datepicker,m=function(c){var d=Array.apply(null,arguments);d.shift();var e;return this.each(function(){var f=a(this),i=f.data("datepicker"),l="object"==typeof c&&c;if(!i){var m=g(this,"date"),o=a.extend({},n,m,l),p=h(o.language),q=a.extend({},n,p,m,l);if(f.hasClass("input-daterange")||q.inputs){var r={inputs:q.inputs||f.find("input").toArray()};f.data("datepicker",i=new k(this,a.extend(q,r)))}else f.data("datepicker",i=new j(this,q))}return"string"==typeof c&&"function"==typeof i[c]&&(e=i[c].apply(i,d),e!==b)?!1:void 0}),e!==b?e:this};a.fn.datepicker=m;var n=a.fn.datepicker.defaults={autoclose:!1,beforeShowDay:a.noop,beforeShowMonth:a.noop,calendarWeeks:!1,clearBtn:!1,toggleActive:!1,daysOfWeekDisabled:[],datesDisabled:[],endDate:1/0,forceParse:!0,format:"mm/dd/yyyy",keyboardNavigation:!0,language:"en",minViewMode:0,multidate:!1,multidateSeparator:",",orientation:"auto",rtl:!1,startDate:-1/0,startView:0,todayBtn:!1,todayHighlight:!1,weekStart:0,disableTouchKeyboard:!1,enableOnReadonly:!0,container:"body"},o=a.fn.datepicker.locale_opts=["format","rtl","weekStart"];a.fn.datepicker.Constructor=j;var p=a.fn.datepicker.dates={en:{days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday","Sunday"],daysShort:["Sun","Mon","Tue","Wed","Thu","Fri","Sat","Sun"],daysMin:["Su","Mo","Tu","We","Th","Fr","Sa","Su"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],monthsShort:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],today:"Today",clear:"Clear"}},q={modes:[{clsName:"days",navFnc:"Month",navStep:1},{clsName:"months",navFnc:"FullYear",navStep:1},{clsName:"years",navFnc:"FullYear",navStep:10}],isLeapYear:function(a){return a%4===0&&a%100!==0||a%400===0},getDaysInMonth:function(a,b){return[31,q.isLeapYear(a)?29:28,31,30,31,30,31,31,30,31,30,31][b]},validParts:/dd?|DD?|mm?|MM?|yy(?:yy)?/g,nonpunctuation:/[^ -\/:-@\[\u3400-\u9fff-`{-~\t\n\r]+/g,parseFormat:function(a){var b=a.replace(this.validParts,"\x00").split("\x00"),c=a.match(this.validParts);if(!b||!b.length||!c||0===c.length)throw new Error("Invalid date format.");return{separators:b,parts:c}},parseDate:function(d,e,f){function g(){var a=this.slice(0,m[k].length),b=m[k].slice(0,a.length);return a.toLowerCase()===b.toLowerCase()}if(!d)return b;if(d instanceof Date)return d;"string"==typeof e&&(e=q.parseFormat(e));var h,i,k,l=/([\-+]\d+)([dmwy])/,m=d.match(/([\-+]\d+)([dmwy])/g);if(/^[\-+]\d+[dmwy]([\s,]+[\-+]\d+[dmwy])*$/.test(d)){for(d=new Date,k=0;kb;)b+=12;for(b%=12,a.setUTCMonth(b);a.getUTCMonth()!==b;)a.setUTCDate(a.getUTCDate()-1);return a},d:function(a,b){return a.setUTCDate(b)}};t.M=t.MM=t.mm=t.m,t.dd=t.d,d=c(d.getFullYear(),d.getMonth(),d.getDate(),0,0,0);var u=e.parts.slice();if(m.length!==u.length&&(u=a(u).filter(function(b,c){return-1!==a.inArray(c,s)}).toArray()),m.length===u.length){var v;for(k=0,v=u.length;v>k;k++){if(n=parseInt(m[k],10),h=u[k],isNaN(n))switch(h){case"MM":o=a(p[f].months).filter(g),n=a.inArray(o[0],p[f].months)+1;break;case"M":o=a(p[f].monthsShort).filter(g),n=a.inArray(o[0],p[f].monthsShort)+1}r[h]=n}var w,x;for(k=0;k=g;g++)f.length&&b.push(f.shift()),b.push(e[c.parts[g]]);return b.join("")},headTemplate:'«»',contTemplate:'',footTemplate:''};q.template='
'+q.headTemplate+""+q.footTemplate+'
'+q.headTemplate+q.contTemplate+q.footTemplate+'
'+q.headTemplate+q.contTemplate+q.footTemplate+"
",a.fn.datepicker.DPGlobal=q,a.fn.datepicker.noConflict=function(){return a.fn.datepicker=l,this},a.fn.datepicker.version="1.4.0",a(document).on("focus.datepicker.data-api click.datepicker.data-api",'[data-provide="datepicker"]',function(b){var c=a(this);c.data("datepicker")||(b.preventDefault(),m.call(c,"show"))}),a(function(){m.call(a('[data-provide="datepicker-inline"]'))})}(window.jQuery); \ No newline at end of file diff --git a/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/jquery/jquery-2.1.1.min.js b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/jquery/jquery-2.1.1.min.js new file mode 100644 index 00000000000..18a8b895d9b --- /dev/null +++ b/components/device-mgt/org.wso2.carbon.device.mgt.ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.geo-devices/public/js/jquery/jquery-2.1.1.min.js @@ -0,0 +1,2066 @@ +/*! jQuery v2.1.1 | (c) 2005, 2014 jQuery Foundation, Inc. | 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 = c.slice, e = c.concat, f = c.push, g = c.indexOf, h = {}, i = h.toString, j = h.hasOwnProperty, k = {}, l = a.document, m = "2.1.1", 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 d.call(this) + }, get: function (a) { + return null != a ? 0 > a ? this[a + this.length] : this[a] : d.call(this) + }, pushStack: function (a) { + var b = n.merge(this.constructor(), a); + return b.prevObject = this, b.context = this.context, b + }, each: function (a, b) { + return n.each(this, a, b) + }, map: function (a) { + return this.pushStack(n.map(this, function (b, c) { + return a.call(b, c, b) + })) + }, slice: function () { + return this.pushStack(d.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(null) + }, push: f, 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) { + return!n.isArray(a) && a - parseFloat(a) >= 0 + }, isPlainObject: function (a) { + return"object" !== n.type(a) || a.nodeType || n.isWindow(a) ? !1 : a.constructor && !j.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 ? h[i.call(a)] || "object" : typeof a + }, globalEval: function (a) { + var b, c = eval; + a = n.trim(a), a && (1 === a.indexOf("use strict") ? (b = l.createElement("script"), b.text = a, l.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, c) { + var d, e = 0, f = a.length, g = s(a); + if (c) { + if (g) { + for (; f > e; e++)if (d = b.apply(a[e], c), d === !1)break + } else for (e in a)if (d = b.apply(a[e], c), d === !1)break + } else if (g) { + for (; f > e; e++)if (d = b.call(a[e], e, a[e]), d === !1)break + } else for (e in a)if (d = b.call(a[e], e, a[e]), 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) : f.call(c, a)), c + }, inArray: function (a, b, c) { + return null == b ? -1 : g.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, f = 0, g = a.length, h = s(a), i = []; + if (h)for (; g > f; f++)d = b(a[f], f, c), null != d && i.push(d); else for (f in a)d = b(a[f], f, c), null != d && i.push(d); + return e.apply([], i) + }, guid: 1, proxy: function (a, b) { + var c, e, f; + return"string" == typeof b && (c = a[b], b = a, a = c), n.isFunction(a) ? (e = d.call(arguments, 2), f = function () { + return a.apply(b || this, e.concat(d.call(arguments))) + }, f.guid = a.guid = a.guid || n.guid++, f) : void 0 + }, now: Date.now, support: k}), n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "), function (a, b) { + h["[object " + b + "]"] = b.toLowerCase() + }); + function s(a) { + var b = a.length, c = n.type(a); + return"function" === c || n.isWindow(a) ? !1 : 1 === a.nodeType && b ? !0 : "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" + -new Date, v = a.document, w = 0, x = 0, y = gb(), z = gb(), A = gb(), B = function (a, b) { + return a === b && (l = !0), 0 + }, C = "undefined", D = 1 << 31, E = {}.hasOwnProperty, F = [], G = F.pop, H = F.push, I = F.push, J = F.slice, K = F.indexOf || function (a) { + for (var b = 0, c = this.length; c > b; b++)if (this[b] === a)return b; + return-1 + }, L = "checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped", M = "[\\x20\\t\\r\\n\\f]", N = "(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+", O = N.replace("w", "w#"), P = "\\[" + M + "*(" + N + ")(?:" + M + "*([*^$|!~]?=)" + M + "*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|(" + O + "))|)" + M + "*\\]", Q = ":(" + N + ")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|" + P + ")*)|.*)\\)|)", R = new RegExp("^" + M + "+|((?:^|[^\\\\])(?:\\\\.)*)" + M + "+$", "g"), S = new RegExp("^" + M + "*," + M + "*"), T = new RegExp("^" + M + "*([>+~]|" + M + ")" + M + "*"), U = new RegExp("=" + M + "*([^\\]'\"]*?)" + M + "*\\]", "g"), V = new RegExp(Q), W = new RegExp("^" + O + "$"), X = {ID: new RegExp("^#(" + N + ")"), CLASS: new RegExp("^\\.(" + N + ")"), TAG: new RegExp("^(" + N.replace("w", "w*") + ")"), ATTR: new RegExp("^" + P), PSEUDO: new RegExp("^" + Q), CHILD: new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + M + "*(even|odd|(([+-]|)(\\d*)n|)" + M + "*(?:([+-]|)" + M + "*(\\d+)|))" + M + "*\\)|)", "i"), bool: new RegExp("^(?:" + L + ")$", "i"), needsContext: new RegExp("^" + M + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + M + "*((?:-\\d)?\\d*)" + M + "*\\)|)(?=[^-]|$)", "i")}, Y = /^(?:input|select|textarea|button)$/i, Z = /^h\d$/i, $ = /^[^{]+\{\s*\[native \w/, _ = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/, ab = /[+~]/, bb = /'|\\/g, cb = new RegExp("\\\\([\\da-f]{1,6}" + M + "?|(" + M + ")|.)", "ig"), db = 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) + }; + try { + I.apply(F = J.call(v.childNodes), v.childNodes), F[v.childNodes.length].nodeType + } catch (eb) { + I = {apply: F.length ? function (a, b) { + H.apply(a, J.call(b)) + } : function (a, b) { + var c = a.length, d = 0; + while (a[c++] = b[d++]); + a.length = c - 1 + }} + } + function fb(a, b, d, e) { + var f, h, j, k, l, o, r, s, w, x; + if ((b ? b.ownerDocument || b : v) !== n && m(b), b = b || n, d = d || [], !a || "string" != typeof a)return d; + if (1 !== (k = b.nodeType) && 9 !== k)return[]; + if (p && !e) { + if (f = _.exec(a))if (j = f[1]) { + if (9 === k) { + if (h = b.getElementById(j), !h || !h.parentNode)return d; + if (h.id === j)return d.push(h), d + } else if (b.ownerDocument && (h = b.ownerDocument.getElementById(j)) && t(b, h) && h.id === j)return d.push(h), d + } else { + if (f[2])return I.apply(d, b.getElementsByTagName(a)), d; + if ((j = f[3]) && c.getElementsByClassName && b.getElementsByClassName)return I.apply(d, b.getElementsByClassName(j)), d + } + if (c.qsa && (!q || !q.test(a))) { + if (s = r = u, w = b, x = 9 === k && a, 1 === k && "object" !== b.nodeName.toLowerCase()) { + o = g(a), (r = b.getAttribute("id")) ? s = r.replace(bb, "\\$&") : b.setAttribute("id", s), s = "[id='" + s + "'] ", l = o.length; + while (l--)o[l] = s + qb(o[l]); + w = ab.test(a) && ob(b.parentNode) || b, x = o.join(",") + } + if (x)try { + return I.apply(d, w.querySelectorAll(x)), d + } catch (y) { + } finally { + r || b.removeAttribute("id") + } + } + } + return i(a.replace(R, "$1"), b, d, e) + } + + function gb() { + var a = []; + + function b(c, e) { + return a.push(c + " ") > d.cacheLength && delete b[a.shift()], b[c + " "] = e + } + + return b + } + + function hb(a) { + return a[u] = !0, a + } + + function ib(a) { + var b = n.createElement("div"); + try { + return!!a(b) + } catch (c) { + return!1 + } finally { + b.parentNode && b.parentNode.removeChild(b), b = null + } + } + + function jb(a, b) { + var c = a.split("|"), e = a.length; + while (e--)d.attrHandle[c[e]] = b + } + + function kb(a, b) { + var c = b && a, d = c && 1 === a.nodeType && 1 === b.nodeType && (~b.sourceIndex || D) - (~a.sourceIndex || D); + if (d)return d; + if (c)while (c = c.nextSibling)if (c === b)return-1; + return a ? 1 : -1 + } + + function lb(a) { + return function (b) { + var c = b.nodeName.toLowerCase(); + return"input" === c && b.type === a + } + } + + function mb(a) { + return function (b) { + var c = b.nodeName.toLowerCase(); + return("input" === c || "button" === c) && b.type === a + } + } + + function nb(a) { + return hb(function (b) { + return b = +b, hb(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 ob(a) { + return a && typeof a.getElementsByTagName !== C && a + } + + c = fb.support = {}, f = fb.isXML = function (a) { + var b = a && (a.ownerDocument || a).documentElement; + return b ? "HTML" !== b.nodeName : !1 + }, m = fb.setDocument = function (a) { + var b, e = a ? a.ownerDocument || a : v, g = e.defaultView; + return e !== n && 9 === e.nodeType && e.documentElement ? (n = e, o = e.documentElement, p = !f(e), g && g !== g.top && (g.addEventListener ? g.addEventListener("unload", function () { + m() + }, !1) : g.attachEvent && g.attachEvent("onunload", function () { + m() + })), c.attributes = ib(function (a) { + return a.className = "i", !a.getAttribute("className") + }), c.getElementsByTagName = ib(function (a) { + return a.appendChild(e.createComment("")), !a.getElementsByTagName("*").length + }), c.getElementsByClassName = $.test(e.getElementsByClassName) && ib(function (a) { + return a.innerHTML = "
", a.firstChild.className = "i", 2 === a.getElementsByClassName("i").length + }), c.getById = ib(function (a) { + return o.appendChild(a).id = u, !e.getElementsByName || !e.getElementsByName(u).length + }), c.getById ? (d.find.ID = function (a, b) { + if (typeof b.getElementById !== C && p) { + var c = b.getElementById(a); + return c && c.parentNode ? [c] : [] + } + }, d.filter.ID = function (a) { + var b = a.replace(cb, db); + return function (a) { + return a.getAttribute("id") === b + } + }) : (delete d.find.ID, d.filter.ID = function (a) { + var b = a.replace(cb, db); + return function (a) { + var c = typeof a.getAttributeNode !== C && a.getAttributeNode("id"); + return c && c.value === b + } + }), d.find.TAG = c.getElementsByTagName ? function (a, b) { + return typeof b.getElementsByTagName !== C ? b.getElementsByTagName(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 typeof b.getElementsByClassName !== C && p ? b.getElementsByClassName(a) : void 0 + }, r = [], q = [], (c.qsa = $.test(e.querySelectorAll)) && (ib(function (a) { + a.innerHTML = "", a.querySelectorAll("[msallowclip^='']").length && q.push("[*^$]=" + M + "*(?:''|\"\")"), a.querySelectorAll("[selected]").length || q.push("\\[" + M + "*(?:value|" + L + ")"), a.querySelectorAll(":checked").length || q.push(":checked") + }), ib(function (a) { + var b = e.createElement("input"); + b.setAttribute("type", "hidden"), a.appendChild(b).setAttribute("name", "D"), a.querySelectorAll("[name=d]").length && q.push("name" + M + "*[*^$|!~]?="), a.querySelectorAll(":enabled").length || q.push(":enabled", ":disabled"), a.querySelectorAll("*,:x"), q.push(",.*:") + })), (c.matchesSelector = $.test(s = o.matches || o.webkitMatchesSelector || o.mozMatchesSelector || o.oMatchesSelector || o.msMatchesSelector)) && ib(function (a) { + c.disconnectedMatch = s.call(a, "div"), s.call(a, "[s!='']:x"), r.push("!=", Q) + }), q = q.length && new RegExp(q.join("|")), r = r.length && new RegExp(r.join("|")), b = $.test(o.compareDocumentPosition), t = b || $.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 === e || a.ownerDocument === v && t(v, a) ? -1 : b === e || b.ownerDocument === v && t(v, b) ? 1 : k ? K.call(k, a) - K.call(k, b) : 0 : 4 & d ? -1 : 1) + } : function (a, b) { + if (a === b)return l = !0, 0; + var c, d = 0, f = a.parentNode, g = b.parentNode, h = [a], i = [b]; + if (!f || !g)return a === e ? -1 : b === e ? 1 : f ? -1 : g ? 1 : k ? K.call(k, a) - K.call(k, b) : 0; + if (f === g)return kb(a, b); + c = a; + while (c = c.parentNode)h.unshift(c); + c = b; + while (c = c.parentNode)i.unshift(c); + while (h[d] === i[d])d++; + return d ? kb(h[d], i[d]) : h[d] === v ? -1 : i[d] === v ? 1 : 0 + }, e) : n + }, fb.matches = function (a, b) { + return fb(a, null, null, b) + }, fb.matchesSelector = function (a, b) { + if ((a.ownerDocument || a) !== n && m(a), b = b.replace(U, "='$1']"), !(!c.matchesSelector || !p || 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 fb(b, n, null, [a]).length > 0 + }, fb.contains = function (a, b) { + return(a.ownerDocument || a) !== n && m(a), t(a, b) + }, fb.attr = function (a, b) { + (a.ownerDocument || a) !== n && m(a); + var e = d.attrHandle[b.toLowerCase()], f = e && E.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 + }, fb.error = function (a) { + throw new Error("Syntax error, unrecognized expression: " + a) + }, fb.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 = fb.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 = fb.selectors = {cacheLength: 50, createPseudo: hb, match: X, 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(cb, db), a[3] = (a[3] || a[4] || a[5] || "").replace(cb, db), "~=" === 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] || fb.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] && fb.error(a[0]), a + }, PSEUDO: function (a) { + var b, c = !a[6] && a[2]; + return X.CHILD.test(a[0]) ? null : (a[3] ? a[2] = a[4] || a[5] || "" : c && V.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(cb, db).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("(^|" + M + ")" + a + "(" + M + "|$)")) && y(a, function (a) { + return b.test("string" == typeof a.className && a.className || typeof a.getAttribute !== C && a.getAttribute("class") || "") + }) + }, ATTR: function (a, b, c) { + return function (d) { + var e = fb.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 + " ").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; + if (q) { + if (f) { + while (p) { + l = b; + while (l = l[p])if (h ? l.nodeName.toLowerCase() === r : 1 === l.nodeType)return!1; + o = p = "only" === a && !o && "nextSibling" + } + return!0 + } + if (o = [g ? q.firstChild : q.lastChild], g && s) { + k = q[u] || (q[u] = {}), j = k[a] || [], n = j[0] === w && j[1], m = j[0] === w && j[2], l = n && q.childNodes[n]; + while (l = ++n && l && l[p] || (m = n = 0) || o.pop())if (1 === l.nodeType && ++m && l === b) { + k[a] = [w, n, m]; + break + } + } else if (s && (j = (b[u] || (b[u] = {}))[a]) && j[0] === w)m = j[1]; else while (l = ++n && l && l[p] || (m = n = 0) || o.pop())if ((h ? l.nodeName.toLowerCase() === r : 1 === l.nodeType) && ++m && (s && ((l[u] || (l[u] = {}))[a] = [w, m]), l === b))break; + return m -= e, m === d || m % d === 0 && m / d >= 0 + } + } + }, PSEUDO: function (a, b) { + var c, e = d.pseudos[a] || d.setFilters[a.toLowerCase()] || fb.error("unsupported pseudo: " + a); + return e[u] ? e(b) : e.length > 1 ? (c = [a, a, "", b], d.setFilters.hasOwnProperty(a.toLowerCase()) ? hb(function (a, c) { + var d, f = e(a, b), g = f.length; + while (g--)d = K.call(a, f[g]), a[d] = !(c[d] = f[g]) + }) : function (a) { + return e(a, 0, c) + }) : e + }}, pseudos: {not: hb(function (a) { + var b = [], c = [], d = h(a.replace(R, "$1")); + return d[u] ? hb(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), !c.pop() + } + }), has: hb(function (a) { + return function (b) { + return fb(a, b).length > 0 + } + }), contains: hb(function (a) { + return function (b) { + return(b.textContent || b.innerText || e(b)).indexOf(a) > -1 + } + }), lang: hb(function (a) { + return W.test(a || "") || fb.error("unsupported lang: " + a), a = a.replace(cb, db).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 Z.test(a.nodeName) + }, input: function (a) { + return Y.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: nb(function () { + return[0] + }), last: nb(function (a, b) { + return[b - 1] + }), eq: nb(function (a, b, c) { + return[0 > c ? c + b : c] + }), even: nb(function (a, b) { + for (var c = 0; b > c; c += 2)a.push(c); + return a + }), odd: nb(function (a, b) { + for (var c = 1; b > c; c += 2)a.push(c); + return a + }), lt: nb(function (a, b, c) { + for (var d = 0 > c ? c + b : c; --d >= 0;)a.push(d); + return a + }), gt: nb(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] = lb(b); + for (b in{submit: !0, reset: !0})d.pseudos[b] = mb(b); + function pb() { + } + + pb.prototype = d.filters = d.pseudos, d.setFilters = new pb, g = fb.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 = S.exec(h))) && (e && (h = h.slice(e[0].length) || h), i.push(f = [])), c = !1, (e = T.exec(h)) && (c = e.shift(), f.push({value: c, type: e[0].replace(R, " ")}), h = h.slice(c.length)); + for (g in d.filter)!(e = X[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 ? fb.error(a) : z(a, i).slice(0) + }; + function qb(a) { + for (var b = 0, c = a.length, d = ""; c > b; b++)d += a[b].value; + return d + } + + function rb(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 = [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 (i = b[u] || (b[u] = {}), (h = i[d]) && h[0] === w && h[1] === f)return j[2] = h[2]; + if (i[d] = j, j[2] = a(b, c, g))return!0 + } + } + } + + function sb(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 tb(a, b, c) { + for (var d = 0, e = b.length; e > d; d++)fb(a, b[d], c); + return c + } + + function ub(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 vb(a, b, c, d, e, f) { + return d && !d[u] && (d = vb(d)), e && !e[u] && (e = vb(e, f)), hb(function (f, g, h, i) { + var j, k, l, m = [], n = [], o = g.length, p = f || tb(b || "*", h.nodeType ? [h] : h, []), q = !a || !f && b ? p : ub(p, m, a, h, i), r = c ? e || (f ? a : o || d) ? [] : g : q; + if (c && c(q, r, h, i), d) { + j = ub(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 ? K.call(f, l) : m[k]) > -1 && (f[j] = !(g[j] = l)) + } + } else r = ub(r === g ? r.splice(o, r.length) : r), e ? e(null, g, r, i) : I.apply(g, r) + }) + } + + function wb(a) { + for (var b, c, e, f = a.length, g = d.relative[a[0].type], h = g || d.relative[" "], i = g ? 1 : 0, k = rb(function (a) { + return a === b + }, h, !0), l = rb(function (a) { + return K.call(b, a) > -1 + }, h, !0), m = [function (a, c, d) { + return!g && (d || c !== j) || ((b = c).nodeType ? k(a, c, d) : l(a, c, d)) + }]; f > i; i++)if (c = d.relative[a[i].type])m = [rb(sb(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 vb(i > 1 && sb(m), i > 1 && qb(a.slice(0, i - 1).concat({value: " " === a[i - 2].type ? "*" : ""})).replace(R, "$1"), c, e > i && wb(a.slice(i, e)), f > e && wb(a = a.slice(e)), f > e && qb(a)) + } + m.push(c) + } + return sb(m) + } + + function xb(a, b) { + var c = b.length > 0, e = a.length > 0, f = function (f, g, h, i, k) { + var l, m, o, p = 0, q = "0", r = f && [], s = [], t = j, u = f || e && d.find.TAG("*", k), v = w += null == t ? 1 : Math.random() || .1, x = u.length; + for (k && (j = g !== n && g); q !== x && null != (l = u[q]); q++) { + if (e && l) { + m = 0; + while (o = a[m++])if (o(l, g, h)) { + i.push(l); + break + } + k && (w = v) + } + c && ((l = !o && l) && p--, f && r.push(l)) + } + if (p += q, c && q !== p) { + m = 0; + while (o = b[m++])o(r, s, g, h); + if (f) { + if (p > 0)while (q--)r[q] || s[q] || (s[q] = G.call(i)); + s = ub(s) + } + I.apply(i, s), k && !f && s.length > 0 && p + b.length > 1 && fb.uniqueSort(i) + } + return k && (w = v, j = t), r + }; + return c ? hb(f) : f + } + + return h = fb.compile = function (a, b) { + var c, d = [], e = [], f = A[a + " "]; + if (!f) { + b || (b = g(a)), c = b.length; + while (c--)f = wb(b[c]), f[u] ? d.push(f) : e.push(f); + f = A(a, xb(e, d)), f.selector = a + } + return f + }, i = fb.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(cb, db), b) || [])[0], !b)return e; + n && (b = b.parentNode), a = a.slice(j.shift().value.length) + } + i = X.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(cb, db), ab.test(j[0].type) && ob(b.parentNode) || b))) { + if (j.splice(i, 1), a = f.length && qb(j), !a)return I.apply(e, f), e; + break + } + } + } + return(n || h(a, o))(f, b, !p, e, ab.test(a) && ob(b.parentNode) || b), e + }, c.sortStable = u.split("").sort(B).join("") === u, c.detectDuplicates = !!l, m(), c.sortDetached = ib(function (a) { + return 1 & a.compareDocumentPosition(n.createElement("div")) + }), ib(function (a) { + return a.innerHTML = "
", "#" === a.firstChild.getAttribute("href") + }) || jb("type|href|height|width", function (a, b, c) { + return c ? void 0 : a.getAttribute(b, "type" === b.toLowerCase() ? 1 : 2) + }), c.attributes && ib(function (a) { + return a.innerHTML = "", a.firstChild.setAttribute("value", ""), "" === a.firstChild.getAttribute("value") + }) || jb("value", function (a, b, c) { + return c || "input" !== a.nodeName.toLowerCase() ? void 0 : a.defaultValue + }), ib(function (a) { + return null == a.getAttribute("disabled") + }) || jb(L, function (a, b, c) { + var d; + return c ? void 0 : a[b] === !0 ? b.toLowerCase() : (d = a.getAttributeNode(b)) && d.specified ? d.value : null + }), fb + }(a); + n.find = t, n.expr = t.selectors, n.expr[":"] = n.expr.pseudos, n.unique = t.uniqueSort, n.text = t.getText, n.isXMLDoc = t.isXML, n.contains = t.contains; + var u = n.expr.match.needsContext, v = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, w = /^.[^:#\[\.,]*$/; + + function x(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 (w.test(b))return n.filter(b, a, c); + b = n.filter(b, a) + } + return n.grep(a, function (a) { + return g.call(b, a) >= 0 !== 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(x(this, a || [], !1)) + }, not: function (a) { + return this.pushStack(x(this, a || [], !0)) + }, is: function (a) { + return!!x(this, "string" == typeof a && u.test(a) ? n(a) : a || [], !1).length + }}); + var y, z = /^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/, A = n.fn.init = function (a, b) { + var c, d; + if (!a)return this; + if ("string" == typeof a) { + if (c = "<" === a[0] && ">" === a[a.length - 1] && a.length >= 3 ? [null, a, null] : z.exec(a), !c || !c[1] && b)return!b || b.jquery ? (b || y).find(a) : this.constructor(b).find(a); + if (c[1]) { + if (b = b instanceof n ? b[0] : b, n.merge(this, n.parseHTML(c[1], b && b.nodeType ? b.ownerDocument || b : l, !0)), v.test(c[1]) && n.isPlainObject(b))for (c in b)n.isFunction(this[c]) ? this[c](b[c]) : this.attr(c, b[c]); + return this + } + return d = l.getElementById(c[2]), d && d.parentNode && (this.length = 1, this[0] = d), this.context = l, this.selector = a, this + } + return a.nodeType ? (this.context = this[0] = a, this.length = 1, this) : n.isFunction(a) ? "undefined" != typeof y.ready ? y.ready(a) : a(n) : (void 0 !== a.selector && (this.selector = a.selector, this.context = a.context), n.makeArray(a, this)) + }; + A.prototype = n.fn, y = n(l); + var B = /^(?:parents|prev(?:Until|All))/, C = {children: !0, contents: !0, next: !0, prev: !0}; + n.extend({dir: 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 + }, sibling: function (a, b) { + for (var c = []; a; a = a.nextSibling)1 === a.nodeType && a !== b && c.push(a); + return c + }}), 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 = u.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.unique(f) : f) + }, index: function (a) { + return a ? "string" == typeof a ? g.call(n(a), this[0]) : g.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.unique(n.merge(this.get(), n(a, b)))) + }, addBack: function (a) { + return this.add(null == a ? this.prevObject : this.prevObject.filter(a)) + }}); + function D(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 n.dir(a, "parentNode") + }, parentsUntil: function (a, b, c) { + return n.dir(a, "parentNode", c) + }, next: function (a) { + return D(a, "nextSibling") + }, prev: function (a) { + return D(a, "previousSibling") + }, nextAll: function (a) { + return n.dir(a, "nextSibling") + }, prevAll: function (a) { + return n.dir(a, "previousSibling") + }, nextUntil: function (a, b, c) { + return n.dir(a, "nextSibling", c) + }, prevUntil: function (a, b, c) { + return n.dir(a, "previousSibling", c) + }, siblings: function (a) { + return n.sibling((a.parentNode || {}).firstChild, a) + }, children: function (a) { + return n.sibling(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 && (C[a] || n.unique(e), B.test(a) && e.reverse()), this.pushStack(e) + } + }); + var E = /\S+/g, F = {}; + + function G(a) { + var b = F[a] = {}; + return n.each(a.match(E) || [], function (a, c) { + b[c] = !0 + }), b + } + + n.Callbacks = function (a) { + a = "string" == typeof a ? F[a] || G(a) : n.extend({}, a); + var b, c, d, e, f, g, h = [], i = !a.once && [], j = function (l) { + for (b = a.memory && l, c = !0, g = e || 0, e = 0, f = h.length, d = !0; h && f > g; g++)if (h[g].apply(l[0], l[1]) === !1 && a.stopOnFalse) { + b = !1; + break + } + d = !1, h && (i ? i.length && j(i.shift()) : b ? h = [] : k.disable()) + }, k = {add: function () { + if (h) { + var c = h.length; + !function g(b) { + n.each(b, function (b, c) { + var d = n.type(c); + "function" === d ? a.unique && k.has(c) || h.push(c) : c && c.length && "string" !== d && g(c) + }) + }(arguments), d ? f = h.length : b && (e = c, j(b)) + } + return this + }, remove: function () { + return h && n.each(arguments, function (a, b) { + var c; + while ((c = n.inArray(b, h, c)) > -1)h.splice(c, 1), d && (f >= c && f--, g >= c && g--) + }), this + }, has: function (a) { + return a ? n.inArray(a, h) > -1 : !(!h || !h.length) + }, empty: function () { + return h = [], f = 0, this + }, disable: function () { + return h = i = b = void 0, this + }, disabled: function () { + return!h + }, lock: function () { + return i = void 0, b || k.disable(), this + }, locked: function () { + return!i + }, fireWith: function (a, b) { + return!h || c && !i || (b = b || [], b = [a, b.slice ? b.slice() : b], d ? i.push(b) : j(b)), this + }, fire: function () { + return k.fireWith(this, arguments), this + }, fired: function () { + return!!c + }}; + return k + }, 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().done(c.resolve).fail(c.reject).progress(c.notify) : 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 = d.call(arguments), e = c.length, f = 1 !== e || a && n.isFunction(a.promise) ? e : 0, g = 1 === f ? a : n.Deferred(), h = function (a, b, c) { + return function (e) { + b[a] = this, c[a] = arguments.length > 1 ? d.call(arguments) : e, c === i ? g.notifyWith(b, c) : --f || g.resolveWith(b, c) + } + }, i, j, k; + if (e > 1)for (i = new Array(e), j = new Array(e), k = new Array(e); e > b; b++)c[b] && n.isFunction(c[b].promise) ? c[b].promise().done(h(b, k, c)).fail(g.reject).progress(h(b, j, i)) : --f; + return f || g.resolveWith(k, c), g.promise() + }}); + var H; + 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 || (H.resolveWith(l, [n]), n.fn.triggerHandler && (n(l).triggerHandler("ready"), n(l).off("ready")))) + }}); + function I() { + l.removeEventListener("DOMContentLoaded", I, !1), a.removeEventListener("load", I, !1), n.ready() + } + + n.ready.promise = function (b) { + return H || (H = n.Deferred(), "complete" === l.readyState ? setTimeout(n.ready) : (l.addEventListener("DOMContentLoaded", I, !1), a.addEventListener("load", I, !1))), H.promise(b) + }, n.ready.promise(); + var J = n.access = 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)n.access(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 + }; + n.acceptData = function (a) { + return 1 === a.nodeType || 9 === a.nodeType || !+a.nodeType + }; + function K() { + Object.defineProperty(this.cache = {}, 0, {get: function () { + return{} + }}), this.expando = n.expando + Math.random() + } + + K.uid = 1, K.accepts = n.acceptData, K.prototype = {key: function (a) { + if (!K.accepts(a))return 0; + var b = {}, c = a[this.expando]; + if (!c) { + c = K.uid++; + try { + b[this.expando] = {value: c}, Object.defineProperties(a, b) + } catch (d) { + b[this.expando] = c, n.extend(a, b) + } + } + return this.cache[c] || (this.cache[c] = {}), c + }, set: function (a, b, c) { + var d, e = this.key(a), f = this.cache[e]; + if ("string" == typeof b)f[b] = c; else if (n.isEmptyObject(f))n.extend(this.cache[e], b); else for (d in b)f[d] = b[d]; + return f + }, get: function (a, b) { + var c = this.cache[this.key(a)]; + return void 0 === b ? c : c[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 = this.key(a), g = this.cache[f]; + if (void 0 === b)this.cache[f] = {}; else { + n.isArray(b) ? d = b.concat(b.map(n.camelCase)) : (e = n.camelCase(b), b in g ? d = [b, e] : (d = e, d = d in g ? [d] : d.match(E) || [])), c = d.length; + while (c--)delete g[d[c]] + } + }, hasData: function (a) { + return!n.isEmptyObject(this.cache[a[this.expando]] || {}) + }, discard: function (a) { + a[this.expando] && delete this.cache[a[this.expando]] + }}; + var L = new K, M = new K, N = /^(?:\{[\w\W]*\}|\[[\w\W]*\])$/, O = /([A-Z])/g; + + function P(a, b, c) { + var d; + if (void 0 === c && 1 === a.nodeType)if (d = "data-" + b.replace(O, "-$1").toLowerCase(), c = a.getAttribute(d), "string" == typeof c) { + try { + c = "true" === c ? !0 : "false" === c ? !1 : "null" === c ? null : +c + "" === c ? +c : N.test(c) ? n.parseJSON(c) : c + } catch (e) { + } + M.set(a, b, c) + } else c = void 0; + return c + } + + n.extend({hasData: function (a) { + return M.hasData(a) || L.hasData(a) + }, data: function (a, b, c) { + return M.access(a, b, c) + }, removeData: function (a, b) { + M.remove(a, b) + }, _data: function (a, b, c) { + return L.access(a, b, c) + }, _removeData: function (a, b) { + L.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 = M.get(f), 1 === f.nodeType && !L.get(f, "hasDataAttrs"))) { + c = g.length; + while (c--)g[c] && (d = g[c].name, 0 === d.indexOf("data-") && (d = n.camelCase(d.slice(5)), P(f, d, e[d]))); + L.set(f, "hasDataAttrs", !0) + } + return e + } + return"object" == typeof a ? this.each(function () { + M.set(this, a) + }) : J(this, function (b) { + var c, d = n.camelCase(a); + if (f && void 0 === b) { + if (c = M.get(f, a), void 0 !== c)return c; + if (c = M.get(f, d), void 0 !== c)return c; + if (c = P(f, d, void 0), void 0 !== c)return c + } else this.each(function () { + var c = M.get(this, d); + M.set(this, d, b), -1 !== a.indexOf("-") && void 0 !== c && M.set(this, a, b) + }) + }, null, b, arguments.length > 1, null, !0) + }, removeData: function (a) { + return this.each(function () { + M.remove(this, a) + }) + }}), n.extend({queue: function (a, b, c) { + var d; + return a ? (b = (b || "fx") + "queue", d = L.get(a, b), c && (!d || n.isArray(c) ? d = L.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 L.get(a, c) || L.access(a, c, {empty: n.Callbacks("once memory").add(function () { + L.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 = L.get(f[g], a + "queueHooks"), c && c.empty && (d++, c.empty.add(h)); + return h(), e.promise(b) + }}); + var Q = /[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source, R = ["Top", "Right", "Bottom", "Left"], S = function (a, b) { + return a = b || a, "none" === n.css(a, "display") || !n.contains(a.ownerDocument, a) + }, T = /^(?:checkbox|radio)$/i; + !function () { + var a = l.createDocumentFragment(), b = a.appendChild(l.createElement("div")), c = l.createElement("input"); + c.setAttribute("type", "radio"), c.setAttribute("checked", "checked"), c.setAttribute("name", "t"), b.appendChild(c), k.checkClone = b.cloneNode(!0).cloneNode(!0).lastChild.checked, b.innerHTML = "", k.noCloneChecked = !!b.cloneNode(!0).lastChild.defaultValue + }(); + var U = "undefined"; + k.focusinBubbles = "onfocusin"in a; + var V = /^key/, W = /^(?:mouse|pointer|contextmenu)|click/, X = /^(?:focusinfocus|focusoutblur)$/, Y = /^([^.]*)(?:\.(.+)|)$/; + + function Z() { + return!0 + } + + function $() { + return!1 + } + + function _() { + try { + return l.activeElement + } catch (a) { + } + } + + n.event = {global: {}, add: function (a, b, c, d, e) { + var f, g, h, i, j, k, l, m, o, p, q, r = L.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 typeof n !== U && n.event.triggered !== b.type ? n.event.dispatch.apply(a, arguments) : void 0 + }), b = (b || "").match(E) || [""], j = b.length; + while (j--)h = Y.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, !1)), 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 = L.hasData(a) && L.get(a); + if (r && (i = r.events)) { + b = (b || "").match(E) || [""], j = b.length; + while (j--)if (h = Y.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) && (delete r.handle, L.remove(a, "events")) + } + }, trigger: function (b, c, d, e) { + var f, g, h, i, k, m, o, p = [d || l], q = j.call(b, "type") ? b.type : b, r = j.call(b, "namespace") ? b.namespace.split(".") : []; + if (g = h = d = d || l, 3 !== d.nodeType && 8 !== d.nodeType && !X.test(q + n.event.triggered) && (q.indexOf(".") >= 0 && (r = q.split("."), q = r.shift(), r.sort()), k = q.indexOf(":") < 0 && "on" + q, b = b[n.expando] ? b : new n.Event(q, "object" == typeof b && b), b.isTrigger = e ? 2 : 3, b.namespace = r.join("."), b.namespace_re = b.namespace ? new RegExp("(^|\\.)" + r.join("\\.(?:.*\\.|)") + "(\\.|$)") : null, b.result = void 0, b.target || (b.target = d), c = null == c ? [b] : n.makeArray(c, [b]), o = n.event.special[q] || {}, e || !o.trigger || o.trigger.apply(d, c) !== !1)) { + if (!e && !o.noBubble && !n.isWindow(d)) { + for (i = o.delegateType || q, X.test(i + q) || (g = g.parentNode); g; g = g.parentNode)p.push(g), h = g; + h === (d.ownerDocument || l) && p.push(h.defaultView || h.parentWindow || a) + } + f = 0; + while ((g = p[f++]) && !b.isPropagationStopped())b.type = f > 1 ? i : o.bindType || q, m = (L.get(g, "events") || {})[b.type] && L.get(g, "handle"), m && m.apply(g, c), m = k && g[k], m && m.apply && n.acceptData(g) && (b.result = m.apply(g, c), b.result === !1 && b.preventDefault()); + return b.type = q, e || b.isDefaultPrevented() || o._default && o._default.apply(p.pop(), c) !== !1 || !n.acceptData(d) || k && n.isFunction(d[q]) && !n.isWindow(d) && (h = d[k], h && (d[k] = null), n.event.triggered = q, d[q](), n.event.triggered = void 0, h && (d[k] = h)), b.result + } + }, dispatch: function (a) { + a = n.event.fix(a); + var b, c, e, f, g, h = [], i = d.call(arguments), j = (L.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.namespace_re || a.namespace_re.test(g.namespace)) && (a.handleObj = g, a.data = g.data, e = ((n.event.special[g.origType] || {}).handle || g.handler).apply(f.elem, i), void 0 !== e && (a.result = e) === !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 && (!a.button || "click" !== a.type))for (; i !== this; i = i.parentNode || this)if (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) >= 0 : 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 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, d, e, f = b.button; + return null == a.pageX && null != b.clientX && (c = a.target.ownerDocument || l, d = c.documentElement, e = c.body, a.pageX = b.clientX + (d && d.scrollLeft || e && e.scrollLeft || 0) - (d && d.clientLeft || e && e.clientLeft || 0), a.pageY = b.clientY + (d && d.scrollTop || e && e.scrollTop || 0) - (d && d.clientTop || e && e.clientTop || 0)), a.which || void 0 === f || (a.which = 1 & f ? 1 : 2 & f ? 3 : 4 & f ? 2 : 0), a + }}, fix: function (a) { + if (a[n.expando])return a; + var b, c, d, e = a.type, f = a, g = this.fixHooks[e]; + g || (this.fixHooks[e] = g = W.test(e) ? this.mouseHooks : V.test(e) ? this.keyHooks : {}), d = g.props ? this.props.concat(g.props) : this.props, a = new n.Event(f), b = d.length; + while (b--)c = d[b], a[c] = f[c]; + return a.target || (a.target = l), 3 === a.target.nodeType && (a.target = a.target.parentNode), g.filter ? g.filter(a, f) : a + }, special: {load: {noBubble: !0}, focus: {trigger: function () { + return this !== _() && this.focus ? (this.focus(), !1) : void 0 + }, delegateType: "focusin"}, blur: {trigger: function () { + return this === _() && 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) + }}}, simulate: function (a, b, c, d) { + var e = n.extend(new n.Event, c, {type: a, isSimulated: !0, originalEvent: {}}); + d ? n.event.trigger(e, null, b) : n.event.dispatch.call(b, e), e.isDefaultPrevented() && c.preventDefault() + }}, n.removeEvent = function (a, b, c) { + a.removeEventListener && a.removeEventListener(b, c, !1) + }, 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 ? Z : $) : 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 = {isDefaultPrevented: $, isPropagationStopped: $, isImmediatePropagationStopped: $, preventDefault: function () { + var a = this.originalEvent; + this.isDefaultPrevented = Z, a && a.preventDefault && a.preventDefault() + }, stopPropagation: function () { + var a = this.originalEvent; + this.isPropagationStopped = Z, a && a.stopPropagation && a.stopPropagation() + }, stopImmediatePropagation: function () { + var a = this.originalEvent; + this.isImmediatePropagationStopped = Z, a && a.stopImmediatePropagation && 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 + }} + }), k.focusinBubbles || n.each({focus: "focusin", blur: "focusout"}, function (a, b) { + var c = function (a) { + n.event.simulate(b, a.target, n.event.fix(a), !0) + }; + n.event.special[b] = {setup: function () { + var d = this.ownerDocument || this, e = L.access(d, b); + e || d.addEventListener(a, c, !0), L.access(d, b, (e || 0) + 1) + }, teardown: function () { + var d = this.ownerDocument || this, e = L.access(d, b) - 1; + e ? L.access(d, b, e) : (d.removeEventListener(a, c, !0), L.remove(d, b)) + }} + }), n.fn.extend({on: function (a, b, c, d, e) { + var f, g; + if ("object" == typeof a) { + "string" != typeof b && (c = c || b, b = void 0); + for (g in a)this.on(g, b, c, a[g], e); + return this + } + if (null == c && null == d ? (d = b, c = b = void 0) : null == d && ("string" == typeof b ? (d = c, c = void 0) : (d = c, c = b, b = void 0)), d === !1)d = $; else if (!d)return this; + return 1 === e && (f = d, d = function (a) { + return n().off(a), f.apply(this, arguments) + }, d.guid = f.guid || (f.guid = n.guid++)), this.each(function () { + n.event.add(this, a, d, c, b) + }) + }, one: function (a, b, c, d) { + return this.on(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 = $), this.each(function () { + n.event.remove(this, a, c, b) + }) + }, 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 + }}); + var ab = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, bb = /<([\w:]+)/, cb = /<|&#?\w+;/, db = /<(?:script|style|link)/i, eb = /checked\s*(?:[^=]|=\s*.checked.)/i, fb = /^$|\/(?:java|ecma)script/i, gb = /^true\/(.*)/, hb = /^\s*\s*$/g, ib = {option: [1, ""], thead: [1, "", "
"], col: [2, "", "
"], tr: [2, "", "
"], td: [3, "", "
"], _default: [0, "", ""]}; + ib.optgroup = ib.option, ib.tbody = ib.tfoot = ib.colgroup = ib.caption = ib.thead, ib.th = ib.td; + function jb(a, b) { + return n.nodeName(a, "table") && n.nodeName(11 !== b.nodeType ? b : b.firstChild, "tr") ? a.getElementsByTagName("tbody")[0] || a.appendChild(a.ownerDocument.createElement("tbody")) : a + } + + function kb(a) { + return a.type = (null !== a.getAttribute("type")) + "/" + a.type, a + } + + function lb(a) { + var b = gb.exec(a.type); + return b ? a.type = b[1] : a.removeAttribute("type"), a + } + + function mb(a, b) { + for (var c = 0, d = a.length; d > c; c++)L.set(a[c], "globalEval", !b || L.get(b[c], "globalEval")) + } + + function nb(a, b) { + var c, d, e, f, g, h, i, j; + if (1 === b.nodeType) { + if (L.hasData(a) && (f = L.access(a), g = L.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]) + } + M.hasData(a) && (h = M.access(a), i = n.extend({}, h), M.set(b, i)) + } + } + + function ob(a, b) { + var c = a.getElementsByTagName ? a.getElementsByTagName(b || "*") : a.querySelectorAll ? a.querySelectorAll(b || "*") : []; + return void 0 === b || b && n.nodeName(a, b) ? n.merge([a], c) : c + } + + function pb(a, b) { + var c = b.nodeName.toLowerCase(); + "input" === c && T.test(a.type) ? b.checked = a.checked : ("input" === c || "textarea" === c) && (b.defaultValue = a.defaultValue) + } + + n.extend({clone: function (a, b, c) { + var d, e, f, g, h = a.cloneNode(!0), i = n.contains(a.ownerDocument, a); + if (!(k.noCloneChecked || 1 !== a.nodeType && 11 !== a.nodeType || n.isXMLDoc(a)))for (g = ob(h), f = ob(a), d = 0, e = f.length; e > d; d++)pb(f[d], g[d]); + if (b)if (c)for (f = f || ob(a), g = g || ob(h), d = 0, e = f.length; e > d; d++)nb(f[d], g[d]); else nb(a, h); + return g = ob(h, "script"), g.length > 0 && mb(g, !i && ob(a, "script")), h + }, buildFragment: function (a, b, c, d) { + for (var e, f, g, h, i, j, k = b.createDocumentFragment(), l = [], m = 0, o = a.length; o > m; m++)if (e = a[m], e || 0 === e)if ("object" === n.type(e))n.merge(l, e.nodeType ? [e] : e); else if (cb.test(e)) { + f = f || k.appendChild(b.createElement("div")), g = (bb.exec(e) || ["", ""])[1].toLowerCase(), h = ib[g] || ib._default, f.innerHTML = h[1] + e.replace(ab, "<$1>") + h[2], j = h[0]; + while (j--)f = f.lastChild; + n.merge(l, f.childNodes), f = k.firstChild, f.textContent = "" + } else l.push(b.createTextNode(e)); + k.textContent = "", m = 0; + while (e = l[m++])if ((!d || -1 === n.inArray(e, d)) && (i = n.contains(e.ownerDocument, e), f = ob(k.appendChild(e), "script"), i && mb(f), c)) { + j = 0; + while (e = f[j++])fb.test(e.type || "") && c.push(e) + } + return k + }, cleanData: function (a) { + for (var b, c, d, e, f = n.event.special, g = 0; void 0 !== (c = a[g]); g++) { + if (n.acceptData(c) && (e = c[L.expando], e && (b = L.cache[e]))) { + if (b.events)for (d in b.events)f[d] ? n.event.remove(c, d) : n.removeEvent(c, d, b.handle); + L.cache[e] && delete L.cache[e] + } + delete M.cache[c[M.expando]] + } + }}), n.fn.extend({text: function (a) { + return J(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 this.domManip(arguments, function (a) { + if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) { + var b = jb(this, a); + b.appendChild(a) + } + }) + }, prepend: function () { + return this.domManip(arguments, function (a) { + if (1 === this.nodeType || 11 === this.nodeType || 9 === this.nodeType) { + var b = jb(this, a); + b.insertBefore(a, b.firstChild) + } + }) + }, before: function () { + return this.domManip(arguments, function (a) { + this.parentNode && this.parentNode.insertBefore(a, this) + }) + }, after: function () { + return this.domManip(arguments, function (a) { + this.parentNode && this.parentNode.insertBefore(a, this.nextSibling) + }) + }, remove: function (a, b) { + for (var c, d = a ? n.filter(a, this) : this, e = 0; null != (c = d[e]); e++)b || 1 !== c.nodeType || n.cleanData(ob(c)), c.parentNode && (b && n.contains(c.ownerDocument, c) && mb(ob(c, "script")), c.parentNode.removeChild(c)); + return this + }, empty: function () { + for (var a, b = 0; null != (a = this[b]); b++)1 === a.nodeType && (n.cleanData(ob(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 J(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 && !db.test(a) && !ib[(bb.exec(a) || ["", ""])[1].toLowerCase()]) { + a = a.replace(ab, "<$1>"); + try { + for (; d > c; c++)b = this[c] || {}, 1 === b.nodeType && (n.cleanData(ob(b, !1)), b.innerHTML = a); + b = 0 + } catch (e) { + } + } + b && this.empty().append(a) + }, null, a, arguments.length) + }, replaceWith: function () { + var a = arguments[0]; + return this.domManip(arguments, function (b) { + a = this.parentNode, n.cleanData(ob(this)), a && a.replaceChild(b, this) + }), a && (a.length || a.nodeType) ? this : this.remove() + }, detach: function (a) { + return this.remove(a, !0) + }, domManip: function (a, b) { + a = e.apply([], a); + var c, d, f, g, h, i, j = 0, l = this.length, m = this, o = l - 1, p = a[0], q = n.isFunction(p); + if (q || l > 1 && "string" == typeof p && !k.checkClone && eb.test(p))return this.each(function (c) { + var d = m.eq(c); + q && (a[0] = p.call(this, c, d.html())), d.domManip(a, b) + }); + if (l && (c = n.buildFragment(a, this[0].ownerDocument, !1, this), d = c.firstChild, 1 === c.childNodes.length && (c = d), d)) { + for (f = n.map(ob(c, "script"), kb), g = f.length; l > j; j++)h = c, j !== o && (h = n.clone(h, !0, !0), g && n.merge(f, ob(h, "script"))), b.call(this[j], h, j); + if (g)for (i = f[f.length - 1].ownerDocument, n.map(f, lb), j = 0; g > j; j++)h = f[j], fb.test(h.type || "") && !L.access(h, "globalEval") && n.contains(i, h) && (h.src ? n._evalUrl && n._evalUrl(h.src) : n.globalEval(h.textContent.replace(hb, ""))) + } + return this + }}), 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), g = e.length - 1, h = 0; g >= h; h++)c = h === g ? this : this.clone(!0), n(e[h])[b](c), f.apply(d, c.get()); + return this.pushStack(d) + } + }); + var qb, rb = {}; + + function sb(b, c) { + var d, e = n(c.createElement(b)).appendTo(c.body), f = a.getDefaultComputedStyle && (d = a.getDefaultComputedStyle(e[0])) ? d.display : n.css(e[0], "display"); + return e.detach(), f + } + + function tb(a) { + var b = l, c = rb[a]; + return c || (c = sb(a, b), "none" !== c && c || (qb = (qb || n("