From 8f8209db080d980f3138b23aada54008cda979cb Mon Sep 17 00:00:00 2001 From: Ace Date: Wed, 17 Feb 2016 00:31:11 +0530 Subject: [PATCH 01/12] Adding method to check if user exists --- .../api/DoorManagerManagerService.java | 4 ++- .../impl/dao/impl/DoorManagerDAOImpl.java | 28 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java b/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java index 359b035b..40546dc8 100644 --- a/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java +++ b/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java @@ -274,9 +274,11 @@ public class DoorManagerManagerService { String accessToken = userStoreManager.getUserClaimValue(userInfo.userName, "http://wso2.org/claims/lock/accesstoken", null); String cardNumber = userStoreManager.getUserClaimValue(userInfo.userName, "http://wso2.org/claims/lock/cardnumber", null); if(cardNumber.equals(userInfo.cardNumber)){ - if(accessToken != null){ + if(accessToken != null && doorManagerDAO.getAutomaticDoorLockerDeviceDAO(). + checkCardDoorAssociation(cardNumber, userInfo.deviceId)){ JSONObject credentials = new JSONObject(); credentials.put(DoorManagerConstants.DEVICE_PLUGIN_PROPERTY_ACCESS_TOKEN, accessToken); + credentials.put(DoorManagerConstants.DEVICE_PLUGIN_PROPERTY_ACCESS_TOKEN, accessToken); return Response.ok(credentials, MediaType.APPLICATION_JSON_TYPE).build(); } } diff --git a/modules/samples/doormanager/component/plugin/src/main/java/org.homeautomation/doormanager/plugin/impl/dao/impl/DoorManagerDAOImpl.java b/modules/samples/doormanager/component/plugin/src/main/java/org.homeautomation/doormanager/plugin/impl/dao/impl/DoorManagerDAOImpl.java index 7876773b..56ee8906 100644 --- a/modules/samples/doormanager/component/plugin/src/main/java/org.homeautomation/doormanager/plugin/impl/dao/impl/DoorManagerDAOImpl.java +++ b/modules/samples/doormanager/component/plugin/src/main/java/org.homeautomation/doormanager/plugin/impl/dao/impl/DoorManagerDAOImpl.java @@ -261,6 +261,34 @@ public class DoorManagerDAOImpl { return status; } + public boolean checkCardDoorAssociation(String cardNum, String deviceID) throws DoorManagerDeviceMgtPluginException { + boolean status = false; + Connection conn = null; + PreparedStatement stmt = null; + try { + conn = DoorManagerDAO.getConnection(); + String createDBQuery = "SELECT * FROM SHARED_DOORLOCK_SAFE WHERE" + + " DOORMANAGER_DEVICE_ID = ? AND SERIAL_NUMBER = ?"; + stmt = conn.prepareStatement(createDBQuery); + stmt.setString(1, cardNum); + stmt.setString(2, deviceID); + int rows = stmt.executeUpdate(); + if (rows > 0) { + status = true; + if (log.isDebugEnabled()) { + log.debug("Lock : "+ deviceID + " is associated with card no : "+cardNum); + } + } + } catch (SQLException e) { + String msg = "No associations were found between lock : "+ deviceID +" and card : "+ cardNum; + log.error(msg, e); + throw new DoorManagerDeviceMgtPluginException(msg, e); + } finally { + DoorManagerUtils.cleanupResources(stmt, null); + } + return status; + } + public List getUserCredentials(String deviceId, String UIDofUser) throws DoorManagerDeviceMgtPluginException { Connection conn = null; From bb1216c6bfb4d2477ea29f2e8d53221e7885fb25 Mon Sep 17 00:00:00 2001 From: Ace Date: Wed, 17 Feb 2016 01:19:03 +0530 Subject: [PATCH 02/12] logic to send event to CEP --- .../doormanager/component/manager/pom.xml | 5 ++ .../api/DoorManagerManagerService.java | 48 +++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/modules/samples/doormanager/component/manager/pom.xml b/modules/samples/doormanager/component/manager/pom.xml index 3efeb0df..130acacd 100644 --- a/modules/samples/doormanager/component/manager/pom.xml +++ b/modules/samples/doormanager/component/manager/pom.xml @@ -228,5 +228,10 @@ json-simple 1.1.wso2v1 + + com.google.code.gson + gson + 2.2.4 + \ No newline at end of file diff --git a/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java b/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java index 40546dc8..d7ccb5cd 100644 --- a/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java +++ b/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java @@ -18,9 +18,16 @@ package org.homeautomation.doormanager.manager.api; +import com.google.gson.JsonObject; import org.apache.commons.io.FileUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.geronimo.mail.util.Base64; +import org.apache.http.client.ClientProtocolException; +import org.apache.http.client.HttpClient; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.SystemDefaultHttpClient; import org.homeautomation.doormanager.manager.api.dto.UserInfo; import org.homeautomation.doormanager.plugin.constants.DoorManagerConstants; import org.homeautomation.doormanager.plugin.exception.DoorManagerDeviceMgtPluginException; @@ -46,6 +53,7 @@ import org.wso2.carbon.device.mgt.iot.util.ZipUtil; import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreManager; import org.wso2.carbon.user.core.service.RealmService; +import com.google.code.gson.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -54,6 +62,7 @@ import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; import java.io.IOException; +import java.io.UnsupportedEncodingException; import java.nio.ByteBuffer; import java.nio.charset.StandardCharsets; import java.util.*; @@ -279,6 +288,7 @@ public class DoorManagerManagerService { JSONObject credentials = new JSONObject(); credentials.put(DoorManagerConstants.DEVICE_PLUGIN_PROPERTY_ACCESS_TOKEN, accessToken); credentials.put(DoorManagerConstants.DEVICE_PLUGIN_PROPERTY_ACCESS_TOKEN, accessToken); + sendCEPEvent(userInfo.deviceId, cardNumber, true); return Response.ok(credentials, MediaType.APPLICATION_JSON_TYPE).build(); } } @@ -301,6 +311,44 @@ public class DoorManagerManagerService { return Response.status(Response.Status.INTERNAL_SERVER_ERROR).build(); } + private void sendCEPEvent(String deviceId, String cardId, boolean accessStatus){ + String cepEventReciever = " http://localhost:9763/endpoints/lockAuthorizedEvent"; + + HttpClient httpClient = new SystemDefaultHttpClient(); + HttpPost method = new HttpPost(cepEventReciever); + JsonObject event = new JsonObject(); + JsonObject metaData = new JsonObject(); + JsonObject payLoadData = new JsonObject(); + + metaData.addProperty("timestamp", System.currentTimeMillis()); + metaData.addProperty("sensorName", "deviceLock"); + + payLoadData.addProperty("deviceID", deviceId); + payLoadData.addProperty("cardID", cardId); + + event.add("metaData", metaData); + event.add("payloadData", payLoadData); + + String eventString = "{\"event\": " + event + "}"; + + try { + StringEntity entity = new StringEntity(eventString); + method.setEntity(entity); + if (cepEventReciever.startsWith("https")) { + method.setHeader("Authorization", "Basic " + Base64.encode(("admin" + ":" + "admin").getBytes())); + } + httpClient.execute(method).getEntity().getContent().close(); + } catch (UnsupportedEncodingException e) { + log.error("Error while constituting CEP event"+ e.getMessage()); + } catch (ClientProtocolException e) { + log.error("Error while sending message to CEP "+ e.getMessage()); + } catch (IOException e) { + log.error("Error while sending message to CEP "+ e.getMessage()); + } + + + } + @POST @Path("manager/get_user_info") @Produces(MediaType.APPLICATION_JSON) From fca3016181b93397cf77c79b0d330f71a1d31ee1 Mon Sep 17 00:00:00 2001 From: Ace Date: Wed, 17 Feb 2016 01:39:15 +0530 Subject: [PATCH 03/12] Bug fixes --- .../doormanager/manager/api/DoorManagerManagerService.java | 1 - 1 file changed, 1 deletion(-) diff --git a/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java b/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java index d7ccb5cd..c7461a7b 100644 --- a/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java +++ b/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java @@ -53,7 +53,6 @@ import org.wso2.carbon.device.mgt.iot.util.ZipUtil; import org.wso2.carbon.user.api.UserStoreException; import org.wso2.carbon.user.api.UserStoreManager; import org.wso2.carbon.user.core.service.RealmService; -import com.google.code.gson.*; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; From c556a9a7b052e137242b4c667113b170e6076314 Mon Sep 17 00:00:00 2001 From: charithag Date: Wed, 17 Feb 2016 16:35:47 +0530 Subject: [PATCH 04/12] Geesara's changes --- .../api/DoorManagerControllerService.java | 36 +++++++++++- .../api/util/DoorManagerMQTTConnector.java | 22 ++++++- .../api/util/DoorManagerServiceUtils.java | 54 ++++++++++++++++++ .../api/DoorManagerManagerService.java | 16 ++---- .../impl/dao/impl/DoorManagerDAOImpl.java | 48 +++++++++++----- .../device-view.hbs | 2 +- .../public/images/doormanager-icon.png | Bin 40558 -> 6697 bytes .../public/images/thumb.png | Bin 44816 -> 6697 bytes .../public/images/doormanager-icon.png | Bin 0 -> 6697 bytes .../public/images/myDevices_analytics.png | Bin 104066 -> 45802 bytes .../public/images/thumb.png | Bin 48636 -> 6697 bytes .../type-view.hbs | 2 +- .../src/main/resources/carbonapps/Sensor.car | Bin 0 -> 6981 bytes .../resources/database/doormanagerDM_DB.h2.db | Bin 0 -> 18432 bytes .../public/images/doorManager-icon.png | Bin 0 -> 6697 bytes .../public/images/doormanager-icon.png | Bin 40558 -> 6697 bytes .../public/images/doorManager-icon.png | Bin 46940 -> 6697 bytes .../public/images/doormanager-icon.png | Bin 0 -> 6697 bytes .../public/images/myDevices_analytics.png | Bin 104066 -> 45802 bytes modules/samples/doormanager/pom.xml | 7 ++- 20 files changed, 157 insertions(+), 30 deletions(-) create mode 100644 modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/util/DoorManagerServiceUtils.java create mode 100644 modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doormanager-icon.png create mode 100644 modules/samples/doormanager/feature/feature/src/main/resources/carbonapps/Sensor.car create mode 100644 modules/samples/doormanager/feature/feature/src/main/resources/database/doormanagerDM_DB.h2.db create mode 100644 modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/doorManager-icon.png create mode 100644 modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doormanager-icon.png diff --git a/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/DoorManagerControllerService.java b/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/DoorManagerControllerService.java index 2924a442..eb51bf19 100644 --- a/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/DoorManagerControllerService.java +++ b/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/DoorManagerControllerService.java @@ -147,11 +147,13 @@ public class DoorManagerControllerService { @FormParam("policy") String policy, @FormParam("cardNumber") String cardNumber, @FormParam("userName") String userName, + @FormParam("emailAddress") String emailAddress, @Context HttpServletResponse response) { try { if (userName != null && cardNumber != null && deviceId != null) { try { UserStoreManager userStoreManager = this.getUserStoreManager(); + DoorLockSafe doorLockSafe = new DoorLockSafe(); if (userStoreManager.isExistingUser(userName)) { TokenClient accessTokenClient = new TokenClient(DoorManagerConstants.DEVICE_TYPE); AccessTokenInfo accessTokenInfo = accessTokenClient.getAccessToken(deviceId, userName); @@ -165,7 +167,35 @@ public class DoorManagerControllerService { claims.put("http://wso2.org/claims/lock/refreshtoken", accessTokenInfo.getRefresh_token()); claims.put("http://wso2.org/claims/lock/cardnumber", cardNumber); userStoreManager.setUserClaimValues(userName, claims, null); - //TODO: Add content to dto + doorLockSafe.setAccessToken(accessTokenInfo.getAccess_token()); + doorLockSafe.setRefreshToken(accessTokenInfo.getRefresh_token()); + doorLockSafe.setDeviceId(deviceId); + doorLockSafe.setOwner(owner); + doorLockSafe.setEmailAddress(emailAddress); + doorLockSafe.setUIDofUser(cardNumber); + doorLockSafe.setPolicy(policy); + doorLockSafe.setSerialNumber(deviceId); + boolean status; + try { + DoorManagerDAO.beginTransaction(); + status = DOOR_MANAGER_DAO.getAutomaticDoorLockerDeviceDAO().registerDoorLockSafe(doorLockSafe); + DoorManagerDAO.commitTransaction(); + if (status) { + response.setStatus(Response.Status.OK.getStatusCode()); + } else { + response.setStatus(Response.Status.FORBIDDEN.getStatusCode()); + } + } catch (DoorManagerDeviceMgtPluginException e) { + try { + DoorManagerDAO.rollbackTransaction(); + } catch (DoorManagerDeviceMgtPluginException e1) { + String msg = "Error while updating the enrollment of the Door Manager Locker device : " + + doorLockSafe.getOwner(); + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + log.error(msg, e); + } + } + response.setStatus(Response.Status.OK.getStatusCode()); } else { response.setStatus(Response.Status.NOT_FOUND.getStatusCode()); @@ -184,7 +214,7 @@ public class DoorManagerControllerService { } } - @Path("controller/registerNewUser") + /* @Path("controller/registerNewUser") @POST @Feature(code = "registerNewUser", name = "Assign to new user", type = "operation", description = "Assign to new user") @@ -241,7 +271,7 @@ public class DoorManagerControllerService { response.setStatus(Response.Status.BAD_REQUEST.getStatusCode()); log.error(e); } - } + }*/ /*@Path("controller/registerNewUser") @POST diff --git a/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/util/DoorManagerMQTTConnector.java b/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/util/DoorManagerMQTTConnector.java index fd1919a2..bf61fdb8 100644 --- a/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/util/DoorManagerMQTTConnector.java +++ b/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/util/DoorManagerMQTTConnector.java @@ -12,6 +12,7 @@ import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager; import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException; import org.wso2.carbon.device.mgt.iot.transport.mqtt.MQTTTransportHandler; +import javax.ws.rs.core.Response; import java.io.File; import java.util.Calendar; import java.util.UUID; @@ -80,12 +81,16 @@ public class DoorManagerMQTTConnector extends MQTTTransportHandler { } if (messageData.length == 2) { log.warn("-------------------------------------------"); - log.warn(messageData[2]); + log.warn(messageData[0]); log.warn(messageData[1]); String lockerCurrentState = messageData[1]; try { SensorDataManager.getInstance().setSensorRecord(deviceId, "door_locker_state", String.valueOf(1), Calendar.getInstance().getTimeInMillis()); + if (!DoorManagerServiceUtils.publishToDASCurrent(owner, deviceId, 1)) { + log.warn("An error occured whilst trying to publish with ID [" + deviceId + + "] of owner [" + owner + "]"); + } } catch(Exception e){ log.error(e); } @@ -110,6 +115,21 @@ public class DoorManagerMQTTConnector extends MQTTTransportHandler { String payload = operation + param; try { publishToAutomaticDoorLocker(topic, payload, 2, false); + if(param.equals("LOCK")){ + if (!DoorManagerServiceUtils.publishToDASCurrent(deviceOwner, deviceId, 0)) { + log.warn("An error occured whilst trying to publish with ID [" + deviceId + + "] of owner [" + deviceOwner + "]"); + } + }else{ + if (!DoorManagerServiceUtils.publishToDASCurrent(deviceOwner, deviceId, 1)) { + log.warn("An error occured whilst trying to publish with ID [" + deviceId + + "] of owner [" + deviceOwner + "]"); + } + } + if (!DoorManagerServiceUtils.publishToDASCurrent(deviceOwner, deviceId, 1)) { + log.warn("An error occured whilst trying to publish with ID [" + deviceId + + "] of owner [" + deviceOwner + "]"); + } } catch (TransportHandlerException e) { String errorMessage = "Error publishing data to device with ID " + deviceId; throw new DoorManagerException(errorMessage, e); diff --git a/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/util/DoorManagerServiceUtils.java b/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/util/DoorManagerServiceUtils.java new file mode 100644 index 00000000..7775005a --- /dev/null +++ b/modules/samples/doormanager/component/controller/src/main/java/org.homeautomation/doormanager/controller/api/util/DoorManagerServiceUtils.java @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2016, 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.homeautomation.doormanager.controller.api.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.homeautomation.doormanager.plugin.constants.DoorManagerConstants; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.analytics.exception.DataPublisherConfigurationException; +import org.wso2.carbon.device.mgt.analytics.service.DeviceAnalyticsService; + +public class DoorManagerServiceUtils { + private static final Log log = LogFactory.getLog(DoorManagerServiceUtils.class); + + //TODO; replace this tenant domain + private static final String SUPER_TENANT = "carbon.super"; + private static final String CURRENT_STREAM_DEFINITION = "org.wso2.iot.devices.sensor"; + + public static boolean publishToDASCurrent(String owner, String deviceId, float current) { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + ctx.setTenantDomain(SUPER_TENANT, true); + DeviceAnalyticsService deviceAnalyticsService = (DeviceAnalyticsService) ctx.getOSGiService( + DeviceAnalyticsService.class, null); + Object metdaData[] = {owner, DoorManagerConstants.DEVICE_TYPE, deviceId, System.currentTimeMillis()}; + Object payloadCurrent[] = {current}; + + try { + deviceAnalyticsService.publishEvent(CURRENT_STREAM_DEFINITION, "1.0.0", metdaData, new Object[0], payloadCurrent); + } catch (DataPublisherConfigurationException e) { + return false; + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + return true; + } + +} diff --git a/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java b/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java index c7461a7b..a6183dc3 100644 --- a/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java +++ b/modules/samples/doormanager/component/manager/src/main/java/org.homeautomation/doormanager/manager/api/DoorManagerManagerService.java @@ -273,14 +273,14 @@ public class DoorManagerManagerService { log.warn(userInfo.userName); log.warn(userInfo.cardNumber); log.warn(userInfo.deviceId); - response.addHeader("REMOTE_USER", "ppppppppppppppppppppp"); - //response.addDateHeader("Authentication","55555555555555555555"); if (userInfo.userName != null && userInfo.cardNumber != null && userInfo.deviceId != null) { try { UserStoreManager userStoreManager = this.getUserStoreManager(); if (userStoreManager.isExistingUser(userInfo.userName)) { String accessToken = userStoreManager.getUserClaimValue(userInfo.userName, "http://wso2.org/claims/lock/accesstoken", null); String cardNumber = userStoreManager.getUserClaimValue(userInfo.userName, "http://wso2.org/claims/lock/cardnumber", null); + log.warn(accessToken); + log.warn(cardNumber); if(cardNumber.equals(userInfo.cardNumber)){ if(accessToken != null && doorManagerDAO.getAutomaticDoorLockerDeviceDAO(). checkCardDoorAssociation(cardNumber, userInfo.deviceId)){ @@ -288,6 +288,7 @@ public class DoorManagerManagerService { credentials.put(DoorManagerConstants.DEVICE_PLUGIN_PROPERTY_ACCESS_TOKEN, accessToken); credentials.put(DoorManagerConstants.DEVICE_PLUGIN_PROPERTY_ACCESS_TOKEN, accessToken); sendCEPEvent(userInfo.deviceId, cardNumber, true); + log.warn(doorManagerDAO.getAutomaticDoorLockerDeviceDAO().getUserEmailAddress(cardNumber)); return Response.ok(credentials, MediaType.APPLICATION_JSON_TYPE).build(); } } @@ -311,22 +312,17 @@ public class DoorManagerManagerService { } private void sendCEPEvent(String deviceId, String cardId, boolean accessStatus){ - String cepEventReciever = " http://localhost:9763/endpoints/lockAuthorizedEvent"; + String cepEventReciever = "http://localhost:9768/endpoints/LockEventReciever"; HttpClient httpClient = new SystemDefaultHttpClient(); HttpPost method = new HttpPost(cepEventReciever); JsonObject event = new JsonObject(); JsonObject metaData = new JsonObject(); - JsonObject payLoadData = new JsonObject(); - metaData.addProperty("timestamp", System.currentTimeMillis()); - metaData.addProperty("sensorName", "deviceLock"); - - payLoadData.addProperty("deviceID", deviceId); - payLoadData.addProperty("cardID", cardId); + metaData.addProperty("deviceID", deviceId); + metaData.addProperty("cardID", cardId); event.add("metaData", metaData); - event.add("payloadData", payLoadData); String eventString = "{\"event\": " + event + "}"; diff --git a/modules/samples/doormanager/component/plugin/src/main/java/org.homeautomation/doormanager/plugin/impl/dao/impl/DoorManagerDAOImpl.java b/modules/samples/doormanager/component/plugin/src/main/java/org.homeautomation/doormanager/plugin/impl/dao/impl/DoorManagerDAOImpl.java index 56ee8906..56d5affa 100644 --- a/modules/samples/doormanager/component/plugin/src/main/java/org.homeautomation/doormanager/plugin/impl/dao/impl/DoorManagerDAOImpl.java +++ b/modules/samples/doormanager/component/plugin/src/main/java/org.homeautomation/doormanager/plugin/impl/dao/impl/DoorManagerDAOImpl.java @@ -262,33 +262,55 @@ public class DoorManagerDAOImpl { } public boolean checkCardDoorAssociation(String cardNum, String deviceID) throws DoorManagerDeviceMgtPluginException { - boolean status = false; - Connection conn = null; + Connection conn; PreparedStatement stmt = null; + ResultSet resultSet = null; try { conn = DoorManagerDAO.getConnection(); - String createDBQuery = "SELECT * FROM SHARED_DOORLOCK_SAFE WHERE" + - " DOORMANAGER_DEVICE_ID = ? AND SERIAL_NUMBER = ?"; - stmt = conn.prepareStatement(createDBQuery); + String selectDBQuery = "SELECT * FROM REGISTERED_DOORLOCK_SAFE WHERE UID_of_USER = ? AND doormanager_DEVICE_ID = ?"; + stmt = conn.prepareStatement(selectDBQuery); stmt.setString(1, cardNum); stmt.setString(2, deviceID); - int rows = stmt.executeUpdate(); - if (rows > 0) { - status = true; - if (log.isDebugEnabled()) { - log.debug("Lock : "+ deviceID + " is associated with card no : "+cardNum); - } + resultSet = stmt.executeQuery(); + String result; + if(resultSet.next()){ + return true; + }else{ + return false; } } catch (SQLException e) { String msg = "No associations were found between lock : "+ deviceID +" and card : "+ cardNum; - log.error(msg, e); throw new DoorManagerDeviceMgtPluginException(msg, e); } finally { DoorManagerUtils.cleanupResources(stmt, null); } - return status; } + + public String getUserEmailAddress(String cardNum) throws DoorManagerDeviceMgtPluginException { + Connection conn; + PreparedStatement stmt = null; + ResultSet resultSet = null; + String email; + try { + conn = DoorManagerDAO.getConnection(); + String selectDBQuery = "SELECT EMAIL_ADDRESS FROM REGISTERED_DOORLOCK_SAFE WHERE UID_of_USER = ?"; + stmt = conn.prepareStatement(selectDBQuery); + stmt.setString(1, cardNum); + resultSet = stmt.executeQuery(); + if(resultSet.next()){ + email = resultSet.getString("EMAIL_ADDRESS"); + log.warn(email); + return email; + } + return null; + } catch (SQLException e) { + String msg = "No email found for the and card : "+ cardNum; + throw new DoorManagerDeviceMgtPluginException(msg, e); + } finally { + DoorManagerUtils.cleanupResources(stmt, null); + } + } public List getUserCredentials(String deviceId, String UIDofUser) throws DoorManagerDeviceMgtPluginException { Connection conn = null; diff --git a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/device-view.hbs b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/device-view.hbs index 7506942d..4fc403d6 100644 --- a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/device-view.hbs +++ b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/device-view.hbs @@ -25,7 +25,7 @@ {{/zone}} {{#zone "device-thumbnail"}} - + {{/zone}} {{#zone "operation-status"}} diff --git a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/doormanager-icon.png b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/doormanager-icon.png index fe7065142f65a256763557df31e1a2ef1cf8eb99..a44f50fc48a55fdae888184ecb9133e7ff3f057f 100644 GIT binary patch literal 6697 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 bATa1N>A@I+6Bf1q=Z)TFBkht)_Ba0rw^AMC delta 40034 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≻aG zL5O+^A&5-*WBiwe3aKW;45QWc}&3M|BQh%~~aSg##83j7H#qDg5I(N%;jisWz^F1bAM38VHT(xeSC z2G#!}=o}4=kPl^N2^GrYMYD_+7DN|DHsHLL+5q39LiVRR(qrKy*_U~8p}~WEPbDa| xv4xLn(M01v%5|GS+x+j#|If41&^@6L1d;we?VT+3TL}12fASPjt@JwVe*i?#>p%bi diff --git a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/thumb.png b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/thumb.png index 510859d86cab2dbac49a30b96f213183593d0ea4..a44f50fc48a55fdae888184ecb9133e7ff3f057f 100644 GIT binary patch literal 6697 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 bATa1N>A@I+6Bf1q=Z)TFBkht)_Ba0rw^AMC literal 44816 zcmbTdbyU@1*DbnfkZzC;k?wA!1tg@qySv#)Nh8wTQqrB95Cf3z25AsbI`8BAecw6f zj&a8Q<1&UrHv5-PtTor1b49DYk;i=Y{22rS!BkX`(SShUjQ{;ZMFxKvW$}3q{v-92 z)%ASqV(sZ;=57U%vUD-GqE>V=v$4{!GPCq^`)(x)fgrfqY3h3FswfLvxHz$!{X2%; z*U1%}4S|SC__~@|I9Pd7n_Jn~Ig8PrboSCx+gXay>hP&>s<=v9+1e@iyIZ~Wf1_#P z?_eQhNh={vE$S-_F5qP4X-4hq?=n5pX&;P-~auYgO>U~hj==O(f-#%>8hwv zOS`yRQS-6$u~~3(b5RQjv2*e93UP63_X~ldFo#|GKcV$A1qL7%~oDGgl5S zc1{i_r+@GDpQAlIHLU*kWBgx__R#cmwc^mQ@^JBTw*d2DP4_=1gR%SnzR|w}!P5w< zy4!(CF>{o0vG8)Ta`se|5u*j)uv^+$3JYRDr#P*f zoH6+B#=s($%{xBJb}%vqlYopLr$p)F>YaMR3B__m`?j!r=hDrC9MjJxJ727s2Le*Vb>=31xFMLpRV}w?a3V?R`kFbyc&_^#9i-TfQ0cYHhsW<>l4%i=*#0EX{DplwgrH9Fvo` z@38pXcb#4CR+ZwGP`<2N^~#h(#Vdbb#SO=dZsObUFwfM~6dB~$Bf><5g_*fQNl9t# z*UnC)tehMJ7Nw|Ql%eK}7cT~UMOT&ES~xWE+psx?4BJjf@7F$`o}Ma+`JXF<_M(*s zFqg7@d(H2etMOHH@`;#;$a`vX^7+?oca*+TqjgnL(MYx8;U7N&@$vB!MTCT8lPpj| z8oBuRoGL0R7D#`)y{ptQHqKL1Q#-vs-55wrV>1}CN$`40_LlIa%I2B@;jFe1axGK0 zgmDfN6O+HSwe_$mTrhHP3&D(Ks3ZCqonncFSx+4y_v8QWf>U6u_*sW2e4Bh229s1FCMMQ_$f1z% zAnf%ULcZ84DGkqEXIXqruv5+C-bSFHpb(wS^TnW#GkN3fec6$dlcU4W&rb(e65uMB zQ{(%V$V+S_QOEW8iItW0=RhstbR>(dy+y^hMJ==u^U&6YK4SVuzsn;%EY_IH2=CkT z{g{WlD|G1hML}WVyhx?nISc&Pv9YmFNJ;TroSYf(v8@Qj5}ZnxV?TZfBSL>mv+7E{ zwNg>Rbj8QRQ!Y3WM}p-d^m<#A!(T&Uu+1=P4i68v9(`)ZE@5&VpF*A<9o~h7-E0lT zOBc(0w`E14s8dLUtb6 z{;q7Y7V@(d#4mn95fO?0>hE8_%J&A{T}DDkvLNKL9y=q7y#ZIwRu&wqau96_F)=Y7 z5}t?TDT#&`LaLMsV_q>DQB#U|Qe7q78 zPmBE#=p6YXJ~cUok@iV$mZ9lLtNvDPFn4SB_T{y8i^HAi)^Q1|_V)HWvjIr7t_`Xq z2LE&yQ)mPkM(pk8&EMU`(JVfeDBU)AEd*211c(MZr0ws<7H4_F-UF#3>AAFE{#Y*> zY!;4x25t0s#nf3G6&>ARwNxpc81r+Q>A(94hp{}8kdTy570IGkk5wUFzQs~5U!N$J zm*{_Yudby>&ANCAg(?E@0cXwwmIlxhN06}%ckjuVfObM7A9sc z+WMi-{^Sd~c^O2`M5LFhc_Rz$9yUVlmMKgtU=PFBE}Lejr_W*Onz~%i6V5xzU-O7# z@IWh7jI={DY3c^O6)u$g&vJd#R{y5Zw?C$?PI#0&!x~S4YD#7<>l|u(a9W5HSx0G)cfh_>Ae^l8uA{mec~n9v$nL9K|w@Z&JywYjd}g(zL)$o zXq26sOOc+DLGrjaQJfxyMe!{7{@RVwFr>czR+Sp3WTnH)Ve&mL-8<6kYN)P7D(h*C zZ}g6F>cyikWyz;cWJE+nmx$^I2-iYHkP;U|!yIXQdwYpChTet`vAMY`ytcc7n?Vh zB5w^-AdiOu&2kSE(JQZ@_`^JgGESg-_dYX%B!i27W4MyWH z85$Z|!@MjC6C#E2hR&;o@;=tRq4e|fYlnwi`QKe0GtMh8z&dWIg@oF-rYqj=yY0k0 zcWC~?O5|GwH-{`~PQfaSVM;jI)qnfl+)-Q01iux8$$WO*I@9lYVgdY+ze4Ei*W?Vp zMbziy6KHAuV~a(edt;DYZC-A(?DhAxV1=3vfzSH(gRd`Rck&?+iGM3h{(`Tp&N-$ajr(yVD*hO^$&HKCJV@PQ6uveK zp2Oee{5RUi9VZK}NSB_Q9fRaA<^|+D)+6%riIfk7M2Q^A%f7ez7#S?u)iCr9s_8tn zmGVUddlwd#s=}+^D@*9H{8%RFrakZoJk#RS7uUjx2q;*Am}7+I-%+qBmnECceig~a z?jQ(u5zQF4`S8>og&g$9nSE43Lqj9QUW>rI^%@WGS@1_OxetVdX?Y>ew&jZWIG3=0dZ|GF0CY0@9yKlOx7X8+33@#w*AYiN`PI{lH73bNSCWQrx~xi`-J%rfdN z*|DkpvRFY!Z}5XZai6dS$lRt90l~jp*Mbd@vu}8lNw-cyx*Cy8q8DKmAEP@eb*O{pbygYdMNYPn-so!Av{Tz(napYJK6YTie3{oYJm(g5p z&#gTkXE8BvLCE=pe1890lp1TtQ;Fh7hW@8s^Omdoo4)~EJU!mWi=o2rTpnYIIm-GQ zL`t|ui3vLkZ!{3yV7nGfJ`uglhWF}vaW^NWj7>QRRd@8e1d*L6t`U4@}sVK4iw_4RdIGqZ`ITf zrRPTrjbvr2`N5dtX&O-k@b<6VQ7K66=V~ahi2~sQSwr=ejZCDBhD+xWg(_Go5U|C! z+DU$SE-x>SKqLkFi$=UXJ(p#~s%|qszEo{Nj6Ae5H=m4mJ_Mg0&rVMT-_^FeZ~xen z3PVKXqlGg4s*e8h1P6oYZ*UnFPL%ylBtL%93EYjY~;MNlInW`7PxBOF`7x z!rXjQ)!W;?w%w7-nAn zfEXD<1clj+y9A*b3R?K$jEv=|_QFWss;5P;dMxp~qegxZx4e){FF83mVdCeqw6LaR zeczcVd`JiU!PE75e_2m#PnxQhKO8N*@-S*rjk^!hL{pb^6jp5LXEze`u4jmk4_9k= z^Q^()4Wr}ZW9!NnKJ*HSAV-N!^0N@tJ~8ZT%pk#p51`i@1<7A;da5 zddEZqt5is~EN<7Qgoau2q=Zb64MmYg1j2{ZH}9qyu9G{sjpHlcesVY6T-k7MM@X4K zHjQIiSXiiMXJ?lHh(1j%wj_?Xs*ngbYTQLDH22e|Pmdsr@u04=(TuqBqMmN!pqIp% zViFEEXCbP2L>~@E+e}u+$aB6>Ie2`Ae7ecu z@t@B@rBFj%S`F_eQ4F9i%UYM;z{}g(_ofZ-uiOg-WZW?_CsET$uO^S7L zv_!N_m0Y2@hHWK5FEA(d5z*=33g6LO9vF3a+6i(_4T5p|gflm>S-*2QSKEv1Evm1h zGxz304}u&K222E#e^7I%tf*XsSzM5!ytvqdkZI2hprSkHf0;?U#_%SNB;P*r;P`lj z11#F@Ig=2TvfHK{xUN#oCkIZLrexhB_q#9lI2L_YajlYry0MG4pc+(4q{Hmck89E7 z41V_bcz42%&!9YC`T6s4!3bY+R@Q-olhebCSzonvC1+6pcq-XX-B){pmU>jO`AK}g zuzw@wFgE1j=H?#y&<^FY3vFXCegB<2P!7@Yb5ltPJ$8ok^ZYSY2~ZU@J1w=y@<5uB z#}|^q3P0ajqLTNLbOm~3F(*O z;=$5Y+Mg@wJVOa^FpIX$Fv?q6T8v6Dm94FJLUwj`Vwu(}jg#ih6^+LuY?^twxX!{7 zFOzG&+%AA{DgWWa2ed|;G2_?oeuMb*Gx*Qud~*CW>)XQ4kS0 zyvu9zg#1WEH^VTl{BLI##;Wgn`0E$kNw!qpd2NGhAnWSsdCg5v5B_|io6Hsdq5v}$ zr8)VB`@6g6wFpwA1WEVqryYCq^;@oP511aCsTCDW;?zHjVd)jd7G7PI`cSk9$(Jpn zLASiuu^c_9k^o%uc$jK&6B*(%C39=SJ;z85Lk{ywq1&M5Nd+s$BlN?EB4)Hi5eD68 zd!HAD2J|OY^pN7@LKX(>;~!|LGDvj~RK-O_)n;Z|6vBP_tdBRl`C&CCy_7zW0DRXa zbt)Wq@bEOE(a_LvND{25Ub0~=(qbPPb$YWAOZwEZ7LXAToELzd@@e;Hu7il(WQhz; zmBD83z)%3X9jWqiGyIT6ObK!f%9kj!Ek=GNb64 zA{A_63Gca3!gpFbJ4J%8Itg?SH8jG+D}@HPVr)MR4X1PTCQa{xO>TvF?GWRa@S50b zl)KvPXudu!CML#Gkys^P{K3N1zGd(gGYyFE zeYg6r$%A=(PuD;G>Wub1!Q*-|p)I0fK~*EVm2eYBD;i25w?H;vvk`p@BeB`hCBkoh z@0*W@Y-c)aKExn1TSO+{jNt=Hs*kiY^jwrsw?W~n!Xp|e>nTu2MqHQrp&cM^vC3ZiF|IW7~(o(y1}}u6y%=k zC$~)n%EZ<;i+3+yypZ)gS$$B|w7Av6aJ*x1q?DqQPgtfm4|{<<@|yJI&1LksAl?Jx z^cb%ov)O&gC>mbDm(fm*A<@sK3Z}fe#2Oymv(F(+1Jxkg;sdDi0{N~NEFyedX2Odf z{uO0d1itAr7gtwbDILBfGjMvdo?cw6#I1_Zn9}(il|!+~77MNx=v|#6R=;k3Ihw~~ zej{nC5N%^F)-b5tgPdqU9lHfr_`Fbc!Y@vmLO;Y-;Ue?_;Q!F>vpQqqD6K(^S;CN2 zKqeSMzWUlBUjZ19T^`I=c&qVNW3Aw7mf4VG%3w0@;rB`>F`Ge4PTXpMm)T2%>gRpR zqh9-yrN!?rH@RHon+M|Xnwv@d{ndl|?Oty&o)}8^dvEA|F;(uCz-q9RAHC5Yd|nrY zdDwt)#!^)M`E&hON^jJC1+n3bED`eNK2|`^cXM!Eph*vJu$8jT>Gkig(ek)(*t8{>? zgsR>R)w?_2_rQRhMhvce80IsqGwsu$cYLIu{6bJgLQ6+C+T7ec_j>B^5#W|xEGlvG zVL=Qw%cj(6BO)HGVMIL72IddH72>ekQ{3d#KOX{gXbjsr%PFZ?L&1Fh>*u&1x(qpT zgRrp{@*3c8p5W1Ew9;Y$y%yE#w4{xKw)7<}S}>3i-|JhU99b3wt#gEk=e&3(>f;*N z@wMkPIc?^4c0#u!nLH1f>nyM4s?1zmp4jf&Q%iPV(9?IpwFD&2lgm)#5b|LCun(=t zDyPXr@z{oSdV|;^M#c)pH1k z$Je|0Ay~4_qqc~&Zwj;`Zy4LuGNZVQ?71NJf2KaEUZtg^(7)ELUIz0T!W45cxgHx* zR#w&$@ugQmybK)!cnnhRU$pO^@Ki>W zm6b*RfljINp|0x1pe%S3Oc41`7%4h+3Bzh@Pg0|>sjRu?1?}J&f8a$h;Wb8>)@^KT z@Shf^i(ZkEk_y!rwof9>?0uN|St&&!RcxPR7WJFvB%af3G30W=#vAd}{R0NWn*-FI zP37{WIx&aTo>Nep8-!jADf*Xv`m`H}eE2y{Skm8ablY9xgJ;N_H*XH&NO_#O=h@LZ zN=833{uOTiXlkja1SWpKjLj?UN)C`8KNaTTWeVrJSWo$j8@vv+*)mwI|EvNaIcMMZ z4rw5%?##!C0YjYWx1O=_>Pu$k*9Kwgn##&nl>J&^CzGX0YbB+nM(MPL=fb|Hrr3k7 zl`z7`6OZ#pOGDNrvB2w7A^Ia!jegS(cr+E~S*VhgGJk|0e?e2zv}~q_vb?-a%)2Yn zSUq`rxE}j`?xW*lqnjBWlT^s{>+HIZV7XfqeE!U4yVAi&OyWWcvBcBJ+wkEEls9#A zb7Mh4iE1Y#B$Nvjf1-p0Qsa3)5V{jkyciV{&#QGbnl0xL+LKd-#mo1haN@}XbB{@Vo~T^FGJ zvR-ZF$oCB5Kuk!On__)ZQB@^^+dakrjX!c*By>EF|4dyM^og*to^6|PKnPC8`mUj& zK?Oc^o%{XjuyMElj7ExJ8LfpJ*`CAO2U`j%s;5r`ovZNkoNkrmM_n4*BS{}W{%t29 zI|>JgYIFLvpe_2(U(jQ(-8pI!ezvbh z-`Ri$S3Dv2QA#O@^D1!}Nl&Hj9z``1b8I)q8a7 zYvOM4V*Rs>KGg#PmbCkop&f6)>i{ru&q(e>r=lIJS-(dB`1JzJMF8D0MiUB%yRqA_rr()34@%alap zQo70$FjHg5#~WOk&P#=BXoX&*Y30LpP^Dq~TMdmj3TAa?X=!QmnC+wBx}t8A=8BF! zUlS-K-Z~O1v0O`{1W=kMN{i8dL24JOGe}zYA6TA8@u0`BM;%#k0YC?{{ECi+bhh!Q z2MSszfyH;YfVu@JqPxoTB}^==o_DLeVFN#vjw>!K%iqN57=;q65*5$S&(BOUpg~te zAh38>u>{x}QMZqYQ)qb5C0`0^muH>5*z0@l^S^&RSlHRc5ztwYbpVh72cDFZ z!<#GDwPu%gR6L)?_1%ZfAOnKf4gvo%mG=~BT*>$HXhA>bSYHiYhl%OC`Z08t_wYr~ z7FVb9*}+VeI^?xDFC^^SPI_+c!^M|aVyA2#bOwIu`<^tI=EIBlub}cuG`)Pbg~z<# zkuBgtN$c5}TXE))=1AO1cw34PcjpgTlw`h?BH>)6*d5DvNwha-OqzKQZxUqHV1%2^ zfc*`|WoyvZ)J%Yb;~FW{2HiI{>5qmP-07igM)n3i`^AzeW6GL z??mBYe7Y&R3x=NEy-$w;0(*yyZd;I(95OPp0If;gZXg)J^;LJ^rD3S#9dEX*w0p?o z^Uqa4T67d)5k9@7czE1-c_;+91yx8$T^dq4q)y?ZJ!DPC#-(vc^L`A~x%+!TByR*> zk4ozE)|t_0k^5H7VAi2OX))O_v9boDZU#v_3-n4sb5;;!Dq|@8J7WXo$gATAMdU$R zUS2Q`ktJ)Pd;mIZJ2xqb6Ky8^ljEenX&F7d`32i|Tx2A8MGMcHKigu6jqXx$ZM7F-uieDBnwm$I>6R#`5x?K6eQm?C)Pt0-5wX5HnhFxatobtz|RxKd`qH znNyD?(S|vyxjiRpUut69U6uY zB-uGbOD^G#CXK^Tu>WymoYRw&lY?omsgZ|T9T)I;#$TCFq7qyn;vvX1T|Mt^`xYS= zIX#sj>i0+K`X&U#>n&mLqwCC?8fP60Sew4SehU)hk(}r>*uY>3{nxvav#MxcC#^6S zOG`^=bF-J|xsQV%)jJ+>DlvavxacvuIZFs}384dInZq~GJEGr{3H~~0NU;JI%lHylL^_iSftE9y5?luvHYs8n{t_ByW@dlp<17%fLgZC(AS-x7GBj^%=Cb$R z$lO<&atbZd#Xjoo93SUSfk-h5(BGr*%a^-EtiOEkFXxiH!h?~ZHz6?Wj0^_{ihsVX)KMlI z3;YThy&tGM_~(DJG0Y2kaA~uBi$Eui%*evkRDe7E((1C7K!gN~ z|LhD)!;BGKpQ+M0Q;_-bcSwV0y=QP@*A&5UxlD!31Y*c>{gxQd73gQbbHoC?+nbv& zEf;fU3E0fxUQr+~3{LaW~J{odF(8v}ZbI0Dy+iFkfK z46<$pc!Wi5L&JMj1qFo=nGDJaE}G})fpAI51nrp`NL+vY`P#BV(#v1eiRu zT>*FAtA6|!?E=w+kMCu%EQ9EGOevWLl%X?aWRXD`)2Npd0TzM6E3K0%KMpc*)4aQ2 zWpC$?FtW)Oim!e*P;h{KZxtN;$inqI$EA=83x2DAN9UDZGTEQ*@{?&ybo6ZP3d#MM zsyW1SaidQ3i$~1gyrFmK{0W6k1{{s?b#QW4mX?P4jnGjI|B>v2}9PL12rjp_}k zT3$nH;gXZRyKqHezSGvwrO4ypea%C`oKhvgZHhq&DF;qyk)g!^qVlsFwvFS>Ai`I^ zv0Ih=Nw8S=T}21cmyM0>4F2oBt*{zQivn6oGX&wUWiR=Z`Cf?N4JrD_+Q1@#}r zdg)f*=69#Vtt}oZBISBkN=IN%`Kqp>Y)mmNBRZH=ca=?qlp{CIU?$ClIWjLoB@rAL zY;0_t)OLlaeYpu(-M@?wo!5>rk&sm&q?ol%=PAfk&)s4fBmCXfaf8N6^Ocp9b9IhP3=Tlsvb-~o}2X+)R znOd!uJ0qEJK&~(%AtdzD&@3}yWBcq31Z)XHBBH#2+w%&Mi@Yx6@h9#0_@17gQd)t3 zCAdyFR{iREK@(*w$ln5j1Zzn-9Z^Z^m%l;C)sW;CX6c=#|87$7W*vk;4aZ4@jr;A-6s@ZtHM4MM;C{J1TL z(ZiD~-vt>2UIYfV7r@uh}`K@~D;IhM4SJ;h| zcG!sb10?I93e2n~O=`GSR5X+&7h4A;yX;{`Bcqjp)A~=!>-`(9pR23S%dghyHZ0+1 zR@3eMU}Zy<$YnLejr4DI6|jF1I)#pknsj(pAXK8|OwkX%LOVdYJso{F`CyLQiq9E5 z*4Eahbd96_?v@6JV*1z&SoyP0YDkleO2;XO`7ErAR}CUMp5sRxE=R zgp5YcBgOKGkMb1f7lpx>C7S5$DeQA;f+bF_K^@hEJ2DcAC(Je1*Vjj~e7Kv!Y9|iL zHTYhGtX@}!RcSG{jjSpvDin6aE{jceRzR}j+?qiqB0;OZ+GufFdR-npXq7R{8!@Vt zbCsPmCd!&T&F{2$?+ZkJMM_Fa4_9p~+yj&=ptc8WZ*Rwo0ZD$5qvx77vxh1`iAAww z4iy!(4q9(p^=%YrLD#SYUX9?aY~~#l>S^NnYyB>}XbqP26%onfa=z;D(FFmK~a+VqIs)z`#JsL`tzsLIQ&EAhkZ6W+gQzk<+rgecgef zp&i0|jAD8UVA?uSP4~uEU<;&QjIB$~NVM0PUiFB#3~%f2M@#m808y{!X*=B{N0yTr zGxAxnVh_vKX}q;*$?sOzhuaGpAY_=()6-u|<#*vOvIDkkk&glJP{9)2= zAXGiLWKZNd;A&X)n`~JNjVti4HCX2?#tWq8OnG!)V0mt2WdO#3!p+-zs6feO$0`mp zt77=Gb%=^+x9CF1bC|bHXJ=;!yHf`eGO`?~sb#0r_5tHIboVy)EsD%?PlII%G$PgY zV7el8uN#vA*~~HhJ$Bxnq2nmcb(`P{$82m%nWuY=POY&K<_Q@~g+$%Ho~`Ykr{bz5p;0P{Pk!G%~4{Uk~%!jaX50VAVG`ja&vp9i*RPzE zGc~p|KoA;?2XyLo)hU-F{gfVMJRyaHHEl)EAZdFO*m?pE<3dwcVeG{P3f2%-tUF32 z*X>;LZUL&vUr-2XL)>ebQ`PYB@i_{!5Yrz^wv_JPWd(2aRWZHB_+Mi;LpWoUGpfj9e}k zio(VP0D1U)NK^Q5ZmFcA@^CePEpa3nnyS%&Ezq#UmD|vXg!DXv&l?f9LlxLCtaAMH z;Qz*lVebDP%@znKeqJkHAt@aa0(>_b&XMTi+6%3TA_Ooo&&wB zNsknn{4XXMKL$)#M2N_*0GPQ1H9w*@>eU-_Ie%@MBXjbO>?8@c(f5ho3BEo76qxa(COSmMOay>?${H%UQ0I^z zn$_rq`kYm&jh&HM*qY3=nJV9DX=#7sviEnZ$H&&8%@8klR2vcbYGM1fPY=S@?XIR& zB`{H-A4mi1%X9Pcdi2!QJEI#+oSum)%t)sL8TNB{Pjvb$6`(3Z)JF6yLkg~dp8C4-d}(`w|^v%M!&5eRFl`Z&0R>hNh4I{bM^DD|@6>r5*oscsMr6Ytu}f zjOca%MC!zk^3%>m>s31xm-9G|XP5LOKix&NL8`8!&!TsqA;v*L33Zsg8WnyDMio zZOC(IrodoE<0xi+%Muh6RPo^X=hyd(Dy}dmb5J)>FCMO$O+jjR34*W4FMXx!M5NE->npxa)@bd8m2%O(Ziuj9& zh-|eHOqoePOifJG_ok)IemzY%{<0FLf+8&~{U9bPnt&M0R(Bk=mgC06^=yn zKN&0gq3`WZLGAf@Ts5zVGd-ixTf#1xPXbuWt&TtnW zD~#2cxP)0)9L|zxq`eOg53iEFodA^n3xz@*>2q+>G&}1GfWb9z{cw9bH8mrn%^>X# zh!w(b@inET^ zM)gl(?W@VdHRfRqsr5c5s~4lkxzPGg@OzXmGMwvC%c{5wVt1)VoTN?LSVA=oC#R?H z^|i;poCJdy5eDg)BRN3Q{z6?^w_~ZnKxAdCP59~z@JctpE_VC-`^T4hSXfy3KmK5V zBFRy6tpgD5-Y}?ylB%l2c%@d=-*N_2A*Y%dR#Hy7JU5~CvZW@wsiRetA*F1b%uEK0 zSMB{-JbUJ_h;~~{=p7U1^8RU6r|8u{&_56JGFVQA67=NDxnpX4z{SjM{G|>F_vH(=5(+tPlvPO;Y z6v@p9Qsl6sjaQ!w|i9l~CmBZiee{nEJA>y4AS)$7(BQKwil9q!R zM-%w;_#lu-E|mN({I4^brkUAR&pV$SI9NcDP>(by6Gs4t&?5{YG=_hOnx-VeGppga zth;L&IXU6%>}>39SHU-&FE0R+-&Is+BcK3gsjGKL==Y@b;j^J1f6{X+As_g+4Z+vO zog}_pz*$#9!T4H_ey&|>eEjFIwl^JeB5x2 zj-LLP0^mYIUP4=CWTEMKUuU!#A?41E)}zV3wmBa^;-ir5&%Jkh&m4OEgEvvH3b{pr z!UdN(irL~8@J5>CA+n1Ifk8n}KHwsWLvf@Q(e{5n&IrBKeaiwmL`+}|(+xtsVcp#i z1z^GoG4U>6InHV`$}CmwECRUP30%{)*;n`$*YDJV z?o~f@wGhy|VxSyRM04=)@I#mTQ@iC|W1D|(Y9a4W5O7RHfSOngVjmH3L&+gH5S3Z$ z#sO=##PGKJ%PM%5P`7A=0^#2~J1tZ*f~uPJ9oF2G&!>^i&CJcY$%m|PpiVB=9>hX- zG~K`{@pJ{!G{!U6OgPuQzi92)Q~y%C&Id)Ks!$u;ns z^*elHFdb`eFH+0CFb zi096)q(0G%zN~B~y>ig=dl3+^fpzM9 z6fET<*-(`WU*6^ceiC$(7ZrL9fFA9!0@Row7T00s5cg`?fG_DnG}qymdSAC!3O1$+ z=#x`ZCXD^uczAd}0jGv(v-hQa)N%YSP)mi~Nwlv{GkHJe+Y-?wAWSm%f+~Hx83ZY{ zb`pT*)(EnWp@y!mulA}BD+dP$P|z+(C4%n*eP>C|#S34)*@@0&%fX>D@UW;h(t@#q z@E?Bl$&t?P&e+Ia{Q%^tFi^&0g>kR+_xEef?zVSyU;&!)hZG<3!3bw~ynkDmo-q*1 z4e02KolYHWw5&Rcp5>1ve*f{K!_>i{6OOO&y$3D#CtE5Z_mVAO`8^qSm+(${9~Xxq z=(-L|1vINX&4%gKCOp!NA7w+71MBIm*CdbFk}YIN!poHVid?{X*%ye_eF`z%&ftfh zGwl?pee$3@^J@k^A~jQ*c3L9;Qj!b#Aa-ZgpX?2Q;Kd8!~wl-R%I@1e67)bML?NqGu&>CgNIO*$TQL#jS~5+EVE zM^Wo+Fl7k{RXKPuEeY9h_&3l0oc*4Ibzjm_(YDSYXcathU)nq7H)2?T1;i&OH&@_o zfkAlq7`{TJ(%6eqd2$OaOx9CoGAN%6#5MJ{Z)qvudcNM`3Q}&zr1&d-YN;mo!LMzT%`Tmxf5U#zV+SykxHX*O`y-XNg6x@3M{vk zm6Z!1IPJxe60mN*Ih`Vew#0W(rtop%^x~i*7M}8S0h1~LjN=#B^wGdx!&dl-4o{r( z#b<)1f9)!>qoc>ZMoVy#kM|!{#TRx?PVy7%S&9CrAA4S0>A+BFq(uoY& zeM~*bEy$r{x)zkbRejSdr4Vqc!h@$gyu2O?+J74PM(L=%EwF~oZ*NFzmPcIsl+R<5 z1w>}{&1b<*%0R)D&vI+DzrT+g92_hFq?x}rf&L#E!d3}rH_qiS%?kVeRs9!OFy3qP z+1SyMy1R;CfJoRt2wnaJSe!7)lB1%kDu;=j0c>XdqT*sIz(QGf2i|a>19|)ebP6_Z zZf(W7A${mh%S&NjTwHvvt*xyO?6(~t=?Wle+a7LiZlZ=b?Em`3i&J3-SHK?i7#9_c z*#Q~{wm`Csgse~AhFH^%y^2hkrgoG1m*-jwVd>LX$t^u?_SwK={4-yocLn&W#J>Q9 zTvr(;4I)lA;2qwF05|Iwa1D)*A3rLg;-(`T?AWN&3U$|OJvG(UjXxLjZ<_c6cT!fG*@R~E2$X9ROiE*89 zatRk=XtmqvxX^H!A9T6U1o%%3-~i>)lJ$fj--$9Y?H>ai{ZKfxv%8y)3zG~(a7uWI z^EMMUOvAkL_58$ePiYie;(q)&e{(Q}u&1j7Xb_{)I-COoQXTwo8-y_ViV{zpq*#wV zX#Gdi)HaW#&UnfkJ36pB%@PLM30Qo7p_DcczsKHCU!OU;;p(YH=n6-W_wHN36S(gJ zh8m*{1QBhpNK%J<>jg`?+R1n-3e2I-dh|KAs_GanFg6}lF+arW*@GlMh{pKO1&6P> z6)LB*bMk9#n_KKZJ(Jc*U9__;5ySgvo~wUlB?!mSw_6hpI?&(G4u4H~dUmGBK*EmJ z^h-|1Wykzq=iX8YGH#fQxp`48klmgjt~S(!Y%tf_f3zwwU|LgH;T>-<#tB~+Cxr93 zB^@BS!Ky-K4g=aT(89F;YVI$B=0sa8*1%Vw4aP_d4GOwlw}AB1={J(WrSrj6L4IdQ zd*OXw(0>-shGc737kNO$ad@KB!C?T%=Xt3qDZd7Mv``V>Y5aMrV zLKSx}S>rM~XsLPl-FcFyt*OcB6&r{P8$NHrFV!}Elre|tjfa(Z)b?r5f_tv$4R=DRq4qU8j#(XaizJraH31+N^t0X7})0|CZP z@8j225SQY2|CwNZ#=U;{dpM#M7XsAjb|7cV04LUV|5yoF*R8m?xZnQ;xDKF}GO+rG zqP8#sN1L)Q5Y_pScIGO9{m>~iVkr~!JZcl*{A)<^_@4aYlk-|n?wdM;EVoonSURF1 z_dyoau{H;dfR6;q`V7j4)*QxfwDF*lKq)3XJUZ%BQ@sXkE)+Vtx)}%$PwXI6V8QqS z;-?2pjl*{kG6G4mpK+1BkNo`ka~jxTtDt;8T5NT3IbL5M{{i@!QV^_~fk*0N!w$tr z7)}N@I_Sir2oGO@{-=S|E0j1)%F?oghP65u=4;J_;OO?_*p(6DS_oz_R%Vk8BC`O~ zevLCB1VOY09c=d!IK5)qc5`4uCjjJqCJI$y!ux5cHUcp!)0e7H?;eEIMOshIo z%E5_L%U<5=gWs#&OBR6s`U}0eN;_AEd`AM2Ravh2VtSL6`&+zfvaH<9hUr>QkU`+z zQGsrdki?)!A|ya^s2B+3h^oKsTU~wR(8M;Q{0}%%#Gp0agS~MA^8bY z$yQCoVcGbm^-Rc!RXJrP>?(>X*!AZ2ur?ilzxOkD|9S;_fz-CwLn3EFBXy8e@@#`! zlUB*Cy^T1A}*IL^1Aa1N`YRSh<{g z-a088w?K*lt)4Kd8U9FOt4J+&WKWh-PGk2okAGhEHr0G_iG#g8K_!Hh?trVux4)U-LSsP2vKx6&85flDb*^;Und*~q|`lYuAryBXtgz|?})|nCy<*NccOG?f;rGBYP?~&Bb#o@A^9KNC#US z2BAqBQErDs29l7k$`^CyVLR{^XRsGc;6JlQnDf2NBt>g)MzqqvyKY79uSp)D`ZN7a z(*M-Su+D+R+mKbJ`}rW#JY96W7!wU@e1V&e7tF_P1uAL3FrBa@Ni5nc?Mq)hS?B)P zRyxds-TH;d_m~0tg$W;b_a^!ZRk9Ki;JV{M`tZVbw%kMmbtRrz|Kpq0d{Jt8CQ%Zf zlaCnL{|NLiDdCvBX0{b}U6PQn?2UXG=hm6TK&aC2D3yz?^Tng1X>o849>NuM^iLt! zRZ}xQ3v9@<+kw7)$Z~a>cWrP4mCAK(bZ$maIU(dJyy(Ap!YPy+t{ zou}=uYHMp#ueyow1NZ`BlnZ=1slU`HZi;CZyiclnX;wa$%IE7hx554Lh%1GIH~IFk zgd(A!J3UcV9er4rYfK_sf1r+uP~lg-djzh4e}&L7ckmv9RO?M>d&}0w#vcx}c15L8 zB{R#BmEIz{&-!#aVmnZS|D2zLidHM=T2}(py+W?*6_BW*9ecF$&Gz(IU4f2%K?@u|3l%vrtB%z5WV^3S zR+-Do*&l#eQ-g)*`EoF1fg0n2x&B$7P=Uy^YKmzoT3oR&0jBl@rDXg|r0UMMhd|SK znV5t`5sVRbc*b^^)3KKM-H6a0!u{8XJYr8q zO-+qu_qiV~Z_I9#!Tog|hOb|Sh8*DII3cTJwPv4lumDlcRlVynZU1;ulw~7ROPOuL zkkVbe`+>}ro@oqTHgfTP(!zZ=TQl$HC=HM*x+xsi>*p$0E!#WH$bJ!I!n4Hu;)Q!G{o`^8R=t z-CGuV4*WG%n_oc{Z{L3Tl)`OBD;La7^X09MXl3U&fq55q_hV|V6mioT{~%s;Q2Xq5 zmKilnG6j`?mS?vKrgRaG%;oBwtnVIJs$L?ap~;AH_;x2nSTCde!-~<#DCkCV;tzNQ z1b*I900h?c4JF)dMIsMWNAqF6{uvz^d6bM2P}Oq20PUaA)IdQO7Q2hZqBcLai`Bkw{uKx+^Xbn|pC1Yf3Qj-# zxERl&^L9VVDit7lMR@!x;%>ixeCZ&f*9|n+QFG2k(pNhB29VKP5X0TAmKs}HdNBiY zRx`uQP%zq3!DsKP7m350FBmws(czmK$&y~ipFaI_XVX*NfG#^dEp2{sX66)8>mScB z=H}ty@YccK>h?{sNcZ3%6lZIY2+QsR<(ZlWGe+g$&IPKtKAsU0< z#SIS9kHSp6@4Z2;Cpq6>aP|q=AYvWn2SLKBH|Pf1QI8y|8*@H%SxC+jA2AFK4ehd* zL>Q{5;KVG2wM~Xw-a)G4*TylNvyPa_nVxTXWNZW>KRqdJYpUY5g&~KMW=qnRXKYFgvQ8gZqFu;p7J){-;L*kziG6)y`7ersIBP5m zuq)xNfy|);R0t2Dkdl(JialD59@<45`+tEy_%0YVv}Wy)uJ%Kw@thZGCs@*4B}-_Y zif_aRqhOeh3=d<+Z@z$3mSA8Ul`)upz8={1GtiOm;c5qgq1KZpU+k-m@tyAaK?|=I zTj_822qpLc2k~0x1gY6`2b80UK%%@+=(c^x-oSc%1#(0j0R62Jk0lKEk08ik5huen zu*fMjhV(B;IBB^7>W#;`Lme{%JPq?}b>Z9a7}uV%F1UH{BD^dZvA>}`@Fm0iro*@R zau3Z@mih)+<_trT-|Vv?LgKQexp@=|4=)o_Gw5;Vi}f>v_Z*VYH&+`;m89H%#h&fJ zNR;go1t|J99pB=_m6eq|D#=&DY3~4b{KPBYY=J+oPvd&sAzjz=3|`ylFl8Th`2Zdk zgjpzV4gkzqm#o`FtALxc;9g~B zSGDmKSTi0fohul8#?_y9BCB}^7CO%Hc8Y5BRt?)Ks9TkmeNoat5=*vM31?(fCc~P?Nd>ve12inFF>;y&cLUS(>-&=eR9gesO zA-){k7kI1n>W6EMliYl=@ILuVA8qYKA;du})GIoer~d@w{`}hi6DrXDDg3uQ(BE&# z^7c}!vJ`!}qT@!ay|(sG*?nOcOaS-0wTf+1qRq_Uk>)+& zk0J=k{Ft%U?yW?XCsoPz-kutY#>qD1-@H%E$~sH}!T-`LW%aRYQk zBg6x7R-HVA(Nzs;#=q{;>OHiQ~2ydWS?k2~%M`)nrjd4{(KENRVfd z@vTLZI{v4Nm)#$;$f&8mlL&EW5!BQvR2JsTsrmB{-da0)xPW7a6KmxuHQau+S&ex~aV_6_#oUjSaoIyma@#-C`xw z$B!S!AQE2Ust8azp#Lo*zez?qG{HPHdBl6|VP0|%ayJ70`dpgA*`lpfpg}=FG11b} zQl@=3i{&8P*q1iEscJuZjhwEiuBkaG>pPH(v-8NJjwG(%6q^Y@G&?(6nWsaNX%Qto za0g1jCmN{$@=q^^6c20iwKL3E`6{Lb+gg~1FKqONJJ-D8H@jiTQqaVf*A7PyBf}(( zmSwtWZO>q!tN|&>NHF`?I$(q}(g!ipRrSo@o1t8tw8G=()+$hWUGRf6lPXCmxW_O+ z(yIa?RHa$Em4x0p7wrsppemwuB2l~hePUIo(MvRPBn%lf2OM4Mn`1bUuM7K)KT%J2 z#Ur5{z(E%Ufzw_kr@dB{q57wg0b&F<(PONs`{tPx(8q)g4h~*)_74Z?JOf=f2i$@= zAh&nqPv!6iBsH0tnOPT+8V(UKszXmBU|b<8hh!0F5(0wCYM6@Eluo1PbCG{G7|vps z8Wv2+0GBi15N;Gnm==@41^~QCdX?iWmsaW==_D8Ggz&e40hUmtR%FFFE}BMag)Og6 zfr9BXW#rgbh}aD~J3A}$K{i&_&jZqkKWJ0kTjUfJJMw}E4IuIQsc#BgZEU6=O`}sU ziIZM34vmc+?(BU1vaLFG;=3>`tPQgnzCxp zES3S2Fu%LD_KWVsL`PG{q?7E2VQPN<9~@nf4wqrp8;62X~$)Xbc$wBiB4vpTes;@u_I#dwEh$RoOnYoJJ zMfW{x;2E<)dSSJDow_o7+jS57o}8SNS%f$!w*aM4tKQ9!gy|+PC+FMA_cG+&dSaO& zBKvLddur58u#=39Wl3kL1Vsl;*xG(`3?2r{(-kQ@I;*sP?0ayL9q3F8mAvO*QD-RB$Mtds%x51aZb>{L zc0DVrb)l$Y+Mt}#aNJswTK`43@vFDJhlNQgx|7yl!J5hbLoEMrmE` zFpes8#D*BOu%GSTkmLahXnniw9*WdSUox)9R|U2Jy)c1sPImTR2!s(XowPb%LbQsK zQltdrb!0%oM;NbAga@y5UobYCYQji_5X#rTKhj;PgBRb{HZ&Z%I5;fi6phjlR1oEu z$(i>w`u^FT@I`jAf7heQ^b?iQMZPQ%y;WgzVtRPE$M z$H!m(4u|ZUk}CeAq2^$W_31UJ%z8-ri}y^jQc}nud_m$)NBPy=`lwnwp-A6O?7VpKJ~0ecSG~+AR%;!Uf7l zx~G-*LMfB@E+5?amW0}F{PAUNWR@XFeGkvNFz8gOs;Z9F{{+e`L?Nq7+~y!k&s3OY zJ*m}WxXS+_;*ug1w4*q89-)ME;Tik107P5XIg|<2mQlw4&-|MV(j)3^dXAud`PiTK z{>DF~(2IA7C1hk@v=KY_VY*bkU$~LnSh_0$lgczj{7-+@fx5ZFGRV2;KcRuz&TO($ z5kbtNVQW5dT1@svxsEp!KnPodayT7p8(C%_BM6HGss3K?79V?c_?y5y z=ci8#Arw-43^Am&@|eq)O${BTT3n`&l4C z&vmxgL7en4$fVe(F~lM_Duq~Q%l;uunRu8Fz(qa?)cs|?zZ8UgzUNSR%A;E8Mv9hX z?u@KHM{!wdz2GMZ7TIm78Z_WML2>WYebiQCJw84)b=yu6B3#9+LM@`-guR`nU+=$9 z@ZZL~Ek|E4H~RPSadi}GJ0#N2sy3lqJlhYU7xqW;E7mltEM7&KCUax?&`v~~rhyMHTn8_T6Kau9i zo0&~K8nHhWkP~=ETYMm$_1K`4OE3KE(PP3j_BQfiOkEb#DFpH+TsHp%Sy`WA@|amW zIejnB=_gP|PTjc;5jaLYA|b4Mg_y@O_>;>Q)t`h~8F#HMdqSjztL+Uu>n|Y7N^b)* zUF_^4)~OqGH(FqBYcVh~;zl_Y#}R4`1f7AW+YQ$HYb;(~yoY+pTOcXX;|WSZGfO_6 zQI4};MT#Zol@*30L2e%73ZPAI2G)=9W-+#<{Qhjmw6t8kK$yI5BIQj>WMYn3y85eE zBcj+D)|^$F$ZCV2{?dvqqrLb(GxMf8CzZS2v=KNH!H}JJXLhEb6z*cRM4{LJ390zEa2Jb{Q%C6NKc7_;FHux#|K-^coVZsjvTacFT5SxRPuC0kq$?0VW4dnDuE-=F}#}A9l!_ z^)XnqIUr3uto6&O=7mlmqh#*MF2H!dfmjz&q*zf#af5)!Mj86ZU_-o(>^fj%Ml`

hJ9uTo%36JC(ov8X^gNcT1M{A)~8|rdKmJIw_4ydTe|i1Ti8SpFYGx+>0cXizW4; z!qivN)w9_TLfVAhP(A{e>a-2QU6cb0$$@FvleFl5rL1(GT@|FxEx^7VwZpP-kaEC+ z(|!pFr)EgXG`aVW%9Mk>;?DLPmQ`zmL0-Qo$Zr~L^sQga{9 zL>g(lRW@Tpy&u>uY2w>PAKhr`nfz(qD zNH05+ufqqRkb%+@?FptfdBo%C2-kEWXEEgT?^ZT7CSaW3Q=03}CCA)rO~=`Oyu(5n zfK5Y9{ep{?HPQ*oIqYP@p0 z(%nWWi9O?u0)$62NsplEh{05D3tig8z_{;XX5^cp4i}75{lc8Z=obxfhyLvp{}* z{-;kYzJ7k0%)LJtw6Cn&2T`K_J1XcP(P_7ZHgqu0O3q(!9o_ba=Yd#r=?_*Q_abI{S&{t3!Gk@g~0 zEeA93^3Flyl$xzfTOdd^e$PFO;M4HI_ojrh`zG8mf~_F?961M__# zFa>vq){C1$xPH?Y4LJ@&zibH3kPO9bz-YDsVzbSqbgeYB_4>kQ6heN)d9#tARuAPL zT`0dkq;~GMy=MXLRx$};CMGC}-G2Y59mB-@;mmE-#mAs^jdDhP zeE|M0&0m9g+}<%50V;%x1NoMJ%BJLa6wX+Il*gpVG0UXY_ZZi*S6aqPNo=7vYCJeS zB4S_}(aP%;xD9Xc5X#QYV=%kAz)Uy@0hyT%janS*C^2JRWU% zq2*~!MO26j5XNyb^hXui+2-B|qTTx{Qx`|~M-m5KoGtp8b)n*xYg-~sToFr9J>>cQ zD(ZLIsuP~Kx>5GogA@H%U)6(oH`KAenuB@K`Sb@Kv6l?+y!lh!JN9H-(s0&~_326mnwXe8 z1iU!|^qUE1^Dyf*0S36fDq5g^Qsm9?fz*_QN7;meTQzO;nWv`&I+g3o=dR#d4OrdW ztgC@Agn=M~wp@d42o5*R0$RBO(luG{6_Iy?^}DlHKHsrMG%Y3NxX>?(yoA7?1|(uLw#yM9lV;(Qd!i^nKnuS=dk)bkb;gj->TP6Xgu?W5vmkk; zB&IWZ-_yM~1MS!ML{Jaow_HER$A8xYs4QA9>OB@)5_xin2Tg1CBSrd#YXB$KS$kdR z@ehO+T3flo43KVAdE4?3FqrL&FA_HVIMDiz0~??6bdgO71;` z>y=Ly^((}XD$wuS@&mrsu~HK(k$nY{?3-JmcuFC2P<^2`Z|$&)&h40;0i6kfA|;lk z_Y{0RJ0lGvZ@{9fuXA4qAqrYXrp_c|McUYm43iPW(qobXZiULFU#{SDxicc(WNB(` zW0QY(;2yG5tnUxhdO?mj2yTiv`IdwY9#m|SCIx=r<-2o)+zz8*u~mJa*% z7T}~!h6zk@o$|3%jb%`zm>_UY( znQ^Iem}V~+lC|K#AoWe>*@l>`m7|!fVLz05w8cjE^%uO^%E(;&VXAeX5P2~l1n?G)65DwiodVnaCnWo_8&qN_WZ_*Y(w5AoFT3FYi{YS|8gtd~ei5YCJ zHCUG>KSCveyDb6{$gX^F#X^;-7h;Ls#~l34&eeGA^%J-LoC(nBzhWHBA+wjsV__2& z9VU_3_I(D)`}E;+pC0%BtL78=Kwd2uXNSmL;7I z71}De=rSOm{#W)EO1l3bB`@wn0V=>HJQx`nCB3vo3(?lSJUxy7Ls`^FcB~pq1^M#5 za8*6x?f3}ek1o{Mr29lusU&v5O6%(E$)iIIDt8Q(TFzPyo4=QJ*`asD76CARzrL~Ys_jt8 zq+-ZOv{2$`VQ%iPwEq?otB@gt$O1oT%-Otpx+e~N2^c>n8;)+W4`QP&`l&12Ok zP*gxd+a$>=5g^Qa@E^S-k{sq;Tumk99m#a-uin2i2K`<6{A<$NzQuDs%iNM`3HCo+ z;`^Qc4=|k{^6D)I0p93J%QU=}y{1#XP0j`eoy4;0cc`e0@_wQ{R8U|dL~EWX<**9D zG&OvXv<`QBX`H*Eq;Jm8#UIaPyu7^7{*3fe=MN9FaB<{Fma~8ne$f~N-l1cM-$2zo z2X9(rYGqFlYufR%@Y8shf$^pei~_v-iI~77{1T`6QIeATuA<_28Al`NXGz@Ju>-h8 z`1yZ#!Ii72(L?`GFrL;xh#jTRF=xmfL6mmbKTcE=>pl*YvMSkYg;j}|xJ}E#d!qwn z?I#ppLA?4{R_5nwI&aynW2V9WYxv1Y^@`xrX~*#u_-!-LyuQ318->U*VZCx=ir19f z3FW&VBkMp^Vs%~9inEgS8xrgJrbJ2y=Dy?HXZ@lhinr84<3OHg!BJ85iha7v2TFGz z@ZzEpnY=q6W9fI42yBwPuN~;1Z_df~d#ap&yPJDe8qv@|l)I zJcWwXZT)1tgh$>Xd~xtIl?KK#pkn@d1_l%ruf%%7anpNQO@*GN$qt-Qmaf6~bEyCH zi}=y}8Mx_ET)#KQy~|6OC`>=BPi9MK?K0BT)O@qit3^pA2|$+}hWgX|p(^0tJ$|s7 zS}AvHVoXLwVTHMGj5nsq;|Jq(XxUf4zJGoz5vm%GUf*=Q1p&u}mwa<+*6tIz79NhO zcR6Bh+KXk;0Q~q7w1MP98ZF-y38!~{{H9GCgU?3ZV~y?YmoGe^I#KhD2rj1HgZIpd z()s|&j1P};%C-P3-N5AN$s>#wmzl5IbO5&RFR^09aqdAWf|iU%wyR{oC46p9-zQjx zCuD3CI-~{&dmH|*ZdmoTwod`M5fbX-paz1$m`?&ieU6rPc3b7UT`@5+&N%~C9JyXgb6qsr&JM)E-1#}t7~1)98Y4VyH|`IgDLo z?0@`r6V#VwWEr1(CzJ^cwZ~<|SQX?Nw=D(yexioliY&jMM78i_x-JF~?22FWqM-X) z1qqeGtMuSSfwVW_4JBRu{SShy-?3BS2BgJu6Kz-3YHdkCDAmqja5-;RLwPI0*O7RC zuH2-h%X)EwK46bU|1UH#B3jFmv&KP9p!_8J&sC3&g#$pKg@u`;S@cZ zM*X>~a|p-fcMjo755*9yFLcrah!kYQn5WmmaT^4qFl{4k*?&6>?N zj0f4Q2=aCS$^NZ~l=^nPh2SW1!7(N_&>F2>VCUS7d^1=159B&U$UHBfd;mbPX&4^) zmAg(w)%o+B+0NnVm4k!wButj?Z|oW3SYyWAL8mUIBv#zD@?8Nv-xs3lOpscgN%sFk z%l3sP*S^r5?>#9vC?Qu$?m?F@b4MO#YYJJ;ET1kBOV3^V>`Z3Ho$P>IjkfV;+n^h83%Y_RU z){X{vj{>QrSj`{wNMOg7T+FkOg!tn`z?qMyrxU0Ab8_r}Cr-}JpAh#i9WQ&wiFR+D zU$n;Ol$E=JqHZfeD9cRp5L?7mZH!CFJJ@V-3Px2)XP%$2*`^GcvtxdQZl>QYyRpw;>iFPI?S|{uO&>dmYUK*@iLHOpIXK9M&|Z0_n~^GOPbb?fC9Xg*t#@qF1tGJVKd;)-SZgi_nsv^@Od$B!ON{to5LUC}M0 zk6C`9Cs7CGJ@mw-Y$p$ZGb+Ebh&%n`5D_VcijF=iGg(4S{^7mlGn1gG{rr*J^SHm! zNHxV${-+xeVC(T-pi1LtSM#}*kSQT5LtNyOuun-p%}S#}y6LiiR)OB@AnNvK3!Nqg z_1@9a`nt4mBMH3H?HvAA&~qAON;?BAnHjZ!X!_ApJPH#ycXCMcDUTH$XC(31t?NpY zWiw@U@(wr!IN#tIQ!a$h&<@d}vd;&?@efsBM|gzR78e&Q2IygF%%=VqVE_^;$J)tY zq^{ZC!9n{wiEXq))Ehs4en+>LcB!8k8BwvQ(7sQq$B06=&cjMqp}@fQqb4^cB?TAB zuuLU6Rm`iH!ZRxgy&^Z)Y6}Q6bcUUxa`gFoTwtul3`$+1c1ZDU4+NdYZ&3&R7*%u1G2%NiSts%I?B-`ty zX;SFo_wUVZCo@L-jm5L-+7#{YV3Up!q@qnPP^%}{0jvK4riv^^)x^-d63d;PoyW!J z!#S#Rps|^iPcOdpL;mdjPqB@jkk5^u^+=8^OfN{N_CR;RRvBXZ{EGZ|sHrM}mw6P) z|7|EpyW%wjEIdH;_9maZ!?$V%djC!c*=hPL^S5opYrPKLu2BC+GjwaqTH(9XsZgRY zD{^P`CSEYa6~=n1(W9sk+dOUW;gb@FWnf)TzMXVVPHL7>=)>&aBP-}5KRKMeeN9i* zezUu~d+&(1@?Hf>4_W4MDM+X1jT=JSrPiV4_{n{kw|fi&-05t=T9{ZD$8I4Qis&eO zr5r+$xrtk~rLOAizxLzWv!Iy zegCzBV+=55vGdEz(YNp3z0}G|;^tpmpqtwG*Y)f~>qJ7GJ0SMWh5)4>sfb^gp0Pjl z6nK0`N%}aLt-f66TA7RN!pMyah2{mj z%!d8;5Be2|k$9*gcd`5JnNV=}rB#p%w_sKnQG5o83XvshXbSvzKR>@@>J>_y0NlsN z5K&br>YXkC67U%%|E_u8=NG5yGgG5w(HOy(r~BfL!^xbBv9uA=ya`O`vU<-r18A}x zXEA1{2@?-Ppr0zbEC`^O{o)biB8@A7!Ln@=m)0dt%f}(K9zi~93%5ntbvO0j9_U? zfJw4({^Q-i^9EVtzggglM0b`jdb%MAAzaghg0$9J7k!2xpnT~&I`k^e&Yy|4;xGU?6j_yiD|)-PuCU)-NDTqCP^}CrF=?0NR?ucB z13R)J6H?)98^>Rom(5L0^H=BRwc%TbtFRja=Wv#!xxryGsItDEb^|;y$Q{zm;3ka# zI~uKgPCz?1n_jT)iSkED@$NGD-nx>>( zM0`$}eMJ3gCa}2vkOJXz3I<8DTZhbD2Yumk#g$=p8Ffq7&bBcvF9O`=Gfc#6EmXR5 zz-O3YvzPQeu!@)L&|q9GI>4|cK7wtF ztxuw9fk|)tc_pANJG$BI>t6UEf1Hvh3oM5N7j=d6h}SFu7Lp)F5Cus%3GRy+nnax@ zUmmn6CqrM~^L?;WNHltEVl|2Vcc!HgNl1~=?Hz}fZCGYI`e8@hyc1#e^5wrwgrzjJ zWppG+)Fv7l?zGLlEucqAsKqq5wTbc0mfPz5oq_xkT|h5m0VebBK1Jq+k39wbBJ4;}hqx0aHuTnq^3 zrXb|~<=JjYMK~XKlW`Jqzi}uV>qo)tT0Oz7wjS39DChAo<@ua!Ppq5u8nkK|9of`G zgYMx=*keI$gB4pFo4%06TU*9COhS|D>wOQKvc4mcxr8u!kXlN5#{H4eSlj}Tqty-; zPEq?k4As`@J{qCxzRn8q7r7O1SW_%oCQ(Y&pCPth61J=M9yf8WvfMTwx=#!1`A+2W zm*~rh#?_q>bys)ac^C^=e~xW{Q<63Omzg7cPK>Q!W!mIuZO9f0;nC=S#^o){`a$Xf z#GNl?cwgk%B9&b2!#bzm*(%6JYZNj_FC(YPbvxlsv=iOcvmtOh1d8ULK!$+*9aZtj zXYFe)6`IFGbFNf`gzo!b)VL95W`3X)l;oA7O|-68aD!@7yclH83Iz2@A0#$jXOG~$+7iR7FJJIxWA#;A z9q0E=aqFpSljY6w=q=C1kc>tN=$FVw631_g!yR!=;z^G!dZ#mT^)MXSG?dD?2Te*$ ztQncTlMO^BVJm$c81CQXp z2(G_2($do2iTWXjuTg_OUNJs6JRYgJ5n(2~!Q}qRZ#ush%4Nr=T^

R~8;NHV0F- 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 II*xb#4;5{2p#T5? diff --git a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doormanager-icon.png b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doormanager-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a44f50fc48a55fdae888184ecb9133e7ff3f057f GIT binary patch literal 6697 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 bATa1N>A@I+6Bf1q=Z)TFBkht)_Ba0rw^AMC literal 0 HcmV?d00001 diff --git a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/myDevices_analytics.png b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/myDevices_analytics.png index ee5152dc8d648446a467cab6164522d8b89eac21..dc5f9a7d99446d847c118055650139302719e710 100644 GIT binary patch literal 45802 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 bATa1N>A@I+6Bf1q=Z)TFBkht)_Ba0rw^AMC literal 48636 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 diff --git a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/type-view.hbs b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/type-view.hbs index 16c36759..cab924e0 100644 --- a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/type-view.hbs +++ b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/type-view.hbs @@ -4,7 +4,7 @@

- +
diff --git a/modules/samples/doormanager/feature/feature/src/main/resources/carbonapps/Sensor.car b/modules/samples/doormanager/feature/feature/src/main/resources/carbonapps/Sensor.car new file mode 100644 index 0000000000000000000000000000000000000000..af22e266b8cbf26096ce4b9e96c63d1e6a597ded GIT binary patch literal 6981 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 literal 0 HcmV?d00001 diff --git a/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/doorManager-icon.png b/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/doorManager-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a44f50fc48a55fdae888184ecb9133e7ff3f057f GIT binary patch literal 6697 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 bATa1N>A@I+6Bf1q=Z)TFBkht)_Ba0rw^AMC literal 0 HcmV?d00001 diff --git a/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/doormanager-icon.png b/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.device-view/public/images/doormanager-icon.png index fe7065142f65a256763557df31e1a2ef1cf8eb99..a44f50fc48a55fdae888184ecb9133e7ff3f057f 100644 GIT binary patch literal 6697 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 bATa1N>A@I+6Bf1q=Z)TFBkht)_Ba0rw^AMC delta 40034 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≻aG zL5O+^A&5-*WBiwe3aKW;45QWc}&3M|BQh%~~aSg##83j7H#qDg5I(N%;jisWz^F1bAM38VHT(xeSC z2G#!}=o}4=kPl^N2^GrYMYD_+7DN|DHsHLL+5q39LiVRR(qrKy*_U~8p}~WEPbDa| xv4xLn(M01v%5|GS+x+j#|If41&^@6L1d;we?VT+3TL}12fASPjt@JwVe*i?#>p%bi diff --git a/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doorManager-icon.png b/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doorManager-icon.png index 0c7744ff42d16a9761778c98749aa50ea93e5cb4..a44f50fc48a55fdae888184ecb9133e7ff3f057f 100644 GIT binary patch literal 6697 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 bATa1N>A@I+6Bf1q=Z)TFBkht)_Ba0rw^AMC delta 46467 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 IsB!TB00Bcj_W%F@ diff --git a/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doormanager-icon.png b/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doormanager-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..a44f50fc48a55fdae888184ecb9133e7ff3f057f GIT binary patch literal 6697 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 bATa1N>A@I+6Bf1q=Z)TFBkht)_Ba0rw^AMC literal 0 HcmV?d00001 diff --git a/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/myDevices_analytics.png b/modules/samples/doormanager/feature/feature/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/myDevices_analytics.png index ee5152dc8d648446a467cab6164522d8b89eac21..dc5f9a7d99446d847c118055650139302719e710 100644 GIT binary patch literal 45802 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 d6oT4.1 provided + + com.google.code.gson + gson + 2.2.4 + @@ -254,4 +259,4 @@ 1.8 1.7.2 - \ No newline at end of file + From 4c2eeb4b2abc89487d4e8eea7858e884e1b7ec95 Mon Sep 17 00:00:00 2001 From: GPrathap Date: Thu, 25 Feb 2016 23:52:21 +0530 Subject: [PATCH 05/12] Fix for JIRA IOTS-80 --- modules/samples/installer/device-deployer.xml | 7 +++--- .../tools/cdmf-devicetype-archetype/README.md | 24 ++++++++++++------- .../tools/cdmf-devicetype-archetype/pom.xml | 4 ++-- 3 files changed, 21 insertions(+), 14 deletions(-) diff --git a/modules/samples/installer/device-deployer.xml b/modules/samples/installer/device-deployer.xml index 583a9282..efb3575e 100644 --- a/modules/samples/installer/device-deployer.xml +++ b/modules/samples/installer/device-deployer.xml @@ -32,7 +32,7 @@ http://wso2.org - + samples/connectedcup samples/currentsensor @@ -43,7 +43,6 @@ org.wso2.maven carbon-p2-plugin 1.5.3 - 2-p2-repo-generation @@ -59,7 +58,7 @@ - + org.wso2.carbon.devicemgt-plugins:org.coffeeking.connectedcup.feature:2.0.4-SNAPSHOT @@ -89,7 +88,7 @@ repository/components true - + org.coffeeking.connectedcup.feature.group 2.0.4-SNAPSHOT diff --git a/modules/tools/cdmf-devicetype-archetype/README.md b/modules/tools/cdmf-devicetype-archetype/README.md index c72d2e90..de25c9c9 100644 --- a/modules/tools/cdmf-devicetype-archetype/README.md +++ b/modules/tools/cdmf-devicetype-archetype/README.md @@ -1,16 +1,16 @@ # cdmf-devicetype-archetype To install this maven archetype - go to this folder cdmf-devicetype-archetype + go to this folder `cdmf-devicetype-archetype` mvn clean install To create new project - go to this folder /wso2iots-1.0.0-SNAPSHOT/samples + go to this folder `/wso2iots-1.0.0-SNAPSHOT/samples` mvn archetype:generate -DarchetypeCatalog=local -Then select the cdmf.devicetype:cdmf-devicetype-archetype as new archetype. Then you need to provide groupId, artifactId, +Then select the `cdmf.devicetype:cdmf-devicetype-archetype` as new archetype. Then you need to provide groupId, artifactId, version, packaging, name of your device type and name for sensor as shown bellow. Choose a number or apply filter (format: [groupId:]artifactId, case sensitive contains): : 3 @@ -30,20 +30,28 @@ version, packaging, name of your device type and name for sensor as shown bellow To install sample app into IOTS - open '`device-deployer.xml` which is located in wso2iots-1.0.0-SNAPSHOT directory - Under featureArtifacts tag add feature artifact definition as below + open `device-deployer.xml` which is located in wso2iots-1.0.0-SNAPSHOT directory + +Under modules tag add name of sample which you created as module as below + + samples/safeLocker + +Under featureArtifacts tag add feature artifact definition as below org.homeautomation:org.homeautomation.safeLocker.feature:1.0.0-SNAPSHOT - Under features tag add feature group definition as below +Under features tag add feature group definition as below org.homeautomation.safeLocker.feature.group 1.0.0-SNAPSHOT - mvn clean install -f device-deployer.xml - +Finally to deploy sample device type into IoT Server + + mvn clean install -f device-deployer.xml + +Note: This command should be executed place where `device-deployer.xml` is located diff --git a/modules/tools/cdmf-devicetype-archetype/pom.xml b/modules/tools/cdmf-devicetype-archetype/pom.xml index d9255a41..4f4cbfb8 100644 --- a/modules/tools/cdmf-devicetype-archetype/pom.xml +++ b/modules/tools/cdmf-devicetype-archetype/pom.xml @@ -28,8 +28,8 @@ cdmf.devicetype cdmf-devicetype-archetype 1.0.0-SNAPSHOT - Archetype of WSO2 CDMF Device Type - Archetype of WSO2 CDMF Device Type + WSO2 CDMF Device Type Archetype + WSO2 CDMF Device Type Archetype maven-archetype WSO2 Inc. From 0a29e013567e29bb659cab816c32401529a89769 Mon Sep 17 00:00:00 2001 From: Geesara Prathap Date: Thu, 25 Feb 2016 23:57:26 +0530 Subject: [PATCH 06/12] Update README.md --- modules/tools/cdmf-devicetype-archetype/README.md | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/modules/tools/cdmf-devicetype-archetype/README.md b/modules/tools/cdmf-devicetype-archetype/README.md index de25c9c9..8ee77d26 100644 --- a/modules/tools/cdmf-devicetype-archetype/README.md +++ b/modules/tools/cdmf-devicetype-archetype/README.md @@ -1,12 +1,14 @@ # cdmf-devicetype-archetype To install this maven archetype - go to this folder `cdmf-devicetype-archetype` + +go to this folder `cdmf-devicetype-archetype` mvn clean install To create new project - go to this folder `/wso2iots-1.0.0-SNAPSHOT/samples` + +go to this folder `/wso2iots-1.0.0-SNAPSHOT/samples` mvn archetype:generate -DarchetypeCatalog=local @@ -32,7 +34,7 @@ version, packaging, name of your device type and name for sensor as shown bellow To install sample app into IOTS open `device-deployer.xml` which is located in wso2iots-1.0.0-SNAPSHOT directory -Under modules tag add name of sample which you created as module as below +Under modules tag add name of sample which you created as module samples/safeLocker From f087baaa49938d1074acc02b75860997339b14a1 Mon Sep 17 00:00:00 2001 From: charithag Date: Thu, 3 Mar 2016 16:03:58 +0530 Subject: [PATCH 07/12] Bump event processing version to comply with analytics --- modules/p2-profile-gen/pom.xml | 4 ++-- pom.xml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/p2-profile-gen/pom.xml b/modules/p2-profile-gen/pom.xml index 6210a234..0ec0df42 100644 --- a/modules/p2-profile-gen/pom.xml +++ b/modules/p2-profile-gen/pom.xml @@ -738,7 +738,7 @@ org.wso2.carbon.analytics-common:org.wso2.carbon.event.publisher.feature:${carbon.analytics.common.version} - org.wso2.carbon.event-processing:org.wso2.carbon.event.processor.feature:${carbon.event-processing.version} + org.wso2.carbon.event-processing:org.wso2.carbon.event.processor.server.feature:${carbon.event-processing.version} org.wso2.carbon.analytics-common:org.wso2.carbon.event.tracer.feature:${carbon.analytics.common.version} @@ -1617,7 +1617,7 @@ ${carbon.analytics.common.version} - org.wso2.carbon.event.processor.feature.group + org.wso2.carbon.event.processor.server.feature.group ${carbon.event-processing.version} diff --git a/pom.xml b/pom.xml index bff2ec7d..711438a1 100644 --- a/pom.xml +++ b/pom.xml @@ -1079,7 +1079,7 @@ 1.0.0-wso2v3 1.0.9 1.0.0 - 2.0.11 + 2.0.12 4.3.5-SNAPSHOT 3.1.0.wso2v2 From 6c7041dcda5eacd2ce85a0e53057458c102d0cd9 Mon Sep 17 00:00:00 2001 From: charithag Date: Fri, 4 Mar 2016 10:59:33 +0530 Subject: [PATCH 08/12] Add ESP8266 based fire alarm sample --- .../firealarm/component/analytics/build.xml | 40 + .../firealarm/component/analytics/pom.xml | 90 ++ .../component/analytics/src/assembly/src.xml | 36 + .../EventReceiver_humidity.xml | 27 + .../Eventreceiver_humidity_1.0.0/artifact.xml | 23 + .../Eventstore_humidity_1.0.0/artifact.xml | 23 + .../org_wso2_iot_devices_humidity.xml | 62 + .../Eventstream_humidity_1.0.0/artifact.xml | 24 + .../org.wso2.iot.devices.humidity_1.0.0.json | 33 + .../Humidity_Sensor_Script.xml | 37 + .../Sparkscripts_1.0.0/artifact.xml | 23 + .../carbonapps/Humidity_Sensor/artifacts.xml | 33 + .../EventReceiver_temperature.xml | 27 + .../artifact.xml | 23 + .../Eventstore_temperature_1.0.0/artifact.xml | 23 + .../org_wso2_iot_devices_temperature.xml | 62 + .../artifact.xml | 24 + ...rg.wso2.iot.devices.temperature_1.0.0.json | 33 + .../Temperature_Sensor_Script.xml | 37 + .../Sparkscripts_1.0.0/artifact.xml | 23 + .../Temperature_Sensor/artifacts.xml | 34 + .../firealarm/component/controller/pom.xml | 226 +++ .../controller/api/ControllerService.java | 220 +++ .../controller/api/dto/DeviceJSON.java | 38 + .../api/exception/DeviceTypeException.java | 57 + .../api/transport/MQTTConnector.java | 229 +++ .../controller/api/util/ServiceUtils.java | 83 ++ .../webapp/META-INF/webapp-classloading.xml | 35 + .../src/main/webapp/WEB-INF/cxf-servlet.xml | 42 + .../src/main/webapp/WEB-INF/web.xml | 68 + .../firealarm/component/manager/pom.xml | 231 +++ .../firealarm/manager/api/ManagerService.java | 337 +++++ .../firealarm/manager/api/util/APIUtil.java | 54 + .../manager/api/util/ResponsePayload.java | 108 ++ .../src/main/webapp/META-INF/permissions.xml | 73 + .../webapp/META-INF/webapp-classloading.xml | 35 + .../src/main/webapp/WEB-INF/cxf-servlet.xml | 38 + .../manager/src/main/webapp/WEB-INF/web.xml | 68 + .../firealarm/component/plugin/pom.xml | 114 ++ .../plugin/constants/DeviceTypeConstants.java | 33 + .../exception/FirealarmPluginException.java | 56 + .../plugin/impl/DeviceTypeManager.java | 259 ++++ .../plugin/impl/DeviceTypeManagerService.java | 114 ++ .../plugin/impl/dao/DeviceTypeDAO.java | 132 ++ .../impl/dao/impl/DeviceTypeDAOImpl.java | 239 ++++ .../plugin/impl/dao/util/DeviceTypeUtils.java | 87 ++ .../plugin/internal/ServiceComponent.java | 72 + modules/samples/firealarm/component/pom.xml | 268 ++++ .../samples/firealarm/component/ui/pom.xml | 58 + .../component/ui/src/assembly/src.xml | 38 + .../device-view.hbs | 130 ++ .../device-view.js | 57 + .../device-view.json | 3 + .../public/images/current-sensor.png | Bin 0 -> 38879 bytes .../policy-edit.hbs | 18 + .../policy-edit.json | 3 + .../policy-view.hbs | 18 + .../policy-view.json | 3 + .../policy-wizard.hbs | 18 + .../policy-wizard.json | 3 + .../public/images/deviceType.png | Bin 0 -> 28584 bytes .../public/images/myDevices_analytics.png | Bin 0 -> 6693 bytes .../public/images/schematicsGuide.png | Bin 0 -> 128984 bytes .../public/images/thumb.png | Bin 0 -> 31021 bytes .../public/js/download.js | 195 +++ .../public/js/jquery.validate.js | 1234 +++++++++++++++++ .../type-view.hbs | 378 +++++ .../type-view.json | 3 + .../samples/firealarm/feature/feature/pom.xml | 244 ++++ .../src/main/resources/agent/dht_lib.lua | 65 + .../feature/src/main/resources/agent/init.lua | 4 + .../src/main/resources/agent/read-sensor.lua | 74 + .../main/resources/agent/sketch.properties | 16 + .../src/main/resources/agent/wifi-connect.lua | 2 + .../src/main/resources/build.properties | 18 + .../src/main/resources/configs/firealarm.json | 54 + .../src/main/resources/configs/firealarm.xml | 25 + .../datasources/firealarm-datasources.xml | 48 + .../src/main/resources/dbscripts/h2.sql | 13 + .../src/main/resources/dbscripts/mysql.sql | 12 + .../feature/feature/src/main/resources/p2.inf | 16 + modules/samples/firealarm/feature/pom.xml | 37 + modules/samples/firealarm/pom.xml | 257 ++++ modules/samples/installer/device-deployer.xml | 8 + 84 files changed, 7105 insertions(+) create mode 100644 modules/samples/firealarm/component/analytics/build.xml create mode 100644 modules/samples/firealarm/component/analytics/pom.xml create mode 100644 modules/samples/firealarm/component/analytics/src/assembly/src.xml create mode 100644 modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventreceiver_humidity_1.0.0/EventReceiver_humidity.xml create mode 100644 modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventreceiver_humidity_1.0.0/artifact.xml create mode 100644 modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstore_humidity_1.0.0/artifact.xml create mode 100644 modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstore_humidity_1.0.0/org_wso2_iot_devices_humidity.xml create mode 100644 modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstream_humidity_1.0.0/artifact.xml create mode 100644 modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstream_humidity_1.0.0/org.wso2.iot.devices.humidity_1.0.0.json create mode 100644 modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Sparkscripts_1.0.0/Humidity_Sensor_Script.xml create mode 100644 modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Sparkscripts_1.0.0/artifact.xml create mode 100644 modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/artifacts.xml create mode 100644 modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventreceiver_temperature_1.0.0/EventReceiver_temperature.xml create mode 100644 modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventreceiver_temperature_1.0.0/artifact.xml create mode 100644 modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstore_temperature_1.0.0/artifact.xml create mode 100644 modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstore_temperature_1.0.0/org_wso2_iot_devices_temperature.xml create mode 100644 modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstream_temperature_1.0.0/artifact.xml create mode 100644 modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstream_temperature_1.0.0/org.wso2.iot.devices.temperature_1.0.0.json create mode 100644 modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Sparkscripts_1.0.0/Temperature_Sensor_Script.xml create mode 100644 modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Sparkscripts_1.0.0/artifact.xml create mode 100644 modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/artifacts.xml create mode 100644 modules/samples/firealarm/component/controller/pom.xml create mode 100644 modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/ControllerService.java create mode 100644 modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/dto/DeviceJSON.java create mode 100644 modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/exception/DeviceTypeException.java create mode 100644 modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/transport/MQTTConnector.java create mode 100644 modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/util/ServiceUtils.java create mode 100644 modules/samples/firealarm/component/controller/src/main/webapp/META-INF/webapp-classloading.xml create mode 100644 modules/samples/firealarm/component/controller/src/main/webapp/WEB-INF/cxf-servlet.xml create mode 100644 modules/samples/firealarm/component/controller/src/main/webapp/WEB-INF/web.xml create mode 100644 modules/samples/firealarm/component/manager/pom.xml create mode 100644 modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/ManagerService.java create mode 100644 modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/util/APIUtil.java create mode 100644 modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/util/ResponsePayload.java create mode 100644 modules/samples/firealarm/component/manager/src/main/webapp/META-INF/permissions.xml create mode 100644 modules/samples/firealarm/component/manager/src/main/webapp/META-INF/webapp-classloading.xml create mode 100644 modules/samples/firealarm/component/manager/src/main/webapp/WEB-INF/cxf-servlet.xml create mode 100644 modules/samples/firealarm/component/manager/src/main/webapp/WEB-INF/web.xml create mode 100644 modules/samples/firealarm/component/plugin/pom.xml create mode 100644 modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/constants/DeviceTypeConstants.java create mode 100644 modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/exception/FirealarmPluginException.java create mode 100644 modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/DeviceTypeManager.java create mode 100644 modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/DeviceTypeManagerService.java create mode 100644 modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/DeviceTypeDAO.java create mode 100644 modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/impl/DeviceTypeDAOImpl.java create mode 100644 modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/util/DeviceTypeUtils.java create mode 100644 modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/internal/ServiceComponent.java create mode 100644 modules/samples/firealarm/component/pom.xml create mode 100644 modules/samples/firealarm/component/ui/pom.xml create mode 100644 modules/samples/firealarm/component/ui/src/assembly/src.xml create mode 100644 modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.hbs create mode 100644 modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.js create mode 100644 modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.json create mode 100644 modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/public/images/current-sensor.png create mode 100644 modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-edit/policy-edit.hbs create mode 100644 modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-edit/policy-edit.json create mode 100644 modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-view/policy-view.hbs create mode 100644 modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-view/policy-view.json create mode 100644 modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-wizard/policy-wizard.hbs create mode 100644 modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-wizard/policy-wizard.json create mode 100644 modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/deviceType.png create mode 100644 modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/myDevices_analytics.png create mode 100644 modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/schematicsGuide.png create mode 100644 modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/thumb.png create mode 100644 modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/js/download.js create mode 100644 modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/js/jquery.validate.js create mode 100644 modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/type-view.hbs create mode 100644 modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/type-view.json create mode 100644 modules/samples/firealarm/feature/feature/pom.xml create mode 100644 modules/samples/firealarm/feature/feature/src/main/resources/agent/dht_lib.lua create mode 100644 modules/samples/firealarm/feature/feature/src/main/resources/agent/init.lua create mode 100644 modules/samples/firealarm/feature/feature/src/main/resources/agent/read-sensor.lua create mode 100644 modules/samples/firealarm/feature/feature/src/main/resources/agent/sketch.properties create mode 100644 modules/samples/firealarm/feature/feature/src/main/resources/agent/wifi-connect.lua create mode 100644 modules/samples/firealarm/feature/feature/src/main/resources/build.properties create mode 100644 modules/samples/firealarm/feature/feature/src/main/resources/configs/firealarm.json create mode 100644 modules/samples/firealarm/feature/feature/src/main/resources/configs/firealarm.xml create mode 100644 modules/samples/firealarm/feature/feature/src/main/resources/datasources/firealarm-datasources.xml create mode 100644 modules/samples/firealarm/feature/feature/src/main/resources/dbscripts/h2.sql create mode 100644 modules/samples/firealarm/feature/feature/src/main/resources/dbscripts/mysql.sql create mode 100644 modules/samples/firealarm/feature/feature/src/main/resources/p2.inf create mode 100644 modules/samples/firealarm/feature/pom.xml create mode 100644 modules/samples/firealarm/pom.xml diff --git a/modules/samples/firealarm/component/analytics/build.xml b/modules/samples/firealarm/component/analytics/build.xml new file mode 100644 index 00000000..2f3be332 --- /dev/null +++ b/modules/samples/firealarm/component/analytics/build.xml @@ -0,0 +1,40 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/modules/samples/firealarm/component/analytics/pom.xml b/modules/samples/firealarm/component/analytics/pom.xml new file mode 100644 index 00000000..d587c1ae --- /dev/null +++ b/modules/samples/firealarm/component/analytics/pom.xml @@ -0,0 +1,90 @@ + + + + + + + org.homeautomation + firealarm-component + 1.0.0-SNAPSHOT + ../pom.xml + + 4.0.0 + ${groupId}.firealarm.analytics + 1.0.0-SNAPSHOT + pom + ${groupId}.firealarm.analytics + http://wso2.org + + + + maven-clean-plugin + ${maven-clean-plugin.version} + + + auto-clean + initialize + + clean + + + + + + maven-antrun-plugin + ${wso2.maven.compiler.source} + + + process-resources + + + + + + + run + + + + + + maven-assembly-plugin + ${maven-assembly-plugin.version} + + ${project.artifactId}-1.0.0-SNAPSHOT + false + + src/assembly/src.xml + + + + + create-archive + package + + single + + + + + + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/analytics/src/assembly/src.xml b/modules/samples/firealarm/component/analytics/src/assembly/src.xml new file mode 100644 index 00000000..b7735b0b --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/assembly/src.xml @@ -0,0 +1,36 @@ + + + + src + + zip + + false + ${basedir}/src + + + ${basedir}/target/carbonapps + / + true + + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventreceiver_humidity_1.0.0/EventReceiver_humidity.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventreceiver_humidity_1.0.0/EventReceiver_humidity.xml new file mode 100644 index 00000000..8f117bdb --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventreceiver_humidity_1.0.0/EventReceiver_humidity.xml @@ -0,0 +1,27 @@ + + + + + + false + + + + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventreceiver_humidity_1.0.0/artifact.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventreceiver_humidity_1.0.0/artifact.xml new file mode 100644 index 00000000..59756609 --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventreceiver_humidity_1.0.0/artifact.xml @@ -0,0 +1,23 @@ + + + + + EventReceiver_humidity.xml + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstore_humidity_1.0.0/artifact.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstore_humidity_1.0.0/artifact.xml new file mode 100644 index 00000000..484978bb --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstore_humidity_1.0.0/artifact.xml @@ -0,0 +1,23 @@ + + + + + org_wso2_iot_devices_humidity.xml + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstore_humidity_1.0.0/org_wso2_iot_devices_humidity.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstore_humidity_1.0.0/org_wso2_iot_devices_humidity.xml new file mode 100644 index 00000000..5d490868 --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstore_humidity_1.0.0/org_wso2_iot_devices_humidity.xml @@ -0,0 +1,62 @@ + + + + + + org.wso2.iot.devices.humidity:1.0.0 + + EVENT_STORE + + + meta_owner + true + true + false + STRING + + + meta_deviceType + true + true + false + STRING + + + meta_deviceId + true + true + false + STRING + + + meta_time + true + true + false + LONG + + + humidity + false + false + false + FLOAT + + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstream_humidity_1.0.0/artifact.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstream_humidity_1.0.0/artifact.xml new file mode 100644 index 00000000..84836c69 --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstream_humidity_1.0.0/artifact.xml @@ -0,0 +1,24 @@ + + + + + org.wso2.iot.devices.humidity_1.0.0.json + + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstream_humidity_1.0.0/org.wso2.iot.devices.humidity_1.0.0.json b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstream_humidity_1.0.0/org.wso2.iot.devices.humidity_1.0.0.json new file mode 100644 index 00000000..fd9ea41b --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Eventstream_humidity_1.0.0/org.wso2.iot.devices.humidity_1.0.0.json @@ -0,0 +1,33 @@ +{ + "name": "org.wso2.iot.devices.humidity", + "version": "1.0.0", + "nickName": "Humidity Data", + "description": "Humidity data received from the Device", + "metaData": [ + { + "name": "owner", + "type": "STRING" + }, + { + "name": "deviceType", + "type": "STRING" + }, + { + "name": "deviceId", + "type": "STRING" + }, + { + "name": "time", + "type": "LONG" + } + ], + "payloadData": [ + { + "name": "humidity", + "type": "FLOAT" + } + ] +} + + + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Sparkscripts_1.0.0/Humidity_Sensor_Script.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Sparkscripts_1.0.0/Humidity_Sensor_Script.xml new file mode 100644 index 00000000..ed215baa --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Sparkscripts_1.0.0/Humidity_Sensor_Script.xml @@ -0,0 +1,37 @@ + + + + + IoTServer_Sensor_Script + + 0 * * * * ? + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Sparkscripts_1.0.0/artifact.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Sparkscripts_1.0.0/artifact.xml new file mode 100644 index 00000000..1d92c387 --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/Sparkscripts_1.0.0/artifact.xml @@ -0,0 +1,23 @@ + + + + + Humidity_Sensor_Script.xml + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/artifacts.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/artifacts.xml new file mode 100644 index 00000000..d89620e4 --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Humidity_Sensor/artifacts.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventreceiver_temperature_1.0.0/EventReceiver_temperature.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventreceiver_temperature_1.0.0/EventReceiver_temperature.xml new file mode 100644 index 00000000..b4026b4e --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventreceiver_temperature_1.0.0/EventReceiver_temperature.xml @@ -0,0 +1,27 @@ + + + + + + false + + + + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventreceiver_temperature_1.0.0/artifact.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventreceiver_temperature_1.0.0/artifact.xml new file mode 100644 index 00000000..7cac6e0b --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventreceiver_temperature_1.0.0/artifact.xml @@ -0,0 +1,23 @@ + + + + + EventReceiver_temperature.xml + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstore_temperature_1.0.0/artifact.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstore_temperature_1.0.0/artifact.xml new file mode 100644 index 00000000..02990e3c --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstore_temperature_1.0.0/artifact.xml @@ -0,0 +1,23 @@ + + + + + org_wso2_iot_devices_temperature.xml + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstore_temperature_1.0.0/org_wso2_iot_devices_temperature.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstore_temperature_1.0.0/org_wso2_iot_devices_temperature.xml new file mode 100644 index 00000000..9e41647b --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstore_temperature_1.0.0/org_wso2_iot_devices_temperature.xml @@ -0,0 +1,62 @@ + + + + + + org.wso2.iot.devices.temperature:1.0.0 + + EVENT_STORE + + + meta_owner + true + true + false + STRING + + + meta_deviceType + true + true + false + STRING + + + meta_deviceId + true + true + false + STRING + + + meta_time + true + true + false + LONG + + + temperature + false + false + false + FLOAT + + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstream_temperature_1.0.0/artifact.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstream_temperature_1.0.0/artifact.xml new file mode 100644 index 00000000..6f41292b --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstream_temperature_1.0.0/artifact.xml @@ -0,0 +1,24 @@ + + + + + org.wso2.iot.devices.temperature_1.0.0.json + + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstream_temperature_1.0.0/org.wso2.iot.devices.temperature_1.0.0.json b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstream_temperature_1.0.0/org.wso2.iot.devices.temperature_1.0.0.json new file mode 100644 index 00000000..b851e5bb --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Eventstream_temperature_1.0.0/org.wso2.iot.devices.temperature_1.0.0.json @@ -0,0 +1,33 @@ +{ + "name": "org.wso2.iot.devices.temperature", + "version": "1.0.0", + "nickName": "Temperature Data", + "description": "Temperature data received from the Device", + "metaData": [ + { + "name": "owner", + "type": "STRING" + }, + { + "name": "deviceType", + "type": "STRING" + }, + { + "name": "deviceId", + "type": "STRING" + }, + { + "name": "time", + "type": "LONG" + } + ], + "payloadData": [ + { + "name": "temperature", + "type": "FLOAT" + } + ] +} + + + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Sparkscripts_1.0.0/Temperature_Sensor_Script.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Sparkscripts_1.0.0/Temperature_Sensor_Script.xml new file mode 100644 index 00000000..d184528c --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Sparkscripts_1.0.0/Temperature_Sensor_Script.xml @@ -0,0 +1,37 @@ + + + + + IoTServer_Sensor_Script + + 0 * * * * ? + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Sparkscripts_1.0.0/artifact.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Sparkscripts_1.0.0/artifact.xml new file mode 100644 index 00000000..fa653516 --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/Sparkscripts_1.0.0/artifact.xml @@ -0,0 +1,23 @@ + + + + + Temperature_Sensor_Script.xml + diff --git a/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/artifacts.xml b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/artifacts.xml new file mode 100644 index 00000000..4fa4b796 --- /dev/null +++ b/modules/samples/firealarm/component/analytics/src/main/resources/carbonapps/Temperature_Sensor/artifacts.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + diff --git a/modules/samples/firealarm/component/controller/pom.xml b/modules/samples/firealarm/component/controller/pom.xml new file mode 100644 index 00000000..0ffa899e --- /dev/null +++ b/modules/samples/firealarm/component/controller/pom.xml @@ -0,0 +1,226 @@ + + + + + + + org.homeautomation + firealarm-component + 1.0.0-SNAPSHOT + ../pom.xml + + 4.0.0 + ${groupId}.firealarm.controller + 1.0.0-SNAPSHOT + war + ${groupId}.firealarm.controller + http://wso2.com + + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + UTF-8 + ${wso2.maven.compiler.source} + ${wso2.maven.compiler.target} + + + + maven-war-plugin + ${maven-war-plugin.version} + + ${groupId}.firealarm.controller + + + + + + + org.homeautomation + ${project-base-package}.plugin + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.common + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.core + + + org.apache.axis2.wso2 + axis2-client + + + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.analytics + + + org.apache.axis2.wso2 + axis2-client + + + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.certificate.mgt.core + + + + + org.apache.cxf + cxf-rt-frontend-jaxws + + + org.apache.cxf + cxf-rt-frontend-jaxrs + + + org.apache.cxf + cxf-rt-transports-http + + + + + org.apache.httpcomponents + httpasyncclient + 4.1 + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot + + + + + org.eclipse.paho + org.eclipse.paho.client.mqttv3 + + + + + org.codehaus.jackson + jackson-core-asl + + + org.codehaus.jackson + jackson-jaxrs + + + javax + javaee-web-api + + + javax.ws.rs + jsr311-api + + + commons-httpclient.wso2 + commons-httpclient + + + + org.wso2.carbon + org.wso2.carbon.utils + + + org.bouncycastle.wso2 + bcprov-jdk15on + + + org.wso2.carbon + org.wso2.carbon.user.api + + + org.wso2.carbon + org.wso2.carbon.queuing + + + org.wso2.carbon + org.wso2.carbon.base + + + org.apache.axis2.wso2 + axis2 + + + org.igniterealtime.smack.wso2 + smack + + + org.igniterealtime.smack.wso2 + smackx + + + jaxen + jaxen + + + commons-fileupload.wso2 + commons-fileupload + + + org.apache.ant.wso2 + ant + + + org.apache.ant.wso2 + ant + + + commons-httpclient.wso2 + commons-httpclient + + + org.eclipse.equinox + javax.servlet + + + org.wso2.carbon + org.wso2.carbon.registry.api + + + + + org.igniterealtime.smack.wso2 + smack + + + org.igniterealtime.smack.wso2 + smackx + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.annotations + + + org.json.wso2 + json + + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/ControllerService.java b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/ControllerService.java new file mode 100644 index 00000000..20fdcd86 --- /dev/null +++ b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/ControllerService.java @@ -0,0 +1,220 @@ +/* +* Copyright (c) 2016, 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.homeautomation.firealarm.controller.api; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.homeautomation.firealarm.controller.api.dto.DeviceJSON; +import org.homeautomation.firealarm.controller.api.exception.DeviceTypeException; +import org.homeautomation.firealarm.controller.api.transport.MQTTConnector; +import org.homeautomation.firealarm.plugin.constants.DeviceTypeConstants; +import org.wso2.carbon.apimgt.annotations.api.API; +import org.wso2.carbon.apimgt.annotations.device.DeviceType; +import org.wso2.carbon.apimgt.annotations.device.feature.Feature; +import org.wso2.carbon.context.CarbonContext; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.iot.DeviceManagement; +import org.wso2.carbon.device.mgt.iot.DeviceValidator; +import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig; +import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException; +import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager; +import org.wso2.carbon.device.mgt.iot.sensormgt.SensorRecord; + +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; +import javax.ws.rs.GET; +import javax.ws.rs.HeaderParam; +import javax.ws.rs.POST; +import javax.ws.rs.Path; +import javax.ws.rs.Produces; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; + +/** + * This is the controller API which is used to control agent side functionality + */ +@SuppressWarnings("NonJaxWsWebServices") +@API(name = "firealarm", version = "1.0.0", context = "/firealarm") +@DeviceType(value = "firealarm") +public class ControllerService { + + private static Log log = LogFactory.getLog(ControllerService.class); + private MQTTConnector mqttConnector; + + private boolean waitForServerStartup() { + while (!DeviceManagement.isServerReady()) { + try { + Thread.sleep(1000); + } catch (InterruptedException e) { + return true; + } + } + return false; + } + + @SuppressWarnings("unused") + public MQTTConnector getMQTTConnector() { + return mqttConnector; + } + + @SuppressWarnings("unused") + public void setMQTTConnector(final MQTTConnector MQTTConnector) { + Runnable connector = new Runnable() { + public void run() { + if (waitForServerStartup()) { + return; + } + ControllerService.this.mqttConnector = MQTTConnector; + if (MqttConfig.getInstance().isEnabled()) { + mqttConnector.connect(); + } else { + log.warn("MQTT disabled in 'devicemgt-config.xml'. Hence, MQTTConnector" + + " not started."); + } + } + }; + Thread connectorThread = new Thread(connector); + connectorThread.setDaemon(true); + connectorThread.start(); + } + + /** + * @param agentInfo device owner,id and sensor value + * @return device registration status + */ + @Path("controller/register") + @POST + @Consumes(MediaType.APPLICATION_JSON) + public Response registerDevice(final DeviceJSON agentInfo) { + if ((agentInfo.deviceId != null) && (agentInfo.owner != null)) { + return Response.status(Response.Status.OK).entity("Device has been registered successfully").build(); + } + return Response.status(Response.Status.NOT_ACCEPTABLE).entity("Message body not " + + "well-formed and still invalid").build(); + } + + /** + * @param owner device owner + * @param deviceId unique identifier for given device type + * @param protocol name of supported protocol. here MQTT is used + * @param response to request + * @return sensor record + */ + @Path("controller/read-temperature") + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Feature(code = "read-temperature", name = "Temperature", type = "monitor", + description = "Request temperature reading from device") + public SensorRecord readTemperature(@HeaderParam("owner") String owner, + @HeaderParam("deviceId") String deviceId, + @HeaderParam("protocol") String protocol, + @Context HttpServletResponse response) { + SensorRecord sensorRecord = null; + if (isPermitted(owner, deviceId, response)) { + try { + sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId, + DeviceTypeConstants.SENSOR_TEMPERATURE); + } catch (DeviceControllerException e) { + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + } + response.setStatus(Response.Status.OK.getStatusCode()); + } + return sensorRecord; + } + + /** + * @param owner device owner + * @param deviceId unique identifier for given device type + * @param protocol name of supported protocol. here MQTT is used + * @param response to request + * @return sensor record + */ + @Path("controller/read-humidity") + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + @Feature(code = "read-humidity", name = "Humidity", type = "monitor", + description = "Request humidity reading from device") + public SensorRecord readHumidity(@HeaderParam("owner") String owner, + @HeaderParam("deviceId") String deviceId, + @HeaderParam("protocol") String protocol, + @Context HttpServletResponse response) { + SensorRecord sensorRecord = null; + if (isPermitted(owner, deviceId, response)) { + try { + sensorRecord = SensorDataManager.getInstance().getSensorRecord(deviceId, + DeviceTypeConstants.SENSOR_HUMIDITY); + } catch (DeviceControllerException e) { + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + } + response.setStatus(Response.Status.OK.getStatusCode()); + } + return sensorRecord; + } + + /** + * @param owner device owner + * @param deviceId unique identifier for given device type + * @param protocol name of supported protocol. Here MQTT is used + * @param state change status of buzzer: on/off + * @param response to request + */ + @Path("controller/change-status") + @POST + @Feature(code = "change-status", name = "Buzzer: on/off", type = "operation", + description = "Switch on/off Fire Alarm Buzzer. (On / Off)") + public void changeBuzzerState(@HeaderParam("owner") String owner, + @HeaderParam("deviceId") String deviceId, + @HeaderParam("protocol") String protocol, + @FormParam("state") String state, + @Context HttpServletResponse response) { + if (isPermitted(owner, deviceId, response)) { + try { + mqttConnector.sendCommandViaMQTT(owner, deviceId, "buzzer:", state.toUpperCase()); + response.setStatus(Response.Status.OK.getStatusCode()); + } catch (DeviceManagementException e) { + log.error(e); + response.setStatus(Response.Status.UNAUTHORIZED.getStatusCode()); + } catch (DeviceTypeException e) { + log.error(e); + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + } + } + } + + private boolean isPermitted(String owner, String deviceId, HttpServletResponse response) { + DeviceValidator deviceValidator = new DeviceValidator(); + try { + String tenantDomain = CarbonContext.getThreadLocalCarbonContext().getTenantDomain(); + if (!deviceValidator.isExist(owner, tenantDomain, new DeviceIdentifier( + deviceId, DeviceTypeConstants.DEVICE_TYPE))) { + response.setStatus(Response.Status.UNAUTHORIZED.getStatusCode()); + } else { + return true; + } + } catch (DeviceManagementException e) { + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + } + return false; + } +} \ No newline at end of file diff --git a/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/dto/DeviceJSON.java b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/dto/DeviceJSON.java new file mode 100644 index 00000000..db95b8ea --- /dev/null +++ b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/dto/DeviceJSON.java @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2016, 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.homeautomation.firealarm.controller.api.dto; + +import org.codehaus.jackson.annotate.JsonIgnoreProperties; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +/** + * These information are sent by agent in each request to server + */ +@XmlRootElement +@JsonIgnoreProperties(ignoreUnknown = true) +public class DeviceJSON { + @XmlElement(required = true) + public String owner; + @XmlElement(required = true) + public String deviceId; + @XmlElement(required = true) + public Float sensorValue; +} diff --git a/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/exception/DeviceTypeException.java b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/exception/DeviceTypeException.java new file mode 100644 index 00000000..e790a4fc --- /dev/null +++ b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/exception/DeviceTypeException.java @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016, 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.homeautomation.firealarm.controller.api.exception; + +public class DeviceTypeException extends Exception { + + private static final long serialVersionUID = 2736466230451105441L; + + private String errorMessage; + + public DeviceTypeException(String msg, DeviceTypeException nestedEx) { + super(msg, nestedEx); + setErrorMessage(msg); + } + + public DeviceTypeException(String message, Throwable cause) { + super(message, cause); + setErrorMessage(message); + } + + public DeviceTypeException(String msg) { + super(msg); + setErrorMessage(msg); + } + + public DeviceTypeException() { + super(); + } + + public DeviceTypeException(Throwable cause) { + super(cause); + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } +} diff --git a/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/transport/MQTTConnector.java b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/transport/MQTTConnector.java new file mode 100644 index 00000000..803e4a97 --- /dev/null +++ b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/transport/MQTTConnector.java @@ -0,0 +1,229 @@ +/* + * Copyright (c) 2016, 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.homeautomation.firealarm.controller.api.transport; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.eclipse.paho.client.mqttv3.MqttException; +import org.eclipse.paho.client.mqttv3.MqttMessage; +import org.homeautomation.firealarm.controller.api.exception.DeviceTypeException; +import org.homeautomation.firealarm.controller.api.util.ServiceUtils; +import org.homeautomation.firealarm.plugin.constants.DeviceTypeConstants; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.iot.controlqueue.mqtt.MqttConfig; +import org.wso2.carbon.device.mgt.iot.sensormgt.SensorDataManager; +import org.wso2.carbon.device.mgt.iot.transport.TransportHandlerException; +import org.wso2.carbon.device.mgt.iot.transport.mqtt.MQTTTransportHandler; + +import java.io.File; +import java.util.Calendar; +import java.util.UUID; + +/** + * MQTT is used as transport protocol. So this will provide basic functional requirement in order to communicate over + * MQTT + */ +@SuppressWarnings("no JAX-WS annotation") +public class MQTTConnector extends MQTTTransportHandler { + + private static final String publisherContext = "publisher"; + private static final String subscriberContext = "subscriber"; + private static final String subscribeTopic = + "wso2" + File.separator + "iot" + File.separator + "+" + File.separator + + DeviceTypeConstants.DEVICE_TYPE + File.separator + "+" + File.separator + + publisherContext; + private static Log log = LogFactory.getLog(MQTTConnector.class); + private static String iotServerSubscriber = UUID.randomUUID().toString().substring(0, 5); + String publisher = "wso2/iot/%s/firealarm/%s/" + subscriberContext; + + private MQTTConnector() { + super(iotServerSubscriber, DeviceTypeConstants.DEVICE_TYPE, + MqttConfig.getInstance().getMqttQueueEndpoint(), subscribeTopic); + } + + /** + * This method will initialize connection with message broker + */ + @Override + public void connect() { + Runnable connector = new Runnable() { + public void run() { + while (!isConnected()) { + try { + String brokerUsername = MqttConfig.getInstance().getMqttQueueUsername(); + String brokerPassword = MqttConfig.getInstance().getMqttQueuePassword(); + setUsernameAndPassword(brokerUsername, brokerPassword); + connectToQueue(); + } catch (TransportHandlerException e) { + log.error("Connection to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e); + try { + Thread.sleep(timeoutInterval); + } catch (InterruptedException ex) { + log.error("MQTT-Connector: Thread Sleep Interrupt Exception.", ex); + } + } + try { + subscribeToQueue(); + } catch (TransportHandlerException e) { + log.warn("Subscription to MQTT Broker at: " + mqttBrokerEndPoint + " failed", e); + } + } + } + }; + Thread connectorThread = new Thread(connector); + connectorThread.setDaemon(true); + connectorThread.start(); + } + + /** + * This callback function will be called by message broker when some messages available to subscribed topic + * + * @param message mqtt message which is coming form agent side + * @param messageParams metadata of mqtt message + */ + @Override + public void processIncomingMessage(MqttMessage message, String... messageParams) { + String topic = messageParams[0]; + String ownerAndId = topic.replace("wso2" + File.separator + "iot" + File.separator, ""); + ownerAndId = ownerAndId.replace(File.separator + DeviceTypeConstants.DEVICE_TYPE + + File.separator, ":"); + ownerAndId = ownerAndId.replace(File.separator + publisherContext, ""); + String owner = ownerAndId.split(":")[0]; + String deviceId = ownerAndId.split(":")[1]; + String[] messageData = message.toString().split(":"); + if (log.isDebugEnabled()) { + log.debug("Received MQTT message for: [OWNER-" + owner + "] & [DEVICE.ID-" + deviceId + "]"); + } + if (messageData.length == 4) { + SensorDataManager.getInstance().setSensorRecord(deviceId, DeviceTypeConstants.SENSOR_TEMPERATURE, + messageData[1], Calendar.getInstance().getTimeInMillis()); + SensorDataManager.getInstance().setSensorRecord(deviceId, DeviceTypeConstants.SENSOR_HUMIDITY, + messageData[3], Calendar.getInstance().getTimeInMillis()); + + + if (!ServiceUtils.publishTemperatureToDAS(owner, deviceId, messageData[1])) { + log.error("MQTT Subscriber: Publishing data to DAS failed."); + } + + if (!ServiceUtils.publishHumidityToDAS(owner, deviceId, messageData[3])) { + log.error("MQTT Subscriber: Publishing data to DAS failed."); + } + + if (log.isDebugEnabled()) { + log.debug("Temperature: " + messageData[1]); + log.debug("Humidity: " + messageData[3]); + } + } + } + + /** + * Publish a MQTT message to device through message broker + * + * @param topic mqtt topic which will be used to uniquely identify who are the subscribers to this topic + * @param payLoad message is to be published + * @param qos level of qos(quality of service):1,2,3 + * @param retained life status + * @throws TransportHandlerException + */ + private void publishToAgent(String topic, String payLoad, int qos, boolean retained) + throws TransportHandlerException { + if (log.isDebugEnabled()) { + log.debug("Publishing message [" + payLoad + "to topic [" + topic + "]."); + } + publishToQueue(topic, payLoad, qos, retained); + } + + /** + * Publish a MQTT message to device through message broker + * + * @param deviceOwner person who own the device + * @param deviceId unique identifier for each device + * @param operation command is to executed at agent side e.g: off, on + * @param param additional payload + * @throws DeviceManagementException + * @throws DeviceTypeException + */ + public void sendCommandViaMQTT(String deviceOwner, String deviceId, String operation, + String param) + throws DeviceManagementException, DeviceTypeException { + String topic = String.format(publisher, deviceOwner, deviceId); + String payload = operation + param; + try { + publishToAgent(topic, payload, 2, false); + } catch (TransportHandlerException e) { + String errorMessage = "Error publishing data to device with ID " + deviceId; + throw new DeviceTypeException(errorMessage, e); + } + } + + /** + * connection with message broker can be terminated + */ + @Override + public void disconnect() { + Runnable stopConnection = new Runnable() { + public void run() { + while (isConnected()) { + try { + closeConnection(); + } catch (MqttException e) { + if (log.isDebugEnabled()) { + log.warn("Unable to 'STOP' MQTT connection at broker at: " + mqttBrokerEndPoint); + } + try { + Thread.sleep(timeoutInterval); + } catch (InterruptedException e1) { + log.error("MQTT-Terminator: Thread Sleep Interrupt Exception"); + } + } + } + } + }; + Thread terminatorThread = new Thread(stopConnection); + terminatorThread.setDaemon(true); + terminatorThread.start(); + } + + + @Override + public void publishDeviceData() throws TransportHandlerException { + + } + + @Override + public void publishDeviceData(MqttMessage publishData) throws TransportHandlerException { + + } + + @Override + public void publishDeviceData(String... publishData) throws TransportHandlerException { + + } + + @Override + public void processIncomingMessage() { + + } + + @Override + public void processIncomingMessage(MqttMessage message) throws TransportHandlerException { + + } + +} diff --git a/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/util/ServiceUtils.java b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/util/ServiceUtils.java new file mode 100644 index 00000000..98ad99c2 --- /dev/null +++ b/modules/samples/firealarm/component/controller/src/main/java/org.homeautomation/firealarm/controller/api/util/ServiceUtils.java @@ -0,0 +1,83 @@ +/* + * Copyright (c) 2016, 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.homeautomation.firealarm.controller.api.util; + +import org.homeautomation.firealarm.plugin.constants.DeviceTypeConstants; +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.analytics.exception.DataPublisherConfigurationException; +import org.wso2.carbon.device.mgt.analytics.service.DeviceAnalyticsService; + +public class ServiceUtils { + + private static final String ORG_WSO2_IOT_DEVICES_TEMPERATURE = "org.wso2.iot.devices.temperature"; + private static final String ORG_WSO2_IOT_DEVICES_HUMIDITY = "org.wso2.iot.devices.humidity"; + private static final String SENSOR_STREAM_VERSION = "1.0.0"; + + /** + * sensor data are published to DAS + * + * @param owner name of device owner + * @param deviceId unique identifier of the device + * @param sensorValue current value of sensor which is set at agent side + * @return status + */ + public static boolean publishTemperatureToDAS(String owner, String deviceId, + String sensorValue) { + float temperature = Float.parseFloat(sensorValue); + Object payloadCurrent[] = {temperature}; + return publishToDAS(owner, deviceId, payloadCurrent, ORG_WSO2_IOT_DEVICES_TEMPERATURE); + } + + /** + * sensor data are published to DAS + * + * @param owner name of device owner + * @param deviceId unique identifier of the device + * @param sensorValue current value of sensor which is set at agent side + * @return status + */ + public static boolean publishHumidityToDAS(String owner, String deviceId, + String sensorValue) { + float humidity = Float.parseFloat(sensorValue); + Object payloadCurrent[] = {humidity}; + return publishToDAS(owner, deviceId, payloadCurrent, ORG_WSO2_IOT_DEVICES_HUMIDITY); + } + + private static boolean publishToDAS(String owner, String deviceId, Object[] payloadCurrent, + String definition) { + PrivilegedCarbonContext.startTenantFlow(); + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + ctx.setUsername(owner); + if (ctx.getTenantDomain(true) == null) { + ctx.setTenantDomain("carbon.super", true); + } + DeviceAnalyticsService deviceAnalyticsService = (DeviceAnalyticsService) ctx.getOSGiService( + DeviceAnalyticsService.class, null); + Object metaData[] = {owner, DeviceTypeConstants.DEVICE_TYPE, deviceId, System.currentTimeMillis()}; + try { + deviceAnalyticsService.publishEvent(definition, SENSOR_STREAM_VERSION, metaData, + new Object[0], payloadCurrent); + } catch (DataPublisherConfigurationException e) { + return false; + } finally { + PrivilegedCarbonContext.endTenantFlow(); + } + return true; + } +} diff --git a/modules/samples/firealarm/component/controller/src/main/webapp/META-INF/webapp-classloading.xml b/modules/samples/firealarm/component/controller/src/main/webapp/META-INF/webapp-classloading.xml new file mode 100644 index 00000000..b410b426 --- /dev/null +++ b/modules/samples/firealarm/component/controller/src/main/webapp/META-INF/webapp-classloading.xml @@ -0,0 +1,35 @@ + + + + + + + + + false + + + CXF,Carbon + diff --git a/modules/samples/firealarm/component/controller/src/main/webapp/WEB-INF/cxf-servlet.xml b/modules/samples/firealarm/component/controller/src/main/webapp/WEB-INF/cxf-servlet.xml new file mode 100644 index 00000000..46a71e29 --- /dev/null +++ b/modules/samples/firealarm/component/controller/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -0,0 +1,42 @@ + + + + + + + + + + + + + + + + + + + diff --git a/modules/samples/firealarm/component/controller/src/main/webapp/WEB-INF/web.xml b/modules/samples/firealarm/component/controller/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000..7f6126d2 --- /dev/null +++ b/modules/samples/firealarm/component/controller/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,68 @@ + + + + + + Sample-Webapp-Controller + + JAX-WS/JAX-RS Endpoint + JAX-WS/JAX-RS Servlet + CXFServlet + + org.apache.cxf.transport.servlet.CXFServlet + + 1 + + + CXFServlet + /* + + + isAdminService + false + + + doAuthentication + false + + + + managed-api-enabled + true + + + managed-api-owner + admin + + + managed-api-context-template + /firealarm/{version} + + + managed-api-application + firealarm + + + managed-api-isSecured + true + + diff --git a/modules/samples/firealarm/component/manager/pom.xml b/modules/samples/firealarm/component/manager/pom.xml new file mode 100644 index 00000000..fd549767 --- /dev/null +++ b/modules/samples/firealarm/component/manager/pom.xml @@ -0,0 +1,231 @@ + + + + + + + org.homeautomation + firealarm-component + 1.0.0-SNAPSHOT + ../pom.xml + + 4.0.0 + ${groupId}.firealarm.manager + war + 1.0.0-SNAPSHOT + ${groupId}.firealarm.manager + http://wso2.org + + ${basedir}/src/main/java + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + UTF-8 + ${wso2.maven.compiler.source} + ${wso2.maven.compiler.target} + + + + maven-war-plugin + ${maven-war-plugin.version} + + ${groupId}.firealarm.manager_mgt + + + + + + + org.homeautomation + ${project-base-package}.plugin + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.common + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.core + + + org.apache.axis2.wso2 + axis2-client + + + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.analytics + + + org.apache.axis2.wso2 + axis2-client + + + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.certificate.mgt.core + + + commons-codec.wso2 + commons-codec + + + + + + + org.apache.cxf + cxf-rt-frontend-jaxws + + + org.apache.cxf + cxf-rt-frontend-jaxrs + + + org.apache.cxf + cxf-rt-transports-http + + + + org.apache.httpcomponents + httpasyncclient + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot + + + + org.codehaus.jackson + jackson-core-asl + + + org.codehaus.jackson + jackson-jaxrs + + + javax + javaee-web-api + + + javax.ws.rs + jsr311-api + + + commons-httpclient.wso2 + commons-httpclient + + + org.wso2.carbon + org.wso2.carbon.utils + + + org.bouncycastle.wso2 + bcprov-jdk15on + + + org.wso2.carbon + org.wso2.carbon.user.api + + + org.wso2.carbon + org.wso2.carbon.queuing + + + org.wso2.carbon + org.wso2.carbon.base + + + org.apache.axis2.wso2 + axis2 + + + org.igniterealtime.smack.wso2 + smack + + + org.igniterealtime.smack.wso2 + smackx + + + jaxen + jaxen + + + commons-fileupload.wso2 + commons-fileupload + + + org.apache.ant.wso2 + ant + + + org.apache.ant.wso2 + ant + + + commons-httpclient.wso2 + commons-httpclient + + + org.eclipse.equinox + javax.servlet + + + org.wso2.carbon + org.wso2.carbon.registry.api + + + + + commons-codec + commons-codec + + + commons-io + commons-io + + + + org.igniterealtime.smack.wso2 + smack + + + org.igniterealtime.smack.wso2 + smackx + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.annotations + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.webapp.publisher + + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/ManagerService.java b/modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/ManagerService.java new file mode 100644 index 00000000..9c4cc572 --- /dev/null +++ b/modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/ManagerService.java @@ -0,0 +1,337 @@ +/* + * Copyright (c) 2016, 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.homeautomation.firealarm.manager.api; + +import org.apache.commons.httpclient.HttpStatus; +import org.apache.commons.io.FileUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.homeautomation.firealarm.manager.api.util.APIUtil; +import org.homeautomation.firealarm.manager.api.util.ResponsePayload; +import org.homeautomation.firealarm.plugin.constants.DeviceTypeConstants; +import org.wso2.carbon.apimgt.annotations.device.DeviceType; +import org.wso2.carbon.apimgt.webapp.publisher.KeyGenerationUtil; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; +import org.wso2.carbon.device.mgt.iot.apimgt.AccessTokenInfo; +import org.wso2.carbon.device.mgt.iot.apimgt.TokenClient; +import org.wso2.carbon.device.mgt.iot.exception.AccessTokenException; +import org.wso2.carbon.device.mgt.iot.exception.DeviceControllerException; +import org.wso2.carbon.device.mgt.iot.util.ZipArchive; +import org.wso2.carbon.device.mgt.iot.util.ZipUtil; + +import javax.servlet.http.HttpServletResponse; +import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; +import javax.ws.rs.GET; +import javax.ws.rs.POST; +import javax.ws.rs.PUT; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.QueryParam; +import javax.ws.rs.core.Context; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; +import java.io.IOException; +import java.nio.ByteBuffer; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.Date; +import java.util.List; +import java.util.UUID; + +@SuppressWarnings("NonJaxWsWebServices") +@DeviceType(value = "firealarm") +public class ManagerService { + + private static Log log = LogFactory.getLog(ManagerService.class); + + @Context //injected response proxy supporting multiple thread + private HttpServletResponse response; + + /** + * Generate UUID + * + * @return generated UUID + */ + private static String shortUUID() { + UUID uuid = UUID.randomUUID(); + long l = ByteBuffer.wrap(uuid.toString().getBytes(StandardCharsets.UTF_8)).getLong(); + return Long.toString(l, Character.MAX_RADIX); + } + + /** + * Register new device into IoT Server + * + * @param deviceId unique identifier for device + * @param name name of new device + * @return registration status + */ + @Path("manager/device/register") + @PUT + public boolean register(@QueryParam("deviceId") String deviceId, + @QueryParam("name") String name) { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(deviceId); + deviceIdentifier.setType(DeviceTypeConstants.DEVICE_TYPE); + try { + if (APIUtil.getDeviceManagementService().isEnrolled(deviceIdentifier)) { + response.setStatus(Response.Status.CONFLICT.getStatusCode()); + return false; + } + + String owner = APIUtil.getAuthenticatedUser(); + Device device = new Device(); + device.setDeviceIdentifier(deviceId); + EnrolmentInfo enrolmentInfo = new EnrolmentInfo(); + enrolmentInfo.setDateOfEnrolment(new Date().getTime()); + enrolmentInfo.setDateOfLastUpdate(new Date().getTime()); + enrolmentInfo.setStatus(EnrolmentInfo.Status.ACTIVE); + enrolmentInfo.setOwnership(EnrolmentInfo.OwnerShip.BYOD); + device.setName(name); + device.setType(DeviceTypeConstants.DEVICE_TYPE); + enrolmentInfo.setOwner(owner); + device.setEnrolmentInfo(enrolmentInfo); + KeyGenerationUtil.createApplicationKeys(DeviceTypeConstants.DEVICE_TYPE); + TokenClient accessTokenClient = new TokenClient(DeviceTypeConstants.DEVICE_TYPE); + AccessTokenInfo accessTokenInfo = accessTokenClient.getAccessToken(owner, deviceId); + + //create token + String accessToken = accessTokenInfo.getAccess_token(); + String refreshToken = accessTokenInfo.getRefresh_token(); + List properties = new ArrayList<>(); + Device.Property accessTokenProperty = new Device.Property(); + accessTokenProperty.setName("accessToken"); + accessTokenProperty.setValue(accessToken); + Device.Property refreshTokenProperty = new Device.Property(); + refreshTokenProperty.setName("refreshToken"); + refreshTokenProperty.setValue(refreshToken); + properties.add(accessTokenProperty); + properties.add(refreshTokenProperty); + device.setProperties(properties); + + boolean added = APIUtil.getDeviceManagementService().enrollDevice(device); + if (added) { + response.setStatus(Response.Status.OK.getStatusCode()); + } else { + response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode()); + } + return added; + } catch (DeviceManagementException e) { + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + log.error(e.getErrorMessage(), e); + return false; + } catch (AccessTokenException e) { + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + log.error("Unable to obtain access token", e); + return false; + } + } + + /** + * Remove installed device + * + * @param deviceId unique identifier for device + * @param response to request + */ + @Path("manager/device/remove/{device_id}") + @DELETE + public void removeDevice(@PathParam("device_id") String deviceId, + @Context HttpServletResponse response) { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(deviceId); + deviceIdentifier.setType(DeviceTypeConstants.DEVICE_TYPE); + try { + boolean removed = APIUtil.getDeviceManagementService().disenrollDevice( + deviceIdentifier); + if (removed) { + response.setStatus(Response.Status.OK.getStatusCode()); + } else { + response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode()); + } + } catch (DeviceManagementException e) { + response.setStatus(Response.Status.INTERNAL_SERVER_ERROR.getStatusCode()); + } + } + + /** + * Update device name + * + * @param deviceId unique identifier for device + * @param name new name of the device + * @param response to request + * @return update status + */ + @Path("manager/device/update/{device_id}") + @POST + public boolean updateDevice(@PathParam("device_id") String deviceId, + @QueryParam("name") String name, + @Context HttpServletResponse response) { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(deviceId); + deviceIdentifier.setType(DeviceTypeConstants.DEVICE_TYPE); + try { + Device device = APIUtil.getDeviceManagementService().getDevice(deviceIdentifier); + device.setDeviceIdentifier(deviceId); + device.getEnrolmentInfo().setDateOfLastUpdate(new Date().getTime()); + device.setName(name); + device.setType(DeviceTypeConstants.DEVICE_TYPE); + boolean updated = APIUtil.getDeviceManagementService().modifyEnrollment(device); + if (updated) { + response.setStatus(Response.Status.OK.getStatusCode()); + } else { + response.setStatus(Response.Status.NOT_ACCEPTABLE.getStatusCode()); + } + return updated; + } catch (DeviceManagementException e) { + log.error(e.getErrorMessage()); + return false; + } + } + + /** + * Get device information + * + * @param deviceId unique identifier for device + * @return device + */ + @Path("manager/device/{device_id}") + @GET + @Consumes(MediaType.APPLICATION_JSON) + @Produces(MediaType.APPLICATION_JSON) + public Device getDevice(@PathParam("device_id") String deviceId) { + DeviceIdentifier deviceIdentifier = new DeviceIdentifier(); + deviceIdentifier.setId(deviceId); + deviceIdentifier.setType(DeviceTypeConstants.DEVICE_TYPE); + try { + return APIUtil.getDeviceManagementService().getDevice(deviceIdentifier); + } catch (DeviceManagementException ex) { + log.error("Error occurred while retrieving device with Id " + deviceId + "\n" + ex); + return null; + } + } + + /** + * This will download the agent for given device type + * + * @param deviceName name of the device which is to be created + * @param sketchType name of sketch type + * @return agent archive + */ + @Path("manager/device/{sketch_type}/download") + @GET + @Produces(MediaType.APPLICATION_JSON) + public Response downloadSketch(@QueryParam("deviceName") String deviceName, + @PathParam("sketch_type") String sketchType) { + try { + ZipArchive zipFile = createDownloadFile(APIUtil.getAuthenticatedUser(), deviceName, sketchType); + Response.ResponseBuilder response = Response.ok(FileUtils.readFileToByteArray(zipFile.getZipFile())); + response.type("application/zip"); + response.header("Content-Disposition", "attachment; filename=\"" + zipFile.getFileName() + "\""); + return response.build(); + } catch (IllegalArgumentException ex) { + return Response.status(400).entity(ex.getMessage()).build();//bad request + } catch (DeviceManagementException ex) { + return Response.status(500).entity(ex.getMessage()).build(); + } catch (AccessTokenException ex) { + return Response.status(500).entity(ex.getMessage()).build(); + } catch (DeviceControllerException ex) { + return Response.status(500).entity(ex.getMessage()).build(); + } catch (IOException ex) { + return Response.status(500).entity(ex.getMessage()).build(); + } + } + + /** + * This will give link to generated agent + * + * @param deviceName name of the device which is to be created + * @param sketchType name of sketch type + * @return link to generated agent + */ + @Path("manager/device/{sketch_type}/generate_link") + @GET + public Response generateSketchLink(@QueryParam("deviceName") String deviceName, + @PathParam("sketch_type") String sketchType) { + + try { + ZipArchive zipFile = createDownloadFile(APIUtil.getAuthenticatedUser(), deviceName, sketchType); + ResponsePayload responsePayload = new ResponsePayload(); + responsePayload.setStatusCode(HttpStatus.SC_OK); + responsePayload.setMessageFromServer("Sending Requested sketch by type: " + sketchType + + " and id: " + zipFile.getDeviceId() + "."); + responsePayload.setResponseContent(zipFile.getDeviceId()); + return Response.status(HttpStatus.SC_OK).entity(responsePayload).build(); + } catch (IllegalArgumentException ex) { + return Response.status(HttpStatus.SC_BAD_REQUEST).entity(ex.getMessage()).build(); + } catch (DeviceManagementException ex) { + log.error("Error occurred while creating device with name " + deviceName + "\n", ex); + return Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).entity(ex.getMessage()).build(); + } catch (AccessTokenException ex) { + log.error(ex.getMessage(), ex); + return Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).entity(ex.getMessage()).build(); + } catch (DeviceControllerException ex) { + log.error(ex.getMessage(), ex); + return Response.status(HttpStatus.SC_INTERNAL_SERVER_ERROR).entity(ex.getMessage()).build(); + } + } + + /** + * Make zip file which include all the agent source codes and configuration file + * + * @param owner owner of the device + * @param deviceName name of device + * @param sketchType name of sketch type + * @return zip archive file + * @throws DeviceManagementException + * @throws AccessTokenException + * @throws DeviceControllerException + */ + private ZipArchive createDownloadFile(String owner, String deviceName, String sketchType) + throws DeviceManagementException, AccessTokenException, DeviceControllerException { + if (owner == null) { + throw new IllegalArgumentException("Error on createDownloadFile() Owner is null!"); + } + //create new device id + String deviceId = shortUUID(); + KeyGenerationUtil.createApplicationKeys(DeviceTypeConstants.DEVICE_TYPE); + TokenClient accessTokenClient = new TokenClient(DeviceTypeConstants.DEVICE_TYPE); + AccessTokenInfo accessTokenInfo = accessTokenClient.getAccessToken(owner, deviceId); + //create token + String accessToken = accessTokenInfo.getAccess_token(); + String refreshToken = accessTokenInfo.getRefresh_token(); + //adding registering data + boolean status; + //Register the device with CDMF + status = register(deviceId, deviceName); + if (!status) { + String msg = "Error occurred while registering the device with " + "id: " + deviceId + " owner:" + owner; + throw new DeviceManagementException(msg); + } + ZipUtil ziputil = new ZipUtil(); + ZipArchive zipFile = ziputil.createZipFile(owner, APIUtil.getTenantDomainOfUser(), sketchType, deviceId, deviceName, accessToken, + refreshToken); + zipFile.setDeviceId(deviceId); + return zipFile; + } + +} diff --git a/modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/util/APIUtil.java b/modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/util/APIUtil.java new file mode 100644 index 00000000..c3699691 --- /dev/null +++ b/modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/util/APIUtil.java @@ -0,0 +1,54 @@ +/* +* Copyright (c) 2016, 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.homeautomation.firealarm.manager.api.util; + +import org.wso2.carbon.context.PrivilegedCarbonContext; +import org.wso2.carbon.device.mgt.core.service.DeviceManagementProviderService; + +/** + * This class provides utility functions used by REST-API. + */ +public class APIUtil { + + public static String getAuthenticatedUser() { + PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + String username = threadLocalCarbonContext.getUsername(); + String tenantDomain = threadLocalCarbonContext.getTenantDomain(); + if (username.endsWith(tenantDomain)) { + return username.substring(0, username.lastIndexOf("@")); + } + return username; + } + + public static String getTenantDomainOfUser() { + PrivilegedCarbonContext threadLocalCarbonContext = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + return threadLocalCarbonContext.getTenantDomain(); + } + + public static DeviceManagementProviderService getDeviceManagementService() { + PrivilegedCarbonContext ctx = PrivilegedCarbonContext.getThreadLocalCarbonContext(); + DeviceManagementProviderService deviceManagementProviderService = + (DeviceManagementProviderService) ctx.getOSGiService(DeviceManagementProviderService.class, null); + if (deviceManagementProviderService == null) { + String msg = "Device Management service has not initialized."; + throw new IllegalStateException(msg); + } + return deviceManagementProviderService; + } +} diff --git a/modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/util/ResponsePayload.java b/modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/util/ResponsePayload.java new file mode 100644 index 00000000..684e9374 --- /dev/null +++ b/modules/samples/firealarm/component/manager/src/main/java/org/homeautomation/firealarm/manager/api/util/ResponsePayload.java @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2016, 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.homeautomation.firealarm.manager.api.util; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement +public class ResponsePayload { + + private int statusCode; + private String messageFromServer; + private Object responseContent; + + public static ResponsePayload.ResponsePayloadBuilder statusCode(int statusCode) { + ResponsePayload message = new ResponsePayload(); + return message.getBuilder().statusCode(statusCode); + } + + public static ResponsePayload.ResponsePayloadBuilder messageFromServer( + String messageFromServer) { + ResponsePayload message = new ResponsePayload(); + return message.getBuilder().messageFromServer(messageFromServer); + } + + public static ResponsePayload.ResponsePayloadBuilder responseContent(String responseContent) { + ResponsePayload message = new ResponsePayload(); + return message.getBuilder().responseContent(responseContent); + } + + @XmlElement + public int getStatusCode() { + return statusCode; + } + + public void setStatusCode(int statusCode) { + this.statusCode = statusCode; + } + + @XmlElement + public String getMessageFromServer() { + return messageFromServer; + } + + public void setMessageFromServer(String messageFromServer) { + this.messageFromServer = messageFromServer; + } + + @XmlElement + public Object getResponseContent() { + return responseContent; + } + + public void setResponseContent(Object responseContent) { + this.responseContent = responseContent; + } + + private ResponsePayload.ResponsePayloadBuilder getBuilder() { + return new ResponsePayload.ResponsePayloadBuilder(); + } + + public class ResponsePayloadBuilder { + + private int statusCode; + private String messageFromServer; + private Object responseContent; + + public ResponsePayloadBuilder statusCode(int statusCode) { + this.statusCode = statusCode; + return this; + } + + public ResponsePayloadBuilder messageFromServer(String messageFromServer) { + this.messageFromServer = messageFromServer; + return this; + } + + public ResponsePayloadBuilder responseContent(String responseContent) { + this.responseContent = responseContent; + return this; + } + + public ResponsePayload build() { + ResponsePayload payload = new ResponsePayload(); + payload.setStatusCode(statusCode); + payload.setMessageFromServer(messageFromServer); + payload.setResponseContent(responseContent); + return payload; + } + } + +} diff --git a/modules/samples/firealarm/component/manager/src/main/webapp/META-INF/permissions.xml b/modules/samples/firealarm/component/manager/src/main/webapp/META-INF/permissions.xml new file mode 100644 index 00000000..a98f6a8e --- /dev/null +++ b/modules/samples/firealarm/component/manager/src/main/webapp/META-INF/permissions.xml @@ -0,0 +1,73 @@ + + + + + + + + + + Get device + /device-mgt/user/devices/list + /manager/device/* + GET + emm_admin,emm_user + + + Add device + /device-mgt/user/devices/add + /manager/device/register + PUT + emm_admin,emm_user + + + Download device + /device-mgt/user/devices/add + /manager/device/firealarm/download + GET + emm_admin,emm_user + + + Generate link to download + /device-mgt/user/devices/add + /manager/device/firealarm/generate_link + GET + emm_admin,emm_user + + + Update device + /device-mgt/user/devices/update + /manager/device/update/* + POST + emm_admin,emm_user + + + Remove device + /device-mgt/user/devices/remove + /manager/device/remove/* + DELETE + emm_admin,emm_user + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/manager/src/main/webapp/META-INF/webapp-classloading.xml b/modules/samples/firealarm/component/manager/src/main/webapp/META-INF/webapp-classloading.xml new file mode 100644 index 00000000..b410b426 --- /dev/null +++ b/modules/samples/firealarm/component/manager/src/main/webapp/META-INF/webapp-classloading.xml @@ -0,0 +1,35 @@ + + + + + + + + + false + + + CXF,Carbon + diff --git a/modules/samples/firealarm/component/manager/src/main/webapp/WEB-INF/cxf-servlet.xml b/modules/samples/firealarm/component/manager/src/main/webapp/WEB-INF/cxf-servlet.xml new file mode 100644 index 00000000..854b0248 --- /dev/null +++ b/modules/samples/firealarm/component/manager/src/main/webapp/WEB-INF/cxf-servlet.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + diff --git a/modules/samples/firealarm/component/manager/src/main/webapp/WEB-INF/web.xml b/modules/samples/firealarm/component/manager/src/main/webapp/WEB-INF/web.xml new file mode 100644 index 00000000..a5f0c0c6 --- /dev/null +++ b/modules/samples/firealarm/component/manager/src/main/webapp/WEB-INF/web.xml @@ -0,0 +1,68 @@ + + + + + + Firealarm-Webapp-Manager + + JAX-WS/JAX-RS Endpoint + JAX-WS/JAX-RS Servlet + CXFServlet + + org.apache.cxf.transport.servlet.CXFServlet + + 1 + + + CXFServlet + /* + + + isAdminService + false + + + doAuthentication + true + + + + managed-api-enabled + false + + + managed-api-owner + admin + + + managed-api-context-template + /firealarm/{version} + + + managed-api-application + firealarm + + + managed-api-isSecured + true + + diff --git a/modules/samples/firealarm/component/plugin/pom.xml b/modules/samples/firealarm/component/plugin/pom.xml new file mode 100644 index 00000000..492d5a4e --- /dev/null +++ b/modules/samples/firealarm/component/plugin/pom.xml @@ -0,0 +1,114 @@ + + + + + + + org.homeautomation + firealarm-component + 1.0.0-SNAPSHOT + ../pom.xml + + 4.0.0 + 1.0.0-SNAPSHOT + ${groupId}.firealarm.plugin + bundle + ${groupId}.firealarm.plugin + http://wso2.org + + + + org.apache.felix + maven-scr-plugin + + + org.apache.maven.plugins + maven-compiler-plugin + ${maven-compiler-plugin.version} + + UTF-8 + ${wso2.maven.compiler.source} + ${wso2.maven.compiler.target} + + + + org.apache.felix + maven-bundle-plugin + ${org.apache.felix.version} + true + + + ${groupId}.firealarm.plugin + ${groupId}.firealarm.plugin + 1.0.0-SNAPSHOT + IoT Server Impl Bundle + ${project-base-package}.plugin.internal + + org.osgi.framework, + org.osgi.service.component, + org.apache.commons.logging, + javax.naming, + javax.sql, + javax.xml.parsers, + javax.net, + javax.net.ssl, + org.w3c.dom, + org.wso2.carbon.device.mgt.common.*, + org.wso2.carbon.context.*, + org.wso2.carbon.ndatasource.core, + org.wso2.carbon.device.mgt.iot.*, + + + !${project-base-package}.plugin.internal, + ${project-base-package}.plugin.* + + + + + + + + + org.eclipse.osgi + org.eclipse.osgi + + + org.eclipse.osgi + org.eclipse.osgi.services + + + org.wso2.carbon + org.wso2.carbon.logging + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.common + + + org.wso2.carbon + org.wso2.carbon.ndatasource.core + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot + + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/constants/DeviceTypeConstants.java b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/constants/DeviceTypeConstants.java new file mode 100644 index 00000000..48db43cf --- /dev/null +++ b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/constants/DeviceTypeConstants.java @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2016, 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.homeautomation.firealarm.plugin.constants; + +public class DeviceTypeConstants { + + public final static String DEVICE_TYPE = "firealarm"; + public final static String DEVICE_PLUGIN_DEVICE_NAME = "DEVICE_NAME"; + public final static String DEVICE_PLUGIN_DEVICE_ID = "firealarm_DEVICE_ID"; + public final static String SENSOR_TEMPERATURE = "temperature"; + public final static String SENSOR_HUMIDITY = "humidity"; + public static final String DATA_SOURCE_NAME = "jdbc/firealarmDM_DB"; + + public final static String DEVICE_PLUGIN_PROPERTY_ACCESS_TOKEN = "accessToken"; + public final static String DEVICE_PLUGIN_PROPERTY_REFRESH_TOKEN = "refreshToken"; + +} diff --git a/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/exception/FirealarmPluginException.java b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/exception/FirealarmPluginException.java new file mode 100644 index 00000000..60b41c98 --- /dev/null +++ b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/exception/FirealarmPluginException.java @@ -0,0 +1,56 @@ +/* + * Copyright (c) 2016, 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.homeautomation.firealarm.plugin.exception; + +public class FirealarmPluginException extends Exception { + + private String errorMessage; + + public FirealarmPluginException(String msg, Exception nestedEx) { + super(msg, nestedEx); + setErrorMessage(msg); + } + + public FirealarmPluginException(String message, Throwable cause) { + super(message, cause); + setErrorMessage(message); + } + + public FirealarmPluginException(String msg) { + super(msg); + setErrorMessage(msg); + } + + public FirealarmPluginException() { + super(); + } + + public FirealarmPluginException(Throwable cause) { + super(cause); + } + + public String getErrorMessage() { + return errorMessage; + } + + public void setErrorMessage(String errorMessage) { + this.errorMessage = errorMessage; + } + +} diff --git a/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/DeviceTypeManager.java b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/DeviceTypeManager.java new file mode 100644 index 00000000..63063cc6 --- /dev/null +++ b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/DeviceTypeManager.java @@ -0,0 +1,259 @@ +/* + * Copyright (c) 2016, 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.homeautomation.firealarm.plugin.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.homeautomation.firealarm.plugin.exception.FirealarmPluginException; +import org.homeautomation.firealarm.plugin.impl.dao.DeviceTypeDAO; +import org.wso2.carbon.device.mgt.common.Device; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.DeviceManager; +import org.wso2.carbon.device.mgt.common.EnrolmentInfo; +import org.wso2.carbon.device.mgt.common.FeatureManager; +import org.wso2.carbon.device.mgt.common.configuration.mgt.TenantConfiguration; +import org.wso2.carbon.device.mgt.common.license.mgt.License; +import org.wso2.carbon.device.mgt.common.license.mgt.LicenseManagementException; + +import java.util.List; + +/** + * + */ +public class DeviceTypeManager implements DeviceManager { + + private static final Log log = LogFactory.getLog(DeviceTypeManager.class); + + private static final DeviceTypeDAO connectedCupDAO = new DeviceTypeDAO(); + + @Override + public FeatureManager getFeatureManager() { + return null; + } + + @Override + public boolean saveConfiguration(TenantConfiguration tenantConfiguration) + throws DeviceManagementException { + //TODO implement this + return false; + } + + @Override + public TenantConfiguration getConfiguration() throws DeviceManagementException { + //TODO implement this + return null; + } + + @Override + public boolean enrollDevice(Device device) throws DeviceManagementException { + boolean status; + try { + if (log.isDebugEnabled()) { + log.debug("Enrolling a new Connected Cup device : " + device.getDeviceIdentifier()); + } + DeviceTypeDAO.beginTransaction(); + status = connectedCupDAO.getConnectedCupDeviceDAO().addDevice(device); + DeviceTypeDAO.commitTransaction(); + } catch (FirealarmPluginException e) { + try { + DeviceTypeDAO.rollbackTransaction(); + } catch (FirealarmPluginException iotDAOEx) { + String msg = "Error occurred while roll back the device enrol transaction :" + device.toString(); + log.warn(msg, iotDAOEx); + } + String msg = "Error while enrolling the Connected Cup device : " + device.getDeviceIdentifier(); + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } + return status; + } + + @Override + public boolean modifyEnrollment(Device device) throws DeviceManagementException { + boolean status; + try { + if (log.isDebugEnabled()) { + log.debug("Modifying the Connected Cup device enrollment data"); + } + DeviceTypeDAO.beginTransaction(); + status = connectedCupDAO.getConnectedCupDeviceDAO().updateDevice(device); + DeviceTypeDAO.commitTransaction(); + } catch (FirealarmPluginException e) { + try { + DeviceTypeDAO.rollbackTransaction(); + } catch (FirealarmPluginException iotDAOEx) { + String msg = "Error occurred while roll back the update device transaction :" + device.toString(); + log.warn(msg, iotDAOEx); + } + String msg = "Error while updating the enrollment of the Connected Cup device : " + + device.getDeviceIdentifier(); + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } + return status; + } + + @Override + public boolean disenrollDevice(DeviceIdentifier deviceId) throws DeviceManagementException { + boolean status; + try { + if (log.isDebugEnabled()) { + log.debug("Dis-enrolling Connected Cup device : " + deviceId); + } + DeviceTypeDAO.beginTransaction(); + status = connectedCupDAO.getConnectedCupDeviceDAO().deleteDevice(deviceId.getId()); + DeviceTypeDAO.commitTransaction(); + } catch (FirealarmPluginException e) { + try { + DeviceTypeDAO.rollbackTransaction(); + } catch (FirealarmPluginException iotDAOEx) { + String msg = "Error occurred while roll back the device dis enrol transaction :" + deviceId.toString(); + log.warn(msg, iotDAOEx); + } + String msg = "Error while removing the Connected Cup device : " + deviceId.getId(); + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } + return status; + } + + @Override + public boolean isEnrolled(DeviceIdentifier deviceId) throws DeviceManagementException { + boolean isEnrolled = false; + try { + if (log.isDebugEnabled()) { + log.debug("Checking the enrollment of Connected Cup device : " + deviceId.getId()); + } + Device iotDevice = connectedCupDAO.getConnectedCupDeviceDAO().getDevice(deviceId.getId()); + if (iotDevice != null) { + isEnrolled = true; + } + } catch (FirealarmPluginException e) { + String msg = "Error while checking the enrollment status of Connected Cup device : " + + deviceId.getId(); + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } + return isEnrolled; + } + + @Override + public boolean isActive(DeviceIdentifier deviceId) throws DeviceManagementException { + return true; + } + + @Override + public boolean setActive(DeviceIdentifier deviceId, boolean status) + throws DeviceManagementException { + return true; + } + + @Override + public Device getDevice(DeviceIdentifier deviceId) throws DeviceManagementException { + Device device; + try { + if (log.isDebugEnabled()) { + log.debug("Getting the details of Connected Cup device : " + deviceId.getId()); + } + device = connectedCupDAO.getConnectedCupDeviceDAO().getDevice(deviceId.getId()); + + } catch (FirealarmPluginException e) { + String msg = "Error while fetching the Connected Cup device : " + deviceId.getId(); + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } + return device; + } + + @Override + public boolean setOwnership(DeviceIdentifier deviceId, String ownershipType) + throws DeviceManagementException { + return true; + } + + public boolean isClaimable(DeviceIdentifier deviceIdentifier) throws DeviceManagementException { + return false; + } + + @Override + public boolean setStatus(DeviceIdentifier deviceId, String currentOwner, + EnrolmentInfo.Status status) throws DeviceManagementException { + return false; + } + + @Override + public License getLicense(String s) throws LicenseManagementException { + return null; + } + + @Override + public void addLicense(License license) throws LicenseManagementException { + + } + + @Override + public boolean requireDeviceAuthorization() { + return false; + } + + @Override + public boolean updateDeviceInfo(DeviceIdentifier deviceIdentifier, Device device) + throws DeviceManagementException { + boolean status; + try { + if (log.isDebugEnabled()) { + log.debug( + "updating the details of Connected Cup device : " + deviceIdentifier); + } + DeviceTypeDAO.beginTransaction(); + status = connectedCupDAO.getConnectedCupDeviceDAO().updateDevice(device); + DeviceTypeDAO.commitTransaction(); + } catch (FirealarmPluginException e) { + try { + DeviceTypeDAO.rollbackTransaction(); + } catch (FirealarmPluginException iotDAOEx) { + String msg = "Error occurred while roll back the update device info transaction :" + device.toString(); + log.warn(msg, iotDAOEx); + } + String msg = + "Error while updating the Connected Cup device : " + deviceIdentifier; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } + return status; + } + + @Override + public List getAllDevices() throws DeviceManagementException { + List devices; + try { + if (log.isDebugEnabled()) { + log.debug("Fetching the details of all Connected Cup devices"); + } + devices = connectedCupDAO.getConnectedCupDeviceDAO().getAllDevices(); + } catch (FirealarmPluginException e) { + String msg = "Error while fetching all Connected Cup devices."; + log.error(msg, e); + throw new DeviceManagementException(msg, e); + } + return devices; + } + +} \ No newline at end of file diff --git a/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/DeviceTypeManagerService.java b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/DeviceTypeManagerService.java new file mode 100644 index 00000000..86d7351b --- /dev/null +++ b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/DeviceTypeManagerService.java @@ -0,0 +1,114 @@ +/* + * Copyright (c) 2016, 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.homeautomation.firealarm.plugin.impl; + +import org.homeautomation.firealarm.plugin.constants.DeviceTypeConstants; +import org.wso2.carbon.device.mgt.common.DeviceIdentifier; +import org.wso2.carbon.device.mgt.common.DeviceManagementException; +import org.wso2.carbon.device.mgt.common.DeviceManager; +import org.wso2.carbon.device.mgt.common.app.mgt.Application; +import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManagementException; +import org.wso2.carbon.device.mgt.common.app.mgt.ApplicationManager; +import org.wso2.carbon.device.mgt.common.operation.mgt.Operation; +import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService; + +import java.util.List; + +public class DeviceTypeManagerService implements DeviceManagementService { + private DeviceManager deviceManager; + + @Override + public String getType() { + return DeviceTypeConstants.DEVICE_TYPE; + } + + + @Override + public String getProviderTenantDomain() { + return "carbon.super"; + } + + @Override + public boolean isSharedWithAllTenants() { + return true; + } + + @Override + public String[] getSharedTenantsDomain() { + return new String[0]; + } + + @Override + public void init() throws DeviceManagementException { + this.deviceManager = new DeviceTypeManager(); + } + + @Override + public DeviceManager getDeviceManager() { + return deviceManager; + } + + @Override + public ApplicationManager getApplicationManager() { + return null; + } + + @Override + public void notifyOperationToDevices(Operation operation, List deviceIds) + throws DeviceManagementException { + + } + + @Override + public Application[] getApplications(String domain, int pageNumber, int size) + throws ApplicationManagementException { + return new Application[0]; + } + + @Override + public void updateApplicationStatus(DeviceIdentifier deviceId, Application application, + String status) throws ApplicationManagementException { + + } + + @Override + public String getApplicationStatus(DeviceIdentifier deviceId, Application application) + throws ApplicationManagementException { + return null; + } + + @Override + public void installApplicationForDevices(Operation operation, + List deviceIdentifiers) + throws ApplicationManagementException { + + } + + @Override + public void installApplicationForUsers(Operation operation, List userNameList) + throws ApplicationManagementException { + + } + + @Override + public void installApplicationForUserRoles(Operation operation, List userRoleList) + throws ApplicationManagementException { + + } +} diff --git a/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/DeviceTypeDAO.java b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/DeviceTypeDAO.java new file mode 100644 index 00000000..e78b3ab0 --- /dev/null +++ b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/DeviceTypeDAO.java @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2016, 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.homeautomation.firealarm.plugin.impl.dao; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.homeautomation.firealarm.plugin.constants.DeviceTypeConstants; +import org.homeautomation.firealarm.plugin.exception.FirealarmPluginException; +import org.homeautomation.firealarm.plugin.impl.dao.impl.DeviceTypeDAOImpl; + +import javax.naming.Context; +import javax.naming.InitialContext; +import javax.naming.NamingException; +import javax.sql.DataSource; +import java.sql.Connection; +import java.sql.SQLException; + +public class DeviceTypeDAO { + + private static final Log log = LogFactory.getLog(DeviceTypeDAO.class); + private static DataSource dataSource; + private static ThreadLocal currentConnection = new ThreadLocal<>(); + + public DeviceTypeDAO() { + initConnectedCupDAO(); + } + + public static void initConnectedCupDAO() { + try { + Context ctx = new InitialContext(); + dataSource = (DataSource) ctx.lookup(DeviceTypeConstants.DATA_SOURCE_NAME); + } catch (NamingException e) { + log.error("Error while looking up the data source: " + + DeviceTypeConstants.DATA_SOURCE_NAME); + } + + } + + public static void beginTransaction() throws FirealarmPluginException { + try { + Connection conn = dataSource.getConnection(); + conn.setAutoCommit(false); + currentConnection.set(conn); + } catch (SQLException e) { + throw new FirealarmPluginException( + "Error occurred while retrieving datasource connection", e); + } + } + + public static Connection getConnection() throws FirealarmPluginException { + if (currentConnection.get() == null) { + try { + currentConnection.set(dataSource.getConnection()); + } catch (SQLException e) { + throw new FirealarmPluginException( + "Error occurred while retrieving data source connection", e); + } + } + return currentConnection.get(); + } + + public static void commitTransaction() throws FirealarmPluginException { + try { + Connection conn = currentConnection.get(); + if (conn != null) { + conn.commit(); + } else { + if (log.isDebugEnabled()) { + log.debug("Datasource connection associated with the current thread is null, " + + "hence commit has not been attempted"); + } + } + } catch (SQLException e) { + throw new FirealarmPluginException( + "Error occurred while committing the transaction", e); + } finally { + closeConnection(); + } + } + + public static void closeConnection() throws FirealarmPluginException { + + Connection con = currentConnection.get(); + if (con != null) { + try { + con.close(); + } catch (SQLException e) { + log.error("Error occurred while close the connection"); + } + } + currentConnection.remove(); + } + + public static void rollbackTransaction() throws FirealarmPluginException { + try { + Connection conn = currentConnection.get(); + if (conn != null) { + conn.rollback(); + } else { + if (log.isDebugEnabled()) { + log.debug( + "Datasource connection associated with the current thread is null, " + + "hence rollback has not been attempted"); + } + } + } catch (SQLException e) { + throw new FirealarmPluginException("Error occurred while rollback the transaction", e); + } finally { + closeConnection(); + } + } + + public DeviceTypeDAOImpl getConnectedCupDeviceDAO() { + return new DeviceTypeDAOImpl(); + } +} diff --git a/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/impl/DeviceTypeDAOImpl.java b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/impl/DeviceTypeDAOImpl.java new file mode 100644 index 00000000..e9b09baa --- /dev/null +++ b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/impl/DeviceTypeDAOImpl.java @@ -0,0 +1,239 @@ +/* + * Copyright (c) 2016, 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.homeautomation.firealarm.plugin.impl.dao.impl; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.homeautomation.firealarm.plugin.constants.DeviceTypeConstants; +import org.homeautomation.firealarm.plugin.exception.FirealarmPluginException; +import org.homeautomation.firealarm.plugin.impl.dao.DeviceTypeDAO; +import org.homeautomation.firealarm.plugin.impl.dao.util.DeviceTypeUtils; +import org.wso2.carbon.device.mgt.common.Device; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; + +/** + * Device Dao for Firealarm Devices. + */ +public class DeviceTypeDAOImpl { + + private static final Log log = LogFactory.getLog(DeviceTypeDAOImpl.class); + + public Device getDevice(String deviceId) throws FirealarmPluginException { + Connection conn; + PreparedStatement stmt = null; + Device connectedCupDevice = null; + ResultSet resultSet = null; + try { + conn = DeviceTypeDAO.getConnection(); + String selectDBQuery = + "SELECT firealarm_DEVICE_ID, DEVICE_NAME, ACCESS_TOKEN, REFRESH_TOKEN" + + " FROM firealarm_DEVICE WHERE firealarm_DEVICE_ID = ?"; + stmt = conn.prepareStatement(selectDBQuery); + stmt.setString(1, deviceId); + resultSet = stmt.executeQuery(); + + if (resultSet.next()) { + connectedCupDevice = new Device(); + connectedCupDevice.setName(resultSet.getString( + DeviceTypeConstants.DEVICE_PLUGIN_DEVICE_NAME)); + List propertyList = new ArrayList<>(); + propertyList.add(DeviceTypeUtils.getProperty( + DeviceTypeConstants.DEVICE_PLUGIN_PROPERTY_ACCESS_TOKEN, + resultSet.getString("ACCESS_TOKEN"))); + propertyList.add(DeviceTypeUtils.getProperty( + DeviceTypeConstants.DEVICE_PLUGIN_PROPERTY_REFRESH_TOKEN, + resultSet.getString("REFRESH_TOKEN"))); + connectedCupDevice.setProperties(propertyList); + + if (log.isDebugEnabled()) { + log.debug("Firealarm service " + deviceId + " data has been fetched from" + + "Firealarm database."); + } + } + } catch (SQLException e) { + String msg = "Error occurred while fetching Firealarm device : '" + deviceId + "'"; + log.error(msg, e); + throw new FirealarmPluginException(msg, e); + } finally { + DeviceTypeUtils.cleanupResources(stmt, resultSet); + DeviceTypeDAO.closeConnection(); + } + return connectedCupDevice; + } + + public boolean addDevice(Device connectedCupDevice) throws FirealarmPluginException { + boolean status = false; + Connection conn; + PreparedStatement stmt = null; + try { + conn = DeviceTypeDAO.getConnection(); + String createDBQuery = + "INSERT INTO firealarm_DEVICE(firealarm_DEVICE_ID, DEVICE_NAME, " + + "ACCESS_TOKEN, REFRESH_TOKEN) VALUES (?, ?, ?, ?)"; + + stmt = conn.prepareStatement(createDBQuery); + stmt.setString(1, connectedCupDevice.getDeviceIdentifier()); + stmt.setString(2, connectedCupDevice.getName()); + stmt.setString(3, DeviceTypeUtils.getDeviceProperty( + connectedCupDevice.getProperties(), + DeviceTypeConstants.DEVICE_PLUGIN_PROPERTY_ACCESS_TOKEN)); + stmt.setString(4, DeviceTypeUtils.getDeviceProperty( + connectedCupDevice.getProperties(), + DeviceTypeConstants.DEVICE_PLUGIN_PROPERTY_REFRESH_TOKEN)); + + int rows = stmt.executeUpdate(); + if (rows > 0) { + status = true; + if (log.isDebugEnabled()) { + log.debug("Connected Cup device " + connectedCupDevice.getDeviceIdentifier() + + " data has been added to the Connected Cup database."); + } + } + } catch (SQLException e) { + String msg = "Error occurred while adding the Connected Cup device '" + + connectedCupDevice.getDeviceIdentifier() + "' to the Connected Cup db."; + throw new FirealarmPluginException(msg, e); + } finally { + DeviceTypeUtils.cleanupResources(stmt, null); + } + return status; + } + + public boolean updateDevice(Device connectedCupDevice) throws FirealarmPluginException { + boolean status = false; + Connection conn; + PreparedStatement stmt = null; + try { + conn = DeviceTypeDAO.getConnection(); + String updateDBQuery = + "UPDATE firealarm_DEVICE SET DEVICE_NAME = ?, ACCESS_TOKEN=?, " + + "REFRESH_TOKEN=? WHERE firealarm_DEVICE_ID = ?"; + + stmt = conn.prepareStatement(updateDBQuery); + + if (connectedCupDevice.getProperties() == null) { + connectedCupDevice.setProperties(new ArrayList()); + } + stmt.setString(1, connectedCupDevice.getName()); + stmt.setString(2, DeviceTypeUtils.getDeviceProperty( + connectedCupDevice.getProperties(), + DeviceTypeConstants.DEVICE_PLUGIN_PROPERTY_ACCESS_TOKEN)); + stmt.setString(3, DeviceTypeUtils.getDeviceProperty( + connectedCupDevice.getProperties(), + DeviceTypeConstants.DEVICE_PLUGIN_PROPERTY_REFRESH_TOKEN)); + stmt.setString(4, connectedCupDevice.getDeviceIdentifier()); + int rows = stmt.executeUpdate(); + if (rows > 0) { + status = true; + if (log.isDebugEnabled()) { + log.debug("Connected Cup device " + connectedCupDevice.getDeviceIdentifier() + + " data has been modified."); + } + } + } catch (SQLException e) { + String msg = "Error occurred while modifying the Connected Cup device '" + + connectedCupDevice.getDeviceIdentifier() + "' data."; + log.error(msg, e); + throw new FirealarmPluginException(msg, e); + } finally { + DeviceTypeUtils.cleanupResources(stmt, null); + } + return status; + } + + public boolean deleteDevice(String deviceId) throws FirealarmPluginException { + boolean status = false; + Connection conn; + PreparedStatement stmt = null; + try { + conn = DeviceTypeDAO.getConnection(); + String deleteDBQuery = + "DELETE FROM firealarm_DEVICE WHERE firealarm_DEVICE_ID = ?"; + stmt = conn.prepareStatement(deleteDBQuery); + stmt.setString(1, deviceId); + int rows = stmt.executeUpdate(); + if (rows > 0) { + status = true; + if (log.isDebugEnabled()) { + log.debug("Connected Cup device " + deviceId + " data has deleted" + + " from the Connected Cup database."); + } + } + } catch (SQLException e) { + String msg = "Error occurred while deleting Connected Cup device " + deviceId; + log.error(msg, e); + throw new FirealarmPluginException(msg, e); + } finally { + DeviceTypeUtils.cleanupResources(stmt, null); + } + return status; + } + + public List getAllDevices() throws FirealarmPluginException { + Connection conn; + PreparedStatement stmt = null; + ResultSet resultSet = null; + Device connectedCupDevice; + List iotDevices = new ArrayList<>(); + + try { + conn = DeviceTypeDAO.getConnection(); + String selectDBQuery = + "SELECT firealarm_DEVICE_ID, DEVICE_NAME, ACCESS_TOKEN, REFRESH_TOKEN" + + "FROM firealarm_DEVICE"; + stmt = conn.prepareStatement(selectDBQuery); + resultSet = stmt.executeQuery(); + while (resultSet.next()) { + connectedCupDevice = new Device(); + connectedCupDevice.setDeviceIdentifier(resultSet.getString( + DeviceTypeConstants.DEVICE_PLUGIN_DEVICE_ID)); + connectedCupDevice.setName(resultSet.getString( + DeviceTypeConstants.DEVICE_PLUGIN_DEVICE_NAME)); + + List propertyList = new ArrayList<>(); + propertyList.add(DeviceTypeUtils.getProperty( + DeviceTypeConstants.DEVICE_PLUGIN_PROPERTY_ACCESS_TOKEN, + resultSet.getString("ACCESS_TOKEN"))); + propertyList.add(DeviceTypeUtils.getProperty( + DeviceTypeConstants.DEVICE_PLUGIN_PROPERTY_REFRESH_TOKEN, + resultSet.getString("REFRESH_TOKEN"))); + connectedCupDevice.setProperties(propertyList); + } + if (log.isDebugEnabled()) { + log.debug("All Connected Cup device details have fetched from Connected Cup database" + + "."); + } + return iotDevices; + } catch (SQLException e) { + String msg = "Error occurred while fetching all Connected Cup device data'"; + log.error(msg, e); + throw new FirealarmPluginException(msg, e); + } finally { + DeviceTypeUtils.cleanupResources(stmt, resultSet); + DeviceTypeDAO.closeConnection(); + } + } + +} diff --git a/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/util/DeviceTypeUtils.java b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/util/DeviceTypeUtils.java new file mode 100644 index 00000000..e8c5c6c9 --- /dev/null +++ b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/impl/dao/util/DeviceTypeUtils.java @@ -0,0 +1,87 @@ +/* + * Copyright (c) 2016, 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.homeautomation.firealarm.plugin.impl.dao.util; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.wso2.carbon.device.mgt.common.Device; + +import java.sql.Connection; +import java.sql.PreparedStatement; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.util.List; + +/** + * Contains utility methods used by FireAlarm plugin. + */ +public class DeviceTypeUtils { + + private static Log log = LogFactory.getLog(DeviceTypeUtils.class); + + public static String getDeviceProperty(List deviceProperties, + String propertyKey) { + String deviceProperty = ""; + for (Device.Property property : deviceProperties) { + if (propertyKey.equals(property.getName())) { + deviceProperty = property.getValue(); + } + } + return deviceProperty; + } + + public static Device.Property getProperty(String property, String value) { + if (property != null) { + Device.Property prop = new Device.Property(); + prop.setName(property); + prop.setValue(value); + return prop; + } + return null; + } + + public static void cleanupResources(Connection conn, PreparedStatement stmt, ResultSet rs) { + if (rs != null) { + try { + rs.close(); + } catch (SQLException e) { + log.warn("Error occurred while closing result set", e); + } + } + if (stmt != null) { + try { + stmt.close(); + } catch (SQLException e) { + log.warn("Error occurred while closing prepared statement", e); + } + } + if (conn != null) { + try { + conn.close(); + } catch (SQLException e) { + log.warn("Error occurred while closing database connection", e); + } + } + } + + public static void cleanupResources(PreparedStatement stmt, ResultSet rs) { + cleanupResources(null, stmt, rs); + } + +} diff --git a/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/internal/ServiceComponent.java b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/internal/ServiceComponent.java new file mode 100644 index 00000000..d949e6a8 --- /dev/null +++ b/modules/samples/firealarm/component/plugin/src/main/java/org/homeautomation/firealarm/plugin/internal/ServiceComponent.java @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2016, 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.homeautomation.firealarm.plugin.internal; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.homeautomation.firealarm.plugin.impl.DeviceTypeManagerService; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceRegistration; +import org.osgi.service.component.ComponentContext; +import org.wso2.carbon.device.mgt.common.spi.DeviceManagementService; + +/** + * @scr.component name="org.homeautomation.firealarm.plugin.internal.ServiceComponent" + * immediate="true" + */ + +public class ServiceComponent { + + private static final Log log = LogFactory.getLog(ServiceComponent.class); + private ServiceRegistration serviceRegistration; + + protected void activate(ComponentContext ctx) { + if (log.isDebugEnabled()) { + log.debug("Activating firealarm Management Service Component"); + } + try { + BundleContext bundleContext = ctx.getBundleContext(); + serviceRegistration = + bundleContext.registerService(DeviceManagementService.class.getName(), new + DeviceTypeManagerService(), null); + if (log.isDebugEnabled()) { + log.debug("firealarm Management Service Component has been successfully activated"); + } + } catch (Throwable e) { + log.error("Error occurred while activating Current Sensor Management Service Component", e); + } + } + + protected void deactivate(ComponentContext ctx) { + if (log.isDebugEnabled()) { + log.debug("De-activating firealarm Management Service Component"); + } + try { + if (serviceRegistration != null) { + serviceRegistration.unregister(); + } + if (log.isDebugEnabled()) { + log.debug("Current Sensor Management Service Component has been successfully de-activated"); + } + } catch (Throwable e) { + log.error("Error occurred while de-activating Iot Device Management bundle", e); + } + } + +} diff --git a/modules/samples/firealarm/component/pom.xml b/modules/samples/firealarm/component/pom.xml new file mode 100644 index 00000000..45d5e76c --- /dev/null +++ b/modules/samples/firealarm/component/pom.xml @@ -0,0 +1,268 @@ + + + + + + + org.homeautomation + firealarm + 1.0.0-SNAPSHOT + ../pom.xml + + 4.0.0 + 1.0.0-SNAPSHOT + firealarm-component + pom + + + + + org.apache.felix + maven-scr-plugin + ${maven-scr-plugin.version} + + + generate-scr-scrdescriptor + + scr + + + + + + + + + + + org.homeautomation + ${project-base-package}.plugin + 1.0.0-SNAPSHOT + provided + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.webapp.publisher + ${carbon.device.mgt.version} + system + + ${basedir}/../../../../repository/components/plugins/org.wso2.carbon.apimgt.webapp.publisher_${carbon.device.mgt.jar.version}.jar + + + + org.wso2.carbon + org.wso2.carbon.ndatasource.core + ${carbon.kernel.version} + system + + ${basedir}/../../../../repository/components/plugins/org.wso2.carbon.ndatasource.core_${carbon.kernel.version}.jar + + + + org.wso2.carbon.devicemgt-plugins + org.wso2.carbon.device.mgt.iot + ${carbon.iot.device.mgt.version} + system + + ${basedir}/../../../../repository/components/plugins/org.wso2.carbon.device.mgt.iot_${carbon.iot.device.mgt.jar.version}.jar + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.core + ${carbon.device.mgt.version} + system + + ${basedir}/../../../../repository/components/plugins/org.wso2.carbon.device.mgt.core_${carbon.device.mgt.jar.version}.jar + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.common + ${carbon.device.mgt.version} + system + + ${basedir}/../../../../repository/components/plugins/org.wso2.carbon.device.mgt.common_${carbon.device.mgt.jar.version}.jar + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.certificate.mgt.core + ${carbon.device.mgt.version} + system + + ${basedir}/../../../../repository/components/plugins/org.wso2.carbon.certificate.mgt.core_${carbon.device.mgt.jar.version}.jar + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.apimgt.annotations + ${carbon.device.mgt.version} + system + + ${basedir}/../../../../repository/components/plugins/org.wso2.carbon.apimgt.annotations_${carbon.device.mgt.jar.version}.jar + + + + org.wso2.carbon.devicemgt + org.wso2.carbon.device.mgt.analytics + ${carbon.device.mgt.version} + system + + ${basedir}/../../../../repository/components/plugins/org.wso2.carbon.device.mgt.analytics_${carbon.device.mgt.jar.version}.jar + + + + commons-httpclient.wso2 + commons-httpclient + ${commons-httpclient.orbit.version} + system + + ${basedir}/../../../../repository/components/plugins/commons-httpclient_3.1.0.wso2v2.jar + + + + commons-httpclient.wso2 + commons-httpclient + ${commons-httpclient.orbit.version} + system + + ${basedir}/../../../../repository/components/plugins/commons-httpclient_3.1.0.wso2v2.jar + + + + org.wso2.carbon + org.wso2.carbon.utils + ${carbon.kernel.version} + + + org.bouncycastle.wso2 + bcprov-jdk15on + + + org.wso2.carbon + org.wso2.carbon.user.api + + + org.wso2.carbon + org.wso2.carbon.queuing + + + org.wso2.carbon + org.wso2.carbon.base + + + org.apache.axis2.wso2 + axis2 + + + org.igniterealtime.smack.wso2 + smack + + + org.igniterealtime.smack.wso2 + smackx + + + jaxen + jaxen + + + commons-fileupload.wso2 + commons-fileupload + + + org.apache.ant.wso2 + ant + + + org.apache.ant.wso2 + ant + + + commons-httpclient.wso2 + commons-httpclient + + + org.eclipse.equinox + javax.servlet + + + org.wso2.carbon + org.wso2.carbon.registry.api + + + system + + ${basedir}/../../../../repository/components/plugins/org.wso2.carbon.utils_${carbon.kernel.version}.jar + + + + org.igniterealtime.smack.wso2 + smack + ${smack.wso2.version} + system + + ${basedir}/../../../../repository/components/plugins/smack_3.0.4.wso2v1.jar + + + + org.igniterealtime.smack.wso2 + smackx + ${smackx.wso2.version} + system + + ${basedir}/../../../../repository/components/plugins/smackx_3.0.4.wso2v1.jar + + + + org.json.wso2 + json + ${commons-json.version} + system + + ${basedir}/../../../../repository/components/plugins/json_2.0.0.wso2v1.jar + + + + commons-codec + commons-codec + 1.4.0.wso2v1 + system + + ${basedir}/../../../../repository/components/plugins/commons-codec_1.4.0.wso2v1.jar + + + + commons-io + commons-io + ${commons-io.version} + + + + + plugin + controller + manager + analytics + ui + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/pom.xml b/modules/samples/firealarm/component/ui/pom.xml new file mode 100644 index 00000000..3e6076d1 --- /dev/null +++ b/modules/samples/firealarm/component/ui/pom.xml @@ -0,0 +1,58 @@ + + + + + + + org.homeautomation + firealarm-component + 1.0.0-SNAPSHOT + ../pom.xml + + 4.0.0 + ${groupId}.firealarm.ui + ${groupId}.firealarm.ui + pom + + + + maven-assembly-plugin + ${maven-assembly-plugin.version} + + ${project.artifactId}-1.0.0-SNAPSHOT + false + + src/assembly/src.xml + + + + + create-archive + package + + single + + + + + + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/assembly/src.xml b/modules/samples/firealarm/component/ui/src/assembly/src.xml new file mode 100644 index 00000000..3f381cbe --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/assembly/src.xml @@ -0,0 +1,38 @@ + + + + + + src + + zip + + false + ${basedir}/src + + + ${basedir}/src/main/resources/jaggeryapps/ + / + true + + + \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.hbs b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.hbs new file mode 100644 index 00000000..429c632a --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.hbs @@ -0,0 +1,130 @@ + +{{#zone "topCss"}} + +{{/zone}} + +{{#zone "device-thumbnail"}} + +{{/zone}} + +{{#zone "operation-status"}} + +{{/zone}} + +{{#zone "device-opetations"}} +
+ Operations +
+
+ {{unit "iot.unit.device.operation-bar" device=device}} +
+{{/zone}} + +{{#zone "device-detail-properties"}} +
+{{/zone}} + + + diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.js b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.js new file mode 100644 index 00000000..9cf48f5e --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.js @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016, 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. + */ + + +/* + * Copyright (c) 2016, 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("device-view.js"); + var deviceType = context.uriParams.deviceType; + var deviceId = request.getParameter("id"); + + var getProperty = require("process").getProperty; + var port = getProperty("carbon.https.port"); + var host = getProperty("carbon.local.ip"); + var sessionId = session.getId(); + if (deviceType != null && deviceType != undefined && deviceId != null && deviceId != undefined) { + var deviceModule = require("/app/modules/device.js").deviceModule; + var device = deviceModule.viewDevice(deviceType, deviceId); + + if (device && device.status != "error") { + log.info(device); + return {"device": device, "port": port, "host": host, "sessionId": sessionId}; + } + } +} \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.json b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.json new file mode 100644 index 00000000..688e9398 --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/device-view.json @@ -0,0 +1,3 @@ +{ + "version": "1.0.0" +} \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/public/images/current-sensor.png b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.device-view/public/images/current-sensor.png new file mode 100644 index 0000000000000000000000000000000000000000..b1ce4901bcbd4f7485f759d26d81520cd22623be GIT binary patch literal 38879 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 Jbz07G{{fC<96A61 literal 0 HcmV?d00001 diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-edit/policy-edit.hbs b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-edit/policy-edit.hbs new file mode 100644 index 00000000..cf80b006 --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-edit/policy-edit.hbs @@ -0,0 +1,18 @@ + +{{unit "iot.unit.policy.edit"}} \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-edit/policy-edit.json b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-edit/policy-edit.json new file mode 100644 index 00000000..688e9398 --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-edit/policy-edit.json @@ -0,0 +1,3 @@ +{ + "version": "1.0.0" +} \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-view/policy-view.hbs b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-view/policy-view.hbs new file mode 100644 index 00000000..c2a4706b --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-view/policy-view.hbs @@ -0,0 +1,18 @@ + +{{unit "iot.unit.policy.view"}} \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-view/policy-view.json b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-view/policy-view.json new file mode 100644 index 00000000..688e9398 --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-view/policy-view.json @@ -0,0 +1,3 @@ +{ + "version": "1.0.0" +} \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-wizard/policy-wizard.hbs b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-wizard/policy-wizard.hbs new file mode 100644 index 00000000..7b94f953 --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-wizard/policy-wizard.hbs @@ -0,0 +1,18 @@ + +{{unit "iot.unit.policy.wizard"}} \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-wizard/policy-wizard.json b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-wizard/policy-wizard.json new file mode 100644 index 00000000..688e9398 --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.policy-wizard/policy-wizard.json @@ -0,0 +1,3 @@ +{ + "version": "1.0.0" +} \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/deviceType.png b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/deviceType.png new file mode 100644 index 0000000000000000000000000000000000000000..7c5808697e193b734c127fdf563f335ecd094bea GIT binary patch literal 28584 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 n9x@LG1!9c`wn52X|@D literal 0 HcmV?d00001 diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/schematicsGuide.png b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/images/schematicsGuide.png new file mode 100644 index 0000000000000000000000000000000000000000..db4d0adbb760dbff877884209c7f878083b1aa2f GIT binary patch literal 128984 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

(E+-BQ13%VTKFa^1 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 4) { + payload.deviceName = deviceName; + invokerUtil.post( + downloadDeviceAPI, + payload, + function (data, textStatus, jqxhr) { + doAction(data); + }, + function (data) { + doAction(data); + } + ); + } else if (deviceName) { + $('.controls').append(''); + $('.control-group').removeClass('success').addClass('error'); + } else { + $('.controls').append(''); + $('.control-group').removeClass('success').addClass('error'); + } + }); + + $("a#download-device-cancel-link").click(function () { + hidePopup(); + }); + + }); +} + +function downloadAgent() { + var deviceName = ""; + $('.new-device-name').each(function () { + if (this.value != "") { + deviceName = this.value; + } + }); + var deviceType = ""; + $('.deviceType').each(function () { + if (this.value != "") { + deviceType = this.value; + } + }); + var sketchType = ""; + $('.sketchType').each(function () { + if (this.value != "") { + sketchType = this.value; + } + }); + var deviceNameFormat = /^[^~?!#$:;%^*`+={}\[\]\\()|<>,'"]{1,30}$/; + if (deviceName && deviceNameFormat.test(deviceName)) { + $(modalPopupContent).html($('#device-agent-downloading-content').html()); + var successCallback = function (data) { + data = JSON.parse(data); + hidePopup(); + window.location = "/devicemgt/api/devices/sketch/download/" + data.responseContent; + }; + var generateLink = "/" + deviceType + "_mgt/manager/device/" + sketchType + + "/generate_link?deviceName=" + deviceName; + invokerUtil.get(generateLink, successCallback, function (message) { + console.log(message.content); + hidePopup(); + doAction(data); + }); + } else { + $("#invalid-username-error-msg span").text("Invalid device name"); + $("#invalid-username-error-msg").removeClass("hidden"); + } +} + +function doAction(data) { + //if it is saml redirection response + if (data.status == null) { + document.write(data); + } + + if (data.status == "401") { + $(modalPopupContent).html($('#device-401-content').html()); + $("#device-401-link").click(function () { + window.location = "/devicemgt/login"; + }); + showPopup(); + } else if (data == "403") { + $(modalPopupContent).html($('#device-403-content').html()); + $("#device-403-link").click(function () { + window.location = "/devicemgt/login"; + }); + showPopup(); + } else { + $(modalPopupContent).html($('#device-unexpected-error-content').html()); + $("a#device-unexpected-error-link").click(function () { + hidePopup(); + }); + } +} \ No newline at end of file diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/js/jquery.validate.js b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/js/jquery.validate.js new file mode 100644 index 00000000..ae92b49e --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/public/js/jquery.validate.js @@ -0,0 +1,1234 @@ +/* + * Copyright (c) 2016, 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 ($) { + + $.extend($.fn, { + // http://docs.jquery.com/Plugins/Validation/validate + validate: function (options) { + + // if nothing is selected, return nothing; can't chain anyway + if (!this.length) { + if (options && options.debug && window.console) { + console.warn("Nothing selected, can't validate, returning nothing."); + } + return; + } + + // check if a validator for this form was already created + var validator = $.data(this[0], "validator"); + if (validator) { + return validator; + } + + // Add novalidate tag if HTML5. + this.attr("novalidate", "novalidate"); + + validator = new $.validator(options, this[0]); + $.data(this[0], "validator", validator); + + if (validator.settings.onsubmit) { + + this.validateDelegate(":submit", "click", function (event) { + if (validator.settings.submitHandler) { + validator.submitButton = event.target; + } + // allow suppressing validation by adding a cancel class to the submit button + if ($(event.target).hasClass("cancel")) { + validator.cancelSubmit = true; + } + }); + + // validate the form on submit + this.submit(function (event) { + if (validator.settings.debug) { + // prevent form submit to be able to see console output + event.preventDefault(); + } + function handle() { + var hidden; + if (validator.settings.submitHandler) { + if (validator.submitButton) { + // insert a hidden input as a replacement for the missing submit button + hidden = $("").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm); + } + validator.settings.submitHandler.call(validator, validator.currentForm, event); + if (validator.submitButton) { + // and clean up afterwards; thanks to no-block-scope, hidden can be referenced + hidden.remove(); + } + return false; + } + return true; + } + + // prevent submit for invalid forms or custom submit handlers + if (validator.cancelSubmit) { + validator.cancelSubmit = false; + return handle(); + } + if (validator.form()) { + if (validator.pendingRequest) { + validator.formSubmitted = true; + return false; + } + return handle(); + } else { + validator.focusInvalid(); + return false; + } + }); + } + + return validator; + }, + // http://docs.jquery.com/Plugins/Validation/valid + valid: function () { + if ($(this[0]).is("form")) { + return this.validate().form(); + } else { + var valid = true; + var validator = $(this[0].form).validate(); + this.each(function () { + valid &= validator.element(this); + }); + return valid; + } + }, + // attributes: space seperated list of attributes to retrieve and remove + removeAttrs: function (attributes) { + var result = {}, + $element = this; + $.each(attributes.split(/\s/), function (index, value) { + result[value] = $element.attr(value); + $element.removeAttr(value); + }); + return result; + }, + // http://docs.jquery.com/Plugins/Validation/rules + rules: function (command, argument) { + var element = this[0]; + + if (command) { + var settings = $.data(element.form, "validator").settings; + var staticRules = settings.rules; + var existingRules = $.validator.staticRules(element); + switch (command) { + case "add": + $.extend(existingRules, $.validator.normalizeRule(argument)); + staticRules[element.name] = existingRules; + if (argument.messages) { + settings.messages[element.name] = $.extend(settings.messages[element.name], argument.messages); + } + break; + case "remove": + if (!argument) { + delete staticRules[element.name]; + return existingRules; + } + var filtered = {}; + $.each(argument.split(/\s/), function (index, method) { + filtered[method] = existingRules[method]; + delete existingRules[method]; + }); + return filtered; + } + } + + var data = $.validator.normalizeRules( + $.extend( + {}, + $.validator.classRules(element), + $.validator.attributeRules(element), + $.validator.dataRules(element), + $.validator.staticRules(element) + ), element); + + // make sure required is at front + if (data.required) { + var param = data.required; + delete data.required; + data = $.extend({required: param}, data); + } + + return data; + } + }); + +// Custom selectors + $.extend($.expr[":"], { + // http://docs.jquery.com/Plugins/Validation/blank + blank: function (a) { + return !$.trim("" + a.value); + }, + // http://docs.jquery.com/Plugins/Validation/filled + filled: function (a) { + return !!$.trim("" + a.value); + }, + // http://docs.jquery.com/Plugins/Validation/unchecked + unchecked: function (a) { + return !a.checked; + } + }); + +// constructor for validator + $.validator = function (options, form) { + this.settings = $.extend(true, {}, $.validator.defaults, options); + this.currentForm = form; + this.init(); + }; + + $.validator.format = function (source, params) { + if (arguments.length === 1) { + return function () { + var args = $.makeArray(arguments); + args.unshift(source); + return $.validator.format.apply(this, args); + }; + } + if (arguments.length > 2 && params.constructor !== Array) { + params = $.makeArray(arguments).slice(1); + } + if (params.constructor !== Array) { + params = [params]; + } + $.each(params, function (i, n) { + source = source.replace(new RegExp("\\{" + i + "\\}", "g"), function () { + return n; + }); + }); + return source; + }; + + $.extend($.validator, { + + defaults: { + messages: {}, + groups: {}, + rules: {}, + errorClass: "error", + validClass: "valid", + errorElement: "label", + focusInvalid: true, + errorContainer: $([]), + errorLabelContainer: $([]), + onsubmit: true, + ignore: ":hidden", + ignoreTitle: false, + onfocusin: function (element, event) { + this.lastActive = element; + + // hide error label and remove error class on focus if enabled + if (this.settings.focusCleanup && !this.blockFocusCleanup) { + if (this.settings.unhighlight) { + this.settings.unhighlight.call(this, element, this.settings.errorClass, this.settings.validClass); + } + this.addWrapper(this.errorsFor(element)).hide(); + } + }, + onfocusout: function (element, event) { + if (!this.checkable(element) && (element.name in this.submitted || !this.optional(element))) { + this.element(element); + } + }, + onkeyup: function (element, event) { + if (event.which === 9 && this.elementValue(element) === "") { + return; + } else if (element.name in this.submitted || element === this.lastElement) { + this.element(element); + } + }, + onclick: function (element, event) { + // click on selects, radiobuttons and checkboxes + if (element.name in this.submitted) { + this.element(element); + } + // or option elements, check parent select in that case + else if (element.parentNode.name in this.submitted) { + this.element(element.parentNode); + } + }, + highlight: function (element, errorClass, validClass) { + if (element.type === "radio") { + this.findByName(element.name).addClass(errorClass).removeClass(validClass); + } else { + $(element).addClass(errorClass).removeClass(validClass); + } + }, + unhighlight: function (element, errorClass, validClass) { + if (element.type === "radio") { + this.findByName(element.name).removeClass(errorClass).addClass(validClass); + } else { + $(element).removeClass(errorClass).addClass(validClass); + } + } + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults + setDefaults: function (settings) { + $.extend($.validator.defaults, settings); + }, + + messages: { + required: "This field is required.", + remote: "Please fix this field.", + email: "Please enter a valid email address.", + url: "Please enter a valid URL.", + date: "Please enter a valid date.", + dateISO: "Please enter a valid date (ISO).", + number: "Please enter a valid number.", + digits: "Please enter only digits.", + creditcard: "Please enter a valid credit card number.", + equalTo: "Please enter the same value again.", + maxlength: $.validator.format("Please enter no more than {0} characters."), + minlength: $.validator.format("Please enter at least {0} characters."), + rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."), + range: $.validator.format("Please enter a value between {0} and {1}."), + max: $.validator.format("Please enter a value less than or equal to {0}."), + min: $.validator.format("Please enter a value greater than or equal to {0}.") + }, + + autoCreateRanges: false, + + prototype: { + + init: function () { + this.labelContainer = $(this.settings.errorLabelContainer); + this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm); + this.containers = $(this.settings.errorContainer).add(this.settings.errorLabelContainer); + this.submitted = {}; + this.valueCache = {}; + this.pendingRequest = 0; + this.pending = {}; + this.invalid = {}; + this.reset(); + + var groups = (this.groups = {}); + $.each(this.settings.groups, function (key, value) { + if (typeof value === "string") { + value = value.split(/\s/); + } + $.each(value, function (index, name) { + groups[name] = key; + }); + }); + var rules = this.settings.rules; + $.each(rules, function (key, value) { + rules[key] = $.validator.normalizeRule(value); + }); + + function delegate(event) { + var validator = $.data(this[0].form, "validator"), + eventType = "on" + event.type.replace(/^validate/, ""); + if (validator.settings[eventType]) { + validator.settings[eventType].call(validator, this[0], event); + } + } + + $(this.currentForm) + .validateDelegate( ":text, [type='password'], [type='file'], select, textarea, " + + "[type='number'], [type='search'] ,[type='tel'], [type='url'], " + + "[type='email'], [type='datetime'], [type='date'], [type='month'], " + + "[type='week'], [type='time'], [type='datetime-local'], " + + "[type='range'], [type='color'] ", + "focusin focusout keyup", delegate) + .validateDelegate("[type='radio'], [type='checkbox'], select, option", "click", delegate); + + if (this.settings.invalidHandler) { + $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler); + } + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/form + form: function () { + this.checkForm(); + $.extend(this.submitted, this.errorMap); + this.invalid = $.extend({}, this.errorMap); + if (!this.valid()) { + $(this.currentForm).triggerHandler("invalid-form", [this]); + } + this.showErrors(); + return this.valid(); + }, + + checkForm: function () { + this.prepareForm(); + for (var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++) { + this.check(elements[i]); + } + return this.valid(); + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/element + element: function (element) { + element = this.validationTargetFor(this.clean(element)); + this.lastElement = element; + this.prepareElement(element); + this.currentElements = $(element); + var result = this.check(element) !== false; + if (result) { + delete this.invalid[element.name]; + } else { + this.invalid[element.name] = true; + } + if (!this.numberOfInvalids()) { + // Hide error containers on last error + this.toHide = this.toHide.add(this.containers); + } + this.showErrors(); + return result; + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/showErrors + showErrors: function (errors) { + if (errors) { + // add items to error list and map + $.extend(this.errorMap, errors); + this.errorList = []; + for (var name in errors) { + this.errorList.push({ + message: errors[name], + element: this.findByName(name)[0] + }); + } + // remove items from success list + this.successList = $.grep(this.successList, function (element) { + return !(element.name in errors); + }); + } + if (this.settings.showErrors) { + this.settings.showErrors.call(this, this.errorMap, this.errorList); + } else { + this.defaultShowErrors(); + } + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/resetForm + resetForm: function () { + if ($.fn.resetForm) { + $(this.currentForm).resetForm(); + } + this.submitted = {}; + this.lastElement = null; + this.prepareForm(); + this.hideErrors(); + this.elements().removeClass(this.settings.errorClass).removeData("previousValue"); + }, + + numberOfInvalids: function () { + return this.objectLength(this.invalid); + }, + + objectLength: function (obj) { + var count = 0; + for (var i in obj) { + count++; + } + return count; + }, + + hideErrors: function () { + this.addWrapper(this.toHide).hide(); + }, + + valid: function () { + return this.size() === 0; + }, + + size: function () { + return this.errorList.length; + }, + + focusInvalid: function () { + if (this.settings.focusInvalid) { + try { + $(this.findLastActive() || this.errorList.length && this.errorList[0].element || []) + .filter(":visible") + .focus() + // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find + .trigger("focusin"); + } catch (e) { + // ignore IE throwing errors when focusing hidden elements + } + } + }, + + findLastActive: function () { + var lastActive = this.lastActive; + return lastActive && $.grep(this.errorList, function (n) { + return n.element.name === lastActive.name; + }).length === 1 && lastActive; + }, + + elements: function () { + var validator = this, + rulesCache = {}; + + // select all valid inputs inside the form (no submit or reset buttons) + return $(this.currentForm) + .find("input, select, textarea") + .not(":submit, :reset, :image, [disabled]") + .not(this.settings.ignore) + .filter(function () { + if (!this.name) { + if (window.console) { + console.error("%o has no name assigned", this); + } + throw new Error("Failed to validate, found an element with no name assigned. See console for element reference."); + } + + // select only the first element for each name, and only those with rules specified + if (this.name in rulesCache || !validator.objectLength($(this).rules())) { + return false; + } + + rulesCache[this.name] = true; + return true; + }); + }, + + clean: function (selector) { + return $(selector)[0]; + }, + + errors: function () { + var errorClass = this.settings.errorClass.replace(" ", "."); + return $(this.settings.errorElement + "." + errorClass, this.errorContext); + }, + + reset: function () { + this.successList = []; + this.errorList = []; + this.errorMap = {}; + this.toShow = $([]); + this.toHide = $([]); + this.currentElements = $([]); + }, + + prepareForm: function () { + this.reset(); + this.toHide = this.errors().add(this.containers); + }, + + prepareElement: function (element) { + this.reset(); + this.toHide = this.errorsFor(element); + }, + + elementValue: function (element) { + var type = $(element).attr("type"), + val = $(element).val(); + + if (type === "radio" || type === "checkbox") { + return $("input[name='" + $(element).attr("name") + "']:checked").val(); + } + + if (typeof val === "string") { + return val.replace(/\r/g, ""); + } + return val; + }, + + check: function (element) { + element = this.validationTargetFor(this.clean(element)); + + var rules = $(element).rules(); + var dependencyMismatch = false; + var val = this.elementValue(element); + var result; + + for (var method in rules) { + var rule = {method: method, parameters: rules[method]}; + try { + + result = $.validator.methods[method].call(this, val, element, rule.parameters); + + // if a method indicates that the field is optional and therefore valid, + // don't mark it as valid when there are no other rules + if (result === "dependency-mismatch") { + dependencyMismatch = true; + continue; + } + dependencyMismatch = false; + + if (result === "pending") { + this.toHide = this.toHide.not(this.errorsFor(element)); + return; + } + + if (!result) { + this.formatAndAdd(element, rule); + return false; + } + } catch (e) { + if (this.settings.debug && window.console) { + console.log("Exception occured when checking element " + element.id + ", check the '" + rule.method + "' method.", e); + } + throw e; + } + } + if (dependencyMismatch) { + return; + } + if (this.objectLength(rules)) { + this.successList.push(element); + } + return true; + }, + + // return the custom message for the given element and validation method + // specified in the element's HTML5 data attribute + customDataMessage: function (element, method) { + return $(element).data("msg-" + method.toLowerCase()) || (element.attributes && $(element).attr("data-msg-" + method.toLowerCase())); + }, + + // return the custom message for the given element name and validation method + customMessage: function (name, method) { + var m = this.settings.messages[name]; + return m && (m.constructor === String ? m : m[method]); + }, + + // return the first defined argument, allowing empty strings + findDefined: function () { + for (var i = 0; i < arguments.length; i++) { + if (arguments[i] !== undefined) { + return arguments[i]; + } + } + return undefined; + }, + + defaultMessage: function (element, method) { + return this.findDefined( + this.customMessage(element.name, method), + this.customDataMessage(element, method), + // title is never undefined, so handle empty string as undefined + !this.settings.ignoreTitle && element.title || undefined, + $.validator.messages[method], + "Warning: No message defined for " + element.name + "" + ); + }, + + formatAndAdd: function (element, rule) { + var message = this.defaultMessage(element, rule.method), + theregex = /\$?\{(\d+)\}/g; + if (typeof message === "function") { + message = message.call(this, rule.parameters, element); + } else if (theregex.test(message)) { + message = $.validator.format(message.replace(theregex, "{$1}"), rule.parameters); + } + this.errorList.push({ + message: message, + element: element + }); + + this.errorMap[element.name] = message; + this.submitted[element.name] = message; + }, + + addWrapper: function (toToggle) { + if (this.settings.wrapper) { + toToggle = toToggle.add(toToggle.parent(this.settings.wrapper)); + } + return toToggle; + }, + + defaultShowErrors: function () { + var i, elements; + for (i = 0; this.errorList[i]; i++) { + var error = this.errorList[i]; + if (this.settings.highlight) { + this.settings.highlight.call(this, error.element, this.settings.errorClass, this.settings.validClass); + } + this.showLabel(error.element, error.message); + } + if (this.errorList.length) { + this.toShow = this.toShow.add(this.containers); + } + if (this.settings.success) { + for (i = 0; this.successList[i]; i++) { + this.showLabel(this.successList[i]); + } + } + if (this.settings.unhighlight) { + for (i = 0, elements = this.validElements(); elements[i]; i++) { + this.settings.unhighlight.call(this, elements[i], this.settings.errorClass, this.settings.validClass); + } + } + this.toHide = this.toHide.not(this.toShow); + this.hideErrors(); + this.addWrapper(this.toShow).show(); + }, + + validElements: function () { + return this.currentElements.not(this.invalidElements()); + }, + + invalidElements: function () { + return $(this.errorList).map(function () { + return this.element; + }); + }, + + showLabel: function (element, message) { + var label = this.errorsFor(element); + if (label.length) { + // refresh error/success class + label.removeClass(this.settings.validClass).addClass(this.settings.errorClass); + + // check if we have a generated label, replace the message then + if (label.attr("generated")) { + label.html(message); + } + } else { + // create label + label = $("<" + this.settings.errorElement + "/>") + .attr({"for": this.idOrName(element), generated: true}) + .addClass(this.settings.errorClass) + .html(message || ""); + if (this.settings.wrapper) { + // make sure the element is visible, even in IE + // actually showing the wrapped element is handled elsewhere + label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent(); + } + if (!this.labelContainer.append(label).length) { + if (this.settings.errorPlacement) { + this.settings.errorPlacement(label, $(element)); + } else { + label.insertAfter(element); + } + } + } + if (!message && this.settings.success) { + label.text(""); + if (typeof this.settings.success === "string") { + label.addClass(this.settings.success); + } else { + this.settings.success(label, element); + } + } + this.toShow = this.toShow.add(label); + }, + + errorsFor: function (element) { + var name = this.idOrName(element); + return this.errors().filter(function () { + return $(this).attr("for") === name; + }); + }, + + idOrName: function (element) { + return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name); + }, + + validationTargetFor: function (element) { + // if radio/checkbox, validate first element in group instead + if (this.checkable(element)) { + element = this.findByName(element.name).not(this.settings.ignore)[0]; + } + return element; + }, + + checkable: function (element) { + return (/radio|checkbox/i).test(element.type); + }, + + findByName: function (name) { + return $(this.currentForm).find("[name='" + name + "']"); + }, + + getLength: function (value, element) { + switch (element.nodeName.toLowerCase()) { + case "select": + return $("option:selected", element).length; + case "input": + if (this.checkable(element)) { + return this.findByName(element.name).filter(":checked").length; + } + } + return value.length; + }, + + depend: function (param, element) { + return this.dependTypes[typeof param] ? this.dependTypes[typeof param](param, element) : true; + }, + + dependTypes: { + "boolean": function (param, element) { + return param; + }, + "string": function (param, element) { + return !!$(param, element.form).length; + }, + "function": function (param, element) { + return param(element); + } + }, + + optional: function (element) { + var val = this.elementValue(element); + return !$.validator.methods.required.call(this, val, element) && "dependency-mismatch"; + }, + + startRequest: function (element) { + if (!this.pending[element.name]) { + this.pendingRequest++; + this.pending[element.name] = true; + } + }, + + stopRequest: function (element, valid) { + this.pendingRequest--; + // sometimes synchronization fails, make sure pendingRequest is never < 0 + if (this.pendingRequest < 0) { + this.pendingRequest = 0; + } + delete this.pending[element.name]; + if (valid && this.pendingRequest === 0 && this.formSubmitted && this.form()) { + $(this.currentForm).submit(); + this.formSubmitted = false; + } else if (!valid && this.pendingRequest === 0 && this.formSubmitted) { + $(this.currentForm).triggerHandler("invalid-form", [this]); + this.formSubmitted = false; + } + }, + + previousValue: function (element) { + return $.data(element, "previousValue") || $.data(element, "previousValue", { + old: null, + valid: true, + message: this.defaultMessage(element, "remote") + }); + } + + }, + + classRuleSettings: { + required: {required: true}, + email: {email: true}, + url: {url: true}, + date: {date: true}, + dateISO: {dateISO: true}, + number: {number: true}, + digits: {digits: true}, + creditcard: {creditcard: true} + }, + + addClassRules: function (className, rules) { + if (className.constructor === String) { + this.classRuleSettings[className] = rules; + } else { + $.extend(this.classRuleSettings, className); + } + }, + + classRules: function (element) { + var rules = {}; + var classes = $(element).attr("class"); + if (classes) { + $.each(classes.split(" "), function () { + if (this in $.validator.classRuleSettings) { + $.extend(rules, $.validator.classRuleSettings[this]); + } + }); + } + return rules; + }, + + attributeRules: function (element) { + var rules = {}; + var $element = $(element); + + for (var method in $.validator.methods) { + var value; + + // support for in both html5 and older browsers + if (method === "required") { + value = $element.get(0).getAttribute(method); + // Some browsers return an empty string for the required attribute + // and non-HTML5 browsers might have required="" markup + if (value === "") { + value = true; + } + // force non-HTML5 browsers to return bool + value = !!value; + } else { + value = $element.attr(method); + } + + if (value) { + rules[method] = value; + } else if ($element[0].getAttribute("type") === method) { + rules[method] = true; + } + } + + // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs + if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) { + delete rules.maxlength; + } + + return rules; + }, + + dataRules: function (element) { + var method, value, + rules = {}, $element = $(element); + for (method in $.validator.methods) { + value = $element.data("rule-" + method.toLowerCase()); + if (value !== undefined) { + rules[method] = value; + } + } + return rules; + }, + + staticRules: function (element) { + var rules = {}; + var validator = $.data(element.form, "validator"); + if (validator.settings.rules) { + rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {}; + } + return rules; + }, + + normalizeRules: function (rules, element) { + // handle dependency check + $.each(rules, function (prop, val) { + // ignore rule when param is explicitly false, eg. required:false + if (val === false) { + delete rules[prop]; + return; + } + if (val.param || val.depends) { + var keepRule = true; + switch (typeof val.depends) { + case "string": + keepRule = !!$(val.depends, element.form).length; + break; + case "function": + keepRule = val.depends.call(element, element); + break; + } + if (keepRule) { + rules[prop] = val.param !== undefined ? val.param : true; + } else { + delete rules[prop]; + } + } + }); + + // evaluate parameters + $.each(rules, function (rule, parameter) { + rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter; + }); + + // clean number parameters + $.each(["minlength", "maxlength", "min", "max"], function () { + if (rules[this]) { + rules[this] = Number(rules[this]); + } + }); + $.each(["rangelength", "range"], function () { + var parts; + if (rules[this]) { + if ($.isArray(rules[this])) { + rules[this] = [Number(rules[this][0]), Number(rules[this][1])]; + } else if (typeof rules[this] === "string") { + parts = rules[this].split(/[\s,]+/); + rules[this] = [Number(parts[0]), Number(parts[1])]; + } + } + }); + + if ($.validator.autoCreateRanges) { + // auto-create ranges + if (rules.min && rules.max) { + rules.range = [rules.min, rules.max]; + delete rules.min; + delete rules.max; + } + if (rules.minlength && rules.maxlength) { + rules.rangelength = [rules.minlength, rules.maxlength]; + delete rules.minlength; + delete rules.maxlength; + } + } + + return rules; + }, + + // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true} + normalizeRule: function (data) { + if (typeof data === "string") { + var transformed = {}; + $.each(data.split(/\s/), function () { + transformed[this] = true; + }); + data = transformed; + } + return data; + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/addMethod + addMethod: function (name, method, message) { + $.validator.methods[name] = method; + $.validator.messages[name] = message !== undefined ? message : $.validator.messages[name]; + if (method.length < 3) { + $.validator.addClassRules(name, $.validator.normalizeRule(name)); + } + }, + + methods: { + + // http://docs.jquery.com/Plugins/Validation/Methods/required + required: function (value, element, param) { + // check if dependency is met + if (!this.depend(param, element)) { + return "dependency-mismatch"; + } + if (element.nodeName.toLowerCase() === "select") { + // could be an array for select-multiple or a string, both are fine this way + var val = $(element).val(); + return val && val.length > 0; + } + if (this.checkable(element)) { + return this.getLength(value, element) > 0; + } + return $.trim(value).length > 0; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/remote + remote: function (value, element, param) { + if (this.optional(element)) { + return "dependency-mismatch"; + } + + var previous = this.previousValue(element); + if (!this.settings.messages[element.name]) { + this.settings.messages[element.name] = {}; + } + previous.originalMessage = this.settings.messages[element.name].remote; + this.settings.messages[element.name].remote = previous.message; + + param = typeof param === "string" && {url: param} || param; + + if (previous.old === value) { + return previous.valid; + } + + previous.old = value; + var validator = this; + this.startRequest(element); + var data = {}; + data[element.name] = value; + $.ajax($.extend(true, { + url: param, + mode: "abort", + port: "validate" + element.name, + dataType: "json", + data: data, + success: function (response) { + validator.settings.messages[element.name].remote = previous.originalMessage; + var valid = response === true || response === "true"; + if (valid) { + var submitted = validator.formSubmitted; + validator.prepareElement(element); + validator.formSubmitted = submitted; + validator.successList.push(element); + delete validator.invalid[element.name]; + validator.showErrors(); + } else { + var errors = {}; + var message = response || validator.defaultMessage(element, "remote"); + errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message; + validator.invalid[element.name] = true; + validator.showErrors(errors); + } + previous.valid = valid; + validator.stopRequest(element, valid); + } + }, param)); + return "pending"; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/minlength + minlength: function (value, element, param) { + var length = $.isArray(value) ? value.length : this.getLength($.trim(value), element); + return this.optional(element) || length >= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/maxlength + maxlength: function (value, element, param) { + var length = $.isArray(value) ? value.length : this.getLength($.trim(value), element); + return this.optional(element) || length <= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/rangelength + rangelength: function (value, element, param) { + var length = $.isArray(value) ? value.length : this.getLength($.trim(value), element); + return this.optional(element) || ( length >= param[0] && length <= param[1] ); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/min + min: function (value, element, param) { + return this.optional(element) || value >= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/max + max: function (value, element, param) { + return this.optional(element) || value <= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/range + range: function (value, element, param) { + return this.optional(element) || ( value >= param[0] && value <= param[1] ); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/email + email: function (value, element) { + // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/ + return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))$/i.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/url + url: function (value, element) { + // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/ + return this.optional(element) || /^(https?|s?ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/date + date: function (value, element) { + return this.optional(element) || !/Invalid|NaN/.test(new Date(value).toString()); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/dateISO + dateISO: function (value, element) { + return this.optional(element) || /^\d{4}[\/\-]\d{1,2}[\/\-]\d{1,2}$/.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/number + number: function (value, element) { + return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/digits + digits: function (value, element) { + return this.optional(element) || /^\d+$/.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/creditcard + // based on http://en.wikipedia.org/wiki/Luhn + creditcard: function (value, element) { + if (this.optional(element)) { + return "dependency-mismatch"; + } + // accept only spaces, digits and dashes + if (/[^0-9 \-]+/.test(value)) { + return false; + } + var nCheck = 0, + nDigit = 0, + bEven = false; + + value = value.replace(/\D/g, ""); + + for (var n = value.length - 1; n >= 0; n--) { + var cDigit = value.charAt(n); + nDigit = parseInt(cDigit, 10); + if (bEven) { + if ((nDigit *= 2) > 9) { + nDigit -= 9; + } + } + nCheck += nDigit; + bEven = !bEven; + } + + return (nCheck % 10) === 0; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/equalTo + equalTo: function (value, element, param) { + // bind to the blur event of the target in order to revalidate whenever the target field is updated + // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead + var target = $(param); + if (this.settings.onfocusout) { + target.unbind(".validate-equalTo").bind("blur.validate-equalTo", function () { + $(element).valid(); + }); + } + return value === target.val(); + } + + } + + }); + +// deprecated, use $.validator.format instead + $.format = $.validator.format; + +}(jQuery)); + +// ajax mode: abort +// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); +// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() +(function ($) { + var pendingRequests = {}; + // Use a prefilter if available (1.5+) + if ($.ajaxPrefilter) { + $.ajaxPrefilter(function (settings, _, xhr) { + var port = settings.port; + if (settings.mode === "abort") { + if (pendingRequests[port]) { + pendingRequests[port].abort(); + } + pendingRequests[port] = xhr; + } + }); + } else { + // Proxy ajax + var ajax = $.ajax; + $.ajax = function (settings) { + var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode, + port = ( "port" in settings ? settings : $.ajaxSettings ).port; + if (mode === "abort") { + if (pendingRequests[port]) { + pendingRequests[port].abort(); + } + return (pendingRequests[port] = ajax.apply(this, arguments)); + } + return ajax.apply(this, arguments); + }; + } +}(jQuery)); + +// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation +// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target +(function ($) { + $.extend($.fn, { + validateDelegate: function (delegate, type, handler) { + return this.bind(type, function (event) { + var target = $(event.target); + if (target.is(delegate)) { + return handler.apply(target, arguments); + } + }); + } + }); +}(jQuery)); diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/type-view.hbs b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/type-view.hbs new file mode 100644 index 00000000..8299b21e --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/type-view.hbs @@ -0,0 +1,378 @@ +

+ +
+ +
+ +
+ +

What it Does

+
+

Connect your Fire Alarm to WSO2 IoT Server.

+
+

An ESP8266 based fire alarm device. Once run, the Fire alarm will connect to WSO2 IoTServer + and push Temperature and Humidity readings via MQTT. You can also on/off fire alarm buzzer + remotely with IoTServer. +

+
+

What You Need

+
+
+
+ View API
  + Download + Agent + +
+ +
+ +
+ +
+ + + +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +
+ +

+
+ +
+

Prepare

+
+
    +
  • + 01 +    Connect USB to TTL converter and other component with ESP8266 201 + module + as schematic in FIRE ALARM SETUP. +
  • +
  • + 02 +    Download Agent files from [Download Agent] link above. +
  • +
  • + 03 +    Unzip the downloaded Fire Alarm Agent +
  • +
  • + 04 +    Open wifi-connect.lua and provide appropriate values for + [SSID] and + [Password] + variables according to your network. +
  • +
  • + 05 +    Upload all .lua files to ESP8266 using ESPlorer in following order. + Then restart the ESP8266. +
    +                + + + + +    dht_lib.lua +
    +                + + + + +    wifi-connect.lua +
    +                + + + + +    read-sensor.lua +
    +                + + + + +    init.lua +

    +
  • +
  • + 06 +    Now you can remove USB to TTL module and fix fire alarm device in any + place you want. +

    +                + + + + +    ESP8266 will publish temperature and humidity from DHT11 to + WSO2-IoT-Server +

    +                + + + + +    Buzzer can be controlled from Device Management page. +
  • +
+
+
+ +
+

Fire alarm Setup

+
+

Click on the image to zoom

+
+ + + +
+
+
+ +
+

Try Out

+
+
    +
  • 01   You can view + all your connected + devices at [Device + Management] + page. +
  • +
  • 02   Select one of + connected devices and check for + available control operations. +
  • +
+
+ +
+ + + +{{#zone "bottomJs"}} + {{js "/js/download.js"}} + {{js "/js/jquery.validate.js"}} +{{/zone}} + diff --git a/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/type-view.json b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/type-view.json new file mode 100644 index 00000000..688e9398 --- /dev/null +++ b/modules/samples/firealarm/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.firealarm.type-view/type-view.json @@ -0,0 +1,3 @@ +{ + "version": "1.0.0" +} \ No newline at end of file diff --git a/modules/samples/firealarm/feature/feature/pom.xml b/modules/samples/firealarm/feature/feature/pom.xml new file mode 100644 index 00000000..aa60607d --- /dev/null +++ b/modules/samples/firealarm/feature/feature/pom.xml @@ -0,0 +1,244 @@ + + + + + + + org.homeautomation + firealarm-feature + 1.0.0-SNAPSHOT + ../pom.xml + + 4.0.0 + 1.0.0-SNAPSHOT + ${groupId}.firealarm.feature + pom + ${project.artifactId} + http://wso2.org + + + org.homeautomation + ${project-base-package}.plugin + 1.0.0-SNAPSHOT + + + org.homeautomation + ${project-base-package}.manager + 1.0.0-SNAPSHOT + war + + + org.homeautomation + ${project-base-package}.controller + 1.0.0-SNAPSHOT + war + + + com.h2database.wso2 + h2-database-engine + 1.2.140.wso2v3 + + + + + + maven-resources-plugin + + + copy-resources + generate-resources + + copy-resources + + + src/main/resources + + + resources + + build.properties + p2.inf + + + + + + + + + org.apache.maven.plugins + maven-dependency-plugin + + + unpack + package + + unpack + + + + + org.homeautomation + ${project-base-package}.analytics + 1.0.0-SNAPSHOT + zip + true + + ${project.build.directory}/maven-shared-archive-resources/carbonapps + + **/* + + + org.homeautomation + ${project-base-package}.ui + + ${project.version} + zip + true + + ${project.build.directory}/maven-shared-archive-resources/jaggeryapps + + **/* + + + + + + copy-jaxrs-manager-war + package + + copy + + + + + org.homeautomation + ${project-base-package}.manager + war + true + + + ${project.build.directory}/maven-shared-archive-resources/webapps/ + + firealarm_mgt.war + + + + + + copy-jaxrs-controller-war + package + + copy + + + + + org.homeautomation + ${project-base-package}.controller + war + true + + + ${project.build.directory}/maven-shared-archive-resources/webapps/ + + firealarm.war + + + + + + + + org.apache.maven.plugins + maven-antrun-plugin + ${maven-antrun-plugin.version} + + + create-firealarm-plugin-mgt-schema + package + + run + + + + + + + + + + + + + + + + + + + + + org.wso2.maven + carbon-p2-plugin + + + p2-feature-generation + package + + p2-feature-gen + + + ${project-base-package} + ../../../features/etc/feature.properties + + + + org.wso2.carbon.p2.category.type:server + + org.eclipse.equinox.p2.type.group:false + + + + + + org.homeautomation:${project-base-package}.plugin:1.0.0-SNAPSHOT + + + + + org.wso2.carbon.core.server:${carbon.kernel.version} + + + org.wso2.carbon.device.mgt.server:${carbon.device.mgt.version} + + + + + + + + + diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/agent/dht_lib.lua b/modules/samples/firealarm/feature/feature/src/main/resources/agent/dht_lib.lua new file mode 100644 index 00000000..643cd05d --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/agent/dht_lib.lua @@ -0,0 +1,65 @@ +local dht_lib = {} + +local humidity +local temperature + +local bitStream = {} + +function dht_lib.read(pin) + for j = 1, 40, 1 do + bitStream[j]=0 + end + bitlength=0 + + gpio.mode(pin, gpio.OUTPUT) + gpio.write(pin, gpio.LOW) + tmr.delay(20000) + + gpio_read=gpio.read + gpio_write=gpio.write + + gpio.mode(pin, gpio.INPUT) + + while (gpio_read(pin)==0 ) do end + + c=0 + while (gpio_read(pin)==1 and c<100) do c=c+1 end + + while (gpio_read(pin)==0 ) do end + + c=0 + while (gpio_read(pin)==1 and c<100) do c=c+1 end + + for j = 1, 40, 1 do + while (gpio_read(pin)==1 and bitlength<10 ) do + bitlength=bitlength+1 + end + bitStream[j]=bitlength + bitlength=0 + while (gpio_read(pin)==0) do end + end + + humidity = 0 + temperature = 0 + + for i = 1, 8, 1 do + if (bitStream[i+0] > 2) then + humidity = humidity+2^(8-i) + end + end + for i = 1, 8, 1 do + if (bitStream[i+16] > 2) then + temperature = temperature+2^(8-i) + end + end +end + +function dht_lib.getTemperature() + return temperature +end + +function dht_lib.getHumidity() + return humidity +end + +return dht_lib diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/agent/init.lua b/modules/samples/firealarm/feature/feature/src/main/resources/agent/init.lua new file mode 100644 index 00000000..31ece4ba --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/agent/init.lua @@ -0,0 +1,4 @@ +tmr.alarm(0,1000,0,function() + dofile("wifi-connect.lua"); + dofile("read-sensor.lua"); +end) diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/agent/read-sensor.lua b/modules/samples/firealarm/feature/feature/src/main/resources/agent/read-sensor.lua new file mode 100644 index 00000000..99727b9e --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/agent/read-sensor.lua @@ -0,0 +1,74 @@ +DHT= require("dht_lib") + +dht_data = 2 +buzzer = 1 +gpio.mode(buzzer, gpio.OUTPUT) +client_connected = false +m = mqtt.Client("ESP8266-"..node.chipid(), 120, "", "") + +tmr.alarm(0,10000,1,function() + DHT.read(dht_data) + + t = DHT.getTemperature() + h = DHT.getHumidity() + + if t == nil then + print("Error reading from DHTxx") + else + if (client_connected) then + m:publish("wso2/iot/${DEVICE_OWNER}/firealarm/${DEVICE_ID}/publisher", "Temperature:"..t..":Humidity:"..h, 0, 0, function(client) + print("Published> Temperature: "..t.."C Humidity: "..h.."%") + end) + else + connectMQTTClient() + end + end +end) + +function connectMQTTClient() + ip = wifi.sta.getip() + if ip == nil then + print("Waiting for network") + else + print("Client IP: "..ip) + print("Trying to connect MQTT client") + m:connect("${SERVER_IP}", 1883, 0, function(client) + client_connected = true + print("MQTT client connected") + subscribeToMQTTQueue() + end) + end +end + +function subscribeToMQTTQueue() + m:subscribe("wso2/iot/${DEVICE_OWNER}/firealarm/${DEVICE_ID}/subscriber", 0, function(client, topic, message) + print("Subscribed to MQTT Queue") + end) + m:on("message", function(client, topic, message) + print("MQTT message received") + print(message) + buzz(message == "buzzer:ON") + end) + m:on("offline", function(client) + print("Disconnected") + client_connected = false + end) +end + +function buzz(status) + buzzerOn=true + if (status) then + tmr.alarm(1,500,1,function() + if buzzerOn then + buzzerOn=false + gpio.write(buzzer, gpio.HIGH) + else + buzzerOn=true + gpio.write(buzzer, gpio.LOW) + end + end) + else + tmr.stop(1) + gpio.write(buzzer, gpio.LOW) + end +end \ No newline at end of file diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/agent/sketch.properties b/modules/samples/firealarm/feature/feature/src/main/resources/agent/sketch.properties new file mode 100644 index 00000000..5485808b --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/agent/sketch.properties @@ -0,0 +1,16 @@ +#/* +# * Copyright (c) 2016, 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. +# */ +templates=read-sensor.lua +zipfilename=firealarm.zip diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/agent/wifi-connect.lua b/modules/samples/firealarm/feature/feature/src/main/resources/agent/wifi-connect.lua new file mode 100644 index 00000000..1c4498b9 --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/agent/wifi-connect.lua @@ -0,0 +1,2 @@ +wifi.setmode(wifi.STATION) +wifi.sta.config("SSID","Password") \ No newline at end of file diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/build.properties b/modules/samples/firealarm/feature/feature/src/main/resources/build.properties new file mode 100644 index 00000000..a7e289bc --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/build.properties @@ -0,0 +1,18 @@ +# +custom = true diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/configs/firealarm.json b/modules/samples/firealarm/feature/feature/src/main/resources/configs/firealarm.json new file mode 100644 index 00000000..b627d223 --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/configs/firealarm.json @@ -0,0 +1,54 @@ +{ + "deviceType": { + "label": "Fire Alarm", + "category": "iot" + }, + "analyticStreams": [ + { + "name": "Temperature", + "table": "DEVICE_TEMPERATURE_SUMMARY", + "ui_unit": { + "name": "cdmf.unit.analytics.line-chart", + "data": [ + { + "column": { + "name": "TIME", + "label": "time", + "ui-mapping": "x-axis" + } + }, + { + "column": { + "name": "TEMPERATURE", + "label": "Temperature", + "ui-mapping": "y-axis" + } + } + ] + } + }, + { + "name": "Humidity", + "table": "DEVICE_HUMIDITY_SUMMARY", + "ui_unit": { + "name": "cdmf.unit.analytics.line-chart", + "data": [ + { + "column": { + "name": "TIME", + "label": "time", + "ui-mapping": "x-axis" + } + }, + { + "column": { + "name": "HUMIDITY", + "label": "Humidity", + "ui-mapping": "y-axis" + } + } + ] + } + } + ] +} \ No newline at end of file diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/configs/firealarm.xml b/modules/samples/firealarm/feature/feature/src/main/resources/configs/firealarm.xml new file mode 100644 index 00000000..b505b3ff --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/configs/firealarm.xml @@ -0,0 +1,25 @@ + + + + + + + jdbc/firealarmDM_DB + + diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/datasources/firealarm-datasources.xml b/modules/samples/firealarm/feature/feature/src/main/resources/datasources/firealarm-datasources.xml new file mode 100644 index 00000000..7d219601 --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/datasources/firealarm-datasources.xml @@ -0,0 +1,48 @@ + + + + + + + org.wso2.carbon.ndatasource.rdbms.RDBMSDataSourceReader + + + + firealarmDM_DB + The datasource used for the this device type + + jdbc/firealarmDM_DB + + + + jdbc:h2:repository/database/firealarmDM_DB;DB_CLOSE_ON_EXIT=FALSE + + wso2carbon + wso2carbon + org.h2.Driver + 50 + 60000 + true + SELECT 1 + 30000 + + + + + diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/dbscripts/h2.sql b/modules/samples/firealarm/feature/feature/src/main/resources/dbscripts/h2.sql new file mode 100644 index 00000000..df4b2214 --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/dbscripts/h2.sql @@ -0,0 +1,13 @@ + +-- ----------------------------------------------------- +-- Agent Database +-- ----------------------------------------------------- +CREATE TABLE IF NOT EXISTS `firealarm_DEVICE` ( + `firealarm_DEVICE_ID` VARCHAR(45) NOT NULL , + `DEVICE_NAME` VARCHAR(100) NULL DEFAULT NULL, + `ACCESS_TOKEN` VARCHAR(50) NOT NULL, + `REFRESH_TOKEN` VARCHAR(50) NOT NULL, + PRIMARY KEY (`firealarm_DEVICE_ID`) ); + + + diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/dbscripts/mysql.sql b/modules/samples/firealarm/feature/feature/src/main/resources/dbscripts/mysql.sql new file mode 100644 index 00000000..344812ba --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/dbscripts/mysql.sql @@ -0,0 +1,12 @@ + +CREATE TABLE IF NOT EXISTS `firealarm_DEVICE` ( + `firealarm_DEVICE_ID` VARCHAR(45) NOT NULL , + `DEVICE_NAME` VARCHAR(100) NULL DEFAULT NULL, + `ACCESS_TOKEN` VARCHAR(50) NOT NULL, + `REFRESH_TOKEN` VARCHAR(50) NOT NULL, + PRIMARY KEY (`firealarm_DEVICE_ID`) ) +ENGINE = InnoDB; + + + + diff --git a/modules/samples/firealarm/feature/feature/src/main/resources/p2.inf b/modules/samples/firealarm/feature/feature/src/main/resources/p2.inf new file mode 100644 index 00000000..f747e63a --- /dev/null +++ b/modules/samples/firealarm/feature/feature/src/main/resources/p2.inf @@ -0,0 +1,16 @@ +instructions.configure = \ +org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../conf/device-types/);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.homeautomation.firealarm_${feature.version}/configs/,target:${installFolder}/../../conf/device-types/,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/webapps/);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.homeautomation.firealarm_${feature.version}/webapps/,target:${installFolder}/../../deployment/server/webapps/,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../resources/sketches/);\ +org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../resources/sketches/firealarm/);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.homeautomation.firealarm_${feature.version}/agent/,target:${installFolder}/../../resources/sketches/firealarm/,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.homeautomation.firealarm_${feature.version}/dbscripts/,target:${installFolder}/../../../dbscripts/cdm/plugins/firealarm,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.homeautomation.firealarm_${feature.version}/datasources/,target:${installFolder}/../../conf/datasources/,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/jaggeryapps/);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.homeautomation.firealarm_${feature.version}/jaggeryapps/,target:${installFolder}/../../deployment/server/jaggeryapps/,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../database/);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.homeautomation.firealarm_${feature.version}/database/,target:${installFolder}/../../database/,overwrite:true);\ +org.eclipse.equinox.p2.touchpoint.natives.mkdir(path:${installFolder}/../../deployment/server/carbonapps/);\ +org.eclipse.equinox.p2.touchpoint.natives.copy(source:${installFolder}/../features/org.homeautomation.firealarm_${feature.version}/carbonapps/,target:${installFolder}/../../deployment/server/carbonapps/,overwrite:true);\ diff --git a/modules/samples/firealarm/feature/pom.xml b/modules/samples/firealarm/feature/pom.xml new file mode 100644 index 00000000..86265530 --- /dev/null +++ b/modules/samples/firealarm/feature/pom.xml @@ -0,0 +1,37 @@ + + + + + + + org.homeautomation + firealarm + 1.0.0-SNAPSHOT + ../pom.xml + + firealarm-feature + 4.0.0 + pom + 1.0.0-SNAPSHOT + + feature + + \ No newline at end of file diff --git a/modules/samples/firealarm/pom.xml b/modules/samples/firealarm/pom.xml new file mode 100644 index 00000000..4d5c36dd --- /dev/null +++ b/modules/samples/firealarm/pom.xml @@ -0,0 +1,257 @@ + + + + + + + org.wso2 + wso2 + 1 + + org.homeautomation + firealarm + 1.0.0-SNAPSHOT + pom + 4.0.0 + http://wso2.com + + component + feature + + + + + org.eclipse.osgi + org.eclipse.osgi + ${eclipse.osgi.version} + provided + + + org.eclipse.equinox + org.eclipse.equinox.common + ${eclipse.equinox.common.version} + provided + + + org.testng + testng + ${testng.version} + + + junit + junit + + + org.beanshell + bsh + + + org.yaml + snakeyaml + + + provided + + + org.eclipse.osgi + org.eclipse.osgi.services + 3.3.100.v20120522-1822 + provided + + + org.wso2.carbon + org.wso2.carbon.logging + ${carbon.kernel.version} + + + org.apache.log4j.wso2 + log4j + + + commons-logging + commons-logging + + + org.wso2.carbon + org.wso2.carbon.bootstrap + + + provided + + + + org.apache.cxf + cxf-rt-frontend-jaxws + ${cxf.version} + provided + + + org.apache.cxf + cxf-rt-frontend-jaxrs + ${cxf.version} + provided + + + org.apache.cxf + cxf-rt-transports-http + ${cxf.version} + provided + + + org.eclipse.paho + org.eclipse.paho.client.mqttv3 + ${paho.mqtt.version} + provided + + + org.codehaus.jackson + jackson-core-asl + ${jackson.version} + + + org.codehaus.jackson + jackson-jaxrs + ${jackson.version} + + + javax + javaee-web-api + 6.0 + provided + + + javax.ws.rs + jsr311-api + ${javax.ws.rs.version} + provided + + + org.apache.httpcomponents + httpasyncclient + 4.1 + provided + + + + + + wso2.releases + WSO2 internal Repository + http://maven.wso2.org/nexus/content/repositories/releases/ + + true + daily + ignore + + + + wso2.snapshots + Apache Snapshot Repository + http://maven.wso2.org/nexus/content/repositories/snapshots/ + + true + daily + + + false + + + + wso2-nexus + WSO2 internal Repository + http://maven.wso2.org/nexus/content/groups/wso2-public/ + + true + daily + ignore + + + + + + wso2-nexus + WSO2 internal Repository + http://maven.wso2.org/nexus/content/groups/wso2-public/ + + true + daily + ignore + + + + wso2.releases + WSO2 internal Repository + http://maven.wso2.org/nexus/content/repositories/releases/ + + true + daily + ignore + + + + wso2.snapshots + WSO2 Snapshot Repository + http://maven.wso2.org/nexus/content/repositories/snapshots/ + + true + daily + + + false + + + + gcm-server-repository + GCM Server repository - GitHub + https://github.com/slorber/gcm-server-repository/raw/master/releases/ + + + + 4.4.3 + 1.1.0-SNAPSHOT + 1.1.0.SNAPSHOT + 1.0.2 + 3.0.0.wso2v1 + 3.8.1.v20120830-144521 + 2.0.4-SNAPSHOT + 2.0.4.SNAPSHOT + 1.1.1 + 2.4 + + 3.0.4.wso2v1 + 3.0.4.wso2v1 + 2.6.1 + 1.9.0 + 3.1.0.wso2v2 + 3.6.100.v20120522-1841 + 1.7 + 1.7 + org.homeautomation.firealarm + 3.8.1 + 1.4.0 + 2.4.1 + 2.3.2 + 2.6 + 1.8 + 1.7.2 + 2.5.5 + + \ No newline at end of file diff --git a/modules/samples/installer/device-deployer.xml b/modules/samples/installer/device-deployer.xml index efb3575e..4a437faa 100644 --- a/modules/samples/installer/device-deployer.xml +++ b/modules/samples/installer/device-deployer.xml @@ -35,6 +35,7 @@ samples/connectedcup samples/currentsensor + samples/firealarm @@ -64,6 +65,9 @@ org.homeautomation:org.homeautomation.currentsensor.feature:2.0.4-SNAPSHOT + + org.homeautomation:org.homeautomation.firealarm.feature:1.0.0-SNAPSHOT + @@ -97,6 +101,10 @@ org.homeautomation.currentsensor.feature.group 2.0.4-SNAPSHOT + + org.homeautomation.firealarm.feature.group + 1.0.0-SNAPSHOT + From 745d2369d34eed18106a42d6ba21bd89fefd80ef Mon Sep 17 00:00:00 2001 From: Shabirmean Date: Mon, 7 Mar 2016 09:09:02 +0530 Subject: [PATCH 09/12] Added portal app specific analytics changes and IoT-Gadget samples --- .../portal/controllers/apis/analytics.jag | 380 + .../portal/js/outputAdapterUiLibrary.js | 286 + .../css/bootstrap.min.css | 717 + .../css/d3.geomap.css | 29 + .../IoTServerTemperatureStats/css/igviz.css | 80 + .../IoTServerTemperatureStats/gadget.json | 1 + .../IoTServerTemperatureStats/index.xml | 57 + .../js/VizGrammar.min.js | 16 + .../IoTServerTemperatureStats/js/d3.min.js | 5 + .../js/excanvas.min.js | 48 + .../js/gadgetconf.js | 24 + .../IoTServerTemperatureStats/js/jquery.js | 9472 +++++++ .../IoTServerTemperatureStats/js/main.js | 568 + .../js/moment.min.js | 7 + .../js/outputAdapterUiLibrary.js | 286 + .../IoTServerTemperatureStats/js/topojson.js | 534 + .../IoTServerTemperatureStats/js/vega.js | 20654 ++++++++++++++++ .../TemperatureChart/css/bootstrap.min.css | 717 + .../gadget/TemperatureChart/css/d3.geomap.css | 29 + .../gadget/TemperatureChart/css/igviz.css | 80 + .../gadget/TemperatureChart/gadget.json | 9 + .../gadget/TemperatureChart/index.xml | 57 + .../TemperatureChart/js/VizGrammar.min.js | 16 + .../gadget/TemperatureChart/js/d3.min.js | 5 + .../TemperatureChart/js/excanvas.min.js | 48 + .../gadget/TemperatureChart/js/gadgetconf.js | 22 + .../gadget/TemperatureChart/js/jquery.js | 9472 +++++++ .../gadget/TemperatureChart/js/main.js | 568 + .../js/outputAdapterUiLibrary.js | 285 + .../gadget/TemperatureChart/js/topojson.js | 534 + .../gadget/TemperatureChart/js/vega.js | 20654 ++++++++++++++++ .../igviz/js/outputAdapterUiLibrary.js | 286 + 32 files changed, 65946 insertions(+) create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/controllers/apis/analytics.jag create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/js/outputAdapterUiLibrary.js create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/css/bootstrap.min.css create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/css/d3.geomap.css create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/css/igviz.css create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/gadget.json create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/index.xml create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/VizGrammar.min.js create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/d3.min.js create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/excanvas.min.js create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/gadgetconf.js create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/jquery.js create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/main.js create mode 100755 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/moment.min.js create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/outputAdapterUiLibrary.js create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/topojson.js create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/vega.js create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/css/bootstrap.min.css create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/css/d3.geomap.css create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/css/igviz.css create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/gadget.json create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/index.xml create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/VizGrammar.min.js create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/d3.min.js create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/excanvas.min.js create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/gadgetconf.js create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/jquery.js create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/main.js create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/outputAdapterUiLibrary.js create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/topojson.js create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/vega.js create mode 100644 modules/distribution/src/repository/jaggeryapps/portal/templates/gadgets/igviz/js/outputAdapterUiLibrary.js diff --git a/modules/distribution/src/repository/jaggeryapps/portal/controllers/apis/analytics.jag b/modules/distribution/src/repository/jaggeryapps/portal/controllers/apis/analytics.jag new file mode 100644 index 00000000..d1e90465 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/controllers/apis/analytics.jag @@ -0,0 +1,380 @@ +<% +(function () { + var TYPE = "type"; + var TABLE_NAME = "tableName"; + var TIME_FROM = "timeFrom"; + var TIME_TO = "timeTo"; + var START = "start"; + var COUNT = "count"; + var FILTER = "filter"; + var QUERY = "query"; + var SORT_SCORE_VALUE = "scoreFunc"; + var RECORDSTORE_NAME = "recordStore"; + var HTTPS_TRANSPORT = "https"; + var CONTENT_TYPE_JSON = "application/json"; + var AUTHORIZATION_HEADER = "Authorization"; + var USER_TOKEN = "user"; + var USERNAME = "username"; + var WAIT_TIME = "waitTime"; + var LOCALHOST = "localhost"; + var HTTP_USER_NOT_AUTHENTICATED = 403; + var HTTP_INTERNAL_ERROR = 500; + var MILLISECONDS_PER_SECOND = 1000; + var JS_MAX_VALUE = "9007199254740992"; + var JS_MIN_VALUE = "-9007199254740992"; + var ZERO_INDEX = "0"; + var LAST_INDEX = "5000"; //Set the max value to 5000. This is to prevent accidental loading of millions of records. + var DEFAULT_COUNT = 20; + + var TYPE_CLEAR_INDEX_DATA = 1; +// var TYPE_CREATE_TABLE = 2; +// var TYPE_DELETE_BY_ID = 3; +// var TYPE_DELETE_BY_RANGE = 4; +// var TYPE_DELETE_TABLE = 5; + var TYPE_GET_RECORD_COUNT = 6; + var TYPE_GET_BY_ID = 7; + var TYPE_GET_BY_RANGE = 8; + var TYPE_LIST_TABLES = 9; + var TYPE_GET_SCHEMA = 10; +// var TYPE_PUT_RECORDS = 11; +// var TYPE_PUT_RECORDS_TO_TABLE = 12; + var TYPE_SEARCH = 13; + var TYPE_SEARCH_COUNT = 14; + var TYPE_SET_SCHEMA = 15; + var TYPE_TABLE_EXISTS = 16; + var TYPE_WAIT_FOR_INDEXING = 17; + var TYPE_PAGINATION_SUPPORTED = 18; + var TYPE_DRILLDOWN_CATEGORIES = 19; + var TYPE_DRILLDOWN_SEARCH = 20; + var TYPE_DRILLDOWN_SEARCH_COUNT = 21; + var TYPE_ADD_STREAM_DEFINITION = 22; + var TYPE_GET_STREAM_DEFINITION = 23; + var TYPE_PUBLISH_EVENTS = 24; + var TYPE_GET_WITH_KEY_VALUES = 25; + var TYPE_GET_RECORDSTORES = 26; + var TYPE_GET_RECORDSTORE_BY_TABLE = 27; + var TYPE_WAIT_FOR_INDEXING_FOR_TABLE = 28; + var TYPE_SEARCH_WITH_AGGREGATES = 29; + var TYPE_REINDEX = 30; + var log = new Log(); + var carbon = require('carbon'); + var configs = require('/configs/designer.json'); + var utils = require('/modules/utils.js'); + var JSUtils = Packages.org.wso2.carbon.analytics.jsservice.Utils; + var AnalyticsCachedJSServiceConnector = Packages.org.wso2.carbon.analytics.jsservice.AnalyticsCachedJSServiceConnector; + var AnalyticsCache = Packages.org.wso2.carbon.analytics.jsservice.AnalyticsCachedJSServiceConnector.AnalyticsCache; + var cacheTimeoutSeconds = 5; + var loggedInUser = null; + + if(configs.cacheTimeoutSeconds) { + cacheTimeoutSeconds = parseInt(configs.cacheTimeoutSeconds); + } + var cacheSizeBytes = 1024 * 1024 * 1024; // 1GB + if(configs.cacheSizeBytes) { + cacheSizeBytes = parseInt(configs.cacheSizeBytes); + } + response.contentType = CONTENT_TYPE_JSON; + + var authParam = request.getHeader(AUTHORIZATION_HEADER); + if (authParam != null) { + credentials = JSUtils.authenticate(authParam); + loggedInUser = credentials[0]; + } else { + var token = session.get(USER_TOKEN); + if (token != null) { + loggedInUser = token[USERNAME]; + } else { + log.error("user is not authenticated!"); + response.status = HTTP_USER_NOT_AUTHENTICATED; + print('{ "status": "Failed", "message": "User is not authenticated." }'); + return; + } + } + + var cache = application.get("AnalyticsWebServiceCache"); + if (cache == null) { + cache = new AnalyticsCache(cacheTimeoutSeconds, cacheSizeBytes); + application.put("AnalyticsWebServiceCache", cache); + } + + var connector = new AnalyticsCachedJSServiceConnector(cache); + + var type = 0; + var typeParam = request.getParameter(TYPE); + if (typeParam != null) { + type = parseInt(typeParam); + } + + if (type == 0) { + log.error("operation type is not specified!"); + response.status = HTTP_INTERNAL_ERROR; + print('{ "status": "Failed", "message": "Operation type is not specified" }'); + return; + } + + var tableName = request.getParameter(TABLE_NAME); + if (type != TYPE_LIST_TABLES && + // type != TYPE_PUT_RECORDS && + type != TYPE_PAGINATION_SUPPORTED && + type != TYPE_ADD_STREAM_DEFINITION && + type != TYPE_GET_STREAM_DEFINITION && + type != TYPE_PUBLISH_EVENTS && + type != TYPE_WAIT_FOR_INDEXING && + type != TYPE_GET_RECORDSTORES) { + if (tableName == null) { + log.error("tableName is not provided!"); + response.status = HTTP_INTERNAL_ERROR; + print('{ "status": "Failed", "message": "Table name param is empty" }'); + return; + } + } + + var content = request.getContent(); + var contentAsString = null; + if (content != '' && content != null) { + contentAsString = stringify(content); + if (log.isDebugEnabled()) { + log.debug("value of content: " + contentAsString); + } + } + if (connector != null && loggedInUser != null) { + var result = null; + switch (type) { + case TYPE_LIST_TABLES: + { + result = connector.getTableList(loggedInUser); + break; + } + /*case TYPE_CREATE_TABLE: + { + print(connector.createTable(tableName)); + break; + } + case TYPE_DELETE_TABLE: + { + print(connector.deleteTable(tableName)); + break; + } */ + case TYPE_TABLE_EXISTS: + { + result = connector.tableExists(loggedInUser, tableName); + break; + } + case TYPE_GET_BY_RANGE: + { + var from = request.getParameter(TIME_FROM); + if (from == 'undefined') from = JS_MIN_VALUE; + var to = request.getParameter(TIME_TO); + if (to == 'undefined') to = JS_MAX_VALUE; + var start = request.getParameter(START); + var intStart = ZERO_INDEX; + if (start != 'undefined' && start != null) { + intStart = parseInt(start, 10); + } + var count = request.getParameter(COUNT); + var intCount = LAST_INDEX; + if (count != 'undefined' && count != null) { + intCount = parseInt(count, 10); + } + result = connector.getRecordsByRange(loggedInUser, tableName, from, to, intStart, intCount, contentAsString); + break; + } + case TYPE_GET_WITH_KEY_VALUES: + { + result = connector.getWithKeyValues(loggedInUser, tableName, contentAsString); + break; + } + case TYPE_GET_BY_ID: + { + result = connector.getRecordsByIds(loggedInUser, tableName, contentAsString); + break; + } + case TYPE_GET_RECORD_COUNT: + { + result = connector.getRecordCount(loggedInUser, tableName); + break; + } + /*case TYPE_DELETE_BY_RANGE: + { + var timeFrom = Long.parseLong(request.getParameter(TIME_FROM)); + var timeTo = Long.parseLong(request.getParameter(TIME_TO)); + print(connector.deleteRecordsByRange(tableName, timeFrom, timeTo)); + break; + } + case TYPE_DELETE_BY_ID: + { + print(connector.deleteRecordsByIds(tableName, contentAsString)); + break; + }*/ + case TYPE_CLEAR_INDEX_DATA: + { + result = connector.clearIndexData(loggedInUser, tableName); + break; + } + /*case TYPE_PUT_RECORDS: + { + print(connector.insertRecords(contentAsString)); + break; + }*/ + case TYPE_SEARCH_COUNT: + { + var queryString = request.getParameter(QUERY); + if (queryString == 'undefined' || queryString == null || queryString == '') { + result = '{ "status": "Failed", "statusCode": "400", "message": "Invalid Request" }'; + break; + }; + + contentAsString = "{query: " + queryString + "}"; + result = connector.searchCount(loggedInUser, tableName, contentAsString); + break; + } + case TYPE_SEARCH: + { + var queryString = request.getParameter(QUERY); + if (queryString == 'undefined' || queryString == null || queryString == '') { + result = '{ "status": "Failed", "statusCode": "400", "message": "Invalid Request" }'; + break; + }; + + var count = request.getParameter(COUNT); + if (count == 'undefined' || count == null || count == '') { + count = DEFAULT_COUNT; + } + + contentAsString = "{query: " + queryString + ", count:" + count + "}"; + result = connector.search(loggedInUser, tableName, contentAsString); + break; + } + case TYPE_SET_SCHEMA: + { + print(connector.setTableSchema(loggedInUser, tableName, contentAsString)); + break; + } + case TYPE_GET_SCHEMA: + { + result = connector.getTableSchema(loggedInUser, tableName); + break; + } + case TYPE_PAGINATION_SUPPORTED: + { + var recordStore = request.getParameter(RECORDSTORE_NAME) + result = connector.isPaginationSupported(recordStore); + break; + } + case TYPE_WAIT_FOR_INDEXING: + { + var waitTimeAsString = request.getParameter(WAIT_TIME); + var waitTime = -1; + if (waitTimeAsString != null) { + waitTime = parseInt(waitTimeAsString); + } + result = connector.waitForIndexing(waitTime * MILLISECONDS_PER_SECOND); + break; + } + case TYPE_WAIT_FOR_INDEXING_FOR_TABLE: + { + var waitTimeAsString = request.getParameter(WAIT_TIME); + var waitTime = -1; + if (waitTimeAsString != null) { + waitTime = parseInt(waitTimeAsString); + } + result = connector.waitForIndexing(tableName, waitTime * MILLISECONDS_PER_SECOND); + break; + } + case TYPE_DRILLDOWN_CATEGORIES: + { + result = connector.drillDownCategories(loggedInUser, tableName, contentAsString); + break; + } + case TYPE_DRILLDOWN_SEARCH: + { + var queryString = request.getParameter(QUERY); + if (queryString == 'undefined' || queryString == null || queryString == '') { + result = '{ "status": "Failed", "statusCode": "400", "message": "Invalid Request. Query string not found." }'; + break; + }; + + var scoreFunction = request.getParameter(SORT_SCORE_VALUE); + if (scoreFunction == 'undefined' || scoreFunction == null || scoreFunction == '') { + result = '{ "status": "Failed", "statusCode": "400", "message": "Invalid Request. Score function not found." }'; + break; + }; + + var count = request.getParameter(COUNT); + if (count == 'undefined' || count == null || count == '') { + count = DEFAULT_COUNT; + } + + contentAsString = "{query: " + queryString + ", recordCount:"+ count +", scoreFunction:'"+ scoreFunction +"', categories: []}"; + result = connector.drillDownSearch(loggedInUser, tableName, contentAsString); + break; + } + case TYPE_DRILLDOWN_SEARCH_COUNT: + { + result = connector.drillDownSearchCount(loggedInUser, tableName, contentAsString); + break; + } + case TYPE_ADD_STREAM_DEFINITION: + { + result = connector.addStreamDefinition(contentAsString); + break; + } + case TYPE_GET_STREAM_DEFINITION: + { + result = connector.getStreamDefinition(contentAsString); + break; + } + case TYPE_PUBLISH_EVENTS: + { + result = connector.publishEvent(contentAsString); + break; + } + case TYPE_GET_RECORDSTORES: + { + result = connector.getRecordStoreList(); + break; + } + case TYPE_GET_RECORDSTORE_BY_TABLE: + { + result = connector.getRecordStoreByTable(loggedInUser, tableName); + break; + } + case TYPE_SEARCH_WITH_AGGREGATES: + { + result = connector.searchWithAggregates(loggedInUser, contentAsString); + break; + } + case TYPE_REINDEX: + { + var from = request.getParameter(TIME_FROM); + if (from == 'undefined') from = JS_MIN_VALUE; + var to = request.getParameter(TIME_TO); + if (to == 'undefined') to = JS_MAX_VALUE; + result = connector.reIndex(loggedInUser, tableName, from, to); + break; + } + default: + result = '{ "status": "Failed", "statusCode": "500", "message": "Unidentified operation" }'; + } + if (result != null) { + if (log.isDebugEnabled()) { + log.debug("value of result: " + result); + log.debug("status code: " + result.getstatusCode()) + } + + var statusCode = result.getStatusCode(); + var status = result.getStatus(); + var message = result.getMessage(); + response.status = statusCode; + var finalResult = { + status: status, + message: message + }; + print(finalResult); + } + } else { + print('{ "status": "Failed", "statusCode": "500", "message": "AnalyticsCachedWebServiceConnector is unavailable" }'); + } + +}()); +%> diff --git a/modules/distribution/src/repository/jaggeryapps/portal/js/outputAdapterUiLibrary.js b/modules/distribution/src/repository/jaggeryapps/portal/js/outputAdapterUiLibrary.js new file mode 100644 index 00000000..50f07a80 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/js/outputAdapterUiLibrary.js @@ -0,0 +1,286 @@ +/* + * + * + * Copyright (c) 2015, 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 CONSTANTS = { + webAppName: 'outputui', + urlSeperator: '/', + urlGetParameter : '?lastUpdatedTime=', + urlQueryStringBegin : '?', + tenantUrlAttribute: 't', + urlUnsecureTransportHttp : 'http://', + urlUnsecureTransportWebsocket : 'ws://', + urlSecureTransportWebsocket : 'wss://', + urlSecureTransportHttp : 'https://', + colon : ':', + defaultIntervalTime : 10 * 1000, + defaultUserDomain : 'carbon.super', + defaultHostName : 'localhost', + defaultNonsecurePortNumber : '9763', + defaultSecurePortNumber : '9443', + defaultMode : 'AUTO', + processModeHTTP : 'HTTP', + processModeWebSocket : 'WEBSOCKET', + processModeAuto : 'AUTO', + domain : 'carbon.super', + numThousand : 1000, + websocketTimeAppender : 400, + secureMode : 'SECURED' +}; + + +var websocket = null; +var webSocketUrl; +var httpUrl; +var cepHostName; +var cepPortNumber; +var isErrorOccured = false; +var lastUpdatedtime = -1; +var polingInterval; +var stream; +var streamVersion; +var firstPollingAttempt; +var processMode; +var onSuccessFunction; +var onErrorFunction; +var userDomainUrl = ""; +var terminateWebsocketInstance = false; +var pollingContinue = true; +var transportToBeUsedHttp; +var transportToBeUsedWebsocket; + +function subscribe(streamName,version,intervalTime,domain, + listeningFuncSuccessData,listeningFuncErrorData, + cepHost,cepPort,mode,secureMode, queryParams){ + + stopPollingProcesses(); + stream = streamName; + streamVersion = version; + onSuccessFunction = listeningFuncSuccessData; + onErrorFunction = listeningFuncErrorData; + + if(secureMode == CONSTANTS.secureMode){ + transportToBeUsedHttp = CONSTANTS.urlSecureTransportHttp; + transportToBeUsedWebsocket = CONSTANTS.urlSecureTransportWebsocket; + } else { + transportToBeUsedHttp = CONSTANTS.urlUnsecureTransportHttp; + transportToBeUsedWebsocket = CONSTANTS.urlUnsecureTransportWebsocket; + } + + if(intervalTime == null || intervalTime == ""){ + polingInterval = CONSTANTS.defaultIntervalTime; + } else{ + polingInterval = intervalTime * CONSTANTS.numThousand; + } + + if(domain == null || domain == ""){ + domain = CONSTANTS.defaultUserDomain; + } + + if(cepHost == null || cepHost == ""){ + cepHostName = CONSTANTS.defaultHostName; + } else{ + cepHostName = cepHost; + } + + if(cepPort == null || cepPort == ""){ + if(secureMode == CONSTANTS.secureMode){ + cepPortNumber = CONSTANTS.defaultSecurePortNumber; + } else{ + cepPortNumber = CONSTANTS.defaultNonsecurePortNumber; + } + } else{ + cepPortNumber = cepPort; + } + + if(mode == null || mode == ""){ + processMode = CONSTANTS.defaultMode; + } else{ + processMode = mode; + } + + if(domain != CONSTANTS.domain){ + userDomainUrl = CONSTANTS.tenantUrlAttribute + CONSTANTS.urlSeperator + domain + CONSTANTS.urlSeperator; + + } + + if (queryParams == null) { + queryParams = ""; + } else if (queryParams != "") { + queryParams = CONSTANTS.urlQueryStringBegin + queryParams; + } + + webSocketUrl = transportToBeUsedWebsocket + cepHostName + CONSTANTS.colon + cepPortNumber + + CONSTANTS.urlSeperator + CONSTANTS.webAppName+ CONSTANTS.urlSeperator + userDomainUrl + stream + + CONSTANTS.urlSeperator + streamVersion + queryParams; + + + if(processMode == CONSTANTS.processModeHTTP){ + firstPollingAttempt = true; + pollingContinue = true; + startPoll(); + } else{ + initializeWebSocket(webSocketUrl); + } +} + + +/** + * Initializing Web Socket + */ +function initializeWebSocket(webSocketUrl){ + websocket = new WebSocket(webSocketUrl); + websocket.onopen = webSocketOnOpen; + websocket.onmessage = webSocketOnMessage; + websocket.onclose = webSocketOnClose; + websocket.onerror = webSocketOnError; +} + +/** + * Web socket On Open + */ + +var webSocketOnOpen = function () { + // alert("Successfully connected to "+webSocketUrl); + //onErrorFunction("Successfully connected to URL:" + webSocketUrl + "\n"); +}; + + +/** + * On server sends a message + */ +var webSocketOnMessage = function (evt) { + var event = evt.data; + var array = JSON.parse(event); + constructPayload(array); +}; + +/** + * On server close + */ +var webSocketOnClose =function (e) { + + if(isErrorOccured){ + if(processMode != CONSTANTS.processModeWebSocket){ + firstPollingAttempt = true; + pollingContinue = true; + startPoll(); + } + } else{ + if(!terminateWebsocketInstance){ + waitForSocketConnection(websocket); + } else{ + terminateWebsocketInstance = false; + } + + } +}; + +/** + * On server Error + */ +var webSocketOnError = function (err) { + var error = "Error: Cannot connect to Websocket URL:" + webSocketUrl + " .Hence closing the connection!"; + + onErrorFunction(error); + isErrorOccured = true; + +}; + +/** + * Gracefully increments the connection retry + */ +var waitTime = CONSTANTS.numThousand; +function waitForSocketConnection(socket, callback){ + setTimeout( + function () { + if (socket.readyState === 1) { + initializeWebSocket(webSocketUrl); + console.log("Connection is made"); + if(callback != null){ + callback(); + } + return; + } else { + websocket = new WebSocket(webSocketUrl); + waitTime += CONSTANTS.websocketTimeAppender; + waitForSocketConnection(websocket, callback); + } + }, waitTime); +} + +/** + * Polling to retrieve events from http request periodically + */ +function startPoll(){ + + (function poll(){ + setTimeout(function(){ + httpUrl = transportToBeUsedHttp + cepHostName + CONSTANTS.colon + cepPortNumber + CONSTANTS.urlSeperator + + CONSTANTS.webAppName + CONSTANTS.urlSeperator + userDomainUrl + stream + CONSTANTS.urlSeperator + + streamVersion + CONSTANTS.urlGetParameter + lastUpdatedtime; + + $.getJSON(httpUrl, function(responseText) { + if(firstPollingAttempt){ + /*var data = $("textarea#idConsole").val(); + $("textarea#idConsole").val(data + "Successfully connected to HTTP.");*/ + firstPollingAttempt = false; + } + + var eventList = $.parseJSON(responseText.events); + if(eventList.length != 0){ + lastUpdatedtime = responseText.lastEventTime; + for(var i=0;i.radio:first-child,.controls>.checkbox:first-child{padding-top:5px;} +.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle;} +.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px;} +.input-mini{width:60px;} +.input-small{width:90px;} +.input-medium{width:150px;} +.input-large{width:210px;} +.input-xlarge{width:270px;} +.input-xxlarge{width:530px;} +input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0;} +.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block;} +input,textarea,.uneditable-input{margin-left:0;} +.controls-row [class*="span"]+[class*="span"]{margin-left:20px;} +input.span12, textarea.span12, .uneditable-input.span12{width:926px;} +input.span11, textarea.span11, .uneditable-input.span11{width:846px;} +input.span10, textarea.span10, .uneditable-input.span10{width:766px;} +input.span9, textarea.span9, .uneditable-input.span9{width:686px;} +input.span8, textarea.span8, .uneditable-input.span8{width:606px;} +input.span7, textarea.span7, .uneditable-input.span7{width:526px;} +input.span6, textarea.span6, .uneditable-input.span6{width:446px;} +input.span5, textarea.span5, .uneditable-input.span5{width:366px;} +input.span4, textarea.span4, .uneditable-input.span4{width:286px;} +input.span3, textarea.span3, .uneditable-input.span3{width:206px;} +input.span2, textarea.span2, .uneditable-input.span2{width:126px;} +input.span1, textarea.span1, .uneditable-input.span1{width:46px;} +.controls-row{*zoom:1;}.controls-row:before,.controls-row:after{display:table;content:"";line-height:0;} +.controls-row:after{clear:both;} +.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left;} +.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px;} +input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eeeeee;} +input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent;} +.control-group.warning>label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853;} +.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;} +.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;} +.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853;} +.control-group.error>label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48;} +.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;} +.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;} +.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48;} +.control-group.success>label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847;} +.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;} +.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;} +.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847;} +.control-group.info>label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad;} +.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad;} +.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;} +.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad;} +input:focus:required:invalid,textarea:focus:required:invalid,select:focus:required:invalid{color:#b94a48;border-color:#ee5f5b;}input:focus:required:invalid:focus,textarea:focus:required:invalid:focus,select:focus:required:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7;} +.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1;}.form-actions:before,.form-actions:after{display:table;content:"";line-height:0;} +.form-actions:after{clear:both;} +.help-block,.help-inline{color:#595959;} +.help-block{display:block;margin-bottom:10px;} +.help-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding-left:5px;} +.input-append,.input-prepend{margin-bottom:5px;font-size:0;white-space:nowrap;}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu{font-size:14px;} +.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2;} +.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #ffffff;background-color:#eeeeee;border:1px solid #ccc;} +.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546;} +.input-prepend .add-on,.input-prepend .btn{margin-right:-1px;} +.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;} +.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}.input-append input+.btn-group .btn,.input-append select+.btn-group .btn,.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px;} +.input-append .add-on:last-child,.input-append .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;} +.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.input-prepend.input-append .btn-group:first-child{margin-left:0;} +input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;} +.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px;} +.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0;} +.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0;} +.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px;} +.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;*zoom:1;margin-bottom:0;vertical-align:middle;} +.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none;} +.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block;} +.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0;} +.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle;} +.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0;} +.control-group{margin-bottom:10px;} +legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate;} +.form-horizontal .control-group{margin-bottom:20px;*zoom:1;}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";line-height:0;} +.form-horizontal .control-group:after{clear:both;} +.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right;} +.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0;}.form-horizontal .controls:first-child{*padding-left:180px;} +.form-horizontal .help-block{margin-bottom:0;} +.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block{margin-top:10px;} +.form-horizontal .form-actions{padding-left:180px;} +.btn{display:inline-block;*display:inline;*zoom:1;padding:4px 12px;margin-bottom:0;font-size:14px;line-height:20px;*line-height:20px;text-align:center;vertical-align:middle;cursor:pointer;color:#333333;text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #ffffff, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #ffffff, #e6e6e6);background-image:-o-linear-gradient(top, #ffffff, #e6e6e6);background-image:linear-gradient(to bottom, #ffffff, #e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #bbbbbb;*border:0;border-bottom-color:#a2a2a2;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*margin-left:.3em;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333333;background-color:#e6e6e6;*background-color:#d9d9d9;} +.btn:active,.btn.active{background-color:#cccccc \9;} +.btn:first-child{*margin-left:0;} +.btn:hover{color:#333333;text-decoration:none;background-color:#e6e6e6;*background-color:#d9d9d9;background-position:0 -15px;-webkit-transition:background-position 0.1s linear;-moz-transition:background-position 0.1s linear;-o-transition:background-position 0.1s linear;transition:background-position 0.1s linear;} +.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;} +.btn.active,.btn:active{background-color:#e6e6e6;background-color:#d9d9d9 \9;background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);} +.btn.disabled,.btn[disabled]{cursor:default;background-color:#e6e6e6;background-image:none;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} +.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} +.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:2px;} +.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0;} +.btn-mini{padding:1px 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.btn-block{display:block;width:100%;padding-left:0;padding-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} +.btn-block+.btn-block{margin-top:5px;} +input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%;} +.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255, 255, 255, 0.75);} +.btn{border-color:#c5c5c5;border-color:rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25);} +.btn-primary{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top, #0088cc, #0044cc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));background-image:-webkit-linear-gradient(top, #0088cc, #0044cc);background-image:-o-linear-gradient(top, #0088cc, #0044cc);background-image:linear-gradient(to bottom, #0088cc, #0044cc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);border-color:#0044cc #0044cc #002a80;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#0044cc;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#ffffff;background-color:#0044cc;*background-color:#003bb3;} +.btn-primary:active,.btn-primary.active{background-color:#003399 \9;} +.btn-warning{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#f89406;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#ffffff;background-color:#f89406;*background-color:#df8505;} +.btn-warning:active,.btn-warning.active{background-color:#c67605 \9;} +.btn-danger{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#da4f49;background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);background-image:linear-gradient(to bottom, #ee5f5b, #bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#bd362f;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#ffffff;background-color:#bd362f;*background-color:#a9302a;} +.btn-danger:active,.btn-danger.active{background-color:#942a25 \9;} +.btn-success{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#5bb75b;background-image:-moz-linear-gradient(top, #62c462, #51a351);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));background-image:-webkit-linear-gradient(top, #62c462, #51a351);background-image:-o-linear-gradient(top, #62c462, #51a351);background-image:linear-gradient(to bottom, #62c462, #51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#51a351;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#ffffff;background-color:#51a351;*background-color:#499249;} +.btn-success:active,.btn-success.active{background-color:#408140 \9;} +.btn-info{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#49afcd;background-image:-moz-linear-gradient(top, #5bc0de, #2f96b4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));background-image:-webkit-linear-gradient(top, #5bc0de, #2f96b4);background-image:-o-linear-gradient(top, #5bc0de, #2f96b4);background-image:linear-gradient(to bottom, #5bc0de, #2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#2f96b4;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#ffffff;background-color:#2f96b4;*background-color:#2a85a0;} +.btn-info:active,.btn-info.active{background-color:#24748c \9;} +.btn-inverse{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#363636;background-image:-moz-linear-gradient(top, #444444, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222));background-image:-webkit-linear-gradient(top, #444444, #222222);background-image:-o-linear-gradient(top, #444444, #222222);background-image:linear-gradient(to bottom, #444444, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0);border-color:#222222 #222222 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#222222;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#ffffff;background-color:#222222;*background-color:#151515;} +.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9;} +button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px;}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0;} +button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px;} +button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px;} +button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px;} +.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} +.btn-link{border-color:transparent;cursor:pointer;color:#0088cc;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.btn-link:hover{color:#005580;text-decoration:underline;background-color:transparent;} +.btn-link[disabled]:hover{color:#333333;text-decoration:none;} +.btn-group{position:relative;display:inline-block;*display:inline;*zoom:1;font-size:0;vertical-align:middle;white-space:nowrap;*margin-left:.3em;}.btn-group:first-child{*margin-left:0;} +.btn-group+.btn-group{margin-left:5px;} +.btn-toolbar{font-size:0;margin-top:10px;margin-bottom:10px;}.btn-toolbar .btn+.btn,.btn-toolbar .btn-group+.btn,.btn-toolbar .btn+.btn-group{margin-left:5px;} +.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.btn-group>.btn+.btn{margin-left:-1px;} +.btn-group>.btn,.btn-group>.dropdown-menu{font-size:14px;} +.btn-group>.btn-mini{font-size:11px;} +.btn-group>.btn-small{font-size:12px;} +.btn-group>.btn-large{font-size:16px;} +.btn-group>.btn:first-child{margin-left:0;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;} +.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;} +.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;} +.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;} +.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2;} +.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0;} +.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);*padding-top:5px;*padding-bottom:5px;} +.btn-group>.btn-mini+.dropdown-toggle{padding-left:5px;padding-right:5px;*padding-top:2px;*padding-bottom:2px;} +.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px;} +.btn-group>.btn-large+.dropdown-toggle{padding-left:12px;padding-right:12px;*padding-top:7px;*padding-bottom:7px;} +.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);} +.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6;} +.btn-group.open .btn-primary.dropdown-toggle{background-color:#0044cc;} +.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406;} +.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f;} +.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351;} +.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4;} +.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222222;} +.btn .caret{margin-top:8px;margin-left:0;} +.btn-mini .caret,.btn-small .caret,.btn-large .caret{margin-top:6px;} +.btn-large .caret{border-left-width:5px;border-right-width:5px;border-top-width:5px;} +.dropup .btn-large .caret{border-bottom-width:5px;} +.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;} +.btn-group-vertical{display:inline-block;*display:inline;*zoom:1;} +.btn-group-vertical .btn{display:block;float:none;width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.btn-group-vertical .btn+.btn{margin-left:0;margin-top:-1px;} +.btn-group-vertical .btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;} +.btn-group-vertical .btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;} +.btn-group-vertical .btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0;} +.btn-group-vertical .btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;} +.nav{margin-left:0;margin-bottom:20px;list-style:none;} +.nav>li>a{display:block;} +.nav>li>a:hover{text-decoration:none;background-color:#eeeeee;} +.nav>.pull-right{float:right;} +.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999999;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);text-transform:uppercase;} +.nav li+.nav-header{margin-top:9px;} +.nav-list{padding-left:15px;padding-right:15px;margin-bottom:0;} +.nav-list>li>a,.nav-list .nav-header{margin-left:-15px;margin-right:-15px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);} +.nav-list>li>a{padding:3px 15px;} +.nav-list>.active>a,.nav-list>.active>a:hover{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.2);background-color:#0088cc;} +.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px;} +.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;} +.nav-tabs,.nav-pills{*zoom:1;}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:"";line-height:0;} +.nav-tabs:after,.nav-pills:after{clear:both;} +.nav-tabs>li,.nav-pills>li{float:left;} +.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px;} +.nav-tabs{border-bottom:1px solid #ddd;} +.nav-tabs>li{margin-bottom:-1px;} +.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #dddddd;} +.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555555;background-color:#ffffff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default;} +.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} +.nav-pills>.active>a,.nav-pills>.active>a:hover{color:#ffffff;background-color:#0088cc;} +.nav-stacked>li{float:none;} +.nav-stacked>li>a{margin-right:0;} +.nav-tabs.nav-stacked{border-bottom:0;} +.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;} +.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;} +.nav-tabs.nav-stacked>li>a:hover{border-color:#ddd;z-index:2;} +.nav-pills.nav-stacked>li>a{margin-bottom:3px;} +.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px;} +.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;} +.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} +.nav .dropdown-toggle .caret{border-top-color:#0088cc;border-bottom-color:#0088cc;margin-top:6px;} +.nav .dropdown-toggle:hover .caret{border-top-color:#005580;border-bottom-color:#005580;} +.nav-tabs .dropdown-toggle .caret{margin-top:8px;} +.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff;} +.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555555;border-bottom-color:#555555;} +.nav>.dropdown.active>a:hover{cursor:pointer;} +.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover{color:#ffffff;background-color:#999999;border-color:#999999;} +.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;opacity:1;filter:alpha(opacity=100);} +.tabs-stacked .open>a:hover{border-color:#999999;} +.tabbable{*zoom:1;}.tabbable:before,.tabbable:after{display:table;content:"";line-height:0;} +.tabbable:after{clear:both;} +.tab-content{overflow:auto;} +.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0;} +.tab-content>.tab-pane,.pill-content>.pill-pane{display:none;} +.tab-content>.active,.pill-content>.active{display:block;} +.tabs-below>.nav-tabs{border-top:1px solid #ddd;} +.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0;} +.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;}.tabs-below>.nav-tabs>li>a:hover{border-bottom-color:transparent;border-top-color:#ddd;} +.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd #ddd;} +.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none;} +.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px;} +.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd;} +.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;} +.tabs-left>.nav-tabs>li>a:hover{border-color:#eeeeee #dddddd #eeeeee #eeeeee;} +.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#ffffff;} +.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd;} +.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.tabs-right>.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #eeeeee #dddddd;} +.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#ffffff;} +.nav>.disabled>a{color:#999999;} +.nav>.disabled>a:hover{text-decoration:none;background-color:transparent;cursor:default;} +.navbar{overflow:visible;margin-bottom:20px;color:#777777;*position:relative;*z-index:2;} +.navbar-inner{min-height:40px;padding-left:20px;padding-right:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top, #ffffff, #f2f2f2);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2));background-image:-webkit-linear-gradient(top, #ffffff, #f2f2f2);background-image:-o-linear-gradient(top, #ffffff, #f2f2f2);background-image:linear-gradient(to bottom, #ffffff, #f2f2f2);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0);border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);-moz-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);*zoom:1;}.navbar-inner:before,.navbar-inner:after{display:table;content:"";line-height:0;} +.navbar-inner:after{clear:both;} +.navbar .container{width:auto;} +.nav-collapse.collapse{height:auto;overflow:visible;} +.navbar .brand{float:left;display:block;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777777;text-shadow:0 1px 0 #ffffff;}.navbar .brand:hover{text-decoration:none;} +.navbar-text{margin-bottom:0;line-height:40px;} +.navbar-link{color:#777777;}.navbar-link:hover{color:#333333;} +.navbar .divider-vertical{height:40px;margin:0 9px;border-left:1px solid #f2f2f2;border-right:1px solid #ffffff;} +.navbar .btn,.navbar .btn-group{margin-top:5px;} +.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn{margin-top:0;} +.navbar-form{margin-bottom:0;*zoom:1;}.navbar-form:before,.navbar-form:after{display:table;content:"";line-height:0;} +.navbar-form:after{clear:both;} +.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px;} +.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0;} +.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px;} +.navbar-form .input-append,.navbar-form .input-prepend{margin-top:6px;white-space:nowrap;}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0;} +.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0;}.navbar-search .search-query{margin-bottom:0;padding:4px 14px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;} +.navbar-static-top{position:static;margin-bottom:0;}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0;} +.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px;} +.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0;} +.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-left:0;padding-right:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;} +.navbar-fixed-top{top:0;} +.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,.1);box-shadow:0 1px 10px rgba(0,0,0,.1);} +.navbar-fixed-bottom{bottom:0;}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,.1);box-shadow:0 -1px 10px rgba(0,0,0,.1);} +.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0;} +.navbar .nav.pull-right{float:right;margin-right:0;} +.navbar .nav>li{float:left;} +.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777777;text-decoration:none;text-shadow:0 1px 0 #ffffff;} +.navbar .nav .dropdown-toggle .caret{margin-top:8px;} +.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{background-color:transparent;color:#333333;text-decoration:none;} +.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);-moz-box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);} +.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#ededed;background-image:-moz-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5));background-image:-webkit-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:-o-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:linear-gradient(to bottom, #f2f2f2, #e5e5e5);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0);border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#e5e5e5;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);}.navbar .btn-navbar:hover,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#ffffff;background-color:#e5e5e5;*background-color:#d9d9d9;} +.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#cccccc \9;} +.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);-moz-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);} +.btn-navbar .icon-bar+.icon-bar{margin-top:3px;} +.navbar .nav>li>.dropdown-menu:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0, 0, 0, 0.2);position:absolute;top:-7px;left:9px;} +.navbar .nav>li>.dropdown-menu:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #ffffff;position:absolute;top:-6px;left:10px;} +.navbar-fixed-bottom .nav>li>.dropdown-menu:before{border-top:7px solid #ccc;border-top-color:rgba(0, 0, 0, 0.2);border-bottom:0;bottom:-7px;top:auto;} +.navbar-fixed-bottom .nav>li>.dropdown-menu:after{border-top:6px solid #ffffff;border-bottom:0;bottom:-6px;top:auto;} +.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{background-color:#e5e5e5;color:#555555;} +.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777777;border-bottom-color:#777777;} +.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555555;border-bottom-color:#555555;} +.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{left:auto;right:0;}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{left:auto;right:12px;} +.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{left:auto;right:13px;} +.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{left:auto;right:100%;margin-left:0;margin-right:-1px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px;} +.navbar-inverse{color:#999999;}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top, #222222, #111111);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111));background-image:-webkit-linear-gradient(top, #222222, #111111);background-image:-o-linear-gradient(top, #222222, #111111);background-image:linear-gradient(to bottom, #222222, #111111);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0);border-color:#252525;} +.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999999;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover{color:#ffffff;} +.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{background-color:transparent;color:#ffffff;} +.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#ffffff;background-color:#111111;} +.navbar-inverse .navbar-link{color:#999999;}.navbar-inverse .navbar-link:hover{color:#ffffff;} +.navbar-inverse .divider-vertical{border-left-color:#111111;border-right-color:#222222;} +.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{background-color:#111111;color:#ffffff;} +.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999999;border-bottom-color:#999999;} +.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;} +.navbar-inverse .navbar-search .search-query{color:#ffffff;background-color:#515151;border-color:#111111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none;}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#cccccc;} +.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#cccccc;} +.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#cccccc;} +.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333333;text-shadow:0 1px 0 #ffffff;background-color:#ffffff;border:0;-webkit-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);-moz-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);box-shadow:0 0 3px rgba(0, 0, 0, 0.15);outline:0;} +.navbar-inverse .btn-navbar{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e0e0e;background-image:-moz-linear-gradient(top, #151515, #040404);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404));background-image:-webkit-linear-gradient(top, #151515, #040404);background-image:-o-linear-gradient(top, #151515, #040404);background-image:linear-gradient(to bottom, #151515, #040404);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0);border-color:#040404 #040404 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#040404;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#ffffff;background-color:#040404;*background-color:#000000;} +.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000000 \9;} +.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.breadcrumb li{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 0 #ffffff;} +.breadcrumb .divider{padding:0 5px;color:#ccc;} +.breadcrumb .active{color:#999999;} +.pagination{margin:20px 0;} +.pagination ul{display:inline-block;*display:inline;*zoom:1;margin-left:0;margin-bottom:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);} +.pagination ul>li{display:inline;} +.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#ffffff;border:1px solid #dddddd;border-left-width:0;} +.pagination ul>li>a:hover,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5;} +.pagination ul>.active>a,.pagination ul>.active>span{color:#999999;cursor:default;} +.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover{color:#999999;background-color:transparent;cursor:default;} +.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;} +.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;} +.pagination-centered{text-align:center;} +.pagination-right{text-align:right;} +.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px;} +.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;} +.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;} +.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-top-left-radius:3px;-moz-border-radius-topleft:3px;border-top-left-radius:3px;-webkit-border-bottom-left-radius:3px;-moz-border-radius-bottomleft:3px;border-bottom-left-radius:3px;} +.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;-moz-border-radius-topright:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;-moz-border-radius-bottomright:3px;border-bottom-right-radius:3px;} +.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px;} +.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:1px 6px;font-size:10.5px;} +.pager{margin:20px 0;list-style:none;text-align:center;*zoom:1;}.pager:before,.pager:after{display:table;content:"";line-height:0;} +.pager:after{clear:both;} +.pager li{display:inline;} +.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;} +.pager li>a:hover{text-decoration:none;background-color:#f5f5f5;} +.pager .next>a,.pager .next>span{float:right;} +.pager .previous>a,.pager .previous>span{float:left;} +.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>span{color:#999999;background-color:#fff;cursor:default;} +.thumbnails{margin-left:-20px;list-style:none;*zoom:1;}.thumbnails:before,.thumbnails:after{display:table;content:"";line-height:0;} +.thumbnails:after{clear:both;} +.row-fluid .thumbnails{margin-left:0;} +.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px;} +.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;-o-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out;} +a.thumbnail:hover{border-color:#0088cc;-webkit-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);-moz-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);} +.thumbnail>img{display:block;max-width:100%;margin-left:auto;margin-right:auto;} +.thumbnail .caption{padding:9px;color:#555555;} +.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;color:#c09853;} +.alert h4{margin:0;} +.alert .close{position:relative;top:-2px;right:-21px;line-height:20px;} +.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#468847;} +.alert-danger,.alert-error{background-color:#f2dede;border-color:#eed3d7;color:#b94a48;} +.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad;} +.alert-block{padding-top:14px;padding-bottom:14px;} +.alert-block>p,.alert-block>ul{margin-bottom:0;} +.alert-block p+p{margin-top:5px;} +@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-o-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f7f7f7;background-image:-moz-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));background-image:-webkit-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-o-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:linear-gradient(to bottom, #f5f5f5, #f9f9f9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.progress .bar{width:0%;height:100%;color:#ffffff;float:left;font-size:12px;text-align:center;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top, #149bdf, #0480be);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));background-image:-webkit-linear-gradient(top, #149bdf, #0480be);background-image:-o-linear-gradient(top, #149bdf, #0480be);background-image:linear-gradient(to bottom, #149bdf, #0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width 0.6s ease;-moz-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease;} +.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);} +.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px;} +.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite;} +.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);background-image:linear-gradient(to bottom, #ee5f5b, #c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0);} +.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top, #62c462, #57a957);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));background-image:-webkit-linear-gradient(top, #62c462, #57a957);background-image:-o-linear-gradient(top, #62c462, #57a957);background-image:linear-gradient(to bottom, #62c462, #57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0);} +.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top, #5bc0de, #339bb9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));background-image:-webkit-linear-gradient(top, #5bc0de, #339bb9);background-image:-o-linear-gradient(top, #5bc0de, #339bb9);background-image:linear-gradient(to bottom, #5bc0de, #339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0);} +.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);} +.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eeeeee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;color:inherit;letter-spacing:-1px;} +.hero-unit li{line-height:30px;} +.media,.media-body{overflow:hidden;*overflow:visible;zoom:1;} +.media,.media .media{margin-top:15px;} +.media:first-child{margin-top:0;} +.media-object{display:block;} +.media-heading{margin:0 0 5px;} +.media .pull-left{margin-right:10px;} +.media .pull-right{margin-left:10px;} +.media-list{margin-left:0;list-style:none;} +.tooltip{position:absolute;z-index:1030;display:block;visibility:visible;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0);}.tooltip.in{opacity:0.8;filter:alpha(opacity=80);} +.tooltip.top{margin-top:-3px;} +.tooltip.right{margin-left:3px;} +.tooltip.bottom{margin-top:3px;} +.tooltip.left{margin-left:-3px;} +.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;text-decoration:none;background-color:#000000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid;} +.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000000;} +.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000000;} +.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000000;} +.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000000;} +.popover{position:absolute;top:0;left:0;z-index:1010;display:none;width:236px;padding:1px;background-color:#ffffff;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);}.popover.top{margin-top:-10px;} +.popover.right{margin-left:10px;} +.popover.bottom{margin-top:10px;} +.popover.left{margin-left:-10px;} +.popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0;} +.popover-content{padding:9px 14px;}.popover-content p,.popover-content ul,.popover-content ol{margin-bottom:0;} +.popover .arrow,.popover .arrow:after{position:absolute;display:inline-block;width:0;height:0;border-color:transparent;border-style:solid;} +.popover .arrow:after{content:"";z-index:-1;} +.popover.top .arrow{bottom:-10px;left:50%;margin-left:-10px;border-width:10px 10px 0;border-top-color:#ffffff;}.popover.top .arrow:after{border-width:11px 11px 0;border-top-color:rgba(0, 0, 0, 0.25);bottom:-1px;left:-11px;} +.popover.right .arrow{top:50%;left:-10px;margin-top:-10px;border-width:10px 10px 10px 0;border-right-color:#ffffff;}.popover.right .arrow:after{border-width:11px 11px 11px 0;border-right-color:rgba(0, 0, 0, 0.25);bottom:-11px;left:-1px;} +.popover.bottom .arrow{top:-10px;left:50%;margin-left:-10px;border-width:0 10px 10px;border-bottom-color:#ffffff;}.popover.bottom .arrow:after{border-width:0 11px 11px;border-bottom-color:rgba(0, 0, 0, 0.25);top:-1px;left:-11px;} +.popover.left .arrow{top:50%;right:-10px;margin-top:-10px;border-width:10px 0 10px 10px;border-left-color:#ffffff;}.popover.left .arrow:after{border-width:11px 0 11px 11px;border-left-color:rgba(0, 0, 0, 0.25);bottom:-11px;right:-1px;} +.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000;}.modal-backdrop.fade{opacity:0;} +.modal-backdrop,.modal-backdrop.fade.in{opacity:0.8;filter:alpha(opacity=80);} +.modal{position:fixed;top:50%;left:50%;z-index:1050;width:560px;margin:-250px 0 0 -280px;background-color:#ffffff;border:1px solid #999;border:1px solid rgba(0, 0, 0, 0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;outline:none;}.modal.fade{-webkit-transition:opacity .3s linear, top .3s ease-out;-moz-transition:opacity .3s linear, top .3s ease-out;-o-transition:opacity .3s linear, top .3s ease-out;transition:opacity .3s linear, top .3s ease-out;top:-25%;} +.modal.fade.in{top:50%;} +.modal-header{padding:9px 15px;border-bottom:1px solid #eee;}.modal-header .close{margin-top:2px;} +.modal-header h3{margin:0;line-height:30px;} +.modal-body{overflow-y:auto;max-height:400px;padding:15px;} +.modal-form{margin-bottom:0;} +.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;*zoom:1;}.modal-footer:before,.modal-footer:after{display:table;content:"";line-height:0;} +.modal-footer:after{clear:both;} +.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0;} +.modal-footer .btn-group .btn+.btn{margin-left:-1px;} +.modal-footer .btn-block+.btn-block{margin-left:0;} +.dropup,.dropdown{position:relative;} +.dropdown-toggle{*margin-bottom:-3px;} +.dropdown-toggle:active,.open .dropdown-toggle{outline:0;} +.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000000;border-right:4px solid transparent;border-left:4px solid transparent;content:"";} +.dropdown .caret{margin-top:8px;margin-left:2px;} +.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#ffffff;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;}.dropdown-menu.pull-right{right:0;left:auto;} +.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;} +.dropdown-menu li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333333;white-space:nowrap;} +.dropdown-menu li>a:hover,.dropdown-menu li>a:focus,.dropdown-submenu:hover>a{text-decoration:none;color:#ffffff;background-color:#0081c2;background-image:-moz-linear-gradient(top, #0088cc, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));background-image:-webkit-linear-gradient(top, #0088cc, #0077b3);background-image:-o-linear-gradient(top, #0088cc, #0077b3);background-image:linear-gradient(to bottom, #0088cc, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);} +.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#333333;text-decoration:none;outline:0;background-color:#0081c2;background-image:-moz-linear-gradient(top, #0088cc, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));background-image:-webkit-linear-gradient(top, #0088cc, #0077b3);background-image:-o-linear-gradient(top, #0088cc, #0077b3);background-image:linear-gradient(to bottom, #0088cc, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);} +.dropdown-menu .disabled>a,.dropdown-menu .disabled>a:hover{color:#999999;} +.dropdown-menu .disabled>a:hover{text-decoration:none;background-color:transparent;background-image:none;cursor:default;} +.open{*z-index:1000;}.open >.dropdown-menu{display:block;} +.pull-right>.dropdown-menu{right:0;left:auto;} +.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000000;content:"";} +.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px;} +.dropdown-submenu{position:relative;} +.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px;} +.dropdown-submenu:hover>.dropdown-menu{display:block;} +.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0;} +.dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#cccccc;margin-top:5px;margin-right:-10px;} +.dropdown-submenu:hover>a:after{border-left-color:#ffffff;} +.dropdown-submenu.pull-left{float:none;}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px;} +.dropdown .dropdown-menu .nav-header{padding-left:20px;padding-right:20px;} +.typeahead{margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.accordion{margin-bottom:20px;} +.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.accordion-heading{border-bottom:0;} +.accordion-heading .accordion-toggle{display:block;padding:8px 15px;} +.accordion-toggle{cursor:pointer;} +.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5;} +.carousel{position:relative;margin-bottom:20px;line-height:1;} +.carousel-inner{overflow:hidden;width:100%;position:relative;} +.carousel .item{display:none;position:relative;-webkit-transition:0.6s ease-in-out left;-moz-transition:0.6s ease-in-out left;-o-transition:0.6s ease-in-out left;transition:0.6s ease-in-out left;} +.carousel .item>img{display:block;line-height:1;} +.carousel .active,.carousel .next,.carousel .prev{display:block;} +.carousel .active{left:0;} +.carousel .next,.carousel .prev{position:absolute;top:0;width:100%;} +.carousel .next{left:100%;} +.carousel .prev{left:-100%;} +.carousel .next.left,.carousel .prev.right{left:0;} +.carousel .active.left{left:-100%;} +.carousel .active.right{left:100%;} +.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#ffffff;text-align:center;background:#222222;border:3px solid #ffffff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:0.5;filter:alpha(opacity=50);}.carousel-control.right{left:auto;right:15px;} +.carousel-control:hover{color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90);} +.carousel-caption{position:absolute;left:0;right:0;bottom:0;padding:15px;background:#333333;background:rgba(0, 0, 0, 0.75);} +.carousel-caption h4,.carousel-caption p{color:#ffffff;line-height:20px;} +.carousel-caption h4{margin:0 0 5px;} +.carousel-caption p{margin-bottom:0;} +.media,.media-body{overflow:hidden;*overflow:visible;zoom:1;} +.media,.media .media{margin-top:15px;} +.media:first-child{margin-top:0;} +.media-object{display:block;} +.media-heading{margin:0 0 5px;} +.media .pull-left{margin-right:10px;} +.media .pull-right{margin-left:10px;} +.media-list{margin-left:0;list-style:none;} +.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);}.well blockquote{border-color:#ddd;border-color:rgba(0, 0, 0, 0.15);} +.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} +.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20);}.close:hover{color:#000000;text-decoration:none;cursor:pointer;opacity:0.4;filter:alpha(opacity=40);} +button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;} +.pull-right{float:right;} +.pull-left{float:left;} +.hide{display:none;} +.show{display:block;} +.invisible{visibility:hidden;} +.affix{position:fixed;} +.fade{opacity:0;-webkit-transition:opacity 0.15s linear;-moz-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear;}.fade.in{opacity:1;} +.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height 0.35s ease;-moz-transition:height 0.35s ease;-o-transition:height 0.35s ease;transition:height 0.35s ease;}.collapse.in{height:auto;} +.hidden{display:none;visibility:hidden;} +.visible-phone{display:none !important;} +.visible-tablet{display:none !important;} +.hidden-desktop{display:none !important;} +.visible-desktop{display:inherit !important;} +@media (min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important ;} .visible-tablet{display:inherit !important;} .hidden-tablet{display:none !important;}}@media (max-width:767px){.hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important;} .visible-phone{display:inherit !important;} .hidden-phone{display:none !important;}}@media (max-width:767px){body{padding-left:20px;padding-right:20px;} .navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-left:-20px;margin-right:-20px;} .container-fluid{padding:0;} .dl-horizontal dt{float:none;clear:none;width:auto;text-align:left;} .dl-horizontal dd{margin-left:0;} .container{width:auto;} .row-fluid{width:100%;} .row,.thumbnails{margin-left:0;} .thumbnails>li{float:none;margin-left:0;} [class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{float:none;display:block;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .row-fluid [class*="offset"]:first-child{margin-left:0;} .input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto;} .controls-row [class*="span"]+[class*="span"]{margin-left:0;} .modal{position:fixed;top:20px;left:20px;right:20px;width:auto;margin:0;}.modal.fade{top:-100px;} .modal.fade.in{top:20px;}}@media (max-width:480px){.nav-collapse{-webkit-transform:translate3d(0, 0, 0);} .page-header h1 small{display:block;line-height:20px;} input[type="checkbox"],input[type="radio"]{border:1px solid #ccc;} .form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left;} .form-horizontal .controls{margin-left:0;} .form-horizontal .control-list{padding-top:0;} .form-horizontal .form-actions{padding-left:10px;padding-right:10px;} .media .pull-left,.media .pull-right{float:none;display:block;margin-bottom:10px;} .media-object{margin-right:0;margin-left:0;} .modal{top:10px;left:10px;right:10px;} .modal-header .close{padding:10px;margin:-10px;} .carousel-caption{position:static;}}@media (min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} [class*="span"]{float:left;min-height:1px;margin-left:20px;} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px;} .span12{width:724px;} .span11{width:662px;} .span10{width:600px;} .span9{width:538px;} .span8{width:476px;} .span7{width:414px;} .span6{width:352px;} .span5{width:290px;} .span4{width:228px;} .span3{width:166px;} .span2{width:104px;} .span1{width:42px;} .offset12{margin-left:764px;} .offset11{margin-left:702px;} .offset10{margin-left:640px;} .offset9{margin-left:578px;} .offset8{margin-left:516px;} .offset7{margin-left:454px;} .offset6{margin-left:392px;} .offset5{margin-left:330px;} .offset4{margin-left:268px;} .offset3{margin-left:206px;} .offset2{margin-left:144px;} .offset1{margin-left:82px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%;} .row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%;} .row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%;} .row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%;} .row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%;} .row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%;} .row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%;} .row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%;} .row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%;} .row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%;} .row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%;} .row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%;} .row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%;} .row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%;} .row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%;} .row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%;} .row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%;} .row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%;} .row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%;} .row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%;} .row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%;} .row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%;} .row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%;} .row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%;} .row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%;} .row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%;} .row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%;} .row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%;} .row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%;} .row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%;} .row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%;} .row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%;} .row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%;} .row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%;} .row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*="span"]+[class*="span"]{margin-left:20px;} input.span12, textarea.span12, .uneditable-input.span12{width:710px;} input.span11, textarea.span11, .uneditable-input.span11{width:648px;} input.span10, textarea.span10, .uneditable-input.span10{width:586px;} input.span9, textarea.span9, .uneditable-input.span9{width:524px;} input.span8, textarea.span8, .uneditable-input.span8{width:462px;} input.span7, textarea.span7, .uneditable-input.span7{width:400px;} input.span6, textarea.span6, .uneditable-input.span6{width:338px;} input.span5, textarea.span5, .uneditable-input.span5{width:276px;} input.span4, textarea.span4, .uneditable-input.span4{width:214px;} input.span3, textarea.span3, .uneditable-input.span3{width:152px;} input.span2, textarea.span2, .uneditable-input.span2{width:90px;} input.span1, textarea.span1, .uneditable-input.span1{width:28px;}}@media (min-width:1200px){.row{margin-left:-30px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} [class*="span"]{float:left;min-height:1px;margin-left:30px;} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px;} .span12{width:1170px;} .span11{width:1070px;} .span10{width:970px;} .span9{width:870px;} .span8{width:770px;} .span7{width:670px;} .span6{width:570px;} .span5{width:470px;} .span4{width:370px;} .span3{width:270px;} .span2{width:170px;} .span1{width:70px;} .offset12{margin-left:1230px;} .offset11{margin-left:1130px;} .offset10{margin-left:1030px;} .offset9{margin-left:930px;} .offset8{margin-left:830px;} .offset7{margin-left:730px;} .offset6{margin-left:630px;} .offset5{margin-left:530px;} .offset4{margin-left:430px;} .offset3{margin-left:330px;} .offset2{margin-left:230px;} .offset1{margin-left:130px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%;} .row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%;} .row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%;} .row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%;} .row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%;} .row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%;} .row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%;} .row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%;} .row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%;} .row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%;} .row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%;} .row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%;} .row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%;} .row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%;} .row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%;} .row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%;} .row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%;} .row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%;} .row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%;} .row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%;} .row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%;} .row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%;} .row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%;} .row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%;} .row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%;} .row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%;} .row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%;} .row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%;} .row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%;} .row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%;} .row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%;} .row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%;} .row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%;} .row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%;} .row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*="span"]+[class*="span"]{margin-left:30px;} input.span12, textarea.span12, .uneditable-input.span12{width:1156px;} input.span11, textarea.span11, .uneditable-input.span11{width:1056px;} input.span10, textarea.span10, .uneditable-input.span10{width:956px;} input.span9, textarea.span9, .uneditable-input.span9{width:856px;} input.span8, textarea.span8, .uneditable-input.span8{width:756px;} input.span7, textarea.span7, .uneditable-input.span7{width:656px;} input.span6, textarea.span6, .uneditable-input.span6{width:556px;} input.span5, textarea.span5, .uneditable-input.span5{width:456px;} input.span4, textarea.span4, .uneditable-input.span4{width:356px;} input.span3, textarea.span3, .uneditable-input.span3{width:256px;} input.span2, textarea.span2, .uneditable-input.span2{width:156px;} input.span1, textarea.span1, .uneditable-input.span1{width:56px;} .thumbnails{margin-left:-30px;} .thumbnails>li{margin-left:30px;} .row-fluid .thumbnails{margin-left:0;}}@media (max-width:979px){body{padding-top:0;} .navbar-fixed-top,.navbar-fixed-bottom{position:static;} .navbar-fixed-top{margin-bottom:20px;} .navbar-fixed-bottom{margin-top:20px;} .navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px;} .navbar .container{width:auto;padding:0;} .navbar .brand{padding-left:10px;padding-right:10px;margin:0 0 0 -5px;} .nav-collapse{clear:both;} .nav-collapse .nav{float:none;margin:0 0 10px;} .nav-collapse .nav>li{float:none;} .nav-collapse .nav>li>a{margin-bottom:2px;} .nav-collapse .nav>.divider-vertical{display:none;} .nav-collapse .nav .nav-header{color:#777777;text-shadow:none;} .nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} .nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} .nav-collapse .dropdown-menu li+li a{margin-bottom:2px;} .nav-collapse .nav>li>a:hover,.nav-collapse .dropdown-menu a:hover{background-color:#f2f2f2;} .navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999999;} .navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:hover{background-color:#111111;} .nav-collapse.in .btn-group{margin-top:5px;padding:0;} .nav-collapse .dropdown-menu{position:static;top:auto;left:auto;float:none;display:none;max-width:none;margin:0 15px;padding:0;background-color:transparent;border:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} .nav-collapse .open>.dropdown-menu{display:block;} .nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none;} .nav-collapse .dropdown-menu .divider{display:none;} .nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none;} .nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);} .navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111111;border-bottom-color:#111111;} .navbar .nav-collapse .nav.pull-right{float:none;margin-left:0;} .nav-collapse,.nav-collapse.collapse{overflow:hidden;height:0;} .navbar .btn-navbar{display:block;} .navbar-static .navbar-inner{padding-left:10px;padding-right:10px;}}@media (min-width:980px){.nav-collapse.collapse{height:auto !important;overflow:visible !important;}} diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/css/d3.geomap.css b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/css/d3.geomap.css new file mode 100644 index 00000000..ff005b50 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/css/d3.geomap.css @@ -0,0 +1,29 @@ +/*! + * d3.geomap + * https://github.com/yaph/d3-geomap/blob/master/LICENSE + * MIT licensed + * Copyright (C) 2015 by Ramiro Gómez (http://ramiro.org/) + */ +text { + fill: #333; + font-size: 12px; } + +.background { + fill: none; + pointer-events: all; } + +.unit { + cursor: pointer; + fill: #ccc; + stroke: #000; + stroke-width: 0.4px; } + +.legend-bg { + fill: #fff; + fill-opacity: 0.8; } + +.legend-bar { + stroke: #333; + stroke-width: 1px; } + +/*# sourceMappingURL=geomap.css.map */ diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/css/igviz.css b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/css/igviz.css new file mode 100644 index 00000000..0fa42f15 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/css/igviz.css @@ -0,0 +1,80 @@ +#rect { + fill: none; + stroke: rgb(0, 0, 0); + stroke-width: 2; +} + +#rectCurve { + fill: none; + stroke: rgb(0, 0, 0); + stroke-width: 0.5; +} + +.axis path, +.axis line { + fill: none; + shape-rendering: crispEdges; + stroke: grey; + stroke-width: 2; +} + +.line { + fill: none; + stroke: steelblue; + stroke-width: 1.5px; +} + + +.label{ + font-size: 16.844px !important; +} + +/* arc tween shit*/ +.background { + fill: #FFFFFF; + fill-opacity: 0.01; +} + +.component { + fill: #e1e1e1; +} + +.component .label { + font-family: Myriad, "Helvetic Neue", Helvetica, Arial; + text-anchor: middle; + fill: #0000FF; +} + +.arc { + stroke-weight:0.1; + fill: #4e8fff; +} + + +.arc2 { + stroke-weight:0.1; + fill: #3660b0; +} + + +.label { + font-family: Myriad, "Helvetic Neue", Helvetica, Arial; + text-anchor: middle; +} + +.labelArc { + font-family: Myriad, "Helvetic Neue", Helvetica, Arial; + text-anchor: middle; + fill: #0000FF; +} + +.tooltipClass { + background-color: #e5f2ff; + padding: 4px 8px; + +} +.tooltipClass p{ + margin: 0; + padding: 0; + +} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/gadget.json b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/gadget.json new file mode 100644 index 00000000..3a0dea46 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/gadget.json @@ -0,0 +1 @@ +{"id":"IoTServerTemperatureStats","title":"IoTServerTemperatureStats","type":"gadget","thumbnail":"local://images/gadgetIcon.png","data":{"url":"local://store/carbon.super/gadget/IoTServerTemperatureStats/index.xml"}} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/index.xml b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/index.xml new file mode 100644 index 00000000..9cc11d51 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/index.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + Bar Chart + + + + + + + + + + + + + + + + + +
+ + + + ]]> +
+
+ + diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/VizGrammar.min.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/VizGrammar.min.js new file mode 100644 index 00000000..b7d10b77 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/VizGrammar.min.js @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2016, 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. + */ +function getPieMark(a,b){var c;if("donut"==a.mode)var c=a.width/5;else var c=0;var d={type:"arc",from:{data:a.title},properties:{update:{x:{field:{group:"width"},mult:.5},y:{field:{group:"height"},mult:.5},startAngle:{field:"layout_start"},endAngle:{field:"layout_end"},innerRadius:{value:c},outerRadius:{value:.4*a.width},fill:{scale:"color",field:b.names[a.color]},fillOpacity:{value:1}},hover:{fillOpacity:{value:.8}}}};return d}function getPieText(a,b){var c={type:"text",from:{data:a.title},properties:{update:{x:{field:{group:"width"},mult:.5},y:{field:{group:"height"},mult:.5},radius:{value:.5*a.width},theta:{field:"layout_mid"},fill:{value:"#000"},align:{value:"center"},baseline:{value:"middle"},text:{field:b.names[a.x],mult:.5}}}};return c}function getAreaMark(a,b){var c={type:"area",from:{data:a.title},properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},y2:{scale:"y",value:0},fill:{value:a.markColor},strokeWidth:{value:2},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5}}}};return c}function getBarMark(a,b){var c={type:"rect",from:{data:a.title},properties:{update:{x:{scale:"x",field:b.names[a.x]},width:{scale:"x",band:!0,offset:-1},y:{scale:"y",field:b.names[a.y]},y2:{scale:"y",value:0},fill:{value:"steelblue"},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5}}}};return c}function getStackBarMark(a,b){var c={type:"rect",from:{data:"table",transform:[{type:"stack",groupby:[b.names[a.x]],sortby:[b.names[a.color]],field:b.names[a.y]}]},properties:{update:{x:{scale:"x",field:b.names[a.x]},width:{scale:"x",band:!0,offset:-1},y:{scale:"y",field:"layout_start"},y2:{scale:"y",field:"layout_end"},fill:{scale:"color",field:b.names[a.color]},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5}}}};return c}function getLineMark(a,b){var c;return c=-1!=a.color?{type:"group",from:{data:a.title,transform:[{type:"facet",groupby:[b.names[a.color]]}]},marks:[{type:"line",properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},stroke:{scale:"color",field:b.names[a.color]},strokeWidth:{value:2},strokeOpacity:{value:1}},hover:{strokeOpacity:{value:.5}}}}]}:{type:"line",from:{data:a.title},properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},stroke:{value:a.markColor},strokeWidth:{value:2},strokeOpacity:{value:1}},hover:{strokeOpacity:{value:.5}}}}}function getTopoJson(a,b){var c,d=a.width,e=a.height,f=a.charts[0].mapType,g="mercator";"usa"==f?(d=a.width-160,e=a.height-130,c=a.height+270,g="albersUsa"):"europe"==f?(d=(a.width/2+100)/2,e=a.height+150,c=a.height+50):(c=a.width/640*120,d=a.width/2+10,e=a.height/2+40);var h=a.geoCodesUrl,i={name:"geoData",url:h,format:{type:"topojson",feature:"units"},transform:[{type:"geopath",value:"data",scale:c,translate:[d,e],projection:g},{type:"lookup",keys:["id"],on:a.title,onKey:b.names[a.x],as:["zipped"],"default":{v:null,country:"No data"}}]};return i}function getMapMark(a,b){var c=[{name:"map",type:"path",from:{data:"geoData"},properties:{enter:{path:{field:"layout_path"}},update:{fill:{rule:[{predicate:{name:"isNotNull",id:{field:"zipped.v"}},scale:"color",field:"zipped.v"},{value:"grey"}]}},hover:{fill:{value:"#989898"}}}},{type:"group",from:{data:a.title,transform:[{type:"filter",test:"datum."+b.names[a.x]+" == tooltipSignal.datum."+b.names[a.x]}]},properties:{update:{x:{signal:"tooltipSignal.x",offset:-5},y:{signal:"tooltipSignal.y",offset:20},width:{value:a.toolTip.width},height:{value:a.toolTip.height},fill:{value:a.toolTip.color}}},marks:[{type:"text",properties:{update:{x:{value:6},y:{value:14},text:{template:"{{tooltipSignal.datum.unitName}} {{tooltipSignal.datum.v}}"},fill:{value:"black"}}}}]}];return c}function getMapSignals(){var a=[{name:"tooltipSignal",init:{expr:"{x: 0, y: 0, datum: {} }"},streams:[{type:"@map:mouseover",expr:"{x: eventX(), y: eventY(), datum: eventItem().datum.zipped}"},{type:"@map:mouseout",expr:"{x: 0, y: 0, datum: {} }"}]}];return a}function getMapPredicates(){var a={name:"isNotNull",type:"!=",operands:[{value:null},{arg:"id"}]};return a}function getMapLegends(a,b){var c={fill:"color",title:b.names[a.y],properties:{gradient:{stroke:{value:"transparent"}},title:{fontSize:{value:14}},legend:{x:{value:0},y:{value:a.height-40}}}};return c}function loadGeoMapCodes(a){var b,c=new XMLHttpRequest;return c.overrideMimeType("application/json"),c.open("GET",a,!1),c.onreadystatechange=function(){4==c.readyState&&"200"==c.status&&(b=JSON.parse(c.responseText))},c.send(null),b}function getMapCode(a,b,c){if("world"==b||"europe"==b)for(d=0;d
+ +
+
+
+
Device Statistics
+ {{unit "iot.unit.device.stats" device=device}} +
+
+
Policy Compliance +
+
+
Policies
+
+ +
+
+ No policies found +
+
+
+
+
+ + + + + Add device specific policy +
+
+
Operations Log
+
+ +
+
+ Not available yet +
+
+
+
+
+
+
+
"),$("#wrapper").append("
"),$tip=$("#tip"),$tip.empty();var i=g.datum,j="";for(var k in i)if(i.hasOwnProperty(k))if(void 0!=f){for(var l=0;l"+f[l]+" ("+k+"):"+i[k]+"

";break}}else e.names[d.x]==k&&(j+="

X ("+k+"):"+i[k]+"

"),e.names[d.y]==k&&(j+="

Y ("+k+"):"+i[k]+"

");$tip.append(j);var n=h.width,o=h.height,p=$('.marks[style*="width"]');p.length>0&&(n=parseFloat($(".marks")[0].style.width),o=parseFloat($(".marks")[0].style.height));var q,r=$tip.width(),s=$tip.height(),t=g.bounds.x2+d.padding.left+r,u=o-g.bounds.y2-d.padding.top+s,v=g.bounds.y2+d.padding.top-s;q=t>n?g.bounds.x2+d.padding.left-r:g.bounds.x2+d.padding.left,u>o&&(v=g.bounds.y2+d.padding.top),$tip.css({left:q,top:v}).show()}else $("#wrapper #tip").length&&$tip.remove(),$(a).closest("#wrapper").length&&$(a).unwrap()})}var arc=function(a,b){this.metadata=a[0].metadata;var c=[];this.spec={},b=checkConfig(b,this.metadata),this.config=b,a[0].name=b.title,a[0].transform=[{type:"pie",field:this.metadata.names[b.x]}];var d=[];null==b.colorDomain&&(b.colorDomain={data:b.title,field:this.metadata.names[b.color]});var e={name:"color",type:"ordinal",domain:b.colorDomain,range:b.colorScale};d.push(e),c.push(getPieMark(b,this.metadata)),c.push(getPieText(b,this.metadata));var f="Legend";"table"!=b.title&&(f=b.title);var g=[{fill:"color",title:"Legend",offset:20,properties:{symbols:{fillOpacity:{value:.5},stroke:{value:"transparent"}}}}];this.spec.legends=g,this.spec.width=b.width,this.spec.height=b.height,this.spec.data=a,this.spec.scales=d,this.spec.padding=b.padding,this.spec.marks=c};arc.prototype.draw=function(a,b){var c=function(c){if(this.view=c({el:a}).renderer(this.config.renderer).update(),null!=b)for(var d=0;d=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h-1&&(h=!0,f.splice(j,1)),h||f.splice(f.length-1,1)}else this.view.data(this.config.title).insert([a[i]]),this.view.update()}var k,l=function(a){return a[b]==k};for(i=0;i=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h

"+c+"

";document.getElementById(a).innerHTML=d,this.view=b},number.prototype.insert=function(a){document.getElementById(this.view).innerHTML=a[a.length-1][this.metadata.names[this.config.x]]};var scatter=function(a,b){this.metadata=a[0].metadata;var c=[];this.spec={},b=checkConfig(b,this.metadata),this.config=b,a[0].name=b.title;var d={name:"x",type:this.metadata.types[b.x],range:"width",zero:b.zero,domain:{data:b.title,field:this.metadata.names[b.x]}},e={name:"y",type:this.metadata.types[b.y],range:"height",zero:b.zero,domain:{data:b.title,field:this.metadata.names[b.y]}},f={name:"size",type:"linear",range:[0,576],domain:{data:b.title,field:this.metadata.names[b.size]}},g={name:"color",type:"linear",range:[b.minColor,b.maxColor],domain:{data:b.title,field:this.metadata.names[b.color]}},h=[d,e,f,g],i=[{type:"x",scale:"x",grid:b.grid,title:b.xTitle},{type:"y",scale:"y",grid:b.grid,title:b.yTitle}];c.push(getScatterMark(b,this.metadata)),this.spec.width=b.width,this.spec.height=b.height,this.spec.axes=i,this.spec.data=a,this.spec.scales=h,this.spec.padding=b.padding,this.spec.marks=c};scatter.prototype.draw=function(a,b){var c=function(c){if(this.view=c({el:a}).renderer(this.config.renderer).update(),0!=this.config.tooltip&&bindTooltip(a,"symbol",this.view,this.config,this.metadata,["x","y","size"]),null!=b)for(var d=0;d=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h-1&&(j=!0,g.splice(k,1)),j||g.splice(g.length-1,1)}else this.view.data(this.config.title).insert([a[i]]),this.view.update()}var l,m=function(a){return a[b]==l};for(i=0;ib.maxLength){var k=d3.select("tbody").selectAll("tr").data().slice(d3.select("tbody").selectAll("tr").data().length-b.maxLength,b.maxLength);d3.select("tbody").selectAll("tr").data(k,function(a){return a}).remove()}}; \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/d3.min.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/d3.min.js new file mode 100644 index 00000000..e3ee0f91 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/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?0/0:+n}function e(n){return!isNaN(n)}function r(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 u(n){return n.length}function i(n){for(var t=1;n*t%1;)t*=10;return t}function o(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function a(){this._=Object.create(null)}function c(n){return(n+="")===da||n[0]===ma?ma+n:n}function l(n){return(n+="")[0]===ma?n.slice(1):n}function s(n){return c(n)in this._}function f(n){return(n=c(n))in this._&&delete this._[n]}function h(){var n=[];for(var t in this._)n.push(l(t));return n}function g(){var n=0;for(var t in this._)++n;return n}function p(){for(var n in this._)return!1;return!0}function v(){this._=Object.create(null)}function d(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function m(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=ya.length;r>e;++e){var u=ya[e]+t;if(u in n)return u}}function y(){}function M(){}function x(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 O(n){return xa(n,Aa),n}function Y(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.slice(0,a));var l=Ca.get(n);return l&&(n=l,c=V),a?t?u:r:t?y:i}function Z(n,t){return function(e){var r=ta.event;ta.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ta.event=r}}}function V(n,t){var e=Z(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function X(){var n=".dragsuppress-"+ ++qa,t="click"+n,e=ta.select(oa).on("touchmove"+n,b).on("dragstart"+n,b).on("selectstart"+n,b);if(za){var r=ia.style,u=r[za];r[za]="none"}return function(i){if(e.on(n,null),za&&(r[za]=u),i){var o=function(){e.on(t,null)};e.on(t,function(){b(),o()},!0),setTimeout(o,0)}}}function $(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>La&&(oa.scrollX||oa.scrollY)){e=ta.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();La=!(u.f||u.e),e.remove()}return La?(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 B(){return ta.event.changedTouches[0].identifier}function W(){return ta.event.target}function J(){return oa}function G(n){return n>0?1:0>n?-1:0}function K(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function Q(n){return n>1?0:-1>n?Da:Math.acos(n)}function nt(n){return n>1?ja:-1>n?-ja:Math.asin(n)}function tt(n){return((n=Math.exp(n))-1/n)/2}function et(n){return((n=Math.exp(n))+1/n)/2}function rt(n){return((n=Math.exp(2*n))-1)/(n+1)}function ut(n){return(n=Math.sin(n/2))*n}function it(){}function ot(n,t,e){return this instanceof ot?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ot?new ot(n.h,n.s,n.l):xt(""+n,bt,ot):new ot(n,t,e)}function at(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 dt(u(n+120),u(n),u(n-120))}function ct(n,t,e){return this instanceof ct?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof ct?new ct(n.h,n.c,n.l):n instanceof st?ht(n.l,n.a,n.b):ht((n=_t((n=ta.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new ct(n,t,e)}function lt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new st(e,Math.cos(n*=Fa)*t,Math.sin(n)*t)}function st(n,t,e){return this instanceof st?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof st?new st(n.l,n.a,n.b):n instanceof ct?lt(n.h,n.c,n.l):_t((n=dt(n)).r,n.g,n.b):new st(n,t,e)}function ft(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=gt(u)*Ja,r=gt(r)*Ga,i=gt(i)*Ka,new dt(vt(3.2404542*u-1.5371385*r-.4985314*i),vt(-.969266*u+1.8760108*r+.041556*i),vt(.0556434*u-.2040259*r+1.0572252*i))}function ht(n,t,e){return n>0?new ct(Math.atan2(e,t)*Ha,Math.sqrt(t*t+e*e),n):new ct(0/0,0/0,n)}function gt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function pt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function vt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function dt(n,t,e){return this instanceof dt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof dt?new dt(n.r,n.g,n.b):xt(""+n,dt,at):new dt(n,t,e)}function mt(n){return new dt(n>>16,255&n>>8,255&n)}function yt(n){return mt(n)+""}function Mt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function xt(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(St(u[0]),St(u[1]),St(u[2]))}return(i=tc.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(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 bt(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 ot(r,u,c)}function _t(n,t,e){n=wt(n),t=wt(t),e=wt(e);var r=pt((.4124564*n+.3575761*t+.1804375*e)/Ja),u=pt((.2126729*n+.7151522*t+.072175*e)/Ga),i=pt((.0193339*n+.119192*t+.9503041*e)/Ka);return st(116*u-16,500*(r-u),200*(u-i))}function wt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function St(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function kt(n){return"function"==typeof n?n:function(){return n}}function Et(n){return n}function At(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Nt(t,e,n,r)}}function Nt(n,t,e,r){function u(){var n,t=c.status;if(!t&&zt(c)||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=ta.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!oa.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=ta.event;ta.event=n;try{o.progress.call(i,c)}finally{ta.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?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(ra(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 s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),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},ta.rebind(i,o,"on"),null==r?i:i.get(Ct(r))}function Ct(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function zt(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qt(){var n=Lt(),t=Tt()-n;t>24?(isFinite(t)&&(clearTimeout(ic),ic=setTimeout(qt,t)),uc=0):(uc=1,ac(qt))}function Lt(){var n=Date.now();for(oc=ec;oc;)n>=oc.t&&(oc.f=oc.c(n-oc.t)),oc=oc.n;return n}function Tt(){for(var n,t=ec,e=1/0;t;)t.f?t=n?n.n=t.n:ec=t.n:(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],o=0,a=r[0],c=0;u>0&&a>0&&(c+a+1>t&&(a=Math.max(1,t-c)),i.push(n.substring(u-=a,u+a)),!((c+=a+1)>t));)a=r[o=(o+1)%r.length];return i.reverse().join(e)}:Et;return function(n){var e=lc.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",c=e[4]||"",l=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(l||"0"===r&&"="===o)&&(l=r="0",o="="),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":y=!1;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=sc.get(g)||Ut;var M=l&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>p){var c=ta.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=y?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!l&&f&&(x=i(x,1/0));var S=v.length+x.length+b.length+(M?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return M&&(x=i(k+x,k.length?s-b.length:1/0)),u+=v,n=x+b,("<"===o?u+n+k:">"===o?k+u+n:"^"===o?k.substring(0,S>>=1)+u+n+k.substring(S):u+(M?n:k+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ft(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 hc(e-1)),1),e}function i(n,e){return t(n=new hc(+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{hc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{hc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ht(n);return c.floor=c,c.round=Ht(r),c.ceil=Ht(u),c.offset=Ht(i),c.range=a,n}function Ht(n){return function(t,e){try{hc=jt;var r=new jt;return r._=t,n(r,e)._}finally{hc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++aa;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=C[o in pc?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){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.slice(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.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,N.c.toString(),t,r)}function c(n,t,r){return e(n,N.x.toString(),t,r)}function l(n,t,r){return e(n,N.X.toString(),t,r)}function s(n,t,e){var r=M.get(t.slice(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{hc=jt;var t=new hc;return t._=n,r(t)}finally{hc=Date}}var r=t(n);return e.parse=function(n){try{hc=jt;var t=r.parse(n);return t&&t._}finally{hc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var M=ta.map(),x=It(v),b=Zt(v),_=It(d),w=Zt(d),S=It(m),k=Zt(m),E=It(y),A=Zt(y);p.forEach(function(n,t){M.set(n.toLowerCase(),t)});var N={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 Yt(n.getDate(),t,2)},e:function(n,t){return Yt(n.getDate(),t,2)},H:function(n,t){return Yt(n.getHours(),t,2)},I:function(n,t){return Yt(n.getHours()%12||12,t,2)},j:function(n,t){return Yt(1+fc.dayOfYear(n),t,3)},L:function(n,t){return Yt(n.getMilliseconds(),t,3)},m:function(n,t){return Yt(n.getMonth()+1,t,2)},M:function(n,t){return Yt(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Yt(n.getSeconds(),t,2)},U:function(n,t){return Yt(fc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Yt(fc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Yt(n.getFullYear()%100,t,2)},Y:function(n,t){return Yt(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},C={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:s,S:re,U:Xt,w:Vt,W:$t,x:c,X:l,y:Wt,Y:Bt,Z:Jt,"%":oe};return t}function Yt(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 It(n){return new RegExp("^(?:"+n.map(ta.requote).join("|")+")","i")}function Zt(n){for(var t=new a,e=-1,r=n.length;++e68?1900:2e3)}function Kt(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=0|va(t)/60,u=va(t)%60;return e+Yt(r,"0",2)+Yt(u,"0",2)}function oe(n,t,e){dc.lastIndex=0;var r=dc.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,c=Math.cos(t),l=Math.sin(t),s=i*l,f=u*c+s*Math.cos(a),h=s*o*Math.sin(a);_c.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;wc.point=function(o,a){wc.point=n,r=(t=o)*Fa,u=Math.cos(a=(e=a)*Fa/2+Da/4),i=Math.sin(a)},wc.lineEnd=function(){n(t,e)}}function pe(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 ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(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 me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function Me(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 xe(n){return[Math.atan2(n[1],n[0]),nt(n[2])]}function be(n,t){return va(n[0]-t[0])a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new qe(e,n,null,!0),l=new qe(e,null,c,!1);c.o=l,i.push(c),o.push(l),c=new qe(r,n,null,!1),l=new qe(r,null,c,!0),c.o=l,i.push(c),o.push(l)}}),o.sort(t),ze(i),ze(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].e=c=!c;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,l=s.length;l>a;++a)u.point((f=s[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var a=s.length-1;a>=0;--a)u.point((f=s[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ze(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r0){for(b||(i.polygonStart(),b=!0),i.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Te))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=ta.merge(g);var n=Fe(m,p);g.length?(b||(i.polygonStart(),b=!0),Ce(g,De,n,e,i)):n&&(b||(i.polygonStart(),b=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),b&&(i.polygonEnd(),b=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},M=Re(),x=t(M),b=!1;return y}}function Te(n){return n.length>1}function Re(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:y,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function De(n,t){return((n=n.x)[0]<0?n[1]-ja-Ta:ja-n[1])-((t=t.x)[0]<0?t[1]-ja-Ta:ja-t[1])}function Pe(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?Da:-Da,c=va(i-e);va(c-Da)0?ja:-ja),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Da&&(va(e-u)Ta?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 je(n,t,e,r){var u;if(null==n)u=e*ja,r.point(-Da,u),r.point(0,u),r.point(Da,u),r.point(Da,0),r.point(Da,-u),r.point(0,-u),r.point(-Da,-u),r.point(-Da,0),r.point(-Da,u);else if(va(n[0]-t[0])>Ta){var i=n[0]a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+Da/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=l[d];var m=n[0],y=n[1]/2+Da/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=b>=0?1:-1,w=_*b,S=w>Da,k=p*M;if(_c.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),i+=S?b+_*Pa:b,S^h>=e^m>=e){var E=de(pe(f),pe(n));Me(E);var A=de(u,E);Me(A);var N=(S^b>=0?-1:1)*nt(A[2]);(r>N||r===N&&(E[0]||E[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=m,p=M,v=x,f=n}}return(-Ta>i||Ta>i&&0>_c)^1&o}function He(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=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?Da:-Da),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(be(e,g)||be(p,g))&&(p[0]+=Ta,p[1]+=Ta,v=t(p[0],p[1]))),v!==c)s=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))||(s=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&&be(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),M=m*m-y*(ve(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=ye(d,(-m-x)/y);if(me(b,p),b=xe(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=va(A-Da)A;if(!N&&k>E&&(_=k,k=E,E=_),C?N?k+E>0^b[1]<(va(b[0]-w)Da^(w<=b[0]&&b[0]<=S)){var z=ye(d,(-m+x)/y);return me(z,p),[b,xe(z)]}}}function u(t,e){var r=o?n:Da-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=va(i)>Ta,c=gr(n,6*Fa);return Le(t,e,c,o?[0,-n]:[-Da,n-Da])}function Oe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,l=o.y,s=a.x,f=a.y,h=0,g=1,p=s-c,v=f-l;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-l,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-l,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:l+h*v}),1>g&&(u.b={x:c+g*p,y:l+g*v}),u}}}}}}function Ye(n,t,e,r){function u(r,u){return va(r[0]-n)0?0:3:va(r[0]-e)0?2:1:va(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,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&K(l,i,n)>0&&++t:i[1]<=r&&K(l,i,n)<0&&--t,l=i;return 0!==t}function l(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&a.point(n,t)}function h(){C.point=p,d&&d.push(m=[]),S=!0,w=!1,b=_=0/0}function g(){v&&(p(y,M),x&&w&&A.rejoin(),v.push(A.buffer())),C.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Uc,Math.min(Uc,n)),t=Math.max(-Uc,Math.min(Uc,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};N(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)}b=n,_=t,w=e}var v,d,m,y,M,x,b,_,w,S,k,E=a,A=Re(),N=Oe(n,t,e,r),C={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=ta.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,l,a),a.polygonEnd()),v=d=m=null}};return C}}function Ie(n){var t=0,e=Da/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Da/180,e=n[1]*Da/180):[180*(t/Da),180*(e/Da)]},u}function Ze(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,nt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Fc+=u*n-r*t,r=n,u=t}var t,e,r,u;Zc.point=function(i,o){Zc.point=n,t=r=i,e=u=o},Zc.lineEnd=function(){n(t,e)}}function Xe(n,t){Hc>n&&(Hc=n),n>Yc&&(Yc=n),Oc>t&&(Oc=t),t>Ic&&(Ic=t)}function $e(){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=Be(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=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function We(n,t){Ec+=n,Ac+=t,++Nc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);Cc+=o*(t+n)/2,zc+=o*(e+r)/2,qc+=o,We(t=n,e=r)}var t,e;Xc.point=function(r,u){Xc.point=n,We(t=r,e=u)}}function Ge(){Xc.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);Cc+=o*(r+n)/2,zc+=o*(u+t)/2,qc+=o,o=u*n-r*t,Lc+=o*(r+n),Tc+=o*(u+t),Rc+=3*o,We(r=n,u=t)}var t,e,r,u;Xc.point=function(i,o){Xc.point=n,We(t=r=i,e=u=o)},Xc.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Pa)}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:y};return a}function nr(n){function t(n){return(a?r:e)(n)}function e(t){return rr(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(){M=0/0,S.point=i,t.lineStart()}function i(e,r){var i=pe([e,r]),o=n(e,r);u(M,x,y,b,_,w,M=o[0],x=o[1],y=e,b=i[0],_=i[1],w=i[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=l,S.lineEnd=s}function l(n,t){i(f=n,h=t),g=M,p=x,v=b,d=_,m=w,S.point=i}function s(){u(M,x,y,b,_,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,M,x,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,l,s,f,h,g,p,v,d,m){var y=s-t,M=f-e,x=y*y+M*M;if(x>4*i&&d--){var b=a+g,_=c+p,w=l+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),E=va(va(w)-1)i||va((y*z+M*q)/x-.5)>.3||o>a*g+c*p+l*v)&&(u(t,e,r,a,c,l,N,C,E,b/=S,_/=S,w,d,m),m.point(N,C),u(N,C,E,b,_,w,s,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Fa),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function tr(n){var t=nr(function(t,e){return n([t*Ha,e*Ha])});return function(n){return or(t(n))}}function er(n){this.stream=n}function rr(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 ur(n){return ir(function(){return n})()}function ir(n){function t(n){return n=a(n[0]*Fa,n[1]*Fa),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*Ha,n[1]*Ha]}function r(){a=Ae(o=lr(m,y,M),i);var n=i(v,d);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=nr(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,M=0,x=Pc,b=Et,_=null,w=null;return t.stream=function(n){return s&&(s.valid=!1),s=or(x(o,f(b(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(x=null==n?(_=n,Pc):He((_=+n)*Fa),u()):_},t.clipExtent=function(n){return arguments.length?(w=n,b=n?Ye(n[0][0],n[0][1],n[1][0],n[1][1]):Et,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*Fa,d=n[1]%360*Fa,r()):[v*Ha,d*Ha]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Fa,y=n[1]%360*Fa,M=n.length>2?n[2]%360*Fa:0,r()):[m*Ha,y*Ha,M*Ha]},ta.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function or(n){return rr(n,function(t,e){n.point(t*Fa,e*Fa)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>Da?n-Pa:-Da>n?n+Pa:n,t]}function lr(n,t,e){return n?t||e?Ae(fr(n),hr(t,e)):fr(n):t||e?hr(t,e):cr}function sr(n){return function(t,e){return t+=n,[t>Da?t-Pa:-Da>t?t+Pa:t,e]}}function fr(n){var t=sr(n);return t.invert=sr(-n),t}function hr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),nt(s*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,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),nt(s*r-a*u)]},e}function gr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=pr(e,u),i=pr(e,i),(o>0?i>u:u>i)&&(u+=o*Pa)):(u=n+o*Pa,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=xe([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function pr(n,t){var e=pe(t);e[0]-=n,Me(e);var r=Q(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Ta)%(2*Math.PI)}function vr(n,t,e){var r=ta.range(n,t-Ta,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function dr(n,t,e){var r=ta.range(n,t-Ta,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function mr(n){return n.source}function yr(n){return n.target}function Mr(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),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(ut(r-t)+u*o*ut(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*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Ha,Math.atan2(o,Math.sqrt(r*r+u*u))*Ha]}:function(){return[n*Ha,t*Ha]};return p.distance=h,p}function xr(){function n(n,u){var i=Math.sin(u*=Fa),o=Math.cos(u),a=va((n*=Fa)-t),c=Math.cos(a);$c+=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;Bc.point=function(u,i){t=u*Fa,e=Math.sin(i*=Fa),r=Math.cos(i),Bc.point=n},Bc.lineEnd=function(){Bc.point=Bc.lineEnd=y}}function br(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 _r(n,t){function e(n,t){o>0?-ja+Ta>t&&(t=-ja+Ta):t>ja-Ta&&(t=ja-Ta);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(Da/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=G(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-ja]},e):Sr}function wr(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 va(u)u;u++){for(;r>1&&K(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function zr(n,t){return n[0]-t[0]||n[1]-t[1]}function qr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Lr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function Tr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Rr(){tu(this),this.edge=this.site=this.circle=null}function Dr(n){var t=ol.pop()||new Rr;return t.site=n,t}function Pr(n){Xr(n),rl.remove(n),ol.push(n),tu(n)}function Ur(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Pr(n);for(var c=i;c.circle&&va(e-c.circle.x)s;++s)l=a[s],c=a[s-1],Kr(l.edge,c.site,l.site,u);c=a[0],l=a[f-1],l.edge=Jr(c.site,l.site,null,u),Vr(c),Vr(l)}function jr(n){for(var t,e,r,u,i=n.x,o=n.y,a=rl._;a;)if(r=Fr(a,o)-i,r>Ta)a=a.L;else{if(u=i-Hr(a,o),!(u>Ta)){r>-Ta?(t=a.P,e=a):u>-Ta?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(rl.insert(t,c),t||e){if(t===e)return Xr(t),e=Dr(t.site),rl.insert(c,e),c.edge=e.edge=Jr(t.site,c.site),Vr(t),Vr(e),void 0;if(!e)return c.edge=Jr(t.site,c.site),void 0;Xr(t),Xr(e);var l=t.site,s=l.x,f=l.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,M=v*v+d*d,x={x:(d*y-g*M)/m+s,y:(h*M-v*y)/m+f};Kr(e.edge,l,p,x),c.edge=Jr(l,n,null,x),e.edge=Jr(n,p,null,x),Vr(t),Vr(e)}}function Fr(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,l=c-t;if(!l)return a;var s=a-r,f=1/i-1/l,h=s/l;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*l)-c+l/2+u-i/2)))/f+r:(r+a)/2}function Hr(n,t){var e=n.N;if(e)return Fr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Or(n){this.site=n,this.edges=[]}function Yr(n){for(var t,e,r,u,i,o,a,c,l,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=el,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)s=a[o].end(),r=s.x,u=s.y,l=a[++o%c].start(),t=l.x,e=l.y,(va(r-t)>Ta||va(u-e)>Ta)&&(a.splice(o,0,new Qr(Gr(i.site,s,va(r-f)Ta?{x:f,y:va(t-f)Ta?{x:va(e-p)Ta?{x:h,y:va(t-h)Ta?{x:va(e-g)=-Ra)){var g=c*c+l*l,p=s*s+f*f,v=(f*g-l*p)/h,d=(c*p-s*g)/h,f=d+a,m=al.pop()||new Zr;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,M=il._;M;)if(m.yd||d>=a)return;if(h>p){if(i){if(i.y>=l)return}else i={x:d,y:c};e={x:d,y:l}}else{if(i){if(i.yr||r>1)if(h>p){if(i){if(i.y>=l)return}else i={x:(c-u)/r,y:c};e={x:(l-u)/r,y:l}}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||f>o||r>h||u>g)){if(p=n.point){var p,v=t-p[0],d=e-p[1],m=v*v+d*d;if(c>m){var y=Math.sqrt(c=m);r=t-y,u=e-y,i=t+y,o=e+y,a=p}}for(var M=n.nodes,x=.5*(s+h),b=.5*(f+g),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:l(n,s,f,x,b);break;case 1:l(n,x,f,h,b);break;case 2:l(n,s,b,x,g);break;case 3:l(n,x,b,h,g)}}}(n,r,u,i,o),a}function gu(n,t){n=ta.rgb(n),t=ta.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+Mt(Math.round(e+i*n))+Mt(Math.round(r+o*n))+Mt(Math.round(u+a*n))}}function pu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=mu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function vu(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function du(n,t){var e,r,u,i=ll.lastIndex=sl.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=ll.exec(n))&&(r=sl.exec(t));)(u=r.index)>i&&(u=t.slice(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:vu(e,r)})),i=sl.lastIndex;return ir;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function mu(n,t){for(var e,r=ta.interpolators.length;--r>=0&&!(e=ta.interpolators[r](n,t)););return e}function yu(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(mu(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 Mu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function xu(n){return function(t){return 1-n(1-t)}}function bu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function _u(n){return n*n}function wu(n){return n*n*n}function Su(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 ku(n){return function(t){return Math.pow(t,n)}}function Eu(n){return 1-Math.cos(n*ja)}function Au(n){return Math.pow(2,10*(n-1))}function Nu(n){return 1-Math.sqrt(1-n*n)}function Cu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Pa*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Pa/t)}}function zu(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function qu(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 Lu(n,t){n=ta.hcl(n),t=ta.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 lt(e+i*n,r+o*n,u+a*n)+""}}function Tu(n,t){n=ta.hsl(n),t=ta.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 at(e+i*n,r+o*n,u+a*n)+""}}function Ru(n,t){n=ta.lab(n),t=ta.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 ft(e+i*n,r+o*n,u+a*n)+""}}function Du(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Pu(n){var t=[n.a,n.b],e=[n.c,n.d],r=ju(t),u=Uu(t,e),i=ju(Fu(e,t,-u))||0;t[0]*e[1]180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:vu(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:vu(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:vu(g[0],p[0])},{i:e-2,x:vu(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 Qu(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 si(n){return n.reduce(fi,0)}function fi(n,t){return n+t[1]}function hi(n,t){return gi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function gi(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 pi(n){return[ta.min(n),ta.max(n)]}function vi(n,t){return n.value-t.value}function di(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function mi(n,t){n._pack_next=t,t._pack_prev=n}function yi(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 Mi(n){function t(n){s=Math.min(n.x-n.r,s),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)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(xi),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],wi(r,u,i),t(i),di(r,i),r._pack_prev=i,di(i,u),u=r._pack_next,o=3;l>o;o++){wi(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(yi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!yi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.ro;o++)i=e[o],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(bi)}}function xi(n){n._pack_next=n._pack_prev=n}function bi(n){delete n._pack_next,delete n._pack_prev}function _i(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 Ci(n,t,e){return n.a.parent===t.parent?n.a:e}function zi(n){return 1+ta.max(n,function(n){return n.y})}function qi(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Li(n){var t=n.children;return t&&t.length?Li(t[0]):n}function Ti(n){var t,e=n.children;return e&&(t=e.length)?Ti(e[t-1]):n}function Ri(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Di(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 Pi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ui(n){return n.rangeExtent?n.rangeExtent():Pi(n.range())}function ji(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 Fi(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 Hi(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:bl}function Oi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Oi:ji,c=r?Yu:Ou;return o=u(n,t,c,e),a=u(t,n,c,mu),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(Du)},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 Xi(n,t)},i.tickFormat=function(t,e){return $i(n,t,e)},i.nice=function(t){return Zi(n,t),u()},i.copy=function(){return Yi(n,t,e,r)},u()}function Ii(n,t){return ta.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Zi(n,t){return Fi(n,Hi(Vi(n,t)[2]))}function Vi(n,t){null==t&&(t=10);var e=Pi(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 Xi(n,t){return ta.range.apply(ta,Vi(n,t))}function $i(n,t,e){var r=Vi(n,t);if(e){var u=lc.exec(e);if(u.shift(),"s"===u[8]){var i=ta.formatPrefix(Math.max(va(r[0]),va(r[1])));return u[7]||(u[7]="."+Bi(i.scale(r[2]))),u[8]="f",e=ta.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Wi(u[8],r)),e=u.join("")}else e=",."+Bi(r[2])+"f";return ta.format(e)}function Bi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Wi(n,t){var e=Bi(t[2]);return n in _l?Math.abs(e-Bi(Math.max(va(t[0]),va(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Ji(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=Fi(r.map(u),e?Math:Sl);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Pi(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++0;h--)o.push(i(l)*h);for(l=0;o[l]c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return wl;arguments.length<2?t=wl:"function"!=typeof t&&(t=ta.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 Ji(n.copy(),t,e,r)},Ii(o,n)}function Gi(n,t,e){function r(t){return n(u(t))}var u=Ki(t),i=Ki(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 Xi(e,n)},r.tickFormat=function(n,t){return $i(e,n,t)},r.nice=function(n){return r.domain(Zi(e,n))},r.exponent=function(o){return arguments.length?(u=Ki(t=o),i=Ki(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Gi(n.copy(),t,e)},Ii(r,n)}function Ki(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Qi(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 ta.range(n.length).map(function(n){return t+e*n})}var u,i,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new a;for(var i,o=-1,c=r.length;++on?[0/0,0/0]:[n>0?a[n-1]:r[0],nt?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return to(n,t,e)},u()}function eo(n,t){function e(e){return e>=e?t[ta.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 eo(n,t)},e}function ro(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 Xi(n,t)},t.tickFormat=function(t,e){return $i(n,t,e)},t.copy=function(){return ro(n)},t}function uo(){return 0}function io(n){return n.innerRadius}function oo(n){return n.outerRadius}function ao(n){return n.startAngle}function co(n){return n.endAngle}function lo(n){return n&&n.padAngle}function so(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function fo(n,t,e,r,u){var i=n[0]-t[0],o=n[1]-t[1],a=(u?r:-r)/Math.sqrt(i*i+o*o),c=a*o,l=-a*i,s=n[0]+c,f=n[1]+l,h=t[0]+c,g=t[1]+l,p=(s+h)/2,v=(f+g)/2,d=h-s,m=g-f,y=d*d+m*m,M=e-r,x=s*g-h*f,b=(0>m?-1:1)*Math.sqrt(M*M*y-x*x),_=(x*m-d*b)/y,w=(-x*d-m*b)/y,S=(x*m+d*b)/y,k=(-x*d+m*b)/y,E=_-p,A=w-v,N=S-p,C=k-v;return E*E+A*A>N*N+C*C&&(_=S,w=k),[[_-c,w-l],[_*e/M,w*e/M]]}function ho(n){function t(t){function o(){l.push("M",i(n(s),a))}for(var c,l=[],s=[],f=-1,h=t.length,g=kt(e),p=kt(r);++f1&&u.push("H",r[0]),u.join("")}function mo(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 l=2;l9&&(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 To(n){return n.length<3?go(n):n[0]+_o(n,Lo(n))}function Ro(n){for(var t,e,r,u=-1,i=n.length;++ur)return s();var u=i[i.active];u&&(--i.count,delete i[i.active],u.event&&u.event.interrupt.call(n,n.__data__,u.index)),i.active=r,o.event&&o.event.start.call(n,n.__data__,t),o.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&v.push(r)}),h=o.ease,f=o.duration,ta.timer(function(){return p.c=l(e||1)?Ne:l,1},0,c)}function l(e){if(i.active!==r)return 1;for(var u=e/f,a=h(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,n.__data__,t),s()):void 0}function s(){return--i.count?delete i[r]:delete n[e],1}var f,h,g=o.delay,p=oc,v=[];return p.t=g+c,u>=g?a(u-g):(p.c=a,void 0)},0,c)}}function Bo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function Wo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function Jo(n){return n.toISOString()}function Go(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=ta.bisect(Wl,u);return i==Wl.length?[t.year,Vi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Wl[i-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=Ko(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Ko(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Pi(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],Ko(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Go(n.copy(),t,e)},Ii(r,n)}function Ko(n){return new Date(n)}function Qo(n){return JSON.parse(n.responseText)}function na(n){var t=ua.createRange();return t.selectNode(ua.body),t.createContextualFragment(n.responseText)}var ta={version:"3.5.3"};Date.now||(Date.now=function(){return+new Date});var ea=[].slice,ra=function(n){return ea.call(n)},ua=document,ia=ua.documentElement,oa=window;try{ra(ia.childNodes)[0].nodeType}catch(aa){ra=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{ua.createElement("div").style.setProperty("opacity",0,"")}catch(ca){var la=oa.Element.prototype,sa=la.setAttribute,fa=la.setAttributeNS,ha=oa.CSSStyleDeclaration.prototype,ga=ha.setProperty;la.setAttribute=function(n,t){sa.call(this,n,t+"")},la.setAttributeNS=function(n,t,e){fa.call(this,n,t,e+"")},ha.setProperty=function(n,t,e){ga.call(this,n,t+"",e)}}ta.ascending=n,ta.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},ta.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=r){e=r;break}for(;++ur&&(e=r)}else{for(;++u=r){e=r;break}for(;++ur&&(e=r)}return e},ta.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=r){e=r;break}for(;++ue&&(e=r)}else{for(;++u=r){e=r;break}for(;++ue&&(e=r)}return e},ta.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i=r){e=u=r;break}for(;++ir&&(e=r),r>u&&(u=r))}else{for(;++i=r){e=u=r;break}for(;++ir&&(e=r),r>u&&(u=r))}return[e,u]},ta.sum=function(n,t){var r,u=0,i=n.length,o=-1;if(1===arguments.length)for(;++o1?c/(s-1):void 0},ta.deviation=function(){var n=ta.variance.apply(this,arguments);return n?Math.sqrt(n):n};var pa=r(n);ta.bisectLeft=pa.left,ta.bisect=ta.bisectRight=pa.right,ta.bisector=function(t){return r(1===t.length?function(e,r){return n(t(e),r)}:t)},ta.shuffle=function(n,t,e){(i=arguments.length)<3&&(e=n.length,2>i&&(t=0));for(var r,u,i=e-t;i;)u=0|Math.random()*i--,r=n[i+t],n[i+t]=n[u+t],n[u+t]=r;return n},ta.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ta.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},ta.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=ta.min(arguments,u),e=new Array(t);++n=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var va=Math.abs;ta.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,u=[],o=i(va(e)),a=-1;if(n*=o,t*=o,e*=o,0>e)for(;(r=n+e*++a)>t;)u.push(r/o);else for(;(r=n+e*++a)=i.length)return r?r.call(u,o):e?o.sort(e):o;for(var l,s,f,h,g=-1,p=o.length,v=i[c++],d=new a;++g=i.length)return n;var r=[],u=o[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=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(ta.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return o[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},ta.set=function(n){var t=new v;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},o(v,{has:s,add:function(n){return this._[c(n+="")]=!0,n},remove:f,values:h,size:g,empty:p,forEach:function(n){for(var t in this._)n.call(this,l(t))}}),ta.behavior={},ta.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(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}},ta.event=null,ta.requote=function(n){return n.replace(Ma,"\\$&")};var Ma=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,xa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ba=function(n,t){return t.querySelector(n)},_a=function(n,t){return t.querySelectorAll(n)},wa=ia.matches||ia[m(ia,"matchesSelector")],Sa=function(n,t){return wa.call(n,t)};"function"==typeof Sizzle&&(ba=function(n,t){return Sizzle(n,t)[0]||null},_a=Sizzle,Sa=Sizzle.matchesSelector),ta.selection=function(){return Na};var ka=ta.selection.prototype=[];ka.select=function(n){var t,e,r,u,i=[];n=k(n);for(var o=-1,a=this.length;++o=0&&(e=n.slice(0,t),n=n.slice(t+1)),Ea.hasOwnProperty(e)?{space:Ea[e],local:n}:n}},ka.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ta.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(A(t,n[t]));return this}return this.each(A(n,t))},ka.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=z(n)).length,u=-1;if(t=e.classList){for(;++ur){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(T(e,n[e],t));return this}if(2>r)return oa.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(T(n,t,e))},ka.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},ka.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},ka.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},ka.append=function(n){return n=D(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},ka.insert=function(n,t){return n=D(n),t=k(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},ka.remove=function(){return this.each(P)},ka.data=function(n,t){function e(n,e){var r,u,i,o=n.length,f=e.length,h=Math.min(o,f),g=new Array(f),p=new Array(f),v=new Array(o);if(t){var d,m=new a,y=new Array(o);for(r=-1;++rr;++r)p[r]=U(e[r]);for(;o>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),l.push(g),s.push(v)}var r,u,i=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(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 S(u)},ka.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},ka.sort=function(n){n=F.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},ka.size=function(){var n=0;return H(this,function(){++n}),n};var Aa=[];ta.selection.enter=O,ta.selection.enter.prototype=Aa,Aa.append=ka.append,Aa.empty=ka.empty,Aa.node=ka.node,Aa.call=ka.call,Aa.size=ka.size,Aa.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(I(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(I(n,t,e))};var Ca=ta.map({mouseenter:"mouseover",mouseleave:"mouseout"});Ca.forEach(function(n){"on"+n in ua&&Ca.remove(n)});var za="onselectstart"in ua?null:m(ia.style,"userSelect"),qa=0;ta.mouse=function(n){return $(n,_())};var La=/WebKit/.test(oa.navigator.userAgent)?-1:0;ta.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=_().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return $(n,r)},ta.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]-M[0],e=r[1]-M[1],p|=n|e,M=r,g({type:"drag",x:r[0]+l[0],y:r[1]+l[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&ta.event.target===f),g({type:"dragend"}))}var l,s=this,f=ta.event.target,h=s.parentNode,g=e.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=ta.select(u()).on(i+d,a).on(o+d,c),y=X(),M=t(h,v);r?(l=r.apply(s,arguments),l=[l.x-M[0],l.y-M[1]]):l=[0,0],g({type:"dragstart"})}}var e=w(n,"drag","dragstart","dragend"),r=null,u=t(y,ta.mouse,J,"mousemove","mouseup"),i=t(B,ta.touch,W,"touchmove","touchend");return n.origin=function(t){return arguments.length?(r=t,n):r},ta.rebind(n,e,"on")},ta.touches=function(n,t){return arguments.length<2&&(t=_().touches),t?ra(t).map(function(t){var e=$(n,t);return e.identifier=t.identifier,e}):[]};var Ta=1e-6,Ra=Ta*Ta,Da=Math.PI,Pa=2*Da,Ua=Pa-Ta,ja=Da/2,Fa=Da/180,Ha=180/Da,Oa=Math.SQRT2,Ya=2,Ia=4;ta.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=et(v),o=i/(Ya*h)*(e*rt(Oa*t+v)-tt(v));return[r+o*l,u+o*s,i*e/et(Oa*t+v)]}return[r+n*l,u+n*s,i*Math.exp(Oa*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+Ia*f)/(2*i*Ya*h),p=(c*c-i*i-Ia*f)/(2*c*Ya*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))/Oa;return e.duration=1e3*y,e},ta.behavior.zoom=function(){function n(n){n.on(z,s).on(Xa+".zoom",h).on("dblclick.zoom",g).on(T,f)}function t(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function e(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function r(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=e(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function i(t,e,i,o){t.__chart__={x:k.x,y:k.y,k:k.k},r(Math.pow(2,o)),u(v=e,i),t=ta.select(t),N>0&&(t=t.transition().duration(N)),t.call(n.event)}function o(){x&&x.domain(M.range().map(function(n){return(n-k.x)/k.k}).map(M.invert)),S&&S.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function a(n){C++||n({type:"zoomstart"})}function c(n){o(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function l(n){--C||n({type:"zoomend"}),v=null}function s(){function n(){s=1,u(ta.mouse(r),h),c(o)}function e(){f.on(q,null).on(L,null),g(s&&ta.event.target===i),l(o)}var r=this,i=ta.event.target,o=R.of(r,arguments),s=0,f=ta.select(oa).on(q,n).on(L,e),h=t(ta.mouse(r)),g=X();Fl.call(r),a(o)}function f(){function n(){var n=ta.touches(p);return g=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=t(n))}),n}function e(){var t=ta.event.target;ta.select(t).on(x,o).on(_,h),w.push(t);for(var e=ta.event.changedTouches,r=0,u=e.length;u>r;++r)d[e[r].identifier]=null;var a=n(),c=Date.now();if(1===a.length){if(500>c-y){var l=a[0];i(p,l,d[l.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),b()}y=c}else if(a.length>1){var l=a[0],s=a[1],f=l[0]-s[0],g=l[1]-s[1];m=f*f+g*g}}function o(){var n,t,e,i,o=ta.touches(p);Fl.call(p);for(var a=0,l=o.length;l>a;++a,i=null)if(e=o[a],i=d[e.identifier]){if(t)break;n=e,t=i}if(i){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*g)}y=null,u(n,t),c(v)}function h(){if(ta.event.touches.length){for(var t=ta.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var u in d)return void n()}ta.selectAll(w).on(M,null),S.on(z,s).on(T,f),E(),l(v)}var g,p=this,v=R.of(p,arguments),d={},m=0,M=".zoom-"+ta.event.changedTouches[0].identifier,x="touchmove"+M,_="touchend"+M,w=[],S=ta.select(p),E=X();e(),a(v),S.on(z,null).on(T,e)}function h(){var n=R.of(this,arguments);m?clearTimeout(m):(p=t(v=d||ta.mouse(this)),Fl.call(this),a(n)),m=setTimeout(function(){m=null,l(n)},50),b(),r(Math.pow(2,.002*Za())*k.k),u(v,p),c(n)}function g(){var n=ta.mouse(this),e=Math.log(k.k)/Math.LN2;i(this,n,t(n),ta.event.shiftKey?Math.ceil(e)-1:Math.floor(e)+1)}var p,v,d,m,y,M,x,_,S,k={x:0,y:0,k:1},E=[960,500],A=Va,N=250,C=0,z="mousedown.zoom",q="mousemove.zoom",L="mouseup.zoom",T="touchstart.zoom",R=w(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=R.of(this,arguments),t=k;Ul?ta.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},a(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],u=v?v[0]:e/2,i=v?v[1]:r/2,o=ta.interpolateZoom([(u-k.x)/k.k,(i-k.y)/k.k,e/k.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:u-r[0]*a,y:i-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){l(n)}).each("end.zoom",function(){l(n)}):(this.__chart__=k,a(n),c(n),l(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},o(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:+t},o(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Va:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(d=t&&[+t[0],+t[1]],n):d},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(N=+t,n):N},n.x=function(t){return arguments.length?(x=t,M=t.copy(),k={x:0,y:0,k:1},n):x},n.y=function(t){return arguments.length?(S=t,_=t.copy(),k={x:0,y:0,k:1},n):S},ta.rebind(n,R,"on")};var Za,Va=[0,1/0],Xa="onwheel"in ua?(Za=function(){return-ta.event.deltaY*(ta.event.deltaMode?120:1)},"wheel"):"onmousewheel"in ua?(Za=function(){return ta.event.wheelDelta},"mousewheel"):(Za=function(){return-ta.event.detail},"MozMousePixelScroll");ta.color=it,it.prototype.toString=function(){return this.rgb()+""},ta.hsl=ot;var $a=ot.prototype=new it;$a.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ot(this.h,this.s,this.l/n)},$a.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ot(this.h,this.s,n*this.l)},$a.rgb=function(){return at(this.h,this.s,this.l)},ta.hcl=ct;var Ba=ct.prototype=new it;Ba.brighter=function(n){return new ct(this.h,this.c,Math.min(100,this.l+Wa*(arguments.length?n:1)))},Ba.darker=function(n){return new ct(this.h,this.c,Math.max(0,this.l-Wa*(arguments.length?n:1)))},Ba.rgb=function(){return lt(this.h,this.c,this.l).rgb()},ta.lab=st;var Wa=18,Ja=.95047,Ga=1,Ka=1.08883,Qa=st.prototype=new it;Qa.brighter=function(n){return new st(Math.min(100,this.l+Wa*(arguments.length?n:1)),this.a,this.b)},Qa.darker=function(n){return new st(Math.max(0,this.l-Wa*(arguments.length?n:1)),this.a,this.b)},Qa.rgb=function(){return ft(this.l,this.a,this.b)},ta.rgb=dt;var nc=dt.prototype=new it;nc.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 dt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new dt(u,u,u)},nc.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new dt(n*this.r,n*this.g,n*this.b)},nc.hsl=function(){return bt(this.r,this.g,this.b)},nc.toString=function(){return"#"+Mt(this.r)+Mt(this.g)+Mt(this.b)};var tc=ta.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});tc.forEach(function(n,t){tc.set(n,mt(t))}),ta.functor=kt,ta.xhr=At(Et),ta.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=Nt(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(s>=l)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==c)continue;return n.slice(t,s-a)}return n.slice(t)}for(var r,u,i={},o={},a=[],l=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();t&&null==(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 v,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},ta.csv=ta.dsv(",","text/csv"),ta.tsv=ta.dsv(" ","text/tab-separated-values");var ec,rc,uc,ic,oc,ac=oa[m(oa,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ta.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};rc?rc.n=i:ec=i,rc=i,uc||(ic=clearTimeout(ic),uc=1,ac(qt))},ta.timer.flush=function(){Lt(),Tt()},ta.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var cc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Dt);ta.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=ta.round(n,Rt(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)))),cc[8+e/3]};var lc=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,sc=ta.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=ta.round(n,Rt(n,t))).toFixed(Math.max(0,Math.min(20,Rt(n*(1+1e-15),t))))}}),fc=ta.time={},hc=Date;jt.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(){gc.setUTCDate.apply(this._,arguments)},setDay:function(){gc.setUTCDay.apply(this._,arguments)},setFullYear:function(){gc.setUTCFullYear.apply(this._,arguments)},setHours:function(){gc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){gc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){gc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){gc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){gc.setUTCSeconds.apply(this._,arguments)},setTime:function(){gc.setTime.apply(this._,arguments)}};var gc=Date.prototype;fc.year=Ft(function(n){return n=fc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),fc.years=fc.year.range,fc.years.utc=fc.year.utc.range,fc.day=Ft(function(n){var t=new hc(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}),fc.days=fc.day.range,fc.days.utc=fc.day.utc.range,fc.dayOfYear=function(n){var t=fc.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=fc[n]=Ft(function(n){return(n=fc.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=fc.year(n).getDay();return Math.floor((fc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});fc[n+"s"]=e.range,fc[n+"s"].utc=e.utc.range,fc[n+"OfYear"]=function(n){var e=fc.year(n).getDay();return Math.floor((fc.dayOfYear(n)+(e+t)%7)/7)}}),fc.week=fc.sunday,fc.weeks=fc.sunday.range,fc.weeks.utc=fc.sunday.utc.range,fc.weekOfYear=fc.sundayOfYear;var pc={"-":"",_:" ",0:"0"},vc=/^\s*\d+/,dc=/^%/;ta.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var mc=ta.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"]});ta.format=mc.numberFormat,ta.geo={},ce.prototype={s:0,t:0,add:function(n){le(n,this.t,yc),le(yc.s,this.s,this),this.s?this.t+=yc.t:this.s=yc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var yc=new ce;ta.geo.stream=function(n,t){n&&Mc.hasOwnProperty(n.type)?Mc[n.type](n,t):se(n,t)};var Mc={Feature:function(n,t){se(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++rn?4*Da+n:n,wc.lineStart=wc.lineEnd=wc.point=y}};ta.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=pe([t*Fa,e*Fa]);if(m){var u=de(m,r),i=[u[1],-u[0],0],o=de(i,u);Me(o),o=xe(o);var c=t-p,l=c>0?1:-1,v=o[0]*Ha*l,d=va(c)>180;if(d^(v>l*p&&l*t>v)){var y=o[1]*Ha;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>l*p&&l*t>v)){var y=-o[1]*Ha;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=va(r)>180?r+(r>0?360:-360):r}else v=n,d=e;wc.point(n,e),t(n,e)}function i(){wc.lineStart()}function o(){u(v,d),wc.lineEnd(),va(y)>Ta&&(s=-(h=180)),x[0]=s,x[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 l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n_c?(s=-(h=180),f=-(g=90)):y>Ta?g=90:-Ta>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],ta.geo.stream(n,b);var t=M.length;if(t){M.sort(c);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],l(e[0],u)||l(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,s=e[0],h=u[1])}return M=x=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),ta.geo.centroid=function(n){Sc=kc=Ec=Ac=Nc=Cc=zc=qc=Lc=Tc=Rc=0,ta.geo.stream(n,Dc);var t=Lc,e=Tc,r=Rc,u=t*t+e*e+r*r;return Ra>u&&(t=Cc,e=zc,r=qc,Ta>kc&&(t=Ec,e=Ac,r=Nc),u=t*t+e*e+r*r,Ra>u)?[0/0,0/0]:[Math.atan2(e,t)*Ha,nt(r/Math.sqrt(u))*Ha]};var Sc,kc,Ec,Ac,Nc,Cc,zc,qc,Lc,Tc,Rc,Dc={sphere:y,point:_e,lineStart:Se,lineEnd:ke,polygonStart:function(){Dc.lineStart=Ee},polygonEnd:function(){Dc.lineStart=Se}},Pc=Le(Ne,Pe,je,[-Da,-Da/2]),Uc=1e9;ta.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=Ye(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]])},(ta.geo.conicEqualArea=function(){return Ie(Ze)}).raw=Ze,ta.geo.albers=function(){return ta.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ta.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=ta.geo.albers(),o=ta.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ta.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 l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Ta,f+.12*l+Ta],[s-.214*l-Ta,f+.234*l-Ta]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Ta,f+.166*l+Ta],[s-.115*l-Ta,f+.234*l-Ta]]).stream(c).point,n},n.scale(1070)};var jc,Fc,Hc,Oc,Yc,Ic,Zc={point:y,lineStart:y,lineEnd:y,polygonStart:function(){Fc=0,Zc.lineStart=Ve},polygonEnd:function(){Zc.lineStart=Zc.lineEnd=Zc.point=y,jc+=va(Fc/2)}},Vc={point:Xe,lineStart:y,lineEnd:y,polygonStart:y,polygonEnd:y},Xc={point:We,lineStart:Je,lineEnd:Ge,polygonStart:function(){Xc.lineStart=Ke},polygonEnd:function(){Xc.point=We,Xc.lineStart=Je,Xc.lineEnd=Ge}};ta.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),ta.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 jc=0,ta.geo.stream(n,u(Zc)),jc},n.centroid=function(n){return Ec=Ac=Nc=Cc=zc=qc=Lc=Tc=Rc=0,ta.geo.stream(n,u(Xc)),Rc?[Lc/Rc,Tc/Rc]:qc?[Cc/qc,zc/qc]:Nc?[Ec/Nc,Ac/Nc]:[0/0,0/0]},n.bounds=function(n){return Yc=Ic=-(Hc=Oc=1/0),ta.geo.stream(n,u(Vc)),[[Hc,Oc],[Yc,Ic]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):Et,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new $e:new Qe(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(ta.geo.albersUsa()).context(null)},ta.geo.transform=function(n){return{stream:function(t){var e=new er(t);for(var r in n)e[r]=n[r];return e}}},er.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()}},ta.geo.projection=ur,ta.geo.projectionMutator=ir,(ta.geo.equirectangular=function(){return ur(ar)}).raw=ar.invert=ar,ta.geo.rotation=function(n){function t(t){return t=n(t[0]*Fa,t[1]*Fa),t[0]*=Ha,t[1]*=Ha,t}return n=lr(n[0]%360*Fa,n[1]*Fa,n.length>2?n[2]*Fa:0),t.invert=function(t){return t=n.invert(t[0]*Fa,t[1]*Fa),t[0]*=Ha,t[1]*=Ha,t},t},cr.invert=ar,ta.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=lr(-n[0]*Fa,-n[1]*Fa,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Ha,n[1]*=Ha}}),{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=gr((t=+r)*Fa,u*Fa),n):t},n.precision=function(r){return arguments.length?(e=gr(t*Fa,(u=+r)*Fa),n):u},n.angle(90)},ta.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Fa,u=n[1]*Fa,i=t[1]*Fa,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},ta.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ta.range(Math.ceil(i/d)*d,u,d).map(h).concat(ta.range(Math.ceil(l/m)*m,c,m).map(g)).concat(ta.range(Math.ceil(r/p)*p,e,p).filter(function(n){return va(n%d)>Ta}).map(s)).concat(ta.range(Math.ceil(a/v)*v,o,v).filter(function(n){return va(n%m)>Ta}).map(f))}var e,r,u,i,o,a,c,l,s,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(l).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],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[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,s=vr(a,o,90),f=dr(r,e,y),h=vr(l,c,90),g=dr(i,u,y),n):y},n.majorExtent([[-180,-90+Ta],[180,90-Ta]]).minorExtent([[-180,-80-Ta],[180,80+Ta]])},ta.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=mr,u=yr;return n.distance=function(){return ta.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},ta.geo.interpolate=function(n,t){return Mr(n[0]*Fa,n[1]*Fa,t[0]*Fa,t[1]*Fa)},ta.geo.length=function(n){return $c=0,ta.geo.stream(n,Bc),$c};var $c,Bc={sphere:y,point:y,lineStart:xr,lineEnd:y,polygonStart:y,polygonEnd:y},Wc=br(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ta.geo.azimuthalEqualArea=function(){return ur(Wc)}).raw=Wc;var Jc=br(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},Et);(ta.geo.azimuthalEquidistant=function(){return ur(Jc)}).raw=Jc,(ta.geo.conicConformal=function(){return Ie(_r)}).raw=_r,(ta.geo.conicEquidistant=function(){return Ie(wr)}).raw=wr;var Gc=br(function(n){return 1/n},Math.atan);(ta.geo.gnomonic=function(){return ur(Gc)}).raw=Gc,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-ja]},(ta.geo.mercator=function(){return kr(Sr)}).raw=Sr;var Kc=br(function(){return 1},Math.asin);(ta.geo.orthographic=function(){return ur(Kc)}).raw=Kc;var Qc=br(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ta.geo.stereographic=function(){return ur(Qc)}).raw=Qc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-ja]},(ta.geo.transverseMercator=function(){var n=kr(Er),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=Er,ta.geom={},ta.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=kt(e),i=kt(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(zr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var l=Cr(a),s=Cr(c),f=s[0]===l[0],h=s[s.length-1]===l[l.length-1],g=[];for(t=l.length-1;t>=0;--t)g.push(n[a[l[t]][2]]);for(t=+f;t=r&&l.x<=i&&l.y>=u&&l.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];s.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Ta)*Ta,y:Math.round(o(n,t)/Ta)*Ta,i:t}})}var r=Ar,u=Nr,i=r,o=u,a=cl;return n?t(n):(t.links=function(n){return iu(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 iu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Ir),c=-1,l=a.length,s=a[l-1].edge,f=s.l===o?s.r:s.l;++c=l,h=r>=s,g=h<<1|f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=su()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,v,d,m,y,M=kt(a),x=kt(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)s=n[g],s.xm&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);v>b&&(v=b),d>_&&(d=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=su();if(k.add=function(n){i(k,n,+M(n,++g),+x(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},k.find=function(n){return hu(k,n[0],n[1],v,d,m,y)},g=-1,null==t){for(;++g=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=hl.get(e)||fl,r=gl.get(r)||Et,Mu(r(e.apply(null,ea.call(arguments,1))))},ta.interpolateHcl=Lu,ta.interpolateHsl=Tu,ta.interpolateLab=Ru,ta.interpolateRound=Du,ta.transform=function(n){var t=ua.createElementNS(ta.ns.prefix.svg,"g");return(ta.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Pu(e?e.matrix:pl)})(n)},Pu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var pl={a:1,b:0,c:0,d:1,e:0,f:0};ta.interpolateTransform=Hu,ta.layout={},ta.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/d){if(p>c){var l=t.charge/c;n.px-=i*l,n.py-=o*l}return!0}if(t.point&&c&&p>c){var l=t.pointCharge/c;n.px-=i*l,n.py-=o*l}}return!t.charge}}function t(n){n.px=ta.event.x,n.py=ta.event.y,a.resume()}var e,r,u,i,o,a={},c=ta.dispatch("start","tick","end"),l=[1,1],s=.9,f=vl,h=dl,g=-30,p=ml,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,M,x,b=m.length,_=y.length;for(e=0;_>e;++e)a=y[e],f=a.source,h=a.target,M=h.x-f.x,x=h.y-f.y,(p=M*M+x*x)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,M*=p,x*=p,h.x-=M*(d=f.weight/(h.weight+f.weight)),h.y-=x*d,f.x+=M*(d=1-d),f.y+=x*d);if((d=r*v)&&(M=l[0]/2,x=l[1]/2,e=-1,d))for(;++e0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),ta.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;l>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,l=o.length;++at;++t)(r=m[t]).index=t,r.weight=0;for(t=0;s>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;s>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;s>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;s>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;s>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=ta.behavior.drag().origin(Et).on("dragstart.force",Xu).on("drag.force",t).on("dragend.force",$u)),arguments.length?(this.on("mouseover.force",Bu).on("mouseout.force",Wu).call(e),void 0):e},ta.rebind(a,c,"on")};var vl=20,dl=1,ml=1/0;ta.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(l=e.call(n,i,i.depth))&&(c=l.length)){for(var c,l,s;--c>=0;)o.push(s=l[c]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=l}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Qu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=ei,e=ni,r=ti;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&&(Ku(t,function(n){n.children&&(n.value=0)}),Qu(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},ta.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,l=-1;for(r=t.value?r/t.value:0;++lf?-1:1),p=(f-c*g)/ta.sum(l),v=ta.range(c),d=[];return null!=e&&v.sort(e===yl?function(n,t){return l[t]-l[n]}:function(n,t){return e(o[n],o[t])}),v.forEach(function(n){d[n]={data:o[n],value:a=l[n],startAngle:s,endAngle:s+=a*p+g,padAngle:h}}),d}var t=Number,e=yl,r=0,u=Pa,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var yl={};ta.layout.stack=function(){function n(a,c){if(!(h=a.length))return a;var l=a.map(function(e,r){return t.call(n,e,r)}),s=l.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,s,c);l=ta.permute(l,f),s=ta.permute(s,f);var h,g,p,v,d=r.call(n,s,c),m=l[0].length;for(p=0;m>p;++p)for(u.call(n,l[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,l[g][p],v+=s[g-1][p][1],s[g][p][1]);return a}var t=Et,e=ai,r=ci,u=oi,i=ui,o=ii;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:Ml.get(t)||ai,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:xl.get(t)||ci,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 Ml=ta.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(li),i=n.map(si),o=ta.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return ta.range(n.length).reverse()},"default":ai}),xl=ta.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,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>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,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;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:ci});ta.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i0)for(i=-1;++i=s[0]&&a<=s[1]&&(o=c[ta.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=pi,u=hi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=kt(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return gi(n,t)}:kt(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ta.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Qu(a,function(n){n.r=+s(n.value)}),Qu(a,Mi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Qu(a,function(n){n.r+=f}),Qu(a,Mi),Qu(a,function(n){n.r-=f})}return _i(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=ta.layout.hierarchy().sort(vi),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},Gu(n,e)},ta.layout.tree=function(){function n(n,u){var s=o.call(this,n,u),f=s[0],h=t(f);if(Qu(h,e),h.parent.m=-h.z,Ku(h,r),l)Ku(f,i);else{var g=f,p=f,v=f;Ku(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);Ku(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}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){Ni(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],l=u.m,s=i.m,f=o.m,h=c.m;o=Ei(o),u=ki(u),o&&u;)c=ki(c),i=Ei(i),i.a=n,r=o.z+f-u.z-l+a(o._,u._),r>0&&(Ai(Ci(o,n,e),n,r),l+=r,s+=r),f+=o.m,l+=u.m,h+=c.m,s+=i.m;o&&!Ei(i)&&(i.t=o,i.m+=f-s),u&&!ki(c)&&(c.t=u,c.m+=l-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=ta.layout.hierarchy().sort(null).value(null),a=Si,c=[1,1],l=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(l=null==(c=t)?i:null,n):l?null:c},n.nodeSize=function(t){return arguments.length?(l=null==(c=t)?null:i,n):l?c:null},Gu(n,o)},ta.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Qu(c,function(n){var t=n.children;t&&t.length?(n.x=qi(t),n.y=zi(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Li(c),f=Ti(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Qu(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=ta.layout.hierarchy().sort(null).value(null),e=Si,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},Gu(n,t)},ta.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,l=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,v))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,v,l,!1),v=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,l,!0),s.length=s.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,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++ie.dx)&&(s=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=ta.random.normal.apply(ta,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ta.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}}},ta.scale={};var bl={floor:Et,ceil:Et};ta.scale.linear=function(){return Yi([0,1],[0,1],mu,!1)};var _l={s:1,g:1,p:1,r:1,e:1};ta.scale.log=function(){return Ji(ta.scale.linear().domain([0,1]),10,!0,[1,10])};var wl=ta.format(".0e"),Sl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ta.scale.pow=function(){return Gi(ta.scale.linear(),1,[0,1])},ta.scale.sqrt=function(){return ta.scale.pow().exponent(.5)},ta.scale.ordinal=function(){return Qi([],{t:"range",a:[[]]})},ta.scale.category10=function(){return ta.scale.ordinal().range(kl)},ta.scale.category20=function(){return ta.scale.ordinal().range(El)},ta.scale.category20b=function(){return ta.scale.ordinal().range(Al)},ta.scale.category20c=function(){return ta.scale.ordinal().range(Nl)};var kl=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(yt),El=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(yt),Al=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(yt),Nl=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(yt);ta.scale.quantile=function(){return no([],[])},ta.scale.quantize=function(){return to(0,1,[0,1])},ta.scale.threshold=function(){return eo([.5],[0,1])},ta.scale.identity=function(){return ro([0,1])},ta.svg={},ta.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),l=Math.max(0,+r.apply(this,arguments)),s=o.apply(this,arguments)-ja,f=a.apply(this,arguments)-ja,h=Math.abs(f-s),g=s>f?0:1;if(n>l&&(p=l,l=n,n=p),h>=Ua)return t(l,g)+(n?t(n,1-g):"")+"Z";var p,v,d,m,y,M,x,b,_,w,S,k,E=0,A=0,N=[];if((m=(+c.apply(this,arguments)||0)/2)&&(d=i===Cl?Math.sqrt(n*n+l*l):+i.apply(this,arguments),g||(A*=-1),l&&(A=nt(d/l*Math.sin(m))),n&&(E=nt(d/n*Math.sin(m)))),l){y=l*Math.cos(s+A),M=l*Math.sin(s+A),x=l*Math.cos(f-A),b=l*Math.sin(f-A);var C=Math.abs(f-s-2*A)<=Da?0:1;if(A&&so(y,M,x,b)===g^C){var z=(s+f)/2;y=l*Math.cos(z),M=l*Math.sin(z),x=b=null}}else y=M=0;if(n){_=n*Math.cos(f-E),w=n*Math.sin(f-E),S=n*Math.cos(s+E),k=n*Math.sin(s+E);var q=Math.abs(s-f+2*E)<=Da?0:1;if(E&&so(_,w,S,k)===1-g^q){var L=(s+f)/2;_=n*Math.cos(L),w=n*Math.sin(L),S=k=null}}else _=w=0;if((p=Math.min(Math.abs(l-n)/2,+u.apply(this,arguments)))>.001){v=l>n^g?0:1;var T=null==S?[_,w]:null==x?[y,M]:Lr([y,M],[S,k],[x,b],[_,w]),R=y-T[0],D=M-T[1],P=x-T[0],U=b-T[1],j=1/Math.sin(Math.acos((R*P+D*U)/(Math.sqrt(R*R+D*D)*Math.sqrt(P*P+U*U)))/2),F=Math.sqrt(T[0]*T[0]+T[1]*T[1]);if(null!=x){var H=Math.min(p,(l-F)/(j+1)),O=fo(null==S?[_,w]:[S,k],[y,M],l,H,g),Y=fo([x,b],[_,w],l,H,g);p===H?N.push("M",O[0],"A",H,",",H," 0 0,",v," ",O[1],"A",l,",",l," 0 ",1-g^so(O[1][0],O[1][1],Y[1][0],Y[1][1]),",",g," ",Y[1],"A",H,",",H," 0 0,",v," ",Y[0]):N.push("M",O[0],"A",H,",",H," 0 1,",v," ",Y[0])}else N.push("M",y,",",M);if(null!=S){var I=Math.min(p,(n-F)/(j-1)),Z=fo([y,M],[S,k],n,-I,g),V=fo([_,w],null==x?[y,M]:[x,b],n,-I,g);p===I?N.push("L",V[0],"A",I,",",I," 0 0,",v," ",V[1],"A",n,",",n," 0 ",g^so(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-g," ",Z[1],"A",I,",",I," 0 0,",v," ",Z[0]):N.push("L",V[0],"A",I,",",I," 0 0,",v," ",Z[0])}else N.push("L",_,",",w)}else N.push("M",y,",",M),null!=x&&N.push("A",l,",",l," 0 ",C,",",g," ",x,",",b),N.push("L",_,",",w),null!=S&&N.push("A",n,",",n," 0 ",q,",",1-g," ",S,",",k);return N.push("Z"),N.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=io,r=oo,u=uo,i=Cl,o=ao,a=co,c=lo;return n.innerRadius=function(t){return arguments.length?(e=kt(t),n):e},n.outerRadius=function(t){return arguments.length?(r=kt(t),n):r},n.cornerRadius=function(t){return arguments.length?(u=kt(t),n):u},n.padRadius=function(t){return arguments.length?(i=t==Cl?Cl:kt(t),n):i},n.startAngle=function(t){return arguments.length?(o=kt(t),n):o},n.endAngle=function(t){return arguments.length?(a=kt(t),n):a},n.padAngle=function(t){return arguments.length?(c=kt(t),n):c},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-ja;return[Math.cos(t)*n,Math.sin(t)*n]},n};var Cl="auto";ta.svg.line=function(){return ho(Et)};var zl=ta.map({linear:go,"linear-closed":po,step:vo,"step-before":mo,"step-after":yo,basis:So,"basis-open":ko,"basis-closed":Eo,bundle:Ao,cardinal:bo,"cardinal-open":Mo,"cardinal-closed":xo,monotone:To});zl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var ql=[0,2/3,1/3,0],Ll=[0,1/3,2/3,0],Tl=[0,1/6,2/3,1/6];ta.svg.line.radial=function(){var n=ho(Ro);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},mo.reverse=yo,yo.reverse=mo,ta.svg.area=function(){return Do(Et)},ta.svg.area.radial=function(){var n=Do(Ro);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},ta.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.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)-ja,s=l.call(n,u,r)-ja;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Da)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Po,c=ao,l=co;return n.radius=function(t){return arguments.length?(a=kt(t),n):a},n.source=function(t){return arguments.length?(i=kt(t),n):i},n.target=function(t){return arguments.length?(o=kt(t),n):o},n.startAngle=function(t){return arguments.length?(c=kt(t),n):c},n.endAngle=function(t){return arguments.length?(l=kt(t),n):l},n},ta.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=mr,e=yr,r=Uo;return n.source=function(e){return arguments.length?(t=kt(e),n):t},n.target=function(t){return arguments.length?(e=kt(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ta.svg.diagonal.radial=function(){var n=ta.svg.diagonal(),t=Uo,e=n.projection;return n.projection=function(n){return arguments.length?e(jo(t=n)):t},n},ta.svg.symbol=function(){function n(n,r){return(Rl.get(t.call(this,n,r))||Oo)(e.call(this,n,r))}var t=Ho,e=Fo;return n.type=function(e){return arguments.length?(t=kt(e),n):t},n.size=function(t){return arguments.length?(e=kt(t),n):e},n};var Rl=ta.map({circle:Oo,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*Pl)),e=t*Pl;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/Dl),e=t*Dl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/Dl),e=t*Dl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ta.svg.symbolTypes=Rl.keys();var Dl=Math.sqrt(3),Pl=Math.tan(30*Fa);ka.transition=function(n){for(var t,e,r=Ul||++Ol,u=Xo(n),i=[],o=jl||{time:Date.now(),ease:Su,delay:0,duration:250},a=-1,c=this.length;++ai;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 Io(u,this.namespace,this.id)},Hl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):H(this,null==t?function(t){t[r][e].tween.remove(n)}:function(u){u[r][e].tween.set(n,t)})},Hl.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?Hu:mu,a=ta.ns.qualify(n);return Zo(this,"attr."+n,t,a.local?i:u)},Hl.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=ta.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Hl.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=oa.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=mu(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 Zo(this,"style."+n,t,u)},Hl.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,oa.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)},Hl.text=function(n){return Zo(this,"text",n,Vo)},Hl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Hl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ta.ease.apply(ta,arguments)),H(this,function(r){r[e][t].ease=n}))},Hl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:H(this,"function"==typeof n?function(r,u,i){r[e][t].delay=+n.call(r,r.__data__,u,i)}:(n=+n,function(r){r[e][t].delay=n}))},Hl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:H(this,"function"==typeof n?function(r,u,i){r[e][t].duration=Math.max(1,n.call(r,r.__data__,u,i))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Hl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var u=jl,i=Ul;try{Ul=e,H(this,function(t,u,i){jl=t[r][e],n.call(t,t.__data__,u,i)})}finally{jl=u,Ul=i}}else H(this,function(u){var i=u[r][e];(i.event||(i.event=ta.dispatch("start","end","interrupt"))).on(n,t)});return this},Hl.transition=function(){for(var n,t,e,r,u=this.id,i=++Ol,o=this.namespace,a=[],c=0,l=this.length;l>c;c++){a.push(n=[]);for(var t=this[c],s=0,f=t.length;f>s;s++)(e=t[s])&&(r=e[o][u],$o(e,s,o,i,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Io(a,o,i)},ta.svg.axis=function(){function n(n){n.each(function(){var n,l=ta.select(this),s=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):Et:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Ta),d=ta.transition(p.exit()).style("opacity",Ta).remove(),m=ta.transition(p.order()).style("opacity",1),y=Math.max(u,0)+o,M=Ui(f),x=l.selectAll(".domain").data([0]),b=(x.enter().append("path").attr("class","domain"),ta.transition(x));v.append("line"),v.append("text");var _,w,S,k,E=v.select("line"),A=m.select("line"),N=p.select("text").text(g),C=v.select("text"),z=m.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Bo,_="x",S="y",w="x2",k="y2",N.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),b.attr("d","M"+M[0]+","+q*i+"V0H"+M[1]+"V"+q*i)):(n=Wo,_="y",S="x",w="y2",k="x2",N.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),b.attr("d","M"+q*i+","+M[0]+"H0V"+M[1]+"H"+q*i)),E.attr(k,q*u),C.attr(S,q*y),A.attr(w,0).attr(k,q*u),z.attr(_,0).attr(S,q*y),f.rangeBand){var L=f,T=L.rangeBand()/2;s=f=function(n){return L(n)+T}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=ta.scale.linear(),r=Yl,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 Il?t+"":Yl,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 Yl="bottom",Il={top:1,right:1,bottom:1,left:1};ta.svg.brush=function(){function n(i){i.each(function(){var i=ta.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,Et);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Zl[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 s,f=ta.transition(i),h=ta.transition(o);c&&(s=Ui(c),h.attr("x",s[0]).attr("width",s[1]-s[0]),e(f)),l&&(s=Ui(l),h.attr("y",s[0]).attr("height",s[1]-s[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[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==ta.event.keyCode&&(N||(y=null,z[0]-=s[1],z[1]-=f[1],N=2),b())}function p(){32==ta.event.keyCode&&2==N&&(z[0]+=s[1],z[1]+=f[1],N=0,b())}function v(){var n=ta.mouse(x),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),N||(ta.event.altKey?(y||(y=[(s[0]+s[1])/2,(f[0]+f[1])/2]),z[0]=s[+(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),ta.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),C(),w({type:"brushend"})}var y,M,x=this,_=ta.select(ta.event.target),w=a.of(x,arguments),S=ta.select(x),k=_.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&l,N=_.classed("extent"),C=X(),z=ta.mouse(x),q=ta.select(oa).on("keydown.brush",u).on("keyup.brush",p);if(ta.event.changedTouches?q.on("touchmove.brush",v).on("touchend.brush",m):q.on("mousemove.brush",v).on("mouseup.brush",m),S.interrupt().selectAll("*").interrupt(),N)z[0]=s[0]-z[0],z[1]=f[0]-z[1];else if(k){var L=+/w$/.test(k),T=+/^n/.test(k);M=[s[1-L]-z[0],f[1-T]-z[1]],z[0]=s[L],z[1]=f[T]}else ta.event.altKey&&(y=z.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),ta.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=w(n,"brushstart","brush","brushend"),c=null,l=null,s=[0,0],f=[0,0],h=!0,g=!0,p=Vl[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:s,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,Ul?ta.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,s=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=yu(s,t.x),r=yu(f,t.y);return i=o=null,function(u){s=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=Vl[!c<<1|!l],n):c},n.y=function(t){return arguments.length?(l=t,p=Vl[!c<<1|!l],n):l},n.clamp=function(t){return arguments.length?(c&&l?(h=!!t[0],g=!!t[1]):c?h=!!t:l&&(g=!!t),n):c&&l?[h,g]:c?h:l?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],l&&(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!=s[0]||r!=s[1])&&(s=[e,r])),l&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],l.invert&&(u=l(u),a=l(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=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),l&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],l.invert&&(u=l.invert(u),a=l.invert(a)),u>a&&(h=u,u=a,a=h))),c&&l?[[e,u],[r,a]]:c?[e,r]:l&&[u,a])},n.clear=function(){return n.empty()||(s=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!l&&f[0]==f[1]},ta.rebind(n,a,"on")};var Zl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Vl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Xl=fc.format=mc.timeFormat,$l=Xl.utc,Bl=$l("%Y-%m-%dT%H:%M:%S.%LZ");Xl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Jo:Bl,Jo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Jo.toString=Bl.toString,fc.second=Ft(function(n){return new hc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),fc.seconds=fc.second.range,fc.seconds.utc=fc.second.utc.range,fc.minute=Ft(function(n){return new hc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),fc.minutes=fc.minute.range,fc.minutes.utc=fc.minute.utc.range,fc.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new hc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),fc.hours=fc.hour.range,fc.hours.utc=fc.hour.utc.range,fc.month=Ft(function(n){return n=fc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),fc.months=fc.month.range,fc.months.utc=fc.month.utc.range;var Wl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Jl=[[fc.second,1],[fc.second,5],[fc.second,15],[fc.second,30],[fc.minute,1],[fc.minute,5],[fc.minute,15],[fc.minute,30],[fc.hour,1],[fc.hour,3],[fc.hour,6],[fc.hour,12],[fc.day,1],[fc.day,2],[fc.week,1],[fc.month,1],[fc.month,3],[fc.year,1]],Gl=Xl.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",Ne]]),Kl={range:function(n,t,e){return ta.range(Math.ceil(n/e)*e,+t,e).map(Ko)},floor:Et,ceil:Et};Jl.year=fc.year,fc.scale=function(){return Go(ta.scale.linear(),Jl,Gl)};var Ql=Jl.map(function(n){return[n[0].utc,n[1]]}),ns=$l.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",Ne]]);Ql.year=fc.year.utc,fc.scale.utc=function(){return Go(ta.scale.linear(),Ql,ns)},ta.text=At(function(n){return n.responseText}),ta.json=function(n,t){return Nt(n,"application/json",Qo,t)},ta.html=function(n,t){return Nt(n,"text/html",na,t)},ta.xml=At(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(ta):"object"==typeof module&&module.exports&&(module.exports=ta),this.d3=ta}(); \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/excanvas.min.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/excanvas.min.js new file mode 100644 index 00000000..2a5250fb --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/excanvas.min.js @@ -0,0 +1,48 @@ +if(navigator.appVersion.indexOf("MSIE")!=-1&&parseFloat(navigator.appVersion.split("MSIE")[1])<=8&&!document.createElement("canvas").getContext)(function(){var m=Math;var mr=m.round;var ms=m.sin;var mc=m.cos;var abs=m.abs;var sqrt=m.sqrt;var Z=10;var Z2=Z/2;var IE_VERSION=+navigator.userAgent.match(/MSIE ([\d.]+)?/)[1];function getContext(){return this.context_||(this.context_=new CanvasRenderingContext2D_(this))}var slice=Array.prototype.slice;function bind(f,obj,var_args){var a=slice.call(arguments, +2);return function(){return f.apply(obj,a.concat(slice.call(arguments)))}}function encodeHtmlAttribute(s){return String(s).replace(/&/g,"&").replace(/"/g,""")}function addNamespace(doc,prefix,urn){if(!doc.namespaces[prefix])doc.namespaces.add(prefix,urn,"#default#VML")}function addNamespacesAndStylesheet(doc){addNamespace(doc,"g_vml_","urn:schemas-microsoft-com:vml");addNamespace(doc,"g_o_","urn:schemas-microsoft-com:office:office");if(!doc.styleSheets["ex_canvas_"]){var ss=doc.createStyleSheet(); +ss.owningElement.id="ex_canvas_";ss.cssText="canvas{display:inline-block;overflow:hidden;"+"text-align:left;width:300px;height:150px}"}}addNamespacesAndStylesheet(document);var G_vmlCanvasManager_={init:function(opt_doc){var doc=opt_doc||document;doc.createElement("canvas");doc.attachEvent("onreadystatechange",bind(this.init_,this,doc))},init_:function(doc){var els=doc.getElementsByTagName("canvas");for(var i=0;i1)h--;if(6*h<1)return m1+(m2-m1)*6*h;else if(2*h<1)return m2;else if(3*h<2)return m1+(m2-m1)*(2/3-h)*6;else return m1}var processStyleCache={};function processStyle(styleString){if(styleString in processStyleCache)return processStyleCache[styleString];var str,alpha=1;styleString=String(styleString);if(styleString.charAt(0)=="#")str=styleString;else if(/^rgb/.test(styleString)){var parts= +getRgbHslContent(styleString);var str="#",n;for(var i=0;i<3;i++){if(parts[i].indexOf("%")!=-1)n=Math.floor(percent(parts[i])*255);else n=+parts[i];str+=decToHex[clamp(n,0,255)]}alpha=+parts[3]}else if(/^hsl/.test(styleString)){var parts=getRgbHslContent(styleString);str=hslToRgb(parts);alpha=parts[3]}else str=colorData[styleString]||styleString;return processStyleCache[styleString]={color:str,alpha:alpha}}var DEFAULT_STYLE={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"}; +var fontStyleCache={};function processFontStyle(styleString){if(fontStyleCache[styleString])return fontStyleCache[styleString];var el=document.createElement("div");var style=el.style;try{style.font=styleString}catch(ex){}return fontStyleCache[styleString]={style:style.fontStyle||DEFAULT_STYLE.style,variant:style.fontVariant||DEFAULT_STYLE.variant,weight:style.fontWeight||DEFAULT_STYLE.weight,size:style.fontSize||DEFAULT_STYLE.size,family:style.fontFamily||DEFAULT_STYLE.family}}function getComputedStyle(style, +element){var computedStyle={};for(var p in style)computedStyle[p]=style[p];var canvasFontSize=parseFloat(element.currentStyle.fontSize),fontSize=parseFloat(style.size);if(typeof style.size=="number")computedStyle.size=style.size;else if(style.size.indexOf("px")!=-1)computedStyle.size=fontSize;else if(style.size.indexOf("em")!=-1)computedStyle.size=canvasFontSize*fontSize;else if(style.size.indexOf("%")!=-1)computedStyle.size=canvasFontSize/100*fontSize;else if(style.size.indexOf("pt")!=-1)computedStyle.size= +fontSize/0.75;else computedStyle.size=canvasFontSize;computedStyle.size*=0.981;return computedStyle}function buildStyle(style){return style.style+" "+style.variant+" "+style.weight+" "+style.size+"px "+style.family}var lineCapMap={"butt":"flat","round":"round"};function processLineCap(lineCap){return lineCapMap[lineCap]||"square"}function CanvasRenderingContext2D_(canvasElement){this.m_=createMatrixIdentity();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle= +"#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=Z*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=canvasElement;var cssText="width:"+canvasElement.clientWidth+"px;height:"+canvasElement.clientHeight+"px;overflow:hidden;position:absolute";var el=canvasElement.ownerDocument.createElement("div");el.style.cssText=cssText;canvasElement.appendChild(el);var overlayEl=el.cloneNode(false);overlayEl.style.backgroundColor= +"red";overlayEl.style.filter="alpha(opacity=0)";canvasElement.appendChild(overlayEl);this.element_=el;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var contextPrototype=CanvasRenderingContext2D_.prototype;contextPrototype.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};contextPrototype.beginPath=function(){this.currentPath_=[]};contextPrototype.moveTo=function(aX,aY){var p=getCoords(this,aX,aY);this.currentPath_.push({type:"moveTo", +x:p.x,y:p.y});this.currentX_=p.x;this.currentY_=p.y};contextPrototype.lineTo=function(aX,aY){var p=getCoords(this,aX,aY);this.currentPath_.push({type:"lineTo",x:p.x,y:p.y});this.currentX_=p.x;this.currentY_=p.y};contextPrototype.bezierCurveTo=function(aCP1x,aCP1y,aCP2x,aCP2y,aX,aY){var p=getCoords(this,aX,aY);var cp1=getCoords(this,aCP1x,aCP1y);var cp2=getCoords(this,aCP2x,aCP2y);bezierCurveTo(this,cp1,cp2,p)};function bezierCurveTo(self,cp1,cp2,p){self.currentPath_.push({type:"bezierCurveTo",cp1x:cp1.x, +cp1y:cp1.y,cp2x:cp2.x,cp2y:cp2.y,x:p.x,y:p.y});self.currentX_=p.x;self.currentY_=p.y}contextPrototype.quadraticCurveTo=function(aCPx,aCPy,aX,aY){var cp=getCoords(this,aCPx,aCPy);var p=getCoords(this,aX,aY);var cp1={x:this.currentX_+2/3*(cp.x-this.currentX_),y:this.currentY_+2/3*(cp.y-this.currentY_)};var cp2={x:cp1.x+(p.x-this.currentX_)/3,y:cp1.y+(p.y-this.currentY_)/3};bezierCurveTo(this,cp1,cp2,p)};contextPrototype.arc=function(aX,aY,aRadius,aStartAngle,aEndAngle,aClockwise){aRadius*=Z;var arcType= +aClockwise?"at":"wa";var xStart=aX+mc(aStartAngle)*aRadius-Z2;var yStart=aY+ms(aStartAngle)*aRadius-Z2;var xEnd=aX+mc(aEndAngle)*aRadius-Z2;var yEnd=aY+ms(aEndAngle)*aRadius-Z2;if(xStart==xEnd&&!aClockwise)xStart+=0.125;var p=getCoords(this,aX,aY);var pStart=getCoords(this,xStart,yStart);var pEnd=getCoords(this,xEnd,yEnd);this.currentPath_.push({type:arcType,x:p.x,y:p.y,radius:aRadius,xStart:pStart.x,yStart:pStart.y,xEnd:pEnd.x,yEnd:pEnd.y})};contextPrototype.rect=function(aX,aY,aWidth,aHeight){this.moveTo(aX, +aY);this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath()};contextPrototype.strokeRect=function(aX,aY,aWidth,aHeight){var oldPath=this.currentPath_;this.beginPath();this.moveTo(aX,aY);this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath();this.stroke();this.currentPath_=oldPath};contextPrototype.fillRect=function(aX,aY,aWidth,aHeight){var oldPath=this.currentPath_;this.beginPath();this.moveTo(aX,aY); +this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath();this.fill();this.currentPath_=oldPath};contextPrototype.createLinearGradient=function(aX0,aY0,aX1,aY1){var gradient=new CanvasGradient_("gradient");gradient.x0_=aX0;gradient.y0_=aY0;gradient.x1_=aX1;gradient.y1_=aY1;return gradient};contextPrototype.createRadialGradient=function(aX0,aY0,aR0,aX1,aY1,aR1){var gradient=new CanvasGradient_("gradientradial");gradient.x0_=aX0;gradient.y0_=aY0;gradient.r0_= +aR0;gradient.x1_=aX1;gradient.y1_=aY1;gradient.r1_=aR1;return gradient};contextPrototype.drawImage=function(image,var_args){var dx,dy,dw,dh,sx,sy,sw,sh;var oldRuntimeWidth=image.runtimeStyle.width;var oldRuntimeHeight=image.runtimeStyle.height;image.runtimeStyle.width="auto";image.runtimeStyle.height="auto";var w=image.width;var h=image.height;image.runtimeStyle.width=oldRuntimeWidth;image.runtimeStyle.height=oldRuntimeHeight;if(arguments.length==3){dx=arguments[1];dy=arguments[2];sx=sy=0;sw=dw=w; +sh=dh=h}else if(arguments.length==5){dx=arguments[1];dy=arguments[2];dw=arguments[3];dh=arguments[4];sx=sy=0;sw=w;sh=h}else if(arguments.length==9){sx=arguments[1];sy=arguments[2];sw=arguments[3];sh=arguments[4];dx=arguments[5];dy=arguments[6];dw=arguments[7];dh=arguments[8]}else throw Error("Invalid number of arguments");var d=getCoords(this,dx,dy);var w2=sw/2;var h2=sh/2;var vmlStr=[];var W=10;var H=10;vmlStr.push(" ','","");this.element_.insertAdjacentHTML("BeforeEnd",vmlStr.join(""))};contextPrototype.stroke=function(aFill){var W= +10;var H=10;var chunkSize=5E3;var min={x:null,y:null};var max={x:null,y:null};for(var j=0;jmax.x)max.x=p.x;if(min.y==null||p.ymax.y)max.y=p.y}}lineStr.push(' ">');if(!aFill)appendStroke(this,lineStr);else appendFill(this,lineStr,min,max);lineStr.push("");this.element_.insertAdjacentHTML("beforeEnd",lineStr.join(""))}};function appendStroke(ctx, +lineStr){var a=processStyle(ctx.strokeStyle);var color=a.color;var opacity=a.alpha*ctx.globalAlpha;var lineWidth=ctx.lineScale_*ctx.lineWidth;if(lineWidth<1)opacity*=lineWidth;lineStr.push("')}function appendFill(ctx,lineStr,min,max){var fillStyle=ctx.fillStyle;var arcScaleX=ctx.arcScaleX_;var arcScaleY= +ctx.arcScaleY_;var width=max.x-min.x;var height=max.y-min.y;if(fillStyle instanceof CanvasGradient_){var angle=0;var focus={x:0,y:0};var shift=0;var expansion=1;if(fillStyle.type_=="gradient"){var x0=fillStyle.x0_/arcScaleX;var y0=fillStyle.y0_/arcScaleY;var x1=fillStyle.x1_/arcScaleX;var y1=fillStyle.y1_/arcScaleY;var p0=getCoords(ctx,x0,y0);var p1=getCoords(ctx,x1,y1);var dx=p1.x-p0.x;var dy=p1.y-p0.y;angle=Math.atan2(dx,dy)*180/Math.PI;if(angle<0)angle+=360;if(angle<1E-6)angle=0}else{var p0=getCoords(ctx, +fillStyle.x0_,fillStyle.y0_);focus={x:(p0.x-min.x)/width,y:(p0.y-min.y)/height};width/=arcScaleX*Z;height/=arcScaleY*Z;var dimension=m.max(width,height);shift=2*fillStyle.r0_/dimension;expansion=2*fillStyle.r1_/dimension-shift}var stops=fillStyle.colors_;stops.sort(function(cs1,cs2){return cs1.offset-cs2.offset});var length=stops.length;var color1=stops[0].color;var color2=stops[length-1].color;var opacity1=stops[0].alpha*ctx.globalAlpha;var opacity2=stops[length-1].alpha*ctx.globalAlpha;var colors= +[];for(var i=0;i')}else if(fillStyle instanceof CanvasPattern_){if(width&&height){var deltaLeft=-min.x;var deltaTop=-min.y;lineStr.push("')}}else{var a=processStyle(ctx.fillStyle);var color=a.color;var opacity=a.alpha*ctx.globalAlpha;lineStr.push('')}}contextPrototype.fill=function(){this.stroke(true)};contextPrototype.closePath=function(){this.currentPath_.push({type:"close"})};function getCoords(ctx,aX,aY){var m=ctx.m_;return{x:Z*(aX*m[0][0]+ +aY*m[1][0]+m[2][0])-Z2,y:Z*(aX*m[0][1]+aY*m[1][1]+m[2][1])-Z2}}contextPrototype.save=function(){var o={};copyState(this,o);this.aStack_.push(o);this.mStack_.push(this.m_);this.m_=matrixMultiply(createMatrixIdentity(),this.m_)};contextPrototype.restore=function(){if(this.aStack_.length){copyState(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function matrixIsFinite(m){return isFinite(m[0][0])&&isFinite(m[0][1])&&isFinite(m[1][0])&&isFinite(m[1][1])&&isFinite(m[2][0])&&isFinite(m[2][1])}function setM(ctx, +m,updateLineScale){if(!matrixIsFinite(m))return;ctx.m_=m;if(updateLineScale){var det=m[0][0]*m[1][1]-m[0][1]*m[1][0];ctx.lineScale_=sqrt(abs(det))}}contextPrototype.translate=function(aX,aY){var m1=[[1,0,0],[0,1,0],[aX,aY,1]];setM(this,matrixMultiply(m1,this.m_),false)};contextPrototype.rotate=function(aRot){var c=mc(aRot);var s=ms(aRot);var m1=[[c,s,0],[-s,c,0],[0,0,1]];setM(this,matrixMultiply(m1,this.m_),false)};contextPrototype.scale=function(aX,aY){this.arcScaleX_*=aX;this.arcScaleY_*=aY;var m1= +[[aX,0,0],[0,aY,0],[0,0,1]];setM(this,matrixMultiply(m1,this.m_),true)};contextPrototype.transform=function(m11,m12,m21,m22,dx,dy){var m1=[[m11,m12,0],[m21,m22,0],[dx,dy,1]];setM(this,matrixMultiply(m1,this.m_),true)};contextPrototype.setTransform=function(m11,m12,m21,m22,dx,dy){var m=[[m11,m12,0],[m21,m22,0],[dx,dy,1]];setM(this,m,true)};contextPrototype.drawText_=function(text,x,y,maxWidth,stroke){var m=this.m_,delta=1E3,left=0,right=delta,offset={x:0,y:0},lineStr=[];var fontStyle=getComputedStyle(processFontStyle(this.font), +this.element_);var fontStyleString=buildStyle(fontStyle);var elementStyle=this.element_.currentStyle;var textAlign=this.textAlign.toLowerCase();switch(textAlign){case "left":case "center":case "right":break;case "end":textAlign=elementStyle.direction=="ltr"?"right":"left";break;case "start":textAlign=elementStyle.direction=="rtl"?"right":"left";break;default:textAlign="left"}switch(this.textBaseline){case "hanging":case "top":offset.y=fontStyle.size/1.75;break;case "middle":break;default:case null:case "alphabetic":case "ideographic":case "bottom":offset.y= +-fontStyle.size/2.25;break}switch(textAlign){case "right":left=delta;right=0.05;break;case "center":left=right=delta/2;break}var d=getCoords(this,x+offset.x,y+offset.y);lineStr.push('');if(stroke)appendStroke(this,lineStr);else appendFill(this,lineStr,{x:-left,y:0},{x:right,y:fontStyle.size});var skewM=m[0][0].toFixed(3)+ +","+m[1][0].toFixed(3)+","+m[0][1].toFixed(3)+","+m[1][1].toFixed(3)+",0,0";var skewOffset=mr(d.x/Z)+","+mr(d.y/Z);lineStr.push('','','');this.element_.insertAdjacentHTML("beforeEnd",lineStr.join(""))};contextPrototype.fillText= +function(text,x,y,maxWidth){this.drawText_(text,x,y,maxWidth,false)};contextPrototype.strokeText=function(text,x,y,maxWidth){this.drawText_(text,x,y,maxWidth,true)};contextPrototype.measureText=function(text){if(!this.textMeasureEl_){var s='';this.element_.insertAdjacentHTML("beforeEnd",s);this.textMeasureEl_=this.element_.lastChild}var doc=this.element_.ownerDocument;this.textMeasureEl_.innerHTML= +"";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(doc.createTextNode(text));return{width:this.textMeasureEl_.offsetWidth}};contextPrototype.clip=function(){};contextPrototype.arcTo=function(){};contextPrototype.createPattern=function(image,repetition){return new CanvasPattern_(image,repetition)};function CanvasGradient_(aType){this.type_=aType;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}CanvasGradient_.prototype.addColorStop=function(aOffset, +aColor){aColor=processStyle(aColor);this.colors_.push({offset:aOffset,color:aColor.color,alpha:aColor.alpha})};function CanvasPattern_(image,repetition){assertImageIsValid(image);switch(repetition){case "repeat":case null:case "":this.repetition_="repeat";break;case "repeat-x":case "repeat-y":case "no-repeat":this.repetition_=repetition;break;default:throwException("SYNTAX_ERR")}this.src_=image.src;this.width_=image.width;this.height_=image.height}function throwException(s){throw new DOMException_(s); +}function assertImageIsValid(img){if(!img||img.nodeType!=1||img.tagName!="IMG")throwException("TYPE_MISMATCH_ERR");if(img.readyState!="complete")throwException("INVALID_STATE_ERR")}function DOMException_(s){this.code=this[s];this.message=s+": DOM Exception "+this.code}var p=DOMException_.prototype=new Error;p.INDEX_SIZE_ERR=1;p.DOMSTRING_SIZE_ERR=2;p.HIERARCHY_REQUEST_ERR=3;p.WRONG_DOCUMENT_ERR=4;p.INVALID_CHARACTER_ERR=5;p.NO_DATA_ALLOWED_ERR=6;p.NO_MODIFICATION_ALLOWED_ERR=7;p.NOT_FOUND_ERR=8;p.NOT_SUPPORTED_ERR= +9;p.INUSE_ATTRIBUTE_ERR=10;p.INVALID_STATE_ERR=11;p.SYNTAX_ERR=12;p.INVALID_MODIFICATION_ERR=13;p.NAMESPACE_ERR=14;p.INVALID_ACCESS_ERR=15;p.VALIDATION_ERR=16;p.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=G_vmlCanvasManager_;CanvasRenderingContext2D=CanvasRenderingContext2D_;CanvasGradient=CanvasGradient_;CanvasPattern=CanvasPattern_;DOMException=DOMException_})(); diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/gadgetconf.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/gadgetconf.js new file mode 100644 index 00000000..d06ad45b --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/gadgetconf.js @@ -0,0 +1,24 @@ +var gadgetConfig = { + "id": "IoTServerTemperatureStats", + "title": "IoTServerTemperatureStats", + "datasource": "ORG_WSO2_IOT_DEVICES_TEMPERATURE", + "type": "batch", + "columns": [ + {"name": "TIMESTAMP", "type": "time"}, + {"name": "owner", "type": "string"}, + {"name": "deviceType", "type": "string"}, + {"name": "deviceId", "type": "string"}, + {"name": "time", "type": "long"}, + {"name": "temperature", "type": "float"} + ], + "chartConfig": { + "x": "time", + "maxLength": "10", + "padding": {"top": 30, "left": 45, "bottom": 38, "right": 55}, + "charts": [{"type": "line", "y": "temperature"}] + }, + "domain": "carbon.super", + /* timeFrom and timeTo need not be mentioned here since they will be automatically fetched + if found in the QueryString of the URL */ + "params": ["owner", "deviceId"] +}; diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/jquery.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/jquery.js new file mode 100644 index 00000000..14ba6362 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/jquery.js @@ -0,0 +1,9472 @@ +/*! + * jQuery JavaScript Library v1.8.3 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time) + */ +(function( window, undefined ) { +var + // A central reference to the root jQuery(document) + rootjQuery, + + // The deferred used on DOM ready + readyList, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + location = window.location, + navigator = window.navigator, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // Save a reference to some core methods + core_push = Array.prototype.push, + core_slice = Array.prototype.slice, + core_indexOf = Array.prototype.indexOf, + core_toString = Object.prototype.toString, + core_hasOwn = Object.prototype.hasOwnProperty, + core_trim = String.prototype.trim, + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Used for matching numbers + core_pnum = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source, + + // Used for detecting and trimming whitespace + core_rnotwhite = /\S/, + core_rspace = /\s+/, + + // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, + rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // The ready event handler and self cleanup method + DOMContentLoaded = function() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + } else if ( document.readyState === "complete" ) { + // we're here because readyState === "complete" in oldIE + // which is good enough for us to call the dom ready! + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context && context.nodeType ? context.ownerDocument || context : document ); + + // scripts is true for back-compat + selector = jQuery.parseHTML( match[1], doc, true ); + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + this.attr.call( selector, context, true ); + } + + return jQuery.merge( this, selector ); + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.8.3", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return core_slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; + }, + + eq: function( i ) { + i = +i; + return i === -1 ? + this.slice( i ) : + this.slice( i, i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( core_slice.apply( this, arguments ), + "slice", core_slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: core_push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger("ready").off("ready"); + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ core_toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !core_hasOwn.call(obj, "constructor") && + !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || core_hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + // data: string of html + // context (optional): If specified, the fragment will be created in this context, defaults to document + // scripts (optional): If true, will include scripts passed in the html string + parseHTML: function( data, context, scripts ) { + var parsed; + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + scripts = context; + context = 0; + } + context = context || document; + + // Single tag + if ( (parsed = rsingleTag.exec( data )) ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] ); + return jQuery.merge( [], + (parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes ); + }, + + parseJSON: function( data ) { + if ( !data || typeof data !== "string") { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + + } + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && core_rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var name, + i = 0, + length = obj.length, + isObj = length === undefined || jQuery.isFunction( obj ); + + if ( args ) { + if ( isObj ) { + for ( name in obj ) { + if ( callback.apply( obj[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( obj[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in obj ) { + if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) { + break; + } + } + } + } + + return obj; + }, + + // Use native String.trim function wherever possible + trim: core_trim && !core_trim.call("\uFEFF\xA0") ? + function( text ) { + return text == null ? + "" : + core_trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var type, + ret = results || []; + + if ( arr != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + type = jQuery.type( arr ); + + if ( arr.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( arr ) ) { + core_push.call( ret, arr ); + } else { + jQuery.merge( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( core_indexOf ) { + return core_indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var l = second.length, + i = first.length, + j = 0; + + if ( typeof l === "number" ) { + for ( ; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var retVal, + ret = [], + i = 0, + length = elems.length; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, + ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = core_slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context, args.concat( core_slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + // Multifunctional method to get and set values of a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, pass ) { + var exec, + bulk = key == null, + i = 0, + length = elems.length; + + // Sets many values + if ( key && typeof key === "object" ) { + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); + } + chainable = 1; + + // Sets one value + } else if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = pass === undefined && jQuery.isFunction( value ); + + if ( bulk ) { + // Bulk operations only iterate when executing function values + if ( exec ) { + exec = fn; + fn = function( elem, key, value ) { + return exec.call( jQuery( elem ), value ); + }; + + // Otherwise they run against the entire set + } else { + fn.call( elems, value ); + fn = null; + } + } + + if ( fn ) { + for (; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + } + + chainable = 1; + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + } +}); + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready, 1 ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.split( core_rspace ), function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + return jQuery.inArray( fn, list ) > -1; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( list && ( !fired || stack ) ) { + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var action = tuple[ 0 ], + fn = fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ]( jQuery.isFunction( fn ) ? + function() { + var returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + } : + newDefer[ action ] + ); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] = list.fire + deferred[ tuple[0] ] = list.fire; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = core_slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; + if( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + fragment, + eventName, + i, + isSupported, + clickFn, + div = document.createElement("div"); + + // Setup + div.setAttribute( "className", "t" ); + div.innerHTML = "
a"; + + // Support tests won't run in some limited or non-browser environments + all = div.getElementsByTagName("*"); + a = div.getElementsByTagName("a")[ 0 ]; + if ( !all || !a || !all.length ) { + return {}; + } + + // First batch of tests + select = document.createElement("select"); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName("input")[ 0 ]; + + a.style.cssText = "top:1px;float:left;opacity:.5"; + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute("href") === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.5/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form (#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode + boxModel: ( document.compatMode === "CSS1Compat" ), + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + boxSizingReliable: true, + pixelPosition: false + }; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", clickFn = function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent("onclick"); + div.detachEvent( "onclick", clickFn ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute( "type", "radio" ); + support.radioValue = input.value === "t"; + + input.setAttribute( "checked", "checked" ); + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for ( i in { + submit: true, + change: true, + focusin: true + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + // Run tests that need a body at doc ready + jQuery(function() { + var container, div, tds, marginDiv, + divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;", + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + container = document.createElement("div"); + container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + div.innerHTML = "
t
"; + tds = div.getElementsByTagName("td"); + tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE <= 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check box-sizing and margin behavior + div.innerHTML = ""; + div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; + support.boxSizing = ( div.offsetWidth === 4 ); + support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); + + // NOTE: To any future maintainer, we've window.getComputedStyle + // because jsdom on node.js will break without it. + if ( window.getComputedStyle ) { + support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + marginDiv = document.createElement("div"); + marginDiv.style.cssText = div.style.cssText = divReset; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); + } + + if ( typeof div.style.zoom !== "undefined" ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.innerHTML = ""; + div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = "block"; + div.style.overflow = "visible"; + div.innerHTML = "
"; + div.firstChild.style.width = "5px"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + + container.style.zoom = 1; + } + + // Null elements to avoid leaks in IE + body.removeChild( container ); + container = div = tds = marginDiv = null; + }); + + // Null elements to avoid leaks in IE + fragment.removeChild( div ); + all = a = select = opt = input = fragment = div = null; + + return support; +})(); +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + deletedIds: [], + + // Remove at next major release (1.9/2.0) + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + } else if ( jQuery.support.deleteExpando || cache != cache.window ) { + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; + + // nodes accept data unless otherwise specified; rejection can be conditional + return !noData || noData !== true && elem.getAttribute("classid") === noData; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, part, attr, name, l, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attr = elem.attributes; + for ( l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( !name.indexOf( "data-" ) ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split( ".", 2 ); + parts[1] = parts[1] ? "." + parts[1] : ""; + part = parts[1] + "!"; + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + data = this.triggerHandler( "getData" + part, [ parts[0] ] ); + + // Try to fetch any internally stored data first + if ( data === undefined && elem ) { + data = jQuery.data( elem, key ); + data = dataAttr( elem, key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + } + + parts[1] = value; + this.each(function() { + var self = jQuery( this ); + + self.triggerHandler( "setData" + part, parts ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + part, parts ); + }); + }, null, value, arguments.length > 1, null, false ); + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery.removeData( elem, type + "queue", true ); + jQuery.removeData( elem, key, true ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var nodeHook, boolHook, fixSpecified, + rclass = /[\t\r\n]/g, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea|)$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( core_rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( setClass.indexOf( " " + classNames[ c ] + " " ) < 0 ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var removes, className, elem, c, cl, i, l; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + if ( (value && typeof value === "string") || value === undefined ) { + removes = ( value || "" ).split( core_rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + if ( elem.nodeType === 1 && elem.className ) { + + className = (" " + elem.className + " ").replace( rclass, " " ); + + // loop over each item in the removal list + for ( c = 0, cl = removes.length; c < cl; c++ ) { + // Remove until there is nothing to remove, + while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) { + className = className.replace( " " + removes[ c ] + " " , " " ); + } + } + elem.className = value ? jQuery.trim( className ) : ""; + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( core_rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val, + self = jQuery(this); + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, option, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one" || index < 0, + values = one ? null : [], + max = one ? index + 1 : options.length, + i = index < 0 ? + max : + one ? index : 0; + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // oldIE doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && + ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + // Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9 + attrFn: {}, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, value + "" ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, isBool, + i = 0; + + if ( value && elem.nodeType === 1 ) { + + attrNames = value.split( core_rspace ); + + for ( ; i < attrNames.length; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + isBool = rboolean.test( name ); + + // See #9699 for explanation of this approach (setting first, then removal) + // Do not do this for boolean attributes (see #10870) + if ( !isBool ) { + jQuery.attr( elem, name, "" ); + } + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( isBool && propName in elem ) { + elem[ propName ] = false; + } + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true, + coords: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.value !== "" : ret.specified ) ? + ret.value : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.value = value + "" ); + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = value + "" ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); +var rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*|)(?:\.(.+)|)$/, + rhoverHack = /(?:^|\s)hover(\.\S+|)\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var t, tns, type, origType, namespaces, origCount, + j, events, special, eventType, handleObj, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, "events", true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType, + type = event.type || event, + namespaces = []; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + for ( old = elem; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old === (elem.ownerDocument || document) ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related, + handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = core_slice.call( arguments ), + run_all = !event.exclusive && !event.namespace, + special = jQuery.event.special[ event.type ] || {}, + handlerQueue = []; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers that should run if there are delegated events + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !(event.button && event.type === "click") ) { + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + + // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.disabled !== true || event.type !== "click" ) { + selMatch = {}; + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8) + event.metaKey = !!event.metaKey; + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === "undefined" ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "_submit_attached" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "_submit_attached", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "_change_attached" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "_change_attached", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { // && selector != null + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://sizzlejs.com/ + */ +(function( window, undefined ) { + +var cachedruns, + assertGetIdNotName, + Expr, + getText, + isXML, + contains, + compile, + sortOrder, + hasDuplicate, + outermostContext, + + baseHasDuplicate = true, + strundefined = "undefined", + + expando = ( "sizcache" + Math.random() ).replace( ".", "" ), + + Token = String, + document = window.document, + docElem = document.documentElement, + dirruns = 0, + done = 0, + pop = [].pop, + push = [].push, + slice = [].slice, + // Use a stripped-down indexOf if a native one is unavailable + indexOf = [].indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + // Augment a function for special use by Sizzle + markFunction = function( fn, value ) { + fn[ expando ] = value == null || value; + return fn; + }, + + createCache = function() { + var cache = {}, + keys = []; + + return markFunction(function( key, value ) { + // Only keep the most recent entries + if ( keys.push( key ) > Expr.cacheLength ) { + delete cache[ keys.shift() ]; + } + + // Retrieve with (key + " ") to avoid collision with native Object.prototype properties (see Issue #157) + return (cache[ key + " " ] = value); + }, cache ); + }, + + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + + // Regex + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors) + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors + operators = "([*^$|!~]?=)", + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + + "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", + + // Prefer arguments not in parens/brackets, + // then attribute selectors and non-pseudos (denoted by :), + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)", + + // For matchExpr.POS and matchExpr.needsContext + pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ), + rpseudo = new RegExp( pseudos ), + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/, + + rnot = /^:not/, + rsibling = /[\x20\t\r\n\f]*[+~]/, + rendsWithNot = /:not\($/, + + rheader = /h\d/i, + rinputs = /input|select|textarea|button/i, + + rbackslash = /\\(?!\\)/g, + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "POS": new RegExp( pos, "i" ), + "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + // For use in libraries implementing .is() + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" ) + }, + + // Support + + // Used for testing something on an element + assert = function( fn ) { + var div = document.createElement("div"); + + try { + return fn( div ); + } catch (e) { + return false; + } finally { + // release memory in IE + div = null; + } + }, + + // Check if getElementsByTagName("*") returns only elements + assertTagNameNoComments = assert(function( div ) { + div.appendChild( document.createComment("") ); + return !div.getElementsByTagName("*").length; + }), + + // Check if getAttribute returns normalized href attributes + assertHrefNotNormalized = assert(function( div ) { + div.innerHTML = ""; + return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && + div.firstChild.getAttribute("href") === "#"; + }), + + // Check if attributes should be retrieved by attribute nodes + assertAttributes = assert(function( div ) { + div.innerHTML = ""; + var type = typeof div.lastChild.getAttribute("multiple"); + // IE8 returns a string for some attributes even when not present + return type !== "boolean" && type !== "string"; + }), + + // Check if getElementsByClassName can be trusted + assertUsableClassName = assert(function( div ) { + // Opera can't find a second classname (in 9.6) + div.innerHTML = ""; + if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) { + return false; + } + + // Safari 3.2 caches class attributes and doesn't catch changes + div.lastChild.className = "e"; + return div.getElementsByClassName("e").length === 2; + }), + + // Check if getElementById returns elements by name + // Check if getElementsByName privileges form controls or returns elements by ID + assertUsableName = assert(function( div ) { + // Inject content + div.id = expando + 0; + div.innerHTML = "
"; + docElem.insertBefore( div, docElem.firstChild ); + + // Test + var pass = document.getElementsByName && + // buggy browsers will return fewer than the correct 2 + document.getElementsByName( expando ).length === 2 + + // buggy browsers will return more than the correct 0 + document.getElementsByName( expando + 0 ).length; + assertGetIdNotName = !document.getElementById( expando ); + + // Cleanup + docElem.removeChild( div ); + + return pass; + }); + +// If slice is not available, provide a backup +try { + slice.call( docElem.childNodes, 0 )[0].nodeType; +} catch ( e ) { + slice = function( i ) { + var elem, + results = []; + for ( ; (elem = this[i]); i++ ) { + results.push( elem ); + } + return results; + }; +} + +function Sizzle( selector, context, results, seed ) { + results = results || []; + context = context || document; + var match, elem, xml, m, + nodeType = context.nodeType; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( nodeType !== 1 && nodeType !== 9 ) { + return []; + } + + xml = isXML( context ); + + if ( !xml && !seed ) { + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) { + push.apply( results, slice.call(context.getElementsByClassName( m ), 0) ); + return results; + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed, xml ); +} + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + return Sizzle( expr, null, null, [ elem ] ).length > 0; +}; + +// Returns a function to use in pseudos for input types +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +// Returns a function to use in pseudos for buttons +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +// Returns a function to use in pseudos for positionals +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (see #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + } else { + + // If no nodeType, this is expected to be an array + for ( ; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } + return ret; +}; + +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +// Element contains another +contains = Sizzle.contains = docElem.contains ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) ); + } : + docElem.compareDocumentPosition ? + function( a, b ) { + return b && !!( a.compareDocumentPosition( b ) & 16 ); + } : + function( a, b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + return false; + }; + +Sizzle.attr = function( elem, name ) { + var val, + xml = isXML( elem ); + + if ( !xml ) { + name = name.toLowerCase(); + } + if ( (val = Expr.attrHandle[ name ]) ) { + return val( elem ); + } + if ( xml || assertAttributes ) { + return elem.getAttribute( name ); + } + val = elem.getAttributeNode( name ); + return val ? + typeof elem[ name ] === "boolean" ? + elem[ name ] ? name : null : + val.specified ? val.value : null : + null; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + // IE6/7 return a modified href + attrHandle: assertHrefNotNormalized ? + {} : + { + "href": function( elem ) { + return elem.getAttribute( "href", 2 ); + }, + "type": function( elem ) { + return elem.getAttribute("type"); + } + }, + + find: { + "ID": assertGetIdNotName ? + function( id, context, xml ) { + if ( typeof context.getElementById !== strundefined && !xml ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + } : + function( id, context, xml ) { + if ( typeof context.getElementById !== strundefined && !xml ) { + var m = context.getElementById( id ); + + return m ? + m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ? + [m] : + undefined : + []; + } + }, + + "TAG": assertTagNameNoComments ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + var elem, + tmp = [], + i = 0; + + for ( ; (elem = results[i]); i++ ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }, + + "NAME": assertUsableName && function( tag, context ) { + if ( typeof context.getElementsByName !== strundefined ) { + return context.getElementsByName( name ); + } + }, + + "CLASS": assertUsableClassName && function( className, context, xml ) { + if ( typeof context.getElementsByClassName !== strundefined && !xml ) { + return context.getElementsByClassName( className ); + } + } + }, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( rbackslash, "" ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 3 xn-component of xn+y argument ([+-]?\d*n|) + 4 sign of xn-component + 5 x of xn-component + 6 sign of y-component + 7 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1] === "nth" ) { + // nth-child requires argument + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) ); + match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" ); + + // other types prohibit arguments + } else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var unquoted, excess; + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + if ( match[3] ) { + match[2] = match[3]; + } else if ( (unquoted = match[4]) ) { + // Only check arguments that contain a pseudo + if ( rpseudo.test(unquoted) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + unquoted = unquoted.slice( 0, excess ); + match[0] = match[0].slice( 0, excess ); + } + match[2] = unquoted; + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + "ID": assertGetIdNotName ? + function( id ) { + id = id.replace( rbackslash, "" ); + return function( elem ) { + return elem.getAttribute("id") === id; + }; + } : + function( id ) { + id = id.replace( rbackslash, "" ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === id; + }; + }, + + "TAG": function( nodeName ) { + if ( nodeName === "*" ) { + return function() { return true; }; + } + nodeName = nodeName.replace( rbackslash, "" ).toLowerCase(); + + return function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ expando ][ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem, context ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.substr( result.length - check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, argument, first, last ) { + + if ( type === "nth" ) { + return function( elem ) { + var node, diff, + parent = elem.parentNode; + + if ( first === 1 && last === 0 ) { + return true; + } + + if ( parent ) { + diff = 0; + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + diff++; + if ( elem === node ) { + break; + } + } + } + } + + // Incorporate the offset (or cast to NaN), then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + }; + } + + return function( elem ) { + var node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + /* falls through */ + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), + // not comment, processing instructions, or others + // Thanks to Diego Perini for the nodeName shortcut + // Greater than "@" means alpha characters (specifically not starting with "#" or "?") + var nodeType; + elem = elem.firstChild; + while ( elem ) { + if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) { + return false; + } + elem = elem.nextSibling; + } + return true; + }, + + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "text": function( elem ) { + var type, attr; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && + (type = elem.type) === "text" && + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type ); + }, + + // Input types + "radio": createInputPseudo("radio"), + "checkbox": createInputPseudo("checkbox"), + "file": createInputPseudo("file"), + "password": createInputPseudo("password"), + "image": createInputPseudo("image"), + + "submit": createButtonPseudo("submit"), + "reset": createButtonPseudo("reset"), + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "focus": function( elem ) { + var doc = elem.ownerDocument; + return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + "active": function( elem ) { + return elem === elem.ownerDocument.activeElement; + }, + + // Positional types + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + for ( var i = 0; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + for ( var i = 1; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +function siblingCheck( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; +} + +sortOrder = docElem.compareDocumentPosition ? + function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + return ( !a.compareDocumentPosition || !b.compareDocumentPosition ? + a.compareDocumentPosition : + a.compareDocumentPosition(b) & 4 + ) ? -1 : 1; + } : + function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + +// Always assume the presence of duplicates if sort doesn't +// pass them to our comparison function (as in Google Chrome). +[0, 0].sort( sortOrder ); +baseHasDuplicate = !hasDuplicate; + +// Document sorting and removing duplicates +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + i = 1, + j = 0; + + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( ; (elem = results[i]); i++ ) { + if ( elem === results[ i - 1 ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + return results; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ expando ][ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( tokens = [] ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + tokens.push( matched = new Token( match.shift() ) ); + soFar = soFar.slice( matched.length ); + + // Cast descendant combinators to space + matched.type = match[0].replace( rtrim, " " ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + + tokens.push( matched = new Token( match.shift() ) ); + soFar = soFar.slice( matched.length ); + matched.type = type; + matched.matches = match; + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && combinator.dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( !xml ) { + var cache, + dirkey = dirruns + " " + doneName + " ", + cachedkey = dirkey + cachedruns; + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + if ( (cache = elem[ expando ]) === cachedkey ) { + return elem.sizset; + } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) { + if ( elem.sizset ) { + return elem; + } + } else { + elem[ expando ] = cachedkey; + if ( matcher( elem, context, xml ) ) { + elem.sizset = true; + return elem; + } + elem.sizset = false; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + if ( matcher( elem, context, xml ) ) { + return elem; + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && tokens.join("") + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, expandContext ) { + var elem, j, matcher, + setMatched = [], + matchedCount = 0, + i = "0", + unmatched = seed && [], + outermost = expandContext != null, + contextBackup = outermostContext, + // We must always have either seed elements or context + elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), + // Nested matchers should use non-integer dirruns + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E); + + if ( outermost ) { + outermostContext = context !== document && context; + cachedruns = superMatcher.el; + } + + // Add elements passing elementMatchers directly to results + for ( ; (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + for ( j = 0; (matcher = elementMatchers[j]); j++ ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + cachedruns = ++superMatcher.el; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + for ( j = 0; (matcher = setMatchers[j]); j++ ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + superMatcher.el = 0; + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ expando ][ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !group ) { + group = tokenize( selector ); + } + i = group.length; + while ( i-- ) { + cached = matcherFromTokens( group[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + } + return cached; +}; + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function select( selector, context, results, seed, xml ) { + var i, tokens, token, type, find, + match = tokenize( selector ), + j = match.length; + + if ( !seed ) { + // Try to minimize operations if there is only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && !xml && + Expr.relative[ tokens[1].type ] ) { + + context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0]; + if ( !context ) { + return results; + } + + selector = selector.slice( tokens.shift().length ); + } + + // Fetch a seed set for right-to-left matching + for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( rbackslash, "" ), + rsibling.test( tokens[0].type ) && context.parentNode || context, + xml + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && tokens.join(""); + if ( !selector ) { + push.apply( results, slice.call( seed, 0 ) ); + return results; + } + + break; + } + } + } + } + } + + // Compile and execute a filtering function + // Provide `match` to avoid retokenization if we modified the selector above + compile( selector, match )( + seed, + context, + xml, + results, + rsibling.test( selector ) + ); + return results; +} + +if ( document.querySelectorAll ) { + (function() { + var disconnectedMatch, + oldSelect = select, + rescape = /'|\\/g, + rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, + + // qSa(:focus) reports false when true (Chrome 21), no need to also add to buggyMatches since matches checks buggyQSA + // A support test would require too much code (would include document ready) + rbuggyQSA = [ ":focus" ], + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + // A support test would require too much code (would include document ready) + // just skip matchesSelector for :active + rbuggyMatches = [ ":active" ], + matches = docElem.matchesSelector || + docElem.mozMatchesSelector || + docElem.webkitMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector; + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explictly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // IE8 - Some boolean attributes are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here (do not put tests after this one) + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + + // Opera 10-12/IE9 - ^= $= *= and empty values + // Should not select anything + div.innerHTML = "

"; + if ( div.querySelectorAll("[test^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here (do not put tests after this one) + div.innerHTML = ""; + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push(":enabled", ":disabled"); + } + }); + + // rbuggyQSA always contains :focus, so no need for a length check + rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") ); + + select = function( selector, context, results, seed, xml ) { + // Only use querySelectorAll when not filtering, + // when this is not xml, + // and when no QSA bugs apply + if ( !seed && !xml && !rbuggyQSA.test( selector ) ) { + var groups, i, + old = true, + nid = expando, + newContext = context, + newSelector = context.nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + groups[i].join(""); + } + newContext = rsibling.test( selector ) && context.parentNode || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, slice.call( newContext.querySelectorAll( + newSelector + ), 0 ) ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + + return oldSelect( selector, context, results, seed, xml ); + }; + + if ( matches ) { + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + try { + matches.call( div, "[test!='']:sizzle" ); + rbuggyMatches.push( "!=", pseudos ); + } catch ( e ) {} + }); + + // rbuggyMatches always contains :active and :focus, so no need for a length check + rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") ); + + Sizzle.matchesSelector = function( elem, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + // rbuggyMatches always contains :active, so no need for an existence check + if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && !rbuggyQSA.test( expr ) ) { + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, null, null, [ elem ] ).length > 0; + }; + } + })(); +} + +// Deprecated +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Back-compat +function setFilters() {} +Expr.filters = setFilters.prototype = Expr.pseudos; +Expr.setFilters = new setFilters(); + +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})( window ); +var runtil = /Until$/, + rparentsprev = /^(?:parents|prev(?:Until|All))/, + isSimple = /^.[^:#\[\.,]*$/, + rneedsContext = jQuery.expr.match.needsContext, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var i, l, length, n, r, ret, + self = this; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + ret = this.pushStack( "", "find", selector ); + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + rneedsContext.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + ret = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + cur = this[i]; + + while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + } + cur = cur.parentNode; + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +jQuery.fn.andSelf = jQuery.fn.addBack; + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( this.length > 1 && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, core_slice.call( arguments ).join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /]", "i"), + rcheckableType = /^(?:checkbox|radio)$/, + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /\/(java|ecma)script/i, + rcleanScript = /^\s*\s*$/g, + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
", "
" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + col: [ 2, "", "
" ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, +// unless wrapped in a div with non-breaking characters in front of it. +if ( !jQuery.support.htmlSerialize ) { + wrapMap._default = [ 1, "X
", "
" ]; +} + +jQuery.fn.extend({ + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + }, + + append: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { + this.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { + this.insertBefore( elem, this.firstChild ); + } + }); + }, + + before: function() { + if ( !isDisconnected( this[0] ) ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this ); + }); + } + + if ( arguments.length ) { + var set = jQuery.clean( arguments ); + return this.pushStack( jQuery.merge( set, this ), "before", this.selector ); + } + }, + + after: function() { + if ( !isDisconnected( this[0] ) ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + }); + } + + if ( arguments.length ) { + var set = jQuery.clean( arguments ); + return this.pushStack( jQuery.merge( this, set ), "after", this.selector ); + } + }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + jQuery.cleanData( [ elem ] ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function () { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return jQuery.access( this, function( value ) { + var elem = this[0] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName( "*" ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function( value ) { + if ( !isDisconnected( this[0] ) ) { + // Make sure that the elements are removed from the DOM before they are inserted + // this can help fix replacing a parent with child elements + if ( jQuery.isFunction( value ) ) { + return this.each(function(i) { + var self = jQuery(this), old = self.html(); + self.replaceWith( value.call( this, i, old ) ); + }); + } + + if ( typeof value !== "string" ) { + value = jQuery( value ).detach(); + } + + return this.each(function() { + var next = this.nextSibling, + parent = this.parentNode; + + jQuery( this ).remove(); + + if ( next ) { + jQuery(next).before( value ); + } else { + jQuery(parent).append( value ); + } + }); + } + + return this.length ? + this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : + this; + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, table, callback ) { + + // Flatten any nested arrays + args = [].concat.apply( [], args ); + + var results, first, fragment, iNoClone, + i = 0, + value = args[0], + scripts = [], + l = this.length; + + // We can't cloneNode fragments that contain checked, in WebKit + if ( !jQuery.support.checkClone && l > 1 && typeof value === "string" && rchecked.test( value ) ) { + return this.each(function() { + jQuery(this).domManip( args, table, callback ); + }); + } + + if ( jQuery.isFunction(value) ) { + return this.each(function(i) { + var self = jQuery(this); + args[0] = value.call( this, i, table ? self.html() : undefined ); + self.domManip( args, table, callback ); + }); + } + + if ( this[0] ) { + results = jQuery.buildFragment( args, this, scripts ); + fragment = results.fragment; + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + table = table && jQuery.nodeName( first, "tr" ); + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + // Fragments from the fragment cache must always be cloned and never used in place. + for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) { + callback.call( + table && jQuery.nodeName( this[i], "table" ) ? + findOrAppend( this[i], "tbody" ) : + this[i], + i === iNoClone ? + fragment : + jQuery.clone( fragment, true, true ) + ); + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + + if ( scripts.length ) { + jQuery.each( scripts, function( i, elem ) { + if ( elem.src ) { + if ( jQuery.ajax ) { + jQuery.ajax({ + url: elem.src, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); + } else { + jQuery.error("no ajax"); + } + } else { + jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + }); + } + } + + return this; + } +}); + +function findOrAppend( elem, tag ) { + return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) ); +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function cloneFixAttributes( src, dest ) { + var nodeName; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + // clearAttributes removes the attributes, which we don't want, + // but also removes the attachEvent events, which we *do* want + if ( dest.clearAttributes ) { + dest.clearAttributes(); + } + + // mergeAttributes, in contrast, only merges back on the + // original attributes, not the events + if ( dest.mergeAttributes ) { + dest.mergeAttributes( src ); + } + + nodeName = dest.nodeName.toLowerCase(); + + if ( nodeName === "object" ) { + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + + // IE blanks contents when cloning scripts + } else if ( nodeName === "script" && dest.text !== src.text ) { + dest.text = src.text; + } + + // Event data gets referenced instead of copied if the expando + // gets copied too + dest.removeAttribute( jQuery.expando ); +} + +jQuery.buildFragment = function( args, context, scripts ) { + var fragment, cacheable, cachehit, + first = args[ 0 ]; + + // Set context from what may come in as undefined or a jQuery collection or a node + // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 & + // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception + context = context || document; + context = !context.nodeType && context[0] || context; + context = context.ownerDocument || context; + + // Only cache "small" (1/2 KB) HTML strings that are associated with the main document + // Cloning options loses the selected state, so don't cache them + // IE 6 doesn't like it when you put or elements in a fragment + // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache + // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501 + if ( args.length === 1 && typeof first === "string" && first.length < 512 && context === document && + first.charAt(0) === "<" && !rnocache.test( first ) && + (jQuery.support.checkClone || !rchecked.test( first )) && + (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) { + + // Mark cacheable and look for a hit + cacheable = true; + fragment = jQuery.fragments[ first ]; + cachehit = fragment !== undefined; + } + + if ( !fragment ) { + fragment = context.createDocumentFragment(); + jQuery.clean( args, context, fragment, scripts ); + + // Update the cache, but only store false + // unless this is a second parsing of the same content + if ( cacheable ) { + jQuery.fragments[ first ] = cachehit && fragment; + } + } + + return { fragment: fragment, cacheable: cacheable }; +}; + +jQuery.fragments = {}; + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + l = insert.length, + parent = this.length === 1 && this[0].parentNode; + + if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) { + insert[ original ]( this[0] ); + return this; + } else { + for ( ; i < l; i++ ) { + elems = ( i > 0 ? this.clone(true) : this ).get(); + jQuery( insert[i] )[ original ]( elems ); + ret = ret.concat( elems ); + } + + return this.pushStack( ret, name, insert.selector ); + } + }; +}); + +function getAll( elem ) { + if ( typeof elem.getElementsByTagName !== "undefined" ) { + return elem.getElementsByTagName( "*" ); + + } else if ( typeof elem.querySelectorAll !== "undefined" ) { + return elem.querySelectorAll( "*" ); + + } else { + return []; + } +} + +// Used in clean, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var srcElements, + destElements, + i, + clone; + + if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + // IE copies events bound via attachEvent when using cloneNode. + // Calling detachEvent on the clone will also remove the events + // from the original. In order to get around this, we use some + // proprietary methods to clear the events. Thanks to MooTools + // guys for this hotness. + + cloneFixAttributes( elem, clone ); + + // Using Sizzle here is crazy slow, so we use getElementsByTagName instead + srcElements = getAll( elem ); + destElements = getAll( clone ); + + // Weird iteration because IE will replace the length property + // with an element if you are cloning the body and one of the + // elements on the page has a name or id of "length" + for ( i = 0; srcElements[i]; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + cloneFixAttributes( srcElements[i], destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + cloneCopyEvent( elem, clone ); + + if ( deepDataAndEvents ) { + srcElements = getAll( elem ); + destElements = getAll( clone ); + + for ( i = 0; srcElements[i]; ++i ) { + cloneCopyEvent( srcElements[i], destElements[i] ); + } + } + } + + srcElements = destElements = null; + + // Return the cloned set + return clone; + }, + + clean: function( elems, context, fragment, scripts ) { + var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags, + safe = context === document && safeFragment, + ret = []; + + // Ensure that context is a document + if ( !context || typeof context.createDocumentFragment === "undefined" ) { + context = document; + } + + // Use the already-created safe fragment if context permits + for ( i = 0; (elem = elems[i]) != null; i++ ) { + if ( typeof elem === "number" ) { + elem += ""; + } + + if ( !elem ) { + continue; + } + + // Convert html string into DOM nodes + if ( typeof elem === "string" ) { + if ( !rhtml.test( elem ) ) { + elem = context.createTextNode( elem ); + } else { + // Ensure a safe container in which to render the html + safe = safe || createSafeFragment( context ); + div = context.createElement("div"); + safe.appendChild( div ); + + // Fix "XHTML"-style tags in all browsers + elem = elem.replace(rxhtmlTag, "<$1>"); + + // Go to html and back, then peel off extra wrappers + tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + depth = wrap[0]; + div.innerHTML = wrap[1] + elem + wrap[2]; + + // Move to the right depth + while ( depth-- ) { + div = div.lastChild; + } + + // Remove IE's autoinserted from table fragments + if ( !jQuery.support.tbody ) { + + // String was a , *may* have spurious + hasBody = rtbody.test(elem); + tbody = tag === "table" && !hasBody ? + div.firstChild && div.firstChild.childNodes : + + // String was a bare or + wrap[1] === "
" && !hasBody ? + div.childNodes : + []; + + for ( j = tbody.length - 1; j >= 0 ; --j ) { + if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { + tbody[ j ].parentNode.removeChild( tbody[ j ] ); + } + } + } + + // IE completely kills leading whitespace when innerHTML is used + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); + } + + elem = div.childNodes; + + // Take out of fragment container (we need a fresh div each time) + div.parentNode.removeChild( div ); + } + } + + if ( elem.nodeType ) { + ret.push( elem ); + } else { + jQuery.merge( ret, elem ); + } + } + + // Fix #11356: Clear elements from safeFragment + if ( div ) { + elem = div = safe = null; + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !jQuery.support.appendChecked ) { + for ( i = 0; (elem = ret[i]) != null; i++ ) { + if ( jQuery.nodeName( elem, "input" ) ) { + fixDefaultChecked( elem ); + } else if ( typeof elem.getElementsByTagName !== "undefined" ) { + jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); + } + } + } + + // Append elements to a provided document fragment + if ( fragment ) { + // Special handling of each script element + handleScript = function( elem ) { + // Check if we consider it executable + if ( !elem.type || rscriptType.test( elem.type ) ) { + // Detach the script and store it in the scripts array (if provided) or the fragment + // Return truthy to indicate that it has been handled + return scripts ? + scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) : + fragment.appendChild( elem ); + } + }; + + for ( i = 0; (elem = ret[i]) != null; i++ ) { + // Check if we're done after handling an executable script + if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) { + // Append to fragment and handle embedded scripts + fragment.appendChild( elem ); + if ( typeof elem.getElementsByTagName !== "undefined" ) { + // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration + jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript ); + + // Splice the scripts into ret after their former ancestor and advance our index beyond them + ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); + i += jsTags.length; + } + } + } + } + + return ret; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var data, id, elem, type, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = jQuery.support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + jQuery.deletedIds.push( id ); + } + } + } + } + } +}); +// Limit scope pollution from any deprecated API +(function() { + +var matched, browser; + +// Use of jQuery.browser is frowned upon. +// More details: http://api.jquery.com/jQuery.browser +// jQuery.uaMatch maintained for back-compat +jQuery.uaMatch = function( ua ) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || + /(webkit)[ \/]([\w.]+)/.exec( ua ) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || + /(msie) ([\w.]+)/.exec( ua ) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; +}; + +matched = jQuery.uaMatch( navigator.userAgent ); +browser = {}; + +if ( matched.browser ) { + browser[ matched.browser ] = true; + browser.version = matched.version; +} + +// Chrome is Webkit, but Webkit is also Safari. +if ( browser.chrome ) { + browser.webkit = true; +} else if ( browser.webkit ) { + browser.safari = true; +} + +jQuery.browser = browser; + +jQuery.sub = function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; +}; + +})(); +var curCSS, iframe, iframeDoc, + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity=([^)]*)/, + rposition = /^(top|right|bottom|left)$/, + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rmargin = /^margin/, + rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), + rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), + rrelNum = new RegExp( "^([-+])=(" + core_pnum + ")", "i" ), + elemdisplay = { BODY: "block" }, + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: 0, + fontWeight: 400 + }, + + cssExpand = [ "Top", "Right", "Bottom", "Left" ], + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ], + + eventsToggle = jQuery.fn.toggle; + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function isHidden( elem, el ) { + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); +} + +function showHide( elements, show ) { + var elem, display, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + values[ index ] = jQuery._data( elem, "olddisplay" ); + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && elem.style.display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); + } + } else { + display = curCSS( elem, "display" ); + + if ( !values[ index ] && display !== "none" ) { + jQuery._data( elem, "olddisplay", display ); + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +jQuery.fn.extend({ + css: function( name, value ) { + return jQuery.access( this, function( elem, name, value ) { + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state, fn2 ) { + var bool = typeof state === "boolean"; + + if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) { + return eventsToggle.apply( this, arguments ); + } + + return this.each(function() { + if ( bool ? state : isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + + } + } + } + }, + + // Exclude the following css properties to add px + cssNumber: { + "fillOpacity": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that NaN and null values aren't set. See: #7116 + if ( value == null || type === "number" && isNaN( value ) ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + // Wrapped to prevent IE from throwing errors when 'invalid' values are provided + // Fixes bug #5509 + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, numeric, extra ) { + var val, num, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( numeric || extra !== undefined ) { + num = parseFloat( val ); + return numeric || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations + swap: function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; + } +}); + +// NOTE: To any future maintainer, we've window.getComputedStyle +// because jsdom on node.js will break without it. +if ( window.getComputedStyle ) { + curCSS = function( elem, name ) { + var ret, width, minWidth, maxWidth, + computed = window.getComputedStyle( elem, null ), + style = elem.style; + + if ( computed ) { + + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret; + }; +} else if ( document.documentElement.currentStyle ) { + curCSS = function( elem, name ) { + var left, rsLeft, + ret = elem.currentStyle && elem.currentStyle[ name ], + style = elem.style; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rsLeft = elem.runtimeStyle && elem.runtimeStyle.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + elem.runtimeStyle.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + elem.runtimeStyle.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + // we use jQuery.css instead of curCSS here + // because of the reliableMarginRight CSS hook! + val += jQuery.css( elem, extra + cssExpand[ i ], true ); + } + + // From this point on we use curCSS for maximum performance (relevant in animations) + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } else { + // at this point, extra isn't content, so add padding + val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + valueIsBorderBox = true, + isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox + ) + ) + "px"; +} + + +// Try to determine the default display value of an element +function css_defaultDisplay( nodeName ) { + if ( elemdisplay[ nodeName ] ) { + return elemdisplay[ nodeName ]; + } + + var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ), + display = elem.css("display"); + elem.remove(); + + // If the simple way fails, + // get element's real default display by attaching it to a temp iframe + if ( display === "none" || display === "" ) { + // Use the already-created iframe if possible + iframe = document.body.appendChild( + iframe || jQuery.extend( document.createElement("iframe"), { + frameBorder: 0, + width: 0, + height: 0 + }) + ); + + // Create a cacheable copy of the iframe document on first call. + // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML + // document to it; WebKit & Firefox won't allow reusing the iframe document. + if ( !iframeDoc || !iframe.createElement ) { + iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; + iframeDoc.write(""); + iframeDoc.close(); + } + + elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) ); + + display = curCSS( elem, "display" ); + document.body.removeChild( iframe ); + } + + // Store the correct default display + elemdisplay[ nodeName ] = display; + + return display; +} + +jQuery.each([ "height", "width" ], function( i, name ) { + jQuery.cssHooks[ name ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + // certain elements can have dimension info if we invisibly show them + // however, it must have a current display style that would benefit from this + if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) { + return jQuery.swap( elem, cssShow, function() { + return getWidthOrHeight( elem, name, extra ); + }); + } else { + return getWidthOrHeight( elem, name, extra ); + } + } + }, + + set: function( elem, value, extra ) { + return setPositiveNumber( elem, value, extra ? + augmentWidthOrHeight( + elem, + name, + extra, + jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box" + ) : 0 + ); + } + }; +}); + +if ( !jQuery.support.opacity ) { + jQuery.cssHooks.opacity = { + get: function( elem, computed ) { + // IE uses filters for opacity + return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? + ( 0.01 * parseFloat( RegExp.$1 ) ) + "" : + computed ? "1" : ""; + }, + + set: function( elem, value ) { + var style = elem.style, + currentStyle = elem.currentStyle, + opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", + filter = currentStyle && currentStyle.filter || style.filter || ""; + + // IE has trouble with opacity if it does not have layout + // Force it by setting the zoom level + style.zoom = 1; + + // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 + if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" && + style.removeAttribute ) { + + // Setting style.filter to null, "" & " " still leave "filter:" in the cssText + // if "filter:" is present at all, clearType is disabled, we want to avoid this + // style.removeAttribute is IE Only, but so apparently is this code path... + style.removeAttribute( "filter" ); + + // if there there is no filter style applied in a css rule, we are done + if ( currentStyle && !currentStyle.filter ) { + return; + } + } + + // otherwise, set new filter values + style.filter = ralpha.test( filter ) ? + filter.replace( ralpha, opacity ) : + filter + " " + opacity; + } + }; +} + +// These hooks cannot be added until DOM ready because the support test +// for it is not run until after DOM ready +jQuery(function() { + if ( !jQuery.support.reliableMarginRight ) { + jQuery.cssHooks.marginRight = { + get: function( elem, computed ) { + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + // Work around by temporarily setting element display to inline-block + return jQuery.swap( elem, { "display": "inline-block" }, function() { + if ( computed ) { + return curCSS( elem, "marginRight" ); + } + }); + } + }; + } + + // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 + // getComputedStyle returns percent when specified for top/left/bottom/right + // rather than make the css module depend on the offset module, we just check for it here + if ( !jQuery.support.pixelPosition && jQuery.fn.position ) { + jQuery.each( [ "top", "left" ], function( i, prop ) { + jQuery.cssHooks[ prop ] = { + get: function( elem, computed ) { + if ( computed ) { + var ret = curCSS( elem, prop ); + // if curCSS returns percentage, fallback to offset + return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + "px" : ret; + } + } + }; + }); + } + +}); + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.hidden = function( elem ) { + return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, "display" )) === "none"); + }; + + jQuery.expr.filters.visible = function( elem ) { + return !jQuery.expr.filters.hidden( elem ); + }; +} + +// These hooks are used by animate to expand properties +jQuery.each({ + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i, + + // assumes a single number if not a string + parts = typeof value === "string" ? value.split(" ") : [ value ], + expanded = {}; + + for ( i = 0; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( !rmargin.test( prefix ) ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +}); +var r20 = /%20/g, + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, + rselectTextarea = /^(?:select|textarea)/i; + +jQuery.fn.extend({ + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map(function(){ + return this.elements ? jQuery.makeArray( this.elements ) : this; + }) + .filter(function(){ + return this.name && !this.disabled && + ( this.checked || rselectTextarea.test( this.nodeName ) || + rinput.test( this.type ) ); + }) + .map(function( i, elem ){ + var val = jQuery( this ).val(); + + return val == null ? + null : + jQuery.isArray( val ) ? + jQuery.map( val, function( val, i ){ + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }) : + { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }).get(); + } +}); + +//Serialize an array of form elements or a set of +//key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, value ) { + // If value is a function, invoke it and return its value + value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); + s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); + }; + + // Set traditional to true for jQuery <= 1.3.2 behavior. + if ( traditional === undefined ) { + traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + }); + + } else { + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ).replace( r20, "+" ); +}; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( jQuery.isArray( obj ) ) { + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + // If array item is non-scalar (array or object), encode its + // numeric index to resolve deserialization ambiguity issues. + // Note that rack (as of 1.0.0) can't currently deserialize + // nested arrays properly, and attempting to do so may cause + // a server error. Possible fixes are to modify rack's + // deserialization algorithm or to provide an option or flag + // to force array serialization to be shallow. + buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); + } + }); + + } else if ( !traditional && jQuery.type( obj ) === "object" ) { + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + // Serialize scalar item. + add( prefix, obj ); + } +} +var + // Document location + ajaxLocParts, + ajaxLocation, + + rhash = /#.*$/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + rquery = /\?/, + rscript = /)<[^<]*)*<\/script>/gi, + rts = /([?&])_=[^&]*/, + rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, + + // Keep a copy of the old load method + _load = jQuery.fn.load, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = ["*/"] + ["*"]; + +// #8138, IE may throw an exception when accessing +// a field from window.location if document.domain has been set +try { + ajaxLocation = location.href; +} catch( e ) { + // Use the href attribute of an A element + // since IE will modify it given document.location + ajaxLocation = document.createElement( "a" ); + ajaxLocation.href = ""; + ajaxLocation = ajaxLocation.href; +} + +// Segment location into parts +ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, list, placeBefore, + dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ), + i = 0, + length = dataTypes.length; + + if ( jQuery.isFunction( func ) ) { + // For each dataType in the dataTypeExpression + for ( ; i < length; i++ ) { + dataType = dataTypes[ i ]; + // We control if we're asked to add before + // any existing element + placeBefore = /^\+/.test( dataType ); + if ( placeBefore ) { + dataType = dataType.substr( 1 ) || "*"; + } + list = structure[ dataType ] = structure[ dataType ] || []; + // then we add to the structure accordingly + list[ placeBefore ? "unshift" : "push" ]( func ); + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, + dataType /* internal */, inspected /* internal */ ) { + + dataType = dataType || options.dataTypes[ 0 ]; + inspected = inspected || {}; + + inspected[ dataType ] = true; + + var selection, + list = structure[ dataType ], + i = 0, + length = list ? list.length : 0, + executeOnly = ( structure === prefilters ); + + for ( ; i < length && ( executeOnly || !selection ); i++ ) { + selection = list[ i ]( options, originalOptions, jqXHR ); + // If we got redirected to another dataType + // we try there if executing only and not done already + if ( typeof selection === "string" ) { + if ( !executeOnly || inspected[ selection ] ) { + selection = undefined; + } else { + options.dataTypes.unshift( selection ); + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, selection, inspected ); + } + } + } + // If we're only executing or nothing was selected + // we try the catchall dataType if not done already + if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, "*", inspected ); + } + // unnecessary when only executing (prefilters) + // but it'll be ignored by the caller in that case + return selection; +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } +} + +jQuery.fn.load = function( url, params, callback ) { + if ( typeof url !== "string" && _load ) { + return _load.apply( this, arguments ); + } + + // Don't do a request if no elements are being requested + if ( !this.length ) { + return this; + } + + var selector, type, response, + self = this, + off = url.indexOf(" "); + + if ( off >= 0 ) { + selector = url.slice( off, url.length ); + url = url.slice( 0, off ); + } + + // If it's a function + if ( jQuery.isFunction( params ) ) { + + // We assume that it's the callback + callback = params; + params = undefined; + + // Otherwise, build a param string + } else if ( params && typeof params === "object" ) { + type = "POST"; + } + + // Request the remote document + jQuery.ajax({ + url: url, + + // if "type" variable is undefined, then "GET" method will be used + type: type, + dataType: "html", + data: params, + complete: function( jqXHR, status ) { + if ( callback ) { + self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); + } + } + }).done(function( responseText ) { + + // Save response for use in complete callback + response = arguments; + + // See if a selector was specified + self.html( selector ? + + // Create a dummy div to hold the results + jQuery("
") + + // inject the contents of the document in, removing the scripts + // to avoid any 'Permission Denied' errors in IE + .append( responseText.replace( rscript, "" ) ) + + // Locate the specified elements + .find( selector ) : + + // If not, just inject the full result + responseText ); + + }); + + return this; +}; + +// Attach a bunch of functions for handling common AJAX events +jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ + jQuery.fn[ o ] = function( f ){ + return this.on( o, f ); + }; +}); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + // shift arguments if data argument was omitted + if ( jQuery.isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + return jQuery.ajax({ + type: method, + url: url, + data: data, + success: callback, + dataType: type + }); + }; +}); + +jQuery.extend({ + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + if ( settings ) { + // Building a settings object + ajaxExtend( target, jQuery.ajaxSettings ); + } else { + // Extending ajaxSettings + settings = target; + target = jQuery.ajaxSettings; + } + ajaxExtend( target, settings ); + return target; + }, + + ajaxSettings: { + url: ajaxLocation, + isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), + global: true, + type: "GET", + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + processData: true, + async: true, + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + xml: "application/xml, text/xml", + html: "text/html", + text: "text/plain", + json: "application/json, text/javascript", + "*": allTypes + }, + + contents: { + xml: /xml/, + html: /html/, + json: /json/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText" + }, + + // List of data converters + // 1) key format is "source_type destination_type" (a single space in-between) + // 2) the catchall symbol "*" can be used for source_type + converters: { + + // Convert anything to text + "* text": window.String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": jQuery.parseJSON, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + context: true, + url: true + } + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var // ifModified key + ifModifiedKey, + // Response headers + responseHeadersString, + responseHeaders, + // transport + transport, + // timeout handle + timeoutTimer, + // Cross-domain detection vars + parts, + // To know if global events are to be dispatched + fireGlobals, + // Loop variable + i, + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + // Callbacks context + callbackContext = s.context || s, + // Context for global events + // It's the callbackContext if one was provided in the options + // and if it's a DOM node or a jQuery collection + globalEventContext = callbackContext !== s && + ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? + jQuery( callbackContext ) : jQuery.event, + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + // Status-dependent callbacks + statusCode = s.statusCode || {}, + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + // The jqXHR state + state = 0, + // Default abort message + strAbort = "canceled", + // Fake xhr + jqXHR = { + + readyState: 0, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( !state ) { + var lname = name.toLowerCase(); + name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Raw string + getAllResponseHeaders: function() { + return state === 2 ? responseHeadersString : null; + }, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( state === 2 ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match === undefined ? null : match; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( !state ) { + s.mimeType = type; + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + statusText = statusText || strAbort; + if ( transport ) { + transport.abort( statusText ); + } + done( 0, statusText ); + return this; + } + }; + + // Callback for when everything is done + // It is defined here because jslint complains if it is declared + // at the end of the function (which would be more logical and readable) + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Called once + if ( state === 2 ) { + return; + } + + // State is "done" now + state = 2; + + // Clear timeout if it exists + if ( timeoutTimer ) { + clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // If successful, handle type chaining + if ( status >= 200 && status < 300 || status === 304 ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + + modified = jqXHR.getResponseHeader("Last-Modified"); + if ( modified ) { + jQuery.lastModified[ ifModifiedKey ] = modified; + } + modified = jqXHR.getResponseHeader("Etag"); + if ( modified ) { + jQuery.etag[ ifModifiedKey ] = modified; + } + } + + // If not modified + if ( status === 304 ) { + + statusText = "notmodified"; + isSuccess = true; + + // If we have data + } else { + + isSuccess = ajaxConvert( s, response ); + statusText = isSuccess.state; + success = isSuccess.data; + error = isSuccess.error; + isSuccess = !error; + } + } else { + // We extract error from statusText + // then normalize statusText and status for non-aborts + error = statusText; + if ( !statusText || status ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + // Attach deferreds + deferred.promise( jqXHR ); + jqXHR.success = jqXHR.done; + jqXHR.error = jqXHR.fail; + jqXHR.complete = completeDeferred.add; + + // Status-dependent callbacks + jqXHR.statusCode = function( map ) { + if ( map ) { + var tmp; + if ( state < 2 ) { + for ( tmp in map ) { + statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ]; + } + } else { + tmp = map[ jqXHR.status ]; + jqXHR.always( tmp ); + } + } + return this; + }; + + // Remove hash character (#7531: and string promotion) + // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) + // We also use the url parameter if available + s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); + + // Extract dataTypes list + s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace ); + + // A cross-domain request is in order when we have a protocol:host:port mismatch + if ( s.crossDomain == null ) { + parts = rurl.exec( s.url.toLowerCase() ); + s.crossDomain = !!( parts && + ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || + ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != + ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ) + ); + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( state === 2 ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + fireGlobals = s.global; + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // If data is available, append data to url + if ( s.data ) { + s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Get ifModifiedKey before adding the anti-cache parameter + ifModifiedKey = s.url; + + // Add anti-cache in url if needed + if ( s.cache === false ) { + + var ts = jQuery.now(), + // try replacing _= if it is there + ret = s.url.replace( rts, "$1_=" + ts ); + + // if nothing was replaced, add timestamp to the end + s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + ifModifiedKey = ifModifiedKey || s.url; + if ( jQuery.lastModified[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] ); + } + if ( jQuery.etag[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] ); + } + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? + s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { + // Abort if not done already and return + return jqXHR.abort(); + + } + + // aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + for ( i in { success: 1, error: 1, complete: 1 } ) { + jqXHR[ i ]( s[ i ] ); + } + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = setTimeout( function(){ + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + state = 1; + transport.send( requestHeaders, done ); + } catch (e) { + // Propagate exception as error if not done + if ( state < 2 ) { + done( -1, e ); + // Simply rethrow otherwise + } else { + throw e; + } + } + } + + return jqXHR; + }, + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {} + +}); + +/* Handles responses to an ajax request: + * - sets all responseXXX fields accordingly + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes, + responseFields = s.responseFields; + + // Fill responseXXX fields + for ( type in responseFields ) { + if ( type in responses ) { + jqXHR[ responseFields[type] ] = responses[ type ]; + } + } + + // Remove auto dataType and get content-type in the process + while( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +// Chain conversions given the request and the original response +function ajaxConvert( s, response ) { + + var conv, conv2, current, tmp, + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(), + prev = dataTypes[ 0 ], + converters = {}, + i = 0; + + // Apply the dataFilter if provided + if ( s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + // Convert to each sequential dataType, tolerating list modification + for ( ; (current = dataTypes[++i]); ) { + + // There's only work to do if current dataType is non-auto + if ( current !== "*" ) { + + // Convert response if prev dataType is non-auto and differs from current + if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split(" "); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.splice( i--, 0, current ); + } + + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s["throws"] ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; + } + } + } + } + + // Update prev for next iteration + prev = current; + } + } + + return { state: "success", data: response }; +} +var oldCallbacks = [], + rquestion = /\?/, + rjsonp = /(=)\?(?=&|$)|\?\?/, + nonce = jQuery.now(); + +// Default jsonp settings +jQuery.ajaxSetup({ + jsonp: "callback", + jsonpCallback: function() { + var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); + this[ callback ] = true; + return callback; + } +}); + +// Detect, normalize options and install callbacks for jsonp requests +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { + + var callbackName, overwritten, responseContainer, + data = s.data, + url = s.url, + hasCallback = s.jsonp !== false, + replaceInUrl = hasCallback && rjsonp.test( url ), + replaceInData = hasCallback && !replaceInUrl && typeof data === "string" && + !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && + rjsonp.test( data ); + + // Handle iff the expected data type is "jsonp" or we have a parameter to set + if ( s.dataTypes[ 0 ] === "jsonp" || replaceInUrl || replaceInData ) { + + // Get callback name, remembering preexisting value associated with it + callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? + s.jsonpCallback() : + s.jsonpCallback; + overwritten = window[ callbackName ]; + + // Insert callback into url or form data + if ( replaceInUrl ) { + s.url = url.replace( rjsonp, "$1" + callbackName ); + } else if ( replaceInData ) { + s.data = data.replace( rjsonp, "$1" + callbackName ); + } else if ( hasCallback ) { + s.url += ( rquestion.test( url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; + } + + // Use data converter to retrieve json after script execution + s.converters["script json"] = function() { + if ( !responseContainer ) { + jQuery.error( callbackName + " was not called" ); + } + return responseContainer[ 0 ]; + }; + + // force json dataType + s.dataTypes[ 0 ] = "json"; + + // Install callback + window[ callbackName ] = function() { + responseContainer = arguments; + }; + + // Clean-up function (fires after converters) + jqXHR.always(function() { + // Restore preexisting value + window[ callbackName ] = overwritten; + + // Save back as free + if ( s[ callbackName ] ) { + // make sure that re-using the options doesn't screw things around + s.jsonpCallback = originalSettings.jsonpCallback; + + // save the callback name for future use + oldCallbacks.push( callbackName ); + } + + // Call if it was a function and we have a response + if ( responseContainer && jQuery.isFunction( overwritten ) ) { + overwritten( responseContainer[ 0 ] ); + } + + responseContainer = overwritten = undefined; + }); + + // Delegate to script + return "script"; + } +}); +// Install script dataType +jQuery.ajaxSetup({ + accepts: { + script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /javascript|ecmascript/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +}); + +// Handle cache's special case and global +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + s.global = false; + } +}); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function(s) { + + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + + var script, + head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; + + return { + + send: function( _, callback ) { + + script = document.createElement( "script" ); + + script.async = "async"; + + if ( s.scriptCharset ) { + script.charset = s.scriptCharset; + } + + script.src = s.url; + + // Attach handlers for all browsers + script.onload = script.onreadystatechange = function( _, isAbort ) { + + if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { + + // Handle memory leak in IE + script.onload = script.onreadystatechange = null; + + // Remove the script + if ( head && script.parentNode ) { + head.removeChild( script ); + } + + // Dereference the script + script = undefined; + + // Callback if not abort + if ( !isAbort ) { + callback( 200, "success" ); + } + } + }; + // Use insertBefore instead of appendChild to circumvent an IE6 bug. + // This arises when a base node is used (#2709 and #4378). + head.insertBefore( script, head.firstChild ); + }, + + abort: function() { + if ( script ) { + script.onload( 0, 1 ); + } + } + }; + } +}); +var xhrCallbacks, + // #5280: Internet Explorer will keep connections alive if we don't abort on unload + xhrOnUnloadAbort = window.ActiveXObject ? function() { + // Abort all pending requests + for ( var key in xhrCallbacks ) { + xhrCallbacks[ key ]( 0, 1 ); + } + } : false, + xhrId = 0; + +// Functions to create xhrs +function createStandardXHR() { + try { + return new window.XMLHttpRequest(); + } catch( e ) {} +} + +function createActiveXHR() { + try { + return new window.ActiveXObject( "Microsoft.XMLHTTP" ); + } catch( e ) {} +} + +// Create the request object +// (This is still attached to ajaxSettings for backward compatibility) +jQuery.ajaxSettings.xhr = window.ActiveXObject ? + /* Microsoft failed to properly + * implement the XMLHttpRequest in IE7 (can't request local files), + * so we use the ActiveXObject when it is available + * Additionally XMLHttpRequest can be disabled in IE7/IE8 so + * we need a fallback. + */ + function() { + return !this.isLocal && createStandardXHR() || createActiveXHR(); + } : + // For all other browsers, use the standard XMLHttpRequest object + createStandardXHR; + +// Determine support properties +(function( xhr ) { + jQuery.extend( jQuery.support, { + ajax: !!xhr, + cors: !!xhr && ( "withCredentials" in xhr ) + }); +})( jQuery.ajaxSettings.xhr() ); + +// Create transport if the browser can provide an xhr +if ( jQuery.support.ajax ) { + + jQuery.ajaxTransport(function( s ) { + // Cross domain only allowed if supported through XMLHttpRequest + if ( !s.crossDomain || jQuery.support.cors ) { + + var callback; + + return { + send: function( headers, complete ) { + + // Get a new xhr + var handle, i, + xhr = s.xhr(); + + // Open the socket + // Passing null username, generates a login popup on Opera (#2865) + if ( s.username ) { + xhr.open( s.type, s.url, s.async, s.username, s.password ); + } else { + xhr.open( s.type, s.url, s.async ); + } + + // Apply custom fields if provided + if ( s.xhrFields ) { + for ( i in s.xhrFields ) { + xhr[ i ] = s.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( s.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( s.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !s.crossDomain && !headers["X-Requested-With"] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Need an extra try/catch for cross domain requests in Firefox 3 + try { + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + } catch( _ ) {} + + // Do send the request + // This may raise an exception which is actually + // handled in jQuery.ajax (so no try/catch here) + xhr.send( ( s.hasContent && s.data ) || null ); + + // Listener + callback = function( _, isAbort ) { + + var status, + statusText, + responseHeaders, + responses, + xml; + + // Firefox throws exceptions when accessing properties + // of an xhr when a network error occurred + // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) + try { + + // Was never called and is aborted or complete + if ( callback && ( isAbort || xhr.readyState === 4 ) ) { + + // Only called once + callback = undefined; + + // Do not keep as active anymore + if ( handle ) { + xhr.onreadystatechange = jQuery.noop; + if ( xhrOnUnloadAbort ) { + delete xhrCallbacks[ handle ]; + } + } + + // If it's an abort + if ( isAbort ) { + // Abort it manually if needed + if ( xhr.readyState !== 4 ) { + xhr.abort(); + } + } else { + status = xhr.status; + responseHeaders = xhr.getAllResponseHeaders(); + responses = {}; + xml = xhr.responseXML; + + // Construct response list + if ( xml && xml.documentElement /* #4958 */ ) { + responses.xml = xml; + } + + // When requesting binary data, IE6-9 will throw an exception + // on any attempt to access responseText (#11426) + try { + responses.text = xhr.responseText; + } catch( e ) { + } + + // Firefox throws an exception when accessing + // statusText for faulty cross-domain requests + try { + statusText = xhr.statusText; + } catch( e ) { + // We normalize with Webkit giving an empty statusText + statusText = ""; + } + + // Filter status for non standard behaviors + + // If the request is local and we have data: assume a success + // (success with no data won't get notified, that's the best we + // can do given current implementations) + if ( !status && s.isLocal && !s.crossDomain ) { + status = responses.text ? 200 : 404; + // IE - #1450: sometimes returns 1223 when it should be 204 + } else if ( status === 1223 ) { + status = 204; + } + } + } + } catch( firefoxAccessException ) { + if ( !isAbort ) { + complete( -1, firefoxAccessException ); + } + } + + // Call complete if needed + if ( responses ) { + complete( status, statusText, responses, responseHeaders ); + } + }; + + if ( !s.async ) { + // if we're in sync mode we fire the callback + callback(); + } else if ( xhr.readyState === 4 ) { + // (IE6 & IE7) if it's in cache and has been + // retrieved directly we need to fire the callback + setTimeout( callback, 0 ); + } else { + handle = ++xhrId; + if ( xhrOnUnloadAbort ) { + // Create the active xhrs callbacks list if needed + // and attach the unload handler + if ( !xhrCallbacks ) { + xhrCallbacks = {}; + jQuery( window ).unload( xhrOnUnloadAbort ); + } + // Add to list of active xhrs callbacks + xhrCallbacks[ handle ] = callback; + } + xhr.onreadystatechange = callback; + } + }, + + abort: function() { + if ( callback ) { + callback(0,1); + } + } + }; + } + }); +} +var fxNow, timerId, + rfxtypes = /^(?:toggle|show|hide)$/, + rfxnum = new RegExp( "^(?:([-+])=|)(" + core_pnum + ")([a-z%]*)$", "i" ), + rrun = /queueHooks$/, + animationPrefilters = [ defaultPrefilter ], + tweeners = { + "*": [function( prop, value ) { + var end, unit, + tween = this.createTween( prop, value ), + parts = rfxnum.exec( value ), + target = tween.cur(), + start = +target || 0, + scale = 1, + maxIterations = 20; + + if ( parts ) { + end = +parts[2]; + unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + + // We need to compute starting value + if ( unit !== "px" && start ) { + // Iteratively approximate from a nonzero starting point + // Prefer the current property, because this process will be trivial if it uses the same units + // Fallback to end or a simple constant + start = jQuery.css( tween.elem, prop, true ) || end || 1; + + do { + // If previous iteration zeroed out, double until we get *something* + // Use a string for doubling factor so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + start = start / scale; + jQuery.style( tween.elem, prop, start + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // And breaking the loop if scale is unchanged or perfect, or if we've just had enough + } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); + } + + tween.unit = unit; + tween.start = start; + // If a +=/-= token was provided, we're doing a relative animation + tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end; + } + return tween; + }] + }; + +// Animations created synchronously will run synchronously +function createFxNow() { + setTimeout(function() { + fxNow = undefined; + }, 0 ); + return ( fxNow = jQuery.now() ); +} + +function createTweens( animation, props ) { + jQuery.each( props, function( prop, value ) { + var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( collection[ index ].call( animation, prop, value ) ) { + + // we're done with this property + return; + } + } + }); +} + +function Animation( elem, properties, options ) { + var result, + index = 0, + tweenerIndex = 0, + length = animationPrefilters.length, + deferred = jQuery.Deferred().always( function() { + // don't match elem in the :animated selector + delete tick.elem; + }), + tick = function() { + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ]); + + if ( percent < 1 && length ) { + return remaining; + } else { + deferred.resolveWith( elem, [ animation ] ); + return false; + } + }, + animation = deferred.promise({ + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { specialEasing: {} }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end, easing ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + // if we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // resolve when we played the last frame + // otherwise, reject + if ( gotoEnd ) { + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + }), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length ; index++ ) { + result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + return result; + } + } + + createTweens( animation, props ); + + if ( jQuery.isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + jQuery.fx.timer( + jQuery.extend( tick, { + anim: animation, + queue: animation.opts.queue, + elem: elem + }) + ); + + // attach callbacks from options + return animation.progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = jQuery.camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( jQuery.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // not quite $.extend, this wont overwrite keys already present. + // also - reusing 'index' from above because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweener: function( props, callback ) { + if ( jQuery.isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.split(" "); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length ; index++ ) { + prop = props[ index ]; + tweeners[ prop ] = tweeners[ prop ] || []; + tweeners[ prop ].unshift( callback ); + } + }, + + prefilter: function( callback, prepend ) { + if ( prepend ) { + animationPrefilters.unshift( callback ); + } else { + animationPrefilters.push( callback ); + } + } +}); + +function defaultPrefilter( elem, props, opts ) { + var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire, + anim = this, + style = elem.style, + orig = {}, + handled = [], + hidden = elem.nodeType && isHidden( elem ); + + // handle queue: false promises + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always(function() { + // doing this makes sure that the complete handler will be called + // before this completes + anim.always(function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + }); + }); + } + + // height/width overflow pass + if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { + // Make sure that nothing sneaks out + // Record all 3 overflow attributes because IE does not + // change the overflow attribute when overflowX and + // overflowY are set to the same value + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Set display property to inline-block for height/width + // animations on inline elements that are having width/height animated + if ( jQuery.css( elem, "display" ) === "inline" && + jQuery.css( elem, "float" ) === "none" ) { + + // inline-level elements accept inline-block; + // block-level elements need to be inline with layout + if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) { + style.display = "inline-block"; + + } else { + style.zoom = 1; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + if ( !jQuery.support.shrinkWrapBlocks ) { + anim.done(function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + }); + } + } + + + // show/hide pass + for ( index in props ) { + value = props[ index ]; + if ( rfxtypes.exec( value ) ) { + delete props[ index ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + continue; + } + handled.push( index ); + } + } + + length = handled.length; + if ( length ) { + dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} ); + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + + // store state if its toggle - enables .stop().toggle() to "reverse" + if ( toggle ) { + dataShow.hidden = !hidden; + } + if ( hidden ) { + jQuery( elem ).show(); + } else { + anim.done(function() { + jQuery( elem ).hide(); + }); + } + anim.done(function() { + var prop; + jQuery.removeData( elem, "fxshow", true ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + }); + for ( index = 0 ; index < length ; index++ ) { + prop = handled[ index ]; + tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 ); + orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop ); + + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = tween.start; + if ( hidden ) { + tween.end = tween.start; + tween.start = prop === "width" || prop === "height" ? 1 : 0; + } + } + } + } +} + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || "swing"; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + if ( tween.elem[ tween.prop ] != null && + (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { + return tween.elem[ tween.prop ]; + } + + // passing any value as a 4th parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails + // so, simple values such as "10px" are parsed to Float. + // complex values such as "rotate(1rad)" are returned as is. + result = jQuery.css( tween.elem, tween.prop, false, "" ); + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + // use step hook for back compat - use cssHook if its there - use .style if its + // available and use plain properties where available + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Remove in 2.0 - this supports IE8's panic based approach +// to setting things on disconnected nodes + +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" || + // special check for .toggle( handler, handler, ... ) + ( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +}); + +jQuery.fn.extend({ + fadeTo: function( speed, to, easing, callback ) { + + // show any hidden elements after setting opacity to 0 + return this.filter( isHidden ).css( "opacity", 0 ).show() + + // animate to the value specified + .end().animate({ opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations resolve immediately + if ( empty ) { + anim.stop( true ); + } + }; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each(function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = jQuery._data( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // start the next in the queue if the last step wasn't forced + // timers currently will call their complete callbacks, which will dequeue + // but only if they were gotoEnd + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + }); + } +}); + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + attrs = { height: type }, + i = 0; + + // if we include width, step value is 1 to do all cssExpand values, + // if we don't include width, step value is 2 to skip over Left and Right + includeWidth = includeWidth? 1 : 0; + for( ; i < 4 ; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +// Generate shortcuts for custom animations +jQuery.each({ + slideDown: genFx("show"), + slideUp: genFx("hide"), + slideToggle: genFx("toggle"), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +}); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + jQuery.isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing + }; + + opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : + opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; + + // normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( jQuery.isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p*Math.PI ) / 2; + } +}; + +jQuery.timers = []; +jQuery.fx = Tween.prototype.init; +jQuery.fx.tick = function() { + var timer, + timers = jQuery.timers, + i = 0; + + fxNow = jQuery.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + // Checks the timer has not already been removed + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + if ( timer() && jQuery.timers.push( timer ) && !timerId ) { + timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); + } +}; + +jQuery.fx.interval = 13; + +jQuery.fx.stop = function() { + clearInterval( timerId ); + timerId = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + // Default speed + _default: 400 +}; + +// Back Compat <1.8 extension point +jQuery.fx.step = {}; + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.animated = function( elem ) { + return jQuery.grep(jQuery.timers, function( fn ) { + return elem === fn.elem; + }).length; + }; +} +var rroot = /^(?:body|html)$/i; + +jQuery.fn.offset = function( options ) { + if ( arguments.length ) { + return options === undefined ? + this : + this.each(function( i ) { + jQuery.offset.setOffset( this, options, i ); + }); + } + + var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft, + box = { top: 0, left: 0 }, + elem = this[ 0 ], + doc = elem && elem.ownerDocument; + + if ( !doc ) { + return; + } + + if ( (body = doc.body) === elem ) { + return jQuery.offset.bodyOffset( elem ); + } + + docElem = doc.documentElement; + + // Make sure it's not a disconnected DOM node + if ( !jQuery.contains( docElem, elem ) ) { + return box; + } + + // If we don't have gBCR, just use 0,0 rather than error + // BlackBerry 5, iOS 3 (original iPhone) + if ( typeof elem.getBoundingClientRect !== "undefined" ) { + box = elem.getBoundingClientRect(); + } + win = getWindow( doc ); + clientTop = docElem.clientTop || body.clientTop || 0; + clientLeft = docElem.clientLeft || body.clientLeft || 0; + scrollTop = win.pageYOffset || docElem.scrollTop; + scrollLeft = win.pageXOffset || docElem.scrollLeft; + return { + top: box.top + scrollTop - clientTop, + left: box.left + scrollLeft - clientLeft + }; +}; + +jQuery.offset = { + + bodyOffset: function( body ) { + var top = body.offsetTop, + left = body.offsetLeft; + + if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) { + top += parseFloat( jQuery.css(body, "marginTop") ) || 0; + left += parseFloat( jQuery.css(body, "marginLeft") ) || 0; + } + + return { top: top, left: left }; + }, + + setOffset: function( elem, options, i ) { + var position = jQuery.css( elem, "position" ); + + // set position first, in-case top/left are set even on static elem + if ( position === "static" ) { + elem.style.position = "relative"; + } + + var curElem = jQuery( elem ), + curOffset = curElem.offset(), + curCSSTop = jQuery.css( elem, "top" ), + curCSSLeft = jQuery.css( elem, "left" ), + calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1, + props = {}, curPosition = {}, curTop, curLeft; + + // need to be able to calculate position if either top or left is auto and position is either absolute or fixed + if ( calculatePosition ) { + curPosition = curElem.position(); + curTop = curPosition.top; + curLeft = curPosition.left; + } else { + curTop = parseFloat( curCSSTop ) || 0; + curLeft = parseFloat( curCSSLeft ) || 0; + } + + if ( jQuery.isFunction( options ) ) { + options = options.call( elem, i, curOffset ); + } + + if ( options.top != null ) { + props.top = ( options.top - curOffset.top ) + curTop; + } + if ( options.left != null ) { + props.left = ( options.left - curOffset.left ) + curLeft; + } + + if ( "using" in options ) { + options.using.call( elem, props ); + } else { + curElem.css( props ); + } + } +}; + + +jQuery.fn.extend({ + + position: function() { + if ( !this[0] ) { + return; + } + + var elem = this[0], + + // Get *real* offsetParent + offsetParent = this.offsetParent(), + + // Get correct offsets + offset = this.offset(), + parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); + + // Subtract element margins + // note: when an element has margin: auto the offsetLeft and marginLeft + // are the same in Safari causing offset.left to incorrectly be 0 + offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0; + offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0; + + // Add offsetParent borders + parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0; + parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0; + + // Subtract the two offsets + return { + top: offset.top - parentOffset.top, + left: offset.left - parentOffset.left + }; + }, + + offsetParent: function() { + return this.map(function() { + var offsetParent = this.offsetParent || document.body; + while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { + offsetParent = offsetParent.offsetParent; + } + return offsetParent || document.body; + }); + } +}); + + +// Create scrollLeft and scrollTop methods +jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) { + var top = /Y/.test( prop ); + + jQuery.fn[ method ] = function( val ) { + return jQuery.access( this, function( elem, method, val ) { + var win = getWindow( elem ); + + if ( val === undefined ) { + return win ? (prop in win) ? win[ prop ] : + win.document.documentElement[ method ] : + elem[ method ]; + } + + if ( win ) { + win.scrollTo( + !top ? val : jQuery( win ).scrollLeft(), + top ? val : jQuery( win ).scrollTop() + ); + + } else { + elem[ method ] = val; + } + }, method, val, arguments.length, null ); + }; +}); + +function getWindow( elem ) { + return jQuery.isWindow( elem ) ? + elem : + elem.nodeType === 9 ? + elem.defaultView || elem.parentWindow : + false; +} +// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { + jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { + // margin is only for outerHeight, outerWidth + jQuery.fn[ funcName ] = function( margin, value ) { + var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), + extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); + + return jQuery.access( this, function( elem, type, value ) { + var doc; + + if ( jQuery.isWindow( elem ) ) { + // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there + // isn't a whole lot we can do. See pull request at this URL for discussion: + // https://github.com/jquery/jquery/pull/764 + return elem.document.documentElement[ "client" + name ]; + } + + // Get document width or height + if ( elem.nodeType === 9 ) { + doc = elem.documentElement; + + // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest + // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it. + return Math.max( + elem.body[ "scroll" + name ], doc[ "scroll" + name ], + elem.body[ "offset" + name ], doc[ "offset" + name ], + doc[ "client" + name ] + ); + } + + return value === undefined ? + // Get width or height on the element, requesting but not forcing parseFloat + jQuery.css( elem, type, value, extra ) : + + // Set width or height on the element + jQuery.style( elem, type, value, extra ); + }, type, chainable ? margin : undefined, chainable, null ); + }; + }); +}); +// Expose jQuery to the global object +window.jQuery = window.$ = jQuery; + +// Expose jQuery as an AMD module, but only for AMD loaders that +// understand the issues with loading multiple versions of jQuery +// in a page that all might call define(). The loader will indicate +// they have special allowances for multiple jQuery versions by +// specifying define.amd.jQuery = true. Register as a named module, +// since jQuery can be concatenated with other files that may use define, +// but not use a proper concatenation script that understands anonymous +// AMD modules. A named AMD is safest and most robust way to register. +// Lowercase jquery is used because AMD module names are derived from +// file names, and jQuery is normally delivered in a lowercase file name. +// Do this after creating the global so that if an AMD module wants to call +// noConflict to hide this version of jQuery, it will work. +if ( typeof define === "function" && define.amd && define.amd.jQuery ) { + define( "jquery", [], function () { return jQuery; } ); +} + +})( window ); diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/main.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/main.js new file mode 100644 index 00000000..153a6c8e --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/main.js @@ -0,0 +1,568 @@ +var datasource, type, columns, filter, maxUpdateValue, paramsToFilterBy; + +var REFRESH_INTERVAL = 5000; + +//this needs to be loaded from an autogenerated +datasource = gadgetConfig.datasource; +filter = gadgetConfig.filter; +type = gadgetConfig.type; +maxUpdateValue = gadgetConfig.maxUpdateValue; +columns = gadgetConfig.columns; +paramsToFilterBy = gadgetConfig.params; + +var counter = 0; +var TYPE_GET_BY_RANGE = 8; +var TYPE_SEARCH = 13; +var TYPE_SEARCH_COUNT = 14; + +var TIME_FROM_STRING = "timeFrom"; +var TIME_TO_STRING = "timeTo"; +var UNIX_TIME_MAX_VALUE = "9007199254740992"; +var UNIX_TIME_MIN_VALUE = "-9007199254740992"; +var META_TAG = "meta_"; +var initialConfig, urlQueryParams, queryParamValPair, queryString; +var dataTable, chart; + +executeDataFetchForGadget(); + +/** + * The main execution logic of the gadget is implemented in this function. + */ +function executeDataFetchForGadget() { + var urlQueryString; + + // fetch all queryParams from the URL. + urlQueryParams = getAllQueryParamsFromURL(); + + // check if params config exists in the gadgetConf. + if (typeof paramsToFilterBy != "undefined" && paramsToFilterBy.length != 0) { + + if (urlQueryParams != null) { + // get the values corresponding to the query "params" given in the gadgetConf + queryParamValPair = getValuesOfQueryFilter(); + + // if at-least one of the given params in the conf are missing from the URL params then returns null. + if (queryParamValPair == null) { + console.log("Incomplete set of Query Params were found in the URL."); + return; + } + + // construct the Lucene query string based on the params given in the gadget-conf + // and the values parsed from the URL Query String. + queryString = constructQueryString(); + + switch (type) { + case "realtime": + urlQueryString = decodeURIComponent(window.top.location.search.substring(1)); + //subscribe to websocket + subscribe( + datasource.split(":")[0], datasource.split(":")[1], '10', gadgetConfig.domain, + onRealTimeEventSuccessRecieval, onRealTimeEventErrorRecieval, + location.hostname, location.port, 'WEBSOCKET', "SECURED", urlQueryString); + break; + + case "batch": + //load data immediately + fetchDataOnQuery(fetchDataWithCount); + // then start periodic polling + setInterval(function () { + fetchDataOnQuery(fetchDataWithCount); + }, REFRESH_INTERVAL); + break; + } + + } else { + // if there are NO queryParams in the URL then exit. + console.log("No Query Params were found in the URL to match the given filter-parameters."); + } + } else { + // if no params to filter by are given in the gadget-conf, then fetch all info available + // based on date range(if given). + switch (type) { + case "realtime": + urlQueryString = decodeURIComponent(window.top.location.search.substring(1)); + //subscribe to websocket + subscribe(datasource.split(":")[0], datasource.split(":")[1], '10', gadgetConfig.domain, + onRealTimeEventSuccessRecieval, onRealTimeEventErrorRecieval, location.hostname, location.port, + 'WEBSOCKET', "SECURED", urlQueryString); + break; + + case "batch": + //load data immediately + fetchDataWithoutQuery(drawBatchChart); + + // then start periodic polling + setInterval(function () { + fetchDataWithoutQuery(drawBatchChart); + }, REFRESH_INTERVAL); + break; + } + } +} + +/** + * Reads the page's URL Query-Params and returns them as an associative array. + * @returns {*} an associative array containing the URL QueryParams and corresponding values. + * If no such Query-Params exists then returns null. + */ +function getAllQueryParamsFromURL() { + var queryParamList = [], qParam; + var urlQueryString = decodeURIComponent(window.top.location.search.substring(1)); + if (urlQueryString) { + var queryStringPairs = urlQueryString.split('&'); + for (var i = 0; i < queryStringPairs.length; i++) { + qParam = queryStringPairs[i].split('='); + queryParamList[qParam[0]] = qParam[1]; + } + return queryParamList; + } else { + return null; + } +} + +/** + * Retrieves the values from the URL-QueryString corresponding to the given QueryParams in the gadget-conf file. + * The parameters "timeTo" & "timeFrom" (if found in the query string) are added to the returned object regardless + * of whether they are listed in the gadget-conf. + * @returns {*} an associative array of the given params in the conf and corresponding value fetched from the + * URL string. + */ +function getValuesOfQueryFilter() { + var queryValues = []; + + if (TIME_FROM_STRING in urlQueryParams) { + queryValues[TIME_FROM_STRING] = urlQueryParams[TIME_FROM_STRING]; + } + + if (TIME_TO_STRING in urlQueryParams) { + queryValues[TIME_TO_STRING] = urlQueryParams[TIME_TO_STRING]; + } + + for (var i = 0; i < paramsToFilterBy.length; i++) { + var queryV = urlQueryParams[paramsToFilterBy[i]]; + + // if atleast one of the queryParams given in the gadgetConf is missing then return "null". + if (typeof queryV != "undefined" && queryV != null && queryV != "") { + queryValues[paramsToFilterBy[i]] = queryV; + } else { + return null; + } + } + return queryValues; +} + +/** + * Constructs the Lucene Query String to be sent to DAS API. + * @returns {string} a fully constructed query string from the params given in gadget-conf and + * the query string of the URL. + */ +function constructQueryString() { + var queryString = "'"; + for (var a = 0; a < paramsToFilterBy.length; a++) { + if (queryString.length == 1) { + queryString += META_TAG + paramsToFilterBy[a] + ":" + queryParamValPair[paramsToFilterBy[a]]; + } else { + queryString += " AND " + META_TAG + paramsToFilterBy[a] + ":" + queryParamValPair[paramsToFilterBy[a]]; + } + } + + if (TIME_FROM_STRING in queryParamValPair && TIME_TO_STRING in queryParamValPair) { + // both ends of the time-range (From What Date - To What Date) is given + queryString += " AND " + META_TAG + "time:" + + "[" + queryParamValPair[TIME_FROM_STRING] + " TO " + queryParamValPair[TIME_TO_STRING] + "]"; + + } else if (TIME_FROM_STRING in queryParamValPair && !(TIME_TO_STRING in queryParamValPair)) { + // Only the start of the time-range (From What Date) is given + queryString += " AND " + META_TAG + "time:" + + "[" + queryParamValPair[TIME_FROM_STRING] + " TO " + UNIX_TIME_MAX_VALUE + "]"; + + } else if (!(TIME_FROM_STRING in queryParamValPair) && TIME_TO_STRING in queryParamValPair) { + // Only the end of the time-range (To What Date) is given + queryString += " AND " + META_TAG + "time:" + + "[" + UNIX_TIME_MIN_VALUE + " TO " + queryParamValPair[TIME_TO_STRING] + "]"; + } + //queryString += " AND meta_time:[1456467843079 TO 1456468494817]'"; + queryString += "'"; + return queryString; +} + +/** + * Utility method to fetch columns of the datasource provided for a Batch-Type Gadget. + * @param table the name of the datasource table whose columns needs to be extracted. + */ +function getColumns(table) { + console.log("Fetching table schema for table: " + table); + var url = "/portal/apis/analytics?type=10&tableName=" + table; + $.getJSON(url, function (data) { + if (data) { + columns = parseColumns(JSON.parse(data.message)); + } + + }); +} + +/** Constructs an associative array containing the columns and the corresponding data-type ("String", "Long", etc) + * from the returned object as a result of the "getColumns" method above. + * @param data the response object returned from the "getColumns(table)" call to the DAS API. + * @returns {Array|*} an array containing the column names as keys and their type as values. + */ +function parseColumns(data) { + if (data.columns) { + var keys = Object.getOwnPropertyNames(data.columns); + columns = keys.map(function (key, i) { + return column = { + name: key, + type: data.columns[key].type + }; + }); + return columns; + } +} + +/** + * Makes the initial call to the DAS APIs to get the count of all matching indexes based on a given query. + * Upon receiving a response (count), a subsequent method is called to fetch the given "count" amount of data from + * DAS that matches the query. + * @param callback the subsequent method to be called using the "count" response value received from the API call. + */ +function fetchDataOnQuery(callback) { + var request = { + type: TYPE_SEARCH_COUNT, // DAS API type corresponding to fetching data-count for "query" + tableName: datasource, + query: queryString + }; + $.ajax({ + url: "/portal/apis/analytics", + method: "GET", + data: request, + contentType: "application/json", + success: function (data) { + if (callback != null) { + callback(drawBatchChart, data.message); + } + } + }); +} + +/** + * Makes an API call to the DAS to fetch the "count" number of data matching the queryString constructed from the + * query-string and the param-list provided in the gadget-conf. The fetched data are passed into the provided + * "callback" method which further processes and draws the chart against this data. + * @param callback the method to which the fetched data are to be passed in for further processing. + * @param totalCount the count of all matching data available against the queryString. + */ +function fetchDataWithCount(callback, totalCount) { + var timeFrom = "undefined"; + var timeTo = "undefined"; + var request = { + type: TYPE_SEARCH, // DAS API type corresponding to fetching data for "query" + tableName: datasource, + filter: filter, + query: queryString, + timeFrom: timeFrom, + timeTo: timeTo, + start: 0, + count: totalCount + }; + $.ajax({ + url: "/portal/apis/analytics", + method: "GET", + data: request, + contentType: "application/json", + success: function (data) { + if (callback != null) { + var sortedData = sortData(data.message); + callback(makeRows(sortedData)); + } + } + }); +} + +/** + * Retrieves all data available in a datasource irrespective of any query filters. However, the API call incorporates + * a data range to be submitted whilst fetching this info. If such date range related query strings + * ("timeFrom" or "timeTo") are found in the URL, then they are used. + * @param callback the method to which the fetched data are to be passed in for further processing. + */ +function fetchDataWithoutQuery(callback) { + var timeFrom = "undefined"; + var timeTo = "undefined"; + + if (urlQueryParams != null) { + if (TIME_FROM_STRING in urlQueryParams) { + timeFrom = urlQueryParams[TIME_FROM_STRING]; + } + + if (TIME_TO_STRING in urlQueryParams) { + timeTo = urlQueryParams[TIME_TO_STRING]; + } + } + + var request = { + type: TYPE_GET_BY_RANGE, // DAS API type corresponding to fetching data by date range. + tableName: datasource, + timeFrom: timeFrom, + timeTo: timeTo, + start: 0 + }; + $.ajax({ + url: "/portal/apis/analytics", + method: "GET", + data: request, + contentType: "application/json", + success: function (data) { + if (callback != null) { + callback(makeRows(JSON.parse(data.message))); + } + } + }); +} + +/** + * This is a utility method to convert Unix-Timestamp values to Epoch Time + * @param unix_timestamp the unix time to be converted + * @returns {string} the formatted epoch-time of the given unix-timestamp + */ +function convertToEpoch(unix_timestamp) { + // Create a new JavaScript Date object based on the timestamp + // multiplied by 1000 so that the argument is in milliseconds, not seconds. + var date = new Date(unix_timestamp * 1000); + // Hours part from the timestamp + var hours = date.getHours(); + // Minutes part from the timestamp + var minutes = "0" + date.getMinutes(); + // Seconds part from the timestamp + var seconds = "0" + date.getSeconds(); + + var thisDate = date.getDate(); + var thisMonth = date.getMonth(); + var thisYear = date.getUTCFullYear(); + + var formattedTime = hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2); + + // Will display time in 10:30:23 format + return (formattedTime); +} + +/** + * Sorts the given data array according to the values of its "timestamp" key. + * @param payload a JSON string with multiple data-arrays having a "timestamp" key-value pair. + * @returns {*} JSON Object with multiple sorted by "timestamp" + */ +function sortData(payload) { + var dataFromDAS = JSON.parse(payload); + sortedData = dataFromDAS.sort(function (a, b) { + return a.timestamp - b.timestamp; + }); + return sortedData; +} + +/** + * Fetches the values corresponding to the keys in the "columns" (either provided in the gadget-conf or fetched via the + * "getColumns(table)" method) array from the data object passed in. + * @param data a JSON Object containing multiple data values fetched from the datasource with column-name:value pairs. + * @returns {Array} an array with objects that contain the columns from the fetched "columns" and their corresponding + * values. + */ +function makeRows(data) { + var rows = []; + for (var i = 0; i < data.length; i++) { + var record = data[i]; + var keys = Object.getOwnPropertyNames(record.values); + keys.push(); + + var row = columns.map(function (column, i) { + var colName = column.name; + var recordVal = record.values[colName]; + + if (typeof recordVal == 'undefined') { + if (column.name.toUpperCase() === "TIMESTAMP" && (record.timestamp || record.TIMESTAMP)) { + recordVal = record.timestamp; + } else { + recordVal = record.values[META_TAG + colName]; + } + } + return recordVal; + }); + rows.push(row); + } + return rows; +} + +function makeDataTable(data) { + var dataTable = new igviz.DataTable(); + if (columns.length > 0) { + columns.forEach(function (column, i) { + var type = "N"; + if (column.type == "STRING" || column.type == "string") { + type = "C"; + } else if (column.type == "TIME" || column.type == "time") { + type = "T"; + } + dataTable.addColumn(column.name, type); + }); + } + data.forEach(function (row, index) { + for (var i = 0; i < row.length; i++) { + if (dataTable.metadata.types[i] == "N") { + data[index][i] = parseInt(data[index][i]); + } + } + }); + dataTable.addRows(data); + return dataTable; +} + +function drawChart(data) { + var dataTable = makeDataTable(data); + gadgetConfig.chartConfig.width = $("#placeholder").width(); + gadgetConfig.chartConfig.height = $("#placeholder").height() - 65; + var chartType = gadgetConfig.chartConfig.chartType; + var xAxis = gadgetConfig.chartConfig.xAxis; + jQuery("#noChart").html(""); + if (chartType === "bar" && dataTable.metadata.types[xAxis] === "N") { + dataTable.metadata.types[xAxis] = "C"; + } + + if (gadgetConfig.chartConfig.chartType === "table" || gadgetConfig.chartConfig.chartType === "singleNumber") { + gadgetConfig.chartConfig.height = $("#placeholder").height(); + chart = igviz.draw("#placeholder", gadgetConfig.chartConfig, dataTable); + chart.plot(dataTable.data); + + } else { + chart = igviz.setUp("#placeholder", gadgetConfig.chartConfig, dataTable); + chart.setXAxis({ + "labelAngle": -35, + "labelAlign": "right", + "labelDy": 0, + "labelDx": 0, + "titleDy": 25 + }) + .setYAxis({ + "titleDy": -30 + }); + chart.plot(dataTable.data); + } +} + + +//stuff required for realtime charting +function onRealTimeEventSuccessRecieval(streamId, data) { + drawRealtimeChart(data); +} + +function onRealTimeEventErrorRecieval(dataError) { + console.log("Error occurred " + dataError); +} + +/** + * Draws the real-time chart based on the values in the data object passed in. + * @param data an object containing all the column:value pair data + */ +function drawRealtimeChart(data) { + if (chart == null) { + jQuery("#noChart").html(""); + gadgetConfig.chartConfig.width = $("#placeholder").width() - 110; + gadgetConfig.chartConfig.height = $("#placeholder").height() - 40; + + if (gadgetConfig.chartConfig.charts[0].type == "map") { + var mapType = gadgetConfig.chartConfig.charts[0].mapType; + + if (mapType == "world") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/world/'; + } else if (mapType == "usa") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usaInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usa/'; + } else if (mapType == "europe") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/europe/'; + } + } + + chart = new vizg(createDataTable(convertData(data)), gadgetConfig.chartConfig); + chart.draw("#placeholder"); + } else { + chart.insert(convertData(data)); + } +} + +/** + * Draws the batch-chart based on the values in the data object passed in. + * @param data an object containing all the column:value pair data + */ +function drawBatchChart(data) { + if (chart == null) { + jQuery("#noChart").html(""); + gadgetConfig.chartConfig.width = $("#placeholder").width() - 110; + gadgetConfig.chartConfig.height = $("#placeholder").height() - 40; + + if (gadgetConfig.chartConfig.charts[0].type == "map") { + var mapType = gadgetConfig.chartConfig.charts[0].mapType; + + if (mapType == "world") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/world/'; + } else if (mapType == "usa") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usaInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usa/'; + } else if (mapType == "europe") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/europe/'; + } + } + + initialConfig = JSON.parse(JSON.stringify(gadgetConfig.chartConfig)); + + } else { + gadgetConfig.chartConfig = initialConfig; + initialConfig = JSON.parse(JSON.stringify(gadgetConfig.chartConfig)); + } + + chart = new vizg(createDataTable(convertData(data)), gadgetConfig.chartConfig); + chart.draw("#placeholder"); +} + + +function convertData(data) { + for (var i = 0; i < data.length; i++) { + for (var x = 0; x < data[i].length; x++) { + var type = gadgetConfig.columns[x]["type"].toUpperCase(); + if (type != "STRING" && type != "BOOLEAN") { + data[i][x] = parseFloat(data[i][x]); + } + } + } + return data; +} + +function createDataTable(data) { + var names = []; + var types = []; + + for (var i = 0; i < gadgetConfig.columns.length; i++) { + var name = gadgetConfig.columns[i]["name"]; + names.push(name); + var type = columns[i]["type"].toUpperCase(); + + if (type === "INT" || type === "INTEGER" || type === "FLOAT" || type === "DOUBLE") { + type = "linear"; + } else if (gadgetConfig.columns[i]["type"].toUpperCase() == "TIME" || name.toUpperCase() == "TIME") { + type = "time"; + } else { + type = "ordinal"; + } + types.push(type); + } + + datatable = [ + { + "metadata": { + "names": names, + "types": types + }, + "data": data + } + ]; + return datatable; +} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/moment.min.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/moment.min.js new file mode 100755 index 00000000..caaf8b3c --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/moment.min.js @@ -0,0 +1,7 @@ +//! moment.js +//! version : 2.11.2 +//! authors : Tim Wood, Iskren Chernev, Moment.js contributors +//! license : MIT +//! momentjs.com +!function(a,b){"object"==typeof exports&&"undefined"!=typeof module?module.exports=b():"function"==typeof define&&define.amd?define(b):a.moment=b()}(this,function(){"use strict";function a(){return Uc.apply(null,arguments)}function b(a){Uc=a}function c(a){return"[object Array]"===Object.prototype.toString.call(a)}function d(a){return a instanceof Date||"[object Date]"===Object.prototype.toString.call(a)}function e(a,b){var c,d=[];for(c=0;c0)for(c in Wc)d=Wc[c],e=b[d],m(e)||(a[d]=e);return a}function o(b){n(this,b),this._d=new Date(null!=b._d?b._d.getTime():NaN),Xc===!1&&(Xc=!0,a.updateOffset(this),Xc=!1)}function p(a){return a instanceof o||null!=a&&null!=a._isAMomentObject}function q(a){return 0>a?Math.ceil(a):Math.floor(a)}function r(a){var b=+a,c=0;return 0!==b&&isFinite(b)&&(c=q(b)),c}function s(a,b,c){var d,e=Math.min(a.length,b.length),f=Math.abs(a.length-b.length),g=0;for(d=0;e>d;d++)(c&&a[d]!==b[d]||!c&&r(a[d])!==r(b[d]))&&g++;return g+f}function t(){}function u(a){return a?a.toLowerCase().replace("_","-"):a}function v(a){for(var b,c,d,e,f=0;f0;){if(d=w(e.slice(0,b).join("-")))return d;if(c&&c.length>=b&&s(e,c,!0)>=b-1)break;b--}f++}return null}function w(a){var b=null;if(!Yc[a]&&"undefined"!=typeof module&&module&&module.exports)try{b=Vc._abbr,require("./locale/"+a),x(b)}catch(c){}return Yc[a]}function x(a,b){var c;return a&&(c=m(b)?z(a):y(a,b),c&&(Vc=c)),Vc._abbr}function y(a,b){return null!==b?(b.abbr=a,Yc[a]=Yc[a]||new t,Yc[a].set(b),x(a),Yc[a]):(delete Yc[a],null)}function z(a){var b;if(a&&a._locale&&a._locale._abbr&&(a=a._locale._abbr),!a)return Vc;if(!c(a)){if(b=w(a))return b;a=[a]}return v(a)}function A(a,b){var c=a.toLowerCase();Zc[c]=Zc[c+"s"]=Zc[b]=a}function B(a){return"string"==typeof a?Zc[a]||Zc[a.toLowerCase()]:void 0}function C(a){var b,c,d={};for(c in a)f(a,c)&&(b=B(c),b&&(d[b]=a[c]));return d}function D(a){return a instanceof Function||"[object Function]"===Object.prototype.toString.call(a)}function E(b,c){return function(d){return null!=d?(G(this,b,d),a.updateOffset(this,c),this):F(this,b)}}function F(a,b){return a.isValid()?a._d["get"+(a._isUTC?"UTC":"")+b]():NaN}function G(a,b,c){a.isValid()&&a._d["set"+(a._isUTC?"UTC":"")+b](c)}function H(a,b){var c;if("object"==typeof a)for(c in a)this.set(c,a[c]);else if(a=B(a),D(this[a]))return this[a](b);return this}function I(a,b,c){var d=""+Math.abs(a),e=b-d.length,f=a>=0;return(f?c?"+":"":"-")+Math.pow(10,Math.max(0,e)).toString().substr(1)+d}function J(a,b,c,d){var e=d;"string"==typeof d&&(e=function(){return this[d]()}),a&&(bd[a]=e),b&&(bd[b[0]]=function(){return I(e.apply(this,arguments),b[1],b[2])}),c&&(bd[c]=function(){return this.localeData().ordinal(e.apply(this,arguments),a)})}function K(a){return a.match(/\[[\s\S]/)?a.replace(/^\[|\]$/g,""):a.replace(/\\/g,"")}function L(a){var b,c,d=a.match($c);for(b=0,c=d.length;c>b;b++)bd[d[b]]?d[b]=bd[d[b]]:d[b]=K(d[b]);return function(e){var f="";for(b=0;c>b;b++)f+=d[b]instanceof Function?d[b].call(e,a):d[b];return f}}function M(a,b){return a.isValid()?(b=N(b,a.localeData()),ad[b]=ad[b]||L(b),ad[b](a)):a.localeData().invalidDate()}function N(a,b){function c(a){return b.longDateFormat(a)||a}var d=5;for(_c.lastIndex=0;d>=0&&_c.test(a);)a=a.replace(_c,c),_c.lastIndex=0,d-=1;return a}function O(a,b,c){td[a]=D(b)?b:function(a,d){return a&&c?c:b}}function P(a,b){return f(td,a)?td[a](b._strict,b._locale):new RegExp(Q(a))}function Q(a){return R(a.replace("\\","").replace(/\\(\[)|\\(\])|\[([^\]\[]*)\]|\\(.)/g,function(a,b,c,d,e){return b||c||d||e}))}function R(a){return a.replace(/[-\/\\^$*+?.()|[\]{}]/g,"\\$&")}function S(a,b){var c,d=b;for("string"==typeof a&&(a=[a]),"number"==typeof b&&(d=function(a,c){c[b]=r(a)}),c=0;cd;d++){if(e=h([2e3,d]),c&&!this._longMonthsParse[d]&&(this._longMonthsParse[d]=new RegExp("^"+this.months(e,"").replace(".","")+"$","i"),this._shortMonthsParse[d]=new RegExp("^"+this.monthsShort(e,"").replace(".","")+"$","i")),c||this._monthsParse[d]||(f="^"+this.months(e,"")+"|^"+this.monthsShort(e,""),this._monthsParse[d]=new RegExp(f.replace(".",""),"i")),c&&"MMMM"===b&&this._longMonthsParse[d].test(a))return d;if(c&&"MMM"===b&&this._shortMonthsParse[d].test(a))return d;if(!c&&this._monthsParse[d].test(a))return d}}function Z(a,b){var c;return a.isValid()?"string"==typeof b&&(b=a.localeData().monthsParse(b),"number"!=typeof b)?a:(c=Math.min(a.date(),V(a.year(),b)),a._d["set"+(a._isUTC?"UTC":"")+"Month"](b,c),a):a}function $(b){return null!=b?(Z(this,b),a.updateOffset(this,!0),this):F(this,"Month")}function _(){return V(this.year(),this.month())}function aa(a){return this._monthsParseExact?(f(this,"_monthsRegex")||ca.call(this),a?this._monthsShortStrictRegex:this._monthsShortRegex):this._monthsShortStrictRegex&&a?this._monthsShortStrictRegex:this._monthsShortRegex}function ba(a){return this._monthsParseExact?(f(this,"_monthsRegex")||ca.call(this),a?this._monthsStrictRegex:this._monthsRegex):this._monthsStrictRegex&&a?this._monthsStrictRegex:this._monthsRegex}function ca(){function a(a,b){return b.length-a.length}var b,c,d=[],e=[],f=[];for(b=0;12>b;b++)c=h([2e3,b]),d.push(this.monthsShort(c,"")),e.push(this.months(c,"")),f.push(this.months(c,"")),f.push(this.monthsShort(c,""));for(d.sort(a),e.sort(a),f.sort(a),b=0;12>b;b++)d[b]=R(d[b]),e[b]=R(e[b]),f[b]=R(f[b]);this._monthsRegex=new RegExp("^("+f.join("|")+")","i"),this._monthsShortRegex=this._monthsRegex,this._monthsStrictRegex=new RegExp("^("+e.join("|")+")$","i"),this._monthsShortStrictRegex=new RegExp("^("+d.join("|")+")$","i")}function da(a){var b,c=a._a;return c&&-2===j(a).overflow&&(b=c[wd]<0||c[wd]>11?wd:c[xd]<1||c[xd]>V(c[vd],c[wd])?xd:c[yd]<0||c[yd]>24||24===c[yd]&&(0!==c[zd]||0!==c[Ad]||0!==c[Bd])?yd:c[zd]<0||c[zd]>59?zd:c[Ad]<0||c[Ad]>59?Ad:c[Bd]<0||c[Bd]>999?Bd:-1,j(a)._overflowDayOfYear&&(vd>b||b>xd)&&(b=xd),j(a)._overflowWeeks&&-1===b&&(b=Cd),j(a)._overflowWeekday&&-1===b&&(b=Dd),j(a).overflow=b),a}function ea(b){a.suppressDeprecationWarnings===!1&&"undefined"!=typeof console&&console.warn&&console.warn("Deprecation warning: "+b)}function fa(a,b){var c=!0;return g(function(){return c&&(ea(a+"\nArguments: "+Array.prototype.slice.call(arguments).join(", ")+"\n"+(new Error).stack),c=!1),b.apply(this,arguments)},b)}function ga(a,b){Jd[a]||(ea(b),Jd[a]=!0)}function ha(a){var b,c,d,e,f,g,h=a._i,i=Kd.exec(h)||Ld.exec(h);if(i){for(j(a).iso=!0,b=0,c=Nd.length;c>b;b++)if(Nd[b][1].exec(i[1])){e=Nd[b][0],d=Nd[b][2]!==!1;break}if(null==e)return void(a._isValid=!1);if(i[3]){for(b=0,c=Od.length;c>b;b++)if(Od[b][1].exec(i[3])){f=(i[2]||" ")+Od[b][0];break}if(null==f)return void(a._isValid=!1)}if(!d&&null!=f)return void(a._isValid=!1);if(i[4]){if(!Md.exec(i[4]))return void(a._isValid=!1);g="Z"}a._f=e+(f||"")+(g||""),wa(a)}else a._isValid=!1}function ia(b){var c=Pd.exec(b._i);return null!==c?void(b._d=new Date(+c[1])):(ha(b),void(b._isValid===!1&&(delete b._isValid,a.createFromInputFallback(b))))}function ja(a,b,c,d,e,f,g){var h=new Date(a,b,c,d,e,f,g);return 100>a&&a>=0&&isFinite(h.getFullYear())&&h.setFullYear(a),h}function ka(a){var b=new Date(Date.UTC.apply(null,arguments));return 100>a&&a>=0&&isFinite(b.getUTCFullYear())&&b.setUTCFullYear(a),b}function la(a){return ma(a)?366:365}function ma(a){return a%4===0&&a%100!==0||a%400===0}function na(){return ma(this.year())}function oa(a,b,c){var d=7+b-c,e=(7+ka(a,0,d).getUTCDay()-b)%7;return-e+d-1}function pa(a,b,c,d,e){var f,g,h=(7+c-d)%7,i=oa(a,d,e),j=1+7*(b-1)+h+i;return 0>=j?(f=a-1,g=la(f)+j):j>la(a)?(f=a+1,g=j-la(a)):(f=a,g=j),{year:f,dayOfYear:g}}function qa(a,b,c){var d,e,f=oa(a.year(),b,c),g=Math.floor((a.dayOfYear()-f-1)/7)+1;return 1>g?(e=a.year()-1,d=g+ra(e,b,c)):g>ra(a.year(),b,c)?(d=g-ra(a.year(),b,c),e=a.year()+1):(e=a.year(),d=g),{week:d,year:e}}function ra(a,b,c){var d=oa(a,b,c),e=oa(a+1,b,c);return(la(a)-d+e)/7}function sa(a,b,c){return null!=a?a:null!=b?b:c}function ta(b){var c=new Date(a.now());return b._useUTC?[c.getUTCFullYear(),c.getUTCMonth(),c.getUTCDate()]:[c.getFullYear(),c.getMonth(),c.getDate()]}function ua(a){var b,c,d,e,f=[];if(!a._d){for(d=ta(a),a._w&&null==a._a[xd]&&null==a._a[wd]&&va(a),a._dayOfYear&&(e=sa(a._a[vd],d[vd]),a._dayOfYear>la(e)&&(j(a)._overflowDayOfYear=!0),c=ka(e,0,a._dayOfYear),a._a[wd]=c.getUTCMonth(),a._a[xd]=c.getUTCDate()),b=0;3>b&&null==a._a[b];++b)a._a[b]=f[b]=d[b];for(;7>b;b++)a._a[b]=f[b]=null==a._a[b]?2===b?1:0:a._a[b];24===a._a[yd]&&0===a._a[zd]&&0===a._a[Ad]&&0===a._a[Bd]&&(a._nextDay=!0,a._a[yd]=0),a._d=(a._useUTC?ka:ja).apply(null,f),null!=a._tzm&&a._d.setUTCMinutes(a._d.getUTCMinutes()-a._tzm),a._nextDay&&(a._a[yd]=24)}}function va(a){var b,c,d,e,f,g,h,i;b=a._w,null!=b.GG||null!=b.W||null!=b.E?(f=1,g=4,c=sa(b.GG,a._a[vd],qa(Ea(),1,4).year),d=sa(b.W,1),e=sa(b.E,1),(1>e||e>7)&&(i=!0)):(f=a._locale._week.dow,g=a._locale._week.doy,c=sa(b.gg,a._a[vd],qa(Ea(),f,g).year),d=sa(b.w,1),null!=b.d?(e=b.d,(0>e||e>6)&&(i=!0)):null!=b.e?(e=b.e+f,(b.e<0||b.e>6)&&(i=!0)):e=f),1>d||d>ra(c,f,g)?j(a)._overflowWeeks=!0:null!=i?j(a)._overflowWeekday=!0:(h=pa(c,d,e,f,g),a._a[vd]=h.year,a._dayOfYear=h.dayOfYear)}function wa(b){if(b._f===a.ISO_8601)return void ha(b);b._a=[],j(b).empty=!0;var c,d,e,f,g,h=""+b._i,i=h.length,k=0;for(e=N(b._f,b._locale).match($c)||[],c=0;c0&&j(b).unusedInput.push(g),h=h.slice(h.indexOf(d)+d.length),k+=d.length),bd[f]?(d?j(b).empty=!1:j(b).unusedTokens.push(f),U(f,d,b)):b._strict&&!d&&j(b).unusedTokens.push(f);j(b).charsLeftOver=i-k,h.length>0&&j(b).unusedInput.push(h),j(b).bigHour===!0&&b._a[yd]<=12&&b._a[yd]>0&&(j(b).bigHour=void 0),b._a[yd]=xa(b._locale,b._a[yd],b._meridiem),ua(b),da(b)}function xa(a,b,c){var d;return null==c?b:null!=a.meridiemHour?a.meridiemHour(b,c):null!=a.isPM?(d=a.isPM(c),d&&12>b&&(b+=12),d||12!==b||(b=0),b):b}function ya(a){var b,c,d,e,f;if(0===a._f.length)return j(a).invalidFormat=!0,void(a._d=new Date(NaN));for(e=0;ef)&&(d=f,c=b));g(a,c||b)}function za(a){if(!a._d){var b=C(a._i);a._a=e([b.year,b.month,b.day||b.date,b.hour,b.minute,b.second,b.millisecond],function(a){return a&&parseInt(a,10)}),ua(a)}}function Aa(a){var b=new o(da(Ba(a)));return b._nextDay&&(b.add(1,"d"),b._nextDay=void 0),b}function Ba(a){var b=a._i,e=a._f;return a._locale=a._locale||z(a._l),null===b||void 0===e&&""===b?l({nullInput:!0}):("string"==typeof b&&(a._i=b=a._locale.preparse(b)),p(b)?new o(da(b)):(c(e)?ya(a):e?wa(a):d(b)?a._d=b:Ca(a),k(a)||(a._d=null),a))}function Ca(b){var f=b._i;void 0===f?b._d=new Date(a.now()):d(f)?b._d=new Date(+f):"string"==typeof f?ia(b):c(f)?(b._a=e(f.slice(0),function(a){return parseInt(a,10)}),ua(b)):"object"==typeof f?za(b):"number"==typeof f?b._d=new Date(f):a.createFromInputFallback(b)}function Da(a,b,c,d,e){var f={};return"boolean"==typeof c&&(d=c,c=void 0),f._isAMomentObject=!0,f._useUTC=f._isUTC=e,f._l=c,f._i=a,f._f=b,f._strict=d,Aa(f)}function Ea(a,b,c,d){return Da(a,b,c,d,!1)}function Fa(a,b){var d,e;if(1===b.length&&c(b[0])&&(b=b[0]),!b.length)return Ea();for(d=b[0],e=1;ea&&(a=-a,c="-"),c+I(~~(a/60),2)+b+I(~~a%60,2)})}function La(a,b){var c=(b||"").match(a)||[],d=c[c.length-1]||[],e=(d+"").match(Ud)||["-",0,0],f=+(60*e[1])+r(e[2]);return"+"===e[0]?f:-f}function Ma(b,c){var e,f;return c._isUTC?(e=c.clone(),f=(p(b)||d(b)?+b:+Ea(b))-+e,e._d.setTime(+e._d+f),a.updateOffset(e,!1),e):Ea(b).local()}function Na(a){return 15*-Math.round(a._d.getTimezoneOffset()/15)}function Oa(b,c){var d,e=this._offset||0;return this.isValid()?null!=b?("string"==typeof b?b=La(qd,b):Math.abs(b)<16&&(b=60*b),!this._isUTC&&c&&(d=Na(this)),this._offset=b,this._isUTC=!0,null!=d&&this.add(d,"m"),e!==b&&(!c||this._changeInProgress?cb(this,Za(b-e,"m"),1,!1):this._changeInProgress||(this._changeInProgress=!0,a.updateOffset(this,!0),this._changeInProgress=null)),this):this._isUTC?e:Na(this):null!=b?this:NaN}function Pa(a,b){return null!=a?("string"!=typeof a&&(a=-a),this.utcOffset(a,b),this):-this.utcOffset()}function Qa(a){return this.utcOffset(0,a)}function Ra(a){return this._isUTC&&(this.utcOffset(0,a),this._isUTC=!1,a&&this.subtract(Na(this),"m")),this}function Sa(){return this._tzm?this.utcOffset(this._tzm):"string"==typeof this._i&&this.utcOffset(La(pd,this._i)),this}function Ta(a){return this.isValid()?(a=a?Ea(a).utcOffset():0,(this.utcOffset()-a)%60===0):!1}function Ua(){return this.utcOffset()>this.clone().month(0).utcOffset()||this.utcOffset()>this.clone().month(5).utcOffset()}function Va(){if(!m(this._isDSTShifted))return this._isDSTShifted;var a={};if(n(a,this),a=Ba(a),a._a){var b=a._isUTC?h(a._a):Ea(a._a);this._isDSTShifted=this.isValid()&&s(a._a,b.toArray())>0}else this._isDSTShifted=!1;return this._isDSTShifted}function Wa(){return this.isValid()?!this._isUTC:!1}function Xa(){return this.isValid()?this._isUTC:!1}function Ya(){return this.isValid()?this._isUTC&&0===this._offset:!1}function Za(a,b){var c,d,e,g=a,h=null;return Ja(a)?g={ms:a._milliseconds,d:a._days,M:a._months}:"number"==typeof a?(g={},b?g[b]=a:g.milliseconds=a):(h=Vd.exec(a))?(c="-"===h[1]?-1:1,g={y:0,d:r(h[xd])*c,h:r(h[yd])*c,m:r(h[zd])*c,s:r(h[Ad])*c,ms:r(h[Bd])*c}):(h=Wd.exec(a))?(c="-"===h[1]?-1:1,g={y:$a(h[2],c),M:$a(h[3],c),d:$a(h[4],c),h:$a(h[5],c),m:$a(h[6],c),s:$a(h[7],c),w:$a(h[8],c)}):null==g?g={}:"object"==typeof g&&("from"in g||"to"in g)&&(e=ab(Ea(g.from),Ea(g.to)),g={},g.ms=e.milliseconds,g.M=e.months),d=new Ia(g),Ja(a)&&f(a,"_locale")&&(d._locale=a._locale),d}function $a(a,b){var c=a&&parseFloat(a.replace(",","."));return(isNaN(c)?0:c)*b}function _a(a,b){var c={milliseconds:0,months:0};return c.months=b.month()-a.month()+12*(b.year()-a.year()),a.clone().add(c.months,"M").isAfter(b)&&--c.months,c.milliseconds=+b-+a.clone().add(c.months,"M"),c}function ab(a,b){var c;return a.isValid()&&b.isValid()?(b=Ma(b,a),a.isBefore(b)?c=_a(a,b):(c=_a(b,a),c.milliseconds=-c.milliseconds,c.months=-c.months),c):{milliseconds:0,months:0}}function bb(a,b){return function(c,d){var e,f;return null===d||isNaN(+d)||(ga(b,"moment()."+b+"(period, number) is deprecated. Please use moment()."+b+"(number, period)."),f=c,c=d,d=f),c="string"==typeof c?+c:c,e=Za(c,d),cb(this,e,a),this}}function cb(b,c,d,e){var f=c._milliseconds,g=c._days,h=c._months;b.isValid()&&(e=null==e?!0:e,f&&b._d.setTime(+b._d+f*d),g&&G(b,"Date",F(b,"Date")+g*d),h&&Z(b,F(b,"Month")+h*d),e&&a.updateOffset(b,g||h))}function db(a,b){var c=a||Ea(),d=Ma(c,this).startOf("day"),e=this.diff(d,"days",!0),f=-6>e?"sameElse":-1>e?"lastWeek":0>e?"lastDay":1>e?"sameDay":2>e?"nextDay":7>e?"nextWeek":"sameElse",g=b&&(D(b[f])?b[f]():b[f]);return this.format(g||this.localeData().calendar(f,this,Ea(c)))}function eb(){return new o(this)}function fb(a,b){var c=p(a)?a:Ea(a);return this.isValid()&&c.isValid()?(b=B(m(b)?"millisecond":b),"millisecond"===b?+this>+c:+c<+this.clone().startOf(b)):!1}function gb(a,b){var c=p(a)?a:Ea(a);return this.isValid()&&c.isValid()?(b=B(m(b)?"millisecond":b),"millisecond"===b?+c>+this:+this.clone().endOf(b)<+c):!1}function hb(a,b,c){return this.isAfter(a,c)&&this.isBefore(b,c)}function ib(a,b){var c,d=p(a)?a:Ea(a);return this.isValid()&&d.isValid()?(b=B(b||"millisecond"),"millisecond"===b?+this===+d:(c=+d,+this.clone().startOf(b)<=c&&c<=+this.clone().endOf(b))):!1}function jb(a,b){return this.isSame(a,b)||this.isAfter(a,b)}function kb(a,b){return this.isSame(a,b)||this.isBefore(a,b)}function lb(a,b,c){var d,e,f,g;return this.isValid()?(d=Ma(a,this),d.isValid()?(e=6e4*(d.utcOffset()-this.utcOffset()),b=B(b),"year"===b||"month"===b||"quarter"===b?(g=mb(this,d),"quarter"===b?g/=3:"year"===b&&(g/=12)):(f=this-d,g="second"===b?f/1e3:"minute"===b?f/6e4:"hour"===b?f/36e5:"day"===b?(f-e)/864e5:"week"===b?(f-e)/6048e5:f),c?g:q(g)):NaN):NaN}function mb(a,b){var c,d,e=12*(b.year()-a.year())+(b.month()-a.month()),f=a.clone().add(e,"months");return 0>b-f?(c=a.clone().add(e-1,"months"),d=(b-f)/(f-c)):(c=a.clone().add(e+1,"months"),d=(b-f)/(c-f)),-(e+d)}function nb(){return this.clone().locale("en").format("ddd MMM DD YYYY HH:mm:ss [GMT]ZZ")}function ob(){var a=this.clone().utc();return 0f&&(b=f),Ob.call(this,a,b,c,d,e))}function Ob(a,b,c,d,e){var f=pa(a,b,c,d,e),g=ka(f.year,0,f.dayOfYear);return this.year(g.getUTCFullYear()),this.month(g.getUTCMonth()),this.date(g.getUTCDate()),this}function Pb(a){return null==a?Math.ceil((this.month()+1)/3):this.month(3*(a-1)+this.month()%3)}function Qb(a){return qa(a,this._week.dow,this._week.doy).week}function Rb(){return this._week.dow}function Sb(){return this._week.doy}function Tb(a){var b=this.localeData().week(this);return null==a?b:this.add(7*(a-b),"d")}function Ub(a){var b=qa(this,1,4).week;return null==a?b:this.add(7*(a-b),"d")}function Vb(a,b){return"string"!=typeof a?a:isNaN(a)?(a=b.weekdaysParse(a),"number"==typeof a?a:null):parseInt(a,10)}function Wb(a,b){return c(this._weekdays)?this._weekdays[a.day()]:this._weekdays[this._weekdays.isFormat.test(b)?"format":"standalone"][a.day()]}function Xb(a){return this._weekdaysShort[a.day()]}function Yb(a){return this._weekdaysMin[a.day()]}function Zb(a,b,c){var d,e,f;for(this._weekdaysParse||(this._weekdaysParse=[],this._minWeekdaysParse=[],this._shortWeekdaysParse=[],this._fullWeekdaysParse=[]),d=0;7>d;d++){if(e=Ea([2e3,1]).day(d),c&&!this._fullWeekdaysParse[d]&&(this._fullWeekdaysParse[d]=new RegExp("^"+this.weekdays(e,"").replace(".",".?")+"$","i"),this._shortWeekdaysParse[d]=new RegExp("^"+this.weekdaysShort(e,"").replace(".",".?")+"$","i"),this._minWeekdaysParse[d]=new RegExp("^"+this.weekdaysMin(e,"").replace(".",".?")+"$","i")),this._weekdaysParse[d]||(f="^"+this.weekdays(e,"")+"|^"+this.weekdaysShort(e,"")+"|^"+this.weekdaysMin(e,""),this._weekdaysParse[d]=new RegExp(f.replace(".",""),"i")),c&&"dddd"===b&&this._fullWeekdaysParse[d].test(a))return d;if(c&&"ddd"===b&&this._shortWeekdaysParse[d].test(a))return d;if(c&&"dd"===b&&this._minWeekdaysParse[d].test(a))return d;if(!c&&this._weekdaysParse[d].test(a))return d}}function $b(a){if(!this.isValid())return null!=a?this:NaN;var b=this._isUTC?this._d.getUTCDay():this._d.getDay();return null!=a?(a=Vb(a,this.localeData()),this.add(a-b,"d")):b}function _b(a){if(!this.isValid())return null!=a?this:NaN;var b=(this.day()+7-this.localeData()._week.dow)%7;return null==a?b:this.add(a-b,"d")}function ac(a){return this.isValid()?null==a?this.day()||7:this.day(this.day()%7?a:a-7):null!=a?this:NaN}function bc(a){var b=Math.round((this.clone().startOf("day")-this.clone().startOf("year"))/864e5)+1;return null==a?b:this.add(a-b,"d")}function cc(){return this.hours()%12||12}function dc(a,b){J(a,0,0,function(){return this.localeData().meridiem(this.hours(),this.minutes(),b)})}function ec(a,b){return b._meridiemParse}function fc(a){return"p"===(a+"").toLowerCase().charAt(0)}function gc(a,b,c){return a>11?c?"pm":"PM":c?"am":"AM"}function hc(a,b){b[Bd]=r(1e3*("0."+a))}function ic(){return this._isUTC?"UTC":""}function jc(){return this._isUTC?"Coordinated Universal Time":""}function kc(a){return Ea(1e3*a)}function lc(){return Ea.apply(null,arguments).parseZone()}function mc(a,b,c){var d=this._calendar[a];return D(d)?d.call(b,c):d}function nc(a){var b=this._longDateFormat[a],c=this._longDateFormat[a.toUpperCase()];return b||!c?b:(this._longDateFormat[a]=c.replace(/MMMM|MM|DD|dddd/g,function(a){return a.slice(1)}),this._longDateFormat[a])}function oc(){return this._invalidDate}function pc(a){return this._ordinal.replace("%d",a)}function qc(a){return a}function rc(a,b,c,d){var e=this._relativeTime[c];return D(e)?e(a,b,c,d):e.replace(/%d/i,a)}function sc(a,b){var c=this._relativeTime[a>0?"future":"past"];return D(c)?c(b):c.replace(/%s/i,b)}function tc(a){var b,c;for(c in a)b=a[c],D(b)?this[c]=b:this["_"+c]=b;this._ordinalParseLenient=new RegExp(this._ordinalParse.source+"|"+/\d{1,2}/.source)}function uc(a,b,c,d){var e=z(),f=h().set(d,b);return e[c](f,a)}function vc(a,b,c,d,e){if("number"==typeof a&&(b=a,a=void 0),a=a||"",null!=b)return uc(a,b,c,e);var f,g=[];for(f=0;d>f;f++)g[f]=uc(a,f,c,e);return g}function wc(a,b){return vc(a,b,"months",12,"month")}function xc(a,b){return vc(a,b,"monthsShort",12,"month")}function yc(a,b){return vc(a,b,"weekdays",7,"day")}function zc(a,b){return vc(a,b,"weekdaysShort",7,"day")}function Ac(a,b){return vc(a,b,"weekdaysMin",7,"day")}function Bc(){var a=this._data;return this._milliseconds=se(this._milliseconds),this._days=se(this._days),this._months=se(this._months),a.milliseconds=se(a.milliseconds),a.seconds=se(a.seconds),a.minutes=se(a.minutes),a.hours=se(a.hours),a.months=se(a.months),a.years=se(a.years),this}function Cc(a,b,c,d){var e=Za(b,c);return a._milliseconds+=d*e._milliseconds,a._days+=d*e._days,a._months+=d*e._months,a._bubble()}function Dc(a,b){return Cc(this,a,b,1)}function Ec(a,b){return Cc(this,a,b,-1)}function Fc(a){return 0>a?Math.floor(a):Math.ceil(a)}function Gc(){var a,b,c,d,e,f=this._milliseconds,g=this._days,h=this._months,i=this._data;return f>=0&&g>=0&&h>=0||0>=f&&0>=g&&0>=h||(f+=864e5*Fc(Ic(h)+g),g=0,h=0),i.milliseconds=f%1e3,a=q(f/1e3),i.seconds=a%60,b=q(a/60),i.minutes=b%60,c=q(b/60),i.hours=c%24,g+=q(c/24),e=q(Hc(g)),h+=e,g-=Fc(Ic(e)),d=q(h/12),h%=12,i.days=g,i.months=h,i.years=d,this}function Hc(a){return 4800*a/146097}function Ic(a){return 146097*a/4800}function Jc(a){var b,c,d=this._milliseconds;if(a=B(a),"month"===a||"year"===a)return b=this._days+d/864e5,c=this._months+Hc(b),"month"===a?c:c/12;switch(b=this._days+Math.round(Ic(this._months)),a){case"week":return b/7+d/6048e5;case"day":return b+d/864e5;case"hour":return 24*b+d/36e5;case"minute":return 1440*b+d/6e4;case"second":return 86400*b+d/1e3;case"millisecond":return Math.floor(864e5*b)+d;default:throw new Error("Unknown unit "+a)}}function Kc(){return this._milliseconds+864e5*this._days+this._months%12*2592e6+31536e6*r(this._months/12)}function Lc(a){return function(){return this.as(a)}}function Mc(a){return a=B(a),this[a+"s"]()}function Nc(a){return function(){return this._data[a]}}function Oc(){return q(this.days()/7)}function Pc(a,b,c,d,e){return e.relativeTime(b||1,!!c,a,d)}function Qc(a,b,c){var d=Za(a).abs(),e=Ie(d.as("s")),f=Ie(d.as("m")),g=Ie(d.as("h")),h=Ie(d.as("d")),i=Ie(d.as("M")),j=Ie(d.as("y")),k=e=f&&["m"]||f=g&&["h"]||g=h&&["d"]||h=i&&["M"]||i=j&&["y"]||["yy",j];return k[2]=b,k[3]=+a>0,k[4]=c,Pc.apply(null,k)}function Rc(a,b){return void 0===Je[a]?!1:void 0===b?Je[a]:(Je[a]=b,!0)}function Sc(a){var b=this.localeData(),c=Qc(this,!a,b);return a&&(c=b.pastFuture(+this,c)),b.postformat(c)}function Tc(){var a,b,c,d=Ke(this._milliseconds)/1e3,e=Ke(this._days),f=Ke(this._months);a=q(d/60),b=q(a/60),d%=60,a%=60,c=q(f/12),f%=12;var g=c,h=f,i=e,j=b,k=a,l=d,m=this.asSeconds();return m?(0>m?"-":"")+"P"+(g?g+"Y":"")+(h?h+"M":"")+(i?i+"D":"")+(j||k||l?"T":"")+(j?j+"H":"")+(k?k+"M":"")+(l?l+"S":""):"P0D"}var Uc,Vc,Wc=a.momentProperties=[],Xc=!1,Yc={},Zc={},$c=/(\[[^\[]*\])|(\\)?([Hh]mm(ss)?|Mo|MM?M?M?|Do|DDDo|DD?D?D?|ddd?d?|do?|w[o|w]?|W[o|W]?|Qo?|YYYYYY|YYYYY|YYYY|YY|gg(ggg?)?|GG(GGG?)?|e|E|a|A|hh?|HH?|mm?|ss?|S{1,9}|x|X|zz?|ZZ?|.)/g,_c=/(\[[^\[]*\])|(\\)?(LTS|LT|LL?L?L?|l{1,4})/g,ad={},bd={},cd=/\d/,dd=/\d\d/,ed=/\d{3}/,fd=/\d{4}/,gd=/[+-]?\d{6}/,hd=/\d\d?/,id=/\d\d\d\d?/,jd=/\d\d\d\d\d\d?/,kd=/\d{1,3}/,ld=/\d{1,4}/,md=/[+-]?\d{1,6}/,nd=/\d+/,od=/[+-]?\d+/,pd=/Z|[+-]\d\d:?\d\d/gi,qd=/Z|[+-]\d\d(?::?\d\d)?/gi,rd=/[+-]?\d+(\.\d{1,3})?/,sd=/[0-9]*['a-z\u00A0-\u05FF\u0700-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]+|[\u0600-\u06FF\/]+(\s*?[\u0600-\u06FF]+){1,2}/i,td={},ud={},vd=0,wd=1,xd=2,yd=3,zd=4,Ad=5,Bd=6,Cd=7,Dd=8;J("M",["MM",2],"Mo",function(){return this.month()+1}),J("MMM",0,0,function(a){return this.localeData().monthsShort(this,a)}),J("MMMM",0,0,function(a){return this.localeData().months(this,a)}),A("month","M"),O("M",hd),O("MM",hd,dd),O("MMM",function(a,b){return b.monthsShortRegex(a)}),O("MMMM",function(a,b){return b.monthsRegex(a)}),S(["M","MM"],function(a,b){b[wd]=r(a)-1}),S(["MMM","MMMM"],function(a,b,c,d){var e=c._locale.monthsParse(a,d,c._strict);null!=e?b[wd]=e:j(c).invalidMonth=a});var Ed=/D[oD]?(\[[^\[\]]*\]|\s+)+MMMM?/,Fd="January_February_March_April_May_June_July_August_September_October_November_December".split("_"),Gd="Jan_Feb_Mar_Apr_May_Jun_Jul_Aug_Sep_Oct_Nov_Dec".split("_"),Hd=sd,Id=sd,Jd={};a.suppressDeprecationWarnings=!1;var Kd=/^\s*((?:[+-]\d{6}|\d{4})-(?:\d\d-\d\d|W\d\d-\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?::\d\d(?::\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/,Ld=/^\s*((?:[+-]\d{6}|\d{4})(?:\d\d\d\d|W\d\d\d|W\d\d|\d\d\d|\d\d))(?:(T| )(\d\d(?:\d\d(?:\d\d(?:[.,]\d+)?)?)?)([\+\-]\d\d(?::?\d\d)?|\s*Z)?)?/,Md=/Z|[+-]\d\d(?::?\d\d)?/,Nd=[["YYYYYY-MM-DD",/[+-]\d{6}-\d\d-\d\d/],["YYYY-MM-DD",/\d{4}-\d\d-\d\d/],["GGGG-[W]WW-E",/\d{4}-W\d\d-\d/],["GGGG-[W]WW",/\d{4}-W\d\d/,!1],["YYYY-DDD",/\d{4}-\d{3}/],["YYYY-MM",/\d{4}-\d\d/,!1],["YYYYYYMMDD",/[+-]\d{10}/],["YYYYMMDD",/\d{8}/],["GGGG[W]WWE",/\d{4}W\d{3}/],["GGGG[W]WW",/\d{4}W\d{2}/,!1],["YYYYDDD",/\d{7}/]],Od=[["HH:mm:ss.SSSS",/\d\d:\d\d:\d\d\.\d+/],["HH:mm:ss,SSSS",/\d\d:\d\d:\d\d,\d+/],["HH:mm:ss",/\d\d:\d\d:\d\d/],["HH:mm",/\d\d:\d\d/],["HHmmss.SSSS",/\d\d\d\d\d\d\.\d+/],["HHmmss,SSSS",/\d\d\d\d\d\d,\d+/],["HHmmss",/\d\d\d\d\d\d/],["HHmm",/\d\d\d\d/],["HH",/\d\d/]],Pd=/^\/?Date\((\-?\d+)/i;a.createFromInputFallback=fa("moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release. Please refer to https://github.com/moment/moment/issues/1407 for more info.",function(a){a._d=new Date(a._i+(a._useUTC?" UTC":""))}),J("Y",0,0,function(){var a=this.year();return 9999>=a?""+a:"+"+a}),J(0,["YY",2],0,function(){return this.year()%100}),J(0,["YYYY",4],0,"year"),J(0,["YYYYY",5],0,"year"),J(0,["YYYYYY",6,!0],0,"year"),A("year","y"),O("Y",od),O("YY",hd,dd),O("YYYY",ld,fd),O("YYYYY",md,gd),O("YYYYYY",md,gd),S(["YYYYY","YYYYYY"],vd),S("YYYY",function(b,c){c[vd]=2===b.length?a.parseTwoDigitYear(b):r(b)}),S("YY",function(b,c){c[vd]=a.parseTwoDigitYear(b)}),S("Y",function(a,b){b[vd]=parseInt(a,10)}),a.parseTwoDigitYear=function(a){return r(a)+(r(a)>68?1900:2e3)};var Qd=E("FullYear",!1);a.ISO_8601=function(){};var Rd=fa("moment().min is deprecated, use moment.min instead. https://github.com/moment/moment/issues/1548",function(){var a=Ea.apply(null,arguments);return this.isValid()&&a.isValid()?this>a?this:a:l()}),Sd=fa("moment().max is deprecated, use moment.max instead. https://github.com/moment/moment/issues/1548",function(){var a=Ea.apply(null,arguments);return this.isValid()&&a.isValid()?a>this?this:a:l()}),Td=function(){return Date.now?Date.now():+new Date};Ka("Z",":"),Ka("ZZ",""),O("Z",qd),O("ZZ",qd),S(["Z","ZZ"],function(a,b,c){c._useUTC=!0,c._tzm=La(qd,a)});var Ud=/([\+\-]|\d\d)/gi;a.updateOffset=function(){};var Vd=/^(\-)?(?:(\d*)[. ])?(\d+)\:(\d+)(?:\:(\d+)\.?(\d{3})?\d*)?$/,Wd=/^(-)?P(?:(?:([0-9,.]*)Y)?(?:([0-9,.]*)M)?(?:([0-9,.]*)D)?(?:T(?:([0-9,.]*)H)?(?:([0-9,.]*)M)?(?:([0-9,.]*)S)?)?|([0-9,.]*)W)$/; +Za.fn=Ia.prototype;var Xd=bb(1,"add"),Yd=bb(-1,"subtract");a.defaultFormat="YYYY-MM-DDTHH:mm:ssZ";var Zd=fa("moment().lang() is deprecated. Instead, use moment().localeData() to get the language configuration. Use moment().locale() to change languages.",function(a){return void 0===a?this.localeData():this.locale(a)});J(0,["gg",2],0,function(){return this.weekYear()%100}),J(0,["GG",2],0,function(){return this.isoWeekYear()%100}),Ib("gggg","weekYear"),Ib("ggggg","weekYear"),Ib("GGGG","isoWeekYear"),Ib("GGGGG","isoWeekYear"),A("weekYear","gg"),A("isoWeekYear","GG"),O("G",od),O("g",od),O("GG",hd,dd),O("gg",hd,dd),O("GGGG",ld,fd),O("gggg",ld,fd),O("GGGGG",md,gd),O("ggggg",md,gd),T(["gggg","ggggg","GGGG","GGGGG"],function(a,b,c,d){b[d.substr(0,2)]=r(a)}),T(["gg","GG"],function(b,c,d,e){c[e]=a.parseTwoDigitYear(b)}),J("Q",0,"Qo","quarter"),A("quarter","Q"),O("Q",cd),S("Q",function(a,b){b[wd]=3*(r(a)-1)}),J("w",["ww",2],"wo","week"),J("W",["WW",2],"Wo","isoWeek"),A("week","w"),A("isoWeek","W"),O("w",hd),O("ww",hd,dd),O("W",hd),O("WW",hd,dd),T(["w","ww","W","WW"],function(a,b,c,d){b[d.substr(0,1)]=r(a)});var $d={dow:0,doy:6};J("D",["DD",2],"Do","date"),A("date","D"),O("D",hd),O("DD",hd,dd),O("Do",function(a,b){return a?b._ordinalParse:b._ordinalParseLenient}),S(["D","DD"],xd),S("Do",function(a,b){b[xd]=r(a.match(hd)[0],10)});var _d=E("Date",!0);J("d",0,"do","day"),J("dd",0,0,function(a){return this.localeData().weekdaysMin(this,a)}),J("ddd",0,0,function(a){return this.localeData().weekdaysShort(this,a)}),J("dddd",0,0,function(a){return this.localeData().weekdays(this,a)}),J("e",0,0,"weekday"),J("E",0,0,"isoWeekday"),A("day","d"),A("weekday","e"),A("isoWeekday","E"),O("d",hd),O("e",hd),O("E",hd),O("dd",sd),O("ddd",sd),O("dddd",sd),T(["dd","ddd","dddd"],function(a,b,c,d){var e=c._locale.weekdaysParse(a,d,c._strict);null!=e?b.d=e:j(c).invalidWeekday=a}),T(["d","e","E"],function(a,b,c,d){b[d]=r(a)});var ae="Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),be="Sun_Mon_Tue_Wed_Thu_Fri_Sat".split("_"),ce="Su_Mo_Tu_We_Th_Fr_Sa".split("_");J("DDD",["DDDD",3],"DDDo","dayOfYear"),A("dayOfYear","DDD"),O("DDD",kd),O("DDDD",ed),S(["DDD","DDDD"],function(a,b,c){c._dayOfYear=r(a)}),J("H",["HH",2],0,"hour"),J("h",["hh",2],0,cc),J("hmm",0,0,function(){return""+cc.apply(this)+I(this.minutes(),2)}),J("hmmss",0,0,function(){return""+cc.apply(this)+I(this.minutes(),2)+I(this.seconds(),2)}),J("Hmm",0,0,function(){return""+this.hours()+I(this.minutes(),2)}),J("Hmmss",0,0,function(){return""+this.hours()+I(this.minutes(),2)+I(this.seconds(),2)}),dc("a",!0),dc("A",!1),A("hour","h"),O("a",ec),O("A",ec),O("H",hd),O("h",hd),O("HH",hd,dd),O("hh",hd,dd),O("hmm",id),O("hmmss",jd),O("Hmm",id),O("Hmmss",jd),S(["H","HH"],yd),S(["a","A"],function(a,b,c){c._isPm=c._locale.isPM(a),c._meridiem=a}),S(["h","hh"],function(a,b,c){b[yd]=r(a),j(c).bigHour=!0}),S("hmm",function(a,b,c){var d=a.length-2;b[yd]=r(a.substr(0,d)),b[zd]=r(a.substr(d)),j(c).bigHour=!0}),S("hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[yd]=r(a.substr(0,d)),b[zd]=r(a.substr(d,2)),b[Ad]=r(a.substr(e)),j(c).bigHour=!0}),S("Hmm",function(a,b,c){var d=a.length-2;b[yd]=r(a.substr(0,d)),b[zd]=r(a.substr(d))}),S("Hmmss",function(a,b,c){var d=a.length-4,e=a.length-2;b[yd]=r(a.substr(0,d)),b[zd]=r(a.substr(d,2)),b[Ad]=r(a.substr(e))});var de=/[ap]\.?m?\.?/i,ee=E("Hours",!0);J("m",["mm",2],0,"minute"),A("minute","m"),O("m",hd),O("mm",hd,dd),S(["m","mm"],zd);var fe=E("Minutes",!1);J("s",["ss",2],0,"second"),A("second","s"),O("s",hd),O("ss",hd,dd),S(["s","ss"],Ad);var ge=E("Seconds",!1);J("S",0,0,function(){return~~(this.millisecond()/100)}),J(0,["SS",2],0,function(){return~~(this.millisecond()/10)}),J(0,["SSS",3],0,"millisecond"),J(0,["SSSS",4],0,function(){return 10*this.millisecond()}),J(0,["SSSSS",5],0,function(){return 100*this.millisecond()}),J(0,["SSSSSS",6],0,function(){return 1e3*this.millisecond()}),J(0,["SSSSSSS",7],0,function(){return 1e4*this.millisecond()}),J(0,["SSSSSSSS",8],0,function(){return 1e5*this.millisecond()}),J(0,["SSSSSSSSS",9],0,function(){return 1e6*this.millisecond()}),A("millisecond","ms"),O("S",kd,cd),O("SS",kd,dd),O("SSS",kd,ed);var he;for(he="SSSS";he.length<=9;he+="S")O(he,nd);for(he="S";he.length<=9;he+="S")S(he,hc);var ie=E("Milliseconds",!1);J("z",0,0,"zoneAbbr"),J("zz",0,0,"zoneName");var je=o.prototype;je.add=Xd,je.calendar=db,je.clone=eb,je.diff=lb,je.endOf=xb,je.format=pb,je.from=qb,je.fromNow=rb,je.to=sb,je.toNow=tb,je.get=H,je.invalidAt=Gb,je.isAfter=fb,je.isBefore=gb,je.isBetween=hb,je.isSame=ib,je.isSameOrAfter=jb,je.isSameOrBefore=kb,je.isValid=Eb,je.lang=Zd,je.locale=ub,je.localeData=vb,je.max=Sd,je.min=Rd,je.parsingFlags=Fb,je.set=H,je.startOf=wb,je.subtract=Yd,je.toArray=Bb,je.toObject=Cb,je.toDate=Ab,je.toISOString=ob,je.toJSON=Db,je.toString=nb,je.unix=zb,je.valueOf=yb,je.creationData=Hb,je.year=Qd,je.isLeapYear=na,je.weekYear=Jb,je.isoWeekYear=Kb,je.quarter=je.quarters=Pb,je.month=$,je.daysInMonth=_,je.week=je.weeks=Tb,je.isoWeek=je.isoWeeks=Ub,je.weeksInYear=Mb,je.isoWeeksInYear=Lb,je.date=_d,je.day=je.days=$b,je.weekday=_b,je.isoWeekday=ac,je.dayOfYear=bc,je.hour=je.hours=ee,je.minute=je.minutes=fe,je.second=je.seconds=ge,je.millisecond=je.milliseconds=ie,je.utcOffset=Oa,je.utc=Qa,je.local=Ra,je.parseZone=Sa,je.hasAlignedHourOffset=Ta,je.isDST=Ua,je.isDSTShifted=Va,je.isLocal=Wa,je.isUtcOffset=Xa,je.isUtc=Ya,je.isUTC=Ya,je.zoneAbbr=ic,je.zoneName=jc,je.dates=fa("dates accessor is deprecated. Use date instead.",_d),je.months=fa("months accessor is deprecated. Use month instead",$),je.years=fa("years accessor is deprecated. Use year instead",Qd),je.zone=fa("moment().zone is deprecated, use moment().utcOffset instead. https://github.com/moment/moment/issues/1779",Pa);var ke=je,le={sameDay:"[Today at] LT",nextDay:"[Tomorrow at] LT",nextWeek:"dddd [at] LT",lastDay:"[Yesterday at] LT",lastWeek:"[Last] dddd [at] LT",sameElse:"L"},me={LTS:"h:mm:ss A",LT:"h:mm A",L:"MM/DD/YYYY",LL:"MMMM D, YYYY",LLL:"MMMM D, YYYY h:mm A",LLLL:"dddd, MMMM D, YYYY h:mm A"},ne="Invalid date",oe="%d",pe=/\d{1,2}/,qe={future:"in %s",past:"%s ago",s:"a few seconds",m:"a minute",mm:"%d minutes",h:"an hour",hh:"%d hours",d:"a day",dd:"%d days",M:"a month",MM:"%d months",y:"a year",yy:"%d years"},re=t.prototype;re._calendar=le,re.calendar=mc,re._longDateFormat=me,re.longDateFormat=nc,re._invalidDate=ne,re.invalidDate=oc,re._ordinal=oe,re.ordinal=pc,re._ordinalParse=pe,re.preparse=qc,re.postformat=qc,re._relativeTime=qe,re.relativeTime=rc,re.pastFuture=sc,re.set=tc,re.months=W,re._months=Fd,re.monthsShort=X,re._monthsShort=Gd,re.monthsParse=Y,re._monthsRegex=Id,re.monthsRegex=ba,re._monthsShortRegex=Hd,re.monthsShortRegex=aa,re.week=Qb,re._week=$d,re.firstDayOfYear=Sb,re.firstDayOfWeek=Rb,re.weekdays=Wb,re._weekdays=ae,re.weekdaysMin=Yb,re._weekdaysMin=ce,re.weekdaysShort=Xb,re._weekdaysShort=be,re.weekdaysParse=Zb,re.isPM=fc,re._meridiemParse=de,re.meridiem=gc,x("en",{ordinalParse:/\d{1,2}(th|st|nd|rd)/,ordinal:function(a){var b=a%10,c=1===r(a%100/10)?"th":1===b?"st":2===b?"nd":3===b?"rd":"th";return a+c}}),a.lang=fa("moment.lang is deprecated. Use moment.locale instead.",x),a.langData=fa("moment.langData is deprecated. Use moment.localeData instead.",z);var se=Math.abs,te=Lc("ms"),ue=Lc("s"),ve=Lc("m"),we=Lc("h"),xe=Lc("d"),ye=Lc("w"),ze=Lc("M"),Ae=Lc("y"),Be=Nc("milliseconds"),Ce=Nc("seconds"),De=Nc("minutes"),Ee=Nc("hours"),Fe=Nc("days"),Ge=Nc("months"),He=Nc("years"),Ie=Math.round,Je={s:45,m:45,h:22,d:26,M:11},Ke=Math.abs,Le=Ia.prototype;Le.abs=Bc,Le.add=Dc,Le.subtract=Ec,Le.as=Jc,Le.asMilliseconds=te,Le.asSeconds=ue,Le.asMinutes=ve,Le.asHours=we,Le.asDays=xe,Le.asWeeks=ye,Le.asMonths=ze,Le.asYears=Ae,Le.valueOf=Kc,Le._bubble=Gc,Le.get=Mc,Le.milliseconds=Be,Le.seconds=Ce,Le.minutes=De,Le.hours=Ee,Le.days=Fe,Le.weeks=Oc,Le.months=Ge,Le.years=He,Le.humanize=Sc,Le.toISOString=Tc,Le.toString=Tc,Le.toJSON=Tc,Le.locale=ub,Le.localeData=vb,Le.toIsoString=fa("toIsoString() is deprecated. Please use toISOString() instead (notice the capitals)",Tc),Le.lang=Zd,J("X",0,0,"unix"),J("x",0,0,"valueOf"),O("x",od),O("X",rd),S("X",function(a,b,c){c._d=new Date(1e3*parseFloat(a,10))}),S("x",function(a,b,c){c._d=new Date(r(a))}),a.version="2.11.2",b(Ea),a.fn=ke,a.min=Ga,a.max=Ha,a.now=Td,a.utc=h,a.unix=kc,a.months=wc,a.isDate=d,a.locale=x,a.invalid=l,a.duration=Za,a.isMoment=p,a.weekdays=yc,a.parseZone=lc,a.localeData=z,a.isDuration=Ja,a.monthsShort=xc,a.weekdaysMin=Ac,a.defineLocale=y,a.weekdaysShort=zc,a.normalizeUnits=B,a.relativeTimeThreshold=Rc,a.prototype=ke;var Me=a;return Me}); \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/outputAdapterUiLibrary.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/outputAdapterUiLibrary.js new file mode 100644 index 00000000..50f07a80 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/outputAdapterUiLibrary.js @@ -0,0 +1,286 @@ +/* + * + * + * Copyright (c) 2015, 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 CONSTANTS = { + webAppName: 'outputui', + urlSeperator: '/', + urlGetParameter : '?lastUpdatedTime=', + urlQueryStringBegin : '?', + tenantUrlAttribute: 't', + urlUnsecureTransportHttp : 'http://', + urlUnsecureTransportWebsocket : 'ws://', + urlSecureTransportWebsocket : 'wss://', + urlSecureTransportHttp : 'https://', + colon : ':', + defaultIntervalTime : 10 * 1000, + defaultUserDomain : 'carbon.super', + defaultHostName : 'localhost', + defaultNonsecurePortNumber : '9763', + defaultSecurePortNumber : '9443', + defaultMode : 'AUTO', + processModeHTTP : 'HTTP', + processModeWebSocket : 'WEBSOCKET', + processModeAuto : 'AUTO', + domain : 'carbon.super', + numThousand : 1000, + websocketTimeAppender : 400, + secureMode : 'SECURED' +}; + + +var websocket = null; +var webSocketUrl; +var httpUrl; +var cepHostName; +var cepPortNumber; +var isErrorOccured = false; +var lastUpdatedtime = -1; +var polingInterval; +var stream; +var streamVersion; +var firstPollingAttempt; +var processMode; +var onSuccessFunction; +var onErrorFunction; +var userDomainUrl = ""; +var terminateWebsocketInstance = false; +var pollingContinue = true; +var transportToBeUsedHttp; +var transportToBeUsedWebsocket; + +function subscribe(streamName,version,intervalTime,domain, + listeningFuncSuccessData,listeningFuncErrorData, + cepHost,cepPort,mode,secureMode, queryParams){ + + stopPollingProcesses(); + stream = streamName; + streamVersion = version; + onSuccessFunction = listeningFuncSuccessData; + onErrorFunction = listeningFuncErrorData; + + if(secureMode == CONSTANTS.secureMode){ + transportToBeUsedHttp = CONSTANTS.urlSecureTransportHttp; + transportToBeUsedWebsocket = CONSTANTS.urlSecureTransportWebsocket; + } else { + transportToBeUsedHttp = CONSTANTS.urlUnsecureTransportHttp; + transportToBeUsedWebsocket = CONSTANTS.urlUnsecureTransportWebsocket; + } + + if(intervalTime == null || intervalTime == ""){ + polingInterval = CONSTANTS.defaultIntervalTime; + } else{ + polingInterval = intervalTime * CONSTANTS.numThousand; + } + + if(domain == null || domain == ""){ + domain = CONSTANTS.defaultUserDomain; + } + + if(cepHost == null || cepHost == ""){ + cepHostName = CONSTANTS.defaultHostName; + } else{ + cepHostName = cepHost; + } + + if(cepPort == null || cepPort == ""){ + if(secureMode == CONSTANTS.secureMode){ + cepPortNumber = CONSTANTS.defaultSecurePortNumber; + } else{ + cepPortNumber = CONSTANTS.defaultNonsecurePortNumber; + } + } else{ + cepPortNumber = cepPort; + } + + if(mode == null || mode == ""){ + processMode = CONSTANTS.defaultMode; + } else{ + processMode = mode; + } + + if(domain != CONSTANTS.domain){ + userDomainUrl = CONSTANTS.tenantUrlAttribute + CONSTANTS.urlSeperator + domain + CONSTANTS.urlSeperator; + + } + + if (queryParams == null) { + queryParams = ""; + } else if (queryParams != "") { + queryParams = CONSTANTS.urlQueryStringBegin + queryParams; + } + + webSocketUrl = transportToBeUsedWebsocket + cepHostName + CONSTANTS.colon + cepPortNumber + + CONSTANTS.urlSeperator + CONSTANTS.webAppName+ CONSTANTS.urlSeperator + userDomainUrl + stream + + CONSTANTS.urlSeperator + streamVersion + queryParams; + + + if(processMode == CONSTANTS.processModeHTTP){ + firstPollingAttempt = true; + pollingContinue = true; + startPoll(); + } else{ + initializeWebSocket(webSocketUrl); + } +} + + +/** + * Initializing Web Socket + */ +function initializeWebSocket(webSocketUrl){ + websocket = new WebSocket(webSocketUrl); + websocket.onopen = webSocketOnOpen; + websocket.onmessage = webSocketOnMessage; + websocket.onclose = webSocketOnClose; + websocket.onerror = webSocketOnError; +} + +/** + * Web socket On Open + */ + +var webSocketOnOpen = function () { + // alert("Successfully connected to "+webSocketUrl); + //onErrorFunction("Successfully connected to URL:" + webSocketUrl + "\n"); +}; + + +/** + * On server sends a message + */ +var webSocketOnMessage = function (evt) { + var event = evt.data; + var array = JSON.parse(event); + constructPayload(array); +}; + +/** + * On server close + */ +var webSocketOnClose =function (e) { + + if(isErrorOccured){ + if(processMode != CONSTANTS.processModeWebSocket){ + firstPollingAttempt = true; + pollingContinue = true; + startPoll(); + } + } else{ + if(!terminateWebsocketInstance){ + waitForSocketConnection(websocket); + } else{ + terminateWebsocketInstance = false; + } + + } +}; + +/** + * On server Error + */ +var webSocketOnError = function (err) { + var error = "Error: Cannot connect to Websocket URL:" + webSocketUrl + " .Hence closing the connection!"; + + onErrorFunction(error); + isErrorOccured = true; + +}; + +/** + * Gracefully increments the connection retry + */ +var waitTime = CONSTANTS.numThousand; +function waitForSocketConnection(socket, callback){ + setTimeout( + function () { + if (socket.readyState === 1) { + initializeWebSocket(webSocketUrl); + console.log("Connection is made"); + if(callback != null){ + callback(); + } + return; + } else { + websocket = new WebSocket(webSocketUrl); + waitTime += CONSTANTS.websocketTimeAppender; + waitForSocketConnection(websocket, callback); + } + }, waitTime); +} + +/** + * Polling to retrieve events from http request periodically + */ +function startPoll(){ + + (function poll(){ + setTimeout(function(){ + httpUrl = transportToBeUsedHttp + cepHostName + CONSTANTS.colon + cepPortNumber + CONSTANTS.urlSeperator + + CONSTANTS.webAppName + CONSTANTS.urlSeperator + userDomainUrl + stream + CONSTANTS.urlSeperator + + streamVersion + CONSTANTS.urlGetParameter + lastUpdatedtime; + + $.getJSON(httpUrl, function(responseText) { + if(firstPollingAttempt){ + /*var data = $("textarea#idConsole").val(); + $("textarea#idConsole").val(data + "Successfully connected to HTTP.");*/ + firstPollingAttempt = false; + } + + var eventList = $.parseJSON(responseText.events); + if(eventList.length != 0){ + lastUpdatedtime = responseText.lastEventTime; + for(var i=0;i 1) { + var geomsByArc = [], + geom; + + function arc(i) { + var j = i < 0 ? ~i : i; + (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom}); + } + + function line(arcs) { + arcs.forEach(arc); + } + + function polygon(arcs) { + arcs.forEach(line); + } + + function geometry(o) { + if (o.type === "GeometryCollection") o.geometries.forEach(geometry); + else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs); + } + + var geometryType = { + LineString: line, + MultiLineString: polygon, + Polygon: polygon, + MultiPolygon: function(arcs) { arcs.forEach(polygon); } + }; + + geometry(o); + + geomsByArc.forEach(arguments.length < 3 + ? function(geoms) { arcs.push(geoms[0].i); } + : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); }); + } else { + for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i); + } + + return {type: "MultiLineString", arcs: stitchArcs(topology, arcs)}; + } + + function mergeArcs(topology, objects) { + var polygonsByArc = {}, + polygons = [], + components = []; + + objects.forEach(function(o) { + if (o.type === "Polygon") register(o.arcs); + else if (o.type === "MultiPolygon") o.arcs.forEach(register); + }); + + function register(polygon) { + polygon.forEach(function(ring) { + ring.forEach(function(arc) { + (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon); + }); + }); + polygons.push(polygon); + } + + function exterior(ring) { + return cartesianRingArea(object(topology, {type: "Polygon", arcs: [ring]}).coordinates[0]) > 0; // TODO allow spherical? + } + + polygons.forEach(function(polygon) { + if (!polygon._) { + var component = [], + neighbors = [polygon]; + polygon._ = 1; + components.push(component); + while (polygon = neighbors.pop()) { + component.push(polygon); + polygon.forEach(function(ring) { + ring.forEach(function(arc) { + polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) { + if (!polygon._) { + polygon._ = 1; + neighbors.push(polygon); + } + }); + }); + }); + } + } + }); + + polygons.forEach(function(polygon) { + delete polygon._; + }); + + return { + type: "MultiPolygon", + arcs: components.map(function(polygons) { + var arcs = []; + + // Extract the exterior (unique) arcs. + polygons.forEach(function(polygon) { + polygon.forEach(function(ring) { + ring.forEach(function(arc) { + if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) { + arcs.push(arc); + } + }); + }); + }); + + // Stitch the arcs into one or more rings. + arcs = stitchArcs(topology, arcs); + + // If more than one ring is returned, + // at most one of these rings can be the exterior; + // this exterior ring has the same winding order + // as any exterior ring in the original polygons. + if ((n = arcs.length) > 1) { + var sgn = exterior(polygons[0][0]); + for (var i = 0, t; i < n; ++i) { + if (sgn === exterior(arcs[i])) { + t = arcs[0], arcs[0] = arcs[i], arcs[i] = t; + break; + } + } + } + + return arcs; + }) + }; + } + + function featureOrCollection(topology, o) { + return o.type === "GeometryCollection" ? { + type: "FeatureCollection", + features: o.geometries.map(function(o) { return feature(topology, o); }) + } : feature(topology, o); + } + + function feature(topology, o) { + var f = { + type: "Feature", + id: o.id, + properties: o.properties || {}, + geometry: object(topology, o) + }; + if (o.id == null) delete f.id; + return f; + } + + function object(topology, o) { + var absolute = transformAbsolute(topology.transform), + arcs = topology.arcs; + + function arc(i, points) { + if (points.length) points.pop(); + for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) { + points.push(p = a[k].slice()); + absolute(p, k); + } + if (i < 0) reverse(points, n); + } + + function point(p) { + p = p.slice(); + absolute(p, 0); + return p; + } + + function line(arcs) { + var points = []; + for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points); + if (points.length < 2) points.push(points[0].slice()); + return points; + } + + function ring(arcs) { + var points = line(arcs); + while (points.length < 4) points.push(points[0].slice()); + return points; + } + + function polygon(arcs) { + return arcs.map(ring); + } + + function geometry(o) { + var t = o.type; + return t === "GeometryCollection" ? {type: t, geometries: o.geometries.map(geometry)} + : t in geometryType ? {type: t, coordinates: geometryType[t](o)} + : null; + } + + var geometryType = { + Point: function(o) { return point(o.coordinates); }, + MultiPoint: function(o) { return o.coordinates.map(point); }, + LineString: function(o) { return line(o.arcs); }, + MultiLineString: function(o) { return o.arcs.map(line); }, + Polygon: function(o) { return polygon(o.arcs); }, + MultiPolygon: function(o) { return o.arcs.map(polygon); } + }; + + return geometry(o); + } + + function reverse(array, n) { + var t, j = array.length, i = j - n; while (i < --j) t = array[i], array[i++] = array[j], array[j] = t; + } + + function bisect(a, x) { + var lo = 0, hi = a.length; + while (lo < hi) { + var mid = lo + hi >>> 1; + if (a[mid] < x) lo = mid + 1; + else hi = mid; + } + return lo; + } + + function neighbors(objects) { + var indexesByArc = {}, // arc index -> array of object indexes + neighbors = objects.map(function() { return []; }); + + function line(arcs, i) { + arcs.forEach(function(a) { + if (a < 0) a = ~a; + var o = indexesByArc[a]; + if (o) o.push(i); + else indexesByArc[a] = [i]; + }); + } + + function polygon(arcs, i) { + arcs.forEach(function(arc) { line(arc, i); }); + } + + function geometry(o, i) { + if (o.type === "GeometryCollection") o.geometries.forEach(function(o) { geometry(o, i); }); + else if (o.type in geometryType) geometryType[o.type](o.arcs, i); + } + + var geometryType = { + LineString: line, + MultiLineString: polygon, + Polygon: polygon, + MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); } + }; + + objects.forEach(geometry); + + for (var i in indexesByArc) { + for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) { + for (var k = j + 1; k < m; ++k) { + var ij = indexes[j], ik = indexes[k], n; + if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik); + if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij); + } + } + } + + return neighbors; + } + + function presimplify(topology, triangleArea) { + var absolute = transformAbsolute(topology.transform), + relative = transformRelative(topology.transform), + heap = minAreaHeap(); + + if (!triangleArea) triangleArea = cartesianTriangleArea; + + topology.arcs.forEach(function(arc) { + var triangles = [], + maxArea = 0, + triangle; + + // To store each point’s effective area, we create a new array rather than + // extending the passed-in point to workaround a Chrome/V8 bug (getting + // stuck in smi mode). For midpoints, the initial effective area of + // Infinity will be computed in the next step. + for (var i = 0, n = arc.length, p; i < n; ++i) { + p = arc[i]; + absolute(arc[i] = [p[0], p[1], Infinity], i); + } + + for (var i = 1, n = arc.length - 1; i < n; ++i) { + triangle = arc.slice(i - 1, i + 2); + triangle[1][2] = triangleArea(triangle); + triangles.push(triangle); + heap.push(triangle); + } + + for (var i = 0, n = triangles.length; i < n; ++i) { + triangle = triangles[i]; + triangle.previous = triangles[i - 1]; + triangle.next = triangles[i + 1]; + } + + while (triangle = heap.pop()) { + var previous = triangle.previous, + next = triangle.next; + + // If the area of the current point is less than that of the previous point + // to be eliminated, use the latter's area instead. This ensures that the + // current point cannot be eliminated without eliminating previously- + // eliminated points. + if (triangle[1][2] < maxArea) triangle[1][2] = maxArea; + else maxArea = triangle[1][2]; + + if (previous) { + previous.next = next; + previous[2] = triangle[2]; + update(previous); + } + + if (next) { + next.previous = previous; + next[0] = triangle[0]; + update(next); + } + } + + arc.forEach(relative); + }); + + function update(triangle) { + heap.remove(triangle); + triangle[1][2] = triangleArea(triangle); + heap.push(triangle); + } + + return topology; + }; + + function cartesianRingArea(ring) { + var i = -1, + n = ring.length, + a, + b = ring[n - 1], + area = 0; + + while (++i < n) { + a = b; + b = ring[i]; + area += a[0] * b[1] - a[1] * b[0]; + } + + return area * .5; + } + + function cartesianTriangleArea(triangle) { + var a = triangle[0], b = triangle[1], c = triangle[2]; + return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1])); + } + + function compareArea(a, b) { + return a[1][2] - b[1][2]; + } + + function minAreaHeap() { + var heap = {}, + array = [], + size = 0; + + heap.push = function(object) { + up(array[object._ = size] = object, size++); + return size; + }; + + heap.pop = function() { + if (size <= 0) return; + var removed = array[0], object; + if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0); + return removed; + }; + + heap.remove = function(removed) { + var i = removed._, object; + if (array[i] !== removed) return; // invalid request + if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i); + return i; + }; + + function up(object, i) { + while (i > 0) { + var j = ((i + 1) >> 1) - 1, + parent = array[j]; + if (compareArea(object, parent) >= 0) break; + array[parent._ = i] = parent; + array[object._ = i = j] = object; + } + } + + function down(object, i) { + while (true) { + var r = (i + 1) << 1, + l = r - 1, + j = i, + child = array[j]; + if (l < size && compareArea(array[l], child) < 0) child = array[j = l]; + if (r < size && compareArea(array[r], child) < 0) child = array[j = r]; + if (j === i) break; + array[child._ = i] = child; + array[object._ = i = j] = object; + } + } + + return heap; + } + + function transformAbsolute(transform) { + if (!transform) return noop; + var x0, + y0, + kx = transform.scale[0], + ky = transform.scale[1], + dx = transform.translate[0], + dy = transform.translate[1]; + return function(point, i) { + if (!i) x0 = y0 = 0; + point[0] = (x0 += point[0]) * kx + dx; + point[1] = (y0 += point[1]) * ky + dy; + }; + } + + function transformRelative(transform) { + if (!transform) return noop; + var x0, + y0, + kx = transform.scale[0], + ky = transform.scale[1], + dx = transform.translate[0], + dy = transform.translate[1]; + return function(point, i) { + if (!i) x0 = y0 = 0; + var x1 = (point[0] - dx) / kx | 0, + y1 = (point[1] - dy) / ky | 0; + point[0] = x1 - x0; + point[1] = y1 - y0; + x0 = x1; + y0 = y1; + }; + } + + function noop() {} + + if (typeof define === "function" && define.amd) define(topojson); + else if (typeof module === "object" && module.exports) module.exports = topojson; + else this.topojson = topojson; +}(); diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/vega.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/vega.js new file mode 100644 index 00000000..c6b8b0af --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/IoTServerTemperatureStats/js/vega.js @@ -0,0 +1,20654 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.vg = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o> 5, + ch = 1 << 11; + + module.exports = function() { + var size = [256, 256], + text = cloudText, + font = cloudFont, + fontSize = cloudFontSize, + fontStyle = cloudFontNormal, + fontWeight = cloudFontNormal, + rotate = cloudRotate, + padding = cloudPadding, + spiral = archimedeanSpiral, + words = [], + timeInterval = Infinity, + event = dispatch("word", "end"), + timer = null, + random = Math.random, + cloud = {}, + canvas = cloudCanvas; + + cloud.canvas = function(_) { + return arguments.length ? (canvas = functor(_), cloud) : canvas; + }; + + cloud.start = function() { + var contextAndRatio = getContext(canvas()), + board = zeroArray((size[0] >> 5) * size[1]), + bounds = null, + n = words.length, + i = -1, + tags = [], + data = words.map(function(d, i) { + d.text = text.call(this, d, i); + d.font = font.call(this, d, i); + d.style = fontStyle.call(this, d, i); + d.weight = fontWeight.call(this, d, i); + d.rotate = rotate.call(this, d, i); + d.size = ~~fontSize.call(this, d, i); + d.padding = padding.call(this, d, i); + return d; + }).sort(function(a, b) { return b.size - a.size; }); + + if (timer) clearInterval(timer); + timer = setInterval(step, 0); + step(); + + return cloud; + + function step() { + var start = Date.now(); + while (Date.now() - start < timeInterval && ++i < n && timer) { + var d = data[i]; + d.x = (size[0] * (random() + .5)) >> 1; + d.y = (size[1] * (random() + .5)) >> 1; + cloudSprite(contextAndRatio, d, data, i); + if (d.hasText && place(board, d, bounds)) { + tags.push(d); + event.word(d); + if (bounds) cloudBounds(bounds, d); + else bounds = [{x: d.x + d.x0, y: d.y + d.y0}, {x: d.x + d.x1, y: d.y + d.y1}]; + // Temporary hack + d.x -= size[0] >> 1; + d.y -= size[1] >> 1; + } + } + if (i >= n) { + cloud.stop(); + event.end(tags, bounds); + } + } + } + + cloud.stop = function() { + if (timer) { + clearInterval(timer); + timer = null; + } + return cloud; + }; + + function getContext(canvas) { + canvas.width = canvas.height = 1; + var ratio = Math.sqrt(canvas.getContext("2d").getImageData(0, 0, 1, 1).data.length >> 2); + canvas.width = (cw << 5) / ratio; + canvas.height = ch / ratio; + + var context = canvas.getContext("2d"); + context.fillStyle = context.strokeStyle = "red"; + context.textAlign = "center"; + + return {context: context, ratio: ratio}; + } + + function place(board, tag, bounds) { + var perimeter = [{x: 0, y: 0}, {x: size[0], y: size[1]}], + startX = tag.x, + startY = tag.y, + maxDelta = Math.sqrt(size[0] * size[0] + size[1] * size[1]), + s = spiral(size), + dt = random() < .5 ? 1 : -1, + t = -dt, + dxdy, + dx, + dy; + + while (dxdy = s(t += dt)) { + dx = ~~dxdy[0]; + dy = ~~dxdy[1]; + + if (Math.min(Math.abs(dx), Math.abs(dy)) >= maxDelta) break; + + tag.x = startX + dx; + tag.y = startY + dy; + + if (tag.x + tag.x0 < 0 || tag.y + tag.y0 < 0 || + tag.x + tag.x1 > size[0] || tag.y + tag.y1 > size[1]) continue; + // TODO only check for collisions within current bounds. + if (!bounds || !cloudCollide(tag, board, size[0])) { + if (!bounds || collideRects(tag, bounds)) { + var sprite = tag.sprite, + w = tag.width >> 5, + sw = size[0] >> 5, + lx = tag.x - (w << 4), + sx = lx & 0x7f, + msx = 32 - sx, + h = tag.y1 - tag.y0, + x = (tag.y + tag.y0) * sw + (lx >> 5), + last; + for (var j = 0; j < h; j++) { + last = 0; + for (var i = 0; i <= w; i++) { + board[x + i] |= (last << msx) | (i < w ? (last = sprite[j * w + i]) >>> sx : 0); + } + x += sw; + } + delete tag.sprite; + return true; + } + } + } + return false; + } + + cloud.timeInterval = function(_) { + return arguments.length ? (timeInterval = _ == null ? Infinity : _, cloud) : timeInterval; + }; + + cloud.words = function(_) { + return arguments.length ? (words = _, cloud) : words; + }; + + cloud.size = function(_) { + return arguments.length ? (size = [+_[0], +_[1]], cloud) : size; + }; + + cloud.font = function(_) { + return arguments.length ? (font = functor(_), cloud) : font; + }; + + cloud.fontStyle = function(_) { + return arguments.length ? (fontStyle = functor(_), cloud) : fontStyle; + }; + + cloud.fontWeight = function(_) { + return arguments.length ? (fontWeight = functor(_), cloud) : fontWeight; + }; + + cloud.rotate = function(_) { + return arguments.length ? (rotate = functor(_), cloud) : rotate; + }; + + cloud.text = function(_) { + return arguments.length ? (text = functor(_), cloud) : text; + }; + + cloud.spiral = function(_) { + return arguments.length ? (spiral = spirals[_] || _, cloud) : spiral; + }; + + cloud.fontSize = function(_) { + return arguments.length ? (fontSize = functor(_), cloud) : fontSize; + }; + + cloud.padding = function(_) { + return arguments.length ? (padding = functor(_), cloud) : padding; + }; + + cloud.random = function(_) { + return arguments.length ? (random = _, cloud) : random; + }; + + cloud.on = function() { + var value = event.on.apply(event, arguments); + return value === event ? cloud : value; + }; + + return cloud; + }; + + function cloudText(d) { + return d.text; + } + + function cloudFont() { + return "serif"; + } + + function cloudFontNormal() { + return "normal"; + } + + function cloudFontSize(d) { + return Math.sqrt(d.value); + } + + function cloudRotate() { + return (~~(Math.random() * 6) - 3) * 30; + } + + function cloudPadding() { + return 1; + } + +// Fetches a monochrome sprite bitmap for the specified text. +// Load in batches for speed. + function cloudSprite(contextAndRatio, d, data, di) { + if (d.sprite) return; + var c = contextAndRatio.context, + ratio = contextAndRatio.ratio; + + c.clearRect(0, 0, (cw << 5) / ratio, ch / ratio); + var x = 0, + y = 0, + maxh = 0, + n = data.length; + --di; + while (++di < n) { + d = data[di]; + c.save(); + c.font = d.style + " " + d.weight + " " + ~~((d.size + 1) / ratio) + "px " + d.font; + var w = c.measureText(d.text + "m").width * ratio, + h = d.size << 1; + if (d.rotate) { + var sr = Math.sin(d.rotate * cloudRadians), + cr = Math.cos(d.rotate * cloudRadians), + wcr = w * cr, + wsr = w * sr, + hcr = h * cr, + hsr = h * sr; + w = (Math.max(Math.abs(wcr + hsr), Math.abs(wcr - hsr)) + 0x1f) >> 5 << 5; + h = ~~Math.max(Math.abs(wsr + hcr), Math.abs(wsr - hcr)); + } else { + w = (w + 0x1f) >> 5 << 5; + } + if (h > maxh) maxh = h; + if (x + w >= (cw << 5)) { + x = 0; + y += maxh; + maxh = 0; + } + if (y + h >= ch) break; + c.translate((x + (w >> 1)) / ratio, (y + (h >> 1)) / ratio); + if (d.rotate) c.rotate(d.rotate * cloudRadians); + c.fillText(d.text, 0, 0); + if (d.padding) c.lineWidth = 2 * d.padding, c.strokeText(d.text, 0, 0); + c.restore(); + d.width = w; + d.height = h; + d.xoff = x; + d.yoff = y; + d.x1 = w >> 1; + d.y1 = h >> 1; + d.x0 = -d.x1; + d.y0 = -d.y1; + d.hasText = true; + x += w; + } + var pixels = c.getImageData(0, 0, (cw << 5) / ratio, ch / ratio).data, + sprite = []; + while (--di >= 0) { + d = data[di]; + if (!d.hasText) continue; + var w = d.width, + w32 = w >> 5, + h = d.y1 - d.y0; + // Zero the buffer + for (var i = 0; i < h * w32; i++) sprite[i] = 0; + x = d.xoff; + if (x == null) return; + y = d.yoff; + var seen = 0, + seenRow = -1; + for (var j = 0; j < h; j++) { + for (var i = 0; i < w; i++) { + var k = w32 * j + (i >> 5), + m = pixels[((y + j) * (cw << 5) + (x + i)) << 2] ? 1 << (31 - (i % 32)) : 0; + sprite[k] |= m; + seen |= m; + } + if (seen) seenRow = j; + else { + d.y0++; + h--; + j--; + y++; + } + } + d.y1 = d.y0 + seenRow; + d.sprite = sprite.slice(0, (d.y1 - d.y0) * w32); + } + } + +// Use mask-based collision detection. + function cloudCollide(tag, board, sw) { + sw >>= 5; + var sprite = tag.sprite, + w = tag.width >> 5, + lx = tag.x - (w << 4), + sx = lx & 0x7f, + msx = 32 - sx, + h = tag.y1 - tag.y0, + x = (tag.y + tag.y0) * sw + (lx >> 5), + last; + for (var j = 0; j < h; j++) { + last = 0; + for (var i = 0; i <= w; i++) { + if (((last << msx) | (i < w ? (last = sprite[j * w + i]) >>> sx : 0)) + & board[x + i]) return true; + } + x += sw; + } + return false; + } + + function cloudBounds(bounds, d) { + var b0 = bounds[0], + b1 = bounds[1]; + if (d.x + d.x0 < b0.x) b0.x = d.x + d.x0; + if (d.y + d.y0 < b0.y) b0.y = d.y + d.y0; + if (d.x + d.x1 > b1.x) b1.x = d.x + d.x1; + if (d.y + d.y1 > b1.y) b1.y = d.y + d.y1; + } + + function collideRects(a, b) { + return a.x + a.x1 > b[0].x && a.x + a.x0 < b[1].x && a.y + a.y1 > b[0].y && a.y + a.y0 < b[1].y; + } + + function archimedeanSpiral(size) { + var e = size[0] / size[1]; + return function(t) { + return [e * (t *= .1) * Math.cos(t), t * Math.sin(t)]; + }; + } + + function rectangularSpiral(size) { + var dy = 4, + dx = dy * size[0] / size[1], + x = 0, + y = 0; + return function(t) { + var sign = t < 0 ? -1 : 1; + // See triangular numbers: T_n = n * (n + 1) / 2. + switch ((Math.sqrt(1 + 4 * sign * t) - sign) & 3) { + case 0: x += dx; break; + case 1: y += dy; break; + case 2: x -= dx; break; + default: y -= dy; break; + } + return [x, y]; + }; + } + +// TODO reuse arrays? + function zeroArray(n) { + var a = [], + i = -1; + while (++i < n) a[i] = 0; + return a; + } + + function cloudCanvas() { + return document.createElement("canvas"); + } + + function functor(d) { + return typeof d === "function" ? d : function() { return d; }; + } + + var spirals = { + archimedean: archimedeanSpiral, + rectangular: rectangularSpiral + }; + +},{"d3-dispatch":4}],4:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define('d3-dispatch', ['exports'], factory) : + factory((global.d3_dispatch = {})); + }(this, function (exports) { 'use strict'; + + function dispatch() { + return new Dispatch(arguments); + } + + function Dispatch(types) { + var i = -1, + n = types.length, + callbacksByType = {}, + callbackByName = {}, + type, + that = this; + + that.on = function(type, callback) { + type = parseType(type); + + // Return the current callback, if any. + if (arguments.length < 2) { + return (callback = callbackByName[type.name]) && callback.value; + } + + // If a type was specified… + if (type.type) { + var callbacks = callbacksByType[type.type], + callback0 = callbackByName[type.name], + i; + + // Remove the current callback, if any, using copy-on-remove. + if (callback0) { + callback0.value = null; + i = callbacks.indexOf(callback0); + callbacksByType[type.type] = callbacks = callbacks.slice(0, i).concat(callbacks.slice(i + 1)); + delete callbackByName[type.name]; + } + + // Add the new callback, if any. + if (callback) { + callback = {value: callback}; + callbackByName[type.name] = callback; + callbacks.push(callback); + } + } + + // Otherwise, if a null callback was specified, remove all callbacks with the given name. + else if (callback == null) { + for (var otherType in callbacksByType) { + if (callback = callbackByName[otherType + type.name]) { + callback.value = null; + var callbacks = callbacksByType[otherType], i = callbacks.indexOf(callback); + callbacksByType[otherType] = callbacks.slice(0, i).concat(callbacks.slice(i + 1)); + delete callbackByName[callback.name]; + } + } + } + + return that; + }; + + while (++i < n) { + type = types[i] + ""; + if (!type || (type in that)) throw new Error("illegal or duplicate type: " + type); + callbacksByType[type] = []; + that[type] = applier(type); + } + + function parseType(type) { + var i = (type += "").indexOf("."), name = type; + if (i >= 0) type = type.slice(0, i); else name += "."; + if (type && !callbacksByType.hasOwnProperty(type)) throw new Error("unknown type: " + type); + return {type: type, name: name}; + } + + function applier(type) { + return function() { + var callbacks = callbacksByType[type], // Defensive reference; copy-on-remove. + callback, + callbackValue, + i = -1, + n = callbacks.length; + + while (++i < n) { + if (callbackValue = (callback = callbacks[i]).value) { + callbackValue.apply(this, arguments); + } + } + + return that; + }; + } + } + + dispatch.prototype = Dispatch.prototype; + + var version = "0.2.4"; + + exports.version = version; + exports.dispatch = dispatch; + + })); +},{}],5:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define('d3-dsv', ['exports'], factory) : + factory((global.d3_dsv = {})); + }(this, function (exports) { 'use strict'; + + function dsv(delimiter) { + return new Dsv(delimiter); + } + + function Dsv(delimiter) { + var reFormat = new RegExp("[\"" + delimiter + "\n]"), + delimiterCode = delimiter.charCodeAt(0); + + this.parse = function(text, f) { + var o; + return this.parseRows(text, function(row, i) { + if (o) return o(row, i - 1); + var a = new Function("d", "return {" + row.map(function(name, i) { + return JSON.stringify(name) + ": d[" + i + "]"; + }).join(",") + "}"); + o = f ? function(row, i) { return f(a(row), i); } : a; + }); + }; + + this.parseRows = function(text, f) { + var EOL = {}, // sentinel value for end-of-line + EOF = {}, // sentinel value for end-of-file + rows = [], // output rows + N = text.length, + I = 0, // current character index + n = 0, // the current line number + t, // the current token + eol; // is the current token followed by EOL? + + function token() { + if (I >= N) return EOF; // special case: end of file + if (eol) return eol = false, EOL; // special case: end of line + + // special case: quotes + var j = I; + if (text.charCodeAt(j) === 34) { + var i = j; + while (i++ < N) { + if (text.charCodeAt(i) === 34) { + if (text.charCodeAt(i + 1) !== 34) break; + ++i; + } + } + I = i + 2; + var c = text.charCodeAt(i + 1); + if (c === 13) { + eol = true; + if (text.charCodeAt(i + 2) === 10) ++I; + } else if (c === 10) { + eol = true; + } + return text.slice(j + 1, i).replace(/""/g, "\""); + } + + // common case: find next delimiter or newline + while (I < N) { + var c = text.charCodeAt(I++), k = 1; + if (c === 10) eol = true; // \n + else if (c === 13) { eol = true; if (text.charCodeAt(I) === 10) ++I, ++k; } // \r|\r\n + else if (c !== delimiterCode) continue; + return text.slice(j, I - k); + } + + // special case: last token before EOF + return text.slice(j); + } + + while ((t = token()) !== EOF) { + var a = []; + while (t !== EOL && t !== EOF) { + a.push(t); + t = token(); + } + if (f && (a = f(a, n++)) == null) continue; + rows.push(a); + } + + return rows; + } + + this.format = function(rows) { + if (Array.isArray(rows[0])) return this.formatRows(rows); // deprecated; use formatRows + var fieldSet = Object.create(null), fields = []; + + // Compute unique fields in order of discovery. + rows.forEach(function(row) { + for (var field in row) { + if (!((field += "") in fieldSet)) { + fields.push(fieldSet[field] = field); + } + } + }); + + return [fields.map(formatValue).join(delimiter)].concat(rows.map(function(row) { + return fields.map(function(field) { + return formatValue(row[field]); + }).join(delimiter); + })).join("\n"); + }; + + this.formatRows = function(rows) { + return rows.map(formatRow).join("\n"); + }; + + function formatRow(row) { + return row.map(formatValue).join(delimiter); + } + + function formatValue(text) { + return reFormat.test(text) ? "\"" + text.replace(/\"/g, "\"\"") + "\"" : text; + } + }; + + dsv.prototype = Dsv.prototype; + + var csv = dsv(","); + var tsv = dsv("\t"); + + var version = "0.1.9"; + + exports.version = version; + exports.dsv = dsv; + exports.csv = csv; + exports.tsv = tsv; + + })); +},{}],6:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define('d3-format', ['exports'], factory) : + factory((global.d3_format = {})); + }(this, function (exports) { 'use strict'; + + var zhCn = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["¥", ""] + }; + + var svSe = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "SEK"] + }; + + var ruRu = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "\xa0руб."] + }; + + var ptBr = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["R$", ""] + }; + + var plPl = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "zł"] + }; + + var nlNl = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["€\xa0", ""] + }; + + var mkMk = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0ден."] + }; + + var koKr = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["₩", ""] + }; + + var jaJp = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["", "円"] + }; + + var itIt = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["€", ""] + }; + + var huHu = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "\xa0Ft"] + }; + + var heIl = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["₪", ""] + }; + + var frFr = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0€"] + }; + + var frCa = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "$"] + }; + + var fiFi = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "\xa0€"] + }; + + var esEs = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0€"] + }; + + var enUs = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["$", ""] + }; + + var enGb = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["£", ""] + }; + + var enCa = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["$", ""] + }; + + var deDe = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0€"] + }; + + var deCh = { + decimal: ",", + thousands: "'", + grouping: [3], + currency: ["", "\xa0CHF"] + }; + + var caEs = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0€"] + }; + + // Computes the decimal coefficient and exponent of the specified number x with + // significant digits p, where x is positive and p is in [1, 21] or undefined. + // For example, formatDecimal(1.23) returns ["123", 0]. + function formatDecimal(x, p) { + if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity + var i, coefficient = x.slice(0, i); + + // The string returned by toExponential either has the form \d\.\d+e[-+]\d+ + // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3). + return [ + coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient, + +x.slice(i + 1) + ]; + }; + + function exponent(x) { + return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN; + }; + + function formatGroup(grouping, thousands) { + return function(value, width) { + var i = value.length, + t = [], + j = 0, + g = grouping[0], + length = 0; + + while (i > 0 && g > 0) { + if (length + g + 1 > width) g = Math.max(1, width - length); + t.push(value.substring(i -= g, i + g)); + if ((length += g + 1) > width) break; + g = grouping[j = (j + 1) % grouping.length]; + } + + return t.reverse().join(thousands); + }; + }; + + var prefixExponent; + + function formatPrefixAuto(x, p) { + var d = formatDecimal(x, p); + if (!d) return x + ""; + var coefficient = d[0], + exponent = d[1], + i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1, + n = coefficient.length; + return i === n ? coefficient + : i > n ? coefficient + new Array(i - n + 1).join("0") + : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i) + : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y! + }; + + function formatRounded(x, p) { + var d = formatDecimal(x, p); + if (!d) return x + ""; + var coefficient = d[0], + exponent = d[1]; + return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient + : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) + : coefficient + new Array(exponent - coefficient.length + 2).join("0"); + }; + + function formatDefault(x, p) { + x = x.toPrecision(p); + + out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) { + switch (x[i]) { + case ".": i0 = i1 = i; break; + case "0": if (i0 === 0) i0 = i; i1 = i; break; + case "e": break out; + default: if (i0 > 0) i0 = 0; break; + } + } + + return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x; + }; + + var formatTypes = { + "": formatDefault, + "%": function(x, p) { return (x * 100).toFixed(p); }, + "b": function(x) { return Math.round(x).toString(2); }, + "c": function(x) { return x + ""; }, + "d": function(x) { return Math.round(x).toString(10); }, + "e": function(x, p) { return x.toExponential(p); }, + "f": function(x, p) { return x.toFixed(p); }, + "g": function(x, p) { return x.toPrecision(p); }, + "o": function(x) { return Math.round(x).toString(8); }, + "p": function(x, p) { return formatRounded(x * 100, p); }, + "r": formatRounded, + "s": formatPrefixAuto, + "X": function(x) { return Math.round(x).toString(16).toUpperCase(); }, + "x": function(x) { return Math.round(x).toString(16); } + }; + + // [[fill]align][sign][symbol][0][width][,][.precision][type] + var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i; + + function formatSpecifier(specifier) { + return new FormatSpecifier(specifier); + }; + + function FormatSpecifier(specifier) { + if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier); + + var match, + fill = match[1] || " ", + align = match[2] || ">", + sign = match[3] || "-", + symbol = match[4] || "", + zero = !!match[5], + width = match[6] && +match[6], + comma = !!match[7], + precision = match[8] && +match[8].slice(1), + type = match[9] || ""; + + // The "n" type is an alias for ",g". + if (type === "n") comma = true, type = "g"; + + // Map invalid types to the default format. + else if (!formatTypes[type]) type = ""; + + // If zero fill is specified, padding goes after sign and before digits. + if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "="; + + this.fill = fill; + this.align = align; + this.sign = sign; + this.symbol = symbol; + this.zero = zero; + this.width = width; + this.comma = comma; + this.precision = precision; + this.type = type; + } + + FormatSpecifier.prototype.toString = function() { + return this.fill + + this.align + + this.sign + + this.symbol + + (this.zero ? "0" : "") + + (this.width == null ? "" : Math.max(1, this.width | 0)) + + (this.comma ? "," : "") + + (this.precision == null ? "" : "." + Math.max(0, this.precision | 0)) + + this.type; + }; + + var prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"]; + + function identity(x) { + return x; + } + + function locale(locale) { + var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity, + currency = locale.currency, + decimal = locale.decimal; + + function format(specifier) { + specifier = formatSpecifier(specifier); + + var fill = specifier.fill, + align = specifier.align, + sign = specifier.sign, + symbol = specifier.symbol, + zero = specifier.zero, + width = specifier.width, + comma = specifier.comma, + precision = specifier.precision, + type = specifier.type; + + // Compute the prefix and suffix. + // For SI-prefix, the suffix is lazily computed. + var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "", + suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? "%" : ""; + + // What format function should we use? + // Is this an integer type? + // Can this type generate exponential notation? + var formatType = formatTypes[type], + maybeSuffix = !type || /[defgprs%]/.test(type); + + // Set the default precision if not specified, + // or clamp the specified precision to the supported range. + // For significant precision, it must be in [1, 21]. + // For fixed precision, it must be in [0, 20]. + precision = precision == null ? (type ? 6 : 12) + : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision)) + : Math.max(0, Math.min(20, precision)); + + return function(value) { + var valuePrefix = prefix, + valueSuffix = suffix; + + if (type === "c") { + valueSuffix = formatType(value) + valueSuffix; + value = ""; + } else { + value = +value; + + // Convert negative to positive, and compute the prefix. + // Note that -0 is not less than 0, but 1 / -0 is! + var valueNegative = (value < 0 || 1 / value < 0) && (value *= -1, true); + + // Perform the initial formatting. + value = formatType(value, precision); + + // If the original value was negative, it may be rounded to zero during + // formatting; treat this as (positive) zero. + if (valueNegative) { + var i = -1, n = value.length, c; + valueNegative = false; + while (++i < n) { + if (c = value.charCodeAt(i), (48 < c && c < 58) + || (type === "x" && 96 < c && c < 103) + || (type === "X" && 64 < c && c < 71)) { + valueNegative = true; + break; + } + } + } + + // Compute the prefix and suffix. + valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix; + valueSuffix = valueSuffix + (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + (valueNegative && sign === "(" ? ")" : ""); + + // Break the formatted value into the integer “value” part that can be + // grouped, and fractional or exponential “suffix” part that is not. + if (maybeSuffix) { + var i = -1, n = value.length, c; + while (++i < n) { + if (c = value.charCodeAt(i), 48 > c || c > 57) { + valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix; + value = value.slice(0, i); + break; + } + } + } + } + + // If the fill character is not "0", grouping is applied before padding. + if (comma && !zero) value = group(value, Infinity); + + // Compute the padding. + var length = valuePrefix.length + value.length + valueSuffix.length, + padding = length < width ? new Array(width - length + 1).join(fill) : ""; + + // If the fill character is "0", grouping is applied after padding. + if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = ""; + + // Reconstruct the final output based on the desired alignment. + switch (align) { + case "<": return valuePrefix + value + valueSuffix + padding; + case "=": return valuePrefix + padding + value + valueSuffix; + case "^": return padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); + } + return padding + valuePrefix + value + valueSuffix; + }; + } + + function formatPrefix(specifier, value) { + var f = format((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)), + e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3, + k = Math.pow(10, -e), + prefix = prefixes[8 + e / 3]; + return function(value) { + return f(k * value) + prefix; + }; + } + + return { + format: format, + formatPrefix: formatPrefix + }; + }; + + function precisionFixed(step) { + return Math.max(0, -exponent(Math.abs(step))); + }; + + function precisionPrefix(step, value) { + return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step))); + }; + + function precisionRound(step, max) { + return Math.max(0, exponent(Math.abs(max)) - exponent(Math.abs(step))) + 1; + }; + + var localeDefinitions = { + "ca-ES": caEs, + "de-CH": deCh, + "de-DE": deDe, + "en-CA": enCa, + "en-GB": enGb, + "en-US": enUs, + "es-ES": esEs, + "fi-FI": fiFi, + "fr-CA": frCa, + "fr-FR": frFr, + "he-IL": heIl, + "hu-HU": huHu, + "it-IT": itIt, + "ja-JP": jaJp, + "ko-KR": koKr, + "mk-MK": mkMk, + "nl-NL": nlNl, + "pl-PL": plPl, + "pt-BR": ptBr, + "ru-RU": ruRu, + "sv-SE": svSe, + "zh-CN": zhCn + }; + + var defaultLocale = locale(enUs); + var format = defaultLocale.format; + var formatPrefix = defaultLocale.formatPrefix; + + function localeFormat(definition) { + if (typeof definition === "string") { + if (!localeDefinitions.hasOwnProperty(definition)) return null; + definition = localeDefinitions[definition]; + } + return locale(definition); + }; + + var version = "0.3.6"; + + exports.version = version; + exports.format = format; + exports.formatPrefix = formatPrefix; + exports.localeFormat = localeFormat; + exports.formatSpecifier = formatSpecifier; + exports.precisionFixed = precisionFixed; + exports.precisionPrefix = precisionPrefix; + exports.precisionRound = precisionRound; + + })); +},{}],7:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-time')) : + typeof define === 'function' && define.amd ? define('d3-time-format', ['exports', 'd3-time'], factory) : + factory((global.d3_time_format = {}),global.d3_time); + }(this, function (exports,d3Time) { 'use strict'; + + var zhCn = { + dateTime: "%a %b %e %X %Y", + date: "%Y/%-m/%-d", + time: "%H:%M:%S", + periods: ["上午", "下午"], + days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"], + shortDays: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"], + months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], + shortMonths: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"] + }; + + var svSe = { + dateTime: "%A den %d %B %Y %X", + date: "%Y-%m-%d", + time: "%H:%M:%S", + periods: ["fm", "em"], + days: ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"], + shortDays: ["Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"], + months: ["Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"], + shortMonths: ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"] + }; + + var ruRu = { + dateTime: "%A, %e %B %Y г. %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["воскресенье", "понедельник", "вторник", "среда", "четверг", "пятница", "суббота"], + shortDays: ["вс", "пн", "вт", "ср", "чт", "пт", "сб"], + months: ["января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"], + shortMonths: ["янв", "фев", "мар", "апр", "май", "июн", "июл", "авг", "сен", "окт", "ноя", "дек"] + }; + + var ptBr = { + dateTime: "%A, %e de %B de %Y. %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"], + shortDays: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"], + months: ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"], + shortMonths: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"] + }; + + var plPl = { + dateTime: "%A, %e %B %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota"], + shortDays: ["Niedz.", "Pon.", "Wt.", "Śr.", "Czw.", "Pt.", "Sob."], + months: ["Styczeń", "Luty", "Marzec", "Kwiecień", "Maj", "Czerwiec", "Lipiec", "Sierpień", "Wrzesień", "Październik", "Listopad", "Grudzień"], + shortMonths: ["Stycz.", "Luty", "Marz.", "Kwie.", "Maj", "Czerw.", "Lipc.", "Sierp.", "Wrz.", "Paźdz.", "Listop.", "Grudz."]/* In Polish language abbraviated months are not commonly used so there is a dispute about the proper abbraviations. */ + }; + + var nlNl = { + dateTime: "%a %e %B %Y %T", + date: "%d-%m-%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"], + shortDays: ["zo", "ma", "di", "wo", "do", "vr", "za"], + months: ["januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"], + shortMonths: ["jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec"] + }; + + var mkMk = { + dateTime: "%A, %e %B %Y г. %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["недела", "понеделник", "вторник", "среда", "четврток", "петок", "сабота"], + shortDays: ["нед", "пон", "вто", "сре", "чет", "пет", "саб"], + months: ["јануари", "февруари", "март", "април", "мај", "јуни", "јули", "август", "септември", "октомври", "ноември", "декември"], + shortMonths: ["јан", "фев", "мар", "апр", "мај", "јун", "јул", "авг", "сеп", "окт", "ное", "дек"] + }; + + var koKr = { + dateTime: "%Y/%m/%d %a %X", + date: "%Y/%m/%d", + time: "%H:%M:%S", + periods: ["오전", "오후"], + days: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"], + shortDays: ["일", "월", "화", "수", "목", "금", "토"], + months: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"], + shortMonths: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"] + }; + + var jaJp = { + dateTime: "%Y %b %e %a %X", + date: "%Y/%m/%d", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"], + shortDays: ["日", "月", "火", "水", "木", "金", "土"], + months: ["睦月", "如月", "弥生", "卯月", "皐月", "水無月", "文月", "葉月", "長月", "神無月", "霜月", "師走"], + shortMonths: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"] + }; + + var itIt = { + dateTime: "%A %e %B %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"], + shortDays: ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"], + months: ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"], + shortMonths: ["Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"] + }; + + var huHu = { + dateTime: "%Y. %B %-e., %A %X", + date: "%Y. %m. %d.", + time: "%H:%M:%S", + periods: ["de.", "du."], // unused + days: ["vasárnap", "hétfő", "kedd", "szerda", "csütörtök", "péntek", "szombat"], + shortDays: ["V", "H", "K", "Sze", "Cs", "P", "Szo"], + months: ["január", "február", "március", "április", "május", "június", "július", "augusztus", "szeptember", "október", "november", "december"], + shortMonths: ["jan.", "feb.", "már.", "ápr.", "máj.", "jún.", "júl.", "aug.", "szept.", "okt.", "nov.", "dec."] + }; + + var heIl = { + dateTime: "%A, %e ב%B %Y %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["ראשון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת"], + shortDays: ["א׳", "ב׳", "ג׳", "ד׳", "ה׳", "ו׳", "ש׳"], + months: ["ינואר", "פברואר", "מרץ", "אפריל", "מאי", "יוני", "יולי", "אוגוסט", "ספטמבר", "אוקטובר", "נובמבר", "דצמבר"], + shortMonths: ["ינו׳", "פבר׳", "מרץ", "אפר׳", "מאי", "יוני", "יולי", "אוג׳", "ספט׳", "אוק׳", "נוב׳", "דצמ׳"] + }; + + var frFr = { + dateTime: "%A, le %e %B %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"], + shortDays: ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."], + months: ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"], + shortMonths: ["janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc."] + }; + + var frCa = { + dateTime: "%a %e %b %Y %X", + date: "%Y-%m-%d", + time: "%H:%M:%S", + periods: ["", ""], + days: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"], + shortDays: ["dim", "lun", "mar", "mer", "jeu", "ven", "sam"], + months: ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"], + shortMonths: ["jan", "fév", "mar", "avr", "mai", "jui", "jul", "aoû", "sep", "oct", "nov", "déc"] + }; + + var fiFi = { + dateTime: "%A, %-d. %Bta %Y klo %X", + date: "%-d.%-m.%Y", + time: "%H:%M:%S", + periods: ["a.m.", "p.m."], + days: ["sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai"], + shortDays: ["Su", "Ma", "Ti", "Ke", "To", "Pe", "La"], + months: ["tammikuu", "helmikuu", "maaliskuu", "huhtikuu", "toukokuu", "kesäkuu", "heinäkuu", "elokuu", "syyskuu", "lokakuu", "marraskuu", "joulukuu"], + shortMonths: ["Tammi", "Helmi", "Maalis", "Huhti", "Touko", "Kesä", "Heinä", "Elo", "Syys", "Loka", "Marras", "Joulu"] + }; + + var esEs = { + dateTime: "%A, %e de %B de %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado"], + shortDays: ["dom", "lun", "mar", "mié", "jue", "vie", "sáb"], + months: ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"], + shortMonths: ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"] + }; + + var locale$1 = { + 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"] + }; + + var enGb = { + dateTime: "%a %e %b %X %Y", + date: "%d/%m/%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"] + }; + + var enCa = { + dateTime: "%a %b %e %X %Y", + date: "%Y-%m-%d", + 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"] + }; + + var deDe = { + dateTime: "%A, der %e. %B %Y, %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"], + shortDays: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"], + months: ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"], + shortMonths: ["Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"] + }; + + var deCh = { + dateTime: "%A, der %e. %B %Y, %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"], + shortDays: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"], + months: ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"], + shortMonths: ["Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"] + }; + + var caEs = { + dateTime: "%A, %e de %B de %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["diumenge", "dilluns", "dimarts", "dimecres", "dijous", "divendres", "dissabte"], + shortDays: ["dg.", "dl.", "dt.", "dc.", "dj.", "dv.", "ds."], + months: ["gener", "febrer", "març", "abril", "maig", "juny", "juliol", "agost", "setembre", "octubre", "novembre", "desembre"], + shortMonths: ["gen.", "febr.", "març", "abr.", "maig", "juny", "jul.", "ag.", "set.", "oct.", "nov.", "des."] + }; + + function localDate(d) { + if (0 <= d.y && d.y < 100) { + var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L); + date.setFullYear(d.y); + return date; + } + return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L); + } + + function utcDate(d) { + if (0 <= d.y && d.y < 100) { + var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L)); + date.setUTCFullYear(d.y); + return date; + } + return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L)); + } + + function newYear(y) { + return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0}; + } + + function locale(locale) { + var locale_dateTime = locale.dateTime, + locale_date = locale.date, + locale_time = locale.time, + locale_periods = locale.periods, + locale_weekdays = locale.days, + locale_shortWeekdays = locale.shortDays, + locale_months = locale.months, + locale_shortMonths = locale.shortMonths; + + var periodLookup = formatLookup(locale_periods), + weekdayRe = formatRe(locale_weekdays), + weekdayLookup = formatLookup(locale_weekdays), + shortWeekdayRe = formatRe(locale_shortWeekdays), + shortWeekdayLookup = formatLookup(locale_shortWeekdays), + monthRe = formatRe(locale_months), + monthLookup = formatLookup(locale_months), + shortMonthRe = formatRe(locale_shortMonths), + shortMonthLookup = formatLookup(locale_shortMonths); + + var formats = { + "a": formatShortWeekday, + "A": formatWeekday, + "b": formatShortMonth, + "B": formatMonth, + "c": null, + "d": formatDayOfMonth, + "e": formatDayOfMonth, + "H": formatHour24, + "I": formatHour12, + "j": formatDayOfYear, + "L": formatMilliseconds, + "m": formatMonthNumber, + "M": formatMinutes, + "p": formatPeriod, + "S": formatSeconds, + "U": formatWeekNumberSunday, + "w": formatWeekdayNumber, + "W": formatWeekNumberMonday, + "x": null, + "X": null, + "y": formatYear, + "Y": formatFullYear, + "Z": formatZone, + "%": formatLiteralPercent + }; + + var utcFormats = { + "a": formatUTCShortWeekday, + "A": formatUTCWeekday, + "b": formatUTCShortMonth, + "B": formatUTCMonth, + "c": null, + "d": formatUTCDayOfMonth, + "e": formatUTCDayOfMonth, + "H": formatUTCHour24, + "I": formatUTCHour12, + "j": formatUTCDayOfYear, + "L": formatUTCMilliseconds, + "m": formatUTCMonthNumber, + "M": formatUTCMinutes, + "p": formatUTCPeriod, + "S": formatUTCSeconds, + "U": formatUTCWeekNumberSunday, + "w": formatUTCWeekdayNumber, + "W": formatUTCWeekNumberMonday, + "x": null, + "X": null, + "y": formatUTCYear, + "Y": formatUTCFullYear, + "Z": formatUTCZone, + "%": formatLiteralPercent + }; + + var parses = { + "a": parseShortWeekday, + "A": parseWeekday, + "b": parseShortMonth, + "B": parseMonth, + "c": parseLocaleDateTime, + "d": parseDayOfMonth, + "e": parseDayOfMonth, + "H": parseHour24, + "I": parseHour24, + "j": parseDayOfYear, + "L": parseMilliseconds, + "m": parseMonthNumber, + "M": parseMinutes, + "p": parsePeriod, + "S": parseSeconds, + "U": parseWeekNumberSunday, + "w": parseWeekdayNumber, + "W": parseWeekNumberMonday, + "x": parseLocaleDate, + "X": parseLocaleTime, + "y": parseYear, + "Y": parseFullYear, + "Z": parseZone, + "%": parseLiteralPercent + }; + + // These recursive directive definitions must be deferred. + formats.x = newFormat(locale_date, formats); + formats.X = newFormat(locale_time, formats); + formats.c = newFormat(locale_dateTime, formats); + utcFormats.x = newFormat(locale_date, utcFormats); + utcFormats.X = newFormat(locale_time, utcFormats); + utcFormats.c = newFormat(locale_dateTime, utcFormats); + + function newFormat(specifier, formats) { + return function(date) { + var string = [], + i = -1, + j = 0, + n = specifier.length, + c, + pad, + format; + + while (++i < n) { + if (specifier.charCodeAt(i) === 37) { + string.push(specifier.slice(j, i)); + if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i); + if (format = formats[c]) c = format(date, pad == null ? (c === "e" ? " " : "0") : pad); + string.push(c); + j = i + 1; + } + } + + string.push(specifier.slice(j, i)); + return string.join(""); + }; + } + + function newParse(specifier, newDate) { + return function(string) { + var d = newYear(1900), + i = parseSpecifier(d, specifier, string, 0); + if (i != string.length) return null; + + // The am-pm flag is 0 for AM, and 1 for PM. + if ("p" in d) d.H = d.H % 12 + d.p * 12; + + // If a time zone is specified, all fields are interpreted as UTC and then + // offset according to the specified time zone. + if ("Z" in d) { + if ("w" in d && ("W" in d || "U" in d)) { + var day = utcDate(newYear(d.y)).getUTCDay(); + if ("W" in d) d.U = d.W, d.w = (d.w + 6) % 7, --day; + d.m = 0; + d.d = d.w + d.U * 7 - (day + 6) % 7; + } + d.H += d.Z / 100 | 0; + d.M += d.Z % 100; + return utcDate(d); + } + + // Otherwise, all fields are in local time. + if ("w" in d && ("W" in d || "U" in d)) { + var day = newDate(newYear(d.y)).getDay(); + if ("W" in d) d.U = d.W, d.w = (d.w + 6) % 7, --day; + d.m = 0; + d.d = d.w + d.U * 7 - (day + 6) % 7; + } + return newDate(d); + }; + } + + function parseSpecifier(d, specifier, string, j) { + var i = 0, + n = specifier.length, + m = string.length, + c, + parse; + + while (i < n) { + if (j >= m) return -1; + c = specifier.charCodeAt(i++); + if (c === 37) { + c = specifier.charAt(i++); + parse = parses[c in pads ? specifier.charAt(i++) : c]; + if (!parse || ((j = parse(d, string, j)) < 0)) return -1; + } else if (c != string.charCodeAt(j++)) { + return -1; + } + } + + return j; + } + + function parseShortWeekday(d, string, i) { + var n = shortWeekdayRe.exec(string.slice(i)); + return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseWeekday(d, string, i) { + var n = weekdayRe.exec(string.slice(i)); + return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseShortMonth(d, string, i) { + var n = shortMonthRe.exec(string.slice(i)); + return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseMonth(d, string, i) { + var n = monthRe.exec(string.slice(i)); + return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseLocaleDateTime(d, string, i) { + return parseSpecifier(d, locale_dateTime, string, i); + } + + function parseLocaleDate(d, string, i) { + return parseSpecifier(d, locale_date, string, i); + } + + function parseLocaleTime(d, string, i) { + return parseSpecifier(d, locale_time, string, i); + } + + function parsePeriod(d, string, i) { + var n = periodLookup[string.slice(i, i += 2).toLowerCase()]; + return n == null ? -1 : (d.p = n, i); + } + + function formatShortWeekday(d) { + return locale_shortWeekdays[d.getDay()]; + } + + function formatWeekday(d) { + return locale_weekdays[d.getDay()]; + } + + function formatShortMonth(d) { + return locale_shortMonths[d.getMonth()]; + } + + function formatMonth(d) { + return locale_months[d.getMonth()]; + } + + function formatPeriod(d) { + return locale_periods[+(d.getHours() >= 12)]; + } + + function formatUTCShortWeekday(d) { + return locale_shortWeekdays[d.getUTCDay()]; + } + + function formatUTCWeekday(d) { + return locale_weekdays[d.getUTCDay()]; + } + + function formatUTCShortMonth(d) { + return locale_shortMonths[d.getUTCMonth()]; + } + + function formatUTCMonth(d) { + return locale_months[d.getUTCMonth()]; + } + + function formatUTCPeriod(d) { + return locale_periods[+(d.getUTCHours() >= 12)]; + } + + return { + format: function(specifier) { + var f = newFormat(specifier += "", formats); + f.parse = newParse(specifier, localDate); + f.toString = function() { return specifier; }; + return f; + }, + utcFormat: function(specifier) { + var f = newFormat(specifier += "", utcFormats); + f.parse = newParse(specifier, utcDate); + f.toString = function() { return specifier; }; + return f; + } + }; + }; + + var pads = {"-": "", "_": " ", "0": "0"}; + var numberRe = /^\s*\d+/; + var percentRe = /^%/; + var requoteRe = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; + function pad(value, fill, width) { + var sign = value < 0 ? "-" : "", + string = (sign ? -value : value) + "", + length = string.length; + return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); + } + + function requote(s) { + return s.replace(requoteRe, "\\$&"); + } + + function formatRe(names) { + return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i"); + } + + function formatLookup(names) { + var map = {}, i = -1, n = names.length; + while (++i < n) map[names[i].toLowerCase()] = i; + return map; + } + + function parseWeekdayNumber(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 1)); + return n ? (d.w = +n[0], i + n[0].length) : -1; + } + + function parseWeekNumberSunday(d, string, i) { + var n = numberRe.exec(string.slice(i)); + return n ? (d.U = +n[0], i + n[0].length) : -1; + } + + function parseWeekNumberMonday(d, string, i) { + var n = numberRe.exec(string.slice(i)); + return n ? (d.W = +n[0], i + n[0].length) : -1; + } + + function parseFullYear(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 4)); + return n ? (d.y = +n[0], i + n[0].length) : -1; + } + + function parseYear(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1; + } + + function parseZone(d, string, i) { + var n = /^(Z)|([+-]\d\d)(?:\:?(\d\d))?/.exec(string.slice(i, i + 6)); + if (n) { + d.Z = n[1] ? 0 // 'Z' for UTC + : n[3] ? -(n[2] + n[3]) // sign differs from getTimezoneOffset! + : -n[2] * 100; + return i + n[0].length; + } + return -1; + } + + function parseMonthNumber(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.m = n[0] - 1, i + n[0].length) : -1; + } + + function parseDayOfMonth(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.d = +n[0], i + n[0].length) : -1; + } + + function parseDayOfYear(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 3)); + return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1; + } + + function parseHour24(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.H = +n[0], i + n[0].length) : -1; + } + + function parseMinutes(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.M = +n[0], i + n[0].length) : -1; + } + + function parseSeconds(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.S = +n[0], i + n[0].length) : -1; + } + + function parseMilliseconds(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 3)); + return n ? (d.L = +n[0], i + n[0].length) : -1; + } + + function parseLiteralPercent(d, string, i) { + var n = percentRe.exec(string.slice(i, i + 1)); + return n ? i + n[0].length : -1; + } + + function formatDayOfMonth(d, p) { + return pad(d.getDate(), p, 2); + } + + function formatHour24(d, p) { + return pad(d.getHours(), p, 2); + } + + function formatHour12(d, p) { + return pad(d.getHours() % 12 || 12, p, 2); + } + + function formatDayOfYear(d, p) { + return pad(1 + d3Time.day.count(d3Time.year(d), d), p, 3); + } + + function formatMilliseconds(d, p) { + return pad(d.getMilliseconds(), p, 3); + } + + function formatMonthNumber(d, p) { + return pad(d.getMonth() + 1, p, 2); + } + + function formatMinutes(d, p) { + return pad(d.getMinutes(), p, 2); + } + + function formatSeconds(d, p) { + return pad(d.getSeconds(), p, 2); + } + + function formatWeekNumberSunday(d, p) { + return pad(d3Time.sunday.count(d3Time.year(d), d), p, 2); + } + + function formatWeekdayNumber(d) { + return d.getDay(); + } + + function formatWeekNumberMonday(d, p) { + return pad(d3Time.monday.count(d3Time.year(d), d), p, 2); + } + + function formatYear(d, p) { + return pad(d.getFullYear() % 100, p, 2); + } + + function formatFullYear(d, p) { + return pad(d.getFullYear() % 10000, p, 4); + } + + function formatZone(d) { + var z = d.getTimezoneOffset(); + return (z > 0 ? "-" : (z *= -1, "+")) + + pad(z / 60 | 0, "0", 2) + + pad(z % 60, "0", 2); + } + + function formatUTCDayOfMonth(d, p) { + return pad(d.getUTCDate(), p, 2); + } + + function formatUTCHour24(d, p) { + return pad(d.getUTCHours(), p, 2); + } + + function formatUTCHour12(d, p) { + return pad(d.getUTCHours() % 12 || 12, p, 2); + } + + function formatUTCDayOfYear(d, p) { + return pad(1 + d3Time.utcDay.count(d3Time.utcYear(d), d), p, 3); + } + + function formatUTCMilliseconds(d, p) { + return pad(d.getUTCMilliseconds(), p, 3); + } + + function formatUTCMonthNumber(d, p) { + return pad(d.getUTCMonth() + 1, p, 2); + } + + function formatUTCMinutes(d, p) { + return pad(d.getUTCMinutes(), p, 2); + } + + function formatUTCSeconds(d, p) { + return pad(d.getUTCSeconds(), p, 2); + } + + function formatUTCWeekNumberSunday(d, p) { + return pad(d3Time.utcSunday.count(d3Time.utcYear(d), d), p, 2); + } + + function formatUTCWeekdayNumber(d) { + return d.getUTCDay(); + } + + function formatUTCWeekNumberMonday(d, p) { + return pad(d3Time.utcMonday.count(d3Time.utcYear(d), d), p, 2); + } + + function formatUTCYear(d, p) { + return pad(d.getUTCFullYear() % 100, p, 2); + } + + function formatUTCFullYear(d, p) { + return pad(d.getUTCFullYear() % 10000, p, 4); + } + + function formatUTCZone() { + return "+0000"; + } + + function formatLiteralPercent() { + return "%"; + } + + var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ"; + + function formatIsoNative(date) { + return date.toISOString(); + } + + formatIsoNative.parse = function(string) { + var date = new Date(string); + return isNaN(date) ? null : date; + }; + + formatIsoNative.toString = function() { + return isoSpecifier; + }; + + var formatIso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") + ? formatIsoNative + : locale$1.utcFormat(isoSpecifier); + + var localeDefinitions = { + "ca-ES": caEs, + "de-CH": deCh, + "de-DE": deDe, + "en-CA": enCa, + "en-GB": enGb, + "en-US": locale$1, + "es-ES": esEs, + "fi-FI": fiFi, + "fr-CA": frCa, + "fr-FR": frFr, + "he-IL": heIl, + "hu-HU": huHu, + "it-IT": itIt, + "ja-JP": jaJp, + "ko-KR": koKr, + "mk-MK": mkMk, + "nl-NL": nlNl, + "pl-PL": plPl, + "pt-BR": ptBr, + "ru-RU": ruRu, + "sv-SE": svSe, + "zh-CN": zhCn + }; + + var defaultLocale = locale(locale$1); + var format = defaultLocale.format; + var utcFormat = defaultLocale.utcFormat; + + function localeFormat(definition) { + if (typeof definition === "string") { + if (!localeDefinitions.hasOwnProperty(definition)) return null; + definition = localeDefinitions[definition]; + } + return locale(definition); + }; + + var version = "0.1.5"; + + exports.version = version; + exports.format = format; + exports.utcFormat = utcFormat; + exports.localeFormat = localeFormat; + exports.isoFormat = formatIso; + + })); +},{"d3-time":8}],8:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define('d3-time', ['exports'], factory) : + factory((global.d3_time = {})); + }(this, function (exports) { 'use strict'; + + var t0 = new Date; + var t1 = new Date; + function newInterval(floori, offseti, count) { + + function interval(date) { + return floori(date = new Date(+date)), date; + } + + interval.floor = interval; + + interval.round = function(date) { + var d0 = new Date(+date), + d1 = new Date(date - 1); + floori(d0), floori(d1), offseti(d1, 1); + return date - d0 < d1 - date ? d0 : d1; + }; + + interval.ceil = function(date) { + return floori(date = new Date(date - 1)), offseti(date, 1), date; + }; + + interval.offset = function(date, step) { + return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date; + }; + + interval.range = function(start, stop, step) { + var range = []; + start = new Date(start - 1); + stop = new Date(+stop); + step = step == null ? 1 : Math.floor(step); + if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date + offseti(start, 1), floori(start); + if (start < stop) range.push(new Date(+start)); + while (offseti(start, step), floori(start), start < stop) range.push(new Date(+start)); + return range; + }; + + interval.filter = function(test) { + return newInterval(function(date) { + while (floori(date), !test(date)) date.setTime(date - 1); + }, function(date, step) { + while (--step >= 0) while (offseti(date, 1), !test(date)); + }); + }; + + if (count) interval.count = function(start, end) { + t0.setTime(+start), t1.setTime(+end); + floori(t0), floori(t1); + return Math.floor(count(t0, t1)); + }; + + return interval; + }; + + var millisecond = newInterval(function() { + // noop + }, function(date, step) { + date.setTime(+date + step); + }, function(start, end) { + return end - start; + }); + + var second = newInterval(function(date) { + date.setMilliseconds(0); + }, function(date, step) { + date.setTime(+date + step * 1e3); + }, function(start, end) { + return (end - start) / 1e3; + }); + + var minute = newInterval(function(date) { + date.setSeconds(0, 0); + }, function(date, step) { + date.setTime(+date + step * 6e4); + }, function(start, end) { + return (end - start) / 6e4; + }); + + var hour = newInterval(function(date) { + date.setMinutes(0, 0, 0); + }, function(date, step) { + date.setTime(+date + step * 36e5); + }, function(start, end) { + return (end - start) / 36e5; + }); + + var day = newInterval(function(date) { + date.setHours(0, 0, 0, 0); + }, function(date, step) { + date.setDate(date.getDate() + step); + }, function(start, end) { + return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * 6e4) / 864e5; + }); + + function weekday(i) { + return newInterval(function(date) { + date.setHours(0, 0, 0, 0); + date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7); + }, function(date, step) { + date.setDate(date.getDate() + step * 7); + }, function(start, end) { + return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * 6e4) / 6048e5; + }); + } + + var sunday = weekday(0); + var monday = weekday(1); + var tuesday = weekday(2); + var wednesday = weekday(3); + var thursday = weekday(4); + var friday = weekday(5); + var saturday = weekday(6); + + var month = newInterval(function(date) { + date.setHours(0, 0, 0, 0); + date.setDate(1); + }, function(date, step) { + date.setMonth(date.getMonth() + step); + }, function(start, end) { + return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12; + }); + + var year = newInterval(function(date) { + date.setHours(0, 0, 0, 0); + date.setMonth(0, 1); + }, function(date, step) { + date.setFullYear(date.getFullYear() + step); + }, function(start, end) { + return end.getFullYear() - start.getFullYear(); + }); + + var utcSecond = newInterval(function(date) { + date.setUTCMilliseconds(0); + }, function(date, step) { + date.setTime(+date + step * 1e3); + }, function(start, end) { + return (end - start) / 1e3; + }); + + var utcMinute = newInterval(function(date) { + date.setUTCSeconds(0, 0); + }, function(date, step) { + date.setTime(+date + step * 6e4); + }, function(start, end) { + return (end - start) / 6e4; + }); + + var utcHour = newInterval(function(date) { + date.setUTCMinutes(0, 0, 0); + }, function(date, step) { + date.setTime(+date + step * 36e5); + }, function(start, end) { + return (end - start) / 36e5; + }); + + var utcDay = newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + }, function(date, step) { + date.setUTCDate(date.getUTCDate() + step); + }, function(start, end) { + return (end - start) / 864e5; + }); + + function utcWeekday(i) { + return newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7); + }, function(date, step) { + date.setUTCDate(date.getUTCDate() + step * 7); + }, function(start, end) { + return (end - start) / 6048e5; + }); + } + + var utcSunday = utcWeekday(0); + var utcMonday = utcWeekday(1); + var utcTuesday = utcWeekday(2); + var utcWednesday = utcWeekday(3); + var utcThursday = utcWeekday(4); + var utcFriday = utcWeekday(5); + var utcSaturday = utcWeekday(6); + + var utcMonth = newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + date.setUTCDate(1); + }, function(date, step) { + date.setUTCMonth(date.getUTCMonth() + step); + }, function(start, end) { + return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12; + }); + + var utcYear = newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + date.setUTCMonth(0, 1); + }, function(date, step) { + date.setUTCFullYear(date.getUTCFullYear() + step); + }, function(start, end) { + return end.getUTCFullYear() - start.getUTCFullYear(); + }); + + var milliseconds = millisecond.range; + var seconds = second.range; + var minutes = minute.range; + var hours = hour.range; + var days = day.range; + var sundays = sunday.range; + var mondays = monday.range; + var tuesdays = tuesday.range; + var wednesdays = wednesday.range; + var thursdays = thursday.range; + var fridays = friday.range; + var saturdays = saturday.range; + var weeks = sunday.range; + var months = month.range; + var years = year.range; + + var utcMillisecond = millisecond; + var utcMilliseconds = milliseconds; + var utcSeconds = utcSecond.range; + var utcMinutes = utcMinute.range; + var utcHours = utcHour.range; + var utcDays = utcDay.range; + var utcSundays = utcSunday.range; + var utcMondays = utcMonday.range; + var utcTuesdays = utcTuesday.range; + var utcWednesdays = utcWednesday.range; + var utcThursdays = utcThursday.range; + var utcFridays = utcFriday.range; + var utcSaturdays = utcSaturday.range; + var utcWeeks = utcSunday.range; + var utcMonths = utcMonth.range; + var utcYears = utcYear.range; + + var version = "0.0.7"; + + exports.version = version; + exports.milliseconds = milliseconds; + exports.seconds = seconds; + exports.minutes = minutes; + exports.hours = hours; + exports.days = days; + exports.sundays = sundays; + exports.mondays = mondays; + exports.tuesdays = tuesdays; + exports.wednesdays = wednesdays; + exports.thursdays = thursdays; + exports.fridays = fridays; + exports.saturdays = saturdays; + exports.weeks = weeks; + exports.months = months; + exports.years = years; + exports.utcMillisecond = utcMillisecond; + exports.utcMilliseconds = utcMilliseconds; + exports.utcSeconds = utcSeconds; + exports.utcMinutes = utcMinutes; + exports.utcHours = utcHours; + exports.utcDays = utcDays; + exports.utcSundays = utcSundays; + exports.utcMondays = utcMondays; + exports.utcTuesdays = utcTuesdays; + exports.utcWednesdays = utcWednesdays; + exports.utcThursdays = utcThursdays; + exports.utcFridays = utcFridays; + exports.utcSaturdays = utcSaturdays; + exports.utcWeeks = utcWeeks; + exports.utcMonths = utcMonths; + exports.utcYears = utcYears; + exports.millisecond = millisecond; + exports.second = second; + exports.minute = minute; + exports.hour = hour; + exports.day = day; + exports.sunday = sunday; + exports.monday = monday; + exports.tuesday = tuesday; + exports.wednesday = wednesday; + exports.thursday = thursday; + exports.friday = friday; + exports.saturday = saturday; + exports.week = sunday; + exports.month = month; + exports.year = year; + exports.utcSecond = utcSecond; + exports.utcMinute = utcMinute; + exports.utcHour = utcHour; + exports.utcDay = utcDay; + exports.utcSunday = utcSunday; + exports.utcMonday = utcMonday; + exports.utcTuesday = utcTuesday; + exports.utcWednesday = utcWednesday; + exports.utcThursday = utcThursday; + exports.utcFriday = utcFriday; + exports.utcSaturday = utcSaturday; + exports.utcWeek = utcSunday; + exports.utcMonth = utcMonth; + exports.utcYear = utcYear; + exports.interval = newInterval; + + })); +},{}],9:[function(require,module,exports){ + var util = require('../util'), + Measures = require('./measures'), + Collector = require('./collector'); + + function Aggregator() { + this._cells = {}; + this._aggr = []; + this._stream = false; + } + + var Flags = Aggregator.Flags = { + ADD_CELL: 1, + MOD_CELL: 2 + }; + + var proto = Aggregator.prototype; + +// Parameters + + proto.stream = function(v) { + if (v == null) return this._stream; + this._stream = !!v; + this._aggr = []; + return this; + }; + +// key accessor to use for streaming removes + proto.key = function(key) { + if (key == null) return this._key; + this._key = util.$(key); + return this; + }; + +// Input: array of objects of the form +// {name: string, get: function} + proto.groupby = function(dims) { + this._dims = util.array(dims).map(function(d, i) { + d = util.isString(d) ? {name: d, get: util.$(d)} + : util.isFunction(d) ? {name: util.name(d) || d.name || ('_' + i), get: d} + : (d.name && util.isFunction(d.get)) ? d : null; + if (d == null) throw 'Invalid groupby argument: ' + d; + return d; + }); + return this.clear(); + }; + +// Input: array of objects of the form +// {name: string, ops: [string, ...]} + proto.summarize = function(fields) { + fields = summarize_args(fields); + this._count = true; + var aggr = (this._aggr = []), + m, f, i, j, op, as, get; + + for (i=0; i 0) { + // consolidate collector values + if (cell.collect) { + cell.data.values(); + } + // update tuple properties + for (i=0; i 0) { + m[a[i]] -= 1; + } else { + x[j++] = a[i]; + } + } + } else if (k) { + // has unique key field, so use that + m = util.toMap(r, k); + for (i=0, j=0, n=a.length; i 1 ? this.dev / (this.valid-1) : 0', + req: ['mean'], idx: 1 + }), + 'variancep': measure({ + name: 'variancep', + set: 'this.valid > 1 ? this.dev / this.valid : 0', + req: ['variance'], idx: 2 + }), + 'stdev': measure({ + name: 'stdev', + set: 'this.valid > 1 ? Math.sqrt(this.dev / (this.valid-1)) : 0', + req: ['variance'], idx: 2 + }), + 'stdevp': measure({ + name: 'stdevp', + set: 'this.valid > 1 ? Math.sqrt(this.dev / this.valid) : 0', + req: ['variance'], idx: 2 + }), + 'median': measure({ + name: 'median', + set: 'cell.data.q2(this.get)', + req: ['values'], idx: 3 + }), + 'q1': measure({ + name: 'q1', + set: 'cell.data.q1(this.get)', + req: ['values'], idx: 3 + }), + 'q3': measure({ + name: 'q3', + set: 'cell.data.q3(this.get)', + req: ['values'], idx: 3 + }), + 'distinct': measure({ + name: 'distinct', + set: 'this.distinct(cell.data.values(), this.get)', + req: ['values'], idx: 3 + }), + 'argmin': measure({ + name: 'argmin', + add: 'if (v < this.min) this.argmin = t;', + rem: 'if (v <= this.min) this.argmin = null;', + set: 'this.argmin = this.argmin || cell.data.argmin(this.get)', + req: ['min'], str: ['values'], idx: 3 + }), + 'argmax': measure({ + name: 'argmax', + add: 'if (v > this.max) this.argmax = t;', + rem: 'if (v >= this.max) this.argmax = null;', + set: 'this.argmax = this.argmax || cell.data.argmax(this.get)', + req: ['max'], str: ['values'], idx: 3 + }), + 'min': measure({ + name: 'min', + init: 'this.min = +Infinity;', + add: 'if (v < this.min) this.min = v;', + rem: 'if (v <= this.min) this.min = NaN;', + set: 'this.min = (isNaN(this.min) ? cell.data.min(this.get) : this.min)', + str: ['values'], idx: 4 + }), + 'max': measure({ + name: 'max', + init: 'this.max = -Infinity;', + add: 'if (v > this.max) this.max = v;', + rem: 'if (v >= this.max) this.max = NaN;', + set: 'this.max = (isNaN(this.max) ? cell.data.max(this.get) : this.max)', + str: ['values'], idx: 4 + }), + 'modeskew': measure({ + name: 'modeskew', + set: 'this.dev===0 ? 0 : (this.mean - cell.data.q2(this.get)) / Math.sqrt(this.dev/(this.valid-1))', + req: ['mean', 'stdev', 'median'], idx: 5 + }) + }; + + function measure(base) { + return function(out) { + var m = util.extend({init:'', add:'', rem:'', idx:0}, base); + m.out = out || base.name; + return m; + }; + } + + function resolve(agg, stream) { + function collect(m, a) { + function helper(r) { if (!m[r]) collect(m, m[r] = types[r]()); } + if (a.req) a.req.forEach(helper); + if (stream && a.str) a.str.forEach(helper); + return m; + } + var map = agg.reduce( + collect, + agg.reduce(function(m, a) { return (m[a.name] = a, m); }, {}) + ); + return util.vals(map).sort(function(a, b) { return a.idx - b.idx; }); + } + + function create(agg, stream, accessor, mutator) { + var all = resolve(agg, stream), + ctr = 'this.cell = cell; this.tuple = t; this.valid = 0; this.missing = 0;', + add = 'if (v==null) this.missing++; if (!this.isValid(v)) return; ++this.valid;', + rem = 'if (v==null) this.missing--; if (!this.isValid(v)) return; --this.valid;', + set = 'var t = this.tuple; var cell = this.cell;'; + + all.forEach(function(a) { + if (a.idx < 0) { + ctr = a.init + ctr; + add = a.add + add; + rem = a.rem + rem; + } else { + ctr += a.init; + add += a.add; + rem += a.rem; + } + }); + agg.slice() + .sort(function(a, b) { return a.idx - b.idx; }) + .forEach(function(a) { + set += 'this.assign(t,\''+a.out+'\','+a.set+');'; + }); + set += 'return t;'; + + /* jshint evil: true */ + ctr = Function('cell', 't', ctr); + ctr.prototype.assign = mutator; + ctr.prototype.add = Function('t', 'var v = this.get(t);' + add); + ctr.prototype.rem = Function('t', 'var v = this.get(t);' + rem); + ctr.prototype.set = Function(set); + ctr.prototype.get = accessor; + ctr.prototype.distinct = require('../stats').count.distinct; + ctr.prototype.isValid = util.isValid; + ctr.fields = agg.map(util.$('out')); + return ctr; + } + + types.create = create; + module.exports = types; + +},{"../stats":28,"../util":31}],13:[function(require,module,exports){ + var util = require('../util'), + time = require('../time'), + EPSILON = 1e-15; + + function bins(opt) { + if (!opt) { throw Error("Missing binning options."); } + + // determine range + var maxb = opt.maxbins || 15, + base = opt.base || 10, + logb = Math.log(base), + div = opt.div || [5, 2], + min = opt.min, + max = opt.max, + span = max - min, + step, level, minstep, precision, v, i, eps; + + if (opt.step) { + // if step size is explicitly given, use that + step = opt.step; + } else if (opt.steps) { + // if provided, limit choice to acceptable step sizes + step = opt.steps[Math.min( + opt.steps.length - 1, + bisect(opt.steps, span/maxb, 0, opt.steps.length) + )]; + } else { + // else use span to determine step size + level = Math.ceil(Math.log(maxb) / logb); + minstep = opt.minstep || 0; + step = Math.max( + minstep, + Math.pow(base, Math.round(Math.log(span) / logb) - level) + ); + + // increase step size if too many bins + do { step *= base; } while (Math.ceil(span/step) > maxb); + + // decrease step size if allowed + for (i=0; i= minstep && span / v <= maxb) step = v; + } + } + + // update precision, min and max + v = Math.log(step); + precision = v >= 0 ? 0 : ~~(-v / logb) + 1; + eps = Math.pow(base, -precision - 1); + min = Math.min(min, Math.floor(min / step + eps) * step); + max = Math.ceil(max / step) * step; + + return { + start: min, + stop: max, + step: step, + unit: {precision: precision}, + value: value, + index: index + }; + } + + function bisect(a, x, lo, hi) { + while (lo < hi) { + var mid = lo + hi >>> 1; + if (util.cmp(a[mid], x) < 0) { lo = mid + 1; } + else { hi = mid; } + } + return lo; + } + + function value(v) { + return this.step * Math.floor(v / this.step + EPSILON); + } + + function index(v) { + return Math.floor((v - this.start) / this.step + EPSILON); + } + + function date_value(v) { + return this.unit.date(value.call(this, v)); + } + + function date_index(v) { + return index.call(this, this.unit.unit(v)); + } + + bins.date = function(opt) { + if (!opt) { throw Error("Missing date binning options."); } + + // find time step, then bin + var units = opt.utc ? time.utc : time, + dmin = opt.min, + dmax = opt.max, + maxb = opt.maxbins || 20, + minb = opt.minbins || 4, + span = (+dmax) - (+dmin), + unit = opt.unit ? units[opt.unit] : units.find(span, minb, maxb), + spec = bins({ + min: unit.min != null ? unit.min : unit.unit(dmin), + max: unit.max != null ? unit.max : unit.unit(dmax), + maxbins: maxb, + minstep: unit.minstep, + steps: unit.step + }); + + spec.unit = unit; + spec.index = date_index; + if (!opt.raw) spec.value = date_value; + return spec; + }; + + module.exports = bins; + +},{"../time":30,"../util":31}],14:[function(require,module,exports){ + var bins = require('./bins'), + gen = require('../generate'), + type = require('../import/type'), + util = require('../util'), + stats = require('../stats'); + + var qtype = { + 'integer': 1, + 'number': 1, + 'date': 1 + }; + + function $bin(values, f, opt) { + opt = options(values, f, opt); + var b = spec(opt); + return !b ? (opt.accessor || util.identity) : + util.$func('bin', b.unit.unit ? + function(x) { return b.value(b.unit.unit(x)); } : + function(x) { return b.value(x); } + )(opt.accessor); + } + + function histogram(values, f, opt) { + opt = options(values, f, opt); + var b = spec(opt); + return b ? + numerical(values, opt.accessor, b) : + categorical(values, opt.accessor, opt && opt.sort); + } + + function spec(opt) { + var t = opt.type, b = null; + if (t == null || qtype[t]) { + if (t === 'integer' && opt.minstep == null) opt.minstep = 1; + b = (t === 'date') ? bins.date(opt) : bins(opt); + } + return b; + } + + function options() { + var a = arguments, + i = 0, + values = util.isArray(a[i]) ? a[i++] : null, + f = util.isFunction(a[i]) || util.isString(a[i]) ? util.$(a[i++]) : null, + opt = util.extend({}, a[i]); + + if (values) { + opt.type = opt.type || type(values, f); + if (qtype[opt.type]) { + var ext = stats.extent(values, f); + opt = util.extend({min: ext[0], max: ext[1]}, opt); + } + } + if (f) { opt.accessor = f; } + return opt; + } + + function numerical(values, f, b) { + var h = gen.range(b.start, b.stop + b.step/2, b.step) + .map(function(v) { return {value: b.value(v), count: 0}; }); + + for (var i=0, v, j; i= h.length || !isFinite(j)) continue; + h[j].count += 1; + } + } + h.bins = b; + return h; + } + + function categorical(values, f, sort) { + var u = stats.unique(values, f), + c = stats.count.map(values, f); + return u.map(function(k) { return {value: k, count: c[k]}; }) + .sort(util.comparator(sort ? '-count' : '+value')); + } + + module.exports = { + $bin: $bin, + histogram: histogram + }; + +},{"../generate":16,"../import/type":25,"../stats":28,"../util":31,"./bins":13}],15:[function(require,module,exports){ + var d3_time = require('d3-time'), + d3_timeF = require('d3-time-format'), + d3_numberF = require('d3-format'), + numberF = d3_numberF, // defaults to EN-US + timeF = d3_timeF; // defaults to EN-US + + function numberLocale(l) { + var f = d3_numberF.localeFormat(l); + if (f == null) throw Error('Unrecognized locale: ' + l); + numberF = f; + } + + function timeLocale(l) { + var f = d3_timeF.localeFormat(l); + if (f == null) throw Error('Unrecognized locale: ' + l); + timeF = f; + } + + module.exports = { + // Update number formatter to use provided locale configuration. + // For more see https://github.com/d3/d3-format + numberLocale: numberLocale, + number: function(f) { return numberF.format(f); }, + numberPrefix: function(f, v) { return numberF.formatPrefix(f, v); }, + + // Update time formatter to use provided locale configuration. + // For more see https://github.com/d3/d3-time-format + timeLocale: timeLocale, + time: function(f) { return timeF.format(f); }, + utc: function(f) { return timeF.utcFormat(f); }, + + // Set number and time locale simultaneously. + locale: function(l) { numberLocale(l); timeLocale(l); }, + + // automatic formatting functions + auto: { + number: numberAutoFormat, + time: function() { return timeAutoFormat(); }, + utc: function() { return utcAutoFormat(); } + } + }; + + var e10 = Math.sqrt(50), + e5 = Math.sqrt(10), + e2 = Math.sqrt(2); + + function intervals(domain, count) { + if (!domain.length) domain = [0]; + if (count == null) count = 10; + + var start = domain[0], + stop = domain[domain.length - 1]; + + if (stop < start) { error = stop; stop = start; start = error; } + + var span = (stop - start) || (count = 1, start || stop || 1), + step = Math.pow(10, Math.floor(Math.log(span / count) / Math.LN10)), + error = span / count / step; + + // Filter ticks to get closer to the desired count. + if (error >= e10) step *= 10; + else if (error >= e5) step *= 5; + else if (error >= e2) step *= 2; + + // Round start and stop values to step interval. + return [ + Math.ceil(start / step) * step, + Math.floor(stop / step) * step + step / 2, // inclusive + step + ]; + } + + function significantDigits(domain) { + return domain.map(function(x) { + // determine significant digits based on exponential format + var s = x.toExponential(), + e = s.indexOf('e'), + d = s.indexOf('.'); + return d < 0 ? 1 : (e-d); + }).reduce(function(max, p) { + // return the maximum sig digit count + return Math.max(max, p); + }, 0); + } + + function numberAutoFormat(domain, count, f) { + var range = intervals(domain, count); + if (f == null) { + f = ',.' + d3_numberF.precisionFixed(range[2]) + 'f'; + } else { + switch (f = d3_numberF.formatSpecifier(f), f.type) { + case 's': { + if (f.precision == null) f.precision = significantDigits(domain); + return numberF.format(f); + } + case '': + case 'e': + case 'g': + case 'p': + case 'r': { + if (f.precision == null) f.precision = d3_numberF.precisionRound(range[2], Math.max(Math.abs(range[0]), Math.abs(range[1]))) - (f.type === 'e'); + break; + } + case 'f': + case '%': { + if (f.precision == null) f.precision = d3_numberF.precisionFixed(range[2]) - (f.type === '%') * 2; + break; + } + } + } + return numberF.format(f); + } + + function timeAutoFormat() { + var f = timeF.format, + formatMillisecond = f('.%L'), + formatSecond = f(':%S'), + formatMinute = f('%I:%M'), + formatHour = f('%I %p'), + formatDay = f('%a %d'), + formatWeek = f('%b %d'), + formatMonth = f('%B'), + formatYear = f('%Y'); + + return function(date) { + var d = +date; + return (d3_time.second(date) < d ? formatMillisecond + : d3_time.minute(date) < d ? formatSecond + : d3_time.hour(date) < d ? formatMinute + : d3_time.day(date) < d ? formatHour + : d3_time.month(date) < d ? + (d3_time.week(date) < d ? formatDay : formatWeek) + : d3_time.year(date) < d ? formatMonth + : formatYear)(date); + }; + } + + function utcAutoFormat() { + var f = timeF.utcFormat, + formatMillisecond = f('.%L'), + formatSecond = f(':%S'), + formatMinute = f('%I:%M'), + formatHour = f('%I %p'), + formatDay = f('%a %d'), + formatWeek = f('%b %d'), + formatMonth = f('%B'), + formatYear = f('%Y'); + + return function(date) { + var d = +date; + return (d3_time.utcSecond(date) < d ? formatMillisecond + : d3_time.utcMinute(date) < d ? formatSecond + : d3_time.utcHour(date) < d ? formatMinute + : d3_time.utcDay(date) < d ? formatHour + : d3_time.utcMonth(date) < d ? + (d3_time.utcWeek(date) < d ? formatDay : formatWeek) + : d3_time.utcYear(date) < d ? formatMonth + : formatYear)(date); + }; + } + +},{"d3-format":6,"d3-time":8,"d3-time-format":7}],16:[function(require,module,exports){ + var gen = module.exports = {}; + + gen.repeat = function(val, n) { + var a = Array(n), i; + for (i=0; i stop) range.push(j); + else while ((j = start + step * ++i) < stop) range.push(j); + return range; + }; + + gen.random = {}; + + gen.random.uniform = function(min, max) { + if (max === undefined) { + max = min === undefined ? 1 : min; + min = 0; + } + var d = max - min; + var f = function() { + return min + d * Math.random(); + }; + f.samples = function(n) { return gen.zeros(n).map(f); }; + return f; + }; + + gen.random.integer = function(a, b) { + if (b === undefined) { + b = a; + a = 0; + } + var d = b - a; + var f = function() { + return a + Math.floor(d * Math.random()); + }; + f.samples = function(n) { return gen.zeros(n).map(f); }; + return f; + }; + + gen.random.normal = function(mean, stdev) { + mean = mean || 0; + stdev = stdev || 1; + var next; + var f = function() { + var x = 0, y = 0, rds, c; + if (next !== undefined) { + x = next; + next = undefined; + return x; + } + do { + x = Math.random()*2-1; + y = Math.random()*2-1; + rds = x*x + y*y; + } while (rds === 0 || rds > 1); + c = Math.sqrt(-2*Math.log(rds)/rds); // Box-Muller transform + next = mean + y*c*stdev; + return mean + x*c*stdev; + }; + f.samples = function(n) { return gen.zeros(n).map(f); }; + return f; + }; + +},{}],17:[function(require,module,exports){ + var util = require('../../util'); + var d3_dsv = require('d3-dsv'); + + function dsv(data, format) { + if (data) { + var h = format.header; + data = (h ? h.join(format.delimiter) + '\n' : '') + data; + } + return d3_dsv.dsv(format.delimiter).parse(data); + } + + dsv.delimiter = function(delim) { + var fmt = {delimiter: delim}; + return function(data, format) { + return dsv(data, format ? util.extend(format, fmt) : fmt); + }; + }; + + module.exports = dsv; + +},{"../../util":31,"d3-dsv":5}],18:[function(require,module,exports){ + var dsv = require('./dsv'); + + module.exports = { + json: require('./json'), + topojson: require('./topojson'), + treejson: require('./treejson'), + dsv: dsv, + csv: dsv.delimiter(','), + tsv: dsv.delimiter('\t') + }; + +},{"./dsv":17,"./json":19,"./topojson":20,"./treejson":21}],19:[function(require,module,exports){ + var util = require('../../util'); + + module.exports = function(data, format) { + var d = util.isObject(data) && !util.isBuffer(data) ? + data : JSON.parse(data); + if (format && format.property) { + d = util.accessor(format.property)(d); + } + return d; + }; + +},{"../../util":31}],20:[function(require,module,exports){ + (function (global){ + var json = require('./json'); + + var reader = function(data, format) { + var topojson = reader.topojson; + if (topojson == null) { throw Error('TopoJSON library not loaded.'); } + + var t = json(data, format), obj; + + if (format && format.feature) { + if ((obj = t.objects[format.feature])) { + return topojson.feature(t, obj).features; + } else { + throw Error('Invalid TopoJSON object: ' + format.feature); + } + } else if (format && format.mesh) { + if ((obj = t.objects[format.mesh])) { + return [topojson.mesh(t, t.objects[format.mesh])]; + } else { + throw Error('Invalid TopoJSON object: ' + format.mesh); + } + } else { + throw Error('Missing TopoJSON feature or mesh parameter.'); + } + }; + + reader.topojson = (typeof window !== "undefined" ? window['topojson'] : typeof global !== "undefined" ? global['topojson'] : null); + module.exports = reader; + + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./json":19}],21:[function(require,module,exports){ + var json = require('./json'); + + module.exports = function(tree, format) { + return toTable(json(tree, format), format); + }; + + function toTable(root, fields) { + var childrenField = fields && fields.children || 'children', + parentField = fields && fields.parent || 'parent', + table = []; + + function visit(node, parent) { + node[parentField] = parent; + table.push(node); + var children = node[childrenField]; + if (children) { + for (var i=0; i 1 && domain[idx-1] === '.' && domain.lastIndexOf(d) === idx); + }); + if (!whiteListed) { + throw 'URL is not whitelisted: ' + url; + } + } + } + return url; + } + + function load(opt, callback) { + var error = callback || function(e) { throw e; }, url; + + try { + url = load.sanitizeUrl(opt); // enable override + } catch (err) { + error(err); + return; + } + + if (!url) { + error('Invalid URL: ' + opt.url); + } else if (load.useXHR) { + // on client, use xhr + return xhr(url, callback); + } else if (startsWith(url, fileProtocol)) { + // on server, if url starts with 'file://', strip it and load from file + return file(url.slice(fileProtocol.length), callback); + } else if (url.indexOf('://') < 0) { // TODO better protocol check? + // on server, if no protocol assume file + return file(url, callback); + } else { + // for regular URLs on server + return http(url, callback); + } + } + + function xhrHasResponse(request) { + var type = request.responseType; + return type && type !== 'text' ? + request.response : // null on error + request.responseText; // '' on error + } + + function xhr(url, callback) { + var async = !!callback; + var request = new XMLHttpRequest(); + // If IE does not support CORS, use XDomainRequest (copied from d3.xhr) + if (this.XDomainRequest && + !('withCredentials' in request) && + /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest(); + + function respond() { + var status = request.status; + if (!status && xhrHasResponse(request) || status >= 200 && status < 300 || status === 304) { + callback(null, request.responseText); + } else { + callback(request, null); + } + } + + if (async) { + if ('onload' in request) { + request.onload = request.onerror = respond; + } else { + request.onreadystatechange = function() { + if (request.readyState > 3) respond(); + }; + } + } + + request.open('GET', url, async); + request.send(); + + if (!async && xhrHasResponse(request)) { + return request.responseText; + } + } + + function file(filename, callback) { + var fs = require('fs'); + if (!callback) { + return fs.readFileSync(filename, 'utf8'); + } + fs.readFile(filename, callback); + } + + function http(url, callback) { + if (!callback) { + return require('sync-request')('GET', url).getBody(); + } + + var options = {url: url, encoding: null, gzip: true}; + require('request')(options, function(error, response, body) { + if (!error && response.statusCode === 200) { + callback(null, body); + } else { + error = error || + 'Load failed with response code ' + response.statusCode + '.'; + callback(error, null); + } + }); + } + + function startsWith(string, searchString) { + return string == null ? false : string.lastIndexOf(searchString, 0) === 0; + } + + load.sanitizeUrl = sanitizeUrl; + + load.useXHR = (typeof XMLHttpRequest !== 'undefined'); + + module.exports = load; + +},{"fs":2,"request":2,"sync-request":2,"url":2}],23:[function(require,module,exports){ + var util = require('../util'); + var type = require('./type'); + var formats = require('./formats'); + + function read(data, format) { + var type = (format && format.type) || 'json'; + data = formats[type](data, format); + if (format && format.parse) parse(data, format.parse); + return data; + } + + function parse(data, types) { + var cols, parsers, d, i, j, clen, len = data.length; + + types = (types==='auto') ? type.inferAll(data) : util.duplicate(types); + cols = util.keys(types); + parsers = cols.map(function(c) { return type.parsers[types[c]]; }); + + for (i=0, clen=cols.length; i 0 ? Math.min(l, opt.maxwidth) : l; + }); + + // print header row + var head = fields.map(function(name, i) { + return util.truncate(util.pad(name, lens[i], 'center'), lens[i]); + }).join(opt.separator); + + // build template function for each row + var tmpl = template(fields.map(function(name, i) { + return '{{' + + name + + (FMT[types[name]] || '') + + ('|pad:' + lens[i] + ',' + (POS[types[name]] || 'right')) + + ('|truncate:' + lens[i]) + + '}}'; + }).join(opt.separator)); + + // print table + return head + "\n" + data.map(tmpl).join('\n'); + }; + + module.exports.summary = function(s) { + s = s ? s.__summary__ ? s : stats.summary(s) : this; + var str = [], i, n; + for (i=0, n=s.length; i b) b = v; + } + } + return [a, b]; + }; + +// Find the integer indices of the minimum and maximum values. + stats.extent.index = function(values, f) { + f = util.$(f); + var x = -1, y = -1, a, b, v, i, n = values.length; + for (i=0; i b) { b = v; y = i; } + } + } + return [x, y]; + }; + +// Compute the dot product of two arrays of numbers. + stats.dot = function(values, a, b) { + var sum = 0, i, v; + if (!b) { + if (values.length !== a.length) { + throw Error('Array lengths must match.'); + } + for (i=0; i -1 && p !== v) { + mu = 1 + (i-1 + tie) / 2; + for (; tie -1) { + mu = 1 + (n-1 + tie) / 2; + for (; tie max) max = x; + delta = x - mean; + mean = mean + delta / (++valid); + M2 = M2 + delta * (x - mean); + vals.push(x); + } + } + M2 = M2 / (valid - 1); + sd = Math.sqrt(M2); + + // sort values for median and iqr + vals.sort(util.cmp); + + return { + type: type(values, f), + unique: u, + count: values.length, + valid: valid, + missing: missing, + distinct: distinct, + min: min, + max: max, + mean: mean, + stdev: sd, + median: (v = stats.quantile(vals, 0.5)), + q1: stats.quantile(vals, 0.25), + q3: stats.quantile(vals, 0.75), + modeskew: sd === 0 ? 0 : (mean - v) / sd + }; + }; + +// Compute profiles for all variables in a data set. + stats.summary = function(data, fields) { + fields = fields || util.keys(data[0]); + var s = fields.map(function(f) { + var p = stats.profile(data, util.$(f)); + return (p.field = f, p); + }); + return (s.__summary__ = true, s); + }; + + module.exports = stats; + +},{"./generate":16,"./import/type":25,"./util":31}],29:[function(require,module,exports){ + var util = require('./util'), + format = require('./format'); + + var context = { + formats: [], + format_map: {}, + truncate: util.truncate, + pad: util.pad + }; + + function template(text) { + var src = source(text, 'd'); + src = 'var __t; return ' + src + ';'; + + /* jshint evil: true */ + return (new Function('d', src)).bind(context); + } + + template.source = source; + template.context = context; + module.exports = template; + +// Clear cache of format objects. +// This can *break* prior template functions, so invoke with care! + template.clearFormatCache = function() { + context.formats = []; + context.format_map = {}; + }; + +// Generate property access code for use within template source. +// object: the name of the object (variable) containing template data +// property: the property access string, verbatim from template tag + template.property = function(object, property) { + var src = util.field(property).map(util.str).join(']['); + return object + '[' + src + ']'; + }; + +// Generate source code for a template function. +// text: the template text +// variable: the name of the data object variable ('obj' by default) +// properties: optional hash for collecting all accessed properties + function source(text, variable, properties) { + variable = variable || 'obj'; + var index = 0; + var src = '\''; + var regex = template_re; + + // Compile the template source, escaping string literals appropriately. + text.replace(regex, function(match, interpolate, offset) { + src += text + .slice(index, offset) + .replace(template_escaper, template_escapeChar); + index = offset + match.length; + + if (interpolate) { + src += '\'\n+((__t=(' + + template_var(interpolate, variable, properties) + + '))==null?\'\':__t)+\n\''; + } + + // Adobe VMs need the match returned to produce the correct offest. + return match; + }); + return src + '\''; + } + + function template_var(text, variable, properties) { + var filters = text.match(filter_re); + var prop = filters.shift().trim(); + var stringCast = true; + + function strcall(fn) { + fn = fn || ''; + if (stringCast) { + stringCast = false; + src = 'String(' + src + ')' + fn; + } else { + src += fn; + } + return src; + } + + function date() { + return '(typeof ' + src + '==="number"?new Date('+src+'):'+src+')'; + } + + function number_format(fmt, key) { + a = template_format(args[0], key, fmt); + stringCast = false; + src = 'this.formats['+a+']('+src+')'; + } + + function time_format(fmt, key) { + a = template_format(args[0], key, fmt); + stringCast = false; + src = 'this.formats['+a+']('+date()+')'; + } + + if (properties) properties[prop] = 1; + var src = template.property(variable, prop); + + for (var i=0; i 0) { + f = f.slice(0, pidx); + args = filters[i].slice(pidx+1) + .match(args_re) + .map(function(s) { return s.trim(); }); + } + f = f.trim(); + + switch (f) { + case 'length': + strcall('.length'); + break; + case 'lower': + strcall('.toLowerCase()'); + break; + case 'upper': + strcall('.toUpperCase()'); + break; + case 'lower-locale': + strcall('.toLocaleLowerCase()'); + break; + case 'upper-locale': + strcall('.toLocaleUpperCase()'); + break; + case 'trim': + strcall('.trim()'); + break; + case 'left': + a = util.number(args[0]); + strcall('.slice(0,' + a + ')'); + break; + case 'right': + a = util.number(args[0]); + strcall('.slice(-' + a +')'); + break; + case 'mid': + a = util.number(args[0]); + b = a + util.number(args[1]); + strcall('.slice(+'+a+','+b+')'); + break; + case 'slice': + a = util.number(args[0]); + strcall('.slice('+ a + + (args.length > 1 ? ',' + util.number(args[1]) : '') + + ')'); + break; + case 'truncate': + a = util.number(args[0]); + b = args[1]; + b = (b!=='left' && b!=='middle' && b!=='center') ? 'right' : b; + src = 'this.truncate(' + strcall() + ',' + a + ',\'' + b + '\')'; + break; + case 'pad': + a = util.number(args[0]); + b = args[1]; + b = (b!=='left' && b!=='middle' && b!=='center') ? 'right' : b; + src = 'this.pad(' + strcall() + ',' + a + ',\'' + b + '\')'; + break; + case 'number': + number_format(format.number, 'number'); + break; + case 'time': + time_format(format.time, 'time'); + break; + case 'time-utc': + time_format(format.utc, 'time-utc'); + break; + default: + throw Error('Unrecognized template filter: ' + f); + } + } + + return src; + } + + var template_re = /\{\{(.+?)\}\}|$/g, + filter_re = /(?:"[^"]*"|\'[^\']*\'|[^\|"]+|[^\|\']+)+/g, + args_re = /(?:"[^"]*"|\'[^\']*\'|[^,"]+|[^,\']+)+/g; + +// Certain characters need to be escaped so that they can be put into a +// string literal. + var template_escapes = { + '\'': '\'', + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var template_escaper = /\\|'|\r|\n|\u2028|\u2029/g; + + function template_escapeChar(match) { + return '\\' + template_escapes[match]; + } + + function template_format(pattern, key, fmt) { + if ((pattern[0] === '\'' && pattern[pattern.length-1] === '\'') || + (pattern[0] === '"' && pattern[pattern.length-1] === '"')) { + pattern = pattern.slice(1, -1); + } else { + throw Error('Format pattern must be quoted: ' + pattern); + } + key = key + ':' + pattern; + if (!context.format_map[key]) { + var f = fmt(pattern); + var i = context.formats.length; + context.formats.push(f); + context.format_map[key] = i; + } + return context.format_map[key]; + } + +},{"./format":15,"./util":31}],30:[function(require,module,exports){ + var d3_time = require('d3-time'); + + var tempDate = new Date(), + baseDate = new Date(0, 0, 1).setFullYear(0), // Jan 1, 0 AD + utcBaseDate = new Date(Date.UTC(0, 0, 1)).setUTCFullYear(0); + + function date(d) { + return (tempDate.setTime(+d), tempDate); + } + +// create a time unit entry + function entry(type, date, unit, step, min, max) { + var e = { + type: type, + date: date, + unit: unit + }; + if (step) { + e.step = step; + } else { + e.minstep = 1; + } + if (min != null) e.min = min; + if (max != null) e.max = max; + return e; + } + + function create(type, unit, base, step, min, max) { + return entry(type, + function(d) { return unit.offset(base, d); }, + function(d) { return unit.count(base, d); }, + step, min, max); + } + + var locale = [ + create('second', d3_time.second, baseDate), + create('minute', d3_time.minute, baseDate), + create('hour', d3_time.hour, baseDate), + create('day', d3_time.day, baseDate, [1, 7]), + create('month', d3_time.month, baseDate, [1, 3, 6]), + create('year', d3_time.year, baseDate), + + // periodic units + entry('seconds', + function(d) { return new Date(1970, 0, 1, 0, 0, d); }, + function(d) { return date(d).getSeconds(); }, + null, 0, 59 + ), + entry('minutes', + function(d) { return new Date(1970, 0, 1, 0, d); }, + function(d) { return date(d).getMinutes(); }, + null, 0, 59 + ), + entry('hours', + function(d) { return new Date(1970, 0, 1, d); }, + function(d) { return date(d).getHours(); }, + null, 0, 23 + ), + entry('weekdays', + function(d) { return new Date(1970, 0, 4+d); }, + function(d) { return date(d).getDay(); }, + [1], 0, 6 + ), + entry('dates', + function(d) { return new Date(1970, 0, d); }, + function(d) { return date(d).getDate(); }, + [1], 1, 31 + ), + entry('months', + function(d) { return new Date(1970, d % 12, 1); }, + function(d) { return date(d).getMonth(); }, + [1], 0, 11 + ) + ]; + + var utc = [ + create('second', d3_time.utcSecond, utcBaseDate), + create('minute', d3_time.utcMinute, utcBaseDate), + create('hour', d3_time.utcHour, utcBaseDate), + create('day', d3_time.utcDay, utcBaseDate, [1, 7]), + create('month', d3_time.utcMonth, utcBaseDate, [1, 3, 6]), + create('year', d3_time.utcYear, utcBaseDate), + + // periodic units + entry('seconds', + function(d) { return new Date(Date.UTC(1970, 0, 1, 0, 0, d)); }, + function(d) { return date(d).getUTCSeconds(); }, + null, 0, 59 + ), + entry('minutes', + function(d) { return new Date(Date.UTC(1970, 0, 1, 0, d)); }, + function(d) { return date(d).getUTCMinutes(); }, + null, 0, 59 + ), + entry('hours', + function(d) { return new Date(Date.UTC(1970, 0, 1, d)); }, + function(d) { return date(d).getUTCHours(); }, + null, 0, 23 + ), + entry('weekdays', + function(d) { return new Date(Date.UTC(1970, 0, 4+d)); }, + function(d) { return date(d).getUTCDay(); }, + [1], 0, 6 + ), + entry('dates', + function(d) { return new Date(Date.UTC(1970, 0, d)); }, + function(d) { return date(d).getUTCDate(); }, + [1], 1, 31 + ), + entry('months', + function(d) { return new Date(Date.UTC(1970, d % 12, 1)); }, + function(d) { return date(d).getUTCMonth(); }, + [1], 0, 11 + ) + ]; + + var STEPS = [ + [31536e6, 5], // 1-year + [7776e6, 4], // 3-month + [2592e6, 4], // 1-month + [12096e5, 3], // 2-week + [6048e5, 3], // 1-week + [1728e5, 3], // 2-day + [864e5, 3], // 1-day + [432e5, 2], // 12-hour + [216e5, 2], // 6-hour + [108e5, 2], // 3-hour + [36e5, 2], // 1-hour + [18e5, 1], // 30-minute + [9e5, 1], // 15-minute + [3e5, 1], // 5-minute + [6e4, 1], // 1-minute + [3e4, 0], // 30-second + [15e3, 0], // 15-second + [5e3, 0], // 5-second + [1e3, 0] // 1-second + ]; + + function find(units, span, minb, maxb) { + var step = STEPS[0], i, n, bins; + + for (i=1, n=STEPS.length; i step[0]) { + bins = span / step[0]; + if (bins > maxb) { + return units[STEPS[i-1][1]]; + } + if (bins >= minb) { + return units[step[1]]; + } + } + } + return units[STEPS[n-1][1]]; + } + + function toUnitMap(units) { + var map = {}, i, n; + for (i=0, n=units.length; i 1 ? + function(x) { return s.reduce(function(x,f) { return x[f]; }, x); } : + function(x) { return x[f]; } + ); + }; + +// short-cut for accessor + u.$ = u.accessor; + + u.mutator = function(f) { + var s; + return u.isString(f) && (s=u.field(f)).length > 1 ? + function(x, v) { + for (var i=0; i y) return sign[i]; + } + return 0; + }; + }; + + u.cmp = function(a, b) { + if (a < b) { + return -1; + } else if (a > b) { + return 1; + } else if (a >= b) { + return 0; + } else if (a === null) { + return -1; + } else if (b === null) { + return 1; + } + return NaN; + }; + + u.numcmp = function(a, b) { return a - b; }; + + u.stablesort = function(array, sortBy, keyFn) { + var indices = array.reduce(function(idx, v, i) { + return (idx[keyFn(v)] = i, idx); + }, {}); + + array.sort(function(a, b) { + var sa = sortBy(a), + sb = sortBy(b); + return sa < sb ? -1 : sa > sb ? 1 + : (indices[keyFn(a)] - indices[keyFn(b)]); + }); + + return array; + }; + + +// string functions + + u.pad = function(s, length, pos, padchar) { + padchar = padchar || " "; + var d = length - s.length; + if (d <= 0) return s; + switch (pos) { + case 'left': + return strrep(d, padchar) + s; + case 'middle': + case 'center': + return strrep(Math.floor(d/2), padchar) + + s + strrep(Math.ceil(d/2), padchar); + default: + return s + strrep(d, padchar); + } + }; + + function strrep(n, str) { + var s = "", i; + for (i=0; i 1) { + for (var i=1, n=ref.length; i 0) { + node = pq.peek(); + pulse = pulses[node._id]; + + if (node.rank() !== node.qrank()) { + // A node's rank might change during a propagation. Re-queue if so. + pq.replace(node.qrank(true)); + } else { + // Evaluate node and propagate pulse. + pq.pop(); + pulses[node._id] = null; + listeners = node._listeners; + pulse = this.evaluate(pulse, node); + + // Propagate the pulse. + if (pulse !== this.doNotPropagate) { + // Ensure reflow pulses always send reflow pulses even if skipped. + if (!pulse.reflow && node.reflows()) { + pulse = ChangeSet.create(pulse, true); + } + + for (i=0, len=listeners.length; i 0) branch[i-1].addListener(node); + } + + return branch; + }; + + prototype.disconnect = function(branch) { + var collector, node, data, signals, i, n, j, m; + + for (i=0, n=branch.length; i= pulse.stamp, + run = node.router() || pulse.add.length || pulse.rem.length; + + return run || !reflowed || node.reevaluate(pulse); + }; + + prototype.evaluate = function(pulse, node) { + if (!this.reevaluate(pulse, node)) return pulse; + pulse = node.evaluate(pulse); + node.last(pulse.stamp); + return pulse; + }; + + module.exports = Graph; + +},{"./ChangeSet":32,"./Collector":33,"./DataSource":34,"./Dependencies":35,"./Heap":37,"./Signal":39,"./Tuple":40,"datalib":26}],37:[function(require,module,exports){ + function Heap(comparator) { + this.cmp = comparator; + this.nodes = []; + } + + var prototype = Heap.prototype; + + prototype.size = function() { + return this.nodes.length; + }; + + prototype.clear = function() { + return (this.nodes = [], this); + }; + + prototype.peek = function() { + return this.nodes[0]; + }; + + prototype.push = function(x) { + var array = this.nodes; + array.push(x); + return _siftdown(array, 0, array.length-1, this.cmp); + }; + + prototype.pop = function() { + var array = this.nodes, + last = array.pop(), + item; + + if (array.length) { + item = array[0]; + array[0] = last; + _siftup(array, 0, this.cmp); + } else { + item = last; + } + return item; + }; + + prototype.replace = function(item) { + var array = this.nodes, + retval = array[0]; + array[0] = item; + _siftup(array, 0, this.cmp); + return retval; + }; + + prototype.pushpop = function(item) { + var array = this.nodes, ref = array[0]; + if (array.length && this.cmp(ref, item) < 0) { + array[0] = item; + item = ref; + _siftup(array, 0, this.cmp); + } + return item; + }; + + function _siftdown(array, start, idx, cmp) { + var item, parent, pidx; + + item = array[idx]; + while (idx > start) { + pidx = (idx - 1) >> 1; + parent = array[pidx]; + if (cmp(item, parent) < 0) { + array[idx] = parent; + idx = pidx; + continue; + } + break; + } + return (array[idx] = item); + } + + function _siftup(array, idx, cmp) { + var start = idx, + end = array.length, + item = array[idx], + cidx = 2 * idx + 1, ridx; + + while (cidx < end) { + ridx = cidx + 1; + if (ridx < end && cmp(array[cidx], array[ridx]) >= 0) { + cidx = ridx; + } + array[idx] = array[cidx]; + idx = cidx; + cidx = 2 * idx + 1; + } + array[idx] = item; + return _siftdown(array, start, idx, cmp); + } + + module.exports = Heap; + +},{}],38:[function(require,module,exports){ + var DEPS = require('./Dependencies').ALL, + nodeID = 0; + + function Node(graph) { + if (graph) this.init(graph); + } + + var Flags = Node.Flags = { + Router: 0x01, // Responsible for propagating tuples, cannot be skipped. + Collector: 0x02, // Holds a materialized dataset, pulse node to reflow. + Produces: 0x04, // Produces new tuples. + Mutates: 0x08, // Sets properties of incoming tuples. + Reflows: 0x10, // Forwards a reflow pulse. + Batch: 0x20 // Performs batch data processing, needs collector. + }; + + var prototype = Node.prototype; + + prototype.init = function(graph) { + this._id = ++nodeID; + this._graph = graph; + this._rank = graph.rank(); // Topological sort by rank + this._qrank = null; // Rank when enqueued for propagation + this._stamp = 0; // Last stamp seen + + this._listeners = []; + this._listeners._ids = {}; // To prevent duplicate listeners + + // Initialize dependencies. + this._deps = {}; + for (var i=0, n=DEPS.length; i l._rank) { + l.rerank(); + } + + return this; + }; + + prototype.removeListener = function(l) { + if (!this._listeners._ids[l._id]) return false; + + var idx = this._listeners.indexOf(l), + b = idx >= 0; + + if (b) { + this._listeners.splice(idx, 1); + this._listeners._ids[l._id] = null; + } + return b; + }; + + prototype.disconnect = function() { + this._listeners = []; + this._listeners._ids = {}; + }; + +// Evaluate this dataflow node for the current pulse. +// Subclasses should override to perform custom processing. + prototype.evaluate = function(pulse) { + return pulse; + }; + +// Should this node be re-evaluated for the current pulse? +// Searches pulse to see if any dependencies have updated. + prototype.reevaluate = function(pulse) { + var prop, dep, i, n, j, m; + + for (i=0, n=DEPS.length; i=0;) { + if (!handler || h[i].handler === handler) { + x = h.splice(i, 1)[0]; + this.removeListener(x.node); + } + } + + return this; + }; + + module.exports = Signal; + +},{"./ChangeSet":32,"./Node":38}],40:[function(require,module,exports){ + var tupleID = 0; + + function ingest(datum) { + datum = (datum === Object(datum)) ? datum : {data: datum}; + datum._id = ++tupleID; + if (datum._prev) datum._prev = null; + return datum; + } + + function idMap(a, ids) { + ids = ids || {}; + for (var i=0, n=a.length; i0;) { + idMap(arguments[i], ids); + } + return data.filter(function(x) { return !ids[x._id]; }); + } + }; + +},{}],41:[function(require,module,exports){ + module.exports = { + ChangeSet: require('./ChangeSet'), + Collector: require('./Collector'), + DataSource: require('./DataSource'), + Dependencies: require('./Dependencies'), + Graph: require('./Graph'), + Node: require('./Node'), + Signal: require('./Signal'), + Tuple: require('./Tuple'), + debug: require('vega-logging').debug + }; + +},{"./ChangeSet":32,"./Collector":33,"./DataSource":34,"./Dependencies":35,"./Graph":36,"./Node":38,"./Signal":39,"./Tuple":40,"vega-logging":47}],42:[function(require,module,exports){ + function toMap(list) { + var map = {}, i, n; + for (i=0, n=list.length; i 0) { + return id; + } + if (constants.hasOwnProperty(id)) { + return constants[id]; + } + if (idWhiteList) { + if (idWhiteList.hasOwnProperty(id)) { + return id; + } else { + globals[id] = 1; + return lookupGlobal(id); + } + } + if (idBlackList && idBlackList.hasOwnProperty(id)) { + throw new Error('Illegal identifier: ' + id); + } + return id; + }, + 'Program': function(n) { + return n.body.map(codegen).join('\n'); + }, + 'MemberExpression': function(n) { + var d = !n.computed; + var o = codegen(n.object); + if (d) memberDepth += 1; + var p = codegen(n.property); + if (o === FIELD_VAR) { fields[p] = 1; } // HACKish... + if (d) memberDepth -= 1; + return o + (d ? '.'+p : '['+p+']'); + }, + 'CallExpression': function(n) { + if (n.callee.type !== 'Identifier') { + throw new Error('Illegal callee type: ' + n.callee.type); + } + var callee = n.callee.name; + var args = n.arguments; + var fn = functions.hasOwnProperty(callee) && functions[callee]; + if (!fn) throw new Error('Unrecognized function: ' + callee); + return fn instanceof Function ? + fn(args) : + fn + '(' + args.map(codegen).join(',') + ')'; + }, + 'ArrayExpression': function(n) { + return '[' + n.elements.map(codegen).join(',') + ']'; + }, + 'BinaryExpression': function(n) { + return '(' + codegen(n.left) + n.operator + codegen(n.right) + ')'; + }, + 'UnaryExpression': function(n) { + return '(' + n.operator + codegen(n.argument) + ')'; + }, + 'ConditionalExpression': function(n) { + return '(' + codegen(n.test) + + '?' + codegen(n.consequent) + + ':' + codegen(n.alternate) + + ')'; + }, + 'LogicalExpression': function(n) { + return '(' + codegen(n.left) + n.operator + codegen(n.right) + ')'; + }, + 'ObjectExpression': function(n) { + return '{' + n.properties.map(codegen).join(',') + '}'; + }, + 'Property': function(n) { + memberDepth += 1; + var k = codegen(n.key); + memberDepth -= 1; + return k + ':' + codegen(n.value); + }, + 'ExpressionStatement': function(n) { + return codegen(n.expression); + } + }; + + codegen_wrap.functions = functions; + codegen_wrap.constants = constants; + return codegen_wrap; + }; + +},{"./constants":43,"./functions":44}],43:[function(require,module,exports){ + module.exports = { + 'NaN': 'NaN', + 'E': 'Math.E', + 'LN2': 'Math.LN2', + 'LN10': 'Math.LN10', + 'LOG2E': 'Math.LOG2E', + 'LOG10E': 'Math.LOG10E', + 'PI': 'Math.PI', + 'SQRT1_2': 'Math.SQRT1_2', + 'SQRT2': 'Math.SQRT2' + }; +},{}],44:[function(require,module,exports){ + module.exports = function(codegen) { + + function fncall(name, args, cast, type) { + var obj = codegen(args[0]); + if (cast) { + obj = cast + '(' + obj + ')'; + if (cast.lastIndexOf('new ', 0) === 0) obj = '(' + obj + ')'; + } + return obj + '.' + name + (type < 0 ? '' : type === 0 ? + '()' : + '(' + args.slice(1).map(codegen).join(',') + ')'); + } + + function fn(name, cast, type) { + return function(args) { + return fncall(name, args, cast, type); + }; + } + + var DATE = 'new Date', + STRING = 'String', + REGEXP = 'RegExp'; + + return { + // MATH functions + 'isNaN': 'isNaN', + 'isFinite': 'isFinite', + 'abs': 'Math.abs', + 'acos': 'Math.acos', + 'asin': 'Math.asin', + 'atan': 'Math.atan', + 'atan2': 'Math.atan2', + 'ceil': 'Math.ceil', + 'cos': 'Math.cos', + 'exp': 'Math.exp', + 'floor': 'Math.floor', + 'log': 'Math.log', + 'max': 'Math.max', + 'min': 'Math.min', + 'pow': 'Math.pow', + 'random': 'Math.random', + 'round': 'Math.round', + 'sin': 'Math.sin', + 'sqrt': 'Math.sqrt', + 'tan': 'Math.tan', + + 'clamp': function(args) { + if (args.length < 3) + throw new Error('Missing arguments to clamp function.'); + if (args.length > 3) + throw new Error('Too many arguments to clamp function.'); + var a = args.map(codegen); + return 'Math.max('+a[1]+', Math.min('+a[2]+','+a[0]+'))'; + }, + + // DATE functions + 'now': 'Date.now', + 'datetime': DATE, + 'date': fn('getDate', DATE, 0), + 'day': fn('getDay', DATE, 0), + 'year': fn('getFullYear', DATE, 0), + 'month': fn('getMonth', DATE, 0), + 'hours': fn('getHours', DATE, 0), + 'minutes': fn('getMinutes', DATE, 0), + 'seconds': fn('getSeconds', DATE, 0), + 'milliseconds': fn('getMilliseconds', DATE, 0), + 'time': fn('getTime', DATE, 0), + 'timezoneoffset': fn('getTimezoneOffset', DATE, 0), + 'utcdate': fn('getUTCDate', DATE, 0), + 'utcday': fn('getUTCDay', DATE, 0), + 'utcyear': fn('getUTCFullYear', DATE, 0), + 'utcmonth': fn('getUTCMonth', DATE, 0), + 'utchours': fn('getUTCHours', DATE, 0), + 'utcminutes': fn('getUTCMinutes', DATE, 0), + 'utcseconds': fn('getUTCSeconds', DATE, 0), + 'utcmilliseconds': fn('getUTCMilliseconds', DATE, 0), + + // shared sequence functions + 'length': fn('length', null, -1), + 'indexof': fn('indexOf', null), + 'lastindexof': fn('lastIndexOf', null), + + // STRING functions + 'parseFloat': 'parseFloat', + 'parseInt': 'parseInt', + 'upper': fn('toUpperCase', STRING, 0), + 'lower': fn('toLowerCase', STRING, 0), + 'slice': fn('slice', STRING), + 'substring': fn('substring', STRING), + + // REGEXP functions + 'regexp': REGEXP, + 'test': fn('test', REGEXP), + + // Control Flow functions + 'if': function(args) { + if (args.length < 3) + throw new Error('Missing arguments to if function.'); + if (args.length > 3) + throw new Error('Too many arguments to if function.'); + var a = args.map(codegen); + return a[0]+'?'+a[1]+':'+a[2]; + } + }; + }; +},{}],45:[function(require,module,exports){ + var parser = require('./parser'), + codegen = require('./codegen'); + + var expr = module.exports = { + parse: function(input, opt) { + return parser.parse('('+input+')', opt); + }, + code: function(opt) { + return codegen(opt); + }, + compiler: function(args, opt) { + args = args.slice(); + var generator = codegen(opt), + len = args.length, + compile = function(str) { + var value = generator(expr.parse(str)); + args[len] = '"use strict"; return (' + value.code + ');'; + value.fn = Function.apply(null, args); + return value; + }; + compile.codegen = generator; + return compile; + }, + functions: require('./functions'), + constants: require('./constants') + }; + +},{"./codegen":42,"./constants":43,"./functions":44,"./parser":46}],46:[function(require,module,exports){ + /* + The following expression parser is based on Esprima (http://esprima.org/). + Original header comment and license for Esprima is included here: + + Copyright (C) 2013 Ariya Hidayat + Copyright (C) 2013 Thaddee Tyl + Copyright (C) 2013 Mathias Bynens + Copyright (C) 2012 Ariya Hidayat + Copyright (C) 2012 Mathias Bynens + Copyright (C) 2012 Joost-Wim Boekesteijn + Copyright (C) 2012 Kris Kowal + Copyright (C) 2012 Yusuke Suzuki + Copyright (C) 2012 Arpad Borsos + Copyright (C) 2011 Ariya Hidayat + + 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. + + 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 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. + */ + /* istanbul ignore next */ + module.exports = (function() { + 'use strict'; + + var Token, + TokenName, + Syntax, + PropertyKind, + Messages, + Regex, + source, + strict, + index, + lineNumber, + lineStart, + length, + lookahead, + state, + extra; + + Token = { + BooleanLiteral: 1, + EOF: 2, + Identifier: 3, + Keyword: 4, + NullLiteral: 5, + NumericLiteral: 6, + Punctuator: 7, + StringLiteral: 8, + RegularExpression: 9 + }; + + TokenName = {}; + TokenName[Token.BooleanLiteral] = 'Boolean'; + TokenName[Token.EOF] = ''; + TokenName[Token.Identifier] = 'Identifier'; + TokenName[Token.Keyword] = 'Keyword'; + TokenName[Token.NullLiteral] = 'Null'; + TokenName[Token.NumericLiteral] = 'Numeric'; + TokenName[Token.Punctuator] = 'Punctuator'; + TokenName[Token.StringLiteral] = 'String'; + TokenName[Token.RegularExpression] = 'RegularExpression'; + + Syntax = { + AssignmentExpression: 'AssignmentExpression', + ArrayExpression: 'ArrayExpression', + BinaryExpression: 'BinaryExpression', + CallExpression: 'CallExpression', + ConditionalExpression: 'ConditionalExpression', + ExpressionStatement: 'ExpressionStatement', + Identifier: 'Identifier', + Literal: 'Literal', + LogicalExpression: 'LogicalExpression', + MemberExpression: 'MemberExpression', + ObjectExpression: 'ObjectExpression', + Program: 'Program', + Property: 'Property', + UnaryExpression: 'UnaryExpression' + }; + + PropertyKind = { + Data: 1, + Get: 2, + Set: 4 + }; + + // Error messages should be identical to V8. + Messages = { + UnexpectedToken: 'Unexpected token %0', + UnexpectedNumber: 'Unexpected number', + UnexpectedString: 'Unexpected string', + UnexpectedIdentifier: 'Unexpected identifier', + UnexpectedReserved: 'Unexpected reserved word', + UnexpectedEOS: 'Unexpected end of input', + NewlineAfterThrow: 'Illegal newline after throw', + InvalidRegExp: 'Invalid regular expression', + UnterminatedRegExp: 'Invalid regular expression: missing /', + InvalidLHSInAssignment: 'Invalid left-hand side in assignment', + InvalidLHSInForIn: 'Invalid left-hand side in for-in', + MultipleDefaultsInSwitch: 'More than one default clause in switch statement', + NoCatchOrFinally: 'Missing catch or finally after try', + UnknownLabel: 'Undefined label \'%0\'', + Redeclaration: '%0 \'%1\' has already been declared', + IllegalContinue: 'Illegal continue statement', + IllegalBreak: 'Illegal break statement', + IllegalReturn: 'Illegal return statement', + StrictModeWith: 'Strict mode code may not include a with statement', + StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode', + StrictVarName: 'Variable name may not be eval or arguments in strict mode', + StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode', + StrictParamDupe: 'Strict mode function may not have duplicate parameter names', + StrictFunctionName: 'Function name may not be eval or arguments in strict mode', + StrictOctalLiteral: 'Octal literals are not allowed in strict mode.', + StrictDelete: 'Delete of an unqualified identifier in strict mode.', + StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode', + AccessorDataProperty: 'Object literal may not have data and accessor property with the same name', + AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name', + StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode', + StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode', + StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode', + StrictReservedWord: 'Use of future reserved word in strict mode' + }; + + // See also tools/generate-unicode-regex.py. + Regex = { + NonAsciiIdentifierStart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]'), + NonAsciiIdentifierPart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]') + }; + + // Ensure the condition is true, otherwise throw an error. + // This is only to have a better contract semantic, i.e. another safety net + // to catch a logic error. The condition shall be fulfilled in normal case. + // Do NOT use this to enforce a certain condition on any user input. + + function assert(condition, message) { + if (!condition) { + throw new Error('ASSERT: ' + message); + } + } + + function isDecimalDigit(ch) { + return (ch >= 0x30 && ch <= 0x39); // 0..9 + } + + function isHexDigit(ch) { + return '0123456789abcdefABCDEF'.indexOf(ch) >= 0; + } + + function isOctalDigit(ch) { + return '01234567'.indexOf(ch) >= 0; + } + + // 7.2 White Space + + function isWhiteSpace(ch) { + return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) || + (ch >= 0x1680 && [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) >= 0); + } + + // 7.3 Line Terminators + + function isLineTerminator(ch) { + return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029); + } + + // 7.6 Identifier Names and Identifiers + + function isIdentifierStart(ch) { + return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore) + (ch >= 0x41 && ch <= 0x5A) || // A..Z + (ch >= 0x61 && ch <= 0x7A) || // a..z + (ch === 0x5C) || // \ (backslash) + ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch))); + } + + function isIdentifierPart(ch) { + return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore) + (ch >= 0x41 && ch <= 0x5A) || // A..Z + (ch >= 0x61 && ch <= 0x7A) || // a..z + (ch >= 0x30 && ch <= 0x39) || // 0..9 + (ch === 0x5C) || // \ (backslash) + ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch))); + } + + // 7.6.1.2 Future Reserved Words + + function isFutureReservedWord(id) { + switch (id) { + case 'class': + case 'enum': + case 'export': + case 'extends': + case 'import': + case 'super': + return true; + default: + return false; + } + } + + function isStrictModeReservedWord(id) { + switch (id) { + case 'implements': + case 'interface': + case 'package': + case 'private': + case 'protected': + case 'public': + case 'static': + case 'yield': + case 'let': + return true; + default: + return false; + } + } + + // 7.6.1.1 Keywords + + function isKeyword(id) { + if (strict && isStrictModeReservedWord(id)) { + return true; + } + + // 'const' is specialized as Keyword in V8. + // 'yield' and 'let' are for compatiblity with SpiderMonkey and ES.next. + // Some others are from future reserved words. + + switch (id.length) { + case 2: + return (id === 'if') || (id === 'in') || (id === 'do'); + case 3: + return (id === 'var') || (id === 'for') || (id === 'new') || + (id === 'try') || (id === 'let'); + case 4: + return (id === 'this') || (id === 'else') || (id === 'case') || + (id === 'void') || (id === 'with') || (id === 'enum'); + case 5: + return (id === 'while') || (id === 'break') || (id === 'catch') || + (id === 'throw') || (id === 'const') || (id === 'yield') || + (id === 'class') || (id === 'super'); + case 6: + return (id === 'return') || (id === 'typeof') || (id === 'delete') || + (id === 'switch') || (id === 'export') || (id === 'import'); + case 7: + return (id === 'default') || (id === 'finally') || (id === 'extends'); + case 8: + return (id === 'function') || (id === 'continue') || (id === 'debugger'); + case 10: + return (id === 'instanceof'); + default: + return false; + } + } + + function skipComment() { + var ch, start; + + start = (index === 0); + while (index < length) { + ch = source.charCodeAt(index); + + if (isWhiteSpace(ch)) { + ++index; + } else if (isLineTerminator(ch)) { + ++index; + if (ch === 0x0D && source.charCodeAt(index) === 0x0A) { + ++index; + } + ++lineNumber; + lineStart = index; + start = true; + } else { + break; + } + } + } + + function scanHexEscape(prefix) { + var i, len, ch, code = 0; + + len = (prefix === 'u') ? 4 : 2; + for (i = 0; i < len; ++i) { + if (index < length && isHexDigit(source[index])) { + ch = source[index++]; + code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); + } else { + return ''; + } + } + return String.fromCharCode(code); + } + + function scanUnicodeCodePointEscape() { + var ch, code, cu1, cu2; + + ch = source[index]; + code = 0; + + // At least, one hex digit is required. + if (ch === '}') { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + while (index < length) { + ch = source[index++]; + if (!isHexDigit(ch)) { + break; + } + code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); + } + + if (code > 0x10FFFF || ch !== '}') { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + // UTF-16 Encoding + if (code <= 0xFFFF) { + return String.fromCharCode(code); + } + cu1 = ((code - 0x10000) >> 10) + 0xD800; + cu2 = ((code - 0x10000) & 1023) + 0xDC00; + return String.fromCharCode(cu1, cu2); + } + + function getEscapedIdentifier() { + var ch, id; + + ch = source.charCodeAt(index++); + id = String.fromCharCode(ch); + + // '\u' (U+005C, U+0075) denotes an escaped character. + if (ch === 0x5C) { + if (source.charCodeAt(index) !== 0x75) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + ++index; + ch = scanHexEscape('u'); + if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + id = ch; + } + + while (index < length) { + ch = source.charCodeAt(index); + if (!isIdentifierPart(ch)) { + break; + } + ++index; + id += String.fromCharCode(ch); + + // '\u' (U+005C, U+0075) denotes an escaped character. + if (ch === 0x5C) { + id = id.substr(0, id.length - 1); + if (source.charCodeAt(index) !== 0x75) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + ++index; + ch = scanHexEscape('u'); + if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + id += ch; + } + } + + return id; + } + + function getIdentifier() { + var start, ch; + + start = index++; + while (index < length) { + ch = source.charCodeAt(index); + if (ch === 0x5C) { + // Blackslash (U+005C) marks Unicode escape sequence. + index = start; + return getEscapedIdentifier(); + } + if (isIdentifierPart(ch)) { + ++index; + } else { + break; + } + } + + return source.slice(start, index); + } + + function scanIdentifier() { + var start, id, type; + + start = index; + + // Backslash (U+005C) starts an escaped character. + id = (source.charCodeAt(index) === 0x5C) ? getEscapedIdentifier() : getIdentifier(); + + // There is no keyword or literal with only one character. + // Thus, it must be an identifier. + if (id.length === 1) { + type = Token.Identifier; + } else if (isKeyword(id)) { + type = Token.Keyword; + } else if (id === 'null') { + type = Token.NullLiteral; + } else if (id === 'true' || id === 'false') { + type = Token.BooleanLiteral; + } else { + type = Token.Identifier; + } + + return { + type: type, + value: id, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // 7.7 Punctuators + + function scanPunctuator() { + var start = index, + code = source.charCodeAt(index), + code2, + ch1 = source[index], + ch2, + ch3, + ch4; + + switch (code) { + + // Check for most common single-character punctuators. + case 0x2E: // . dot + case 0x28: // ( open bracket + case 0x29: // ) close bracket + case 0x3B: // ; semicolon + case 0x2C: // , comma + case 0x7B: // { open curly brace + case 0x7D: // } close curly brace + case 0x5B: // [ + case 0x5D: // ] + case 0x3A: // : + case 0x3F: // ? + case 0x7E: // ~ + ++index; + if (extra.tokenize) { + if (code === 0x28) { + extra.openParenToken = extra.tokens.length; + } else if (code === 0x7B) { + extra.openCurlyToken = extra.tokens.length; + } + } + return { + type: Token.Punctuator, + value: String.fromCharCode(code), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + + default: + code2 = source.charCodeAt(index + 1); + + // '=' (U+003D) marks an assignment or comparison operator. + if (code2 === 0x3D) { + switch (code) { + case 0x2B: // + + case 0x2D: // - + case 0x2F: // / + case 0x3C: // < + case 0x3E: // > + case 0x5E: // ^ + case 0x7C: // | + case 0x25: // % + case 0x26: // & + case 0x2A: // * + index += 2; + return { + type: Token.Punctuator, + value: String.fromCharCode(code) + String.fromCharCode(code2), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + + case 0x21: // ! + case 0x3D: // = + index += 2; + + // !== and === + if (source.charCodeAt(index) === 0x3D) { + ++index; + } + return { + type: Token.Punctuator, + value: source.slice(start, index), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + } + } + + // 4-character punctuator: >>>= + + ch4 = source.substr(index, 4); + + if (ch4 === '>>>=') { + index += 4; + return { + type: Token.Punctuator, + value: ch4, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // 3-character punctuators: === !== >>> <<= >>= + + ch3 = ch4.substr(0, 3); + + if (ch3 === '>>>' || ch3 === '<<=' || ch3 === '>>=') { + index += 3; + return { + type: Token.Punctuator, + value: ch3, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // Other 2-character punctuators: ++ -- << >> && || + ch2 = ch3.substr(0, 2); + + if ((ch1 === ch2[1] && ('+-<>&|'.indexOf(ch1) >= 0)) || ch2 === '=>') { + index += 2; + return { + type: Token.Punctuator, + value: ch2, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // 1-character punctuators: < > = ! + - * % & | ^ / + + if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) { + ++index; + return { + type: Token.Punctuator, + value: ch1, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + // 7.8.3 Numeric Literals + + function scanHexLiteral(start) { + var number = ''; + + while (index < length) { + if (!isHexDigit(source[index])) { + break; + } + number += source[index++]; + } + + if (number.length === 0) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + if (isIdentifierStart(source.charCodeAt(index))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + return { + type: Token.NumericLiteral, + value: parseInt('0x' + number, 16), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + function scanOctalLiteral(start) { + var number = '0' + source[index++]; + while (index < length) { + if (!isOctalDigit(source[index])) { + break; + } + number += source[index++]; + } + + if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + return { + type: Token.NumericLiteral, + value: parseInt(number, 8), + octal: true, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + function scanNumericLiteral() { + var number, start, ch; + + ch = source[index]; + assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'), + 'Numeric literal must start with a decimal digit or a decimal point'); + + start = index; + number = ''; + if (ch !== '.') { + number = source[index++]; + ch = source[index]; + + // Hex number starts with '0x'. + // Octal number starts with '0'. + if (number === '0') { + if (ch === 'x' || ch === 'X') { + ++index; + return scanHexLiteral(start); + } + if (isOctalDigit(ch)) { + return scanOctalLiteral(start); + } + + // decimal number starts with '0' such as '09' is illegal. + if (ch && isDecimalDigit(ch.charCodeAt(0))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } + + while (isDecimalDigit(source.charCodeAt(index))) { + number += source[index++]; + } + ch = source[index]; + } + + if (ch === '.') { + number += source[index++]; + while (isDecimalDigit(source.charCodeAt(index))) { + number += source[index++]; + } + ch = source[index]; + } + + if (ch === 'e' || ch === 'E') { + number += source[index++]; + + ch = source[index]; + if (ch === '+' || ch === '-') { + number += source[index++]; + } + if (isDecimalDigit(source.charCodeAt(index))) { + while (isDecimalDigit(source.charCodeAt(index))) { + number += source[index++]; + } + } else { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } + + if (isIdentifierStart(source.charCodeAt(index))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + return { + type: Token.NumericLiteral, + value: parseFloat(number), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // 7.8.4 String Literals + + function scanStringLiteral() { + var str = '', quote, start, ch, code, unescaped, restore, octal = false, startLineNumber, startLineStart; + startLineNumber = lineNumber; + startLineStart = lineStart; + + quote = source[index]; + assert((quote === '\'' || quote === '"'), + 'String literal must starts with a quote'); + + start = index; + ++index; + + while (index < length) { + ch = source[index++]; + + if (ch === quote) { + quote = ''; + break; + } else if (ch === '\\') { + ch = source[index++]; + if (!ch || !isLineTerminator(ch.charCodeAt(0))) { + switch (ch) { + case 'u': + case 'x': + if (source[index] === '{') { + ++index; + str += scanUnicodeCodePointEscape(); + } else { + restore = index; + unescaped = scanHexEscape(ch); + if (unescaped) { + str += unescaped; + } else { + index = restore; + str += ch; + } + } + break; + case 'n': + str += '\n'; + break; + case 'r': + str += '\r'; + break; + case 't': + str += '\t'; + break; + case 'b': + str += '\b'; + break; + case 'f': + str += '\f'; + break; + case 'v': + str += '\x0B'; + break; + + default: + if (isOctalDigit(ch)) { + code = '01234567'.indexOf(ch); + + // \0 is not octal escape sequence + if (code !== 0) { + octal = true; + } + + if (index < length && isOctalDigit(source[index])) { + octal = true; + code = code * 8 + '01234567'.indexOf(source[index++]); + + // 3 digits are only allowed when string starts + // with 0, 1, 2, 3 + if ('0123'.indexOf(ch) >= 0 && + index < length && + isOctalDigit(source[index])) { + code = code * 8 + '01234567'.indexOf(source[index++]); + } + } + str += String.fromCharCode(code); + } else { + str += ch; + } + break; + } + } else { + ++lineNumber; + if (ch === '\r' && source[index] === '\n') { + ++index; + } + lineStart = index; + } + } else if (isLineTerminator(ch.charCodeAt(0))) { + break; + } else { + str += ch; + } + } + + if (quote !== '') { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + return { + type: Token.StringLiteral, + value: str, + octal: octal, + startLineNumber: startLineNumber, + startLineStart: startLineStart, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + function testRegExp(pattern, flags) { + var tmp = pattern, + value; + + if (flags.indexOf('u') >= 0) { + // Replace each astral symbol and every Unicode code point + // escape sequence with a single ASCII symbol to avoid throwing on + // regular expressions that are only valid in combination with the + // `/u` flag. + // Note: replacing with the ASCII symbol `x` might cause false + // negatives in unlikely scenarios. For example, `[\u{61}-b]` is a + // perfectly valid pattern that is equivalent to `[a-b]`, but it + // would be replaced by `[x-b]` which throws an error. + tmp = tmp + .replace(/\\u\{([0-9a-fA-F]+)\}/g, function ($0, $1) { + if (parseInt($1, 16) <= 0x10FFFF) { + return 'x'; + } + throwError({}, Messages.InvalidRegExp); + }) + .replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, 'x'); + } + + // First, detect invalid regular expressions. + try { + value = new RegExp(tmp); + } catch (e) { + throwError({}, Messages.InvalidRegExp); + } + + // Return a regular expression object for this pattern-flag pair, or + // `null` in case the current environment doesn't support the flags it + // uses. + try { + return new RegExp(pattern, flags); + } catch (exception) { + return null; + } + } + + function scanRegExpBody() { + var ch, str, classMarker, terminated, body; + + ch = source[index]; + assert(ch === '/', 'Regular expression literal must start with a slash'); + str = source[index++]; + + classMarker = false; + terminated = false; + while (index < length) { + ch = source[index++]; + str += ch; + if (ch === '\\') { + ch = source[index++]; + // ECMA-262 7.8.5 + if (isLineTerminator(ch.charCodeAt(0))) { + throwError({}, Messages.UnterminatedRegExp); + } + str += ch; + } else if (isLineTerminator(ch.charCodeAt(0))) { + throwError({}, Messages.UnterminatedRegExp); + } else if (classMarker) { + if (ch === ']') { + classMarker = false; + } + } else { + if (ch === '/') { + terminated = true; + break; + } else if (ch === '[') { + classMarker = true; + } + } + } + + if (!terminated) { + throwError({}, Messages.UnterminatedRegExp); + } + + // Exclude leading and trailing slash. + body = str.substr(1, str.length - 2); + return { + value: body, + literal: str + }; + } + + function scanRegExpFlags() { + var ch, str, flags, restore; + + str = ''; + flags = ''; + while (index < length) { + ch = source[index]; + if (!isIdentifierPart(ch.charCodeAt(0))) { + break; + } + + ++index; + if (ch === '\\' && index < length) { + ch = source[index]; + if (ch === 'u') { + ++index; + restore = index; + ch = scanHexEscape('u'); + if (ch) { + flags += ch; + for (str += '\\u'; restore < index; ++restore) { + str += source[restore]; + } + } else { + index = restore; + flags += 'u'; + str += '\\u'; + } + throwErrorTolerant({}, Messages.UnexpectedToken, 'ILLEGAL'); + } else { + str += '\\'; + throwErrorTolerant({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } else { + flags += ch; + str += ch; + } + } + + return { + value: flags, + literal: str + }; + } + + function scanRegExp() { + var start, body, flags, value; + + lookahead = null; + skipComment(); + start = index; + + body = scanRegExpBody(); + flags = scanRegExpFlags(); + value = testRegExp(body.value, flags.value); + + if (extra.tokenize) { + return { + type: Token.RegularExpression, + value: value, + regex: { + pattern: body.value, + flags: flags.value + }, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + return { + literal: body.literal + flags.literal, + value: value, + regex: { + pattern: body.value, + flags: flags.value + }, + start: start, + end: index + }; + } + + function collectRegex() { + var pos, loc, regex, token; + + skipComment(); + + pos = index; + loc = { + start: { + line: lineNumber, + column: index - lineStart + } + }; + + regex = scanRegExp(); + + loc.end = { + line: lineNumber, + column: index - lineStart + }; + + if (!extra.tokenize) { + // Pop the previous token, which is likely '/' or '/=' + if (extra.tokens.length > 0) { + token = extra.tokens[extra.tokens.length - 1]; + if (token.range[0] === pos && token.type === 'Punctuator') { + if (token.value === '/' || token.value === '/=') { + extra.tokens.pop(); + } + } + } + + extra.tokens.push({ + type: 'RegularExpression', + value: regex.literal, + regex: regex.regex, + range: [pos, index], + loc: loc + }); + } + + return regex; + } + + function isIdentifierName(token) { + return token.type === Token.Identifier || + token.type === Token.Keyword || + token.type === Token.BooleanLiteral || + token.type === Token.NullLiteral; + } + + function advanceSlash() { + var prevToken, + checkToken; + // Using the following algorithm: + // https://github.com/mozilla/sweet.js/wiki/design + prevToken = extra.tokens[extra.tokens.length - 1]; + if (!prevToken) { + // Nothing before that: it cannot be a division. + return collectRegex(); + } + if (prevToken.type === 'Punctuator') { + if (prevToken.value === ']') { + return scanPunctuator(); + } + if (prevToken.value === ')') { + checkToken = extra.tokens[extra.openParenToken - 1]; + if (checkToken && + checkToken.type === 'Keyword' && + (checkToken.value === 'if' || + checkToken.value === 'while' || + checkToken.value === 'for' || + checkToken.value === 'with')) { + return collectRegex(); + } + return scanPunctuator(); + } + if (prevToken.value === '}') { + // Dividing a function by anything makes little sense, + // but we have to check for that. + if (extra.tokens[extra.openCurlyToken - 3] && + extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') { + // Anonymous function. + checkToken = extra.tokens[extra.openCurlyToken - 4]; + if (!checkToken) { + return scanPunctuator(); + } + } else if (extra.tokens[extra.openCurlyToken - 4] && + extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') { + // Named function. + checkToken = extra.tokens[extra.openCurlyToken - 5]; + if (!checkToken) { + return collectRegex(); + } + } else { + return scanPunctuator(); + } + return scanPunctuator(); + } + return collectRegex(); + } + if (prevToken.type === 'Keyword' && prevToken.value !== 'this') { + return collectRegex(); + } + return scanPunctuator(); + } + + function advance() { + var ch; + + skipComment(); + + if (index >= length) { + return { + type: Token.EOF, + lineNumber: lineNumber, + lineStart: lineStart, + start: index, + end: index + }; + } + + ch = source.charCodeAt(index); + + if (isIdentifierStart(ch)) { + return scanIdentifier(); + } + + // Very common: ( and ) and ; + if (ch === 0x28 || ch === 0x29 || ch === 0x3B) { + return scanPunctuator(); + } + + // String literal starts with single quote (U+0027) or double quote (U+0022). + if (ch === 0x27 || ch === 0x22) { + return scanStringLiteral(); + } + + + // Dot (.) U+002E can also start a floating-point number, hence the need + // to check the next character. + if (ch === 0x2E) { + if (isDecimalDigit(source.charCodeAt(index + 1))) { + return scanNumericLiteral(); + } + return scanPunctuator(); + } + + if (isDecimalDigit(ch)) { + return scanNumericLiteral(); + } + + // Slash (/) U+002F can also start a regex. + if (extra.tokenize && ch === 0x2F) { + return advanceSlash(); + } + + return scanPunctuator(); + } + + function collectToken() { + var loc, token, value, entry; + + skipComment(); + loc = { + start: { + line: lineNumber, + column: index - lineStart + } + }; + + token = advance(); + loc.end = { + line: lineNumber, + column: index - lineStart + }; + + if (token.type !== Token.EOF) { + value = source.slice(token.start, token.end); + entry = { + type: TokenName[token.type], + value: value, + range: [token.start, token.end], + loc: loc + }; + if (token.regex) { + entry.regex = { + pattern: token.regex.pattern, + flags: token.regex.flags + }; + } + extra.tokens.push(entry); + } + + return token; + } + + function lex() { + var token; + + token = lookahead; + index = token.end; + lineNumber = token.lineNumber; + lineStart = token.lineStart; + + lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance(); + + index = token.end; + lineNumber = token.lineNumber; + lineStart = token.lineStart; + + return token; + } + + function peek() { + var pos, line, start; + + pos = index; + line = lineNumber; + start = lineStart; + lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance(); + index = pos; + lineNumber = line; + lineStart = start; + } + + function Position() { + this.line = lineNumber; + this.column = index - lineStart; + } + + function SourceLocation() { + this.start = new Position(); + this.end = null; + } + + function WrappingSourceLocation(startToken) { + if (startToken.type === Token.StringLiteral) { + this.start = { + line: startToken.startLineNumber, + column: startToken.start - startToken.startLineStart + }; + } else { + this.start = { + line: startToken.lineNumber, + column: startToken.start - startToken.lineStart + }; + } + this.end = null; + } + + function Node() { + // Skip comment. + index = lookahead.start; + if (lookahead.type === Token.StringLiteral) { + lineNumber = lookahead.startLineNumber; + lineStart = lookahead.startLineStart; + } else { + lineNumber = lookahead.lineNumber; + lineStart = lookahead.lineStart; + } + if (extra.range) { + this.range = [index, 0]; + } + if (extra.loc) { + this.loc = new SourceLocation(); + } + } + + function WrappingNode(startToken) { + if (extra.range) { + this.range = [startToken.start, 0]; + } + if (extra.loc) { + this.loc = new WrappingSourceLocation(startToken); + } + } + + WrappingNode.prototype = Node.prototype = { + + finish: function () { + if (extra.range) { + this.range[1] = index; + } + if (extra.loc) { + this.loc.end = new Position(); + if (extra.source) { + this.loc.source = extra.source; + } + } + }, + + finishArrayExpression: function (elements) { + this.type = Syntax.ArrayExpression; + this.elements = elements; + this.finish(); + return this; + }, + + finishAssignmentExpression: function (operator, left, right) { + this.type = Syntax.AssignmentExpression; + this.operator = operator; + this.left = left; + this.right = right; + this.finish(); + return this; + }, + + finishBinaryExpression: function (operator, left, right) { + this.type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression : Syntax.BinaryExpression; + this.operator = operator; + this.left = left; + this.right = right; + this.finish(); + return this; + }, + + finishCallExpression: function (callee, args) { + this.type = Syntax.CallExpression; + this.callee = callee; + this.arguments = args; + this.finish(); + return this; + }, + + finishConditionalExpression: function (test, consequent, alternate) { + this.type = Syntax.ConditionalExpression; + this.test = test; + this.consequent = consequent; + this.alternate = alternate; + this.finish(); + return this; + }, + + finishExpressionStatement: function (expression) { + this.type = Syntax.ExpressionStatement; + this.expression = expression; + this.finish(); + return this; + }, + + finishIdentifier: function (name) { + this.type = Syntax.Identifier; + this.name = name; + this.finish(); + return this; + }, + + finishLiteral: function (token) { + this.type = Syntax.Literal; + this.value = token.value; + this.raw = source.slice(token.start, token.end); + if (token.regex) { + if (this.raw == '//') { + this.raw = '/(?:)/'; + } + this.regex = token.regex; + } + this.finish(); + return this; + }, + + finishMemberExpression: function (accessor, object, property) { + this.type = Syntax.MemberExpression; + this.computed = accessor === '['; + this.object = object; + this.property = property; + this.finish(); + return this; + }, + + finishObjectExpression: function (properties) { + this.type = Syntax.ObjectExpression; + this.properties = properties; + this.finish(); + return this; + }, + + finishProgram: function (body) { + this.type = Syntax.Program; + this.body = body; + this.finish(); + return this; + }, + + finishProperty: function (kind, key, value) { + this.type = Syntax.Property; + this.key = key; + this.value = value; + this.kind = kind; + this.finish(); + return this; + }, + + finishUnaryExpression: function (operator, argument) { + this.type = Syntax.UnaryExpression; + this.operator = operator; + this.argument = argument; + this.prefix = true; + this.finish(); + return this; + } + }; + + // Return true if there is a line terminator before the next token. + + function peekLineTerminator() { + var pos, line, start, found; + + pos = index; + line = lineNumber; + start = lineStart; + skipComment(); + found = lineNumber !== line; + index = pos; + lineNumber = line; + lineStart = start; + + return found; + } + + // Throw an exception + + function throwError(token, messageFormat) { + var error, + args = Array.prototype.slice.call(arguments, 2), + msg = messageFormat.replace( + /%(\d)/g, + function (whole, index) { + assert(index < args.length, 'Message reference must be in range'); + return args[index]; + } + ); + + if (typeof token.lineNumber === 'number') { + error = new Error('Line ' + token.lineNumber + ': ' + msg); + error.index = token.start; + error.lineNumber = token.lineNumber; + error.column = token.start - lineStart + 1; + } else { + error = new Error('Line ' + lineNumber + ': ' + msg); + error.index = index; + error.lineNumber = lineNumber; + error.column = index - lineStart + 1; + } + + error.description = msg; + throw error; + } + + function throwErrorTolerant() { + try { + throwError.apply(null, arguments); + } catch (e) { + if (extra.errors) { + extra.errors.push(e); + } else { + throw e; + } + } + } + + + // Throw an exception because of the token. + + function throwUnexpected(token) { + if (token.type === Token.EOF) { + throwError(token, Messages.UnexpectedEOS); + } + + if (token.type === Token.NumericLiteral) { + throwError(token, Messages.UnexpectedNumber); + } + + if (token.type === Token.StringLiteral) { + throwError(token, Messages.UnexpectedString); + } + + if (token.type === Token.Identifier) { + throwError(token, Messages.UnexpectedIdentifier); + } + + if (token.type === Token.Keyword) { + if (isFutureReservedWord(token.value)) { + throwError(token, Messages.UnexpectedReserved); + } else if (strict && isStrictModeReservedWord(token.value)) { + throwErrorTolerant(token, Messages.StrictReservedWord); + return; + } + throwError(token, Messages.UnexpectedToken, token.value); + } + + // BooleanLiteral, NullLiteral, or Punctuator. + throwError(token, Messages.UnexpectedToken, token.value); + } + + // Expect the next token to match the specified punctuator. + // If not, an exception will be thrown. + + function expect(value) { + var token = lex(); + if (token.type !== Token.Punctuator || token.value !== value) { + throwUnexpected(token); + } + } + + /** + * @name expectTolerant + * @description Quietly expect the given token value when in tolerant mode, otherwise delegates + * to expect(value) + * @param {String} value The value we are expecting the lookahead token to have + * @since 2.0 + */ + function expectTolerant(value) { + if (extra.errors) { + var token = lookahead; + if (token.type !== Token.Punctuator && token.value !== value) { + throwErrorTolerant(token, Messages.UnexpectedToken, token.value); + } else { + lex(); + } + } else { + expect(value); + } + } + + // Return true if the next token matches the specified punctuator. + + function match(value) { + return lookahead.type === Token.Punctuator && lookahead.value === value; + } + + // Return true if the next token matches the specified keyword + + function matchKeyword(keyword) { + return lookahead.type === Token.Keyword && lookahead.value === keyword; + } + + function consumeSemicolon() { + var line; + + // Catch the very common case first: immediately a semicolon (U+003B). + if (source.charCodeAt(index) === 0x3B || match(';')) { + lex(); + return; + } + + line = lineNumber; + skipComment(); + if (lineNumber !== line) { + return; + } + + if (lookahead.type !== Token.EOF && !match('}')) { + throwUnexpected(lookahead); + } + } + + // 11.1.4 Array Initialiser + + function parseArrayInitialiser() { + var elements = [], node = new Node(); + + expect('['); + + while (!match(']')) { + if (match(',')) { + lex(); + elements.push(null); + } else { + elements.push(parseAssignmentExpression()); + + if (!match(']')) { + expect(','); + } + } + } + + lex(); + + return node.finishArrayExpression(elements); + } + + // 11.1.5 Object Initialiser + + function parseObjectPropertyKey() { + var token, node = new Node(); + + token = lex(); + + // Note: This function is called only from parseObjectProperty(), where + // EOF and Punctuator tokens are already filtered out. + + if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) { + if (strict && token.octal) { + throwErrorTolerant(token, Messages.StrictOctalLiteral); + } + return node.finishLiteral(token); + } + + return node.finishIdentifier(token.value); + } + + function parseObjectProperty() { + var token, key, id, value, node = new Node(); + + token = lookahead; + + if (token.type === Token.Identifier) { + id = parseObjectPropertyKey(); + expect(':'); + value = parseAssignmentExpression(); + return node.finishProperty('init', id, value); + } + if (token.type === Token.EOF || token.type === Token.Punctuator) { + throwUnexpected(token); + } else { + key = parseObjectPropertyKey(); + expect(':'); + value = parseAssignmentExpression(); + return node.finishProperty('init', key, value); + } + } + + function parseObjectInitialiser() { + var properties = [], property, name, key, kind, map = {}, toString = String, node = new Node(); + + expect('{'); + + while (!match('}')) { + property = parseObjectProperty(); + + if (property.key.type === Syntax.Identifier) { + name = property.key.name; + } else { + name = toString(property.key.value); + } + kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set; + + key = '$' + name; + if (Object.prototype.hasOwnProperty.call(map, key)) { + if (map[key] === PropertyKind.Data) { + if (strict && kind === PropertyKind.Data) { + throwErrorTolerant({}, Messages.StrictDuplicateProperty); + } else if (kind !== PropertyKind.Data) { + throwErrorTolerant({}, Messages.AccessorDataProperty); + } + } else { + if (kind === PropertyKind.Data) { + throwErrorTolerant({}, Messages.AccessorDataProperty); + } else if (map[key] & kind) { + throwErrorTolerant({}, Messages.AccessorGetSet); + } + } + map[key] |= kind; + } else { + map[key] = kind; + } + + properties.push(property); + + if (!match('}')) { + expectTolerant(','); + } + } + + expect('}'); + + return node.finishObjectExpression(properties); + } + + // 11.1.6 The Grouping Operator + + function parseGroupExpression() { + var expr; + + expect('('); + + ++state.parenthesisCount; + + expr = parseExpression(); + + expect(')'); + + return expr; + } + + + // 11.1 Primary Expressions + + var legalKeywords = {"if":1, "this":1}; + + function parsePrimaryExpression() { + var type, token, expr, node; + + if (match('(')) { + return parseGroupExpression(); + } + + if (match('[')) { + return parseArrayInitialiser(); + } + + if (match('{')) { + return parseObjectInitialiser(); + } + + type = lookahead.type; + node = new Node(); + + if (type === Token.Identifier || legalKeywords[lookahead.value]) { + expr = node.finishIdentifier(lex().value); + } else if (type === Token.StringLiteral || type === Token.NumericLiteral) { + if (strict && lookahead.octal) { + throwErrorTolerant(lookahead, Messages.StrictOctalLiteral); + } + expr = node.finishLiteral(lex()); + } else if (type === Token.Keyword) { + throw new Error("Disabled."); + } else if (type === Token.BooleanLiteral) { + token = lex(); + token.value = (token.value === 'true'); + expr = node.finishLiteral(token); + } else if (type === Token.NullLiteral) { + token = lex(); + token.value = null; + expr = node.finishLiteral(token); + } else if (match('/') || match('/=')) { + if (typeof extra.tokens !== 'undefined') { + expr = node.finishLiteral(collectRegex()); + } else { + expr = node.finishLiteral(scanRegExp()); + } + peek(); + } else { + throwUnexpected(lex()); + } + + return expr; + } + + // 11.2 Left-Hand-Side Expressions + + function parseArguments() { + var args = []; + + expect('('); + + if (!match(')')) { + while (index < length) { + args.push(parseAssignmentExpression()); + if (match(')')) { + break; + } + expectTolerant(','); + } + } + + expect(')'); + + return args; + } + + function parseNonComputedProperty() { + var token, node = new Node(); + + token = lex(); + + if (!isIdentifierName(token)) { + throwUnexpected(token); + } + + return node.finishIdentifier(token.value); + } + + function parseNonComputedMember() { + expect('.'); + + return parseNonComputedProperty(); + } + + function parseComputedMember() { + var expr; + + expect('['); + + expr = parseExpression(); + + expect(']'); + + return expr; + } + + function parseLeftHandSideExpressionAllowCall() { + var expr, args, property, startToken, previousAllowIn = state.allowIn; + + startToken = lookahead; + state.allowIn = true; + expr = parsePrimaryExpression(); + + for (;;) { + if (match('.')) { + property = parseNonComputedMember(); + expr = new WrappingNode(startToken).finishMemberExpression('.', expr, property); + } else if (match('(')) { + args = parseArguments(); + expr = new WrappingNode(startToken).finishCallExpression(expr, args); + } else if (match('[')) { + property = parseComputedMember(); + expr = new WrappingNode(startToken).finishMemberExpression('[', expr, property); + } else { + break; + } + } + state.allowIn = previousAllowIn; + + return expr; + } + + // 11.3 Postfix Expressions + + function parsePostfixExpression() { + var expr = parseLeftHandSideExpressionAllowCall(); + + if (lookahead.type === Token.Punctuator) { + if ((match('++') || match('--')) && !peekLineTerminator()) { + throw new Error("Disabled."); + } + } + + return expr; + } + + // 11.4 Unary Operators + + function parseUnaryExpression() { + var token, expr, startToken; + + if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) { + expr = parsePostfixExpression(); + } else if (match('++') || match('--')) { + throw new Error("Disabled."); + } else if (match('+') || match('-') || match('~') || match('!')) { + startToken = lookahead; + token = lex(); + expr = parseUnaryExpression(); + expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr); + } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) { + throw new Error("Disabled."); + } else { + expr = parsePostfixExpression(); + } + + return expr; + } + + function binaryPrecedence(token, allowIn) { + var prec = 0; + + if (token.type !== Token.Punctuator && token.type !== Token.Keyword) { + return 0; + } + + switch (token.value) { + case '||': + prec = 1; + break; + + case '&&': + prec = 2; + break; + + case '|': + prec = 3; + break; + + case '^': + prec = 4; + break; + + case '&': + prec = 5; + break; + + case '==': + case '!=': + case '===': + case '!==': + prec = 6; + break; + + case '<': + case '>': + case '<=': + case '>=': + case 'instanceof': + prec = 7; + break; + + case 'in': + prec = allowIn ? 7 : 0; + break; + + case '<<': + case '>>': + case '>>>': + prec = 8; + break; + + case '+': + case '-': + prec = 9; + break; + + case '*': + case '/': + case '%': + prec = 11; + break; + + default: + break; + } + + return prec; + } + + // 11.5 Multiplicative Operators + // 11.6 Additive Operators + // 11.7 Bitwise Shift Operators + // 11.8 Relational Operators + // 11.9 Equality Operators + // 11.10 Binary Bitwise Operators + // 11.11 Binary Logical Operators + + function parseBinaryExpression() { + var marker, markers, expr, token, prec, stack, right, operator, left, i; + + marker = lookahead; + left = parseUnaryExpression(); + + token = lookahead; + prec = binaryPrecedence(token, state.allowIn); + if (prec === 0) { + return left; + } + token.prec = prec; + lex(); + + markers = [marker, lookahead]; + right = parseUnaryExpression(); + + stack = [left, token, right]; + + while ((prec = binaryPrecedence(lookahead, state.allowIn)) > 0) { + + // Reduce: make a binary expression from the three topmost entries. + while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) { + right = stack.pop(); + operator = stack.pop().value; + left = stack.pop(); + markers.pop(); + expr = new WrappingNode(markers[markers.length - 1]).finishBinaryExpression(operator, left, right); + stack.push(expr); + } + + // Shift. + token = lex(); + token.prec = prec; + stack.push(token); + markers.push(lookahead); + expr = parseUnaryExpression(); + stack.push(expr); + } + + // Final reduce to clean-up the stack. + i = stack.length - 1; + expr = stack[i]; + markers.pop(); + while (i > 1) { + expr = new WrappingNode(markers.pop()).finishBinaryExpression(stack[i - 1].value, stack[i - 2], expr); + i -= 2; + } + + return expr; + } + + // 11.12 Conditional Operator + + function parseConditionalExpression() { + var expr, previousAllowIn, consequent, alternate, startToken; + + startToken = lookahead; + + expr = parseBinaryExpression(); + + if (match('?')) { + lex(); + previousAllowIn = state.allowIn; + state.allowIn = true; + consequent = parseAssignmentExpression(); + state.allowIn = previousAllowIn; + expect(':'); + alternate = parseAssignmentExpression(); + + expr = new WrappingNode(startToken).finishConditionalExpression(expr, consequent, alternate); + } + + return expr; + } + + // 11.13 Assignment Operators + + function parseAssignmentExpression() { + var oldParenthesisCount, token, expr, startToken; + + oldParenthesisCount = state.parenthesisCount; + + startToken = lookahead; + token = lookahead; + + expr = parseConditionalExpression(); + + return expr; + } + + // 11.14 Comma Operator + + function parseExpression() { + var expr = parseAssignmentExpression(); + + if (match(',')) { + throw new Error("Disabled."); // no sequence expressions + } + + return expr; + } + + // 12.4 Expression Statement + + function parseExpressionStatement(node) { + var expr = parseExpression(); + consumeSemicolon(); + return node.finishExpressionStatement(expr); + } + + // 12 Statements + + function parseStatement() { + var type = lookahead.type, + expr, + node; + + if (type === Token.EOF) { + throwUnexpected(lookahead); + } + + if (type === Token.Punctuator && lookahead.value === '{') { + throw new Error("Disabled."); // block statement + } + + node = new Node(); + + if (type === Token.Punctuator) { + switch (lookahead.value) { + case ';': + throw new Error("Disabled."); // empty statement + case '(': + return parseExpressionStatement(node); + default: + break; + } + } else if (type === Token.Keyword) { + throw new Error("Disabled."); // keyword + } + + expr = parseExpression(); + consumeSemicolon(); + return node.finishExpressionStatement(expr); + } + + // 14 Program + + function parseSourceElement() { + if (lookahead.type === Token.Keyword) { + switch (lookahead.value) { + case 'const': + case 'let': + throw new Error("Disabled."); + case 'function': + throw new Error("Disabled."); + default: + return parseStatement(); + } + } + + if (lookahead.type !== Token.EOF) { + return parseStatement(); + } + } + + function parseSourceElements() { + var sourceElement, sourceElements = [], token, directive, firstRestricted; + + while (index < length) { + token = lookahead; + if (token.type !== Token.StringLiteral) { + break; + } + + sourceElement = parseSourceElement(); + sourceElements.push(sourceElement); + if (sourceElement.expression.type !== Syntax.Literal) { + // this is not directive + break; + } + directive = source.slice(token.start + 1, token.end - 1); + if (directive === 'use strict') { + strict = true; + if (firstRestricted) { + throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral); + } + } else { + if (!firstRestricted && token.octal) { + firstRestricted = token; + } + } + } + + while (index < length) { + sourceElement = parseSourceElement(); + if (typeof sourceElement === 'undefined') { + break; + } + sourceElements.push(sourceElement); + } + return sourceElements; + } + + function parseProgram() { + var body, node; + + skipComment(); + peek(); + node = new Node(); + strict = true; // assume strict + + body = parseSourceElements(); + return node.finishProgram(body); + } + + function filterTokenLocation() { + var i, entry, token, tokens = []; + + for (i = 0; i < extra.tokens.length; ++i) { + entry = extra.tokens[i]; + token = { + type: entry.type, + value: entry.value + }; + if (entry.regex) { + token.regex = { + pattern: entry.regex.pattern, + flags: entry.regex.flags + }; + } + if (extra.range) { + token.range = entry.range; + } + if (extra.loc) { + token.loc = entry.loc; + } + tokens.push(token); + } + + extra.tokens = tokens; + } + + function tokenize(code, options) { + var toString, + tokens; + + toString = String; + if (typeof code !== 'string' && !(code instanceof String)) { + code = toString(code); + } + + source = code; + index = 0; + lineNumber = (source.length > 0) ? 1 : 0; + lineStart = 0; + length = source.length; + lookahead = null; + state = { + allowIn: true, + labelSet: {}, + inFunctionBody: false, + inIteration: false, + inSwitch: false, + lastCommentStart: -1 + }; + + extra = {}; + + // Options matching. + options = options || {}; + + // Of course we collect tokens here. + options.tokens = true; + extra.tokens = []; + extra.tokenize = true; + // The following two fields are necessary to compute the Regex tokens. + extra.openParenToken = -1; + extra.openCurlyToken = -1; + + extra.range = (typeof options.range === 'boolean') && options.range; + extra.loc = (typeof options.loc === 'boolean') && options.loc; + + if (typeof options.tolerant === 'boolean' && options.tolerant) { + extra.errors = []; + } + + try { + peek(); + if (lookahead.type === Token.EOF) { + return extra.tokens; + } + + lex(); + while (lookahead.type !== Token.EOF) { + try { + lex(); + } catch (lexError) { + if (extra.errors) { + extra.errors.push(lexError); + // We have to break on the first error + // to avoid infinite loops. + break; + } else { + throw lexError; + } + } + } + + filterTokenLocation(); + tokens = extra.tokens; + if (typeof extra.errors !== 'undefined') { + tokens.errors = extra.errors; + } + } catch (e) { + throw e; + } finally { + extra = {}; + } + return tokens; + } + + function parse(code, options) { + var program, toString; + + toString = String; + if (typeof code !== 'string' && !(code instanceof String)) { + code = toString(code); + } + + source = code; + index = 0; + lineNumber = (source.length > 0) ? 1 : 0; + lineStart = 0; + length = source.length; + lookahead = null; + state = { + allowIn: true, + labelSet: {}, + parenthesisCount: 0, + inFunctionBody: false, + inIteration: false, + inSwitch: false, + lastCommentStart: -1 + }; + + extra = {}; + if (typeof options !== 'undefined') { + extra.range = (typeof options.range === 'boolean') && options.range; + extra.loc = (typeof options.loc === 'boolean') && options.loc; + + if (extra.loc && options.source !== null && options.source !== undefined) { + extra.source = toString(options.source); + } + + if (typeof options.tokens === 'boolean' && options.tokens) { + extra.tokens = []; + } + if (typeof options.tolerant === 'boolean' && options.tolerant) { + extra.errors = []; + } + } + + try { + program = parseProgram(); + if (typeof extra.tokens !== 'undefined') { + filterTokenLocation(); + program.tokens = extra.tokens; + } + if (typeof extra.errors !== 'undefined') { + program.errors = extra.errors; + } + } catch (e) { + throw e; + } finally { + extra = {}; + } + + return program; + } + + return { + tokenize: tokenize, + parse: parse + }; + + })(); +},{}],47:[function(require,module,exports){ + var ts = Date.now(); + + function write(msg) { + msg = '[Vega Log] ' + msg; + console.log(msg); + } + + function error(msg) { + msg = '[Vega Err] ' + msg; + console.error(msg); + } + + function debug(input, args) { + if (!debug.enable) return; + var log = Function.prototype.bind.call(console.log, console); + var state = { + prevTime: Date.now() - ts, + stamp: input.stamp + }; + + if (input.add) { + state.add = input.add.length; + state.mod = input.mod.length; + state.rem = input.rem.length; + state.reflow = !!input.reflow; + } + + log.apply(console, (args.push(JSON.stringify(state)), args)); + ts = Date.now(); + } + + module.exports = { + log: write, + error: error, + debug: (debug.enable = false, debug) + }; + +},{}],48:[function(require,module,exports){ + module.exports = { + path: require('./path'), + render: require('./render'), + Item: require('./util/Item'), + bound: require('./util/bound'), + Bounds: require('./util/Bounds'), + canvas: require('./util/canvas'), + Gradient: require('./util/Gradient'), + toJSON: require('./util/scene').toJSON, + fromJSON: require('./util/scene').fromJSON + }; +},{"./path":50,"./render":70,"./util/Bounds":76,"./util/Gradient":78,"./util/Item":80,"./util/bound":81,"./util/canvas":82,"./util/scene":84}],49:[function(require,module,exports){ + var segmentCache = {}, + bezierCache = {}, + join = [].join; + +// Copied from Inkscape svgtopdf, thanks! + function segments(x, y, rx, ry, large, sweep, rotateX, ox, oy) { + var key = join.call(arguments); + if (segmentCache[key]) { + return segmentCache[key]; + } + + var th = rotateX * (Math.PI/180); + var sin_th = Math.sin(th); + var cos_th = Math.cos(th); + rx = Math.abs(rx); + ry = Math.abs(ry); + var px = cos_th * (ox - x) * 0.5 + sin_th * (oy - y) * 0.5; + var py = cos_th * (oy - y) * 0.5 - sin_th * (ox - x) * 0.5; + var pl = (px*px) / (rx*rx) + (py*py) / (ry*ry); + if (pl > 1) { + pl = Math.sqrt(pl); + rx *= pl; + ry *= pl; + } + + var a00 = cos_th / rx; + var a01 = sin_th / rx; + var a10 = (-sin_th) / ry; + var a11 = (cos_th) / ry; + var x0 = a00 * ox + a01 * oy; + var y0 = a10 * ox + a11 * oy; + var x1 = a00 * x + a01 * y; + var y1 = a10 * x + a11 * y; + + var d = (x1-x0) * (x1-x0) + (y1-y0) * (y1-y0); + var sfactor_sq = 1 / d - 0.25; + if (sfactor_sq < 0) sfactor_sq = 0; + var sfactor = Math.sqrt(sfactor_sq); + if (sweep == large) sfactor = -sfactor; + var xc = 0.5 * (x0 + x1) - sfactor * (y1-y0); + var yc = 0.5 * (y0 + y1) + sfactor * (x1-x0); + + var th0 = Math.atan2(y0-yc, x0-xc); + var th1 = Math.atan2(y1-yc, x1-xc); + + var th_arc = th1-th0; + if (th_arc < 0 && sweep === 1){ + th_arc += 2 * Math.PI; + } else if (th_arc > 0 && sweep === 0) { + th_arc -= 2 * Math.PI; + } + + var segs = Math.ceil(Math.abs(th_arc / (Math.PI * 0.5 + 0.001))); + var result = []; + for (var i=0; i len) { + for (j=1, m=parsed.length; j=0;) { + if (h[i].type !== type) continue; + if (!handler || h[i].handler === handler) h.splice(i, 1); + } + return this; + }; + + prototype.pickEvent = function(evt) { + var rect = this._canvas.getBoundingClientRect(), + pad = this._padding, x, y; + return this.pick(this._scene, + x = (evt.clientX - rect.left), + y = (evt.clientY - rect.top), + x - pad.left, y - pad.top); + }; + +// find the scenegraph item at the current mouse position +// x, y -- the absolute x, y mouse coordinates on the canvas element +// gx, gy -- the relative coordinates within the current group + prototype.pick = function(scene, x, y, gx, gy) { + var g = this.context(), + mark = marks[scene.marktype]; + return mark.pick.call(this, g, scene, x, y, gx, gy); + }; + + module.exports = CanvasHandler; + +},{"../../util/dom":83,"../Handler":53,"./marks":62}],56:[function(require,module,exports){ + var DOM = require('../../util/dom'), + Bounds = require('../../util/Bounds'), + ImageLoader = require('../../util/ImageLoader'), + Canvas = require('../../util/canvas'), + Renderer = require('../Renderer'), + marks = require('./marks'); + + function CanvasRenderer(loadConfig) { + Renderer.call(this); + this._loader = new ImageLoader(loadConfig); + } + + CanvasRenderer.RETINA = true; + + var base = Renderer.prototype; + var prototype = (CanvasRenderer.prototype = Object.create(base)); + prototype.constructor = CanvasRenderer; + + prototype.initialize = function(el, width, height, padding) { + this._canvas = Canvas.instance(width, height); + if (el) { + DOM.clear(el, 0).appendChild(this._canvas); + this._canvas.setAttribute('class', 'marks'); + } + return base.initialize.call(this, el, width, height, padding); + }; + + prototype.resize = function(width, height, padding) { + base.resize.call(this, width, height, padding); + Canvas.resize(this._canvas, this._width, this._height, + this._padding, CanvasRenderer.RETINA); + return this; + }; + + prototype.canvas = function() { + return this._canvas; + }; + + prototype.context = function() { + return this._canvas ? this._canvas.getContext('2d') : null; + }; + + prototype.pendingImages = function() { + return this._loader.pending(); + }; + + function clipToBounds(g, items) { + if (!items) return null; + + var b = new Bounds(), i, n, item, mark, group; + for (i=0, n=items.length; i 0) { + if (group.fill && util.fill(g, group, opac)) { + g.fillRect(gx, gy, w, h); + } + if (group.stroke && util.stroke(g, group, opac)) { + g.strokeRect(gx, gy, w, h); + } + } + } + + // setup graphics context + g.save(); + g.translate(gx, gy); + if (group.clip) { + g.beginPath(); + g.rect(0, 0, w, h); + g.clip(); + } + if (bounds) bounds.translate(-gx, -gy); + + // draw group contents + for (j=0, m=axes.length; j=0;) { + group = groups[i]; + + // first hit test against bounding box + // if a group is clipped, that should be handled by the bounds check. + b = group.bounds; + if (b && !b.contains(gx, gy)) continue; + + // passed bounds check, so test sub-groups + axes = group.axisItems || EMPTY; + items = group.items || EMPTY; + legends = group.legendItems || EMPTY; + dx = (group.x || 0); + dy = (group.y || 0); + + g.save(); + g.translate(dx, dy); + dx = gx - dx; + dy = gy - dy; + for (j=legends.length; --j>=0;) { + subscene = legends[j]; + if (subscene.interactive !== false) { + hits = this.pick(subscene, x, y, dx, dy); + if (hits) { g.restore(); return hits; } + } + } + for (j=axes.length; --j>=0;) { + subscene = axes[j]; + if (subscene.interactive !== false && subscene.layer !== 'back') { + hits = this.pick(subscene, x, y, dx, dy); + if (hits) { g.restore(); return hits; } + } + } + for (j=items.length; --j>=0;) { + subscene = items[j]; + if (subscene.interactive !== false) { + hits = this.pick(subscene, x, y, dx, dy); + if (hits) { g.restore(); return hits; } + } + } + for (j=axes.length; --j>=0;) { + subscene = axes[j]; + if (subscene.interative !== false && subscene.layer === 'back') { + hits = this.pick(subscene, x, y, dx, dy); + if (hits) { g.restore(); return hits; } + } + } + g.restore(); + + if (scene.interactive !== false && (group.fill || group.stroke) && + dx >= 0 && dx <= group.width && dy >= 0 && dy <= group.height) { + return group; + } + } + + return null; + } + + module.exports = { + draw: draw, + pick: pick + }; + +},{"./util":69}],61:[function(require,module,exports){ + var util = require('./util'); + + function draw(g, scene, bounds) { + if (!scene.items || !scene.items.length) return; + + var renderer = this, + items = scene.items, o; + + for (var i=0, len=items.length; i= 0;) { + o = scene.items[i]; b = o.bounds; + // first hit test against bounding box + if ((b && !b.contains(gx, gy)) || !b) continue; + // if in bounding box, perform more careful test + if (test(g, o, x, y, gx, gy)) return o; + } + return null; + }; + } + + function testPath(path, filled) { + return function(g, o, x, y) { + var item = Array.isArray(o) ? o[0] : o, + fill = (filled == null) ? item.fill : filled, + stroke = item.stroke && g.isPointInStroke, lw, lc; + + if (stroke) { + lw = item.strokeWidth; + lc = item.strokeCap; + g.lineWidth = lw != null ? lw : 1; + g.lineCap = lc != null ? lc : 'butt'; + } + + return path(g, o) ? false : + (fill && g.isPointInPath(x, y)) || + (stroke && g.isPointInStroke(x, y)); + }; + } + + function pickPath(path) { + return pick(testPath(path)); + } + + function fill(g, o, opacity) { + opacity *= (o.fillOpacity==null ? 1 : o.fillOpacity); + if (opacity > 0) { + g.globalAlpha = opacity; + g.fillStyle = color(g, o, o.fill); + return true; + } else { + return false; + } + } + + function stroke(g, o, opacity) { + var lw = (lw = o.strokeWidth) != null ? lw : 1, lc; + if (lw <= 0) return false; + + opacity *= (o.strokeOpacity==null ? 1 : o.strokeOpacity); + if (opacity > 0) { + g.globalAlpha = opacity; + g.strokeStyle = color(g, o, o.stroke); + g.lineWidth = lw; + g.lineCap = (lc = o.strokeCap) != null ? lc : 'butt'; + g.vgLineDash(o.strokeDash || null); + g.vgLineDashOffset(o.strokeDashOffset || 0); + return true; + } else { + return false; + } + } + + function color(g, o, value) { + return (value.id) ? + gradient(g, value, o.bounds) : + value; + } + + function gradient(g, p, b) { + var w = b.width(), + h = b.height(), + x1 = b.x1 + p.x1 * w, + y1 = b.y1 + p.y1 * h, + x2 = b.x1 + p.x2 * w, + y2 = b.y1 + p.y2 * h, + grad = g.createLinearGradient(x1, y1, x2, y2), + stop = p.stops, + i, n; + + for (i=0, n=stop.length; i=0;) { + if (h[i].type === type && !handler || h[i].handler === handler) { + svg.removeEventListener(name, h[i].listener); + h.splice(i, 1); + } + } + return this; + }; + + module.exports = SVGHandler; + +},{"../../util/dom":83,"../Handler":53}],72:[function(require,module,exports){ + var ImageLoader = require('../../util/ImageLoader'), + Renderer = require('../Renderer'), + text = require('../../util/text'), + DOM = require('../../util/dom'), + SVG = require('../../util/svg'), + ns = SVG.metadata.xmlns, + marks = require('./marks'); + + function SVGRenderer(loadConfig) { + Renderer.call(this); + this._loader = new ImageLoader(loadConfig); + this._dirtyID = 0; + } + + var base = Renderer.prototype; + var prototype = (SVGRenderer.prototype = Object.create(base)); + prototype.constructor = SVGRenderer; + + prototype.initialize = function(el, width, height, padding) { + if (el) { + this._svg = DOM.child(el, 0, 'svg', ns, 'marks'); + DOM.clear(el, 1); + // set the svg root group + this._root = DOM.child(this._svg, 0, 'g', ns); + DOM.clear(this._svg, 1); + } + + // create the svg definitions cache + this._defs = { + clip_id: 1, + gradient: {}, + clipping: {} + }; + + // set background color if defined + this.background(this._bgcolor); + + return base.initialize.call(this, el, width, height, padding); + }; + + prototype.background = function(bgcolor) { + if (arguments.length && this._svg) { + this._svg.style.setProperty('background-color', bgcolor); + } + return base.background.apply(this, arguments); + }; + + prototype.resize = function(width, height, padding) { + base.resize.call(this, width, height, padding); + + if (this._svg) { + var w = this._width, + h = this._height, + p = this._padding; + + this._svg.setAttribute('width', w + p.left + p.right); + this._svg.setAttribute('height', h + p.top + p.bottom); + + this._root.setAttribute('transform', 'translate('+p.left+','+p.top+')'); + } + + return this; + }; + + prototype.svg = function() { + if (!this._svg) return null; + + var attr = { + 'class': 'marks', + 'width': this._width + this._padding.left + this._padding.right, + 'height': this._height + this._padding.top + this._padding.bottom, + }; + for (var key in SVG.metadata) { + attr[key] = SVG.metadata[key]; + } + + return DOM.openTag('svg', attr) + this._svg.innerHTML + DOM.closeTag('svg'); + }; + + prototype.imageURL = function(url) { + return this._loader.imageURL(url); + }; + + +// -- Render entry point -- + + prototype.render = function(scene, items) { + if (this._dirtyCheck(items)) { + if (this._dirtyAll) this._resetDefs(); + this.draw(this._root, scene, -1); + DOM.clear(this._root, 1); + } + this.updateDefs(); + return this; + }; + + prototype.draw = function(el, scene, index) { + this.drawMark(el, scene, index, marks[scene.marktype]); + }; + + +// -- Manage SVG definitions ('defs') block -- + + prototype.updateDefs = function() { + var svg = this._svg, + defs = this._defs, + el = defs.el, + index = 0, id; + + for (id in defs.gradient) { + if (!el) el = (defs.el = DOM.child(svg, 0, 'defs', ns)); + updateGradient(el, defs.gradient[id], index++); + } + + for (id in defs.clipping) { + if (!el) el = (defs.el = DOM.child(svg, 0, 'defs', ns)); + updateClipping(el, defs.clipping[id], index++); + } + + // clean-up + if (el) { + if (index === 0) { + svg.removeChild(el); + defs.el = null; + } else { + DOM.clear(el, index); + } + } + }; + + function updateGradient(el, grad, index) { + var i, n, stop; + + el = DOM.child(el, index, 'linearGradient', ns); + el.setAttribute('id', grad.id); + el.setAttribute('x1', grad.x1); + el.setAttribute('x2', grad.x2); + el.setAttribute('y1', grad.y1); + el.setAttribute('y2', grad.y2); + + for (i=0, n=grad.stops.length; i 0) ? openTag('defs') + defs + closeTag('defs') : ''; + }; + + prototype.imageURL = function(url) { + return this._loader.imageURL(url); + }; + + var object; + + function emit(name, value, ns, prefixed) { + object[prefixed || name] = value; + } + + prototype.attributes = function(attr, item) { + object = {}; + attr(emit, item, this); + return object; + }; + + prototype.mark = function(scene) { + var mdef = MARKS[scene.marktype], + tag = mdef.tag, + attr = mdef.attr, + nest = mdef.nest || false, + data = nest ? + (scene.items && scene.items.length ? [scene.items[0]] : []) : + (scene.items || []), + defs = this._defs, + str = '', + style, i, item; + + if (tag !== 'g' && scene.interactive === false) { + style = 'style="pointer-events: none;"'; + } + + // render opening group tag + str += openTag('g', { + 'class': DOM.cssClass(scene) + }, style); + + // render contained elements + for (i=0; i/g, '>'); + } + + module.exports = SVGStringRenderer; + +},{"../../util/ImageLoader":79,"../../util/dom":83,"../../util/svg":85,"../../util/text":86,"../Renderer":54,"./marks":75}],74:[function(require,module,exports){ + module.exports = { + Handler: require('./SVGHandler'), + Renderer: require('./SVGRenderer'), + string: { + Renderer : require('./SVGStringRenderer') + } + }; +},{"./SVGHandler":71,"./SVGRenderer":72,"./SVGStringRenderer":73}],75:[function(require,module,exports){ + var text = require('../../util/text'), + SVG = require('../../util/svg'), + textAlign = SVG.textAlign, + path = SVG.path; + + function translateItem(o) { + return translate(o.x || 0, o.y || 0); + } + + function translate(x, y) { + return 'translate(' + x + ',' + y + ')'; + } + + module.exports = { + arc: { + tag: 'path', + type: 'arc', + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('d', path.arc(o)); + } + }, + area: { + tag: 'path', + type: 'area', + nest: true, + attr: function(emit, o) { + var items = o.mark.items; + if (items.length) emit('d', path.area(items)); + } + }, + group: { + tag: 'g', + type: 'group', + attr: function(emit, o, renderer) { + var id = null, defs, c; + emit('transform', translateItem(o)); + if (o.clip) { + defs = renderer._defs; + id = o.clip_id || (o.clip_id = 'clip' + defs.clip_id++); + c = defs.clipping[id] || (defs.clipping[id] = {id: id}); + c.width = o.width || 0; + c.height = o.height || 0; + } + emit('clip-path', id ? ('url(#' + id + ')') : null); + }, + background: function(emit, o) { + emit('class', 'background'); + emit('width', o.width || 0); + emit('height', o.height || 0); + } + }, + image: { + tag: 'image', + type: 'image', + attr: function(emit, o, renderer) { + var x = o.x || 0, + y = o.y || 0, + w = o.width || 0, + h = o.height || 0, + url = renderer.imageURL(o.url); + + x = x - (o.align === 'center' ? w/2 : o.align === 'right' ? w : 0); + y = y - (o.baseline === 'middle' ? h/2 : o.baseline === 'bottom' ? h : 0); + + emit('href', url, 'http://www.w3.org/1999/xlink', 'xlink:href'); + emit('transform', translate(x, y)); + emit('width', w); + emit('height', h); + } + }, + line: { + tag: 'path', + type: 'line', + nest: true, + attr: function(emit, o) { + var items = o.mark.items; + if (items.length) emit('d', path.line(items)); + } + }, + path: { + tag: 'path', + type: 'path', + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('d', o.path); + } + }, + rect: { + tag: 'rect', + type: 'rect', + nest: false, + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('width', o.width || 0); + emit('height', o.height || 0); + } + }, + rule: { + tag: 'line', + type: 'rule', + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('x2', o.x2 != null ? o.x2 - (o.x||0) : 0); + emit('y2', o.y2 != null ? o.y2 - (o.y||0) : 0); + } + }, + symbol: { + tag: 'path', + type: 'symbol', + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('d', path.symbol(o)); + } + }, + text: { + tag: 'text', + type: 'text', + nest: false, + attr: function(emit, o) { + var dx = (o.dx || 0), + dy = (o.dy || 0) + text.offset(o), + x = (o.x || 0), + y = (o.y || 0), + a = o.angle || 0, + r = o.radius || 0, t; + + if (r) { + t = (o.theta || 0) - Math.PI/2; + x += r * Math.cos(t); + y += r * Math.sin(t); + } + + emit('text-anchor', textAlign[o.align] || 'start'); + + if (a) { + t = translate(x, y) + ' rotate('+a+')'; + if (dx || dy) t += ' ' + translate(dx, dy); + } else { + t = translate(x+dx, y+dy); + } + emit('transform', t); + } + } + }; + +},{"../../util/svg":85,"../../util/text":86}],76:[function(require,module,exports){ + function Bounds(b) { + this.clear(); + if (b) this.union(b); + } + + var prototype = Bounds.prototype; + + prototype.clone = function() { + return new Bounds(this); + }; + + prototype.clear = function() { + this.x1 = +Number.MAX_VALUE; + this.y1 = +Number.MAX_VALUE; + this.x2 = -Number.MAX_VALUE; + this.y2 = -Number.MAX_VALUE; + return this; + }; + + prototype.set = function(x1, y1, x2, y2) { + this.x1 = x1; + this.y1 = y1; + this.x2 = x2; + this.y2 = y2; + return this; + }; + + prototype.add = function(x, y) { + if (x < this.x1) this.x1 = x; + if (y < this.y1) this.y1 = y; + if (x > this.x2) this.x2 = x; + if (y > this.y2) this.y2 = y; + return this; + }; + + prototype.expand = function(d) { + this.x1 -= d; + this.y1 -= d; + this.x2 += d; + this.y2 += d; + return this; + }; + + prototype.round = function() { + this.x1 = Math.floor(this.x1); + this.y1 = Math.floor(this.y1); + this.x2 = Math.ceil(this.x2); + this.y2 = Math.ceil(this.y2); + return this; + }; + + prototype.translate = function(dx, dy) { + this.x1 += dx; + this.x2 += dx; + this.y1 += dy; + this.y2 += dy; + return this; + }; + + prototype.rotate = function(angle, x, y) { + var cos = Math.cos(angle), + sin = Math.sin(angle), + cx = x - x*cos + y*sin, + cy = y - x*sin - y*cos, + x1 = this.x1, x2 = this.x2, + y1 = this.y1, y2 = this.y2; + + return this.clear() + .add(cos*x1 - sin*y1 + cx, sin*x1 + cos*y1 + cy) + .add(cos*x1 - sin*y2 + cx, sin*x1 + cos*y2 + cy) + .add(cos*x2 - sin*y1 + cx, sin*x2 + cos*y1 + cy) + .add(cos*x2 - sin*y2 + cx, sin*x2 + cos*y2 + cy); + }; + + prototype.union = function(b) { + if (b.x1 < this.x1) this.x1 = b.x1; + if (b.y1 < this.y1) this.y1 = b.y1; + if (b.x2 > this.x2) this.x2 = b.x2; + if (b.y2 > this.y2) this.y2 = b.y2; + return this; + }; + + prototype.encloses = function(b) { + return b && ( + this.x1 <= b.x1 && + this.x2 >= b.x2 && + this.y1 <= b.y1 && + this.y2 >= b.y2 + ); + }; + + prototype.intersects = function(b) { + return b && !( + this.x2 < b.x1 || + this.x1 > b.x2 || + this.y2 < b.y1 || + this.y1 > b.y2 + ); + }; + + prototype.contains = function(x, y) { + return !( + x < this.x1 || + x > this.x2 || + y < this.y1 || + y > this.y2 + ); + }; + + prototype.width = function() { + return this.x2 - this.x1; + }; + + prototype.height = function() { + return this.y2 - this.y1; + }; + + module.exports = Bounds; + +},{}],77:[function(require,module,exports){ + module.exports = function(b) { + function noop() { } + function add(x,y) { b.add(x, y); } + + return { + bounds: function(_) { + if (!arguments.length) return b; + return (b = _, this); + }, + beginPath: noop, + closePath: noop, + moveTo: add, + lineTo: add, + quadraticCurveTo: function(x1, y1, x2, y2) { + b.add(x1, y1); + b.add(x2, y2); + }, + bezierCurveTo: function(x1, y1, x2, y2, x3, y3) { + b.add(x1, y1); + b.add(x2, y2); + b.add(x3, y3); + } + }; + }; + +},{}],78:[function(require,module,exports){ + var gradient_id = 0; + + function Gradient(type) { + this.id = 'gradient_' + (gradient_id++); + this.type = type || 'linear'; + this.stops = []; + this.x1 = 0; + this.x2 = 1; + this.y1 = 0; + this.y2 = 0; + } + + var prototype = Gradient.prototype; + + prototype.stop = function(offset, color) { + this.stops.push({ + offset: offset, + color: color + }); + return this; + }; + + module.exports = Gradient; +},{}],79:[function(require,module,exports){ + (function (global){ + var load = require('datalib/src/import/load'); + + function ImageLoader(loadConfig) { + this._pending = 0; + this._config = loadConfig || ImageLoader.Config; + } + +// Overridable global default load configuration + ImageLoader.Config = null; + + var prototype = ImageLoader.prototype; + + prototype.pending = function() { + return this._pending; + }; + + prototype.params = function(uri) { + var p = {url: uri}, k; + for (k in this._config) { p[k] = this._config[k]; } + return p; + }; + + prototype.imageURL = function(uri) { + return load.sanitizeUrl(this.params(uri)); + }; + + function browser(uri, callback) { + var url = load.sanitizeUrl(this.params(uri)); + if (!url) { // error + if (callback) callback(uri, null); + return null; + } + + var loader = this, + image = new Image(); + + loader._pending += 1; + + image.onload = function() { + loader._pending -= 1; + image.loaded = true; + if (callback) callback(null, image); + }; + image.src = url; + + return image; + } + + function server(uri, callback) { + var loader = this, + image = new ((typeof window !== "undefined" ? window['canvas'] : typeof global !== "undefined" ? global['canvas'] : null).Image)(); + + loader._pending += 1; + + load(this.params(uri), function(err, data) { + loader._pending -= 1; + if (err) { + if (callback) callback(err, null); + return null; + } + image.src = data; + image.loaded = true; + if (callback) callback(null, image); + }); + + return image; + } + + prototype.loadImage = function(uri, callback) { + return load.useXHR ? + browser.call(this, uri, callback) : + server.call(this, uri, callback); + }; + + module.exports = ImageLoader; + + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"datalib/src/import/load":22}],80:[function(require,module,exports){ + function Item(mark) { + this.mark = mark; + } + + var prototype = Item.prototype; + + prototype.hasPropertySet = function(name) { + var props = this.mark.def.properties; + return props && props[name] != null; + }; + + prototype.cousin = function(offset, index) { + if (offset === 0) return this; + offset = offset || -1; + var mark = this.mark, + group = mark.group, + iidx = index==null ? mark.items.indexOf(this) : index, + midx = group.items.indexOf(mark) + offset; + return group.items[midx].items[iidx]; + }; + + prototype.sibling = function(offset) { + if (offset === 0) return this; + offset = offset || -1; + var mark = this.mark, + iidx = mark.items.indexOf(this) + offset; + return mark.items[iidx]; + }; + + prototype.remove = function() { + var item = this, + list = item.mark.items, + i = list.indexOf(item); + if (i >= 0) { + if (i===list.length-1) { + list.pop(); + } else { + list.splice(i, 1); + } + } + return item; + }; + + prototype.touch = function() { + if (this.pathCache) this.pathCache = null; + }; + + module.exports = Item; +},{}],81:[function(require,module,exports){ + var BoundsContext = require('./BoundsContext'), + Bounds = require('./Bounds'), + canvas = require('./canvas'), + svg = require('./svg'), + text = require('./text'), + paths = require('../path'), + parse = paths.parse, + drawPath = paths.render, + areaPath = svg.path.area, + linePath = svg.path.line, + halfpi = Math.PI / 2, + sqrt3 = Math.sqrt(3), + tan30 = Math.tan(30 * Math.PI / 180), + g2D = null, + bc = BoundsContext(); + + function context() { + return g2D || (g2D = canvas.instance(1,1).getContext('2d')); + } + + function strokeBounds(o, bounds) { + if (o.stroke && o.opacity !== 0 && o.stokeOpacity !== 0) { + bounds.expand(o.strokeWidth != null ? o.strokeWidth : 1); + } + return bounds; + } + + function pathBounds(o, path, bounds, x, y) { + if (path == null) { + bounds.set(0, 0, 0, 0); + } else { + drawPath(bc.bounds(bounds), path, x, y); + strokeBounds(o, bounds); + } + return bounds; + } + + function path(o, bounds) { + var p = o.path ? o.pathCache || (o.pathCache = parse(o.path)) : null; + return pathBounds(o, p, bounds, o.x, o.y); + } + + function area(mark, bounds) { + if (mark.items.length === 0) return bounds; + var items = mark.items, + item = items[0], + p = item.pathCache || (item.pathCache = parse(areaPath(items))); + return pathBounds(item, p, bounds); + } + + function line(mark, bounds) { + if (mark.items.length === 0) return bounds; + var items = mark.items, + item = items[0], + p = item.pathCache || (item.pathCache = parse(linePath(items))); + return pathBounds(item, p, bounds); + } + + function rect(o, bounds) { + var x, y; + return strokeBounds(o, bounds.set( + x = o.x || 0, + y = o.y || 0, + (x + o.width) || 0, + (y + o.height) || 0 + )); + } + + function image(o, bounds) { + var x = o.x || 0, + y = o.y || 0, + w = o.width || 0, + h = o.height || 0; + x = x - (o.align === 'center' ? w/2 : (o.align === 'right' ? w : 0)); + y = y - (o.baseline === 'middle' ? h/2 : (o.baseline === 'bottom' ? h : 0)); + return bounds.set(x, y, x+w, y+h); + } + + function rule(o, bounds) { + var x1, y1; + return strokeBounds(o, bounds.set( + x1 = o.x || 0, + y1 = o.y || 0, + o.x2 != null ? o.x2 : x1, + o.y2 != null ? o.y2 : y1 + )); + } + + function arc(o, bounds) { + var cx = o.x || 0, + cy = o.y || 0, + ir = o.innerRadius || 0, + or = o.outerRadius || 0, + sa = (o.startAngle || 0) - halfpi, + ea = (o.endAngle || 0) - halfpi, + xmin = Infinity, xmax = -Infinity, + ymin = Infinity, ymax = -Infinity, + a, i, n, x, y, ix, iy, ox, oy; + + var angles = [sa, ea], + s = sa - (sa % halfpi); + for (i=0; i<4 && s index) { + el.removeChild(el.childNodes[--curr]); + } + return el; + }, + remove: remove, + // generate css class name for mark + cssClass: function(mark) { + return 'mark-' + mark.marktype + (mark.name ? ' '+mark.name : ''); + }, + // generate string for an opening xml tag + // tag: the name of the xml tag + // attr: hash of attribute name-value pairs to include + // raw: additional raw string to include in tag markup + openTag: function(tag, attr, raw) { + var s = '<' + tag, key, val; + if (attr) { + for (key in attr) { + val = attr[key]; + if (val != null) { + s += ' ' + key + '="' + val + '"'; + } + } + } + if (raw) s += ' ' + raw; + return s + '>'; + }, + // generate string for closing xml tag + // tag: the name of the xml tag + closeTag: function(tag) { + return ''; + } + }; + +},{}],84:[function(require,module,exports){ + var bound = require('../util/bound'); + + var sets = [ + 'items', + 'axisItems', + 'legendItems' + ]; + + var keys = [ + 'marktype', 'name', 'interactive', 'clip', + 'items', 'axisItems', 'legendItems', 'layer', + 'x', 'y', 'width', 'height', 'align', 'baseline', // layout + 'fill', 'fillOpacity', 'opacity', // fill + 'stroke', 'strokeOpacity', 'strokeWidth', 'strokeCap', // stroke + 'strokeDash', 'strokeDashOffset', // stroke dash + 'startAngle', 'endAngle', 'innerRadius', 'outerRadius', // arc + 'interpolate', 'tension', 'orient', // area, line + 'url', // image + 'path', // path + 'x2', 'y2', // rule + 'size', 'shape', // symbol + 'text', 'angle', 'theta', 'radius', 'dx', 'dy', // text + 'font', 'fontSize', 'fontWeight', 'fontStyle', 'fontVariant' // font + ]; + + function toJSON(scene, indent) { + return JSON.stringify(scene, keys, indent); + } + + function fromJSON(json) { + var scene = (typeof json === 'string' ? JSON.parse(json) : json); + return initialize(scene); + } + + function initialize(scene) { + var type = scene.marktype, + i, n, s, m, items; + + for (s=0, m=sets.length; s 0) { wait(); } else { callback(this.canvas()); } + }; + + prototype.svg = function() { + return (this._type === 'svg') ? this._renderer.svg() : null; + }; + + prototype.initialize = function() { + var w = this._width, + h = this._height, + bg = this._bgcolor, + pad = this._padding, + config = this.model().config(); + + if (this._viewport) { + w = this._viewport[0] - (pad ? pad.left + pad.right : 0); + h = this._viewport[1] - (pad ? pad.top + pad.bottom : 0); + } + + this._renderer = (this._renderer || new this._io.Renderer(config.load)) + .initialize(null, w, h, pad) + .background(bg); + + return this; + }; + + module.exports = HeadlessView; +},{"./View":89,"vega-scenegraph":48}],88:[function(require,module,exports){ + var dl = require('datalib'), + df = require('vega-dataflow'), + ChangeSet = df.ChangeSet, + Base = df.Graph.prototype, + Node = df.Node, // jshint ignore:line + GroupBuilder = require('../scene/GroupBuilder'), + visit = require('../scene/visit'), + config = require('./config'); + + function Model(cfg) { + this._defs = {}; + this._predicates = {}; + this._scene = null; + + this._node = null; + this._builder = null; // Top-level scenegraph builder + + this._reset = {axes: false, legends: false}; + + this.config(cfg); + Base.init.call(this); + } + + var prototype = (Model.prototype = Object.create(Base)); + prototype.constructor = Model; + + prototype.defs = function(defs) { + if (!arguments.length) return this._defs; + this._defs = defs; + return this; + }; + + prototype.config = function(cfg) { + if (!arguments.length) return this._config; + this._config = Object.create(config); + for (var name in cfg) { + var x = cfg[name], y = this._config[name]; + if (dl.isObject(x) && dl.isObject(y)) { + dl.extend(y, x); + } else { + this._config[name] = x; + } + } + + return this; + }; + + prototype.width = function(width) { + if (this._defs) this._defs.width = width; + if (this._defs && this._defs.marks) this._defs.marks.width = width; + if (this._scene) { + this._scene.items[0].width = width; + this._scene.items[0]._dirty = true; + } + this._reset.axes = true; + return this; + }; + + prototype.height = function(height) { + if (this._defs) this._defs.height = height; + if (this._defs && this._defs.marks) this._defs.marks.height = height; + if (this._scene) { + this._scene.items[0].height = height; + this._scene.items[0]._dirty = true; + } + this._reset.axes = true; + return this; + }; + + prototype.node = function() { + return this._node || (this._node = new Node(this)); + }; + + prototype.data = function() { + var data = Base.data.apply(this, arguments); + if (arguments.length > 1) { // new Datasource + this.node().addListener(data.pipeline()[0]); + } + return data; + }; + + function predicates(name) { + var m = this, pred = {}; + if (!dl.isArray(name)) return this._predicates[name]; + name.forEach(function(n) { pred[n] = m._predicates[n]; }); + return pred; + } + + prototype.predicate = function(name, predicate) { + if (arguments.length === 1) return predicates.call(this, name); + return (this._predicates[name] = predicate); + }; + + prototype.predicates = function() { return this._predicates; }; + + prototype.scene = function(renderer) { + if (!arguments.length) return this._scene; + + if (this._builder) { + this.node().removeListener(this._builder); + this._builder._groupBuilder.disconnect(); + } + + var m = this, + b = this._builder = new Node(this); + + b.evaluate = function(input) { + if (b._groupBuilder) return input; + + var gb = b._groupBuilder = new GroupBuilder(m, m._defs.marks, m._scene={}), + p = gb.pipeline(); + + this.addListener(gb.connect()); + p[p.length-1].addListener(renderer); + return input; + }; + + this.addListener(b); + return this; + }; + + prototype.reset = function() { + if (this._scene && this._reset.axes) { + visit(this._scene, function(item) { + if (item.axes) item.axes.forEach(function(axis) { axis.reset(); }); + }); + this._reset.axes = false; + } + if (this._scene && this._reset.legends) { + visit(this._scene, function(item) { + if (item.legends) item.legends.forEach(function(l) { l.reset(); }); + }); + this._reset.legends = false; + } + return this; + }; + + prototype.addListener = function(l) { + this.node().addListener(l); + }; + + prototype.removeListener = function(l) { + this.node().removeListener(l); + }; + + prototype.fire = function(cs) { + if (!cs) cs = ChangeSet.create(); + this.propagate(cs, this.node()); + }; + + module.exports = Model; +},{"../scene/GroupBuilder":112,"../scene/visit":117,"./config":90,"datalib":26,"vega-dataflow":41}],89:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + df = require('vega-dataflow'), + sg = require('vega-scenegraph').render, + log = require('vega-logging'), + Deps = df.Dependencies, + parseStreams = require('../parse/streams'), + Encoder = require('../scene/Encoder'), + Transition = require('../scene/Transition'); + + function View(el, width, height) { + this._el = null; + this._model = null; + this._width = this.__width = width || 500; + this._height = this.__height = height || 300; + this._bgcolor = null; + this._autopad = 1; + this._padding = {top:0, left:0, bottom:0, right:0}; + this._viewport = null; + this._renderer = null; + this._handler = null; + this._streamer = null; // Targeted update for streaming changes + this._changeset = null; + this._repaint = true; // Full re-render on every re-init + this._renderers = sg; + this._io = null; + this._api = {}; // Stash streaming data API sandboxes. + } + + var prototype = View.prototype; + + prototype.model = function(model) { + if (!arguments.length) return this._model; + if (this._model !== model) { + this._model = model; + this._streamer = new df.Node(model); + this._streamer._rank = -1; // HACK: To reduce re-ranking churn. + this._changeset = df.ChangeSet.create(); + if (this._handler) this._handler.model(model); + } + return this; + }; + +// Sandboxed streaming data API + function streaming(src) { + var view = this, + ds = this._model.data(src), + name = ds.name(), + listener = ds.pipeline()[0], + streamer = this._streamer, + api = {}; + + // If we have it stashed, don't create a new closure. + if (this._api[src]) return this._api[src]; + + api.insert = function(vals) { + ds.insert(dl.duplicate(vals)); // Don't pollute the environment + streamer.addListener(listener); + view._changeset.data[name] = 1; + return api; + }; + + api.update = function() { + streamer.addListener(listener); + view._changeset.data[name] = 1; + return (ds.update.apply(ds, arguments), api); + }; + + api.remove = function() { + streamer.addListener(listener); + view._changeset.data[name] = 1; + return (ds.remove.apply(ds, arguments), api); + }; + + api.values = function() { return ds.values(); }; + + return (this._api[src] = api); + } + + prototype.data = function(data) { + var v = this; + if (!arguments.length) return v._model.values(); + else if (dl.isString(data)) return streaming.call(v, data); + else if (dl.isObject(data)) { + dl.keys(data).forEach(function(k) { + var api = streaming.call(v, k); + data[k](api); + }); + } + return this; + }; + + var VIEW_SIGNALS = dl.toMap(['width', 'height', 'padding']); + + prototype.signal = function(name, value, propagate) { + var m = this._model, + key, values; + + // Getter. Returns the value for the specified signal, or + // returns all signal values. + if (!arguments.length) { + return m.values(Deps.SIGNALS); + } else if (arguments.length === 1 && dl.isString(name)) { + return m.values(Deps.SIGNALS, name); + } + + // Setter. Can be done in batch or individually. In either case, + // the final argument determines if set values should propagate. + if (dl.isObject(name)) { + values = name; + propagate = value; + } else { + values = {}; + values[name] = value; + } + for (key in values) { + if (VIEW_SIGNALS[key]) { + this[key](values[key]); + } else { + setSignal.call(this, key, values[key], propagate); + } + } + return this; + }; + + function setSignal(name, value, propagate) { + var cs = this._changeset; + this._streamer.addListener(this._model.signal(name).value(value)); + if (propagate !== false) cs.signals[name] = 1; + cs.reflow = true; + } + + prototype.width = function(width) { + if (!arguments.length) return this.__width; + if (this.__width !== width) { + this._width = this.__width = width; + this.model().width(width); + this.initialize(); + if (this._strict) this._autopad = 1; + setSignal.call(this, 'width', width); + } + return this; + }; + + prototype.height = function(height) { + if (!arguments.length) return this.__height; + if (this.__height !== height) { + this._height = this.__height = height; + this.model().height(height); + this.initialize(); + if (this._strict) this._autopad = 1; + setSignal.call(this, 'height', height); + } + return this; + }; + + prototype.background = function(bgcolor) { + if (!arguments.length) return this._bgcolor; + if (this._bgcolor !== bgcolor) { + this._bgcolor = bgcolor; + this.initialize(); + } + return this; + }; + + prototype.padding = function(pad) { + if (!arguments.length) return this._padding; + if (this._padding !== pad) { + if (dl.isString(pad)) { + this._autopad = 1; + this._padding = {top:0, left:0, bottom:0, right:0}; + this._strict = (pad === 'strict'); + } else { + this._autopad = 0; + this._padding = pad; + this._strict = false; + } + if (this._renderer) this._renderer.resize(this._width, this._height, this._padding); + if (this._handler) this._handler.padding(this._padding); + setSignal.call(this, 'padding', this._padding); + } + return (this._repaint = true, this); + }; + + prototype.autopad = function(opt) { + if (this._autopad < 1) return this; + else this._autopad = 0; + + var b = this.model().scene().bounds, + pad = this._padding, + config = this.model().config(), + inset = config.autopadInset, + l = b.x1 < 0 ? Math.ceil(-b.x1) + inset : 0, + t = b.y1 < 0 ? Math.ceil(-b.y1) + inset : 0, + r = b.x2 > this._width ? Math.ceil(+b.x2 - this._width) + inset : 0; + b = b.y2 > this._height ? Math.ceil(+b.y2 - this._height) + inset : 0; + pad = {left:l, top:t, right:r, bottom:b}; + + if (this._strict) { + this._autopad = 0; + this._padding = pad; + this._width = Math.max(0, this.__width - (l+r)); + this._height = Math.max(0, this.__height - (t+b)); + + this._model.width(this._width).height(this._height).reset(); + setSignal.call(this, 'width', this._width); + setSignal.call(this, 'height', this._height); + setSignal.call(this, 'padding', pad); + + this.initialize().update({props:'enter'}).update({props:'update'}); + } else { + this.padding(pad).update(opt); + } + return this; + }; + + prototype.viewport = function(size) { + if (!arguments.length) return this._viewport; + if (this._viewport !== size) { + this._viewport = size; + this.initialize(); + } + return this; + }; + + prototype.renderer = function(type) { + if (!arguments.length) return this._renderer; + if (this._renderers[type]) type = this._renderers[type]; + else if (dl.isString(type)) throw new Error('Unknown renderer: ' + type); + else if (!type) throw new Error('No renderer specified'); + + if (this._io !== type) { + this._io = type; + this._renderer = null; + this.initialize(); + if (this._build) this.render(); + } + return this; + }; + + prototype.initialize = function(el) { + var v = this, prevHandler, + w = v._width, h = v._height, pad = v._padding, bg = v._bgcolor, + config = this.model().config(); + + if (!arguments.length || el === null) { + el = this._el ? this._el.parentNode : null; + if (!el) return this; // This View cannot init w/o an + } + + // clear pre-existing container + d3.select(el).select('div.vega').remove(); + + // add div container + this._el = el = d3.select(el) + .append('div') + .attr('class', 'vega') + .style('position', 'relative') + .node(); + if (v._viewport) { + d3.select(el) + .style('width', (v._viewport[0] || w)+'px') + .style('height', (v._viewport[1] || h)+'px') + .style('overflow', 'auto'); + } + + // renderer + sg.canvas.Renderer.RETINA = config.render.retina; + v._renderer = (v._renderer || new this._io.Renderer(config.load)) + .initialize(el, w, h, pad) + .background(bg); + + // input handler + prevHandler = v._handler; + v._handler = new this._io.Handler() + .initialize(el, pad, v); + + if (prevHandler) { + prevHandler.handlers().forEach(function(h) { + v._handler.on(h.type, h.handler); + }); + } else { + // Register event listeners for signal stream definitions. + v._detach = parseStreams(this); + } + + return (this._repaint = true, this); + }; + + prototype.destroy = function() { + if (this._detach) this._detach(); + }; + + function build() { + var v = this; + v._renderNode = new df.Node(v._model) + .router(true); + + v._renderNode.evaluate = function(input) { + log.debug(input, ['rendering']); + + var s = v._model.scene(), + h = v._handler; + + if (h && h.scene) h.scene(s); + + if (input.trans) { + input.trans.start(function(items) { v._renderer.render(s, items); }); + } else if (v._repaint) { + v._renderer.render(s); + v._repaint = false; + } else if (input.dirty.length) { + v._renderer.render(s, input.dirty); + } + + if (input.dirty.length) { + input.dirty.forEach(function(i) { i._dirty = false; }); + s.items[0]._dirty = false; + } + + // For all updated datasources, clear their previous values. + for (var d in input.data) { v._model.data(d).synchronize(); } + return input; + }; + + return (v._model.scene(v._renderNode), true); + } + + prototype.update = function(opt) { + opt = opt || {}; + var v = this, + model = this._model, + streamer = this._streamer, + cs = this._changeset, + trans = opt.duration ? new Transition(opt.duration, opt.ease) : null; + + if (trans) cs.trans = trans; + if (opt.props !== undefined) { + if (dl.keys(cs.data).length > 0) { + throw Error( + 'New data values are not reflected in the visualization.' + + ' Please call view.update() before updating a specified property set.' + ); + } + + cs.reflow = true; + cs.request = opt.props; + } + + var built = v._build; + v._build = v._build || build.call(this); + + // If specific items are specified, short-circuit dataflow graph. + // Else-If there are streaming updates, perform a targeted propagation. + // Otherwise, re-evaluate the entire model (datasources + scene). + if (opt.items && built) { + Encoder.update(model, opt.trans, opt.props, opt.items, cs.dirty); + v._renderNode.evaluate(cs); + } else if (streamer.listeners().length && built) { + // Include re-evaluation entire model when repaint flag is set + if (this._repaint) streamer.addListener(model.node()); + model.propagate(cs, streamer); + streamer.disconnect(); + } else { + model.fire(cs); + } + + v._changeset = df.ChangeSet.create(); + + return v.autopad(opt); + }; + + prototype.toImageURL = function(type) { + var v = this, Renderer; + + // lookup appropriate renderer + switch (type || 'png') { + case 'canvas': + case 'png': + Renderer = sg.canvas.Renderer; break; + case 'svg': + Renderer = sg.svg.string.Renderer; break; + default: throw Error('Unrecognized renderer type: ' + type); + } + + var retina = sg.canvas.Renderer.RETINA; + sg.canvas.Renderer.RETINA = false; // ignore retina screen + + // render the scenegraph + var ren = new Renderer(v._model.config.load) + .initialize(null, v._width, v._height, v._padding) + .render(v._model.scene()); + + sg.canvas.Renderer.RETINA = retina; // restore retina settings + + // return data url + if (type === 'svg') { + var blob = new Blob([ren.svg()], {type: 'image/svg+xml'}); + return window.URL.createObjectURL(blob); + } else { + return ren.canvas().toDataURL('image/png'); + } + }; + + prototype.render = function(items) { + this._renderer.render(this._model.scene(), items); + return this; + }; + + prototype.on = function() { + this._handler.on.apply(this._handler, arguments); + return this; + }; + + prototype.onSignal = function(name, handler) { + this._model.signal(name).on(handler); + return this; + }; + + prototype.off = function() { + this._handler.off.apply(this._handler, arguments); + return this; + }; + + prototype.offSignal = function(name, handler) { + this._model.signal(name).off(handler); + return this; + }; + + View.factory = function(model) { + var HeadlessView = require('./HeadlessView'); + return function(opt) { + opt = opt || {}; + var defs = model.defs(); + var v = (opt.el ? new View() : new HeadlessView()) + .model(model) + .renderer(opt.renderer || 'canvas') + .width(defs.width) + .height(defs.height) + .background(defs.background) + .padding(defs.padding) + .viewport(defs.viewport) + .initialize(opt.el); + + if (opt.data) v.data(opt.data); + + if (opt.hover !== false && opt.el) { + v.on('mouseover', function(evt, item) { + if (item && item.hasPropertySet('hover')) { + this.update({props:'hover', items:item}); + } + }) + .on('mouseout', function(evt, item) { + if (item && item.hasPropertySet('hover')) { + this.update({props:'update', items:item}); + } + }); + } + + return v; + }; + }; + + module.exports = View; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"../parse/streams":107,"../scene/Encoder":111,"../scene/Transition":114,"./HeadlessView":87,"datalib":26,"vega-dataflow":41,"vega-logging":47,"vega-scenegraph":48}],90:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + config = {}; + + config.load = { + // base url for loading external data files + // used only for server-side operation + baseURL: '', + // Allows domain restriction when using data loading via XHR. + // To enable, set it to a list of allowed domains + // e.g., ['wikipedia.org', 'eff.org'] + domainWhiteList: false + }; + +// inset padding for automatic padding calculation + config.autopadInset = 5; + +// extensible scale lookup table +// all d3.scale.* instances also supported + config.scale = { + time: d3.time.scale, + utc: d3.time.scale.utc + }; + +// default rendering settings + config.render = { + retina: true + }; + +// root scenegraph group + config.scene = { + fill: undefined, + fillOpacity: undefined, + stroke: undefined, + strokeOpacity: undefined, + strokeWidth: undefined, + strokeDash: undefined, + strokeDashOffset: undefined + }; + +// default axis properties + config.axis = { + orient: 'bottom', + ticks: 10, + padding: 3, + axisColor: '#000', + axisWidth: 1, + gridColor: '#000', + gridOpacity: 0.15, + tickColor: '#000', + tickLabelColor: '#000', + tickWidth: 1, + tickSize: 6, + tickLabelFontSize: 11, + tickLabelFont: 'sans-serif', + titleColor: '#000', + titleFont: 'sans-serif', + titleFontSize: 11, + titleFontWeight: 'bold', + titleOffset: 'auto', + titleOffsetAutoMin: 30, + titleOffsetAutoMax: Infinity, + titleOffsetAutoMargin: 4 + }; + +// default legend properties + config.legend = { + orient: 'right', + offset: 20, + padding: 3, // padding between legend items and border + margin: 2, // extra margin between two consecutive legends + gradientStrokeColor: '#888', + gradientStrokeWidth: 1, + gradientHeight: 16, + gradientWidth: 100, + labelColor: '#000', + labelFontSize: 10, + labelFont: 'sans-serif', + labelAlign: 'left', + labelBaseline: 'middle', + labelOffset: 8, + symbolShape: 'circle', + symbolSize: 50, + symbolColor: '#888', + symbolStrokeWidth: 1, + titleColor: '#000', + titleFont: 'sans-serif', + titleFontSize: 11, + titleFontWeight: 'bold' + }; + +// default color values + config.color = { + rgb: [128, 128, 128], + lab: [50, 0, 0], + hcl: [0, 0, 50], + hsl: [0, 0, 0.5] + }; + +// default scale ranges + config.range = { + category10: d3.scale.category10().range(), + category20: d3.scale.category20().range(), + category20b: d3.scale.category20b().range(), + category20c: d3.scale.category20c().range(), + shapes: [ + 'circle', + 'cross', + 'diamond', + 'square', + 'triangle-down', + 'triangle-up' + ] + }; + + module.exports = config; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],91:[function(require,module,exports){ + var dl = require('datalib'), + parse = require('../parse'), + Scale = require('../scene/Scale'), + config = require('./config'); + + function compile(module, opt, schema) { + var s = module.schema; + if (!s) return; + if (s.refs) dl.extend(schema.refs, s.refs); + if (s.defs) dl.extend(schema.defs, s.defs); + } + + module.exports = function(opt) { + var schema = null; + opt = opt || {}; + + // Compile if we're not loading the schema from a URL. + // Load from a URL to extend the existing base schema. + if (opt.url) { + schema = dl.json(dl.extend({url: opt.url}, config.load)); + } else { + schema = { + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Vega Visualization Specification Language", + "defs": {}, + "refs": {}, + "$ref": "#/defs/spec" + }; + + dl.keys(parse).forEach(function(k) { compile(parse[k], opt, schema); }); + + // Scales aren't in the parser, add schema manually + compile(Scale, opt, schema); + } + + // Extend schema to support custom mark properties or property sets. + if (opt.properties) dl.keys(opt.properties).forEach(function(k) { + schema.defs.propset.properties[k] = {"$ref": "#/refs/"+opt.properties[k]+"Value"}; + }); + + if (opt.propertySets) dl.keys(opt.propertySets).forEach(function(k) { + schema.defs.mark.properties.properties.properties[k] = {"$ref": "#/defs/propset"}; + }); + + return schema; + }; +},{"../parse":97,"../scene/Scale":113,"./config":90,"datalib":26}],92:[function(require,module,exports){ + var dl = require('datalib'), + axs = require('../scene/axis'); + + var ORIENT = { + "x": "bottom", + "y": "left", + "top": "top", + "bottom": "bottom", + "left": "left", + "right": "right" + }; + + function parseAxes(model, spec, axes, group) { + var config = model.config(); + (spec || []).forEach(function(def, index) { + axes[index] = axes[index] || axs(model); + parseAxis(config, def, index, axes[index], group); + }); + } + + function parseAxis(config, def, index, axis, group) { + // axis scale + if (def.scale !== undefined) { + axis.scale(group.scale(def.scale)); + } + + // axis orientation + axis.orient(def.orient || ORIENT[def.type]); + // axis offset + axis.offset(def.offset || 0); + // axis layer + axis.layer(def.layer || "front"); + // axis grid lines + axis.grid(def.grid || false); + // axis title + axis.title(def.title || null); + // axis title offset + axis.titleOffset(def.titleOffset != null ? + def.titleOffset : config.axis.titleOffset); + // axis values + axis.tickValues(def.values || null); + // axis label formatting + axis.tickFormat(def.format || null); + axis.tickFormatType(def.formatType || null); + // axis tick subdivision + axis.tickSubdivide(def.subdivide || 0); + // axis tick padding + axis.tickPadding(def.tickPadding || config.axis.padding); + + // axis tick size(s) + var size = []; + if (def.tickSize !== undefined) { + for (var i=0; i<3; ++i) size.push(def.tickSize); + } else { + var ts = config.axis.tickSize; + size = [ts, ts, ts]; + } + if (def.tickSizeMajor != null) size[0] = def.tickSizeMajor; + if (def.tickSizeMinor != null) size[1] = def.tickSizeMinor; + if (def.tickSizeEnd != null) size[2] = def.tickSizeEnd; + if (size.length) { + axis.tickSize.apply(axis, size); + } + + // axis tick count + axis.tickCount(def.ticks || config.axis.ticks); + + // style properties + var p = def.properties; + if (p && p.ticks) { + axis.majorTickProperties(p.majorTicks ? + dl.extend({}, p.ticks, p.majorTicks) : p.ticks); + axis.minorTickProperties(p.minorTicks ? + dl.extend({}, p.ticks, p.minorTicks) : p.ticks); + } else { + axis.majorTickProperties(p && p.majorTicks || {}); + axis.minorTickProperties(p && p.minorTicks || {}); + } + axis.tickLabelProperties(p && p.labels || {}); + axis.titleProperties(p && p.title || {}); + axis.gridLineProperties(p && p.grid || {}); + axis.domainProperties(p && p.axis || {}); + } + + module.exports = parseAxes; +},{"../scene/axis":115,"datalib":26}],93:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null); + + function parseBg(bg) { + // return null if input is null or undefined + if (bg == null) return null; + // run through d3 rgb to sanity check + return d3.rgb(bg) + ''; + } + + module.exports = parseBg; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],94:[function(require,module,exports){ + var dl = require('datalib'), + log = require('vega-logging'), + parseTransforms = require('./transforms'), + parseModify = require('./modify'); + + function parseData(model, spec, callback) { + var config = model.config(), + count = 0; + + function loaded(d) { + return function(error, data) { + if (error) { + log.error('LOADING FAILED: ' + d.url + ' ' + error); + } else { + model.data(d.name).values(dl.read(data, d.format)); + } + if (--count === 0) callback(); + }; + } + + // process each data set definition + (spec || []).forEach(function(d) { + if (d.url) { + count += 1; + dl.load(dl.extend({url: d.url}, config.load), loaded(d)); + } + parseData.datasource(model, d); + }); + + if (count === 0) setTimeout(callback, 1); + return spec; + } + + parseData.datasource = function(model, d) { + var transform = (d.transform || []).map(function(t) { + return parseTransforms(model, t); + }), + mod = (d.modify || []).map(function(m) { + return parseModify(model, m, d); + }), + ds = model.data(d.name, mod.concat(transform)); + + if (d.values) { + ds.values(dl.read(d.values, d.format)); + } else if (d.source) { + // Derived ds will be pulsed by its src rather than the model. + ds.source(d.source).addListener(ds); + model.removeListener(ds.pipeline()[0]); + } + + return ds; + }; + + module.exports = parseData; +},{"./modify":101,"./transforms":108,"datalib":26,"vega-logging":47}],95:[function(require,module,exports){ + module.exports = (function() { + /* + * Generated by PEG.js 0.8.0. + * + * http://pegjs.majda.cz/ + */ + + function peg$subclass(child, parent) { + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + } + + function SyntaxError(message, expected, found, offset, line, column) { + this.message = message; + this.expected = expected; + this.found = found; + this.offset = offset; + this.line = line; + this.column = column; + + this.name = "SyntaxError"; + } + + peg$subclass(SyntaxError, Error); + + function parse(input) { + var options = arguments.length > 1 ? arguments[1] : {}, + + peg$FAILED = {}, + + peg$startRuleFunctions = { start: peg$parsestart }, + peg$startRuleFunction = peg$parsestart, + + peg$c0 = peg$FAILED, + peg$c1 = ",", + peg$c2 = { type: "literal", value: ",", description: "\",\"" }, + peg$c3 = function(o, m) { return [o].concat(m); }, + peg$c4 = function(o) { return [o]; }, + peg$c5 = "[", + peg$c6 = { type: "literal", value: "[", description: "\"[\"" }, + peg$c7 = "]", + peg$c8 = { type: "literal", value: "]", description: "\"]\"" }, + peg$c9 = ">", + peg$c10 = { type: "literal", value: ">", description: "\">\"" }, + peg$c11 = function(f1, f2, o) { return {start: f1, end: f2, middle: o}; }, + peg$c12 = [], + peg$c13 = function(s, f) { return (s.filters = f, s); }, + peg$c14 = function(s) { return s; }, + peg$c15 = "(", + peg$c16 = { type: "literal", value: "(", description: "\"(\"" }, + peg$c17 = ")", + peg$c18 = { type: "literal", value: ")", description: "\")\"" }, + peg$c19 = function(m) { return {stream: m}; }, + peg$c20 = "@", + peg$c21 = { type: "literal", value: "@", description: "\"@\"" }, + peg$c22 = ":", + peg$c23 = { type: "literal", value: ":", description: "\":\"" }, + peg$c24 = function(n, e) { return {event: e, name: n}; }, + peg$c25 = function(m, e) { return {event: e, mark: m}; }, + peg$c26 = function(t, e) { return {event: e, target: t}; }, + peg$c27 = function(e) { return {event: e}; }, + peg$c28 = function(s) { return {signal: s}; }, + peg$c29 = "rect", + peg$c30 = { type: "literal", value: "rect", description: "\"rect\"" }, + peg$c31 = "symbol", + peg$c32 = { type: "literal", value: "symbol", description: "\"symbol\"" }, + peg$c33 = "path", + peg$c34 = { type: "literal", value: "path", description: "\"path\"" }, + peg$c35 = "arc", + peg$c36 = { type: "literal", value: "arc", description: "\"arc\"" }, + peg$c37 = "area", + peg$c38 = { type: "literal", value: "area", description: "\"area\"" }, + peg$c39 = "line", + peg$c40 = { type: "literal", value: "line", description: "\"line\"" }, + peg$c41 = "rule", + peg$c42 = { type: "literal", value: "rule", description: "\"rule\"" }, + peg$c43 = "image", + peg$c44 = { type: "literal", value: "image", description: "\"image\"" }, + peg$c45 = "text", + peg$c46 = { type: "literal", value: "text", description: "\"text\"" }, + peg$c47 = "group", + peg$c48 = { type: "literal", value: "group", description: "\"group\"" }, + peg$c49 = "mousedown", + peg$c50 = { type: "literal", value: "mousedown", description: "\"mousedown\"" }, + peg$c51 = "mouseup", + peg$c52 = { type: "literal", value: "mouseup", description: "\"mouseup\"" }, + peg$c53 = "click", + peg$c54 = { type: "literal", value: "click", description: "\"click\"" }, + peg$c55 = "dblclick", + peg$c56 = { type: "literal", value: "dblclick", description: "\"dblclick\"" }, + peg$c57 = "wheel", + peg$c58 = { type: "literal", value: "wheel", description: "\"wheel\"" }, + peg$c59 = "keydown", + peg$c60 = { type: "literal", value: "keydown", description: "\"keydown\"" }, + peg$c61 = "keypress", + peg$c62 = { type: "literal", value: "keypress", description: "\"keypress\"" }, + peg$c63 = "keyup", + peg$c64 = { type: "literal", value: "keyup", description: "\"keyup\"" }, + peg$c65 = "mousewheel", + peg$c66 = { type: "literal", value: "mousewheel", description: "\"mousewheel\"" }, + peg$c67 = "mousemove", + peg$c68 = { type: "literal", value: "mousemove", description: "\"mousemove\"" }, + peg$c69 = "mouseout", + peg$c70 = { type: "literal", value: "mouseout", description: "\"mouseout\"" }, + peg$c71 = "mouseover", + peg$c72 = { type: "literal", value: "mouseover", description: "\"mouseover\"" }, + peg$c73 = "mouseenter", + peg$c74 = { type: "literal", value: "mouseenter", description: "\"mouseenter\"" }, + peg$c75 = "touchstart", + peg$c76 = { type: "literal", value: "touchstart", description: "\"touchstart\"" }, + peg$c77 = "touchmove", + peg$c78 = { type: "literal", value: "touchmove", description: "\"touchmove\"" }, + peg$c79 = "touchend", + peg$c80 = { type: "literal", value: "touchend", description: "\"touchend\"" }, + peg$c81 = function(e) { return e; }, + peg$c82 = /^[a-zA-Z0-9_\-]/, + peg$c83 = { type: "class", value: "[a-zA-Z0-9_\\-]", description: "[a-zA-Z0-9_\\-]" }, + peg$c84 = function(n) { return n.join(""); }, + peg$c85 = /^[a-zA-Z0-9\-_ #.>+~[\]=|\^$*]/, + peg$c86 = { type: "class", value: "[a-zA-Z0-9\\-_ #.>+~[\\]=|\\^$*]", description: "[a-zA-Z0-9\\-_ #.>+~[\\]=|\\^$*]" }, + peg$c87 = function(c) { return c.join(""); }, + peg$c88 = /^['"a-zA-Z0-9_().><=! \t-&|~]/, + peg$c89 = { type: "class", value: "['\"a-zA-Z0-9_().><=! \\t-&|~]", description: "['\"a-zA-Z0-9_().><=! \\t-&|~]" }, + peg$c90 = function(v) { return v.join(""); }, + peg$c91 = /^[ \t\r\n]/, + peg$c92 = { type: "class", value: "[ \\t\\r\\n]", description: "[ \\t\\r\\n]" }, + + peg$currPos = 0, + peg$reportedPos = 0, + peg$cachedPos = 0, + peg$cachedPosDetails = { line: 1, column: 1, seenCR: false }, + peg$maxFailPos = 0, + peg$maxFailExpected = [], + peg$silentFails = 0, + + peg$result; + + if ("startRule" in options) { + if (!(options.startRule in peg$startRuleFunctions)) { + throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); + } + + peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; + } + + function text() { + return input.substring(peg$reportedPos, peg$currPos); + } + + function offset() { + return peg$reportedPos; + } + + function line() { + return peg$computePosDetails(peg$reportedPos).line; + } + + function column() { + return peg$computePosDetails(peg$reportedPos).column; + } + + function expected(description) { + throw peg$buildException( + null, + [{ type: "other", description: description }], + peg$reportedPos + ); + } + + function error(message) { + throw peg$buildException(message, null, peg$reportedPos); + } + + function peg$computePosDetails(pos) { + function advance(details, startPos, endPos) { + var p, ch; + + for (p = startPos; p < endPos; p++) { + ch = input.charAt(p); + if (ch === "\n") { + if (!details.seenCR) { details.line++; } + details.column = 1; + details.seenCR = false; + } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") { + details.line++; + details.column = 1; + details.seenCR = true; + } else { + details.column++; + details.seenCR = false; + } + } + } + + if (peg$cachedPos !== pos) { + if (peg$cachedPos > pos) { + peg$cachedPos = 0; + peg$cachedPosDetails = { line: 1, column: 1, seenCR: false }; + } + advance(peg$cachedPosDetails, peg$cachedPos, pos); + peg$cachedPos = pos; + } + + return peg$cachedPosDetails; + } + + function peg$fail(expected) { + if (peg$currPos < peg$maxFailPos) { return; } + + if (peg$currPos > peg$maxFailPos) { + peg$maxFailPos = peg$currPos; + peg$maxFailExpected = []; + } + + peg$maxFailExpected.push(expected); + } + + function peg$buildException(message, expected, pos) { + function cleanupExpected(expected) { + var i = 1; + + expected.sort(function(a, b) { + if (a.description < b.description) { + return -1; + } else if (a.description > b.description) { + return 1; + } else { + return 0; + } + }); + + while (i < expected.length) { + if (expected[i - 1] === expected[i]) { + expected.splice(i, 1); + } else { + i++; + } + } + } + + function buildMessage(expected, found) { + function stringEscape(s) { + function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); } + + return s + .replace(/\\/g, '\\\\') + .replace(/"/g, '\\"') + .replace(/\x08/g, '\\b') + .replace(/\t/g, '\\t') + .replace(/\n/g, '\\n') + .replace(/\f/g, '\\f') + .replace(/\r/g, '\\r') + .replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) + .replace(/[\x10-\x1F\x80-\xFF]/g, function(ch) { return '\\x' + hex(ch); }) + .replace(/[\u0180-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); }) + .replace(/[\u1080-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); }); + } + + var expectedDescs = new Array(expected.length), + expectedDesc, foundDesc, i; + + for (i = 0; i < expected.length; i++) { + expectedDescs[i] = expected[i].description; + } + + expectedDesc = expected.length > 1 + ? expectedDescs.slice(0, -1).join(", ") + + " or " + + expectedDescs[expected.length - 1] + : expectedDescs[0]; + + foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input"; + + return "Expected " + expectedDesc + " but " + foundDesc + " found."; + } + + var posDetails = peg$computePosDetails(pos), + found = pos < input.length ? input.charAt(pos) : null; + + if (expected !== null) { + cleanupExpected(expected); + } + + return new SyntaxError( + message !== null ? message : buildMessage(expected, found), + expected, + found, + pos, + posDetails.line, + posDetails.column + ); + } + + function peg$parsestart() { + var s0; + + s0 = peg$parsemerged(); + + return s0; + } + + function peg$parsemerged() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + s1 = peg$parseordered(); + if (s1 !== peg$FAILED) { + s2 = peg$parsesep(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s3 = peg$c1; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c2); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parsesep(); + if (s4 !== peg$FAILED) { + s5 = peg$parsemerged(); + if (s5 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c3(s1, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parseordered(); + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c4(s1); + } + s0 = s1; + } + + return s0; + } + + function peg$parseordered() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 91) { + s1 = peg$c5; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c6); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parsesep(); + if (s2 !== peg$FAILED) { + s3 = peg$parsefiltered(); + if (s3 !== peg$FAILED) { + s4 = peg$parsesep(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c1; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c2); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parsesep(); + if (s6 !== peg$FAILED) { + s7 = peg$parsefiltered(); + if (s7 !== peg$FAILED) { + s8 = peg$parsesep(); + if (s8 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s9 = peg$c7; + peg$currPos++; + } else { + s9 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c8); } + } + if (s9 !== peg$FAILED) { + s10 = peg$parsesep(); + if (s10 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 62) { + s11 = peg$c9; + peg$currPos++; + } else { + s11 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c10); } + } + if (s11 !== peg$FAILED) { + s12 = peg$parsesep(); + if (s12 !== peg$FAILED) { + s13 = peg$parseordered(); + if (s13 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c11(s3, s7, s13); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$parsefiltered(); + } + + return s0; + } + + function peg$parsefiltered() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$parsestream(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$parsefilter(); + if (s3 !== peg$FAILED) { + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$parsefilter(); + } + } else { + s2 = peg$c0; + } + if (s2 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c13(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsestream(); + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c14(s1); + } + s0 = s1; + } + + return s0; + } + + function peg$parsestream() { + var s0, s1, s2, s3, s4; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c15; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c16); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parsemerged(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s3 = peg$c17; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c19(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 64) { + s1 = peg$c20; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c21); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parsename(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c22; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c23); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parseeventType(); + if (s4 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c24(s2, s4); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsemarkType(); + if (s1 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s2 = peg$c22; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c23); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parseeventType(); + if (s3 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c25(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsecss(); + if (s1 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s2 = peg$c22; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c23); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parseeventType(); + if (s3 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c26(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parseeventType(); + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c27(s1); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsename(); + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c28(s1); + } + s0 = s1; + } + } + } + } + } + + return s0; + } + + function peg$parsemarkType() { + var s0; + + if (input.substr(peg$currPos, 4) === peg$c29) { + s0 = peg$c29; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c30); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c31) { + s0 = peg$c31; + peg$currPos += 6; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c32); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c33) { + s0 = peg$c33; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c34); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 3) === peg$c35) { + s0 = peg$c35; + peg$currPos += 3; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c36); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c37) { + s0 = peg$c37; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c38); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c39) { + s0 = peg$c39; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c40); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c41) { + s0 = peg$c41; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c42); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c43) { + s0 = peg$c43; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c44); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c45) { + s0 = peg$c45; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c46); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c47) { + s0 = peg$c47; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c48); } + } + } + } + } + } + } + } + } + } + } + + return s0; + } + + function peg$parseeventType() { + var s0; + + if (input.substr(peg$currPos, 9) === peg$c49) { + s0 = peg$c49; + peg$currPos += 9; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c50); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 7) === peg$c51) { + s0 = peg$c51; + peg$currPos += 7; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c52); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c53) { + s0 = peg$c53; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c54); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 8) === peg$c55) { + s0 = peg$c55; + peg$currPos += 8; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c56); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c57) { + s0 = peg$c57; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c58); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 7) === peg$c59) { + s0 = peg$c59; + peg$currPos += 7; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c60); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 8) === peg$c61) { + s0 = peg$c61; + peg$currPos += 8; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c62); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c63) { + s0 = peg$c63; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c64); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 10) === peg$c65) { + s0 = peg$c65; + peg$currPos += 10; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c66); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 9) === peg$c67) { + s0 = peg$c67; + peg$currPos += 9; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c68); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 8) === peg$c69) { + s0 = peg$c69; + peg$currPos += 8; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c70); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 9) === peg$c71) { + s0 = peg$c71; + peg$currPos += 9; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c72); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 10) === peg$c73) { + s0 = peg$c73; + peg$currPos += 10; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c74); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 10) === peg$c75) { + s0 = peg$c75; + peg$currPos += 10; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c76); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 9) === peg$c77) { + s0 = peg$c77; + peg$currPos += 9; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c78); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 8) === peg$c79) { + s0 = peg$c79; + peg$currPos += 8; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c80); } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + return s0; + } + + function peg$parsefilter() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 91) { + s1 = peg$c5; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c6); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseexpr(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s3 = peg$c7; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c8); } + } + if (s3 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c81(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + + return s0; + } + + function peg$parsename() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = []; + if (peg$c82.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c83); } + } + if (s2 !== peg$FAILED) { + while (s2 !== peg$FAILED) { + s1.push(s2); + if (peg$c82.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c83); } + } + } + } else { + s1 = peg$c0; + } + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c84(s1); + } + s0 = s1; + + return s0; + } + + function peg$parsecss() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = []; + if (peg$c85.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c86); } + } + if (s2 !== peg$FAILED) { + while (s2 !== peg$FAILED) { + s1.push(s2); + if (peg$c85.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c86); } + } + } + } else { + s1 = peg$c0; + } + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c87(s1); + } + s0 = s1; + + return s0; + } + + function peg$parseexpr() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = []; + if (peg$c88.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c89); } + } + if (s2 !== peg$FAILED) { + while (s2 !== peg$FAILED) { + s1.push(s2); + if (peg$c88.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c89); } + } + } + } else { + s1 = peg$c0; + } + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c90(s1); + } + s0 = s1; + + return s0; + } + + function peg$parsesep() { + var s0, s1; + + s0 = []; + if (peg$c91.test(input.charAt(peg$currPos))) { + s1 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c92); } + } + while (s1 !== peg$FAILED) { + s0.push(s1); + if (peg$c91.test(input.charAt(peg$currPos))) { + s1 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c92); } + } + } + + return s0; + } + + peg$result = peg$startRuleFunction(); + + if (peg$result !== peg$FAILED && peg$currPos === input.length) { + return peg$result; + } else { + if (peg$result !== peg$FAILED && peg$currPos < input.length) { + peg$fail({ type: "end", description: "end of input" }); + } + + throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos); + } + } + + return { + SyntaxError: SyntaxError, + parse: parse + }; + })(); +},{}],96:[function(require,module,exports){ + var expr = require('vega-expression'), + args = ['datum', 'event', 'signals']; + + module.exports = expr.compiler(args, { + idWhiteList: args, + fieldVar: args[0], + globalVar: args[2], + functions: function(codegen) { + var fn = expr.functions(codegen); + fn.eventItem = function() { return 'event.vg.item'; }; + fn.eventGroup = 'event.vg.getGroup'; + fn.eventX = 'event.vg.getX'; + fn.eventY = 'event.vg.getY'; + fn.open = 'window.open'; + return fn; + } + }); +},{"vega-expression":45}],97:[function(require,module,exports){ + module.exports = { + axes: require('./axes'), + background: require('./background'), + data: require('./data'), + events: require('./events'), + expr: require('./expr'), + legends: require('./legends'), + mark: require('./mark'), + marks: require('./marks'), + modify: require('./modify'), + padding: require('./padding'), + predicates: require('./predicates'), + properties: require('./properties'), + signals: require('./signals'), + spec: require('./spec'), + streams: require('./streams'), + transforms: require('./transforms') + }; +},{"./axes":92,"./background":93,"./data":94,"./events":95,"./expr":96,"./legends":98,"./mark":99,"./marks":100,"./modify":101,"./padding":102,"./predicates":103,"./properties":104,"./signals":105,"./spec":106,"./streams":107,"./transforms":108}],98:[function(require,module,exports){ + var lgnd = require('../scene/legend'); + + function parseLegends(model, spec, legends, group) { + (spec || []).forEach(function(def, index) { + legends[index] = legends[index] || lgnd(model); + parseLegend(def, index, legends[index], group); + }); + } + + function parseLegend(def, index, legend, group) { + // legend scales + legend.size (def.size ? group.scale(def.size) : null); + legend.shape (def.shape ? group.scale(def.shape) : null); + legend.fill (def.fill ? group.scale(def.fill) : null); + legend.stroke(def.stroke ? group.scale(def.stroke) : null); + + // legend orientation + if (def.orient) legend.orient(def.orient); + + // legend offset + if (def.offset != null) legend.offset(def.offset); + + // legend title + legend.title(def.title || null); + + // legend values + legend.values(def.values || null); + + // legend label formatting + legend.format(def.format !== undefined ? def.format : null); + + // style properties + var p = def.properties; + legend.titleProperties(p && p.title || {}); + legend.labelProperties(p && p.labels || {}); + legend.legendProperties(p && p.legend || {}); + legend.symbolProperties(p && p.symbols || {}); + legend.gradientProperties(p && p.gradient || {}); + } + + module.exports = parseLegends; +},{"../scene/legend":116}],99:[function(require,module,exports){ + var dl = require('datalib'), + parseProperties = require('./properties'); + + function parseMark(model, mark) { + var props = mark.properties, + group = mark.marks; + + // parse mark property definitions + dl.keys(props).forEach(function(k) { + props[k] = parseProperties(model, mark.type, props[k]); + }); + + // parse delay function + if (mark.delay) { + mark.delay = parseProperties(model, mark.type, {delay: mark.delay}); + } + + // recurse if group type + if (group) { + mark.marks = group.map(function(g) { return parseMark(model, g); }); + } + + return mark; + } + + module.exports = parseMark; +},{"./properties":104,"datalib":26}],100:[function(require,module,exports){ + var parseMark = require('./mark'), + parseProperties = require('./properties'); + + function parseRootMark(model, spec, width, height) { + return { + type: 'group', + width: width, + height: height, + properties: defaults(spec.scene || {}, model), + scales: spec.scales || [], + axes: spec.axes || [], + legends: spec.legends || [], + marks: (spec.marks || []).map(function(m) { return parseMark(model, m); }) + }; + } + + var PROPERTIES = [ + 'fill', 'fillOpacity', 'stroke', 'strokeOpacity', + 'strokeWidth', 'strokeDash', 'strokeDashOffset' + ]; + + function defaults(spec, model) { + var config = model.config().scene, + props = {}, i, n, m, p, s; + + for (i=0, n=m=PROPERTIES.length; i= 0; --i) { + if (src[i][field] == value) + dest.push.apply(dest, src.splice(i, 1)); + } + }; + + function parseModify(model, def, ds) { + var signal = def.signal ? dl.field(def.signal) : null, + signalName = signal ? signal[0] : null, + predicate = def.predicate ? model.predicate(def.predicate.name || def.predicate) : null, + reeval = (predicate === null), + isClear = def.type === Types.CLEAR, + node = new Node(model).router(isClear); + + node.evaluate = function(input) { + if (predicate !== null) { // TODO: predicate args + var db = model.values(Deps.DATA, predicate.data || EMPTY), + sg = model.values(Deps.SIGNALS, predicate.signals || EMPTY); + reeval = predicate.call(predicate, {}, db, sg, model._predicates); + } + + log.debug(input, [def.type+"ing", reeval]); + if (!reeval || (!isClear && !input.signals[signalName])) return input; + + var datum = {}, + value = signal ? model.signalRef(def.signal) : null, + d = model.data(ds.name), + t = null; + + datum[def.field] = value; + + // We have to modify ds._data so that subsequent pulses contain + // our dynamic data. W/o modifying ds._data, only the output + // collector will contain dynamic tuples. + if (def.type === Types.INSERT) { + t = Tuple.ingest(datum); + input.add.push(t); + d._data.push(t); + } else if (def.type === Types.REMOVE) { + filter(def.field, value, input.add, input.rem); + filter(def.field, value, input.mod, input.rem); + d._data = d._data.filter(function(x) { return x[def.field] !== value; }); + } else if (def.type === Types.TOGGLE) { + var add = [], rem = []; + filter(def.field, value, input.rem, add); + filter(def.field, value, input.add, rem); + filter(def.field, value, input.mod, rem); + if (!(add.length || rem.length)) add.push(Tuple.ingest(datum)); + + input.add.push.apply(input.add, add); + d._data.push.apply(d._data, add); + input.rem.push.apply(input.rem, rem); + d._data = d._data.filter(function(x) { return rem.indexOf(x) === -1; }); + } else if (def.type === Types.CLEAR) { + input.rem.push.apply(input.rem, input.add); + input.rem.push.apply(input.rem, input.mod); + input.add = []; + input.mod = []; + d._data = []; + } + + input.fields[def.field] = 1; + return input; + }; + + if (signalName) node.dependency(Deps.SIGNALS, signalName); + + if (predicate) { + node.dependency(Deps.DATA, predicate.data); + node.dependency(Deps.SIGNALS, predicate.signals); + } + + return node; + } + + module.exports = parseModify; +},{"datalib":26,"vega-dataflow":41,"vega-logging":47}],102:[function(require,module,exports){ + var dl = require('datalib'); + + function parsePadding(pad) { + return pad == null ? 'auto' : + dl.isObject(pad) ? pad : + dl.isNumber(pad) ? {top:pad, left:pad, right:pad, bottom:pad} : + pad === 'strict' ? pad : 'auto'; + } + + module.exports = parsePadding; +},{"datalib":26}],103:[function(require,module,exports){ + var dl = require('datalib'); + + var types = { + '=': parseComparator, + '==': parseComparator, + '!=': parseComparator, + '>': parseComparator, + '>=': parseComparator, + '<': parseComparator, + '<=': parseComparator, + 'and': parseLogical, + '&&': parseLogical, + 'or': parseLogical, + '||': parseLogical, + 'in': parseIn + }; + + var nullScale = function() { return 0; }; + nullScale.invert = nullScale; + + function parsePredicates(model, spec) { + (spec || []).forEach(function(s) { + var parse = types[s.type](model, s); + + /* jshint evil:true */ + var pred = Function("args", "db", "signals", "predicates", parse.code); + pred.root = function() { return model.scene().items[0]; }; // For global scales + pred.nullScale = nullScale; + pred.isFunction = dl.isFunction; + pred.signals = parse.signals; + pred.data = parse.data; + + model.predicate(s.name, pred); + }); + + return spec; + } + + function parseSignal(signal, signals) { + var s = dl.field(signal), + code = "signals["+s.map(dl.str).join("][")+"]"; + signals[s[0]] = 1; + return code; + } + + function parseOperands(model, operands) { + var decl = [], defs = [], + signals = {}, db = {}; + + function setSignal(s) { signals[s] = 1; } + function setData(d) { db[d] = 1; } + + dl.array(operands).forEach(function(o, i) { + var name = "o" + i, + def = ""; + + if (o.value !== undefined) { + def = dl.str(o.value); + } else if (o.arg) { + def = "args["+dl.str(o.arg)+"]"; + } else if (o.signal) { + def = parseSignal(o.signal, signals); + } else if (o.predicate) { + var ref = o.predicate, + predName = ref && (ref.name || ref), + pred = model.predicate(predName), + p = "predicates["+dl.str(predName)+"]"; + + pred.signals.forEach(setSignal); + pred.data.forEach(setData); + + if (dl.isObject(ref)) { + dl.keys(ref).forEach(function(k) { + if (k === "name") return; + var i = ref[k]; + def += "args["+dl.str(k)+"] = "; + if (i.signal) { + def += parseSignal(i.signal, signals); + } else if (i.arg) { + def += "args["+dl.str(i.arg)+"]"; + } + def += ", "; + }); + } + + def += p+".call("+p+", args, db, signals, predicates)"; + } + + decl.push(name); + defs.push(name+"=("+def+")"); + }); + + return { + code: "var " + decl.join(", ") + ";\n" + defs.join(";\n") + ";\n", + signals: dl.keys(signals), + data: dl.keys(db) + }; + } + + function parseComparator(model, spec) { + var ops = parseOperands(model, spec.operands); + if (spec.type === '=') spec.type = '=='; + + ops.code += "o0 = o0 instanceof Date ? o0.getTime() : o0;\n" + + "o1 = o1 instanceof Date ? o1.getTime() : o1;\n"; + + return { + code: ops.code + "return " + ["o0", "o1"].join(spec.type) + ";", + signals: ops.signals, + data: ops.data + }; + } + + function parseLogical(model, spec) { + var ops = parseOperands(model, spec.operands), + o = [], i = 0, len = spec.operands.length; + + while (o.push("o"+i++) < len); + if (spec.type === 'and') spec.type = '&&'; + else if (spec.type === 'or') spec.type = '||'; + + return { + code: ops.code + "return " + o.join(spec.type) + ";", + signals: ops.signals, + data: ops.data + }; + } + + function parseIn(model, spec) { + var o = [spec.item], code = ""; + if (spec.range) o.push.apply(o, spec.range); + if (spec.scale) { + code = parseScale(spec.scale, o); + } + + var ops = parseOperands(model, o); + code = ops.code + code + "\n var ordSet = null;\n"; + + if (spec.data) { + var field = dl.field(spec.field).map(dl.str); + code += "var where = function(d) { return d["+field.join("][")+"] == o0 };\n"; + code += "return db["+dl.str(spec.data)+"].filter(where).length > 0;"; + } else if (spec.range) { + // TODO: inclusive/exclusive range? + if (spec.scale) { + code += "if (scale.length == 2) {\n" + // inverting ordinal scales + " ordSet = scale(o1, o2);\n" + + "} else {\n" + + " o1 = scale(o1);\no2 = scale(o2);\n" + + "}"; + } + + code += "return ordSet !== null ? ordSet.indexOf(o0) !== -1 :\n" + + " o1 < o2 ? o1 <= o0 && o0 <= o2 : o2 <= o0 && o0 <= o1;"; + } + + return { + code: code, + signals: ops.signals, + data: ops.data.concat(spec.data ? [spec.data] : []) + }; + } + +// Populate ops such that ultimate scale/inversion function will be in `scale` var. + function parseScale(spec, ops) { + var code = "var scale = ", + idx = ops.length; + + if (dl.isString(spec)) { + ops.push({ value: spec }); + code += "this.root().scale(o"+idx+")"; + } else if (spec.arg) { // Scale function is being passed as an arg + ops.push(spec); + code += "o"+idx; + } else if (spec.name) { // Full scale parameter {name: ..} + ops.push(dl.isString(spec.name) ? {value: spec.name} : spec.name); + code += "(this.isFunction(o"+idx+") ? o"+idx+" : "; + if (spec.scope) { + ops.push(spec.scope); + code += "((o"+(idx+1)+".scale || this.root().scale)(o"+idx+") || this.nullScale)"; + } else { + code += "this.root().scale(o"+idx+")"; + } + code += ")"; + } + + if (spec.invert === true) { // Allow spec.invert.arg? + code += ".invert"; + } + + return code+";\n"; + } + + module.exports = parsePredicates; +},{"datalib":26}],104:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + log = require('vega-logging'), + Tuple = require('vega-dataflow').Tuple; + + var DEPS = ["signals", "scales", "data", "fields"]; + + function properties(model, mark, spec) { + var config = model.config(), + code = "", + names = dl.keys(spec), + i, len, name, ref, vars = {}, + deps = { + signals: {}, + scales: {}, + data: {}, + fields: {}, + nested: [], + _nRefs: {}, // Temp stash to de-dupe nested refs. + reflow: false + }; + + code += "var o = trans ? {} : item, d=0, set=this.tpl.set, tmpl=signals||{}, t;\n" + + // Stash for dl.template + "tmpl.datum = item.datum;\n" + + "tmpl.group = group;\n" + + "tmpl.parent = group.datum;\n"; + + function handleDep(p) { + if (ref[p] == null) return; + var k = dl.array(ref[p]), i, n; + for (i=0, n=k.length; i 0) ? "\n " : " "; + if (ref.rule) { + ref = rule(model, name, ref.rule); + code += "\n " + ref.code; + } else if (dl.isArray(ref)) { + ref = rule(model, name, ref); + code += "\n " + ref.code; + } else { + ref = valueRef(config, name, ref); + code += "d += set(o, "+dl.str(name)+", "+ref.val+");"; + } + + vars[name] = true; + DEPS.forEach(handleDep); + deps.reflow = deps.reflow || ref.reflow; + if (ref.nested.length) ref.nested.forEach(handleNestedRefs); + } + + // If nested references are present, sort them based on their level + // to speed up determination of whether encoders should be reeval'd. + dl.keys(deps._nRefs).forEach(function(k) { deps.nested.push(deps._nRefs[k]); }); + deps.nested.sort(function(a, b) { + a = a.level; + b = b.level; + return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; + }); + + if (vars.x2) { + if (vars.x) { + code += "\n if (o.x > o.x2) { " + + "\n t = o.x;" + + "\n d += set(o, 'x', o.x2);" + + "\n d += set(o, 'x2', t); " + + "\n };"; + code += "\n d += set(o, 'width', (o.x2 - o.x));"; + } else if (vars.width) { + code += "\n d += set(o, 'x', (o.x2 - o.width));"; + } else { + code += "\n d += set(o, 'x', o.x2);"; + } + } + + if (vars.xc) { + if (vars.width) { + code += "\n d += set(o, 'x', (o.xc - o.width/2));" ; + } else { + code += "\n d += set(o, 'x', o.xc);" ; + } + } + + if (vars.y2) { + if (vars.y) { + code += "\n if (o.y > o.y2) { " + + "\n t = o.y;" + + "\n d += set(o, 'y', o.y2);" + + "\n d += set(o, 'y2', t);" + + "\n };"; + code += "\n d += set(o, 'height', (o.y2 - o.y));"; + } else if (vars.height) { + code += "\n d += set(o, 'y', (o.y2 - o.height));"; + } else { + code += "\n d += set(o, 'y', o.y2);"; + } + } + + if (vars.yc) { + if (vars.height) { + code += "\n d += set(o, 'y', (o.yc - o.height/2));" ; + } else { + code += "\n d += set(o, 'y', o.yc);" ; + } + } + + if (hasPath(mark, vars)) code += "\n d += (item.touch(), 1);"; + code += "\n if (trans) trans.interpolate(item, o);"; + code += "\n return d > 0;"; + + try { + /* jshint evil:true */ + var encoder = Function('item', 'group', 'trans', 'db', + 'signals', 'predicates', code); + encoder.tpl = Tuple; + encoder.util = dl; + encoder.d3 = d3; // For color spaces + dl.extend(encoder, dl.template.context); + return { + encode: encoder, + signals: dl.keys(deps.signals), + scales: dl.keys(deps.scales), + data: dl.keys(deps.data), + fields: dl.keys(deps.fields), + nested: deps.nested, + reflow: deps.reflow + }; + } catch (e) { + log.error(e); + log.log(code); + } + } + + function dependencies(a, b) { + if (!dl.isObject(a)) { + a = {reflow: false, nested: []}; + DEPS.forEach(function(d) { a[d] = []; }); + } + + if (dl.isObject(b)) { + a.reflow = a.reflow || b.reflow; + a.nested.push.apply(a.nested, b.nested); + DEPS.forEach(function(d) { a[d].push.apply(a[d], b[d]); }); + } + + return a; + } + + function hasPath(mark, vars) { + return vars.path || + ((mark==='area' || mark==='line') && + (vars.x || vars.x2 || vars.width || + vars.y || vars.y2 || vars.height || + vars.tension || vars.interpolate)); + } + + function rule(model, name, rules) { + var config = model.config(), + deps = dependencies(), + inputs = [], code = ''; + + (rules||[]).forEach(function(r, i) { + var def = r.predicate, + predName = def && (def.name || def), + pred = model.predicate(predName), + p = 'predicates['+dl.str(predName)+']', + input = [], args = name+'_arg'+i, + ref; + + if (dl.isObject(def)) { + dl.keys(def).forEach(function(k) { + if (k === 'name') return; + var ref = valueRef(config, i, def[k]); + input.push(dl.str(k)+': '+ref.val); + dependencies(deps, ref); + }); + } + + ref = valueRef(config, name, r); + dependencies(deps, ref); + + if (predName) { + deps.signals.push.apply(deps.signals, pred.signals); + deps.data.push.apply(deps.data, pred.data); + inputs.push(args+" = {\n "+input.join(",\n ")+"\n }"); + code += "if ("+p+".call("+p+","+args+", db, signals, predicates)) {" + + "\n d += set(o, "+dl.str(name)+", "+ref.val+");"; + code += rules[i+1] ? "\n } else " : " }"; + } else { + code += "{" + + "\n d += set(o, "+dl.str(name)+", "+ref.val+");"+ + "\n }\n"; + } + }); + + code = "var " + inputs.join(",\n ") + ";\n " + code; + return (deps.code = code, deps); + } + + function valueRef(config, name, ref) { + if (ref == null) return null; + + if (name==='fill' || name==='stroke') { + if (ref.c) { + return colorRef(config, 'hcl', ref.h, ref.c, ref.l); + } else if (ref.h || ref.s) { + return colorRef(config, 'hsl', ref.h, ref.s, ref.l); + } else if (ref.l || ref.a) { + return colorRef(config, 'lab', ref.l, ref.a, ref.b); + } else if (ref.r || ref.g || ref.b) { + return colorRef(config, 'rgb', ref.r, ref.g, ref.b); + } + } + + // initialize value + var val = null, scale = null, + deps = dependencies(), + sgRef = null, fRef = null, sRef = null, tmpl = {}; + + if (ref.template !== undefined) { + val = dl.template.source(ref.template, 'tmpl', tmpl); + dl.keys(tmpl).forEach(function(k) { + var f = dl.field(k), + a = f.shift(); + if (a === 'parent' || a === 'group') { + deps.nested.push({ + parent: a === 'parent', + group: a === 'group', + level: 1 + }); + } else if (a === 'datum') { + deps.fields.push(f[0]); + } else { + deps.signals.push(a); + } + }); + } + + if (ref.value !== undefined) { + val = dl.str(ref.value); + } + + if (ref.signal !== undefined) { + sgRef = dl.field(ref.signal); + val = 'signals['+sgRef.map(dl.str).join('][')+']'; + deps.signals.push(sgRef.shift()); + } + + if (ref.field !== undefined) { + ref.field = dl.isString(ref.field) ? {datum: ref.field} : ref.field; + fRef = fieldRef(ref.field); + val = fRef.val; + dependencies(deps, fRef); + } + + if (ref.scale !== undefined) { + sRef = scaleRef(ref.scale); + scale = sRef.val; + dependencies(deps, sRef); + deps.scales.push(ref.scale.name || ref.scale); + + // run through scale function if val specified. + // if no val, scale function is predicate arg. + if (val !== null || ref.band || ref.mult || ref.offset) { + val = scale + (ref.band ? '.rangeBand()' : + '('+(val !== null ? val : 'item.datum.data')+')'); + } else { + val = scale; + } + } + + // multiply, offset, return value + val = '(' + (ref.mult?(dl.number(ref.mult)+' * '):'') + val + ')' + + (ref.offset ? ' + ' + dl.number(ref.offset) : ''); + + // Collate dependencies + return (deps.val = val, deps); + } + + function colorRef(config, type, x, y, z) { + var xx = x ? valueRef(config, '', x) : config.color[type][0], + yy = y ? valueRef(config, '', y) : config.color[type][1], + zz = z ? valueRef(config, '', z) : config.color[type][2], + deps = dependencies(); + + [xx, yy, zz].forEach(function(v) { + if (dl.isArray) return; + dependencies(deps, v); + }); + + var val = '(this.d3.' + type + '(' + [xx.val, yy.val, zz.val].join(',') + ') + "")'; + return (deps.val = val, deps); + } + +// {field: {datum: "foo"} } -> item.datum.foo +// {field: {group: "foo"} } -> group.foo +// {field: {parent: "foo"} } -> group.datum.foo + function fieldRef(ref) { + if (dl.isString(ref)) { + return {val: dl.field(ref).map(dl.str).join('][')}; + } + + // Resolve nesting/parent lookups + var l = ref.level || 1, + nested = (ref.group || ref.parent) && l, + scope = nested ? Array(l).join('group.mark.') : '', + r = fieldRef(ref.datum || ref.group || ref.parent || ref.signal), + val = r.val, + deps = dependencies(null, r); + + if (ref.datum) { + val = 'item.datum['+val+']'; + deps.fields.push(ref.datum); + } else if (ref.group) { + val = scope+'group['+val+']'; + deps.nested.push({ level: l, group: true }); + } else if (ref.parent) { + val = scope+'group.datum['+val+']'; + deps.nested.push({ level: l, parent: true }); + } else if (ref.signal) { + val = 'signals['+val+']'; + deps.signals.push(dl.field(ref.signal)[0]); + deps.reflow = true; + } + + return (deps.val = val, deps); + } + +// {scale: "x"} +// {scale: {name: "x"}}, +// {scale: fieldRef} + function scaleRef(ref) { + var scale = null, + fr = null, + deps = dependencies(); + + if (dl.isString(ref)) { + scale = dl.str(ref); + } else if (ref.name) { + scale = dl.isString(ref.name) ? dl.str(ref.name) : (fr = fieldRef(ref.name)).val; + } else { + scale = (fr = fieldRef(ref)).val; + } + + scale = '(item.mark._scaleRefs['+scale+'] = 1, group.scale('+scale+'))'; + if (ref.invert) scale += '.invert'; + + // Mark scale refs as they're dealt with separately in mark._scaleRefs. + if (fr) fr.nested.forEach(function(g) { g.scale = true; }); + return fr ? (fr.val = scale, fr) : (deps.val = scale, deps); + } + + module.exports = properties; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"datalib":26,"vega-dataflow":41,"vega-logging":47}],105:[function(require,module,exports){ + var dl = require('datalib'), + SIGNALS = require('vega-dataflow').Dependencies.SIGNALS, + expr = require('./expr'); + + var RESERVED = ['datum', 'event', 'signals', 'width', 'height', 'padding'] + .concat(dl.keys(expr.codegen.functions)); + + function parseSignals(model, spec) { + // process each signal definition + (spec || []).forEach(function(s) { + if (RESERVED.indexOf(s.name) !== -1) { + throw Error('Signal name "'+s.name+'" is a '+ + 'reserved keyword ('+RESERVED.join(', ')+').'); + } + + var signal = model.signal(s.name, s.init) + .verbose(s.verbose); + + if (s.init && s.init.expr) { + s.init.expr = expr(s.init.expr); + signal.value(exprVal(model, s.init)); + } + + if (s.expr) { + s.expr = expr(s.expr); + signal.evaluate = function(input) { + var val = exprVal(model, s), + sg = input.signals; + if (val !== signal.value() || signal.verbose()) { + signal.value(val); + sg[s.name] = 1; + } + return sg[s.name] ? input : model.doNotPropagate; + }; + signal.dependency(SIGNALS, s.expr.globals); + s.expr.globals.forEach(function(dep) { + model.signal(dep).addListener(signal); + }); + } + }); + + return spec; + } + + function exprVal(model, spec) { + var e = spec.expr, + val = e.fn(null, null, model.values(SIGNALS, e.globals)); + return spec.scale ? parseSignals.scale(model, spec, val) : val; + } + + parseSignals.scale = function scale(model, spec, value, datum, evt) { + var def = spec.scale, + name = def.name || def.signal || def, + scope = def.scope, e; + + if (scope) { + if (scope.signal) { + scope = model.signalRef(scope.signal); + } else if (dl.isString(scope)) { // Scope is an expression + e = def._expr = (def._expr || expr(scope)); + scope = e.fn(datum, evt, model.values(SIGNALS, e.globals)); + } + } + + if (!scope || !scope.scale) { + scope = (scope && scope.mark) ? scope.mark.group : model.scene().items[0]; + } + + var s = scope.scale(name); + return !s ? value : (def.invert ? s.invert(value) : s(value)); + }; + + module.exports = parseSignals; +},{"./expr":96,"datalib":26,"vega-dataflow":41}],106:[function(require,module,exports){ + var dl = require('datalib'), + log = require('vega-logging'), + Model = require('../core/Model'), + View = require('../core/View'); + + function parseSpec(spec, callback) { + var vf = arguments[arguments.length-1], + viewFactory = arguments.length > 2 && dl.isFunction(vf) ? vf : View.factory, + config = arguments[2] !== viewFactory ? arguments[2] : {}, + model = new Model(config); + + function parse(spec) { + // protect against subsequent spec modification + spec = dl.duplicate(spec); + + var parsers = require('./'), + create = function() { callback(viewFactory(model)); }, + width = spec.width || 500, + height = spec.height || 500, + padding = parsers.padding(spec.padding); + + // create signals for width, height and padding + model.signal('width', width); + model.signal('height', height); + model.signal('padding', padding); + + // initialize model + model.defs({ + width: width, + height: height, + padding: padding, + viewport: spec.viewport || null, + background: parsers.background(spec.background), + signals: parsers.signals(model, spec.signals), + predicates: parsers.predicates(model, spec.predicates), + marks: parsers.marks(model, spec, width, height), + data: parsers.data(model, spec.data, create) + }); + } + + if (dl.isObject(spec)) { + parse(spec); + } else if (dl.isString(spec)) { + var opts = dl.extend({url: spec}, model.config().load); + dl.load(opts, function(err, data) { + if (err) { + log.error('LOADING SPECIFICATION FAILED: ' + err.statusText); + } else { + try { + parse(JSON.parse(data)); + } catch (e) { + log.error('INVALID SPECIFICATION: Must be a valid JSON object. '+e); + } + } + }); + } else { + log.error('INVALID SPECIFICATION: Must be a valid JSON object or URL.'); + } + } + + module.exports = parseSpec; +},{"../core/Model":88,"../core/View":89,"./":97,"datalib":26,"vega-logging":47}],107:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + df = require('vega-dataflow'), + SIGNALS = df.Dependencies.SIGNALS, + parseSignals = require('./signals'), + selector = require('./events'), + expr = require('./expr'); + + var GATEKEEPER = '_vgGATEKEEPER'; + + var vgEvent = { + getGroup: function(name) { return name ? this.name[name] : this.group; }, + getXY: function(item) { + var p = {x: this.x, y: this.y}; + if (typeof item === 'string') { + item = this.name[item]; + } + for (; item; item = item.mark && item.mark.group) { + p.x -= item.x || 0; + p.y -= item.y || 0; + } + return p; + }, + getX: function(item) { return this.getXY(item).x; }, + getY: function(item) { return this.getXY(item).y; } + }; + + function parseStreams(view) { + var model = view.model(), + spec = model.defs().signals, + registry = {handlers: {}, nodes: {}}, + internal = dl.duplicate(registry), // Internal event processing + external = dl.duplicate(registry); // External event processing + + (spec || []).forEach(function(sig) { + var signal = model.signal(sig.name); + if (sig.expr) return; // Cannot have an expr and stream definition. + + (sig.streams || []).forEach(function(stream) { + var sel = selector.parse(stream.type), + exp = expr(stream.expr); + mergedStream(signal, sel, exp, stream); + }); + }); + + // We register the event listeners all together so that if multiple + // signals are registered on the same event, they will receive the + // new value on the same pulse. + dl.keys(internal.handlers).forEach(function(type) { + view.on(type, function(evt, item) { + evt.preventDefault(); // stop text selection + extendEvent(evt, item); + fire(internal, type, (item && item.datum) || {}, evt); + }); + }); + + // add external event listeners + dl.keys(external.handlers).forEach(function(type) { + if (typeof window === 'undefined') return; // No external support + + var h = external.handlers[type], + t = type.split(':'), // --> no element pseudo-selectors + elt = (t[0] === 'window') ? [window] : + window.document.querySelectorAll(t[0]); + + function handler(evt) { + extendEvent(evt); + fire(external, type, d3.select(this).datum(), evt); + } + + for (var i=0; i 0, + i, ilen, j, jlen, group, legend; + + if (input.add.length || input.rem.length || !items.length || + input.mod.length === items.length || + type === 'area' || type === 'line') { + bound.mark(this._mark, null, isGrp && !hasLegends); + } else { + input.mod.forEach(function(item) { bound.item(item); }); + } + + if (isGrp && hasLegends) { + for (i=0, ilen=items.length; i this._stamp) { + join.call(this, fcs, output, this._ds.values(), true, fullUpdate); + } else if (fullUpdate) { + output.mod = this._mark.items.slice(); + } + } else { + data = dl.isFunction(this._def.from) ? this._def.from() : [Sentinel]; + join.call(this, input, output, data); + } + + // Stash output before Bounder for downstream reactive geometry. + this._output = output = this._graph.evaluate(output, this._encoder); + + // Add any new scale references to the dependency list, and ensure + // they're connected. + if (update.nested && update.nested.length && this._status === CONNECTED) { + dl.keys(this._mark._scaleRefs).forEach(function(s) { + var scale = self._parent.scale(s); + if (!scale) return; + + scale.addListener(self); + self.dependency(Deps.SCALES, s); + self._encoder.dependency(Deps.SCALES, s); + }); + } + + // Supernodes calculate bounds too, but only on items marked dirty. + if (this._isSuper) { + output.mod = output.mod.filter(function(x) { return x._dirty; }); + output = this._graph.evaluate(output, this._bounder); + } + + return output; + }; + + function newItem() { + var item = Tuple.ingest(new Item(this._mark)); + + // For the root node's item + if (this._def.width) Tuple.set(item, 'width', this._def.width); + if (this._def.height) Tuple.set(item, 'height', this._def.height); + return item; + } + + function join(input, output, data, ds, fullUpdate) { + var keyf = keyFunction(this._def.key || (ds ? '_id' : null)), + prev = this._mark.items || [], + rem = ds ? input.rem : prev, + mod = Tuple.idMap((!ds || fullUpdate) ? data : input.mod), + next = [], + i, key, len, item, datum, enter, diff; + + // Only mark rems as exiting. Due to keyf, there may be an add/mod + // tuple that replaces it. + for (i=0, len=rem.length; i0) s += '|'; + s += String(f[i](d)); + } + return s; + }; + } + + module.exports = Builder; +},{"../parse/data":94,"./Bounder":109,"./Encoder":111,"datalib":26,"vega-dataflow":41,"vega-logging":47,"vega-scenegraph":48}],111:[function(require,module,exports){ + var dl = require('datalib'), + log = require('vega-logging'), + df = require('vega-dataflow'), + Node = df.Node, // jshint ignore:line + Deps = df.Dependencies, + bound = require('vega-scenegraph').bound; + + var EMPTY = {}; + + function Encoder(graph, mark, builder) { + var props = mark.def.properties || {}, + enter = props.enter, + update = props.update, + exit = props.exit; + + Node.prototype.init.call(this, graph); + + this._mark = mark; + this._builder = builder; + var s = this._scales = []; + + // Only scales used in the 'update' property set are set as + // encoder depedencies to have targeted reevaluations. However, + // we still want scales in 'enter' and 'exit' to be evaluated + // before the encoder. + if (enter) s.push.apply(s, enter.scales); + + if (update) { + this.dependency(Deps.DATA, update.data); + this.dependency(Deps.SIGNALS, update.signals); + this.dependency(Deps.FIELDS, update.fields); + this.dependency(Deps.SCALES, update.scales); + s.push.apply(s, update.scales); + } + + if (exit) s.push.apply(s, exit.scales); + + return this.mutates(true); + } + + var proto = (Encoder.prototype = new Node()); + + proto.evaluate = function(input) { + log.debug(input, ['encoding', this._mark.def.type]); + var graph = this._graph, + props = this._mark.def.properties || {}, + items = this._mark.items, + enter = props.enter, + update = props.update, + exit = props.exit, + dirty = input.dirty, + preds = graph.predicates(), + req = input.request, + group = this._mark.group, + guide = group && (group.mark.axis || group.mark.legend), + db = EMPTY, sg = EMPTY, i, len, item, prop; + + if (req && !guide) { + if ((prop = props[req]) && input.mod.length) { + db = prop.data ? graph.values(Deps.DATA, prop.data) : null; + sg = prop.signals ? graph.values(Deps.SIGNALS, prop.signals) : null; + + for (i=0, len=input.mod.length; i this._stamp) return true; + } + + return false; + } + +// Short-circuit encoder if user specifies items + Encoder.update = function(graph, trans, request, items, dirty) { + items = dl.array(items); + var preds = graph.predicates(), + db = graph.values(Deps.DATA), + sg = graph.values(Deps.SIGNALS), + i, len, item, props, prop; + + for (i=0, len=items.length; i 0, + hasAxes = dl.array(this._def.axes).length > 0, + hasLegends = dl.array(this._def.legends).length > 0, + i, j, c, len, group, pipeline, def, inline = false; + + for (i=0, len=input.add.length; i=0; --i) { + group = input.add[i]; + for (j=this._children[group._id].length-1; j>=0; --j) { + c = this._children[group._id][j]; + c.builder.connect(); + pipeline = c.builder.pipeline(); + def = c.builder._def; + + // This new child needs to be built during this propagation cycle. + // We could add its builder as a listener off the _recursor node, + // but try to inline it if we can to minimize graph dispatches. + inline = (def.type !== Types.GROUP); + inline = inline && (this._graph.data(c.from) !== undefined); + inline = inline && (pipeline[pipeline.length-1].listeners().length === 1); // Reactive geom source + inline = inline && (def.from && !def.from.mark); // Reactive geom target + c.inline = inline; + + if (inline) this._graph.evaluate(input, c.builder); + else this._recursor.addListener(c.builder); + } + } + + function removeTemp(c) { + if (c.type == Types.MARK && !c.inline && + builder._graph.data(c.from) !== undefined) { + builder._recursor.removeListener(c.builder); + } + } + + function updateAxis(a) { + var scale = a.scale(); + if (!input.scales[scale.scaleName]) return; + a.reset().def(); + } + + function updateLegend(l) { + var scale = l.size() || l.shape() || l.fill() || l.stroke(); + if (!input.scales[scale.scaleName]) return; + l.reset().def(); + } + + for (i=0, len=input.mod.length; i rng[1]) { + start = rng[1] || 0; + rng = [start + (bw * len + space), start]; + } else { + start = rng[0] || 0; + rng = [start, start + (bw * len + space)]; + } + } + + str = typeof rng[0] === 'string'; + if (str || rng.length > 2 || rng.length===1 || dataDrivenRange) { + scale.range(rng); // color or shape values + spatial = false; + } else if (points && round) { + scale.rangeRoundPoints(rng, pad); + } else if (points) { + scale.rangePoints(rng, pad); + } else if (round) { + scale.rangeRoundBands(rng, pad, outer); + } else { + scale.rangeBands(rng, pad, outer); + } + + prev.range = rng; + this._updated = true; + } + + if (!scale.invert && spatial) invertOrdinal(scale); + } + +// "Polyfill" ordinal scale inversion. Currently, only ordinal scales +// with ordered numeric ranges are supported. + var bisect = d3.bisector(dl.numcmp).right, + findAsc = function(a, x) { return bisect(a,x) - 1; }, + findDsc = d3.bisector(function(a,b) { return -1 * dl.numcmp(a,b); }).left; + + function invertOrdinal(scale) { + scale.invert = function(x, y) { + var rng = scale.range(), + asc = rng[0] < rng[1], + find = asc ? findAsc : findDsc; + + if (arguments.length === 1) { + if (!dl.isNumber(x)) { + throw Error('Ordinal scale inversion is only supported for numeric input ('+x+').'); + } + return scale.domain()[find(rng, x)]; + + } else if (arguments.length === 2) { // Invert extents + if (!dl.isNumber(x) || !dl.isNumber(y)) { + throw Error('Extents to ordinal invert are not numbers ('+x+', '+y+').'); + } + + var domain = scale.domain(), + a = find(rng, x), + b = find(rng, y), + n = rng.length - 1, r; + if (b < a) { r = a; a = b; b = a; } // ensure a <= b + if (a < 0) a = 0; + if (b > n) b = n; + + return (asc ? dl.range(a, b+1) : dl.range(b, a-1, -1)) + .map(function(i) { return domain[i]; }); + } + }; + } + + function quantitative(scale, rng, group) { + var def = this._def, + prev = scale._prev, + round = signal.call(this, def.round), + exponent = signal.call(this, def.exponent), + clamp = signal.call(this, def.clamp), + nice = signal.call(this, def.nice), + domain, interval; + + // domain + domain = (def.type === Types.QUANTILE) ? + dataRef.call(this, DataRef.DOMAIN, def.domain, scale, group) : + domainMinMax.call(this, scale, group); + if (domain && !dl.equal(prev.domain, domain)) { + scale.domain(domain); + prev.domain = domain; + this._updated = true; + } + + // range + // vertical scales should flip by default, so use XOR here + if (signal.call(this, def.range) === 'height') rng = rng.reverse(); + if (dl.equal(prev.range, rng)) return; + scale[round && scale.rangeRound ? 'rangeRound' : 'range'](rng); + prev.range = rng; + this._updated = true; + + // TODO: Support signals for these properties. Until then, only eval + // them once. + if (this._stamp > 0) return; + if (exponent && def.type===Types.POWER) scale.exponent(exponent); + if (clamp) scale.clamp(true); + if (nice) { + if (def.type === Types.TIME) { + interval = d3.time[nice]; + if (!interval) log.error('Unrecognized interval: ' + interval); + scale.nice(interval); + } else { + scale.nice(); + } + } + } + + function isUniques(scale) { + return scale.type === Types.ORDINAL || scale.type === Types.QUANTILE; + } + + function getRefs(def) { + return def.fields || dl.array(def); + } + + function inherits(refs) { + return refs.some(function(r) { + if (!r.data) return true; + return r.data && dl.array(r.field).some(function(f) { + return f.parent; + }); + }); + } + + function getFields(ref, group) { + return dl.array(ref.field).map(function(f) { + return f.parent ? + dl.accessor(f.parent)(group.datum) : + f; // String or {'signal'} + }); + } + +// Scale datarefs can be computed over multiple schema types. +// This function determines the type of aggregator created, and +// what data is sent to it: values, tuples, or multi-tuples that must +// be standardized into a consistent schema. + function aggrType(def, scale) { + var refs = getRefs(def); + + // If we're operating over only a single domain, send full tuples + // through for efficiency (fewer accessor creations/calls) + if (refs.length == 1 && dl.array(refs[0].field).length == 1) { + return Aggregate.TYPES.TUPLE; + } + + // With quantitative scales, we only care about min/max. + if (!isUniques(scale)) return Aggregate.TYPES.VALUE; + + // If we don't sort, then we can send values directly to aggrs as well + if (!dl.isObject(def.sort)) return Aggregate.TYPES.VALUE; + + return Aggregate.TYPES.MULTI; + } + + function getCache(which, def, scale, group) { + var refs = getRefs(def), + inherit = inherits(refs), + atype = aggrType(def, scale), + uniques = isUniques(scale), + sort = def.sort, + ck = '_'+which, + fields = getFields(refs[0], group); + + if (scale[ck] || this[ck]) return scale[ck] || this[ck]; + + var cache = new Aggregate(this._graph).type(atype), + groupby, summarize; + + // If a scale's dataref doesn't inherit data from the group, we can + // store the dataref aggregator at the Scale (dataflow node) level. + if (inherit) { + scale[ck] = cache; + } else { + this[ck] = cache; + } + + if (uniques) { + if (atype === Aggregate.TYPES.VALUE) { + groupby = [{ name: DataRef.GROUPBY, get: dl.identity }]; + summarize = {'*': DataRef.COUNT}; + } else if (atype === Aggregate.TYPES.TUPLE) { + groupby = [{ name: DataRef.GROUPBY, get: dl.$(fields[0]) }]; + summarize = dl.isObject(sort) ? [{ + field: DataRef.VALUE, + get: dl.$(sort.field), + ops: [sort.op] + }] : {'*': DataRef.COUNT}; + } else { // atype === Aggregate.TYPES.MULTI + groupby = DataRef.GROUPBY; + summarize = [{ field: DataRef.VALUE, ops: [sort.op] }]; + } + } else { + groupby = []; + summarize = [{ + field: DataRef.VALUE, + get: (atype == Aggregate.TYPES.TUPLE) ? dl.$(fields[0]) : dl.identity, + ops: [DataRef.MIN, DataRef.MAX], + as: [DataRef.MIN, DataRef.MAX] + }]; + } + + cache.param('groupby', groupby) + .param('summarize', summarize); + + return (cache._lastUpdate = -1, cache); + } + + function dataRef(which, def, scale, group) { + if (def == null) { return []; } + if (dl.isArray(def)) return def.map(signal.bind(this)); + + var self = this, graph = this._graph, + refs = getRefs(def), + inherit = inherits(refs), + atype = aggrType(def, scale), + cache = getCache.apply(this, arguments), + sort = def.sort, + uniques = isUniques(scale), + i, rlen, j, flen, ref, fields, field, data, from, so, cmp; + + function addDep(s) { + self.dependency(Deps.SIGNALS, s); + } + + if (inherit || (!inherit && cache._lastUpdate < this._stamp)) { + for (i=0, rlen=refs.length; i 1) f = 1; + e = curr.ease(f); + + for (i=0, n=curr.length; i 0 ? (e = 1e-12, Math.ceil) : (e = -1e-12, Math.floor), + e; + function log(x) { + return (domain[0] < 0 ? + -Math.log(x > 0 ? 0 : -x) : + Math.log(x < 0 ? 0 : x)) / Math.log(base); + } + function pow(x) { + return domain[0] < 0 ? -Math.pow(base, -x) : Math.pow(base, x); + } + return function(d) { + return pow(v(log(d) + e)) / d >= k ? f(d) : ''; + }; + } + + function getFormatter(formatType, str) { + var fmt = dl.format, + log = scale.type === 'log', + domain, f; + + switch (formatType) { + case NUMBER: + domain = scale.domain(); + f = fmt.auto.number(domain, tickCount, str || (log ? '.1r' : null)); + return log ? logFilter(domain, tickCount, f) : f; + case TIME: return (str ? fmt : fmt.auto).time(str); + case UTC: return (str ? fmt : fmt.auto).utc(str); + default: return String; + } + } + + function getTicks(format) { + var major = tickValues || (scale.ticks ? scale.ticks(tickCount) : scale.domain()), + minor = axisSubdivide(scale, major, tickSubdivide).map(ingest); + major = major.map(function(d) { return (d = ingest(d), d.label = format(d.data), d); }); + return [major, minor]; + } + + axis.def = function() { + if (!axisDef.type) axis_def(scale); + + var ticks = getTicks(getTickFormat()); + var tdata = title ? [title].map(ingest) : []; + + axisDef.marks[0].from = function() { return grid ? ticks[0] : []; }; + axisDef.marks[1].from = function() { return ticks[0]; }; + axisDef.marks[2].from = function() { return ticks[1]; }; + axisDef.marks[3].from = axisDef.marks[1].from; + axisDef.marks[4].from = function() { return [1]; }; + axisDef.marks[5].from = function() { return tdata; }; + axisDef.offset = offset; + axisDef.orient = orient; + axisDef.layer = layer; + if (titleOffset === 'auto') titleAutoOffset(axisDef); + + return axisDef; + }; + + function titleAutoOffset(axisDef) { + var orient = axisDef.orient, + update = axisDef.marks[5].properties.update, + fn = update.encode, + min = config.titleOffsetAutoMin, + max = config.titleOffsetAutoMax, + pad = config.titleOffsetAutoMargin; + + // Offset axis title using bounding box of axis domain and labels + // Assumes other components are **encoded and bounded** beforehand + update.encode = function(item, group, trans, db, signals, preds) { + var dirty = fn.call(fn, item, group, trans, db, signals, preds), + field = (orient==='bottom' || orient==='top') ? 'y' : 'x'; + if (titleStyle[field] != null) return dirty; + + axisBounds.clear() + .union(group.items[3].bounds) + .union(group.items[4].bounds); + + var o = trans ? {} : item, + method = (orient==='left' || orient==='right') ? 'width' : 'height', + sign = (orient==='top' || orient==='left') ? -1 : 1, + off = ~~(axisBounds[method]() + item.fontSize/2 + pad); + + Tuple.set(o, field, sign * Math.min(Math.max(min, off), max)); + if (trans) trans.interpolate(item, o); + return true; + }; + } + + function axis_def(scale) { + // setup scale mapping + var newScale, oldScale, range; + if (scale.type === ORDINAL) { + newScale = {scale: scale.scaleName, offset: 0.5 + scale.rangeBand()/2}; + oldScale = newScale; + } else { + newScale = {scale: scale.scaleName, offset: 0.5}; + oldScale = {scale: scale.scaleName+':prev', offset: 0.5}; + } + range = axisScaleRange(scale); + + // setup axis marks + dl.extend(m.gridLines, axisTicks(config)); + dl.extend(m.majorTicks, axisTicks(config)); + dl.extend(m.minorTicks, axisTicks(config)); + dl.extend(m.tickLabels, axisTickLabels(config)); + dl.extend(m.domain, axisDomain(config)); + dl.extend(m.title, axisTitle(config)); + m.gridLines.properties.enter.stroke = {value: config.gridColor}; + m.gridLines.properties.enter.strokeOpacity = {value: config.gridOpacity}; + + // extend axis marks based on axis orientation + axisTicksExtend(orient, m.gridLines, oldScale, newScale, Infinity); + axisTicksExtend(orient, m.majorTicks, oldScale, newScale, tickMajorSize); + axisTicksExtend(orient, m.minorTicks, oldScale, newScale, tickMinorSize); + axisLabelExtend(orient, m.tickLabels, oldScale, newScale, tickMajorSize, tickPadding); + + axisDomainExtend(orient, m.domain, range, tickEndSize); + axisTitleExtend(orient, m.title, range, +titleOffset || -1); + + // add / override custom style properties + dl.extend(m.gridLines.properties.update, gridLineStyle); + dl.extend(m.majorTicks.properties.update, majorTickStyle); + dl.extend(m.minorTicks.properties.update, minorTickStyle); + dl.extend(m.tickLabels.properties.update, tickLabelStyle); + dl.extend(m.domain.properties.update, domainStyle); + dl.extend(m.title.properties.update, titleStyle); + + var marks = [m.gridLines, m.majorTicks, m.minorTicks, m.tickLabels, m.domain, m.title]; + dl.extend(axisDef, { + type: 'group', + interactive: false, + properties: { + enter: { + encode: axisUpdate, + scales: [scale.scaleName], + signals: [], data: [] + }, + update: { + encode: axisUpdate, + scales: [scale.scaleName], + signals: [], data: [] + } + } + }); + + axisDef.marks = marks.map(function(m) { return parseMark(model, m); }); + } + + axis.scale = function(x) { + if (!arguments.length) return scale; + if (scale !== x) { scale = x; reset(); } + return axis; + }; + + axis.orient = function(x) { + if (!arguments.length) return orient; + if (orient !== x) { + orient = x in axisOrients ? x + '' : config.orient; + reset(); + } + return axis; + }; + + axis.title = function(x) { + if (!arguments.length) return title; + if (title !== x) { title = x; reset(); } + return axis; + }; + + axis.tickCount = function(x) { + if (!arguments.length) return tickCount; + tickCount = x; + return axis; + }; + + axis.tickValues = function(x) { + if (!arguments.length) return tickValues; + tickValues = x; + return axis; + }; + + axis.tickFormat = function(x) { + if (!arguments.length) return tickFormatString; + if (tickFormatString !== x) { + tickFormatString = x; + reset(); + } + return axis; + }; + + axis.tickFormatType = function(x) { + if (!arguments.length) return tickFormatType; + if (tickFormatType !== x) { + tickFormatType = x; + reset(); + } + return axis; + }; + + axis.tickSize = function(x, y) { + if (!arguments.length) return tickMajorSize; + var n = arguments.length - 1, + major = +x, + minor = n > 1 ? +y : tickMajorSize, + end = n > 0 ? +arguments[n] : tickMajorSize; + + if (tickMajorSize !== major || + tickMinorSize !== minor || + tickEndSize !== end) { + reset(); + } + + tickMajorSize = major; + tickMinorSize = minor; + tickEndSize = end; + return axis; + }; + + axis.tickSubdivide = function(x) { + if (!arguments.length) return tickSubdivide; + tickSubdivide = +x; + return axis; + }; + + axis.offset = function(x) { + if (!arguments.length) return offset; + offset = dl.isObject(x) ? x : +x; + return axis; + }; + + axis.tickPadding = function(x) { + if (!arguments.length) return tickPadding; + if (tickPadding !== +x) { tickPadding = +x; reset(); } + return axis; + }; + + axis.titleOffset = function(x) { + if (!arguments.length) return titleOffset; + if (titleOffset !== x) { titleOffset = x; reset(); } + return axis; + }; + + axis.layer = function(x) { + if (!arguments.length) return layer; + if (layer !== x) { layer = x; reset(); } + return axis; + }; + + axis.grid = function(x) { + if (!arguments.length) return grid; + if (grid !== x) { grid = x; reset(); } + return axis; + }; + + axis.gridLineProperties = function(x) { + if (!arguments.length) return gridLineStyle; + if (gridLineStyle !== x) { gridLineStyle = x; } + return axis; + }; + + axis.majorTickProperties = function(x) { + if (!arguments.length) return majorTickStyle; + if (majorTickStyle !== x) { majorTickStyle = x; } + return axis; + }; + + axis.minorTickProperties = function(x) { + if (!arguments.length) return minorTickStyle; + if (minorTickStyle !== x) { minorTickStyle = x; } + return axis; + }; + + axis.tickLabelProperties = function(x) { + if (!arguments.length) return tickLabelStyle; + if (tickLabelStyle !== x) { tickLabelStyle = x; } + return axis; + }; + + axis.titleProperties = function(x) { + if (!arguments.length) return titleStyle; + if (titleStyle !== x) { titleStyle = x; } + return axis; + }; + + axis.domainProperties = function(x) { + if (!arguments.length) return domainStyle; + if (domainStyle !== x) { domainStyle = x; } + return axis; + }; + + axis.reset = function() { + reset(); + return axis; + }; + + return axis; + } + + var axisOrients = {top: 1, right: 1, bottom: 1, left: 1}; + + function axisSubdivide(scale, ticks, m) { + var subticks = []; + if (m && ticks.length > 1) { + var extent = axisScaleExtent(scale.domain()), + i = -1, + n = ticks.length, + d = (ticks[1] - ticks[0]) / ++m, + j, + v; + while (++i < n) { + for (j = m; --j > 0;) { + if ((v = +ticks[i] - j * d) >= extent[0]) { + subticks.push(v); + } + } + } + for (--i, j = 0; ++j < m && (v = +ticks[i] + j * d) < extent[1];) { + subticks.push(v); + } + } + return subticks; + } + + function axisScaleExtent(domain) { + var start = domain[0], stop = domain[domain.length - 1]; + return start < stop ? [start, stop] : [stop, start]; + } + + function axisScaleRange(scale) { + return scale.rangeExtent ? + scale.rangeExtent() : + axisScaleExtent(scale.range()); + } + + var axisAlign = { + bottom: 'center', + top: 'center', + left: 'right', + right: 'left' + }; + + var axisBaseline = { + bottom: 'top', + top: 'bottom', + left: 'middle', + right: 'middle' + }; + + function axisLabelExtend(orient, labels, oldScale, newScale, size, pad) { + size = Math.max(size, 0) + pad; + if (orient === 'left' || orient === 'top') { + size *= -1; + } + if (orient === 'top' || orient === 'bottom') { + dl.extend(labels.properties.enter, { + x: oldScale, + y: {value: size}, + }); + dl.extend(labels.properties.update, { + x: newScale, + y: {value: size}, + align: {value: 'center'}, + baseline: {value: axisBaseline[orient]} + }); + } else { + dl.extend(labels.properties.enter, { + x: {value: size}, + y: oldScale, + }); + dl.extend(labels.properties.update, { + x: {value: size}, + y: newScale, + align: {value: axisAlign[orient]}, + baseline: {value: 'middle'} + }); + } + } + + function axisTicksExtend(orient, ticks, oldScale, newScale, size) { + var sign = (orient === 'left' || orient === 'top') ? -1 : 1; + if (size === Infinity) { + size = (orient === 'top' || orient === 'bottom') ? + {field: {group: 'height', level: 2}, mult: -sign} : + {field: {group: 'width', level: 2}, mult: -sign}; + } else { + size = {value: sign * size}; + } + if (orient === 'top' || orient === 'bottom') { + dl.extend(ticks.properties.enter, { + x: oldScale, + y: {value: 0}, + y2: size + }); + dl.extend(ticks.properties.update, { + x: newScale, + y: {value: 0}, + y2: size + }); + dl.extend(ticks.properties.exit, { + x: newScale, + }); + } else { + dl.extend(ticks.properties.enter, { + x: {value: 0}, + x2: size, + y: oldScale + }); + dl.extend(ticks.properties.update, { + x: {value: 0}, + x2: size, + y: newScale + }); + dl.extend(ticks.properties.exit, { + y: newScale, + }); + } + } + + function axisTitleExtend(orient, title, range, offset) { + var update = title.properties.update, + mid = ~~((range[0] + range[1]) / 2), + sign = (orient === 'top' || orient === 'left') ? -1 : 1; + + if (orient === 'bottom' || orient === 'top') { + update.x = {value: mid}; + update.angle = {value: 0}; + if (offset >= 0) update.y = sign * offset; + } else { + update.y = {value: mid}; + update.angle = {value: orient === 'left' ? -90 : 90}; + if (offset >= 0) update.x = sign * offset; + } + } + + function axisDomainExtend(orient, domain, range, size) { + var path; + if (orient === 'top' || orient === 'left') { + size = -1 * size; + } + if (orient === 'bottom' || orient === 'top') { + path = 'M' + range[0] + ',' + size + 'V0H' + range[1] + 'V' + size; + } else { + path = 'M' + size + ',' + range[0] + 'H0V' + range[1] + 'H' + size; + } + domain.properties.update.path = {value: path}; + } + + function axisUpdate(item, group, trans) { + var o = trans ? {} : item, + offset = item.mark.def.offset, + orient = item.mark.def.orient, + width = group.width, + height = group.height; // TODO fallback to global w,h? + + if (dl.isArray(offset)) { + var ofx = offset[0], + ofy = offset[1]; + + switch (orient) { + case 'left': { Tuple.set(o, 'x', -ofx); Tuple.set(o, 'y', ofy); break; } + case 'right': { Tuple.set(o, 'x', width + ofx); Tuple.set(o, 'y', ofy); break; } + case 'bottom': { Tuple.set(o, 'x', ofx); Tuple.set(o, 'y', height + ofy); break; } + case 'top': { Tuple.set(o, 'x', ofx); Tuple.set(o, 'y', -ofy); break; } + default: { Tuple.set(o, 'x', ofx); Tuple.set(o, 'y', ofy); } + } + } else { + if (dl.isObject(offset)) { + offset = -group.scale(offset.scale)(offset.value); + } + + switch (orient) { + case 'left': { Tuple.set(o, 'x', -offset); Tuple.set(o, 'y', 0); break; } + case 'right': { Tuple.set(o, 'x', width + offset); Tuple.set(o, 'y', 0); break; } + case 'bottom': { Tuple.set(o, 'x', 0); Tuple.set(o, 'y', height + offset); break; } + case 'top': { Tuple.set(o, 'x', 0); Tuple.set(o, 'y', -offset); break; } + default: { Tuple.set(o, 'x', 0); Tuple.set(o, 'y', 0); } + } + } + + if (trans) trans.interpolate(item, o); + return true; + } + + function axisTicks(config) { + return { + type: 'rule', + interactive: false, + key: 'data', + properties: { + enter: { + stroke: {value: config.tickColor}, + strokeWidth: {value: config.tickWidth}, + opacity: {value: 1e-6} + }, + exit: { opacity: {value: 1e-6} }, + update: { opacity: {value: 1} } + } + }; + } + + function axisTickLabels(config) { + return { + type: 'text', + interactive: true, + key: 'data', + properties: { + enter: { + fill: {value: config.tickLabelColor}, + font: {value: config.tickLabelFont}, + fontSize: {value: config.tickLabelFontSize}, + opacity: {value: 1e-6}, + text: {field: 'label'} + }, + exit: { opacity: {value: 1e-6} }, + update: { opacity: {value: 1} } + } + }; + } + + function axisTitle(config) { + return { + type: 'text', + interactive: true, + properties: { + enter: { + font: {value: config.titleFont}, + fontSize: {value: config.titleFontSize}, + fontWeight: {value: config.titleFontWeight}, + fill: {value: config.titleColor}, + align: {value: 'center'}, + baseline: {value: 'middle'}, + text: {field: 'data'} + }, + update: {} + } + }; + } + + function axisDomain(config) { + return { + type: 'path', + interactive: false, + properties: { + enter: { + x: {value: 0.5}, + y: {value: 0.5}, + stroke: {value: config.axisColor}, + strokeWidth: {value: config.axisWidth} + }, + update: {} + } + }; + } + + module.exports = axs; +},{"../parse/mark":99,"datalib":26,"vega-dataflow":41,"vega-scenegraph":48}],116:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + Gradient = require('vega-scenegraph').Gradient, + parseProperties = require('../parse/properties'), + parseMark = require('../parse/mark'); + + function lgnd(model) { + var size = null, + shape = null, + fill = null, + stroke = null, + spacing = null, + values = null, + format = null, + formatString = null, + config = model.config().legend, + title, + orient = config.orient, + offset = config.offset, + padding = config.padding, + tickArguments = [5], + legendStyle = {}, + symbolStyle = {}, + gradientStyle = {}, + titleStyle = {}, + labelStyle = {}, + m = { // Legend marks as references for updates + titles: {}, + symbols: {}, + labels: {}, + gradient: {} + }; + + var legend = {}, + legendDef = {}; + + function reset() { legendDef.type = null; } + function ingest(d, i) { return {data: d, index: i}; } + + legend.def = function() { + var scale = size || shape || fill || stroke; + + format = !formatString ? null : ((scale.type === 'time') ? + dl.format.time(formatString) : dl.format.number(formatString)); + + if (!legendDef.type) { + legendDef = (scale===fill || scale===stroke) && !discrete(scale.type) ? + quantDef(scale) : ordinalDef(scale); + } + legendDef.orient = orient; + legendDef.offset = offset; + legendDef.padding = padding; + legendDef.margin = config.margin; + return legendDef; + }; + + function discrete(type) { + return type==='ordinal' || type==='quantize' || + type==='quantile' || type==='threshold'; + } + + function ordinalDef(scale) { + var def = o_legend_def(size, shape, fill, stroke); + + // generate data + var data = (values == null ? + (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : + values).map(ingest); + var fmt = format==null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : String) : format; + + // determine spacing between legend entries + var fs, range, offset, pad=5, domain = d3.range(data.length); + if (size) { + range = data.map(function(x) { return Math.sqrt(size(x.data)); }); + offset = d3.max(range); + range = range.reduce(function(a,b,i,z) { + if (i > 0) a[i] = a[i-1] + z[i-1]/2 + pad; + return (a[i] += b/2, a); }, [0]).map(Math.round); + } else { + offset = Math.round(Math.sqrt(config.symbolSize)); + range = spacing || + (fs = labelStyle.fontSize) && (fs.value + pad) || + (config.labelFontSize + pad); + range = domain.map(function(d,i) { + return Math.round(offset/2 + i*range); + }); + } + + // account for padding and title size + var sz = padding, ts; + if (title) { + ts = titleStyle.fontSize; + sz += 5 + ((ts && ts.value) || config.titleFontSize); + } + for (var i=0, n=range.length; i'}, + summarize: { + type: 'custom', + set: function(summarize) { + var signalDeps = {}, + tx = this._transform, + i, len, f, fields, name, ops; + + if (!dl.isArray(fields = summarize)) { // Object syntax from dl + fields = []; + for (name in summarize) { + ops = dl.array(summarize[name]); + fields.push({field: name, ops: ops}); + } + } + + function sg(x) { if (x.signal) signalDeps[x.signal] = 1; } + + for (i=0, len=fields.length; i', default: [5, 2]} + }); + + this._output = { + start: 'bin_start', + end: 'bin_end', + mid: 'bin_mid' + }; + return this.mutates(true); + } + + var prototype = (Bin.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Bin; + + prototype.extent = function(data) { + // TODO only recompute extent upon data or field change? + var e = [this.param('min'), this.param('max')], d; + if (e[0] == null || e[1] == null) { + d = dl.extent(data, this.param('field').accessor); + if (e[0] == null) e[0] = d[0]; + if (e[1] == null) e[1] = d[1]; + } + return e; + }; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['binning']); + + var extent = this.extent(data), + output = this._output, + step = this.param('step'), + steps = this.param('steps'), + minstep = this.param('minstep'), + get = this.param('field').accessor, + opt = { + min: extent[0], + max: extent[1], + base: this.param('base'), + maxbins: this.param('maxbins'), + div: this.param('div') + }; + + if (step) opt.step = step; + if (steps) opt.steps = steps; + if (minstep) opt.minstep = minstep; + var b = dl.bins(opt), + s = b.step; + + function update(d) { + var v = get(d); + v = v == null ? null + : b.start + s * ~~((v - b.start) / s); + Tuple.set(d, output.start, v); + Tuple.set(d, output.end, v + s); + Tuple.set(d, output.mid, v + s/2); + } + input.add.forEach(update); + input.mod.forEach(update); + input.rem.forEach(update); + + input.fields[output.start] = 1; + input.fields[output.end] = 1; + input.fields[output.mid] = 1; + return input; + }; + + module.exports = Bin; +},{"./BatchTransform":119,"./Transform":139,"datalib":26,"vega-dataflow":41,"vega-logging":47}],121:[function(require,module,exports){ + var df = require('vega-dataflow'), + Tuple = df.Tuple, + log = require('vega-logging'), + Transform = require('./Transform'); + + function CountPattern(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, { + field: {type: 'field', default: 'data'}, + pattern: {type: 'value', default: '[\\w\']+'}, + case: {type: 'value', default: 'lower'}, + stopwords: {type: 'value', default: ''} + }); + + this._output = {text: 'text', count: 'count'}; + + return this.router(true).produces(true); + } + + var prototype = (CountPattern.prototype = Object.create(Transform.prototype)); + prototype.constructor = CountPattern; + + prototype.transform = function(input, reset) { + log.debug(input, ['countpattern']); + + var get = this.param('field').accessor, + pattern = this.param('pattern'), + stop = this.param('stopwords'), + rem = false; + + // update parameters + if (this._stop !== stop) { + this._stop = stop; + this._stop_re = new RegExp('^' + stop + '$', 'i'); + reset = true; + } + + if (this._pattern !== pattern) { + this._pattern = pattern; + this._match = new RegExp(this._pattern, 'g'); + reset = true; + } + + if (reset) this._counts = {}; + + function curr(t) { return (Tuple.prev_init(t), get(t)); } + function prev(t) { return get(Tuple.prev(t)); } + + this._add(input.add, curr); + if (!reset) this._rem(input.rem, prev); + if (reset || (rem = input.fields[get.field])) { + if (rem) this._rem(input.mod, prev); + this._add(input.mod, curr); + } + + // generate output tuples + return this._changeset(input); + }; + + prototype._changeset = function(input) { + var counts = this._counts, + tuples = this._tuples || (this._tuples = {}), + change = df.ChangeSet.create(input), + out = this._output, w, t, c; + + for (w in counts) { + t = tuples[w]; + c = counts[w] || 0; + if (!t && c) { + tuples[w] = (t = Tuple.ingest({})); + t[out.text] = w; + t[out.count] = c; + change.add.push(t); + } else if (c === 0) { + if (t) change.rem.push(t); + delete counts[w]; + delete tuples[w]; + } else if (t[out.count] !== c) { + Tuple.set(t, out.count, c); + change.mod.push(t); + } + } + return change; + }; + + prototype._tokenize = function(text) { + switch (this.param('case')) { + case 'upper': text = text.toUpperCase(); break; + case 'lower': text = text.toLowerCase(); break; + } + return text.match(this._match); + }; + + prototype._add = function(tuples, get) { + var counts = this._counts, + stop = this._stop_re, + tok, i, j, t; + + for (j=0; j cross.s, + fltrd = !cross || cross.f, + omod = output.mod, + orem = output.rem, + i, t, y; + + // If we have cached values, iterate through them for lazy + // removal, and to re-run the filter. + if (tpls) { + if (lazy || test) { + for (i=tpls.length-1; i>=0; --i) { + t = tpls[i]; + y = t[other]; + + if (lazy && !cache[y._id]) { + tpls.splice(i, 1); + continue; + } + + if (!test || test(t)) { + omod.push(t); + } else { + orem.push.apply(orem, tpls.splice(i, 1)); + cross.f = true; + } + } + + cross.s = this._lastRem; + } else { + omod.push.apply(omod, tpls); + } + } + + // If we have a filter param, call add to catch any tuples that may + // have previously been filtered. + if (test && fltrd) add.call(this, output, left, data, diag, test, x); + } + + function rem(output, x) { + var cross = this._cache[x._id]; + if (!cross) return; + output.rem.push.apply(output.rem, cross.c); + this._cache[x._id] = null; + this._lastRem = this._stamp; + } + + function purge(output) { + var cache = this._cache, + keys = dl.keys(cache), + rem = output.rem, + ids = {}, + i, len, j, jlen, cross, t; + + for (i=0, len=keys.length; i this._lastWith) { + woutput.rem.forEach(r); + woutput.add.forEach(add.bind(this, output, false, data, diag, test)); + woutput.mod.forEach(mod.bind(this, output, false, data, diag, test)); + this._lastWith = woutput.stamp; + } + + // Mods need to come after all removals have been run. + input.mod.forEach(mod.bind(this, output, true, wdata, diag, test)); + } + + output.fields[as.left] = 1; + output.fields[as.right] = 1; + return output; + }; + + module.exports = Cross; +},{"./BatchTransform":119,"./Transform":139,"datalib":26,"vega-dataflow":41,"vega-logging":47}],123:[function(require,module,exports){ + var Transform = require('./Transform'), + Aggregate = require('./Aggregate'); + + function Facet(graph) { + Transform.addParameters(this, { + transform: { + type: "custom", + set: function(pipeline) { + return (this._transform._pipeline = pipeline, this._transform); + }, + get: function() { + var parse = require('../parse/transforms'), + facet = this._transform; + return facet._pipeline.map(function(t) { + return parse(facet._graph, t); + }); + } + } + }); + + this._pipeline = []; + return Aggregate.call(this, graph); + } + + var prototype = (Facet.prototype = Object.create(Aggregate.prototype)); + prototype.constructor = Facet; + + prototype.aggr = function() { + return Aggregate.prototype.aggr.call(this).facet(this); + }; + + prototype.transform = function(input, reset) { + var output = Aggregate.prototype.transform.call(this, input, reset); + + // New facet cells should trigger a re-ranking of the dataflow graph. + // This ensures facet datasources are computed before scenegraph nodes. + // We rerank the Facet's first listener, which is the next node in the + // datasource's pipeline. + if (input.add.length) { + this.listeners()[0].rerank(); + } + + return output; + }; + + module.exports = Facet; +},{"../parse/transforms":108,"./Aggregate":118,"./Transform":139}],124:[function(require,module,exports){ + var dl = require('datalib'), + Aggregator = dl.Aggregator, + Base = Aggregator.prototype, + df = require('vega-dataflow'), + Tuple = df.Tuple, + log = require('vega-logging'), + facetID = 0; + + function Facetor() { + Aggregator.call(this); + this._facet = null; + this._facetID = ++facetID; + } + + var prototype = (Facetor.prototype = Object.create(Base)); + prototype.constructor = Facetor; + + prototype.facet = function(f) { + return arguments.length ? (this._facet = f, this) : this._facet; + }; + + prototype._ingest = function(t) { + return Tuple.ingest(t, null); + }; + + prototype._assign = Tuple.set; + + function disconnect_cell(facet) { + log.debug({}, ['disconnecting cell', this.tuple._id]); + var pipeline = this.ds.pipeline(); + facet.removeListener(pipeline[0]); + facet._graph.removeListener(pipeline[0]); + facet._graph.disconnect(pipeline); + } + + prototype._newcell = function(x, key) { + var cell = Base._newcell.call(this, x, key), + facet = this._facet; + + if (facet) { + var graph = facet._graph, + tuple = cell.tuple, + pipeline = facet.param('transform'); + cell.ds = graph.data(tuple._facetID, pipeline, tuple); + cell.disconnect = disconnect_cell; + facet.addListener(pipeline[0]); + } + + return cell; + }; + + prototype._newtuple = function(x, key) { + var t = Base._newtuple.call(this, x); + if (this._facet) { + Tuple.set(t, 'key', key); + Tuple.set(t, '_facetID', this._facetID + '_' + key); + } + return t; + }; + + prototype.clear = function() { + if (this._facet) { + for (var k in this._cells) { + this._cells[k].disconnect(this._facet); + } + } + return Base.clear.call(this); + }; + + prototype._on_add = function(x, cell) { + if (this._facet) cell.ds._input.add.push(x); + }; + + prototype._on_rem = function(x, cell) { + if (this._facet) cell.ds._input.rem.push(x); + }; + + prototype._on_mod = function(x, prev, cell0, cell1) { + if (this._facet) { // Propagate tuples + if (cell0 === cell1) { + cell0.ds._input.mod.push(x); + } else { + cell0.ds._input.rem.push(x); + cell1.ds._input.add.push(x); + } + } + }; + + prototype._on_drop = function(cell) { + if (this._facet) cell.disconnect(this._facet); + }; + + prototype._on_keep = function(cell) { + // propagate sort, signals, fields, etc. + if (this._facet) df.ChangeSet.copy(this._input, cell.ds._input); + }; + + module.exports = Facetor; +},{"datalib":26,"vega-dataflow":41,"vega-logging":47}],125:[function(require,module,exports){ + var df = require('vega-dataflow'), + SIGNALS = df.Dependencies.SIGNALS, + log = require('vega-logging'), + Transform = require('./Transform'); + + function Filter(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, {test: {type: 'expr'}}); + + this._skip = {}; + return this.router(true); + } + + var prototype = (Filter.prototype = Object.create(Transform.prototype)); + prototype.constructor = Filter; + + prototype.transform = function(input) { + log.debug(input, ['filtering']); + + var output = df.ChangeSet.create(input), + graph = this._graph, + skip = this._skip, + test = this.param('test'), + signals = graph.values(SIGNALS, this.dependency(SIGNALS)); + + input.rem.forEach(function(x) { + if (skip[x._id] !== 1) output.rem.push(x); + else skip[x._id] = 0; + }); + + input.add.forEach(function(x) { + if (test(x, null, signals)) output.add.push(x); + else skip[x._id] = 1; + }); + + input.mod.forEach(function(x) { + var b = test(x, null, signals), + s = (skip[x._id] === 1); + if (b && s) { + skip[x._id] = 0; + output.add.push(x); + } else if (b && !s) { + output.mod.push(x); + } else if (!b && s) { + // do nothing, keep skip true + } else { // !b && !s + output.rem.push(x); + skip[x._id] = 1; + } + }); + + return output; + }; + + module.exports = Filter; +},{"./Transform":139,"vega-dataflow":41,"vega-logging":47}],126:[function(require,module,exports){ + var df = require('vega-dataflow'), + Tuple = df.Tuple, + log = require('vega-logging'), + Transform = require('./Transform'); + + function Fold(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, { + fields: {type: 'array'} + }); + + this._output = {key: 'key', value: 'value'}; + this._cache = {}; + + return this.router(true).produces(true); + } + + var prototype = (Fold.prototype = Object.create(Transform.prototype)); + prototype.constructor = Fold; + + prototype._reset = function(input, output) { + for (var id in this._cache) { + output.rem.push.apply(output.rem, this._cache[id]); + } + this._cache = {}; + }; + + prototype._tuple = function(x, i, len) { + var list = this._cache[x._id] || (this._cache[x._id] = Array(len)); + return list[i] ? Tuple.rederive(x, list[i]) : (list[i] = Tuple.derive(x)); + }; + + prototype._fn = function(data, on, out) { + var i, j, n, m, d, t; + for (i=0, n=data.length; i', default: require('./screen').size}, + bound: {type: 'value', default: true}, + links: {type: 'data'}, + + // TODO: for now force these to be value params only (pun-intended) + // Can update to include fields after Parameter refactoring. + linkStrength: {type: 'value', default: 1}, + linkDistance: {type: 'value', default: 20}, + charge: {type: 'value', default: -30}, + + chargeDistance: {type: 'value', default: Infinity}, + friction: {type: 'value', default: 0.9}, + theta: {type: 'value', default: 0.8}, + gravity: {type: 'value', default: 0.1}, + alpha: {type: 'value', default: 0.1}, + iterations: {type: 'value', default: 500}, + + interactive: {type: 'value', default: this._interactive}, + active: {type: 'value', default: this._prev}, + fixed: {type: 'data'} + }); + + this._output = { + 'x': 'layout_x', + 'y': 'layout_y' + }; + + return this.mutates(true); + } + + var prototype = (Force.prototype = Object.create(Transform.prototype)); + prototype.constructor = Force; + + prototype.transform = function(nodeInput, reset) { + log.debug(nodeInput, ['force']); + reset = reset - (nodeInput.signals.active ? 1 : 0); + + // get variables + var interactive = this.param('interactive'), + linkSource = this.param('links').source, + linkInput = linkSource.last(), + active = this.param('active'), + output = this._output, + layout = this._layout, + nodes = this._nodes, + links = this._links; + + // configure nodes, links and layout + if (linkInput.stamp < nodeInput.stamp) linkInput = null; + this.configure(nodeInput, linkInput, interactive, reset); + + // run batch layout + if (!interactive) { + var iterations = this.param('iterations'); + for (var i=0; i'}, + translate: {type: 'array', default: require('./screen').center}, + rotate: {type: 'array'}, + scale: {type: 'value'}, + precision: {type: 'value'}, + clipAngle: {type: 'value'}, + clipExtent: {type: 'value'} + }; + + Geo.d3Projection = function() { + var p = this.param('projection'), + param = Geo.Parameters, + proj, name, value; + + if (p !== this._mode) { + this._mode = p; + this._projection = d3.geo[p](); + } + proj = this._projection; + + for (name in param) { + if (name === 'projection' || !proj[name]) continue; + value = this.param(name); + if (value === undefined || (dl.isArray(value) && value.length === 0)) { + continue; + } + if (value !== proj[name]()) { + proj[name](value); + } + } + + return proj; + }; + + var prototype = (Geo.prototype = Object.create(Transform.prototype)); + prototype.constructor = Geo; + + prototype.transform = function(input) { + log.debug(input, ['geo']); + + var output = this._output, + lon = this.param('lon').accessor, + lat = this.param('lat').accessor, + proj = Geo.d3Projection.call(this); + + function set(t) { + var ll = [lon(t), lat(t)]; + var xy = proj(ll) || [null, null]; + Tuple.set(t, output.x, xy[0]); + Tuple.set(t, output.y, xy[1]); + } + + input.add.forEach(set); + if (this.reevaluate(input)) { + input.mod.forEach(set); + input.rem.forEach(set); + } + + input.fields[output.x] = 1; + input.fields[output.y] = 1; + return input; + }; + + module.exports = Geo; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./Transform":139,"./screen":145,"datalib":26,"vega-dataflow":41,"vega-logging":47}],130:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Geo = require('./Geo'), + Transform = require('./Transform'); + + function GeoPath(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, Geo.Parameters); + Transform.addParameters(this, { + field: {type: 'field', default: null}, + }); + + this._output = { + 'path': 'layout_path' + }; + return this.mutates(true); + } + + var prototype = (GeoPath.prototype = Object.create(Transform.prototype)); + prototype.constructor = GeoPath; + + prototype.transform = function(input) { + log.debug(input, ['geopath']); + + var output = this._output, + geojson = this.param('field').accessor || dl.identity, + proj = Geo.d3Projection.call(this), + path = d3.geo.path().projection(proj); + + function set(t) { + Tuple.set(t, output.path, path(geojson(t))); + } + + input.add.forEach(set); + if (this.reevaluate(input)) { + input.mod.forEach(set); + input.rem.forEach(set); + } + + input.fields[output.path] = 1; + return input; + }; + + module.exports = GeoPath; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./Geo":129,"./Transform":139,"datalib":26,"vega-dataflow":41,"vega-logging":47}],131:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Hierarchy(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + // hierarchy parameters + sort: {type: 'array', default: null}, + children: {type: 'field', default: 'children'}, + parent: {type: 'field', default: 'parent'}, + field: {type: 'value', default: null}, + // layout parameters + mode: {type: 'value', default: 'tidy'}, // tidy, cluster, partition + size: {type: 'array', default: require('./screen').size}, + nodesize: {type: 'array', default: null}, + orient: {type: 'value', default: 'cartesian'} + }); + + this._mode = null; + this._output = { + 'x': 'layout_x', + 'y': 'layout_y', + 'width': 'layout_width', + 'height': 'layout_height', + 'depth': 'layout_depth' + }; + return this.mutates(true); + } + + var PARTITION = 'partition'; + + var SEPARATION = { + cartesian: function(a, b) { return (a.parent === b.parent ? 1 : 2); }, + radial: function(a, b) { return (a.parent === b.parent ? 1 : 2) / a.depth; } + }; + + var prototype = (Hierarchy.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Hierarchy; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['hierarchy layout']); + + // get variables + var layout = this._layout, + output = this._output, + mode = this.param('mode'), + sort = this.param('sort'), + nodesz = this.param('nodesize'), + parent = this.param('parent').accessor, + root = data.filter(function(d) { return parent(d) === null; })[0]; + + if (mode !== this._mode) { + this._mode = mode; + if (mode === 'tidy') mode = 'tree'; + layout = (this._layout = d3.layout[mode]()); + } + + input.fields[output.x] = 1; + input.fields[output.y] = 1; + input.fields[output.depth] = 1; + if (mode === PARTITION) { + input.fields[output.width] = 1; + input.fields[output.height] = 1; + layout.value(this.param('field').accessor); + } else { + layout.separation(SEPARATION[this.param('orient')]); + } + + if (nodesz.length && mode !== PARTITION) { + layout.nodeSize(nodesz); + } else { + layout.size(this.param('size')); + } + + layout + .sort(sort.field.length ? dl.comparator(sort.field) : null) + .children(this.param('children').accessor) + .nodes(root); + + // copy layout values to nodes + data.forEach(function(n) { + Tuple.set(n, output.x, n.x); + Tuple.set(n, output.y, n.y); + Tuple.set(n, output.depth, n.depth); + if (mode === PARTITION) { + Tuple.set(n, output.width, n.dx); + Tuple.set(n, output.height, n.dy); + } + }); + + // return changeset + return input; + }; + + module.exports = Hierarchy; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./BatchTransform":119,"./Transform":139,"./screen":145,"datalib":26,"vega-dataflow":41,"vega-logging":47}],132:[function(require,module,exports){ + var dl = require('datalib'), + log = require('vega-logging'), + Tuple = require('vega-dataflow').Tuple, + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Impute(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + groupby: {type: 'array'}, + orderby: {type: 'array'}, + field: {type: 'field'}, + method: {type: 'value', default: 'value'}, + value: {type: 'value', default: 0} + }); + + return this.router(true).produces(true); + } + + var prototype = (Impute.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Impute; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['imputing']); + + var groupby = this.param('groupby'), + orderby = this.param('orderby'), + method = this.param('method'), + value = this.param('value'), + field = this.param('field'), + get = field.accessor, + name = field.field, + prev = this._imputed || [], curr = [], + groups = partition(data, groupby.accessor, orderby.accessor), + domain = groups.domain, + group, i, j, n, m, t; + + function getval(x) { + return x == null ? null : get(x); + } + + for (j=0, m=groups.length; j Math.PI ? ta <= sa : ta > sa; + return 'M' + (sr*sc) + ',' + (sr*ss) + + 'A' + sr + ',' + sr + ' 0 0,' + (sf?1:0) + + ' ' + (sr*tc) + ',' + (sr*ts) + + 'L' + (tr*tc) + ',' + (tr*ts); + } + + function diagonalX(sx, sy, tx, ty) { + var m = (sx + tx) / 2; + return 'M' + sx + ',' + sy + + 'C' + m + ',' + sy + + ' ' + m + ',' + ty + + ' ' + tx + ',' + ty; + } + + function diagonalY(sx, sy, tx, ty) { + var m = (sy + ty) / 2; + return 'M' + sx + ',' + sy + + 'C' + sx + ',' + m + + ' ' + tx + ',' + m + + ' ' + tx + ',' + ty; + } + + function diagonalR(sa, sr, ta, tr) { + var sc = Math.cos(sa), + ss = Math.sin(sa), + tc = Math.cos(ta), + ts = Math.sin(ta), + mr = (sr + tr) / 2; + return 'M' + (sr*sc) + ',' + (sr*ss) + + 'C' + (mr*sc) + ',' + (mr*ss) + + ' ' + (mr*tc) + ',' + (mr*ts) + + ' ' + (tr*tc) + ',' + (tr*ts); + } + + var shapes = { + line: line, + curve: curve, + cornerX: cornerX, + cornerY: cornerY, + cornerR: cornerR, + diagonalX: diagonalX, + diagonalY: diagonalY, + diagonalR: diagonalR + }; + + prototype.transform = function(input) { + log.debug(input, ['linkpath']); + + var output = this._output, + shape = shapes[this.param('shape')] || shapes.line, + sourceX = this.param('sourceX').accessor, + sourceY = this.param('sourceY').accessor, + targetX = this.param('targetX').accessor, + targetY = this.param('targetY').accessor, + tension = this.param('tension'); + + function set(t) { + var path = shape(sourceX(t), sourceY(t), targetX(t), targetY(t), tension); + Tuple.set(t, output.path, path); + } + + input.add.forEach(set); + if (this.reevaluate(input)) { + input.mod.forEach(set); + input.rem.forEach(set); + } + + input.fields[output.path] = 1; + return input; + }; + + module.exports = LinkPath; +},{"./Transform":139,"vega-dataflow":41,"vega-logging":47}],134:[function(require,module,exports){ + var Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Transform = require('./Transform'); + + function Lookup(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, { + on: {type: 'data'}, + onKey: {type: 'field', default: null}, + as: {type: 'array'}, + keys: {type: 'array', default: ['data']}, + default: {type: 'value'} + }); + + return this.mutates(true); + } + + var prototype = (Lookup.prototype = Object.create(Transform.prototype)); + prototype.constructor = Lookup; + + prototype.transform = function(input, reset) { + log.debug(input, ['lookup']); + + var on = this.param('on'), + onLast = on.source.last(), + onData = on.source.values(), + onKey = this.param('onKey'), + onF = onKey.field, + keys = this.param('keys'), + get = keys.accessor, + as = this.param('as'), + defaultValue = this.param('default'), + lut = this._lut, + i, v; + + // build lookup table on init, withKey modified, or tuple add/rem + if (lut == null || this._on !== onF || onF && onLast.fields[onF] || + onLast.add.length || onLast.rem.length) + { + if (onF) { // build hash from withKey field + onKey = onKey.accessor; + for (lut={}, i=0; i'} }); + this.router(true); + } + + var prototype = (Sort.prototype = Object.create(Transform.prototype)); + prototype.constructor = Sort; + + prototype.transform = function(input) { + log.debug(input, ['sorting']); + + if (input.add.length || input.mod.length || input.rem.length) { + input.sort = dl.comparator(this.param('by').field); + } + return input; + }; + + module.exports = Sort; +},{"./Transform":139,"datalib":26,"vega-logging":47}],138:[function(require,module,exports){ + var dl = require('datalib'), + Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Stack(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + groupby: {type: 'array'}, + sortby: {type: 'array'}, + field: {type: 'field'}, + offset: {type: 'value', default: 'zero'} + }); + + this._output = { + 'start': 'layout_start', + 'end': 'layout_end', + 'mid': 'layout_mid' + }; + return this.mutates(true); + } + + var prototype = (Stack.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Stack; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['stacking']); + + var groupby = this.param('groupby').accessor, + sortby = dl.comparator(this.param('sortby').field), + field = this.param('field').accessor, + offset = this.param('offset'), + output = this._output; + + // partition, sum, and sort the stack groups + var groups = partition(data, groupby, sortby, field); + + // compute stack layouts per group + for (var i=0, max=groups.max; i max) max = s; + if (sortby != null) g.sort(sortby); + } + groups.max = max; + + return groups; + } + + module.exports = Stack; +},{"./BatchTransform":119,"./Transform":139,"datalib":26,"vega-dataflow":41,"vega-logging":47}],139:[function(require,module,exports){ + var df = require('vega-dataflow'), + Base = df.Node.prototype, // jshint ignore:line + Deps = df.Dependencies, + Parameter = require('./Parameter'); + + function Transform(graph) { + if (graph) Base.init.call(this, graph); + } + + Transform.addParameters = function(proto, params) { + proto._parameters = proto._parameters || {}; + for (var name in params) { + var p = params[name], + param = new Parameter(name, p.type, proto); + + proto._parameters[name] = param; + + if (p.type === 'custom') { + if (p.set) param.set = p.set.bind(param); + if (p.get) param.get = p.get.bind(param); + } + + if (p.hasOwnProperty('default')) param.set(p.default); + } + }; + + var prototype = (Transform.prototype = Object.create(Base)); + prototype.constructor = Transform; + + prototype.param = function(name, value) { + var param = this._parameters[name]; + return (param === undefined) ? this : + (arguments.length === 1) ? param.get() : param.set(value); + }; + +// Perform transformation. Subclasses should override. + prototype.transform = function(input/*, reset */) { + return input; + }; + + prototype.evaluate = function(input) { + // Many transforms store caches that must be invalidated if + // a signal value has changed. + var reset = this._stamp < input.stamp && + this.dependency(Deps.SIGNALS).reduce(function(c, s) { + return c += input.signals[s] ? 1 : 0; + }, 0); + return this.transform(input, reset); + }; + + prototype.output = function(map) { + for (var key in this._output) { + if (map[key] !== undefined) { + this._output[key] = map[key]; + } + } + return this; + }; + + module.exports = Transform; +},{"./Parameter":135,"vega-dataflow":41}],140:[function(require,module,exports){ + var dl = require('datalib'), + Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Treeify(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + groupby: {type: 'array'} + }); + + this._output = { + 'children': 'children', + 'parent': 'parent' + }; + return this.router(true).produces(true); + } + + var prototype = (Treeify.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Treeify; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['treeifying']); + + var fields = this.param('groupby').field, + childField = this._output.children, + parentField = this._output.parent, + summary = [{name:'*', ops: ['values'], as: [childField]}], + aggrs = fields.map(function(f) { + return dl.groupby(f).summarize(summary); + }), + prev = this._internal || [], curr = [], i, n; + + function level(index, node, values) { + var vals = aggrs[index].execute(values); + + node[childField] = vals; + vals.forEach(function(n) { + n[parentField] = node; + curr.push(Tuple.ingest(n)); + if (index+1 < fields.length) level(index+1, n, n[childField]); + else n[childField].forEach(function(c) { c[parentField] = n; }); + }); + } + + var root = Tuple.ingest({}); + root[parentField] = null; + curr.push(root); + level(0, root, data); + + // update changeset with internal nodes + for (i=0, n=curr.length; i', default: ['-value']}, + children: {type: 'field', default: 'children'}, + parent: {type: 'field', default: 'parent'}, + field: {type: 'field', default: 'value'}, + // treemap parameters + size: {type: 'array', default: require('./screen').size}, + round: {type: 'value', default: true}, + sticky: {type: 'value', default: false}, + ratio: {type: 'value', default: defaultRatio}, + padding: {type: 'value', default: null}, + mode: {type: 'value', default: 'squarify'} + }); + + this._layout = d3.layout.treemap(); + + this._output = { + 'x': 'layout_x', + 'y': 'layout_y', + 'width': 'layout_width', + 'height': 'layout_height', + 'depth': 'layout_depth', + }; + return this.mutates(true); + } + + var prototype = (Treemap.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Treemap; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['treemap']); + + // get variables + var layout = this._layout, + output = this._output, + sticky = this.param('sticky'), + parent = this.param('parent').accessor, + root = data.filter(function(d) { return parent(d) === null; })[0]; + + // layout.sticky resets state _regardless_ of input value + // so, we perform out own check first + if (layout.sticky() !== sticky) { layout.sticky(sticky); } + + // configure layout + layout + .sort(dl.comparator(this.param('sort').field)) + .children(this.param('children').accessor) + .value(this.param('field').accessor) + .size(this.param('size')) + .round(this.param('round')) + .ratio(this.param('ratio')) + .padding(this.param('padding')) + .mode(this.param('mode')) + .nodes(root); + + // copy layout values to nodes + data.forEach(function(n) { + Tuple.set(n, output.x, n.x); + Tuple.set(n, output.y, n.y); + Tuple.set(n, output.width, n.dx); + Tuple.set(n, output.height, n.dy); + Tuple.set(n, output.depth, n.depth); + }); + + // return changeset + input.fields[output.x] = 1; + input.fields[output.y] = 1; + input.fields[output.width] = 1; + input.fields[output.height] = 1; + input.fields[output.depth] = 1; + return input; + }; + + module.exports = Treemap; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./BatchTransform":119,"./Transform":139,"./screen":145,"datalib":26,"vega-dataflow":41,"vega-logging":47}],142:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + Tuple = require('vega-dataflow/src/Tuple'), + log = require('vega-logging'), + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Voronoi(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + clipExtent: {type: 'array', default: require('./screen').extent}, + x: {type: 'field', default: 'layout_x'}, + y: {type: 'field', default: 'layout_y'} + }); + + this._layout = d3.geom.voronoi(); + this._output = {'path': 'layout_path'}; + + return this.mutates(true); + } + + var prototype = (Voronoi.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Voronoi; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['voronoi']); + + // get variables + var pathname = this._output.path; + + // configure layout + var polygons = this._layout + .clipExtent(this.param('clipExtent')) + .x(this.param('x').accessor) + .y(this.param('y').accessor) + (data); + + // build and assign path strings + for (var i=0; i', default: require('./screen').size}, + text: {type: 'field', default: 'data'}, + rotate: {type: 'field|value', default: 0}, + font: {type: 'field|value', default: {value: 'sans-serif'}}, + fontSize: {type: 'field|value', default: 14}, + fontStyle: {type: 'field|value', default: {value: 'normal'}}, + fontWeight: {type: 'field|value', default: {value: 'normal'}}, + fontScale: {type: 'array', default: [10, 50]}, + padding: {type: 'value', default: 1}, + spiral: {type: 'value', default: 'archimedean'} + }); + + this._layout = d3_cloud().canvas(canvas.instance); + + this._output = { + 'x': 'layout_x', + 'y': 'layout_y', + 'font': 'layout_font', + 'fontSize': 'layout_fontSize', + 'fontStyle': 'layout_fontStyle', + 'fontWeight': 'layout_fontWeight', + 'rotate': 'layout_rotate', + }; + + return this.mutates(true); + } + + var prototype = (Wordcloud.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Wordcloud; + + function get(p) { + return (p && p.accessor) || p; + } + + function wrap(tuple) { + var x = Object.create(tuple); + x._tuple = tuple; + return x; + } + + prototype.batchTransform = function(input, data) { + log.debug(input, ['wordcloud']); + + // get variables + var layout = this._layout, + output = this._output, + fontSize = this.param('fontSize'), + range = fontSize.accessor && this.param('fontScale'), + size, scale; + fontSize = fontSize.accessor || d3.functor(fontSize); + + // create font size scaling function as needed + if (range.length) { + scale = d3.scale.sqrt() + .domain(dl.extent(data, size=fontSize)) + .range(range); + fontSize = function(x) { return scale(size(x)); }; + } + + // configure layout + layout + .size(this.param('size')) + .text(get(this.param('text'))) + .padding(this.param('padding')) + .spiral(this.param('spiral')) + .rotate(get(this.param('rotate'))) + .font(get(this.param('font'))) + .fontStyle(get(this.param('fontStyle'))) + .fontWeight(get(this.param('fontWeight'))) + .fontSize(fontSize) + .words(data.map(wrap)) // wrap to avoid tuple writes + .on('end', function(words) { + var size = layout.size(), + dx = size[0] >> 1, + dy = size[1] >> 1, + w, t, i, len; + + for (i=0, len=words.length; i.radio:first-child,.controls>.checkbox:first-child{padding-top:5px;} +.radio.inline,.checkbox.inline{display:inline-block;padding-top:5px;margin-bottom:0;vertical-align:middle;} +.radio.inline+.radio.inline,.checkbox.inline+.checkbox.inline{margin-left:10px;} +.input-mini{width:60px;} +.input-small{width:90px;} +.input-medium{width:150px;} +.input-large{width:210px;} +.input-xlarge{width:270px;} +.input-xxlarge{width:530px;} +input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"]{float:none;margin-left:0;} +.input-append input[class*="span"],.input-append .uneditable-input[class*="span"],.input-prepend input[class*="span"],.input-prepend .uneditable-input[class*="span"],.row-fluid input[class*="span"],.row-fluid select[class*="span"],.row-fluid textarea[class*="span"],.row-fluid .uneditable-input[class*="span"],.row-fluid .input-prepend [class*="span"],.row-fluid .input-append [class*="span"]{display:inline-block;} +input,textarea,.uneditable-input{margin-left:0;} +.controls-row [class*="span"]+[class*="span"]{margin-left:20px;} +input.span12, textarea.span12, .uneditable-input.span12{width:926px;} +input.span11, textarea.span11, .uneditable-input.span11{width:846px;} +input.span10, textarea.span10, .uneditable-input.span10{width:766px;} +input.span9, textarea.span9, .uneditable-input.span9{width:686px;} +input.span8, textarea.span8, .uneditable-input.span8{width:606px;} +input.span7, textarea.span7, .uneditable-input.span7{width:526px;} +input.span6, textarea.span6, .uneditable-input.span6{width:446px;} +input.span5, textarea.span5, .uneditable-input.span5{width:366px;} +input.span4, textarea.span4, .uneditable-input.span4{width:286px;} +input.span3, textarea.span3, .uneditable-input.span3{width:206px;} +input.span2, textarea.span2, .uneditable-input.span2{width:126px;} +input.span1, textarea.span1, .uneditable-input.span1{width:46px;} +.controls-row{*zoom:1;}.controls-row:before,.controls-row:after{display:table;content:"";line-height:0;} +.controls-row:after{clear:both;} +.controls-row [class*="span"],.row-fluid .controls-row [class*="span"]{float:left;} +.controls-row .checkbox[class*="span"],.controls-row .radio[class*="span"]{padding-top:5px;} +input[disabled],select[disabled],textarea[disabled],input[readonly],select[readonly],textarea[readonly]{cursor:not-allowed;background-color:#eeeeee;} +input[type="radio"][disabled],input[type="checkbox"][disabled],input[type="radio"][readonly],input[type="checkbox"][readonly]{background-color:transparent;} +.control-group.warning>label,.control-group.warning .help-block,.control-group.warning .help-inline{color:#c09853;} +.control-group.warning .checkbox,.control-group.warning .radio,.control-group.warning input,.control-group.warning select,.control-group.warning textarea{color:#c09853;} +.control-group.warning input,.control-group.warning select,.control-group.warning textarea{border-color:#c09853;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.warning input:focus,.control-group.warning select:focus,.control-group.warning textarea:focus{border-color:#a47e3c;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #dbc59e;} +.control-group.warning .input-prepend .add-on,.control-group.warning .input-append .add-on{color:#c09853;background-color:#fcf8e3;border-color:#c09853;} +.control-group.error>label,.control-group.error .help-block,.control-group.error .help-inline{color:#b94a48;} +.control-group.error .checkbox,.control-group.error .radio,.control-group.error input,.control-group.error select,.control-group.error textarea{color:#b94a48;} +.control-group.error input,.control-group.error select,.control-group.error textarea{border-color:#b94a48;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.error input:focus,.control-group.error select:focus,.control-group.error textarea:focus{border-color:#953b39;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #d59392;} +.control-group.error .input-prepend .add-on,.control-group.error .input-append .add-on{color:#b94a48;background-color:#f2dede;border-color:#b94a48;} +.control-group.success>label,.control-group.success .help-block,.control-group.success .help-inline{color:#468847;} +.control-group.success .checkbox,.control-group.success .radio,.control-group.success input,.control-group.success select,.control-group.success textarea{color:#468847;} +.control-group.success input,.control-group.success select,.control-group.success textarea{border-color:#468847;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.success input:focus,.control-group.success select:focus,.control-group.success textarea:focus{border-color:#356635;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7aba7b;} +.control-group.success .input-prepend .add-on,.control-group.success .input-append .add-on{color:#468847;background-color:#dff0d8;border-color:#468847;} +.control-group.info>label,.control-group.info .help-block,.control-group.info .help-inline{color:#3a87ad;} +.control-group.info .checkbox,.control-group.info .radio,.control-group.info input,.control-group.info select,.control-group.info textarea{color:#3a87ad;} +.control-group.info input,.control-group.info select,.control-group.info textarea{border-color:#3a87ad;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075);}.control-group.info input:focus,.control-group.info select:focus,.control-group.info textarea:focus{border-color:#2d6987;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.075),0 0 6px #7ab5d3;} +.control-group.info .input-prepend .add-on,.control-group.info .input-append .add-on{color:#3a87ad;background-color:#d9edf7;border-color:#3a87ad;} +input:focus:required:invalid,textarea:focus:required:invalid,select:focus:required:invalid{color:#b94a48;border-color:#ee5f5b;}input:focus:required:invalid:focus,textarea:focus:required:invalid:focus,select:focus:required:invalid:focus{border-color:#e9322d;-webkit-box-shadow:0 0 6px #f8b9b7;-moz-box-shadow:0 0 6px #f8b9b7;box-shadow:0 0 6px #f8b9b7;} +.form-actions{padding:19px 20px 20px;margin-top:20px;margin-bottom:20px;background-color:#f5f5f5;border-top:1px solid #e5e5e5;*zoom:1;}.form-actions:before,.form-actions:after{display:table;content:"";line-height:0;} +.form-actions:after{clear:both;} +.help-block,.help-inline{color:#595959;} +.help-block{display:block;margin-bottom:10px;} +.help-inline{display:inline-block;*display:inline;*zoom:1;vertical-align:middle;padding-left:5px;} +.input-append,.input-prepend{margin-bottom:5px;font-size:0;white-space:nowrap;}.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input,.input-append .dropdown-menu,.input-prepend .dropdown-menu{font-size:14px;} +.input-append input,.input-prepend input,.input-append select,.input-prepend select,.input-append .uneditable-input,.input-prepend .uneditable-input{position:relative;margin-bottom:0;*margin-left:0;vertical-align:top;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;}.input-append input:focus,.input-prepend input:focus,.input-append select:focus,.input-prepend select:focus,.input-append .uneditable-input:focus,.input-prepend .uneditable-input:focus{z-index:2;} +.input-append .add-on,.input-prepend .add-on{display:inline-block;width:auto;height:20px;min-width:16px;padding:4px 5px;font-size:14px;font-weight:normal;line-height:20px;text-align:center;text-shadow:0 1px 0 #ffffff;background-color:#eeeeee;border:1px solid #ccc;} +.input-append .add-on,.input-prepend .add-on,.input-append .btn,.input-prepend .btn{vertical-align:top;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.input-append .active,.input-prepend .active{background-color:#a9dba9;border-color:#46a546;} +.input-prepend .add-on,.input-prepend .btn{margin-right:-1px;} +.input-prepend .add-on:first-child,.input-prepend .btn:first-child{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;} +.input-append input,.input-append select,.input-append .uneditable-input{-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;}.input-append input+.btn-group .btn,.input-append select+.btn-group .btn,.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.input-append .add-on,.input-append .btn,.input-append .btn-group{margin-left:-1px;} +.input-append .add-on:last-child,.input-append .btn:last-child{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.input-prepend.input-append input,.input-prepend.input-append select,.input-prepend.input-append .uneditable-input{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;}.input-prepend.input-append input+.btn-group .btn,.input-prepend.input-append select+.btn-group .btn,.input-prepend.input-append .uneditable-input+.btn-group .btn{-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.input-prepend.input-append .add-on:first-child,.input-prepend.input-append .btn:first-child{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;} +.input-prepend.input-append .add-on:last-child,.input-prepend.input-append .btn:last-child{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.input-prepend.input-append .btn-group:first-child{margin-left:0;} +input.search-query{padding-right:14px;padding-right:4px \9;padding-left:14px;padding-left:4px \9;margin-bottom:0;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;} +.form-search .input-append .search-query,.form-search .input-prepend .search-query{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.form-search .input-append .search-query{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px;} +.form-search .input-append .btn{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0;} +.form-search .input-prepend .search-query{-webkit-border-radius:0 14px 14px 0;-moz-border-radius:0 14px 14px 0;border-radius:0 14px 14px 0;} +.form-search .input-prepend .btn{-webkit-border-radius:14px 0 0 14px;-moz-border-radius:14px 0 0 14px;border-radius:14px 0 0 14px;} +.form-search input,.form-inline input,.form-horizontal input,.form-search textarea,.form-inline textarea,.form-horizontal textarea,.form-search select,.form-inline select,.form-horizontal select,.form-search .help-inline,.form-inline .help-inline,.form-horizontal .help-inline,.form-search .uneditable-input,.form-inline .uneditable-input,.form-horizontal .uneditable-input,.form-search .input-prepend,.form-inline .input-prepend,.form-horizontal .input-prepend,.form-search .input-append,.form-inline .input-append,.form-horizontal .input-append{display:inline-block;*display:inline;*zoom:1;margin-bottom:0;vertical-align:middle;} +.form-search .hide,.form-inline .hide,.form-horizontal .hide{display:none;} +.form-search label,.form-inline label,.form-search .btn-group,.form-inline .btn-group{display:inline-block;} +.form-search .input-append,.form-inline .input-append,.form-search .input-prepend,.form-inline .input-prepend{margin-bottom:0;} +.form-search .radio,.form-search .checkbox,.form-inline .radio,.form-inline .checkbox{padding-left:0;margin-bottom:0;vertical-align:middle;} +.form-search .radio input[type="radio"],.form-search .checkbox input[type="checkbox"],.form-inline .radio input[type="radio"],.form-inline .checkbox input[type="checkbox"]{float:left;margin-right:3px;margin-left:0;} +.control-group{margin-bottom:10px;} +legend+.control-group{margin-top:20px;-webkit-margin-top-collapse:separate;} +.form-horizontal .control-group{margin-bottom:20px;*zoom:1;}.form-horizontal .control-group:before,.form-horizontal .control-group:after{display:table;content:"";line-height:0;} +.form-horizontal .control-group:after{clear:both;} +.form-horizontal .control-label{float:left;width:160px;padding-top:5px;text-align:right;} +.form-horizontal .controls{*display:inline-block;*padding-left:20px;margin-left:180px;*margin-left:0;}.form-horizontal .controls:first-child{*padding-left:180px;} +.form-horizontal .help-block{margin-bottom:0;} +.form-horizontal input+.help-block,.form-horizontal select+.help-block,.form-horizontal textarea+.help-block{margin-top:10px;} +.form-horizontal .form-actions{padding-left:180px;} +.btn{display:inline-block;*display:inline;*zoom:1;padding:4px 12px;margin-bottom:0;font-size:14px;line-height:20px;*line-height:20px;text-align:center;vertical-align:middle;cursor:pointer;color:#333333;text-shadow:0 1px 1px rgba(255, 255, 255, 0.75);background-color:#f5f5f5;background-image:-moz-linear-gradient(top, #ffffff, #e6e6e6);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#e6e6e6));background-image:-webkit-linear-gradient(top, #ffffff, #e6e6e6);background-image:-o-linear-gradient(top, #ffffff, #e6e6e6);background-image:linear-gradient(to bottom, #ffffff, #e6e6e6);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#ffe6e6e6', GradientType=0);border-color:#e6e6e6 #e6e6e6 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#e6e6e6;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);border:1px solid #bbbbbb;*border:0;border-bottom-color:#a2a2a2;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;*margin-left:.3em;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);}.btn:hover,.btn:active,.btn.active,.btn.disabled,.btn[disabled]{color:#333333;background-color:#e6e6e6;*background-color:#d9d9d9;} +.btn:active,.btn.active{background-color:#cccccc \9;} +.btn:first-child{*margin-left:0;} +.btn:hover{color:#333333;text-decoration:none;background-color:#e6e6e6;*background-color:#d9d9d9;background-position:0 -15px;-webkit-transition:background-position 0.1s linear;-moz-transition:background-position 0.1s linear;-o-transition:background-position 0.1s linear;transition:background-position 0.1s linear;} +.btn:focus{outline:thin dotted #333;outline:5px auto -webkit-focus-ring-color;outline-offset:-2px;} +.btn.active,.btn:active{background-color:#e6e6e6;background-color:#d9d9d9 \9;background-image:none;outline:0;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);} +.btn.disabled,.btn[disabled]{cursor:default;background-color:#e6e6e6;background-image:none;opacity:0.65;filter:alpha(opacity=65);-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} +.btn-large{padding:11px 19px;font-size:17.5px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} +.btn-large [class^="icon-"],.btn-large [class*=" icon-"]{margin-top:2px;} +.btn-small{padding:2px 10px;font-size:11.9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.btn-small [class^="icon-"],.btn-small [class*=" icon-"]{margin-top:0;} +.btn-mini{padding:1px 6px;font-size:10.5px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.btn-block{display:block;width:100%;padding-left:0;padding-right:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} +.btn-block+.btn-block{margin-top:5px;} +input[type="submit"].btn-block,input[type="reset"].btn-block,input[type="button"].btn-block{width:100%;} +.btn-primary.active,.btn-warning.active,.btn-danger.active,.btn-success.active,.btn-info.active,.btn-inverse.active{color:rgba(255, 255, 255, 0.75);} +.btn{border-color:#c5c5c5;border-color:rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.15) rgba(0, 0, 0, 0.25);} +.btn-primary{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#006dcc;background-image:-moz-linear-gradient(top, #0088cc, #0044cc);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc));background-image:-webkit-linear-gradient(top, #0088cc, #0044cc);background-image:-o-linear-gradient(top, #0088cc, #0044cc);background-image:linear-gradient(to bottom, #0088cc, #0044cc);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0044cc', GradientType=0);border-color:#0044cc #0044cc #002a80;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#0044cc;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-primary:hover,.btn-primary:active,.btn-primary.active,.btn-primary.disabled,.btn-primary[disabled]{color:#ffffff;background-color:#0044cc;*background-color:#003bb3;} +.btn-primary:active,.btn-primary.active{background-color:#003399 \9;} +.btn-warning{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);border-color:#f89406 #f89406 #ad6704;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#f89406;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-warning:hover,.btn-warning:active,.btn-warning.active,.btn-warning.disabled,.btn-warning[disabled]{color:#ffffff;background-color:#f89406;*background-color:#df8505;} +.btn-warning:active,.btn-warning.active{background-color:#c67605 \9;} +.btn-danger{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#da4f49;background-image:-moz-linear-gradient(top, #ee5f5b, #bd362f);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#bd362f));background-image:-webkit-linear-gradient(top, #ee5f5b, #bd362f);background-image:-o-linear-gradient(top, #ee5f5b, #bd362f);background-image:linear-gradient(to bottom, #ee5f5b, #bd362f);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffbd362f', GradientType=0);border-color:#bd362f #bd362f #802420;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#bd362f;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-danger:hover,.btn-danger:active,.btn-danger.active,.btn-danger.disabled,.btn-danger[disabled]{color:#ffffff;background-color:#bd362f;*background-color:#a9302a;} +.btn-danger:active,.btn-danger.active{background-color:#942a25 \9;} +.btn-success{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#5bb75b;background-image:-moz-linear-gradient(top, #62c462, #51a351);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#51a351));background-image:-webkit-linear-gradient(top, #62c462, #51a351);background-image:-o-linear-gradient(top, #62c462, #51a351);background-image:linear-gradient(to bottom, #62c462, #51a351);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff51a351', GradientType=0);border-color:#51a351 #51a351 #387038;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#51a351;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-success:hover,.btn-success:active,.btn-success.active,.btn-success.disabled,.btn-success[disabled]{color:#ffffff;background-color:#51a351;*background-color:#499249;} +.btn-success:active,.btn-success.active{background-color:#408140 \9;} +.btn-info{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#49afcd;background-image:-moz-linear-gradient(top, #5bc0de, #2f96b4);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#2f96b4));background-image:-webkit-linear-gradient(top, #5bc0de, #2f96b4);background-image:-o-linear-gradient(top, #5bc0de, #2f96b4);background-image:linear-gradient(to bottom, #5bc0de, #2f96b4);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff2f96b4', GradientType=0);border-color:#2f96b4 #2f96b4 #1f6377;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#2f96b4;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-info:hover,.btn-info:active,.btn-info.active,.btn-info.disabled,.btn-info[disabled]{color:#ffffff;background-color:#2f96b4;*background-color:#2a85a0;} +.btn-info:active,.btn-info.active{background-color:#24748c \9;} +.btn-inverse{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#363636;background-image:-moz-linear-gradient(top, #444444, #222222);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#444444), to(#222222));background-image:-webkit-linear-gradient(top, #444444, #222222);background-image:-o-linear-gradient(top, #444444, #222222);background-image:linear-gradient(to bottom, #444444, #222222);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff444444', endColorstr='#ff222222', GradientType=0);border-color:#222222 #222222 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#222222;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.btn-inverse:hover,.btn-inverse:active,.btn-inverse.active,.btn-inverse.disabled,.btn-inverse[disabled]{color:#ffffff;background-color:#222222;*background-color:#151515;} +.btn-inverse:active,.btn-inverse.active{background-color:#080808 \9;} +button.btn,input[type="submit"].btn{*padding-top:3px;*padding-bottom:3px;}button.btn::-moz-focus-inner,input[type="submit"].btn::-moz-focus-inner{padding:0;border:0;} +button.btn.btn-large,input[type="submit"].btn.btn-large{*padding-top:7px;*padding-bottom:7px;} +button.btn.btn-small,input[type="submit"].btn.btn-small{*padding-top:3px;*padding-bottom:3px;} +button.btn.btn-mini,input[type="submit"].btn.btn-mini{*padding-top:1px;*padding-bottom:1px;} +.btn-link,.btn-link:active,.btn-link[disabled]{background-color:transparent;background-image:none;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} +.btn-link{border-color:transparent;cursor:pointer;color:#0088cc;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.btn-link:hover{color:#005580;text-decoration:underline;background-color:transparent;} +.btn-link[disabled]:hover{color:#333333;text-decoration:none;} +.btn-group{position:relative;display:inline-block;*display:inline;*zoom:1;font-size:0;vertical-align:middle;white-space:nowrap;*margin-left:.3em;}.btn-group:first-child{*margin-left:0;} +.btn-group+.btn-group{margin-left:5px;} +.btn-toolbar{font-size:0;margin-top:10px;margin-bottom:10px;}.btn-toolbar .btn+.btn,.btn-toolbar .btn-group+.btn,.btn-toolbar .btn+.btn-group{margin-left:5px;} +.btn-group>.btn{position:relative;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.btn-group>.btn+.btn{margin-left:-1px;} +.btn-group>.btn,.btn-group>.dropdown-menu{font-size:14px;} +.btn-group>.btn-mini{font-size:11px;} +.btn-group>.btn-small{font-size:12px;} +.btn-group>.btn-large{font-size:16px;} +.btn-group>.btn:first-child{margin-left:0;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;} +.btn-group>.btn:last-child,.btn-group>.dropdown-toggle{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;} +.btn-group>.btn.large:first-child{margin-left:0;-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;} +.btn-group>.btn.large:last-child,.btn-group>.large.dropdown-toggle{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;} +.btn-group>.btn:hover,.btn-group>.btn:focus,.btn-group>.btn:active,.btn-group>.btn.active{z-index:2;} +.btn-group .dropdown-toggle:active,.btn-group.open .dropdown-toggle{outline:0;} +.btn-group>.btn+.dropdown-toggle{padding-left:8px;padding-right:8px;-webkit-box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 1px 0 0 rgba(255,255,255,.125), inset 0 1px 0 rgba(255,255,255,.2), 0 1px 2px rgba(0,0,0,.05);*padding-top:5px;*padding-bottom:5px;} +.btn-group>.btn-mini+.dropdown-toggle{padding-left:5px;padding-right:5px;*padding-top:2px;*padding-bottom:2px;} +.btn-group>.btn-small+.dropdown-toggle{*padding-top:5px;*padding-bottom:4px;} +.btn-group>.btn-large+.dropdown-toggle{padding-left:12px;padding-right:12px;*padding-top:7px;*padding-bottom:7px;} +.btn-group.open .dropdown-toggle{background-image:none;-webkit-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);-moz-box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);box-shadow:inset 0 2px 4px rgba(0,0,0,.15), 0 1px 2px rgba(0,0,0,.05);} +.btn-group.open .btn.dropdown-toggle{background-color:#e6e6e6;} +.btn-group.open .btn-primary.dropdown-toggle{background-color:#0044cc;} +.btn-group.open .btn-warning.dropdown-toggle{background-color:#f89406;} +.btn-group.open .btn-danger.dropdown-toggle{background-color:#bd362f;} +.btn-group.open .btn-success.dropdown-toggle{background-color:#51a351;} +.btn-group.open .btn-info.dropdown-toggle{background-color:#2f96b4;} +.btn-group.open .btn-inverse.dropdown-toggle{background-color:#222222;} +.btn .caret{margin-top:8px;margin-left:0;} +.btn-mini .caret,.btn-small .caret,.btn-large .caret{margin-top:6px;} +.btn-large .caret{border-left-width:5px;border-right-width:5px;border-top-width:5px;} +.dropup .btn-large .caret{border-bottom-width:5px;} +.btn-primary .caret,.btn-warning .caret,.btn-danger .caret,.btn-info .caret,.btn-success .caret,.btn-inverse .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;} +.btn-group-vertical{display:inline-block;*display:inline;*zoom:1;} +.btn-group-vertical .btn{display:block;float:none;width:100%;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.btn-group-vertical .btn+.btn{margin-left:0;margin-top:-1px;} +.btn-group-vertical .btn:first-child{-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;} +.btn-group-vertical .btn:last-child{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;} +.btn-group-vertical .btn-large:first-child{-webkit-border-radius:6px 6px 0 0;-moz-border-radius:6px 6px 0 0;border-radius:6px 6px 0 0;} +.btn-group-vertical .btn-large:last-child{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;} +.nav{margin-left:0;margin-bottom:20px;list-style:none;} +.nav>li>a{display:block;} +.nav>li>a:hover{text-decoration:none;background-color:#eeeeee;} +.nav>.pull-right{float:right;} +.nav-header{display:block;padding:3px 15px;font-size:11px;font-weight:bold;line-height:20px;color:#999999;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);text-transform:uppercase;} +.nav li+.nav-header{margin-top:9px;} +.nav-list{padding-left:15px;padding-right:15px;margin-bottom:0;} +.nav-list>li>a,.nav-list .nav-header{margin-left:-15px;margin-right:-15px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);} +.nav-list>li>a{padding:3px 15px;} +.nav-list>.active>a,.nav-list>.active>a:hover{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.2);background-color:#0088cc;} +.nav-list [class^="icon-"],.nav-list [class*=" icon-"]{margin-right:2px;} +.nav-list .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;} +.nav-tabs,.nav-pills{*zoom:1;}.nav-tabs:before,.nav-pills:before,.nav-tabs:after,.nav-pills:after{display:table;content:"";line-height:0;} +.nav-tabs:after,.nav-pills:after{clear:both;} +.nav-tabs>li,.nav-pills>li{float:left;} +.nav-tabs>li>a,.nav-pills>li>a{padding-right:12px;padding-left:12px;margin-right:2px;line-height:14px;} +.nav-tabs{border-bottom:1px solid #ddd;} +.nav-tabs>li{margin-bottom:-1px;} +.nav-tabs>li>a{padding-top:8px;padding-bottom:8px;line-height:20px;border:1px solid transparent;-webkit-border-radius:4px 4px 0 0;-moz-border-radius:4px 4px 0 0;border-radius:4px 4px 0 0;}.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #dddddd;} +.nav-tabs>.active>a,.nav-tabs>.active>a:hover{color:#555555;background-color:#ffffff;border:1px solid #ddd;border-bottom-color:transparent;cursor:default;} +.nav-pills>li>a{padding-top:8px;padding-bottom:8px;margin-top:2px;margin-bottom:2px;-webkit-border-radius:5px;-moz-border-radius:5px;border-radius:5px;} +.nav-pills>.active>a,.nav-pills>.active>a:hover{color:#ffffff;background-color:#0088cc;} +.nav-stacked>li{float:none;} +.nav-stacked>li>a{margin-right:0;} +.nav-tabs.nav-stacked{border-bottom:0;} +.nav-tabs.nav-stacked>li>a{border:1px solid #ddd;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.nav-tabs.nav-stacked>li:first-child>a{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;} +.nav-tabs.nav-stacked>li:last-child>a{-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;} +.nav-tabs.nav-stacked>li>a:hover{border-color:#ddd;z-index:2;} +.nav-pills.nav-stacked>li>a{margin-bottom:3px;} +.nav-pills.nav-stacked>li:last-child>a{margin-bottom:1px;} +.nav-tabs .dropdown-menu{-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;} +.nav-pills .dropdown-menu{-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} +.nav .dropdown-toggle .caret{border-top-color:#0088cc;border-bottom-color:#0088cc;margin-top:6px;} +.nav .dropdown-toggle:hover .caret{border-top-color:#005580;border-bottom-color:#005580;} +.nav-tabs .dropdown-toggle .caret{margin-top:8px;} +.nav .active .dropdown-toggle .caret{border-top-color:#fff;border-bottom-color:#fff;} +.nav-tabs .active .dropdown-toggle .caret{border-top-color:#555555;border-bottom-color:#555555;} +.nav>.dropdown.active>a:hover{cursor:pointer;} +.nav-tabs .open .dropdown-toggle,.nav-pills .open .dropdown-toggle,.nav>li.dropdown.open.active>a:hover{color:#ffffff;background-color:#999999;border-color:#999999;} +.nav li.dropdown.open .caret,.nav li.dropdown.open.active .caret,.nav li.dropdown.open a:hover .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;opacity:1;filter:alpha(opacity=100);} +.tabs-stacked .open>a:hover{border-color:#999999;} +.tabbable{*zoom:1;}.tabbable:before,.tabbable:after{display:table;content:"";line-height:0;} +.tabbable:after{clear:both;} +.tab-content{overflow:auto;} +.tabs-below>.nav-tabs,.tabs-right>.nav-tabs,.tabs-left>.nav-tabs{border-bottom:0;} +.tab-content>.tab-pane,.pill-content>.pill-pane{display:none;} +.tab-content>.active,.pill-content>.active{display:block;} +.tabs-below>.nav-tabs{border-top:1px solid #ddd;} +.tabs-below>.nav-tabs>li{margin-top:-1px;margin-bottom:0;} +.tabs-below>.nav-tabs>li>a{-webkit-border-radius:0 0 4px 4px;-moz-border-radius:0 0 4px 4px;border-radius:0 0 4px 4px;}.tabs-below>.nav-tabs>li>a:hover{border-bottom-color:transparent;border-top-color:#ddd;} +.tabs-below>.nav-tabs>.active>a,.tabs-below>.nav-tabs>.active>a:hover{border-color:transparent #ddd #ddd #ddd;} +.tabs-left>.nav-tabs>li,.tabs-right>.nav-tabs>li{float:none;} +.tabs-left>.nav-tabs>li>a,.tabs-right>.nav-tabs>li>a{min-width:74px;margin-right:0;margin-bottom:3px;} +.tabs-left>.nav-tabs{float:left;margin-right:19px;border-right:1px solid #ddd;} +.tabs-left>.nav-tabs>li>a{margin-right:-1px;-webkit-border-radius:4px 0 0 4px;-moz-border-radius:4px 0 0 4px;border-radius:4px 0 0 4px;} +.tabs-left>.nav-tabs>li>a:hover{border-color:#eeeeee #dddddd #eeeeee #eeeeee;} +.tabs-left>.nav-tabs .active>a,.tabs-left>.nav-tabs .active>a:hover{border-color:#ddd transparent #ddd #ddd;*border-right-color:#ffffff;} +.tabs-right>.nav-tabs{float:right;margin-left:19px;border-left:1px solid #ddd;} +.tabs-right>.nav-tabs>li>a{margin-left:-1px;-webkit-border-radius:0 4px 4px 0;-moz-border-radius:0 4px 4px 0;border-radius:0 4px 4px 0;} +.tabs-right>.nav-tabs>li>a:hover{border-color:#eeeeee #eeeeee #eeeeee #dddddd;} +.tabs-right>.nav-tabs .active>a,.tabs-right>.nav-tabs .active>a:hover{border-color:#ddd #ddd #ddd transparent;*border-left-color:#ffffff;} +.nav>.disabled>a{color:#999999;} +.nav>.disabled>a:hover{text-decoration:none;background-color:transparent;cursor:default;} +.navbar{overflow:visible;margin-bottom:20px;color:#777777;*position:relative;*z-index:2;} +.navbar-inner{min-height:40px;padding-left:20px;padding-right:20px;background-color:#fafafa;background-image:-moz-linear-gradient(top, #ffffff, #f2f2f2);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ffffff), to(#f2f2f2));background-image:-webkit-linear-gradient(top, #ffffff, #f2f2f2);background-image:-o-linear-gradient(top, #ffffff, #f2f2f2);background-image:linear-gradient(to bottom, #ffffff, #f2f2f2);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffffffff', endColorstr='#fff2f2f2', GradientType=0);border:1px solid #d4d4d4;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);-moz-box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);box-shadow:0 1px 4px rgba(0, 0, 0, 0.065);*zoom:1;}.navbar-inner:before,.navbar-inner:after{display:table;content:"";line-height:0;} +.navbar-inner:after{clear:both;} +.navbar .container{width:auto;} +.nav-collapse.collapse{height:auto;overflow:visible;} +.navbar .brand{float:left;display:block;padding:10px 20px 10px;margin-left:-20px;font-size:20px;font-weight:200;color:#777777;text-shadow:0 1px 0 #ffffff;}.navbar .brand:hover{text-decoration:none;} +.navbar-text{margin-bottom:0;line-height:40px;} +.navbar-link{color:#777777;}.navbar-link:hover{color:#333333;} +.navbar .divider-vertical{height:40px;margin:0 9px;border-left:1px solid #f2f2f2;border-right:1px solid #ffffff;} +.navbar .btn,.navbar .btn-group{margin-top:5px;} +.navbar .btn-group .btn,.navbar .input-prepend .btn,.navbar .input-append .btn{margin-top:0;} +.navbar-form{margin-bottom:0;*zoom:1;}.navbar-form:before,.navbar-form:after{display:table;content:"";line-height:0;} +.navbar-form:after{clear:both;} +.navbar-form input,.navbar-form select,.navbar-form .radio,.navbar-form .checkbox{margin-top:5px;} +.navbar-form input,.navbar-form select,.navbar-form .btn{display:inline-block;margin-bottom:0;} +.navbar-form input[type="image"],.navbar-form input[type="checkbox"],.navbar-form input[type="radio"]{margin-top:3px;} +.navbar-form .input-append,.navbar-form .input-prepend{margin-top:6px;white-space:nowrap;}.navbar-form .input-append input,.navbar-form .input-prepend input{margin-top:0;} +.navbar-search{position:relative;float:left;margin-top:5px;margin-bottom:0;}.navbar-search .search-query{margin-bottom:0;padding:4px 14px;font-family:"Helvetica Neue",Helvetica,Arial,sans-serif;font-size:13px;font-weight:normal;line-height:1;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;} +.navbar-static-top{position:static;margin-bottom:0;}.navbar-static-top .navbar-inner{-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.navbar-fixed-top,.navbar-fixed-bottom{position:fixed;right:0;left:0;z-index:1030;margin-bottom:0;} +.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{border-width:0 0 1px;} +.navbar-fixed-bottom .navbar-inner{border-width:1px 0 0;} +.navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding-left:0;padding-right:0;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;} +.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:940px;} +.navbar-fixed-top{top:0;} +.navbar-fixed-top .navbar-inner,.navbar-static-top .navbar-inner{-webkit-box-shadow:0 1px 10px rgba(0,0,0,.1);-moz-box-shadow:0 1px 10px rgba(0,0,0,.1);box-shadow:0 1px 10px rgba(0,0,0,.1);} +.navbar-fixed-bottom{bottom:0;}.navbar-fixed-bottom .navbar-inner{-webkit-box-shadow:0 -1px 10px rgba(0,0,0,.1);-moz-box-shadow:0 -1px 10px rgba(0,0,0,.1);box-shadow:0 -1px 10px rgba(0,0,0,.1);} +.navbar .nav{position:relative;left:0;display:block;float:left;margin:0 10px 0 0;} +.navbar .nav.pull-right{float:right;margin-right:0;} +.navbar .nav>li{float:left;} +.navbar .nav>li>a{float:none;padding:10px 15px 10px;color:#777777;text-decoration:none;text-shadow:0 1px 0 #ffffff;} +.navbar .nav .dropdown-toggle .caret{margin-top:8px;} +.navbar .nav>li>a:focus,.navbar .nav>li>a:hover{background-color:transparent;color:#333333;text-decoration:none;} +.navbar .nav>.active>a,.navbar .nav>.active>a:hover,.navbar .nav>.active>a:focus{color:#555555;text-decoration:none;background-color:#e5e5e5;-webkit-box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);-moz-box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);box-shadow:inset 0 3px 8px rgba(0, 0, 0, 0.125);} +.navbar .btn-navbar{display:none;float:right;padding:7px 10px;margin-left:5px;margin-right:5px;color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#ededed;background-image:-moz-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f2f2f2), to(#e5e5e5));background-image:-webkit-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:-o-linear-gradient(top, #f2f2f2, #e5e5e5);background-image:linear-gradient(to bottom, #f2f2f2, #e5e5e5);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff2f2f2', endColorstr='#ffe5e5e5', GradientType=0);border-color:#e5e5e5 #e5e5e5 #bfbfbf;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#e5e5e5;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.075);}.navbar .btn-navbar:hover,.navbar .btn-navbar:active,.navbar .btn-navbar.active,.navbar .btn-navbar.disabled,.navbar .btn-navbar[disabled]{color:#ffffff;background-color:#e5e5e5;*background-color:#d9d9d9;} +.navbar .btn-navbar:active,.navbar .btn-navbar.active{background-color:#cccccc \9;} +.navbar .btn-navbar .icon-bar{display:block;width:18px;height:2px;background-color:#f5f5f5;-webkit-border-radius:1px;-moz-border-radius:1px;border-radius:1px;-webkit-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);-moz-box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);box-shadow:0 1px 0 rgba(0, 0, 0, 0.25);} +.btn-navbar .icon-bar+.icon-bar{margin-top:3px;} +.navbar .nav>li>.dropdown-menu:before{content:'';display:inline-block;border-left:7px solid transparent;border-right:7px solid transparent;border-bottom:7px solid #ccc;border-bottom-color:rgba(0, 0, 0, 0.2);position:absolute;top:-7px;left:9px;} +.navbar .nav>li>.dropdown-menu:after{content:'';display:inline-block;border-left:6px solid transparent;border-right:6px solid transparent;border-bottom:6px solid #ffffff;position:absolute;top:-6px;left:10px;} +.navbar-fixed-bottom .nav>li>.dropdown-menu:before{border-top:7px solid #ccc;border-top-color:rgba(0, 0, 0, 0.2);border-bottom:0;bottom:-7px;top:auto;} +.navbar-fixed-bottom .nav>li>.dropdown-menu:after{border-top:6px solid #ffffff;border-bottom:0;bottom:-6px;top:auto;} +.navbar .nav li.dropdown.open>.dropdown-toggle,.navbar .nav li.dropdown.active>.dropdown-toggle,.navbar .nav li.dropdown.open.active>.dropdown-toggle{background-color:#e5e5e5;color:#555555;} +.navbar .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#777777;border-bottom-color:#777777;} +.navbar .nav li.dropdown.open>.dropdown-toggle .caret,.navbar .nav li.dropdown.active>.dropdown-toggle .caret,.navbar .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#555555;border-bottom-color:#555555;} +.navbar .pull-right>li>.dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right{left:auto;right:0;}.navbar .pull-right>li>.dropdown-menu:before,.navbar .nav>li>.dropdown-menu.pull-right:before{left:auto;right:12px;} +.navbar .pull-right>li>.dropdown-menu:after,.navbar .nav>li>.dropdown-menu.pull-right:after{left:auto;right:13px;} +.navbar .pull-right>li>.dropdown-menu .dropdown-menu,.navbar .nav>li>.dropdown-menu.pull-right .dropdown-menu{left:auto;right:100%;margin-left:0;margin-right:-1px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px;} +.navbar-inverse{color:#999999;}.navbar-inverse .navbar-inner{background-color:#1b1b1b;background-image:-moz-linear-gradient(top, #222222, #111111);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#222222), to(#111111));background-image:-webkit-linear-gradient(top, #222222, #111111);background-image:-o-linear-gradient(top, #222222, #111111);background-image:linear-gradient(to bottom, #222222, #111111);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff222222', endColorstr='#ff111111', GradientType=0);border-color:#252525;} +.navbar-inverse .brand,.navbar-inverse .nav>li>a{color:#999999;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);}.navbar-inverse .brand:hover,.navbar-inverse .nav>li>a:hover{color:#ffffff;} +.navbar-inverse .nav>li>a:focus,.navbar-inverse .nav>li>a:hover{background-color:transparent;color:#ffffff;} +.navbar-inverse .nav .active>a,.navbar-inverse .nav .active>a:hover,.navbar-inverse .nav .active>a:focus{color:#ffffff;background-color:#111111;} +.navbar-inverse .navbar-link{color:#999999;}.navbar-inverse .navbar-link:hover{color:#ffffff;} +.navbar-inverse .divider-vertical{border-left-color:#111111;border-right-color:#222222;} +.navbar-inverse .nav li.dropdown.open>.dropdown-toggle,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle{background-color:#111111;color:#ffffff;} +.navbar-inverse .nav li.dropdown>.dropdown-toggle .caret{border-top-color:#999999;border-bottom-color:#999999;} +.navbar-inverse .nav li.dropdown.open>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.active>.dropdown-toggle .caret,.navbar-inverse .nav li.dropdown.open.active>.dropdown-toggle .caret{border-top-color:#ffffff;border-bottom-color:#ffffff;} +.navbar-inverse .navbar-search .search-query{color:#ffffff;background-color:#515151;border-color:#111111;-webkit-box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);-moz-box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);box-shadow:inset 0 1px 2px rgba(0,0,0,.1), 0 1px 0 rgba(255,255,255,.15);-webkit-transition:none;-moz-transition:none;-o-transition:none;transition:none;}.navbar-inverse .navbar-search .search-query:-moz-placeholder{color:#cccccc;} +.navbar-inverse .navbar-search .search-query:-ms-input-placeholder{color:#cccccc;} +.navbar-inverse .navbar-search .search-query::-webkit-input-placeholder{color:#cccccc;} +.navbar-inverse .navbar-search .search-query:focus,.navbar-inverse .navbar-search .search-query.focused{padding:5px 15px;color:#333333;text-shadow:0 1px 0 #ffffff;background-color:#ffffff;border:0;-webkit-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);-moz-box-shadow:0 0 3px rgba(0, 0, 0, 0.15);box-shadow:0 0 3px rgba(0, 0, 0, 0.15);outline:0;} +.navbar-inverse .btn-navbar{color:#ffffff;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e0e0e;background-image:-moz-linear-gradient(top, #151515, #040404);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#151515), to(#040404));background-image:-webkit-linear-gradient(top, #151515, #040404);background-image:-o-linear-gradient(top, #151515, #040404);background-image:linear-gradient(to bottom, #151515, #040404);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff151515', endColorstr='#ff040404', GradientType=0);border-color:#040404 #040404 #000000;border-color:rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25);*background-color:#040404;filter:progid:DXImageTransform.Microsoft.gradient(enabled = false);}.navbar-inverse .btn-navbar:hover,.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active,.navbar-inverse .btn-navbar.disabled,.navbar-inverse .btn-navbar[disabled]{color:#ffffff;background-color:#040404;*background-color:#000000;} +.navbar-inverse .btn-navbar:active,.navbar-inverse .btn-navbar.active{background-color:#000000 \9;} +.breadcrumb{padding:8px 15px;margin:0 0 20px;list-style:none;background-color:#f5f5f5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;}.breadcrumb li{display:inline-block;*display:inline;*zoom:1;text-shadow:0 1px 0 #ffffff;} +.breadcrumb .divider{padding:0 5px;color:#ccc;} +.breadcrumb .active{color:#999999;} +.pagination{margin:20px 0;} +.pagination ul{display:inline-block;*display:inline;*zoom:1;margin-left:0;margin-bottom:0;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);-moz-box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);box-shadow:0 1px 2px rgba(0, 0, 0, 0.05);} +.pagination ul>li{display:inline;} +.pagination ul>li>a,.pagination ul>li>span{float:left;padding:4px 12px;line-height:20px;text-decoration:none;background-color:#ffffff;border:1px solid #dddddd;border-left-width:0;} +.pagination ul>li>a:hover,.pagination ul>.active>a,.pagination ul>.active>span{background-color:#f5f5f5;} +.pagination ul>.active>a,.pagination ul>.active>span{color:#999999;cursor:default;} +.pagination ul>.disabled>span,.pagination ul>.disabled>a,.pagination ul>.disabled>a:hover{color:#999999;background-color:transparent;cursor:default;} +.pagination ul>li:first-child>a,.pagination ul>li:first-child>span{border-left-width:1px;-webkit-border-top-left-radius:4px;-moz-border-radius-topleft:4px;border-top-left-radius:4px;-webkit-border-bottom-left-radius:4px;-moz-border-radius-bottomleft:4px;border-bottom-left-radius:4px;} +.pagination ul>li:last-child>a,.pagination ul>li:last-child>span{-webkit-border-top-right-radius:4px;-moz-border-radius-topright:4px;border-top-right-radius:4px;-webkit-border-bottom-right-radius:4px;-moz-border-radius-bottomright:4px;border-bottom-right-radius:4px;} +.pagination-centered{text-align:center;} +.pagination-right{text-align:right;} +.pagination-large ul>li>a,.pagination-large ul>li>span{padding:11px 19px;font-size:17.5px;} +.pagination-large ul>li:first-child>a,.pagination-large ul>li:first-child>span{-webkit-border-top-left-radius:6px;-moz-border-radius-topleft:6px;border-top-left-radius:6px;-webkit-border-bottom-left-radius:6px;-moz-border-radius-bottomleft:6px;border-bottom-left-radius:6px;} +.pagination-large ul>li:last-child>a,.pagination-large ul>li:last-child>span{-webkit-border-top-right-radius:6px;-moz-border-radius-topright:6px;border-top-right-radius:6px;-webkit-border-bottom-right-radius:6px;-moz-border-radius-bottomright:6px;border-bottom-right-radius:6px;} +.pagination-mini ul>li:first-child>a,.pagination-small ul>li:first-child>a,.pagination-mini ul>li:first-child>span,.pagination-small ul>li:first-child>span{-webkit-border-top-left-radius:3px;-moz-border-radius-topleft:3px;border-top-left-radius:3px;-webkit-border-bottom-left-radius:3px;-moz-border-radius-bottomleft:3px;border-bottom-left-radius:3px;} +.pagination-mini ul>li:last-child>a,.pagination-small ul>li:last-child>a,.pagination-mini ul>li:last-child>span,.pagination-small ul>li:last-child>span{-webkit-border-top-right-radius:3px;-moz-border-radius-topright:3px;border-top-right-radius:3px;-webkit-border-bottom-right-radius:3px;-moz-border-radius-bottomright:3px;border-bottom-right-radius:3px;} +.pagination-small ul>li>a,.pagination-small ul>li>span{padding:2px 10px;font-size:11.9px;} +.pagination-mini ul>li>a,.pagination-mini ul>li>span{padding:1px 6px;font-size:10.5px;} +.pager{margin:20px 0;list-style:none;text-align:center;*zoom:1;}.pager:before,.pager:after{display:table;content:"";line-height:0;} +.pager:after{clear:both;} +.pager li{display:inline;} +.pager li>a,.pager li>span{display:inline-block;padding:5px 14px;background-color:#fff;border:1px solid #ddd;-webkit-border-radius:15px;-moz-border-radius:15px;border-radius:15px;} +.pager li>a:hover{text-decoration:none;background-color:#f5f5f5;} +.pager .next>a,.pager .next>span{float:right;} +.pager .previous>a,.pager .previous>span{float:left;} +.pager .disabled>a,.pager .disabled>a:hover,.pager .disabled>span{color:#999999;background-color:#fff;cursor:default;} +.thumbnails{margin-left:-20px;list-style:none;*zoom:1;}.thumbnails:before,.thumbnails:after{display:table;content:"";line-height:0;} +.thumbnails:after{clear:both;} +.row-fluid .thumbnails{margin-left:0;} +.thumbnails>li{float:left;margin-bottom:20px;margin-left:20px;} +.thumbnail{display:block;padding:4px;line-height:20px;border:1px solid #ddd;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);-moz-box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);box-shadow:0 1px 3px rgba(0, 0, 0, 0.055);-webkit-transition:all 0.2s ease-in-out;-moz-transition:all 0.2s ease-in-out;-o-transition:all 0.2s ease-in-out;transition:all 0.2s ease-in-out;} +a.thumbnail:hover{border-color:#0088cc;-webkit-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);-moz-box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);box-shadow:0 1px 4px rgba(0, 105, 214, 0.25);} +.thumbnail>img{display:block;max-width:100%;margin-left:auto;margin-right:auto;} +.thumbnail .caption{padding:9px;color:#555555;} +.alert{padding:8px 35px 8px 14px;margin-bottom:20px;text-shadow:0 1px 0 rgba(255, 255, 255, 0.5);background-color:#fcf8e3;border:1px solid #fbeed5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;color:#c09853;} +.alert h4{margin:0;} +.alert .close{position:relative;top:-2px;right:-21px;line-height:20px;} +.alert-success{background-color:#dff0d8;border-color:#d6e9c6;color:#468847;} +.alert-danger,.alert-error{background-color:#f2dede;border-color:#eed3d7;color:#b94a48;} +.alert-info{background-color:#d9edf7;border-color:#bce8f1;color:#3a87ad;} +.alert-block{padding-top:14px;padding-bottom:14px;} +.alert-block>p,.alert-block>ul{margin-bottom:0;} +.alert-block p+p{margin-top:5px;} +@-webkit-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-moz-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-ms-keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}@-o-keyframes progress-bar-stripes{from{background-position:0 0;} to{background-position:40px 0;}}@keyframes progress-bar-stripes{from{background-position:40px 0;} to{background-position:0 0;}}.progress{overflow:hidden;height:20px;margin-bottom:20px;background-color:#f7f7f7;background-image:-moz-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#f5f5f5), to(#f9f9f9));background-image:-webkit-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:-o-linear-gradient(top, #f5f5f5, #f9f9f9);background-image:linear-gradient(to bottom, #f5f5f5, #f9f9f9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fff5f5f5', endColorstr='#fff9f9f9', GradientType=0);-webkit-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-moz-box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);box-shadow:inset 0 1px 2px rgba(0, 0, 0, 0.1);-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.progress .bar{width:0%;height:100%;color:#ffffff;float:left;font-size:12px;text-align:center;text-shadow:0 -1px 0 rgba(0, 0, 0, 0.25);background-color:#0e90d2;background-image:-moz-linear-gradient(top, #149bdf, #0480be);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#149bdf), to(#0480be));background-image:-webkit-linear-gradient(top, #149bdf, #0480be);background-image:-o-linear-gradient(top, #149bdf, #0480be);background-image:linear-gradient(to bottom, #149bdf, #0480be);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff149bdf', endColorstr='#ff0480be', GradientType=0);-webkit-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-moz-box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);box-shadow:inset 0 -1px 0 rgba(0, 0, 0, 0.15);-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;-webkit-transition:width 0.6s ease;-moz-transition:width 0.6s ease;-o-transition:width 0.6s ease;transition:width 0.6s ease;} +.progress .bar+.bar{-webkit-box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);-moz-box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);box-shadow:inset 1px 0 0 rgba(0,0,0,.15), inset 0 -1px 0 rgba(0,0,0,.15);} +.progress-striped .bar{background-color:#149bdf;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);-webkit-background-size:40px 40px;-moz-background-size:40px 40px;-o-background-size:40px 40px;background-size:40px 40px;} +.progress.active .bar{-webkit-animation:progress-bar-stripes 2s linear infinite;-moz-animation:progress-bar-stripes 2s linear infinite;-ms-animation:progress-bar-stripes 2s linear infinite;-o-animation:progress-bar-stripes 2s linear infinite;animation:progress-bar-stripes 2s linear infinite;} +.progress-danger .bar,.progress .bar-danger{background-color:#dd514c;background-image:-moz-linear-gradient(top, #ee5f5b, #c43c35);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#ee5f5b), to(#c43c35));background-image:-webkit-linear-gradient(top, #ee5f5b, #c43c35);background-image:-o-linear-gradient(top, #ee5f5b, #c43c35);background-image:linear-gradient(to bottom, #ee5f5b, #c43c35);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ffee5f5b', endColorstr='#ffc43c35', GradientType=0);} +.progress-danger.progress-striped .bar,.progress-striped .bar-danger{background-color:#ee5f5b;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-success .bar,.progress .bar-success{background-color:#5eb95e;background-image:-moz-linear-gradient(top, #62c462, #57a957);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#62c462), to(#57a957));background-image:-webkit-linear-gradient(top, #62c462, #57a957);background-image:-o-linear-gradient(top, #62c462, #57a957);background-image:linear-gradient(to bottom, #62c462, #57a957);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff62c462', endColorstr='#ff57a957', GradientType=0);} +.progress-success.progress-striped .bar,.progress-striped .bar-success{background-color:#62c462;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-info .bar,.progress .bar-info{background-color:#4bb1cf;background-image:-moz-linear-gradient(top, #5bc0de, #339bb9);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#5bc0de), to(#339bb9));background-image:-webkit-linear-gradient(top, #5bc0de, #339bb9);background-image:-o-linear-gradient(top, #5bc0de, #339bb9);background-image:linear-gradient(to bottom, #5bc0de, #339bb9);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff5bc0de', endColorstr='#ff339bb9', GradientType=0);} +.progress-info.progress-striped .bar,.progress-striped .bar-info{background-color:#5bc0de;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.progress-warning .bar,.progress .bar-warning{background-color:#faa732;background-image:-moz-linear-gradient(top, #fbb450, #f89406);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#fbb450), to(#f89406));background-image:-webkit-linear-gradient(top, #fbb450, #f89406);background-image:-o-linear-gradient(top, #fbb450, #f89406);background-image:linear-gradient(to bottom, #fbb450, #f89406);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#fffbb450', endColorstr='#fff89406', GradientType=0);} +.progress-warning.progress-striped .bar,.progress-striped .bar-warning{background-color:#fbb450;background-image:-webkit-gradient(linear, 0 100%, 100% 0, color-stop(0.25, rgba(255, 255, 255, 0.15)), color-stop(0.25, transparent), color-stop(0.5, transparent), color-stop(0.5, rgba(255, 255, 255, 0.15)), color-stop(0.75, rgba(255, 255, 255, 0.15)), color-stop(0.75, transparent), to(transparent));background-image:-webkit-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-moz-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:-o-linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);background-image:linear-gradient(45deg, rgba(255, 255, 255, 0.15) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, 0.15) 50%, rgba(255, 255, 255, 0.15) 75%, transparent 75%, transparent);} +.hero-unit{padding:60px;margin-bottom:30px;font-size:18px;font-weight:200;line-height:30px;color:inherit;background-color:#eeeeee;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;}.hero-unit h1{margin-bottom:0;font-size:60px;line-height:1;color:inherit;letter-spacing:-1px;} +.hero-unit li{line-height:30px;} +.media,.media-body{overflow:hidden;*overflow:visible;zoom:1;} +.media,.media .media{margin-top:15px;} +.media:first-child{margin-top:0;} +.media-object{display:block;} +.media-heading{margin:0 0 5px;} +.media .pull-left{margin-right:10px;} +.media .pull-right{margin-left:10px;} +.media-list{margin-left:0;list-style:none;} +.tooltip{position:absolute;z-index:1030;display:block;visibility:visible;padding:5px;font-size:11px;opacity:0;filter:alpha(opacity=0);}.tooltip.in{opacity:0.8;filter:alpha(opacity=80);} +.tooltip.top{margin-top:-3px;} +.tooltip.right{margin-left:3px;} +.tooltip.bottom{margin-top:3px;} +.tooltip.left{margin-left:-3px;} +.tooltip-inner{max-width:200px;padding:3px 8px;color:#ffffff;text-align:center;text-decoration:none;background-color:#000000;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.tooltip-arrow{position:absolute;width:0;height:0;border-color:transparent;border-style:solid;} +.tooltip.top .tooltip-arrow{bottom:0;left:50%;margin-left:-5px;border-width:5px 5px 0;border-top-color:#000000;} +.tooltip.right .tooltip-arrow{top:50%;left:0;margin-top:-5px;border-width:5px 5px 5px 0;border-right-color:#000000;} +.tooltip.left .tooltip-arrow{top:50%;right:0;margin-top:-5px;border-width:5px 0 5px 5px;border-left-color:#000000;} +.tooltip.bottom .tooltip-arrow{top:0;left:50%;margin-left:-5px;border-width:0 5px 5px;border-bottom-color:#000000;} +.popover{position:absolute;top:0;left:0;z-index:1010;display:none;width:236px;padding:1px;background-color:#ffffff;-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);}.popover.top{margin-top:-10px;} +.popover.right{margin-left:10px;} +.popover.bottom{margin-top:10px;} +.popover.left{margin-left:-10px;} +.popover-title{margin:0;padding:8px 14px;font-size:14px;font-weight:normal;line-height:18px;background-color:#f7f7f7;border-bottom:1px solid #ebebeb;-webkit-border-radius:5px 5px 0 0;-moz-border-radius:5px 5px 0 0;border-radius:5px 5px 0 0;} +.popover-content{padding:9px 14px;}.popover-content p,.popover-content ul,.popover-content ol{margin-bottom:0;} +.popover .arrow,.popover .arrow:after{position:absolute;display:inline-block;width:0;height:0;border-color:transparent;border-style:solid;} +.popover .arrow:after{content:"";z-index:-1;} +.popover.top .arrow{bottom:-10px;left:50%;margin-left:-10px;border-width:10px 10px 0;border-top-color:#ffffff;}.popover.top .arrow:after{border-width:11px 11px 0;border-top-color:rgba(0, 0, 0, 0.25);bottom:-1px;left:-11px;} +.popover.right .arrow{top:50%;left:-10px;margin-top:-10px;border-width:10px 10px 10px 0;border-right-color:#ffffff;}.popover.right .arrow:after{border-width:11px 11px 11px 0;border-right-color:rgba(0, 0, 0, 0.25);bottom:-11px;left:-1px;} +.popover.bottom .arrow{top:-10px;left:50%;margin-left:-10px;border-width:0 10px 10px;border-bottom-color:#ffffff;}.popover.bottom .arrow:after{border-width:0 11px 11px;border-bottom-color:rgba(0, 0, 0, 0.25);top:-1px;left:-11px;} +.popover.left .arrow{top:50%;right:-10px;margin-top:-10px;border-width:10px 0 10px 10px;border-left-color:#ffffff;}.popover.left .arrow:after{border-width:11px 0 11px 11px;border-left-color:rgba(0, 0, 0, 0.25);bottom:-11px;right:-1px;} +.modal-backdrop{position:fixed;top:0;right:0;bottom:0;left:0;z-index:1040;background-color:#000000;}.modal-backdrop.fade{opacity:0;} +.modal-backdrop,.modal-backdrop.fade.in{opacity:0.8;filter:alpha(opacity=80);} +.modal{position:fixed;top:50%;left:50%;z-index:1050;width:560px;margin:-250px 0 0 -280px;background-color:#ffffff;border:1px solid #999;border:1px solid rgba(0, 0, 0, 0.3);*border:1px solid #999;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-moz-box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);box-shadow:0 3px 7px rgba(0, 0, 0, 0.3);-webkit-background-clip:padding-box;-moz-background-clip:padding-box;background-clip:padding-box;outline:none;}.modal.fade{-webkit-transition:opacity .3s linear, top .3s ease-out;-moz-transition:opacity .3s linear, top .3s ease-out;-o-transition:opacity .3s linear, top .3s ease-out;transition:opacity .3s linear, top .3s ease-out;top:-25%;} +.modal.fade.in{top:50%;} +.modal-header{padding:9px 15px;border-bottom:1px solid #eee;}.modal-header .close{margin-top:2px;} +.modal-header h3{margin:0;line-height:30px;} +.modal-body{overflow-y:auto;max-height:400px;padding:15px;} +.modal-form{margin-bottom:0;} +.modal-footer{padding:14px 15px 15px;margin-bottom:0;text-align:right;background-color:#f5f5f5;border-top:1px solid #ddd;-webkit-border-radius:0 0 6px 6px;-moz-border-radius:0 0 6px 6px;border-radius:0 0 6px 6px;-webkit-box-shadow:inset 0 1px 0 #ffffff;-moz-box-shadow:inset 0 1px 0 #ffffff;box-shadow:inset 0 1px 0 #ffffff;*zoom:1;}.modal-footer:before,.modal-footer:after{display:table;content:"";line-height:0;} +.modal-footer:after{clear:both;} +.modal-footer .btn+.btn{margin-left:5px;margin-bottom:0;} +.modal-footer .btn-group .btn+.btn{margin-left:-1px;} +.modal-footer .btn-block+.btn-block{margin-left:0;} +.dropup,.dropdown{position:relative;} +.dropdown-toggle{*margin-bottom:-3px;} +.dropdown-toggle:active,.open .dropdown-toggle{outline:0;} +.caret{display:inline-block;width:0;height:0;vertical-align:top;border-top:4px solid #000000;border-right:4px solid transparent;border-left:4px solid transparent;content:"";} +.dropdown .caret{margin-top:8px;margin-left:2px;} +.dropdown-menu{position:absolute;top:100%;left:0;z-index:1000;display:none;float:left;min-width:160px;padding:5px 0;margin:2px 0 0;list-style:none;background-color:#ffffff;border:1px solid #ccc;border:1px solid rgba(0, 0, 0, 0.2);*border-right-width:2px;*border-bottom-width:2px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;-webkit-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-moz-box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);box-shadow:0 5px 10px rgba(0, 0, 0, 0.2);-webkit-background-clip:padding-box;-moz-background-clip:padding;background-clip:padding-box;}.dropdown-menu.pull-right{right:0;left:auto;} +.dropdown-menu .divider{*width:100%;height:1px;margin:9px 1px;*margin:-5px 0 5px;overflow:hidden;background-color:#e5e5e5;border-bottom:1px solid #ffffff;} +.dropdown-menu li>a{display:block;padding:3px 20px;clear:both;font-weight:normal;line-height:20px;color:#333333;white-space:nowrap;} +.dropdown-menu li>a:hover,.dropdown-menu li>a:focus,.dropdown-submenu:hover>a{text-decoration:none;color:#ffffff;background-color:#0081c2;background-image:-moz-linear-gradient(top, #0088cc, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));background-image:-webkit-linear-gradient(top, #0088cc, #0077b3);background-image:-o-linear-gradient(top, #0088cc, #0077b3);background-image:linear-gradient(to bottom, #0088cc, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);} +.dropdown-menu .active>a,.dropdown-menu .active>a:hover{color:#333333;text-decoration:none;outline:0;background-color:#0081c2;background-image:-moz-linear-gradient(top, #0088cc, #0077b3);background-image:-webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0077b3));background-image:-webkit-linear-gradient(top, #0088cc, #0077b3);background-image:-o-linear-gradient(top, #0088cc, #0077b3);background-image:linear-gradient(to bottom, #0088cc, #0077b3);background-repeat:repeat-x;filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ff0088cc', endColorstr='#ff0077b3', GradientType=0);} +.dropdown-menu .disabled>a,.dropdown-menu .disabled>a:hover{color:#999999;} +.dropdown-menu .disabled>a:hover{text-decoration:none;background-color:transparent;background-image:none;cursor:default;} +.open{*z-index:1000;}.open >.dropdown-menu{display:block;} +.pull-right>.dropdown-menu{right:0;left:auto;} +.dropup .caret,.navbar-fixed-bottom .dropdown .caret{border-top:0;border-bottom:4px solid #000000;content:"";} +.dropup .dropdown-menu,.navbar-fixed-bottom .dropdown .dropdown-menu{top:auto;bottom:100%;margin-bottom:1px;} +.dropdown-submenu{position:relative;} +.dropdown-submenu>.dropdown-menu{top:0;left:100%;margin-top:-6px;margin-left:-1px;-webkit-border-radius:0 6px 6px 6px;-moz-border-radius:0 6px 6px 6px;border-radius:0 6px 6px 6px;} +.dropdown-submenu:hover>.dropdown-menu{display:block;} +.dropup .dropdown-submenu>.dropdown-menu{top:auto;bottom:0;margin-top:0;margin-bottom:-2px;-webkit-border-radius:5px 5px 5px 0;-moz-border-radius:5px 5px 5px 0;border-radius:5px 5px 5px 0;} +.dropdown-submenu>a:after{display:block;content:" ";float:right;width:0;height:0;border-color:transparent;border-style:solid;border-width:5px 0 5px 5px;border-left-color:#cccccc;margin-top:5px;margin-right:-10px;} +.dropdown-submenu:hover>a:after{border-left-color:#ffffff;} +.dropdown-submenu.pull-left{float:none;}.dropdown-submenu.pull-left>.dropdown-menu{left:-100%;margin-left:10px;-webkit-border-radius:6px 0 6px 6px;-moz-border-radius:6px 0 6px 6px;border-radius:6px 0 6px 6px;} +.dropdown .dropdown-menu .nav-header{padding-left:20px;padding-right:20px;} +.typeahead{margin-top:2px;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.accordion{margin-bottom:20px;} +.accordion-group{margin-bottom:2px;border:1px solid #e5e5e5;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} +.accordion-heading{border-bottom:0;} +.accordion-heading .accordion-toggle{display:block;padding:8px 15px;} +.accordion-toggle{cursor:pointer;} +.accordion-inner{padding:9px 15px;border-top:1px solid #e5e5e5;} +.carousel{position:relative;margin-bottom:20px;line-height:1;} +.carousel-inner{overflow:hidden;width:100%;position:relative;} +.carousel .item{display:none;position:relative;-webkit-transition:0.6s ease-in-out left;-moz-transition:0.6s ease-in-out left;-o-transition:0.6s ease-in-out left;transition:0.6s ease-in-out left;} +.carousel .item>img{display:block;line-height:1;} +.carousel .active,.carousel .next,.carousel .prev{display:block;} +.carousel .active{left:0;} +.carousel .next,.carousel .prev{position:absolute;top:0;width:100%;} +.carousel .next{left:100%;} +.carousel .prev{left:-100%;} +.carousel .next.left,.carousel .prev.right{left:0;} +.carousel .active.left{left:-100%;} +.carousel .active.right{left:100%;} +.carousel-control{position:absolute;top:40%;left:15px;width:40px;height:40px;margin-top:-20px;font-size:60px;font-weight:100;line-height:30px;color:#ffffff;text-align:center;background:#222222;border:3px solid #ffffff;-webkit-border-radius:23px;-moz-border-radius:23px;border-radius:23px;opacity:0.5;filter:alpha(opacity=50);}.carousel-control.right{left:auto;right:15px;} +.carousel-control:hover{color:#ffffff;text-decoration:none;opacity:0.9;filter:alpha(opacity=90);} +.carousel-caption{position:absolute;left:0;right:0;bottom:0;padding:15px;background:#333333;background:rgba(0, 0, 0, 0.75);} +.carousel-caption h4,.carousel-caption p{color:#ffffff;line-height:20px;} +.carousel-caption h4{margin:0 0 5px;} +.carousel-caption p{margin-bottom:0;} +.media,.media-body{overflow:hidden;*overflow:visible;zoom:1;} +.media,.media .media{margin-top:15px;} +.media:first-child{margin-top:0;} +.media-object{display:block;} +.media-heading{margin:0 0 5px;} +.media .pull-left{margin-right:10px;} +.media .pull-right{margin-left:10px;} +.media-list{margin-left:0;list-style:none;} +.well{min-height:20px;padding:19px;margin-bottom:20px;background-color:#f5f5f5;border:1px solid #e3e3e3;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;-webkit-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);-moz-box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);box-shadow:inset 0 1px 1px rgba(0, 0, 0, 0.05);}.well blockquote{border-color:#ddd;border-color:rgba(0, 0, 0, 0.15);} +.well-large{padding:24px;-webkit-border-radius:6px;-moz-border-radius:6px;border-radius:6px;} +.well-small{padding:9px;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} +.close{float:right;font-size:20px;font-weight:bold;line-height:20px;color:#000000;text-shadow:0 1px 0 #ffffff;opacity:0.2;filter:alpha(opacity=20);}.close:hover{color:#000000;text-decoration:none;cursor:pointer;opacity:0.4;filter:alpha(opacity=40);} +button.close{padding:0;cursor:pointer;background:transparent;border:0;-webkit-appearance:none;} +.pull-right{float:right;} +.pull-left{float:left;} +.hide{display:none;} +.show{display:block;} +.invisible{visibility:hidden;} +.affix{position:fixed;} +.fade{opacity:0;-webkit-transition:opacity 0.15s linear;-moz-transition:opacity 0.15s linear;-o-transition:opacity 0.15s linear;transition:opacity 0.15s linear;}.fade.in{opacity:1;} +.collapse{position:relative;height:0;overflow:hidden;-webkit-transition:height 0.35s ease;-moz-transition:height 0.35s ease;-o-transition:height 0.35s ease;transition:height 0.35s ease;}.collapse.in{height:auto;} +.hidden{display:none;visibility:hidden;} +.visible-phone{display:none !important;} +.visible-tablet{display:none !important;} +.hidden-desktop{display:none !important;} +.visible-desktop{display:inherit !important;} +@media (min-width:768px) and (max-width:979px){.hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important ;} .visible-tablet{display:inherit !important;} .hidden-tablet{display:none !important;}}@media (max-width:767px){.hidden-desktop{display:inherit !important;} .visible-desktop{display:none !important;} .visible-phone{display:inherit !important;} .hidden-phone{display:none !important;}}@media (max-width:767px){body{padding-left:20px;padding-right:20px;} .navbar-fixed-top,.navbar-fixed-bottom,.navbar-static-top{margin-left:-20px;margin-right:-20px;} .container-fluid{padding:0;} .dl-horizontal dt{float:none;clear:none;width:auto;text-align:left;} .dl-horizontal dd{margin-left:0;} .container{width:auto;} .row-fluid{width:100%;} .row,.thumbnails{margin-left:0;} .thumbnails>li{float:none;margin-left:0;} [class*="span"],.uneditable-input[class*="span"],.row-fluid [class*="span"]{float:none;display:block;width:100%;margin-left:0;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .span12,.row-fluid .span12{width:100%;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .row-fluid [class*="offset"]:first-child{margin-left:0;} .input-large,.input-xlarge,.input-xxlarge,input[class*="span"],select[class*="span"],textarea[class*="span"],.uneditable-input{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;} .input-prepend input,.input-append input,.input-prepend input[class*="span"],.input-append input[class*="span"]{display:inline-block;width:auto;} .controls-row [class*="span"]+[class*="span"]{margin-left:0;} .modal{position:fixed;top:20px;left:20px;right:20px;width:auto;margin:0;}.modal.fade{top:-100px;} .modal.fade.in{top:20px;}}@media (max-width:480px){.nav-collapse{-webkit-transform:translate3d(0, 0, 0);} .page-header h1 small{display:block;line-height:20px;} input[type="checkbox"],input[type="radio"]{border:1px solid #ccc;} .form-horizontal .control-label{float:none;width:auto;padding-top:0;text-align:left;} .form-horizontal .controls{margin-left:0;} .form-horizontal .control-list{padding-top:0;} .form-horizontal .form-actions{padding-left:10px;padding-right:10px;} .media .pull-left,.media .pull-right{float:none;display:block;margin-bottom:10px;} .media-object{margin-right:0;margin-left:0;} .modal{top:10px;left:10px;right:10px;} .modal-header .close{padding:10px;margin:-10px;} .carousel-caption{position:static;}}@media (min-width:768px) and (max-width:979px){.row{margin-left:-20px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} [class*="span"]{float:left;min-height:1px;margin-left:20px;} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:724px;} .span12{width:724px;} .span11{width:662px;} .span10{width:600px;} .span9{width:538px;} .span8{width:476px;} .span7{width:414px;} .span6{width:352px;} .span5{width:290px;} .span4{width:228px;} .span3{width:166px;} .span2{width:104px;} .span1{width:42px;} .offset12{margin-left:764px;} .offset11{margin-left:702px;} .offset10{margin-left:640px;} .offset9{margin-left:578px;} .offset8{margin-left:516px;} .offset7{margin-left:454px;} .offset6{margin-left:392px;} .offset5{margin-left:330px;} .offset4{margin-left:268px;} .offset3{margin-left:206px;} .offset2{margin-left:144px;} .offset1{margin-left:82px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.7624309392265194%;*margin-left:2.709239449864817%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.7624309392265194%;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.43646408839778%;*width:91.38327259903608%;} .row-fluid .span10{width:82.87292817679558%;*width:82.81973668743387%;} .row-fluid .span9{width:74.30939226519337%;*width:74.25620077583166%;} .row-fluid .span8{width:65.74585635359117%;*width:65.69266486422946%;} .row-fluid .span7{width:57.18232044198895%;*width:57.12912895262725%;} .row-fluid .span6{width:48.61878453038674%;*width:48.56559304102504%;} .row-fluid .span5{width:40.05524861878453%;*width:40.00205712942283%;} .row-fluid .span4{width:31.491712707182323%;*width:31.43852121782062%;} .row-fluid .span3{width:22.92817679558011%;*width:22.87498530621841%;} .row-fluid .span2{width:14.3646408839779%;*width:14.311449394616199%;} .row-fluid .span1{width:5.801104972375691%;*width:5.747913483013988%;} .row-fluid .offset12{margin-left:105.52486187845304%;*margin-left:105.41847889972962%;} .row-fluid .offset12:first-child{margin-left:102.76243093922652%;*margin-left:102.6560479605031%;} .row-fluid .offset11{margin-left:96.96132596685082%;*margin-left:96.8549429881274%;} .row-fluid .offset11:first-child{margin-left:94.1988950276243%;*margin-left:94.09251204890089%;} .row-fluid .offset10{margin-left:88.39779005524862%;*margin-left:88.2914070765252%;} .row-fluid .offset10:first-child{margin-left:85.6353591160221%;*margin-left:85.52897613729868%;} .row-fluid .offset9{margin-left:79.8342541436464%;*margin-left:79.72787116492299%;} .row-fluid .offset9:first-child{margin-left:77.07182320441989%;*margin-left:76.96544022569647%;} .row-fluid .offset8{margin-left:71.2707182320442%;*margin-left:71.16433525332079%;} .row-fluid .offset8:first-child{margin-left:68.50828729281768%;*margin-left:68.40190431409427%;} .row-fluid .offset7{margin-left:62.70718232044199%;*margin-left:62.600799341718584%;} .row-fluid .offset7:first-child{margin-left:59.94475138121547%;*margin-left:59.838368402492065%;} .row-fluid .offset6{margin-left:54.14364640883978%;*margin-left:54.037263430116376%;} .row-fluid .offset6:first-child{margin-left:51.38121546961326%;*margin-left:51.27483249088986%;} .row-fluid .offset5{margin-left:45.58011049723757%;*margin-left:45.47372751851417%;} .row-fluid .offset5:first-child{margin-left:42.81767955801105%;*margin-left:42.71129657928765%;} .row-fluid .offset4{margin-left:37.01657458563536%;*margin-left:36.91019160691196%;} .row-fluid .offset4:first-child{margin-left:34.25414364640884%;*margin-left:34.14776066768544%;} .row-fluid .offset3{margin-left:28.45303867403315%;*margin-left:28.346655695309746%;} .row-fluid .offset3:first-child{margin-left:25.69060773480663%;*margin-left:25.584224756083227%;} .row-fluid .offset2{margin-left:19.88950276243094%;*margin-left:19.783119783707537%;} .row-fluid .offset2:first-child{margin-left:17.12707182320442%;*margin-left:17.02068884448102%;} .row-fluid .offset1{margin-left:11.32596685082873%;*margin-left:11.219583872105325%;} .row-fluid .offset1:first-child{margin-left:8.56353591160221%;*margin-left:8.457152932878806%;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*="span"]+[class*="span"]{margin-left:20px;} input.span12, textarea.span12, .uneditable-input.span12{width:710px;} input.span11, textarea.span11, .uneditable-input.span11{width:648px;} input.span10, textarea.span10, .uneditable-input.span10{width:586px;} input.span9, textarea.span9, .uneditable-input.span9{width:524px;} input.span8, textarea.span8, .uneditable-input.span8{width:462px;} input.span7, textarea.span7, .uneditable-input.span7{width:400px;} input.span6, textarea.span6, .uneditable-input.span6{width:338px;} input.span5, textarea.span5, .uneditable-input.span5{width:276px;} input.span4, textarea.span4, .uneditable-input.span4{width:214px;} input.span3, textarea.span3, .uneditable-input.span3{width:152px;} input.span2, textarea.span2, .uneditable-input.span2{width:90px;} input.span1, textarea.span1, .uneditable-input.span1{width:28px;}}@media (min-width:1200px){.row{margin-left:-30px;*zoom:1;}.row:before,.row:after{display:table;content:"";line-height:0;} .row:after{clear:both;} [class*="span"]{float:left;min-height:1px;margin-left:30px;} .container,.navbar-static-top .container,.navbar-fixed-top .container,.navbar-fixed-bottom .container{width:1170px;} .span12{width:1170px;} .span11{width:1070px;} .span10{width:970px;} .span9{width:870px;} .span8{width:770px;} .span7{width:670px;} .span6{width:570px;} .span5{width:470px;} .span4{width:370px;} .span3{width:270px;} .span2{width:170px;} .span1{width:70px;} .offset12{margin-left:1230px;} .offset11{margin-left:1130px;} .offset10{margin-left:1030px;} .offset9{margin-left:930px;} .offset8{margin-left:830px;} .offset7{margin-left:730px;} .offset6{margin-left:630px;} .offset5{margin-left:530px;} .offset4{margin-left:430px;} .offset3{margin-left:330px;} .offset2{margin-left:230px;} .offset1{margin-left:130px;} .row-fluid{width:100%;*zoom:1;}.row-fluid:before,.row-fluid:after{display:table;content:"";line-height:0;} .row-fluid:after{clear:both;} .row-fluid [class*="span"]{display:block;width:100%;min-height:30px;-webkit-box-sizing:border-box;-moz-box-sizing:border-box;box-sizing:border-box;float:left;margin-left:2.564102564102564%;*margin-left:2.5109110747408616%;} .row-fluid [class*="span"]:first-child{margin-left:0;} .row-fluid .controls-row [class*="span"]+[class*="span"]{margin-left:2.564102564102564%;} .row-fluid .span12{width:100%;*width:99.94680851063829%;} .row-fluid .span11{width:91.45299145299145%;*width:91.39979996362975%;} .row-fluid .span10{width:82.90598290598291%;*width:82.8527914166212%;} .row-fluid .span9{width:74.35897435897436%;*width:74.30578286961266%;} .row-fluid .span8{width:65.81196581196582%;*width:65.75877432260411%;} .row-fluid .span7{width:57.26495726495726%;*width:57.21176577559556%;} .row-fluid .span6{width:48.717948717948715%;*width:48.664757228587014%;} .row-fluid .span5{width:40.17094017094017%;*width:40.11774868157847%;} .row-fluid .span4{width:31.623931623931625%;*width:31.570740134569924%;} .row-fluid .span3{width:23.076923076923077%;*width:23.023731587561375%;} .row-fluid .span2{width:14.52991452991453%;*width:14.476723040552828%;} .row-fluid .span1{width:5.982905982905983%;*width:5.929714493544281%;} .row-fluid .offset12{margin-left:105.12820512820512%;*margin-left:105.02182214948171%;} .row-fluid .offset12:first-child{margin-left:102.56410256410257%;*margin-left:102.45771958537915%;} .row-fluid .offset11{margin-left:96.58119658119658%;*margin-left:96.47481360247316%;} .row-fluid .offset11:first-child{margin-left:94.01709401709402%;*margin-left:93.91071103837061%;} .row-fluid .offset10{margin-left:88.03418803418803%;*margin-left:87.92780505546462%;} .row-fluid .offset10:first-child{margin-left:85.47008547008548%;*margin-left:85.36370249136206%;} .row-fluid .offset9{margin-left:79.48717948717949%;*margin-left:79.38079650845607%;} .row-fluid .offset9:first-child{margin-left:76.92307692307693%;*margin-left:76.81669394435352%;} .row-fluid .offset8{margin-left:70.94017094017094%;*margin-left:70.83378796144753%;} .row-fluid .offset8:first-child{margin-left:68.37606837606839%;*margin-left:68.26968539734497%;} .row-fluid .offset7{margin-left:62.393162393162385%;*margin-left:62.28677941443899%;} .row-fluid .offset7:first-child{margin-left:59.82905982905982%;*margin-left:59.72267685033642%;} .row-fluid .offset6{margin-left:53.84615384615384%;*margin-left:53.739770867430444%;} .row-fluid .offset6:first-child{margin-left:51.28205128205128%;*margin-left:51.175668303327875%;} .row-fluid .offset5{margin-left:45.299145299145295%;*margin-left:45.1927623204219%;} .row-fluid .offset5:first-child{margin-left:42.73504273504273%;*margin-left:42.62865975631933%;} .row-fluid .offset4{margin-left:36.75213675213675%;*margin-left:36.645753773413354%;} .row-fluid .offset4:first-child{margin-left:34.18803418803419%;*margin-left:34.081651209310785%;} .row-fluid .offset3{margin-left:28.205128205128204%;*margin-left:28.0987452264048%;} .row-fluid .offset3:first-child{margin-left:25.641025641025642%;*margin-left:25.53464266230224%;} .row-fluid .offset2{margin-left:19.65811965811966%;*margin-left:19.551736679396257%;} .row-fluid .offset2:first-child{margin-left:17.094017094017094%;*margin-left:16.98763411529369%;} .row-fluid .offset1{margin-left:11.11111111111111%;*margin-left:11.004728132387708%;} .row-fluid .offset1:first-child{margin-left:8.547008547008547%;*margin-left:8.440625568285142%;} input,textarea,.uneditable-input{margin-left:0;} .controls-row [class*="span"]+[class*="span"]{margin-left:30px;} input.span12, textarea.span12, .uneditable-input.span12{width:1156px;} input.span11, textarea.span11, .uneditable-input.span11{width:1056px;} input.span10, textarea.span10, .uneditable-input.span10{width:956px;} input.span9, textarea.span9, .uneditable-input.span9{width:856px;} input.span8, textarea.span8, .uneditable-input.span8{width:756px;} input.span7, textarea.span7, .uneditable-input.span7{width:656px;} input.span6, textarea.span6, .uneditable-input.span6{width:556px;} input.span5, textarea.span5, .uneditable-input.span5{width:456px;} input.span4, textarea.span4, .uneditable-input.span4{width:356px;} input.span3, textarea.span3, .uneditable-input.span3{width:256px;} input.span2, textarea.span2, .uneditable-input.span2{width:156px;} input.span1, textarea.span1, .uneditable-input.span1{width:56px;} .thumbnails{margin-left:-30px;} .thumbnails>li{margin-left:30px;} .row-fluid .thumbnails{margin-left:0;}}@media (max-width:979px){body{padding-top:0;} .navbar-fixed-top,.navbar-fixed-bottom{position:static;} .navbar-fixed-top{margin-bottom:20px;} .navbar-fixed-bottom{margin-top:20px;} .navbar-fixed-top .navbar-inner,.navbar-fixed-bottom .navbar-inner{padding:5px;} .navbar .container{width:auto;padding:0;} .navbar .brand{padding-left:10px;padding-right:10px;margin:0 0 0 -5px;} .nav-collapse{clear:both;} .nav-collapse .nav{float:none;margin:0 0 10px;} .nav-collapse .nav>li{float:none;} .nav-collapse .nav>li>a{margin-bottom:2px;} .nav-collapse .nav>.divider-vertical{display:none;} .nav-collapse .nav .nav-header{color:#777777;text-shadow:none;} .nav-collapse .nav>li>a,.nav-collapse .dropdown-menu a{padding:9px 15px;font-weight:bold;color:#777777;-webkit-border-radius:3px;-moz-border-radius:3px;border-radius:3px;} .nav-collapse .btn{padding:4px 10px 4px;font-weight:normal;-webkit-border-radius:4px;-moz-border-radius:4px;border-radius:4px;} .nav-collapse .dropdown-menu li+li a{margin-bottom:2px;} .nav-collapse .nav>li>a:hover,.nav-collapse .dropdown-menu a:hover{background-color:#f2f2f2;} .navbar-inverse .nav-collapse .nav>li>a,.navbar-inverse .nav-collapse .dropdown-menu a{color:#999999;} .navbar-inverse .nav-collapse .nav>li>a:hover,.navbar-inverse .nav-collapse .dropdown-menu a:hover{background-color:#111111;} .nav-collapse.in .btn-group{margin-top:5px;padding:0;} .nav-collapse .dropdown-menu{position:static;top:auto;left:auto;float:none;display:none;max-width:none;margin:0 15px;padding:0;background-color:transparent;border:none;-webkit-border-radius:0;-moz-border-radius:0;border-radius:0;-webkit-box-shadow:none;-moz-box-shadow:none;box-shadow:none;} .nav-collapse .open>.dropdown-menu{display:block;} .nav-collapse .dropdown-menu:before,.nav-collapse .dropdown-menu:after{display:none;} .nav-collapse .dropdown-menu .divider{display:none;} .nav-collapse .nav>li>.dropdown-menu:before,.nav-collapse .nav>li>.dropdown-menu:after{display:none;} .nav-collapse .navbar-form,.nav-collapse .navbar-search{float:none;padding:10px 15px;margin:10px 0;border-top:1px solid #f2f2f2;border-bottom:1px solid #f2f2f2;-webkit-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);-moz-box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);box-shadow:inset 0 1px 0 rgba(255,255,255,.1), 0 1px 0 rgba(255,255,255,.1);} .navbar-inverse .nav-collapse .navbar-form,.navbar-inverse .nav-collapse .navbar-search{border-top-color:#111111;border-bottom-color:#111111;} .navbar .nav-collapse .nav.pull-right{float:none;margin-left:0;} .nav-collapse,.nav-collapse.collapse{overflow:hidden;height:0;} .navbar .btn-navbar{display:block;} .navbar-static .navbar-inner{padding-left:10px;padding-right:10px;}}@media (min-width:980px){.nav-collapse.collapse{height:auto !important;overflow:visible !important;}} diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/css/d3.geomap.css b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/css/d3.geomap.css new file mode 100644 index 00000000..ff005b50 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/css/d3.geomap.css @@ -0,0 +1,29 @@ +/*! + * d3.geomap + * https://github.com/yaph/d3-geomap/blob/master/LICENSE + * MIT licensed + * Copyright (C) 2015 by Ramiro Gómez (http://ramiro.org/) + */ +text { + fill: #333; + font-size: 12px; } + +.background { + fill: none; + pointer-events: all; } + +.unit { + cursor: pointer; + fill: #ccc; + stroke: #000; + stroke-width: 0.4px; } + +.legend-bg { + fill: #fff; + fill-opacity: 0.8; } + +.legend-bar { + stroke: #333; + stroke-width: 1px; } + +/*# sourceMappingURL=geomap.css.map */ diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/css/igviz.css b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/css/igviz.css new file mode 100644 index 00000000..0fa42f15 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/css/igviz.css @@ -0,0 +1,80 @@ +#rect { + fill: none; + stroke: rgb(0, 0, 0); + stroke-width: 2; +} + +#rectCurve { + fill: none; + stroke: rgb(0, 0, 0); + stroke-width: 0.5; +} + +.axis path, +.axis line { + fill: none; + shape-rendering: crispEdges; + stroke: grey; + stroke-width: 2; +} + +.line { + fill: none; + stroke: steelblue; + stroke-width: 1.5px; +} + + +.label{ + font-size: 16.844px !important; +} + +/* arc tween shit*/ +.background { + fill: #FFFFFF; + fill-opacity: 0.01; +} + +.component { + fill: #e1e1e1; +} + +.component .label { + font-family: Myriad, "Helvetic Neue", Helvetica, Arial; + text-anchor: middle; + fill: #0000FF; +} + +.arc { + stroke-weight:0.1; + fill: #4e8fff; +} + + +.arc2 { + stroke-weight:0.1; + fill: #3660b0; +} + + +.label { + font-family: Myriad, "Helvetic Neue", Helvetica, Arial; + text-anchor: middle; +} + +.labelArc { + font-family: Myriad, "Helvetic Neue", Helvetica, Arial; + text-anchor: middle; + fill: #0000FF; +} + +.tooltipClass { + background-color: #e5f2ff; + padding: 4px 8px; + +} +.tooltipClass p{ + margin: 0; + padding: 0; + +} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/gadget.json b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/gadget.json new file mode 100644 index 00000000..958b9364 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/gadget.json @@ -0,0 +1,9 @@ +{ + "id": "TemperatureChart", + "title": "TemperatureChart", + "type": "gadget", + "thumbnail": "local://images/gadgetIcon.png", + "data": { + "url": "local://store/carbon.super/gadget/TemperatureChart/index.xml" + } +} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/index.xml b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/index.xml new file mode 100644 index 00000000..9cc11d51 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/index.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + + Bar Chart + + + + + + + + + + + + + + + + + +
+ + + + ]]> +
+
+ + diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/VizGrammar.min.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/VizGrammar.min.js new file mode 100644 index 00000000..b7d10b77 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/VizGrammar.min.js @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2016, 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. + */ +function getPieMark(a,b){var c;if("donut"==a.mode)var c=a.width/5;else var c=0;var d={type:"arc",from:{data:a.title},properties:{update:{x:{field:{group:"width"},mult:.5},y:{field:{group:"height"},mult:.5},startAngle:{field:"layout_start"},endAngle:{field:"layout_end"},innerRadius:{value:c},outerRadius:{value:.4*a.width},fill:{scale:"color",field:b.names[a.color]},fillOpacity:{value:1}},hover:{fillOpacity:{value:.8}}}};return d}function getPieText(a,b){var c={type:"text",from:{data:a.title},properties:{update:{x:{field:{group:"width"},mult:.5},y:{field:{group:"height"},mult:.5},radius:{value:.5*a.width},theta:{field:"layout_mid"},fill:{value:"#000"},align:{value:"center"},baseline:{value:"middle"},text:{field:b.names[a.x],mult:.5}}}};return c}function getAreaMark(a,b){var c={type:"area",from:{data:a.title},properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},y2:{scale:"y",value:0},fill:{value:a.markColor},strokeWidth:{value:2},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5}}}};return c}function getBarMark(a,b){var c={type:"rect",from:{data:a.title},properties:{update:{x:{scale:"x",field:b.names[a.x]},width:{scale:"x",band:!0,offset:-1},y:{scale:"y",field:b.names[a.y]},y2:{scale:"y",value:0},fill:{value:"steelblue"},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5}}}};return c}function getStackBarMark(a,b){var c={type:"rect",from:{data:"table",transform:[{type:"stack",groupby:[b.names[a.x]],sortby:[b.names[a.color]],field:b.names[a.y]}]},properties:{update:{x:{scale:"x",field:b.names[a.x]},width:{scale:"x",band:!0,offset:-1},y:{scale:"y",field:"layout_start"},y2:{scale:"y",field:"layout_end"},fill:{scale:"color",field:b.names[a.color]},fillOpacity:{value:1}},hover:{fillOpacity:{value:.5}}}};return c}function getLineMark(a,b){var c;return c=-1!=a.color?{type:"group",from:{data:a.title,transform:[{type:"facet",groupby:[b.names[a.color]]}]},marks:[{type:"line",properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},stroke:{scale:"color",field:b.names[a.color]},strokeWidth:{value:2},strokeOpacity:{value:1}},hover:{strokeOpacity:{value:.5}}}}]}:{type:"line",from:{data:a.title},properties:{update:{x:{scale:"x",field:b.names[a.x]},y:{scale:"y",field:b.names[a.y]},stroke:{value:a.markColor},strokeWidth:{value:2},strokeOpacity:{value:1}},hover:{strokeOpacity:{value:.5}}}}}function getTopoJson(a,b){var c,d=a.width,e=a.height,f=a.charts[0].mapType,g="mercator";"usa"==f?(d=a.width-160,e=a.height-130,c=a.height+270,g="albersUsa"):"europe"==f?(d=(a.width/2+100)/2,e=a.height+150,c=a.height+50):(c=a.width/640*120,d=a.width/2+10,e=a.height/2+40);var h=a.geoCodesUrl,i={name:"geoData",url:h,format:{type:"topojson",feature:"units"},transform:[{type:"geopath",value:"data",scale:c,translate:[d,e],projection:g},{type:"lookup",keys:["id"],on:a.title,onKey:b.names[a.x],as:["zipped"],"default":{v:null,country:"No data"}}]};return i}function getMapMark(a,b){var c=[{name:"map",type:"path",from:{data:"geoData"},properties:{enter:{path:{field:"layout_path"}},update:{fill:{rule:[{predicate:{name:"isNotNull",id:{field:"zipped.v"}},scale:"color",field:"zipped.v"},{value:"grey"}]}},hover:{fill:{value:"#989898"}}}},{type:"group",from:{data:a.title,transform:[{type:"filter",test:"datum."+b.names[a.x]+" == tooltipSignal.datum."+b.names[a.x]}]},properties:{update:{x:{signal:"tooltipSignal.x",offset:-5},y:{signal:"tooltipSignal.y",offset:20},width:{value:a.toolTip.width},height:{value:a.toolTip.height},fill:{value:a.toolTip.color}}},marks:[{type:"text",properties:{update:{x:{value:6},y:{value:14},text:{template:"{{tooltipSignal.datum.unitName}} {{tooltipSignal.datum.v}}"},fill:{value:"black"}}}}]}];return c}function getMapSignals(){var a=[{name:"tooltipSignal",init:{expr:"{x: 0, y: 0, datum: {} }"},streams:[{type:"@map:mouseover",expr:"{x: eventX(), y: eventY(), datum: eventItem().datum.zipped}"},{type:"@map:mouseout",expr:"{x: 0, y: 0, datum: {} }"}]}];return a}function getMapPredicates(){var a={name:"isNotNull",type:"!=",operands:[{value:null},{arg:"id"}]};return a}function getMapLegends(a,b){var c={fill:"color",title:b.names[a.y],properties:{gradient:{stroke:{value:"transparent"}},title:{fontSize:{value:14}},legend:{x:{value:0},y:{value:a.height-40}}}};return c}function loadGeoMapCodes(a){var b,c=new XMLHttpRequest;return c.overrideMimeType("application/json"),c.open("GET",a,!1),c.onreadystatechange=function(){4==c.readyState&&"200"==c.status&&(b=JSON.parse(c.responseText))},c.send(null),b}function getMapCode(a,b,c){if("world"==b||"europe"==b)for(d=0;d
"),$("#wrapper").append("
"),$tip=$("#tip"),$tip.empty();var i=g.datum,j="";for(var k in i)if(i.hasOwnProperty(k))if(void 0!=f){for(var l=0;l"+f[l]+" ("+k+"):"+i[k]+"

";break}}else e.names[d.x]==k&&(j+="

X ("+k+"):"+i[k]+"

"),e.names[d.y]==k&&(j+="

Y ("+k+"):"+i[k]+"

");$tip.append(j);var n=h.width,o=h.height,p=$('.marks[style*="width"]');p.length>0&&(n=parseFloat($(".marks")[0].style.width),o=parseFloat($(".marks")[0].style.height));var q,r=$tip.width(),s=$tip.height(),t=g.bounds.x2+d.padding.left+r,u=o-g.bounds.y2-d.padding.top+s,v=g.bounds.y2+d.padding.top-s;q=t>n?g.bounds.x2+d.padding.left-r:g.bounds.x2+d.padding.left,u>o&&(v=g.bounds.y2+d.padding.top),$tip.css({left:q,top:v}).show()}else $("#wrapper #tip").length&&$tip.remove(),$(a).closest("#wrapper").length&&$(a).unwrap()})}var arc=function(a,b){this.metadata=a[0].metadata;var c=[];this.spec={},b=checkConfig(b,this.metadata),this.config=b,a[0].name=b.title,a[0].transform=[{type:"pie",field:this.metadata.names[b.x]}];var d=[];null==b.colorDomain&&(b.colorDomain={data:b.title,field:this.metadata.names[b.color]});var e={name:"color",type:"ordinal",domain:b.colorDomain,range:b.colorScale};d.push(e),c.push(getPieMark(b,this.metadata)),c.push(getPieText(b,this.metadata));var f="Legend";"table"!=b.title&&(f=b.title);var g=[{fill:"color",title:"Legend",offset:20,properties:{symbols:{fillOpacity:{value:.5},stroke:{value:"transparent"}}}}];this.spec.legends=g,this.spec.width=b.width,this.spec.height=b.height,this.spec.data=a,this.spec.scales=d,this.spec.padding=b.padding,this.spec.marks=c};arc.prototype.draw=function(a,b){var c=function(c){if(this.view=c({el:a}).renderer(this.config.renderer).update(),null!=b)for(var d=0;d=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h-1&&(h=!0,f.splice(j,1)),h||f.splice(f.length-1,1)}else this.view.data(this.config.title).insert([a[i]]),this.view.update()}var k,l=function(a){return a[b]==k};for(i=0;i=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h

"+c+"

";document.getElementById(a).innerHTML=d,this.view=b},number.prototype.insert=function(a){document.getElementById(this.view).innerHTML=a[a.length-1][this.metadata.names[this.config.x]]};var scatter=function(a,b){this.metadata=a[0].metadata;var c=[];this.spec={},b=checkConfig(b,this.metadata),this.config=b,a[0].name=b.title;var d={name:"x",type:this.metadata.types[b.x],range:"width",zero:b.zero,domain:{data:b.title,field:this.metadata.names[b.x]}},e={name:"y",type:this.metadata.types[b.y],range:"height",zero:b.zero,domain:{data:b.title,field:this.metadata.names[b.y]}},f={name:"size",type:"linear",range:[0,576],domain:{data:b.title,field:this.metadata.names[b.size]}},g={name:"color",type:"linear",range:[b.minColor,b.maxColor],domain:{data:b.title,field:this.metadata.names[b.color]}},h=[d,e,f,g],i=[{type:"x",scale:"x",grid:b.grid,title:b.xTitle},{type:"y",scale:"y",grid:b.grid,title:b.yTitle}];c.push(getScatterMark(b,this.metadata)),this.spec.width=b.width,this.spec.height=b.height,this.spec.axes=i,this.spec.data=a,this.spec.scales=h,this.spec.padding=b.padding,this.spec.marks=c};scatter.prototype.draw=function(a,b){var c=function(c){if(this.view=c({el:a}).renderer(this.config.renderer).update(),0!=this.config.tooltip&&bindTooltip(a,"symbol",this.view,this.config,this.metadata,["x","y","size"]),null!=b)for(var d=0;d=this.config.maxLength){for(var f=[],g=d.length-e,h=g;h-1&&(j=!0,g.splice(k,1)),j||g.splice(g.length-1,1)}else this.view.data(this.config.title).insert([a[i]]),this.view.update()}var l,m=function(a){return a[b]==l};for(i=0;ib.maxLength){var k=d3.select("tbody").selectAll("tr").data().slice(d3.select("tbody").selectAll("tr").data().length-b.maxLength,b.maxLength);d3.select("tbody").selectAll("tr").data(k,function(a){return a}).remove()}}; \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/d3.min.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/d3.min.js new file mode 100644 index 00000000..e3ee0f91 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/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?0/0:+n}function e(n){return!isNaN(n)}function r(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 u(n){return n.length}function i(n){for(var t=1;n*t%1;)t*=10;return t}function o(n,t){for(var e in t)Object.defineProperty(n.prototype,e,{value:t[e],enumerable:!1})}function a(){this._=Object.create(null)}function c(n){return(n+="")===da||n[0]===ma?ma+n:n}function l(n){return(n+="")[0]===ma?n.slice(1):n}function s(n){return c(n)in this._}function f(n){return(n=c(n))in this._&&delete this._[n]}function h(){var n=[];for(var t in this._)n.push(l(t));return n}function g(){var n=0;for(var t in this._)++n;return n}function p(){for(var n in this._)return!1;return!0}function v(){this._=Object.create(null)}function d(n,t,e){return function(){var r=e.apply(t,arguments);return r===t?n:r}}function m(n,t){if(t in n)return t;t=t.charAt(0).toUpperCase()+t.slice(1);for(var e=0,r=ya.length;r>e;++e){var u=ya[e]+t;if(u in n)return u}}function y(){}function M(){}function x(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 O(n){return xa(n,Aa),n}function Y(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.slice(0,a));var l=Ca.get(n);return l&&(n=l,c=V),a?t?u:r:t?y:i}function Z(n,t){return function(e){var r=ta.event;ta.event=e,t[0]=this.__data__;try{n.apply(this,t)}finally{ta.event=r}}}function V(n,t){var e=Z(n,t);return function(n){var t=this,r=n.relatedTarget;r&&(r===t||8&r.compareDocumentPosition(t))||e.call(t,n)}}function X(){var n=".dragsuppress-"+ ++qa,t="click"+n,e=ta.select(oa).on("touchmove"+n,b).on("dragstart"+n,b).on("selectstart"+n,b);if(za){var r=ia.style,u=r[za];r[za]="none"}return function(i){if(e.on(n,null),za&&(r[za]=u),i){var o=function(){e.on(t,null)};e.on(t,function(){b(),o()},!0),setTimeout(o,0)}}}function $(n,t){t.changedTouches&&(t=t.changedTouches[0]);var e=n.ownerSVGElement||n;if(e.createSVGPoint){var r=e.createSVGPoint();if(0>La&&(oa.scrollX||oa.scrollY)){e=ta.select("body").append("svg").style({position:"absolute",top:0,left:0,margin:0,padding:0,border:"none"},"important");var u=e[0][0].getScreenCTM();La=!(u.f||u.e),e.remove()}return La?(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 B(){return ta.event.changedTouches[0].identifier}function W(){return ta.event.target}function J(){return oa}function G(n){return n>0?1:0>n?-1:0}function K(n,t,e){return(t[0]-n[0])*(e[1]-n[1])-(t[1]-n[1])*(e[0]-n[0])}function Q(n){return n>1?0:-1>n?Da:Math.acos(n)}function nt(n){return n>1?ja:-1>n?-ja:Math.asin(n)}function tt(n){return((n=Math.exp(n))-1/n)/2}function et(n){return((n=Math.exp(n))+1/n)/2}function rt(n){return((n=Math.exp(2*n))-1)/(n+1)}function ut(n){return(n=Math.sin(n/2))*n}function it(){}function ot(n,t,e){return this instanceof ot?(this.h=+n,this.s=+t,void(this.l=+e)):arguments.length<2?n instanceof ot?new ot(n.h,n.s,n.l):xt(""+n,bt,ot):new ot(n,t,e)}function at(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 dt(u(n+120),u(n),u(n-120))}function ct(n,t,e){return this instanceof ct?(this.h=+n,this.c=+t,void(this.l=+e)):arguments.length<2?n instanceof ct?new ct(n.h,n.c,n.l):n instanceof st?ht(n.l,n.a,n.b):ht((n=_t((n=ta.rgb(n)).r,n.g,n.b)).l,n.a,n.b):new ct(n,t,e)}function lt(n,t,e){return isNaN(n)&&(n=0),isNaN(t)&&(t=0),new st(e,Math.cos(n*=Fa)*t,Math.sin(n)*t)}function st(n,t,e){return this instanceof st?(this.l=+n,this.a=+t,void(this.b=+e)):arguments.length<2?n instanceof st?new st(n.l,n.a,n.b):n instanceof ct?lt(n.h,n.c,n.l):_t((n=dt(n)).r,n.g,n.b):new st(n,t,e)}function ft(n,t,e){var r=(n+16)/116,u=r+t/500,i=r-e/200;return u=gt(u)*Ja,r=gt(r)*Ga,i=gt(i)*Ka,new dt(vt(3.2404542*u-1.5371385*r-.4985314*i),vt(-.969266*u+1.8760108*r+.041556*i),vt(.0556434*u-.2040259*r+1.0572252*i))}function ht(n,t,e){return n>0?new ct(Math.atan2(e,t)*Ha,Math.sqrt(t*t+e*e),n):new ct(0/0,0/0,n)}function gt(n){return n>.206893034?n*n*n:(n-4/29)/7.787037}function pt(n){return n>.008856?Math.pow(n,1/3):7.787037*n+4/29}function vt(n){return Math.round(255*(.00304>=n?12.92*n:1.055*Math.pow(n,1/2.4)-.055))}function dt(n,t,e){return this instanceof dt?(this.r=~~n,this.g=~~t,void(this.b=~~e)):arguments.length<2?n instanceof dt?new dt(n.r,n.g,n.b):xt(""+n,dt,at):new dt(n,t,e)}function mt(n){return new dt(n>>16,255&n>>8,255&n)}function yt(n){return mt(n)+""}function Mt(n){return 16>n?"0"+Math.max(0,n).toString(16):Math.min(255,n).toString(16)}function xt(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(St(u[0]),St(u[1]),St(u[2]))}return(i=tc.get(n))?t(i.r,i.g,i.b):(null==n||"#"!==n.charAt(0)||isNaN(i=parseInt(n.slice(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 bt(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 ot(r,u,c)}function _t(n,t,e){n=wt(n),t=wt(t),e=wt(e);var r=pt((.4124564*n+.3575761*t+.1804375*e)/Ja),u=pt((.2126729*n+.7151522*t+.072175*e)/Ga),i=pt((.0193339*n+.119192*t+.9503041*e)/Ka);return st(116*u-16,500*(r-u),200*(u-i))}function wt(n){return(n/=255)<=.04045?n/12.92:Math.pow((n+.055)/1.055,2.4)}function St(n){var t=parseFloat(n);return"%"===n.charAt(n.length-1)?Math.round(2.55*t):t}function kt(n){return"function"==typeof n?n:function(){return n}}function Et(n){return n}function At(n){return function(t,e,r){return 2===arguments.length&&"function"==typeof e&&(r=e,e=null),Nt(t,e,n,r)}}function Nt(n,t,e,r){function u(){var n,t=c.status;if(!t&&zt(c)||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=ta.dispatch("beforesend","progress","load","error"),a={},c=new XMLHttpRequest,l=null;return!oa.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=ta.event;ta.event=n;try{o.progress.call(i,c)}finally{ta.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?(l=n,i):l},i.response=function(n){return e=n,i},["get","post"].forEach(function(n){i[n]=function(){return i.send.apply(i,[n].concat(ra(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 s in a)c.setRequestHeader(s,a[s]);return null!=t&&c.overrideMimeType&&c.overrideMimeType(t),null!=l&&(c.responseType=l),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},ta.rebind(i,o,"on"),null==r?i:i.get(Ct(r))}function Ct(n){return 1===n.length?function(t,e){n(null==t?e:null)}:n}function zt(n){var t=n.responseType;return t&&"text"!==t?n.response:n.responseText}function qt(){var n=Lt(),t=Tt()-n;t>24?(isFinite(t)&&(clearTimeout(ic),ic=setTimeout(qt,t)),uc=0):(uc=1,ac(qt))}function Lt(){var n=Date.now();for(oc=ec;oc;)n>=oc.t&&(oc.f=oc.c(n-oc.t)),oc=oc.n;return n}function Tt(){for(var n,t=ec,e=1/0;t;)t.f?t=n?n.n=t.n:ec=t.n:(t.t8?function(n){return n/e}:function(n){return n*e},symbol:n}}function Pt(n){var t=n.decimal,e=n.thousands,r=n.grouping,u=n.currency,i=r&&e?function(n,t){for(var u=n.length,i=[],o=0,a=r[0],c=0;u>0&&a>0&&(c+a+1>t&&(a=Math.max(1,t-c)),i.push(n.substring(u-=a,u+a)),!((c+=a+1)>t));)a=r[o=(o+1)%r.length];return i.reverse().join(e)}:Et;return function(n){var e=lc.exec(n),r=e[1]||" ",o=e[2]||">",a=e[3]||"-",c=e[4]||"",l=e[5],s=+e[6],f=e[7],h=e[8],g=e[9],p=1,v="",d="",m=!1,y=!0;switch(h&&(h=+h.substring(1)),(l||"0"===r&&"="===o)&&(l=r="0",o="="),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":y=!1;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=sc.get(g)||Ut;var M=l&&f;return function(n){var e=d;if(m&&n%1)return"";var u=0>n||0===n&&0>1/n?(n=-n,"-"):"-"===a?"":a;if(0>p){var c=ta.formatPrefix(n,h);n=c.scale(n),e=c.symbol+d}else n*=p;n=g(n,h);var x,b,_=n.lastIndexOf(".");if(0>_){var w=y?n.lastIndexOf("e"):-1;0>w?(x=n,b=""):(x=n.substring(0,w),b=n.substring(w))}else x=n.substring(0,_),b=t+n.substring(_+1);!l&&f&&(x=i(x,1/0));var S=v.length+x.length+b.length+(M?0:u.length),k=s>S?new Array(S=s-S+1).join(r):"";return M&&(x=i(k+x,k.length?s-b.length:1/0)),u+=v,n=x+b,("<"===o?u+n+k:">"===o?k+u+n:"^"===o?k.substring(0,S>>=1)+u+n+k.substring(S):u+(M?n:k+n))+e}}}function Ut(n){return n+""}function jt(){this._=new Date(arguments.length>1?Date.UTC.apply(this,arguments):arguments[0])}function Ft(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 hc(e-1)),1),e}function i(n,e){return t(n=new hc(+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{hc=jt;var r=new jt;return r._=n,o(r,t,e)}finally{hc=Date}}n.floor=n,n.round=r,n.ceil=u,n.offset=i,n.range=o;var c=n.utc=Ht(n);return c.floor=c,c.round=Ht(r),c.ceil=Ht(u),c.offset=Ht(i),c.range=a,n}function Ht(n){return function(t,e){try{hc=jt;var r=new jt;return r._=t,n(r,e)._}finally{hc=Date}}}function Ot(n){function t(n){function t(t){for(var e,u,i,o=[],a=-1,c=0;++aa;){if(r>=l)return-1;if(u=t.charCodeAt(a++),37===u){if(o=t.charAt(a++),i=C[o in pc?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){_.lastIndex=0;var r=_.exec(t.slice(e));return r?(n.w=w.get(r[0].toLowerCase()),e+r[0].length):-1}function u(n,t,e){x.lastIndex=0;var r=x.exec(t.slice(e));return r?(n.w=b.get(r[0].toLowerCase()),e+r[0].length):-1}function i(n,t,e){E.lastIndex=0;var r=E.exec(t.slice(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.slice(e));return r?(n.m=k.get(r[0].toLowerCase()),e+r[0].length):-1}function a(n,t,r){return e(n,N.c.toString(),t,r)}function c(n,t,r){return e(n,N.x.toString(),t,r)}function l(n,t,r){return e(n,N.X.toString(),t,r)}function s(n,t,e){var r=M.get(t.slice(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{hc=jt;var t=new hc;return t._=n,r(t)}finally{hc=Date}}var r=t(n);return e.parse=function(n){try{hc=jt;var t=r.parse(n);return t&&t._}finally{hc=Date}},e.toString=r.toString,e},t.multi=t.utc.multi=ae;var M=ta.map(),x=It(v),b=Zt(v),_=It(d),w=Zt(d),S=It(m),k=Zt(m),E=It(y),A=Zt(y);p.forEach(function(n,t){M.set(n.toLowerCase(),t)});var N={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 Yt(n.getDate(),t,2)},e:function(n,t){return Yt(n.getDate(),t,2)},H:function(n,t){return Yt(n.getHours(),t,2)},I:function(n,t){return Yt(n.getHours()%12||12,t,2)},j:function(n,t){return Yt(1+fc.dayOfYear(n),t,3)},L:function(n,t){return Yt(n.getMilliseconds(),t,3)},m:function(n,t){return Yt(n.getMonth()+1,t,2)},M:function(n,t){return Yt(n.getMinutes(),t,2)},p:function(n){return p[+(n.getHours()>=12)]},S:function(n,t){return Yt(n.getSeconds(),t,2)},U:function(n,t){return Yt(fc.sundayOfYear(n),t,2)},w:function(n){return n.getDay()},W:function(n,t){return Yt(fc.mondayOfYear(n),t,2)},x:t(h),X:t(g),y:function(n,t){return Yt(n.getFullYear()%100,t,2)},Y:function(n,t){return Yt(n.getFullYear()%1e4,t,4)},Z:ie,"%":function(){return"%"}},C={a:r,A:u,b:i,B:o,c:a,d:Qt,e:Qt,H:te,I:te,j:ne,L:ue,m:Kt,M:ee,p:s,S:re,U:Xt,w:Vt,W:$t,x:c,X:l,y:Wt,Y:Bt,Z:Jt,"%":oe};return t}function Yt(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 It(n){return new RegExp("^(?:"+n.map(ta.requote).join("|")+")","i")}function Zt(n){for(var t=new a,e=-1,r=n.length;++e68?1900:2e3)}function Kt(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.m=r[0]-1,e+r[0].length):-1}function Qt(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.d=+r[0],e+r[0].length):-1}function ne(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+3));return r?(n.j=+r[0],e+r[0].length):-1}function te(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.H=+r[0],e+r[0].length):-1}function ee(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.M=+r[0],e+r[0].length):-1}function re(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+2));return r?(n.S=+r[0],e+r[0].length):-1}function ue(n,t,e){vc.lastIndex=0;var r=vc.exec(t.slice(e,e+3));return r?(n.L=+r[0],e+r[0].length):-1}function ie(n){var t=n.getTimezoneOffset(),e=t>0?"-":"+",r=0|va(t)/60,u=va(t)%60;return e+Yt(r,"0",2)+Yt(u,"0",2)}function oe(n,t,e){dc.lastIndex=0;var r=dc.exec(t.slice(e,e+1));return r?e+r[0].length:-1}function ae(n){for(var t=n.length,e=-1;++e=0?1:-1,a=o*e,c=Math.cos(t),l=Math.sin(t),s=i*l,f=u*c+s*Math.cos(a),h=s*o*Math.sin(a);_c.add(Math.atan2(h,f)),r=n,u=c,i=l}var t,e,r,u,i;wc.point=function(o,a){wc.point=n,r=(t=o)*Fa,u=Math.cos(a=(e=a)*Fa/2+Da/4),i=Math.sin(a)},wc.lineEnd=function(){n(t,e)}}function pe(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 ve(n,t){return n[0]*t[0]+n[1]*t[1]+n[2]*t[2]}function de(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 me(n,t){n[0]+=t[0],n[1]+=t[1],n[2]+=t[2]}function ye(n,t){return[n[0]*t,n[1]*t,n[2]*t]}function Me(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 xe(n){return[Math.atan2(n[1],n[0]),nt(n[2])]}function be(n,t){return va(n[0]-t[0])a;++a)u.point((e=n[a])[0],e[1]);return u.lineEnd(),void 0}var c=new qe(e,n,null,!0),l=new qe(e,null,c,!1);c.o=l,i.push(c),o.push(l),c=new qe(r,n,null,!1),l=new qe(r,null,c,!0),c.o=l,i.push(c),o.push(l)}}),o.sort(t),ze(i),ze(o),i.length){for(var a=0,c=e,l=o.length;l>a;++a)o[a].e=c=!c;for(var s,f,h=i[0];;){for(var g=h,p=!0;g.v;)if((g=g.n)===h)return;s=g.z,u.lineStart();do{if(g.v=g.o.v=!0,g.e){if(p)for(var a=0,l=s.length;l>a;++a)u.point((f=s[a])[0],f[1]);else r(g.x,g.n.x,1,u);g=g.n}else{if(p){s=g.p.z;for(var a=s.length-1;a>=0;--a)u.point((f=s[a])[0],f[1])}else r(g.x,g.p.x,-1,u);g=g.p}g=g.o,s=g.z,p=!p}while(!g.v);u.lineEnd()}}}function ze(n){if(t=n.length){for(var t,e,r=0,u=n[0];++r0){for(b||(i.polygonStart(),b=!0),i.lineStart();++o1&&2&t&&e.push(e.pop().concat(e.shift())),g.push(e.filter(Te))}var g,p,v,d=t(i),m=u.invert(r[0],r[1]),y={point:o,lineStart:c,lineEnd:l,polygonStart:function(){y.point=s,y.lineStart=f,y.lineEnd=h,g=[],p=[]},polygonEnd:function(){y.point=o,y.lineStart=c,y.lineEnd=l,g=ta.merge(g);var n=Fe(m,p);g.length?(b||(i.polygonStart(),b=!0),Ce(g,De,n,e,i)):n&&(b||(i.polygonStart(),b=!0),i.lineStart(),e(null,null,1,i),i.lineEnd()),b&&(i.polygonEnd(),b=!1),g=p=null},sphere:function(){i.polygonStart(),i.lineStart(),e(null,null,1,i),i.lineEnd(),i.polygonEnd()}},M=Re(),x=t(M),b=!1;return y}}function Te(n){return n.length>1}function Re(){var n,t=[];return{lineStart:function(){t.push(n=[])},point:function(t,e){n.push([t,e])},lineEnd:y,buffer:function(){var e=t;return t=[],n=null,e},rejoin:function(){t.length>1&&t.push(t.pop().concat(t.shift()))}}}function De(n,t){return((n=n.x)[0]<0?n[1]-ja-Ta:ja-n[1])-((t=t.x)[0]<0?t[1]-ja-Ta:ja-t[1])}function Pe(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?Da:-Da,c=va(i-e);va(c-Da)0?ja:-ja),n.point(u,r),n.lineEnd(),n.lineStart(),n.point(a,r),n.point(i,r),t=0):u!==a&&c>=Da&&(va(e-u)Ta?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 je(n,t,e,r){var u;if(null==n)u=e*ja,r.point(-Da,u),r.point(0,u),r.point(Da,u),r.point(Da,0),r.point(Da,-u),r.point(0,-u),r.point(-Da,-u),r.point(-Da,0),r.point(-Da,u);else if(va(n[0]-t[0])>Ta){var i=n[0]a;++a){var l=t[a],s=l.length;if(s)for(var f=l[0],h=f[0],g=f[1]/2+Da/4,p=Math.sin(g),v=Math.cos(g),d=1;;){d===s&&(d=0),n=l[d];var m=n[0],y=n[1]/2+Da/4,M=Math.sin(y),x=Math.cos(y),b=m-h,_=b>=0?1:-1,w=_*b,S=w>Da,k=p*M;if(_c.add(Math.atan2(k*_*Math.sin(w),v*x+k*Math.cos(w))),i+=S?b+_*Pa:b,S^h>=e^m>=e){var E=de(pe(f),pe(n));Me(E);var A=de(u,E);Me(A);var N=(S^b>=0?-1:1)*nt(A[2]);(r>N||r===N&&(E[0]||E[1]))&&(o+=S^b>=0?1:-1)}if(!d++)break;h=m,p=M,v=x,f=n}}return(-Ta>i||Ta>i&&0>_c)^1&o}function He(n){function t(n,t){return Math.cos(n)*Math.cos(t)>i}function e(n){var e,i,c,l,s;return{lineStart:function(){l=c=!1,s=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?Da:-Da),h):0;if(!e&&(l=c=v)&&n.lineStart(),v!==c&&(g=r(e,p),(be(e,g)||be(p,g))&&(p[0]+=Ta,p[1]+=Ta,v=t(p[0],p[1]))),v!==c)s=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))||(s=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&&be(e,p)||n.point(p[0],p[1]),e=p,c=v,i=d},lineEnd:function(){c&&n.lineEnd(),e=null},clean:function(){return s|(l&&c)<<1}}}function r(n,t,e){var r=pe(n),u=pe(t),o=[1,0,0],a=de(r,u),c=ve(a,a),l=a[0],s=c-l*l;if(!s)return!e&&n;var f=i*c/s,h=-i*l/s,g=de(o,a),p=ye(o,f),v=ye(a,h);me(p,v);var d=g,m=ve(p,d),y=ve(d,d),M=m*m-y*(ve(p,p)-1);if(!(0>M)){var x=Math.sqrt(M),b=ye(d,(-m-x)/y);if(me(b,p),b=xe(b),!e)return b;var _,w=n[0],S=t[0],k=n[1],E=t[1];w>S&&(_=w,w=S,S=_);var A=S-w,N=va(A-Da)A;if(!N&&k>E&&(_=k,k=E,E=_),C?N?k+E>0^b[1]<(va(b[0]-w)Da^(w<=b[0]&&b[0]<=S)){var z=ye(d,(-m+x)/y);return me(z,p),[b,xe(z)]}}}function u(t,e){var r=o?n:Da-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=va(i)>Ta,c=gr(n,6*Fa);return Le(t,e,c,o?[0,-n]:[-Da,n-Da])}function Oe(n,t,e,r){return function(u){var i,o=u.a,a=u.b,c=o.x,l=o.y,s=a.x,f=a.y,h=0,g=1,p=s-c,v=f-l;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-l,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-l,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:l+h*v}),1>g&&(u.b={x:c+g*p,y:l+g*v}),u}}}}}}function Ye(n,t,e,r){function u(r,u){return va(r[0]-n)0?0:3:va(r[0]-e)0?2:1:va(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,l=a[0];c>o;++o)i=a[o],l[1]<=r?i[1]>r&&K(l,i,n)>0&&++t:i[1]<=r&&K(l,i,n)<0&&--t,l=i;return 0!==t}function l(i,a,c,l){var s=0,f=0;if(null==i||(s=u(i,c))!==(f=u(a,c))||o(i,a)<0^c>0){do l.point(0===s||3===s?n:e,s>1?r:t);while((s=(s+c+4)%4)!==f)}else l.point(a[0],a[1])}function s(u,i){return u>=n&&e>=u&&i>=t&&r>=i}function f(n,t){s(n,t)&&a.point(n,t)}function h(){C.point=p,d&&d.push(m=[]),S=!0,w=!1,b=_=0/0}function g(){v&&(p(y,M),x&&w&&A.rejoin(),v.push(A.buffer())),C.point=f,w&&a.lineEnd()}function p(n,t){n=Math.max(-Uc,Math.min(Uc,n)),t=Math.max(-Uc,Math.min(Uc,t));var e=s(n,t);if(d&&m.push([n,t]),S)y=n,M=t,x=e,S=!1,e&&(a.lineStart(),a.point(n,t));else if(e&&w)a.point(n,t);else{var r={a:{x:b,y:_},b:{x:n,y:t}};N(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)}b=n,_=t,w=e}var v,d,m,y,M,x,b,_,w,S,k,E=a,A=Re(),N=Oe(n,t,e,r),C={point:f,lineStart:h,lineEnd:g,polygonStart:function(){a=A,v=[],d=[],k=!0},polygonEnd:function(){a=E,v=ta.merge(v);var t=c([n,r]),e=k&&t,u=v.length;(e||u)&&(a.polygonStart(),e&&(a.lineStart(),l(null,null,1,a),a.lineEnd()),u&&Ce(v,i,t,l,a),a.polygonEnd()),v=d=m=null}};return C}}function Ie(n){var t=0,e=Da/3,r=ir(n),u=r(t,e);return u.parallels=function(n){return arguments.length?r(t=n[0]*Da/180,e=n[1]*Da/180):[180*(t/Da),180*(e/Da)]},u}function Ze(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,nt((i-(n*n+e*e)*u*u)/(2*u))]},e}function Ve(){function n(n,t){Fc+=u*n-r*t,r=n,u=t}var t,e,r,u;Zc.point=function(i,o){Zc.point=n,t=r=i,e=u=o},Zc.lineEnd=function(){n(t,e)}}function Xe(n,t){Hc>n&&(Hc=n),n>Yc&&(Yc=n),Oc>t&&(Oc=t),t>Ic&&(Ic=t)}function $e(){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=Be(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=Be(n),a},result:function(){if(o.length){var n=o.join("");return o=[],n}}};return a}function Be(n){return"m0,"+n+"a"+n+","+n+" 0 1,1 0,"+-2*n+"a"+n+","+n+" 0 1,1 0,"+2*n+"z"}function We(n,t){Ec+=n,Ac+=t,++Nc}function Je(){function n(n,r){var u=n-t,i=r-e,o=Math.sqrt(u*u+i*i);Cc+=o*(t+n)/2,zc+=o*(e+r)/2,qc+=o,We(t=n,e=r)}var t,e;Xc.point=function(r,u){Xc.point=n,We(t=r,e=u)}}function Ge(){Xc.point=We}function Ke(){function n(n,t){var e=n-r,i=t-u,o=Math.sqrt(e*e+i*i);Cc+=o*(r+n)/2,zc+=o*(u+t)/2,qc+=o,o=u*n-r*t,Lc+=o*(r+n),Tc+=o*(u+t),Rc+=3*o,We(r=n,u=t)}var t,e,r,u;Xc.point=function(i,o){Xc.point=n,We(t=r=i,e=u=o)},Xc.lineEnd=function(){n(t,e)}}function Qe(n){function t(t,e){n.moveTo(t+o,e),n.arc(t,e,o,0,Pa)}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:y};return a}function nr(n){function t(n){return(a?r:e)(n)}function e(t){return rr(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(){M=0/0,S.point=i,t.lineStart()}function i(e,r){var i=pe([e,r]),o=n(e,r);u(M,x,y,b,_,w,M=o[0],x=o[1],y=e,b=i[0],_=i[1],w=i[2],a,t),t.point(M,x)}function o(){S.point=e,t.lineEnd()}function c(){r(),S.point=l,S.lineEnd=s}function l(n,t){i(f=n,h=t),g=M,p=x,v=b,d=_,m=w,S.point=i}function s(){u(M,x,y,b,_,w,g,p,f,v,d,m,a,t),S.lineEnd=o,o()}var f,h,g,p,v,d,m,y,M,x,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,l,s,f,h,g,p,v,d,m){var y=s-t,M=f-e,x=y*y+M*M;if(x>4*i&&d--){var b=a+g,_=c+p,w=l+v,S=Math.sqrt(b*b+_*_+w*w),k=Math.asin(w/=S),E=va(va(w)-1)i||va((y*z+M*q)/x-.5)>.3||o>a*g+c*p+l*v)&&(u(t,e,r,a,c,l,N,C,E,b/=S,_/=S,w,d,m),m.point(N,C),u(N,C,E,b,_,w,s,f,h,g,p,v,d,m))}}var i=.5,o=Math.cos(30*Fa),a=16;return t.precision=function(n){return arguments.length?(a=(i=n*n)>0&&16,t):Math.sqrt(i)},t}function tr(n){var t=nr(function(t,e){return n([t*Ha,e*Ha])});return function(n){return or(t(n))}}function er(n){this.stream=n}function rr(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 ur(n){return ir(function(){return n})()}function ir(n){function t(n){return n=a(n[0]*Fa,n[1]*Fa),[n[0]*h+c,l-n[1]*h]}function e(n){return n=a.invert((n[0]-c)/h,(l-n[1])/h),n&&[n[0]*Ha,n[1]*Ha]}function r(){a=Ae(o=lr(m,y,M),i);var n=i(v,d);return c=g-n[0]*h,l=p+n[1]*h,u()}function u(){return s&&(s.valid=!1,s=null),t}var i,o,a,c,l,s,f=nr(function(n,t){return n=i(n,t),[n[0]*h+c,l-n[1]*h]}),h=150,g=480,p=250,v=0,d=0,m=0,y=0,M=0,x=Pc,b=Et,_=null,w=null;return t.stream=function(n){return s&&(s.valid=!1),s=or(x(o,f(b(n)))),s.valid=!0,s},t.clipAngle=function(n){return arguments.length?(x=null==n?(_=n,Pc):He((_=+n)*Fa),u()):_},t.clipExtent=function(n){return arguments.length?(w=n,b=n?Ye(n[0][0],n[0][1],n[1][0],n[1][1]):Et,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*Fa,d=n[1]%360*Fa,r()):[v*Ha,d*Ha]},t.rotate=function(n){return arguments.length?(m=n[0]%360*Fa,y=n[1]%360*Fa,M=n.length>2?n[2]%360*Fa:0,r()):[m*Ha,y*Ha,M*Ha]},ta.rebind(t,f,"precision"),function(){return i=n.apply(this,arguments),t.invert=i.invert&&e,r()}}function or(n){return rr(n,function(t,e){n.point(t*Fa,e*Fa)})}function ar(n,t){return[n,t]}function cr(n,t){return[n>Da?n-Pa:-Da>n?n+Pa:n,t]}function lr(n,t,e){return n?t||e?Ae(fr(n),hr(t,e)):fr(n):t||e?hr(t,e):cr}function sr(n){return function(t,e){return t+=n,[t>Da?t-Pa:-Da>t?t+Pa:t,e]}}function fr(n){var t=sr(n);return t.invert=sr(-n),t}function hr(n,t){function e(n,t){var e=Math.cos(t),a=Math.cos(n)*e,c=Math.sin(n)*e,l=Math.sin(t),s=l*r+a*u;return[Math.atan2(c*i-s*o,a*r-l*u),nt(s*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,l=Math.sin(t),s=l*i-c*o;return[Math.atan2(c*i+l*o,a*r+s*u),nt(s*r-a*u)]},e}function gr(n,t){var e=Math.cos(n),r=Math.sin(n);return function(u,i,o,a){var c=o*t;null!=u?(u=pr(e,u),i=pr(e,i),(o>0?i>u:u>i)&&(u+=o*Pa)):(u=n+o*Pa,i=n-.5*c);for(var l,s=u;o>0?s>i:i>s;s-=c)a.point((l=xe([e,-r*Math.cos(s),-r*Math.sin(s)]))[0],l[1])}}function pr(n,t){var e=pe(t);e[0]-=n,Me(e);var r=Q(-e[1]);return((-e[2]<0?-r:r)+2*Math.PI-Ta)%(2*Math.PI)}function vr(n,t,e){var r=ta.range(n,t-Ta,e).concat(t);return function(n){return r.map(function(t){return[n,t]})}}function dr(n,t,e){var r=ta.range(n,t-Ta,e).concat(t);return function(n){return r.map(function(t){return[t,n]})}}function mr(n){return n.source}function yr(n){return n.target}function Mr(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),l=u*Math.sin(n),s=o*Math.cos(e),f=o*Math.sin(e),h=2*Math.asin(Math.sqrt(ut(r-t)+u*o*ut(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*s,u=e*l+t*f,o=e*i+t*a;return[Math.atan2(u,r)*Ha,Math.atan2(o,Math.sqrt(r*r+u*u))*Ha]}:function(){return[n*Ha,t*Ha]};return p.distance=h,p}function xr(){function n(n,u){var i=Math.sin(u*=Fa),o=Math.cos(u),a=va((n*=Fa)-t),c=Math.cos(a);$c+=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;Bc.point=function(u,i){t=u*Fa,e=Math.sin(i*=Fa),r=Math.cos(i),Bc.point=n},Bc.lineEnd=function(){Bc.point=Bc.lineEnd=y}}function br(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 _r(n,t){function e(n,t){o>0?-ja+Ta>t&&(t=-ja+Ta):t>ja-Ta&&(t=ja-Ta);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(Da/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=G(i)*Math.sqrt(n*n+e*e);return[Math.atan2(n,e)/i,2*Math.atan(Math.pow(o/r,1/i))-ja]},e):Sr}function wr(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 va(u)u;u++){for(;r>1&&K(n[e[r-2]],n[e[r-1]],n[u])<=0;)--r;e[r++]=u}return e.slice(0,r)}function zr(n,t){return n[0]-t[0]||n[1]-t[1]}function qr(n,t,e){return(e[0]-t[0])*(n[1]-t[1])<(e[1]-t[1])*(n[0]-t[0])}function Lr(n,t,e,r){var u=n[0],i=e[0],o=t[0]-u,a=r[0]-i,c=n[1],l=e[1],s=t[1]-c,f=r[1]-l,h=(a*(c-l)-f*(u-i))/(f*o-a*s);return[u+h*o,c+h*s]}function Tr(n){var t=n[0],e=n[n.length-1];return!(t[0]-e[0]||t[1]-e[1])}function Rr(){tu(this),this.edge=this.site=this.circle=null}function Dr(n){var t=ol.pop()||new Rr;return t.site=n,t}function Pr(n){Xr(n),rl.remove(n),ol.push(n),tu(n)}function Ur(n){var t=n.circle,e=t.x,r=t.cy,u={x:e,y:r},i=n.P,o=n.N,a=[n];Pr(n);for(var c=i;c.circle&&va(e-c.circle.x)s;++s)l=a[s],c=a[s-1],Kr(l.edge,c.site,l.site,u);c=a[0],l=a[f-1],l.edge=Jr(c.site,l.site,null,u),Vr(c),Vr(l)}function jr(n){for(var t,e,r,u,i=n.x,o=n.y,a=rl._;a;)if(r=Fr(a,o)-i,r>Ta)a=a.L;else{if(u=i-Hr(a,o),!(u>Ta)){r>-Ta?(t=a.P,e=a):u>-Ta?(t=a,e=a.N):t=e=a;break}if(!a.R){t=a;break}a=a.R}var c=Dr(n);if(rl.insert(t,c),t||e){if(t===e)return Xr(t),e=Dr(t.site),rl.insert(c,e),c.edge=e.edge=Jr(t.site,c.site),Vr(t),Vr(e),void 0;if(!e)return c.edge=Jr(t.site,c.site),void 0;Xr(t),Xr(e);var l=t.site,s=l.x,f=l.y,h=n.x-s,g=n.y-f,p=e.site,v=p.x-s,d=p.y-f,m=2*(h*d-g*v),y=h*h+g*g,M=v*v+d*d,x={x:(d*y-g*M)/m+s,y:(h*M-v*y)/m+f};Kr(e.edge,l,p,x),c.edge=Jr(l,n,null,x),e.edge=Jr(n,p,null,x),Vr(t),Vr(e)}}function Fr(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,l=c-t;if(!l)return a;var s=a-r,f=1/i-1/l,h=s/l;return f?(-h+Math.sqrt(h*h-2*f*(s*s/(-2*l)-c+l/2+u-i/2)))/f+r:(r+a)/2}function Hr(n,t){var e=n.N;if(e)return Fr(e,t);var r=n.site;return r.y===t?r.x:1/0}function Or(n){this.site=n,this.edges=[]}function Yr(n){for(var t,e,r,u,i,o,a,c,l,s,f=n[0][0],h=n[1][0],g=n[0][1],p=n[1][1],v=el,d=v.length;d--;)if(i=v[d],i&&i.prepare())for(a=i.edges,c=a.length,o=0;c>o;)s=a[o].end(),r=s.x,u=s.y,l=a[++o%c].start(),t=l.x,e=l.y,(va(r-t)>Ta||va(u-e)>Ta)&&(a.splice(o,0,new Qr(Gr(i.site,s,va(r-f)Ta?{x:f,y:va(t-f)Ta?{x:va(e-p)Ta?{x:h,y:va(t-h)Ta?{x:va(e-g)=-Ra)){var g=c*c+l*l,p=s*s+f*f,v=(f*g-l*p)/h,d=(c*p-s*g)/h,f=d+a,m=al.pop()||new Zr;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,M=il._;M;)if(m.yd||d>=a)return;if(h>p){if(i){if(i.y>=l)return}else i={x:d,y:c};e={x:d,y:l}}else{if(i){if(i.yr||r>1)if(h>p){if(i){if(i.y>=l)return}else i={x:(c-u)/r,y:c};e={x:(l-u)/r,y:l}}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||f>o||r>h||u>g)){if(p=n.point){var p,v=t-p[0],d=e-p[1],m=v*v+d*d;if(c>m){var y=Math.sqrt(c=m);r=t-y,u=e-y,i=t+y,o=e+y,a=p}}for(var M=n.nodes,x=.5*(s+h),b=.5*(f+g),_=t>=x,w=e>=b,S=w<<1|_,k=S+4;k>S;++S)if(n=M[3&S])switch(3&S){case 0:l(n,s,f,x,b);break;case 1:l(n,x,f,h,b);break;case 2:l(n,s,b,x,g);break;case 3:l(n,x,b,h,g)}}}(n,r,u,i,o),a}function gu(n,t){n=ta.rgb(n),t=ta.rgb(t);var e=n.r,r=n.g,u=n.b,i=t.r-e,o=t.g-r,a=t.b-u;return function(n){return"#"+Mt(Math.round(e+i*n))+Mt(Math.round(r+o*n))+Mt(Math.round(u+a*n))}}function pu(n,t){var e,r={},u={};for(e in n)e in t?r[e]=mu(n[e],t[e]):u[e]=n[e];for(e in t)e in n||(u[e]=t[e]);return function(n){for(e in r)u[e]=r[e](n);return u}}function vu(n,t){return n=+n,t=+t,function(e){return n*(1-e)+t*e}}function du(n,t){var e,r,u,i=ll.lastIndex=sl.lastIndex=0,o=-1,a=[],c=[];for(n+="",t+="";(e=ll.exec(n))&&(r=sl.exec(t));)(u=r.index)>i&&(u=t.slice(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:vu(e,r)})),i=sl.lastIndex;return ir;++r)a[(e=c[r]).i]=e.x(n);return a.join("")})}function mu(n,t){for(var e,r=ta.interpolators.length;--r>=0&&!(e=ta.interpolators[r](n,t)););return e}function yu(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(mu(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 Mu(n){return function(t){return 0>=t?0:t>=1?1:n(t)}}function xu(n){return function(t){return 1-n(1-t)}}function bu(n){return function(t){return.5*(.5>t?n(2*t):2-n(2-2*t))}}function _u(n){return n*n}function wu(n){return n*n*n}function Su(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 ku(n){return function(t){return Math.pow(t,n)}}function Eu(n){return 1-Math.cos(n*ja)}function Au(n){return Math.pow(2,10*(n-1))}function Nu(n){return 1-Math.sqrt(1-n*n)}function Cu(n,t){var e;return arguments.length<2&&(t=.45),arguments.length?e=t/Pa*Math.asin(1/n):(n=1,e=t/4),function(r){return 1+n*Math.pow(2,-10*r)*Math.sin((r-e)*Pa/t)}}function zu(n){return n||(n=1.70158),function(t){return t*t*((n+1)*t-n)}}function qu(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 Lu(n,t){n=ta.hcl(n),t=ta.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 lt(e+i*n,r+o*n,u+a*n)+""}}function Tu(n,t){n=ta.hsl(n),t=ta.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 at(e+i*n,r+o*n,u+a*n)+""}}function Ru(n,t){n=ta.lab(n),t=ta.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 ft(e+i*n,r+o*n,u+a*n)+""}}function Du(n,t){return t-=n,function(e){return Math.round(n+t*e)}}function Pu(n){var t=[n.a,n.b],e=[n.c,n.d],r=ju(t),u=Uu(t,e),i=ju(Fu(e,t,-u))||0;t[0]*e[1]180?s+=360:s-l>180&&(l+=360),u.push({i:r.push(r.pop()+"rotate(",null,")")-2,x:vu(l,s)})):s&&r.push(r.pop()+"rotate("+s+")"),f!=h?u.push({i:r.push(r.pop()+"skewX(",null,")")-2,x:vu(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:vu(g[0],p[0])},{i:e-2,x:vu(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 Qu(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 si(n){return n.reduce(fi,0)}function fi(n,t){return n+t[1]}function hi(n,t){return gi(n,Math.ceil(Math.log(t.length)/Math.LN2+1))}function gi(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 pi(n){return[ta.min(n),ta.max(n)]}function vi(n,t){return n.value-t.value}function di(n,t){var e=n._pack_next;n._pack_next=t,t._pack_prev=n,t._pack_next=e,e._pack_prev=t}function mi(n,t){n._pack_next=t,t._pack_prev=n}function yi(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 Mi(n){function t(n){s=Math.min(n.x-n.r,s),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)&&(l=e.length)){var e,r,u,i,o,a,c,l,s=1/0,f=-1/0,h=1/0,g=-1/0;if(e.forEach(xi),r=e[0],r.x=-r.r,r.y=0,t(r),l>1&&(u=e[1],u.x=u.r,u.y=0,t(u),l>2))for(i=e[2],wi(r,u,i),t(i),di(r,i),r._pack_prev=i,di(i,u),u=r._pack_next,o=3;l>o;o++){wi(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(yi(a,i)){p=1;break}if(1==p)for(c=r._pack_prev;c!==a._pack_prev&&!yi(c,i);c=c._pack_prev,d++);p?(d>v||v==d&&u.ro;o++)i=e[o],i.x-=m,i.y-=y,M=Math.max(M,i.r+Math.sqrt(i.x*i.x+i.y*i.y));n.r=M,e.forEach(bi)}}function xi(n){n._pack_next=n._pack_prev=n}function bi(n){delete n._pack_next,delete n._pack_prev}function _i(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 Ci(n,t,e){return n.a.parent===t.parent?n.a:e}function zi(n){return 1+ta.max(n,function(n){return n.y})}function qi(n){return n.reduce(function(n,t){return n+t.x},0)/n.length}function Li(n){var t=n.children;return t&&t.length?Li(t[0]):n}function Ti(n){var t,e=n.children;return e&&(t=e.length)?Ti(e[t-1]):n}function Ri(n){return{x:n.x,y:n.y,dx:n.dx,dy:n.dy}}function Di(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 Pi(n){var t=n[0],e=n[n.length-1];return e>t?[t,e]:[e,t]}function Ui(n){return n.rangeExtent?n.rangeExtent():Pi(n.range())}function ji(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 Fi(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 Hi(n){return n?{floor:function(t){return Math.floor(t/n)*n},ceil:function(t){return Math.ceil(t/n)*n}}:bl}function Oi(n,t,e,r){var u=[],i=[],o=0,a=Math.min(n.length,t.length)-1;for(n[a]2?Oi:ji,c=r?Yu:Ou;return o=u(n,t,c,e),a=u(t,n,c,mu),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(Du)},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 Xi(n,t)},i.tickFormat=function(t,e){return $i(n,t,e)},i.nice=function(t){return Zi(n,t),u()},i.copy=function(){return Yi(n,t,e,r)},u()}function Ii(n,t){return ta.rebind(n,t,"range","rangeRound","interpolate","clamp")}function Zi(n,t){return Fi(n,Hi(Vi(n,t)[2]))}function Vi(n,t){null==t&&(t=10);var e=Pi(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 Xi(n,t){return ta.range.apply(ta,Vi(n,t))}function $i(n,t,e){var r=Vi(n,t);if(e){var u=lc.exec(e);if(u.shift(),"s"===u[8]){var i=ta.formatPrefix(Math.max(va(r[0]),va(r[1])));return u[7]||(u[7]="."+Bi(i.scale(r[2]))),u[8]="f",e=ta.format(u.join("")),function(n){return e(i.scale(n))+i.symbol}}u[7]||(u[7]="."+Wi(u[8],r)),e=u.join("")}else e=",."+Bi(r[2])+"f";return ta.format(e)}function Bi(n){return-Math.floor(Math.log(n)/Math.LN10+.01)}function Wi(n,t){var e=Bi(t[2]);return n in _l?Math.abs(e-Bi(Math.max(va(t[0]),va(t[1]))))+ +("e"!==n):e-2*("%"===n)}function Ji(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=Fi(r.map(u),e?Math:Sl);return n.domain(t),r=t.map(i),o},o.ticks=function(){var n=Pi(r),o=[],a=n[0],c=n[1],l=Math.floor(u(a)),s=Math.ceil(u(c)),f=t%1?2:t;if(isFinite(s-l)){if(e){for(;s>l;l++)for(var h=1;f>h;h++)o.push(i(l)*h);o.push(i(l))}else for(o.push(i(l));l++0;h--)o.push(i(l)*h);for(l=0;o[l]c;s--);o=o.slice(l,s)}return o},o.tickFormat=function(n,t){if(!arguments.length)return wl;arguments.length<2?t=wl:"function"!=typeof t&&(t=ta.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 Ji(n.copy(),t,e,r)},Ii(o,n)}function Gi(n,t,e){function r(t){return n(u(t))}var u=Ki(t),i=Ki(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 Xi(e,n)},r.tickFormat=function(n,t){return $i(e,n,t)},r.nice=function(n){return r.domain(Zi(e,n))},r.exponent=function(o){return arguments.length?(u=Ki(t=o),i=Ki(1/t),n.domain(e.map(u)),r):t},r.copy=function(){return Gi(n.copy(),t,e)},Ii(r,n)}function Ki(n){return function(t){return 0>t?-Math.pow(-t,n):Math.pow(t,n)}}function Qi(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 ta.range(n.length).map(function(n){return t+e*n})}var u,i,o;return e.domain=function(r){if(!arguments.length)return n;n=[],u=new a;for(var i,o=-1,c=r.length;++on?[0/0,0/0]:[n>0?a[n-1]:r[0],nt?0/0:t/i+n,[t,t+1/i]},r.copy=function(){return to(n,t,e)},u()}function eo(n,t){function e(e){return e>=e?t[ta.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 eo(n,t)},e}function ro(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 Xi(n,t)},t.tickFormat=function(t,e){return $i(n,t,e)},t.copy=function(){return ro(n)},t}function uo(){return 0}function io(n){return n.innerRadius}function oo(n){return n.outerRadius}function ao(n){return n.startAngle}function co(n){return n.endAngle}function lo(n){return n&&n.padAngle}function so(n,t,e,r){return(n-e)*t-(t-r)*n>0?0:1}function fo(n,t,e,r,u){var i=n[0]-t[0],o=n[1]-t[1],a=(u?r:-r)/Math.sqrt(i*i+o*o),c=a*o,l=-a*i,s=n[0]+c,f=n[1]+l,h=t[0]+c,g=t[1]+l,p=(s+h)/2,v=(f+g)/2,d=h-s,m=g-f,y=d*d+m*m,M=e-r,x=s*g-h*f,b=(0>m?-1:1)*Math.sqrt(M*M*y-x*x),_=(x*m-d*b)/y,w=(-x*d-m*b)/y,S=(x*m+d*b)/y,k=(-x*d+m*b)/y,E=_-p,A=w-v,N=S-p,C=k-v;return E*E+A*A>N*N+C*C&&(_=S,w=k),[[_-c,w-l],[_*e/M,w*e/M]]}function ho(n){function t(t){function o(){l.push("M",i(n(s),a))}for(var c,l=[],s=[],f=-1,h=t.length,g=kt(e),p=kt(r);++f1&&u.push("H",r[0]),u.join("")}function mo(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 l=2;l9&&(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 To(n){return n.length<3?go(n):n[0]+_o(n,Lo(n))}function Ro(n){for(var t,e,r,u=-1,i=n.length;++ur)return s();var u=i[i.active];u&&(--i.count,delete i[i.active],u.event&&u.event.interrupt.call(n,n.__data__,u.index)),i.active=r,o.event&&o.event.start.call(n,n.__data__,t),o.tween.forEach(function(e,r){(r=r.call(n,n.__data__,t))&&v.push(r)}),h=o.ease,f=o.duration,ta.timer(function(){return p.c=l(e||1)?Ne:l,1},0,c)}function l(e){if(i.active!==r)return 1;for(var u=e/f,a=h(u),c=v.length;c>0;)v[--c].call(n,a);return u>=1?(o.event&&o.event.end.call(n,n.__data__,t),s()):void 0}function s(){return--i.count?delete i[r]:delete n[e],1}var f,h,g=o.delay,p=oc,v=[];return p.t=g+c,u>=g?a(u-g):(p.c=a,void 0)},0,c)}}function Bo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate("+(isFinite(r)?r:e(n))+",0)"})}function Wo(n,t,e){n.attr("transform",function(n){var r=t(n);return"translate(0,"+(isFinite(r)?r:e(n))+")"})}function Jo(n){return n.toISOString()}function Go(n,t,e){function r(t){return n(t)}function u(n,e){var r=n[1]-n[0],u=r/e,i=ta.bisect(Wl,u);return i==Wl.length?[t.year,Vi(n.map(function(n){return n/31536e6}),e)[2]]:i?t[u/Wl[i-1]1?{floor:function(t){for(;e(t=n.floor(t));)t=Ko(t-1);return t},ceil:function(t){for(;e(t=n.ceil(t));)t=Ko(+t+1);return t}}:n))},r.ticks=function(n,t){var e=Pi(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],Ko(+e[1]+1),1>t?1:t)},r.tickFormat=function(){return e},r.copy=function(){return Go(n.copy(),t,e)},Ii(r,n)}function Ko(n){return new Date(n)}function Qo(n){return JSON.parse(n.responseText)}function na(n){var t=ua.createRange();return t.selectNode(ua.body),t.createContextualFragment(n.responseText)}var ta={version:"3.5.3"};Date.now||(Date.now=function(){return+new Date});var ea=[].slice,ra=function(n){return ea.call(n)},ua=document,ia=ua.documentElement,oa=window;try{ra(ia.childNodes)[0].nodeType}catch(aa){ra=function(n){for(var t=n.length,e=new Array(t);t--;)e[t]=n[t];return e}}try{ua.createElement("div").style.setProperty("opacity",0,"")}catch(ca){var la=oa.Element.prototype,sa=la.setAttribute,fa=la.setAttributeNS,ha=oa.CSSStyleDeclaration.prototype,ga=ha.setProperty;la.setAttribute=function(n,t){sa.call(this,n,t+"")},la.setAttributeNS=function(n,t,e){fa.call(this,n,t,e+"")},ha.setProperty=function(n,t,e){ga.call(this,n,t+"",e)}}ta.ascending=n,ta.descending=function(n,t){return n>t?-1:t>n?1:t>=n?0:0/0},ta.min=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=r){e=r;break}for(;++ur&&(e=r)}else{for(;++u=r){e=r;break}for(;++ur&&(e=r)}return e},ta.max=function(n,t){var e,r,u=-1,i=n.length;if(1===arguments.length){for(;++u=r){e=r;break}for(;++ue&&(e=r)}else{for(;++u=r){e=r;break}for(;++ue&&(e=r)}return e},ta.extent=function(n,t){var e,r,u,i=-1,o=n.length;if(1===arguments.length){for(;++i=r){e=u=r;break}for(;++ir&&(e=r),r>u&&(u=r))}else{for(;++i=r){e=u=r;break}for(;++ir&&(e=r),r>u&&(u=r))}return[e,u]},ta.sum=function(n,t){var r,u=0,i=n.length,o=-1;if(1===arguments.length)for(;++o1?c/(s-1):void 0},ta.deviation=function(){var n=ta.variance.apply(this,arguments);return n?Math.sqrt(n):n};var pa=r(n);ta.bisectLeft=pa.left,ta.bisect=ta.bisectRight=pa.right,ta.bisector=function(t){return r(1===t.length?function(e,r){return n(t(e),r)}:t)},ta.shuffle=function(n,t,e){(i=arguments.length)<3&&(e=n.length,2>i&&(t=0));for(var r,u,i=e-t;i;)u=0|Math.random()*i--,r=n[i+t],n[i+t]=n[u+t],n[u+t]=r;return n},ta.permute=function(n,t){for(var e=t.length,r=new Array(e);e--;)r[e]=n[t[e]];return r},ta.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},ta.zip=function(){if(!(r=arguments.length))return[];for(var n=-1,t=ta.min(arguments,u),e=new Array(t);++n=0;)for(r=n[u],t=r.length;--t>=0;)e[--o]=r[t];return e};var va=Math.abs;ta.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,u=[],o=i(va(e)),a=-1;if(n*=o,t*=o,e*=o,0>e)for(;(r=n+e*++a)>t;)u.push(r/o);else for(;(r=n+e*++a)=i.length)return r?r.call(u,o):e?o.sort(e):o;for(var l,s,f,h,g=-1,p=o.length,v=i[c++],d=new a;++g=i.length)return n;var r=[],u=o[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=[],o=[];return u.map=function(t,e){return n(e,t,0)},u.entries=function(e){return t(n(ta.map,e,0),0)},u.key=function(n){return i.push(n),u},u.sortKeys=function(n){return o[i.length-1]=n,u},u.sortValues=function(n){return e=n,u},u.rollup=function(n){return r=n,u},u},ta.set=function(n){var t=new v;if(n)for(var e=0,r=n.length;r>e;++e)t.add(n[e]);return t},o(v,{has:s,add:function(n){return this._[c(n+="")]=!0,n},remove:f,values:h,size:g,empty:p,forEach:function(n){for(var t in this._)n.call(this,l(t))}}),ta.behavior={},ta.rebind=function(n,t){for(var e,r=1,u=arguments.length;++r=0&&(r=n.slice(e+1),n=n.slice(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}},ta.event=null,ta.requote=function(n){return n.replace(Ma,"\\$&")};var Ma=/[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g,xa={}.__proto__?function(n,t){n.__proto__=t}:function(n,t){for(var e in t)n[e]=t[e]},ba=function(n,t){return t.querySelector(n)},_a=function(n,t){return t.querySelectorAll(n)},wa=ia.matches||ia[m(ia,"matchesSelector")],Sa=function(n,t){return wa.call(n,t)};"function"==typeof Sizzle&&(ba=function(n,t){return Sizzle(n,t)[0]||null},_a=Sizzle,Sa=Sizzle.matchesSelector),ta.selection=function(){return Na};var ka=ta.selection.prototype=[];ka.select=function(n){var t,e,r,u,i=[];n=k(n);for(var o=-1,a=this.length;++o=0&&(e=n.slice(0,t),n=n.slice(t+1)),Ea.hasOwnProperty(e)?{space:Ea[e],local:n}:n}},ka.attr=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node();return n=ta.ns.qualify(n),n.local?e.getAttributeNS(n.space,n.local):e.getAttribute(n)}for(t in n)this.each(A(t,n[t]));return this}return this.each(A(n,t))},ka.classed=function(n,t){if(arguments.length<2){if("string"==typeof n){var e=this.node(),r=(n=z(n)).length,u=-1;if(t=e.classList){for(;++ur){if("string"!=typeof n){2>r&&(t="");for(e in n)this.each(T(e,n[e],t));return this}if(2>r)return oa.getComputedStyle(this.node(),null).getPropertyValue(n);e=""}return this.each(T(n,t,e))},ka.property=function(n,t){if(arguments.length<2){if("string"==typeof n)return this.node()[n];for(t in n)this.each(R(t,n[t]));return this}return this.each(R(n,t))},ka.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},ka.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},ka.append=function(n){return n=D(n),this.select(function(){return this.appendChild(n.apply(this,arguments))})},ka.insert=function(n,t){return n=D(n),t=k(t),this.select(function(){return this.insertBefore(n.apply(this,arguments),t.apply(this,arguments)||null)})},ka.remove=function(){return this.each(P)},ka.data=function(n,t){function e(n,e){var r,u,i,o=n.length,f=e.length,h=Math.min(o,f),g=new Array(f),p=new Array(f),v=new Array(o);if(t){var d,m=new a,y=new Array(o);for(r=-1;++rr;++r)p[r]=U(e[r]);for(;o>r;++r)v[r]=n[r]}p.update=g,p.parentNode=g.parentNode=v.parentNode=n.parentNode,c.push(p),l.push(g),s.push(v)}var r,u,i=-1,o=this.length;if(!arguments.length){for(n=new Array(o=(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 S(u)},ka.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},ka.sort=function(n){n=F.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},ka.size=function(){var n=0;return H(this,function(){++n}),n};var Aa=[];ta.selection.enter=O,ta.selection.enter.prototype=Aa,Aa.append=ka.append,Aa.empty=ka.empty,Aa.node=ka.node,Aa.call=ka.call,Aa.size=ka.size,Aa.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(I(e,n[e],t));return this}if(2>r)return(r=this.node()["__on"+n])&&r._;e=!1}return this.each(I(n,t,e))};var Ca=ta.map({mouseenter:"mouseover",mouseleave:"mouseout"});Ca.forEach(function(n){"on"+n in ua&&Ca.remove(n)});var za="onselectstart"in ua?null:m(ia.style,"userSelect"),qa=0;ta.mouse=function(n){return $(n,_())};var La=/WebKit/.test(oa.navigator.userAgent)?-1:0;ta.touch=function(n,t,e){if(arguments.length<3&&(e=t,t=_().changedTouches),t)for(var r,u=0,i=t.length;i>u;++u)if((r=t[u]).identifier===e)return $(n,r)},ta.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]-M[0],e=r[1]-M[1],p|=n|e,M=r,g({type:"drag",x:r[0]+l[0],y:r[1]+l[1],dx:n,dy:e}))}function c(){t(h,v)&&(m.on(i+d,null).on(o+d,null),y(p&&ta.event.target===f),g({type:"dragend"}))}var l,s=this,f=ta.event.target,h=s.parentNode,g=e.of(s,arguments),p=0,v=n(),d=".drag"+(null==v?"":"-"+v),m=ta.select(u()).on(i+d,a).on(o+d,c),y=X(),M=t(h,v);r?(l=r.apply(s,arguments),l=[l.x-M[0],l.y-M[1]]):l=[0,0],g({type:"dragstart"})}}var e=w(n,"drag","dragstart","dragend"),r=null,u=t(y,ta.mouse,J,"mousemove","mouseup"),i=t(B,ta.touch,W,"touchmove","touchend");return n.origin=function(t){return arguments.length?(r=t,n):r},ta.rebind(n,e,"on")},ta.touches=function(n,t){return arguments.length<2&&(t=_().touches),t?ra(t).map(function(t){var e=$(n,t);return e.identifier=t.identifier,e}):[]};var Ta=1e-6,Ra=Ta*Ta,Da=Math.PI,Pa=2*Da,Ua=Pa-Ta,ja=Da/2,Fa=Da/180,Ha=180/Da,Oa=Math.SQRT2,Ya=2,Ia=4;ta.interpolateZoom=function(n,t){function e(n){var t=n*y;if(m){var e=et(v),o=i/(Ya*h)*(e*rt(Oa*t+v)-tt(v));return[r+o*l,u+o*s,i*e/et(Oa*t+v)]}return[r+n*l,u+n*s,i*Math.exp(Oa*t)]}var r=n[0],u=n[1],i=n[2],o=t[0],a=t[1],c=t[2],l=o-r,s=a-u,f=l*l+s*s,h=Math.sqrt(f),g=(c*c-i*i+Ia*f)/(2*i*Ya*h),p=(c*c-i*i-Ia*f)/(2*c*Ya*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))/Oa;return e.duration=1e3*y,e},ta.behavior.zoom=function(){function n(n){n.on(z,s).on(Xa+".zoom",h).on("dblclick.zoom",g).on(T,f)}function t(n){return[(n[0]-k.x)/k.k,(n[1]-k.y)/k.k]}function e(n){return[n[0]*k.k+k.x,n[1]*k.k+k.y]}function r(n){k.k=Math.max(A[0],Math.min(A[1],n))}function u(n,t){t=e(t),k.x+=n[0]-t[0],k.y+=n[1]-t[1]}function i(t,e,i,o){t.__chart__={x:k.x,y:k.y,k:k.k},r(Math.pow(2,o)),u(v=e,i),t=ta.select(t),N>0&&(t=t.transition().duration(N)),t.call(n.event)}function o(){x&&x.domain(M.range().map(function(n){return(n-k.x)/k.k}).map(M.invert)),S&&S.domain(_.range().map(function(n){return(n-k.y)/k.k}).map(_.invert))}function a(n){C++||n({type:"zoomstart"})}function c(n){o(),n({type:"zoom",scale:k.k,translate:[k.x,k.y]})}function l(n){--C||n({type:"zoomend"}),v=null}function s(){function n(){s=1,u(ta.mouse(r),h),c(o)}function e(){f.on(q,null).on(L,null),g(s&&ta.event.target===i),l(o)}var r=this,i=ta.event.target,o=R.of(r,arguments),s=0,f=ta.select(oa).on(q,n).on(L,e),h=t(ta.mouse(r)),g=X();Fl.call(r),a(o)}function f(){function n(){var n=ta.touches(p);return g=k.k,n.forEach(function(n){n.identifier in d&&(d[n.identifier]=t(n))}),n}function e(){var t=ta.event.target;ta.select(t).on(x,o).on(_,h),w.push(t);for(var e=ta.event.changedTouches,r=0,u=e.length;u>r;++r)d[e[r].identifier]=null;var a=n(),c=Date.now();if(1===a.length){if(500>c-y){var l=a[0];i(p,l,d[l.identifier],Math.floor(Math.log(k.k)/Math.LN2)+1),b()}y=c}else if(a.length>1){var l=a[0],s=a[1],f=l[0]-s[0],g=l[1]-s[1];m=f*f+g*g}}function o(){var n,t,e,i,o=ta.touches(p);Fl.call(p);for(var a=0,l=o.length;l>a;++a,i=null)if(e=o[a],i=d[e.identifier]){if(t)break;n=e,t=i}if(i){var s=(s=e[0]-n[0])*s+(s=e[1]-n[1])*s,f=m&&Math.sqrt(s/m);n=[(n[0]+e[0])/2,(n[1]+e[1])/2],t=[(t[0]+i[0])/2,(t[1]+i[1])/2],r(f*g)}y=null,u(n,t),c(v)}function h(){if(ta.event.touches.length){for(var t=ta.event.changedTouches,e=0,r=t.length;r>e;++e)delete d[t[e].identifier];for(var u in d)return void n()}ta.selectAll(w).on(M,null),S.on(z,s).on(T,f),E(),l(v)}var g,p=this,v=R.of(p,arguments),d={},m=0,M=".zoom-"+ta.event.changedTouches[0].identifier,x="touchmove"+M,_="touchend"+M,w=[],S=ta.select(p),E=X();e(),a(v),S.on(z,null).on(T,e)}function h(){var n=R.of(this,arguments);m?clearTimeout(m):(p=t(v=d||ta.mouse(this)),Fl.call(this),a(n)),m=setTimeout(function(){m=null,l(n)},50),b(),r(Math.pow(2,.002*Za())*k.k),u(v,p),c(n)}function g(){var n=ta.mouse(this),e=Math.log(k.k)/Math.LN2;i(this,n,t(n),ta.event.shiftKey?Math.ceil(e)-1:Math.floor(e)+1)}var p,v,d,m,y,M,x,_,S,k={x:0,y:0,k:1},E=[960,500],A=Va,N=250,C=0,z="mousedown.zoom",q="mousemove.zoom",L="mouseup.zoom",T="touchstart.zoom",R=w(n,"zoomstart","zoom","zoomend");return n.event=function(n){n.each(function(){var n=R.of(this,arguments),t=k;Ul?ta.select(this).transition().each("start.zoom",function(){k=this.__chart__||{x:0,y:0,k:1},a(n)}).tween("zoom:zoom",function(){var e=E[0],r=E[1],u=v?v[0]:e/2,i=v?v[1]:r/2,o=ta.interpolateZoom([(u-k.x)/k.k,(i-k.y)/k.k,e/k.k],[(u-t.x)/t.k,(i-t.y)/t.k,e/t.k]);return function(t){var r=o(t),a=e/r[2];this.__chart__=k={x:u-r[0]*a,y:i-r[1]*a,k:a},c(n)}}).each("interrupt.zoom",function(){l(n)}).each("end.zoom",function(){l(n)}):(this.__chart__=k,a(n),c(n),l(n))})},n.translate=function(t){return arguments.length?(k={x:+t[0],y:+t[1],k:k.k},o(),n):[k.x,k.y]},n.scale=function(t){return arguments.length?(k={x:k.x,y:k.y,k:+t},o(),n):k.k},n.scaleExtent=function(t){return arguments.length?(A=null==t?Va:[+t[0],+t[1]],n):A},n.center=function(t){return arguments.length?(d=t&&[+t[0],+t[1]],n):d},n.size=function(t){return arguments.length?(E=t&&[+t[0],+t[1]],n):E},n.duration=function(t){return arguments.length?(N=+t,n):N},n.x=function(t){return arguments.length?(x=t,M=t.copy(),k={x:0,y:0,k:1},n):x},n.y=function(t){return arguments.length?(S=t,_=t.copy(),k={x:0,y:0,k:1},n):S},ta.rebind(n,R,"on")};var Za,Va=[0,1/0],Xa="onwheel"in ua?(Za=function(){return-ta.event.deltaY*(ta.event.deltaMode?120:1)},"wheel"):"onmousewheel"in ua?(Za=function(){return ta.event.wheelDelta},"mousewheel"):(Za=function(){return-ta.event.detail},"MozMousePixelScroll");ta.color=it,it.prototype.toString=function(){return this.rgb()+""},ta.hsl=ot;var $a=ot.prototype=new it;$a.brighter=function(n){return n=Math.pow(.7,arguments.length?n:1),new ot(this.h,this.s,this.l/n)},$a.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new ot(this.h,this.s,n*this.l)},$a.rgb=function(){return at(this.h,this.s,this.l)},ta.hcl=ct;var Ba=ct.prototype=new it;Ba.brighter=function(n){return new ct(this.h,this.c,Math.min(100,this.l+Wa*(arguments.length?n:1)))},Ba.darker=function(n){return new ct(this.h,this.c,Math.max(0,this.l-Wa*(arguments.length?n:1)))},Ba.rgb=function(){return lt(this.h,this.c,this.l).rgb()},ta.lab=st;var Wa=18,Ja=.95047,Ga=1,Ka=1.08883,Qa=st.prototype=new it;Qa.brighter=function(n){return new st(Math.min(100,this.l+Wa*(arguments.length?n:1)),this.a,this.b)},Qa.darker=function(n){return new st(Math.max(0,this.l-Wa*(arguments.length?n:1)),this.a,this.b)},Qa.rgb=function(){return ft(this.l,this.a,this.b)},ta.rgb=dt;var nc=dt.prototype=new it;nc.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 dt(Math.min(255,t/n),Math.min(255,e/n),Math.min(255,r/n))):new dt(u,u,u)},nc.darker=function(n){return n=Math.pow(.7,arguments.length?n:1),new dt(n*this.r,n*this.g,n*this.b)},nc.hsl=function(){return bt(this.r,this.g,this.b)},nc.toString=function(){return"#"+Mt(this.r)+Mt(this.g)+Mt(this.b)};var tc=ta.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});tc.forEach(function(n,t){tc.set(n,mt(t))}),ta.functor=kt,ta.xhr=At(Et),ta.dsv=function(n,t){function e(n,e,i){arguments.length<3&&(i=e,e=null);var o=Nt(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(s>=l)return o;if(u)return u=!1,i;var t=s;if(34===n.charCodeAt(t)){for(var e=t;e++s;){var r=n.charCodeAt(s++),a=1;if(10===r)u=!0;else if(13===r)u=!0,10===n.charCodeAt(s)&&(++s,++a);else if(r!==c)continue;return n.slice(t,s-a)}return n.slice(t)}for(var r,u,i={},o={},a=[],l=n.length,s=0,f=0;(r=e())!==o;){for(var h=[];r!==i&&r!==o;)h.push(r),r=e();t&&null==(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 v,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},ta.csv=ta.dsv(",","text/csv"),ta.tsv=ta.dsv(" ","text/tab-separated-values");var ec,rc,uc,ic,oc,ac=oa[m(oa,"requestAnimationFrame")]||function(n){setTimeout(n,17)};ta.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};rc?rc.n=i:ec=i,rc=i,uc||(ic=clearTimeout(ic),uc=1,ac(qt))},ta.timer.flush=function(){Lt(),Tt()},ta.round=function(n,t){return t?Math.round(n*(t=Math.pow(10,t)))/t:Math.round(n)};var cc=["y","z","a","f","p","n","\xb5","m","","k","M","G","T","P","E","Z","Y"].map(Dt);ta.formatPrefix=function(n,t){var e=0;return n&&(0>n&&(n*=-1),t&&(n=ta.round(n,Rt(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)))),cc[8+e/3]};var lc=/(?:([^{])?([<>=^]))?([+\- ])?([$#])?(0)?(\d+)?(,)?(\.-?\d+)?([a-z%])?/i,sc=ta.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=ta.round(n,Rt(n,t))).toFixed(Math.max(0,Math.min(20,Rt(n*(1+1e-15),t))))}}),fc=ta.time={},hc=Date;jt.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(){gc.setUTCDate.apply(this._,arguments)},setDay:function(){gc.setUTCDay.apply(this._,arguments)},setFullYear:function(){gc.setUTCFullYear.apply(this._,arguments)},setHours:function(){gc.setUTCHours.apply(this._,arguments)},setMilliseconds:function(){gc.setUTCMilliseconds.apply(this._,arguments)},setMinutes:function(){gc.setUTCMinutes.apply(this._,arguments)},setMonth:function(){gc.setUTCMonth.apply(this._,arguments)},setSeconds:function(){gc.setUTCSeconds.apply(this._,arguments)},setTime:function(){gc.setTime.apply(this._,arguments)}};var gc=Date.prototype;fc.year=Ft(function(n){return n=fc.day(n),n.setMonth(0,1),n},function(n,t){n.setFullYear(n.getFullYear()+t)},function(n){return n.getFullYear()}),fc.years=fc.year.range,fc.years.utc=fc.year.utc.range,fc.day=Ft(function(n){var t=new hc(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}),fc.days=fc.day.range,fc.days.utc=fc.day.utc.range,fc.dayOfYear=function(n){var t=fc.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=fc[n]=Ft(function(n){return(n=fc.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=fc.year(n).getDay();return Math.floor((fc.dayOfYear(n)+(e+t)%7)/7)-(e!==t)});fc[n+"s"]=e.range,fc[n+"s"].utc=e.utc.range,fc[n+"OfYear"]=function(n){var e=fc.year(n).getDay();return Math.floor((fc.dayOfYear(n)+(e+t)%7)/7)}}),fc.week=fc.sunday,fc.weeks=fc.sunday.range,fc.weeks.utc=fc.sunday.utc.range,fc.weekOfYear=fc.sundayOfYear;var pc={"-":"",_:" ",0:"0"},vc=/^\s*\d+/,dc=/^%/;ta.locale=function(n){return{numberFormat:Pt(n),timeFormat:Ot(n)}};var mc=ta.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"]});ta.format=mc.numberFormat,ta.geo={},ce.prototype={s:0,t:0,add:function(n){le(n,this.t,yc),le(yc.s,this.s,this),this.s?this.t+=yc.t:this.s=yc.t},reset:function(){this.s=this.t=0},valueOf:function(){return this.s}};var yc=new ce;ta.geo.stream=function(n,t){n&&Mc.hasOwnProperty(n.type)?Mc[n.type](n,t):se(n,t)};var Mc={Feature:function(n,t){se(n.geometry,t)},FeatureCollection:function(n,t){for(var e=n.features,r=-1,u=e.length;++rn?4*Da+n:n,wc.lineStart=wc.lineEnd=wc.point=y}};ta.geo.bounds=function(){function n(n,t){M.push(x=[s=n,h=n]),f>t&&(f=t),t>g&&(g=t)}function t(t,e){var r=pe([t*Fa,e*Fa]);if(m){var u=de(m,r),i=[u[1],-u[0],0],o=de(i,u);Me(o),o=xe(o);var c=t-p,l=c>0?1:-1,v=o[0]*Ha*l,d=va(c)>180;if(d^(v>l*p&&l*t>v)){var y=o[1]*Ha;y>g&&(g=y)}else if(v=(v+360)%360-180,d^(v>l*p&&l*t>v)){var y=-o[1]*Ha;f>y&&(f=y)}else f>e&&(f=e),e>g&&(g=e);d?p>t?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t):h>=s?(s>t&&(s=t),t>h&&(h=t)):t>p?a(s,t)>a(s,h)&&(h=t):a(t,h)>a(s,h)&&(s=t)}else n(t,e);m=r,p=t}function e(){b.point=t}function r(){x[0]=s,x[1]=h,b.point=n,m=null}function u(n,e){if(m){var r=n-p;y+=va(r)>180?r+(r>0?360:-360):r}else v=n,d=e;wc.point(n,e),t(n,e)}function i(){wc.lineStart()}function o(){u(v,d),wc.lineEnd(),va(y)>Ta&&(s=-(h=180)),x[0]=s,x[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 l(n,t){return t[0]<=t[1]?t[0]<=n&&n<=t[1]:n_c?(s=-(h=180),f=-(g=90)):y>Ta?g=90:-Ta>y&&(f=-90),x[0]=s,x[1]=h}};return function(n){g=h=-(s=f=1/0),M=[],ta.geo.stream(n,b);var t=M.length;if(t){M.sort(c);for(var e,r=1,u=M[0],i=[u];t>r;++r)e=M[r],l(e[0],u)||l(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,s=e[0],h=u[1])}return M=x=null,1/0===s||1/0===f?[[0/0,0/0],[0/0,0/0]]:[[s,f],[h,g]]}}(),ta.geo.centroid=function(n){Sc=kc=Ec=Ac=Nc=Cc=zc=qc=Lc=Tc=Rc=0,ta.geo.stream(n,Dc);var t=Lc,e=Tc,r=Rc,u=t*t+e*e+r*r;return Ra>u&&(t=Cc,e=zc,r=qc,Ta>kc&&(t=Ec,e=Ac,r=Nc),u=t*t+e*e+r*r,Ra>u)?[0/0,0/0]:[Math.atan2(e,t)*Ha,nt(r/Math.sqrt(u))*Ha]};var Sc,kc,Ec,Ac,Nc,Cc,zc,qc,Lc,Tc,Rc,Dc={sphere:y,point:_e,lineStart:Se,lineEnd:ke,polygonStart:function(){Dc.lineStart=Ee},polygonEnd:function(){Dc.lineStart=Se}},Pc=Le(Ne,Pe,je,[-Da,-Da/2]),Uc=1e9;ta.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=Ye(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]])},(ta.geo.conicEqualArea=function(){return Ie(Ze)}).raw=Ze,ta.geo.albers=function(){return ta.geo.conicEqualArea().rotate([96,0]).center([-.6,38.7]).parallels([29.5,45.5]).scale(1070)},ta.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=ta.geo.albers(),o=ta.geo.conicEqualArea().rotate([154,0]).center([-2,58.5]).parallels([55,65]),a=ta.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 l=i.scale(),s=+t[0],f=+t[1];return e=i.translate(t).clipExtent([[s-.455*l,f-.238*l],[s+.455*l,f+.238*l]]).stream(c).point,r=o.translate([s-.307*l,f+.201*l]).clipExtent([[s-.425*l+Ta,f+.12*l+Ta],[s-.214*l-Ta,f+.234*l-Ta]]).stream(c).point,u=a.translate([s-.205*l,f+.212*l]).clipExtent([[s-.214*l+Ta,f+.166*l+Ta],[s-.115*l-Ta,f+.234*l-Ta]]).stream(c).point,n},n.scale(1070)};var jc,Fc,Hc,Oc,Yc,Ic,Zc={point:y,lineStart:y,lineEnd:y,polygonStart:function(){Fc=0,Zc.lineStart=Ve},polygonEnd:function(){Zc.lineStart=Zc.lineEnd=Zc.point=y,jc+=va(Fc/2)}},Vc={point:Xe,lineStart:y,lineEnd:y,polygonStart:y,polygonEnd:y},Xc={point:We,lineStart:Je,lineEnd:Ge,polygonStart:function(){Xc.lineStart=Ke},polygonEnd:function(){Xc.point=We,Xc.lineStart=Je,Xc.lineEnd=Ge}};ta.geo.path=function(){function n(n){return n&&("function"==typeof a&&i.pointRadius(+a.apply(this,arguments)),o&&o.valid||(o=u(i)),ta.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 jc=0,ta.geo.stream(n,u(Zc)),jc},n.centroid=function(n){return Ec=Ac=Nc=Cc=zc=qc=Lc=Tc=Rc=0,ta.geo.stream(n,u(Xc)),Rc?[Lc/Rc,Tc/Rc]:qc?[Cc/qc,zc/qc]:Nc?[Ec/Nc,Ac/Nc]:[0/0,0/0]},n.bounds=function(n){return Yc=Ic=-(Hc=Oc=1/0),ta.geo.stream(n,u(Vc)),[[Hc,Oc],[Yc,Ic]]},n.projection=function(n){return arguments.length?(u=(e=n)?n.stream||tr(n):Et,t()):e},n.context=function(n){return arguments.length?(i=null==(r=n)?new $e:new Qe(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(ta.geo.albersUsa()).context(null)},ta.geo.transform=function(n){return{stream:function(t){var e=new er(t);for(var r in n)e[r]=n[r];return e}}},er.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()}},ta.geo.projection=ur,ta.geo.projectionMutator=ir,(ta.geo.equirectangular=function(){return ur(ar)}).raw=ar.invert=ar,ta.geo.rotation=function(n){function t(t){return t=n(t[0]*Fa,t[1]*Fa),t[0]*=Ha,t[1]*=Ha,t}return n=lr(n[0]%360*Fa,n[1]*Fa,n.length>2?n[2]*Fa:0),t.invert=function(t){return t=n.invert(t[0]*Fa,t[1]*Fa),t[0]*=Ha,t[1]*=Ha,t},t},cr.invert=ar,ta.geo.circle=function(){function n(){var n="function"==typeof r?r.apply(this,arguments):r,t=lr(-n[0]*Fa,-n[1]*Fa,0).invert,u=[];return e(null,null,1,{point:function(n,e){u.push(n=t(n,e)),n[0]*=Ha,n[1]*=Ha}}),{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=gr((t=+r)*Fa,u*Fa),n):t},n.precision=function(r){return arguments.length?(e=gr(t*Fa,(u=+r)*Fa),n):u},n.angle(90)},ta.geo.distance=function(n,t){var e,r=(t[0]-n[0])*Fa,u=n[1]*Fa,i=t[1]*Fa,o=Math.sin(r),a=Math.cos(r),c=Math.sin(u),l=Math.cos(u),s=Math.sin(i),f=Math.cos(i);return Math.atan2(Math.sqrt((e=f*o)*e+(e=l*s-c*f*a)*e),c*s+l*f*a)},ta.geo.graticule=function(){function n(){return{type:"MultiLineString",coordinates:t()}}function t(){return ta.range(Math.ceil(i/d)*d,u,d).map(h).concat(ta.range(Math.ceil(l/m)*m,c,m).map(g)).concat(ta.range(Math.ceil(r/p)*p,e,p).filter(function(n){return va(n%d)>Ta}).map(s)).concat(ta.range(Math.ceil(a/v)*v,o,v).filter(function(n){return va(n%m)>Ta}).map(f))}var e,r,u,i,o,a,c,l,s,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(l).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],l=+t[0][1],c=+t[1][1],i>u&&(t=i,i=u,u=t),l>c&&(t=l,l=c,c=t),n.precision(y)):[[i,l],[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,s=vr(a,o,90),f=dr(r,e,y),h=vr(l,c,90),g=dr(i,u,y),n):y},n.majorExtent([[-180,-90+Ta],[180,90-Ta]]).minorExtent([[-180,-80-Ta],[180,80+Ta]])},ta.geo.greatArc=function(){function n(){return{type:"LineString",coordinates:[t||r.apply(this,arguments),e||u.apply(this,arguments)]}}var t,e,r=mr,u=yr;return n.distance=function(){return ta.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},ta.geo.interpolate=function(n,t){return Mr(n[0]*Fa,n[1]*Fa,t[0]*Fa,t[1]*Fa)},ta.geo.length=function(n){return $c=0,ta.geo.stream(n,Bc),$c};var $c,Bc={sphere:y,point:y,lineStart:xr,lineEnd:y,polygonStart:y,polygonEnd:y},Wc=br(function(n){return Math.sqrt(2/(1+n))},function(n){return 2*Math.asin(n/2)});(ta.geo.azimuthalEqualArea=function(){return ur(Wc)}).raw=Wc;var Jc=br(function(n){var t=Math.acos(n);return t&&t/Math.sin(t)},Et);(ta.geo.azimuthalEquidistant=function(){return ur(Jc)}).raw=Jc,(ta.geo.conicConformal=function(){return Ie(_r)}).raw=_r,(ta.geo.conicEquidistant=function(){return Ie(wr)}).raw=wr;var Gc=br(function(n){return 1/n},Math.atan);(ta.geo.gnomonic=function(){return ur(Gc)}).raw=Gc,Sr.invert=function(n,t){return[n,2*Math.atan(Math.exp(t))-ja]},(ta.geo.mercator=function(){return kr(Sr)}).raw=Sr;var Kc=br(function(){return 1},Math.asin);(ta.geo.orthographic=function(){return ur(Kc)}).raw=Kc;var Qc=br(function(n){return 1/(1+n)},function(n){return 2*Math.atan(n)});(ta.geo.stereographic=function(){return ur(Qc)}).raw=Qc,Er.invert=function(n,t){return[-t,2*Math.atan(Math.exp(n))-ja]},(ta.geo.transverseMercator=function(){var n=kr(Er),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=Er,ta.geom={},ta.geom.hull=function(n){function t(n){if(n.length<3)return[];var t,u=kt(e),i=kt(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(zr),t=0;o>t;t++)c.push([a[t][0],-a[t][1]]);var l=Cr(a),s=Cr(c),f=s[0]===l[0],h=s[s.length-1]===l[l.length-1],g=[];for(t=l.length-1;t>=0;--t)g.push(n[a[l[t]][2]]);for(t=+f;t=r&&l.x<=i&&l.y>=u&&l.y<=o?[[r,o],[i,o],[i,u],[r,u]]:[];s.point=n[a]}),t}function e(n){return n.map(function(n,t){return{x:Math.round(i(n,t)/Ta)*Ta,y:Math.round(o(n,t)/Ta)*Ta,i:t}})}var r=Ar,u=Nr,i=r,o=u,a=cl;return n?t(n):(t.links=function(n){return iu(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 iu(e(n)).cells.forEach(function(e,r){for(var u,i,o=e.site,a=e.edges.sort(Ir),c=-1,l=a.length,s=a[l-1].edge,f=s.l===o?s.r:s.l;++c=l,h=r>=s,g=h<<1|f;n.leaf=!1,n=n.nodes[g]||(n.nodes[g]=su()),f?u=l:a=l,h?o=s:c=s,i(n,t,e,r,u,o,a,c)}var s,f,h,g,p,v,d,m,y,M=kt(a),x=kt(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)s=n[g],s.xm&&(m=s.x),s.y>y&&(y=s.y),f.push(s.x),h.push(s.y);else for(g=0;p>g;++g){var b=+M(s=n[g],g),_=+x(s,g);v>b&&(v=b),d>_&&(d=_),b>m&&(m=b),_>y&&(y=_),f.push(b),h.push(_)}var w=m-v,S=y-d;w>S?y=d+w:m=v+S;var k=su();if(k.add=function(n){i(k,n,+M(n,++g),+x(n,g),v,d,m,y)},k.visit=function(n){fu(n,k,v,d,m,y)},k.find=function(n){return hu(k,n[0],n[1],v,d,m,y)},g=-1,null==t){for(;++g=0?n.slice(0,t):n,r=t>=0?n.slice(t+1):"in";return e=hl.get(e)||fl,r=gl.get(r)||Et,Mu(r(e.apply(null,ea.call(arguments,1))))},ta.interpolateHcl=Lu,ta.interpolateHsl=Tu,ta.interpolateLab=Ru,ta.interpolateRound=Du,ta.transform=function(n){var t=ua.createElementNS(ta.ns.prefix.svg,"g");return(ta.transform=function(n){if(null!=n){t.setAttribute("transform",n);var e=t.transform.baseVal.consolidate()}return new Pu(e?e.matrix:pl)})(n)},Pu.prototype.toString=function(){return"translate("+this.translate+")rotate("+this.rotate+")skewX("+this.skew+")scale("+this.scale+")"};var pl={a:1,b:0,c:0,d:1,e:0,f:0};ta.interpolateTransform=Hu,ta.layout={},ta.layout.bundle=function(){return function(n){for(var t=[],e=-1,r=n.length;++ea*a/d){if(p>c){var l=t.charge/c;n.px-=i*l,n.py-=o*l}return!0}if(t.point&&c&&p>c){var l=t.pointCharge/c;n.px-=i*l,n.py-=o*l}}return!t.charge}}function t(n){n.px=ta.event.x,n.py=ta.event.y,a.resume()}var e,r,u,i,o,a={},c=ta.dispatch("start","tick","end"),l=[1,1],s=.9,f=vl,h=dl,g=-30,p=ml,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,M,x,b=m.length,_=y.length;for(e=0;_>e;++e)a=y[e],f=a.source,h=a.target,M=h.x-f.x,x=h.y-f.y,(p=M*M+x*x)&&(p=r*i[e]*((p=Math.sqrt(p))-u[e])/p,M*=p,x*=p,h.x-=M*(d=f.weight/(h.weight+f.weight)),h.y-=x*d,f.x+=M*(d=1-d),f.y+=x*d);if((d=r*v)&&(M=l[0]/2,x=l[1]/2,e=-1,d))for(;++e0?n:0:n>0&&(c.start({type:"start",alpha:r=n}),ta.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;l>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,l=o.length;++at;++t)(r=m[t]).index=t,r.weight=0;for(t=0;s>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;s>t;++t)u[t]=+f.call(this,y[t],t);else for(t=0;s>t;++t)u[t]=f;if(i=[],"function"==typeof h)for(t=0;s>t;++t)i[t]=+h.call(this,y[t],t);else for(t=0;s>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=ta.behavior.drag().origin(Et).on("dragstart.force",Xu).on("drag.force",t).on("dragend.force",$u)),arguments.length?(this.on("mouseover.force",Bu).on("mouseout.force",Wu).call(e),void 0):e},ta.rebind(a,c,"on")};var vl=20,dl=1,ml=1/0;ta.layout.hierarchy=function(){function n(u){var i,o=[u],a=[];for(u.depth=0;null!=(i=o.pop());)if(a.push(i),(l=e.call(n,i,i.depth))&&(c=l.length)){for(var c,l,s;--c>=0;)o.push(s=l[c]),s.parent=i,s.depth=i.depth+1;r&&(i.value=0),i.children=l}else r&&(i.value=+r.call(n,i,i.depth)||0),delete i.children;return Qu(u,function(n){var e,u;t&&(e=n.children)&&e.sort(t),r&&(u=n.parent)&&(u.value+=n.value)}),a}var t=ei,e=ni,r=ti;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&&(Ku(t,function(n){n.children&&(n.value=0)}),Qu(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},ta.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,l=-1;for(r=t.value?r/t.value:0;++lf?-1:1),p=(f-c*g)/ta.sum(l),v=ta.range(c),d=[];return null!=e&&v.sort(e===yl?function(n,t){return l[t]-l[n]}:function(n,t){return e(o[n],o[t])}),v.forEach(function(n){d[n]={data:o[n],value:a=l[n],startAngle:s,endAngle:s+=a*p+g,padAngle:h}}),d}var t=Number,e=yl,r=0,u=Pa,i=0;return n.value=function(e){return arguments.length?(t=e,n):t},n.sort=function(t){return arguments.length?(e=t,n):e},n.startAngle=function(t){return arguments.length?(r=t,n):r},n.endAngle=function(t){return arguments.length?(u=t,n):u},n.padAngle=function(t){return arguments.length?(i=t,n):i},n};var yl={};ta.layout.stack=function(){function n(a,c){if(!(h=a.length))return a;var l=a.map(function(e,r){return t.call(n,e,r)}),s=l.map(function(t){return t.map(function(t,e){return[i.call(n,t,e),o.call(n,t,e)]})}),f=e.call(n,s,c);l=ta.permute(l,f),s=ta.permute(s,f);var h,g,p,v,d=r.call(n,s,c),m=l[0].length;for(p=0;m>p;++p)for(u.call(n,l[0][p],v=d[p],s[0][p][1]),g=1;h>g;++g)u.call(n,l[g][p],v+=s[g-1][p][1],s[g][p][1]);return a}var t=Et,e=ai,r=ci,u=oi,i=ui,o=ii;return n.values=function(e){return arguments.length?(t=e,n):t},n.order=function(t){return arguments.length?(e="function"==typeof t?t:Ml.get(t)||ai,n):e},n.offset=function(t){return arguments.length?(r="function"==typeof t?t:xl.get(t)||ci,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 Ml=ta.map({"inside-out":function(n){var t,e,r=n.length,u=n.map(li),i=n.map(si),o=ta.range(r).sort(function(n,t){return u[n]-u[t]}),a=0,c=0,l=[],s=[];for(t=0;r>t;++t)e=o[t],c>a?(a+=i[e],l.push(e)):(c+=i[e],s.push(e));return s.reverse().concat(l)},reverse:function(n){return ta.range(n.length).reverse()},"default":ai}),xl=ta.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,l,s=n.length,f=n[0],h=f.length,g=[];for(g[0]=c=l=0,e=1;h>e;++e){for(t=0,u=0;s>t;++t)u+=n[t][e][1];for(t=0,i=0,a=f[e][0]-f[e-1][0];s>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,l>c&&(l=c)}for(e=0;h>e;++e)g[e]-=l;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:ci});ta.layout.histogram=function(){function n(n,i){for(var o,a,c=[],l=n.map(e,this),s=r.call(this,l,i),f=u.call(this,s,l,i),i=-1,h=l.length,g=f.length-1,p=t?1:1/h;++i0)for(i=-1;++i=s[0]&&a<=s[1]&&(o=c[ta.bisect(f,a,1,g)-1],o.y+=p,o.push(n[i]));return c}var t=!0,e=Number,r=pi,u=hi;return n.value=function(t){return arguments.length?(e=t,n):e},n.range=function(t){return arguments.length?(r=kt(t),n):r},n.bins=function(t){return arguments.length?(u="number"==typeof t?function(n){return gi(n,t)}:kt(t),n):u},n.frequency=function(e){return arguments.length?(t=!!e,n):t},n},ta.layout.pack=function(){function n(n,i){var o=e.call(this,n,i),a=o[0],c=u[0],l=u[1],s=null==t?Math.sqrt:"function"==typeof t?t:function(){return t};if(a.x=a.y=0,Qu(a,function(n){n.r=+s(n.value)}),Qu(a,Mi),r){var f=r*(t?1:Math.max(2*a.r/c,2*a.r/l))/2;Qu(a,function(n){n.r+=f}),Qu(a,Mi),Qu(a,function(n){n.r-=f})}return _i(a,c/2,l/2,t?1:1/Math.max(2*a.r/c,2*a.r/l)),o}var t,e=ta.layout.hierarchy().sort(vi),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},Gu(n,e)},ta.layout.tree=function(){function n(n,u){var s=o.call(this,n,u),f=s[0],h=t(f);if(Qu(h,e),h.parent.m=-h.z,Ku(h,r),l)Ku(f,i);else{var g=f,p=f,v=f;Ku(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);Ku(f,function(n){n.x=(n.x+d)*m,n.y=n.depth*y})}return s}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){Ni(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],l=u.m,s=i.m,f=o.m,h=c.m;o=Ei(o),u=ki(u),o&&u;)c=ki(c),i=Ei(i),i.a=n,r=o.z+f-u.z-l+a(o._,u._),r>0&&(Ai(Ci(o,n,e),n,r),l+=r,s+=r),f+=o.m,l+=u.m,h+=c.m,s+=i.m;o&&!Ei(i)&&(i.t=o,i.m+=f-s),u&&!ki(c)&&(c.t=u,c.m+=l-h,e=n)}return e}function i(n){n.x*=c[0],n.y=n.depth*c[1]}var o=ta.layout.hierarchy().sort(null).value(null),a=Si,c=[1,1],l=null;return n.separation=function(t){return arguments.length?(a=t,n):a},n.size=function(t){return arguments.length?(l=null==(c=t)?i:null,n):l?null:c},n.nodeSize=function(t){return arguments.length?(l=null==(c=t)?null:i,n):l?c:null},Gu(n,o)},ta.layout.cluster=function(){function n(n,i){var o,a=t.call(this,n,i),c=a[0],l=0;Qu(c,function(n){var t=n.children;t&&t.length?(n.x=qi(t),n.y=zi(t)):(n.x=o?l+=e(n,o):0,n.y=0,o=n)});var s=Li(c),f=Ti(c),h=s.x-e(s,f)/2,g=f.x+e(f,s)/2;return Qu(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=ta.layout.hierarchy().sort(null).value(null),e=Si,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},Gu(n,t)},ta.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,l=f(e),s=[],h=i.slice(),p=1/0,v="slice"===g?l.dx:"dice"===g?l.dy:"slice-dice"===g?1&e.depth?l.dy:l.dx:Math.min(l.dx,l.dy);for(n(h,l.dx*l.dy/e.value),s.area=0;(c=h.length)>0;)s.push(o=h[c-1]),s.area+=o.area,"squarify"!==g||(a=r(s,v))<=p?(h.pop(),p=a):(s.area-=s.pop().area,u(s,v,l,!1),v=Math.min(l.dx,l.dy),s.length=s.area=0,p=1/0);s.length&&(u(s,v,l,!0),s.length=s.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,l=e.y,s=t?c(n.area/t):0;if(t==e.dx){for((r||s>e.dy)&&(s=e.dy);++ie.dx)&&(s=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=ta.random.normal.apply(ta,arguments);return function(){return Math.exp(n())}},bates:function(n){var t=ta.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}}},ta.scale={};var bl={floor:Et,ceil:Et};ta.scale.linear=function(){return Yi([0,1],[0,1],mu,!1)};var _l={s:1,g:1,p:1,r:1,e:1};ta.scale.log=function(){return Ji(ta.scale.linear().domain([0,1]),10,!0,[1,10])};var wl=ta.format(".0e"),Sl={floor:function(n){return-Math.ceil(-n)},ceil:function(n){return-Math.floor(-n)}};ta.scale.pow=function(){return Gi(ta.scale.linear(),1,[0,1])},ta.scale.sqrt=function(){return ta.scale.pow().exponent(.5)},ta.scale.ordinal=function(){return Qi([],{t:"range",a:[[]]})},ta.scale.category10=function(){return ta.scale.ordinal().range(kl)},ta.scale.category20=function(){return ta.scale.ordinal().range(El)},ta.scale.category20b=function(){return ta.scale.ordinal().range(Al)},ta.scale.category20c=function(){return ta.scale.ordinal().range(Nl)};var kl=[2062260,16744206,2924588,14034728,9725885,9197131,14907330,8355711,12369186,1556175].map(yt),El=[2062260,11454440,16744206,16759672,2924588,10018698,14034728,16750742,9725885,12955861,9197131,12885140,14907330,16234194,8355711,13092807,12369186,14408589,1556175,10410725].map(yt),Al=[3750777,5395619,7040719,10264286,6519097,9216594,11915115,13556636,9202993,12426809,15186514,15190932,8666169,11356490,14049643,15177372,8077683,10834324,13528509,14589654].map(yt),Nl=[3244733,7057110,10406625,13032431,15095053,16616764,16625259,16634018,3253076,7652470,10607003,13101504,7695281,10394312,12369372,14342891,6513507,9868950,12434877,14277081].map(yt);ta.scale.quantile=function(){return no([],[])},ta.scale.quantize=function(){return to(0,1,[0,1])},ta.scale.threshold=function(){return eo([.5],[0,1])},ta.scale.identity=function(){return ro([0,1])},ta.svg={},ta.svg.arc=function(){function n(){var n=Math.max(0,+e.apply(this,arguments)),l=Math.max(0,+r.apply(this,arguments)),s=o.apply(this,arguments)-ja,f=a.apply(this,arguments)-ja,h=Math.abs(f-s),g=s>f?0:1;if(n>l&&(p=l,l=n,n=p),h>=Ua)return t(l,g)+(n?t(n,1-g):"")+"Z";var p,v,d,m,y,M,x,b,_,w,S,k,E=0,A=0,N=[];if((m=(+c.apply(this,arguments)||0)/2)&&(d=i===Cl?Math.sqrt(n*n+l*l):+i.apply(this,arguments),g||(A*=-1),l&&(A=nt(d/l*Math.sin(m))),n&&(E=nt(d/n*Math.sin(m)))),l){y=l*Math.cos(s+A),M=l*Math.sin(s+A),x=l*Math.cos(f-A),b=l*Math.sin(f-A);var C=Math.abs(f-s-2*A)<=Da?0:1;if(A&&so(y,M,x,b)===g^C){var z=(s+f)/2;y=l*Math.cos(z),M=l*Math.sin(z),x=b=null}}else y=M=0;if(n){_=n*Math.cos(f-E),w=n*Math.sin(f-E),S=n*Math.cos(s+E),k=n*Math.sin(s+E);var q=Math.abs(s-f+2*E)<=Da?0:1;if(E&&so(_,w,S,k)===1-g^q){var L=(s+f)/2;_=n*Math.cos(L),w=n*Math.sin(L),S=k=null}}else _=w=0;if((p=Math.min(Math.abs(l-n)/2,+u.apply(this,arguments)))>.001){v=l>n^g?0:1;var T=null==S?[_,w]:null==x?[y,M]:Lr([y,M],[S,k],[x,b],[_,w]),R=y-T[0],D=M-T[1],P=x-T[0],U=b-T[1],j=1/Math.sin(Math.acos((R*P+D*U)/(Math.sqrt(R*R+D*D)*Math.sqrt(P*P+U*U)))/2),F=Math.sqrt(T[0]*T[0]+T[1]*T[1]);if(null!=x){var H=Math.min(p,(l-F)/(j+1)),O=fo(null==S?[_,w]:[S,k],[y,M],l,H,g),Y=fo([x,b],[_,w],l,H,g);p===H?N.push("M",O[0],"A",H,",",H," 0 0,",v," ",O[1],"A",l,",",l," 0 ",1-g^so(O[1][0],O[1][1],Y[1][0],Y[1][1]),",",g," ",Y[1],"A",H,",",H," 0 0,",v," ",Y[0]):N.push("M",O[0],"A",H,",",H," 0 1,",v," ",Y[0])}else N.push("M",y,",",M);if(null!=S){var I=Math.min(p,(n-F)/(j-1)),Z=fo([y,M],[S,k],n,-I,g),V=fo([_,w],null==x?[y,M]:[x,b],n,-I,g);p===I?N.push("L",V[0],"A",I,",",I," 0 0,",v," ",V[1],"A",n,",",n," 0 ",g^so(V[1][0],V[1][1],Z[1][0],Z[1][1]),",",1-g," ",Z[1],"A",I,",",I," 0 0,",v," ",Z[0]):N.push("L",V[0],"A",I,",",I," 0 0,",v," ",Z[0])}else N.push("L",_,",",w)}else N.push("M",y,",",M),null!=x&&N.push("A",l,",",l," 0 ",C,",",g," ",x,",",b),N.push("L",_,",",w),null!=S&&N.push("A",n,",",n," 0 ",q,",",1-g," ",S,",",k);return N.push("Z"),N.join("")}function t(n,t){return"M0,"+n+"A"+n+","+n+" 0 1,"+t+" 0,"+-n+"A"+n+","+n+" 0 1,"+t+" 0,"+n}var e=io,r=oo,u=uo,i=Cl,o=ao,a=co,c=lo;return n.innerRadius=function(t){return arguments.length?(e=kt(t),n):e},n.outerRadius=function(t){return arguments.length?(r=kt(t),n):r},n.cornerRadius=function(t){return arguments.length?(u=kt(t),n):u},n.padRadius=function(t){return arguments.length?(i=t==Cl?Cl:kt(t),n):i},n.startAngle=function(t){return arguments.length?(o=kt(t),n):o},n.endAngle=function(t){return arguments.length?(a=kt(t),n):a},n.padAngle=function(t){return arguments.length?(c=kt(t),n):c},n.centroid=function(){var n=(+e.apply(this,arguments)+ +r.apply(this,arguments))/2,t=(+o.apply(this,arguments)+ +a.apply(this,arguments))/2-ja;return[Math.cos(t)*n,Math.sin(t)*n]},n};var Cl="auto";ta.svg.line=function(){return ho(Et)};var zl=ta.map({linear:go,"linear-closed":po,step:vo,"step-before":mo,"step-after":yo,basis:So,"basis-open":ko,"basis-closed":Eo,bundle:Ao,cardinal:bo,"cardinal-open":Mo,"cardinal-closed":xo,monotone:To});zl.forEach(function(n,t){t.key=n,t.closed=/-closed$/.test(n)});var ql=[0,2/3,1/3,0],Ll=[0,1/3,2/3,0],Tl=[0,1/6,2/3,1/6];ta.svg.line.radial=function(){var n=ho(Ro);return n.radius=n.x,delete n.x,n.angle=n.y,delete n.y,n},mo.reverse=yo,yo.reverse=mo,ta.svg.area=function(){return Do(Et)},ta.svg.area.radial=function(){var n=Do(Ro);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},ta.svg.chord=function(){function n(n,a){var c=t(this,i,n,a),l=t(this,o,n,a);return"M"+c.p0+r(c.r,c.p1,c.a1-c.a0)+(e(c,l)?u(c.r,c.p1,c.r,c.p0):u(c.r,c.p1,l.r,l.p0)+r(l.r,l.p1,l.a1-l.a0)+u(l.r,l.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)-ja,s=l.call(n,u,r)-ja;return{r:i,a0:o,a1:s,p0:[i*Math.cos(o),i*Math.sin(o)],p1:[i*Math.cos(s),i*Math.sin(s)]}}function e(n,t){return n.a0==t.a0&&n.a1==t.a1}function r(n,t,e){return"A"+n+","+n+" 0 "+ +(e>Da)+",1 "+t}function u(n,t,e,r){return"Q 0,0 "+r}var i=mr,o=yr,a=Po,c=ao,l=co;return n.radius=function(t){return arguments.length?(a=kt(t),n):a},n.source=function(t){return arguments.length?(i=kt(t),n):i},n.target=function(t){return arguments.length?(o=kt(t),n):o},n.startAngle=function(t){return arguments.length?(c=kt(t),n):c},n.endAngle=function(t){return arguments.length?(l=kt(t),n):l},n},ta.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=mr,e=yr,r=Uo;return n.source=function(e){return arguments.length?(t=kt(e),n):t},n.target=function(t){return arguments.length?(e=kt(t),n):e},n.projection=function(t){return arguments.length?(r=t,n):r},n},ta.svg.diagonal.radial=function(){var n=ta.svg.diagonal(),t=Uo,e=n.projection;return n.projection=function(n){return arguments.length?e(jo(t=n)):t},n},ta.svg.symbol=function(){function n(n,r){return(Rl.get(t.call(this,n,r))||Oo)(e.call(this,n,r))}var t=Ho,e=Fo;return n.type=function(e){return arguments.length?(t=kt(e),n):t},n.size=function(t){return arguments.length?(e=kt(t),n):e},n};var Rl=ta.map({circle:Oo,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*Pl)),e=t*Pl;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/Dl),e=t*Dl/2;return"M0,"+e+"L"+t+","+-e+" "+-t+","+-e+"Z"},"triangle-up":function(n){var t=Math.sqrt(n/Dl),e=t*Dl/2;return"M0,"+-e+"L"+t+","+e+" "+-t+","+e+"Z"}});ta.svg.symbolTypes=Rl.keys();var Dl=Math.sqrt(3),Pl=Math.tan(30*Fa);ka.transition=function(n){for(var t,e,r=Ul||++Ol,u=Xo(n),i=[],o=jl||{time:Date.now(),ease:Su,delay:0,duration:250},a=-1,c=this.length;++ai;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 Io(u,this.namespace,this.id)},Hl.tween=function(n,t){var e=this.id,r=this.namespace;return arguments.length<2?this.node()[r][e].tween.get(n):H(this,null==t?function(t){t[r][e].tween.remove(n)}:function(u){u[r][e].tween.set(n,t)})},Hl.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?Hu:mu,a=ta.ns.qualify(n);return Zo(this,"attr."+n,t,a.local?i:u)},Hl.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=ta.ns.qualify(n);return this.tween("attr."+n,u.local?r:e)},Hl.style=function(n,t,e){function r(){this.style.removeProperty(n)}function u(t){return null==t?r:(t+="",function(){var r,u=oa.getComputedStyle(this,null).getPropertyValue(n);return u!==t&&(r=mu(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 Zo(this,"style."+n,t,u)},Hl.styleTween=function(n,t,e){function r(r,u){var i=t.call(this,r,u,oa.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)},Hl.text=function(n){return Zo(this,"text",n,Vo)},Hl.remove=function(){var n=this.namespace;return this.each("end.transition",function(){var t;this[n].count<2&&(t=this.parentNode)&&t.removeChild(this)})},Hl.ease=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].ease:("function"!=typeof n&&(n=ta.ease.apply(ta,arguments)),H(this,function(r){r[e][t].ease=n}))},Hl.delay=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].delay:H(this,"function"==typeof n?function(r,u,i){r[e][t].delay=+n.call(r,r.__data__,u,i)}:(n=+n,function(r){r[e][t].delay=n}))},Hl.duration=function(n){var t=this.id,e=this.namespace;return arguments.length<1?this.node()[e][t].duration:H(this,"function"==typeof n?function(r,u,i){r[e][t].duration=Math.max(1,n.call(r,r.__data__,u,i))}:(n=Math.max(1,n),function(r){r[e][t].duration=n}))},Hl.each=function(n,t){var e=this.id,r=this.namespace;if(arguments.length<2){var u=jl,i=Ul;try{Ul=e,H(this,function(t,u,i){jl=t[r][e],n.call(t,t.__data__,u,i)})}finally{jl=u,Ul=i}}else H(this,function(u){var i=u[r][e];(i.event||(i.event=ta.dispatch("start","end","interrupt"))).on(n,t)});return this},Hl.transition=function(){for(var n,t,e,r,u=this.id,i=++Ol,o=this.namespace,a=[],c=0,l=this.length;l>c;c++){a.push(n=[]);for(var t=this[c],s=0,f=t.length;f>s;s++)(e=t[s])&&(r=e[o][u],$o(e,s,o,i,{time:r.time,ease:r.ease,delay:r.delay+r.duration,duration:r.duration})),n.push(e)}return Io(a,o,i)},ta.svg.axis=function(){function n(n){n.each(function(){var n,l=ta.select(this),s=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):Et:t,p=l.selectAll(".tick").data(h,f),v=p.enter().insert("g",".domain").attr("class","tick").style("opacity",Ta),d=ta.transition(p.exit()).style("opacity",Ta).remove(),m=ta.transition(p.order()).style("opacity",1),y=Math.max(u,0)+o,M=Ui(f),x=l.selectAll(".domain").data([0]),b=(x.enter().append("path").attr("class","domain"),ta.transition(x));v.append("line"),v.append("text");var _,w,S,k,E=v.select("line"),A=m.select("line"),N=p.select("text").text(g),C=v.select("text"),z=m.select("text"),q="top"===r||"left"===r?-1:1;if("bottom"===r||"top"===r?(n=Bo,_="x",S="y",w="x2",k="y2",N.attr("dy",0>q?"0em":".71em").style("text-anchor","middle"),b.attr("d","M"+M[0]+","+q*i+"V0H"+M[1]+"V"+q*i)):(n=Wo,_="y",S="x",w="y2",k="x2",N.attr("dy",".32em").style("text-anchor",0>q?"end":"start"),b.attr("d","M"+q*i+","+M[0]+"H0V"+M[1]+"H"+q*i)),E.attr(k,q*u),C.attr(S,q*y),A.attr(w,0).attr(k,q*u),z.attr(_,0).attr(S,q*y),f.rangeBand){var L=f,T=L.rangeBand()/2;s=f=function(n){return L(n)+T}}else s.rangeBand?s=f:d.call(n,f,s);v.call(n,s,f),m.call(n,f,f)})}var t,e=ta.scale.linear(),r=Yl,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 Il?t+"":Yl,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 Yl="bottom",Il={top:1,right:1,bottom:1,left:1};ta.svg.brush=function(){function n(i){i.each(function(){var i=ta.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,Et);a.exit().remove(),a.enter().append("g").attr("class",function(n){return"resize "+n}).style("cursor",function(n){return Zl[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 s,f=ta.transition(i),h=ta.transition(o);c&&(s=Ui(c),h.attr("x",s[0]).attr("width",s[1]-s[0]),e(f)),l&&(s=Ui(l),h.attr("y",s[0]).attr("height",s[1]-s[0]),r(f)),t(f)})}function t(n){n.selectAll(".resize").attr("transform",function(n){return"translate("+s[+/e$/.test(n)]+","+f[+/^s/.test(n)]+")"})}function e(n){n.select(".extent").attr("x",s[0]),n.selectAll(".extent,.n>rect,.s>rect").attr("width",s[1]-s[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==ta.event.keyCode&&(N||(y=null,z[0]-=s[1],z[1]-=f[1],N=2),b())}function p(){32==ta.event.keyCode&&2==N&&(z[0]+=s[1],z[1]+=f[1],N=0,b())}function v(){var n=ta.mouse(x),u=!1;M&&(n[0]+=M[0],n[1]+=M[1]),N||(ta.event.altKey?(y||(y=[(s[0]+s[1])/2,(f[0]+f[1])/2]),z[0]=s[+(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),ta.select("body").style("cursor",null),q.on("mousemove.brush",null).on("mouseup.brush",null).on("touchmove.brush",null).on("touchend.brush",null).on("keydown.brush",null).on("keyup.brush",null),C(),w({type:"brushend"})}var y,M,x=this,_=ta.select(ta.event.target),w=a.of(x,arguments),S=ta.select(x),k=_.datum(),E=!/^(n|s)$/.test(k)&&c,A=!/^(e|w)$/.test(k)&&l,N=_.classed("extent"),C=X(),z=ta.mouse(x),q=ta.select(oa).on("keydown.brush",u).on("keyup.brush",p);if(ta.event.changedTouches?q.on("touchmove.brush",v).on("touchend.brush",m):q.on("mousemove.brush",v).on("mouseup.brush",m),S.interrupt().selectAll("*").interrupt(),N)z[0]=s[0]-z[0],z[1]=f[0]-z[1];else if(k){var L=+/w$/.test(k),T=+/^n/.test(k);M=[s[1-L]-z[0],f[1-T]-z[1]],z[0]=s[L],z[1]=f[T]}else ta.event.altKey&&(y=z.slice());S.style("pointer-events","none").selectAll(".resize").style("display",null),ta.select("body").style("cursor",_.style("cursor")),w({type:"brushstart"}),v()}var i,o,a=w(n,"brushstart","brush","brushend"),c=null,l=null,s=[0,0],f=[0,0],h=!0,g=!0,p=Vl[0];return n.event=function(n){n.each(function(){var n=a.of(this,arguments),t={x:s,y:f,i:i,j:o},e=this.__chart__||t;this.__chart__=t,Ul?ta.select(this).transition().each("start.brush",function(){i=e.i,o=e.j,s=e.x,f=e.y,n({type:"brushstart"})}).tween("brush:brush",function(){var e=yu(s,t.x),r=yu(f,t.y);return i=o=null,function(u){s=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=Vl[!c<<1|!l],n):c},n.y=function(t){return arguments.length?(l=t,p=Vl[!c<<1|!l],n):l},n.clamp=function(t){return arguments.length?(c&&l?(h=!!t[0],g=!!t[1]):c?h=!!t:l&&(g=!!t),n):c&&l?[h,g]:c?h:l?g:null},n.extent=function(t){var e,r,u,a,h;return arguments.length?(c&&(e=t[0],r=t[1],l&&(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!=s[0]||r!=s[1])&&(s=[e,r])),l&&(u=t[0],a=t[1],c&&(u=u[1],a=a[1]),o=[u,a],l.invert&&(u=l(u),a=l(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=s[0],r=s[1],c.invert&&(e=c.invert(e),r=c.invert(r)),e>r&&(h=e,e=r,r=h))),l&&(o?(u=o[0],a=o[1]):(u=f[0],a=f[1],l.invert&&(u=l.invert(u),a=l.invert(a)),u>a&&(h=u,u=a,a=h))),c&&l?[[e,u],[r,a]]:c?[e,r]:l&&[u,a])},n.clear=function(){return n.empty()||(s=[0,0],f=[0,0],i=o=null),n},n.empty=function(){return!!c&&s[0]==s[1]||!!l&&f[0]==f[1]},ta.rebind(n,a,"on")};var Zl={n:"ns-resize",e:"ew-resize",s:"ns-resize",w:"ew-resize",nw:"nwse-resize",ne:"nesw-resize",se:"nwse-resize",sw:"nesw-resize"},Vl=[["n","e","s","w","nw","ne","se","sw"],["e","w"],["n","s"],[]],Xl=fc.format=mc.timeFormat,$l=Xl.utc,Bl=$l("%Y-%m-%dT%H:%M:%S.%LZ");Xl.iso=Date.prototype.toISOString&&+new Date("2000-01-01T00:00:00.000Z")?Jo:Bl,Jo.parse=function(n){var t=new Date(n);return isNaN(t)?null:t},Jo.toString=Bl.toString,fc.second=Ft(function(n){return new hc(1e3*Math.floor(n/1e3))},function(n,t){n.setTime(n.getTime()+1e3*Math.floor(t))},function(n){return n.getSeconds()}),fc.seconds=fc.second.range,fc.seconds.utc=fc.second.utc.range,fc.minute=Ft(function(n){return new hc(6e4*Math.floor(n/6e4))},function(n,t){n.setTime(n.getTime()+6e4*Math.floor(t))},function(n){return n.getMinutes()}),fc.minutes=fc.minute.range,fc.minutes.utc=fc.minute.utc.range,fc.hour=Ft(function(n){var t=n.getTimezoneOffset()/60;return new hc(36e5*(Math.floor(n/36e5-t)+t))},function(n,t){n.setTime(n.getTime()+36e5*Math.floor(t))},function(n){return n.getHours()}),fc.hours=fc.hour.range,fc.hours.utc=fc.hour.utc.range,fc.month=Ft(function(n){return n=fc.day(n),n.setDate(1),n},function(n,t){n.setMonth(n.getMonth()+t)},function(n){return n.getMonth()}),fc.months=fc.month.range,fc.months.utc=fc.month.utc.range;var Wl=[1e3,5e3,15e3,3e4,6e4,3e5,9e5,18e5,36e5,108e5,216e5,432e5,864e5,1728e5,6048e5,2592e6,7776e6,31536e6],Jl=[[fc.second,1],[fc.second,5],[fc.second,15],[fc.second,30],[fc.minute,1],[fc.minute,5],[fc.minute,15],[fc.minute,30],[fc.hour,1],[fc.hour,3],[fc.hour,6],[fc.hour,12],[fc.day,1],[fc.day,2],[fc.week,1],[fc.month,1],[fc.month,3],[fc.year,1]],Gl=Xl.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",Ne]]),Kl={range:function(n,t,e){return ta.range(Math.ceil(n/e)*e,+t,e).map(Ko)},floor:Et,ceil:Et};Jl.year=fc.year,fc.scale=function(){return Go(ta.scale.linear(),Jl,Gl)};var Ql=Jl.map(function(n){return[n[0].utc,n[1]]}),ns=$l.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",Ne]]);Ql.year=fc.year.utc,fc.scale.utc=function(){return Go(ta.scale.linear(),Ql,ns)},ta.text=At(function(n){return n.responseText}),ta.json=function(n,t){return Nt(n,"application/json",Qo,t)},ta.html=function(n,t){return Nt(n,"text/html",na,t)},ta.xml=At(function(n){return n.responseXML}),"function"==typeof define&&define.amd?define(ta):"object"==typeof module&&module.exports&&(module.exports=ta),this.d3=ta}(); \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/excanvas.min.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/excanvas.min.js new file mode 100644 index 00000000..2a5250fb --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/excanvas.min.js @@ -0,0 +1,48 @@ +if(navigator.appVersion.indexOf("MSIE")!=-1&&parseFloat(navigator.appVersion.split("MSIE")[1])<=8&&!document.createElement("canvas").getContext)(function(){var m=Math;var mr=m.round;var ms=m.sin;var mc=m.cos;var abs=m.abs;var sqrt=m.sqrt;var Z=10;var Z2=Z/2;var IE_VERSION=+navigator.userAgent.match(/MSIE ([\d.]+)?/)[1];function getContext(){return this.context_||(this.context_=new CanvasRenderingContext2D_(this))}var slice=Array.prototype.slice;function bind(f,obj,var_args){var a=slice.call(arguments, +2);return function(){return f.apply(obj,a.concat(slice.call(arguments)))}}function encodeHtmlAttribute(s){return String(s).replace(/&/g,"&").replace(/"/g,""")}function addNamespace(doc,prefix,urn){if(!doc.namespaces[prefix])doc.namespaces.add(prefix,urn,"#default#VML")}function addNamespacesAndStylesheet(doc){addNamespace(doc,"g_vml_","urn:schemas-microsoft-com:vml");addNamespace(doc,"g_o_","urn:schemas-microsoft-com:office:office");if(!doc.styleSheets["ex_canvas_"]){var ss=doc.createStyleSheet(); +ss.owningElement.id="ex_canvas_";ss.cssText="canvas{display:inline-block;overflow:hidden;"+"text-align:left;width:300px;height:150px}"}}addNamespacesAndStylesheet(document);var G_vmlCanvasManager_={init:function(opt_doc){var doc=opt_doc||document;doc.createElement("canvas");doc.attachEvent("onreadystatechange",bind(this.init_,this,doc))},init_:function(doc){var els=doc.getElementsByTagName("canvas");for(var i=0;i1)h--;if(6*h<1)return m1+(m2-m1)*6*h;else if(2*h<1)return m2;else if(3*h<2)return m1+(m2-m1)*(2/3-h)*6;else return m1}var processStyleCache={};function processStyle(styleString){if(styleString in processStyleCache)return processStyleCache[styleString];var str,alpha=1;styleString=String(styleString);if(styleString.charAt(0)=="#")str=styleString;else if(/^rgb/.test(styleString)){var parts= +getRgbHslContent(styleString);var str="#",n;for(var i=0;i<3;i++){if(parts[i].indexOf("%")!=-1)n=Math.floor(percent(parts[i])*255);else n=+parts[i];str+=decToHex[clamp(n,0,255)]}alpha=+parts[3]}else if(/^hsl/.test(styleString)){var parts=getRgbHslContent(styleString);str=hslToRgb(parts);alpha=parts[3]}else str=colorData[styleString]||styleString;return processStyleCache[styleString]={color:str,alpha:alpha}}var DEFAULT_STYLE={style:"normal",variant:"normal",weight:"normal",size:10,family:"sans-serif"}; +var fontStyleCache={};function processFontStyle(styleString){if(fontStyleCache[styleString])return fontStyleCache[styleString];var el=document.createElement("div");var style=el.style;try{style.font=styleString}catch(ex){}return fontStyleCache[styleString]={style:style.fontStyle||DEFAULT_STYLE.style,variant:style.fontVariant||DEFAULT_STYLE.variant,weight:style.fontWeight||DEFAULT_STYLE.weight,size:style.fontSize||DEFAULT_STYLE.size,family:style.fontFamily||DEFAULT_STYLE.family}}function getComputedStyle(style, +element){var computedStyle={};for(var p in style)computedStyle[p]=style[p];var canvasFontSize=parseFloat(element.currentStyle.fontSize),fontSize=parseFloat(style.size);if(typeof style.size=="number")computedStyle.size=style.size;else if(style.size.indexOf("px")!=-1)computedStyle.size=fontSize;else if(style.size.indexOf("em")!=-1)computedStyle.size=canvasFontSize*fontSize;else if(style.size.indexOf("%")!=-1)computedStyle.size=canvasFontSize/100*fontSize;else if(style.size.indexOf("pt")!=-1)computedStyle.size= +fontSize/0.75;else computedStyle.size=canvasFontSize;computedStyle.size*=0.981;return computedStyle}function buildStyle(style){return style.style+" "+style.variant+" "+style.weight+" "+style.size+"px "+style.family}var lineCapMap={"butt":"flat","round":"round"};function processLineCap(lineCap){return lineCapMap[lineCap]||"square"}function CanvasRenderingContext2D_(canvasElement){this.m_=createMatrixIdentity();this.mStack_=[];this.aStack_=[];this.currentPath_=[];this.strokeStyle="#000";this.fillStyle= +"#000";this.lineWidth=1;this.lineJoin="miter";this.lineCap="butt";this.miterLimit=Z*1;this.globalAlpha=1;this.font="10px sans-serif";this.textAlign="left";this.textBaseline="alphabetic";this.canvas=canvasElement;var cssText="width:"+canvasElement.clientWidth+"px;height:"+canvasElement.clientHeight+"px;overflow:hidden;position:absolute";var el=canvasElement.ownerDocument.createElement("div");el.style.cssText=cssText;canvasElement.appendChild(el);var overlayEl=el.cloneNode(false);overlayEl.style.backgroundColor= +"red";overlayEl.style.filter="alpha(opacity=0)";canvasElement.appendChild(overlayEl);this.element_=el;this.arcScaleX_=1;this.arcScaleY_=1;this.lineScale_=1}var contextPrototype=CanvasRenderingContext2D_.prototype;contextPrototype.clearRect=function(){if(this.textMeasureEl_){this.textMeasureEl_.removeNode(true);this.textMeasureEl_=null}this.element_.innerHTML=""};contextPrototype.beginPath=function(){this.currentPath_=[]};contextPrototype.moveTo=function(aX,aY){var p=getCoords(this,aX,aY);this.currentPath_.push({type:"moveTo", +x:p.x,y:p.y});this.currentX_=p.x;this.currentY_=p.y};contextPrototype.lineTo=function(aX,aY){var p=getCoords(this,aX,aY);this.currentPath_.push({type:"lineTo",x:p.x,y:p.y});this.currentX_=p.x;this.currentY_=p.y};contextPrototype.bezierCurveTo=function(aCP1x,aCP1y,aCP2x,aCP2y,aX,aY){var p=getCoords(this,aX,aY);var cp1=getCoords(this,aCP1x,aCP1y);var cp2=getCoords(this,aCP2x,aCP2y);bezierCurveTo(this,cp1,cp2,p)};function bezierCurveTo(self,cp1,cp2,p){self.currentPath_.push({type:"bezierCurveTo",cp1x:cp1.x, +cp1y:cp1.y,cp2x:cp2.x,cp2y:cp2.y,x:p.x,y:p.y});self.currentX_=p.x;self.currentY_=p.y}contextPrototype.quadraticCurveTo=function(aCPx,aCPy,aX,aY){var cp=getCoords(this,aCPx,aCPy);var p=getCoords(this,aX,aY);var cp1={x:this.currentX_+2/3*(cp.x-this.currentX_),y:this.currentY_+2/3*(cp.y-this.currentY_)};var cp2={x:cp1.x+(p.x-this.currentX_)/3,y:cp1.y+(p.y-this.currentY_)/3};bezierCurveTo(this,cp1,cp2,p)};contextPrototype.arc=function(aX,aY,aRadius,aStartAngle,aEndAngle,aClockwise){aRadius*=Z;var arcType= +aClockwise?"at":"wa";var xStart=aX+mc(aStartAngle)*aRadius-Z2;var yStart=aY+ms(aStartAngle)*aRadius-Z2;var xEnd=aX+mc(aEndAngle)*aRadius-Z2;var yEnd=aY+ms(aEndAngle)*aRadius-Z2;if(xStart==xEnd&&!aClockwise)xStart+=0.125;var p=getCoords(this,aX,aY);var pStart=getCoords(this,xStart,yStart);var pEnd=getCoords(this,xEnd,yEnd);this.currentPath_.push({type:arcType,x:p.x,y:p.y,radius:aRadius,xStart:pStart.x,yStart:pStart.y,xEnd:pEnd.x,yEnd:pEnd.y})};contextPrototype.rect=function(aX,aY,aWidth,aHeight){this.moveTo(aX, +aY);this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath()};contextPrototype.strokeRect=function(aX,aY,aWidth,aHeight){var oldPath=this.currentPath_;this.beginPath();this.moveTo(aX,aY);this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath();this.stroke();this.currentPath_=oldPath};contextPrototype.fillRect=function(aX,aY,aWidth,aHeight){var oldPath=this.currentPath_;this.beginPath();this.moveTo(aX,aY); +this.lineTo(aX+aWidth,aY);this.lineTo(aX+aWidth,aY+aHeight);this.lineTo(aX,aY+aHeight);this.closePath();this.fill();this.currentPath_=oldPath};contextPrototype.createLinearGradient=function(aX0,aY0,aX1,aY1){var gradient=new CanvasGradient_("gradient");gradient.x0_=aX0;gradient.y0_=aY0;gradient.x1_=aX1;gradient.y1_=aY1;return gradient};contextPrototype.createRadialGradient=function(aX0,aY0,aR0,aX1,aY1,aR1){var gradient=new CanvasGradient_("gradientradial");gradient.x0_=aX0;gradient.y0_=aY0;gradient.r0_= +aR0;gradient.x1_=aX1;gradient.y1_=aY1;gradient.r1_=aR1;return gradient};contextPrototype.drawImage=function(image,var_args){var dx,dy,dw,dh,sx,sy,sw,sh;var oldRuntimeWidth=image.runtimeStyle.width;var oldRuntimeHeight=image.runtimeStyle.height;image.runtimeStyle.width="auto";image.runtimeStyle.height="auto";var w=image.width;var h=image.height;image.runtimeStyle.width=oldRuntimeWidth;image.runtimeStyle.height=oldRuntimeHeight;if(arguments.length==3){dx=arguments[1];dy=arguments[2];sx=sy=0;sw=dw=w; +sh=dh=h}else if(arguments.length==5){dx=arguments[1];dy=arguments[2];dw=arguments[3];dh=arguments[4];sx=sy=0;sw=w;sh=h}else if(arguments.length==9){sx=arguments[1];sy=arguments[2];sw=arguments[3];sh=arguments[4];dx=arguments[5];dy=arguments[6];dw=arguments[7];dh=arguments[8]}else throw Error("Invalid number of arguments");var d=getCoords(this,dx,dy);var w2=sw/2;var h2=sh/2;var vmlStr=[];var W=10;var H=10;vmlStr.push(" ','","");this.element_.insertAdjacentHTML("BeforeEnd",vmlStr.join(""))};contextPrototype.stroke=function(aFill){var W= +10;var H=10;var chunkSize=5E3;var min={x:null,y:null};var max={x:null,y:null};for(var j=0;jmax.x)max.x=p.x;if(min.y==null||p.ymax.y)max.y=p.y}}lineStr.push(' ">');if(!aFill)appendStroke(this,lineStr);else appendFill(this,lineStr,min,max);lineStr.push("");this.element_.insertAdjacentHTML("beforeEnd",lineStr.join(""))}};function appendStroke(ctx, +lineStr){var a=processStyle(ctx.strokeStyle);var color=a.color;var opacity=a.alpha*ctx.globalAlpha;var lineWidth=ctx.lineScale_*ctx.lineWidth;if(lineWidth<1)opacity*=lineWidth;lineStr.push("')}function appendFill(ctx,lineStr,min,max){var fillStyle=ctx.fillStyle;var arcScaleX=ctx.arcScaleX_;var arcScaleY= +ctx.arcScaleY_;var width=max.x-min.x;var height=max.y-min.y;if(fillStyle instanceof CanvasGradient_){var angle=0;var focus={x:0,y:0};var shift=0;var expansion=1;if(fillStyle.type_=="gradient"){var x0=fillStyle.x0_/arcScaleX;var y0=fillStyle.y0_/arcScaleY;var x1=fillStyle.x1_/arcScaleX;var y1=fillStyle.y1_/arcScaleY;var p0=getCoords(ctx,x0,y0);var p1=getCoords(ctx,x1,y1);var dx=p1.x-p0.x;var dy=p1.y-p0.y;angle=Math.atan2(dx,dy)*180/Math.PI;if(angle<0)angle+=360;if(angle<1E-6)angle=0}else{var p0=getCoords(ctx, +fillStyle.x0_,fillStyle.y0_);focus={x:(p0.x-min.x)/width,y:(p0.y-min.y)/height};width/=arcScaleX*Z;height/=arcScaleY*Z;var dimension=m.max(width,height);shift=2*fillStyle.r0_/dimension;expansion=2*fillStyle.r1_/dimension-shift}var stops=fillStyle.colors_;stops.sort(function(cs1,cs2){return cs1.offset-cs2.offset});var length=stops.length;var color1=stops[0].color;var color2=stops[length-1].color;var opacity1=stops[0].alpha*ctx.globalAlpha;var opacity2=stops[length-1].alpha*ctx.globalAlpha;var colors= +[];for(var i=0;i')}else if(fillStyle instanceof CanvasPattern_){if(width&&height){var deltaLeft=-min.x;var deltaTop=-min.y;lineStr.push("')}}else{var a=processStyle(ctx.fillStyle);var color=a.color;var opacity=a.alpha*ctx.globalAlpha;lineStr.push('')}}contextPrototype.fill=function(){this.stroke(true)};contextPrototype.closePath=function(){this.currentPath_.push({type:"close"})};function getCoords(ctx,aX,aY){var m=ctx.m_;return{x:Z*(aX*m[0][0]+ +aY*m[1][0]+m[2][0])-Z2,y:Z*(aX*m[0][1]+aY*m[1][1]+m[2][1])-Z2}}contextPrototype.save=function(){var o={};copyState(this,o);this.aStack_.push(o);this.mStack_.push(this.m_);this.m_=matrixMultiply(createMatrixIdentity(),this.m_)};contextPrototype.restore=function(){if(this.aStack_.length){copyState(this.aStack_.pop(),this);this.m_=this.mStack_.pop()}};function matrixIsFinite(m){return isFinite(m[0][0])&&isFinite(m[0][1])&&isFinite(m[1][0])&&isFinite(m[1][1])&&isFinite(m[2][0])&&isFinite(m[2][1])}function setM(ctx, +m,updateLineScale){if(!matrixIsFinite(m))return;ctx.m_=m;if(updateLineScale){var det=m[0][0]*m[1][1]-m[0][1]*m[1][0];ctx.lineScale_=sqrt(abs(det))}}contextPrototype.translate=function(aX,aY){var m1=[[1,0,0],[0,1,0],[aX,aY,1]];setM(this,matrixMultiply(m1,this.m_),false)};contextPrototype.rotate=function(aRot){var c=mc(aRot);var s=ms(aRot);var m1=[[c,s,0],[-s,c,0],[0,0,1]];setM(this,matrixMultiply(m1,this.m_),false)};contextPrototype.scale=function(aX,aY){this.arcScaleX_*=aX;this.arcScaleY_*=aY;var m1= +[[aX,0,0],[0,aY,0],[0,0,1]];setM(this,matrixMultiply(m1,this.m_),true)};contextPrototype.transform=function(m11,m12,m21,m22,dx,dy){var m1=[[m11,m12,0],[m21,m22,0],[dx,dy,1]];setM(this,matrixMultiply(m1,this.m_),true)};contextPrototype.setTransform=function(m11,m12,m21,m22,dx,dy){var m=[[m11,m12,0],[m21,m22,0],[dx,dy,1]];setM(this,m,true)};contextPrototype.drawText_=function(text,x,y,maxWidth,stroke){var m=this.m_,delta=1E3,left=0,right=delta,offset={x:0,y:0},lineStr=[];var fontStyle=getComputedStyle(processFontStyle(this.font), +this.element_);var fontStyleString=buildStyle(fontStyle);var elementStyle=this.element_.currentStyle;var textAlign=this.textAlign.toLowerCase();switch(textAlign){case "left":case "center":case "right":break;case "end":textAlign=elementStyle.direction=="ltr"?"right":"left";break;case "start":textAlign=elementStyle.direction=="rtl"?"right":"left";break;default:textAlign="left"}switch(this.textBaseline){case "hanging":case "top":offset.y=fontStyle.size/1.75;break;case "middle":break;default:case null:case "alphabetic":case "ideographic":case "bottom":offset.y= +-fontStyle.size/2.25;break}switch(textAlign){case "right":left=delta;right=0.05;break;case "center":left=right=delta/2;break}var d=getCoords(this,x+offset.x,y+offset.y);lineStr.push('');if(stroke)appendStroke(this,lineStr);else appendFill(this,lineStr,{x:-left,y:0},{x:right,y:fontStyle.size});var skewM=m[0][0].toFixed(3)+ +","+m[1][0].toFixed(3)+","+m[0][1].toFixed(3)+","+m[1][1].toFixed(3)+",0,0";var skewOffset=mr(d.x/Z)+","+mr(d.y/Z);lineStr.push('','','');this.element_.insertAdjacentHTML("beforeEnd",lineStr.join(""))};contextPrototype.fillText= +function(text,x,y,maxWidth){this.drawText_(text,x,y,maxWidth,false)};contextPrototype.strokeText=function(text,x,y,maxWidth){this.drawText_(text,x,y,maxWidth,true)};contextPrototype.measureText=function(text){if(!this.textMeasureEl_){var s='';this.element_.insertAdjacentHTML("beforeEnd",s);this.textMeasureEl_=this.element_.lastChild}var doc=this.element_.ownerDocument;this.textMeasureEl_.innerHTML= +"";this.textMeasureEl_.style.font=this.font;this.textMeasureEl_.appendChild(doc.createTextNode(text));return{width:this.textMeasureEl_.offsetWidth}};contextPrototype.clip=function(){};contextPrototype.arcTo=function(){};contextPrototype.createPattern=function(image,repetition){return new CanvasPattern_(image,repetition)};function CanvasGradient_(aType){this.type_=aType;this.x0_=0;this.y0_=0;this.r0_=0;this.x1_=0;this.y1_=0;this.r1_=0;this.colors_=[]}CanvasGradient_.prototype.addColorStop=function(aOffset, +aColor){aColor=processStyle(aColor);this.colors_.push({offset:aOffset,color:aColor.color,alpha:aColor.alpha})};function CanvasPattern_(image,repetition){assertImageIsValid(image);switch(repetition){case "repeat":case null:case "":this.repetition_="repeat";break;case "repeat-x":case "repeat-y":case "no-repeat":this.repetition_=repetition;break;default:throwException("SYNTAX_ERR")}this.src_=image.src;this.width_=image.width;this.height_=image.height}function throwException(s){throw new DOMException_(s); +}function assertImageIsValid(img){if(!img||img.nodeType!=1||img.tagName!="IMG")throwException("TYPE_MISMATCH_ERR");if(img.readyState!="complete")throwException("INVALID_STATE_ERR")}function DOMException_(s){this.code=this[s];this.message=s+": DOM Exception "+this.code}var p=DOMException_.prototype=new Error;p.INDEX_SIZE_ERR=1;p.DOMSTRING_SIZE_ERR=2;p.HIERARCHY_REQUEST_ERR=3;p.WRONG_DOCUMENT_ERR=4;p.INVALID_CHARACTER_ERR=5;p.NO_DATA_ALLOWED_ERR=6;p.NO_MODIFICATION_ALLOWED_ERR=7;p.NOT_FOUND_ERR=8;p.NOT_SUPPORTED_ERR= +9;p.INUSE_ATTRIBUTE_ERR=10;p.INVALID_STATE_ERR=11;p.SYNTAX_ERR=12;p.INVALID_MODIFICATION_ERR=13;p.NAMESPACE_ERR=14;p.INVALID_ACCESS_ERR=15;p.VALIDATION_ERR=16;p.TYPE_MISMATCH_ERR=17;G_vmlCanvasManager=G_vmlCanvasManager_;CanvasRenderingContext2D=CanvasRenderingContext2D_;CanvasGradient=CanvasGradient_;CanvasPattern=CanvasPattern_;DOMException=DOMException_})(); diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/gadgetconf.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/gadgetconf.js new file mode 100644 index 00000000..7b851f57 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/gadgetconf.js @@ -0,0 +1,22 @@ +var gadgetConfig = { + "id": "TemperatureChart", + "title": "TemperatureChart", + "datasource": "org.wso2.iot.devices.temperature:1.0.0", + "type": "realtime", + "columns": [ + {"name": "TIMESTAMP", "type": "time"}, + {"name": "owner", "type": "string"}, + {"name": "deviceType", "type": "string"}, + {"name": "deviceId", "type": "string"}, + {"name": "time", "type": "long"}, + {"name": "temperature", "type": "float"} + ], + "chartConfig": { + "x": "TIMESTAMP", + "maxLength": "10", + "padding": {"top": 30, "left": 45, "bottom": 38, "right": 55}, + "charts": [{"type": "line", "y": "temperature"}] + }, + "domain": "carbon.super", + "params": ["owner", "deviceId"] +}; \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/jquery.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/jquery.js new file mode 100644 index 00000000..14ba6362 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/jquery.js @@ -0,0 +1,9472 @@ +/*! + * jQuery JavaScript Library v1.8.3 + * http://jquery.com/ + * + * Includes Sizzle.js + * http://sizzlejs.com/ + * + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://jquery.org/license + * + * Date: Tue Nov 13 2012 08:20:33 GMT-0500 (Eastern Standard Time) + */ +(function( window, undefined ) { +var + // A central reference to the root jQuery(document) + rootjQuery, + + // The deferred used on DOM ready + readyList, + + // Use the correct document accordingly with window argument (sandbox) + document = window.document, + location = window.location, + navigator = window.navigator, + + // Map over jQuery in case of overwrite + _jQuery = window.jQuery, + + // Map over the $ in case of overwrite + _$ = window.$, + + // Save a reference to some core methods + core_push = Array.prototype.push, + core_slice = Array.prototype.slice, + core_indexOf = Array.prototype.indexOf, + core_toString = Object.prototype.toString, + core_hasOwn = Object.prototype.hasOwnProperty, + core_trim = String.prototype.trim, + + // Define a local copy of jQuery + jQuery = function( selector, context ) { + // The jQuery object is actually just the init constructor 'enhanced' + return new jQuery.fn.init( selector, context, rootjQuery ); + }, + + // Used for matching numbers + core_pnum = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source, + + // Used for detecting and trimming whitespace + core_rnotwhite = /\S/, + core_rspace = /\s+/, + + // Make sure we trim BOM and NBSP (here's looking at you, Safari 5.0 and IE) + rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, + + // A simple way to check for HTML strings + // Prioritize #id over to avoid XSS via location.hash (#9521) + rquickExpr = /^(?:[^#<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, + + // Match a standalone tag + rsingleTag = /^<(\w+)\s*\/?>(?:<\/\1>|)$/, + + // JSON RegExp + rvalidchars = /^[\],:{}\s]*$/, + rvalidbraces = /(?:^|:|,)(?:\s*\[)+/g, + rvalidescape = /\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g, + rvalidtokens = /"[^"\\\r\n]*"|true|false|null|-?(?:\d\d*\.|)\d+(?:[eE][\-+]?\d+|)/g, + + // Matches dashed string for camelizing + rmsPrefix = /^-ms-/, + rdashAlpha = /-([\da-z])/gi, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return ( letter + "" ).toUpperCase(); + }, + + // The ready event handler and self cleanup method + DOMContentLoaded = function() { + if ( document.addEventListener ) { + document.removeEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + jQuery.ready(); + } else if ( document.readyState === "complete" ) { + // we're here because readyState === "complete" in oldIE + // which is good enough for us to call the dom ready! + document.detachEvent( "onreadystatechange", DOMContentLoaded ); + jQuery.ready(); + } + }, + + // [[Class]] -> type pairs + class2type = {}; + +jQuery.fn = jQuery.prototype = { + constructor: jQuery, + init: function( selector, context, rootjQuery ) { + var match, elem, ret, doc; + + // Handle $(""), $(null), $(undefined), $(false) + if ( !selector ) { + return this; + } + + // Handle $(DOMElement) + if ( selector.nodeType ) { + this.context = this[0] = selector; + this.length = 1; + return this; + } + + // Handle HTML strings + if ( typeof selector === "string" ) { + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = rquickExpr.exec( selector ); + } + + // Match html or make sure no context is specified for #id + if ( match && (match[1] || !context) ) { + + // HANDLE: $(html) -> $(array) + if ( match[1] ) { + context = context instanceof jQuery ? context[0] : context; + doc = ( context && context.nodeType ? context.ownerDocument || context : document ); + + // scripts is true for back-compat + selector = jQuery.parseHTML( match[1], doc, true ); + if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) { + this.attr.call( selector, context, true ); + } + + return jQuery.merge( this, selector ); + + // HANDLE: $(#id) + } else { + elem = document.getElementById( match[2] ); + + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE and Opera return items + // by name instead of ID + if ( elem.id !== match[2] ) { + return rootjQuery.find( selector ); + } + + // Otherwise, we inject the element directly into the jQuery object + this.length = 1; + this[0] = elem; + } + + this.context = document; + this.selector = selector; + return this; + } + + // HANDLE: $(expr, $(...)) + } else if ( !context || context.jquery ) { + return ( context || rootjQuery ).find( selector ); + + // HANDLE: $(expr, context) + // (which is just equivalent to: $(context).find(expr) + } else { + return this.constructor( context ).find( selector ); + } + + // HANDLE: $(function) + // Shortcut for document ready + } else if ( jQuery.isFunction( selector ) ) { + return rootjQuery.ready( selector ); + } + + if ( selector.selector !== undefined ) { + this.selector = selector.selector; + this.context = selector.context; + } + + return jQuery.makeArray( selector, this ); + }, + + // Start with an empty selector + selector: "", + + // The current version of jQuery being used + jquery: "1.8.3", + + // The default length of a jQuery object is 0 + length: 0, + + // The number of elements contained in the matched element set + size: function() { + return this.length; + }, + + toArray: function() { + return core_slice.call( this ); + }, + + // Get the Nth element in the matched element set OR + // Get the whole matched element set as a clean array + get: function( num ) { + return num == null ? + + // Return a 'clean' array + this.toArray() : + + // Return just the object + ( num < 0 ? this[ this.length + num ] : this[ num ] ); + }, + + // Take an array of elements and push it onto the stack + // (returning the new matched element set) + pushStack: function( elems, name, selector ) { + + // Build a new jQuery matched element set + var ret = jQuery.merge( this.constructor(), elems ); + + // Add the old object onto the stack (as a reference) + ret.prevObject = this; + + ret.context = this.context; + + if ( name === "find" ) { + ret.selector = this.selector + ( this.selector ? " " : "" ) + selector; + } else if ( name ) { + ret.selector = this.selector + "." + name + "(" + selector + ")"; + } + + // Return the newly-formed element set + return ret; + }, + + // Execute a callback for every element in the matched set. + // (You can seed the arguments with an array of args, but this is + // only used internally.) + each: function( callback, args ) { + return jQuery.each( this, callback, args ); + }, + + ready: function( fn ) { + // Add the callback + jQuery.ready.promise().done( fn ); + + return this; + }, + + eq: function( i ) { + i = +i; + return i === -1 ? + this.slice( i ) : + this.slice( i, i + 1 ); + }, + + first: function() { + return this.eq( 0 ); + }, + + last: function() { + return this.eq( -1 ); + }, + + slice: function() { + return this.pushStack( core_slice.apply( this, arguments ), + "slice", core_slice.call(arguments).join(",") ); + }, + + map: function( callback ) { + return this.pushStack( jQuery.map(this, function( elem, i ) { + return callback.call( elem, i, elem ); + })); + }, + + end: function() { + return this.prevObject || this.constructor(null); + }, + + // For internal use only. + // Behaves like an Array's method, not like a jQuery method. + push: core_push, + sort: [].sort, + splice: [].splice +}; + +// Give the init function the jQuery prototype for later instantiation +jQuery.fn.init.prototype = jQuery.fn; + +jQuery.extend = jQuery.fn.extend = function() { + var options, name, src, copy, copyIsArray, clone, + target = arguments[0] || {}, + i = 1, + length = arguments.length, + deep = false; + + // Handle a deep copy situation + if ( typeof target === "boolean" ) { + deep = target; + target = arguments[1] || {}; + // skip the boolean and the target + i = 2; + } + + // Handle case when target is a string or something (possible in deep copy) + if ( typeof target !== "object" && !jQuery.isFunction(target) ) { + target = {}; + } + + // extend jQuery itself if only one argument is passed + if ( length === i ) { + target = this; + --i; + } + + for ( ; i < length; i++ ) { + // Only deal with non-null/undefined values + if ( (options = arguments[ i ]) != null ) { + // Extend the base object + for ( name in options ) { + src = target[ name ]; + copy = options[ name ]; + + // Prevent never-ending loop + if ( target === copy ) { + continue; + } + + // Recurse if we're merging plain objects or arrays + if ( deep && copy && ( jQuery.isPlainObject(copy) || (copyIsArray = jQuery.isArray(copy)) ) ) { + if ( copyIsArray ) { + copyIsArray = false; + clone = src && jQuery.isArray(src) ? src : []; + + } else { + clone = src && jQuery.isPlainObject(src) ? src : {}; + } + + // Never move original objects, clone them + target[ name ] = jQuery.extend( deep, clone, copy ); + + // Don't bring in undefined values + } else if ( copy !== undefined ) { + target[ name ] = copy; + } + } + } + } + + // Return the modified object + return target; +}; + +jQuery.extend({ + noConflict: function( deep ) { + if ( window.$ === jQuery ) { + window.$ = _$; + } + + if ( deep && window.jQuery === jQuery ) { + window.jQuery = _jQuery; + } + + return jQuery; + }, + + // Is the DOM ready to be used? Set to true once it occurs. + isReady: false, + + // A counter to track how many items to wait for before + // the ready event fires. See #6781 + readyWait: 1, + + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + + // Handle when the DOM is ready + ready: function( wait ) { + + // Abort if there are pending holds or we're already ready + if ( wait === true ? --jQuery.readyWait : jQuery.isReady ) { + return; + } + + // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). + if ( !document.body ) { + return setTimeout( jQuery.ready, 1 ); + } + + // Remember that the DOM is ready + jQuery.isReady = true; + + // If a normal DOM Ready event fired, decrement, and wait if need be + if ( wait !== true && --jQuery.readyWait > 0 ) { + return; + } + + // If there are functions bound, to execute + readyList.resolveWith( document, [ jQuery ] ); + + // Trigger any bound ready events + if ( jQuery.fn.trigger ) { + jQuery( document ).trigger("ready").off("ready"); + } + }, + + // See test/unit/core.js for details concerning isFunction. + // Since version 1.3, DOM methods and functions like alert + // aren't supported. They return false on IE (#2968). + isFunction: function( obj ) { + return jQuery.type(obj) === "function"; + }, + + isArray: Array.isArray || function( obj ) { + return jQuery.type(obj) === "array"; + }, + + isWindow: function( obj ) { + return obj != null && obj == obj.window; + }, + + isNumeric: function( obj ) { + return !isNaN( parseFloat(obj) ) && isFinite( obj ); + }, + + type: function( obj ) { + return obj == null ? + String( obj ) : + class2type[ core_toString.call(obj) ] || "object"; + }, + + isPlainObject: function( obj ) { + // Must be an Object. + // Because of IE, we also have to check the presence of the constructor property. + // Make sure that DOM nodes and window objects don't pass through, as well + if ( !obj || jQuery.type(obj) !== "object" || obj.nodeType || jQuery.isWindow( obj ) ) { + return false; + } + + try { + // Not own constructor property must be Object + if ( obj.constructor && + !core_hasOwn.call(obj, "constructor") && + !core_hasOwn.call(obj.constructor.prototype, "isPrototypeOf") ) { + return false; + } + } catch ( e ) { + // IE8,9 Will throw exceptions on certain host objects #9897 + return false; + } + + // Own properties are enumerated firstly, so to speed up, + // if last one is own, then all properties are own. + + var key; + for ( key in obj ) {} + + return key === undefined || core_hasOwn.call( obj, key ); + }, + + isEmptyObject: function( obj ) { + var name; + for ( name in obj ) { + return false; + } + return true; + }, + + error: function( msg ) { + throw new Error( msg ); + }, + + // data: string of html + // context (optional): If specified, the fragment will be created in this context, defaults to document + // scripts (optional): If true, will include scripts passed in the html string + parseHTML: function( data, context, scripts ) { + var parsed; + if ( !data || typeof data !== "string" ) { + return null; + } + if ( typeof context === "boolean" ) { + scripts = context; + context = 0; + } + context = context || document; + + // Single tag + if ( (parsed = rsingleTag.exec( data )) ) { + return [ context.createElement( parsed[1] ) ]; + } + + parsed = jQuery.buildFragment( [ data ], context, scripts ? null : [] ); + return jQuery.merge( [], + (parsed.cacheable ? jQuery.clone( parsed.fragment ) : parsed.fragment).childNodes ); + }, + + parseJSON: function( data ) { + if ( !data || typeof data !== "string") { + return null; + } + + // Make sure leading/trailing whitespace is removed (IE can't handle it) + data = jQuery.trim( data ); + + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + + // Make sure the incoming data is actual JSON + // Logic borrowed from http://json.org/json2.js + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { + + return ( new Function( "return " + data ) )(); + + } + jQuery.error( "Invalid JSON: " + data ); + }, + + // Cross-browser xml parsing + parseXML: function( data ) { + var xml, tmp; + if ( !data || typeof data !== "string" ) { + return null; + } + try { + if ( window.DOMParser ) { // Standard + tmp = new DOMParser(); + xml = tmp.parseFromString( data , "text/xml" ); + } else { // IE + xml = new ActiveXObject( "Microsoft.XMLDOM" ); + xml.async = "false"; + xml.loadXML( data ); + } + } catch( e ) { + xml = undefined; + } + if ( !xml || !xml.documentElement || xml.getElementsByTagName( "parsererror" ).length ) { + jQuery.error( "Invalid XML: " + data ); + } + return xml; + }, + + noop: function() {}, + + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context + globalEval: function( data ) { + if ( data && core_rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); + } + }, + + // Convert dashed to camelCase; used by the css and data modules + // Microsoft forgot to hump their vendor prefix (#9572) + camelCase: function( string ) { + return string.replace( rmsPrefix, "ms-" ).replace( rdashAlpha, fcamelCase ); + }, + + nodeName: function( elem, name ) { + return elem.nodeName && elem.nodeName.toLowerCase() === name.toLowerCase(); + }, + + // args is for internal usage only + each: function( obj, callback, args ) { + var name, + i = 0, + length = obj.length, + isObj = length === undefined || jQuery.isFunction( obj ); + + if ( args ) { + if ( isObj ) { + for ( name in obj ) { + if ( callback.apply( obj[ name ], args ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.apply( obj[ i++ ], args ) === false ) { + break; + } + } + } + + // A special, fast, case for the most common use of each + } else { + if ( isObj ) { + for ( name in obj ) { + if ( callback.call( obj[ name ], name, obj[ name ] ) === false ) { + break; + } + } + } else { + for ( ; i < length; ) { + if ( callback.call( obj[ i ], i, obj[ i++ ] ) === false ) { + break; + } + } + } + } + + return obj; + }, + + // Use native String.trim function wherever possible + trim: core_trim && !core_trim.call("\uFEFF\xA0") ? + function( text ) { + return text == null ? + "" : + core_trim.call( text ); + } : + + // Otherwise use our own trimming functionality + function( text ) { + return text == null ? + "" : + ( text + "" ).replace( rtrim, "" ); + }, + + // results is for internal usage only + makeArray: function( arr, results ) { + var type, + ret = results || []; + + if ( arr != null ) { + // The window, strings (and functions) also have 'length' + // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 + type = jQuery.type( arr ); + + if ( arr.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( arr ) ) { + core_push.call( ret, arr ); + } else { + jQuery.merge( ret, arr ); + } + } + + return ret; + }, + + inArray: function( elem, arr, i ) { + var len; + + if ( arr ) { + if ( core_indexOf ) { + return core_indexOf.call( arr, elem, i ); + } + + len = arr.length; + i = i ? i < 0 ? Math.max( 0, len + i ) : i : 0; + + for ( ; i < len; i++ ) { + // Skip accessing in sparse arrays + if ( i in arr && arr[ i ] === elem ) { + return i; + } + } + } + + return -1; + }, + + merge: function( first, second ) { + var l = second.length, + i = first.length, + j = 0; + + if ( typeof l === "number" ) { + for ( ; j < l; j++ ) { + first[ i++ ] = second[ j ]; + } + + } else { + while ( second[j] !== undefined ) { + first[ i++ ] = second[ j++ ]; + } + } + + first.length = i; + + return first; + }, + + grep: function( elems, callback, inv ) { + var retVal, + ret = [], + i = 0, + length = elems.length; + inv = !!inv; + + // Go through the array, only saving the items + // that pass the validator function + for ( ; i < length; i++ ) { + retVal = !!callback( elems[ i ], i ); + if ( inv !== retVal ) { + ret.push( elems[ i ] ); + } + } + + return ret; + }, + + // arg is for internal usage only + map: function( elems, callback, arg ) { + var value, key, + ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; + + // Go through the array, translating each of the items to their + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } + } + } + + // Flatten any nested arrays + return ret.concat.apply( [], ret ); + }, + + // A global GUID counter for objects + guid: 1, + + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + var tmp, args, proxy; + + if ( typeof context === "string" ) { + tmp = fn[ context ]; + context = fn; + fn = tmp; + } + + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + args = core_slice.call( arguments, 2 ); + proxy = function() { + return fn.apply( context, args.concat( core_slice.call( arguments ) ) ); + }; + + // Set the guid of unique handler to the same of original handler, so it can be removed + proxy.guid = fn.guid = fn.guid || jQuery.guid++; + + return proxy; + }, + + // Multifunctional method to get and set values of a collection + // The value/s can optionally be executed if it's a function + access: function( elems, fn, key, value, chainable, emptyGet, pass ) { + var exec, + bulk = key == null, + i = 0, + length = elems.length; + + // Sets many values + if ( key && typeof key === "object" ) { + for ( i in key ) { + jQuery.access( elems, fn, i, key[i], 1, emptyGet, value ); + } + chainable = 1; + + // Sets one value + } else if ( value !== undefined ) { + // Optionally, function values get executed if exec is true + exec = pass === undefined && jQuery.isFunction( value ); + + if ( bulk ) { + // Bulk operations only iterate when executing function values + if ( exec ) { + exec = fn; + fn = function( elem, key, value ) { + return exec.call( jQuery( elem ), value ); + }; + + // Otherwise they run against the entire set + } else { + fn.call( elems, value ); + fn = null; + } + } + + if ( fn ) { + for (; i < length; i++ ) { + fn( elems[i], key, exec ? value.call( elems[i], i, fn( elems[i], key ) ) : value, pass ); + } + } + + chainable = 1; + } + + return chainable ? + elems : + + // Gets + bulk ? + fn.call( elems ) : + length ? fn( elems[0], key ) : emptyGet; + }, + + now: function() { + return ( new Date() ).getTime(); + } +}); + +jQuery.ready.promise = function( obj ) { + if ( !readyList ) { + + readyList = jQuery.Deferred(); + + // Catch cases where $(document).ready() is called after the browser event has already occurred. + // we once tried to use readyState "interactive" here, but it caused issues like the one + // discovered by ChrisS here: http://bugs.jquery.com/ticket/12282#comment:15 + if ( document.readyState === "complete" ) { + // Handle it asynchronously to allow scripts the opportunity to delay ready + setTimeout( jQuery.ready, 1 ); + + // Standards-based browsers support DOMContentLoaded + } else if ( document.addEventListener ) { + // Use the handy event callback + document.addEventListener( "DOMContentLoaded", DOMContentLoaded, false ); + + // A fallback to window.onload, that will always work + window.addEventListener( "load", jQuery.ready, false ); + + // If IE event model is used + } else { + // Ensure firing before onload, maybe late but safe also for iframes + document.attachEvent( "onreadystatechange", DOMContentLoaded ); + + // A fallback to window.onload, that will always work + window.attachEvent( "onload", jQuery.ready ); + + // If IE and not a frame + // continually check to see if the document is ready + var top = false; + + try { + top = window.frameElement == null && document.documentElement; + } catch(e) {} + + if ( top && top.doScroll ) { + (function doScrollCheck() { + if ( !jQuery.isReady ) { + + try { + // Use the trick by Diego Perini + // http://javascript.nwbox.com/IEContentLoaded/ + top.doScroll("left"); + } catch(e) { + return setTimeout( doScrollCheck, 50 ); + } + + // and execute any waiting functions + jQuery.ready(); + } + })(); + } + } + } + return readyList.promise( obj ); +}; + +// Populate the class2type map +jQuery.each("Boolean Number String Function Array Date RegExp Object".split(" "), function(i, name) { + class2type[ "[object " + name + "]" ] = name.toLowerCase(); +}); + +// All jQuery objects should point back to these +rootjQuery = jQuery(document); +// String to Object options format cache +var optionsCache = {}; + +// Convert String-formatted options into Object-formatted ones and store in cache +function createOptions( options ) { + var object = optionsCache[ options ] = {}; + jQuery.each( options.split( core_rspace ), function( _, flag ) { + object[ flag ] = true; + }); + return object; +} + +/* + * Create a callback list using the following parameters: + * + * options: an optional list of space-separated options that will change how + * the callback list behaves or a more traditional option object + * + * By default a callback list will act like an event callback list and can be + * "fired" multiple times. + * + * Possible options: + * + * once: will ensure the callback list can only be fired once (like a Deferred) + * + * memory: will keep track of previous values and will call any callback added + * after the list has been fired right away with the latest "memorized" + * values (like a Deferred) + * + * unique: will ensure a callback can only be added once (no duplicate in the list) + * + * stopOnFalse: interrupt callings when a callback returns false + * + */ +jQuery.Callbacks = function( options ) { + + // Convert options from String-formatted to Object-formatted if needed + // (we check in cache first) + options = typeof options === "string" ? + ( optionsCache[ options ] || createOptions( options ) ) : + jQuery.extend( {}, options ); + + var // Last fire value (for non-forgettable lists) + memory, + // Flag to know if list was already fired + fired, + // Flag to know if list is currently firing + firing, + // First callback to fire (used internally by add and fireWith) + firingStart, + // End of the loop when firing + firingLength, + // Index of currently firing callback (modified by remove if needed) + firingIndex, + // Actual callback list + list = [], + // Stack of fire calls for repeatable lists + stack = !options.once && [], + // Fire callbacks + fire = function( data ) { + memory = options.memory && data; + fired = true; + firingIndex = firingStart || 0; + firingStart = 0; + firingLength = list.length; + firing = true; + for ( ; list && firingIndex < firingLength; firingIndex++ ) { + if ( list[ firingIndex ].apply( data[ 0 ], data[ 1 ] ) === false && options.stopOnFalse ) { + memory = false; // To prevent further calls using add + break; + } + } + firing = false; + if ( list ) { + if ( stack ) { + if ( stack.length ) { + fire( stack.shift() ); + } + } else if ( memory ) { + list = []; + } else { + self.disable(); + } + } + }, + // Actual Callbacks object + self = { + // Add a callback or a collection of callbacks to the list + add: function() { + if ( list ) { + // First, we save the current length + var start = list.length; + (function add( args ) { + jQuery.each( args, function( _, arg ) { + var type = jQuery.type( arg ); + if ( type === "function" ) { + if ( !options.unique || !self.has( arg ) ) { + list.push( arg ); + } + } else if ( arg && arg.length && type !== "string" ) { + // Inspect recursively + add( arg ); + } + }); + })( arguments ); + // Do we need to add the callbacks to the + // current firing batch? + if ( firing ) { + firingLength = list.length; + // With memory, if we're not firing then + // we should call right away + } else if ( memory ) { + firingStart = start; + fire( memory ); + } + } + return this; + }, + // Remove a callback from the list + remove: function() { + if ( list ) { + jQuery.each( arguments, function( _, arg ) { + var index; + while( ( index = jQuery.inArray( arg, list, index ) ) > -1 ) { + list.splice( index, 1 ); + // Handle firing indexes + if ( firing ) { + if ( index <= firingLength ) { + firingLength--; + } + if ( index <= firingIndex ) { + firingIndex--; + } + } + } + }); + } + return this; + }, + // Control if a given callback is in the list + has: function( fn ) { + return jQuery.inArray( fn, list ) > -1; + }, + // Remove all callbacks from the list + empty: function() { + list = []; + return this; + }, + // Have the list do nothing anymore + disable: function() { + list = stack = memory = undefined; + return this; + }, + // Is it disabled? + disabled: function() { + return !list; + }, + // Lock the list in its current state + lock: function() { + stack = undefined; + if ( !memory ) { + self.disable(); + } + return this; + }, + // Is it locked? + locked: function() { + return !stack; + }, + // Call all callbacks with the given context and arguments + fireWith: function( context, args ) { + args = args || []; + args = [ context, args.slice ? args.slice() : args ]; + if ( list && ( !fired || stack ) ) { + if ( firing ) { + stack.push( args ); + } else { + fire( args ); + } + } + return this; + }, + // Call all the callbacks with the given arguments + fire: function() { + self.fireWith( this, arguments ); + return this; + }, + // To know if the callbacks have already been called at least once + fired: function() { + return !!fired; + } + }; + + return self; +}; +jQuery.extend({ + + Deferred: function( func ) { + var tuples = [ + // action, add listener, listener list, final state + [ "resolve", "done", jQuery.Callbacks("once memory"), "resolved" ], + [ "reject", "fail", jQuery.Callbacks("once memory"), "rejected" ], + [ "notify", "progress", jQuery.Callbacks("memory") ] + ], + state = "pending", + promise = { + state: function() { + return state; + }, + always: function() { + deferred.done( arguments ).fail( arguments ); + return this; + }, + then: function( /* fnDone, fnFail, fnProgress */ ) { + var fns = arguments; + return jQuery.Deferred(function( newDefer ) { + jQuery.each( tuples, function( i, tuple ) { + var action = tuple[ 0 ], + fn = fns[ i ]; + // deferred[ done | fail | progress ] for forwarding actions to newDefer + deferred[ tuple[1] ]( jQuery.isFunction( fn ) ? + function() { + var returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise() + .done( newDefer.resolve ) + .fail( newDefer.reject ) + .progress( newDefer.notify ); + } else { + newDefer[ action + "With" ]( this === deferred ? newDefer : this, [ returned ] ); + } + } : + newDefer[ action ] + ); + }); + fns = null; + }).promise(); + }, + // Get a promise for this deferred + // If obj is provided, the promise aspect is added to the object + promise: function( obj ) { + return obj != null ? jQuery.extend( obj, promise ) : promise; + } + }, + deferred = {}; + + // Keep pipe for back-compat + promise.pipe = promise.then; + + // Add list-specific methods + jQuery.each( tuples, function( i, tuple ) { + var list = tuple[ 2 ], + stateString = tuple[ 3 ]; + + // promise[ done | fail | progress ] = list.add + promise[ tuple[1] ] = list.add; + + // Handle state + if ( stateString ) { + list.add(function() { + // state = [ resolved | rejected ] + state = stateString; + + // [ reject_list | resolve_list ].disable; progress_list.lock + }, tuples[ i ^ 1 ][ 2 ].disable, tuples[ 2 ][ 2 ].lock ); + } + + // deferred[ resolve | reject | notify ] = list.fire + deferred[ tuple[0] ] = list.fire; + deferred[ tuple[0] + "With" ] = list.fireWith; + }); + + // Make the deferred a promise + promise.promise( deferred ); + + // Call given func if any + if ( func ) { + func.call( deferred, deferred ); + } + + // All done! + return deferred; + }, + + // Deferred helper + when: function( subordinate /* , ..., subordinateN */ ) { + var i = 0, + resolveValues = core_slice.call( arguments ), + length = resolveValues.length, + + // the count of uncompleted subordinates + remaining = length !== 1 || ( subordinate && jQuery.isFunction( subordinate.promise ) ) ? length : 0, + + // the master Deferred. If resolveValues consist of only a single Deferred, just use that. + deferred = remaining === 1 ? subordinate : jQuery.Deferred(), + + // Update function for both resolve and progress values + updateFunc = function( i, contexts, values ) { + return function( value ) { + contexts[ i ] = this; + values[ i ] = arguments.length > 1 ? core_slice.call( arguments ) : value; + if( values === progressValues ) { + deferred.notifyWith( contexts, values ); + } else if ( !( --remaining ) ) { + deferred.resolveWith( contexts, values ); + } + }; + }, + + progressValues, progressContexts, resolveContexts; + + // add listeners to Deferred subordinates; treat others as resolved + if ( length > 1 ) { + progressValues = new Array( length ); + progressContexts = new Array( length ); + resolveContexts = new Array( length ); + for ( ; i < length; i++ ) { + if ( resolveValues[ i ] && jQuery.isFunction( resolveValues[ i ].promise ) ) { + resolveValues[ i ].promise() + .done( updateFunc( i, resolveContexts, resolveValues ) ) + .fail( deferred.reject ) + .progress( updateFunc( i, progressContexts, progressValues ) ); + } else { + --remaining; + } + } + } + + // if we're not waiting on anything, resolve the master + if ( !remaining ) { + deferred.resolveWith( resolveContexts, resolveValues ); + } + + return deferred.promise(); + } +}); +jQuery.support = (function() { + + var support, + all, + a, + select, + opt, + input, + fragment, + eventName, + i, + isSupported, + clickFn, + div = document.createElement("div"); + + // Setup + div.setAttribute( "className", "t" ); + div.innerHTML = "
a"; + + // Support tests won't run in some limited or non-browser environments + all = div.getElementsByTagName("*"); + a = div.getElementsByTagName("a")[ 0 ]; + if ( !all || !a || !all.length ) { + return {}; + } + + // First batch of tests + select = document.createElement("select"); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName("input")[ 0 ]; + + a.style.cssText = "top:1px;float:left;opacity:.5"; + support = { + // IE strips leading whitespace when .innerHTML is used + leadingWhitespace: ( div.firstChild.nodeType === 3 ), + + // Make sure that tbody elements aren't automatically inserted + // IE will insert them into empty tables + tbody: !div.getElementsByTagName("tbody").length, + + // Make sure that link elements get serialized correctly by innerHTML + // This requires a wrapper element in IE + htmlSerialize: !!div.getElementsByTagName("link").length, + + // Get the style information from getAttribute + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), + + // Make sure that URLs aren't manipulated + // (IE normalizes it by default) + hrefNormalized: ( a.getAttribute("href") === "/a" ), + + // Make sure that element opacity exists + // (IE uses filter instead) + // Use a regex to work around a WebKit issue. See #5145 + opacity: /^0.5/.test( a.style.opacity ), + + // Verify style float existence + // (IE uses styleFloat instead of cssFloat) + cssFloat: !!a.style.cssFloat, + + // Make sure that if no value is specified for a checkbox + // that it defaults to "on". + // (WebKit defaults to "" instead) + checkOn: ( input.value === "on" ), + + // Make sure that a selected-by-default option has a working selected property. + // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) + optSelected: opt.selected, + + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + + // Tests for enctype support on a form (#6743) + enctype: !!document.createElement("form").enctype, + + // Makes sure cloning an html5 element does not cause problems + // Where outerHTML is undefined, this still works + html5Clone: document.createElement("nav").cloneNode( true ).outerHTML !== "<:nav>", + + // jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode + boxModel: ( document.compatMode === "CSS1Compat" ), + + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, + deleteExpando: true, + noCloneEvent: true, + inlineBlockNeedsLayout: false, + shrinkWrapBlocks: false, + reliableMarginRight: true, + boxSizingReliable: true, + pixelPosition: false + }; + + // Make sure checked status is properly cloned + input.checked = true; + support.noCloneChecked = input.cloneNode( true ).checked; + + // Make sure that the options inside disabled selects aren't marked as disabled + // (WebKit marks them as disabled) + select.disabled = true; + support.optDisabled = !opt.disabled; + + // Test to see if it's possible to delete an expando from an element + // Fails in Internet Explorer + try { + delete div.test; + } catch( e ) { + support.deleteExpando = false; + } + + if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { + div.attachEvent( "onclick", clickFn = function() { + // Cloning a node shouldn't copy over any + // bound event handlers (IE does this) + support.noCloneEvent = false; + }); + div.cloneNode( true ).fireEvent("onclick"); + div.detachEvent( "onclick", clickFn ); + } + + // Check if a radio maintains its value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute( "type", "radio" ); + support.radioValue = input.value === "t"; + + input.setAttribute( "checked", "checked" ); + + // #11217 - WebKit loses check when the name is after the checked attribute + input.setAttribute( "name", "t" ); + + div.appendChild( input ); + fragment = document.createDocumentFragment(); + fragment.appendChild( div.lastChild ); + + // WebKit doesn't clone checked state correctly in fragments + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; + + fragment.removeChild( input ); + fragment.appendChild( div ); + + // Technique from Juriy Zaytsev + // http://perfectionkills.com/detecting-event-support-without-browser-sniffing/ + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for ( i in { + submit: true, + change: true, + focusin: true + }) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; + } + } + + // Run tests that need a body at doc ready + jQuery(function() { + var container, div, tds, marginDiv, + divReset = "padding:0;margin:0;border:0;display:block;overflow:hidden;", + body = document.getElementsByTagName("body")[0]; + + if ( !body ) { + // Return for frameset docs that don't have a body + return; + } + + container = document.createElement("div"); + container.style.cssText = "visibility:hidden;border:0;width:0;height:0;position:static;top:0;margin-top:1px"; + body.insertBefore( container, body.firstChild ); + + // Construct the test element + div = document.createElement("div"); + container.appendChild( div ); + + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + div.innerHTML = "
t
"; + tds = div.getElementsByTagName("td"); + tds[ 0 ].style.cssText = "padding:0;margin:0;border:0;display:none"; + isSupported = ( tds[ 0 ].offsetHeight === 0 ); + + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; + + // Check if empty table cells still have offsetWidth/Height + // (IE <= 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + + // Check box-sizing and margin behavior + div.innerHTML = ""; + div.style.cssText = "box-sizing:border-box;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;padding:1px;border:1px;display:block;width:4px;margin-top:1%;position:absolute;top:1%;"; + support.boxSizing = ( div.offsetWidth === 4 ); + support.doesNotIncludeMarginInBodyOffset = ( body.offsetTop !== 1 ); + + // NOTE: To any future maintainer, we've window.getComputedStyle + // because jsdom on node.js will break without it. + if ( window.getComputedStyle ) { + support.pixelPosition = ( window.getComputedStyle( div, null ) || {} ).top !== "1%"; + support.boxSizingReliable = ( window.getComputedStyle( div, null ) || { width: "4px" } ).width === "4px"; + + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + marginDiv = document.createElement("div"); + marginDiv.style.cssText = div.style.cssText = divReset; + marginDiv.style.marginRight = marginDiv.style.width = "0"; + div.style.width = "1px"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + !parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight ); + } + + if ( typeof div.style.zoom !== "undefined" ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.innerHTML = ""; + div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1"; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 ); + + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = "block"; + div.style.overflow = "visible"; + div.innerHTML = "
"; + div.firstChild.style.width = "5px"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 3 ); + + container.style.zoom = 1; + } + + // Null elements to avoid leaks in IE + body.removeChild( container ); + container = div = tds = marginDiv = null; + }); + + // Null elements to avoid leaks in IE + fragment.removeChild( div ); + all = a = select = opt = input = fragment = div = null; + + return support; +})(); +var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/, + rmultiDash = /([A-Z])/g; + +jQuery.extend({ + cache: {}, + + deletedIds: [], + + // Remove at next major release (1.9/2.0) + uuid: 0, + + // Unique for each copy of jQuery on the page + // Non-digits removed to match rinlinejQuery + expando: "jQuery" + ( jQuery.fn.jquery + Math.random() ).replace( /\D/g, "" ), + + // The following elements throw uncatchable exceptions if you + // attempt to add expando properties to them. + noData: { + "embed": true, + // Ban all objects except for Flash (which handle expandos) + "object": "clsid:D27CDB6E-AE6D-11cf-96B8-444553540000", + "applet": true + }, + + hasData: function( elem ) { + elem = elem.nodeType ? jQuery.cache[ elem[jQuery.expando] ] : elem[ jQuery.expando ]; + return !!elem && !isEmptyDataObject( elem ); + }, + + data: function( elem, name, data, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, ret, + internalKey = jQuery.expando, + getByName = typeof name === "string", + + // We have to handle DOM nodes and JS objects differently because IE6-7 + // can't GC object references properly across the DOM-JS boundary + isNode = elem.nodeType, + + // Only DOM nodes need the global jQuery cache; JS object data is + // attached directly to the object so GC can occur automatically + cache = isNode ? jQuery.cache : elem, + + // Only defining an ID for JS objects if its cache already exists allows + // the code to shortcut on the same path as a DOM node with no cache + id = isNode ? elem[ internalKey ] : elem[ internalKey ] && internalKey; + + // Avoid doing any more work than we need to when trying to get data on an + // object that has no data at all + if ( (!id || !cache[id] || (!pvt && !cache[id].data)) && getByName && data === undefined ) { + return; + } + + if ( !id ) { + // Only DOM nodes need a new unique ID for each element since their data + // ends up in the global cache + if ( isNode ) { + elem[ internalKey ] = id = jQuery.deletedIds.pop() || jQuery.guid++; + } else { + id = internalKey; + } + } + + if ( !cache[ id ] ) { + cache[ id ] = {}; + + // Avoids exposing jQuery metadata on plain JS objects when the object + // is serialized using JSON.stringify + if ( !isNode ) { + cache[ id ].toJSON = jQuery.noop; + } + } + + // An object can be passed to jQuery.data instead of a key/value pair; this gets + // shallow copied over onto the existing cache + if ( typeof name === "object" || typeof name === "function" ) { + if ( pvt ) { + cache[ id ] = jQuery.extend( cache[ id ], name ); + } else { + cache[ id ].data = jQuery.extend( cache[ id ].data, name ); + } + } + + thisCache = cache[ id ]; + + // jQuery data() is stored in a separate object inside the object's internal data + // cache in order to avoid key collisions between internal data and user-defined + // data. + if ( !pvt ) { + if ( !thisCache.data ) { + thisCache.data = {}; + } + + thisCache = thisCache.data; + } + + if ( data !== undefined ) { + thisCache[ jQuery.camelCase( name ) ] = data; + } + + // Check for both converted-to-camel and non-converted data property names + // If a data property was specified + if ( getByName ) { + + // First Try to find as-is property data + ret = thisCache[ name ]; + + // Test for null|undefined property data + if ( ret == null ) { + + // Try to find the camelCased property + ret = thisCache[ jQuery.camelCase( name ) ]; + } + } else { + ret = thisCache; + } + + return ret; + }, + + removeData: function( elem, name, pvt /* Internal Use Only */ ) { + if ( !jQuery.acceptData( elem ) ) { + return; + } + + var thisCache, i, l, + + isNode = elem.nodeType, + + // See jQuery.data for more information + cache = isNode ? jQuery.cache : elem, + id = isNode ? elem[ jQuery.expando ] : jQuery.expando; + + // If there is already no cache entry for this object, there is no + // purpose in continuing + if ( !cache[ id ] ) { + return; + } + + if ( name ) { + + thisCache = pvt ? cache[ id ] : cache[ id ].data; + + if ( thisCache ) { + + // Support array or space separated string names for data keys + if ( !jQuery.isArray( name ) ) { + + // try the string as a key before any manipulation + if ( name in thisCache ) { + name = [ name ]; + } else { + + // split the camel cased version by spaces unless a key with the spaces exists + name = jQuery.camelCase( name ); + if ( name in thisCache ) { + name = [ name ]; + } else { + name = name.split(" "); + } + } + } + + for ( i = 0, l = name.length; i < l; i++ ) { + delete thisCache[ name[i] ]; + } + + // If there is no data left in the cache, we want to continue + // and let the cache object itself get destroyed + if ( !( pvt ? isEmptyDataObject : jQuery.isEmptyObject )( thisCache ) ) { + return; + } + } + } + + // See jQuery.data for more information + if ( !pvt ) { + delete cache[ id ].data; + + // Don't destroy the parent cache unless the internal data object + // had been the only thing left in it + if ( !isEmptyDataObject( cache[ id ] ) ) { + return; + } + } + + // Destroy the cache + if ( isNode ) { + jQuery.cleanData( [ elem ], true ); + + // Use delete when supported for expandos or `cache` is not a window per isWindow (#10080) + } else if ( jQuery.support.deleteExpando || cache != cache.window ) { + delete cache[ id ]; + + // When all else fails, null + } else { + cache[ id ] = null; + } + }, + + // For internal use only. + _data: function( elem, name, data ) { + return jQuery.data( elem, name, data, true ); + }, + + // A method for determining if a DOM node can handle the data expando + acceptData: function( elem ) { + var noData = elem.nodeName && jQuery.noData[ elem.nodeName.toLowerCase() ]; + + // nodes accept data unless otherwise specified; rejection can be conditional + return !noData || noData !== true && elem.getAttribute("classid") === noData; + } +}); + +jQuery.fn.extend({ + data: function( key, value ) { + var parts, part, attr, name, l, + elem = this[0], + i = 0, + data = null; + + // Gets all values + if ( key === undefined ) { + if ( this.length ) { + data = jQuery.data( elem ); + + if ( elem.nodeType === 1 && !jQuery._data( elem, "parsedAttrs" ) ) { + attr = elem.attributes; + for ( l = attr.length; i < l; i++ ) { + name = attr[i].name; + + if ( !name.indexOf( "data-" ) ) { + name = jQuery.camelCase( name.substring(5) ); + + dataAttr( elem, name, data[ name ] ); + } + } + jQuery._data( elem, "parsedAttrs", true ); + } + } + + return data; + } + + // Sets multiple values + if ( typeof key === "object" ) { + return this.each(function() { + jQuery.data( this, key ); + }); + } + + parts = key.split( ".", 2 ); + parts[1] = parts[1] ? "." + parts[1] : ""; + part = parts[1] + "!"; + + return jQuery.access( this, function( value ) { + + if ( value === undefined ) { + data = this.triggerHandler( "getData" + part, [ parts[0] ] ); + + // Try to fetch any internally stored data first + if ( data === undefined && elem ) { + data = jQuery.data( elem, key ); + data = dataAttr( elem, key, data ); + } + + return data === undefined && parts[1] ? + this.data( parts[0] ) : + data; + } + + parts[1] = value; + this.each(function() { + var self = jQuery( this ); + + self.triggerHandler( "setData" + part, parts ); + jQuery.data( this, key, value ); + self.triggerHandler( "changeData" + part, parts ); + }); + }, null, value, arguments.length > 1, null, false ); + }, + + removeData: function( key ) { + return this.each(function() { + jQuery.removeData( this, key ); + }); + } +}); + +function dataAttr( elem, key, data ) { + // If nothing was found internally, try to fetch any + // data from the HTML5 data-* attribute + if ( data === undefined && elem.nodeType === 1 ) { + + var name = "data-" + key.replace( rmultiDash, "-$1" ).toLowerCase(); + + data = elem.getAttribute( name ); + + if ( typeof data === "string" ) { + try { + data = data === "true" ? true : + data === "false" ? false : + data === "null" ? null : + // Only convert to a number if it doesn't change the string + +data + "" === data ? +data : + rbrace.test( data ) ? jQuery.parseJSON( data ) : + data; + } catch( e ) {} + + // Make sure we set the data so it isn't changed later + jQuery.data( elem, key, data ); + + } else { + data = undefined; + } + } + + return data; +} + +// checks a cache object for emptiness +function isEmptyDataObject( obj ) { + var name; + for ( name in obj ) { + + // if the public data object is empty, the private is still empty + if ( name === "data" && jQuery.isEmptyObject( obj[name] ) ) { + continue; + } + if ( name !== "toJSON" ) { + return false; + } + } + + return true; +} +jQuery.extend({ + queue: function( elem, type, data ) { + var queue; + + if ( elem ) { + type = ( type || "fx" ) + "queue"; + queue = jQuery._data( elem, type ); + + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !queue || jQuery.isArray(data) ) { + queue = jQuery._data( elem, type, jQuery.makeArray(data) ); + } else { + queue.push( data ); + } + } + return queue || []; + } + }, + + dequeue: function( elem, type ) { + type = type || "fx"; + + var queue = jQuery.queue( elem, type ), + startLength = queue.length, + fn = queue.shift(), + hooks = jQuery._queueHooks( elem, type ), + next = function() { + jQuery.dequeue( elem, type ); + }; + + // If the fx queue is dequeued, always remove the progress sentinel + if ( fn === "inprogress" ) { + fn = queue.shift(); + startLength--; + } + + if ( fn ) { + + // Add a progress sentinel to prevent the fx queue from being + // automatically dequeued + if ( type === "fx" ) { + queue.unshift( "inprogress" ); + } + + // clear up the last queue stop function + delete hooks.stop; + fn.call( elem, next, hooks ); + } + + if ( !startLength && hooks ) { + hooks.empty.fire(); + } + }, + + // not intended for public consumption - generates a queueHooks object, or returns the current one + _queueHooks: function( elem, type ) { + var key = type + "queueHooks"; + return jQuery._data( elem, key ) || jQuery._data( elem, key, { + empty: jQuery.Callbacks("once memory").add(function() { + jQuery.removeData( elem, type + "queue", true ); + jQuery.removeData( elem, key, true ); + }) + }); + } +}); + +jQuery.fn.extend({ + queue: function( type, data ) { + var setter = 2; + + if ( typeof type !== "string" ) { + data = type; + type = "fx"; + setter--; + } + + if ( arguments.length < setter ) { + return jQuery.queue( this[0], type ); + } + + return data === undefined ? + this : + this.each(function() { + var queue = jQuery.queue( this, type, data ); + + // ensure a hooks for this queue + jQuery._queueHooks( this, type ); + + if ( type === "fx" && queue[0] !== "inprogress" ) { + jQuery.dequeue( this, type ); + } + }); + }, + dequeue: function( type ) { + return this.each(function() { + jQuery.dequeue( this, type ); + }); + }, + // Based off of the plugin by Clint Helfers, with permission. + // http://blindsignals.com/index.php/2009/07/jquery-delay/ + delay: function( time, type ) { + time = jQuery.fx ? jQuery.fx.speeds[ time ] || time : time; + type = type || "fx"; + + return this.queue( type, function( next, hooks ) { + var timeout = setTimeout( next, time ); + hooks.stop = function() { + clearTimeout( timeout ); + }; + }); + }, + clearQueue: function( type ) { + return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, obj ) { + var tmp, + count = 1, + defer = jQuery.Deferred(), + elements = this, + i = this.length, + resolve = function() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + }; + + if ( typeof type !== "string" ) { + obj = type; + type = undefined; + } + type = type || "fx"; + + while( i-- ) { + tmp = jQuery._data( elements[ i ], type + "queueHooks" ); + if ( tmp && tmp.empty ) { + count++; + tmp.empty.add( resolve ); + } + } + resolve(); + return defer.promise( obj ); + } +}); +var nodeHook, boolHook, fixSpecified, + rclass = /[\t\r\n]/g, + rreturn = /\r/g, + rtype = /^(?:button|input)$/i, + rfocusable = /^(?:button|input|object|select|textarea)$/i, + rclickable = /^a(?:rea|)$/i, + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute; + +jQuery.fn.extend({ + attr: function( name, value ) { + return jQuery.access( this, jQuery.attr, name, value, arguments.length > 1 ); + }, + + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, jQuery.prop, name, value, arguments.length > 1 ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} + }); + }, + + addClass: function( value ) { + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); + }); + } + + if ( value && typeof value === "string" ) { + classNames = value.split( core_rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + + if ( elem.nodeType === 1 ) { + if ( !elem.className && classNames.length === 1 ) { + elem.className = value; + + } else { + setClass = " " + elem.className + " "; + + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( setClass.indexOf( " " + classNames[ c ] + " " ) < 0 ) { + setClass += classNames[ c ] + " "; + } + } + elem.className = jQuery.trim( setClass ); + } + } + } + } + + return this; + }, + + removeClass: function( value ) { + var removes, className, elem, c, cl, i, l; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); + }); + } + if ( (value && typeof value === "string") || value === undefined ) { + removes = ( value || "" ).split( core_rspace ); + + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; + if ( elem.nodeType === 1 && elem.className ) { + + className = (" " + elem.className + " ").replace( rclass, " " ); + + // loop over each item in the removal list + for ( c = 0, cl = removes.length; c < cl; c++ ) { + // Remove until there is nothing to remove, + while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) { + className = className.replace( " " + removes[ c ] + " " , " " ); + } + } + elem.className = value ? jQuery.trim( className ) : ""; + } + } + } + + return this; + }, + + toggleClass: function( value, stateVal ) { + var type = typeof value, + isBool = typeof stateVal === "boolean"; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); + }); + } + + return this.each(function() { + if ( type === "string" ) { + // toggle individual class names + var className, + i = 0, + self = jQuery( this ), + state = stateVal, + classNames = value.split( core_rspace ); + + while ( (className = classNames[ i++ ]) ) { + // check each className given, space separated list + state = isBool ? state : !self.hasClass( className ); + self[ state ? "addClass" : "removeClass" ]( className ); + } + + } else if ( type === "undefined" || type === "boolean" ) { + if ( this.className ) { + // store className if set + jQuery._data( this, "__className__", this.className ); + } + + // toggle whole className + this.className = this.className || value === false ? "" : jQuery._data( this, "__className__" ) || ""; + } + }); + }, + + hasClass: function( selector ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { + if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) >= 0 ) { + return true; + } + } + + return false; + }, + + val: function( value ) { + var hooks, ret, isFunction, + elem = this[0]; + + if ( !arguments.length ) { + if ( elem ) { + hooks = jQuery.valHooks[ elem.type ] || jQuery.valHooks[ elem.nodeName.toLowerCase() ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; + } + + ret = elem.value; + + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; + } + + return; + } + + isFunction = jQuery.isFunction( value ); + + return this.each(function( i ) { + var val, + self = jQuery(this); + + if ( this.nodeType !== 1 ) { + return; + } + + if ( isFunction ) { + val = value.call( this, i, self.val() ); + } else { + val = value; + } + + // Treat null/undefined as ""; convert numbers to string + if ( val == null ) { + val = ""; + } else if ( typeof val === "number" ) { + val += ""; + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { + return value == null ? "" : value + ""; + }); + } + + hooks = jQuery.valHooks[ this.type ] || jQuery.valHooks[ this.nodeName.toLowerCase() ]; + + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { + this.value = val; + } + }); + } +}); + +jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, option, + options = elem.options, + index = elem.selectedIndex, + one = elem.type === "select-one" || index < 0, + values = one ? null : [], + max = one ? index + 1 : options.length, + i = index < 0 ? + max : + one ? index : 0; + + // Loop through all the selected options + for ( ; i < max; i++ ) { + option = options[ i ]; + + // oldIE doesn't update selected after form reset (#2551) + if ( ( option.selected || i === index ) && + // Don't return options that are disabled or in a disabled optgroup + ( jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null ) && + ( !option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" ) ) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + + // Unused in 1.8, left in so attrFn-stabbers won't die; remove in 1.9 + attrFn: {}, + + attr: function( elem, name, value, pass ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set attributes on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + if ( pass && jQuery.isFunction( jQuery.fn[ name ] ) ) { + return jQuery( elem )[ name ]( value ); + } + + // Fallback to prop when attributes are not supported + if ( typeof elem.getAttribute === "undefined" ) { + return jQuery.prop( elem, name, value ); + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + // All attributes are lowercase + // Grab necessary hook if one is defined + if ( notxml ) { + name = name.toLowerCase(); + hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook ); + } + + if ( value !== undefined ) { + + if ( value === null ) { + jQuery.removeAttr( elem, name ); + return; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, value + "" ); + return value; + } + + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); + + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; + } + }, + + removeAttr: function( elem, value ) { + var propName, attrNames, name, isBool, + i = 0; + + if ( value && elem.nodeType === 1 ) { + + attrNames = value.split( core_rspace ); + + for ( ; i < attrNames.length; i++ ) { + name = attrNames[ i ]; + + if ( name ) { + propName = jQuery.propFix[ name ] || name; + isBool = rboolean.test( name ); + + // See #9699 for explanation of this approach (setting first, then removal) + // Do not do this for boolean attributes (see #10870) + if ( !isBool ) { + jQuery.attr( elem, name, "" ); + } + elem.removeAttribute( getSetAttribute ? name : propName ); + + // Set corresponding property to false for boolean attributes + if ( isBool && propName in elem ) { + elem[ propName ] = false; + } + } + } + } + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + // Use the value property for back compat + // Use the nodeHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( nodeHook && jQuery.nodeName( elem, "button" ) ) { + return nodeHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var ret, hooks, notxml, + nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return; + } + + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return ( elem[ name ] = value ); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: { + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabindex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + } + } +}); + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + // Fall back to attribute presence where some booleans are not supported + var attrNode, + property = jQuery.prop( elem, name ); + return property === true || typeof property !== "boolean" && ( attrNode = elem.getAttributeNode(name) ) && attrNode.nodeValue !== false ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !getSetAttribute ) { + + fixSpecified = { + name: true, + id: true, + coords: true + }; + + // Use this for any attribute in IE6/7 + // This fixes almost every IE6/7 issue + nodeHook = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + return ret && ( fixSpecified[ name ] ? ret.value !== "" : ret.specified ) ? + ret.value : + undefined; + }, + set: function( elem, value, name ) { + // Set the existing or create a new attribute node + var ret = elem.getAttributeNode( name ); + if ( !ret ) { + ret = document.createAttribute( name ); + elem.setAttributeNode( ret ); + } + return ( ret.value = value + "" ); + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); + + // Set contenteditable to false on removals(#10429) + // Setting to empty string throws an error as an invalid value + jQuery.attrHooks.contenteditable = { + get: nodeHook.get, + set: function( elem, value, name ) { + if ( value === "" ) { + value = "false"; + } + nodeHook.set( elem, value, name ); + } + }; +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return ( elem.style.cssText = value + "" ); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + return null; + } + }); +} + +// IE6/7 call enctype encoding +if ( !jQuery.support.enctype ) { + jQuery.propFix.enctype = "encoding"; +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 ); + } + } + }); +}); +var rformElems = /^(?:textarea|input|select)$/i, + rtypenamespace = /^([^\.]*|)(?:\.(.+)|)$/, + rhoverHack = /(?:^|\s)hover(\.\S+|)\b/, + rkeyEvent = /^key/, + rmouseEvent = /^(?:mouse|contextmenu)|click/, + rfocusMorph = /^(?:focusinfocus|focusoutblur)$/, + hoverHack = function( events ) { + return jQuery.event.special.hover ? events : events.replace( rhoverHack, "mouseenter$1 mouseleave$1" ); + }; + +/* + * Helper functions for managing events -- not part of the public interface. + * Props to Dean Edwards' addEvent library for many of the ideas. + */ +jQuery.event = { + + add: function( elem, types, handler, data, selector ) { + + var elemData, eventHandle, events, + t, tns, type, namespaces, handleObj, + handleObjIn, handlers, special; + + // Don't attach events to noData or text/comment nodes (allow plain objects tho) + if ( elem.nodeType === 3 || elem.nodeType === 8 || !types || !handler || !(elemData = jQuery._data( elem )) ) { + return; + } + + // Caller can pass in an object of custom data in lieu of the handler + if ( handler.handler ) { + handleObjIn = handler; + handler = handleObjIn.handler; + selector = handleObjIn.selector; + } + + // Make sure that the handler has a unique ID, used to find/remove it later + if ( !handler.guid ) { + handler.guid = jQuery.guid++; + } + + // Init the element's event structure and main handler, if this is the first + events = elemData.events; + if ( !events ) { + elemData.events = events = {}; + } + eventHandle = elemData.handle; + if ( !eventHandle ) { + elemData.handle = eventHandle = function( e ) { + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? + jQuery.event.dispatch.apply( eventHandle.elem, arguments ) : + undefined; + }; + // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events + eventHandle.elem = elem; + } + + // Handle multiple events separated by a space + // jQuery(...).bind("mouseover mouseout", fn); + types = jQuery.trim( hoverHack(types) ).split( " " ); + for ( t = 0; t < types.length; t++ ) { + + tns = rtypenamespace.exec( types[t] ) || []; + type = tns[1]; + namespaces = ( tns[2] || "" ).split( "." ).sort(); + + // If event changes its type, use the special event handlers for the changed type + special = jQuery.event.special[ type ] || {}; + + // If selector defined, determine special event api type, otherwise given type + type = ( selector ? special.delegateType : special.bindType ) || type; + + // Update special based on newly reset type + special = jQuery.event.special[ type ] || {}; + + // handleObj is passed to all event handlers + handleObj = jQuery.extend({ + type: type, + origType: tns[1], + data: data, + handler: handler, + guid: handler.guid, + selector: selector, + needsContext: selector && jQuery.expr.match.needsContext.test( selector ), + namespace: namespaces.join(".") + }, handleObjIn ); + + // Init the event handler queue if we're the first + handlers = events[ type ]; + if ( !handlers ) { + handlers = events[ type ] = []; + handlers.delegateCount = 0; + + // Only use addEventListener/attachEvent if the special events handler returns false + if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) { + // Bind the global event handler to the element + if ( elem.addEventListener ) { + elem.addEventListener( type, eventHandle, false ); + + } else if ( elem.attachEvent ) { + elem.attachEvent( "on" + type, eventHandle ); + } + } + } + + if ( special.add ) { + special.add.call( elem, handleObj ); + + if ( !handleObj.handler.guid ) { + handleObj.handler.guid = handler.guid; + } + } + + // Add to the element's handler list, delegates in front + if ( selector ) { + handlers.splice( handlers.delegateCount++, 0, handleObj ); + } else { + handlers.push( handleObj ); + } + + // Keep track of which events have ever been used, for event optimization + jQuery.event.global[ type ] = true; + } + + // Nullify elem to prevent memory leaks in IE + elem = null; + }, + + global: {}, + + // Detach an event or set of events from an element + remove: function( elem, types, handler, selector, mappedTypes ) { + + var t, tns, type, origType, namespaces, origCount, + j, events, special, eventType, handleObj, + elemData = jQuery.hasData( elem ) && jQuery._data( elem ); + + if ( !elemData || !(events = elemData.events) ) { + return; + } + + // Once for each type.namespace in types; type may be omitted + types = jQuery.trim( hoverHack( types || "" ) ).split(" "); + for ( t = 0; t < types.length; t++ ) { + tns = rtypenamespace.exec( types[t] ) || []; + type = origType = tns[1]; + namespaces = tns[2]; + + // Unbind all events (on this namespace, if provided) for the element + if ( !type ) { + for ( type in events ) { + jQuery.event.remove( elem, type + types[ t ], handler, selector, true ); + } + continue; + } + + special = jQuery.event.special[ type ] || {}; + type = ( selector? special.delegateType : special.bindType ) || type; + eventType = events[ type ] || []; + origCount = eventType.length; + namespaces = namespaces ? new RegExp("(^|\\.)" + namespaces.split(".").sort().join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + + // Remove matching events + for ( j = 0; j < eventType.length; j++ ) { + handleObj = eventType[ j ]; + + if ( ( mappedTypes || origType === handleObj.origType ) && + ( !handler || handler.guid === handleObj.guid ) && + ( !namespaces || namespaces.test( handleObj.namespace ) ) && + ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) { + eventType.splice( j--, 1 ); + + if ( handleObj.selector ) { + eventType.delegateCount--; + } + if ( special.remove ) { + special.remove.call( elem, handleObj ); + } + } + } + + // Remove generic event handler if we removed something and no more handlers exist + // (avoids potential for endless recursion during removal of special event handlers) + if ( eventType.length === 0 && origCount !== eventType.length ) { + if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) { + jQuery.removeEvent( elem, type, elemData.handle ); + } + + delete events[ type ]; + } + } + + // Remove the expando if it's no longer used + if ( jQuery.isEmptyObject( events ) ) { + delete elemData.handle; + + // removeData also checks for emptiness and clears the expando if empty + // so use it instead of delete + jQuery.removeData( elem, "events", true ); + } + }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, + + trigger: function( event, data, elem, onlyHandlers ) { + // Don't do events on text and comment nodes + if ( elem && (elem.nodeType === 3 || elem.nodeType === 8) ) { + return; + } + + // Event object or event type + var cache, exclusive, i, cur, old, ontype, special, handle, eventPath, bubbleType, + type = event.type || event, + namespaces = []; + + // focus/blur morphs to focusin/out; ensure we're not firing them right now + if ( rfocusMorph.test( type + jQuery.event.triggered ) ) { + return; + } + + if ( type.indexOf( "!" ) >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; + } + + if ( type.indexOf( "." ) >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); + } + + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } + + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.isTrigger = true; + event.exclusive = exclusive; + event.namespace = namespaces.join( "." ); + event.namespace_re = event.namespace? new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)") : null; + ontype = type.indexOf( ":" ) < 0 ? "on" + type : ""; + + // Handle a global trigger + if ( !elem ) { + + // TODO: Stop taunting the data cache; remove global events and always attach to document + cache = jQuery.cache; + for ( i in cache ) { + if ( cache[ i ].events && cache[ i ].events[ type ] ) { + jQuery.event.trigger( event, data, cache[ i ].handle.elem, true ); + } + } + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + if ( !event.target ) { + event.target = elem; + } + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + // Allow special events to draw outside the lines + special = jQuery.event.special[ type ] || {}; + if ( special.trigger && special.trigger.apply( elem, data ) === false ) { + return; + } + + // Determine event propagation path in advance, per W3C events spec (#9951) + // Bubble up to document, then to window; watch for a global ownerDocument var (#9724) + eventPath = [[ elem, special.bindType || type ]]; + if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) { + + bubbleType = special.delegateType || type; + cur = rfocusMorph.test( bubbleType + type ) ? elem : elem.parentNode; + for ( old = elem; cur; cur = cur.parentNode ) { + eventPath.push([ cur, bubbleType ]); + old = cur; + } + + // Only add window if we got to document (e.g., not plain obj or detached DOM) + if ( old === (elem.ownerDocument || document) ) { + eventPath.push([ old.defaultView || old.parentWindow || window, bubbleType ]); + } + } + + // Fire handlers on the event path + for ( i = 0; i < eventPath.length && !event.isPropagationStopped(); i++ ) { + + cur = eventPath[i][0]; + event.type = eventPath[i][1]; + + handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" ); + if ( handle ) { + handle.apply( cur, data ); + } + // Note that this is a bare JS function and not a jQuery handler + handle = ontype && cur[ ontype ]; + if ( handle && jQuery.acceptData( cur ) && handle.apply && handle.apply( cur, data ) === false ) { + event.preventDefault(); + } + } + event.type = type; + + // If nobody prevented the default action, do it now + if ( !onlyHandlers && !event.isDefaultPrevented() ) { + + if ( (!special._default || special._default.apply( elem.ownerDocument, data ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction() check here because IE6/7 fails that test. + // Don't do default actions on window, that's where global variables be (#6170) + // IE<9 dies on focus/blur to hidden element (#1486) + if ( ontype && elem[ type ] && ((type !== "focus" && type !== "blur") || event.target.offsetWidth !== 0) && !jQuery.isWindow( elem ) ) { + + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; + + if ( old ) { + elem[ ontype ] = null; + } + + // Prevent re-triggering of the same event, since we already bubbled it above + jQuery.event.triggered = type; + elem[ type ](); + jQuery.event.triggered = undefined; + + if ( old ) { + elem[ ontype ] = old; + } + } + } + } + + return event.result; + }, + + dispatch: function( event ) { + + // Make a writable jQuery.Event from the native event object + event = jQuery.event.fix( event || window.event ); + + var i, j, cur, ret, selMatch, matched, matches, handleObj, sel, related, + handlers = ( (jQuery._data( this, "events" ) || {} )[ event.type ] || []), + delegateCount = handlers.delegateCount, + args = core_slice.call( arguments ), + run_all = !event.exclusive && !event.namespace, + special = jQuery.event.special[ event.type ] || {}, + handlerQueue = []; + + // Use the fix-ed jQuery.Event rather than the (read-only) native event + args[0] = event; + event.delegateTarget = this; + + // Call the preDispatch hook for the mapped type, and let it bail if desired + if ( special.preDispatch && special.preDispatch.call( this, event ) === false ) { + return; + } + + // Determine handlers that should run if there are delegated events + // Avoid non-left-click bubbling in Firefox (#3861) + if ( delegateCount && !(event.button && event.type === "click") ) { + + for ( cur = event.target; cur != this; cur = cur.parentNode || this ) { + + // Don't process clicks (ONLY) on disabled elements (#6911, #8165, #11382, #11764) + if ( cur.disabled !== true || event.type !== "click" ) { + selMatch = {}; + matches = []; + for ( i = 0; i < delegateCount; i++ ) { + handleObj = handlers[ i ]; + sel = handleObj.selector; + + if ( selMatch[ sel ] === undefined ) { + selMatch[ sel ] = handleObj.needsContext ? + jQuery( sel, this ).index( cur ) >= 0 : + jQuery.find( sel, this, null, [ cur ] ).length; + } + if ( selMatch[ sel ] ) { + matches.push( handleObj ); + } + } + if ( matches.length ) { + handlerQueue.push({ elem: cur, matches: matches }); + } + } + } + } + + // Add the remaining (directly-bound) handlers + if ( handlers.length > delegateCount ) { + handlerQueue.push({ elem: this, matches: handlers.slice( delegateCount ) }); + } + + // Run delegates first; they may want to stop propagation beneath us + for ( i = 0; i < handlerQueue.length && !event.isPropagationStopped(); i++ ) { + matched = handlerQueue[ i ]; + event.currentTarget = matched.elem; + + for ( j = 0; j < matched.matches.length && !event.isImmediatePropagationStopped(); j++ ) { + handleObj = matched.matches[ j ]; + + // Triggered event must either 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace). + if ( run_all || (!event.namespace && !handleObj.namespace) || event.namespace_re && event.namespace_re.test( handleObj.namespace ) ) { + + event.data = handleObj.data; + event.handleObj = handleObj; + + ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler ) + .apply( matched.elem, args ); + + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); + } + } + } + } + } + + // Call the postDispatch hook for the mapped type + if ( special.postDispatch ) { + special.postDispatch.call( this, event ); + } + + return event.result; + }, + + // Includes some event props shared by KeyEvent and MouseEvent + // *** attrChange attrName relatedNode srcElement are not normalized, non-W3C, deprecated, will be removed in 1.8 *** + props: "attrChange attrName relatedNode srcElement altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "), + + fixHooks: {}, + + keyHooks: { + props: "char charCode key keyCode".split(" "), + filter: function( event, original ) { + + // Add which for key events + if ( event.which == null ) { + event.which = original.charCode != null ? original.charCode : original.keyCode; + } + + return event; + } + }, + + mouseHooks: { + props: "button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "), + filter: function( event, original ) { + var eventDoc, doc, body, + button = original.button, + fromElement = original.fromElement; + + // Calculate pageX/Y if missing and clientX/Y available + if ( event.pageX == null && original.clientX != null ) { + eventDoc = event.target.ownerDocument || document; + doc = eventDoc.documentElement; + body = eventDoc.body; + + event.pageX = original.clientX + ( doc && doc.scrollLeft || body && body.scrollLeft || 0 ) - ( doc && doc.clientLeft || body && body.clientLeft || 0 ); + event.pageY = original.clientY + ( doc && doc.scrollTop || body && body.scrollTop || 0 ) - ( doc && doc.clientTop || body && body.clientTop || 0 ); + } + + // Add relatedTarget, if necessary + if ( !event.relatedTarget && fromElement ) { + event.relatedTarget = fromElement === event.target ? original.toElement : fromElement; + } + + // Add which for click: 1 === left; 2 === middle; 3 === right + // Note: button is not normalized, so don't use it + if ( !event.which && button !== undefined ) { + event.which = ( button & 1 ? 1 : ( button & 2 ? 3 : ( button & 4 ? 2 : 0 ) ) ); + } + + return event; + } + }, + + fix: function( event ) { + if ( event[ jQuery.expando ] ) { + return event; + } + + // Create a writable copy of the event object and normalize some properties + var i, prop, + originalEvent = event, + fixHook = jQuery.event.fixHooks[ event.type ] || {}, + copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props; + + event = jQuery.Event( originalEvent ); + + for ( i = copy.length; i; ) { + prop = copy[ --i ]; + event[ prop ] = originalEvent[ prop ]; + } + + // Fix target property, if necessary (#1925, IE 6/7/8 & Safari2) + if ( !event.target ) { + event.target = originalEvent.srcElement || document; + } + + // Target should not be a text node (#504, Safari) + if ( event.target.nodeType === 3 ) { + event.target = event.target.parentNode; + } + + // For mouse/key events, metaKey==false if it's undefined (#3368, #11328; IE6/7/8) + event.metaKey = !!event.metaKey; + + return fixHook.filter? fixHook.filter( event, originalEvent ) : event; + }, + + special: { + load: { + // Prevent triggered image.load events from bubbling to window.load + noBubble: true + }, + + focus: { + delegateType: "focusin" + }, + blur: { + delegateType: "focusout" + }, + + beforeunload: { + setup: function( data, namespaces, eventHandle ) { + // We only want to do this special case on windows + if ( jQuery.isWindow( this ) ) { + this.onbeforeunload = eventHandle; + } + }, + + teardown: function( namespaces, eventHandle ) { + if ( this.onbeforeunload === eventHandle ) { + this.onbeforeunload = null; + } + } + } + }, + + simulate: function( type, elem, event, bubble ) { + // Piggyback on a donor event to simulate a different one. + // Fake originalEvent to avoid donor's stopPropagation, but if the + // simulated event prevents default then we do the same on the donor. + var e = jQuery.extend( + new jQuery.Event(), + event, + { type: type, + isSimulated: true, + originalEvent: {} + } + ); + if ( bubble ) { + jQuery.event.trigger( e, null, elem ); + } else { + jQuery.event.dispatch.call( elem, e ); + } + if ( e.isDefaultPrevented() ) { + event.preventDefault(); + } + } +}; + +// Some plugins are using, but it's undocumented/deprecated and will be removed. +// The 1.7 special event interface should provide all the hooks needed now. +jQuery.event.handle = jQuery.event.dispatch; + +jQuery.removeEvent = document.removeEventListener ? + function( elem, type, handle ) { + if ( elem.removeEventListener ) { + elem.removeEventListener( type, handle, false ); + } + } : + function( elem, type, handle ) { + var name = "on" + type; + + if ( elem.detachEvent ) { + + // #8545, #7054, preventing memory leaks for custom events in IE6-8 + // detachEvent needed property on element, by name of that event, to properly expose it to GC + if ( typeof elem[ name ] === "undefined" ) { + elem[ name ] = null; + } + + elem.detachEvent( name, handle ); + } + }; + +jQuery.Event = function( src, props ) { + // Allow instantiation without the 'new' keyword + if ( !(this instanceof jQuery.Event) ) { + return new jQuery.Event( src, props ); + } + + // Event object + if ( src && src.type ) { + this.originalEvent = src; + this.type = src.type; + + // Events bubbling up the document may have been marked as prevented + // by a handler lower down the tree; reflect the correct value. + this.isDefaultPrevented = ( src.defaultPrevented || src.returnValue === false || + src.getPreventDefault && src.getPreventDefault() ) ? returnTrue : returnFalse; + + // Event type + } else { + this.type = src; + } + + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + + // Create a timestamp if incoming event doesn't have one + this.timeStamp = src && src.timeStamp || jQuery.now(); + + // Mark it as fixed + this[ jQuery.expando ] = true; +}; + +function returnFalse() { + return false; +} +function returnTrue() { + return true; +} + +// jQuery.Event is based on DOM3 Events as specified by the ECMAScript Language Binding +// http://www.w3.org/TR/2003/WD-DOM-Level-3-Events-20030331/ecma-script-binding.html +jQuery.Event.prototype = { + preventDefault: function() { + this.isDefaultPrevented = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + + // if preventDefault exists run it on the original event + if ( e.preventDefault ) { + e.preventDefault(); + + // otherwise set the returnValue property of the original event to false (IE) + } else { + e.returnValue = false; + } + }, + stopPropagation: function() { + this.isPropagationStopped = returnTrue; + + var e = this.originalEvent; + if ( !e ) { + return; + } + // if stopPropagation exists run it on the original event + if ( e.stopPropagation ) { + e.stopPropagation(); + } + // otherwise set the cancelBubble property of the original event to true (IE) + e.cancelBubble = true; + }, + stopImmediatePropagation: function() { + this.isImmediatePropagationStopped = returnTrue; + this.stopPropagation(); + }, + isDefaultPrevented: returnFalse, + isPropagationStopped: returnFalse, + isImmediatePropagationStopped: returnFalse +}; + +// Create mouseenter/leave events using mouseover/out and event-time checks +jQuery.each({ + mouseenter: "mouseover", + mouseleave: "mouseout" +}, function( orig, fix ) { + jQuery.event.special[ orig ] = { + delegateType: fix, + bindType: fix, + + handle: function( event ) { + var ret, + target = this, + related = event.relatedTarget, + handleObj = event.handleObj, + selector = handleObj.selector; + + // For mousenter/leave call the handler if related is outside the target. + // NB: No relatedTarget if the mouse left/entered the browser window + if ( !related || (related !== target && !jQuery.contains( target, related )) ) { + event.type = handleObj.origType; + ret = handleObj.handler.apply( this, arguments ); + event.type = fix; + } + return ret; + } + }; +}); + +// IE submit delegation +if ( !jQuery.support.submitBubbles ) { + + jQuery.event.special.submit = { + setup: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Lazy-add a submit handler when a descendant form may potentially be submitted + jQuery.event.add( this, "click._submit keypress._submit", function( e ) { + // Node name check avoids a VML-related crash in IE (#9807) + var elem = e.target, + form = jQuery.nodeName( elem, "input" ) || jQuery.nodeName( elem, "button" ) ? elem.form : undefined; + if ( form && !jQuery._data( form, "_submit_attached" ) ) { + jQuery.event.add( form, "submit._submit", function( event ) { + event._submit_bubble = true; + }); + jQuery._data( form, "_submit_attached", true ); + } + }); + // return undefined since we don't need an event listener + }, + + postDispatch: function( event ) { + // If form was submitted by the user, bubble the event up the tree + if ( event._submit_bubble ) { + delete event._submit_bubble; + if ( this.parentNode && !event.isTrigger ) { + jQuery.event.simulate( "submit", this.parentNode, event, true ); + } + } + }, + + teardown: function() { + // Only need this for delegated form submit events + if ( jQuery.nodeName( this, "form" ) ) { + return false; + } + + // Remove delegated handlers; cleanData eventually reaps submit handlers attached above + jQuery.event.remove( this, "._submit" ); + } + }; +} + +// IE change delegation and checkbox/radio fix +if ( !jQuery.support.changeBubbles ) { + + jQuery.event.special.change = { + + setup: function() { + + if ( rformElems.test( this.nodeName ) ) { + // IE doesn't fire change on a check/radio until blur; trigger it on click + // after a propertychange. Eat the blur-change in special.change.handle. + // This still fires onchange a second time for check/radio after blur. + if ( this.type === "checkbox" || this.type === "radio" ) { + jQuery.event.add( this, "propertychange._change", function( event ) { + if ( event.originalEvent.propertyName === "checked" ) { + this._just_changed = true; + } + }); + jQuery.event.add( this, "click._change", function( event ) { + if ( this._just_changed && !event.isTrigger ) { + this._just_changed = false; + } + // Allow triggered, simulated change events (#11500) + jQuery.event.simulate( "change", this, event, true ); + }); + } + return false; + } + // Delegated event; lazy-add a change handler on descendant inputs + jQuery.event.add( this, "beforeactivate._change", function( e ) { + var elem = e.target; + + if ( rformElems.test( elem.nodeName ) && !jQuery._data( elem, "_change_attached" ) ) { + jQuery.event.add( elem, "change._change", function( event ) { + if ( this.parentNode && !event.isSimulated && !event.isTrigger ) { + jQuery.event.simulate( "change", this.parentNode, event, true ); + } + }); + jQuery._data( elem, "_change_attached", true ); + } + }); + }, + + handle: function( event ) { + var elem = event.target; + + // Swallow native change events from checkbox/radio, we already triggered them above + if ( this !== elem || event.isSimulated || event.isTrigger || (elem.type !== "radio" && elem.type !== "checkbox") ) { + return event.handleObj.handler.apply( this, arguments ); + } + }, + + teardown: function() { + jQuery.event.remove( this, "._change" ); + + return !rformElems.test( this.nodeName ); + } + }; +} + +// Create "bubbling" focus and blur events +if ( !jQuery.support.focusinBubbles ) { + jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { + + // Attach a single capturing handler while someone wants focusin/focusout + var attaches = 0, + handler = function( event ) { + jQuery.event.simulate( fix, event.target, jQuery.event.fix( event ), true ); + }; + + jQuery.event.special[ fix ] = { + setup: function() { + if ( attaches++ === 0 ) { + document.addEventListener( orig, handler, true ); + } + }, + teardown: function() { + if ( --attaches === 0 ) { + document.removeEventListener( orig, handler, true ); + } + } + }; + }); +} + +jQuery.fn.extend({ + + on: function( types, selector, data, fn, /*INTERNAL*/ one ) { + var origFn, type; + + // Types can be a map of types/handlers + if ( typeof types === "object" ) { + // ( types-Object, selector, data ) + if ( typeof selector !== "string" ) { // && selector != null + // ( types-Object, data ) + data = data || selector; + selector = undefined; + } + for ( type in types ) { + this.on( type, selector, data, types[ type ], one ); + } + return this; + } + + if ( data == null && fn == null ) { + // ( types, fn ) + fn = selector; + data = selector = undefined; + } else if ( fn == null ) { + if ( typeof selector === "string" ) { + // ( types, selector, fn ) + fn = data; + data = undefined; + } else { + // ( types, data, fn ) + fn = data; + data = selector; + selector = undefined; + } + } + if ( fn === false ) { + fn = returnFalse; + } else if ( !fn ) { + return this; + } + + if ( one === 1 ) { + origFn = fn; + fn = function( event ) { + // Can use an empty set, since event contains the info + jQuery().off( event ); + return origFn.apply( this, arguments ); + }; + // Use same guid so caller can remove using origFn + fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ ); + } + return this.each( function() { + jQuery.event.add( this, types, fn, data, selector ); + }); + }, + one: function( types, selector, data, fn ) { + return this.on( types, selector, data, fn, 1 ); + }, + off: function( types, selector, fn ) { + var handleObj, type; + if ( types && types.preventDefault && types.handleObj ) { + // ( event ) dispatched jQuery.Event + handleObj = types.handleObj; + jQuery( types.delegateTarget ).off( + handleObj.namespace ? handleObj.origType + "." + handleObj.namespace : handleObj.origType, + handleObj.selector, + handleObj.handler + ); + return this; + } + if ( typeof types === "object" ) { + // ( types-object [, selector] ) + for ( type in types ) { + this.off( type, selector, types[ type ] ); + } + return this; + } + if ( selector === false || typeof selector === "function" ) { + // ( types [, fn] ) + fn = selector; + selector = undefined; + } + if ( fn === false ) { + fn = returnFalse; + } + return this.each(function() { + jQuery.event.remove( this, types, fn, selector ); + }); + }, + + bind: function( types, data, fn ) { + return this.on( types, null, data, fn ); + }, + unbind: function( types, fn ) { + return this.off( types, null, fn ); + }, + + live: function( types, data, fn ) { + jQuery( this.context ).on( types, this.selector, data, fn ); + return this; + }, + die: function( types, fn ) { + jQuery( this.context ).off( types, this.selector || "**", fn ); + return this; + }, + + delegate: function( selector, types, data, fn ) { + return this.on( types, selector, data, fn ); + }, + undelegate: function( selector, types, fn ) { + // ( namespace ) or ( selector, types [, fn] ) + return arguments.length === 1 ? this.off( selector, "**" ) : this.off( types, selector || "**", fn ); + }, + + trigger: function( type, data ) { + return this.each(function() { + jQuery.event.trigger( type, data, this ); + }); + }, + triggerHandler: function( type, data ) { + if ( this[0] ) { + return jQuery.event.trigger( type, data, this[0], true ); + } + }, + + toggle: function( fn ) { + // Save reference to arguments for access in closure + var args = arguments, + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; + + // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; + while ( i < args.length ) { + args[ i++ ].guid = guid; + } + + return this.click( toggler ); + }, + + hover: function( fnOver, fnOut ) { + return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver ); + } +}); + +jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + + "mousedown mouseup mousemove mouseover mouseout mouseenter mouseleave " + + "change select submit keydown keypress keyup error contextmenu").split(" "), function( i, name ) { + + // Handle event binding + jQuery.fn[ name ] = function( data, fn ) { + if ( fn == null ) { + fn = data; + data = null; + } + + return arguments.length > 0 ? + this.on( name, null, data, fn ) : + this.trigger( name ); + }; + + if ( rkeyEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.keyHooks; + } + + if ( rmouseEvent.test( name ) ) { + jQuery.event.fixHooks[ name ] = jQuery.event.mouseHooks; + } +}); +/*! + * Sizzle CSS Selector Engine + * Copyright 2012 jQuery Foundation and other contributors + * Released under the MIT license + * http://sizzlejs.com/ + */ +(function( window, undefined ) { + +var cachedruns, + assertGetIdNotName, + Expr, + getText, + isXML, + contains, + compile, + sortOrder, + hasDuplicate, + outermostContext, + + baseHasDuplicate = true, + strundefined = "undefined", + + expando = ( "sizcache" + Math.random() ).replace( ".", "" ), + + Token = String, + document = window.document, + docElem = document.documentElement, + dirruns = 0, + done = 0, + pop = [].pop, + push = [].push, + slice = [].slice, + // Use a stripped-down indexOf if a native one is unavailable + indexOf = [].indexOf || function( elem ) { + var i = 0, + len = this.length; + for ( ; i < len; i++ ) { + if ( this[i] === elem ) { + return i; + } + } + return -1; + }, + + // Augment a function for special use by Sizzle + markFunction = function( fn, value ) { + fn[ expando ] = value == null || value; + return fn; + }, + + createCache = function() { + var cache = {}, + keys = []; + + return markFunction(function( key, value ) { + // Only keep the most recent entries + if ( keys.push( key ) > Expr.cacheLength ) { + delete cache[ keys.shift() ]; + } + + // Retrieve with (key + " ") to avoid collision with native Object.prototype properties (see Issue #157) + return (cache[ key + " " ] = value); + }, cache ); + }, + + classCache = createCache(), + tokenCache = createCache(), + compilerCache = createCache(), + + // Regex + + // Whitespace characters http://www.w3.org/TR/css3-selectors/#whitespace + whitespace = "[\\x20\\t\\r\\n\\f]", + // http://www.w3.org/TR/css3-syntax/#characters + characterEncoding = "(?:\\\\.|[-\\w]|[^\\x00-\\xa0])+", + + // Loosely modeled on CSS identifier characters + // An unquoted value should be a CSS identifier (http://www.w3.org/TR/css3-selectors/#attribute-selectors) + // Proper syntax: http://www.w3.org/TR/CSS21/syndata.html#value-def-identifier + identifier = characterEncoding.replace( "w", "w#" ), + + // Acceptable operators http://www.w3.org/TR/selectors/#attribute-selectors + operators = "([*^$|!~]?=)", + attributes = "\\[" + whitespace + "*(" + characterEncoding + ")" + whitespace + + "*(?:" + operators + whitespace + "*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|(" + identifier + ")|)|)" + whitespace + "*\\]", + + // Prefer arguments not in parens/brackets, + // then attribute selectors and non-pseudos (denoted by :), + // then anything else + // These preferences are here to reduce the number of selectors + // needing tokenize in the PSEUDO preFilter + pseudos = ":(" + characterEncoding + ")(?:\\((?:(['\"])((?:\\\\.|[^\\\\])*?)\\2|([^()[\\]]*|(?:(?:" + attributes + ")|[^:]|\\\\.)*|.*))\\)|)", + + // For matchExpr.POS and matchExpr.needsContext + pos = ":(even|odd|eq|gt|lt|nth|first|last)(?:\\(" + whitespace + + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", + + // Leading and non-escaped trailing whitespace, capturing some non-whitespace characters preceding the latter + rtrim = new RegExp( "^" + whitespace + "+|((?:^|[^\\\\])(?:\\\\.)*)" + whitespace + "+$", "g" ), + + rcomma = new RegExp( "^" + whitespace + "*," + whitespace + "*" ), + rcombinators = new RegExp( "^" + whitespace + "*([\\x20\\t\\r\\n\\f>+~])" + whitespace + "*" ), + rpseudo = new RegExp( pseudos ), + + // Easily-parseable/retrievable ID or TAG or CLASS selectors + rquickExpr = /^(?:#([\w\-]+)|(\w+)|\.([\w\-]+))$/, + + rnot = /^:not/, + rsibling = /[\x20\t\r\n\f]*[+~]/, + rendsWithNot = /:not\($/, + + rheader = /h\d/i, + rinputs = /input|select|textarea|button/i, + + rbackslash = /\\(?!\\)/g, + + matchExpr = { + "ID": new RegExp( "^#(" + characterEncoding + ")" ), + "CLASS": new RegExp( "^\\.(" + characterEncoding + ")" ), + "NAME": new RegExp( "^\\[name=['\"]?(" + characterEncoding + ")['\"]?\\]" ), + "TAG": new RegExp( "^(" + characterEncoding.replace( "w", "w*" ) + ")" ), + "ATTR": new RegExp( "^" + attributes ), + "PSEUDO": new RegExp( "^" + pseudos ), + "POS": new RegExp( pos, "i" ), + "CHILD": new RegExp( "^:(only|nth|first|last)-child(?:\\(" + whitespace + + "*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace + + "*(\\d+)|))" + whitespace + "*\\)|)", "i" ), + // For use in libraries implementing .is() + "needsContext": new RegExp( "^" + whitespace + "*[>+~]|" + pos, "i" ) + }, + + // Support + + // Used for testing something on an element + assert = function( fn ) { + var div = document.createElement("div"); + + try { + return fn( div ); + } catch (e) { + return false; + } finally { + // release memory in IE + div = null; + } + }, + + // Check if getElementsByTagName("*") returns only elements + assertTagNameNoComments = assert(function( div ) { + div.appendChild( document.createComment("") ); + return !div.getElementsByTagName("*").length; + }), + + // Check if getAttribute returns normalized href attributes + assertHrefNotNormalized = assert(function( div ) { + div.innerHTML = ""; + return div.firstChild && typeof div.firstChild.getAttribute !== strundefined && + div.firstChild.getAttribute("href") === "#"; + }), + + // Check if attributes should be retrieved by attribute nodes + assertAttributes = assert(function( div ) { + div.innerHTML = ""; + var type = typeof div.lastChild.getAttribute("multiple"); + // IE8 returns a string for some attributes even when not present + return type !== "boolean" && type !== "string"; + }), + + // Check if getElementsByClassName can be trusted + assertUsableClassName = assert(function( div ) { + // Opera can't find a second classname (in 9.6) + div.innerHTML = ""; + if ( !div.getElementsByClassName || !div.getElementsByClassName("e").length ) { + return false; + } + + // Safari 3.2 caches class attributes and doesn't catch changes + div.lastChild.className = "e"; + return div.getElementsByClassName("e").length === 2; + }), + + // Check if getElementById returns elements by name + // Check if getElementsByName privileges form controls or returns elements by ID + assertUsableName = assert(function( div ) { + // Inject content + div.id = expando + 0; + div.innerHTML = "
"; + docElem.insertBefore( div, docElem.firstChild ); + + // Test + var pass = document.getElementsByName && + // buggy browsers will return fewer than the correct 2 + document.getElementsByName( expando ).length === 2 + + // buggy browsers will return more than the correct 0 + document.getElementsByName( expando + 0 ).length; + assertGetIdNotName = !document.getElementById( expando ); + + // Cleanup + docElem.removeChild( div ); + + return pass; + }); + +// If slice is not available, provide a backup +try { + slice.call( docElem.childNodes, 0 )[0].nodeType; +} catch ( e ) { + slice = function( i ) { + var elem, + results = []; + for ( ; (elem = this[i]); i++ ) { + results.push( elem ); + } + return results; + }; +} + +function Sizzle( selector, context, results, seed ) { + results = results || []; + context = context || document; + var match, elem, xml, m, + nodeType = context.nodeType; + + if ( !selector || typeof selector !== "string" ) { + return results; + } + + if ( nodeType !== 1 && nodeType !== 9 ) { + return []; + } + + xml = isXML( context ); + + if ( !xml && !seed ) { + if ( (match = rquickExpr.exec( selector )) ) { + // Speed-up: Sizzle("#ID") + if ( (m = match[1]) ) { + if ( nodeType === 9 ) { + elem = context.getElementById( m ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + if ( elem && elem.parentNode ) { + // Handle the case where IE, Opera, and Webkit return items + // by name instead of ID + if ( elem.id === m ) { + results.push( elem ); + return results; + } + } else { + return results; + } + } else { + // Context is not a document + if ( context.ownerDocument && (elem = context.ownerDocument.getElementById( m )) && + contains( context, elem ) && elem.id === m ) { + results.push( elem ); + return results; + } + } + + // Speed-up: Sizzle("TAG") + } else if ( match[2] ) { + push.apply( results, slice.call(context.getElementsByTagName( selector ), 0) ); + return results; + + // Speed-up: Sizzle(".CLASS") + } else if ( (m = match[3]) && assertUsableClassName && context.getElementsByClassName ) { + push.apply( results, slice.call(context.getElementsByClassName( m ), 0) ); + return results; + } + } + } + + // All others + return select( selector.replace( rtrim, "$1" ), context, results, seed, xml ); +} + +Sizzle.matches = function( expr, elements ) { + return Sizzle( expr, null, null, elements ); +}; + +Sizzle.matchesSelector = function( elem, expr ) { + return Sizzle( expr, null, null, [ elem ] ).length > 0; +}; + +// Returns a function to use in pseudos for input types +function createInputPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === type; + }; +} + +// Returns a function to use in pseudos for buttons +function createButtonPseudo( type ) { + return function( elem ) { + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && elem.type === type; + }; +} + +// Returns a function to use in pseudos for positionals +function createPositionalPseudo( fn ) { + return markFunction(function( argument ) { + argument = +argument; + return markFunction(function( seed, matches ) { + var j, + matchIndexes = fn( [], seed.length, argument ), + i = matchIndexes.length; + + // Match elements found at the specified indexes + while ( i-- ) { + if ( seed[ (j = matchIndexes[i]) ] ) { + seed[j] = !(matches[j] = seed[j]); + } + } + }); + }); +} + +/** + * Utility function for retrieving the text value of an array of DOM nodes + * @param {Array|Element} elem + */ +getText = Sizzle.getText = function( elem ) { + var node, + ret = "", + i = 0, + nodeType = elem.nodeType; + + if ( nodeType ) { + if ( nodeType === 1 || nodeType === 9 || nodeType === 11 ) { + // Use textContent for elements + // innerText usage removed for consistency of new lines (see #11153) + if ( typeof elem.textContent === "string" ) { + return elem.textContent; + } else { + // Traverse its children + for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) { + ret += getText( elem ); + } + } + } else if ( nodeType === 3 || nodeType === 4 ) { + return elem.nodeValue; + } + // Do not include comment or processing instruction nodes + } else { + + // If no nodeType, this is expected to be an array + for ( ; (node = elem[i]); i++ ) { + // Do not traverse comment nodes + ret += getText( node ); + } + } + return ret; +}; + +isXML = Sizzle.isXML = function( elem ) { + // documentElement is verified for cases where it doesn't yet exist + // (such as loading iframes in IE - #4833) + var documentElement = elem && (elem.ownerDocument || elem).documentElement; + return documentElement ? documentElement.nodeName !== "HTML" : false; +}; + +// Element contains another +contains = Sizzle.contains = docElem.contains ? + function( a, b ) { + var adown = a.nodeType === 9 ? a.documentElement : a, + bup = b && b.parentNode; + return a === bup || !!( bup && bup.nodeType === 1 && adown.contains && adown.contains(bup) ); + } : + docElem.compareDocumentPosition ? + function( a, b ) { + return b && !!( a.compareDocumentPosition( b ) & 16 ); + } : + function( a, b ) { + while ( (b = b.parentNode) ) { + if ( b === a ) { + return true; + } + } + return false; + }; + +Sizzle.attr = function( elem, name ) { + var val, + xml = isXML( elem ); + + if ( !xml ) { + name = name.toLowerCase(); + } + if ( (val = Expr.attrHandle[ name ]) ) { + return val( elem ); + } + if ( xml || assertAttributes ) { + return elem.getAttribute( name ); + } + val = elem.getAttributeNode( name ); + return val ? + typeof elem[ name ] === "boolean" ? + elem[ name ] ? name : null : + val.specified ? val.value : null : + null; +}; + +Expr = Sizzle.selectors = { + + // Can be adjusted by the user + cacheLength: 50, + + createPseudo: markFunction, + + match: matchExpr, + + // IE6/7 return a modified href + attrHandle: assertHrefNotNormalized ? + {} : + { + "href": function( elem ) { + return elem.getAttribute( "href", 2 ); + }, + "type": function( elem ) { + return elem.getAttribute("type"); + } + }, + + find: { + "ID": assertGetIdNotName ? + function( id, context, xml ) { + if ( typeof context.getElementById !== strundefined && !xml ) { + var m = context.getElementById( id ); + // Check parentNode to catch when Blackberry 4.6 returns + // nodes that are no longer in the document #6963 + return m && m.parentNode ? [m] : []; + } + } : + function( id, context, xml ) { + if ( typeof context.getElementById !== strundefined && !xml ) { + var m = context.getElementById( id ); + + return m ? + m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ? + [m] : + undefined : + []; + } + }, + + "TAG": assertTagNameNoComments ? + function( tag, context ) { + if ( typeof context.getElementsByTagName !== strundefined ) { + return context.getElementsByTagName( tag ); + } + } : + function( tag, context ) { + var results = context.getElementsByTagName( tag ); + + // Filter out possible comments + if ( tag === "*" ) { + var elem, + tmp = [], + i = 0; + + for ( ; (elem = results[i]); i++ ) { + if ( elem.nodeType === 1 ) { + tmp.push( elem ); + } + } + + return tmp; + } + return results; + }, + + "NAME": assertUsableName && function( tag, context ) { + if ( typeof context.getElementsByName !== strundefined ) { + return context.getElementsByName( name ); + } + }, + + "CLASS": assertUsableClassName && function( className, context, xml ) { + if ( typeof context.getElementsByClassName !== strundefined && !xml ) { + return context.getElementsByClassName( className ); + } + } + }, + + relative: { + ">": { dir: "parentNode", first: true }, + " ": { dir: "parentNode" }, + "+": { dir: "previousSibling", first: true }, + "~": { dir: "previousSibling" } + }, + + preFilter: { + "ATTR": function( match ) { + match[1] = match[1].replace( rbackslash, "" ); + + // Move the given value to match[3] whether quoted or unquoted + match[3] = ( match[4] || match[5] || "" ).replace( rbackslash, "" ); + + if ( match[2] === "~=" ) { + match[3] = " " + match[3] + " "; + } + + return match.slice( 0, 4 ); + }, + + "CHILD": function( match ) { + /* matches from matchExpr["CHILD"] + 1 type (only|nth|...) + 2 argument (even|odd|\d*|\d*n([+-]\d+)?|...) + 3 xn-component of xn+y argument ([+-]?\d*n|) + 4 sign of xn-component + 5 x of xn-component + 6 sign of y-component + 7 y of y-component + */ + match[1] = match[1].toLowerCase(); + + if ( match[1] === "nth" ) { + // nth-child requires argument + if ( !match[2] ) { + Sizzle.error( match[0] ); + } + + // numeric x and y parameters for Expr.filter.CHILD + // remember that false/true cast respectively to 0/1 + match[3] = +( match[3] ? match[4] + (match[5] || 1) : 2 * ( match[2] === "even" || match[2] === "odd" ) ); + match[4] = +( ( match[6] + match[7] ) || match[2] === "odd" ); + + // other types prohibit arguments + } else if ( match[2] ) { + Sizzle.error( match[0] ); + } + + return match; + }, + + "PSEUDO": function( match ) { + var unquoted, excess; + if ( matchExpr["CHILD"].test( match[0] ) ) { + return null; + } + + if ( match[3] ) { + match[2] = match[3]; + } else if ( (unquoted = match[4]) ) { + // Only check arguments that contain a pseudo + if ( rpseudo.test(unquoted) && + // Get excess from tokenize (recursively) + (excess = tokenize( unquoted, true )) && + // advance to the next closing parenthesis + (excess = unquoted.indexOf( ")", unquoted.length - excess ) - unquoted.length) ) { + + // excess is a negative index + unquoted = unquoted.slice( 0, excess ); + match[0] = match[0].slice( 0, excess ); + } + match[2] = unquoted; + } + + // Return only captures needed by the pseudo filter method (type and argument) + return match.slice( 0, 3 ); + } + }, + + filter: { + "ID": assertGetIdNotName ? + function( id ) { + id = id.replace( rbackslash, "" ); + return function( elem ) { + return elem.getAttribute("id") === id; + }; + } : + function( id ) { + id = id.replace( rbackslash, "" ); + return function( elem ) { + var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id"); + return node && node.value === id; + }; + }, + + "TAG": function( nodeName ) { + if ( nodeName === "*" ) { + return function() { return true; }; + } + nodeName = nodeName.replace( rbackslash, "" ).toLowerCase(); + + return function( elem ) { + return elem.nodeName && elem.nodeName.toLowerCase() === nodeName; + }; + }, + + "CLASS": function( className ) { + var pattern = classCache[ expando ][ className + " " ]; + + return pattern || + (pattern = new RegExp( "(^|" + whitespace + ")" + className + "(" + whitespace + "|$)" )) && + classCache( className, function( elem ) { + return pattern.test( elem.className || (typeof elem.getAttribute !== strundefined && elem.getAttribute("class")) || "" ); + }); + }, + + "ATTR": function( name, operator, check ) { + return function( elem, context ) { + var result = Sizzle.attr( elem, name ); + + if ( result == null ) { + return operator === "!="; + } + if ( !operator ) { + return true; + } + + result += ""; + + return operator === "=" ? result === check : + operator === "!=" ? result !== check : + operator === "^=" ? check && result.indexOf( check ) === 0 : + operator === "*=" ? check && result.indexOf( check ) > -1 : + operator === "$=" ? check && result.substr( result.length - check.length ) === check : + operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 : + operator === "|=" ? result === check || result.substr( 0, check.length + 1 ) === check + "-" : + false; + }; + }, + + "CHILD": function( type, argument, first, last ) { + + if ( type === "nth" ) { + return function( elem ) { + var node, diff, + parent = elem.parentNode; + + if ( first === 1 && last === 0 ) { + return true; + } + + if ( parent ) { + diff = 0; + for ( node = parent.firstChild; node; node = node.nextSibling ) { + if ( node.nodeType === 1 ) { + diff++; + if ( elem === node ) { + break; + } + } + } + } + + // Incorporate the offset (or cast to NaN), then check against cycle size + diff -= last; + return diff === first || ( diff % first === 0 && diff / first >= 0 ); + }; + } + + return function( elem ) { + var node = elem; + + switch ( type ) { + case "only": + case "first": + while ( (node = node.previousSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + if ( type === "first" ) { + return true; + } + + node = elem; + + /* falls through */ + case "last": + while ( (node = node.nextSibling) ) { + if ( node.nodeType === 1 ) { + return false; + } + } + + return true; + } + }; + }, + + "PSEUDO": function( pseudo, argument ) { + // pseudo-class names are case-insensitive + // http://www.w3.org/TR/selectors/#pseudo-classes + // Prioritize by case sensitivity in case custom pseudos are added with uppercase letters + // Remember that setFilters inherits from pseudos + var args, + fn = Expr.pseudos[ pseudo ] || Expr.setFilters[ pseudo.toLowerCase() ] || + Sizzle.error( "unsupported pseudo: " + pseudo ); + + // The user may use createPseudo to indicate that + // arguments are needed to create the filter function + // just as Sizzle does + if ( fn[ expando ] ) { + return fn( argument ); + } + + // But maintain support for old signatures + if ( fn.length > 1 ) { + args = [ pseudo, pseudo, "", argument ]; + return Expr.setFilters.hasOwnProperty( pseudo.toLowerCase() ) ? + markFunction(function( seed, matches ) { + var idx, + matched = fn( seed, argument ), + i = matched.length; + while ( i-- ) { + idx = indexOf.call( seed, matched[i] ); + seed[ idx ] = !( matches[ idx ] = matched[i] ); + } + }) : + function( elem ) { + return fn( elem, 0, args ); + }; + } + + return fn; + } + }, + + pseudos: { + "not": markFunction(function( selector ) { + // Trim the selector passed to compile + // to avoid treating leading and trailing + // spaces as combinators + var input = [], + results = [], + matcher = compile( selector.replace( rtrim, "$1" ) ); + + return matcher[ expando ] ? + markFunction(function( seed, matches, context, xml ) { + var elem, + unmatched = matcher( seed, null, xml, [] ), + i = seed.length; + + // Match elements unmatched by `matcher` + while ( i-- ) { + if ( (elem = unmatched[i]) ) { + seed[i] = !(matches[i] = elem); + } + } + }) : + function( elem, context, xml ) { + input[0] = elem; + matcher( input, null, xml, results ); + return !results.pop(); + }; + }), + + "has": markFunction(function( selector ) { + return function( elem ) { + return Sizzle( selector, elem ).length > 0; + }; + }), + + "contains": markFunction(function( text ) { + return function( elem ) { + return ( elem.textContent || elem.innerText || getText( elem ) ).indexOf( text ) > -1; + }; + }), + + "enabled": function( elem ) { + return elem.disabled === false; + }, + + "disabled": function( elem ) { + return elem.disabled === true; + }, + + "checked": function( elem ) { + // In CSS3, :checked should return both checked and selected elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + var nodeName = elem.nodeName.toLowerCase(); + return (nodeName === "input" && !!elem.checked) || (nodeName === "option" && !!elem.selected); + }, + + "selected": function( elem ) { + // Accessing this property makes selected-by-default + // options in Safari work properly + if ( elem.parentNode ) { + elem.parentNode.selectedIndex; + } + + return elem.selected === true; + }, + + "parent": function( elem ) { + return !Expr.pseudos["empty"]( elem ); + }, + + "empty": function( elem ) { + // http://www.w3.org/TR/selectors/#empty-pseudo + // :empty is only affected by element nodes and content nodes(including text(3), cdata(4)), + // not comment, processing instructions, or others + // Thanks to Diego Perini for the nodeName shortcut + // Greater than "@" means alpha characters (specifically not starting with "#" or "?") + var nodeType; + elem = elem.firstChild; + while ( elem ) { + if ( elem.nodeName > "@" || (nodeType = elem.nodeType) === 3 || nodeType === 4 ) { + return false; + } + elem = elem.nextSibling; + } + return true; + }, + + "header": function( elem ) { + return rheader.test( elem.nodeName ); + }, + + "text": function( elem ) { + var type, attr; + // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) + // use getAttribute instead to test this case + return elem.nodeName.toLowerCase() === "input" && + (type = elem.type) === "text" && + ( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === type ); + }, + + // Input types + "radio": createInputPseudo("radio"), + "checkbox": createInputPseudo("checkbox"), + "file": createInputPseudo("file"), + "password": createInputPseudo("password"), + "image": createInputPseudo("image"), + + "submit": createButtonPseudo("submit"), + "reset": createButtonPseudo("reset"), + + "button": function( elem ) { + var name = elem.nodeName.toLowerCase(); + return name === "input" && elem.type === "button" || name === "button"; + }, + + "input": function( elem ) { + return rinputs.test( elem.nodeName ); + }, + + "focus": function( elem ) { + var doc = elem.ownerDocument; + return elem === doc.activeElement && (!doc.hasFocus || doc.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex); + }, + + "active": function( elem ) { + return elem === elem.ownerDocument.activeElement; + }, + + // Positional types + "first": createPositionalPseudo(function() { + return [ 0 ]; + }), + + "last": createPositionalPseudo(function( matchIndexes, length ) { + return [ length - 1 ]; + }), + + "eq": createPositionalPseudo(function( matchIndexes, length, argument ) { + return [ argument < 0 ? argument + length : argument ]; + }), + + "even": createPositionalPseudo(function( matchIndexes, length ) { + for ( var i = 0; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "odd": createPositionalPseudo(function( matchIndexes, length ) { + for ( var i = 1; i < length; i += 2 ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "lt": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = argument < 0 ? argument + length : argument; --i >= 0; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }), + + "gt": createPositionalPseudo(function( matchIndexes, length, argument ) { + for ( var i = argument < 0 ? argument + length : argument; ++i < length; ) { + matchIndexes.push( i ); + } + return matchIndexes; + }) + } +}; + +function siblingCheck( a, b, ret ) { + if ( a === b ) { + return ret; + } + + var cur = a.nextSibling; + + while ( cur ) { + if ( cur === b ) { + return -1; + } + + cur = cur.nextSibling; + } + + return 1; +} + +sortOrder = docElem.compareDocumentPosition ? + function( a, b ) { + if ( a === b ) { + hasDuplicate = true; + return 0; + } + + return ( !a.compareDocumentPosition || !b.compareDocumentPosition ? + a.compareDocumentPosition : + a.compareDocumentPosition(b) & 4 + ) ? -1 : 1; + } : + function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + + var al, bl, + ap = [], + bp = [], + aup = a.parentNode, + bup = b.parentNode, + cur = aup; + + // If the nodes are siblings (or identical) we can do a quick check + if ( aup === bup ) { + return siblingCheck( a, b ); + + // If no parents were found then the nodes are disconnected + } else if ( !aup ) { + return -1; + + } else if ( !bup ) { + return 1; + } + + // Otherwise they're somewhere else in the tree so we need + // to build up a full list of the parentNodes for comparison + while ( cur ) { + ap.unshift( cur ); + cur = cur.parentNode; + } + + cur = bup; + + while ( cur ) { + bp.unshift( cur ); + cur = cur.parentNode; + } + + al = ap.length; + bl = bp.length; + + // Start walking down the tree looking for a discrepancy + for ( var i = 0; i < al && i < bl; i++ ) { + if ( ap[i] !== bp[i] ) { + return siblingCheck( ap[i], bp[i] ); + } + } + + // We ended someplace up the tree so do a sibling check + return i === al ? + siblingCheck( a, bp[i], -1 ) : + siblingCheck( ap[i], b, 1 ); + }; + +// Always assume the presence of duplicates if sort doesn't +// pass them to our comparison function (as in Google Chrome). +[0, 0].sort( sortOrder ); +baseHasDuplicate = !hasDuplicate; + +// Document sorting and removing duplicates +Sizzle.uniqueSort = function( results ) { + var elem, + duplicates = [], + i = 1, + j = 0; + + hasDuplicate = baseHasDuplicate; + results.sort( sortOrder ); + + if ( hasDuplicate ) { + for ( ; (elem = results[i]); i++ ) { + if ( elem === results[ i - 1 ] ) { + j = duplicates.push( i ); + } + } + while ( j-- ) { + results.splice( duplicates[ j ], 1 ); + } + } + + return results; +}; + +Sizzle.error = function( msg ) { + throw new Error( "Syntax error, unrecognized expression: " + msg ); +}; + +function tokenize( selector, parseOnly ) { + var matched, match, tokens, type, + soFar, groups, preFilters, + cached = tokenCache[ expando ][ selector + " " ]; + + if ( cached ) { + return parseOnly ? 0 : cached.slice( 0 ); + } + + soFar = selector; + groups = []; + preFilters = Expr.preFilter; + + while ( soFar ) { + + // Comma and first run + if ( !matched || (match = rcomma.exec( soFar )) ) { + if ( match ) { + // Don't consume trailing commas as valid + soFar = soFar.slice( match[0].length ) || soFar; + } + groups.push( tokens = [] ); + } + + matched = false; + + // Combinators + if ( (match = rcombinators.exec( soFar )) ) { + tokens.push( matched = new Token( match.shift() ) ); + soFar = soFar.slice( matched.length ); + + // Cast descendant combinators to space + matched.type = match[0].replace( rtrim, " " ); + } + + // Filters + for ( type in Expr.filter ) { + if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] || + (match = preFilters[ type ]( match ))) ) { + + tokens.push( matched = new Token( match.shift() ) ); + soFar = soFar.slice( matched.length ); + matched.type = type; + matched.matches = match; + } + } + + if ( !matched ) { + break; + } + } + + // Return the length of the invalid excess + // if we're just parsing + // Otherwise, throw an error or return tokens + return parseOnly ? + soFar.length : + soFar ? + Sizzle.error( selector ) : + // Cache the tokens + tokenCache( selector, groups ).slice( 0 ); +} + +function addCombinator( matcher, combinator, base ) { + var dir = combinator.dir, + checkNonElements = base && combinator.dir === "parentNode", + doneName = done++; + + return combinator.first ? + // Check against closest ancestor/preceding element + function( elem, context, xml ) { + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + return matcher( elem, context, xml ); + } + } + } : + + // Check against all ancestor/preceding elements + function( elem, context, xml ) { + // We can't set arbitrary data on XML nodes, so they don't benefit from dir caching + if ( !xml ) { + var cache, + dirkey = dirruns + " " + doneName + " ", + cachedkey = dirkey + cachedruns; + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + if ( (cache = elem[ expando ]) === cachedkey ) { + return elem.sizset; + } else if ( typeof cache === "string" && cache.indexOf(dirkey) === 0 ) { + if ( elem.sizset ) { + return elem; + } + } else { + elem[ expando ] = cachedkey; + if ( matcher( elem, context, xml ) ) { + elem.sizset = true; + return elem; + } + elem.sizset = false; + } + } + } + } else { + while ( (elem = elem[ dir ]) ) { + if ( checkNonElements || elem.nodeType === 1 ) { + if ( matcher( elem, context, xml ) ) { + return elem; + } + } + } + } + }; +} + +function elementMatcher( matchers ) { + return matchers.length > 1 ? + function( elem, context, xml ) { + var i = matchers.length; + while ( i-- ) { + if ( !matchers[i]( elem, context, xml ) ) { + return false; + } + } + return true; + } : + matchers[0]; +} + +function condense( unmatched, map, filter, context, xml ) { + var elem, + newUnmatched = [], + i = 0, + len = unmatched.length, + mapped = map != null; + + for ( ; i < len; i++ ) { + if ( (elem = unmatched[i]) ) { + if ( !filter || filter( elem, context, xml ) ) { + newUnmatched.push( elem ); + if ( mapped ) { + map.push( i ); + } + } + } + } + + return newUnmatched; +} + +function setMatcher( preFilter, selector, matcher, postFilter, postFinder, postSelector ) { + if ( postFilter && !postFilter[ expando ] ) { + postFilter = setMatcher( postFilter ); + } + if ( postFinder && !postFinder[ expando ] ) { + postFinder = setMatcher( postFinder, postSelector ); + } + return markFunction(function( seed, results, context, xml ) { + var temp, i, elem, + preMap = [], + postMap = [], + preexisting = results.length, + + // Get initial elements from seed or context + elems = seed || multipleContexts( selector || "*", context.nodeType ? [ context ] : context, [] ), + + // Prefilter to get matcher input, preserving a map for seed-results synchronization + matcherIn = preFilter && ( seed || !selector ) ? + condense( elems, preMap, preFilter, context, xml ) : + elems, + + matcherOut = matcher ? + // If we have a postFinder, or filtered seed, or non-seed postFilter or preexisting results, + postFinder || ( seed ? preFilter : preexisting || postFilter ) ? + + // ...intermediate processing is necessary + [] : + + // ...otherwise use results directly + results : + matcherIn; + + // Find primary matches + if ( matcher ) { + matcher( matcherIn, matcherOut, context, xml ); + } + + // Apply postFilter + if ( postFilter ) { + temp = condense( matcherOut, postMap ); + postFilter( temp, [], context, xml ); + + // Un-match failing elements by moving them back to matcherIn + i = temp.length; + while ( i-- ) { + if ( (elem = temp[i]) ) { + matcherOut[ postMap[i] ] = !(matcherIn[ postMap[i] ] = elem); + } + } + } + + if ( seed ) { + if ( postFinder || preFilter ) { + if ( postFinder ) { + // Get the final matcherOut by condensing this intermediate into postFinder contexts + temp = []; + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) ) { + // Restore matcherIn since elem is not yet a final match + temp.push( (matcherIn[i] = elem) ); + } + } + postFinder( null, (matcherOut = []), temp, xml ); + } + + // Move matched elements from seed to results to keep them synchronized + i = matcherOut.length; + while ( i-- ) { + if ( (elem = matcherOut[i]) && + (temp = postFinder ? indexOf.call( seed, elem ) : preMap[i]) > -1 ) { + + seed[temp] = !(results[temp] = elem); + } + } + } + + // Add elements to results, through postFinder if defined + } else { + matcherOut = condense( + matcherOut === results ? + matcherOut.splice( preexisting, matcherOut.length ) : + matcherOut + ); + if ( postFinder ) { + postFinder( null, results, matcherOut, xml ); + } else { + push.apply( results, matcherOut ); + } + } + }); +} + +function matcherFromTokens( tokens ) { + var checkContext, matcher, j, + len = tokens.length, + leadingRelative = Expr.relative[ tokens[0].type ], + implicitRelative = leadingRelative || Expr.relative[" "], + i = leadingRelative ? 1 : 0, + + // The foundational matcher ensures that elements are reachable from top-level context(s) + matchContext = addCombinator( function( elem ) { + return elem === checkContext; + }, implicitRelative, true ), + matchAnyContext = addCombinator( function( elem ) { + return indexOf.call( checkContext, elem ) > -1; + }, implicitRelative, true ), + matchers = [ function( elem, context, xml ) { + return ( !leadingRelative && ( xml || context !== outermostContext ) ) || ( + (checkContext = context).nodeType ? + matchContext( elem, context, xml ) : + matchAnyContext( elem, context, xml ) ); + } ]; + + for ( ; i < len; i++ ) { + if ( (matcher = Expr.relative[ tokens[i].type ]) ) { + matchers = [ addCombinator( elementMatcher( matchers ), matcher ) ]; + } else { + matcher = Expr.filter[ tokens[i].type ].apply( null, tokens[i].matches ); + + // Return special upon seeing a positional matcher + if ( matcher[ expando ] ) { + // Find the next relative operator (if any) for proper handling + j = ++i; + for ( ; j < len; j++ ) { + if ( Expr.relative[ tokens[j].type ] ) { + break; + } + } + return setMatcher( + i > 1 && elementMatcher( matchers ), + i > 1 && tokens.slice( 0, i - 1 ).join("").replace( rtrim, "$1" ), + matcher, + i < j && matcherFromTokens( tokens.slice( i, j ) ), + j < len && matcherFromTokens( (tokens = tokens.slice( j )) ), + j < len && tokens.join("") + ); + } + matchers.push( matcher ); + } + } + + return elementMatcher( matchers ); +} + +function matcherFromGroupMatchers( elementMatchers, setMatchers ) { + var bySet = setMatchers.length > 0, + byElement = elementMatchers.length > 0, + superMatcher = function( seed, context, xml, results, expandContext ) { + var elem, j, matcher, + setMatched = [], + matchedCount = 0, + i = "0", + unmatched = seed && [], + outermost = expandContext != null, + contextBackup = outermostContext, + // We must always have either seed elements or context + elems = seed || byElement && Expr.find["TAG"]( "*", expandContext && context.parentNode || context ), + // Nested matchers should use non-integer dirruns + dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.E); + + if ( outermost ) { + outermostContext = context !== document && context; + cachedruns = superMatcher.el; + } + + // Add elements passing elementMatchers directly to results + for ( ; (elem = elems[i]) != null; i++ ) { + if ( byElement && elem ) { + for ( j = 0; (matcher = elementMatchers[j]); j++ ) { + if ( matcher( elem, context, xml ) ) { + results.push( elem ); + break; + } + } + if ( outermost ) { + dirruns = dirrunsUnique; + cachedruns = ++superMatcher.el; + } + } + + // Track unmatched elements for set filters + if ( bySet ) { + // They will have gone through all possible matchers + if ( (elem = !matcher && elem) ) { + matchedCount--; + } + + // Lengthen the array for every element, matched or not + if ( seed ) { + unmatched.push( elem ); + } + } + } + + // Apply set filters to unmatched elements + matchedCount += i; + if ( bySet && i !== matchedCount ) { + for ( j = 0; (matcher = setMatchers[j]); j++ ) { + matcher( unmatched, setMatched, context, xml ); + } + + if ( seed ) { + // Reintegrate element matches to eliminate the need for sorting + if ( matchedCount > 0 ) { + while ( i-- ) { + if ( !(unmatched[i] || setMatched[i]) ) { + setMatched[i] = pop.call( results ); + } + } + } + + // Discard index placeholder values to get only actual matches + setMatched = condense( setMatched ); + } + + // Add matches to results + push.apply( results, setMatched ); + + // Seedless set matches succeeding multiple successful matchers stipulate sorting + if ( outermost && !seed && setMatched.length > 0 && + ( matchedCount + setMatchers.length ) > 1 ) { + + Sizzle.uniqueSort( results ); + } + } + + // Override manipulation of globals by nested matchers + if ( outermost ) { + dirruns = dirrunsUnique; + outermostContext = contextBackup; + } + + return unmatched; + }; + + superMatcher.el = 0; + return bySet ? + markFunction( superMatcher ) : + superMatcher; +} + +compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) { + var i, + setMatchers = [], + elementMatchers = [], + cached = compilerCache[ expando ][ selector + " " ]; + + if ( !cached ) { + // Generate a function of recursive functions that can be used to check each element + if ( !group ) { + group = tokenize( selector ); + } + i = group.length; + while ( i-- ) { + cached = matcherFromTokens( group[i] ); + if ( cached[ expando ] ) { + setMatchers.push( cached ); + } else { + elementMatchers.push( cached ); + } + } + + // Cache the compiled function + cached = compilerCache( selector, matcherFromGroupMatchers( elementMatchers, setMatchers ) ); + } + return cached; +}; + +function multipleContexts( selector, contexts, results ) { + var i = 0, + len = contexts.length; + for ( ; i < len; i++ ) { + Sizzle( selector, contexts[i], results ); + } + return results; +} + +function select( selector, context, results, seed, xml ) { + var i, tokens, token, type, find, + match = tokenize( selector ), + j = match.length; + + if ( !seed ) { + // Try to minimize operations if there is only one group + if ( match.length === 1 ) { + + // Take a shortcut and set the context if the root selector is an ID + tokens = match[0] = match[0].slice( 0 ); + if ( tokens.length > 2 && (token = tokens[0]).type === "ID" && + context.nodeType === 9 && !xml && + Expr.relative[ tokens[1].type ] ) { + + context = Expr.find["ID"]( token.matches[0].replace( rbackslash, "" ), context, xml )[0]; + if ( !context ) { + return results; + } + + selector = selector.slice( tokens.shift().length ); + } + + // Fetch a seed set for right-to-left matching + for ( i = matchExpr["POS"].test( selector ) ? -1 : tokens.length - 1; i >= 0; i-- ) { + token = tokens[i]; + + // Abort if we hit a combinator + if ( Expr.relative[ (type = token.type) ] ) { + break; + } + if ( (find = Expr.find[ type ]) ) { + // Search, expanding context for leading sibling combinators + if ( (seed = find( + token.matches[0].replace( rbackslash, "" ), + rsibling.test( tokens[0].type ) && context.parentNode || context, + xml + )) ) { + + // If seed is empty or no tokens remain, we can return early + tokens.splice( i, 1 ); + selector = seed.length && tokens.join(""); + if ( !selector ) { + push.apply( results, slice.call( seed, 0 ) ); + return results; + } + + break; + } + } + } + } + } + + // Compile and execute a filtering function + // Provide `match` to avoid retokenization if we modified the selector above + compile( selector, match )( + seed, + context, + xml, + results, + rsibling.test( selector ) + ); + return results; +} + +if ( document.querySelectorAll ) { + (function() { + var disconnectedMatch, + oldSelect = select, + rescape = /'|\\/g, + rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g, + + // qSa(:focus) reports false when true (Chrome 21), no need to also add to buggyMatches since matches checks buggyQSA + // A support test would require too much code (would include document ready) + rbuggyQSA = [ ":focus" ], + + // matchesSelector(:active) reports false when true (IE9/Opera 11.5) + // A support test would require too much code (would include document ready) + // just skip matchesSelector for :active + rbuggyMatches = [ ":active" ], + matches = docElem.matchesSelector || + docElem.mozMatchesSelector || + docElem.webkitMatchesSelector || + docElem.oMatchesSelector || + docElem.msMatchesSelector; + + // Build QSA regex + // Regex strategy adopted from Diego Perini + assert(function( div ) { + // Select is set to empty string on purpose + // This is to test IE's treatment of not explictly + // setting a boolean content attribute, + // since its presence should be enough + // http://bugs.jquery.com/ticket/12359 + div.innerHTML = ""; + + // IE8 - Some boolean attributes are not treated correctly + if ( !div.querySelectorAll("[selected]").length ) { + rbuggyQSA.push( "\\[" + whitespace + "*(?:checked|disabled|ismap|multiple|readonly|selected|value)" ); + } + + // Webkit/Opera - :checked should return selected option elements + // http://www.w3.org/TR/2011/REC-css3-selectors-20110929/#checked + // IE8 throws error here (do not put tests after this one) + if ( !div.querySelectorAll(":checked").length ) { + rbuggyQSA.push(":checked"); + } + }); + + assert(function( div ) { + + // Opera 10-12/IE9 - ^= $= *= and empty values + // Should not select anything + div.innerHTML = "

"; + if ( div.querySelectorAll("[test^='']").length ) { + rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" ); + } + + // FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled) + // IE8 throws error here (do not put tests after this one) + div.innerHTML = ""; + if ( !div.querySelectorAll(":enabled").length ) { + rbuggyQSA.push(":enabled", ":disabled"); + } + }); + + // rbuggyQSA always contains :focus, so no need for a length check + rbuggyQSA = /* rbuggyQSA.length && */ new RegExp( rbuggyQSA.join("|") ); + + select = function( selector, context, results, seed, xml ) { + // Only use querySelectorAll when not filtering, + // when this is not xml, + // and when no QSA bugs apply + if ( !seed && !xml && !rbuggyQSA.test( selector ) ) { + var groups, i, + old = true, + nid = expando, + newContext = context, + newSelector = context.nodeType === 9 && selector; + + // qSA works strangely on Element-rooted queries + // We can work around this by specifying an extra ID on the root + // and working up from there (Thanks to Andrew Dupont for the technique) + // IE 8 doesn't work on object elements + if ( context.nodeType === 1 && context.nodeName.toLowerCase() !== "object" ) { + groups = tokenize( selector ); + + if ( (old = context.getAttribute("id")) ) { + nid = old.replace( rescape, "\\$&" ); + } else { + context.setAttribute( "id", nid ); + } + nid = "[id='" + nid + "'] "; + + i = groups.length; + while ( i-- ) { + groups[i] = nid + groups[i].join(""); + } + newContext = rsibling.test( selector ) && context.parentNode || context; + newSelector = groups.join(","); + } + + if ( newSelector ) { + try { + push.apply( results, slice.call( newContext.querySelectorAll( + newSelector + ), 0 ) ); + return results; + } catch(qsaError) { + } finally { + if ( !old ) { + context.removeAttribute("id"); + } + } + } + } + + return oldSelect( selector, context, results, seed, xml ); + }; + + if ( matches ) { + assert(function( div ) { + // Check to see if it's possible to do matchesSelector + // on a disconnected node (IE 9) + disconnectedMatch = matches.call( div, "div" ); + + // This should fail with an exception + // Gecko does not error, returns false instead + try { + matches.call( div, "[test!='']:sizzle" ); + rbuggyMatches.push( "!=", pseudos ); + } catch ( e ) {} + }); + + // rbuggyMatches always contains :active and :focus, so no need for a length check + rbuggyMatches = /* rbuggyMatches.length && */ new RegExp( rbuggyMatches.join("|") ); + + Sizzle.matchesSelector = function( elem, expr ) { + // Make sure that attribute selectors are quoted + expr = expr.replace( rattributeQuotes, "='$1']" ); + + // rbuggyMatches always contains :active, so no need for an existence check + if ( !isXML( elem ) && !rbuggyMatches.test( expr ) && !rbuggyQSA.test( expr ) ) { + try { + var ret = matches.call( elem, expr ); + + // IE 9's matchesSelector returns false on disconnected nodes + if ( ret || disconnectedMatch || + // As well, disconnected nodes are said to be in a document + // fragment in IE 9 + elem.document && elem.document.nodeType !== 11 ) { + return ret; + } + } catch(e) {} + } + + return Sizzle( expr, null, null, [ elem ] ).length > 0; + }; + } + })(); +} + +// Deprecated +Expr.pseudos["nth"] = Expr.pseudos["eq"]; + +// Back-compat +function setFilters() {} +Expr.filters = setFilters.prototype = Expr.pseudos; +Expr.setFilters = new setFilters(); + +// Override sizzle attribute retrieval +Sizzle.attr = jQuery.attr; +jQuery.find = Sizzle; +jQuery.expr = Sizzle.selectors; +jQuery.expr[":"] = jQuery.expr.pseudos; +jQuery.unique = Sizzle.uniqueSort; +jQuery.text = Sizzle.getText; +jQuery.isXMLDoc = Sizzle.isXML; +jQuery.contains = Sizzle.contains; + + +})( window ); +var runtil = /Until$/, + rparentsprev = /^(?:parents|prev(?:Until|All))/, + isSimple = /^.[^:#\[\.,]*$/, + rneedsContext = jQuery.expr.match.needsContext, + // methods guaranteed to produce a unique set when starting from a unique set + guaranteedUnique = { + children: true, + contents: true, + next: true, + prev: true + }; + +jQuery.fn.extend({ + find: function( selector ) { + var i, l, length, n, r, ret, + self = this; + + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + ret = this.pushStack( "", "find", selector ); + + for ( i = 0, l = this.length; i < l; i++ ) { + length = ret.length; + jQuery.find( selector, this[i], ret ); + + if ( i > 0 ) { + // Make sure that the results are unique + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { + if ( ret[r] === ret[n] ) { + ret.splice(n--, 1); + break; + } + } + } + } + } + + return ret; + }, + + has: function( target ) { + var i, + targets = jQuery( target, this ), + len = targets.length; + + return this.filter(function() { + for ( i = 0; i < len; i++ ) { + if ( jQuery.contains( this, targets[i] ) ) { + return true; + } + } + }); + }, + + not: function( selector ) { + return this.pushStack( winnow(this, selector, false), "not", selector); + }, + + filter: function( selector ) { + return this.pushStack( winnow(this, selector, true), "filter", selector ); + }, + + is: function( selector ) { + return !!selector && ( + typeof selector === "string" ? + // If this is a positional/relative selector, check membership in the returned set + // so $("p:first").is("p:last") won't return true for a doc with two "p". + rneedsContext.test( selector ) ? + jQuery( selector, this.context ).index( this[0] ) >= 0 : + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); + }, + + closest: function( selectors, context ) { + var cur, + i = 0, + l = this.length, + ret = [], + pos = rneedsContext.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; + + for ( ; i < l; i++ ) { + cur = this[i]; + + while ( cur && cur.ownerDocument && cur !== context && cur.nodeType !== 11 ) { + if ( pos ? pos.index(cur) > -1 : jQuery.find.matchesSelector(cur, selectors) ) { + ret.push( cur ); + break; + } + cur = cur.parentNode; + } + } + + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; + + return this.pushStack( ret, "closest", selectors ); + }, + + // Determine the position of an element within + // the matched set of elements + index: function( elem ) { + + // No argument, return index in parent + if ( !elem ) { + return ( this[0] && this[0].parentNode ) ? this.prevAll().length : -1; + } + + // index in selector + if ( typeof elem === "string" ) { + return jQuery.inArray( this[0], jQuery( elem ) ); + } + + // Locate the position of the desired element + return jQuery.inArray( + // If it receives a jQuery object, the first element is used + elem.jquery ? elem[0] : elem, this ); + }, + + add: function( selector, context ) { + var set = typeof selector === "string" ? + jQuery( selector, context ) : + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), + all = jQuery.merge( this.get(), set ); + + return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? + all : + jQuery.unique( all ) ); + }, + + addBack: function( selector ) { + return this.add( selector == null ? + this.prevObject : this.prevObject.filter(selector) + ); + } +}); + +jQuery.fn.andSelf = jQuery.fn.addBack; + +// A painfully simple check to see if an element is disconnected +// from a document (should be improved, where feasible). +function isDisconnected( node ) { + return !node || !node.parentNode || node.parentNode.nodeType === 11; +} + +function sibling( cur, dir ) { + do { + cur = cur[ dir ]; + } while ( cur && cur.nodeType !== 1 ); + + return cur; +} + +jQuery.each({ + parent: function( elem ) { + var parent = elem.parentNode; + return parent && parent.nodeType !== 11 ? parent : null; + }, + parents: function( elem ) { + return jQuery.dir( elem, "parentNode" ); + }, + parentsUntil: function( elem, i, until ) { + return jQuery.dir( elem, "parentNode", until ); + }, + next: function( elem ) { + return sibling( elem, "nextSibling" ); + }, + prev: function( elem ) { + return sibling( elem, "previousSibling" ); + }, + nextAll: function( elem ) { + return jQuery.dir( elem, "nextSibling" ); + }, + prevAll: function( elem ) { + return jQuery.dir( elem, "previousSibling" ); + }, + nextUntil: function( elem, i, until ) { + return jQuery.dir( elem, "nextSibling", until ); + }, + prevUntil: function( elem, i, until ) { + return jQuery.dir( elem, "previousSibling", until ); + }, + siblings: function( elem ) { + return jQuery.sibling( ( elem.parentNode || {} ).firstChild, elem ); + }, + children: function( elem ) { + return jQuery.sibling( elem.firstChild ); + }, + contents: function( elem ) { + return jQuery.nodeName( elem, "iframe" ) ? + elem.contentDocument || elem.contentWindow.document : + jQuery.merge( [], elem.childNodes ); + } +}, function( name, fn ) { + jQuery.fn[ name ] = function( until, selector ) { + var ret = jQuery.map( this, fn, until ); + + if ( !runtil.test( name ) ) { + selector = until; + } + + if ( selector && typeof selector === "string" ) { + ret = jQuery.filter( selector, ret ); + } + + ret = this.length > 1 && !guaranteedUnique[ name ] ? jQuery.unique( ret ) : ret; + + if ( this.length > 1 && rparentsprev.test( name ) ) { + ret = ret.reverse(); + } + + return this.pushStack( ret, name, core_slice.call( arguments ).join(",") ); + }; +}); + +jQuery.extend({ + filter: function( expr, elems, not ) { + if ( not ) { + expr = ":not(" + expr + ")"; + } + + return elems.length === 1 ? + jQuery.find.matchesSelector(elems[0], expr) ? [ elems[0] ] : [] : + jQuery.find.matches(expr, elems); + }, + + dir: function( elem, dir, until ) { + var matched = [], + cur = elem[ dir ]; + + while ( cur && cur.nodeType !== 9 && (until === undefined || cur.nodeType !== 1 || !jQuery( cur ).is( until )) ) { + if ( cur.nodeType === 1 ) { + matched.push( cur ); + } + cur = cur[dir]; + } + return matched; + }, + + sibling: function( n, elem ) { + var r = []; + + for ( ; n; n = n.nextSibling ) { + if ( n.nodeType === 1 && n !== elem ) { + r.push( n ); + } + } + + return r; + } +}); + +// Implement the identical functionality for filter and not +function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + + if ( jQuery.isFunction( qualifier ) ) { + return jQuery.grep(elements, function( elem, i ) { + var retVal = !!qualifier.call( elem, i, elem ); + return retVal === keep; + }); + + } else if ( qualifier.nodeType ) { + return jQuery.grep(elements, function( elem, i ) { + return ( elem === qualifier ) === keep; + }); + + } else if ( typeof qualifier === "string" ) { + var filtered = jQuery.grep(elements, function( elem ) { + return elem.nodeType === 1; + }); + + if ( isSimple.test( qualifier ) ) { + return jQuery.filter(qualifier, filtered, !keep); + } else { + qualifier = jQuery.filter( qualifier, filtered ); + } + } + + return jQuery.grep(elements, function( elem, i ) { + return ( jQuery.inArray( elem, qualifier ) >= 0 ) === keep; + }); +} +function createSafeFragment( document ) { + var list = nodeNames.split( "|" ), + safeFrag = document.createDocumentFragment(); + + if ( safeFrag.createElement ) { + while ( list.length ) { + safeFrag.createElement( + list.pop() + ); + } + } + return safeFrag; +} + +var nodeNames = "abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|" + + "header|hgroup|mark|meter|nav|output|progress|section|summary|time|video", + rinlinejQuery = / jQuery\d+="(?:null|\d+)"/g, + rleadingWhitespace = /^\s+/, + rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi, + rtagName = /<([\w:]+)/, + rtbody = /]", "i"), + rcheckableType = /^(?:checkbox|radio)$/, + // checked="checked" or checked + rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /\/(java|ecma)script/i, + rcleanScript = /^\s*\s*$/g, + wrapMap = { + option: [ 1, "" ], + legend: [ 1, "
", "
" ], + thead: [ 1, "", "
" ], + tr: [ 2, "", "
" ], + td: [ 3, "", "
" ], + col: [ 2, "", "
" ], + area: [ 1, "", "" ], + _default: [ 0, "", "" ] + }, + safeFragment = createSafeFragment( document ), + fragmentDiv = safeFragment.appendChild( document.createElement("div") ); + +wrapMap.optgroup = wrapMap.option; +wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead; +wrapMap.th = wrapMap.td; + +// IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags, +// unless wrapped in a div with non-breaking characters in front of it. +if ( !jQuery.support.htmlSerialize ) { + wrapMap._default = [ 1, "X
", "
" ]; +} + +jQuery.fn.extend({ + text: function( value ) { + return jQuery.access( this, function( value ) { + return value === undefined ? + jQuery.text( this ) : + this.empty().append( ( this[0] && this[0].ownerDocument || document ).createTextNode( value ) ); + }, null, value, arguments.length ); + }, + + wrapAll: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapAll( html.call(this, i) ); + }); + } + + if ( this[0] ) { + // The elements to wrap the target around + var wrap = jQuery( html, this[0].ownerDocument ).eq(0).clone(true); + + if ( this[0].parentNode ) { + wrap.insertBefore( this[0] ); + } + + wrap.map(function() { + var elem = this; + + while ( elem.firstChild && elem.firstChild.nodeType === 1 ) { + elem = elem.firstChild; + } + + return elem; + }).append( this ); + } + + return this; + }, + + wrapInner: function( html ) { + if ( jQuery.isFunction( html ) ) { + return this.each(function(i) { + jQuery(this).wrapInner( html.call(this, i) ); + }); + } + + return this.each(function() { + var self = jQuery( this ), + contents = self.contents(); + + if ( contents.length ) { + contents.wrapAll( html ); + + } else { + self.append( html ); + } + }); + }, + + wrap: function( html ) { + var isFunction = jQuery.isFunction( html ); + + return this.each(function(i) { + jQuery( this ).wrapAll( isFunction ? html.call(this, i) : html ); + }); + }, + + unwrap: function() { + return this.parent().each(function() { + if ( !jQuery.nodeName( this, "body" ) ) { + jQuery( this ).replaceWith( this.childNodes ); + } + }).end(); + }, + + append: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { + this.appendChild( elem ); + } + }); + }, + + prepend: function() { + return this.domManip(arguments, true, function( elem ) { + if ( this.nodeType === 1 || this.nodeType === 11 ) { + this.insertBefore( elem, this.firstChild ); + } + }); + }, + + before: function() { + if ( !isDisconnected( this[0] ) ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this ); + }); + } + + if ( arguments.length ) { + var set = jQuery.clean( arguments ); + return this.pushStack( jQuery.merge( set, this ), "before", this.selector ); + } + }, + + after: function() { + if ( !isDisconnected( this[0] ) ) { + return this.domManip(arguments, false, function( elem ) { + this.parentNode.insertBefore( elem, this.nextSibling ); + }); + } + + if ( arguments.length ) { + var set = jQuery.clean( arguments ); + return this.pushStack( jQuery.merge( this, set ), "after", this.selector ); + } + }, + + // keepData is for internal use only--do not document + remove: function( selector, keepData ) { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + if ( !selector || jQuery.filter( selector, [ elem ] ).length ) { + if ( !keepData && elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + jQuery.cleanData( [ elem ] ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + } + } + + return this; + }, + + empty: function() { + var elem, + i = 0; + + for ( ; (elem = this[i]) != null; i++ ) { + // Remove element nodes and prevent memory leaks + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName("*") ); + } + + // Remove any remaining nodes + while ( elem.firstChild ) { + elem.removeChild( elem.firstChild ); + } + } + + return this; + }, + + clone: function( dataAndEvents, deepDataAndEvents ) { + dataAndEvents = dataAndEvents == null ? false : dataAndEvents; + deepDataAndEvents = deepDataAndEvents == null ? dataAndEvents : deepDataAndEvents; + + return this.map( function () { + return jQuery.clone( this, dataAndEvents, deepDataAndEvents ); + }); + }, + + html: function( value ) { + return jQuery.access( this, function( value ) { + var elem = this[0] || {}, + i = 0, + l = this.length; + + if ( value === undefined ) { + return elem.nodeType === 1 ? + elem.innerHTML.replace( rinlinejQuery, "" ) : + undefined; + } + + // See if we can take a shortcut and just use innerHTML + if ( typeof value === "string" && !rnoInnerhtml.test( value ) && + ( jQuery.support.htmlSerialize || !rnoshimcache.test( value ) ) && + ( jQuery.support.leadingWhitespace || !rleadingWhitespace.test( value ) ) && + !wrapMap[ ( rtagName.exec( value ) || ["", ""] )[1].toLowerCase() ] ) { + + value = value.replace( rxhtmlTag, "<$1>" ); + + try { + for (; i < l; i++ ) { + // Remove element nodes and prevent memory leaks + elem = this[i] || {}; + if ( elem.nodeType === 1 ) { + jQuery.cleanData( elem.getElementsByTagName( "*" ) ); + elem.innerHTML = value; + } + } + + elem = 0; + + // If using innerHTML throws an exception, use the fallback method + } catch(e) {} + } + + if ( elem ) { + this.empty().append( value ); + } + }, null, value, arguments.length ); + }, + + replaceWith: function( value ) { + if ( !isDisconnected( this[0] ) ) { + // Make sure that the elements are removed from the DOM before they are inserted + // this can help fix replacing a parent with child elements + if ( jQuery.isFunction( value ) ) { + return this.each(function(i) { + var self = jQuery(this), old = self.html(); + self.replaceWith( value.call( this, i, old ) ); + }); + } + + if ( typeof value !== "string" ) { + value = jQuery( value ).detach(); + } + + return this.each(function() { + var next = this.nextSibling, + parent = this.parentNode; + + jQuery( this ).remove(); + + if ( next ) { + jQuery(next).before( value ); + } else { + jQuery(parent).append( value ); + } + }); + } + + return this.length ? + this.pushStack( jQuery(jQuery.isFunction(value) ? value() : value), "replaceWith", value ) : + this; + }, + + detach: function( selector ) { + return this.remove( selector, true ); + }, + + domManip: function( args, table, callback ) { + + // Flatten any nested arrays + args = [].concat.apply( [], args ); + + var results, first, fragment, iNoClone, + i = 0, + value = args[0], + scripts = [], + l = this.length; + + // We can't cloneNode fragments that contain checked, in WebKit + if ( !jQuery.support.checkClone && l > 1 && typeof value === "string" && rchecked.test( value ) ) { + return this.each(function() { + jQuery(this).domManip( args, table, callback ); + }); + } + + if ( jQuery.isFunction(value) ) { + return this.each(function(i) { + var self = jQuery(this); + args[0] = value.call( this, i, table ? self.html() : undefined ); + self.domManip( args, table, callback ); + }); + } + + if ( this[0] ) { + results = jQuery.buildFragment( args, this, scripts ); + fragment = results.fragment; + first = fragment.firstChild; + + if ( fragment.childNodes.length === 1 ) { + fragment = first; + } + + if ( first ) { + table = table && jQuery.nodeName( first, "tr" ); + + // Use the original fragment for the last item instead of the first because it can end up + // being emptied incorrectly in certain situations (#8070). + // Fragments from the fragment cache must always be cloned and never used in place. + for ( iNoClone = results.cacheable || l - 1; i < l; i++ ) { + callback.call( + table && jQuery.nodeName( this[i], "table" ) ? + findOrAppend( this[i], "tbody" ) : + this[i], + i === iNoClone ? + fragment : + jQuery.clone( fragment, true, true ) + ); + } + } + + // Fix #11809: Avoid leaking memory + fragment = first = null; + + if ( scripts.length ) { + jQuery.each( scripts, function( i, elem ) { + if ( elem.src ) { + if ( jQuery.ajax ) { + jQuery.ajax({ + url: elem.src, + type: "GET", + dataType: "script", + async: false, + global: false, + "throws": true + }); + } else { + jQuery.error("no ajax"); + } + } else { + jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "" ) ); + } + + if ( elem.parentNode ) { + elem.parentNode.removeChild( elem ); + } + }); + } + } + + return this; + } +}); + +function findOrAppend( elem, tag ) { + return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) ); +} + +function cloneCopyEvent( src, dest ) { + + if ( dest.nodeType !== 1 || !jQuery.hasData( src ) ) { + return; + } + + var type, i, l, + oldData = jQuery._data( src ), + curData = jQuery._data( dest, oldData ), + events = oldData.events; + + if ( events ) { + delete curData.handle; + curData.events = {}; + + for ( type in events ) { + for ( i = 0, l = events[ type ].length; i < l; i++ ) { + jQuery.event.add( dest, type, events[ type ][ i ] ); + } + } + } + + // make the cloned public data object a copy from the original + if ( curData.data ) { + curData.data = jQuery.extend( {}, curData.data ); + } +} + +function cloneFixAttributes( src, dest ) { + var nodeName; + + // We do not need to do anything for non-Elements + if ( dest.nodeType !== 1 ) { + return; + } + + // clearAttributes removes the attributes, which we don't want, + // but also removes the attachEvent events, which we *do* want + if ( dest.clearAttributes ) { + dest.clearAttributes(); + } + + // mergeAttributes, in contrast, only merges back on the + // original attributes, not the events + if ( dest.mergeAttributes ) { + dest.mergeAttributes( src ); + } + + nodeName = dest.nodeName.toLowerCase(); + + if ( nodeName === "object" ) { + // IE6-10 improperly clones children of object elements using classid. + // IE10 throws NoModificationAllowedError if parent is null, #12132. + if ( dest.parentNode ) { + dest.outerHTML = src.outerHTML; + } + + // This path appears unavoidable for IE9. When cloning an object + // element in IE9, the outerHTML strategy above is not sufficient. + // If the src has innerHTML and the destination does not, + // copy the src.innerHTML into the dest.innerHTML. #10324 + if ( jQuery.support.html5Clone && (src.innerHTML && !jQuery.trim(dest.innerHTML)) ) { + dest.innerHTML = src.innerHTML; + } + + } else if ( nodeName === "input" && rcheckableType.test( src.type ) ) { + // IE6-8 fails to persist the checked state of a cloned checkbox + // or radio button. Worse, IE6-7 fail to give the cloned element + // a checked appearance if the defaultChecked value isn't also set + + dest.defaultChecked = dest.checked = src.checked; + + // IE6-7 get confused and end up setting the value of a cloned + // checkbox/radio button to an empty string instead of "on" + if ( dest.value !== src.value ) { + dest.value = src.value; + } + + // IE6-8 fails to return the selected option to the default selected + // state when cloning options + } else if ( nodeName === "option" ) { + dest.selected = src.defaultSelected; + + // IE6-8 fails to set the defaultValue to the correct value when + // cloning other types of input fields + } else if ( nodeName === "input" || nodeName === "textarea" ) { + dest.defaultValue = src.defaultValue; + + // IE blanks contents when cloning scripts + } else if ( nodeName === "script" && dest.text !== src.text ) { + dest.text = src.text; + } + + // Event data gets referenced instead of copied if the expando + // gets copied too + dest.removeAttribute( jQuery.expando ); +} + +jQuery.buildFragment = function( args, context, scripts ) { + var fragment, cacheable, cachehit, + first = args[ 0 ]; + + // Set context from what may come in as undefined or a jQuery collection or a node + // Updated to fix #12266 where accessing context[0] could throw an exception in IE9/10 & + // also doubles as fix for #8950 where plain objects caused createDocumentFragment exception + context = context || document; + context = !context.nodeType && context[0] || context; + context = context.ownerDocument || context; + + // Only cache "small" (1/2 KB) HTML strings that are associated with the main document + // Cloning options loses the selected state, so don't cache them + // IE 6 doesn't like it when you put or elements in a fragment + // Also, WebKit does not clone 'checked' attributes on cloneNode, so don't cache + // Lastly, IE6,7,8 will not correctly reuse cached fragments that were created from unknown elems #10501 + if ( args.length === 1 && typeof first === "string" && first.length < 512 && context === document && + first.charAt(0) === "<" && !rnocache.test( first ) && + (jQuery.support.checkClone || !rchecked.test( first )) && + (jQuery.support.html5Clone || !rnoshimcache.test( first )) ) { + + // Mark cacheable and look for a hit + cacheable = true; + fragment = jQuery.fragments[ first ]; + cachehit = fragment !== undefined; + } + + if ( !fragment ) { + fragment = context.createDocumentFragment(); + jQuery.clean( args, context, fragment, scripts ); + + // Update the cache, but only store false + // unless this is a second parsing of the same content + if ( cacheable ) { + jQuery.fragments[ first ] = cachehit && fragment; + } + } + + return { fragment: fragment, cacheable: cacheable }; +}; + +jQuery.fragments = {}; + +jQuery.each({ + appendTo: "append", + prependTo: "prepend", + insertBefore: "before", + insertAfter: "after", + replaceAll: "replaceWith" +}, function( name, original ) { + jQuery.fn[ name ] = function( selector ) { + var elems, + i = 0, + ret = [], + insert = jQuery( selector ), + l = insert.length, + parent = this.length === 1 && this[0].parentNode; + + if ( (parent == null || parent && parent.nodeType === 11 && parent.childNodes.length === 1) && l === 1 ) { + insert[ original ]( this[0] ); + return this; + } else { + for ( ; i < l; i++ ) { + elems = ( i > 0 ? this.clone(true) : this ).get(); + jQuery( insert[i] )[ original ]( elems ); + ret = ret.concat( elems ); + } + + return this.pushStack( ret, name, insert.selector ); + } + }; +}); + +function getAll( elem ) { + if ( typeof elem.getElementsByTagName !== "undefined" ) { + return elem.getElementsByTagName( "*" ); + + } else if ( typeof elem.querySelectorAll !== "undefined" ) { + return elem.querySelectorAll( "*" ); + + } else { + return []; + } +} + +// Used in clean, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( rcheckableType.test( elem.type ) ) { + elem.defaultChecked = elem.checked; + } +} + +jQuery.extend({ + clone: function( elem, dataAndEvents, deepDataAndEvents ) { + var srcElements, + destElements, + i, + clone; + + if ( jQuery.support.html5Clone || jQuery.isXMLDoc(elem) || !rnoshimcache.test( "<" + elem.nodeName + ">" ) ) { + clone = elem.cloneNode( true ); + + // IE<=8 does not properly clone detached, unknown element nodes + } else { + fragmentDiv.innerHTML = elem.outerHTML; + fragmentDiv.removeChild( clone = fragmentDiv.firstChild ); + } + + if ( (!jQuery.support.noCloneEvent || !jQuery.support.noCloneChecked) && + (elem.nodeType === 1 || elem.nodeType === 11) && !jQuery.isXMLDoc(elem) ) { + // IE copies events bound via attachEvent when using cloneNode. + // Calling detachEvent on the clone will also remove the events + // from the original. In order to get around this, we use some + // proprietary methods to clear the events. Thanks to MooTools + // guys for this hotness. + + cloneFixAttributes( elem, clone ); + + // Using Sizzle here is crazy slow, so we use getElementsByTagName instead + srcElements = getAll( elem ); + destElements = getAll( clone ); + + // Weird iteration because IE will replace the length property + // with an element if you are cloning the body and one of the + // elements on the page has a name or id of "length" + for ( i = 0; srcElements[i]; ++i ) { + // Ensure that the destination node is not null; Fixes #9587 + if ( destElements[i] ) { + cloneFixAttributes( srcElements[i], destElements[i] ); + } + } + } + + // Copy the events from the original to the clone + if ( dataAndEvents ) { + cloneCopyEvent( elem, clone ); + + if ( deepDataAndEvents ) { + srcElements = getAll( elem ); + destElements = getAll( clone ); + + for ( i = 0; srcElements[i]; ++i ) { + cloneCopyEvent( srcElements[i], destElements[i] ); + } + } + } + + srcElements = destElements = null; + + // Return the cloned set + return clone; + }, + + clean: function( elems, context, fragment, scripts ) { + var i, j, elem, tag, wrap, depth, div, hasBody, tbody, len, handleScript, jsTags, + safe = context === document && safeFragment, + ret = []; + + // Ensure that context is a document + if ( !context || typeof context.createDocumentFragment === "undefined" ) { + context = document; + } + + // Use the already-created safe fragment if context permits + for ( i = 0; (elem = elems[i]) != null; i++ ) { + if ( typeof elem === "number" ) { + elem += ""; + } + + if ( !elem ) { + continue; + } + + // Convert html string into DOM nodes + if ( typeof elem === "string" ) { + if ( !rhtml.test( elem ) ) { + elem = context.createTextNode( elem ); + } else { + // Ensure a safe container in which to render the html + safe = safe || createSafeFragment( context ); + div = context.createElement("div"); + safe.appendChild( div ); + + // Fix "XHTML"-style tags in all browsers + elem = elem.replace(rxhtmlTag, "<$1>"); + + // Go to html and back, then peel off extra wrappers + tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase(); + wrap = wrapMap[ tag ] || wrapMap._default; + depth = wrap[0]; + div.innerHTML = wrap[1] + elem + wrap[2]; + + // Move to the right depth + while ( depth-- ) { + div = div.lastChild; + } + + // Remove IE's autoinserted from table fragments + if ( !jQuery.support.tbody ) { + + // String was a , *may* have spurious + hasBody = rtbody.test(elem); + tbody = tag === "table" && !hasBody ? + div.firstChild && div.firstChild.childNodes : + + // String was a bare or + wrap[1] === "
" && !hasBody ? + div.childNodes : + []; + + for ( j = tbody.length - 1; j >= 0 ; --j ) { + if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { + tbody[ j ].parentNode.removeChild( tbody[ j ] ); + } + } + } + + // IE completely kills leading whitespace when innerHTML is used + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); + } + + elem = div.childNodes; + + // Take out of fragment container (we need a fresh div each time) + div.parentNode.removeChild( div ); + } + } + + if ( elem.nodeType ) { + ret.push( elem ); + } else { + jQuery.merge( ret, elem ); + } + } + + // Fix #11356: Clear elements from safeFragment + if ( div ) { + elem = div = safe = null; + } + + // Reset defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + if ( !jQuery.support.appendChecked ) { + for ( i = 0; (elem = ret[i]) != null; i++ ) { + if ( jQuery.nodeName( elem, "input" ) ) { + fixDefaultChecked( elem ); + } else if ( typeof elem.getElementsByTagName !== "undefined" ) { + jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); + } + } + } + + // Append elements to a provided document fragment + if ( fragment ) { + // Special handling of each script element + handleScript = function( elem ) { + // Check if we consider it executable + if ( !elem.type || rscriptType.test( elem.type ) ) { + // Detach the script and store it in the scripts array (if provided) or the fragment + // Return truthy to indicate that it has been handled + return scripts ? + scripts.push( elem.parentNode ? elem.parentNode.removeChild( elem ) : elem ) : + fragment.appendChild( elem ); + } + }; + + for ( i = 0; (elem = ret[i]) != null; i++ ) { + // Check if we're done after handling an executable script + if ( !( jQuery.nodeName( elem, "script" ) && handleScript( elem ) ) ) { + // Append to fragment and handle embedded scripts + fragment.appendChild( elem ); + if ( typeof elem.getElementsByTagName !== "undefined" ) { + // handleScript alters the DOM, so use jQuery.merge to ensure snapshot iteration + jsTags = jQuery.grep( jQuery.merge( [], elem.getElementsByTagName("script") ), handleScript ); + + // Splice the scripts into ret after their former ancestor and advance our index beyond them + ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); + i += jsTags.length; + } + } + } + } + + return ret; + }, + + cleanData: function( elems, /* internal */ acceptData ) { + var data, id, elem, type, + i = 0, + internalKey = jQuery.expando, + cache = jQuery.cache, + deleteExpando = jQuery.support.deleteExpando, + special = jQuery.event.special; + + for ( ; (elem = elems[i]) != null; i++ ) { + + if ( acceptData || jQuery.acceptData( elem ) ) { + + id = elem[ internalKey ]; + data = id && cache[ id ]; + + if ( data ) { + if ( data.events ) { + for ( type in data.events ) { + if ( special[ type ] ) { + jQuery.event.remove( elem, type ); + + // This is a shortcut to avoid jQuery.event.remove's overhead + } else { + jQuery.removeEvent( elem, type, data.handle ); + } + } + } + + // Remove cache only if it was not already removed by jQuery.event.remove + if ( cache[ id ] ) { + + delete cache[ id ]; + + // IE does not allow us to delete expando properties from nodes, + // nor does it have a removeAttribute function on Document nodes; + // we must handle all of these cases + if ( deleteExpando ) { + delete elem[ internalKey ]; + + } else if ( elem.removeAttribute ) { + elem.removeAttribute( internalKey ); + + } else { + elem[ internalKey ] = null; + } + + jQuery.deletedIds.push( id ); + } + } + } + } + } +}); +// Limit scope pollution from any deprecated API +(function() { + +var matched, browser; + +// Use of jQuery.browser is frowned upon. +// More details: http://api.jquery.com/jQuery.browser +// jQuery.uaMatch maintained for back-compat +jQuery.uaMatch = function( ua ) { + ua = ua.toLowerCase(); + + var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) || + /(webkit)[ \/]([\w.]+)/.exec( ua ) || + /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) || + /(msie) ([\w.]+)/.exec( ua ) || + ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) || + []; + + return { + browser: match[ 1 ] || "", + version: match[ 2 ] || "0" + }; +}; + +matched = jQuery.uaMatch( navigator.userAgent ); +browser = {}; + +if ( matched.browser ) { + browser[ matched.browser ] = true; + browser.version = matched.version; +} + +// Chrome is Webkit, but Webkit is also Safari. +if ( browser.chrome ) { + browser.webkit = true; +} else if ( browser.webkit ) { + browser.safari = true; +} + +jQuery.browser = browser; + +jQuery.sub = function() { + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); + } + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); + } + + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); + }; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; +}; + +})(); +var curCSS, iframe, iframeDoc, + ralpha = /alpha\([^)]*\)/i, + ropacity = /opacity=([^)]*)/, + rposition = /^(top|right|bottom|left)$/, + // swappable if display is none or starts with table except "table", "table-cell", or "table-caption" + // see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display + rdisplayswap = /^(none|table(?!-c[ea]).+)/, + rmargin = /^margin/, + rnumsplit = new RegExp( "^(" + core_pnum + ")(.*)$", "i" ), + rnumnonpx = new RegExp( "^(" + core_pnum + ")(?!px)[a-z%]+$", "i" ), + rrelNum = new RegExp( "^([-+])=(" + core_pnum + ")", "i" ), + elemdisplay = { BODY: "block" }, + + cssShow = { position: "absolute", visibility: "hidden", display: "block" }, + cssNormalTransform = { + letterSpacing: 0, + fontWeight: 400 + }, + + cssExpand = [ "Top", "Right", "Bottom", "Left" ], + cssPrefixes = [ "Webkit", "O", "Moz", "ms" ], + + eventsToggle = jQuery.fn.toggle; + +// return a css property mapped to a potentially vendor prefixed property +function vendorPropName( style, name ) { + + // shortcut for names that are not vendor prefixed + if ( name in style ) { + return name; + } + + // check for vendor prefixed names + var capName = name.charAt(0).toUpperCase() + name.slice(1), + origName = name, + i = cssPrefixes.length; + + while ( i-- ) { + name = cssPrefixes[ i ] + capName; + if ( name in style ) { + return name; + } + } + + return origName; +} + +function isHidden( elem, el ) { + elem = el || elem; + return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem ); +} + +function showHide( elements, show ) { + var elem, display, + values = [], + index = 0, + length = elements.length; + + for ( ; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + values[ index ] = jQuery._data( elem, "olddisplay" ); + if ( show ) { + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !values[ index ] && elem.style.display === "none" ) { + elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( elem.style.display === "" && isHidden( elem ) ) { + values[ index ] = jQuery._data( elem, "olddisplay", css_defaultDisplay(elem.nodeName) ); + } + } else { + display = curCSS( elem, "display" ); + + if ( !values[ index ] && display !== "none" ) { + jQuery._data( elem, "olddisplay", display ); + } + } + } + + // Set the display of most of the elements in a second loop + // to avoid the constant reflow + for ( index = 0; index < length; index++ ) { + elem = elements[ index ]; + if ( !elem.style ) { + continue; + } + if ( !show || elem.style.display === "none" || elem.style.display === "" ) { + elem.style.display = show ? values[ index ] || "" : "none"; + } + } + + return elements; +} + +jQuery.fn.extend({ + css: function( name, value ) { + return jQuery.access( this, function( elem, name, value ) { + return value !== undefined ? + jQuery.style( elem, name, value ) : + jQuery.css( elem, name ); + }, name, value, arguments.length > 1 ); + }, + show: function() { + return showHide( this, true ); + }, + hide: function() { + return showHide( this ); + }, + toggle: function( state, fn2 ) { + var bool = typeof state === "boolean"; + + if ( jQuery.isFunction( state ) && jQuery.isFunction( fn2 ) ) { + return eventsToggle.apply( this, arguments ); + } + + return this.each(function() { + if ( bool ? state : isHidden( this ) ) { + jQuery( this ).show(); + } else { + jQuery( this ).hide(); + } + }); + } +}); + +jQuery.extend({ + // Add in style property hooks for overriding the default + // behavior of getting and setting a style property + cssHooks: { + opacity: { + get: function( elem, computed ) { + if ( computed ) { + // We should always get a number back from opacity + var ret = curCSS( elem, "opacity" ); + return ret === "" ? "1" : ret; + + } + } + } + }, + + // Exclude the following css properties to add px + cssNumber: { + "fillOpacity": true, + "fontWeight": true, + "lineHeight": true, + "opacity": true, + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true + }, + + // Add in properties whose names you wish to fix before + // setting or getting the value + cssProps: { + // normalize float css property + "float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" + }, + + // Get and set the style property on a DOM Node + style: function( elem, name, value, extra ) { + // Don't set styles on text and comment nodes + if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style ) { + return; + } + + // Make sure that we're working with the right name + var ret, type, hooks, + origName = jQuery.camelCase( name ), + style = elem.style; + + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // Check if we're setting a value + if ( value !== undefined ) { + type = typeof value; + + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && (ret = rrelNum.exec( value )) ) { + value = ( ret[1] + 1 ) * ret[2] + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + + // Make sure that NaN and null values aren't set. See: #7116 + if ( value == null || type === "number" && isNaN( value ) ) { + return; + } + + // If a number was passed in, add 'px' to the (except for certain CSS properties) + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { + value += "px"; + } + + // If a hook was provided, use that value, otherwise just set the specified value + if ( !hooks || !("set" in hooks) || (value = hooks.set( elem, value, extra )) !== undefined ) { + // Wrapped to prevent IE from throwing errors when 'invalid' values are provided + // Fixes bug #5509 + try { + style[ name ] = value; + } catch(e) {} + } + + } else { + // If a hook was provided get the non-computed value from there + if ( hooks && "get" in hooks && (ret = hooks.get( elem, false, extra )) !== undefined ) { + return ret; + } + + // Otherwise just get the value from the style object + return style[ name ]; + } + }, + + css: function( elem, name, numeric, extra ) { + var val, num, hooks, + origName = jQuery.camelCase( name ); + + // Make sure that we're working with the right name + name = jQuery.cssProps[ origName ] || ( jQuery.cssProps[ origName ] = vendorPropName( elem.style, origName ) ); + + // gets hook for the prefixed version + // followed by the unprefixed version + hooks = jQuery.cssHooks[ name ] || jQuery.cssHooks[ origName ]; + + // If a hook was provided get the computed value from there + if ( hooks && "get" in hooks ) { + val = hooks.get( elem, true, extra ); + } + + // Otherwise, if a way to get the computed value exists, use that + if ( val === undefined ) { + val = curCSS( elem, name ); + } + + //convert "normal" to computed value + if ( val === "normal" && name in cssNormalTransform ) { + val = cssNormalTransform[ name ]; + } + + // Return, converting to number if forced or a qualifier was provided and val looks numeric + if ( numeric || extra !== undefined ) { + num = parseFloat( val ); + return numeric || jQuery.isNumeric( num ) ? num || 0 : val; + } + return val; + }, + + // A method for quickly swapping in/out CSS properties to get correct calculations + swap: function( elem, options, callback ) { + var ret, name, + old = {}; + + // Remember the old values, and insert the new ones + for ( name in options ) { + old[ name ] = elem.style[ name ]; + elem.style[ name ] = options[ name ]; + } + + ret = callback.call( elem ); + + // Revert the old values + for ( name in options ) { + elem.style[ name ] = old[ name ]; + } + + return ret; + } +}); + +// NOTE: To any future maintainer, we've window.getComputedStyle +// because jsdom on node.js will break without it. +if ( window.getComputedStyle ) { + curCSS = function( elem, name ) { + var ret, width, minWidth, maxWidth, + computed = window.getComputedStyle( elem, null ), + style = elem.style; + + if ( computed ) { + + // getPropertyValue is only needed for .css('filter') in IE9, see #12537 + ret = computed.getPropertyValue( name ) || computed[ name ]; + + if ( ret === "" && !jQuery.contains( elem.ownerDocument, elem ) ) { + ret = jQuery.style( elem, name ); + } + + // A tribute to the "awesome hack by Dean Edwards" + // Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right + // Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels + // this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values + if ( rnumnonpx.test( ret ) && rmargin.test( name ) ) { + width = style.width; + minWidth = style.minWidth; + maxWidth = style.maxWidth; + + style.minWidth = style.maxWidth = style.width = ret; + ret = computed.width; + + style.width = width; + style.minWidth = minWidth; + style.maxWidth = maxWidth; + } + } + + return ret; + }; +} else if ( document.documentElement.currentStyle ) { + curCSS = function( elem, name ) { + var left, rsLeft, + ret = elem.currentStyle && elem.currentStyle[ name ], + style = elem.style; + + // Avoid setting ret to empty string here + // so we don't default to auto + if ( ret == null && style && style[ name ] ) { + ret = style[ name ]; + } + + // From the awesome hack by Dean Edwards + // http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 + + // If we're not dealing with a regular pixel number + // but a number that has a weird ending, we need to convert it to pixels + // but not position css attributes, as those are proportional to the parent element instead + // and we can't measure the parent instead because it might trigger a "stacking dolls" problem + if ( rnumnonpx.test( ret ) && !rposition.test( name ) ) { + + // Remember the original values + left = style.left; + rsLeft = elem.runtimeStyle && elem.runtimeStyle.left; + + // Put in the new values to get a computed value out + if ( rsLeft ) { + elem.runtimeStyle.left = elem.currentStyle.left; + } + style.left = name === "fontSize" ? "1em" : ret; + ret = style.pixelLeft + "px"; + + // Revert the changed values + style.left = left; + if ( rsLeft ) { + elem.runtimeStyle.left = rsLeft; + } + } + + return ret === "" ? "auto" : ret; + }; +} + +function setPositiveNumber( elem, value, subtract ) { + var matches = rnumsplit.exec( value ); + return matches ? + Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) : + value; +} + +function augmentWidthOrHeight( elem, name, extra, isBorderBox ) { + var i = extra === ( isBorderBox ? "border" : "content" ) ? + // If we already have the right measurement, avoid augmentation + 4 : + // Otherwise initialize for horizontal or vertical properties + name === "width" ? 1 : 0, + + val = 0; + + for ( ; i < 4; i += 2 ) { + // both box models exclude margin, so add it if we want it + if ( extra === "margin" ) { + // we use jQuery.css instead of curCSS here + // because of the reliableMarginRight CSS hook! + val += jQuery.css( elem, extra + cssExpand[ i ], true ); + } + + // From this point on we use curCSS for maximum performance (relevant in animations) + if ( isBorderBox ) { + // border-box includes padding, so remove it if we want content + if ( extra === "content" ) { + val -= parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + } + + // at this point, extra isn't border nor margin, so remove border + if ( extra !== "margin" ) { + val -= parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } else { + // at this point, extra isn't content, so add padding + val += parseFloat( curCSS( elem, "padding" + cssExpand[ i ] ) ) || 0; + + // at this point, extra isn't content nor padding, so add border + if ( extra !== "padding" ) { + val += parseFloat( curCSS( elem, "border" + cssExpand[ i ] + "Width" ) ) || 0; + } + } + } + + return val; +} + +function getWidthOrHeight( elem, name, extra ) { + + // Start with offset property, which is equivalent to the border-box value + var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + valueIsBorderBox = true, + isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box"; + + // some non-html elements return undefined for offsetWidth, so check for null/undefined + // svg - https://bugzilla.mozilla.org/show_bug.cgi?id=649285 + // MathML - https://bugzilla.mozilla.org/show_bug.cgi?id=491668 + if ( val <= 0 || val == null ) { + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name ); + if ( val < 0 || val == null ) { + val = elem.style[ name ]; + } + + // Computed unit is not pixels. Stop here and return. + if ( rnumnonpx.test(val) ) { + return val; + } + + // we need the check for style in case a browser which returns unreliable values + // for getComputedStyle silently falls back to the reliable elem.style + valueIsBorderBox = isBorderBox && ( jQuery.support.boxSizingReliable || val === elem.style[ name ] ); + + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; + } + + // use the active box-sizing model to add/subtract irrelevant styles + return ( val + + augmentWidthOrHeight( + elem, + name, + extra || ( isBorderBox ? "border" : "content" ), + valueIsBorderBox + ) + ) + "px"; +} + + +// Try to determine the default display value of an element +function css_defaultDisplay( nodeName ) { + if ( elemdisplay[ nodeName ] ) { + return elemdisplay[ nodeName ]; + } + + var elem = jQuery( "<" + nodeName + ">" ).appendTo( document.body ), + display = elem.css("display"); + elem.remove(); + + // If the simple way fails, + // get element's real default display by attaching it to a temp iframe + if ( display === "none" || display === "" ) { + // Use the already-created iframe if possible + iframe = document.body.appendChild( + iframe || jQuery.extend( document.createElement("iframe"), { + frameBorder: 0, + width: 0, + height: 0 + }) + ); + + // Create a cacheable copy of the iframe document on first call. + // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML + // document to it; WebKit & Firefox won't allow reusing the iframe document. + if ( !iframeDoc || !iframe.createElement ) { + iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; + iframeDoc.write(""); + iframeDoc.close(); + } + + elem = iframeDoc.body.appendChild( iframeDoc.createElement(nodeName) ); + + display = curCSS( elem, "display" ); + document.body.removeChild( iframe ); + } + + // Store the correct default display + elemdisplay[ nodeName ] = display; + + return display; +} + +jQuery.each([ "height", "width" ], function( i, name ) { + jQuery.cssHooks[ name ] = { + get: function( elem, computed, extra ) { + if ( computed ) { + // certain elements can have dimension info if we invisibly show them + // however, it must have a current display style that would benefit from this + if ( elem.offsetWidth === 0 && rdisplayswap.test( curCSS( elem, "display" ) ) ) { + return jQuery.swap( elem, cssShow, function() { + return getWidthOrHeight( elem, name, extra ); + }); + } else { + return getWidthOrHeight( elem, name, extra ); + } + } + }, + + set: function( elem, value, extra ) { + return setPositiveNumber( elem, value, extra ? + augmentWidthOrHeight( + elem, + name, + extra, + jQuery.support.boxSizing && jQuery.css( elem, "boxSizing" ) === "border-box" + ) : 0 + ); + } + }; +}); + +if ( !jQuery.support.opacity ) { + jQuery.cssHooks.opacity = { + get: function( elem, computed ) { + // IE uses filters for opacity + return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? + ( 0.01 * parseFloat( RegExp.$1 ) ) + "" : + computed ? "1" : ""; + }, + + set: function( elem, value ) { + var style = elem.style, + currentStyle = elem.currentStyle, + opacity = jQuery.isNumeric( value ) ? "alpha(opacity=" + value * 100 + ")" : "", + filter = currentStyle && currentStyle.filter || style.filter || ""; + + // IE has trouble with opacity if it does not have layout + // Force it by setting the zoom level + style.zoom = 1; + + // if setting opacity to 1, and no other filters exist - attempt to remove filter attribute #6652 + if ( value >= 1 && jQuery.trim( filter.replace( ralpha, "" ) ) === "" && + style.removeAttribute ) { + + // Setting style.filter to null, "" & " " still leave "filter:" in the cssText + // if "filter:" is present at all, clearType is disabled, we want to avoid this + // style.removeAttribute is IE Only, but so apparently is this code path... + style.removeAttribute( "filter" ); + + // if there there is no filter style applied in a css rule, we are done + if ( currentStyle && !currentStyle.filter ) { + return; + } + } + + // otherwise, set new filter values + style.filter = ralpha.test( filter ) ? + filter.replace( ralpha, opacity ) : + filter + " " + opacity; + } + }; +} + +// These hooks cannot be added until DOM ready because the support test +// for it is not run until after DOM ready +jQuery(function() { + if ( !jQuery.support.reliableMarginRight ) { + jQuery.cssHooks.marginRight = { + get: function( elem, computed ) { + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + // Work around by temporarily setting element display to inline-block + return jQuery.swap( elem, { "display": "inline-block" }, function() { + if ( computed ) { + return curCSS( elem, "marginRight" ); + } + }); + } + }; + } + + // Webkit bug: https://bugs.webkit.org/show_bug.cgi?id=29084 + // getComputedStyle returns percent when specified for top/left/bottom/right + // rather than make the css module depend on the offset module, we just check for it here + if ( !jQuery.support.pixelPosition && jQuery.fn.position ) { + jQuery.each( [ "top", "left" ], function( i, prop ) { + jQuery.cssHooks[ prop ] = { + get: function( elem, computed ) { + if ( computed ) { + var ret = curCSS( elem, prop ); + // if curCSS returns percentage, fallback to offset + return rnumnonpx.test( ret ) ? jQuery( elem ).position()[ prop ] + "px" : ret; + } + } + }; + }); + } + +}); + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.hidden = function( elem ) { + return ( elem.offsetWidth === 0 && elem.offsetHeight === 0 ) || (!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || curCSS( elem, "display" )) === "none"); + }; + + jQuery.expr.filters.visible = function( elem ) { + return !jQuery.expr.filters.hidden( elem ); + }; +} + +// These hooks are used by animate to expand properties +jQuery.each({ + margin: "", + padding: "", + border: "Width" +}, function( prefix, suffix ) { + jQuery.cssHooks[ prefix + suffix ] = { + expand: function( value ) { + var i, + + // assumes a single number if not a string + parts = typeof value === "string" ? value.split(" ") : [ value ], + expanded = {}; + + for ( i = 0; i < 4; i++ ) { + expanded[ prefix + cssExpand[ i ] + suffix ] = + parts[ i ] || parts[ i - 2 ] || parts[ 0 ]; + } + + return expanded; + } + }; + + if ( !rmargin.test( prefix ) ) { + jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber; + } +}); +var r20 = /%20/g, + rbracket = /\[\]$/, + rCRLF = /\r?\n/g, + rinput = /^(?:color|date|datetime|datetime-local|email|hidden|month|number|password|range|search|tel|text|time|url|week)$/i, + rselectTextarea = /^(?:select|textarea)/i; + +jQuery.fn.extend({ + serialize: function() { + return jQuery.param( this.serializeArray() ); + }, + serializeArray: function() { + return this.map(function(){ + return this.elements ? jQuery.makeArray( this.elements ) : this; + }) + .filter(function(){ + return this.name && !this.disabled && + ( this.checked || rselectTextarea.test( this.nodeName ) || + rinput.test( this.type ) ); + }) + .map(function( i, elem ){ + var val = jQuery( this ).val(); + + return val == null ? + null : + jQuery.isArray( val ) ? + jQuery.map( val, function( val, i ){ + return { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }) : + { name: elem.name, value: val.replace( rCRLF, "\r\n" ) }; + }).get(); + } +}); + +//Serialize an array of form elements or a set of +//key/values into a query string +jQuery.param = function( a, traditional ) { + var prefix, + s = [], + add = function( key, value ) { + // If value is a function, invoke it and return its value + value = jQuery.isFunction( value ) ? value() : ( value == null ? "" : value ); + s[ s.length ] = encodeURIComponent( key ) + "=" + encodeURIComponent( value ); + }; + + // Set traditional to true for jQuery <= 1.3.2 behavior. + if ( traditional === undefined ) { + traditional = jQuery.ajaxSettings && jQuery.ajaxSettings.traditional; + } + + // If an array was passed in, assume that it is an array of form elements. + if ( jQuery.isArray( a ) || ( a.jquery && !jQuery.isPlainObject( a ) ) ) { + // Serialize the form elements + jQuery.each( a, function() { + add( this.name, this.value ); + }); + + } else { + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for ( prefix in a ) { + buildParams( prefix, a[ prefix ], traditional, add ); + } + } + + // Return the resulting serialization + return s.join( "&" ).replace( r20, "+" ); +}; + +function buildParams( prefix, obj, traditional, add ) { + var name; + + if ( jQuery.isArray( obj ) ) { + // Serialize array item. + jQuery.each( obj, function( i, v ) { + if ( traditional || rbracket.test( prefix ) ) { + // Treat each array item as a scalar. + add( prefix, v ); + + } else { + // If array item is non-scalar (array or object), encode its + // numeric index to resolve deserialization ambiguity issues. + // Note that rack (as of 1.0.0) can't currently deserialize + // nested arrays properly, and attempting to do so may cause + // a server error. Possible fixes are to modify rack's + // deserialization algorithm or to provide an option or flag + // to force array serialization to be shallow. + buildParams( prefix + "[" + ( typeof v === "object" ? i : "" ) + "]", v, traditional, add ); + } + }); + + } else if ( !traditional && jQuery.type( obj ) === "object" ) { + // Serialize object item. + for ( name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); + } + + } else { + // Serialize scalar item. + add( prefix, obj ); + } +} +var + // Document location + ajaxLocParts, + ajaxLocation, + + rhash = /#.*$/, + rheaders = /^(.*?):[ \t]*([^\r\n]*)\r?$/mg, // IE leaves an \r character at EOL + // #7653, #8125, #8152: local protocol detection + rlocalProtocol = /^(?:about|app|app\-storage|.+\-extension|file|res|widget):$/, + rnoContent = /^(?:GET|HEAD)$/, + rprotocol = /^\/\//, + rquery = /\?/, + rscript = /)<[^<]*)*<\/script>/gi, + rts = /([?&])_=[^&]*/, + rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/, + + // Keep a copy of the old load method + _load = jQuery.fn.load, + + /* Prefilters + * 1) They are useful to introduce custom dataTypes (see ajax/jsonp.js for an example) + * 2) These are called: + * - BEFORE asking for a transport + * - AFTER param serialization (s.data is a string if s.processData is true) + * 3) key is the dataType + * 4) the catchall symbol "*" can be used + * 5) execution will start with transport dataType and THEN continue down to "*" if needed + */ + prefilters = {}, + + /* Transports bindings + * 1) key is the dataType + * 2) the catchall symbol "*" can be used + * 3) selection will start with transport dataType and THEN go to "*" if needed + */ + transports = {}, + + // Avoid comment-prolog char sequence (#10098); must appease lint and evade compression + allTypes = ["*/"] + ["*"]; + +// #8138, IE may throw an exception when accessing +// a field from window.location if document.domain has been set +try { + ajaxLocation = location.href; +} catch( e ) { + // Use the href attribute of an A element + // since IE will modify it given document.location + ajaxLocation = document.createElement( "a" ); + ajaxLocation.href = ""; + ajaxLocation = ajaxLocation.href; +} + +// Segment location into parts +ajaxLocParts = rurl.exec( ajaxLocation.toLowerCase() ) || []; + +// Base "constructor" for jQuery.ajaxPrefilter and jQuery.ajaxTransport +function addToPrefiltersOrTransports( structure ) { + + // dataTypeExpression is optional and defaults to "*" + return function( dataTypeExpression, func ) { + + if ( typeof dataTypeExpression !== "string" ) { + func = dataTypeExpression; + dataTypeExpression = "*"; + } + + var dataType, list, placeBefore, + dataTypes = dataTypeExpression.toLowerCase().split( core_rspace ), + i = 0, + length = dataTypes.length; + + if ( jQuery.isFunction( func ) ) { + // For each dataType in the dataTypeExpression + for ( ; i < length; i++ ) { + dataType = dataTypes[ i ]; + // We control if we're asked to add before + // any existing element + placeBefore = /^\+/.test( dataType ); + if ( placeBefore ) { + dataType = dataType.substr( 1 ) || "*"; + } + list = structure[ dataType ] = structure[ dataType ] || []; + // then we add to the structure accordingly + list[ placeBefore ? "unshift" : "push" ]( func ); + } + } + }; +} + +// Base inspection function for prefilters and transports +function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, + dataType /* internal */, inspected /* internal */ ) { + + dataType = dataType || options.dataTypes[ 0 ]; + inspected = inspected || {}; + + inspected[ dataType ] = true; + + var selection, + list = structure[ dataType ], + i = 0, + length = list ? list.length : 0, + executeOnly = ( structure === prefilters ); + + for ( ; i < length && ( executeOnly || !selection ); i++ ) { + selection = list[ i ]( options, originalOptions, jqXHR ); + // If we got redirected to another dataType + // we try there if executing only and not done already + if ( typeof selection === "string" ) { + if ( !executeOnly || inspected[ selection ] ) { + selection = undefined; + } else { + options.dataTypes.unshift( selection ); + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, selection, inspected ); + } + } + } + // If we're only executing or nothing was selected + // we try the catchall dataType if not done already + if ( ( executeOnly || !selection ) && !inspected[ "*" ] ) { + selection = inspectPrefiltersOrTransports( + structure, options, originalOptions, jqXHR, "*", inspected ); + } + // unnecessary when only executing (prefilters) + // but it'll be ignored by the caller in that case + return selection; +} + +// A special extend for ajax options +// that takes "flat" options (not to be deep extended) +// Fixes #9887 +function ajaxExtend( target, src ) { + var key, deep, + flatOptions = jQuery.ajaxSettings.flatOptions || {}; + for ( key in src ) { + if ( src[ key ] !== undefined ) { + ( flatOptions[ key ] ? target : ( deep || ( deep = {} ) ) )[ key ] = src[ key ]; + } + } + if ( deep ) { + jQuery.extend( true, target, deep ); + } +} + +jQuery.fn.load = function( url, params, callback ) { + if ( typeof url !== "string" && _load ) { + return _load.apply( this, arguments ); + } + + // Don't do a request if no elements are being requested + if ( !this.length ) { + return this; + } + + var selector, type, response, + self = this, + off = url.indexOf(" "); + + if ( off >= 0 ) { + selector = url.slice( off, url.length ); + url = url.slice( 0, off ); + } + + // If it's a function + if ( jQuery.isFunction( params ) ) { + + // We assume that it's the callback + callback = params; + params = undefined; + + // Otherwise, build a param string + } else if ( params && typeof params === "object" ) { + type = "POST"; + } + + // Request the remote document + jQuery.ajax({ + url: url, + + // if "type" variable is undefined, then "GET" method will be used + type: type, + dataType: "html", + data: params, + complete: function( jqXHR, status ) { + if ( callback ) { + self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] ); + } + } + }).done(function( responseText ) { + + // Save response for use in complete callback + response = arguments; + + // See if a selector was specified + self.html( selector ? + + // Create a dummy div to hold the results + jQuery("
") + + // inject the contents of the document in, removing the scripts + // to avoid any 'Permission Denied' errors in IE + .append( responseText.replace( rscript, "" ) ) + + // Locate the specified elements + .find( selector ) : + + // If not, just inject the full result + responseText ); + + }); + + return this; +}; + +// Attach a bunch of functions for handling common AJAX events +jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".split( " " ), function( i, o ){ + jQuery.fn[ o ] = function( f ){ + return this.on( o, f ); + }; +}); + +jQuery.each( [ "get", "post" ], function( i, method ) { + jQuery[ method ] = function( url, data, callback, type ) { + // shift arguments if data argument was omitted + if ( jQuery.isFunction( data ) ) { + type = type || callback; + callback = data; + data = undefined; + } + + return jQuery.ajax({ + type: method, + url: url, + data: data, + success: callback, + dataType: type + }); + }; +}); + +jQuery.extend({ + + getScript: function( url, callback ) { + return jQuery.get( url, undefined, callback, "script" ); + }, + + getJSON: function( url, data, callback ) { + return jQuery.get( url, data, callback, "json" ); + }, + + // Creates a full fledged settings object into target + // with both ajaxSettings and settings fields. + // If target is omitted, writes into ajaxSettings. + ajaxSetup: function( target, settings ) { + if ( settings ) { + // Building a settings object + ajaxExtend( target, jQuery.ajaxSettings ); + } else { + // Extending ajaxSettings + settings = target; + target = jQuery.ajaxSettings; + } + ajaxExtend( target, settings ); + return target; + }, + + ajaxSettings: { + url: ajaxLocation, + isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ), + global: true, + type: "GET", + contentType: "application/x-www-form-urlencoded; charset=UTF-8", + processData: true, + async: true, + /* + timeout: 0, + data: null, + dataType: null, + username: null, + password: null, + cache: null, + throws: false, + traditional: false, + headers: {}, + */ + + accepts: { + xml: "application/xml, text/xml", + html: "text/html", + text: "text/plain", + json: "application/json, text/javascript", + "*": allTypes + }, + + contents: { + xml: /xml/, + html: /html/, + json: /json/ + }, + + responseFields: { + xml: "responseXML", + text: "responseText" + }, + + // List of data converters + // 1) key format is "source_type destination_type" (a single space in-between) + // 2) the catchall symbol "*" can be used for source_type + converters: { + + // Convert anything to text + "* text": window.String, + + // Text to html (true = no transformation) + "text html": true, + + // Evaluate text as a json expression + "text json": jQuery.parseJSON, + + // Parse text as xml + "text xml": jQuery.parseXML + }, + + // For options that shouldn't be deep extended: + // you can add your own custom options here if + // and when you create one that shouldn't be + // deep extended (see ajaxExtend) + flatOptions: { + context: true, + url: true + } + }, + + ajaxPrefilter: addToPrefiltersOrTransports( prefilters ), + ajaxTransport: addToPrefiltersOrTransports( transports ), + + // Main method + ajax: function( url, options ) { + + // If url is an object, simulate pre-1.5 signature + if ( typeof url === "object" ) { + options = url; + url = undefined; + } + + // Force options to be an object + options = options || {}; + + var // ifModified key + ifModifiedKey, + // Response headers + responseHeadersString, + responseHeaders, + // transport + transport, + // timeout handle + timeoutTimer, + // Cross-domain detection vars + parts, + // To know if global events are to be dispatched + fireGlobals, + // Loop variable + i, + // Create the final options object + s = jQuery.ajaxSetup( {}, options ), + // Callbacks context + callbackContext = s.context || s, + // Context for global events + // It's the callbackContext if one was provided in the options + // and if it's a DOM node or a jQuery collection + globalEventContext = callbackContext !== s && + ( callbackContext.nodeType || callbackContext instanceof jQuery ) ? + jQuery( callbackContext ) : jQuery.event, + // Deferreds + deferred = jQuery.Deferred(), + completeDeferred = jQuery.Callbacks( "once memory" ), + // Status-dependent callbacks + statusCode = s.statusCode || {}, + // Headers (they are sent all at once) + requestHeaders = {}, + requestHeadersNames = {}, + // The jqXHR state + state = 0, + // Default abort message + strAbort = "canceled", + // Fake xhr + jqXHR = { + + readyState: 0, + + // Caches the header + setRequestHeader: function( name, value ) { + if ( !state ) { + var lname = name.toLowerCase(); + name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; + requestHeaders[ name ] = value; + } + return this; + }, + + // Raw string + getAllResponseHeaders: function() { + return state === 2 ? responseHeadersString : null; + }, + + // Builds headers hashtable if needed + getResponseHeader: function( key ) { + var match; + if ( state === 2 ) { + if ( !responseHeaders ) { + responseHeaders = {}; + while( ( match = rheaders.exec( responseHeadersString ) ) ) { + responseHeaders[ match[1].toLowerCase() ] = match[ 2 ]; + } + } + match = responseHeaders[ key.toLowerCase() ]; + } + return match === undefined ? null : match; + }, + + // Overrides response content-type header + overrideMimeType: function( type ) { + if ( !state ) { + s.mimeType = type; + } + return this; + }, + + // Cancel the request + abort: function( statusText ) { + statusText = statusText || strAbort; + if ( transport ) { + transport.abort( statusText ); + } + done( 0, statusText ); + return this; + } + }; + + // Callback for when everything is done + // It is defined here because jslint complains if it is declared + // at the end of the function (which would be more logical and readable) + function done( status, nativeStatusText, responses, headers ) { + var isSuccess, success, error, response, modified, + statusText = nativeStatusText; + + // Called once + if ( state === 2 ) { + return; + } + + // State is "done" now + state = 2; + + // Clear timeout if it exists + if ( timeoutTimer ) { + clearTimeout( timeoutTimer ); + } + + // Dereference transport for early garbage collection + // (no matter how long the jqXHR object will be used) + transport = undefined; + + // Cache response headers + responseHeadersString = headers || ""; + + // Set readyState + jqXHR.readyState = status > 0 ? 4 : 0; + + // Get response data + if ( responses ) { + response = ajaxHandleResponses( s, jqXHR, responses ); + } + + // If successful, handle type chaining + if ( status >= 200 && status < 300 || status === 304 ) { + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + + modified = jqXHR.getResponseHeader("Last-Modified"); + if ( modified ) { + jQuery.lastModified[ ifModifiedKey ] = modified; + } + modified = jqXHR.getResponseHeader("Etag"); + if ( modified ) { + jQuery.etag[ ifModifiedKey ] = modified; + } + } + + // If not modified + if ( status === 304 ) { + + statusText = "notmodified"; + isSuccess = true; + + // If we have data + } else { + + isSuccess = ajaxConvert( s, response ); + statusText = isSuccess.state; + success = isSuccess.data; + error = isSuccess.error; + isSuccess = !error; + } + } else { + // We extract error from statusText + // then normalize statusText and status for non-aborts + error = statusText; + if ( !statusText || status ) { + statusText = "error"; + if ( status < 0 ) { + status = 0; + } + } + } + + // Set data for the fake xhr object + jqXHR.status = status; + jqXHR.statusText = ( nativeStatusText || statusText ) + ""; + + // Success/Error + if ( isSuccess ) { + deferred.resolveWith( callbackContext, [ success, statusText, jqXHR ] ); + } else { + deferred.rejectWith( callbackContext, [ jqXHR, statusText, error ] ); + } + + // Status-dependent callbacks + jqXHR.statusCode( statusCode ); + statusCode = undefined; + + if ( fireGlobals ) { + globalEventContext.trigger( "ajax" + ( isSuccess ? "Success" : "Error" ), + [ jqXHR, s, isSuccess ? success : error ] ); + } + + // Complete + completeDeferred.fireWith( callbackContext, [ jqXHR, statusText ] ); + + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxComplete", [ jqXHR, s ] ); + // Handle the global AJAX counter + if ( !( --jQuery.active ) ) { + jQuery.event.trigger( "ajaxStop" ); + } + } + } + + // Attach deferreds + deferred.promise( jqXHR ); + jqXHR.success = jqXHR.done; + jqXHR.error = jqXHR.fail; + jqXHR.complete = completeDeferred.add; + + // Status-dependent callbacks + jqXHR.statusCode = function( map ) { + if ( map ) { + var tmp; + if ( state < 2 ) { + for ( tmp in map ) { + statusCode[ tmp ] = [ statusCode[tmp], map[tmp] ]; + } + } else { + tmp = map[ jqXHR.status ]; + jqXHR.always( tmp ); + } + } + return this; + }; + + // Remove hash character (#7531: and string promotion) + // Add protocol if not provided (#5866: IE7 issue with protocol-less urls) + // We also use the url parameter if available + s.url = ( ( url || s.url ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" ); + + // Extract dataTypes list + s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().split( core_rspace ); + + // A cross-domain request is in order when we have a protocol:host:port mismatch + if ( s.crossDomain == null ) { + parts = rurl.exec( s.url.toLowerCase() ); + s.crossDomain = !!( parts && + ( parts[ 1 ] !== ajaxLocParts[ 1 ] || parts[ 2 ] !== ajaxLocParts[ 2 ] || + ( parts[ 3 ] || ( parts[ 1 ] === "http:" ? 80 : 443 ) ) != + ( ajaxLocParts[ 3 ] || ( ajaxLocParts[ 1 ] === "http:" ? 80 : 443 ) ) ) + ); + } + + // Convert data if not already a string + if ( s.data && s.processData && typeof s.data !== "string" ) { + s.data = jQuery.param( s.data, s.traditional ); + } + + // Apply prefilters + inspectPrefiltersOrTransports( prefilters, s, options, jqXHR ); + + // If request was aborted inside a prefilter, stop there + if ( state === 2 ) { + return jqXHR; + } + + // We can fire global events as of now if asked to + fireGlobals = s.global; + + // Uppercase the type + s.type = s.type.toUpperCase(); + + // Determine if request has content + s.hasContent = !rnoContent.test( s.type ); + + // Watch for a new set of requests + if ( fireGlobals && jQuery.active++ === 0 ) { + jQuery.event.trigger( "ajaxStart" ); + } + + // More options handling for requests with no content + if ( !s.hasContent ) { + + // If data is available, append data to url + if ( s.data ) { + s.url += ( rquery.test( s.url ) ? "&" : "?" ) + s.data; + // #9682: remove data so that it's not used in an eventual retry + delete s.data; + } + + // Get ifModifiedKey before adding the anti-cache parameter + ifModifiedKey = s.url; + + // Add anti-cache in url if needed + if ( s.cache === false ) { + + var ts = jQuery.now(), + // try replacing _= if it is there + ret = s.url.replace( rts, "$1_=" + ts ); + + // if nothing was replaced, add timestamp to the end + s.url = ret + ( ( ret === s.url ) ? ( rquery.test( s.url ) ? "&" : "?" ) + "_=" + ts : "" ); + } + } + + // Set the correct header, if data is being sent + if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { + jqXHR.setRequestHeader( "Content-Type", s.contentType ); + } + + // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. + if ( s.ifModified ) { + ifModifiedKey = ifModifiedKey || s.url; + if ( jQuery.lastModified[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] ); + } + if ( jQuery.etag[ ifModifiedKey ] ) { + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] ); + } + } + + // Set the Accepts header for the server, depending on the dataType + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? + s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", " + allTypes + "; q=0.01" : "" ) : + s.accepts[ "*" ] + ); + + // Check for headers option + for ( i in s.headers ) { + jqXHR.setRequestHeader( i, s.headers[ i ] ); + } + + // Allow custom headers/mimetypes and early abort + if ( s.beforeSend && ( s.beforeSend.call( callbackContext, jqXHR, s ) === false || state === 2 ) ) { + // Abort if not done already and return + return jqXHR.abort(); + + } + + // aborting is no longer a cancellation + strAbort = "abort"; + + // Install callbacks on deferreds + for ( i in { success: 1, error: 1, complete: 1 } ) { + jqXHR[ i ]( s[ i ] ); + } + + // Get transport + transport = inspectPrefiltersOrTransports( transports, s, options, jqXHR ); + + // If no transport, we auto-abort + if ( !transport ) { + done( -1, "No Transport" ); + } else { + jqXHR.readyState = 1; + // Send global event + if ( fireGlobals ) { + globalEventContext.trigger( "ajaxSend", [ jqXHR, s ] ); + } + // Timeout + if ( s.async && s.timeout > 0 ) { + timeoutTimer = setTimeout( function(){ + jqXHR.abort( "timeout" ); + }, s.timeout ); + } + + try { + state = 1; + transport.send( requestHeaders, done ); + } catch (e) { + // Propagate exception as error if not done + if ( state < 2 ) { + done( -1, e ); + // Simply rethrow otherwise + } else { + throw e; + } + } + } + + return jqXHR; + }, + + // Counter for holding the number of active queries + active: 0, + + // Last-Modified header cache for next request + lastModified: {}, + etag: {} + +}); + +/* Handles responses to an ajax request: + * - sets all responseXXX fields accordingly + * - finds the right dataType (mediates between content-type and expected dataType) + * - returns the corresponding response + */ +function ajaxHandleResponses( s, jqXHR, responses ) { + + var ct, type, finalDataType, firstDataType, + contents = s.contents, + dataTypes = s.dataTypes, + responseFields = s.responseFields; + + // Fill responseXXX fields + for ( type in responseFields ) { + if ( type in responses ) { + jqXHR[ responseFields[type] ] = responses[ type ]; + } + } + + // Remove auto dataType and get content-type in the process + while( dataTypes[ 0 ] === "*" ) { + dataTypes.shift(); + if ( ct === undefined ) { + ct = s.mimeType || jqXHR.getResponseHeader( "content-type" ); + } + } + + // Check if we're dealing with a known content-type + if ( ct ) { + for ( type in contents ) { + if ( contents[ type ] && contents[ type ].test( ct ) ) { + dataTypes.unshift( type ); + break; + } + } + } + + // Check to see if we have a response for the expected dataType + if ( dataTypes[ 0 ] in responses ) { + finalDataType = dataTypes[ 0 ]; + } else { + // Try convertible dataTypes + for ( type in responses ) { + if ( !dataTypes[ 0 ] || s.converters[ type + " " + dataTypes[0] ] ) { + finalDataType = type; + break; + } + if ( !firstDataType ) { + firstDataType = type; + } + } + // Or just use first one + finalDataType = finalDataType || firstDataType; + } + + // If we found a dataType + // We add the dataType to the list if needed + // and return the corresponding response + if ( finalDataType ) { + if ( finalDataType !== dataTypes[ 0 ] ) { + dataTypes.unshift( finalDataType ); + } + return responses[ finalDataType ]; + } +} + +// Chain conversions given the request and the original response +function ajaxConvert( s, response ) { + + var conv, conv2, current, tmp, + // Work with a copy of dataTypes in case we need to modify it for conversion + dataTypes = s.dataTypes.slice(), + prev = dataTypes[ 0 ], + converters = {}, + i = 0; + + // Apply the dataFilter if provided + if ( s.dataFilter ) { + response = s.dataFilter( response, s.dataType ); + } + + // Create converters map with lowercased keys + if ( dataTypes[ 1 ] ) { + for ( conv in s.converters ) { + converters[ conv.toLowerCase() ] = s.converters[ conv ]; + } + } + + // Convert to each sequential dataType, tolerating list modification + for ( ; (current = dataTypes[++i]); ) { + + // There's only work to do if current dataType is non-auto + if ( current !== "*" ) { + + // Convert response if prev dataType is non-auto and differs from current + if ( prev !== "*" && prev !== current ) { + + // Seek a direct converter + conv = converters[ prev + " " + current ] || converters[ "* " + current ]; + + // If none found, seek a pair + if ( !conv ) { + for ( conv2 in converters ) { + + // If conv2 outputs current + tmp = conv2.split(" "); + if ( tmp[ 1 ] === current ) { + + // If prev can be converted to accepted input + conv = converters[ prev + " " + tmp[ 0 ] ] || + converters[ "* " + tmp[ 0 ] ]; + if ( conv ) { + // Condense equivalence converters + if ( conv === true ) { + conv = converters[ conv2 ]; + + // Otherwise, insert the intermediate dataType + } else if ( converters[ conv2 ] !== true ) { + current = tmp[ 0 ]; + dataTypes.splice( i--, 0, current ); + } + + break; + } + } + } + } + + // Apply converter (if not an equivalence) + if ( conv !== true ) { + + // Unless errors are allowed to bubble, catch and return them + if ( conv && s["throws"] ) { + response = conv( response ); + } else { + try { + response = conv( response ); + } catch ( e ) { + return { state: "parsererror", error: conv ? e : "No conversion from " + prev + " to " + current }; + } + } + } + } + + // Update prev for next iteration + prev = current; + } + } + + return { state: "success", data: response }; +} +var oldCallbacks = [], + rquestion = /\?/, + rjsonp = /(=)\?(?=&|$)|\?\?/, + nonce = jQuery.now(); + +// Default jsonp settings +jQuery.ajaxSetup({ + jsonp: "callback", + jsonpCallback: function() { + var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( nonce++ ) ); + this[ callback ] = true; + return callback; + } +}); + +// Detect, normalize options and install callbacks for jsonp requests +jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { + + var callbackName, overwritten, responseContainer, + data = s.data, + url = s.url, + hasCallback = s.jsonp !== false, + replaceInUrl = hasCallback && rjsonp.test( url ), + replaceInData = hasCallback && !replaceInUrl && typeof data === "string" && + !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && + rjsonp.test( data ); + + // Handle iff the expected data type is "jsonp" or we have a parameter to set + if ( s.dataTypes[ 0 ] === "jsonp" || replaceInUrl || replaceInData ) { + + // Get callback name, remembering preexisting value associated with it + callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ? + s.jsonpCallback() : + s.jsonpCallback; + overwritten = window[ callbackName ]; + + // Insert callback into url or form data + if ( replaceInUrl ) { + s.url = url.replace( rjsonp, "$1" + callbackName ); + } else if ( replaceInData ) { + s.data = data.replace( rjsonp, "$1" + callbackName ); + } else if ( hasCallback ) { + s.url += ( rquestion.test( url ) ? "&" : "?" ) + s.jsonp + "=" + callbackName; + } + + // Use data converter to retrieve json after script execution + s.converters["script json"] = function() { + if ( !responseContainer ) { + jQuery.error( callbackName + " was not called" ); + } + return responseContainer[ 0 ]; + }; + + // force json dataType + s.dataTypes[ 0 ] = "json"; + + // Install callback + window[ callbackName ] = function() { + responseContainer = arguments; + }; + + // Clean-up function (fires after converters) + jqXHR.always(function() { + // Restore preexisting value + window[ callbackName ] = overwritten; + + // Save back as free + if ( s[ callbackName ] ) { + // make sure that re-using the options doesn't screw things around + s.jsonpCallback = originalSettings.jsonpCallback; + + // save the callback name for future use + oldCallbacks.push( callbackName ); + } + + // Call if it was a function and we have a response + if ( responseContainer && jQuery.isFunction( overwritten ) ) { + overwritten( responseContainer[ 0 ] ); + } + + responseContainer = overwritten = undefined; + }); + + // Delegate to script + return "script"; + } +}); +// Install script dataType +jQuery.ajaxSetup({ + accepts: { + script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript" + }, + contents: { + script: /javascript|ecmascript/ + }, + converters: { + "text script": function( text ) { + jQuery.globalEval( text ); + return text; + } + } +}); + +// Handle cache's special case and global +jQuery.ajaxPrefilter( "script", function( s ) { + if ( s.cache === undefined ) { + s.cache = false; + } + if ( s.crossDomain ) { + s.type = "GET"; + s.global = false; + } +}); + +// Bind script tag hack transport +jQuery.ajaxTransport( "script", function(s) { + + // This transport only deals with cross domain requests + if ( s.crossDomain ) { + + var script, + head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement; + + return { + + send: function( _, callback ) { + + script = document.createElement( "script" ); + + script.async = "async"; + + if ( s.scriptCharset ) { + script.charset = s.scriptCharset; + } + + script.src = s.url; + + // Attach handlers for all browsers + script.onload = script.onreadystatechange = function( _, isAbort ) { + + if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { + + // Handle memory leak in IE + script.onload = script.onreadystatechange = null; + + // Remove the script + if ( head && script.parentNode ) { + head.removeChild( script ); + } + + // Dereference the script + script = undefined; + + // Callback if not abort + if ( !isAbort ) { + callback( 200, "success" ); + } + } + }; + // Use insertBefore instead of appendChild to circumvent an IE6 bug. + // This arises when a base node is used (#2709 and #4378). + head.insertBefore( script, head.firstChild ); + }, + + abort: function() { + if ( script ) { + script.onload( 0, 1 ); + } + } + }; + } +}); +var xhrCallbacks, + // #5280: Internet Explorer will keep connections alive if we don't abort on unload + xhrOnUnloadAbort = window.ActiveXObject ? function() { + // Abort all pending requests + for ( var key in xhrCallbacks ) { + xhrCallbacks[ key ]( 0, 1 ); + } + } : false, + xhrId = 0; + +// Functions to create xhrs +function createStandardXHR() { + try { + return new window.XMLHttpRequest(); + } catch( e ) {} +} + +function createActiveXHR() { + try { + return new window.ActiveXObject( "Microsoft.XMLHTTP" ); + } catch( e ) {} +} + +// Create the request object +// (This is still attached to ajaxSettings for backward compatibility) +jQuery.ajaxSettings.xhr = window.ActiveXObject ? + /* Microsoft failed to properly + * implement the XMLHttpRequest in IE7 (can't request local files), + * so we use the ActiveXObject when it is available + * Additionally XMLHttpRequest can be disabled in IE7/IE8 so + * we need a fallback. + */ + function() { + return !this.isLocal && createStandardXHR() || createActiveXHR(); + } : + // For all other browsers, use the standard XMLHttpRequest object + createStandardXHR; + +// Determine support properties +(function( xhr ) { + jQuery.extend( jQuery.support, { + ajax: !!xhr, + cors: !!xhr && ( "withCredentials" in xhr ) + }); +})( jQuery.ajaxSettings.xhr() ); + +// Create transport if the browser can provide an xhr +if ( jQuery.support.ajax ) { + + jQuery.ajaxTransport(function( s ) { + // Cross domain only allowed if supported through XMLHttpRequest + if ( !s.crossDomain || jQuery.support.cors ) { + + var callback; + + return { + send: function( headers, complete ) { + + // Get a new xhr + var handle, i, + xhr = s.xhr(); + + // Open the socket + // Passing null username, generates a login popup on Opera (#2865) + if ( s.username ) { + xhr.open( s.type, s.url, s.async, s.username, s.password ); + } else { + xhr.open( s.type, s.url, s.async ); + } + + // Apply custom fields if provided + if ( s.xhrFields ) { + for ( i in s.xhrFields ) { + xhr[ i ] = s.xhrFields[ i ]; + } + } + + // Override mime type if needed + if ( s.mimeType && xhr.overrideMimeType ) { + xhr.overrideMimeType( s.mimeType ); + } + + // X-Requested-With header + // For cross-domain requests, seeing as conditions for a preflight are + // akin to a jigsaw puzzle, we simply never set it to be sure. + // (it can always be set on a per-request basis or even using ajaxSetup) + // For same-domain requests, won't change header if already provided. + if ( !s.crossDomain && !headers["X-Requested-With"] ) { + headers[ "X-Requested-With" ] = "XMLHttpRequest"; + } + + // Need an extra try/catch for cross domain requests in Firefox 3 + try { + for ( i in headers ) { + xhr.setRequestHeader( i, headers[ i ] ); + } + } catch( _ ) {} + + // Do send the request + // This may raise an exception which is actually + // handled in jQuery.ajax (so no try/catch here) + xhr.send( ( s.hasContent && s.data ) || null ); + + // Listener + callback = function( _, isAbort ) { + + var status, + statusText, + responseHeaders, + responses, + xml; + + // Firefox throws exceptions when accessing properties + // of an xhr when a network error occurred + // http://helpful.knobs-dials.com/index.php/Component_returned_failure_code:_0x80040111_(NS_ERROR_NOT_AVAILABLE) + try { + + // Was never called and is aborted or complete + if ( callback && ( isAbort || xhr.readyState === 4 ) ) { + + // Only called once + callback = undefined; + + // Do not keep as active anymore + if ( handle ) { + xhr.onreadystatechange = jQuery.noop; + if ( xhrOnUnloadAbort ) { + delete xhrCallbacks[ handle ]; + } + } + + // If it's an abort + if ( isAbort ) { + // Abort it manually if needed + if ( xhr.readyState !== 4 ) { + xhr.abort(); + } + } else { + status = xhr.status; + responseHeaders = xhr.getAllResponseHeaders(); + responses = {}; + xml = xhr.responseXML; + + // Construct response list + if ( xml && xml.documentElement /* #4958 */ ) { + responses.xml = xml; + } + + // When requesting binary data, IE6-9 will throw an exception + // on any attempt to access responseText (#11426) + try { + responses.text = xhr.responseText; + } catch( e ) { + } + + // Firefox throws an exception when accessing + // statusText for faulty cross-domain requests + try { + statusText = xhr.statusText; + } catch( e ) { + // We normalize with Webkit giving an empty statusText + statusText = ""; + } + + // Filter status for non standard behaviors + + // If the request is local and we have data: assume a success + // (success with no data won't get notified, that's the best we + // can do given current implementations) + if ( !status && s.isLocal && !s.crossDomain ) { + status = responses.text ? 200 : 404; + // IE - #1450: sometimes returns 1223 when it should be 204 + } else if ( status === 1223 ) { + status = 204; + } + } + } + } catch( firefoxAccessException ) { + if ( !isAbort ) { + complete( -1, firefoxAccessException ); + } + } + + // Call complete if needed + if ( responses ) { + complete( status, statusText, responses, responseHeaders ); + } + }; + + if ( !s.async ) { + // if we're in sync mode we fire the callback + callback(); + } else if ( xhr.readyState === 4 ) { + // (IE6 & IE7) if it's in cache and has been + // retrieved directly we need to fire the callback + setTimeout( callback, 0 ); + } else { + handle = ++xhrId; + if ( xhrOnUnloadAbort ) { + // Create the active xhrs callbacks list if needed + // and attach the unload handler + if ( !xhrCallbacks ) { + xhrCallbacks = {}; + jQuery( window ).unload( xhrOnUnloadAbort ); + } + // Add to list of active xhrs callbacks + xhrCallbacks[ handle ] = callback; + } + xhr.onreadystatechange = callback; + } + }, + + abort: function() { + if ( callback ) { + callback(0,1); + } + } + }; + } + }); +} +var fxNow, timerId, + rfxtypes = /^(?:toggle|show|hide)$/, + rfxnum = new RegExp( "^(?:([-+])=|)(" + core_pnum + ")([a-z%]*)$", "i" ), + rrun = /queueHooks$/, + animationPrefilters = [ defaultPrefilter ], + tweeners = { + "*": [function( prop, value ) { + var end, unit, + tween = this.createTween( prop, value ), + parts = rfxnum.exec( value ), + target = tween.cur(), + start = +target || 0, + scale = 1, + maxIterations = 20; + + if ( parts ) { + end = +parts[2]; + unit = parts[3] || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + + // We need to compute starting value + if ( unit !== "px" && start ) { + // Iteratively approximate from a nonzero starting point + // Prefer the current property, because this process will be trivial if it uses the same units + // Fallback to end or a simple constant + start = jQuery.css( tween.elem, prop, true ) || end || 1; + + do { + // If previous iteration zeroed out, double until we get *something* + // Use a string for doubling factor so we don't accidentally see scale as unchanged below + scale = scale || ".5"; + + // Adjust and apply + start = start / scale; + jQuery.style( tween.elem, prop, start + unit ); + + // Update scale, tolerating zero or NaN from tween.cur() + // And breaking the loop if scale is unchanged or perfect, or if we've just had enough + } while ( scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations ); + } + + tween.unit = unit; + tween.start = start; + // If a +=/-= token was provided, we're doing a relative animation + tween.end = parts[1] ? start + ( parts[1] + 1 ) * end : end; + } + return tween; + }] + }; + +// Animations created synchronously will run synchronously +function createFxNow() { + setTimeout(function() { + fxNow = undefined; + }, 0 ); + return ( fxNow = jQuery.now() ); +} + +function createTweens( animation, props ) { + jQuery.each( props, function( prop, value ) { + var collection = ( tweeners[ prop ] || [] ).concat( tweeners[ "*" ] ), + index = 0, + length = collection.length; + for ( ; index < length; index++ ) { + if ( collection[ index ].call( animation, prop, value ) ) { + + // we're done with this property + return; + } + } + }); +} + +function Animation( elem, properties, options ) { + var result, + index = 0, + tweenerIndex = 0, + length = animationPrefilters.length, + deferred = jQuery.Deferred().always( function() { + // don't match elem in the :animated selector + delete tick.elem; + }), + tick = function() { + var currentTime = fxNow || createFxNow(), + remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), + // archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) + temp = remaining / animation.duration || 0, + percent = 1 - temp, + index = 0, + length = animation.tweens.length; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( percent ); + } + + deferred.notifyWith( elem, [ animation, percent, remaining ]); + + if ( percent < 1 && length ) { + return remaining; + } else { + deferred.resolveWith( elem, [ animation ] ); + return false; + } + }, + animation = deferred.promise({ + elem: elem, + props: jQuery.extend( {}, properties ), + opts: jQuery.extend( true, { specialEasing: {} }, options ), + originalProperties: properties, + originalOptions: options, + startTime: fxNow || createFxNow(), + duration: options.duration, + tweens: [], + createTween: function( prop, end, easing ) { + var tween = jQuery.Tween( elem, animation.opts, prop, end, + animation.opts.specialEasing[ prop ] || animation.opts.easing ); + animation.tweens.push( tween ); + return tween; + }, + stop: function( gotoEnd ) { + var index = 0, + // if we are going to the end, we want to run all the tweens + // otherwise we skip this part + length = gotoEnd ? animation.tweens.length : 0; + + for ( ; index < length ; index++ ) { + animation.tweens[ index ].run( 1 ); + } + + // resolve when we played the last frame + // otherwise, reject + if ( gotoEnd ) { + deferred.resolveWith( elem, [ animation, gotoEnd ] ); + } else { + deferred.rejectWith( elem, [ animation, gotoEnd ] ); + } + return this; + } + }), + props = animation.props; + + propFilter( props, animation.opts.specialEasing ); + + for ( ; index < length ; index++ ) { + result = animationPrefilters[ index ].call( animation, elem, props, animation.opts ); + if ( result ) { + return result; + } + } + + createTweens( animation, props ); + + if ( jQuery.isFunction( animation.opts.start ) ) { + animation.opts.start.call( elem, animation ); + } + + jQuery.fx.timer( + jQuery.extend( tick, { + anim: animation, + queue: animation.opts.queue, + elem: elem + }) + ); + + // attach callbacks from options + return animation.progress( animation.opts.progress ) + .done( animation.opts.done, animation.opts.complete ) + .fail( animation.opts.fail ) + .always( animation.opts.always ); +} + +function propFilter( props, specialEasing ) { + var index, name, easing, value, hooks; + + // camelCase, specialEasing and expand cssHook pass + for ( index in props ) { + name = jQuery.camelCase( index ); + easing = specialEasing[ name ]; + value = props[ index ]; + if ( jQuery.isArray( value ) ) { + easing = value[ 1 ]; + value = props[ index ] = value[ 0 ]; + } + + if ( index !== name ) { + props[ name ] = value; + delete props[ index ]; + } + + hooks = jQuery.cssHooks[ name ]; + if ( hooks && "expand" in hooks ) { + value = hooks.expand( value ); + delete props[ name ]; + + // not quite $.extend, this wont overwrite keys already present. + // also - reusing 'index' from above because we have the correct "name" + for ( index in value ) { + if ( !( index in props ) ) { + props[ index ] = value[ index ]; + specialEasing[ index ] = easing; + } + } + } else { + specialEasing[ name ] = easing; + } + } +} + +jQuery.Animation = jQuery.extend( Animation, { + + tweener: function( props, callback ) { + if ( jQuery.isFunction( props ) ) { + callback = props; + props = [ "*" ]; + } else { + props = props.split(" "); + } + + var prop, + index = 0, + length = props.length; + + for ( ; index < length ; index++ ) { + prop = props[ index ]; + tweeners[ prop ] = tweeners[ prop ] || []; + tweeners[ prop ].unshift( callback ); + } + }, + + prefilter: function( callback, prepend ) { + if ( prepend ) { + animationPrefilters.unshift( callback ); + } else { + animationPrefilters.push( callback ); + } + } +}); + +function defaultPrefilter( elem, props, opts ) { + var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire, + anim = this, + style = elem.style, + orig = {}, + handled = [], + hidden = elem.nodeType && isHidden( elem ); + + // handle queue: false promises + if ( !opts.queue ) { + hooks = jQuery._queueHooks( elem, "fx" ); + if ( hooks.unqueued == null ) { + hooks.unqueued = 0; + oldfire = hooks.empty.fire; + hooks.empty.fire = function() { + if ( !hooks.unqueued ) { + oldfire(); + } + }; + } + hooks.unqueued++; + + anim.always(function() { + // doing this makes sure that the complete handler will be called + // before this completes + anim.always(function() { + hooks.unqueued--; + if ( !jQuery.queue( elem, "fx" ).length ) { + hooks.empty.fire(); + } + }); + }); + } + + // height/width overflow pass + if ( elem.nodeType === 1 && ( "height" in props || "width" in props ) ) { + // Make sure that nothing sneaks out + // Record all 3 overflow attributes because IE does not + // change the overflow attribute when overflowX and + // overflowY are set to the same value + opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; + + // Set display property to inline-block for height/width + // animations on inline elements that are having width/height animated + if ( jQuery.css( elem, "display" ) === "inline" && + jQuery.css( elem, "float" ) === "none" ) { + + // inline-level elements accept inline-block; + // block-level elements need to be inline with layout + if ( !jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay( elem.nodeName ) === "inline" ) { + style.display = "inline-block"; + + } else { + style.zoom = 1; + } + } + } + + if ( opts.overflow ) { + style.overflow = "hidden"; + if ( !jQuery.support.shrinkWrapBlocks ) { + anim.done(function() { + style.overflow = opts.overflow[ 0 ]; + style.overflowX = opts.overflow[ 1 ]; + style.overflowY = opts.overflow[ 2 ]; + }); + } + } + + + // show/hide pass + for ( index in props ) { + value = props[ index ]; + if ( rfxtypes.exec( value ) ) { + delete props[ index ]; + toggle = toggle || value === "toggle"; + if ( value === ( hidden ? "hide" : "show" ) ) { + continue; + } + handled.push( index ); + } + } + + length = handled.length; + if ( length ) { + dataShow = jQuery._data( elem, "fxshow" ) || jQuery._data( elem, "fxshow", {} ); + if ( "hidden" in dataShow ) { + hidden = dataShow.hidden; + } + + // store state if its toggle - enables .stop().toggle() to "reverse" + if ( toggle ) { + dataShow.hidden = !hidden; + } + if ( hidden ) { + jQuery( elem ).show(); + } else { + anim.done(function() { + jQuery( elem ).hide(); + }); + } + anim.done(function() { + var prop; + jQuery.removeData( elem, "fxshow", true ); + for ( prop in orig ) { + jQuery.style( elem, prop, orig[ prop ] ); + } + }); + for ( index = 0 ; index < length ; index++ ) { + prop = handled[ index ]; + tween = anim.createTween( prop, hidden ? dataShow[ prop ] : 0 ); + orig[ prop ] = dataShow[ prop ] || jQuery.style( elem, prop ); + + if ( !( prop in dataShow ) ) { + dataShow[ prop ] = tween.start; + if ( hidden ) { + tween.end = tween.start; + tween.start = prop === "width" || prop === "height" ? 1 : 0; + } + } + } + } +} + +function Tween( elem, options, prop, end, easing ) { + return new Tween.prototype.init( elem, options, prop, end, easing ); +} +jQuery.Tween = Tween; + +Tween.prototype = { + constructor: Tween, + init: function( elem, options, prop, end, easing, unit ) { + this.elem = elem; + this.prop = prop; + this.easing = easing || "swing"; + this.options = options; + this.start = this.now = this.cur(); + this.end = end; + this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" ); + }, + cur: function() { + var hooks = Tween.propHooks[ this.prop ]; + + return hooks && hooks.get ? + hooks.get( this ) : + Tween.propHooks._default.get( this ); + }, + run: function( percent ) { + var eased, + hooks = Tween.propHooks[ this.prop ]; + + if ( this.options.duration ) { + this.pos = eased = jQuery.easing[ this.easing ]( + percent, this.options.duration * percent, 0, 1, this.options.duration + ); + } else { + this.pos = eased = percent; + } + this.now = ( this.end - this.start ) * eased + this.start; + + if ( this.options.step ) { + this.options.step.call( this.elem, this.now, this ); + } + + if ( hooks && hooks.set ) { + hooks.set( this ); + } else { + Tween.propHooks._default.set( this ); + } + return this; + } +}; + +Tween.prototype.init.prototype = Tween.prototype; + +Tween.propHooks = { + _default: { + get: function( tween ) { + var result; + + if ( tween.elem[ tween.prop ] != null && + (!tween.elem.style || tween.elem.style[ tween.prop ] == null) ) { + return tween.elem[ tween.prop ]; + } + + // passing any value as a 4th parameter to .css will automatically + // attempt a parseFloat and fallback to a string if the parse fails + // so, simple values such as "10px" are parsed to Float. + // complex values such as "rotate(1rad)" are returned as is. + result = jQuery.css( tween.elem, tween.prop, false, "" ); + // Empty strings, null, undefined and "auto" are converted to 0. + return !result || result === "auto" ? 0 : result; + }, + set: function( tween ) { + // use step hook for back compat - use cssHook if its there - use .style if its + // available and use plain properties where available + if ( jQuery.fx.step[ tween.prop ] ) { + jQuery.fx.step[ tween.prop ]( tween ); + } else if ( tween.elem.style && ( tween.elem.style[ jQuery.cssProps[ tween.prop ] ] != null || jQuery.cssHooks[ tween.prop ] ) ) { + jQuery.style( tween.elem, tween.prop, tween.now + tween.unit ); + } else { + tween.elem[ tween.prop ] = tween.now; + } + } + } +}; + +// Remove in 2.0 - this supports IE8's panic based approach +// to setting things on disconnected nodes + +Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { + set: function( tween ) { + if ( tween.elem.nodeType && tween.elem.parentNode ) { + tween.elem[ tween.prop ] = tween.now; + } + } +}; + +jQuery.each([ "toggle", "show", "hide" ], function( i, name ) { + var cssFn = jQuery.fn[ name ]; + jQuery.fn[ name ] = function( speed, easing, callback ) { + return speed == null || typeof speed === "boolean" || + // special check for .toggle( handler, handler, ... ) + ( !i && jQuery.isFunction( speed ) && jQuery.isFunction( easing ) ) ? + cssFn.apply( this, arguments ) : + this.animate( genFx( name, true ), speed, easing, callback ); + }; +}); + +jQuery.fn.extend({ + fadeTo: function( speed, to, easing, callback ) { + + // show any hidden elements after setting opacity to 0 + return this.filter( isHidden ).css( "opacity", 0 ).show() + + // animate to the value specified + .end().animate({ opacity: to }, speed, easing, callback ); + }, + animate: function( prop, speed, easing, callback ) { + var empty = jQuery.isEmptyObject( prop ), + optall = jQuery.speed( speed, easing, callback ), + doAnimation = function() { + // Operate on a copy of prop so per-property easing won't be lost + var anim = Animation( this, jQuery.extend( {}, prop ), optall ); + + // Empty animations resolve immediately + if ( empty ) { + anim.stop( true ); + } + }; + + return empty || optall.queue === false ? + this.each( doAnimation ) : + this.queue( optall.queue, doAnimation ); + }, + stop: function( type, clearQueue, gotoEnd ) { + var stopQueue = function( hooks ) { + var stop = hooks.stop; + delete hooks.stop; + stop( gotoEnd ); + }; + + if ( typeof type !== "string" ) { + gotoEnd = clearQueue; + clearQueue = type; + type = undefined; + } + if ( clearQueue && type !== false ) { + this.queue( type || "fx", [] ); + } + + return this.each(function() { + var dequeue = true, + index = type != null && type + "queueHooks", + timers = jQuery.timers, + data = jQuery._data( this ); + + if ( index ) { + if ( data[ index ] && data[ index ].stop ) { + stopQueue( data[ index ] ); + } + } else { + for ( index in data ) { + if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { + stopQueue( data[ index ] ); + } + } + } + + for ( index = timers.length; index--; ) { + if ( timers[ index ].elem === this && (type == null || timers[ index ].queue === type) ) { + timers[ index ].anim.stop( gotoEnd ); + dequeue = false; + timers.splice( index, 1 ); + } + } + + // start the next in the queue if the last step wasn't forced + // timers currently will call their complete callbacks, which will dequeue + // but only if they were gotoEnd + if ( dequeue || !gotoEnd ) { + jQuery.dequeue( this, type ); + } + }); + } +}); + +// Generate parameters to create a standard animation +function genFx( type, includeWidth ) { + var which, + attrs = { height: type }, + i = 0; + + // if we include width, step value is 1 to do all cssExpand values, + // if we don't include width, step value is 2 to skip over Left and Right + includeWidth = includeWidth? 1 : 0; + for( ; i < 4 ; i += 2 - includeWidth ) { + which = cssExpand[ i ]; + attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; + } + + if ( includeWidth ) { + attrs.opacity = attrs.width = type; + } + + return attrs; +} + +// Generate shortcuts for custom animations +jQuery.each({ + slideDown: genFx("show"), + slideUp: genFx("hide"), + slideToggle: genFx("toggle"), + fadeIn: { opacity: "show" }, + fadeOut: { opacity: "hide" }, + fadeToggle: { opacity: "toggle" } +}, function( name, props ) { + jQuery.fn[ name ] = function( speed, easing, callback ) { + return this.animate( props, speed, easing, callback ); + }; +}); + +jQuery.speed = function( speed, easing, fn ) { + var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { + complete: fn || !fn && easing || + jQuery.isFunction( speed ) && speed, + duration: speed, + easing: fn && easing || easing && !jQuery.isFunction( easing ) && easing + }; + + opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : + opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[ opt.duration ] : jQuery.fx.speeds._default; + + // normalize opt.queue - true/undefined/null -> "fx" + if ( opt.queue == null || opt.queue === true ) { + opt.queue = "fx"; + } + + // Queueing + opt.old = opt.complete; + + opt.complete = function() { + if ( jQuery.isFunction( opt.old ) ) { + opt.old.call( this ); + } + + if ( opt.queue ) { + jQuery.dequeue( this, opt.queue ); + } + }; + + return opt; +}; + +jQuery.easing = { + linear: function( p ) { + return p; + }, + swing: function( p ) { + return 0.5 - Math.cos( p*Math.PI ) / 2; + } +}; + +jQuery.timers = []; +jQuery.fx = Tween.prototype.init; +jQuery.fx.tick = function() { + var timer, + timers = jQuery.timers, + i = 0; + + fxNow = jQuery.now(); + + for ( ; i < timers.length; i++ ) { + timer = timers[ i ]; + // Checks the timer has not already been removed + if ( !timer() && timers[ i ] === timer ) { + timers.splice( i--, 1 ); + } + } + + if ( !timers.length ) { + jQuery.fx.stop(); + } + fxNow = undefined; +}; + +jQuery.fx.timer = function( timer ) { + if ( timer() && jQuery.timers.push( timer ) && !timerId ) { + timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval ); + } +}; + +jQuery.fx.interval = 13; + +jQuery.fx.stop = function() { + clearInterval( timerId ); + timerId = null; +}; + +jQuery.fx.speeds = { + slow: 600, + fast: 200, + // Default speed + _default: 400 +}; + +// Back Compat <1.8 extension point +jQuery.fx.step = {}; + +if ( jQuery.expr && jQuery.expr.filters ) { + jQuery.expr.filters.animated = function( elem ) { + return jQuery.grep(jQuery.timers, function( fn ) { + return elem === fn.elem; + }).length; + }; +} +var rroot = /^(?:body|html)$/i; + +jQuery.fn.offset = function( options ) { + if ( arguments.length ) { + return options === undefined ? + this : + this.each(function( i ) { + jQuery.offset.setOffset( this, options, i ); + }); + } + + var docElem, body, win, clientTop, clientLeft, scrollTop, scrollLeft, + box = { top: 0, left: 0 }, + elem = this[ 0 ], + doc = elem && elem.ownerDocument; + + if ( !doc ) { + return; + } + + if ( (body = doc.body) === elem ) { + return jQuery.offset.bodyOffset( elem ); + } + + docElem = doc.documentElement; + + // Make sure it's not a disconnected DOM node + if ( !jQuery.contains( docElem, elem ) ) { + return box; + } + + // If we don't have gBCR, just use 0,0 rather than error + // BlackBerry 5, iOS 3 (original iPhone) + if ( typeof elem.getBoundingClientRect !== "undefined" ) { + box = elem.getBoundingClientRect(); + } + win = getWindow( doc ); + clientTop = docElem.clientTop || body.clientTop || 0; + clientLeft = docElem.clientLeft || body.clientLeft || 0; + scrollTop = win.pageYOffset || docElem.scrollTop; + scrollLeft = win.pageXOffset || docElem.scrollLeft; + return { + top: box.top + scrollTop - clientTop, + left: box.left + scrollLeft - clientLeft + }; +}; + +jQuery.offset = { + + bodyOffset: function( body ) { + var top = body.offsetTop, + left = body.offsetLeft; + + if ( jQuery.support.doesNotIncludeMarginInBodyOffset ) { + top += parseFloat( jQuery.css(body, "marginTop") ) || 0; + left += parseFloat( jQuery.css(body, "marginLeft") ) || 0; + } + + return { top: top, left: left }; + }, + + setOffset: function( elem, options, i ) { + var position = jQuery.css( elem, "position" ); + + // set position first, in-case top/left are set even on static elem + if ( position === "static" ) { + elem.style.position = "relative"; + } + + var curElem = jQuery( elem ), + curOffset = curElem.offset(), + curCSSTop = jQuery.css( elem, "top" ), + curCSSLeft = jQuery.css( elem, "left" ), + calculatePosition = ( position === "absolute" || position === "fixed" ) && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1, + props = {}, curPosition = {}, curTop, curLeft; + + // need to be able to calculate position if either top or left is auto and position is either absolute or fixed + if ( calculatePosition ) { + curPosition = curElem.position(); + curTop = curPosition.top; + curLeft = curPosition.left; + } else { + curTop = parseFloat( curCSSTop ) || 0; + curLeft = parseFloat( curCSSLeft ) || 0; + } + + if ( jQuery.isFunction( options ) ) { + options = options.call( elem, i, curOffset ); + } + + if ( options.top != null ) { + props.top = ( options.top - curOffset.top ) + curTop; + } + if ( options.left != null ) { + props.left = ( options.left - curOffset.left ) + curLeft; + } + + if ( "using" in options ) { + options.using.call( elem, props ); + } else { + curElem.css( props ); + } + } +}; + + +jQuery.fn.extend({ + + position: function() { + if ( !this[0] ) { + return; + } + + var elem = this[0], + + // Get *real* offsetParent + offsetParent = this.offsetParent(), + + // Get correct offsets + offset = this.offset(), + parentOffset = rroot.test(offsetParent[0].nodeName) ? { top: 0, left: 0 } : offsetParent.offset(); + + // Subtract element margins + // note: when an element has margin: auto the offsetLeft and marginLeft + // are the same in Safari causing offset.left to incorrectly be 0 + offset.top -= parseFloat( jQuery.css(elem, "marginTop") ) || 0; + offset.left -= parseFloat( jQuery.css(elem, "marginLeft") ) || 0; + + // Add offsetParent borders + parentOffset.top += parseFloat( jQuery.css(offsetParent[0], "borderTopWidth") ) || 0; + parentOffset.left += parseFloat( jQuery.css(offsetParent[0], "borderLeftWidth") ) || 0; + + // Subtract the two offsets + return { + top: offset.top - parentOffset.top, + left: offset.left - parentOffset.left + }; + }, + + offsetParent: function() { + return this.map(function() { + var offsetParent = this.offsetParent || document.body; + while ( offsetParent && (!rroot.test(offsetParent.nodeName) && jQuery.css(offsetParent, "position") === "static") ) { + offsetParent = offsetParent.offsetParent; + } + return offsetParent || document.body; + }); + } +}); + + +// Create scrollLeft and scrollTop methods +jQuery.each( {scrollLeft: "pageXOffset", scrollTop: "pageYOffset"}, function( method, prop ) { + var top = /Y/.test( prop ); + + jQuery.fn[ method ] = function( val ) { + return jQuery.access( this, function( elem, method, val ) { + var win = getWindow( elem ); + + if ( val === undefined ) { + return win ? (prop in win) ? win[ prop ] : + win.document.documentElement[ method ] : + elem[ method ]; + } + + if ( win ) { + win.scrollTo( + !top ? val : jQuery( win ).scrollLeft(), + top ? val : jQuery( win ).scrollTop() + ); + + } else { + elem[ method ] = val; + } + }, method, val, arguments.length, null ); + }; +}); + +function getWindow( elem ) { + return jQuery.isWindow( elem ) ? + elem : + elem.nodeType === 9 ? + elem.defaultView || elem.parentWindow : + false; +} +// Create innerHeight, innerWidth, height, width, outerHeight and outerWidth methods +jQuery.each( { Height: "height", Width: "width" }, function( name, type ) { + jQuery.each( { padding: "inner" + name, content: type, "": "outer" + name }, function( defaultExtra, funcName ) { + // margin is only for outerHeight, outerWidth + jQuery.fn[ funcName ] = function( margin, value ) { + var chainable = arguments.length && ( defaultExtra || typeof margin !== "boolean" ), + extra = defaultExtra || ( margin === true || value === true ? "margin" : "border" ); + + return jQuery.access( this, function( elem, type, value ) { + var doc; + + if ( jQuery.isWindow( elem ) ) { + // As of 5/8/2012 this will yield incorrect results for Mobile Safari, but there + // isn't a whole lot we can do. See pull request at this URL for discussion: + // https://github.com/jquery/jquery/pull/764 + return elem.document.documentElement[ "client" + name ]; + } + + // Get document width or height + if ( elem.nodeType === 9 ) { + doc = elem.documentElement; + + // Either scroll[Width/Height] or offset[Width/Height] or client[Width/Height], whichever is greatest + // unfortunately, this causes bug #3838 in IE6/8 only, but there is currently no good, small way to fix it. + return Math.max( + elem.body[ "scroll" + name ], doc[ "scroll" + name ], + elem.body[ "offset" + name ], doc[ "offset" + name ], + doc[ "client" + name ] + ); + } + + return value === undefined ? + // Get width or height on the element, requesting but not forcing parseFloat + jQuery.css( elem, type, value, extra ) : + + // Set width or height on the element + jQuery.style( elem, type, value, extra ); + }, type, chainable ? margin : undefined, chainable, null ); + }; + }); +}); +// Expose jQuery to the global object +window.jQuery = window.$ = jQuery; + +// Expose jQuery as an AMD module, but only for AMD loaders that +// understand the issues with loading multiple versions of jQuery +// in a page that all might call define(). The loader will indicate +// they have special allowances for multiple jQuery versions by +// specifying define.amd.jQuery = true. Register as a named module, +// since jQuery can be concatenated with other files that may use define, +// but not use a proper concatenation script that understands anonymous +// AMD modules. A named AMD is safest and most robust way to register. +// Lowercase jquery is used because AMD module names are derived from +// file names, and jQuery is normally delivered in a lowercase file name. +// Do this after creating the global so that if an AMD module wants to call +// noConflict to hide this version of jQuery, it will work. +if ( typeof define === "function" && define.amd && define.amd.jQuery ) { + define( "jquery", [], function () { return jQuery; } ); +} + +})( window ); diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/main.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/main.js new file mode 100644 index 00000000..1d7bd128 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/main.js @@ -0,0 +1,568 @@ +var datasource, type, columns, filter, maxUpdateValue, paramsToFilterBy; + +var REFRESH_INTERVAL = 5000; + +//this needs to be loaded from an autogenerated +datasource = gadgetConfig.datasource; +filter = gadgetConfig.filter; +type = gadgetConfig.type; +maxUpdateValue = gadgetConfig.maxUpdateValue; +columns = gadgetConfig.columns; +paramsToFilterBy = gadgetConfig.params; + +var counter = 0; +var TYPE_GET_BY_RANGE = 8; +var TYPE_SEARCH = 13; +var TYPE_SEARCH_COUNT = 14; + +var TIME_FROM_STRING = "timeFrom"; +var TIME_TO_STRING = "timeTo"; +var UNIX_TIME_MAX_VALUE = "9007199254740992"; +var UNIX_TIME_MIN_VALUE = "-9007199254740992"; +var META_TAG = "meta_"; +var initialConfig, urlQueryParams, queryParamValPair, queryString; +var dataTable, chart; + +executeDataFetchForGadget(); + +/** + * The main execution logic of the gadget is implemented in this function. + */ +function executeDataFetchForGadget() { + var urlQueryString; + + // fetch all queryParams from the URL. + urlQueryParams = getAllQueryParamsFromURL(); + + // check if params config exists in the gadgetConf. + if (typeof paramsToFilterBy != "undefined" && paramsToFilterBy.length != 0) { + + if (urlQueryParams != null) { + // get the values corresponding to the query "params" given in the gadgetConf + queryParamValPair = getValuesOfQueryFilter(); + + // if at-least one of the given params in the conf are missing from the URL params then returns null. + if (queryParamValPair == null) { + console.log("Incomplete set of Query Params were found in the URL."); + return; + } + + // construct the Lucene query string based on the params given in the gadget-conf + // and the values parsed from the URL Query String. + queryString = constructQueryString(); + + switch (type) { + case "realtime": + urlQueryString = decodeURIComponent(window.top.location.search.substring(1)); + //subscribe to websocket + subscribe( + datasource.split(":")[0], datasource.split(":")[1], '10', gadgetConfig.domain, + onRealTimeEventSuccessRecieval, onRealTimeEventErrorRecieval, + location.hostname, location.port, 'WEBSOCKET', "SECURED", urlQueryString); + break; + + case "batch": + //load data immediately + fetchDataOnQuery(fetchDataWithCount); + // then start periodic polling + setInterval(function () { + fetchDataOnQuery(fetchDataWithCount); + }, REFRESH_INTERVAL); + break; + } + + } else { + // if there are NO queryParams in the URL then exit. + console.log("No Query Params were found in the URL to match the given filter-parameters."); + } + } else { + // if no params to filter by are given in the gadget-conf, then fetch all info available + // based on date range(if given). + switch (type) { + case "realtime": + urlQueryString = decodeURIComponent(window.top.location.search.substring(1)); + //subscribe to websocket + subscribe(datasource.split(":")[0], datasource.split(":")[1], '10', gadgetConfig.domain, + onRealTimeEventSuccessRecieval, onRealTimeEventErrorRecieval, location.hostname, location.port, + 'WEBSOCKET', "SECURED", urlQueryString); + break; + + case "batch": + //load data immediately + fetchDataWithoutQuery(drawBatchChart); + + // then start periodic polling + setInterval(function () { + fetchDataWithoutQuery(drawBatchChart); + }, REFRESH_INTERVAL); + break; + } + } +} + +/** + * Reads the page's URL Query-Params and returns them as an associative array. + * @returns {*} an associative array containing the URL QueryParams and corresponding values. + * If no such Query-Params exists then returns null. + */ +function getAllQueryParamsFromURL() { + var queryParamList = [], qParam; + var urlQueryString = decodeURIComponent(window.top.location.search.substring(1)); + if (urlQueryString) { + var queryStringPairs = urlQueryString.split('&'); + for (var i = 0; i < queryStringPairs.length; i++) { + qParam = queryStringPairs[i].split('='); + queryParamList[qParam[0]] = qParam[1]; + } + return queryParamList; + } else { + return null; + } +} + +/** + * Retrieves the values from the URL-QueryString corresponding to the given QueryParams in the gadget-conf file. + * The parameters "timeTo" & "timeFrom" (if found in the query string) are added to the returned object regardless + * of whether they are listed in the gadget-conf. + * @returns {*} an associative array of the given params in the conf and corresponding value fetched from the + * URL string. + */ +function getValuesOfQueryFilter() { + var queryValues = []; + + if (TIME_FROM_STRING in urlQueryParams) { + queryValues[TIME_FROM_STRING] = urlQueryParams[TIME_FROM_STRING]; + } + + if (TIME_TO_STRING in urlQueryParams) { + queryValues[TIME_TO_STRING] = urlQueryParams[TIME_TO_STRING]; + } + + for (var i = 0; i < paramsToFilterBy.length; i++) { + var queryV = urlQueryParams[paramsToFilterBy[i]]; + + // if atleast one of the queryParams given in the gadgetConf is missing then return "null". + if (typeof queryV != "undefined" && queryV != null && queryV != "") { + queryValues[paramsToFilterBy[i]] = queryV; + } else { + return null; + } + } + return queryValues; +} + +/** + * Constructs the Lucene Query String to be sent to DAS API. + * @returns {string} a fully constructed query string from the params given in gadget-conf and + * the query string of the URL. + */ +function constructQueryString() { + var queryString = "'"; + for (var a = 0; a < paramsToFilterBy.length; a++) { + if (queryString.length == 1) { + queryString += META_TAG + paramsToFilterBy[a] + ":" + queryParamValPair[paramsToFilterBy[a]]; + } else { + queryString += " AND " + META_TAG + paramsToFilterBy[a] + ":" + queryParamValPair[paramsToFilterBy[a]]; + } + } + + if (TIME_FROM_STRING in queryParamValPair && TIME_TO_STRING in queryParamValPair) { + // both ends of the time-range (From What Date - To What Date) is given + queryString += " AND " + META_TAG + "time:" + + "[" + queryParamValPair[TIME_FROM_STRING] + " TO " + queryParamValPair[TIME_TO_STRING] + "]"; + + } else if (TIME_FROM_STRING in queryParamValPair && !(TIME_TO_STRING in queryParamValPair)) { + // Only the start of the time-range (From What Date) is given + queryString += " AND " + META_TAG + "time:" + + "[" + queryParamValPair[TIME_FROM_STRING] + " TO " + UNIX_TIME_MAX_VALUE + "]"; + + } else if (!(TIME_FROM_STRING in queryParamValPair) && TIME_TO_STRING in queryParamValPair) { + // Only the end of the time-range (To What Date) is given + queryString += " AND " + META_TAG + "time:" + + "[" + UNIX_TIME_MIN_VALUE + " TO " + queryParamValPair[TIME_TO_STRING] + "]"; + } + //queryString += " AND meta_time:[1456467843079 TO 1456468494817]'"; + queryString += "'"; + return queryString; +} + +/** + * Utility method to fetch columns of the datasource provided for a Batch-Type Gadget. + * @param table the name of the datasource table whose columns needs to be extracted. + */ +function getColumns(table) { + console.log("Fetching table schema for table: " + table); + var url = "/portal/apis/analytics?type=10&tableName=" + table; + $.getJSON(url, function (data) { + if (data) { + columns = parseColumns(JSON.parse(data.message)); + } + + }); +} + +/** Constructs an associative array containing the columns and the corresponding data-type ("String", "Long", etc) + * from the returned object as a result of the "getColumns" method above. + * @param data the response object returned from the "getColumns(table)" call to the DAS API. + * @returns {Array|*} an array containing the column names as keys and their type as values. + */ +function parseColumns(data) { + if (data.columns) { + var keys = Object.getOwnPropertyNames(data.columns); + columns = keys.map(function (key, i) { + return column = { + name: key, + type: data.columns[key].type + }; + }); + return columns; + } +} + +/** + * Makes the initial call to the DAS APIs to get the count of all matching indexes based on a given query. + * Upon receiving a response (count), a subsequent method is called to fetch the given "count" amount of data from + * DAS that matches the query. + * @param callback the subsequent method to be called using the "count" response value received from the API call. + */ +function fetchDataOnQuery(callback) { + var request = { + type: TYPE_SEARCH_COUNT, // DAS API type corresponding to fetching data-count for "query" + tableName: datasource, + query: queryString + }; + $.ajax({ + url: "/portal/apis/analytics", + method: "GET", + data: request, + contentType: "application/json", + success: function (data) { + if (callback != null) { + callback(drawBatchChart, data.message); + } + } + }); +} + +/** + * Makes an API call to the DAS to fetch the "count" number of data matching the queryString constructed from the + * query-string and the param-list provided in the gadget-conf. The fetched data are passed into the provided + * "callback" method which further processes and draws the chart against this data. + * @param callback the method to which the fetched data are to be passed in for further processing. + * @param totalCount the count of all matching data available against the queryString. + */ +function fetchDataWithCount(callback, totalCount) { + var timeFrom = "undefined"; + var timeTo = "undefined"; + var request = { + type: TYPE_SEARCH, // DAS API type corresponding to fetching data for "query" + tableName: datasource, + filter: filter, + query: queryString, + timeFrom: timeFrom, + timeTo: timeTo, + start: 0, + count: totalCount + }; + $.ajax({ + url: "/portal/apis/analytics", + method: "GET", + data: request, + contentType: "application/json", + success: function (data) { + if (callback != null) { + var sortedData = sortData(data.message); + callback(makeRows(sortedData)); + } + } + }); +} + +/** + * Retrieves all data available in a datasource irrespective of any query filters. However, the API call incorporates + * a data range to be submitted whilst fetching this info. If such date range related query strings + * ("timeFrom" or "timeTo") are found in the URL, then they are used. + * @param callback the method to which the fetched data are to be passed in for further processing. + */ +function fetchDataWithoutQuery(callback) { + var timeFrom = "undefined"; + var timeTo = "undefined"; + + if (urlQueryParams != null) { + if (TIME_FROM_STRING in urlQueryParams) { + timeFrom = urlQueryParams[TIME_FROM_STRING]; + } + + if (TIME_TO_STRING in urlQueryParams) { + timeTo = urlQueryParams[TIME_TO_STRING]; + } + } + + var request = { + type: TYPE_GET_BY_RANGE, // DAS API type corresponding to fetching data by date range. + tableName: datasource, + timeFrom: timeFrom, + timeTo: timeTo, + start: 0 + }; + $.ajax({ + url: "/portal/apis/analytics", + method: "GET", + data: request, + contentType: "application/json", + success: function (data) { + if (callback != null) { + callback(makeRows(JSON.parse(data.message))); + } + } + }); +} + +/** + * This is a utility method to convert Unix-Timestamp values to Epoch Time + * @param unix_timestamp the unix time to be converted + * @returns {string} the formatted epoch-time of the given unix-timestamp + */ +function convertToEpoch(unix_timestamp) { + // Create a new JavaScript Date object based on the timestamp + // multiplied by 1000 so that the argument is in milliseconds, not seconds. + var date = new Date(unix_timestamp * 1000); + // Hours part from the timestamp + var hours = date.getHours(); + // Minutes part from the timestamp + var minutes = "0" + date.getMinutes(); + // Seconds part from the timestamp + var seconds = "0" + date.getSeconds(); + + var thisDate = date.getDate(); + var thisMonth = date.getMonth(); + var thisYear = date.getUTCFullYear(); + + var formattedTime = hours + ':' + minutes.substr(-2) + ':' + seconds.substr(-2); + + // Will display time in 10:30:23 format + return (formattedTime); +} + +/** + * Sorts the given data array according to the values of its "timestamp" key. + * @param payload a JSON string with multiple data-arrays having a "timestamp" key-value pair. + * @returns {*} JSON Object with multiple sorted by "timestamp" + */ +function sortData(payload) { + var dataFromDAS = JSON.parse(payload); + sortedData = dataFromDAS.sort(function (a, b) { + return a.timestamp - b.timestamp; + }); + return sortedData; +} + +/** + * Fetches the values corresponding to the keys in the "columns" (either provided in the gadget-conf or fetched via the + * "getColumns(table)" method) array from the data object passed in. + * @param data a JSON Object containing multiple data values fetched from the datasource with column-name:value pairs. + * @returns {Array} an array with objects that contain the columns from the fetched "columns" and their corresponding + * values. + */ +function makeRows(data) { + var rows = []; + for (var i = 0; i < data.length; i++) { + var record = data[i]; + var keys = Object.getOwnPropertyNames(record.values); + keys.push(); + + var row = columns.map(function (column, i) { + var colName = column.name; + var recordVal = record.values[colName]; + + if (typeof recordVal == 'undefined') { + if (column.name.toUpperCase() === "TIMESTAMP" && (record.timestamp || record.TIMESTAMP)) { + recordVal = record.timestamp; + } else { + recordVal = record.values[META_TAG + colName]; + } + } + return recordVal; + }); + rows.push(row); + } + return rows; +} + +function makeDataTable(data) { + var dataTable = new igviz.DataTable(); + if (columns.length > 0) { + columns.forEach(function (column, i) { + var type = "N"; + if (column.type == "STRING" || column.type == "string") { + type = "C"; + } else if (column.type == "TIME" || column.type == "time") { + type = "T"; + } + dataTable.addColumn(column.name, type); + }); + } + data.forEach(function (row, index) { + for (var i = 0; i < row.length; i++) { + if (dataTable.metadata.types[i] == "N") { + data[index][i] = parseInt(data[index][i]); + } + } + }); + dataTable.addRows(data); + return dataTable; +} + +function drawChart(data) { + var dataTable = makeDataTable(data); + gadgetConfig.chartConfig.width = $("#placeholder").width(); + gadgetConfig.chartConfig.height = $("#placeholder").height() - 65; + var chartType = gadgetConfig.chartConfig.chartType; + var xAxis = gadgetConfig.chartConfig.xAxis; + jQuery("#noChart").html(""); + if (chartType === "bar" && dataTable.metadata.types[xAxis] === "N") { + dataTable.metadata.types[xAxis] = "C"; + } + + if (gadgetConfig.chartConfig.chartType === "table" || gadgetConfig.chartConfig.chartType === "singleNumber") { + gadgetConfig.chartConfig.height = $("#placeholder").height(); + chart = igviz.draw("#placeholder", gadgetConfig.chartConfig, dataTable); + chart.plot(dataTable.data); + + } else { + chart = igviz.setUp("#placeholder", gadgetConfig.chartConfig, dataTable); + chart.setXAxis({ + "labelAngle": -35, + "labelAlign": "right", + "labelDy": 0, + "labelDx": 0, + "titleDy": 25 + }) + .setYAxis({ + "titleDy": -30 + }); + chart.plot(dataTable.data); + } +} + + +//stuff required for realtime charting +function onRealTimeEventSuccessRecieval(streamId, data) { + drawRealtimeChart(data); +} + +function onRealTimeEventErrorRecieval(dataError) { + console.log("Error occurred " + dataError); +} + +/** + * Draws the real-time chart based on the values in the data object passed in. + * @param data an object containing all the column:value pair data + */ +function drawRealtimeChart(data) { + if (chart == null) { + jQuery("#noChart").html(""); + gadgetConfig.chartConfig.width = $("#placeholder").width() - 110; + gadgetConfig.chartConfig.height = $("#placeholder").height() - 40; + + if (gadgetConfig.chartConfig.charts[0].type == "map") { + var mapType = gadgetConfig.chartConfig.charts[0].mapType; + + if (mapType == "world") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/world/'; + } else if (mapType == "usa") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usaInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usa/'; + } else if (mapType == "europe") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/europe/'; + } + } + + chart = new vizg(createDataTable(convertData(data)), gadgetConfig.chartConfig); + chart.draw("#placeholder"); + } else { + chart.insert(convertData(data)); + } +} + +/** + * Draws the batch-chart based on the values in the data object passed in. + * @param data an object containing all the column:value pair data + */ +function drawBatchChart(data) { + if (chart == null) { + jQuery("#noChart").html(""); + gadgetConfig.chartConfig.width = $("#placeholder").width() - 110; + gadgetConfig.chartConfig.height = $("#placeholder").height() - 40; + + if (gadgetConfig.chartConfig.charts[0].type == "map") { + var mapType = gadgetConfig.chartConfig.charts[0].mapType; + + if (mapType == "world") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/world/'; + } else if (mapType == "usa") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usaInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/usa/'; + } else if (mapType == "europe") { + gadgetConfig.chartConfig.helperUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/countryInfo/'; + gadgetConfig.chartConfig.geoCodesUrl = document.location.protocol + "//" + document.location.host + '/portal/geojson/europe/'; + } + } + + initialConfig = JSON.parse(JSON.stringify(gadgetConfig.chartConfig)); + + } else { + gadgetConfig.chartConfig = initialConfig; + initialConfig = JSON.parse(JSON.stringify(gadgetConfig.chartConfig)); + } + + chart = new vizg(createDataTable(convertData(data)), gadgetConfig.chartConfig); + chart.draw("#placeholder"); +} + + +function convertData(data) { + for (var i = 0; i < data.length; i++) { + for (var x = 0; x < data[i].length; x++) { + var type = gadgetConfig.columns[x]["type"].toUpperCase(); + if (type != "STRING" && type != "BOOLEAN") { + data[i][x] = parseFloat(data[i][x]); + } + } + } + return data; +} + +function createDataTable(data) { + var names = []; + var types = []; + + for (var i = 0; i < gadgetConfig.columns.length; i++) { + var name = gadgetConfig.columns[i]["name"]; + names.push(name); + var type = columns[i]["type"].toUpperCase(); + + if (type === "INT" || type === "INTEGER" || type === "FLOAT" || type === "DOUBLE") { + type = "linear"; + } else if (gadgetConfig.columns[i]["type"].toUpperCase() == "TIME" || name.toUpperCase() == "TIME") { + type = "time"; + } else { + type = "ordinal"; + } + types.push(type); + } + + datatable = [ + { + "metadata": { + "names": names, + "types": types + }, + "data": data + } + ]; + return datatable; +} \ No newline at end of file diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/outputAdapterUiLibrary.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/outputAdapterUiLibrary.js new file mode 100644 index 00000000..2cda2727 --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/outputAdapterUiLibrary.js @@ -0,0 +1,285 @@ +/* + * + * + * Copyright (c) 2015, 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 CONSTANTS = { + webAppName: 'outputui', + urlSeperator: '/', + urlGetParameter : '?lastUpdatedTime=', + urlQueryStringBegin : '?', + tenantUrlAttribute: 't', + urlUnsecureTransportHttp : 'http://', + urlUnsecureTransportWebsocket : 'ws://', + urlSecureTransportWebsocket : 'wss://', + urlSecureTransportHttp : 'https://', + colon : ':', + defaultIntervalTime : 10 * 1000, + defaultUserDomain : 'carbon.super', + defaultHostName : 'localhost', + defaultNonsecurePortNumber : '9763', + defaultSecurePortNumber : '9443', + defaultMode : 'AUTO', + processModeHTTP : 'HTTP', + processModeWebSocket : 'WEBSOCKET', + processModeAuto : 'AUTO', + domain : 'carbon.super', + numThousand : 1000, + websocketTimeAppender : 400, + secureMode : 'SECURED' +}; + + +var websocket = null; +var webSocketUrl; +var httpUrl; +var cepHostName; +var cepPortNumber; +var isErrorOccured = false; +var lastUpdatedtime = -1; +var polingInterval; +var stream; +var streamVersion; +var firstPollingAttempt; +var processMode; +var onSuccessFunction; +var onErrorFunction; +var userDomainUrl = ""; +var terminateWebsocketInstance = false; +var pollingContinue = true; +var transportToBeUsedHttp; +var transportToBeUsedWebsocket; + +function subscribe(streamName,version,intervalTime,domain, + listeningFuncSuccessData,listeningFuncErrorData, + cepHost,cepPort,mode,secureMode, queryParams){ + + stopPollingProcesses(); + stream = streamName; + streamVersion = version; + onSuccessFunction = listeningFuncSuccessData; + onErrorFunction = listeningFuncErrorData; + + if(secureMode == CONSTANTS.secureMode){ + transportToBeUsedHttp = CONSTANTS.urlSecureTransportHttp; + transportToBeUsedWebsocket = CONSTANTS.urlSecureTransportWebsocket; + } else { + transportToBeUsedHttp = CONSTANTS.urlUnsecureTransportHttp; + transportToBeUsedWebsocket = CONSTANTS.urlUnsecureTransportWebsocket; + } + + if(intervalTime == null || intervalTime == ""){ + polingInterval = CONSTANTS.defaultIntervalTime; + } else{ + polingInterval = intervalTime * CONSTANTS.numThousand; + } + + if(domain == null || domain == ""){ + domain = CONSTANTS.defaultUserDomain; + } + + if(cepHost == null || cepHost == ""){ + cepHostName = CONSTANTS.defaultHostName; + } else{ + cepHostName = cepHost; + } + + if(cepPort == null || cepPort == ""){ + if(secureMode == CONSTANTS.secureMode){ + cepPortNumber = CONSTANTS.defaultSecurePortNumber; + } else{ + cepPortNumber = CONSTANTS.defaultNonsecurePortNumber; + } + } else{ + cepPortNumber = cepPort; + } + + if(mode == null || mode == ""){ + processMode = CONSTANTS.defaultMode; + } else{ + processMode = mode; + } + + if(domain != CONSTANTS.domain){ + userDomainUrl = CONSTANTS.tenantUrlAttribute + CONSTANTS.urlSeperator + domain + CONSTANTS.urlSeperator; + + } + + if (queryParams == null) { + queryParams = ""; + } else if (queryParams != "") { + queryParams = CONSTANTS.urlQueryStringBegin + queryParams; + } + + webSocketUrl = transportToBeUsedWebsocket + cepHostName + CONSTANTS.colon + cepPortNumber + + CONSTANTS.urlSeperator + CONSTANTS.webAppName+ CONSTANTS.urlSeperator + userDomainUrl + stream + + CONSTANTS.urlSeperator + streamVersion + queryParams; + + + if(processMode == CONSTANTS.processModeHTTP){ + firstPollingAttempt = true; + pollingContinue = true; + startPoll(); + } else{ + initializeWebSocket(webSocketUrl); + } +} + + +/** + * Initializing Web Socket + */ +function initializeWebSocket(webSocketUrl){ + websocket = new WebSocket(webSocketUrl); + websocket.onopen = webSocketOnOpen; + websocket.onmessage = webSocketOnMessage; + websocket.onclose = webSocketOnClose; + websocket.onerror = webSocketOnError; +} + +/** + * Web socket On Open + */ + +var webSocketOnOpen = function () { + // alert("Successfully connected to "+webSocketUrl); + //onErrorFunction("Successfully connected to URL:" + webSocketUrl + "\n"); +}; + + +/** + * On server sends a message + */ +var webSocketOnMessage = function (evt) { + var event = evt.data; + var array = JSON.parse(event); + constructPayload(array); +}; + +/** + * On server close + */ +var webSocketOnClose =function (e) { + + if(isErrorOccured){ + if(processMode != CONSTANTS.processModeWebSocket){ + firstPollingAttempt = true; + pollingContinue = true; + startPoll(); + } + } else{ + if(!terminateWebsocketInstance){ + waitForSocketConnection(websocket); + } else{ + terminateWebsocketInstance = false; + } + + } +}; + +/** + * On server Error + */ +var webSocketOnError = function (err) { + var error = "Error: Cannot connect to Websocket URL:" + webSocketUrl + " .Hence closing the connection!"; + + onErrorFunction(error); + isErrorOccured = true; + +}; + +/** + * Gracefully increments the connection retry + */ +var waitTime = CONSTANTS.numThousand; +function waitForSocketConnection(socket, callback){ + setTimeout( + function () { + if (socket.readyState === 1) { + initializeWebSocket(webSocketUrl); + console.log("Connection is made"); + if(callback != null){ + callback(); + } + return; + } else { + websocket = new WebSocket(webSocketUrl); + waitTime += CONSTANTS.websocketTimeAppender; + waitForSocketConnection(websocket, callback); + } + }, waitTime); +} + +/** + * Polling to retrieve events from http request periodically + */ +function startPoll(){ + + (function poll(){ + setTimeout(function(){ + httpUrl = transportToBeUsedHttp + cepHostName + CONSTANTS.colon + cepPortNumber + CONSTANTS.urlSeperator + + CONSTANTS.webAppName + CONSTANTS.urlSeperator + userDomainUrl + stream + CONSTANTS.urlSeperator + + streamVersion + CONSTANTS.urlGetParameter + lastUpdatedtime; + + $.getJSON(httpUrl, function(responseText) { + if(firstPollingAttempt){ + /*var data = $("textarea#idConsole").val(); + $("textarea#idConsole").val(data + "Successfully connected to HTTP.");*/ + firstPollingAttempt = false; + } + + var eventList = $.parseJSON(responseText.events); + if(eventList.length != 0){ + lastUpdatedtime = responseText.lastEventTime; + for(var i=0;i 1) { + var geomsByArc = [], + geom; + + function arc(i) { + var j = i < 0 ? ~i : i; + (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom}); + } + + function line(arcs) { + arcs.forEach(arc); + } + + function polygon(arcs) { + arcs.forEach(line); + } + + function geometry(o) { + if (o.type === "GeometryCollection") o.geometries.forEach(geometry); + else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs); + } + + var geometryType = { + LineString: line, + MultiLineString: polygon, + Polygon: polygon, + MultiPolygon: function(arcs) { arcs.forEach(polygon); } + }; + + geometry(o); + + geomsByArc.forEach(arguments.length < 3 + ? function(geoms) { arcs.push(geoms[0].i); } + : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); }); + } else { + for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i); + } + + return {type: "MultiLineString", arcs: stitchArcs(topology, arcs)}; + } + + function mergeArcs(topology, objects) { + var polygonsByArc = {}, + polygons = [], + components = []; + + objects.forEach(function(o) { + if (o.type === "Polygon") register(o.arcs); + else if (o.type === "MultiPolygon") o.arcs.forEach(register); + }); + + function register(polygon) { + polygon.forEach(function(ring) { + ring.forEach(function(arc) { + (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon); + }); + }); + polygons.push(polygon); + } + + function exterior(ring) { + return cartesianRingArea(object(topology, {type: "Polygon", arcs: [ring]}).coordinates[0]) > 0; // TODO allow spherical? + } + + polygons.forEach(function(polygon) { + if (!polygon._) { + var component = [], + neighbors = [polygon]; + polygon._ = 1; + components.push(component); + while (polygon = neighbors.pop()) { + component.push(polygon); + polygon.forEach(function(ring) { + ring.forEach(function(arc) { + polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) { + if (!polygon._) { + polygon._ = 1; + neighbors.push(polygon); + } + }); + }); + }); + } + } + }); + + polygons.forEach(function(polygon) { + delete polygon._; + }); + + return { + type: "MultiPolygon", + arcs: components.map(function(polygons) { + var arcs = []; + + // Extract the exterior (unique) arcs. + polygons.forEach(function(polygon) { + polygon.forEach(function(ring) { + ring.forEach(function(arc) { + if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) { + arcs.push(arc); + } + }); + }); + }); + + // Stitch the arcs into one or more rings. + arcs = stitchArcs(topology, arcs); + + // If more than one ring is returned, + // at most one of these rings can be the exterior; + // this exterior ring has the same winding order + // as any exterior ring in the original polygons. + if ((n = arcs.length) > 1) { + var sgn = exterior(polygons[0][0]); + for (var i = 0, t; i < n; ++i) { + if (sgn === exterior(arcs[i])) { + t = arcs[0], arcs[0] = arcs[i], arcs[i] = t; + break; + } + } + } + + return arcs; + }) + }; + } + + function featureOrCollection(topology, o) { + return o.type === "GeometryCollection" ? { + type: "FeatureCollection", + features: o.geometries.map(function(o) { return feature(topology, o); }) + } : feature(topology, o); + } + + function feature(topology, o) { + var f = { + type: "Feature", + id: o.id, + properties: o.properties || {}, + geometry: object(topology, o) + }; + if (o.id == null) delete f.id; + return f; + } + + function object(topology, o) { + var absolute = transformAbsolute(topology.transform), + arcs = topology.arcs; + + function arc(i, points) { + if (points.length) points.pop(); + for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) { + points.push(p = a[k].slice()); + absolute(p, k); + } + if (i < 0) reverse(points, n); + } + + function point(p) { + p = p.slice(); + absolute(p, 0); + return p; + } + + function line(arcs) { + var points = []; + for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points); + if (points.length < 2) points.push(points[0].slice()); + return points; + } + + function ring(arcs) { + var points = line(arcs); + while (points.length < 4) points.push(points[0].slice()); + return points; + } + + function polygon(arcs) { + return arcs.map(ring); + } + + function geometry(o) { + var t = o.type; + return t === "GeometryCollection" ? {type: t, geometries: o.geometries.map(geometry)} + : t in geometryType ? {type: t, coordinates: geometryType[t](o)} + : null; + } + + var geometryType = { + Point: function(o) { return point(o.coordinates); }, + MultiPoint: function(o) { return o.coordinates.map(point); }, + LineString: function(o) { return line(o.arcs); }, + MultiLineString: function(o) { return o.arcs.map(line); }, + Polygon: function(o) { return polygon(o.arcs); }, + MultiPolygon: function(o) { return o.arcs.map(polygon); } + }; + + return geometry(o); + } + + function reverse(array, n) { + var t, j = array.length, i = j - n; while (i < --j) t = array[i], array[i++] = array[j], array[j] = t; + } + + function bisect(a, x) { + var lo = 0, hi = a.length; + while (lo < hi) { + var mid = lo + hi >>> 1; + if (a[mid] < x) lo = mid + 1; + else hi = mid; + } + return lo; + } + + function neighbors(objects) { + var indexesByArc = {}, // arc index -> array of object indexes + neighbors = objects.map(function() { return []; }); + + function line(arcs, i) { + arcs.forEach(function(a) { + if (a < 0) a = ~a; + var o = indexesByArc[a]; + if (o) o.push(i); + else indexesByArc[a] = [i]; + }); + } + + function polygon(arcs, i) { + arcs.forEach(function(arc) { line(arc, i); }); + } + + function geometry(o, i) { + if (o.type === "GeometryCollection") o.geometries.forEach(function(o) { geometry(o, i); }); + else if (o.type in geometryType) geometryType[o.type](o.arcs, i); + } + + var geometryType = { + LineString: line, + MultiLineString: polygon, + Polygon: polygon, + MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); } + }; + + objects.forEach(geometry); + + for (var i in indexesByArc) { + for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) { + for (var k = j + 1; k < m; ++k) { + var ij = indexes[j], ik = indexes[k], n; + if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik); + if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij); + } + } + } + + return neighbors; + } + + function presimplify(topology, triangleArea) { + var absolute = transformAbsolute(topology.transform), + relative = transformRelative(topology.transform), + heap = minAreaHeap(); + + if (!triangleArea) triangleArea = cartesianTriangleArea; + + topology.arcs.forEach(function(arc) { + var triangles = [], + maxArea = 0, + triangle; + + // To store each point’s effective area, we create a new array rather than + // extending the passed-in point to workaround a Chrome/V8 bug (getting + // stuck in smi mode). For midpoints, the initial effective area of + // Infinity will be computed in the next step. + for (var i = 0, n = arc.length, p; i < n; ++i) { + p = arc[i]; + absolute(arc[i] = [p[0], p[1], Infinity], i); + } + + for (var i = 1, n = arc.length - 1; i < n; ++i) { + triangle = arc.slice(i - 1, i + 2); + triangle[1][2] = triangleArea(triangle); + triangles.push(triangle); + heap.push(triangle); + } + + for (var i = 0, n = triangles.length; i < n; ++i) { + triangle = triangles[i]; + triangle.previous = triangles[i - 1]; + triangle.next = triangles[i + 1]; + } + + while (triangle = heap.pop()) { + var previous = triangle.previous, + next = triangle.next; + + // If the area of the current point is less than that of the previous point + // to be eliminated, use the latter's area instead. This ensures that the + // current point cannot be eliminated without eliminating previously- + // eliminated points. + if (triangle[1][2] < maxArea) triangle[1][2] = maxArea; + else maxArea = triangle[1][2]; + + if (previous) { + previous.next = next; + previous[2] = triangle[2]; + update(previous); + } + + if (next) { + next.previous = previous; + next[0] = triangle[0]; + update(next); + } + } + + arc.forEach(relative); + }); + + function update(triangle) { + heap.remove(triangle); + triangle[1][2] = triangleArea(triangle); + heap.push(triangle); + } + + return topology; + }; + + function cartesianRingArea(ring) { + var i = -1, + n = ring.length, + a, + b = ring[n - 1], + area = 0; + + while (++i < n) { + a = b; + b = ring[i]; + area += a[0] * b[1] - a[1] * b[0]; + } + + return area * .5; + } + + function cartesianTriangleArea(triangle) { + var a = triangle[0], b = triangle[1], c = triangle[2]; + return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1])); + } + + function compareArea(a, b) { + return a[1][2] - b[1][2]; + } + + function minAreaHeap() { + var heap = {}, + array = [], + size = 0; + + heap.push = function(object) { + up(array[object._ = size] = object, size++); + return size; + }; + + heap.pop = function() { + if (size <= 0) return; + var removed = array[0], object; + if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0); + return removed; + }; + + heap.remove = function(removed) { + var i = removed._, object; + if (array[i] !== removed) return; // invalid request + if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i); + return i; + }; + + function up(object, i) { + while (i > 0) { + var j = ((i + 1) >> 1) - 1, + parent = array[j]; + if (compareArea(object, parent) >= 0) break; + array[parent._ = i] = parent; + array[object._ = i = j] = object; + } + } + + function down(object, i) { + while (true) { + var r = (i + 1) << 1, + l = r - 1, + j = i, + child = array[j]; + if (l < size && compareArea(array[l], child) < 0) child = array[j = l]; + if (r < size && compareArea(array[r], child) < 0) child = array[j = r]; + if (j === i) break; + array[child._ = i] = child; + array[object._ = i = j] = object; + } + } + + return heap; + } + + function transformAbsolute(transform) { + if (!transform) return noop; + var x0, + y0, + kx = transform.scale[0], + ky = transform.scale[1], + dx = transform.translate[0], + dy = transform.translate[1]; + return function(point, i) { + if (!i) x0 = y0 = 0; + point[0] = (x0 += point[0]) * kx + dx; + point[1] = (y0 += point[1]) * ky + dy; + }; + } + + function transformRelative(transform) { + if (!transform) return noop; + var x0, + y0, + kx = transform.scale[0], + ky = transform.scale[1], + dx = transform.translate[0], + dy = transform.translate[1]; + return function(point, i) { + if (!i) x0 = y0 = 0; + var x1 = (point[0] - dx) / kx | 0, + y1 = (point[1] - dy) / ky | 0; + point[0] = x1 - x0; + point[1] = y1 - y0; + x0 = x1; + y0 = y1; + }; + } + + function noop() {} + + if (typeof define === "function" && define.amd) define(topojson); + else if (typeof module === "object" && module.exports) module.exports = topojson; + else this.topojson = topojson; +}(); diff --git a/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/vega.js b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/vega.js new file mode 100644 index 00000000..c6b8b0af --- /dev/null +++ b/modules/distribution/src/repository/jaggeryapps/portal/store/carbon.super/gadget/TemperatureChart/js/vega.js @@ -0,0 +1,20654 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.vg = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o> 5, + ch = 1 << 11; + + module.exports = function() { + var size = [256, 256], + text = cloudText, + font = cloudFont, + fontSize = cloudFontSize, + fontStyle = cloudFontNormal, + fontWeight = cloudFontNormal, + rotate = cloudRotate, + padding = cloudPadding, + spiral = archimedeanSpiral, + words = [], + timeInterval = Infinity, + event = dispatch("word", "end"), + timer = null, + random = Math.random, + cloud = {}, + canvas = cloudCanvas; + + cloud.canvas = function(_) { + return arguments.length ? (canvas = functor(_), cloud) : canvas; + }; + + cloud.start = function() { + var contextAndRatio = getContext(canvas()), + board = zeroArray((size[0] >> 5) * size[1]), + bounds = null, + n = words.length, + i = -1, + tags = [], + data = words.map(function(d, i) { + d.text = text.call(this, d, i); + d.font = font.call(this, d, i); + d.style = fontStyle.call(this, d, i); + d.weight = fontWeight.call(this, d, i); + d.rotate = rotate.call(this, d, i); + d.size = ~~fontSize.call(this, d, i); + d.padding = padding.call(this, d, i); + return d; + }).sort(function(a, b) { return b.size - a.size; }); + + if (timer) clearInterval(timer); + timer = setInterval(step, 0); + step(); + + return cloud; + + function step() { + var start = Date.now(); + while (Date.now() - start < timeInterval && ++i < n && timer) { + var d = data[i]; + d.x = (size[0] * (random() + .5)) >> 1; + d.y = (size[1] * (random() + .5)) >> 1; + cloudSprite(contextAndRatio, d, data, i); + if (d.hasText && place(board, d, bounds)) { + tags.push(d); + event.word(d); + if (bounds) cloudBounds(bounds, d); + else bounds = [{x: d.x + d.x0, y: d.y + d.y0}, {x: d.x + d.x1, y: d.y + d.y1}]; + // Temporary hack + d.x -= size[0] >> 1; + d.y -= size[1] >> 1; + } + } + if (i >= n) { + cloud.stop(); + event.end(tags, bounds); + } + } + } + + cloud.stop = function() { + if (timer) { + clearInterval(timer); + timer = null; + } + return cloud; + }; + + function getContext(canvas) { + canvas.width = canvas.height = 1; + var ratio = Math.sqrt(canvas.getContext("2d").getImageData(0, 0, 1, 1).data.length >> 2); + canvas.width = (cw << 5) / ratio; + canvas.height = ch / ratio; + + var context = canvas.getContext("2d"); + context.fillStyle = context.strokeStyle = "red"; + context.textAlign = "center"; + + return {context: context, ratio: ratio}; + } + + function place(board, tag, bounds) { + var perimeter = [{x: 0, y: 0}, {x: size[0], y: size[1]}], + startX = tag.x, + startY = tag.y, + maxDelta = Math.sqrt(size[0] * size[0] + size[1] * size[1]), + s = spiral(size), + dt = random() < .5 ? 1 : -1, + t = -dt, + dxdy, + dx, + dy; + + while (dxdy = s(t += dt)) { + dx = ~~dxdy[0]; + dy = ~~dxdy[1]; + + if (Math.min(Math.abs(dx), Math.abs(dy)) >= maxDelta) break; + + tag.x = startX + dx; + tag.y = startY + dy; + + if (tag.x + tag.x0 < 0 || tag.y + tag.y0 < 0 || + tag.x + tag.x1 > size[0] || tag.y + tag.y1 > size[1]) continue; + // TODO only check for collisions within current bounds. + if (!bounds || !cloudCollide(tag, board, size[0])) { + if (!bounds || collideRects(tag, bounds)) { + var sprite = tag.sprite, + w = tag.width >> 5, + sw = size[0] >> 5, + lx = tag.x - (w << 4), + sx = lx & 0x7f, + msx = 32 - sx, + h = tag.y1 - tag.y0, + x = (tag.y + tag.y0) * sw + (lx >> 5), + last; + for (var j = 0; j < h; j++) { + last = 0; + for (var i = 0; i <= w; i++) { + board[x + i] |= (last << msx) | (i < w ? (last = sprite[j * w + i]) >>> sx : 0); + } + x += sw; + } + delete tag.sprite; + return true; + } + } + } + return false; + } + + cloud.timeInterval = function(_) { + return arguments.length ? (timeInterval = _ == null ? Infinity : _, cloud) : timeInterval; + }; + + cloud.words = function(_) { + return arguments.length ? (words = _, cloud) : words; + }; + + cloud.size = function(_) { + return arguments.length ? (size = [+_[0], +_[1]], cloud) : size; + }; + + cloud.font = function(_) { + return arguments.length ? (font = functor(_), cloud) : font; + }; + + cloud.fontStyle = function(_) { + return arguments.length ? (fontStyle = functor(_), cloud) : fontStyle; + }; + + cloud.fontWeight = function(_) { + return arguments.length ? (fontWeight = functor(_), cloud) : fontWeight; + }; + + cloud.rotate = function(_) { + return arguments.length ? (rotate = functor(_), cloud) : rotate; + }; + + cloud.text = function(_) { + return arguments.length ? (text = functor(_), cloud) : text; + }; + + cloud.spiral = function(_) { + return arguments.length ? (spiral = spirals[_] || _, cloud) : spiral; + }; + + cloud.fontSize = function(_) { + return arguments.length ? (fontSize = functor(_), cloud) : fontSize; + }; + + cloud.padding = function(_) { + return arguments.length ? (padding = functor(_), cloud) : padding; + }; + + cloud.random = function(_) { + return arguments.length ? (random = _, cloud) : random; + }; + + cloud.on = function() { + var value = event.on.apply(event, arguments); + return value === event ? cloud : value; + }; + + return cloud; + }; + + function cloudText(d) { + return d.text; + } + + function cloudFont() { + return "serif"; + } + + function cloudFontNormal() { + return "normal"; + } + + function cloudFontSize(d) { + return Math.sqrt(d.value); + } + + function cloudRotate() { + return (~~(Math.random() * 6) - 3) * 30; + } + + function cloudPadding() { + return 1; + } + +// Fetches a monochrome sprite bitmap for the specified text. +// Load in batches for speed. + function cloudSprite(contextAndRatio, d, data, di) { + if (d.sprite) return; + var c = contextAndRatio.context, + ratio = contextAndRatio.ratio; + + c.clearRect(0, 0, (cw << 5) / ratio, ch / ratio); + var x = 0, + y = 0, + maxh = 0, + n = data.length; + --di; + while (++di < n) { + d = data[di]; + c.save(); + c.font = d.style + " " + d.weight + " " + ~~((d.size + 1) / ratio) + "px " + d.font; + var w = c.measureText(d.text + "m").width * ratio, + h = d.size << 1; + if (d.rotate) { + var sr = Math.sin(d.rotate * cloudRadians), + cr = Math.cos(d.rotate * cloudRadians), + wcr = w * cr, + wsr = w * sr, + hcr = h * cr, + hsr = h * sr; + w = (Math.max(Math.abs(wcr + hsr), Math.abs(wcr - hsr)) + 0x1f) >> 5 << 5; + h = ~~Math.max(Math.abs(wsr + hcr), Math.abs(wsr - hcr)); + } else { + w = (w + 0x1f) >> 5 << 5; + } + if (h > maxh) maxh = h; + if (x + w >= (cw << 5)) { + x = 0; + y += maxh; + maxh = 0; + } + if (y + h >= ch) break; + c.translate((x + (w >> 1)) / ratio, (y + (h >> 1)) / ratio); + if (d.rotate) c.rotate(d.rotate * cloudRadians); + c.fillText(d.text, 0, 0); + if (d.padding) c.lineWidth = 2 * d.padding, c.strokeText(d.text, 0, 0); + c.restore(); + d.width = w; + d.height = h; + d.xoff = x; + d.yoff = y; + d.x1 = w >> 1; + d.y1 = h >> 1; + d.x0 = -d.x1; + d.y0 = -d.y1; + d.hasText = true; + x += w; + } + var pixels = c.getImageData(0, 0, (cw << 5) / ratio, ch / ratio).data, + sprite = []; + while (--di >= 0) { + d = data[di]; + if (!d.hasText) continue; + var w = d.width, + w32 = w >> 5, + h = d.y1 - d.y0; + // Zero the buffer + for (var i = 0; i < h * w32; i++) sprite[i] = 0; + x = d.xoff; + if (x == null) return; + y = d.yoff; + var seen = 0, + seenRow = -1; + for (var j = 0; j < h; j++) { + for (var i = 0; i < w; i++) { + var k = w32 * j + (i >> 5), + m = pixels[((y + j) * (cw << 5) + (x + i)) << 2] ? 1 << (31 - (i % 32)) : 0; + sprite[k] |= m; + seen |= m; + } + if (seen) seenRow = j; + else { + d.y0++; + h--; + j--; + y++; + } + } + d.y1 = d.y0 + seenRow; + d.sprite = sprite.slice(0, (d.y1 - d.y0) * w32); + } + } + +// Use mask-based collision detection. + function cloudCollide(tag, board, sw) { + sw >>= 5; + var sprite = tag.sprite, + w = tag.width >> 5, + lx = tag.x - (w << 4), + sx = lx & 0x7f, + msx = 32 - sx, + h = tag.y1 - tag.y0, + x = (tag.y + tag.y0) * sw + (lx >> 5), + last; + for (var j = 0; j < h; j++) { + last = 0; + for (var i = 0; i <= w; i++) { + if (((last << msx) | (i < w ? (last = sprite[j * w + i]) >>> sx : 0)) + & board[x + i]) return true; + } + x += sw; + } + return false; + } + + function cloudBounds(bounds, d) { + var b0 = bounds[0], + b1 = bounds[1]; + if (d.x + d.x0 < b0.x) b0.x = d.x + d.x0; + if (d.y + d.y0 < b0.y) b0.y = d.y + d.y0; + if (d.x + d.x1 > b1.x) b1.x = d.x + d.x1; + if (d.y + d.y1 > b1.y) b1.y = d.y + d.y1; + } + + function collideRects(a, b) { + return a.x + a.x1 > b[0].x && a.x + a.x0 < b[1].x && a.y + a.y1 > b[0].y && a.y + a.y0 < b[1].y; + } + + function archimedeanSpiral(size) { + var e = size[0] / size[1]; + return function(t) { + return [e * (t *= .1) * Math.cos(t), t * Math.sin(t)]; + }; + } + + function rectangularSpiral(size) { + var dy = 4, + dx = dy * size[0] / size[1], + x = 0, + y = 0; + return function(t) { + var sign = t < 0 ? -1 : 1; + // See triangular numbers: T_n = n * (n + 1) / 2. + switch ((Math.sqrt(1 + 4 * sign * t) - sign) & 3) { + case 0: x += dx; break; + case 1: y += dy; break; + case 2: x -= dx; break; + default: y -= dy; break; + } + return [x, y]; + }; + } + +// TODO reuse arrays? + function zeroArray(n) { + var a = [], + i = -1; + while (++i < n) a[i] = 0; + return a; + } + + function cloudCanvas() { + return document.createElement("canvas"); + } + + function functor(d) { + return typeof d === "function" ? d : function() { return d; }; + } + + var spirals = { + archimedean: archimedeanSpiral, + rectangular: rectangularSpiral + }; + +},{"d3-dispatch":4}],4:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define('d3-dispatch', ['exports'], factory) : + factory((global.d3_dispatch = {})); + }(this, function (exports) { 'use strict'; + + function dispatch() { + return new Dispatch(arguments); + } + + function Dispatch(types) { + var i = -1, + n = types.length, + callbacksByType = {}, + callbackByName = {}, + type, + that = this; + + that.on = function(type, callback) { + type = parseType(type); + + // Return the current callback, if any. + if (arguments.length < 2) { + return (callback = callbackByName[type.name]) && callback.value; + } + + // If a type was specified… + if (type.type) { + var callbacks = callbacksByType[type.type], + callback0 = callbackByName[type.name], + i; + + // Remove the current callback, if any, using copy-on-remove. + if (callback0) { + callback0.value = null; + i = callbacks.indexOf(callback0); + callbacksByType[type.type] = callbacks = callbacks.slice(0, i).concat(callbacks.slice(i + 1)); + delete callbackByName[type.name]; + } + + // Add the new callback, if any. + if (callback) { + callback = {value: callback}; + callbackByName[type.name] = callback; + callbacks.push(callback); + } + } + + // Otherwise, if a null callback was specified, remove all callbacks with the given name. + else if (callback == null) { + for (var otherType in callbacksByType) { + if (callback = callbackByName[otherType + type.name]) { + callback.value = null; + var callbacks = callbacksByType[otherType], i = callbacks.indexOf(callback); + callbacksByType[otherType] = callbacks.slice(0, i).concat(callbacks.slice(i + 1)); + delete callbackByName[callback.name]; + } + } + } + + return that; + }; + + while (++i < n) { + type = types[i] + ""; + if (!type || (type in that)) throw new Error("illegal or duplicate type: " + type); + callbacksByType[type] = []; + that[type] = applier(type); + } + + function parseType(type) { + var i = (type += "").indexOf("."), name = type; + if (i >= 0) type = type.slice(0, i); else name += "."; + if (type && !callbacksByType.hasOwnProperty(type)) throw new Error("unknown type: " + type); + return {type: type, name: name}; + } + + function applier(type) { + return function() { + var callbacks = callbacksByType[type], // Defensive reference; copy-on-remove. + callback, + callbackValue, + i = -1, + n = callbacks.length; + + while (++i < n) { + if (callbackValue = (callback = callbacks[i]).value) { + callbackValue.apply(this, arguments); + } + } + + return that; + }; + } + } + + dispatch.prototype = Dispatch.prototype; + + var version = "0.2.4"; + + exports.version = version; + exports.dispatch = dispatch; + + })); +},{}],5:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define('d3-dsv', ['exports'], factory) : + factory((global.d3_dsv = {})); + }(this, function (exports) { 'use strict'; + + function dsv(delimiter) { + return new Dsv(delimiter); + } + + function Dsv(delimiter) { + var reFormat = new RegExp("[\"" + delimiter + "\n]"), + delimiterCode = delimiter.charCodeAt(0); + + this.parse = function(text, f) { + var o; + return this.parseRows(text, function(row, i) { + if (o) return o(row, i - 1); + var a = new Function("d", "return {" + row.map(function(name, i) { + return JSON.stringify(name) + ": d[" + i + "]"; + }).join(",") + "}"); + o = f ? function(row, i) { return f(a(row), i); } : a; + }); + }; + + this.parseRows = function(text, f) { + var EOL = {}, // sentinel value for end-of-line + EOF = {}, // sentinel value for end-of-file + rows = [], // output rows + N = text.length, + I = 0, // current character index + n = 0, // the current line number + t, // the current token + eol; // is the current token followed by EOL? + + function token() { + if (I >= N) return EOF; // special case: end of file + if (eol) return eol = false, EOL; // special case: end of line + + // special case: quotes + var j = I; + if (text.charCodeAt(j) === 34) { + var i = j; + while (i++ < N) { + if (text.charCodeAt(i) === 34) { + if (text.charCodeAt(i + 1) !== 34) break; + ++i; + } + } + I = i + 2; + var c = text.charCodeAt(i + 1); + if (c === 13) { + eol = true; + if (text.charCodeAt(i + 2) === 10) ++I; + } else if (c === 10) { + eol = true; + } + return text.slice(j + 1, i).replace(/""/g, "\""); + } + + // common case: find next delimiter or newline + while (I < N) { + var c = text.charCodeAt(I++), k = 1; + if (c === 10) eol = true; // \n + else if (c === 13) { eol = true; if (text.charCodeAt(I) === 10) ++I, ++k; } // \r|\r\n + else if (c !== delimiterCode) continue; + return text.slice(j, I - k); + } + + // special case: last token before EOF + return text.slice(j); + } + + while ((t = token()) !== EOF) { + var a = []; + while (t !== EOL && t !== EOF) { + a.push(t); + t = token(); + } + if (f && (a = f(a, n++)) == null) continue; + rows.push(a); + } + + return rows; + } + + this.format = function(rows) { + if (Array.isArray(rows[0])) return this.formatRows(rows); // deprecated; use formatRows + var fieldSet = Object.create(null), fields = []; + + // Compute unique fields in order of discovery. + rows.forEach(function(row) { + for (var field in row) { + if (!((field += "") in fieldSet)) { + fields.push(fieldSet[field] = field); + } + } + }); + + return [fields.map(formatValue).join(delimiter)].concat(rows.map(function(row) { + return fields.map(function(field) { + return formatValue(row[field]); + }).join(delimiter); + })).join("\n"); + }; + + this.formatRows = function(rows) { + return rows.map(formatRow).join("\n"); + }; + + function formatRow(row) { + return row.map(formatValue).join(delimiter); + } + + function formatValue(text) { + return reFormat.test(text) ? "\"" + text.replace(/\"/g, "\"\"") + "\"" : text; + } + }; + + dsv.prototype = Dsv.prototype; + + var csv = dsv(","); + var tsv = dsv("\t"); + + var version = "0.1.9"; + + exports.version = version; + exports.dsv = dsv; + exports.csv = csv; + exports.tsv = tsv; + + })); +},{}],6:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define('d3-format', ['exports'], factory) : + factory((global.d3_format = {})); + }(this, function (exports) { 'use strict'; + + var zhCn = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["¥", ""] + }; + + var svSe = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "SEK"] + }; + + var ruRu = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "\xa0руб."] + }; + + var ptBr = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["R$", ""] + }; + + var plPl = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "zł"] + }; + + var nlNl = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["€\xa0", ""] + }; + + var mkMk = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0ден."] + }; + + var koKr = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["₩", ""] + }; + + var jaJp = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["", "円"] + }; + + var itIt = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["€", ""] + }; + + var huHu = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "\xa0Ft"] + }; + + var heIl = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["₪", ""] + }; + + var frFr = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0€"] + }; + + var frCa = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "$"] + }; + + var fiFi = { + decimal: ",", + thousands: "\xa0", + grouping: [3], + currency: ["", "\xa0€"] + }; + + var esEs = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0€"] + }; + + var enUs = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["$", ""] + }; + + var enGb = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["£", ""] + }; + + var enCa = { + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["$", ""] + }; + + var deDe = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0€"] + }; + + var deCh = { + decimal: ",", + thousands: "'", + grouping: [3], + currency: ["", "\xa0CHF"] + }; + + var caEs = { + decimal: ",", + thousands: ".", + grouping: [3], + currency: ["", "\xa0€"] + }; + + // Computes the decimal coefficient and exponent of the specified number x with + // significant digits p, where x is positive and p is in [1, 21] or undefined. + // For example, formatDecimal(1.23) returns ["123", 0]. + function formatDecimal(x, p) { + if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity + var i, coefficient = x.slice(0, i); + + // The string returned by toExponential either has the form \d\.\d+e[-+]\d+ + // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3). + return [ + coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient, + +x.slice(i + 1) + ]; + }; + + function exponent(x) { + return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN; + }; + + function formatGroup(grouping, thousands) { + return function(value, width) { + var i = value.length, + t = [], + j = 0, + g = grouping[0], + length = 0; + + while (i > 0 && g > 0) { + if (length + g + 1 > width) g = Math.max(1, width - length); + t.push(value.substring(i -= g, i + g)); + if ((length += g + 1) > width) break; + g = grouping[j = (j + 1) % grouping.length]; + } + + return t.reverse().join(thousands); + }; + }; + + var prefixExponent; + + function formatPrefixAuto(x, p) { + var d = formatDecimal(x, p); + if (!d) return x + ""; + var coefficient = d[0], + exponent = d[1], + i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1, + n = coefficient.length; + return i === n ? coefficient + : i > n ? coefficient + new Array(i - n + 1).join("0") + : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i) + : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y! + }; + + function formatRounded(x, p) { + var d = formatDecimal(x, p); + if (!d) return x + ""; + var coefficient = d[0], + exponent = d[1]; + return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient + : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) + : coefficient + new Array(exponent - coefficient.length + 2).join("0"); + }; + + function formatDefault(x, p) { + x = x.toPrecision(p); + + out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) { + switch (x[i]) { + case ".": i0 = i1 = i; break; + case "0": if (i0 === 0) i0 = i; i1 = i; break; + case "e": break out; + default: if (i0 > 0) i0 = 0; break; + } + } + + return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x; + }; + + var formatTypes = { + "": formatDefault, + "%": function(x, p) { return (x * 100).toFixed(p); }, + "b": function(x) { return Math.round(x).toString(2); }, + "c": function(x) { return x + ""; }, + "d": function(x) { return Math.round(x).toString(10); }, + "e": function(x, p) { return x.toExponential(p); }, + "f": function(x, p) { return x.toFixed(p); }, + "g": function(x, p) { return x.toPrecision(p); }, + "o": function(x) { return Math.round(x).toString(8); }, + "p": function(x, p) { return formatRounded(x * 100, p); }, + "r": formatRounded, + "s": formatPrefixAuto, + "X": function(x) { return Math.round(x).toString(16).toUpperCase(); }, + "x": function(x) { return Math.round(x).toString(16); } + }; + + // [[fill]align][sign][symbol][0][width][,][.precision][type] + var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i; + + function formatSpecifier(specifier) { + return new FormatSpecifier(specifier); + }; + + function FormatSpecifier(specifier) { + if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier); + + var match, + fill = match[1] || " ", + align = match[2] || ">", + sign = match[3] || "-", + symbol = match[4] || "", + zero = !!match[5], + width = match[6] && +match[6], + comma = !!match[7], + precision = match[8] && +match[8].slice(1), + type = match[9] || ""; + + // The "n" type is an alias for ",g". + if (type === "n") comma = true, type = "g"; + + // Map invalid types to the default format. + else if (!formatTypes[type]) type = ""; + + // If zero fill is specified, padding goes after sign and before digits. + if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "="; + + this.fill = fill; + this.align = align; + this.sign = sign; + this.symbol = symbol; + this.zero = zero; + this.width = width; + this.comma = comma; + this.precision = precision; + this.type = type; + } + + FormatSpecifier.prototype.toString = function() { + return this.fill + + this.align + + this.sign + + this.symbol + + (this.zero ? "0" : "") + + (this.width == null ? "" : Math.max(1, this.width | 0)) + + (this.comma ? "," : "") + + (this.precision == null ? "" : "." + Math.max(0, this.precision | 0)) + + this.type; + }; + + var prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"]; + + function identity(x) { + return x; + } + + function locale(locale) { + var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity, + currency = locale.currency, + decimal = locale.decimal; + + function format(specifier) { + specifier = formatSpecifier(specifier); + + var fill = specifier.fill, + align = specifier.align, + sign = specifier.sign, + symbol = specifier.symbol, + zero = specifier.zero, + width = specifier.width, + comma = specifier.comma, + precision = specifier.precision, + type = specifier.type; + + // Compute the prefix and suffix. + // For SI-prefix, the suffix is lazily computed. + var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "", + suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? "%" : ""; + + // What format function should we use? + // Is this an integer type? + // Can this type generate exponential notation? + var formatType = formatTypes[type], + maybeSuffix = !type || /[defgprs%]/.test(type); + + // Set the default precision if not specified, + // or clamp the specified precision to the supported range. + // For significant precision, it must be in [1, 21]. + // For fixed precision, it must be in [0, 20]. + precision = precision == null ? (type ? 6 : 12) + : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision)) + : Math.max(0, Math.min(20, precision)); + + return function(value) { + var valuePrefix = prefix, + valueSuffix = suffix; + + if (type === "c") { + valueSuffix = formatType(value) + valueSuffix; + value = ""; + } else { + value = +value; + + // Convert negative to positive, and compute the prefix. + // Note that -0 is not less than 0, but 1 / -0 is! + var valueNegative = (value < 0 || 1 / value < 0) && (value *= -1, true); + + // Perform the initial formatting. + value = formatType(value, precision); + + // If the original value was negative, it may be rounded to zero during + // formatting; treat this as (positive) zero. + if (valueNegative) { + var i = -1, n = value.length, c; + valueNegative = false; + while (++i < n) { + if (c = value.charCodeAt(i), (48 < c && c < 58) + || (type === "x" && 96 < c && c < 103) + || (type === "X" && 64 < c && c < 71)) { + valueNegative = true; + break; + } + } + } + + // Compute the prefix and suffix. + valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix; + valueSuffix = valueSuffix + (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + (valueNegative && sign === "(" ? ")" : ""); + + // Break the formatted value into the integer “value” part that can be + // grouped, and fractional or exponential “suffix” part that is not. + if (maybeSuffix) { + var i = -1, n = value.length, c; + while (++i < n) { + if (c = value.charCodeAt(i), 48 > c || c > 57) { + valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix; + value = value.slice(0, i); + break; + } + } + } + } + + // If the fill character is not "0", grouping is applied before padding. + if (comma && !zero) value = group(value, Infinity); + + // Compute the padding. + var length = valuePrefix.length + value.length + valueSuffix.length, + padding = length < width ? new Array(width - length + 1).join(fill) : ""; + + // If the fill character is "0", grouping is applied after padding. + if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = ""; + + // Reconstruct the final output based on the desired alignment. + switch (align) { + case "<": return valuePrefix + value + valueSuffix + padding; + case "=": return valuePrefix + padding + value + valueSuffix; + case "^": return padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); + } + return padding + valuePrefix + value + valueSuffix; + }; + } + + function formatPrefix(specifier, value) { + var f = format((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)), + e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3, + k = Math.pow(10, -e), + prefix = prefixes[8 + e / 3]; + return function(value) { + return f(k * value) + prefix; + }; + } + + return { + format: format, + formatPrefix: formatPrefix + }; + }; + + function precisionFixed(step) { + return Math.max(0, -exponent(Math.abs(step))); + }; + + function precisionPrefix(step, value) { + return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step))); + }; + + function precisionRound(step, max) { + return Math.max(0, exponent(Math.abs(max)) - exponent(Math.abs(step))) + 1; + }; + + var localeDefinitions = { + "ca-ES": caEs, + "de-CH": deCh, + "de-DE": deDe, + "en-CA": enCa, + "en-GB": enGb, + "en-US": enUs, + "es-ES": esEs, + "fi-FI": fiFi, + "fr-CA": frCa, + "fr-FR": frFr, + "he-IL": heIl, + "hu-HU": huHu, + "it-IT": itIt, + "ja-JP": jaJp, + "ko-KR": koKr, + "mk-MK": mkMk, + "nl-NL": nlNl, + "pl-PL": plPl, + "pt-BR": ptBr, + "ru-RU": ruRu, + "sv-SE": svSe, + "zh-CN": zhCn + }; + + var defaultLocale = locale(enUs); + var format = defaultLocale.format; + var formatPrefix = defaultLocale.formatPrefix; + + function localeFormat(definition) { + if (typeof definition === "string") { + if (!localeDefinitions.hasOwnProperty(definition)) return null; + definition = localeDefinitions[definition]; + } + return locale(definition); + }; + + var version = "0.3.6"; + + exports.version = version; + exports.format = format; + exports.formatPrefix = formatPrefix; + exports.localeFormat = localeFormat; + exports.formatSpecifier = formatSpecifier; + exports.precisionFixed = precisionFixed; + exports.precisionPrefix = precisionPrefix; + exports.precisionRound = precisionRound; + + })); +},{}],7:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('d3-time')) : + typeof define === 'function' && define.amd ? define('d3-time-format', ['exports', 'd3-time'], factory) : + factory((global.d3_time_format = {}),global.d3_time); + }(this, function (exports,d3Time) { 'use strict'; + + var zhCn = { + dateTime: "%a %b %e %X %Y", + date: "%Y/%-m/%-d", + time: "%H:%M:%S", + periods: ["上午", "下午"], + days: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"], + shortDays: ["星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"], + months: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"], + shortMonths: ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月", "十二月"] + }; + + var svSe = { + dateTime: "%A den %d %B %Y %X", + date: "%Y-%m-%d", + time: "%H:%M:%S", + periods: ["fm", "em"], + days: ["Söndag", "Måndag", "Tisdag", "Onsdag", "Torsdag", "Fredag", "Lördag"], + shortDays: ["Sön", "Mån", "Tis", "Ons", "Tor", "Fre", "Lör"], + months: ["Januari", "Februari", "Mars", "April", "Maj", "Juni", "Juli", "Augusti", "September", "Oktober", "November", "December"], + shortMonths: ["Jan", "Feb", "Mar", "Apr", "Maj", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dec"] + }; + + var ruRu = { + dateTime: "%A, %e %B %Y г. %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["воскресенье", "понедельник", "вторник", "среда", "четверг", "пятница", "суббота"], + shortDays: ["вс", "пн", "вт", "ср", "чт", "пт", "сб"], + months: ["января", "февраля", "марта", "апреля", "мая", "июня", "июля", "августа", "сентября", "октября", "ноября", "декабря"], + shortMonths: ["янв", "фев", "мар", "апр", "май", "июн", "июл", "авг", "сен", "окт", "ноя", "дек"] + }; + + var ptBr = { + dateTime: "%A, %e de %B de %Y. %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["Domingo", "Segunda", "Terça", "Quarta", "Quinta", "Sexta", "Sábado"], + shortDays: ["Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb"], + months: ["Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro"], + shortMonths: ["Jan", "Fev", "Mar", "Abr", "Mai", "Jun", "Jul", "Ago", "Set", "Out", "Nov", "Dez"] + }; + + var plPl = { + dateTime: "%A, %e %B %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["Niedziela", "Poniedziałek", "Wtorek", "Środa", "Czwartek", "Piątek", "Sobota"], + shortDays: ["Niedz.", "Pon.", "Wt.", "Śr.", "Czw.", "Pt.", "Sob."], + months: ["Styczeń", "Luty", "Marzec", "Kwiecień", "Maj", "Czerwiec", "Lipiec", "Sierpień", "Wrzesień", "Październik", "Listopad", "Grudzień"], + shortMonths: ["Stycz.", "Luty", "Marz.", "Kwie.", "Maj", "Czerw.", "Lipc.", "Sierp.", "Wrz.", "Paźdz.", "Listop.", "Grudz."]/* In Polish language abbraviated months are not commonly used so there is a dispute about the proper abbraviations. */ + }; + + var nlNl = { + dateTime: "%a %e %B %Y %T", + date: "%d-%m-%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["zondag", "maandag", "dinsdag", "woensdag", "donderdag", "vrijdag", "zaterdag"], + shortDays: ["zo", "ma", "di", "wo", "do", "vr", "za"], + months: ["januari", "februari", "maart", "april", "mei", "juni", "juli", "augustus", "september", "oktober", "november", "december"], + shortMonths: ["jan", "feb", "mrt", "apr", "mei", "jun", "jul", "aug", "sep", "okt", "nov", "dec"] + }; + + var mkMk = { + dateTime: "%A, %e %B %Y г. %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["недела", "понеделник", "вторник", "среда", "четврток", "петок", "сабота"], + shortDays: ["нед", "пон", "вто", "сре", "чет", "пет", "саб"], + months: ["јануари", "февруари", "март", "април", "мај", "јуни", "јули", "август", "септември", "октомври", "ноември", "декември"], + shortMonths: ["јан", "фев", "мар", "апр", "мај", "јун", "јул", "авг", "сеп", "окт", "ное", "дек"] + }; + + var koKr = { + dateTime: "%Y/%m/%d %a %X", + date: "%Y/%m/%d", + time: "%H:%M:%S", + periods: ["오전", "오후"], + days: ["일요일", "월요일", "화요일", "수요일", "목요일", "금요일", "토요일"], + shortDays: ["일", "월", "화", "수", "목", "금", "토"], + months: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"], + shortMonths: ["1월", "2월", "3월", "4월", "5월", "6월", "7월", "8월", "9월", "10월", "11월", "12월"] + }; + + var jaJp = { + dateTime: "%Y %b %e %a %X", + date: "%Y/%m/%d", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["日曜日", "月曜日", "火曜日", "水曜日", "木曜日", "金曜日", "土曜日"], + shortDays: ["日", "月", "火", "水", "木", "金", "土"], + months: ["睦月", "如月", "弥生", "卯月", "皐月", "水無月", "文月", "葉月", "長月", "神無月", "霜月", "師走"], + shortMonths: ["1月", "2月", "3月", "4月", "5月", "6月", "7月", "8月", "9月", "10月", "11月", "12月"] + }; + + var itIt = { + dateTime: "%A %e %B %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["Domenica", "Lunedì", "Martedì", "Mercoledì", "Giovedì", "Venerdì", "Sabato"], + shortDays: ["Dom", "Lun", "Mar", "Mer", "Gio", "Ven", "Sab"], + months: ["Gennaio", "Febbraio", "Marzo", "Aprile", "Maggio", "Giugno", "Luglio", "Agosto", "Settembre", "Ottobre", "Novembre", "Dicembre"], + shortMonths: ["Gen", "Feb", "Mar", "Apr", "Mag", "Giu", "Lug", "Ago", "Set", "Ott", "Nov", "Dic"] + }; + + var huHu = { + dateTime: "%Y. %B %-e., %A %X", + date: "%Y. %m. %d.", + time: "%H:%M:%S", + periods: ["de.", "du."], // unused + days: ["vasárnap", "hétfő", "kedd", "szerda", "csütörtök", "péntek", "szombat"], + shortDays: ["V", "H", "K", "Sze", "Cs", "P", "Szo"], + months: ["január", "február", "március", "április", "május", "június", "július", "augusztus", "szeptember", "október", "november", "december"], + shortMonths: ["jan.", "feb.", "már.", "ápr.", "máj.", "jún.", "júl.", "aug.", "szept.", "okt.", "nov.", "dec."] + }; + + var heIl = { + dateTime: "%A, %e ב%B %Y %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["ראשון", "שני", "שלישי", "רביעי", "חמישי", "שישי", "שבת"], + shortDays: ["א׳", "ב׳", "ג׳", "ד׳", "ה׳", "ו׳", "ש׳"], + months: ["ינואר", "פברואר", "מרץ", "אפריל", "מאי", "יוני", "יולי", "אוגוסט", "ספטמבר", "אוקטובר", "נובמבר", "דצמבר"], + shortMonths: ["ינו׳", "פבר׳", "מרץ", "אפר׳", "מאי", "יוני", "יולי", "אוג׳", "ספט׳", "אוק׳", "נוב׳", "דצמ׳"] + }; + + var frFr = { + dateTime: "%A, le %e %B %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"], + shortDays: ["dim.", "lun.", "mar.", "mer.", "jeu.", "ven.", "sam."], + months: ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"], + shortMonths: ["janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc."] + }; + + var frCa = { + dateTime: "%a %e %b %Y %X", + date: "%Y-%m-%d", + time: "%H:%M:%S", + periods: ["", ""], + days: ["dimanche", "lundi", "mardi", "mercredi", "jeudi", "vendredi", "samedi"], + shortDays: ["dim", "lun", "mar", "mer", "jeu", "ven", "sam"], + months: ["janvier", "février", "mars", "avril", "mai", "juin", "juillet", "août", "septembre", "octobre", "novembre", "décembre"], + shortMonths: ["jan", "fév", "mar", "avr", "mai", "jui", "jul", "aoû", "sep", "oct", "nov", "déc"] + }; + + var fiFi = { + dateTime: "%A, %-d. %Bta %Y klo %X", + date: "%-d.%-m.%Y", + time: "%H:%M:%S", + periods: ["a.m.", "p.m."], + days: ["sunnuntai", "maanantai", "tiistai", "keskiviikko", "torstai", "perjantai", "lauantai"], + shortDays: ["Su", "Ma", "Ti", "Ke", "To", "Pe", "La"], + months: ["tammikuu", "helmikuu", "maaliskuu", "huhtikuu", "toukokuu", "kesäkuu", "heinäkuu", "elokuu", "syyskuu", "lokakuu", "marraskuu", "joulukuu"], + shortMonths: ["Tammi", "Helmi", "Maalis", "Huhti", "Touko", "Kesä", "Heinä", "Elo", "Syys", "Loka", "Marras", "Joulu"] + }; + + var esEs = { + dateTime: "%A, %e de %B de %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["domingo", "lunes", "martes", "miércoles", "jueves", "viernes", "sábado"], + shortDays: ["dom", "lun", "mar", "mié", "jue", "vie", "sáb"], + months: ["enero", "febrero", "marzo", "abril", "mayo", "junio", "julio", "agosto", "septiembre", "octubre", "noviembre", "diciembre"], + shortMonths: ["ene", "feb", "mar", "abr", "may", "jun", "jul", "ago", "sep", "oct", "nov", "dic"] + }; + + var locale$1 = { + 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"] + }; + + var enGb = { + dateTime: "%a %e %b %X %Y", + date: "%d/%m/%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"] + }; + + var enCa = { + dateTime: "%a %b %e %X %Y", + date: "%Y-%m-%d", + 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"] + }; + + var deDe = { + dateTime: "%A, der %e. %B %Y, %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"], + shortDays: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"], + months: ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"], + shortMonths: ["Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"] + }; + + var deCh = { + dateTime: "%A, der %e. %B %Y, %X", + date: "%d.%m.%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], // unused + days: ["Sonntag", "Montag", "Dienstag", "Mittwoch", "Donnerstag", "Freitag", "Samstag"], + shortDays: ["So", "Mo", "Di", "Mi", "Do", "Fr", "Sa"], + months: ["Januar", "Februar", "März", "April", "Mai", "Juni", "Juli", "August", "September", "Oktober", "November", "Dezember"], + shortMonths: ["Jan", "Feb", "Mrz", "Apr", "Mai", "Jun", "Jul", "Aug", "Sep", "Okt", "Nov", "Dez"] + }; + + var caEs = { + dateTime: "%A, %e de %B de %Y, %X", + date: "%d/%m/%Y", + time: "%H:%M:%S", + periods: ["AM", "PM"], + days: ["diumenge", "dilluns", "dimarts", "dimecres", "dijous", "divendres", "dissabte"], + shortDays: ["dg.", "dl.", "dt.", "dc.", "dj.", "dv.", "ds."], + months: ["gener", "febrer", "març", "abril", "maig", "juny", "juliol", "agost", "setembre", "octubre", "novembre", "desembre"], + shortMonths: ["gen.", "febr.", "març", "abr.", "maig", "juny", "jul.", "ag.", "set.", "oct.", "nov.", "des."] + }; + + function localDate(d) { + if (0 <= d.y && d.y < 100) { + var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L); + date.setFullYear(d.y); + return date; + } + return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L); + } + + function utcDate(d) { + if (0 <= d.y && d.y < 100) { + var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L)); + date.setUTCFullYear(d.y); + return date; + } + return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L)); + } + + function newYear(y) { + return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0}; + } + + function locale(locale) { + var locale_dateTime = locale.dateTime, + locale_date = locale.date, + locale_time = locale.time, + locale_periods = locale.periods, + locale_weekdays = locale.days, + locale_shortWeekdays = locale.shortDays, + locale_months = locale.months, + locale_shortMonths = locale.shortMonths; + + var periodLookup = formatLookup(locale_periods), + weekdayRe = formatRe(locale_weekdays), + weekdayLookup = formatLookup(locale_weekdays), + shortWeekdayRe = formatRe(locale_shortWeekdays), + shortWeekdayLookup = formatLookup(locale_shortWeekdays), + monthRe = formatRe(locale_months), + monthLookup = formatLookup(locale_months), + shortMonthRe = formatRe(locale_shortMonths), + shortMonthLookup = formatLookup(locale_shortMonths); + + var formats = { + "a": formatShortWeekday, + "A": formatWeekday, + "b": formatShortMonth, + "B": formatMonth, + "c": null, + "d": formatDayOfMonth, + "e": formatDayOfMonth, + "H": formatHour24, + "I": formatHour12, + "j": formatDayOfYear, + "L": formatMilliseconds, + "m": formatMonthNumber, + "M": formatMinutes, + "p": formatPeriod, + "S": formatSeconds, + "U": formatWeekNumberSunday, + "w": formatWeekdayNumber, + "W": formatWeekNumberMonday, + "x": null, + "X": null, + "y": formatYear, + "Y": formatFullYear, + "Z": formatZone, + "%": formatLiteralPercent + }; + + var utcFormats = { + "a": formatUTCShortWeekday, + "A": formatUTCWeekday, + "b": formatUTCShortMonth, + "B": formatUTCMonth, + "c": null, + "d": formatUTCDayOfMonth, + "e": formatUTCDayOfMonth, + "H": formatUTCHour24, + "I": formatUTCHour12, + "j": formatUTCDayOfYear, + "L": formatUTCMilliseconds, + "m": formatUTCMonthNumber, + "M": formatUTCMinutes, + "p": formatUTCPeriod, + "S": formatUTCSeconds, + "U": formatUTCWeekNumberSunday, + "w": formatUTCWeekdayNumber, + "W": formatUTCWeekNumberMonday, + "x": null, + "X": null, + "y": formatUTCYear, + "Y": formatUTCFullYear, + "Z": formatUTCZone, + "%": formatLiteralPercent + }; + + var parses = { + "a": parseShortWeekday, + "A": parseWeekday, + "b": parseShortMonth, + "B": parseMonth, + "c": parseLocaleDateTime, + "d": parseDayOfMonth, + "e": parseDayOfMonth, + "H": parseHour24, + "I": parseHour24, + "j": parseDayOfYear, + "L": parseMilliseconds, + "m": parseMonthNumber, + "M": parseMinutes, + "p": parsePeriod, + "S": parseSeconds, + "U": parseWeekNumberSunday, + "w": parseWeekdayNumber, + "W": parseWeekNumberMonday, + "x": parseLocaleDate, + "X": parseLocaleTime, + "y": parseYear, + "Y": parseFullYear, + "Z": parseZone, + "%": parseLiteralPercent + }; + + // These recursive directive definitions must be deferred. + formats.x = newFormat(locale_date, formats); + formats.X = newFormat(locale_time, formats); + formats.c = newFormat(locale_dateTime, formats); + utcFormats.x = newFormat(locale_date, utcFormats); + utcFormats.X = newFormat(locale_time, utcFormats); + utcFormats.c = newFormat(locale_dateTime, utcFormats); + + function newFormat(specifier, formats) { + return function(date) { + var string = [], + i = -1, + j = 0, + n = specifier.length, + c, + pad, + format; + + while (++i < n) { + if (specifier.charCodeAt(i) === 37) { + string.push(specifier.slice(j, i)); + if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i); + if (format = formats[c]) c = format(date, pad == null ? (c === "e" ? " " : "0") : pad); + string.push(c); + j = i + 1; + } + } + + string.push(specifier.slice(j, i)); + return string.join(""); + }; + } + + function newParse(specifier, newDate) { + return function(string) { + var d = newYear(1900), + i = parseSpecifier(d, specifier, string, 0); + if (i != string.length) return null; + + // The am-pm flag is 0 for AM, and 1 for PM. + if ("p" in d) d.H = d.H % 12 + d.p * 12; + + // If a time zone is specified, all fields are interpreted as UTC and then + // offset according to the specified time zone. + if ("Z" in d) { + if ("w" in d && ("W" in d || "U" in d)) { + var day = utcDate(newYear(d.y)).getUTCDay(); + if ("W" in d) d.U = d.W, d.w = (d.w + 6) % 7, --day; + d.m = 0; + d.d = d.w + d.U * 7 - (day + 6) % 7; + } + d.H += d.Z / 100 | 0; + d.M += d.Z % 100; + return utcDate(d); + } + + // Otherwise, all fields are in local time. + if ("w" in d && ("W" in d || "U" in d)) { + var day = newDate(newYear(d.y)).getDay(); + if ("W" in d) d.U = d.W, d.w = (d.w + 6) % 7, --day; + d.m = 0; + d.d = d.w + d.U * 7 - (day + 6) % 7; + } + return newDate(d); + }; + } + + function parseSpecifier(d, specifier, string, j) { + var i = 0, + n = specifier.length, + m = string.length, + c, + parse; + + while (i < n) { + if (j >= m) return -1; + c = specifier.charCodeAt(i++); + if (c === 37) { + c = specifier.charAt(i++); + parse = parses[c in pads ? specifier.charAt(i++) : c]; + if (!parse || ((j = parse(d, string, j)) < 0)) return -1; + } else if (c != string.charCodeAt(j++)) { + return -1; + } + } + + return j; + } + + function parseShortWeekday(d, string, i) { + var n = shortWeekdayRe.exec(string.slice(i)); + return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseWeekday(d, string, i) { + var n = weekdayRe.exec(string.slice(i)); + return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseShortMonth(d, string, i) { + var n = shortMonthRe.exec(string.slice(i)); + return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseMonth(d, string, i) { + var n = monthRe.exec(string.slice(i)); + return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseLocaleDateTime(d, string, i) { + return parseSpecifier(d, locale_dateTime, string, i); + } + + function parseLocaleDate(d, string, i) { + return parseSpecifier(d, locale_date, string, i); + } + + function parseLocaleTime(d, string, i) { + return parseSpecifier(d, locale_time, string, i); + } + + function parsePeriod(d, string, i) { + var n = periodLookup[string.slice(i, i += 2).toLowerCase()]; + return n == null ? -1 : (d.p = n, i); + } + + function formatShortWeekday(d) { + return locale_shortWeekdays[d.getDay()]; + } + + function formatWeekday(d) { + return locale_weekdays[d.getDay()]; + } + + function formatShortMonth(d) { + return locale_shortMonths[d.getMonth()]; + } + + function formatMonth(d) { + return locale_months[d.getMonth()]; + } + + function formatPeriod(d) { + return locale_periods[+(d.getHours() >= 12)]; + } + + function formatUTCShortWeekday(d) { + return locale_shortWeekdays[d.getUTCDay()]; + } + + function formatUTCWeekday(d) { + return locale_weekdays[d.getUTCDay()]; + } + + function formatUTCShortMonth(d) { + return locale_shortMonths[d.getUTCMonth()]; + } + + function formatUTCMonth(d) { + return locale_months[d.getUTCMonth()]; + } + + function formatUTCPeriod(d) { + return locale_periods[+(d.getUTCHours() >= 12)]; + } + + return { + format: function(specifier) { + var f = newFormat(specifier += "", formats); + f.parse = newParse(specifier, localDate); + f.toString = function() { return specifier; }; + return f; + }, + utcFormat: function(specifier) { + var f = newFormat(specifier += "", utcFormats); + f.parse = newParse(specifier, utcDate); + f.toString = function() { return specifier; }; + return f; + } + }; + }; + + var pads = {"-": "", "_": " ", "0": "0"}; + var numberRe = /^\s*\d+/; + var percentRe = /^%/; + var requoteRe = /[\\\^\$\*\+\?\|\[\]\(\)\.\{\}]/g; + function pad(value, fill, width) { + var sign = value < 0 ? "-" : "", + string = (sign ? -value : value) + "", + length = string.length; + return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); + } + + function requote(s) { + return s.replace(requoteRe, "\\$&"); + } + + function formatRe(names) { + return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i"); + } + + function formatLookup(names) { + var map = {}, i = -1, n = names.length; + while (++i < n) map[names[i].toLowerCase()] = i; + return map; + } + + function parseWeekdayNumber(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 1)); + return n ? (d.w = +n[0], i + n[0].length) : -1; + } + + function parseWeekNumberSunday(d, string, i) { + var n = numberRe.exec(string.slice(i)); + return n ? (d.U = +n[0], i + n[0].length) : -1; + } + + function parseWeekNumberMonday(d, string, i) { + var n = numberRe.exec(string.slice(i)); + return n ? (d.W = +n[0], i + n[0].length) : -1; + } + + function parseFullYear(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 4)); + return n ? (d.y = +n[0], i + n[0].length) : -1; + } + + function parseYear(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1; + } + + function parseZone(d, string, i) { + var n = /^(Z)|([+-]\d\d)(?:\:?(\d\d))?/.exec(string.slice(i, i + 6)); + if (n) { + d.Z = n[1] ? 0 // 'Z' for UTC + : n[3] ? -(n[2] + n[3]) // sign differs from getTimezoneOffset! + : -n[2] * 100; + return i + n[0].length; + } + return -1; + } + + function parseMonthNumber(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.m = n[0] - 1, i + n[0].length) : -1; + } + + function parseDayOfMonth(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.d = +n[0], i + n[0].length) : -1; + } + + function parseDayOfYear(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 3)); + return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1; + } + + function parseHour24(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.H = +n[0], i + n[0].length) : -1; + } + + function parseMinutes(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.M = +n[0], i + n[0].length) : -1; + } + + function parseSeconds(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.S = +n[0], i + n[0].length) : -1; + } + + function parseMilliseconds(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 3)); + return n ? (d.L = +n[0], i + n[0].length) : -1; + } + + function parseLiteralPercent(d, string, i) { + var n = percentRe.exec(string.slice(i, i + 1)); + return n ? i + n[0].length : -1; + } + + function formatDayOfMonth(d, p) { + return pad(d.getDate(), p, 2); + } + + function formatHour24(d, p) { + return pad(d.getHours(), p, 2); + } + + function formatHour12(d, p) { + return pad(d.getHours() % 12 || 12, p, 2); + } + + function formatDayOfYear(d, p) { + return pad(1 + d3Time.day.count(d3Time.year(d), d), p, 3); + } + + function formatMilliseconds(d, p) { + return pad(d.getMilliseconds(), p, 3); + } + + function formatMonthNumber(d, p) { + return pad(d.getMonth() + 1, p, 2); + } + + function formatMinutes(d, p) { + return pad(d.getMinutes(), p, 2); + } + + function formatSeconds(d, p) { + return pad(d.getSeconds(), p, 2); + } + + function formatWeekNumberSunday(d, p) { + return pad(d3Time.sunday.count(d3Time.year(d), d), p, 2); + } + + function formatWeekdayNumber(d) { + return d.getDay(); + } + + function formatWeekNumberMonday(d, p) { + return pad(d3Time.monday.count(d3Time.year(d), d), p, 2); + } + + function formatYear(d, p) { + return pad(d.getFullYear() % 100, p, 2); + } + + function formatFullYear(d, p) { + return pad(d.getFullYear() % 10000, p, 4); + } + + function formatZone(d) { + var z = d.getTimezoneOffset(); + return (z > 0 ? "-" : (z *= -1, "+")) + + pad(z / 60 | 0, "0", 2) + + pad(z % 60, "0", 2); + } + + function formatUTCDayOfMonth(d, p) { + return pad(d.getUTCDate(), p, 2); + } + + function formatUTCHour24(d, p) { + return pad(d.getUTCHours(), p, 2); + } + + function formatUTCHour12(d, p) { + return pad(d.getUTCHours() % 12 || 12, p, 2); + } + + function formatUTCDayOfYear(d, p) { + return pad(1 + d3Time.utcDay.count(d3Time.utcYear(d), d), p, 3); + } + + function formatUTCMilliseconds(d, p) { + return pad(d.getUTCMilliseconds(), p, 3); + } + + function formatUTCMonthNumber(d, p) { + return pad(d.getUTCMonth() + 1, p, 2); + } + + function formatUTCMinutes(d, p) { + return pad(d.getUTCMinutes(), p, 2); + } + + function formatUTCSeconds(d, p) { + return pad(d.getUTCSeconds(), p, 2); + } + + function formatUTCWeekNumberSunday(d, p) { + return pad(d3Time.utcSunday.count(d3Time.utcYear(d), d), p, 2); + } + + function formatUTCWeekdayNumber(d) { + return d.getUTCDay(); + } + + function formatUTCWeekNumberMonday(d, p) { + return pad(d3Time.utcMonday.count(d3Time.utcYear(d), d), p, 2); + } + + function formatUTCYear(d, p) { + return pad(d.getUTCFullYear() % 100, p, 2); + } + + function formatUTCFullYear(d, p) { + return pad(d.getUTCFullYear() % 10000, p, 4); + } + + function formatUTCZone() { + return "+0000"; + } + + function formatLiteralPercent() { + return "%"; + } + + var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ"; + + function formatIsoNative(date) { + return date.toISOString(); + } + + formatIsoNative.parse = function(string) { + var date = new Date(string); + return isNaN(date) ? null : date; + }; + + formatIsoNative.toString = function() { + return isoSpecifier; + }; + + var formatIso = Date.prototype.toISOString && +new Date("2000-01-01T00:00:00.000Z") + ? formatIsoNative + : locale$1.utcFormat(isoSpecifier); + + var localeDefinitions = { + "ca-ES": caEs, + "de-CH": deCh, + "de-DE": deDe, + "en-CA": enCa, + "en-GB": enGb, + "en-US": locale$1, + "es-ES": esEs, + "fi-FI": fiFi, + "fr-CA": frCa, + "fr-FR": frFr, + "he-IL": heIl, + "hu-HU": huHu, + "it-IT": itIt, + "ja-JP": jaJp, + "ko-KR": koKr, + "mk-MK": mkMk, + "nl-NL": nlNl, + "pl-PL": plPl, + "pt-BR": ptBr, + "ru-RU": ruRu, + "sv-SE": svSe, + "zh-CN": zhCn + }; + + var defaultLocale = locale(locale$1); + var format = defaultLocale.format; + var utcFormat = defaultLocale.utcFormat; + + function localeFormat(definition) { + if (typeof definition === "string") { + if (!localeDefinitions.hasOwnProperty(definition)) return null; + definition = localeDefinitions[definition]; + } + return locale(definition); + }; + + var version = "0.1.5"; + + exports.version = version; + exports.format = format; + exports.utcFormat = utcFormat; + exports.localeFormat = localeFormat; + exports.isoFormat = formatIso; + + })); +},{"d3-time":8}],8:[function(require,module,exports){ + (function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define('d3-time', ['exports'], factory) : + factory((global.d3_time = {})); + }(this, function (exports) { 'use strict'; + + var t0 = new Date; + var t1 = new Date; + function newInterval(floori, offseti, count) { + + function interval(date) { + return floori(date = new Date(+date)), date; + } + + interval.floor = interval; + + interval.round = function(date) { + var d0 = new Date(+date), + d1 = new Date(date - 1); + floori(d0), floori(d1), offseti(d1, 1); + return date - d0 < d1 - date ? d0 : d1; + }; + + interval.ceil = function(date) { + return floori(date = new Date(date - 1)), offseti(date, 1), date; + }; + + interval.offset = function(date, step) { + return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date; + }; + + interval.range = function(start, stop, step) { + var range = []; + start = new Date(start - 1); + stop = new Date(+stop); + step = step == null ? 1 : Math.floor(step); + if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date + offseti(start, 1), floori(start); + if (start < stop) range.push(new Date(+start)); + while (offseti(start, step), floori(start), start < stop) range.push(new Date(+start)); + return range; + }; + + interval.filter = function(test) { + return newInterval(function(date) { + while (floori(date), !test(date)) date.setTime(date - 1); + }, function(date, step) { + while (--step >= 0) while (offseti(date, 1), !test(date)); + }); + }; + + if (count) interval.count = function(start, end) { + t0.setTime(+start), t1.setTime(+end); + floori(t0), floori(t1); + return Math.floor(count(t0, t1)); + }; + + return interval; + }; + + var millisecond = newInterval(function() { + // noop + }, function(date, step) { + date.setTime(+date + step); + }, function(start, end) { + return end - start; + }); + + var second = newInterval(function(date) { + date.setMilliseconds(0); + }, function(date, step) { + date.setTime(+date + step * 1e3); + }, function(start, end) { + return (end - start) / 1e3; + }); + + var minute = newInterval(function(date) { + date.setSeconds(0, 0); + }, function(date, step) { + date.setTime(+date + step * 6e4); + }, function(start, end) { + return (end - start) / 6e4; + }); + + var hour = newInterval(function(date) { + date.setMinutes(0, 0, 0); + }, function(date, step) { + date.setTime(+date + step * 36e5); + }, function(start, end) { + return (end - start) / 36e5; + }); + + var day = newInterval(function(date) { + date.setHours(0, 0, 0, 0); + }, function(date, step) { + date.setDate(date.getDate() + step); + }, function(start, end) { + return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * 6e4) / 864e5; + }); + + function weekday(i) { + return newInterval(function(date) { + date.setHours(0, 0, 0, 0); + date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7); + }, function(date, step) { + date.setDate(date.getDate() + step * 7); + }, function(start, end) { + return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * 6e4) / 6048e5; + }); + } + + var sunday = weekday(0); + var monday = weekday(1); + var tuesday = weekday(2); + var wednesday = weekday(3); + var thursday = weekday(4); + var friday = weekday(5); + var saturday = weekday(6); + + var month = newInterval(function(date) { + date.setHours(0, 0, 0, 0); + date.setDate(1); + }, function(date, step) { + date.setMonth(date.getMonth() + step); + }, function(start, end) { + return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12; + }); + + var year = newInterval(function(date) { + date.setHours(0, 0, 0, 0); + date.setMonth(0, 1); + }, function(date, step) { + date.setFullYear(date.getFullYear() + step); + }, function(start, end) { + return end.getFullYear() - start.getFullYear(); + }); + + var utcSecond = newInterval(function(date) { + date.setUTCMilliseconds(0); + }, function(date, step) { + date.setTime(+date + step * 1e3); + }, function(start, end) { + return (end - start) / 1e3; + }); + + var utcMinute = newInterval(function(date) { + date.setUTCSeconds(0, 0); + }, function(date, step) { + date.setTime(+date + step * 6e4); + }, function(start, end) { + return (end - start) / 6e4; + }); + + var utcHour = newInterval(function(date) { + date.setUTCMinutes(0, 0, 0); + }, function(date, step) { + date.setTime(+date + step * 36e5); + }, function(start, end) { + return (end - start) / 36e5; + }); + + var utcDay = newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + }, function(date, step) { + date.setUTCDate(date.getUTCDate() + step); + }, function(start, end) { + return (end - start) / 864e5; + }); + + function utcWeekday(i) { + return newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7); + }, function(date, step) { + date.setUTCDate(date.getUTCDate() + step * 7); + }, function(start, end) { + return (end - start) / 6048e5; + }); + } + + var utcSunday = utcWeekday(0); + var utcMonday = utcWeekday(1); + var utcTuesday = utcWeekday(2); + var utcWednesday = utcWeekday(3); + var utcThursday = utcWeekday(4); + var utcFriday = utcWeekday(5); + var utcSaturday = utcWeekday(6); + + var utcMonth = newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + date.setUTCDate(1); + }, function(date, step) { + date.setUTCMonth(date.getUTCMonth() + step); + }, function(start, end) { + return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12; + }); + + var utcYear = newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); + date.setUTCMonth(0, 1); + }, function(date, step) { + date.setUTCFullYear(date.getUTCFullYear() + step); + }, function(start, end) { + return end.getUTCFullYear() - start.getUTCFullYear(); + }); + + var milliseconds = millisecond.range; + var seconds = second.range; + var minutes = minute.range; + var hours = hour.range; + var days = day.range; + var sundays = sunday.range; + var mondays = monday.range; + var tuesdays = tuesday.range; + var wednesdays = wednesday.range; + var thursdays = thursday.range; + var fridays = friday.range; + var saturdays = saturday.range; + var weeks = sunday.range; + var months = month.range; + var years = year.range; + + var utcMillisecond = millisecond; + var utcMilliseconds = milliseconds; + var utcSeconds = utcSecond.range; + var utcMinutes = utcMinute.range; + var utcHours = utcHour.range; + var utcDays = utcDay.range; + var utcSundays = utcSunday.range; + var utcMondays = utcMonday.range; + var utcTuesdays = utcTuesday.range; + var utcWednesdays = utcWednesday.range; + var utcThursdays = utcThursday.range; + var utcFridays = utcFriday.range; + var utcSaturdays = utcSaturday.range; + var utcWeeks = utcSunday.range; + var utcMonths = utcMonth.range; + var utcYears = utcYear.range; + + var version = "0.0.7"; + + exports.version = version; + exports.milliseconds = milliseconds; + exports.seconds = seconds; + exports.minutes = minutes; + exports.hours = hours; + exports.days = days; + exports.sundays = sundays; + exports.mondays = mondays; + exports.tuesdays = tuesdays; + exports.wednesdays = wednesdays; + exports.thursdays = thursdays; + exports.fridays = fridays; + exports.saturdays = saturdays; + exports.weeks = weeks; + exports.months = months; + exports.years = years; + exports.utcMillisecond = utcMillisecond; + exports.utcMilliseconds = utcMilliseconds; + exports.utcSeconds = utcSeconds; + exports.utcMinutes = utcMinutes; + exports.utcHours = utcHours; + exports.utcDays = utcDays; + exports.utcSundays = utcSundays; + exports.utcMondays = utcMondays; + exports.utcTuesdays = utcTuesdays; + exports.utcWednesdays = utcWednesdays; + exports.utcThursdays = utcThursdays; + exports.utcFridays = utcFridays; + exports.utcSaturdays = utcSaturdays; + exports.utcWeeks = utcWeeks; + exports.utcMonths = utcMonths; + exports.utcYears = utcYears; + exports.millisecond = millisecond; + exports.second = second; + exports.minute = minute; + exports.hour = hour; + exports.day = day; + exports.sunday = sunday; + exports.monday = monday; + exports.tuesday = tuesday; + exports.wednesday = wednesday; + exports.thursday = thursday; + exports.friday = friday; + exports.saturday = saturday; + exports.week = sunday; + exports.month = month; + exports.year = year; + exports.utcSecond = utcSecond; + exports.utcMinute = utcMinute; + exports.utcHour = utcHour; + exports.utcDay = utcDay; + exports.utcSunday = utcSunday; + exports.utcMonday = utcMonday; + exports.utcTuesday = utcTuesday; + exports.utcWednesday = utcWednesday; + exports.utcThursday = utcThursday; + exports.utcFriday = utcFriday; + exports.utcSaturday = utcSaturday; + exports.utcWeek = utcSunday; + exports.utcMonth = utcMonth; + exports.utcYear = utcYear; + exports.interval = newInterval; + + })); +},{}],9:[function(require,module,exports){ + var util = require('../util'), + Measures = require('./measures'), + Collector = require('./collector'); + + function Aggregator() { + this._cells = {}; + this._aggr = []; + this._stream = false; + } + + var Flags = Aggregator.Flags = { + ADD_CELL: 1, + MOD_CELL: 2 + }; + + var proto = Aggregator.prototype; + +// Parameters + + proto.stream = function(v) { + if (v == null) return this._stream; + this._stream = !!v; + this._aggr = []; + return this; + }; + +// key accessor to use for streaming removes + proto.key = function(key) { + if (key == null) return this._key; + this._key = util.$(key); + return this; + }; + +// Input: array of objects of the form +// {name: string, get: function} + proto.groupby = function(dims) { + this._dims = util.array(dims).map(function(d, i) { + d = util.isString(d) ? {name: d, get: util.$(d)} + : util.isFunction(d) ? {name: util.name(d) || d.name || ('_' + i), get: d} + : (d.name && util.isFunction(d.get)) ? d : null; + if (d == null) throw 'Invalid groupby argument: ' + d; + return d; + }); + return this.clear(); + }; + +// Input: array of objects of the form +// {name: string, ops: [string, ...]} + proto.summarize = function(fields) { + fields = summarize_args(fields); + this._count = true; + var aggr = (this._aggr = []), + m, f, i, j, op, as, get; + + for (i=0; i 0) { + // consolidate collector values + if (cell.collect) { + cell.data.values(); + } + // update tuple properties + for (i=0; i 0) { + m[a[i]] -= 1; + } else { + x[j++] = a[i]; + } + } + } else if (k) { + // has unique key field, so use that + m = util.toMap(r, k); + for (i=0, j=0, n=a.length; i 1 ? this.dev / (this.valid-1) : 0', + req: ['mean'], idx: 1 + }), + 'variancep': measure({ + name: 'variancep', + set: 'this.valid > 1 ? this.dev / this.valid : 0', + req: ['variance'], idx: 2 + }), + 'stdev': measure({ + name: 'stdev', + set: 'this.valid > 1 ? Math.sqrt(this.dev / (this.valid-1)) : 0', + req: ['variance'], idx: 2 + }), + 'stdevp': measure({ + name: 'stdevp', + set: 'this.valid > 1 ? Math.sqrt(this.dev / this.valid) : 0', + req: ['variance'], idx: 2 + }), + 'median': measure({ + name: 'median', + set: 'cell.data.q2(this.get)', + req: ['values'], idx: 3 + }), + 'q1': measure({ + name: 'q1', + set: 'cell.data.q1(this.get)', + req: ['values'], idx: 3 + }), + 'q3': measure({ + name: 'q3', + set: 'cell.data.q3(this.get)', + req: ['values'], idx: 3 + }), + 'distinct': measure({ + name: 'distinct', + set: 'this.distinct(cell.data.values(), this.get)', + req: ['values'], idx: 3 + }), + 'argmin': measure({ + name: 'argmin', + add: 'if (v < this.min) this.argmin = t;', + rem: 'if (v <= this.min) this.argmin = null;', + set: 'this.argmin = this.argmin || cell.data.argmin(this.get)', + req: ['min'], str: ['values'], idx: 3 + }), + 'argmax': measure({ + name: 'argmax', + add: 'if (v > this.max) this.argmax = t;', + rem: 'if (v >= this.max) this.argmax = null;', + set: 'this.argmax = this.argmax || cell.data.argmax(this.get)', + req: ['max'], str: ['values'], idx: 3 + }), + 'min': measure({ + name: 'min', + init: 'this.min = +Infinity;', + add: 'if (v < this.min) this.min = v;', + rem: 'if (v <= this.min) this.min = NaN;', + set: 'this.min = (isNaN(this.min) ? cell.data.min(this.get) : this.min)', + str: ['values'], idx: 4 + }), + 'max': measure({ + name: 'max', + init: 'this.max = -Infinity;', + add: 'if (v > this.max) this.max = v;', + rem: 'if (v >= this.max) this.max = NaN;', + set: 'this.max = (isNaN(this.max) ? cell.data.max(this.get) : this.max)', + str: ['values'], idx: 4 + }), + 'modeskew': measure({ + name: 'modeskew', + set: 'this.dev===0 ? 0 : (this.mean - cell.data.q2(this.get)) / Math.sqrt(this.dev/(this.valid-1))', + req: ['mean', 'stdev', 'median'], idx: 5 + }) + }; + + function measure(base) { + return function(out) { + var m = util.extend({init:'', add:'', rem:'', idx:0}, base); + m.out = out || base.name; + return m; + }; + } + + function resolve(agg, stream) { + function collect(m, a) { + function helper(r) { if (!m[r]) collect(m, m[r] = types[r]()); } + if (a.req) a.req.forEach(helper); + if (stream && a.str) a.str.forEach(helper); + return m; + } + var map = agg.reduce( + collect, + agg.reduce(function(m, a) { return (m[a.name] = a, m); }, {}) + ); + return util.vals(map).sort(function(a, b) { return a.idx - b.idx; }); + } + + function create(agg, stream, accessor, mutator) { + var all = resolve(agg, stream), + ctr = 'this.cell = cell; this.tuple = t; this.valid = 0; this.missing = 0;', + add = 'if (v==null) this.missing++; if (!this.isValid(v)) return; ++this.valid;', + rem = 'if (v==null) this.missing--; if (!this.isValid(v)) return; --this.valid;', + set = 'var t = this.tuple; var cell = this.cell;'; + + all.forEach(function(a) { + if (a.idx < 0) { + ctr = a.init + ctr; + add = a.add + add; + rem = a.rem + rem; + } else { + ctr += a.init; + add += a.add; + rem += a.rem; + } + }); + agg.slice() + .sort(function(a, b) { return a.idx - b.idx; }) + .forEach(function(a) { + set += 'this.assign(t,\''+a.out+'\','+a.set+');'; + }); + set += 'return t;'; + + /* jshint evil: true */ + ctr = Function('cell', 't', ctr); + ctr.prototype.assign = mutator; + ctr.prototype.add = Function('t', 'var v = this.get(t);' + add); + ctr.prototype.rem = Function('t', 'var v = this.get(t);' + rem); + ctr.prototype.set = Function(set); + ctr.prototype.get = accessor; + ctr.prototype.distinct = require('../stats').count.distinct; + ctr.prototype.isValid = util.isValid; + ctr.fields = agg.map(util.$('out')); + return ctr; + } + + types.create = create; + module.exports = types; + +},{"../stats":28,"../util":31}],13:[function(require,module,exports){ + var util = require('../util'), + time = require('../time'), + EPSILON = 1e-15; + + function bins(opt) { + if (!opt) { throw Error("Missing binning options."); } + + // determine range + var maxb = opt.maxbins || 15, + base = opt.base || 10, + logb = Math.log(base), + div = opt.div || [5, 2], + min = opt.min, + max = opt.max, + span = max - min, + step, level, minstep, precision, v, i, eps; + + if (opt.step) { + // if step size is explicitly given, use that + step = opt.step; + } else if (opt.steps) { + // if provided, limit choice to acceptable step sizes + step = opt.steps[Math.min( + opt.steps.length - 1, + bisect(opt.steps, span/maxb, 0, opt.steps.length) + )]; + } else { + // else use span to determine step size + level = Math.ceil(Math.log(maxb) / logb); + minstep = opt.minstep || 0; + step = Math.max( + minstep, + Math.pow(base, Math.round(Math.log(span) / logb) - level) + ); + + // increase step size if too many bins + do { step *= base; } while (Math.ceil(span/step) > maxb); + + // decrease step size if allowed + for (i=0; i= minstep && span / v <= maxb) step = v; + } + } + + // update precision, min and max + v = Math.log(step); + precision = v >= 0 ? 0 : ~~(-v / logb) + 1; + eps = Math.pow(base, -precision - 1); + min = Math.min(min, Math.floor(min / step + eps) * step); + max = Math.ceil(max / step) * step; + + return { + start: min, + stop: max, + step: step, + unit: {precision: precision}, + value: value, + index: index + }; + } + + function bisect(a, x, lo, hi) { + while (lo < hi) { + var mid = lo + hi >>> 1; + if (util.cmp(a[mid], x) < 0) { lo = mid + 1; } + else { hi = mid; } + } + return lo; + } + + function value(v) { + return this.step * Math.floor(v / this.step + EPSILON); + } + + function index(v) { + return Math.floor((v - this.start) / this.step + EPSILON); + } + + function date_value(v) { + return this.unit.date(value.call(this, v)); + } + + function date_index(v) { + return index.call(this, this.unit.unit(v)); + } + + bins.date = function(opt) { + if (!opt) { throw Error("Missing date binning options."); } + + // find time step, then bin + var units = opt.utc ? time.utc : time, + dmin = opt.min, + dmax = opt.max, + maxb = opt.maxbins || 20, + minb = opt.minbins || 4, + span = (+dmax) - (+dmin), + unit = opt.unit ? units[opt.unit] : units.find(span, minb, maxb), + spec = bins({ + min: unit.min != null ? unit.min : unit.unit(dmin), + max: unit.max != null ? unit.max : unit.unit(dmax), + maxbins: maxb, + minstep: unit.minstep, + steps: unit.step + }); + + spec.unit = unit; + spec.index = date_index; + if (!opt.raw) spec.value = date_value; + return spec; + }; + + module.exports = bins; + +},{"../time":30,"../util":31}],14:[function(require,module,exports){ + var bins = require('./bins'), + gen = require('../generate'), + type = require('../import/type'), + util = require('../util'), + stats = require('../stats'); + + var qtype = { + 'integer': 1, + 'number': 1, + 'date': 1 + }; + + function $bin(values, f, opt) { + opt = options(values, f, opt); + var b = spec(opt); + return !b ? (opt.accessor || util.identity) : + util.$func('bin', b.unit.unit ? + function(x) { return b.value(b.unit.unit(x)); } : + function(x) { return b.value(x); } + )(opt.accessor); + } + + function histogram(values, f, opt) { + opt = options(values, f, opt); + var b = spec(opt); + return b ? + numerical(values, opt.accessor, b) : + categorical(values, opt.accessor, opt && opt.sort); + } + + function spec(opt) { + var t = opt.type, b = null; + if (t == null || qtype[t]) { + if (t === 'integer' && opt.minstep == null) opt.minstep = 1; + b = (t === 'date') ? bins.date(opt) : bins(opt); + } + return b; + } + + function options() { + var a = arguments, + i = 0, + values = util.isArray(a[i]) ? a[i++] : null, + f = util.isFunction(a[i]) || util.isString(a[i]) ? util.$(a[i++]) : null, + opt = util.extend({}, a[i]); + + if (values) { + opt.type = opt.type || type(values, f); + if (qtype[opt.type]) { + var ext = stats.extent(values, f); + opt = util.extend({min: ext[0], max: ext[1]}, opt); + } + } + if (f) { opt.accessor = f; } + return opt; + } + + function numerical(values, f, b) { + var h = gen.range(b.start, b.stop + b.step/2, b.step) + .map(function(v) { return {value: b.value(v), count: 0}; }); + + for (var i=0, v, j; i= h.length || !isFinite(j)) continue; + h[j].count += 1; + } + } + h.bins = b; + return h; + } + + function categorical(values, f, sort) { + var u = stats.unique(values, f), + c = stats.count.map(values, f); + return u.map(function(k) { return {value: k, count: c[k]}; }) + .sort(util.comparator(sort ? '-count' : '+value')); + } + + module.exports = { + $bin: $bin, + histogram: histogram + }; + +},{"../generate":16,"../import/type":25,"../stats":28,"../util":31,"./bins":13}],15:[function(require,module,exports){ + var d3_time = require('d3-time'), + d3_timeF = require('d3-time-format'), + d3_numberF = require('d3-format'), + numberF = d3_numberF, // defaults to EN-US + timeF = d3_timeF; // defaults to EN-US + + function numberLocale(l) { + var f = d3_numberF.localeFormat(l); + if (f == null) throw Error('Unrecognized locale: ' + l); + numberF = f; + } + + function timeLocale(l) { + var f = d3_timeF.localeFormat(l); + if (f == null) throw Error('Unrecognized locale: ' + l); + timeF = f; + } + + module.exports = { + // Update number formatter to use provided locale configuration. + // For more see https://github.com/d3/d3-format + numberLocale: numberLocale, + number: function(f) { return numberF.format(f); }, + numberPrefix: function(f, v) { return numberF.formatPrefix(f, v); }, + + // Update time formatter to use provided locale configuration. + // For more see https://github.com/d3/d3-time-format + timeLocale: timeLocale, + time: function(f) { return timeF.format(f); }, + utc: function(f) { return timeF.utcFormat(f); }, + + // Set number and time locale simultaneously. + locale: function(l) { numberLocale(l); timeLocale(l); }, + + // automatic formatting functions + auto: { + number: numberAutoFormat, + time: function() { return timeAutoFormat(); }, + utc: function() { return utcAutoFormat(); } + } + }; + + var e10 = Math.sqrt(50), + e5 = Math.sqrt(10), + e2 = Math.sqrt(2); + + function intervals(domain, count) { + if (!domain.length) domain = [0]; + if (count == null) count = 10; + + var start = domain[0], + stop = domain[domain.length - 1]; + + if (stop < start) { error = stop; stop = start; start = error; } + + var span = (stop - start) || (count = 1, start || stop || 1), + step = Math.pow(10, Math.floor(Math.log(span / count) / Math.LN10)), + error = span / count / step; + + // Filter ticks to get closer to the desired count. + if (error >= e10) step *= 10; + else if (error >= e5) step *= 5; + else if (error >= e2) step *= 2; + + // Round start and stop values to step interval. + return [ + Math.ceil(start / step) * step, + Math.floor(stop / step) * step + step / 2, // inclusive + step + ]; + } + + function significantDigits(domain) { + return domain.map(function(x) { + // determine significant digits based on exponential format + var s = x.toExponential(), + e = s.indexOf('e'), + d = s.indexOf('.'); + return d < 0 ? 1 : (e-d); + }).reduce(function(max, p) { + // return the maximum sig digit count + return Math.max(max, p); + }, 0); + } + + function numberAutoFormat(domain, count, f) { + var range = intervals(domain, count); + if (f == null) { + f = ',.' + d3_numberF.precisionFixed(range[2]) + 'f'; + } else { + switch (f = d3_numberF.formatSpecifier(f), f.type) { + case 's': { + if (f.precision == null) f.precision = significantDigits(domain); + return numberF.format(f); + } + case '': + case 'e': + case 'g': + case 'p': + case 'r': { + if (f.precision == null) f.precision = d3_numberF.precisionRound(range[2], Math.max(Math.abs(range[0]), Math.abs(range[1]))) - (f.type === 'e'); + break; + } + case 'f': + case '%': { + if (f.precision == null) f.precision = d3_numberF.precisionFixed(range[2]) - (f.type === '%') * 2; + break; + } + } + } + return numberF.format(f); + } + + function timeAutoFormat() { + var f = timeF.format, + formatMillisecond = f('.%L'), + formatSecond = f(':%S'), + formatMinute = f('%I:%M'), + formatHour = f('%I %p'), + formatDay = f('%a %d'), + formatWeek = f('%b %d'), + formatMonth = f('%B'), + formatYear = f('%Y'); + + return function(date) { + var d = +date; + return (d3_time.second(date) < d ? formatMillisecond + : d3_time.minute(date) < d ? formatSecond + : d3_time.hour(date) < d ? formatMinute + : d3_time.day(date) < d ? formatHour + : d3_time.month(date) < d ? + (d3_time.week(date) < d ? formatDay : formatWeek) + : d3_time.year(date) < d ? formatMonth + : formatYear)(date); + }; + } + + function utcAutoFormat() { + var f = timeF.utcFormat, + formatMillisecond = f('.%L'), + formatSecond = f(':%S'), + formatMinute = f('%I:%M'), + formatHour = f('%I %p'), + formatDay = f('%a %d'), + formatWeek = f('%b %d'), + formatMonth = f('%B'), + formatYear = f('%Y'); + + return function(date) { + var d = +date; + return (d3_time.utcSecond(date) < d ? formatMillisecond + : d3_time.utcMinute(date) < d ? formatSecond + : d3_time.utcHour(date) < d ? formatMinute + : d3_time.utcDay(date) < d ? formatHour + : d3_time.utcMonth(date) < d ? + (d3_time.utcWeek(date) < d ? formatDay : formatWeek) + : d3_time.utcYear(date) < d ? formatMonth + : formatYear)(date); + }; + } + +},{"d3-format":6,"d3-time":8,"d3-time-format":7}],16:[function(require,module,exports){ + var gen = module.exports = {}; + + gen.repeat = function(val, n) { + var a = Array(n), i; + for (i=0; i stop) range.push(j); + else while ((j = start + step * ++i) < stop) range.push(j); + return range; + }; + + gen.random = {}; + + gen.random.uniform = function(min, max) { + if (max === undefined) { + max = min === undefined ? 1 : min; + min = 0; + } + var d = max - min; + var f = function() { + return min + d * Math.random(); + }; + f.samples = function(n) { return gen.zeros(n).map(f); }; + return f; + }; + + gen.random.integer = function(a, b) { + if (b === undefined) { + b = a; + a = 0; + } + var d = b - a; + var f = function() { + return a + Math.floor(d * Math.random()); + }; + f.samples = function(n) { return gen.zeros(n).map(f); }; + return f; + }; + + gen.random.normal = function(mean, stdev) { + mean = mean || 0; + stdev = stdev || 1; + var next; + var f = function() { + var x = 0, y = 0, rds, c; + if (next !== undefined) { + x = next; + next = undefined; + return x; + } + do { + x = Math.random()*2-1; + y = Math.random()*2-1; + rds = x*x + y*y; + } while (rds === 0 || rds > 1); + c = Math.sqrt(-2*Math.log(rds)/rds); // Box-Muller transform + next = mean + y*c*stdev; + return mean + x*c*stdev; + }; + f.samples = function(n) { return gen.zeros(n).map(f); }; + return f; + }; + +},{}],17:[function(require,module,exports){ + var util = require('../../util'); + var d3_dsv = require('d3-dsv'); + + function dsv(data, format) { + if (data) { + var h = format.header; + data = (h ? h.join(format.delimiter) + '\n' : '') + data; + } + return d3_dsv.dsv(format.delimiter).parse(data); + } + + dsv.delimiter = function(delim) { + var fmt = {delimiter: delim}; + return function(data, format) { + return dsv(data, format ? util.extend(format, fmt) : fmt); + }; + }; + + module.exports = dsv; + +},{"../../util":31,"d3-dsv":5}],18:[function(require,module,exports){ + var dsv = require('./dsv'); + + module.exports = { + json: require('./json'), + topojson: require('./topojson'), + treejson: require('./treejson'), + dsv: dsv, + csv: dsv.delimiter(','), + tsv: dsv.delimiter('\t') + }; + +},{"./dsv":17,"./json":19,"./topojson":20,"./treejson":21}],19:[function(require,module,exports){ + var util = require('../../util'); + + module.exports = function(data, format) { + var d = util.isObject(data) && !util.isBuffer(data) ? + data : JSON.parse(data); + if (format && format.property) { + d = util.accessor(format.property)(d); + } + return d; + }; + +},{"../../util":31}],20:[function(require,module,exports){ + (function (global){ + var json = require('./json'); + + var reader = function(data, format) { + var topojson = reader.topojson; + if (topojson == null) { throw Error('TopoJSON library not loaded.'); } + + var t = json(data, format), obj; + + if (format && format.feature) { + if ((obj = t.objects[format.feature])) { + return topojson.feature(t, obj).features; + } else { + throw Error('Invalid TopoJSON object: ' + format.feature); + } + } else if (format && format.mesh) { + if ((obj = t.objects[format.mesh])) { + return [topojson.mesh(t, t.objects[format.mesh])]; + } else { + throw Error('Invalid TopoJSON object: ' + format.mesh); + } + } else { + throw Error('Missing TopoJSON feature or mesh parameter.'); + } + }; + + reader.topojson = (typeof window !== "undefined" ? window['topojson'] : typeof global !== "undefined" ? global['topojson'] : null); + module.exports = reader; + + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./json":19}],21:[function(require,module,exports){ + var json = require('./json'); + + module.exports = function(tree, format) { + return toTable(json(tree, format), format); + }; + + function toTable(root, fields) { + var childrenField = fields && fields.children || 'children', + parentField = fields && fields.parent || 'parent', + table = []; + + function visit(node, parent) { + node[parentField] = parent; + table.push(node); + var children = node[childrenField]; + if (children) { + for (var i=0; i 1 && domain[idx-1] === '.' && domain.lastIndexOf(d) === idx); + }); + if (!whiteListed) { + throw 'URL is not whitelisted: ' + url; + } + } + } + return url; + } + + function load(opt, callback) { + var error = callback || function(e) { throw e; }, url; + + try { + url = load.sanitizeUrl(opt); // enable override + } catch (err) { + error(err); + return; + } + + if (!url) { + error('Invalid URL: ' + opt.url); + } else if (load.useXHR) { + // on client, use xhr + return xhr(url, callback); + } else if (startsWith(url, fileProtocol)) { + // on server, if url starts with 'file://', strip it and load from file + return file(url.slice(fileProtocol.length), callback); + } else if (url.indexOf('://') < 0) { // TODO better protocol check? + // on server, if no protocol assume file + return file(url, callback); + } else { + // for regular URLs on server + return http(url, callback); + } + } + + function xhrHasResponse(request) { + var type = request.responseType; + return type && type !== 'text' ? + request.response : // null on error + request.responseText; // '' on error + } + + function xhr(url, callback) { + var async = !!callback; + var request = new XMLHttpRequest(); + // If IE does not support CORS, use XDomainRequest (copied from d3.xhr) + if (this.XDomainRequest && + !('withCredentials' in request) && + /^(http(s)?:)?\/\//.test(url)) request = new XDomainRequest(); + + function respond() { + var status = request.status; + if (!status && xhrHasResponse(request) || status >= 200 && status < 300 || status === 304) { + callback(null, request.responseText); + } else { + callback(request, null); + } + } + + if (async) { + if ('onload' in request) { + request.onload = request.onerror = respond; + } else { + request.onreadystatechange = function() { + if (request.readyState > 3) respond(); + }; + } + } + + request.open('GET', url, async); + request.send(); + + if (!async && xhrHasResponse(request)) { + return request.responseText; + } + } + + function file(filename, callback) { + var fs = require('fs'); + if (!callback) { + return fs.readFileSync(filename, 'utf8'); + } + fs.readFile(filename, callback); + } + + function http(url, callback) { + if (!callback) { + return require('sync-request')('GET', url).getBody(); + } + + var options = {url: url, encoding: null, gzip: true}; + require('request')(options, function(error, response, body) { + if (!error && response.statusCode === 200) { + callback(null, body); + } else { + error = error || + 'Load failed with response code ' + response.statusCode + '.'; + callback(error, null); + } + }); + } + + function startsWith(string, searchString) { + return string == null ? false : string.lastIndexOf(searchString, 0) === 0; + } + + load.sanitizeUrl = sanitizeUrl; + + load.useXHR = (typeof XMLHttpRequest !== 'undefined'); + + module.exports = load; + +},{"fs":2,"request":2,"sync-request":2,"url":2}],23:[function(require,module,exports){ + var util = require('../util'); + var type = require('./type'); + var formats = require('./formats'); + + function read(data, format) { + var type = (format && format.type) || 'json'; + data = formats[type](data, format); + if (format && format.parse) parse(data, format.parse); + return data; + } + + function parse(data, types) { + var cols, parsers, d, i, j, clen, len = data.length; + + types = (types==='auto') ? type.inferAll(data) : util.duplicate(types); + cols = util.keys(types); + parsers = cols.map(function(c) { return type.parsers[types[c]]; }); + + for (i=0, clen=cols.length; i 0 ? Math.min(l, opt.maxwidth) : l; + }); + + // print header row + var head = fields.map(function(name, i) { + return util.truncate(util.pad(name, lens[i], 'center'), lens[i]); + }).join(opt.separator); + + // build template function for each row + var tmpl = template(fields.map(function(name, i) { + return '{{' + + name + + (FMT[types[name]] || '') + + ('|pad:' + lens[i] + ',' + (POS[types[name]] || 'right')) + + ('|truncate:' + lens[i]) + + '}}'; + }).join(opt.separator)); + + // print table + return head + "\n" + data.map(tmpl).join('\n'); + }; + + module.exports.summary = function(s) { + s = s ? s.__summary__ ? s : stats.summary(s) : this; + var str = [], i, n; + for (i=0, n=s.length; i b) b = v; + } + } + return [a, b]; + }; + +// Find the integer indices of the minimum and maximum values. + stats.extent.index = function(values, f) { + f = util.$(f); + var x = -1, y = -1, a, b, v, i, n = values.length; + for (i=0; i b) { b = v; y = i; } + } + } + return [x, y]; + }; + +// Compute the dot product of two arrays of numbers. + stats.dot = function(values, a, b) { + var sum = 0, i, v; + if (!b) { + if (values.length !== a.length) { + throw Error('Array lengths must match.'); + } + for (i=0; i -1 && p !== v) { + mu = 1 + (i-1 + tie) / 2; + for (; tie -1) { + mu = 1 + (n-1 + tie) / 2; + for (; tie max) max = x; + delta = x - mean; + mean = mean + delta / (++valid); + M2 = M2 + delta * (x - mean); + vals.push(x); + } + } + M2 = M2 / (valid - 1); + sd = Math.sqrt(M2); + + // sort values for median and iqr + vals.sort(util.cmp); + + return { + type: type(values, f), + unique: u, + count: values.length, + valid: valid, + missing: missing, + distinct: distinct, + min: min, + max: max, + mean: mean, + stdev: sd, + median: (v = stats.quantile(vals, 0.5)), + q1: stats.quantile(vals, 0.25), + q3: stats.quantile(vals, 0.75), + modeskew: sd === 0 ? 0 : (mean - v) / sd + }; + }; + +// Compute profiles for all variables in a data set. + stats.summary = function(data, fields) { + fields = fields || util.keys(data[0]); + var s = fields.map(function(f) { + var p = stats.profile(data, util.$(f)); + return (p.field = f, p); + }); + return (s.__summary__ = true, s); + }; + + module.exports = stats; + +},{"./generate":16,"./import/type":25,"./util":31}],29:[function(require,module,exports){ + var util = require('./util'), + format = require('./format'); + + var context = { + formats: [], + format_map: {}, + truncate: util.truncate, + pad: util.pad + }; + + function template(text) { + var src = source(text, 'd'); + src = 'var __t; return ' + src + ';'; + + /* jshint evil: true */ + return (new Function('d', src)).bind(context); + } + + template.source = source; + template.context = context; + module.exports = template; + +// Clear cache of format objects. +// This can *break* prior template functions, so invoke with care! + template.clearFormatCache = function() { + context.formats = []; + context.format_map = {}; + }; + +// Generate property access code for use within template source. +// object: the name of the object (variable) containing template data +// property: the property access string, verbatim from template tag + template.property = function(object, property) { + var src = util.field(property).map(util.str).join(']['); + return object + '[' + src + ']'; + }; + +// Generate source code for a template function. +// text: the template text +// variable: the name of the data object variable ('obj' by default) +// properties: optional hash for collecting all accessed properties + function source(text, variable, properties) { + variable = variable || 'obj'; + var index = 0; + var src = '\''; + var regex = template_re; + + // Compile the template source, escaping string literals appropriately. + text.replace(regex, function(match, interpolate, offset) { + src += text + .slice(index, offset) + .replace(template_escaper, template_escapeChar); + index = offset + match.length; + + if (interpolate) { + src += '\'\n+((__t=(' + + template_var(interpolate, variable, properties) + + '))==null?\'\':__t)+\n\''; + } + + // Adobe VMs need the match returned to produce the correct offest. + return match; + }); + return src + '\''; + } + + function template_var(text, variable, properties) { + var filters = text.match(filter_re); + var prop = filters.shift().trim(); + var stringCast = true; + + function strcall(fn) { + fn = fn || ''; + if (stringCast) { + stringCast = false; + src = 'String(' + src + ')' + fn; + } else { + src += fn; + } + return src; + } + + function date() { + return '(typeof ' + src + '==="number"?new Date('+src+'):'+src+')'; + } + + function number_format(fmt, key) { + a = template_format(args[0], key, fmt); + stringCast = false; + src = 'this.formats['+a+']('+src+')'; + } + + function time_format(fmt, key) { + a = template_format(args[0], key, fmt); + stringCast = false; + src = 'this.formats['+a+']('+date()+')'; + } + + if (properties) properties[prop] = 1; + var src = template.property(variable, prop); + + for (var i=0; i 0) { + f = f.slice(0, pidx); + args = filters[i].slice(pidx+1) + .match(args_re) + .map(function(s) { return s.trim(); }); + } + f = f.trim(); + + switch (f) { + case 'length': + strcall('.length'); + break; + case 'lower': + strcall('.toLowerCase()'); + break; + case 'upper': + strcall('.toUpperCase()'); + break; + case 'lower-locale': + strcall('.toLocaleLowerCase()'); + break; + case 'upper-locale': + strcall('.toLocaleUpperCase()'); + break; + case 'trim': + strcall('.trim()'); + break; + case 'left': + a = util.number(args[0]); + strcall('.slice(0,' + a + ')'); + break; + case 'right': + a = util.number(args[0]); + strcall('.slice(-' + a +')'); + break; + case 'mid': + a = util.number(args[0]); + b = a + util.number(args[1]); + strcall('.slice(+'+a+','+b+')'); + break; + case 'slice': + a = util.number(args[0]); + strcall('.slice('+ a + + (args.length > 1 ? ',' + util.number(args[1]) : '') + + ')'); + break; + case 'truncate': + a = util.number(args[0]); + b = args[1]; + b = (b!=='left' && b!=='middle' && b!=='center') ? 'right' : b; + src = 'this.truncate(' + strcall() + ',' + a + ',\'' + b + '\')'; + break; + case 'pad': + a = util.number(args[0]); + b = args[1]; + b = (b!=='left' && b!=='middle' && b!=='center') ? 'right' : b; + src = 'this.pad(' + strcall() + ',' + a + ',\'' + b + '\')'; + break; + case 'number': + number_format(format.number, 'number'); + break; + case 'time': + time_format(format.time, 'time'); + break; + case 'time-utc': + time_format(format.utc, 'time-utc'); + break; + default: + throw Error('Unrecognized template filter: ' + f); + } + } + + return src; + } + + var template_re = /\{\{(.+?)\}\}|$/g, + filter_re = /(?:"[^"]*"|\'[^\']*\'|[^\|"]+|[^\|\']+)+/g, + args_re = /(?:"[^"]*"|\'[^\']*\'|[^,"]+|[^,\']+)+/g; + +// Certain characters need to be escaped so that they can be put into a +// string literal. + var template_escapes = { + '\'': '\'', + '\\': '\\', + '\r': 'r', + '\n': 'n', + '\u2028': 'u2028', + '\u2029': 'u2029' + }; + + var template_escaper = /\\|'|\r|\n|\u2028|\u2029/g; + + function template_escapeChar(match) { + return '\\' + template_escapes[match]; + } + + function template_format(pattern, key, fmt) { + if ((pattern[0] === '\'' && pattern[pattern.length-1] === '\'') || + (pattern[0] === '"' && pattern[pattern.length-1] === '"')) { + pattern = pattern.slice(1, -1); + } else { + throw Error('Format pattern must be quoted: ' + pattern); + } + key = key + ':' + pattern; + if (!context.format_map[key]) { + var f = fmt(pattern); + var i = context.formats.length; + context.formats.push(f); + context.format_map[key] = i; + } + return context.format_map[key]; + } + +},{"./format":15,"./util":31}],30:[function(require,module,exports){ + var d3_time = require('d3-time'); + + var tempDate = new Date(), + baseDate = new Date(0, 0, 1).setFullYear(0), // Jan 1, 0 AD + utcBaseDate = new Date(Date.UTC(0, 0, 1)).setUTCFullYear(0); + + function date(d) { + return (tempDate.setTime(+d), tempDate); + } + +// create a time unit entry + function entry(type, date, unit, step, min, max) { + var e = { + type: type, + date: date, + unit: unit + }; + if (step) { + e.step = step; + } else { + e.minstep = 1; + } + if (min != null) e.min = min; + if (max != null) e.max = max; + return e; + } + + function create(type, unit, base, step, min, max) { + return entry(type, + function(d) { return unit.offset(base, d); }, + function(d) { return unit.count(base, d); }, + step, min, max); + } + + var locale = [ + create('second', d3_time.second, baseDate), + create('minute', d3_time.minute, baseDate), + create('hour', d3_time.hour, baseDate), + create('day', d3_time.day, baseDate, [1, 7]), + create('month', d3_time.month, baseDate, [1, 3, 6]), + create('year', d3_time.year, baseDate), + + // periodic units + entry('seconds', + function(d) { return new Date(1970, 0, 1, 0, 0, d); }, + function(d) { return date(d).getSeconds(); }, + null, 0, 59 + ), + entry('minutes', + function(d) { return new Date(1970, 0, 1, 0, d); }, + function(d) { return date(d).getMinutes(); }, + null, 0, 59 + ), + entry('hours', + function(d) { return new Date(1970, 0, 1, d); }, + function(d) { return date(d).getHours(); }, + null, 0, 23 + ), + entry('weekdays', + function(d) { return new Date(1970, 0, 4+d); }, + function(d) { return date(d).getDay(); }, + [1], 0, 6 + ), + entry('dates', + function(d) { return new Date(1970, 0, d); }, + function(d) { return date(d).getDate(); }, + [1], 1, 31 + ), + entry('months', + function(d) { return new Date(1970, d % 12, 1); }, + function(d) { return date(d).getMonth(); }, + [1], 0, 11 + ) + ]; + + var utc = [ + create('second', d3_time.utcSecond, utcBaseDate), + create('minute', d3_time.utcMinute, utcBaseDate), + create('hour', d3_time.utcHour, utcBaseDate), + create('day', d3_time.utcDay, utcBaseDate, [1, 7]), + create('month', d3_time.utcMonth, utcBaseDate, [1, 3, 6]), + create('year', d3_time.utcYear, utcBaseDate), + + // periodic units + entry('seconds', + function(d) { return new Date(Date.UTC(1970, 0, 1, 0, 0, d)); }, + function(d) { return date(d).getUTCSeconds(); }, + null, 0, 59 + ), + entry('minutes', + function(d) { return new Date(Date.UTC(1970, 0, 1, 0, d)); }, + function(d) { return date(d).getUTCMinutes(); }, + null, 0, 59 + ), + entry('hours', + function(d) { return new Date(Date.UTC(1970, 0, 1, d)); }, + function(d) { return date(d).getUTCHours(); }, + null, 0, 23 + ), + entry('weekdays', + function(d) { return new Date(Date.UTC(1970, 0, 4+d)); }, + function(d) { return date(d).getUTCDay(); }, + [1], 0, 6 + ), + entry('dates', + function(d) { return new Date(Date.UTC(1970, 0, d)); }, + function(d) { return date(d).getUTCDate(); }, + [1], 1, 31 + ), + entry('months', + function(d) { return new Date(Date.UTC(1970, d % 12, 1)); }, + function(d) { return date(d).getUTCMonth(); }, + [1], 0, 11 + ) + ]; + + var STEPS = [ + [31536e6, 5], // 1-year + [7776e6, 4], // 3-month + [2592e6, 4], // 1-month + [12096e5, 3], // 2-week + [6048e5, 3], // 1-week + [1728e5, 3], // 2-day + [864e5, 3], // 1-day + [432e5, 2], // 12-hour + [216e5, 2], // 6-hour + [108e5, 2], // 3-hour + [36e5, 2], // 1-hour + [18e5, 1], // 30-minute + [9e5, 1], // 15-minute + [3e5, 1], // 5-minute + [6e4, 1], // 1-minute + [3e4, 0], // 30-second + [15e3, 0], // 15-second + [5e3, 0], // 5-second + [1e3, 0] // 1-second + ]; + + function find(units, span, minb, maxb) { + var step = STEPS[0], i, n, bins; + + for (i=1, n=STEPS.length; i step[0]) { + bins = span / step[0]; + if (bins > maxb) { + return units[STEPS[i-1][1]]; + } + if (bins >= minb) { + return units[step[1]]; + } + } + } + return units[STEPS[n-1][1]]; + } + + function toUnitMap(units) { + var map = {}, i, n; + for (i=0, n=units.length; i 1 ? + function(x) { return s.reduce(function(x,f) { return x[f]; }, x); } : + function(x) { return x[f]; } + ); + }; + +// short-cut for accessor + u.$ = u.accessor; + + u.mutator = function(f) { + var s; + return u.isString(f) && (s=u.field(f)).length > 1 ? + function(x, v) { + for (var i=0; i y) return sign[i]; + } + return 0; + }; + }; + + u.cmp = function(a, b) { + if (a < b) { + return -1; + } else if (a > b) { + return 1; + } else if (a >= b) { + return 0; + } else if (a === null) { + return -1; + } else if (b === null) { + return 1; + } + return NaN; + }; + + u.numcmp = function(a, b) { return a - b; }; + + u.stablesort = function(array, sortBy, keyFn) { + var indices = array.reduce(function(idx, v, i) { + return (idx[keyFn(v)] = i, idx); + }, {}); + + array.sort(function(a, b) { + var sa = sortBy(a), + sb = sortBy(b); + return sa < sb ? -1 : sa > sb ? 1 + : (indices[keyFn(a)] - indices[keyFn(b)]); + }); + + return array; + }; + + +// string functions + + u.pad = function(s, length, pos, padchar) { + padchar = padchar || " "; + var d = length - s.length; + if (d <= 0) return s; + switch (pos) { + case 'left': + return strrep(d, padchar) + s; + case 'middle': + case 'center': + return strrep(Math.floor(d/2), padchar) + + s + strrep(Math.ceil(d/2), padchar); + default: + return s + strrep(d, padchar); + } + }; + + function strrep(n, str) { + var s = "", i; + for (i=0; i 1) { + for (var i=1, n=ref.length; i 0) { + node = pq.peek(); + pulse = pulses[node._id]; + + if (node.rank() !== node.qrank()) { + // A node's rank might change during a propagation. Re-queue if so. + pq.replace(node.qrank(true)); + } else { + // Evaluate node and propagate pulse. + pq.pop(); + pulses[node._id] = null; + listeners = node._listeners; + pulse = this.evaluate(pulse, node); + + // Propagate the pulse. + if (pulse !== this.doNotPropagate) { + // Ensure reflow pulses always send reflow pulses even if skipped. + if (!pulse.reflow && node.reflows()) { + pulse = ChangeSet.create(pulse, true); + } + + for (i=0, len=listeners.length; i 0) branch[i-1].addListener(node); + } + + return branch; + }; + + prototype.disconnect = function(branch) { + var collector, node, data, signals, i, n, j, m; + + for (i=0, n=branch.length; i= pulse.stamp, + run = node.router() || pulse.add.length || pulse.rem.length; + + return run || !reflowed || node.reevaluate(pulse); + }; + + prototype.evaluate = function(pulse, node) { + if (!this.reevaluate(pulse, node)) return pulse; + pulse = node.evaluate(pulse); + node.last(pulse.stamp); + return pulse; + }; + + module.exports = Graph; + +},{"./ChangeSet":32,"./Collector":33,"./DataSource":34,"./Dependencies":35,"./Heap":37,"./Signal":39,"./Tuple":40,"datalib":26}],37:[function(require,module,exports){ + function Heap(comparator) { + this.cmp = comparator; + this.nodes = []; + } + + var prototype = Heap.prototype; + + prototype.size = function() { + return this.nodes.length; + }; + + prototype.clear = function() { + return (this.nodes = [], this); + }; + + prototype.peek = function() { + return this.nodes[0]; + }; + + prototype.push = function(x) { + var array = this.nodes; + array.push(x); + return _siftdown(array, 0, array.length-1, this.cmp); + }; + + prototype.pop = function() { + var array = this.nodes, + last = array.pop(), + item; + + if (array.length) { + item = array[0]; + array[0] = last; + _siftup(array, 0, this.cmp); + } else { + item = last; + } + return item; + }; + + prototype.replace = function(item) { + var array = this.nodes, + retval = array[0]; + array[0] = item; + _siftup(array, 0, this.cmp); + return retval; + }; + + prototype.pushpop = function(item) { + var array = this.nodes, ref = array[0]; + if (array.length && this.cmp(ref, item) < 0) { + array[0] = item; + item = ref; + _siftup(array, 0, this.cmp); + } + return item; + }; + + function _siftdown(array, start, idx, cmp) { + var item, parent, pidx; + + item = array[idx]; + while (idx > start) { + pidx = (idx - 1) >> 1; + parent = array[pidx]; + if (cmp(item, parent) < 0) { + array[idx] = parent; + idx = pidx; + continue; + } + break; + } + return (array[idx] = item); + } + + function _siftup(array, idx, cmp) { + var start = idx, + end = array.length, + item = array[idx], + cidx = 2 * idx + 1, ridx; + + while (cidx < end) { + ridx = cidx + 1; + if (ridx < end && cmp(array[cidx], array[ridx]) >= 0) { + cidx = ridx; + } + array[idx] = array[cidx]; + idx = cidx; + cidx = 2 * idx + 1; + } + array[idx] = item; + return _siftdown(array, start, idx, cmp); + } + + module.exports = Heap; + +},{}],38:[function(require,module,exports){ + var DEPS = require('./Dependencies').ALL, + nodeID = 0; + + function Node(graph) { + if (graph) this.init(graph); + } + + var Flags = Node.Flags = { + Router: 0x01, // Responsible for propagating tuples, cannot be skipped. + Collector: 0x02, // Holds a materialized dataset, pulse node to reflow. + Produces: 0x04, // Produces new tuples. + Mutates: 0x08, // Sets properties of incoming tuples. + Reflows: 0x10, // Forwards a reflow pulse. + Batch: 0x20 // Performs batch data processing, needs collector. + }; + + var prototype = Node.prototype; + + prototype.init = function(graph) { + this._id = ++nodeID; + this._graph = graph; + this._rank = graph.rank(); // Topological sort by rank + this._qrank = null; // Rank when enqueued for propagation + this._stamp = 0; // Last stamp seen + + this._listeners = []; + this._listeners._ids = {}; // To prevent duplicate listeners + + // Initialize dependencies. + this._deps = {}; + for (var i=0, n=DEPS.length; i l._rank) { + l.rerank(); + } + + return this; + }; + + prototype.removeListener = function(l) { + if (!this._listeners._ids[l._id]) return false; + + var idx = this._listeners.indexOf(l), + b = idx >= 0; + + if (b) { + this._listeners.splice(idx, 1); + this._listeners._ids[l._id] = null; + } + return b; + }; + + prototype.disconnect = function() { + this._listeners = []; + this._listeners._ids = {}; + }; + +// Evaluate this dataflow node for the current pulse. +// Subclasses should override to perform custom processing. + prototype.evaluate = function(pulse) { + return pulse; + }; + +// Should this node be re-evaluated for the current pulse? +// Searches pulse to see if any dependencies have updated. + prototype.reevaluate = function(pulse) { + var prop, dep, i, n, j, m; + + for (i=0, n=DEPS.length; i=0;) { + if (!handler || h[i].handler === handler) { + x = h.splice(i, 1)[0]; + this.removeListener(x.node); + } + } + + return this; + }; + + module.exports = Signal; + +},{"./ChangeSet":32,"./Node":38}],40:[function(require,module,exports){ + var tupleID = 0; + + function ingest(datum) { + datum = (datum === Object(datum)) ? datum : {data: datum}; + datum._id = ++tupleID; + if (datum._prev) datum._prev = null; + return datum; + } + + function idMap(a, ids) { + ids = ids || {}; + for (var i=0, n=a.length; i0;) { + idMap(arguments[i], ids); + } + return data.filter(function(x) { return !ids[x._id]; }); + } + }; + +},{}],41:[function(require,module,exports){ + module.exports = { + ChangeSet: require('./ChangeSet'), + Collector: require('./Collector'), + DataSource: require('./DataSource'), + Dependencies: require('./Dependencies'), + Graph: require('./Graph'), + Node: require('./Node'), + Signal: require('./Signal'), + Tuple: require('./Tuple'), + debug: require('vega-logging').debug + }; + +},{"./ChangeSet":32,"./Collector":33,"./DataSource":34,"./Dependencies":35,"./Graph":36,"./Node":38,"./Signal":39,"./Tuple":40,"vega-logging":47}],42:[function(require,module,exports){ + function toMap(list) { + var map = {}, i, n; + for (i=0, n=list.length; i 0) { + return id; + } + if (constants.hasOwnProperty(id)) { + return constants[id]; + } + if (idWhiteList) { + if (idWhiteList.hasOwnProperty(id)) { + return id; + } else { + globals[id] = 1; + return lookupGlobal(id); + } + } + if (idBlackList && idBlackList.hasOwnProperty(id)) { + throw new Error('Illegal identifier: ' + id); + } + return id; + }, + 'Program': function(n) { + return n.body.map(codegen).join('\n'); + }, + 'MemberExpression': function(n) { + var d = !n.computed; + var o = codegen(n.object); + if (d) memberDepth += 1; + var p = codegen(n.property); + if (o === FIELD_VAR) { fields[p] = 1; } // HACKish... + if (d) memberDepth -= 1; + return o + (d ? '.'+p : '['+p+']'); + }, + 'CallExpression': function(n) { + if (n.callee.type !== 'Identifier') { + throw new Error('Illegal callee type: ' + n.callee.type); + } + var callee = n.callee.name; + var args = n.arguments; + var fn = functions.hasOwnProperty(callee) && functions[callee]; + if (!fn) throw new Error('Unrecognized function: ' + callee); + return fn instanceof Function ? + fn(args) : + fn + '(' + args.map(codegen).join(',') + ')'; + }, + 'ArrayExpression': function(n) { + return '[' + n.elements.map(codegen).join(',') + ']'; + }, + 'BinaryExpression': function(n) { + return '(' + codegen(n.left) + n.operator + codegen(n.right) + ')'; + }, + 'UnaryExpression': function(n) { + return '(' + n.operator + codegen(n.argument) + ')'; + }, + 'ConditionalExpression': function(n) { + return '(' + codegen(n.test) + + '?' + codegen(n.consequent) + + ':' + codegen(n.alternate) + + ')'; + }, + 'LogicalExpression': function(n) { + return '(' + codegen(n.left) + n.operator + codegen(n.right) + ')'; + }, + 'ObjectExpression': function(n) { + return '{' + n.properties.map(codegen).join(',') + '}'; + }, + 'Property': function(n) { + memberDepth += 1; + var k = codegen(n.key); + memberDepth -= 1; + return k + ':' + codegen(n.value); + }, + 'ExpressionStatement': function(n) { + return codegen(n.expression); + } + }; + + codegen_wrap.functions = functions; + codegen_wrap.constants = constants; + return codegen_wrap; + }; + +},{"./constants":43,"./functions":44}],43:[function(require,module,exports){ + module.exports = { + 'NaN': 'NaN', + 'E': 'Math.E', + 'LN2': 'Math.LN2', + 'LN10': 'Math.LN10', + 'LOG2E': 'Math.LOG2E', + 'LOG10E': 'Math.LOG10E', + 'PI': 'Math.PI', + 'SQRT1_2': 'Math.SQRT1_2', + 'SQRT2': 'Math.SQRT2' + }; +},{}],44:[function(require,module,exports){ + module.exports = function(codegen) { + + function fncall(name, args, cast, type) { + var obj = codegen(args[0]); + if (cast) { + obj = cast + '(' + obj + ')'; + if (cast.lastIndexOf('new ', 0) === 0) obj = '(' + obj + ')'; + } + return obj + '.' + name + (type < 0 ? '' : type === 0 ? + '()' : + '(' + args.slice(1).map(codegen).join(',') + ')'); + } + + function fn(name, cast, type) { + return function(args) { + return fncall(name, args, cast, type); + }; + } + + var DATE = 'new Date', + STRING = 'String', + REGEXP = 'RegExp'; + + return { + // MATH functions + 'isNaN': 'isNaN', + 'isFinite': 'isFinite', + 'abs': 'Math.abs', + 'acos': 'Math.acos', + 'asin': 'Math.asin', + 'atan': 'Math.atan', + 'atan2': 'Math.atan2', + 'ceil': 'Math.ceil', + 'cos': 'Math.cos', + 'exp': 'Math.exp', + 'floor': 'Math.floor', + 'log': 'Math.log', + 'max': 'Math.max', + 'min': 'Math.min', + 'pow': 'Math.pow', + 'random': 'Math.random', + 'round': 'Math.round', + 'sin': 'Math.sin', + 'sqrt': 'Math.sqrt', + 'tan': 'Math.tan', + + 'clamp': function(args) { + if (args.length < 3) + throw new Error('Missing arguments to clamp function.'); + if (args.length > 3) + throw new Error('Too many arguments to clamp function.'); + var a = args.map(codegen); + return 'Math.max('+a[1]+', Math.min('+a[2]+','+a[0]+'))'; + }, + + // DATE functions + 'now': 'Date.now', + 'datetime': DATE, + 'date': fn('getDate', DATE, 0), + 'day': fn('getDay', DATE, 0), + 'year': fn('getFullYear', DATE, 0), + 'month': fn('getMonth', DATE, 0), + 'hours': fn('getHours', DATE, 0), + 'minutes': fn('getMinutes', DATE, 0), + 'seconds': fn('getSeconds', DATE, 0), + 'milliseconds': fn('getMilliseconds', DATE, 0), + 'time': fn('getTime', DATE, 0), + 'timezoneoffset': fn('getTimezoneOffset', DATE, 0), + 'utcdate': fn('getUTCDate', DATE, 0), + 'utcday': fn('getUTCDay', DATE, 0), + 'utcyear': fn('getUTCFullYear', DATE, 0), + 'utcmonth': fn('getUTCMonth', DATE, 0), + 'utchours': fn('getUTCHours', DATE, 0), + 'utcminutes': fn('getUTCMinutes', DATE, 0), + 'utcseconds': fn('getUTCSeconds', DATE, 0), + 'utcmilliseconds': fn('getUTCMilliseconds', DATE, 0), + + // shared sequence functions + 'length': fn('length', null, -1), + 'indexof': fn('indexOf', null), + 'lastindexof': fn('lastIndexOf', null), + + // STRING functions + 'parseFloat': 'parseFloat', + 'parseInt': 'parseInt', + 'upper': fn('toUpperCase', STRING, 0), + 'lower': fn('toLowerCase', STRING, 0), + 'slice': fn('slice', STRING), + 'substring': fn('substring', STRING), + + // REGEXP functions + 'regexp': REGEXP, + 'test': fn('test', REGEXP), + + // Control Flow functions + 'if': function(args) { + if (args.length < 3) + throw new Error('Missing arguments to if function.'); + if (args.length > 3) + throw new Error('Too many arguments to if function.'); + var a = args.map(codegen); + return a[0]+'?'+a[1]+':'+a[2]; + } + }; + }; +},{}],45:[function(require,module,exports){ + var parser = require('./parser'), + codegen = require('./codegen'); + + var expr = module.exports = { + parse: function(input, opt) { + return parser.parse('('+input+')', opt); + }, + code: function(opt) { + return codegen(opt); + }, + compiler: function(args, opt) { + args = args.slice(); + var generator = codegen(opt), + len = args.length, + compile = function(str) { + var value = generator(expr.parse(str)); + args[len] = '"use strict"; return (' + value.code + ');'; + value.fn = Function.apply(null, args); + return value; + }; + compile.codegen = generator; + return compile; + }, + functions: require('./functions'), + constants: require('./constants') + }; + +},{"./codegen":42,"./constants":43,"./functions":44,"./parser":46}],46:[function(require,module,exports){ + /* + The following expression parser is based on Esprima (http://esprima.org/). + Original header comment and license for Esprima is included here: + + Copyright (C) 2013 Ariya Hidayat + Copyright (C) 2013 Thaddee Tyl + Copyright (C) 2013 Mathias Bynens + Copyright (C) 2012 Ariya Hidayat + Copyright (C) 2012 Mathias Bynens + Copyright (C) 2012 Joost-Wim Boekesteijn + Copyright (C) 2012 Kris Kowal + Copyright (C) 2012 Yusuke Suzuki + Copyright (C) 2012 Arpad Borsos + Copyright (C) 2011 Ariya Hidayat + + 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. + + 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 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. + */ + /* istanbul ignore next */ + module.exports = (function() { + 'use strict'; + + var Token, + TokenName, + Syntax, + PropertyKind, + Messages, + Regex, + source, + strict, + index, + lineNumber, + lineStart, + length, + lookahead, + state, + extra; + + Token = { + BooleanLiteral: 1, + EOF: 2, + Identifier: 3, + Keyword: 4, + NullLiteral: 5, + NumericLiteral: 6, + Punctuator: 7, + StringLiteral: 8, + RegularExpression: 9 + }; + + TokenName = {}; + TokenName[Token.BooleanLiteral] = 'Boolean'; + TokenName[Token.EOF] = ''; + TokenName[Token.Identifier] = 'Identifier'; + TokenName[Token.Keyword] = 'Keyword'; + TokenName[Token.NullLiteral] = 'Null'; + TokenName[Token.NumericLiteral] = 'Numeric'; + TokenName[Token.Punctuator] = 'Punctuator'; + TokenName[Token.StringLiteral] = 'String'; + TokenName[Token.RegularExpression] = 'RegularExpression'; + + Syntax = { + AssignmentExpression: 'AssignmentExpression', + ArrayExpression: 'ArrayExpression', + BinaryExpression: 'BinaryExpression', + CallExpression: 'CallExpression', + ConditionalExpression: 'ConditionalExpression', + ExpressionStatement: 'ExpressionStatement', + Identifier: 'Identifier', + Literal: 'Literal', + LogicalExpression: 'LogicalExpression', + MemberExpression: 'MemberExpression', + ObjectExpression: 'ObjectExpression', + Program: 'Program', + Property: 'Property', + UnaryExpression: 'UnaryExpression' + }; + + PropertyKind = { + Data: 1, + Get: 2, + Set: 4 + }; + + // Error messages should be identical to V8. + Messages = { + UnexpectedToken: 'Unexpected token %0', + UnexpectedNumber: 'Unexpected number', + UnexpectedString: 'Unexpected string', + UnexpectedIdentifier: 'Unexpected identifier', + UnexpectedReserved: 'Unexpected reserved word', + UnexpectedEOS: 'Unexpected end of input', + NewlineAfterThrow: 'Illegal newline after throw', + InvalidRegExp: 'Invalid regular expression', + UnterminatedRegExp: 'Invalid regular expression: missing /', + InvalidLHSInAssignment: 'Invalid left-hand side in assignment', + InvalidLHSInForIn: 'Invalid left-hand side in for-in', + MultipleDefaultsInSwitch: 'More than one default clause in switch statement', + NoCatchOrFinally: 'Missing catch or finally after try', + UnknownLabel: 'Undefined label \'%0\'', + Redeclaration: '%0 \'%1\' has already been declared', + IllegalContinue: 'Illegal continue statement', + IllegalBreak: 'Illegal break statement', + IllegalReturn: 'Illegal return statement', + StrictModeWith: 'Strict mode code may not include a with statement', + StrictCatchVariable: 'Catch variable may not be eval or arguments in strict mode', + StrictVarName: 'Variable name may not be eval or arguments in strict mode', + StrictParamName: 'Parameter name eval or arguments is not allowed in strict mode', + StrictParamDupe: 'Strict mode function may not have duplicate parameter names', + StrictFunctionName: 'Function name may not be eval or arguments in strict mode', + StrictOctalLiteral: 'Octal literals are not allowed in strict mode.', + StrictDelete: 'Delete of an unqualified identifier in strict mode.', + StrictDuplicateProperty: 'Duplicate data property in object literal not allowed in strict mode', + AccessorDataProperty: 'Object literal may not have data and accessor property with the same name', + AccessorGetSet: 'Object literal may not have multiple get/set accessors with the same name', + StrictLHSAssignment: 'Assignment to eval or arguments is not allowed in strict mode', + StrictLHSPostfix: 'Postfix increment/decrement may not have eval or arguments operand in strict mode', + StrictLHSPrefix: 'Prefix increment/decrement may not have eval or arguments operand in strict mode', + StrictReservedWord: 'Use of future reserved word in strict mode' + }; + + // See also tools/generate-unicode-regex.py. + Regex = { + NonAsciiIdentifierStart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]'), + NonAsciiIdentifierPart: new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]') + }; + + // Ensure the condition is true, otherwise throw an error. + // This is only to have a better contract semantic, i.e. another safety net + // to catch a logic error. The condition shall be fulfilled in normal case. + // Do NOT use this to enforce a certain condition on any user input. + + function assert(condition, message) { + if (!condition) { + throw new Error('ASSERT: ' + message); + } + } + + function isDecimalDigit(ch) { + return (ch >= 0x30 && ch <= 0x39); // 0..9 + } + + function isHexDigit(ch) { + return '0123456789abcdefABCDEF'.indexOf(ch) >= 0; + } + + function isOctalDigit(ch) { + return '01234567'.indexOf(ch) >= 0; + } + + // 7.2 White Space + + function isWhiteSpace(ch) { + return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) || + (ch >= 0x1680 && [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) >= 0); + } + + // 7.3 Line Terminators + + function isLineTerminator(ch) { + return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029); + } + + // 7.6 Identifier Names and Identifiers + + function isIdentifierStart(ch) { + return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore) + (ch >= 0x41 && ch <= 0x5A) || // A..Z + (ch >= 0x61 && ch <= 0x7A) || // a..z + (ch === 0x5C) || // \ (backslash) + ((ch >= 0x80) && Regex.NonAsciiIdentifierStart.test(String.fromCharCode(ch))); + } + + function isIdentifierPart(ch) { + return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore) + (ch >= 0x41 && ch <= 0x5A) || // A..Z + (ch >= 0x61 && ch <= 0x7A) || // a..z + (ch >= 0x30 && ch <= 0x39) || // 0..9 + (ch === 0x5C) || // \ (backslash) + ((ch >= 0x80) && Regex.NonAsciiIdentifierPart.test(String.fromCharCode(ch))); + } + + // 7.6.1.2 Future Reserved Words + + function isFutureReservedWord(id) { + switch (id) { + case 'class': + case 'enum': + case 'export': + case 'extends': + case 'import': + case 'super': + return true; + default: + return false; + } + } + + function isStrictModeReservedWord(id) { + switch (id) { + case 'implements': + case 'interface': + case 'package': + case 'private': + case 'protected': + case 'public': + case 'static': + case 'yield': + case 'let': + return true; + default: + return false; + } + } + + // 7.6.1.1 Keywords + + function isKeyword(id) { + if (strict && isStrictModeReservedWord(id)) { + return true; + } + + // 'const' is specialized as Keyword in V8. + // 'yield' and 'let' are for compatiblity with SpiderMonkey and ES.next. + // Some others are from future reserved words. + + switch (id.length) { + case 2: + return (id === 'if') || (id === 'in') || (id === 'do'); + case 3: + return (id === 'var') || (id === 'for') || (id === 'new') || + (id === 'try') || (id === 'let'); + case 4: + return (id === 'this') || (id === 'else') || (id === 'case') || + (id === 'void') || (id === 'with') || (id === 'enum'); + case 5: + return (id === 'while') || (id === 'break') || (id === 'catch') || + (id === 'throw') || (id === 'const') || (id === 'yield') || + (id === 'class') || (id === 'super'); + case 6: + return (id === 'return') || (id === 'typeof') || (id === 'delete') || + (id === 'switch') || (id === 'export') || (id === 'import'); + case 7: + return (id === 'default') || (id === 'finally') || (id === 'extends'); + case 8: + return (id === 'function') || (id === 'continue') || (id === 'debugger'); + case 10: + return (id === 'instanceof'); + default: + return false; + } + } + + function skipComment() { + var ch, start; + + start = (index === 0); + while (index < length) { + ch = source.charCodeAt(index); + + if (isWhiteSpace(ch)) { + ++index; + } else if (isLineTerminator(ch)) { + ++index; + if (ch === 0x0D && source.charCodeAt(index) === 0x0A) { + ++index; + } + ++lineNumber; + lineStart = index; + start = true; + } else { + break; + } + } + } + + function scanHexEscape(prefix) { + var i, len, ch, code = 0; + + len = (prefix === 'u') ? 4 : 2; + for (i = 0; i < len; ++i) { + if (index < length && isHexDigit(source[index])) { + ch = source[index++]; + code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); + } else { + return ''; + } + } + return String.fromCharCode(code); + } + + function scanUnicodeCodePointEscape() { + var ch, code, cu1, cu2; + + ch = source[index]; + code = 0; + + // At least, one hex digit is required. + if (ch === '}') { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + while (index < length) { + ch = source[index++]; + if (!isHexDigit(ch)) { + break; + } + code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); + } + + if (code > 0x10FFFF || ch !== '}') { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + // UTF-16 Encoding + if (code <= 0xFFFF) { + return String.fromCharCode(code); + } + cu1 = ((code - 0x10000) >> 10) + 0xD800; + cu2 = ((code - 0x10000) & 1023) + 0xDC00; + return String.fromCharCode(cu1, cu2); + } + + function getEscapedIdentifier() { + var ch, id; + + ch = source.charCodeAt(index++); + id = String.fromCharCode(ch); + + // '\u' (U+005C, U+0075) denotes an escaped character. + if (ch === 0x5C) { + if (source.charCodeAt(index) !== 0x75) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + ++index; + ch = scanHexEscape('u'); + if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + id = ch; + } + + while (index < length) { + ch = source.charCodeAt(index); + if (!isIdentifierPart(ch)) { + break; + } + ++index; + id += String.fromCharCode(ch); + + // '\u' (U+005C, U+0075) denotes an escaped character. + if (ch === 0x5C) { + id = id.substr(0, id.length - 1); + if (source.charCodeAt(index) !== 0x75) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + ++index; + ch = scanHexEscape('u'); + if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + id += ch; + } + } + + return id; + } + + function getIdentifier() { + var start, ch; + + start = index++; + while (index < length) { + ch = source.charCodeAt(index); + if (ch === 0x5C) { + // Blackslash (U+005C) marks Unicode escape sequence. + index = start; + return getEscapedIdentifier(); + } + if (isIdentifierPart(ch)) { + ++index; + } else { + break; + } + } + + return source.slice(start, index); + } + + function scanIdentifier() { + var start, id, type; + + start = index; + + // Backslash (U+005C) starts an escaped character. + id = (source.charCodeAt(index) === 0x5C) ? getEscapedIdentifier() : getIdentifier(); + + // There is no keyword or literal with only one character. + // Thus, it must be an identifier. + if (id.length === 1) { + type = Token.Identifier; + } else if (isKeyword(id)) { + type = Token.Keyword; + } else if (id === 'null') { + type = Token.NullLiteral; + } else if (id === 'true' || id === 'false') { + type = Token.BooleanLiteral; + } else { + type = Token.Identifier; + } + + return { + type: type, + value: id, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // 7.7 Punctuators + + function scanPunctuator() { + var start = index, + code = source.charCodeAt(index), + code2, + ch1 = source[index], + ch2, + ch3, + ch4; + + switch (code) { + + // Check for most common single-character punctuators. + case 0x2E: // . dot + case 0x28: // ( open bracket + case 0x29: // ) close bracket + case 0x3B: // ; semicolon + case 0x2C: // , comma + case 0x7B: // { open curly brace + case 0x7D: // } close curly brace + case 0x5B: // [ + case 0x5D: // ] + case 0x3A: // : + case 0x3F: // ? + case 0x7E: // ~ + ++index; + if (extra.tokenize) { + if (code === 0x28) { + extra.openParenToken = extra.tokens.length; + } else if (code === 0x7B) { + extra.openCurlyToken = extra.tokens.length; + } + } + return { + type: Token.Punctuator, + value: String.fromCharCode(code), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + + default: + code2 = source.charCodeAt(index + 1); + + // '=' (U+003D) marks an assignment or comparison operator. + if (code2 === 0x3D) { + switch (code) { + case 0x2B: // + + case 0x2D: // - + case 0x2F: // / + case 0x3C: // < + case 0x3E: // > + case 0x5E: // ^ + case 0x7C: // | + case 0x25: // % + case 0x26: // & + case 0x2A: // * + index += 2; + return { + type: Token.Punctuator, + value: String.fromCharCode(code) + String.fromCharCode(code2), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + + case 0x21: // ! + case 0x3D: // = + index += 2; + + // !== and === + if (source.charCodeAt(index) === 0x3D) { + ++index; + } + return { + type: Token.Punctuator, + value: source.slice(start, index), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + } + } + + // 4-character punctuator: >>>= + + ch4 = source.substr(index, 4); + + if (ch4 === '>>>=') { + index += 4; + return { + type: Token.Punctuator, + value: ch4, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // 3-character punctuators: === !== >>> <<= >>= + + ch3 = ch4.substr(0, 3); + + if (ch3 === '>>>' || ch3 === '<<=' || ch3 === '>>=') { + index += 3; + return { + type: Token.Punctuator, + value: ch3, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // Other 2-character punctuators: ++ -- << >> && || + ch2 = ch3.substr(0, 2); + + if ((ch1 === ch2[1] && ('+-<>&|'.indexOf(ch1) >= 0)) || ch2 === '=>') { + index += 2; + return { + type: Token.Punctuator, + value: ch2, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // 1-character punctuators: < > = ! + - * % & | ^ / + + if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) { + ++index; + return { + type: Token.Punctuator, + value: ch1, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + // 7.8.3 Numeric Literals + + function scanHexLiteral(start) { + var number = ''; + + while (index < length) { + if (!isHexDigit(source[index])) { + break; + } + number += source[index++]; + } + + if (number.length === 0) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + if (isIdentifierStart(source.charCodeAt(index))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + return { + type: Token.NumericLiteral, + value: parseInt('0x' + number, 16), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + function scanOctalLiteral(start) { + var number = '0' + source[index++]; + while (index < length) { + if (!isOctalDigit(source[index])) { + break; + } + number += source[index++]; + } + + if (isIdentifierStart(source.charCodeAt(index)) || isDecimalDigit(source.charCodeAt(index))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + return { + type: Token.NumericLiteral, + value: parseInt(number, 8), + octal: true, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + function scanNumericLiteral() { + var number, start, ch; + + ch = source[index]; + assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'), + 'Numeric literal must start with a decimal digit or a decimal point'); + + start = index; + number = ''; + if (ch !== '.') { + number = source[index++]; + ch = source[index]; + + // Hex number starts with '0x'. + // Octal number starts with '0'. + if (number === '0') { + if (ch === 'x' || ch === 'X') { + ++index; + return scanHexLiteral(start); + } + if (isOctalDigit(ch)) { + return scanOctalLiteral(start); + } + + // decimal number starts with '0' such as '09' is illegal. + if (ch && isDecimalDigit(ch.charCodeAt(0))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } + + while (isDecimalDigit(source.charCodeAt(index))) { + number += source[index++]; + } + ch = source[index]; + } + + if (ch === '.') { + number += source[index++]; + while (isDecimalDigit(source.charCodeAt(index))) { + number += source[index++]; + } + ch = source[index]; + } + + if (ch === 'e' || ch === 'E') { + number += source[index++]; + + ch = source[index]; + if (ch === '+' || ch === '-') { + number += source[index++]; + } + if (isDecimalDigit(source.charCodeAt(index))) { + while (isDecimalDigit(source.charCodeAt(index))) { + number += source[index++]; + } + } else { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } + + if (isIdentifierStart(source.charCodeAt(index))) { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + return { + type: Token.NumericLiteral, + value: parseFloat(number), + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + // 7.8.4 String Literals + + function scanStringLiteral() { + var str = '', quote, start, ch, code, unescaped, restore, octal = false, startLineNumber, startLineStart; + startLineNumber = lineNumber; + startLineStart = lineStart; + + quote = source[index]; + assert((quote === '\'' || quote === '"'), + 'String literal must starts with a quote'); + + start = index; + ++index; + + while (index < length) { + ch = source[index++]; + + if (ch === quote) { + quote = ''; + break; + } else if (ch === '\\') { + ch = source[index++]; + if (!ch || !isLineTerminator(ch.charCodeAt(0))) { + switch (ch) { + case 'u': + case 'x': + if (source[index] === '{') { + ++index; + str += scanUnicodeCodePointEscape(); + } else { + restore = index; + unescaped = scanHexEscape(ch); + if (unescaped) { + str += unescaped; + } else { + index = restore; + str += ch; + } + } + break; + case 'n': + str += '\n'; + break; + case 'r': + str += '\r'; + break; + case 't': + str += '\t'; + break; + case 'b': + str += '\b'; + break; + case 'f': + str += '\f'; + break; + case 'v': + str += '\x0B'; + break; + + default: + if (isOctalDigit(ch)) { + code = '01234567'.indexOf(ch); + + // \0 is not octal escape sequence + if (code !== 0) { + octal = true; + } + + if (index < length && isOctalDigit(source[index])) { + octal = true; + code = code * 8 + '01234567'.indexOf(source[index++]); + + // 3 digits are only allowed when string starts + // with 0, 1, 2, 3 + if ('0123'.indexOf(ch) >= 0 && + index < length && + isOctalDigit(source[index])) { + code = code * 8 + '01234567'.indexOf(source[index++]); + } + } + str += String.fromCharCode(code); + } else { + str += ch; + } + break; + } + } else { + ++lineNumber; + if (ch === '\r' && source[index] === '\n') { + ++index; + } + lineStart = index; + } + } else if (isLineTerminator(ch.charCodeAt(0))) { + break; + } else { + str += ch; + } + } + + if (quote !== '') { + throwError({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + + return { + type: Token.StringLiteral, + value: str, + octal: octal, + startLineNumber: startLineNumber, + startLineStart: startLineStart, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + function testRegExp(pattern, flags) { + var tmp = pattern, + value; + + if (flags.indexOf('u') >= 0) { + // Replace each astral symbol and every Unicode code point + // escape sequence with a single ASCII symbol to avoid throwing on + // regular expressions that are only valid in combination with the + // `/u` flag. + // Note: replacing with the ASCII symbol `x` might cause false + // negatives in unlikely scenarios. For example, `[\u{61}-b]` is a + // perfectly valid pattern that is equivalent to `[a-b]`, but it + // would be replaced by `[x-b]` which throws an error. + tmp = tmp + .replace(/\\u\{([0-9a-fA-F]+)\}/g, function ($0, $1) { + if (parseInt($1, 16) <= 0x10FFFF) { + return 'x'; + } + throwError({}, Messages.InvalidRegExp); + }) + .replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, 'x'); + } + + // First, detect invalid regular expressions. + try { + value = new RegExp(tmp); + } catch (e) { + throwError({}, Messages.InvalidRegExp); + } + + // Return a regular expression object for this pattern-flag pair, or + // `null` in case the current environment doesn't support the flags it + // uses. + try { + return new RegExp(pattern, flags); + } catch (exception) { + return null; + } + } + + function scanRegExpBody() { + var ch, str, classMarker, terminated, body; + + ch = source[index]; + assert(ch === '/', 'Regular expression literal must start with a slash'); + str = source[index++]; + + classMarker = false; + terminated = false; + while (index < length) { + ch = source[index++]; + str += ch; + if (ch === '\\') { + ch = source[index++]; + // ECMA-262 7.8.5 + if (isLineTerminator(ch.charCodeAt(0))) { + throwError({}, Messages.UnterminatedRegExp); + } + str += ch; + } else if (isLineTerminator(ch.charCodeAt(0))) { + throwError({}, Messages.UnterminatedRegExp); + } else if (classMarker) { + if (ch === ']') { + classMarker = false; + } + } else { + if (ch === '/') { + terminated = true; + break; + } else if (ch === '[') { + classMarker = true; + } + } + } + + if (!terminated) { + throwError({}, Messages.UnterminatedRegExp); + } + + // Exclude leading and trailing slash. + body = str.substr(1, str.length - 2); + return { + value: body, + literal: str + }; + } + + function scanRegExpFlags() { + var ch, str, flags, restore; + + str = ''; + flags = ''; + while (index < length) { + ch = source[index]; + if (!isIdentifierPart(ch.charCodeAt(0))) { + break; + } + + ++index; + if (ch === '\\' && index < length) { + ch = source[index]; + if (ch === 'u') { + ++index; + restore = index; + ch = scanHexEscape('u'); + if (ch) { + flags += ch; + for (str += '\\u'; restore < index; ++restore) { + str += source[restore]; + } + } else { + index = restore; + flags += 'u'; + str += '\\u'; + } + throwErrorTolerant({}, Messages.UnexpectedToken, 'ILLEGAL'); + } else { + str += '\\'; + throwErrorTolerant({}, Messages.UnexpectedToken, 'ILLEGAL'); + } + } else { + flags += ch; + str += ch; + } + } + + return { + value: flags, + literal: str + }; + } + + function scanRegExp() { + var start, body, flags, value; + + lookahead = null; + skipComment(); + start = index; + + body = scanRegExpBody(); + flags = scanRegExpFlags(); + value = testRegExp(body.value, flags.value); + + if (extra.tokenize) { + return { + type: Token.RegularExpression, + value: value, + regex: { + pattern: body.value, + flags: flags.value + }, + lineNumber: lineNumber, + lineStart: lineStart, + start: start, + end: index + }; + } + + return { + literal: body.literal + flags.literal, + value: value, + regex: { + pattern: body.value, + flags: flags.value + }, + start: start, + end: index + }; + } + + function collectRegex() { + var pos, loc, regex, token; + + skipComment(); + + pos = index; + loc = { + start: { + line: lineNumber, + column: index - lineStart + } + }; + + regex = scanRegExp(); + + loc.end = { + line: lineNumber, + column: index - lineStart + }; + + if (!extra.tokenize) { + // Pop the previous token, which is likely '/' or '/=' + if (extra.tokens.length > 0) { + token = extra.tokens[extra.tokens.length - 1]; + if (token.range[0] === pos && token.type === 'Punctuator') { + if (token.value === '/' || token.value === '/=') { + extra.tokens.pop(); + } + } + } + + extra.tokens.push({ + type: 'RegularExpression', + value: regex.literal, + regex: regex.regex, + range: [pos, index], + loc: loc + }); + } + + return regex; + } + + function isIdentifierName(token) { + return token.type === Token.Identifier || + token.type === Token.Keyword || + token.type === Token.BooleanLiteral || + token.type === Token.NullLiteral; + } + + function advanceSlash() { + var prevToken, + checkToken; + // Using the following algorithm: + // https://github.com/mozilla/sweet.js/wiki/design + prevToken = extra.tokens[extra.tokens.length - 1]; + if (!prevToken) { + // Nothing before that: it cannot be a division. + return collectRegex(); + } + if (prevToken.type === 'Punctuator') { + if (prevToken.value === ']') { + return scanPunctuator(); + } + if (prevToken.value === ')') { + checkToken = extra.tokens[extra.openParenToken - 1]; + if (checkToken && + checkToken.type === 'Keyword' && + (checkToken.value === 'if' || + checkToken.value === 'while' || + checkToken.value === 'for' || + checkToken.value === 'with')) { + return collectRegex(); + } + return scanPunctuator(); + } + if (prevToken.value === '}') { + // Dividing a function by anything makes little sense, + // but we have to check for that. + if (extra.tokens[extra.openCurlyToken - 3] && + extra.tokens[extra.openCurlyToken - 3].type === 'Keyword') { + // Anonymous function. + checkToken = extra.tokens[extra.openCurlyToken - 4]; + if (!checkToken) { + return scanPunctuator(); + } + } else if (extra.tokens[extra.openCurlyToken - 4] && + extra.tokens[extra.openCurlyToken - 4].type === 'Keyword') { + // Named function. + checkToken = extra.tokens[extra.openCurlyToken - 5]; + if (!checkToken) { + return collectRegex(); + } + } else { + return scanPunctuator(); + } + return scanPunctuator(); + } + return collectRegex(); + } + if (prevToken.type === 'Keyword' && prevToken.value !== 'this') { + return collectRegex(); + } + return scanPunctuator(); + } + + function advance() { + var ch; + + skipComment(); + + if (index >= length) { + return { + type: Token.EOF, + lineNumber: lineNumber, + lineStart: lineStart, + start: index, + end: index + }; + } + + ch = source.charCodeAt(index); + + if (isIdentifierStart(ch)) { + return scanIdentifier(); + } + + // Very common: ( and ) and ; + if (ch === 0x28 || ch === 0x29 || ch === 0x3B) { + return scanPunctuator(); + } + + // String literal starts with single quote (U+0027) or double quote (U+0022). + if (ch === 0x27 || ch === 0x22) { + return scanStringLiteral(); + } + + + // Dot (.) U+002E can also start a floating-point number, hence the need + // to check the next character. + if (ch === 0x2E) { + if (isDecimalDigit(source.charCodeAt(index + 1))) { + return scanNumericLiteral(); + } + return scanPunctuator(); + } + + if (isDecimalDigit(ch)) { + return scanNumericLiteral(); + } + + // Slash (/) U+002F can also start a regex. + if (extra.tokenize && ch === 0x2F) { + return advanceSlash(); + } + + return scanPunctuator(); + } + + function collectToken() { + var loc, token, value, entry; + + skipComment(); + loc = { + start: { + line: lineNumber, + column: index - lineStart + } + }; + + token = advance(); + loc.end = { + line: lineNumber, + column: index - lineStart + }; + + if (token.type !== Token.EOF) { + value = source.slice(token.start, token.end); + entry = { + type: TokenName[token.type], + value: value, + range: [token.start, token.end], + loc: loc + }; + if (token.regex) { + entry.regex = { + pattern: token.regex.pattern, + flags: token.regex.flags + }; + } + extra.tokens.push(entry); + } + + return token; + } + + function lex() { + var token; + + token = lookahead; + index = token.end; + lineNumber = token.lineNumber; + lineStart = token.lineStart; + + lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance(); + + index = token.end; + lineNumber = token.lineNumber; + lineStart = token.lineStart; + + return token; + } + + function peek() { + var pos, line, start; + + pos = index; + line = lineNumber; + start = lineStart; + lookahead = (typeof extra.tokens !== 'undefined') ? collectToken() : advance(); + index = pos; + lineNumber = line; + lineStart = start; + } + + function Position() { + this.line = lineNumber; + this.column = index - lineStart; + } + + function SourceLocation() { + this.start = new Position(); + this.end = null; + } + + function WrappingSourceLocation(startToken) { + if (startToken.type === Token.StringLiteral) { + this.start = { + line: startToken.startLineNumber, + column: startToken.start - startToken.startLineStart + }; + } else { + this.start = { + line: startToken.lineNumber, + column: startToken.start - startToken.lineStart + }; + } + this.end = null; + } + + function Node() { + // Skip comment. + index = lookahead.start; + if (lookahead.type === Token.StringLiteral) { + lineNumber = lookahead.startLineNumber; + lineStart = lookahead.startLineStart; + } else { + lineNumber = lookahead.lineNumber; + lineStart = lookahead.lineStart; + } + if (extra.range) { + this.range = [index, 0]; + } + if (extra.loc) { + this.loc = new SourceLocation(); + } + } + + function WrappingNode(startToken) { + if (extra.range) { + this.range = [startToken.start, 0]; + } + if (extra.loc) { + this.loc = new WrappingSourceLocation(startToken); + } + } + + WrappingNode.prototype = Node.prototype = { + + finish: function () { + if (extra.range) { + this.range[1] = index; + } + if (extra.loc) { + this.loc.end = new Position(); + if (extra.source) { + this.loc.source = extra.source; + } + } + }, + + finishArrayExpression: function (elements) { + this.type = Syntax.ArrayExpression; + this.elements = elements; + this.finish(); + return this; + }, + + finishAssignmentExpression: function (operator, left, right) { + this.type = Syntax.AssignmentExpression; + this.operator = operator; + this.left = left; + this.right = right; + this.finish(); + return this; + }, + + finishBinaryExpression: function (operator, left, right) { + this.type = (operator === '||' || operator === '&&') ? Syntax.LogicalExpression : Syntax.BinaryExpression; + this.operator = operator; + this.left = left; + this.right = right; + this.finish(); + return this; + }, + + finishCallExpression: function (callee, args) { + this.type = Syntax.CallExpression; + this.callee = callee; + this.arguments = args; + this.finish(); + return this; + }, + + finishConditionalExpression: function (test, consequent, alternate) { + this.type = Syntax.ConditionalExpression; + this.test = test; + this.consequent = consequent; + this.alternate = alternate; + this.finish(); + return this; + }, + + finishExpressionStatement: function (expression) { + this.type = Syntax.ExpressionStatement; + this.expression = expression; + this.finish(); + return this; + }, + + finishIdentifier: function (name) { + this.type = Syntax.Identifier; + this.name = name; + this.finish(); + return this; + }, + + finishLiteral: function (token) { + this.type = Syntax.Literal; + this.value = token.value; + this.raw = source.slice(token.start, token.end); + if (token.regex) { + if (this.raw == '//') { + this.raw = '/(?:)/'; + } + this.regex = token.regex; + } + this.finish(); + return this; + }, + + finishMemberExpression: function (accessor, object, property) { + this.type = Syntax.MemberExpression; + this.computed = accessor === '['; + this.object = object; + this.property = property; + this.finish(); + return this; + }, + + finishObjectExpression: function (properties) { + this.type = Syntax.ObjectExpression; + this.properties = properties; + this.finish(); + return this; + }, + + finishProgram: function (body) { + this.type = Syntax.Program; + this.body = body; + this.finish(); + return this; + }, + + finishProperty: function (kind, key, value) { + this.type = Syntax.Property; + this.key = key; + this.value = value; + this.kind = kind; + this.finish(); + return this; + }, + + finishUnaryExpression: function (operator, argument) { + this.type = Syntax.UnaryExpression; + this.operator = operator; + this.argument = argument; + this.prefix = true; + this.finish(); + return this; + } + }; + + // Return true if there is a line terminator before the next token. + + function peekLineTerminator() { + var pos, line, start, found; + + pos = index; + line = lineNumber; + start = lineStart; + skipComment(); + found = lineNumber !== line; + index = pos; + lineNumber = line; + lineStart = start; + + return found; + } + + // Throw an exception + + function throwError(token, messageFormat) { + var error, + args = Array.prototype.slice.call(arguments, 2), + msg = messageFormat.replace( + /%(\d)/g, + function (whole, index) { + assert(index < args.length, 'Message reference must be in range'); + return args[index]; + } + ); + + if (typeof token.lineNumber === 'number') { + error = new Error('Line ' + token.lineNumber + ': ' + msg); + error.index = token.start; + error.lineNumber = token.lineNumber; + error.column = token.start - lineStart + 1; + } else { + error = new Error('Line ' + lineNumber + ': ' + msg); + error.index = index; + error.lineNumber = lineNumber; + error.column = index - lineStart + 1; + } + + error.description = msg; + throw error; + } + + function throwErrorTolerant() { + try { + throwError.apply(null, arguments); + } catch (e) { + if (extra.errors) { + extra.errors.push(e); + } else { + throw e; + } + } + } + + + // Throw an exception because of the token. + + function throwUnexpected(token) { + if (token.type === Token.EOF) { + throwError(token, Messages.UnexpectedEOS); + } + + if (token.type === Token.NumericLiteral) { + throwError(token, Messages.UnexpectedNumber); + } + + if (token.type === Token.StringLiteral) { + throwError(token, Messages.UnexpectedString); + } + + if (token.type === Token.Identifier) { + throwError(token, Messages.UnexpectedIdentifier); + } + + if (token.type === Token.Keyword) { + if (isFutureReservedWord(token.value)) { + throwError(token, Messages.UnexpectedReserved); + } else if (strict && isStrictModeReservedWord(token.value)) { + throwErrorTolerant(token, Messages.StrictReservedWord); + return; + } + throwError(token, Messages.UnexpectedToken, token.value); + } + + // BooleanLiteral, NullLiteral, or Punctuator. + throwError(token, Messages.UnexpectedToken, token.value); + } + + // Expect the next token to match the specified punctuator. + // If not, an exception will be thrown. + + function expect(value) { + var token = lex(); + if (token.type !== Token.Punctuator || token.value !== value) { + throwUnexpected(token); + } + } + + /** + * @name expectTolerant + * @description Quietly expect the given token value when in tolerant mode, otherwise delegates + * to expect(value) + * @param {String} value The value we are expecting the lookahead token to have + * @since 2.0 + */ + function expectTolerant(value) { + if (extra.errors) { + var token = lookahead; + if (token.type !== Token.Punctuator && token.value !== value) { + throwErrorTolerant(token, Messages.UnexpectedToken, token.value); + } else { + lex(); + } + } else { + expect(value); + } + } + + // Return true if the next token matches the specified punctuator. + + function match(value) { + return lookahead.type === Token.Punctuator && lookahead.value === value; + } + + // Return true if the next token matches the specified keyword + + function matchKeyword(keyword) { + return lookahead.type === Token.Keyword && lookahead.value === keyword; + } + + function consumeSemicolon() { + var line; + + // Catch the very common case first: immediately a semicolon (U+003B). + if (source.charCodeAt(index) === 0x3B || match(';')) { + lex(); + return; + } + + line = lineNumber; + skipComment(); + if (lineNumber !== line) { + return; + } + + if (lookahead.type !== Token.EOF && !match('}')) { + throwUnexpected(lookahead); + } + } + + // 11.1.4 Array Initialiser + + function parseArrayInitialiser() { + var elements = [], node = new Node(); + + expect('['); + + while (!match(']')) { + if (match(',')) { + lex(); + elements.push(null); + } else { + elements.push(parseAssignmentExpression()); + + if (!match(']')) { + expect(','); + } + } + } + + lex(); + + return node.finishArrayExpression(elements); + } + + // 11.1.5 Object Initialiser + + function parseObjectPropertyKey() { + var token, node = new Node(); + + token = lex(); + + // Note: This function is called only from parseObjectProperty(), where + // EOF and Punctuator tokens are already filtered out. + + if (token.type === Token.StringLiteral || token.type === Token.NumericLiteral) { + if (strict && token.octal) { + throwErrorTolerant(token, Messages.StrictOctalLiteral); + } + return node.finishLiteral(token); + } + + return node.finishIdentifier(token.value); + } + + function parseObjectProperty() { + var token, key, id, value, node = new Node(); + + token = lookahead; + + if (token.type === Token.Identifier) { + id = parseObjectPropertyKey(); + expect(':'); + value = parseAssignmentExpression(); + return node.finishProperty('init', id, value); + } + if (token.type === Token.EOF || token.type === Token.Punctuator) { + throwUnexpected(token); + } else { + key = parseObjectPropertyKey(); + expect(':'); + value = parseAssignmentExpression(); + return node.finishProperty('init', key, value); + } + } + + function parseObjectInitialiser() { + var properties = [], property, name, key, kind, map = {}, toString = String, node = new Node(); + + expect('{'); + + while (!match('}')) { + property = parseObjectProperty(); + + if (property.key.type === Syntax.Identifier) { + name = property.key.name; + } else { + name = toString(property.key.value); + } + kind = (property.kind === 'init') ? PropertyKind.Data : (property.kind === 'get') ? PropertyKind.Get : PropertyKind.Set; + + key = '$' + name; + if (Object.prototype.hasOwnProperty.call(map, key)) { + if (map[key] === PropertyKind.Data) { + if (strict && kind === PropertyKind.Data) { + throwErrorTolerant({}, Messages.StrictDuplicateProperty); + } else if (kind !== PropertyKind.Data) { + throwErrorTolerant({}, Messages.AccessorDataProperty); + } + } else { + if (kind === PropertyKind.Data) { + throwErrorTolerant({}, Messages.AccessorDataProperty); + } else if (map[key] & kind) { + throwErrorTolerant({}, Messages.AccessorGetSet); + } + } + map[key] |= kind; + } else { + map[key] = kind; + } + + properties.push(property); + + if (!match('}')) { + expectTolerant(','); + } + } + + expect('}'); + + return node.finishObjectExpression(properties); + } + + // 11.1.6 The Grouping Operator + + function parseGroupExpression() { + var expr; + + expect('('); + + ++state.parenthesisCount; + + expr = parseExpression(); + + expect(')'); + + return expr; + } + + + // 11.1 Primary Expressions + + var legalKeywords = {"if":1, "this":1}; + + function parsePrimaryExpression() { + var type, token, expr, node; + + if (match('(')) { + return parseGroupExpression(); + } + + if (match('[')) { + return parseArrayInitialiser(); + } + + if (match('{')) { + return parseObjectInitialiser(); + } + + type = lookahead.type; + node = new Node(); + + if (type === Token.Identifier || legalKeywords[lookahead.value]) { + expr = node.finishIdentifier(lex().value); + } else if (type === Token.StringLiteral || type === Token.NumericLiteral) { + if (strict && lookahead.octal) { + throwErrorTolerant(lookahead, Messages.StrictOctalLiteral); + } + expr = node.finishLiteral(lex()); + } else if (type === Token.Keyword) { + throw new Error("Disabled."); + } else if (type === Token.BooleanLiteral) { + token = lex(); + token.value = (token.value === 'true'); + expr = node.finishLiteral(token); + } else if (type === Token.NullLiteral) { + token = lex(); + token.value = null; + expr = node.finishLiteral(token); + } else if (match('/') || match('/=')) { + if (typeof extra.tokens !== 'undefined') { + expr = node.finishLiteral(collectRegex()); + } else { + expr = node.finishLiteral(scanRegExp()); + } + peek(); + } else { + throwUnexpected(lex()); + } + + return expr; + } + + // 11.2 Left-Hand-Side Expressions + + function parseArguments() { + var args = []; + + expect('('); + + if (!match(')')) { + while (index < length) { + args.push(parseAssignmentExpression()); + if (match(')')) { + break; + } + expectTolerant(','); + } + } + + expect(')'); + + return args; + } + + function parseNonComputedProperty() { + var token, node = new Node(); + + token = lex(); + + if (!isIdentifierName(token)) { + throwUnexpected(token); + } + + return node.finishIdentifier(token.value); + } + + function parseNonComputedMember() { + expect('.'); + + return parseNonComputedProperty(); + } + + function parseComputedMember() { + var expr; + + expect('['); + + expr = parseExpression(); + + expect(']'); + + return expr; + } + + function parseLeftHandSideExpressionAllowCall() { + var expr, args, property, startToken, previousAllowIn = state.allowIn; + + startToken = lookahead; + state.allowIn = true; + expr = parsePrimaryExpression(); + + for (;;) { + if (match('.')) { + property = parseNonComputedMember(); + expr = new WrappingNode(startToken).finishMemberExpression('.', expr, property); + } else if (match('(')) { + args = parseArguments(); + expr = new WrappingNode(startToken).finishCallExpression(expr, args); + } else if (match('[')) { + property = parseComputedMember(); + expr = new WrappingNode(startToken).finishMemberExpression('[', expr, property); + } else { + break; + } + } + state.allowIn = previousAllowIn; + + return expr; + } + + // 11.3 Postfix Expressions + + function parsePostfixExpression() { + var expr = parseLeftHandSideExpressionAllowCall(); + + if (lookahead.type === Token.Punctuator) { + if ((match('++') || match('--')) && !peekLineTerminator()) { + throw new Error("Disabled."); + } + } + + return expr; + } + + // 11.4 Unary Operators + + function parseUnaryExpression() { + var token, expr, startToken; + + if (lookahead.type !== Token.Punctuator && lookahead.type !== Token.Keyword) { + expr = parsePostfixExpression(); + } else if (match('++') || match('--')) { + throw new Error("Disabled."); + } else if (match('+') || match('-') || match('~') || match('!')) { + startToken = lookahead; + token = lex(); + expr = parseUnaryExpression(); + expr = new WrappingNode(startToken).finishUnaryExpression(token.value, expr); + } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) { + throw new Error("Disabled."); + } else { + expr = parsePostfixExpression(); + } + + return expr; + } + + function binaryPrecedence(token, allowIn) { + var prec = 0; + + if (token.type !== Token.Punctuator && token.type !== Token.Keyword) { + return 0; + } + + switch (token.value) { + case '||': + prec = 1; + break; + + case '&&': + prec = 2; + break; + + case '|': + prec = 3; + break; + + case '^': + prec = 4; + break; + + case '&': + prec = 5; + break; + + case '==': + case '!=': + case '===': + case '!==': + prec = 6; + break; + + case '<': + case '>': + case '<=': + case '>=': + case 'instanceof': + prec = 7; + break; + + case 'in': + prec = allowIn ? 7 : 0; + break; + + case '<<': + case '>>': + case '>>>': + prec = 8; + break; + + case '+': + case '-': + prec = 9; + break; + + case '*': + case '/': + case '%': + prec = 11; + break; + + default: + break; + } + + return prec; + } + + // 11.5 Multiplicative Operators + // 11.6 Additive Operators + // 11.7 Bitwise Shift Operators + // 11.8 Relational Operators + // 11.9 Equality Operators + // 11.10 Binary Bitwise Operators + // 11.11 Binary Logical Operators + + function parseBinaryExpression() { + var marker, markers, expr, token, prec, stack, right, operator, left, i; + + marker = lookahead; + left = parseUnaryExpression(); + + token = lookahead; + prec = binaryPrecedence(token, state.allowIn); + if (prec === 0) { + return left; + } + token.prec = prec; + lex(); + + markers = [marker, lookahead]; + right = parseUnaryExpression(); + + stack = [left, token, right]; + + while ((prec = binaryPrecedence(lookahead, state.allowIn)) > 0) { + + // Reduce: make a binary expression from the three topmost entries. + while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) { + right = stack.pop(); + operator = stack.pop().value; + left = stack.pop(); + markers.pop(); + expr = new WrappingNode(markers[markers.length - 1]).finishBinaryExpression(operator, left, right); + stack.push(expr); + } + + // Shift. + token = lex(); + token.prec = prec; + stack.push(token); + markers.push(lookahead); + expr = parseUnaryExpression(); + stack.push(expr); + } + + // Final reduce to clean-up the stack. + i = stack.length - 1; + expr = stack[i]; + markers.pop(); + while (i > 1) { + expr = new WrappingNode(markers.pop()).finishBinaryExpression(stack[i - 1].value, stack[i - 2], expr); + i -= 2; + } + + return expr; + } + + // 11.12 Conditional Operator + + function parseConditionalExpression() { + var expr, previousAllowIn, consequent, alternate, startToken; + + startToken = lookahead; + + expr = parseBinaryExpression(); + + if (match('?')) { + lex(); + previousAllowIn = state.allowIn; + state.allowIn = true; + consequent = parseAssignmentExpression(); + state.allowIn = previousAllowIn; + expect(':'); + alternate = parseAssignmentExpression(); + + expr = new WrappingNode(startToken).finishConditionalExpression(expr, consequent, alternate); + } + + return expr; + } + + // 11.13 Assignment Operators + + function parseAssignmentExpression() { + var oldParenthesisCount, token, expr, startToken; + + oldParenthesisCount = state.parenthesisCount; + + startToken = lookahead; + token = lookahead; + + expr = parseConditionalExpression(); + + return expr; + } + + // 11.14 Comma Operator + + function parseExpression() { + var expr = parseAssignmentExpression(); + + if (match(',')) { + throw new Error("Disabled."); // no sequence expressions + } + + return expr; + } + + // 12.4 Expression Statement + + function parseExpressionStatement(node) { + var expr = parseExpression(); + consumeSemicolon(); + return node.finishExpressionStatement(expr); + } + + // 12 Statements + + function parseStatement() { + var type = lookahead.type, + expr, + node; + + if (type === Token.EOF) { + throwUnexpected(lookahead); + } + + if (type === Token.Punctuator && lookahead.value === '{') { + throw new Error("Disabled."); // block statement + } + + node = new Node(); + + if (type === Token.Punctuator) { + switch (lookahead.value) { + case ';': + throw new Error("Disabled."); // empty statement + case '(': + return parseExpressionStatement(node); + default: + break; + } + } else if (type === Token.Keyword) { + throw new Error("Disabled."); // keyword + } + + expr = parseExpression(); + consumeSemicolon(); + return node.finishExpressionStatement(expr); + } + + // 14 Program + + function parseSourceElement() { + if (lookahead.type === Token.Keyword) { + switch (lookahead.value) { + case 'const': + case 'let': + throw new Error("Disabled."); + case 'function': + throw new Error("Disabled."); + default: + return parseStatement(); + } + } + + if (lookahead.type !== Token.EOF) { + return parseStatement(); + } + } + + function parseSourceElements() { + var sourceElement, sourceElements = [], token, directive, firstRestricted; + + while (index < length) { + token = lookahead; + if (token.type !== Token.StringLiteral) { + break; + } + + sourceElement = parseSourceElement(); + sourceElements.push(sourceElement); + if (sourceElement.expression.type !== Syntax.Literal) { + // this is not directive + break; + } + directive = source.slice(token.start + 1, token.end - 1); + if (directive === 'use strict') { + strict = true; + if (firstRestricted) { + throwErrorTolerant(firstRestricted, Messages.StrictOctalLiteral); + } + } else { + if (!firstRestricted && token.octal) { + firstRestricted = token; + } + } + } + + while (index < length) { + sourceElement = parseSourceElement(); + if (typeof sourceElement === 'undefined') { + break; + } + sourceElements.push(sourceElement); + } + return sourceElements; + } + + function parseProgram() { + var body, node; + + skipComment(); + peek(); + node = new Node(); + strict = true; // assume strict + + body = parseSourceElements(); + return node.finishProgram(body); + } + + function filterTokenLocation() { + var i, entry, token, tokens = []; + + for (i = 0; i < extra.tokens.length; ++i) { + entry = extra.tokens[i]; + token = { + type: entry.type, + value: entry.value + }; + if (entry.regex) { + token.regex = { + pattern: entry.regex.pattern, + flags: entry.regex.flags + }; + } + if (extra.range) { + token.range = entry.range; + } + if (extra.loc) { + token.loc = entry.loc; + } + tokens.push(token); + } + + extra.tokens = tokens; + } + + function tokenize(code, options) { + var toString, + tokens; + + toString = String; + if (typeof code !== 'string' && !(code instanceof String)) { + code = toString(code); + } + + source = code; + index = 0; + lineNumber = (source.length > 0) ? 1 : 0; + lineStart = 0; + length = source.length; + lookahead = null; + state = { + allowIn: true, + labelSet: {}, + inFunctionBody: false, + inIteration: false, + inSwitch: false, + lastCommentStart: -1 + }; + + extra = {}; + + // Options matching. + options = options || {}; + + // Of course we collect tokens here. + options.tokens = true; + extra.tokens = []; + extra.tokenize = true; + // The following two fields are necessary to compute the Regex tokens. + extra.openParenToken = -1; + extra.openCurlyToken = -1; + + extra.range = (typeof options.range === 'boolean') && options.range; + extra.loc = (typeof options.loc === 'boolean') && options.loc; + + if (typeof options.tolerant === 'boolean' && options.tolerant) { + extra.errors = []; + } + + try { + peek(); + if (lookahead.type === Token.EOF) { + return extra.tokens; + } + + lex(); + while (lookahead.type !== Token.EOF) { + try { + lex(); + } catch (lexError) { + if (extra.errors) { + extra.errors.push(lexError); + // We have to break on the first error + // to avoid infinite loops. + break; + } else { + throw lexError; + } + } + } + + filterTokenLocation(); + tokens = extra.tokens; + if (typeof extra.errors !== 'undefined') { + tokens.errors = extra.errors; + } + } catch (e) { + throw e; + } finally { + extra = {}; + } + return tokens; + } + + function parse(code, options) { + var program, toString; + + toString = String; + if (typeof code !== 'string' && !(code instanceof String)) { + code = toString(code); + } + + source = code; + index = 0; + lineNumber = (source.length > 0) ? 1 : 0; + lineStart = 0; + length = source.length; + lookahead = null; + state = { + allowIn: true, + labelSet: {}, + parenthesisCount: 0, + inFunctionBody: false, + inIteration: false, + inSwitch: false, + lastCommentStart: -1 + }; + + extra = {}; + if (typeof options !== 'undefined') { + extra.range = (typeof options.range === 'boolean') && options.range; + extra.loc = (typeof options.loc === 'boolean') && options.loc; + + if (extra.loc && options.source !== null && options.source !== undefined) { + extra.source = toString(options.source); + } + + if (typeof options.tokens === 'boolean' && options.tokens) { + extra.tokens = []; + } + if (typeof options.tolerant === 'boolean' && options.tolerant) { + extra.errors = []; + } + } + + try { + program = parseProgram(); + if (typeof extra.tokens !== 'undefined') { + filterTokenLocation(); + program.tokens = extra.tokens; + } + if (typeof extra.errors !== 'undefined') { + program.errors = extra.errors; + } + } catch (e) { + throw e; + } finally { + extra = {}; + } + + return program; + } + + return { + tokenize: tokenize, + parse: parse + }; + + })(); +},{}],47:[function(require,module,exports){ + var ts = Date.now(); + + function write(msg) { + msg = '[Vega Log] ' + msg; + console.log(msg); + } + + function error(msg) { + msg = '[Vega Err] ' + msg; + console.error(msg); + } + + function debug(input, args) { + if (!debug.enable) return; + var log = Function.prototype.bind.call(console.log, console); + var state = { + prevTime: Date.now() - ts, + stamp: input.stamp + }; + + if (input.add) { + state.add = input.add.length; + state.mod = input.mod.length; + state.rem = input.rem.length; + state.reflow = !!input.reflow; + } + + log.apply(console, (args.push(JSON.stringify(state)), args)); + ts = Date.now(); + } + + module.exports = { + log: write, + error: error, + debug: (debug.enable = false, debug) + }; + +},{}],48:[function(require,module,exports){ + module.exports = { + path: require('./path'), + render: require('./render'), + Item: require('./util/Item'), + bound: require('./util/bound'), + Bounds: require('./util/Bounds'), + canvas: require('./util/canvas'), + Gradient: require('./util/Gradient'), + toJSON: require('./util/scene').toJSON, + fromJSON: require('./util/scene').fromJSON + }; +},{"./path":50,"./render":70,"./util/Bounds":76,"./util/Gradient":78,"./util/Item":80,"./util/bound":81,"./util/canvas":82,"./util/scene":84}],49:[function(require,module,exports){ + var segmentCache = {}, + bezierCache = {}, + join = [].join; + +// Copied from Inkscape svgtopdf, thanks! + function segments(x, y, rx, ry, large, sweep, rotateX, ox, oy) { + var key = join.call(arguments); + if (segmentCache[key]) { + return segmentCache[key]; + } + + var th = rotateX * (Math.PI/180); + var sin_th = Math.sin(th); + var cos_th = Math.cos(th); + rx = Math.abs(rx); + ry = Math.abs(ry); + var px = cos_th * (ox - x) * 0.5 + sin_th * (oy - y) * 0.5; + var py = cos_th * (oy - y) * 0.5 - sin_th * (ox - x) * 0.5; + var pl = (px*px) / (rx*rx) + (py*py) / (ry*ry); + if (pl > 1) { + pl = Math.sqrt(pl); + rx *= pl; + ry *= pl; + } + + var a00 = cos_th / rx; + var a01 = sin_th / rx; + var a10 = (-sin_th) / ry; + var a11 = (cos_th) / ry; + var x0 = a00 * ox + a01 * oy; + var y0 = a10 * ox + a11 * oy; + var x1 = a00 * x + a01 * y; + var y1 = a10 * x + a11 * y; + + var d = (x1-x0) * (x1-x0) + (y1-y0) * (y1-y0); + var sfactor_sq = 1 / d - 0.25; + if (sfactor_sq < 0) sfactor_sq = 0; + var sfactor = Math.sqrt(sfactor_sq); + if (sweep == large) sfactor = -sfactor; + var xc = 0.5 * (x0 + x1) - sfactor * (y1-y0); + var yc = 0.5 * (y0 + y1) + sfactor * (x1-x0); + + var th0 = Math.atan2(y0-yc, x0-xc); + var th1 = Math.atan2(y1-yc, x1-xc); + + var th_arc = th1-th0; + if (th_arc < 0 && sweep === 1){ + th_arc += 2 * Math.PI; + } else if (th_arc > 0 && sweep === 0) { + th_arc -= 2 * Math.PI; + } + + var segs = Math.ceil(Math.abs(th_arc / (Math.PI * 0.5 + 0.001))); + var result = []; + for (var i=0; i len) { + for (j=1, m=parsed.length; j=0;) { + if (h[i].type !== type) continue; + if (!handler || h[i].handler === handler) h.splice(i, 1); + } + return this; + }; + + prototype.pickEvent = function(evt) { + var rect = this._canvas.getBoundingClientRect(), + pad = this._padding, x, y; + return this.pick(this._scene, + x = (evt.clientX - rect.left), + y = (evt.clientY - rect.top), + x - pad.left, y - pad.top); + }; + +// find the scenegraph item at the current mouse position +// x, y -- the absolute x, y mouse coordinates on the canvas element +// gx, gy -- the relative coordinates within the current group + prototype.pick = function(scene, x, y, gx, gy) { + var g = this.context(), + mark = marks[scene.marktype]; + return mark.pick.call(this, g, scene, x, y, gx, gy); + }; + + module.exports = CanvasHandler; + +},{"../../util/dom":83,"../Handler":53,"./marks":62}],56:[function(require,module,exports){ + var DOM = require('../../util/dom'), + Bounds = require('../../util/Bounds'), + ImageLoader = require('../../util/ImageLoader'), + Canvas = require('../../util/canvas'), + Renderer = require('../Renderer'), + marks = require('./marks'); + + function CanvasRenderer(loadConfig) { + Renderer.call(this); + this._loader = new ImageLoader(loadConfig); + } + + CanvasRenderer.RETINA = true; + + var base = Renderer.prototype; + var prototype = (CanvasRenderer.prototype = Object.create(base)); + prototype.constructor = CanvasRenderer; + + prototype.initialize = function(el, width, height, padding) { + this._canvas = Canvas.instance(width, height); + if (el) { + DOM.clear(el, 0).appendChild(this._canvas); + this._canvas.setAttribute('class', 'marks'); + } + return base.initialize.call(this, el, width, height, padding); + }; + + prototype.resize = function(width, height, padding) { + base.resize.call(this, width, height, padding); + Canvas.resize(this._canvas, this._width, this._height, + this._padding, CanvasRenderer.RETINA); + return this; + }; + + prototype.canvas = function() { + return this._canvas; + }; + + prototype.context = function() { + return this._canvas ? this._canvas.getContext('2d') : null; + }; + + prototype.pendingImages = function() { + return this._loader.pending(); + }; + + function clipToBounds(g, items) { + if (!items) return null; + + var b = new Bounds(), i, n, item, mark, group; + for (i=0, n=items.length; i 0) { + if (group.fill && util.fill(g, group, opac)) { + g.fillRect(gx, gy, w, h); + } + if (group.stroke && util.stroke(g, group, opac)) { + g.strokeRect(gx, gy, w, h); + } + } + } + + // setup graphics context + g.save(); + g.translate(gx, gy); + if (group.clip) { + g.beginPath(); + g.rect(0, 0, w, h); + g.clip(); + } + if (bounds) bounds.translate(-gx, -gy); + + // draw group contents + for (j=0, m=axes.length; j=0;) { + group = groups[i]; + + // first hit test against bounding box + // if a group is clipped, that should be handled by the bounds check. + b = group.bounds; + if (b && !b.contains(gx, gy)) continue; + + // passed bounds check, so test sub-groups + axes = group.axisItems || EMPTY; + items = group.items || EMPTY; + legends = group.legendItems || EMPTY; + dx = (group.x || 0); + dy = (group.y || 0); + + g.save(); + g.translate(dx, dy); + dx = gx - dx; + dy = gy - dy; + for (j=legends.length; --j>=0;) { + subscene = legends[j]; + if (subscene.interactive !== false) { + hits = this.pick(subscene, x, y, dx, dy); + if (hits) { g.restore(); return hits; } + } + } + for (j=axes.length; --j>=0;) { + subscene = axes[j]; + if (subscene.interactive !== false && subscene.layer !== 'back') { + hits = this.pick(subscene, x, y, dx, dy); + if (hits) { g.restore(); return hits; } + } + } + for (j=items.length; --j>=0;) { + subscene = items[j]; + if (subscene.interactive !== false) { + hits = this.pick(subscene, x, y, dx, dy); + if (hits) { g.restore(); return hits; } + } + } + for (j=axes.length; --j>=0;) { + subscene = axes[j]; + if (subscene.interative !== false && subscene.layer === 'back') { + hits = this.pick(subscene, x, y, dx, dy); + if (hits) { g.restore(); return hits; } + } + } + g.restore(); + + if (scene.interactive !== false && (group.fill || group.stroke) && + dx >= 0 && dx <= group.width && dy >= 0 && dy <= group.height) { + return group; + } + } + + return null; + } + + module.exports = { + draw: draw, + pick: pick + }; + +},{"./util":69}],61:[function(require,module,exports){ + var util = require('./util'); + + function draw(g, scene, bounds) { + if (!scene.items || !scene.items.length) return; + + var renderer = this, + items = scene.items, o; + + for (var i=0, len=items.length; i= 0;) { + o = scene.items[i]; b = o.bounds; + // first hit test against bounding box + if ((b && !b.contains(gx, gy)) || !b) continue; + // if in bounding box, perform more careful test + if (test(g, o, x, y, gx, gy)) return o; + } + return null; + }; + } + + function testPath(path, filled) { + return function(g, o, x, y) { + var item = Array.isArray(o) ? o[0] : o, + fill = (filled == null) ? item.fill : filled, + stroke = item.stroke && g.isPointInStroke, lw, lc; + + if (stroke) { + lw = item.strokeWidth; + lc = item.strokeCap; + g.lineWidth = lw != null ? lw : 1; + g.lineCap = lc != null ? lc : 'butt'; + } + + return path(g, o) ? false : + (fill && g.isPointInPath(x, y)) || + (stroke && g.isPointInStroke(x, y)); + }; + } + + function pickPath(path) { + return pick(testPath(path)); + } + + function fill(g, o, opacity) { + opacity *= (o.fillOpacity==null ? 1 : o.fillOpacity); + if (opacity > 0) { + g.globalAlpha = opacity; + g.fillStyle = color(g, o, o.fill); + return true; + } else { + return false; + } + } + + function stroke(g, o, opacity) { + var lw = (lw = o.strokeWidth) != null ? lw : 1, lc; + if (lw <= 0) return false; + + opacity *= (o.strokeOpacity==null ? 1 : o.strokeOpacity); + if (opacity > 0) { + g.globalAlpha = opacity; + g.strokeStyle = color(g, o, o.stroke); + g.lineWidth = lw; + g.lineCap = (lc = o.strokeCap) != null ? lc : 'butt'; + g.vgLineDash(o.strokeDash || null); + g.vgLineDashOffset(o.strokeDashOffset || 0); + return true; + } else { + return false; + } + } + + function color(g, o, value) { + return (value.id) ? + gradient(g, value, o.bounds) : + value; + } + + function gradient(g, p, b) { + var w = b.width(), + h = b.height(), + x1 = b.x1 + p.x1 * w, + y1 = b.y1 + p.y1 * h, + x2 = b.x1 + p.x2 * w, + y2 = b.y1 + p.y2 * h, + grad = g.createLinearGradient(x1, y1, x2, y2), + stop = p.stops, + i, n; + + for (i=0, n=stop.length; i=0;) { + if (h[i].type === type && !handler || h[i].handler === handler) { + svg.removeEventListener(name, h[i].listener); + h.splice(i, 1); + } + } + return this; + }; + + module.exports = SVGHandler; + +},{"../../util/dom":83,"../Handler":53}],72:[function(require,module,exports){ + var ImageLoader = require('../../util/ImageLoader'), + Renderer = require('../Renderer'), + text = require('../../util/text'), + DOM = require('../../util/dom'), + SVG = require('../../util/svg'), + ns = SVG.metadata.xmlns, + marks = require('./marks'); + + function SVGRenderer(loadConfig) { + Renderer.call(this); + this._loader = new ImageLoader(loadConfig); + this._dirtyID = 0; + } + + var base = Renderer.prototype; + var prototype = (SVGRenderer.prototype = Object.create(base)); + prototype.constructor = SVGRenderer; + + prototype.initialize = function(el, width, height, padding) { + if (el) { + this._svg = DOM.child(el, 0, 'svg', ns, 'marks'); + DOM.clear(el, 1); + // set the svg root group + this._root = DOM.child(this._svg, 0, 'g', ns); + DOM.clear(this._svg, 1); + } + + // create the svg definitions cache + this._defs = { + clip_id: 1, + gradient: {}, + clipping: {} + }; + + // set background color if defined + this.background(this._bgcolor); + + return base.initialize.call(this, el, width, height, padding); + }; + + prototype.background = function(bgcolor) { + if (arguments.length && this._svg) { + this._svg.style.setProperty('background-color', bgcolor); + } + return base.background.apply(this, arguments); + }; + + prototype.resize = function(width, height, padding) { + base.resize.call(this, width, height, padding); + + if (this._svg) { + var w = this._width, + h = this._height, + p = this._padding; + + this._svg.setAttribute('width', w + p.left + p.right); + this._svg.setAttribute('height', h + p.top + p.bottom); + + this._root.setAttribute('transform', 'translate('+p.left+','+p.top+')'); + } + + return this; + }; + + prototype.svg = function() { + if (!this._svg) return null; + + var attr = { + 'class': 'marks', + 'width': this._width + this._padding.left + this._padding.right, + 'height': this._height + this._padding.top + this._padding.bottom, + }; + for (var key in SVG.metadata) { + attr[key] = SVG.metadata[key]; + } + + return DOM.openTag('svg', attr) + this._svg.innerHTML + DOM.closeTag('svg'); + }; + + prototype.imageURL = function(url) { + return this._loader.imageURL(url); + }; + + +// -- Render entry point -- + + prototype.render = function(scene, items) { + if (this._dirtyCheck(items)) { + if (this._dirtyAll) this._resetDefs(); + this.draw(this._root, scene, -1); + DOM.clear(this._root, 1); + } + this.updateDefs(); + return this; + }; + + prototype.draw = function(el, scene, index) { + this.drawMark(el, scene, index, marks[scene.marktype]); + }; + + +// -- Manage SVG definitions ('defs') block -- + + prototype.updateDefs = function() { + var svg = this._svg, + defs = this._defs, + el = defs.el, + index = 0, id; + + for (id in defs.gradient) { + if (!el) el = (defs.el = DOM.child(svg, 0, 'defs', ns)); + updateGradient(el, defs.gradient[id], index++); + } + + for (id in defs.clipping) { + if (!el) el = (defs.el = DOM.child(svg, 0, 'defs', ns)); + updateClipping(el, defs.clipping[id], index++); + } + + // clean-up + if (el) { + if (index === 0) { + svg.removeChild(el); + defs.el = null; + } else { + DOM.clear(el, index); + } + } + }; + + function updateGradient(el, grad, index) { + var i, n, stop; + + el = DOM.child(el, index, 'linearGradient', ns); + el.setAttribute('id', grad.id); + el.setAttribute('x1', grad.x1); + el.setAttribute('x2', grad.x2); + el.setAttribute('y1', grad.y1); + el.setAttribute('y2', grad.y2); + + for (i=0, n=grad.stops.length; i 0) ? openTag('defs') + defs + closeTag('defs') : ''; + }; + + prototype.imageURL = function(url) { + return this._loader.imageURL(url); + }; + + var object; + + function emit(name, value, ns, prefixed) { + object[prefixed || name] = value; + } + + prototype.attributes = function(attr, item) { + object = {}; + attr(emit, item, this); + return object; + }; + + prototype.mark = function(scene) { + var mdef = MARKS[scene.marktype], + tag = mdef.tag, + attr = mdef.attr, + nest = mdef.nest || false, + data = nest ? + (scene.items && scene.items.length ? [scene.items[0]] : []) : + (scene.items || []), + defs = this._defs, + str = '', + style, i, item; + + if (tag !== 'g' && scene.interactive === false) { + style = 'style="pointer-events: none;"'; + } + + // render opening group tag + str += openTag('g', { + 'class': DOM.cssClass(scene) + }, style); + + // render contained elements + for (i=0; i/g, '>'); + } + + module.exports = SVGStringRenderer; + +},{"../../util/ImageLoader":79,"../../util/dom":83,"../../util/svg":85,"../../util/text":86,"../Renderer":54,"./marks":75}],74:[function(require,module,exports){ + module.exports = { + Handler: require('./SVGHandler'), + Renderer: require('./SVGRenderer'), + string: { + Renderer : require('./SVGStringRenderer') + } + }; +},{"./SVGHandler":71,"./SVGRenderer":72,"./SVGStringRenderer":73}],75:[function(require,module,exports){ + var text = require('../../util/text'), + SVG = require('../../util/svg'), + textAlign = SVG.textAlign, + path = SVG.path; + + function translateItem(o) { + return translate(o.x || 0, o.y || 0); + } + + function translate(x, y) { + return 'translate(' + x + ',' + y + ')'; + } + + module.exports = { + arc: { + tag: 'path', + type: 'arc', + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('d', path.arc(o)); + } + }, + area: { + tag: 'path', + type: 'area', + nest: true, + attr: function(emit, o) { + var items = o.mark.items; + if (items.length) emit('d', path.area(items)); + } + }, + group: { + tag: 'g', + type: 'group', + attr: function(emit, o, renderer) { + var id = null, defs, c; + emit('transform', translateItem(o)); + if (o.clip) { + defs = renderer._defs; + id = o.clip_id || (o.clip_id = 'clip' + defs.clip_id++); + c = defs.clipping[id] || (defs.clipping[id] = {id: id}); + c.width = o.width || 0; + c.height = o.height || 0; + } + emit('clip-path', id ? ('url(#' + id + ')') : null); + }, + background: function(emit, o) { + emit('class', 'background'); + emit('width', o.width || 0); + emit('height', o.height || 0); + } + }, + image: { + tag: 'image', + type: 'image', + attr: function(emit, o, renderer) { + var x = o.x || 0, + y = o.y || 0, + w = o.width || 0, + h = o.height || 0, + url = renderer.imageURL(o.url); + + x = x - (o.align === 'center' ? w/2 : o.align === 'right' ? w : 0); + y = y - (o.baseline === 'middle' ? h/2 : o.baseline === 'bottom' ? h : 0); + + emit('href', url, 'http://www.w3.org/1999/xlink', 'xlink:href'); + emit('transform', translate(x, y)); + emit('width', w); + emit('height', h); + } + }, + line: { + tag: 'path', + type: 'line', + nest: true, + attr: function(emit, o) { + var items = o.mark.items; + if (items.length) emit('d', path.line(items)); + } + }, + path: { + tag: 'path', + type: 'path', + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('d', o.path); + } + }, + rect: { + tag: 'rect', + type: 'rect', + nest: false, + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('width', o.width || 0); + emit('height', o.height || 0); + } + }, + rule: { + tag: 'line', + type: 'rule', + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('x2', o.x2 != null ? o.x2 - (o.x||0) : 0); + emit('y2', o.y2 != null ? o.y2 - (o.y||0) : 0); + } + }, + symbol: { + tag: 'path', + type: 'symbol', + attr: function(emit, o) { + emit('transform', translateItem(o)); + emit('d', path.symbol(o)); + } + }, + text: { + tag: 'text', + type: 'text', + nest: false, + attr: function(emit, o) { + var dx = (o.dx || 0), + dy = (o.dy || 0) + text.offset(o), + x = (o.x || 0), + y = (o.y || 0), + a = o.angle || 0, + r = o.radius || 0, t; + + if (r) { + t = (o.theta || 0) - Math.PI/2; + x += r * Math.cos(t); + y += r * Math.sin(t); + } + + emit('text-anchor', textAlign[o.align] || 'start'); + + if (a) { + t = translate(x, y) + ' rotate('+a+')'; + if (dx || dy) t += ' ' + translate(dx, dy); + } else { + t = translate(x+dx, y+dy); + } + emit('transform', t); + } + } + }; + +},{"../../util/svg":85,"../../util/text":86}],76:[function(require,module,exports){ + function Bounds(b) { + this.clear(); + if (b) this.union(b); + } + + var prototype = Bounds.prototype; + + prototype.clone = function() { + return new Bounds(this); + }; + + prototype.clear = function() { + this.x1 = +Number.MAX_VALUE; + this.y1 = +Number.MAX_VALUE; + this.x2 = -Number.MAX_VALUE; + this.y2 = -Number.MAX_VALUE; + return this; + }; + + prototype.set = function(x1, y1, x2, y2) { + this.x1 = x1; + this.y1 = y1; + this.x2 = x2; + this.y2 = y2; + return this; + }; + + prototype.add = function(x, y) { + if (x < this.x1) this.x1 = x; + if (y < this.y1) this.y1 = y; + if (x > this.x2) this.x2 = x; + if (y > this.y2) this.y2 = y; + return this; + }; + + prototype.expand = function(d) { + this.x1 -= d; + this.y1 -= d; + this.x2 += d; + this.y2 += d; + return this; + }; + + prototype.round = function() { + this.x1 = Math.floor(this.x1); + this.y1 = Math.floor(this.y1); + this.x2 = Math.ceil(this.x2); + this.y2 = Math.ceil(this.y2); + return this; + }; + + prototype.translate = function(dx, dy) { + this.x1 += dx; + this.x2 += dx; + this.y1 += dy; + this.y2 += dy; + return this; + }; + + prototype.rotate = function(angle, x, y) { + var cos = Math.cos(angle), + sin = Math.sin(angle), + cx = x - x*cos + y*sin, + cy = y - x*sin - y*cos, + x1 = this.x1, x2 = this.x2, + y1 = this.y1, y2 = this.y2; + + return this.clear() + .add(cos*x1 - sin*y1 + cx, sin*x1 + cos*y1 + cy) + .add(cos*x1 - sin*y2 + cx, sin*x1 + cos*y2 + cy) + .add(cos*x2 - sin*y1 + cx, sin*x2 + cos*y1 + cy) + .add(cos*x2 - sin*y2 + cx, sin*x2 + cos*y2 + cy); + }; + + prototype.union = function(b) { + if (b.x1 < this.x1) this.x1 = b.x1; + if (b.y1 < this.y1) this.y1 = b.y1; + if (b.x2 > this.x2) this.x2 = b.x2; + if (b.y2 > this.y2) this.y2 = b.y2; + return this; + }; + + prototype.encloses = function(b) { + return b && ( + this.x1 <= b.x1 && + this.x2 >= b.x2 && + this.y1 <= b.y1 && + this.y2 >= b.y2 + ); + }; + + prototype.intersects = function(b) { + return b && !( + this.x2 < b.x1 || + this.x1 > b.x2 || + this.y2 < b.y1 || + this.y1 > b.y2 + ); + }; + + prototype.contains = function(x, y) { + return !( + x < this.x1 || + x > this.x2 || + y < this.y1 || + y > this.y2 + ); + }; + + prototype.width = function() { + return this.x2 - this.x1; + }; + + prototype.height = function() { + return this.y2 - this.y1; + }; + + module.exports = Bounds; + +},{}],77:[function(require,module,exports){ + module.exports = function(b) { + function noop() { } + function add(x,y) { b.add(x, y); } + + return { + bounds: function(_) { + if (!arguments.length) return b; + return (b = _, this); + }, + beginPath: noop, + closePath: noop, + moveTo: add, + lineTo: add, + quadraticCurveTo: function(x1, y1, x2, y2) { + b.add(x1, y1); + b.add(x2, y2); + }, + bezierCurveTo: function(x1, y1, x2, y2, x3, y3) { + b.add(x1, y1); + b.add(x2, y2); + b.add(x3, y3); + } + }; + }; + +},{}],78:[function(require,module,exports){ + var gradient_id = 0; + + function Gradient(type) { + this.id = 'gradient_' + (gradient_id++); + this.type = type || 'linear'; + this.stops = []; + this.x1 = 0; + this.x2 = 1; + this.y1 = 0; + this.y2 = 0; + } + + var prototype = Gradient.prototype; + + prototype.stop = function(offset, color) { + this.stops.push({ + offset: offset, + color: color + }); + return this; + }; + + module.exports = Gradient; +},{}],79:[function(require,module,exports){ + (function (global){ + var load = require('datalib/src/import/load'); + + function ImageLoader(loadConfig) { + this._pending = 0; + this._config = loadConfig || ImageLoader.Config; + } + +// Overridable global default load configuration + ImageLoader.Config = null; + + var prototype = ImageLoader.prototype; + + prototype.pending = function() { + return this._pending; + }; + + prototype.params = function(uri) { + var p = {url: uri}, k; + for (k in this._config) { p[k] = this._config[k]; } + return p; + }; + + prototype.imageURL = function(uri) { + return load.sanitizeUrl(this.params(uri)); + }; + + function browser(uri, callback) { + var url = load.sanitizeUrl(this.params(uri)); + if (!url) { // error + if (callback) callback(uri, null); + return null; + } + + var loader = this, + image = new Image(); + + loader._pending += 1; + + image.onload = function() { + loader._pending -= 1; + image.loaded = true; + if (callback) callback(null, image); + }; + image.src = url; + + return image; + } + + function server(uri, callback) { + var loader = this, + image = new ((typeof window !== "undefined" ? window['canvas'] : typeof global !== "undefined" ? global['canvas'] : null).Image)(); + + loader._pending += 1; + + load(this.params(uri), function(err, data) { + loader._pending -= 1; + if (err) { + if (callback) callback(err, null); + return null; + } + image.src = data; + image.loaded = true; + if (callback) callback(null, image); + }); + + return image; + } + + prototype.loadImage = function(uri, callback) { + return load.useXHR ? + browser.call(this, uri, callback) : + server.call(this, uri, callback); + }; + + module.exports = ImageLoader; + + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"datalib/src/import/load":22}],80:[function(require,module,exports){ + function Item(mark) { + this.mark = mark; + } + + var prototype = Item.prototype; + + prototype.hasPropertySet = function(name) { + var props = this.mark.def.properties; + return props && props[name] != null; + }; + + prototype.cousin = function(offset, index) { + if (offset === 0) return this; + offset = offset || -1; + var mark = this.mark, + group = mark.group, + iidx = index==null ? mark.items.indexOf(this) : index, + midx = group.items.indexOf(mark) + offset; + return group.items[midx].items[iidx]; + }; + + prototype.sibling = function(offset) { + if (offset === 0) return this; + offset = offset || -1; + var mark = this.mark, + iidx = mark.items.indexOf(this) + offset; + return mark.items[iidx]; + }; + + prototype.remove = function() { + var item = this, + list = item.mark.items, + i = list.indexOf(item); + if (i >= 0) { + if (i===list.length-1) { + list.pop(); + } else { + list.splice(i, 1); + } + } + return item; + }; + + prototype.touch = function() { + if (this.pathCache) this.pathCache = null; + }; + + module.exports = Item; +},{}],81:[function(require,module,exports){ + var BoundsContext = require('./BoundsContext'), + Bounds = require('./Bounds'), + canvas = require('./canvas'), + svg = require('./svg'), + text = require('./text'), + paths = require('../path'), + parse = paths.parse, + drawPath = paths.render, + areaPath = svg.path.area, + linePath = svg.path.line, + halfpi = Math.PI / 2, + sqrt3 = Math.sqrt(3), + tan30 = Math.tan(30 * Math.PI / 180), + g2D = null, + bc = BoundsContext(); + + function context() { + return g2D || (g2D = canvas.instance(1,1).getContext('2d')); + } + + function strokeBounds(o, bounds) { + if (o.stroke && o.opacity !== 0 && o.stokeOpacity !== 0) { + bounds.expand(o.strokeWidth != null ? o.strokeWidth : 1); + } + return bounds; + } + + function pathBounds(o, path, bounds, x, y) { + if (path == null) { + bounds.set(0, 0, 0, 0); + } else { + drawPath(bc.bounds(bounds), path, x, y); + strokeBounds(o, bounds); + } + return bounds; + } + + function path(o, bounds) { + var p = o.path ? o.pathCache || (o.pathCache = parse(o.path)) : null; + return pathBounds(o, p, bounds, o.x, o.y); + } + + function area(mark, bounds) { + if (mark.items.length === 0) return bounds; + var items = mark.items, + item = items[0], + p = item.pathCache || (item.pathCache = parse(areaPath(items))); + return pathBounds(item, p, bounds); + } + + function line(mark, bounds) { + if (mark.items.length === 0) return bounds; + var items = mark.items, + item = items[0], + p = item.pathCache || (item.pathCache = parse(linePath(items))); + return pathBounds(item, p, bounds); + } + + function rect(o, bounds) { + var x, y; + return strokeBounds(o, bounds.set( + x = o.x || 0, + y = o.y || 0, + (x + o.width) || 0, + (y + o.height) || 0 + )); + } + + function image(o, bounds) { + var x = o.x || 0, + y = o.y || 0, + w = o.width || 0, + h = o.height || 0; + x = x - (o.align === 'center' ? w/2 : (o.align === 'right' ? w : 0)); + y = y - (o.baseline === 'middle' ? h/2 : (o.baseline === 'bottom' ? h : 0)); + return bounds.set(x, y, x+w, y+h); + } + + function rule(o, bounds) { + var x1, y1; + return strokeBounds(o, bounds.set( + x1 = o.x || 0, + y1 = o.y || 0, + o.x2 != null ? o.x2 : x1, + o.y2 != null ? o.y2 : y1 + )); + } + + function arc(o, bounds) { + var cx = o.x || 0, + cy = o.y || 0, + ir = o.innerRadius || 0, + or = o.outerRadius || 0, + sa = (o.startAngle || 0) - halfpi, + ea = (o.endAngle || 0) - halfpi, + xmin = Infinity, xmax = -Infinity, + ymin = Infinity, ymax = -Infinity, + a, i, n, x, y, ix, iy, ox, oy; + + var angles = [sa, ea], + s = sa - (sa % halfpi); + for (i=0; i<4 && s index) { + el.removeChild(el.childNodes[--curr]); + } + return el; + }, + remove: remove, + // generate css class name for mark + cssClass: function(mark) { + return 'mark-' + mark.marktype + (mark.name ? ' '+mark.name : ''); + }, + // generate string for an opening xml tag + // tag: the name of the xml tag + // attr: hash of attribute name-value pairs to include + // raw: additional raw string to include in tag markup + openTag: function(tag, attr, raw) { + var s = '<' + tag, key, val; + if (attr) { + for (key in attr) { + val = attr[key]; + if (val != null) { + s += ' ' + key + '="' + val + '"'; + } + } + } + if (raw) s += ' ' + raw; + return s + '>'; + }, + // generate string for closing xml tag + // tag: the name of the xml tag + closeTag: function(tag) { + return ''; + } + }; + +},{}],84:[function(require,module,exports){ + var bound = require('../util/bound'); + + var sets = [ + 'items', + 'axisItems', + 'legendItems' + ]; + + var keys = [ + 'marktype', 'name', 'interactive', 'clip', + 'items', 'axisItems', 'legendItems', 'layer', + 'x', 'y', 'width', 'height', 'align', 'baseline', // layout + 'fill', 'fillOpacity', 'opacity', // fill + 'stroke', 'strokeOpacity', 'strokeWidth', 'strokeCap', // stroke + 'strokeDash', 'strokeDashOffset', // stroke dash + 'startAngle', 'endAngle', 'innerRadius', 'outerRadius', // arc + 'interpolate', 'tension', 'orient', // area, line + 'url', // image + 'path', // path + 'x2', 'y2', // rule + 'size', 'shape', // symbol + 'text', 'angle', 'theta', 'radius', 'dx', 'dy', // text + 'font', 'fontSize', 'fontWeight', 'fontStyle', 'fontVariant' // font + ]; + + function toJSON(scene, indent) { + return JSON.stringify(scene, keys, indent); + } + + function fromJSON(json) { + var scene = (typeof json === 'string' ? JSON.parse(json) : json); + return initialize(scene); + } + + function initialize(scene) { + var type = scene.marktype, + i, n, s, m, items; + + for (s=0, m=sets.length; s 0) { wait(); } else { callback(this.canvas()); } + }; + + prototype.svg = function() { + return (this._type === 'svg') ? this._renderer.svg() : null; + }; + + prototype.initialize = function() { + var w = this._width, + h = this._height, + bg = this._bgcolor, + pad = this._padding, + config = this.model().config(); + + if (this._viewport) { + w = this._viewport[0] - (pad ? pad.left + pad.right : 0); + h = this._viewport[1] - (pad ? pad.top + pad.bottom : 0); + } + + this._renderer = (this._renderer || new this._io.Renderer(config.load)) + .initialize(null, w, h, pad) + .background(bg); + + return this; + }; + + module.exports = HeadlessView; +},{"./View":89,"vega-scenegraph":48}],88:[function(require,module,exports){ + var dl = require('datalib'), + df = require('vega-dataflow'), + ChangeSet = df.ChangeSet, + Base = df.Graph.prototype, + Node = df.Node, // jshint ignore:line + GroupBuilder = require('../scene/GroupBuilder'), + visit = require('../scene/visit'), + config = require('./config'); + + function Model(cfg) { + this._defs = {}; + this._predicates = {}; + this._scene = null; + + this._node = null; + this._builder = null; // Top-level scenegraph builder + + this._reset = {axes: false, legends: false}; + + this.config(cfg); + Base.init.call(this); + } + + var prototype = (Model.prototype = Object.create(Base)); + prototype.constructor = Model; + + prototype.defs = function(defs) { + if (!arguments.length) return this._defs; + this._defs = defs; + return this; + }; + + prototype.config = function(cfg) { + if (!arguments.length) return this._config; + this._config = Object.create(config); + for (var name in cfg) { + var x = cfg[name], y = this._config[name]; + if (dl.isObject(x) && dl.isObject(y)) { + dl.extend(y, x); + } else { + this._config[name] = x; + } + } + + return this; + }; + + prototype.width = function(width) { + if (this._defs) this._defs.width = width; + if (this._defs && this._defs.marks) this._defs.marks.width = width; + if (this._scene) { + this._scene.items[0].width = width; + this._scene.items[0]._dirty = true; + } + this._reset.axes = true; + return this; + }; + + prototype.height = function(height) { + if (this._defs) this._defs.height = height; + if (this._defs && this._defs.marks) this._defs.marks.height = height; + if (this._scene) { + this._scene.items[0].height = height; + this._scene.items[0]._dirty = true; + } + this._reset.axes = true; + return this; + }; + + prototype.node = function() { + return this._node || (this._node = new Node(this)); + }; + + prototype.data = function() { + var data = Base.data.apply(this, arguments); + if (arguments.length > 1) { // new Datasource + this.node().addListener(data.pipeline()[0]); + } + return data; + }; + + function predicates(name) { + var m = this, pred = {}; + if (!dl.isArray(name)) return this._predicates[name]; + name.forEach(function(n) { pred[n] = m._predicates[n]; }); + return pred; + } + + prototype.predicate = function(name, predicate) { + if (arguments.length === 1) return predicates.call(this, name); + return (this._predicates[name] = predicate); + }; + + prototype.predicates = function() { return this._predicates; }; + + prototype.scene = function(renderer) { + if (!arguments.length) return this._scene; + + if (this._builder) { + this.node().removeListener(this._builder); + this._builder._groupBuilder.disconnect(); + } + + var m = this, + b = this._builder = new Node(this); + + b.evaluate = function(input) { + if (b._groupBuilder) return input; + + var gb = b._groupBuilder = new GroupBuilder(m, m._defs.marks, m._scene={}), + p = gb.pipeline(); + + this.addListener(gb.connect()); + p[p.length-1].addListener(renderer); + return input; + }; + + this.addListener(b); + return this; + }; + + prototype.reset = function() { + if (this._scene && this._reset.axes) { + visit(this._scene, function(item) { + if (item.axes) item.axes.forEach(function(axis) { axis.reset(); }); + }); + this._reset.axes = false; + } + if (this._scene && this._reset.legends) { + visit(this._scene, function(item) { + if (item.legends) item.legends.forEach(function(l) { l.reset(); }); + }); + this._reset.legends = false; + } + return this; + }; + + prototype.addListener = function(l) { + this.node().addListener(l); + }; + + prototype.removeListener = function(l) { + this.node().removeListener(l); + }; + + prototype.fire = function(cs) { + if (!cs) cs = ChangeSet.create(); + this.propagate(cs, this.node()); + }; + + module.exports = Model; +},{"../scene/GroupBuilder":112,"../scene/visit":117,"./config":90,"datalib":26,"vega-dataflow":41}],89:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + df = require('vega-dataflow'), + sg = require('vega-scenegraph').render, + log = require('vega-logging'), + Deps = df.Dependencies, + parseStreams = require('../parse/streams'), + Encoder = require('../scene/Encoder'), + Transition = require('../scene/Transition'); + + function View(el, width, height) { + this._el = null; + this._model = null; + this._width = this.__width = width || 500; + this._height = this.__height = height || 300; + this._bgcolor = null; + this._autopad = 1; + this._padding = {top:0, left:0, bottom:0, right:0}; + this._viewport = null; + this._renderer = null; + this._handler = null; + this._streamer = null; // Targeted update for streaming changes + this._changeset = null; + this._repaint = true; // Full re-render on every re-init + this._renderers = sg; + this._io = null; + this._api = {}; // Stash streaming data API sandboxes. + } + + var prototype = View.prototype; + + prototype.model = function(model) { + if (!arguments.length) return this._model; + if (this._model !== model) { + this._model = model; + this._streamer = new df.Node(model); + this._streamer._rank = -1; // HACK: To reduce re-ranking churn. + this._changeset = df.ChangeSet.create(); + if (this._handler) this._handler.model(model); + } + return this; + }; + +// Sandboxed streaming data API + function streaming(src) { + var view = this, + ds = this._model.data(src), + name = ds.name(), + listener = ds.pipeline()[0], + streamer = this._streamer, + api = {}; + + // If we have it stashed, don't create a new closure. + if (this._api[src]) return this._api[src]; + + api.insert = function(vals) { + ds.insert(dl.duplicate(vals)); // Don't pollute the environment + streamer.addListener(listener); + view._changeset.data[name] = 1; + return api; + }; + + api.update = function() { + streamer.addListener(listener); + view._changeset.data[name] = 1; + return (ds.update.apply(ds, arguments), api); + }; + + api.remove = function() { + streamer.addListener(listener); + view._changeset.data[name] = 1; + return (ds.remove.apply(ds, arguments), api); + }; + + api.values = function() { return ds.values(); }; + + return (this._api[src] = api); + } + + prototype.data = function(data) { + var v = this; + if (!arguments.length) return v._model.values(); + else if (dl.isString(data)) return streaming.call(v, data); + else if (dl.isObject(data)) { + dl.keys(data).forEach(function(k) { + var api = streaming.call(v, k); + data[k](api); + }); + } + return this; + }; + + var VIEW_SIGNALS = dl.toMap(['width', 'height', 'padding']); + + prototype.signal = function(name, value, propagate) { + var m = this._model, + key, values; + + // Getter. Returns the value for the specified signal, or + // returns all signal values. + if (!arguments.length) { + return m.values(Deps.SIGNALS); + } else if (arguments.length === 1 && dl.isString(name)) { + return m.values(Deps.SIGNALS, name); + } + + // Setter. Can be done in batch or individually. In either case, + // the final argument determines if set values should propagate. + if (dl.isObject(name)) { + values = name; + propagate = value; + } else { + values = {}; + values[name] = value; + } + for (key in values) { + if (VIEW_SIGNALS[key]) { + this[key](values[key]); + } else { + setSignal.call(this, key, values[key], propagate); + } + } + return this; + }; + + function setSignal(name, value, propagate) { + var cs = this._changeset; + this._streamer.addListener(this._model.signal(name).value(value)); + if (propagate !== false) cs.signals[name] = 1; + cs.reflow = true; + } + + prototype.width = function(width) { + if (!arguments.length) return this.__width; + if (this.__width !== width) { + this._width = this.__width = width; + this.model().width(width); + this.initialize(); + if (this._strict) this._autopad = 1; + setSignal.call(this, 'width', width); + } + return this; + }; + + prototype.height = function(height) { + if (!arguments.length) return this.__height; + if (this.__height !== height) { + this._height = this.__height = height; + this.model().height(height); + this.initialize(); + if (this._strict) this._autopad = 1; + setSignal.call(this, 'height', height); + } + return this; + }; + + prototype.background = function(bgcolor) { + if (!arguments.length) return this._bgcolor; + if (this._bgcolor !== bgcolor) { + this._bgcolor = bgcolor; + this.initialize(); + } + return this; + }; + + prototype.padding = function(pad) { + if (!arguments.length) return this._padding; + if (this._padding !== pad) { + if (dl.isString(pad)) { + this._autopad = 1; + this._padding = {top:0, left:0, bottom:0, right:0}; + this._strict = (pad === 'strict'); + } else { + this._autopad = 0; + this._padding = pad; + this._strict = false; + } + if (this._renderer) this._renderer.resize(this._width, this._height, this._padding); + if (this._handler) this._handler.padding(this._padding); + setSignal.call(this, 'padding', this._padding); + } + return (this._repaint = true, this); + }; + + prototype.autopad = function(opt) { + if (this._autopad < 1) return this; + else this._autopad = 0; + + var b = this.model().scene().bounds, + pad = this._padding, + config = this.model().config(), + inset = config.autopadInset, + l = b.x1 < 0 ? Math.ceil(-b.x1) + inset : 0, + t = b.y1 < 0 ? Math.ceil(-b.y1) + inset : 0, + r = b.x2 > this._width ? Math.ceil(+b.x2 - this._width) + inset : 0; + b = b.y2 > this._height ? Math.ceil(+b.y2 - this._height) + inset : 0; + pad = {left:l, top:t, right:r, bottom:b}; + + if (this._strict) { + this._autopad = 0; + this._padding = pad; + this._width = Math.max(0, this.__width - (l+r)); + this._height = Math.max(0, this.__height - (t+b)); + + this._model.width(this._width).height(this._height).reset(); + setSignal.call(this, 'width', this._width); + setSignal.call(this, 'height', this._height); + setSignal.call(this, 'padding', pad); + + this.initialize().update({props:'enter'}).update({props:'update'}); + } else { + this.padding(pad).update(opt); + } + return this; + }; + + prototype.viewport = function(size) { + if (!arguments.length) return this._viewport; + if (this._viewport !== size) { + this._viewport = size; + this.initialize(); + } + return this; + }; + + prototype.renderer = function(type) { + if (!arguments.length) return this._renderer; + if (this._renderers[type]) type = this._renderers[type]; + else if (dl.isString(type)) throw new Error('Unknown renderer: ' + type); + else if (!type) throw new Error('No renderer specified'); + + if (this._io !== type) { + this._io = type; + this._renderer = null; + this.initialize(); + if (this._build) this.render(); + } + return this; + }; + + prototype.initialize = function(el) { + var v = this, prevHandler, + w = v._width, h = v._height, pad = v._padding, bg = v._bgcolor, + config = this.model().config(); + + if (!arguments.length || el === null) { + el = this._el ? this._el.parentNode : null; + if (!el) return this; // This View cannot init w/o an + } + + // clear pre-existing container + d3.select(el).select('div.vega').remove(); + + // add div container + this._el = el = d3.select(el) + .append('div') + .attr('class', 'vega') + .style('position', 'relative') + .node(); + if (v._viewport) { + d3.select(el) + .style('width', (v._viewport[0] || w)+'px') + .style('height', (v._viewport[1] || h)+'px') + .style('overflow', 'auto'); + } + + // renderer + sg.canvas.Renderer.RETINA = config.render.retina; + v._renderer = (v._renderer || new this._io.Renderer(config.load)) + .initialize(el, w, h, pad) + .background(bg); + + // input handler + prevHandler = v._handler; + v._handler = new this._io.Handler() + .initialize(el, pad, v); + + if (prevHandler) { + prevHandler.handlers().forEach(function(h) { + v._handler.on(h.type, h.handler); + }); + } else { + // Register event listeners for signal stream definitions. + v._detach = parseStreams(this); + } + + return (this._repaint = true, this); + }; + + prototype.destroy = function() { + if (this._detach) this._detach(); + }; + + function build() { + var v = this; + v._renderNode = new df.Node(v._model) + .router(true); + + v._renderNode.evaluate = function(input) { + log.debug(input, ['rendering']); + + var s = v._model.scene(), + h = v._handler; + + if (h && h.scene) h.scene(s); + + if (input.trans) { + input.trans.start(function(items) { v._renderer.render(s, items); }); + } else if (v._repaint) { + v._renderer.render(s); + v._repaint = false; + } else if (input.dirty.length) { + v._renderer.render(s, input.dirty); + } + + if (input.dirty.length) { + input.dirty.forEach(function(i) { i._dirty = false; }); + s.items[0]._dirty = false; + } + + // For all updated datasources, clear their previous values. + for (var d in input.data) { v._model.data(d).synchronize(); } + return input; + }; + + return (v._model.scene(v._renderNode), true); + } + + prototype.update = function(opt) { + opt = opt || {}; + var v = this, + model = this._model, + streamer = this._streamer, + cs = this._changeset, + trans = opt.duration ? new Transition(opt.duration, opt.ease) : null; + + if (trans) cs.trans = trans; + if (opt.props !== undefined) { + if (dl.keys(cs.data).length > 0) { + throw Error( + 'New data values are not reflected in the visualization.' + + ' Please call view.update() before updating a specified property set.' + ); + } + + cs.reflow = true; + cs.request = opt.props; + } + + var built = v._build; + v._build = v._build || build.call(this); + + // If specific items are specified, short-circuit dataflow graph. + // Else-If there are streaming updates, perform a targeted propagation. + // Otherwise, re-evaluate the entire model (datasources + scene). + if (opt.items && built) { + Encoder.update(model, opt.trans, opt.props, opt.items, cs.dirty); + v._renderNode.evaluate(cs); + } else if (streamer.listeners().length && built) { + // Include re-evaluation entire model when repaint flag is set + if (this._repaint) streamer.addListener(model.node()); + model.propagate(cs, streamer); + streamer.disconnect(); + } else { + model.fire(cs); + } + + v._changeset = df.ChangeSet.create(); + + return v.autopad(opt); + }; + + prototype.toImageURL = function(type) { + var v = this, Renderer; + + // lookup appropriate renderer + switch (type || 'png') { + case 'canvas': + case 'png': + Renderer = sg.canvas.Renderer; break; + case 'svg': + Renderer = sg.svg.string.Renderer; break; + default: throw Error('Unrecognized renderer type: ' + type); + } + + var retina = sg.canvas.Renderer.RETINA; + sg.canvas.Renderer.RETINA = false; // ignore retina screen + + // render the scenegraph + var ren = new Renderer(v._model.config.load) + .initialize(null, v._width, v._height, v._padding) + .render(v._model.scene()); + + sg.canvas.Renderer.RETINA = retina; // restore retina settings + + // return data url + if (type === 'svg') { + var blob = new Blob([ren.svg()], {type: 'image/svg+xml'}); + return window.URL.createObjectURL(blob); + } else { + return ren.canvas().toDataURL('image/png'); + } + }; + + prototype.render = function(items) { + this._renderer.render(this._model.scene(), items); + return this; + }; + + prototype.on = function() { + this._handler.on.apply(this._handler, arguments); + return this; + }; + + prototype.onSignal = function(name, handler) { + this._model.signal(name).on(handler); + return this; + }; + + prototype.off = function() { + this._handler.off.apply(this._handler, arguments); + return this; + }; + + prototype.offSignal = function(name, handler) { + this._model.signal(name).off(handler); + return this; + }; + + View.factory = function(model) { + var HeadlessView = require('./HeadlessView'); + return function(opt) { + opt = opt || {}; + var defs = model.defs(); + var v = (opt.el ? new View() : new HeadlessView()) + .model(model) + .renderer(opt.renderer || 'canvas') + .width(defs.width) + .height(defs.height) + .background(defs.background) + .padding(defs.padding) + .viewport(defs.viewport) + .initialize(opt.el); + + if (opt.data) v.data(opt.data); + + if (opt.hover !== false && opt.el) { + v.on('mouseover', function(evt, item) { + if (item && item.hasPropertySet('hover')) { + this.update({props:'hover', items:item}); + } + }) + .on('mouseout', function(evt, item) { + if (item && item.hasPropertySet('hover')) { + this.update({props:'update', items:item}); + } + }); + } + + return v; + }; + }; + + module.exports = View; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"../parse/streams":107,"../scene/Encoder":111,"../scene/Transition":114,"./HeadlessView":87,"datalib":26,"vega-dataflow":41,"vega-logging":47,"vega-scenegraph":48}],90:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + config = {}; + + config.load = { + // base url for loading external data files + // used only for server-side operation + baseURL: '', + // Allows domain restriction when using data loading via XHR. + // To enable, set it to a list of allowed domains + // e.g., ['wikipedia.org', 'eff.org'] + domainWhiteList: false + }; + +// inset padding for automatic padding calculation + config.autopadInset = 5; + +// extensible scale lookup table +// all d3.scale.* instances also supported + config.scale = { + time: d3.time.scale, + utc: d3.time.scale.utc + }; + +// default rendering settings + config.render = { + retina: true + }; + +// root scenegraph group + config.scene = { + fill: undefined, + fillOpacity: undefined, + stroke: undefined, + strokeOpacity: undefined, + strokeWidth: undefined, + strokeDash: undefined, + strokeDashOffset: undefined + }; + +// default axis properties + config.axis = { + orient: 'bottom', + ticks: 10, + padding: 3, + axisColor: '#000', + axisWidth: 1, + gridColor: '#000', + gridOpacity: 0.15, + tickColor: '#000', + tickLabelColor: '#000', + tickWidth: 1, + tickSize: 6, + tickLabelFontSize: 11, + tickLabelFont: 'sans-serif', + titleColor: '#000', + titleFont: 'sans-serif', + titleFontSize: 11, + titleFontWeight: 'bold', + titleOffset: 'auto', + titleOffsetAutoMin: 30, + titleOffsetAutoMax: Infinity, + titleOffsetAutoMargin: 4 + }; + +// default legend properties + config.legend = { + orient: 'right', + offset: 20, + padding: 3, // padding between legend items and border + margin: 2, // extra margin between two consecutive legends + gradientStrokeColor: '#888', + gradientStrokeWidth: 1, + gradientHeight: 16, + gradientWidth: 100, + labelColor: '#000', + labelFontSize: 10, + labelFont: 'sans-serif', + labelAlign: 'left', + labelBaseline: 'middle', + labelOffset: 8, + symbolShape: 'circle', + symbolSize: 50, + symbolColor: '#888', + symbolStrokeWidth: 1, + titleColor: '#000', + titleFont: 'sans-serif', + titleFontSize: 11, + titleFontWeight: 'bold' + }; + +// default color values + config.color = { + rgb: [128, 128, 128], + lab: [50, 0, 0], + hcl: [0, 0, 50], + hsl: [0, 0, 0.5] + }; + +// default scale ranges + config.range = { + category10: d3.scale.category10().range(), + category20: d3.scale.category20().range(), + category20b: d3.scale.category20b().range(), + category20c: d3.scale.category20c().range(), + shapes: [ + 'circle', + 'cross', + 'diamond', + 'square', + 'triangle-down', + 'triangle-up' + ] + }; + + module.exports = config; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],91:[function(require,module,exports){ + var dl = require('datalib'), + parse = require('../parse'), + Scale = require('../scene/Scale'), + config = require('./config'); + + function compile(module, opt, schema) { + var s = module.schema; + if (!s) return; + if (s.refs) dl.extend(schema.refs, s.refs); + if (s.defs) dl.extend(schema.defs, s.defs); + } + + module.exports = function(opt) { + var schema = null; + opt = opt || {}; + + // Compile if we're not loading the schema from a URL. + // Load from a URL to extend the existing base schema. + if (opt.url) { + schema = dl.json(dl.extend({url: opt.url}, config.load)); + } else { + schema = { + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Vega Visualization Specification Language", + "defs": {}, + "refs": {}, + "$ref": "#/defs/spec" + }; + + dl.keys(parse).forEach(function(k) { compile(parse[k], opt, schema); }); + + // Scales aren't in the parser, add schema manually + compile(Scale, opt, schema); + } + + // Extend schema to support custom mark properties or property sets. + if (opt.properties) dl.keys(opt.properties).forEach(function(k) { + schema.defs.propset.properties[k] = {"$ref": "#/refs/"+opt.properties[k]+"Value"}; + }); + + if (opt.propertySets) dl.keys(opt.propertySets).forEach(function(k) { + schema.defs.mark.properties.properties.properties[k] = {"$ref": "#/defs/propset"}; + }); + + return schema; + }; +},{"../parse":97,"../scene/Scale":113,"./config":90,"datalib":26}],92:[function(require,module,exports){ + var dl = require('datalib'), + axs = require('../scene/axis'); + + var ORIENT = { + "x": "bottom", + "y": "left", + "top": "top", + "bottom": "bottom", + "left": "left", + "right": "right" + }; + + function parseAxes(model, spec, axes, group) { + var config = model.config(); + (spec || []).forEach(function(def, index) { + axes[index] = axes[index] || axs(model); + parseAxis(config, def, index, axes[index], group); + }); + } + + function parseAxis(config, def, index, axis, group) { + // axis scale + if (def.scale !== undefined) { + axis.scale(group.scale(def.scale)); + } + + // axis orientation + axis.orient(def.orient || ORIENT[def.type]); + // axis offset + axis.offset(def.offset || 0); + // axis layer + axis.layer(def.layer || "front"); + // axis grid lines + axis.grid(def.grid || false); + // axis title + axis.title(def.title || null); + // axis title offset + axis.titleOffset(def.titleOffset != null ? + def.titleOffset : config.axis.titleOffset); + // axis values + axis.tickValues(def.values || null); + // axis label formatting + axis.tickFormat(def.format || null); + axis.tickFormatType(def.formatType || null); + // axis tick subdivision + axis.tickSubdivide(def.subdivide || 0); + // axis tick padding + axis.tickPadding(def.tickPadding || config.axis.padding); + + // axis tick size(s) + var size = []; + if (def.tickSize !== undefined) { + for (var i=0; i<3; ++i) size.push(def.tickSize); + } else { + var ts = config.axis.tickSize; + size = [ts, ts, ts]; + } + if (def.tickSizeMajor != null) size[0] = def.tickSizeMajor; + if (def.tickSizeMinor != null) size[1] = def.tickSizeMinor; + if (def.tickSizeEnd != null) size[2] = def.tickSizeEnd; + if (size.length) { + axis.tickSize.apply(axis, size); + } + + // axis tick count + axis.tickCount(def.ticks || config.axis.ticks); + + // style properties + var p = def.properties; + if (p && p.ticks) { + axis.majorTickProperties(p.majorTicks ? + dl.extend({}, p.ticks, p.majorTicks) : p.ticks); + axis.minorTickProperties(p.minorTicks ? + dl.extend({}, p.ticks, p.minorTicks) : p.ticks); + } else { + axis.majorTickProperties(p && p.majorTicks || {}); + axis.minorTickProperties(p && p.minorTicks || {}); + } + axis.tickLabelProperties(p && p.labels || {}); + axis.titleProperties(p && p.title || {}); + axis.gridLineProperties(p && p.grid || {}); + axis.domainProperties(p && p.axis || {}); + } + + module.exports = parseAxes; +},{"../scene/axis":115,"datalib":26}],93:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null); + + function parseBg(bg) { + // return null if input is null or undefined + if (bg == null) return null; + // run through d3 rgb to sanity check + return d3.rgb(bg) + ''; + } + + module.exports = parseBg; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{}],94:[function(require,module,exports){ + var dl = require('datalib'), + log = require('vega-logging'), + parseTransforms = require('./transforms'), + parseModify = require('./modify'); + + function parseData(model, spec, callback) { + var config = model.config(), + count = 0; + + function loaded(d) { + return function(error, data) { + if (error) { + log.error('LOADING FAILED: ' + d.url + ' ' + error); + } else { + model.data(d.name).values(dl.read(data, d.format)); + } + if (--count === 0) callback(); + }; + } + + // process each data set definition + (spec || []).forEach(function(d) { + if (d.url) { + count += 1; + dl.load(dl.extend({url: d.url}, config.load), loaded(d)); + } + parseData.datasource(model, d); + }); + + if (count === 0) setTimeout(callback, 1); + return spec; + } + + parseData.datasource = function(model, d) { + var transform = (d.transform || []).map(function(t) { + return parseTransforms(model, t); + }), + mod = (d.modify || []).map(function(m) { + return parseModify(model, m, d); + }), + ds = model.data(d.name, mod.concat(transform)); + + if (d.values) { + ds.values(dl.read(d.values, d.format)); + } else if (d.source) { + // Derived ds will be pulsed by its src rather than the model. + ds.source(d.source).addListener(ds); + model.removeListener(ds.pipeline()[0]); + } + + return ds; + }; + + module.exports = parseData; +},{"./modify":101,"./transforms":108,"datalib":26,"vega-logging":47}],95:[function(require,module,exports){ + module.exports = (function() { + /* + * Generated by PEG.js 0.8.0. + * + * http://pegjs.majda.cz/ + */ + + function peg$subclass(child, parent) { + function ctor() { this.constructor = child; } + ctor.prototype = parent.prototype; + child.prototype = new ctor(); + } + + function SyntaxError(message, expected, found, offset, line, column) { + this.message = message; + this.expected = expected; + this.found = found; + this.offset = offset; + this.line = line; + this.column = column; + + this.name = "SyntaxError"; + } + + peg$subclass(SyntaxError, Error); + + function parse(input) { + var options = arguments.length > 1 ? arguments[1] : {}, + + peg$FAILED = {}, + + peg$startRuleFunctions = { start: peg$parsestart }, + peg$startRuleFunction = peg$parsestart, + + peg$c0 = peg$FAILED, + peg$c1 = ",", + peg$c2 = { type: "literal", value: ",", description: "\",\"" }, + peg$c3 = function(o, m) { return [o].concat(m); }, + peg$c4 = function(o) { return [o]; }, + peg$c5 = "[", + peg$c6 = { type: "literal", value: "[", description: "\"[\"" }, + peg$c7 = "]", + peg$c8 = { type: "literal", value: "]", description: "\"]\"" }, + peg$c9 = ">", + peg$c10 = { type: "literal", value: ">", description: "\">\"" }, + peg$c11 = function(f1, f2, o) { return {start: f1, end: f2, middle: o}; }, + peg$c12 = [], + peg$c13 = function(s, f) { return (s.filters = f, s); }, + peg$c14 = function(s) { return s; }, + peg$c15 = "(", + peg$c16 = { type: "literal", value: "(", description: "\"(\"" }, + peg$c17 = ")", + peg$c18 = { type: "literal", value: ")", description: "\")\"" }, + peg$c19 = function(m) { return {stream: m}; }, + peg$c20 = "@", + peg$c21 = { type: "literal", value: "@", description: "\"@\"" }, + peg$c22 = ":", + peg$c23 = { type: "literal", value: ":", description: "\":\"" }, + peg$c24 = function(n, e) { return {event: e, name: n}; }, + peg$c25 = function(m, e) { return {event: e, mark: m}; }, + peg$c26 = function(t, e) { return {event: e, target: t}; }, + peg$c27 = function(e) { return {event: e}; }, + peg$c28 = function(s) { return {signal: s}; }, + peg$c29 = "rect", + peg$c30 = { type: "literal", value: "rect", description: "\"rect\"" }, + peg$c31 = "symbol", + peg$c32 = { type: "literal", value: "symbol", description: "\"symbol\"" }, + peg$c33 = "path", + peg$c34 = { type: "literal", value: "path", description: "\"path\"" }, + peg$c35 = "arc", + peg$c36 = { type: "literal", value: "arc", description: "\"arc\"" }, + peg$c37 = "area", + peg$c38 = { type: "literal", value: "area", description: "\"area\"" }, + peg$c39 = "line", + peg$c40 = { type: "literal", value: "line", description: "\"line\"" }, + peg$c41 = "rule", + peg$c42 = { type: "literal", value: "rule", description: "\"rule\"" }, + peg$c43 = "image", + peg$c44 = { type: "literal", value: "image", description: "\"image\"" }, + peg$c45 = "text", + peg$c46 = { type: "literal", value: "text", description: "\"text\"" }, + peg$c47 = "group", + peg$c48 = { type: "literal", value: "group", description: "\"group\"" }, + peg$c49 = "mousedown", + peg$c50 = { type: "literal", value: "mousedown", description: "\"mousedown\"" }, + peg$c51 = "mouseup", + peg$c52 = { type: "literal", value: "mouseup", description: "\"mouseup\"" }, + peg$c53 = "click", + peg$c54 = { type: "literal", value: "click", description: "\"click\"" }, + peg$c55 = "dblclick", + peg$c56 = { type: "literal", value: "dblclick", description: "\"dblclick\"" }, + peg$c57 = "wheel", + peg$c58 = { type: "literal", value: "wheel", description: "\"wheel\"" }, + peg$c59 = "keydown", + peg$c60 = { type: "literal", value: "keydown", description: "\"keydown\"" }, + peg$c61 = "keypress", + peg$c62 = { type: "literal", value: "keypress", description: "\"keypress\"" }, + peg$c63 = "keyup", + peg$c64 = { type: "literal", value: "keyup", description: "\"keyup\"" }, + peg$c65 = "mousewheel", + peg$c66 = { type: "literal", value: "mousewheel", description: "\"mousewheel\"" }, + peg$c67 = "mousemove", + peg$c68 = { type: "literal", value: "mousemove", description: "\"mousemove\"" }, + peg$c69 = "mouseout", + peg$c70 = { type: "literal", value: "mouseout", description: "\"mouseout\"" }, + peg$c71 = "mouseover", + peg$c72 = { type: "literal", value: "mouseover", description: "\"mouseover\"" }, + peg$c73 = "mouseenter", + peg$c74 = { type: "literal", value: "mouseenter", description: "\"mouseenter\"" }, + peg$c75 = "touchstart", + peg$c76 = { type: "literal", value: "touchstart", description: "\"touchstart\"" }, + peg$c77 = "touchmove", + peg$c78 = { type: "literal", value: "touchmove", description: "\"touchmove\"" }, + peg$c79 = "touchend", + peg$c80 = { type: "literal", value: "touchend", description: "\"touchend\"" }, + peg$c81 = function(e) { return e; }, + peg$c82 = /^[a-zA-Z0-9_\-]/, + peg$c83 = { type: "class", value: "[a-zA-Z0-9_\\-]", description: "[a-zA-Z0-9_\\-]" }, + peg$c84 = function(n) { return n.join(""); }, + peg$c85 = /^[a-zA-Z0-9\-_ #.>+~[\]=|\^$*]/, + peg$c86 = { type: "class", value: "[a-zA-Z0-9\\-_ #.>+~[\\]=|\\^$*]", description: "[a-zA-Z0-9\\-_ #.>+~[\\]=|\\^$*]" }, + peg$c87 = function(c) { return c.join(""); }, + peg$c88 = /^['"a-zA-Z0-9_().><=! \t-&|~]/, + peg$c89 = { type: "class", value: "['\"a-zA-Z0-9_().><=! \\t-&|~]", description: "['\"a-zA-Z0-9_().><=! \\t-&|~]" }, + peg$c90 = function(v) { return v.join(""); }, + peg$c91 = /^[ \t\r\n]/, + peg$c92 = { type: "class", value: "[ \\t\\r\\n]", description: "[ \\t\\r\\n]" }, + + peg$currPos = 0, + peg$reportedPos = 0, + peg$cachedPos = 0, + peg$cachedPosDetails = { line: 1, column: 1, seenCR: false }, + peg$maxFailPos = 0, + peg$maxFailExpected = [], + peg$silentFails = 0, + + peg$result; + + if ("startRule" in options) { + if (!(options.startRule in peg$startRuleFunctions)) { + throw new Error("Can't start parsing from rule \"" + options.startRule + "\"."); + } + + peg$startRuleFunction = peg$startRuleFunctions[options.startRule]; + } + + function text() { + return input.substring(peg$reportedPos, peg$currPos); + } + + function offset() { + return peg$reportedPos; + } + + function line() { + return peg$computePosDetails(peg$reportedPos).line; + } + + function column() { + return peg$computePosDetails(peg$reportedPos).column; + } + + function expected(description) { + throw peg$buildException( + null, + [{ type: "other", description: description }], + peg$reportedPos + ); + } + + function error(message) { + throw peg$buildException(message, null, peg$reportedPos); + } + + function peg$computePosDetails(pos) { + function advance(details, startPos, endPos) { + var p, ch; + + for (p = startPos; p < endPos; p++) { + ch = input.charAt(p); + if (ch === "\n") { + if (!details.seenCR) { details.line++; } + details.column = 1; + details.seenCR = false; + } else if (ch === "\r" || ch === "\u2028" || ch === "\u2029") { + details.line++; + details.column = 1; + details.seenCR = true; + } else { + details.column++; + details.seenCR = false; + } + } + } + + if (peg$cachedPos !== pos) { + if (peg$cachedPos > pos) { + peg$cachedPos = 0; + peg$cachedPosDetails = { line: 1, column: 1, seenCR: false }; + } + advance(peg$cachedPosDetails, peg$cachedPos, pos); + peg$cachedPos = pos; + } + + return peg$cachedPosDetails; + } + + function peg$fail(expected) { + if (peg$currPos < peg$maxFailPos) { return; } + + if (peg$currPos > peg$maxFailPos) { + peg$maxFailPos = peg$currPos; + peg$maxFailExpected = []; + } + + peg$maxFailExpected.push(expected); + } + + function peg$buildException(message, expected, pos) { + function cleanupExpected(expected) { + var i = 1; + + expected.sort(function(a, b) { + if (a.description < b.description) { + return -1; + } else if (a.description > b.description) { + return 1; + } else { + return 0; + } + }); + + while (i < expected.length) { + if (expected[i - 1] === expected[i]) { + expected.splice(i, 1); + } else { + i++; + } + } + } + + function buildMessage(expected, found) { + function stringEscape(s) { + function hex(ch) { return ch.charCodeAt(0).toString(16).toUpperCase(); } + + return s + .replace(/\\/g, '\\\\') + .replace(/"/g, '\\"') + .replace(/\x08/g, '\\b') + .replace(/\t/g, '\\t') + .replace(/\n/g, '\\n') + .replace(/\f/g, '\\f') + .replace(/\r/g, '\\r') + .replace(/[\x00-\x07\x0B\x0E\x0F]/g, function(ch) { return '\\x0' + hex(ch); }) + .replace(/[\x10-\x1F\x80-\xFF]/g, function(ch) { return '\\x' + hex(ch); }) + .replace(/[\u0180-\u0FFF]/g, function(ch) { return '\\u0' + hex(ch); }) + .replace(/[\u1080-\uFFFF]/g, function(ch) { return '\\u' + hex(ch); }); + } + + var expectedDescs = new Array(expected.length), + expectedDesc, foundDesc, i; + + for (i = 0; i < expected.length; i++) { + expectedDescs[i] = expected[i].description; + } + + expectedDesc = expected.length > 1 + ? expectedDescs.slice(0, -1).join(", ") + + " or " + + expectedDescs[expected.length - 1] + : expectedDescs[0]; + + foundDesc = found ? "\"" + stringEscape(found) + "\"" : "end of input"; + + return "Expected " + expectedDesc + " but " + foundDesc + " found."; + } + + var posDetails = peg$computePosDetails(pos), + found = pos < input.length ? input.charAt(pos) : null; + + if (expected !== null) { + cleanupExpected(expected); + } + + return new SyntaxError( + message !== null ? message : buildMessage(expected, found), + expected, + found, + pos, + posDetails.line, + posDetails.column + ); + } + + function peg$parsestart() { + var s0; + + s0 = peg$parsemerged(); + + return s0; + } + + function peg$parsemerged() { + var s0, s1, s2, s3, s4, s5; + + s0 = peg$currPos; + s1 = peg$parseordered(); + if (s1 !== peg$FAILED) { + s2 = peg$parsesep(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s3 = peg$c1; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c2); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parsesep(); + if (s4 !== peg$FAILED) { + s5 = peg$parsemerged(); + if (s5 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c3(s1, s5); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parseordered(); + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c4(s1); + } + s0 = s1; + } + + return s0; + } + + function peg$parseordered() { + var s0, s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 91) { + s1 = peg$c5; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c6); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parsesep(); + if (s2 !== peg$FAILED) { + s3 = peg$parsefiltered(); + if (s3 !== peg$FAILED) { + s4 = peg$parsesep(); + if (s4 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 44) { + s5 = peg$c1; + peg$currPos++; + } else { + s5 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c2); } + } + if (s5 !== peg$FAILED) { + s6 = peg$parsesep(); + if (s6 !== peg$FAILED) { + s7 = peg$parsefiltered(); + if (s7 !== peg$FAILED) { + s8 = peg$parsesep(); + if (s8 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s9 = peg$c7; + peg$currPos++; + } else { + s9 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c8); } + } + if (s9 !== peg$FAILED) { + s10 = peg$parsesep(); + if (s10 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 62) { + s11 = peg$c9; + peg$currPos++; + } else { + s11 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c10); } + } + if (s11 !== peg$FAILED) { + s12 = peg$parsesep(); + if (s12 !== peg$FAILED) { + s13 = peg$parseordered(); + if (s13 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c11(s3, s7, s13); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$parsefiltered(); + } + + return s0; + } + + function peg$parsefiltered() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + s1 = peg$parsestream(); + if (s1 !== peg$FAILED) { + s2 = []; + s3 = peg$parsefilter(); + if (s3 !== peg$FAILED) { + while (s3 !== peg$FAILED) { + s2.push(s3); + s3 = peg$parsefilter(); + } + } else { + s2 = peg$c0; + } + if (s2 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c13(s1, s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsestream(); + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c14(s1); + } + s0 = s1; + } + + return s0; + } + + function peg$parsestream() { + var s0, s1, s2, s3, s4; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 40) { + s1 = peg$c15; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c16); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parsemerged(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 41) { + s3 = peg$c17; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c18); } + } + if (s3 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c19(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 64) { + s1 = peg$c20; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c21); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parsename(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s3 = peg$c22; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c23); } + } + if (s3 !== peg$FAILED) { + s4 = peg$parseeventType(); + if (s4 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c24(s2, s4); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsemarkType(); + if (s1 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s2 = peg$c22; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c23); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parseeventType(); + if (s3 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c25(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsecss(); + if (s1 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 58) { + s2 = peg$c22; + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c23); } + } + if (s2 !== peg$FAILED) { + s3 = peg$parseeventType(); + if (s3 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c26(s1, s3); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parseeventType(); + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c27(s1); + } + s0 = s1; + if (s0 === peg$FAILED) { + s0 = peg$currPos; + s1 = peg$parsename(); + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c28(s1); + } + s0 = s1; + } + } + } + } + } + + return s0; + } + + function peg$parsemarkType() { + var s0; + + if (input.substr(peg$currPos, 4) === peg$c29) { + s0 = peg$c29; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c30); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 6) === peg$c31) { + s0 = peg$c31; + peg$currPos += 6; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c32); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c33) { + s0 = peg$c33; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c34); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 3) === peg$c35) { + s0 = peg$c35; + peg$currPos += 3; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c36); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c37) { + s0 = peg$c37; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c38); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c39) { + s0 = peg$c39; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c40); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c41) { + s0 = peg$c41; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c42); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c43) { + s0 = peg$c43; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c44); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 4) === peg$c45) { + s0 = peg$c45; + peg$currPos += 4; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c46); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c47) { + s0 = peg$c47; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c48); } + } + } + } + } + } + } + } + } + } + } + + return s0; + } + + function peg$parseeventType() { + var s0; + + if (input.substr(peg$currPos, 9) === peg$c49) { + s0 = peg$c49; + peg$currPos += 9; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c50); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 7) === peg$c51) { + s0 = peg$c51; + peg$currPos += 7; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c52); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c53) { + s0 = peg$c53; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c54); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 8) === peg$c55) { + s0 = peg$c55; + peg$currPos += 8; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c56); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c57) { + s0 = peg$c57; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c58); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 7) === peg$c59) { + s0 = peg$c59; + peg$currPos += 7; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c60); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 8) === peg$c61) { + s0 = peg$c61; + peg$currPos += 8; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c62); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 5) === peg$c63) { + s0 = peg$c63; + peg$currPos += 5; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c64); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 10) === peg$c65) { + s0 = peg$c65; + peg$currPos += 10; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c66); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 9) === peg$c67) { + s0 = peg$c67; + peg$currPos += 9; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c68); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 8) === peg$c69) { + s0 = peg$c69; + peg$currPos += 8; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c70); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 9) === peg$c71) { + s0 = peg$c71; + peg$currPos += 9; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c72); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 10) === peg$c73) { + s0 = peg$c73; + peg$currPos += 10; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c74); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 10) === peg$c75) { + s0 = peg$c75; + peg$currPos += 10; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c76); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 9) === peg$c77) { + s0 = peg$c77; + peg$currPos += 9; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c78); } + } + if (s0 === peg$FAILED) { + if (input.substr(peg$currPos, 8) === peg$c79) { + s0 = peg$c79; + peg$currPos += 8; + } else { + s0 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c80); } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + } + + return s0; + } + + function peg$parsefilter() { + var s0, s1, s2, s3; + + s0 = peg$currPos; + if (input.charCodeAt(peg$currPos) === 91) { + s1 = peg$c5; + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c6); } + } + if (s1 !== peg$FAILED) { + s2 = peg$parseexpr(); + if (s2 !== peg$FAILED) { + if (input.charCodeAt(peg$currPos) === 93) { + s3 = peg$c7; + peg$currPos++; + } else { + s3 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c8); } + } + if (s3 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c81(s2); + s0 = s1; + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + } else { + peg$currPos = s0; + s0 = peg$c0; + } + + return s0; + } + + function peg$parsename() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = []; + if (peg$c82.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c83); } + } + if (s2 !== peg$FAILED) { + while (s2 !== peg$FAILED) { + s1.push(s2); + if (peg$c82.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c83); } + } + } + } else { + s1 = peg$c0; + } + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c84(s1); + } + s0 = s1; + + return s0; + } + + function peg$parsecss() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = []; + if (peg$c85.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c86); } + } + if (s2 !== peg$FAILED) { + while (s2 !== peg$FAILED) { + s1.push(s2); + if (peg$c85.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c86); } + } + } + } else { + s1 = peg$c0; + } + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c87(s1); + } + s0 = s1; + + return s0; + } + + function peg$parseexpr() { + var s0, s1, s2; + + s0 = peg$currPos; + s1 = []; + if (peg$c88.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c89); } + } + if (s2 !== peg$FAILED) { + while (s2 !== peg$FAILED) { + s1.push(s2); + if (peg$c88.test(input.charAt(peg$currPos))) { + s2 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s2 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c89); } + } + } + } else { + s1 = peg$c0; + } + if (s1 !== peg$FAILED) { + peg$reportedPos = s0; + s1 = peg$c90(s1); + } + s0 = s1; + + return s0; + } + + function peg$parsesep() { + var s0, s1; + + s0 = []; + if (peg$c91.test(input.charAt(peg$currPos))) { + s1 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c92); } + } + while (s1 !== peg$FAILED) { + s0.push(s1); + if (peg$c91.test(input.charAt(peg$currPos))) { + s1 = input.charAt(peg$currPos); + peg$currPos++; + } else { + s1 = peg$FAILED; + if (peg$silentFails === 0) { peg$fail(peg$c92); } + } + } + + return s0; + } + + peg$result = peg$startRuleFunction(); + + if (peg$result !== peg$FAILED && peg$currPos === input.length) { + return peg$result; + } else { + if (peg$result !== peg$FAILED && peg$currPos < input.length) { + peg$fail({ type: "end", description: "end of input" }); + } + + throw peg$buildException(null, peg$maxFailExpected, peg$maxFailPos); + } + } + + return { + SyntaxError: SyntaxError, + parse: parse + }; + })(); +},{}],96:[function(require,module,exports){ + var expr = require('vega-expression'), + args = ['datum', 'event', 'signals']; + + module.exports = expr.compiler(args, { + idWhiteList: args, + fieldVar: args[0], + globalVar: args[2], + functions: function(codegen) { + var fn = expr.functions(codegen); + fn.eventItem = function() { return 'event.vg.item'; }; + fn.eventGroup = 'event.vg.getGroup'; + fn.eventX = 'event.vg.getX'; + fn.eventY = 'event.vg.getY'; + fn.open = 'window.open'; + return fn; + } + }); +},{"vega-expression":45}],97:[function(require,module,exports){ + module.exports = { + axes: require('./axes'), + background: require('./background'), + data: require('./data'), + events: require('./events'), + expr: require('./expr'), + legends: require('./legends'), + mark: require('./mark'), + marks: require('./marks'), + modify: require('./modify'), + padding: require('./padding'), + predicates: require('./predicates'), + properties: require('./properties'), + signals: require('./signals'), + spec: require('./spec'), + streams: require('./streams'), + transforms: require('./transforms') + }; +},{"./axes":92,"./background":93,"./data":94,"./events":95,"./expr":96,"./legends":98,"./mark":99,"./marks":100,"./modify":101,"./padding":102,"./predicates":103,"./properties":104,"./signals":105,"./spec":106,"./streams":107,"./transforms":108}],98:[function(require,module,exports){ + var lgnd = require('../scene/legend'); + + function parseLegends(model, spec, legends, group) { + (spec || []).forEach(function(def, index) { + legends[index] = legends[index] || lgnd(model); + parseLegend(def, index, legends[index], group); + }); + } + + function parseLegend(def, index, legend, group) { + // legend scales + legend.size (def.size ? group.scale(def.size) : null); + legend.shape (def.shape ? group.scale(def.shape) : null); + legend.fill (def.fill ? group.scale(def.fill) : null); + legend.stroke(def.stroke ? group.scale(def.stroke) : null); + + // legend orientation + if (def.orient) legend.orient(def.orient); + + // legend offset + if (def.offset != null) legend.offset(def.offset); + + // legend title + legend.title(def.title || null); + + // legend values + legend.values(def.values || null); + + // legend label formatting + legend.format(def.format !== undefined ? def.format : null); + + // style properties + var p = def.properties; + legend.titleProperties(p && p.title || {}); + legend.labelProperties(p && p.labels || {}); + legend.legendProperties(p && p.legend || {}); + legend.symbolProperties(p && p.symbols || {}); + legend.gradientProperties(p && p.gradient || {}); + } + + module.exports = parseLegends; +},{"../scene/legend":116}],99:[function(require,module,exports){ + var dl = require('datalib'), + parseProperties = require('./properties'); + + function parseMark(model, mark) { + var props = mark.properties, + group = mark.marks; + + // parse mark property definitions + dl.keys(props).forEach(function(k) { + props[k] = parseProperties(model, mark.type, props[k]); + }); + + // parse delay function + if (mark.delay) { + mark.delay = parseProperties(model, mark.type, {delay: mark.delay}); + } + + // recurse if group type + if (group) { + mark.marks = group.map(function(g) { return parseMark(model, g); }); + } + + return mark; + } + + module.exports = parseMark; +},{"./properties":104,"datalib":26}],100:[function(require,module,exports){ + var parseMark = require('./mark'), + parseProperties = require('./properties'); + + function parseRootMark(model, spec, width, height) { + return { + type: 'group', + width: width, + height: height, + properties: defaults(spec.scene || {}, model), + scales: spec.scales || [], + axes: spec.axes || [], + legends: spec.legends || [], + marks: (spec.marks || []).map(function(m) { return parseMark(model, m); }) + }; + } + + var PROPERTIES = [ + 'fill', 'fillOpacity', 'stroke', 'strokeOpacity', + 'strokeWidth', 'strokeDash', 'strokeDashOffset' + ]; + + function defaults(spec, model) { + var config = model.config().scene, + props = {}, i, n, m, p, s; + + for (i=0, n=m=PROPERTIES.length; i= 0; --i) { + if (src[i][field] == value) + dest.push.apply(dest, src.splice(i, 1)); + } + }; + + function parseModify(model, def, ds) { + var signal = def.signal ? dl.field(def.signal) : null, + signalName = signal ? signal[0] : null, + predicate = def.predicate ? model.predicate(def.predicate.name || def.predicate) : null, + reeval = (predicate === null), + isClear = def.type === Types.CLEAR, + node = new Node(model).router(isClear); + + node.evaluate = function(input) { + if (predicate !== null) { // TODO: predicate args + var db = model.values(Deps.DATA, predicate.data || EMPTY), + sg = model.values(Deps.SIGNALS, predicate.signals || EMPTY); + reeval = predicate.call(predicate, {}, db, sg, model._predicates); + } + + log.debug(input, [def.type+"ing", reeval]); + if (!reeval || (!isClear && !input.signals[signalName])) return input; + + var datum = {}, + value = signal ? model.signalRef(def.signal) : null, + d = model.data(ds.name), + t = null; + + datum[def.field] = value; + + // We have to modify ds._data so that subsequent pulses contain + // our dynamic data. W/o modifying ds._data, only the output + // collector will contain dynamic tuples. + if (def.type === Types.INSERT) { + t = Tuple.ingest(datum); + input.add.push(t); + d._data.push(t); + } else if (def.type === Types.REMOVE) { + filter(def.field, value, input.add, input.rem); + filter(def.field, value, input.mod, input.rem); + d._data = d._data.filter(function(x) { return x[def.field] !== value; }); + } else if (def.type === Types.TOGGLE) { + var add = [], rem = []; + filter(def.field, value, input.rem, add); + filter(def.field, value, input.add, rem); + filter(def.field, value, input.mod, rem); + if (!(add.length || rem.length)) add.push(Tuple.ingest(datum)); + + input.add.push.apply(input.add, add); + d._data.push.apply(d._data, add); + input.rem.push.apply(input.rem, rem); + d._data = d._data.filter(function(x) { return rem.indexOf(x) === -1; }); + } else if (def.type === Types.CLEAR) { + input.rem.push.apply(input.rem, input.add); + input.rem.push.apply(input.rem, input.mod); + input.add = []; + input.mod = []; + d._data = []; + } + + input.fields[def.field] = 1; + return input; + }; + + if (signalName) node.dependency(Deps.SIGNALS, signalName); + + if (predicate) { + node.dependency(Deps.DATA, predicate.data); + node.dependency(Deps.SIGNALS, predicate.signals); + } + + return node; + } + + module.exports = parseModify; +},{"datalib":26,"vega-dataflow":41,"vega-logging":47}],102:[function(require,module,exports){ + var dl = require('datalib'); + + function parsePadding(pad) { + return pad == null ? 'auto' : + dl.isObject(pad) ? pad : + dl.isNumber(pad) ? {top:pad, left:pad, right:pad, bottom:pad} : + pad === 'strict' ? pad : 'auto'; + } + + module.exports = parsePadding; +},{"datalib":26}],103:[function(require,module,exports){ + var dl = require('datalib'); + + var types = { + '=': parseComparator, + '==': parseComparator, + '!=': parseComparator, + '>': parseComparator, + '>=': parseComparator, + '<': parseComparator, + '<=': parseComparator, + 'and': parseLogical, + '&&': parseLogical, + 'or': parseLogical, + '||': parseLogical, + 'in': parseIn + }; + + var nullScale = function() { return 0; }; + nullScale.invert = nullScale; + + function parsePredicates(model, spec) { + (spec || []).forEach(function(s) { + var parse = types[s.type](model, s); + + /* jshint evil:true */ + var pred = Function("args", "db", "signals", "predicates", parse.code); + pred.root = function() { return model.scene().items[0]; }; // For global scales + pred.nullScale = nullScale; + pred.isFunction = dl.isFunction; + pred.signals = parse.signals; + pred.data = parse.data; + + model.predicate(s.name, pred); + }); + + return spec; + } + + function parseSignal(signal, signals) { + var s = dl.field(signal), + code = "signals["+s.map(dl.str).join("][")+"]"; + signals[s[0]] = 1; + return code; + } + + function parseOperands(model, operands) { + var decl = [], defs = [], + signals = {}, db = {}; + + function setSignal(s) { signals[s] = 1; } + function setData(d) { db[d] = 1; } + + dl.array(operands).forEach(function(o, i) { + var name = "o" + i, + def = ""; + + if (o.value !== undefined) { + def = dl.str(o.value); + } else if (o.arg) { + def = "args["+dl.str(o.arg)+"]"; + } else if (o.signal) { + def = parseSignal(o.signal, signals); + } else if (o.predicate) { + var ref = o.predicate, + predName = ref && (ref.name || ref), + pred = model.predicate(predName), + p = "predicates["+dl.str(predName)+"]"; + + pred.signals.forEach(setSignal); + pred.data.forEach(setData); + + if (dl.isObject(ref)) { + dl.keys(ref).forEach(function(k) { + if (k === "name") return; + var i = ref[k]; + def += "args["+dl.str(k)+"] = "; + if (i.signal) { + def += parseSignal(i.signal, signals); + } else if (i.arg) { + def += "args["+dl.str(i.arg)+"]"; + } + def += ", "; + }); + } + + def += p+".call("+p+", args, db, signals, predicates)"; + } + + decl.push(name); + defs.push(name+"=("+def+")"); + }); + + return { + code: "var " + decl.join(", ") + ";\n" + defs.join(";\n") + ";\n", + signals: dl.keys(signals), + data: dl.keys(db) + }; + } + + function parseComparator(model, spec) { + var ops = parseOperands(model, spec.operands); + if (spec.type === '=') spec.type = '=='; + + ops.code += "o0 = o0 instanceof Date ? o0.getTime() : o0;\n" + + "o1 = o1 instanceof Date ? o1.getTime() : o1;\n"; + + return { + code: ops.code + "return " + ["o0", "o1"].join(spec.type) + ";", + signals: ops.signals, + data: ops.data + }; + } + + function parseLogical(model, spec) { + var ops = parseOperands(model, spec.operands), + o = [], i = 0, len = spec.operands.length; + + while (o.push("o"+i++) < len); + if (spec.type === 'and') spec.type = '&&'; + else if (spec.type === 'or') spec.type = '||'; + + return { + code: ops.code + "return " + o.join(spec.type) + ";", + signals: ops.signals, + data: ops.data + }; + } + + function parseIn(model, spec) { + var o = [spec.item], code = ""; + if (spec.range) o.push.apply(o, spec.range); + if (spec.scale) { + code = parseScale(spec.scale, o); + } + + var ops = parseOperands(model, o); + code = ops.code + code + "\n var ordSet = null;\n"; + + if (spec.data) { + var field = dl.field(spec.field).map(dl.str); + code += "var where = function(d) { return d["+field.join("][")+"] == o0 };\n"; + code += "return db["+dl.str(spec.data)+"].filter(where).length > 0;"; + } else if (spec.range) { + // TODO: inclusive/exclusive range? + if (spec.scale) { + code += "if (scale.length == 2) {\n" + // inverting ordinal scales + " ordSet = scale(o1, o2);\n" + + "} else {\n" + + " o1 = scale(o1);\no2 = scale(o2);\n" + + "}"; + } + + code += "return ordSet !== null ? ordSet.indexOf(o0) !== -1 :\n" + + " o1 < o2 ? o1 <= o0 && o0 <= o2 : o2 <= o0 && o0 <= o1;"; + } + + return { + code: code, + signals: ops.signals, + data: ops.data.concat(spec.data ? [spec.data] : []) + }; + } + +// Populate ops such that ultimate scale/inversion function will be in `scale` var. + function parseScale(spec, ops) { + var code = "var scale = ", + idx = ops.length; + + if (dl.isString(spec)) { + ops.push({ value: spec }); + code += "this.root().scale(o"+idx+")"; + } else if (spec.arg) { // Scale function is being passed as an arg + ops.push(spec); + code += "o"+idx; + } else if (spec.name) { // Full scale parameter {name: ..} + ops.push(dl.isString(spec.name) ? {value: spec.name} : spec.name); + code += "(this.isFunction(o"+idx+") ? o"+idx+" : "; + if (spec.scope) { + ops.push(spec.scope); + code += "((o"+(idx+1)+".scale || this.root().scale)(o"+idx+") || this.nullScale)"; + } else { + code += "this.root().scale(o"+idx+")"; + } + code += ")"; + } + + if (spec.invert === true) { // Allow spec.invert.arg? + code += ".invert"; + } + + return code+";\n"; + } + + module.exports = parsePredicates; +},{"datalib":26}],104:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + log = require('vega-logging'), + Tuple = require('vega-dataflow').Tuple; + + var DEPS = ["signals", "scales", "data", "fields"]; + + function properties(model, mark, spec) { + var config = model.config(), + code = "", + names = dl.keys(spec), + i, len, name, ref, vars = {}, + deps = { + signals: {}, + scales: {}, + data: {}, + fields: {}, + nested: [], + _nRefs: {}, // Temp stash to de-dupe nested refs. + reflow: false + }; + + code += "var o = trans ? {} : item, d=0, set=this.tpl.set, tmpl=signals||{}, t;\n" + + // Stash for dl.template + "tmpl.datum = item.datum;\n" + + "tmpl.group = group;\n" + + "tmpl.parent = group.datum;\n"; + + function handleDep(p) { + if (ref[p] == null) return; + var k = dl.array(ref[p]), i, n; + for (i=0, n=k.length; i 0) ? "\n " : " "; + if (ref.rule) { + ref = rule(model, name, ref.rule); + code += "\n " + ref.code; + } else if (dl.isArray(ref)) { + ref = rule(model, name, ref); + code += "\n " + ref.code; + } else { + ref = valueRef(config, name, ref); + code += "d += set(o, "+dl.str(name)+", "+ref.val+");"; + } + + vars[name] = true; + DEPS.forEach(handleDep); + deps.reflow = deps.reflow || ref.reflow; + if (ref.nested.length) ref.nested.forEach(handleNestedRefs); + } + + // If nested references are present, sort them based on their level + // to speed up determination of whether encoders should be reeval'd. + dl.keys(deps._nRefs).forEach(function(k) { deps.nested.push(deps._nRefs[k]); }); + deps.nested.sort(function(a, b) { + a = a.level; + b = b.level; + return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; + }); + + if (vars.x2) { + if (vars.x) { + code += "\n if (o.x > o.x2) { " + + "\n t = o.x;" + + "\n d += set(o, 'x', o.x2);" + + "\n d += set(o, 'x2', t); " + + "\n };"; + code += "\n d += set(o, 'width', (o.x2 - o.x));"; + } else if (vars.width) { + code += "\n d += set(o, 'x', (o.x2 - o.width));"; + } else { + code += "\n d += set(o, 'x', o.x2);"; + } + } + + if (vars.xc) { + if (vars.width) { + code += "\n d += set(o, 'x', (o.xc - o.width/2));" ; + } else { + code += "\n d += set(o, 'x', o.xc);" ; + } + } + + if (vars.y2) { + if (vars.y) { + code += "\n if (o.y > o.y2) { " + + "\n t = o.y;" + + "\n d += set(o, 'y', o.y2);" + + "\n d += set(o, 'y2', t);" + + "\n };"; + code += "\n d += set(o, 'height', (o.y2 - o.y));"; + } else if (vars.height) { + code += "\n d += set(o, 'y', (o.y2 - o.height));"; + } else { + code += "\n d += set(o, 'y', o.y2);"; + } + } + + if (vars.yc) { + if (vars.height) { + code += "\n d += set(o, 'y', (o.yc - o.height/2));" ; + } else { + code += "\n d += set(o, 'y', o.yc);" ; + } + } + + if (hasPath(mark, vars)) code += "\n d += (item.touch(), 1);"; + code += "\n if (trans) trans.interpolate(item, o);"; + code += "\n return d > 0;"; + + try { + /* jshint evil:true */ + var encoder = Function('item', 'group', 'trans', 'db', + 'signals', 'predicates', code); + encoder.tpl = Tuple; + encoder.util = dl; + encoder.d3 = d3; // For color spaces + dl.extend(encoder, dl.template.context); + return { + encode: encoder, + signals: dl.keys(deps.signals), + scales: dl.keys(deps.scales), + data: dl.keys(deps.data), + fields: dl.keys(deps.fields), + nested: deps.nested, + reflow: deps.reflow + }; + } catch (e) { + log.error(e); + log.log(code); + } + } + + function dependencies(a, b) { + if (!dl.isObject(a)) { + a = {reflow: false, nested: []}; + DEPS.forEach(function(d) { a[d] = []; }); + } + + if (dl.isObject(b)) { + a.reflow = a.reflow || b.reflow; + a.nested.push.apply(a.nested, b.nested); + DEPS.forEach(function(d) { a[d].push.apply(a[d], b[d]); }); + } + + return a; + } + + function hasPath(mark, vars) { + return vars.path || + ((mark==='area' || mark==='line') && + (vars.x || vars.x2 || vars.width || + vars.y || vars.y2 || vars.height || + vars.tension || vars.interpolate)); + } + + function rule(model, name, rules) { + var config = model.config(), + deps = dependencies(), + inputs = [], code = ''; + + (rules||[]).forEach(function(r, i) { + var def = r.predicate, + predName = def && (def.name || def), + pred = model.predicate(predName), + p = 'predicates['+dl.str(predName)+']', + input = [], args = name+'_arg'+i, + ref; + + if (dl.isObject(def)) { + dl.keys(def).forEach(function(k) { + if (k === 'name') return; + var ref = valueRef(config, i, def[k]); + input.push(dl.str(k)+': '+ref.val); + dependencies(deps, ref); + }); + } + + ref = valueRef(config, name, r); + dependencies(deps, ref); + + if (predName) { + deps.signals.push.apply(deps.signals, pred.signals); + deps.data.push.apply(deps.data, pred.data); + inputs.push(args+" = {\n "+input.join(",\n ")+"\n }"); + code += "if ("+p+".call("+p+","+args+", db, signals, predicates)) {" + + "\n d += set(o, "+dl.str(name)+", "+ref.val+");"; + code += rules[i+1] ? "\n } else " : " }"; + } else { + code += "{" + + "\n d += set(o, "+dl.str(name)+", "+ref.val+");"+ + "\n }\n"; + } + }); + + code = "var " + inputs.join(",\n ") + ";\n " + code; + return (deps.code = code, deps); + } + + function valueRef(config, name, ref) { + if (ref == null) return null; + + if (name==='fill' || name==='stroke') { + if (ref.c) { + return colorRef(config, 'hcl', ref.h, ref.c, ref.l); + } else if (ref.h || ref.s) { + return colorRef(config, 'hsl', ref.h, ref.s, ref.l); + } else if (ref.l || ref.a) { + return colorRef(config, 'lab', ref.l, ref.a, ref.b); + } else if (ref.r || ref.g || ref.b) { + return colorRef(config, 'rgb', ref.r, ref.g, ref.b); + } + } + + // initialize value + var val = null, scale = null, + deps = dependencies(), + sgRef = null, fRef = null, sRef = null, tmpl = {}; + + if (ref.template !== undefined) { + val = dl.template.source(ref.template, 'tmpl', tmpl); + dl.keys(tmpl).forEach(function(k) { + var f = dl.field(k), + a = f.shift(); + if (a === 'parent' || a === 'group') { + deps.nested.push({ + parent: a === 'parent', + group: a === 'group', + level: 1 + }); + } else if (a === 'datum') { + deps.fields.push(f[0]); + } else { + deps.signals.push(a); + } + }); + } + + if (ref.value !== undefined) { + val = dl.str(ref.value); + } + + if (ref.signal !== undefined) { + sgRef = dl.field(ref.signal); + val = 'signals['+sgRef.map(dl.str).join('][')+']'; + deps.signals.push(sgRef.shift()); + } + + if (ref.field !== undefined) { + ref.field = dl.isString(ref.field) ? {datum: ref.field} : ref.field; + fRef = fieldRef(ref.field); + val = fRef.val; + dependencies(deps, fRef); + } + + if (ref.scale !== undefined) { + sRef = scaleRef(ref.scale); + scale = sRef.val; + dependencies(deps, sRef); + deps.scales.push(ref.scale.name || ref.scale); + + // run through scale function if val specified. + // if no val, scale function is predicate arg. + if (val !== null || ref.band || ref.mult || ref.offset) { + val = scale + (ref.band ? '.rangeBand()' : + '('+(val !== null ? val : 'item.datum.data')+')'); + } else { + val = scale; + } + } + + // multiply, offset, return value + val = '(' + (ref.mult?(dl.number(ref.mult)+' * '):'') + val + ')' + + (ref.offset ? ' + ' + dl.number(ref.offset) : ''); + + // Collate dependencies + return (deps.val = val, deps); + } + + function colorRef(config, type, x, y, z) { + var xx = x ? valueRef(config, '', x) : config.color[type][0], + yy = y ? valueRef(config, '', y) : config.color[type][1], + zz = z ? valueRef(config, '', z) : config.color[type][2], + deps = dependencies(); + + [xx, yy, zz].forEach(function(v) { + if (dl.isArray) return; + dependencies(deps, v); + }); + + var val = '(this.d3.' + type + '(' + [xx.val, yy.val, zz.val].join(',') + ') + "")'; + return (deps.val = val, deps); + } + +// {field: {datum: "foo"} } -> item.datum.foo +// {field: {group: "foo"} } -> group.foo +// {field: {parent: "foo"} } -> group.datum.foo + function fieldRef(ref) { + if (dl.isString(ref)) { + return {val: dl.field(ref).map(dl.str).join('][')}; + } + + // Resolve nesting/parent lookups + var l = ref.level || 1, + nested = (ref.group || ref.parent) && l, + scope = nested ? Array(l).join('group.mark.') : '', + r = fieldRef(ref.datum || ref.group || ref.parent || ref.signal), + val = r.val, + deps = dependencies(null, r); + + if (ref.datum) { + val = 'item.datum['+val+']'; + deps.fields.push(ref.datum); + } else if (ref.group) { + val = scope+'group['+val+']'; + deps.nested.push({ level: l, group: true }); + } else if (ref.parent) { + val = scope+'group.datum['+val+']'; + deps.nested.push({ level: l, parent: true }); + } else if (ref.signal) { + val = 'signals['+val+']'; + deps.signals.push(dl.field(ref.signal)[0]); + deps.reflow = true; + } + + return (deps.val = val, deps); + } + +// {scale: "x"} +// {scale: {name: "x"}}, +// {scale: fieldRef} + function scaleRef(ref) { + var scale = null, + fr = null, + deps = dependencies(); + + if (dl.isString(ref)) { + scale = dl.str(ref); + } else if (ref.name) { + scale = dl.isString(ref.name) ? dl.str(ref.name) : (fr = fieldRef(ref.name)).val; + } else { + scale = (fr = fieldRef(ref)).val; + } + + scale = '(item.mark._scaleRefs['+scale+'] = 1, group.scale('+scale+'))'; + if (ref.invert) scale += '.invert'; + + // Mark scale refs as they're dealt with separately in mark._scaleRefs. + if (fr) fr.nested.forEach(function(g) { g.scale = true; }); + return fr ? (fr.val = scale, fr) : (deps.val = scale, deps); + } + + module.exports = properties; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"datalib":26,"vega-dataflow":41,"vega-logging":47}],105:[function(require,module,exports){ + var dl = require('datalib'), + SIGNALS = require('vega-dataflow').Dependencies.SIGNALS, + expr = require('./expr'); + + var RESERVED = ['datum', 'event', 'signals', 'width', 'height', 'padding'] + .concat(dl.keys(expr.codegen.functions)); + + function parseSignals(model, spec) { + // process each signal definition + (spec || []).forEach(function(s) { + if (RESERVED.indexOf(s.name) !== -1) { + throw Error('Signal name "'+s.name+'" is a '+ + 'reserved keyword ('+RESERVED.join(', ')+').'); + } + + var signal = model.signal(s.name, s.init) + .verbose(s.verbose); + + if (s.init && s.init.expr) { + s.init.expr = expr(s.init.expr); + signal.value(exprVal(model, s.init)); + } + + if (s.expr) { + s.expr = expr(s.expr); + signal.evaluate = function(input) { + var val = exprVal(model, s), + sg = input.signals; + if (val !== signal.value() || signal.verbose()) { + signal.value(val); + sg[s.name] = 1; + } + return sg[s.name] ? input : model.doNotPropagate; + }; + signal.dependency(SIGNALS, s.expr.globals); + s.expr.globals.forEach(function(dep) { + model.signal(dep).addListener(signal); + }); + } + }); + + return spec; + } + + function exprVal(model, spec) { + var e = spec.expr, + val = e.fn(null, null, model.values(SIGNALS, e.globals)); + return spec.scale ? parseSignals.scale(model, spec, val) : val; + } + + parseSignals.scale = function scale(model, spec, value, datum, evt) { + var def = spec.scale, + name = def.name || def.signal || def, + scope = def.scope, e; + + if (scope) { + if (scope.signal) { + scope = model.signalRef(scope.signal); + } else if (dl.isString(scope)) { // Scope is an expression + e = def._expr = (def._expr || expr(scope)); + scope = e.fn(datum, evt, model.values(SIGNALS, e.globals)); + } + } + + if (!scope || !scope.scale) { + scope = (scope && scope.mark) ? scope.mark.group : model.scene().items[0]; + } + + var s = scope.scale(name); + return !s ? value : (def.invert ? s.invert(value) : s(value)); + }; + + module.exports = parseSignals; +},{"./expr":96,"datalib":26,"vega-dataflow":41}],106:[function(require,module,exports){ + var dl = require('datalib'), + log = require('vega-logging'), + Model = require('../core/Model'), + View = require('../core/View'); + + function parseSpec(spec, callback) { + var vf = arguments[arguments.length-1], + viewFactory = arguments.length > 2 && dl.isFunction(vf) ? vf : View.factory, + config = arguments[2] !== viewFactory ? arguments[2] : {}, + model = new Model(config); + + function parse(spec) { + // protect against subsequent spec modification + spec = dl.duplicate(spec); + + var parsers = require('./'), + create = function() { callback(viewFactory(model)); }, + width = spec.width || 500, + height = spec.height || 500, + padding = parsers.padding(spec.padding); + + // create signals for width, height and padding + model.signal('width', width); + model.signal('height', height); + model.signal('padding', padding); + + // initialize model + model.defs({ + width: width, + height: height, + padding: padding, + viewport: spec.viewport || null, + background: parsers.background(spec.background), + signals: parsers.signals(model, spec.signals), + predicates: parsers.predicates(model, spec.predicates), + marks: parsers.marks(model, spec, width, height), + data: parsers.data(model, spec.data, create) + }); + } + + if (dl.isObject(spec)) { + parse(spec); + } else if (dl.isString(spec)) { + var opts = dl.extend({url: spec}, model.config().load); + dl.load(opts, function(err, data) { + if (err) { + log.error('LOADING SPECIFICATION FAILED: ' + err.statusText); + } else { + try { + parse(JSON.parse(data)); + } catch (e) { + log.error('INVALID SPECIFICATION: Must be a valid JSON object. '+e); + } + } + }); + } else { + log.error('INVALID SPECIFICATION: Must be a valid JSON object or URL.'); + } + } + + module.exports = parseSpec; +},{"../core/Model":88,"../core/View":89,"./":97,"datalib":26,"vega-logging":47}],107:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + df = require('vega-dataflow'), + SIGNALS = df.Dependencies.SIGNALS, + parseSignals = require('./signals'), + selector = require('./events'), + expr = require('./expr'); + + var GATEKEEPER = '_vgGATEKEEPER'; + + var vgEvent = { + getGroup: function(name) { return name ? this.name[name] : this.group; }, + getXY: function(item) { + var p = {x: this.x, y: this.y}; + if (typeof item === 'string') { + item = this.name[item]; + } + for (; item; item = item.mark && item.mark.group) { + p.x -= item.x || 0; + p.y -= item.y || 0; + } + return p; + }, + getX: function(item) { return this.getXY(item).x; }, + getY: function(item) { return this.getXY(item).y; } + }; + + function parseStreams(view) { + var model = view.model(), + spec = model.defs().signals, + registry = {handlers: {}, nodes: {}}, + internal = dl.duplicate(registry), // Internal event processing + external = dl.duplicate(registry); // External event processing + + (spec || []).forEach(function(sig) { + var signal = model.signal(sig.name); + if (sig.expr) return; // Cannot have an expr and stream definition. + + (sig.streams || []).forEach(function(stream) { + var sel = selector.parse(stream.type), + exp = expr(stream.expr); + mergedStream(signal, sel, exp, stream); + }); + }); + + // We register the event listeners all together so that if multiple + // signals are registered on the same event, they will receive the + // new value on the same pulse. + dl.keys(internal.handlers).forEach(function(type) { + view.on(type, function(evt, item) { + evt.preventDefault(); // stop text selection + extendEvent(evt, item); + fire(internal, type, (item && item.datum) || {}, evt); + }); + }); + + // add external event listeners + dl.keys(external.handlers).forEach(function(type) { + if (typeof window === 'undefined') return; // No external support + + var h = external.handlers[type], + t = type.split(':'), // --> no element pseudo-selectors + elt = (t[0] === 'window') ? [window] : + window.document.querySelectorAll(t[0]); + + function handler(evt) { + extendEvent(evt); + fire(external, type, d3.select(this).datum(), evt); + } + + for (var i=0; i 0, + i, ilen, j, jlen, group, legend; + + if (input.add.length || input.rem.length || !items.length || + input.mod.length === items.length || + type === 'area' || type === 'line') { + bound.mark(this._mark, null, isGrp && !hasLegends); + } else { + input.mod.forEach(function(item) { bound.item(item); }); + } + + if (isGrp && hasLegends) { + for (i=0, ilen=items.length; i this._stamp) { + join.call(this, fcs, output, this._ds.values(), true, fullUpdate); + } else if (fullUpdate) { + output.mod = this._mark.items.slice(); + } + } else { + data = dl.isFunction(this._def.from) ? this._def.from() : [Sentinel]; + join.call(this, input, output, data); + } + + // Stash output before Bounder for downstream reactive geometry. + this._output = output = this._graph.evaluate(output, this._encoder); + + // Add any new scale references to the dependency list, and ensure + // they're connected. + if (update.nested && update.nested.length && this._status === CONNECTED) { + dl.keys(this._mark._scaleRefs).forEach(function(s) { + var scale = self._parent.scale(s); + if (!scale) return; + + scale.addListener(self); + self.dependency(Deps.SCALES, s); + self._encoder.dependency(Deps.SCALES, s); + }); + } + + // Supernodes calculate bounds too, but only on items marked dirty. + if (this._isSuper) { + output.mod = output.mod.filter(function(x) { return x._dirty; }); + output = this._graph.evaluate(output, this._bounder); + } + + return output; + }; + + function newItem() { + var item = Tuple.ingest(new Item(this._mark)); + + // For the root node's item + if (this._def.width) Tuple.set(item, 'width', this._def.width); + if (this._def.height) Tuple.set(item, 'height', this._def.height); + return item; + } + + function join(input, output, data, ds, fullUpdate) { + var keyf = keyFunction(this._def.key || (ds ? '_id' : null)), + prev = this._mark.items || [], + rem = ds ? input.rem : prev, + mod = Tuple.idMap((!ds || fullUpdate) ? data : input.mod), + next = [], + i, key, len, item, datum, enter, diff; + + // Only mark rems as exiting. Due to keyf, there may be an add/mod + // tuple that replaces it. + for (i=0, len=rem.length; i0) s += '|'; + s += String(f[i](d)); + } + return s; + }; + } + + module.exports = Builder; +},{"../parse/data":94,"./Bounder":109,"./Encoder":111,"datalib":26,"vega-dataflow":41,"vega-logging":47,"vega-scenegraph":48}],111:[function(require,module,exports){ + var dl = require('datalib'), + log = require('vega-logging'), + df = require('vega-dataflow'), + Node = df.Node, // jshint ignore:line + Deps = df.Dependencies, + bound = require('vega-scenegraph').bound; + + var EMPTY = {}; + + function Encoder(graph, mark, builder) { + var props = mark.def.properties || {}, + enter = props.enter, + update = props.update, + exit = props.exit; + + Node.prototype.init.call(this, graph); + + this._mark = mark; + this._builder = builder; + var s = this._scales = []; + + // Only scales used in the 'update' property set are set as + // encoder depedencies to have targeted reevaluations. However, + // we still want scales in 'enter' and 'exit' to be evaluated + // before the encoder. + if (enter) s.push.apply(s, enter.scales); + + if (update) { + this.dependency(Deps.DATA, update.data); + this.dependency(Deps.SIGNALS, update.signals); + this.dependency(Deps.FIELDS, update.fields); + this.dependency(Deps.SCALES, update.scales); + s.push.apply(s, update.scales); + } + + if (exit) s.push.apply(s, exit.scales); + + return this.mutates(true); + } + + var proto = (Encoder.prototype = new Node()); + + proto.evaluate = function(input) { + log.debug(input, ['encoding', this._mark.def.type]); + var graph = this._graph, + props = this._mark.def.properties || {}, + items = this._mark.items, + enter = props.enter, + update = props.update, + exit = props.exit, + dirty = input.dirty, + preds = graph.predicates(), + req = input.request, + group = this._mark.group, + guide = group && (group.mark.axis || group.mark.legend), + db = EMPTY, sg = EMPTY, i, len, item, prop; + + if (req && !guide) { + if ((prop = props[req]) && input.mod.length) { + db = prop.data ? graph.values(Deps.DATA, prop.data) : null; + sg = prop.signals ? graph.values(Deps.SIGNALS, prop.signals) : null; + + for (i=0, len=input.mod.length; i this._stamp) return true; + } + + return false; + } + +// Short-circuit encoder if user specifies items + Encoder.update = function(graph, trans, request, items, dirty) { + items = dl.array(items); + var preds = graph.predicates(), + db = graph.values(Deps.DATA), + sg = graph.values(Deps.SIGNALS), + i, len, item, props, prop; + + for (i=0, len=items.length; i 0, + hasAxes = dl.array(this._def.axes).length > 0, + hasLegends = dl.array(this._def.legends).length > 0, + i, j, c, len, group, pipeline, def, inline = false; + + for (i=0, len=input.add.length; i=0; --i) { + group = input.add[i]; + for (j=this._children[group._id].length-1; j>=0; --j) { + c = this._children[group._id][j]; + c.builder.connect(); + pipeline = c.builder.pipeline(); + def = c.builder._def; + + // This new child needs to be built during this propagation cycle. + // We could add its builder as a listener off the _recursor node, + // but try to inline it if we can to minimize graph dispatches. + inline = (def.type !== Types.GROUP); + inline = inline && (this._graph.data(c.from) !== undefined); + inline = inline && (pipeline[pipeline.length-1].listeners().length === 1); // Reactive geom source + inline = inline && (def.from && !def.from.mark); // Reactive geom target + c.inline = inline; + + if (inline) this._graph.evaluate(input, c.builder); + else this._recursor.addListener(c.builder); + } + } + + function removeTemp(c) { + if (c.type == Types.MARK && !c.inline && + builder._graph.data(c.from) !== undefined) { + builder._recursor.removeListener(c.builder); + } + } + + function updateAxis(a) { + var scale = a.scale(); + if (!input.scales[scale.scaleName]) return; + a.reset().def(); + } + + function updateLegend(l) { + var scale = l.size() || l.shape() || l.fill() || l.stroke(); + if (!input.scales[scale.scaleName]) return; + l.reset().def(); + } + + for (i=0, len=input.mod.length; i rng[1]) { + start = rng[1] || 0; + rng = [start + (bw * len + space), start]; + } else { + start = rng[0] || 0; + rng = [start, start + (bw * len + space)]; + } + } + + str = typeof rng[0] === 'string'; + if (str || rng.length > 2 || rng.length===1 || dataDrivenRange) { + scale.range(rng); // color or shape values + spatial = false; + } else if (points && round) { + scale.rangeRoundPoints(rng, pad); + } else if (points) { + scale.rangePoints(rng, pad); + } else if (round) { + scale.rangeRoundBands(rng, pad, outer); + } else { + scale.rangeBands(rng, pad, outer); + } + + prev.range = rng; + this._updated = true; + } + + if (!scale.invert && spatial) invertOrdinal(scale); + } + +// "Polyfill" ordinal scale inversion. Currently, only ordinal scales +// with ordered numeric ranges are supported. + var bisect = d3.bisector(dl.numcmp).right, + findAsc = function(a, x) { return bisect(a,x) - 1; }, + findDsc = d3.bisector(function(a,b) { return -1 * dl.numcmp(a,b); }).left; + + function invertOrdinal(scale) { + scale.invert = function(x, y) { + var rng = scale.range(), + asc = rng[0] < rng[1], + find = asc ? findAsc : findDsc; + + if (arguments.length === 1) { + if (!dl.isNumber(x)) { + throw Error('Ordinal scale inversion is only supported for numeric input ('+x+').'); + } + return scale.domain()[find(rng, x)]; + + } else if (arguments.length === 2) { // Invert extents + if (!dl.isNumber(x) || !dl.isNumber(y)) { + throw Error('Extents to ordinal invert are not numbers ('+x+', '+y+').'); + } + + var domain = scale.domain(), + a = find(rng, x), + b = find(rng, y), + n = rng.length - 1, r; + if (b < a) { r = a; a = b; b = a; } // ensure a <= b + if (a < 0) a = 0; + if (b > n) b = n; + + return (asc ? dl.range(a, b+1) : dl.range(b, a-1, -1)) + .map(function(i) { return domain[i]; }); + } + }; + } + + function quantitative(scale, rng, group) { + var def = this._def, + prev = scale._prev, + round = signal.call(this, def.round), + exponent = signal.call(this, def.exponent), + clamp = signal.call(this, def.clamp), + nice = signal.call(this, def.nice), + domain, interval; + + // domain + domain = (def.type === Types.QUANTILE) ? + dataRef.call(this, DataRef.DOMAIN, def.domain, scale, group) : + domainMinMax.call(this, scale, group); + if (domain && !dl.equal(prev.domain, domain)) { + scale.domain(domain); + prev.domain = domain; + this._updated = true; + } + + // range + // vertical scales should flip by default, so use XOR here + if (signal.call(this, def.range) === 'height') rng = rng.reverse(); + if (dl.equal(prev.range, rng)) return; + scale[round && scale.rangeRound ? 'rangeRound' : 'range'](rng); + prev.range = rng; + this._updated = true; + + // TODO: Support signals for these properties. Until then, only eval + // them once. + if (this._stamp > 0) return; + if (exponent && def.type===Types.POWER) scale.exponent(exponent); + if (clamp) scale.clamp(true); + if (nice) { + if (def.type === Types.TIME) { + interval = d3.time[nice]; + if (!interval) log.error('Unrecognized interval: ' + interval); + scale.nice(interval); + } else { + scale.nice(); + } + } + } + + function isUniques(scale) { + return scale.type === Types.ORDINAL || scale.type === Types.QUANTILE; + } + + function getRefs(def) { + return def.fields || dl.array(def); + } + + function inherits(refs) { + return refs.some(function(r) { + if (!r.data) return true; + return r.data && dl.array(r.field).some(function(f) { + return f.parent; + }); + }); + } + + function getFields(ref, group) { + return dl.array(ref.field).map(function(f) { + return f.parent ? + dl.accessor(f.parent)(group.datum) : + f; // String or {'signal'} + }); + } + +// Scale datarefs can be computed over multiple schema types. +// This function determines the type of aggregator created, and +// what data is sent to it: values, tuples, or multi-tuples that must +// be standardized into a consistent schema. + function aggrType(def, scale) { + var refs = getRefs(def); + + // If we're operating over only a single domain, send full tuples + // through for efficiency (fewer accessor creations/calls) + if (refs.length == 1 && dl.array(refs[0].field).length == 1) { + return Aggregate.TYPES.TUPLE; + } + + // With quantitative scales, we only care about min/max. + if (!isUniques(scale)) return Aggregate.TYPES.VALUE; + + // If we don't sort, then we can send values directly to aggrs as well + if (!dl.isObject(def.sort)) return Aggregate.TYPES.VALUE; + + return Aggregate.TYPES.MULTI; + } + + function getCache(which, def, scale, group) { + var refs = getRefs(def), + inherit = inherits(refs), + atype = aggrType(def, scale), + uniques = isUniques(scale), + sort = def.sort, + ck = '_'+which, + fields = getFields(refs[0], group); + + if (scale[ck] || this[ck]) return scale[ck] || this[ck]; + + var cache = new Aggregate(this._graph).type(atype), + groupby, summarize; + + // If a scale's dataref doesn't inherit data from the group, we can + // store the dataref aggregator at the Scale (dataflow node) level. + if (inherit) { + scale[ck] = cache; + } else { + this[ck] = cache; + } + + if (uniques) { + if (atype === Aggregate.TYPES.VALUE) { + groupby = [{ name: DataRef.GROUPBY, get: dl.identity }]; + summarize = {'*': DataRef.COUNT}; + } else if (atype === Aggregate.TYPES.TUPLE) { + groupby = [{ name: DataRef.GROUPBY, get: dl.$(fields[0]) }]; + summarize = dl.isObject(sort) ? [{ + field: DataRef.VALUE, + get: dl.$(sort.field), + ops: [sort.op] + }] : {'*': DataRef.COUNT}; + } else { // atype === Aggregate.TYPES.MULTI + groupby = DataRef.GROUPBY; + summarize = [{ field: DataRef.VALUE, ops: [sort.op] }]; + } + } else { + groupby = []; + summarize = [{ + field: DataRef.VALUE, + get: (atype == Aggregate.TYPES.TUPLE) ? dl.$(fields[0]) : dl.identity, + ops: [DataRef.MIN, DataRef.MAX], + as: [DataRef.MIN, DataRef.MAX] + }]; + } + + cache.param('groupby', groupby) + .param('summarize', summarize); + + return (cache._lastUpdate = -1, cache); + } + + function dataRef(which, def, scale, group) { + if (def == null) { return []; } + if (dl.isArray(def)) return def.map(signal.bind(this)); + + var self = this, graph = this._graph, + refs = getRefs(def), + inherit = inherits(refs), + atype = aggrType(def, scale), + cache = getCache.apply(this, arguments), + sort = def.sort, + uniques = isUniques(scale), + i, rlen, j, flen, ref, fields, field, data, from, so, cmp; + + function addDep(s) { + self.dependency(Deps.SIGNALS, s); + } + + if (inherit || (!inherit && cache._lastUpdate < this._stamp)) { + for (i=0, rlen=refs.length; i 1) f = 1; + e = curr.ease(f); + + for (i=0, n=curr.length; i 0 ? (e = 1e-12, Math.ceil) : (e = -1e-12, Math.floor), + e; + function log(x) { + return (domain[0] < 0 ? + -Math.log(x > 0 ? 0 : -x) : + Math.log(x < 0 ? 0 : x)) / Math.log(base); + } + function pow(x) { + return domain[0] < 0 ? -Math.pow(base, -x) : Math.pow(base, x); + } + return function(d) { + return pow(v(log(d) + e)) / d >= k ? f(d) : ''; + }; + } + + function getFormatter(formatType, str) { + var fmt = dl.format, + log = scale.type === 'log', + domain, f; + + switch (formatType) { + case NUMBER: + domain = scale.domain(); + f = fmt.auto.number(domain, tickCount, str || (log ? '.1r' : null)); + return log ? logFilter(domain, tickCount, f) : f; + case TIME: return (str ? fmt : fmt.auto).time(str); + case UTC: return (str ? fmt : fmt.auto).utc(str); + default: return String; + } + } + + function getTicks(format) { + var major = tickValues || (scale.ticks ? scale.ticks(tickCount) : scale.domain()), + minor = axisSubdivide(scale, major, tickSubdivide).map(ingest); + major = major.map(function(d) { return (d = ingest(d), d.label = format(d.data), d); }); + return [major, minor]; + } + + axis.def = function() { + if (!axisDef.type) axis_def(scale); + + var ticks = getTicks(getTickFormat()); + var tdata = title ? [title].map(ingest) : []; + + axisDef.marks[0].from = function() { return grid ? ticks[0] : []; }; + axisDef.marks[1].from = function() { return ticks[0]; }; + axisDef.marks[2].from = function() { return ticks[1]; }; + axisDef.marks[3].from = axisDef.marks[1].from; + axisDef.marks[4].from = function() { return [1]; }; + axisDef.marks[5].from = function() { return tdata; }; + axisDef.offset = offset; + axisDef.orient = orient; + axisDef.layer = layer; + if (titleOffset === 'auto') titleAutoOffset(axisDef); + + return axisDef; + }; + + function titleAutoOffset(axisDef) { + var orient = axisDef.orient, + update = axisDef.marks[5].properties.update, + fn = update.encode, + min = config.titleOffsetAutoMin, + max = config.titleOffsetAutoMax, + pad = config.titleOffsetAutoMargin; + + // Offset axis title using bounding box of axis domain and labels + // Assumes other components are **encoded and bounded** beforehand + update.encode = function(item, group, trans, db, signals, preds) { + var dirty = fn.call(fn, item, group, trans, db, signals, preds), + field = (orient==='bottom' || orient==='top') ? 'y' : 'x'; + if (titleStyle[field] != null) return dirty; + + axisBounds.clear() + .union(group.items[3].bounds) + .union(group.items[4].bounds); + + var o = trans ? {} : item, + method = (orient==='left' || orient==='right') ? 'width' : 'height', + sign = (orient==='top' || orient==='left') ? -1 : 1, + off = ~~(axisBounds[method]() + item.fontSize/2 + pad); + + Tuple.set(o, field, sign * Math.min(Math.max(min, off), max)); + if (trans) trans.interpolate(item, o); + return true; + }; + } + + function axis_def(scale) { + // setup scale mapping + var newScale, oldScale, range; + if (scale.type === ORDINAL) { + newScale = {scale: scale.scaleName, offset: 0.5 + scale.rangeBand()/2}; + oldScale = newScale; + } else { + newScale = {scale: scale.scaleName, offset: 0.5}; + oldScale = {scale: scale.scaleName+':prev', offset: 0.5}; + } + range = axisScaleRange(scale); + + // setup axis marks + dl.extend(m.gridLines, axisTicks(config)); + dl.extend(m.majorTicks, axisTicks(config)); + dl.extend(m.minorTicks, axisTicks(config)); + dl.extend(m.tickLabels, axisTickLabels(config)); + dl.extend(m.domain, axisDomain(config)); + dl.extend(m.title, axisTitle(config)); + m.gridLines.properties.enter.stroke = {value: config.gridColor}; + m.gridLines.properties.enter.strokeOpacity = {value: config.gridOpacity}; + + // extend axis marks based on axis orientation + axisTicksExtend(orient, m.gridLines, oldScale, newScale, Infinity); + axisTicksExtend(orient, m.majorTicks, oldScale, newScale, tickMajorSize); + axisTicksExtend(orient, m.minorTicks, oldScale, newScale, tickMinorSize); + axisLabelExtend(orient, m.tickLabels, oldScale, newScale, tickMajorSize, tickPadding); + + axisDomainExtend(orient, m.domain, range, tickEndSize); + axisTitleExtend(orient, m.title, range, +titleOffset || -1); + + // add / override custom style properties + dl.extend(m.gridLines.properties.update, gridLineStyle); + dl.extend(m.majorTicks.properties.update, majorTickStyle); + dl.extend(m.minorTicks.properties.update, minorTickStyle); + dl.extend(m.tickLabels.properties.update, tickLabelStyle); + dl.extend(m.domain.properties.update, domainStyle); + dl.extend(m.title.properties.update, titleStyle); + + var marks = [m.gridLines, m.majorTicks, m.minorTicks, m.tickLabels, m.domain, m.title]; + dl.extend(axisDef, { + type: 'group', + interactive: false, + properties: { + enter: { + encode: axisUpdate, + scales: [scale.scaleName], + signals: [], data: [] + }, + update: { + encode: axisUpdate, + scales: [scale.scaleName], + signals: [], data: [] + } + } + }); + + axisDef.marks = marks.map(function(m) { return parseMark(model, m); }); + } + + axis.scale = function(x) { + if (!arguments.length) return scale; + if (scale !== x) { scale = x; reset(); } + return axis; + }; + + axis.orient = function(x) { + if (!arguments.length) return orient; + if (orient !== x) { + orient = x in axisOrients ? x + '' : config.orient; + reset(); + } + return axis; + }; + + axis.title = function(x) { + if (!arguments.length) return title; + if (title !== x) { title = x; reset(); } + return axis; + }; + + axis.tickCount = function(x) { + if (!arguments.length) return tickCount; + tickCount = x; + return axis; + }; + + axis.tickValues = function(x) { + if (!arguments.length) return tickValues; + tickValues = x; + return axis; + }; + + axis.tickFormat = function(x) { + if (!arguments.length) return tickFormatString; + if (tickFormatString !== x) { + tickFormatString = x; + reset(); + } + return axis; + }; + + axis.tickFormatType = function(x) { + if (!arguments.length) return tickFormatType; + if (tickFormatType !== x) { + tickFormatType = x; + reset(); + } + return axis; + }; + + axis.tickSize = function(x, y) { + if (!arguments.length) return tickMajorSize; + var n = arguments.length - 1, + major = +x, + minor = n > 1 ? +y : tickMajorSize, + end = n > 0 ? +arguments[n] : tickMajorSize; + + if (tickMajorSize !== major || + tickMinorSize !== minor || + tickEndSize !== end) { + reset(); + } + + tickMajorSize = major; + tickMinorSize = minor; + tickEndSize = end; + return axis; + }; + + axis.tickSubdivide = function(x) { + if (!arguments.length) return tickSubdivide; + tickSubdivide = +x; + return axis; + }; + + axis.offset = function(x) { + if (!arguments.length) return offset; + offset = dl.isObject(x) ? x : +x; + return axis; + }; + + axis.tickPadding = function(x) { + if (!arguments.length) return tickPadding; + if (tickPadding !== +x) { tickPadding = +x; reset(); } + return axis; + }; + + axis.titleOffset = function(x) { + if (!arguments.length) return titleOffset; + if (titleOffset !== x) { titleOffset = x; reset(); } + return axis; + }; + + axis.layer = function(x) { + if (!arguments.length) return layer; + if (layer !== x) { layer = x; reset(); } + return axis; + }; + + axis.grid = function(x) { + if (!arguments.length) return grid; + if (grid !== x) { grid = x; reset(); } + return axis; + }; + + axis.gridLineProperties = function(x) { + if (!arguments.length) return gridLineStyle; + if (gridLineStyle !== x) { gridLineStyle = x; } + return axis; + }; + + axis.majorTickProperties = function(x) { + if (!arguments.length) return majorTickStyle; + if (majorTickStyle !== x) { majorTickStyle = x; } + return axis; + }; + + axis.minorTickProperties = function(x) { + if (!arguments.length) return minorTickStyle; + if (minorTickStyle !== x) { minorTickStyle = x; } + return axis; + }; + + axis.tickLabelProperties = function(x) { + if (!arguments.length) return tickLabelStyle; + if (tickLabelStyle !== x) { tickLabelStyle = x; } + return axis; + }; + + axis.titleProperties = function(x) { + if (!arguments.length) return titleStyle; + if (titleStyle !== x) { titleStyle = x; } + return axis; + }; + + axis.domainProperties = function(x) { + if (!arguments.length) return domainStyle; + if (domainStyle !== x) { domainStyle = x; } + return axis; + }; + + axis.reset = function() { + reset(); + return axis; + }; + + return axis; + } + + var axisOrients = {top: 1, right: 1, bottom: 1, left: 1}; + + function axisSubdivide(scale, ticks, m) { + var subticks = []; + if (m && ticks.length > 1) { + var extent = axisScaleExtent(scale.domain()), + i = -1, + n = ticks.length, + d = (ticks[1] - ticks[0]) / ++m, + j, + v; + while (++i < n) { + for (j = m; --j > 0;) { + if ((v = +ticks[i] - j * d) >= extent[0]) { + subticks.push(v); + } + } + } + for (--i, j = 0; ++j < m && (v = +ticks[i] + j * d) < extent[1];) { + subticks.push(v); + } + } + return subticks; + } + + function axisScaleExtent(domain) { + var start = domain[0], stop = domain[domain.length - 1]; + return start < stop ? [start, stop] : [stop, start]; + } + + function axisScaleRange(scale) { + return scale.rangeExtent ? + scale.rangeExtent() : + axisScaleExtent(scale.range()); + } + + var axisAlign = { + bottom: 'center', + top: 'center', + left: 'right', + right: 'left' + }; + + var axisBaseline = { + bottom: 'top', + top: 'bottom', + left: 'middle', + right: 'middle' + }; + + function axisLabelExtend(orient, labels, oldScale, newScale, size, pad) { + size = Math.max(size, 0) + pad; + if (orient === 'left' || orient === 'top') { + size *= -1; + } + if (orient === 'top' || orient === 'bottom') { + dl.extend(labels.properties.enter, { + x: oldScale, + y: {value: size}, + }); + dl.extend(labels.properties.update, { + x: newScale, + y: {value: size}, + align: {value: 'center'}, + baseline: {value: axisBaseline[orient]} + }); + } else { + dl.extend(labels.properties.enter, { + x: {value: size}, + y: oldScale, + }); + dl.extend(labels.properties.update, { + x: {value: size}, + y: newScale, + align: {value: axisAlign[orient]}, + baseline: {value: 'middle'} + }); + } + } + + function axisTicksExtend(orient, ticks, oldScale, newScale, size) { + var sign = (orient === 'left' || orient === 'top') ? -1 : 1; + if (size === Infinity) { + size = (orient === 'top' || orient === 'bottom') ? + {field: {group: 'height', level: 2}, mult: -sign} : + {field: {group: 'width', level: 2}, mult: -sign}; + } else { + size = {value: sign * size}; + } + if (orient === 'top' || orient === 'bottom') { + dl.extend(ticks.properties.enter, { + x: oldScale, + y: {value: 0}, + y2: size + }); + dl.extend(ticks.properties.update, { + x: newScale, + y: {value: 0}, + y2: size + }); + dl.extend(ticks.properties.exit, { + x: newScale, + }); + } else { + dl.extend(ticks.properties.enter, { + x: {value: 0}, + x2: size, + y: oldScale + }); + dl.extend(ticks.properties.update, { + x: {value: 0}, + x2: size, + y: newScale + }); + dl.extend(ticks.properties.exit, { + y: newScale, + }); + } + } + + function axisTitleExtend(orient, title, range, offset) { + var update = title.properties.update, + mid = ~~((range[0] + range[1]) / 2), + sign = (orient === 'top' || orient === 'left') ? -1 : 1; + + if (orient === 'bottom' || orient === 'top') { + update.x = {value: mid}; + update.angle = {value: 0}; + if (offset >= 0) update.y = sign * offset; + } else { + update.y = {value: mid}; + update.angle = {value: orient === 'left' ? -90 : 90}; + if (offset >= 0) update.x = sign * offset; + } + } + + function axisDomainExtend(orient, domain, range, size) { + var path; + if (orient === 'top' || orient === 'left') { + size = -1 * size; + } + if (orient === 'bottom' || orient === 'top') { + path = 'M' + range[0] + ',' + size + 'V0H' + range[1] + 'V' + size; + } else { + path = 'M' + size + ',' + range[0] + 'H0V' + range[1] + 'H' + size; + } + domain.properties.update.path = {value: path}; + } + + function axisUpdate(item, group, trans) { + var o = trans ? {} : item, + offset = item.mark.def.offset, + orient = item.mark.def.orient, + width = group.width, + height = group.height; // TODO fallback to global w,h? + + if (dl.isArray(offset)) { + var ofx = offset[0], + ofy = offset[1]; + + switch (orient) { + case 'left': { Tuple.set(o, 'x', -ofx); Tuple.set(o, 'y', ofy); break; } + case 'right': { Tuple.set(o, 'x', width + ofx); Tuple.set(o, 'y', ofy); break; } + case 'bottom': { Tuple.set(o, 'x', ofx); Tuple.set(o, 'y', height + ofy); break; } + case 'top': { Tuple.set(o, 'x', ofx); Tuple.set(o, 'y', -ofy); break; } + default: { Tuple.set(o, 'x', ofx); Tuple.set(o, 'y', ofy); } + } + } else { + if (dl.isObject(offset)) { + offset = -group.scale(offset.scale)(offset.value); + } + + switch (orient) { + case 'left': { Tuple.set(o, 'x', -offset); Tuple.set(o, 'y', 0); break; } + case 'right': { Tuple.set(o, 'x', width + offset); Tuple.set(o, 'y', 0); break; } + case 'bottom': { Tuple.set(o, 'x', 0); Tuple.set(o, 'y', height + offset); break; } + case 'top': { Tuple.set(o, 'x', 0); Tuple.set(o, 'y', -offset); break; } + default: { Tuple.set(o, 'x', 0); Tuple.set(o, 'y', 0); } + } + } + + if (trans) trans.interpolate(item, o); + return true; + } + + function axisTicks(config) { + return { + type: 'rule', + interactive: false, + key: 'data', + properties: { + enter: { + stroke: {value: config.tickColor}, + strokeWidth: {value: config.tickWidth}, + opacity: {value: 1e-6} + }, + exit: { opacity: {value: 1e-6} }, + update: { opacity: {value: 1} } + } + }; + } + + function axisTickLabels(config) { + return { + type: 'text', + interactive: true, + key: 'data', + properties: { + enter: { + fill: {value: config.tickLabelColor}, + font: {value: config.tickLabelFont}, + fontSize: {value: config.tickLabelFontSize}, + opacity: {value: 1e-6}, + text: {field: 'label'} + }, + exit: { opacity: {value: 1e-6} }, + update: { opacity: {value: 1} } + } + }; + } + + function axisTitle(config) { + return { + type: 'text', + interactive: true, + properties: { + enter: { + font: {value: config.titleFont}, + fontSize: {value: config.titleFontSize}, + fontWeight: {value: config.titleFontWeight}, + fill: {value: config.titleColor}, + align: {value: 'center'}, + baseline: {value: 'middle'}, + text: {field: 'data'} + }, + update: {} + } + }; + } + + function axisDomain(config) { + return { + type: 'path', + interactive: false, + properties: { + enter: { + x: {value: 0.5}, + y: {value: 0.5}, + stroke: {value: config.axisColor}, + strokeWidth: {value: config.axisWidth} + }, + update: {} + } + }; + } + + module.exports = axs; +},{"../parse/mark":99,"datalib":26,"vega-dataflow":41,"vega-scenegraph":48}],116:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + Gradient = require('vega-scenegraph').Gradient, + parseProperties = require('../parse/properties'), + parseMark = require('../parse/mark'); + + function lgnd(model) { + var size = null, + shape = null, + fill = null, + stroke = null, + spacing = null, + values = null, + format = null, + formatString = null, + config = model.config().legend, + title, + orient = config.orient, + offset = config.offset, + padding = config.padding, + tickArguments = [5], + legendStyle = {}, + symbolStyle = {}, + gradientStyle = {}, + titleStyle = {}, + labelStyle = {}, + m = { // Legend marks as references for updates + titles: {}, + symbols: {}, + labels: {}, + gradient: {} + }; + + var legend = {}, + legendDef = {}; + + function reset() { legendDef.type = null; } + function ingest(d, i) { return {data: d, index: i}; } + + legend.def = function() { + var scale = size || shape || fill || stroke; + + format = !formatString ? null : ((scale.type === 'time') ? + dl.format.time(formatString) : dl.format.number(formatString)); + + if (!legendDef.type) { + legendDef = (scale===fill || scale===stroke) && !discrete(scale.type) ? + quantDef(scale) : ordinalDef(scale); + } + legendDef.orient = orient; + legendDef.offset = offset; + legendDef.padding = padding; + legendDef.margin = config.margin; + return legendDef; + }; + + function discrete(type) { + return type==='ordinal' || type==='quantize' || + type==='quantile' || type==='threshold'; + } + + function ordinalDef(scale) { + var def = o_legend_def(size, shape, fill, stroke); + + // generate data + var data = (values == null ? + (scale.ticks ? scale.ticks.apply(scale, tickArguments) : scale.domain()) : + values).map(ingest); + var fmt = format==null ? (scale.tickFormat ? scale.tickFormat.apply(scale, tickArguments) : String) : format; + + // determine spacing between legend entries + var fs, range, offset, pad=5, domain = d3.range(data.length); + if (size) { + range = data.map(function(x) { return Math.sqrt(size(x.data)); }); + offset = d3.max(range); + range = range.reduce(function(a,b,i,z) { + if (i > 0) a[i] = a[i-1] + z[i-1]/2 + pad; + return (a[i] += b/2, a); }, [0]).map(Math.round); + } else { + offset = Math.round(Math.sqrt(config.symbolSize)); + range = spacing || + (fs = labelStyle.fontSize) && (fs.value + pad) || + (config.labelFontSize + pad); + range = domain.map(function(d,i) { + return Math.round(offset/2 + i*range); + }); + } + + // account for padding and title size + var sz = padding, ts; + if (title) { + ts = titleStyle.fontSize; + sz += 5 + ((ts && ts.value) || config.titleFontSize); + } + for (var i=0, n=range.length; i'}, + summarize: { + type: 'custom', + set: function(summarize) { + var signalDeps = {}, + tx = this._transform, + i, len, f, fields, name, ops; + + if (!dl.isArray(fields = summarize)) { // Object syntax from dl + fields = []; + for (name in summarize) { + ops = dl.array(summarize[name]); + fields.push({field: name, ops: ops}); + } + } + + function sg(x) { if (x.signal) signalDeps[x.signal] = 1; } + + for (i=0, len=fields.length; i', default: [5, 2]} + }); + + this._output = { + start: 'bin_start', + end: 'bin_end', + mid: 'bin_mid' + }; + return this.mutates(true); + } + + var prototype = (Bin.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Bin; + + prototype.extent = function(data) { + // TODO only recompute extent upon data or field change? + var e = [this.param('min'), this.param('max')], d; + if (e[0] == null || e[1] == null) { + d = dl.extent(data, this.param('field').accessor); + if (e[0] == null) e[0] = d[0]; + if (e[1] == null) e[1] = d[1]; + } + return e; + }; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['binning']); + + var extent = this.extent(data), + output = this._output, + step = this.param('step'), + steps = this.param('steps'), + minstep = this.param('minstep'), + get = this.param('field').accessor, + opt = { + min: extent[0], + max: extent[1], + base: this.param('base'), + maxbins: this.param('maxbins'), + div: this.param('div') + }; + + if (step) opt.step = step; + if (steps) opt.steps = steps; + if (minstep) opt.minstep = minstep; + var b = dl.bins(opt), + s = b.step; + + function update(d) { + var v = get(d); + v = v == null ? null + : b.start + s * ~~((v - b.start) / s); + Tuple.set(d, output.start, v); + Tuple.set(d, output.end, v + s); + Tuple.set(d, output.mid, v + s/2); + } + input.add.forEach(update); + input.mod.forEach(update); + input.rem.forEach(update); + + input.fields[output.start] = 1; + input.fields[output.end] = 1; + input.fields[output.mid] = 1; + return input; + }; + + module.exports = Bin; +},{"./BatchTransform":119,"./Transform":139,"datalib":26,"vega-dataflow":41,"vega-logging":47}],121:[function(require,module,exports){ + var df = require('vega-dataflow'), + Tuple = df.Tuple, + log = require('vega-logging'), + Transform = require('./Transform'); + + function CountPattern(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, { + field: {type: 'field', default: 'data'}, + pattern: {type: 'value', default: '[\\w\']+'}, + case: {type: 'value', default: 'lower'}, + stopwords: {type: 'value', default: ''} + }); + + this._output = {text: 'text', count: 'count'}; + + return this.router(true).produces(true); + } + + var prototype = (CountPattern.prototype = Object.create(Transform.prototype)); + prototype.constructor = CountPattern; + + prototype.transform = function(input, reset) { + log.debug(input, ['countpattern']); + + var get = this.param('field').accessor, + pattern = this.param('pattern'), + stop = this.param('stopwords'), + rem = false; + + // update parameters + if (this._stop !== stop) { + this._stop = stop; + this._stop_re = new RegExp('^' + stop + '$', 'i'); + reset = true; + } + + if (this._pattern !== pattern) { + this._pattern = pattern; + this._match = new RegExp(this._pattern, 'g'); + reset = true; + } + + if (reset) this._counts = {}; + + function curr(t) { return (Tuple.prev_init(t), get(t)); } + function prev(t) { return get(Tuple.prev(t)); } + + this._add(input.add, curr); + if (!reset) this._rem(input.rem, prev); + if (reset || (rem = input.fields[get.field])) { + if (rem) this._rem(input.mod, prev); + this._add(input.mod, curr); + } + + // generate output tuples + return this._changeset(input); + }; + + prototype._changeset = function(input) { + var counts = this._counts, + tuples = this._tuples || (this._tuples = {}), + change = df.ChangeSet.create(input), + out = this._output, w, t, c; + + for (w in counts) { + t = tuples[w]; + c = counts[w] || 0; + if (!t && c) { + tuples[w] = (t = Tuple.ingest({})); + t[out.text] = w; + t[out.count] = c; + change.add.push(t); + } else if (c === 0) { + if (t) change.rem.push(t); + delete counts[w]; + delete tuples[w]; + } else if (t[out.count] !== c) { + Tuple.set(t, out.count, c); + change.mod.push(t); + } + } + return change; + }; + + prototype._tokenize = function(text) { + switch (this.param('case')) { + case 'upper': text = text.toUpperCase(); break; + case 'lower': text = text.toLowerCase(); break; + } + return text.match(this._match); + }; + + prototype._add = function(tuples, get) { + var counts = this._counts, + stop = this._stop_re, + tok, i, j, t; + + for (j=0; j cross.s, + fltrd = !cross || cross.f, + omod = output.mod, + orem = output.rem, + i, t, y; + + // If we have cached values, iterate through them for lazy + // removal, and to re-run the filter. + if (tpls) { + if (lazy || test) { + for (i=tpls.length-1; i>=0; --i) { + t = tpls[i]; + y = t[other]; + + if (lazy && !cache[y._id]) { + tpls.splice(i, 1); + continue; + } + + if (!test || test(t)) { + omod.push(t); + } else { + orem.push.apply(orem, tpls.splice(i, 1)); + cross.f = true; + } + } + + cross.s = this._lastRem; + } else { + omod.push.apply(omod, tpls); + } + } + + // If we have a filter param, call add to catch any tuples that may + // have previously been filtered. + if (test && fltrd) add.call(this, output, left, data, diag, test, x); + } + + function rem(output, x) { + var cross = this._cache[x._id]; + if (!cross) return; + output.rem.push.apply(output.rem, cross.c); + this._cache[x._id] = null; + this._lastRem = this._stamp; + } + + function purge(output) { + var cache = this._cache, + keys = dl.keys(cache), + rem = output.rem, + ids = {}, + i, len, j, jlen, cross, t; + + for (i=0, len=keys.length; i this._lastWith) { + woutput.rem.forEach(r); + woutput.add.forEach(add.bind(this, output, false, data, diag, test)); + woutput.mod.forEach(mod.bind(this, output, false, data, diag, test)); + this._lastWith = woutput.stamp; + } + + // Mods need to come after all removals have been run. + input.mod.forEach(mod.bind(this, output, true, wdata, diag, test)); + } + + output.fields[as.left] = 1; + output.fields[as.right] = 1; + return output; + }; + + module.exports = Cross; +},{"./BatchTransform":119,"./Transform":139,"datalib":26,"vega-dataflow":41,"vega-logging":47}],123:[function(require,module,exports){ + var Transform = require('./Transform'), + Aggregate = require('./Aggregate'); + + function Facet(graph) { + Transform.addParameters(this, { + transform: { + type: "custom", + set: function(pipeline) { + return (this._transform._pipeline = pipeline, this._transform); + }, + get: function() { + var parse = require('../parse/transforms'), + facet = this._transform; + return facet._pipeline.map(function(t) { + return parse(facet._graph, t); + }); + } + } + }); + + this._pipeline = []; + return Aggregate.call(this, graph); + } + + var prototype = (Facet.prototype = Object.create(Aggregate.prototype)); + prototype.constructor = Facet; + + prototype.aggr = function() { + return Aggregate.prototype.aggr.call(this).facet(this); + }; + + prototype.transform = function(input, reset) { + var output = Aggregate.prototype.transform.call(this, input, reset); + + // New facet cells should trigger a re-ranking of the dataflow graph. + // This ensures facet datasources are computed before scenegraph nodes. + // We rerank the Facet's first listener, which is the next node in the + // datasource's pipeline. + if (input.add.length) { + this.listeners()[0].rerank(); + } + + return output; + }; + + module.exports = Facet; +},{"../parse/transforms":108,"./Aggregate":118,"./Transform":139}],124:[function(require,module,exports){ + var dl = require('datalib'), + Aggregator = dl.Aggregator, + Base = Aggregator.prototype, + df = require('vega-dataflow'), + Tuple = df.Tuple, + log = require('vega-logging'), + facetID = 0; + + function Facetor() { + Aggregator.call(this); + this._facet = null; + this._facetID = ++facetID; + } + + var prototype = (Facetor.prototype = Object.create(Base)); + prototype.constructor = Facetor; + + prototype.facet = function(f) { + return arguments.length ? (this._facet = f, this) : this._facet; + }; + + prototype._ingest = function(t) { + return Tuple.ingest(t, null); + }; + + prototype._assign = Tuple.set; + + function disconnect_cell(facet) { + log.debug({}, ['disconnecting cell', this.tuple._id]); + var pipeline = this.ds.pipeline(); + facet.removeListener(pipeline[0]); + facet._graph.removeListener(pipeline[0]); + facet._graph.disconnect(pipeline); + } + + prototype._newcell = function(x, key) { + var cell = Base._newcell.call(this, x, key), + facet = this._facet; + + if (facet) { + var graph = facet._graph, + tuple = cell.tuple, + pipeline = facet.param('transform'); + cell.ds = graph.data(tuple._facetID, pipeline, tuple); + cell.disconnect = disconnect_cell; + facet.addListener(pipeline[0]); + } + + return cell; + }; + + prototype._newtuple = function(x, key) { + var t = Base._newtuple.call(this, x); + if (this._facet) { + Tuple.set(t, 'key', key); + Tuple.set(t, '_facetID', this._facetID + '_' + key); + } + return t; + }; + + prototype.clear = function() { + if (this._facet) { + for (var k in this._cells) { + this._cells[k].disconnect(this._facet); + } + } + return Base.clear.call(this); + }; + + prototype._on_add = function(x, cell) { + if (this._facet) cell.ds._input.add.push(x); + }; + + prototype._on_rem = function(x, cell) { + if (this._facet) cell.ds._input.rem.push(x); + }; + + prototype._on_mod = function(x, prev, cell0, cell1) { + if (this._facet) { // Propagate tuples + if (cell0 === cell1) { + cell0.ds._input.mod.push(x); + } else { + cell0.ds._input.rem.push(x); + cell1.ds._input.add.push(x); + } + } + }; + + prototype._on_drop = function(cell) { + if (this._facet) cell.disconnect(this._facet); + }; + + prototype._on_keep = function(cell) { + // propagate sort, signals, fields, etc. + if (this._facet) df.ChangeSet.copy(this._input, cell.ds._input); + }; + + module.exports = Facetor; +},{"datalib":26,"vega-dataflow":41,"vega-logging":47}],125:[function(require,module,exports){ + var df = require('vega-dataflow'), + SIGNALS = df.Dependencies.SIGNALS, + log = require('vega-logging'), + Transform = require('./Transform'); + + function Filter(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, {test: {type: 'expr'}}); + + this._skip = {}; + return this.router(true); + } + + var prototype = (Filter.prototype = Object.create(Transform.prototype)); + prototype.constructor = Filter; + + prototype.transform = function(input) { + log.debug(input, ['filtering']); + + var output = df.ChangeSet.create(input), + graph = this._graph, + skip = this._skip, + test = this.param('test'), + signals = graph.values(SIGNALS, this.dependency(SIGNALS)); + + input.rem.forEach(function(x) { + if (skip[x._id] !== 1) output.rem.push(x); + else skip[x._id] = 0; + }); + + input.add.forEach(function(x) { + if (test(x, null, signals)) output.add.push(x); + else skip[x._id] = 1; + }); + + input.mod.forEach(function(x) { + var b = test(x, null, signals), + s = (skip[x._id] === 1); + if (b && s) { + skip[x._id] = 0; + output.add.push(x); + } else if (b && !s) { + output.mod.push(x); + } else if (!b && s) { + // do nothing, keep skip true + } else { // !b && !s + output.rem.push(x); + skip[x._id] = 1; + } + }); + + return output; + }; + + module.exports = Filter; +},{"./Transform":139,"vega-dataflow":41,"vega-logging":47}],126:[function(require,module,exports){ + var df = require('vega-dataflow'), + Tuple = df.Tuple, + log = require('vega-logging'), + Transform = require('./Transform'); + + function Fold(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, { + fields: {type: 'array'} + }); + + this._output = {key: 'key', value: 'value'}; + this._cache = {}; + + return this.router(true).produces(true); + } + + var prototype = (Fold.prototype = Object.create(Transform.prototype)); + prototype.constructor = Fold; + + prototype._reset = function(input, output) { + for (var id in this._cache) { + output.rem.push.apply(output.rem, this._cache[id]); + } + this._cache = {}; + }; + + prototype._tuple = function(x, i, len) { + var list = this._cache[x._id] || (this._cache[x._id] = Array(len)); + return list[i] ? Tuple.rederive(x, list[i]) : (list[i] = Tuple.derive(x)); + }; + + prototype._fn = function(data, on, out) { + var i, j, n, m, d, t; + for (i=0, n=data.length; i', default: require('./screen').size}, + bound: {type: 'value', default: true}, + links: {type: 'data'}, + + // TODO: for now force these to be value params only (pun-intended) + // Can update to include fields after Parameter refactoring. + linkStrength: {type: 'value', default: 1}, + linkDistance: {type: 'value', default: 20}, + charge: {type: 'value', default: -30}, + + chargeDistance: {type: 'value', default: Infinity}, + friction: {type: 'value', default: 0.9}, + theta: {type: 'value', default: 0.8}, + gravity: {type: 'value', default: 0.1}, + alpha: {type: 'value', default: 0.1}, + iterations: {type: 'value', default: 500}, + + interactive: {type: 'value', default: this._interactive}, + active: {type: 'value', default: this._prev}, + fixed: {type: 'data'} + }); + + this._output = { + 'x': 'layout_x', + 'y': 'layout_y' + }; + + return this.mutates(true); + } + + var prototype = (Force.prototype = Object.create(Transform.prototype)); + prototype.constructor = Force; + + prototype.transform = function(nodeInput, reset) { + log.debug(nodeInput, ['force']); + reset = reset - (nodeInput.signals.active ? 1 : 0); + + // get variables + var interactive = this.param('interactive'), + linkSource = this.param('links').source, + linkInput = linkSource.last(), + active = this.param('active'), + output = this._output, + layout = this._layout, + nodes = this._nodes, + links = this._links; + + // configure nodes, links and layout + if (linkInput.stamp < nodeInput.stamp) linkInput = null; + this.configure(nodeInput, linkInput, interactive, reset); + + // run batch layout + if (!interactive) { + var iterations = this.param('iterations'); + for (var i=0; i'}, + translate: {type: 'array', default: require('./screen').center}, + rotate: {type: 'array'}, + scale: {type: 'value'}, + precision: {type: 'value'}, + clipAngle: {type: 'value'}, + clipExtent: {type: 'value'} + }; + + Geo.d3Projection = function() { + var p = this.param('projection'), + param = Geo.Parameters, + proj, name, value; + + if (p !== this._mode) { + this._mode = p; + this._projection = d3.geo[p](); + } + proj = this._projection; + + for (name in param) { + if (name === 'projection' || !proj[name]) continue; + value = this.param(name); + if (value === undefined || (dl.isArray(value) && value.length === 0)) { + continue; + } + if (value !== proj[name]()) { + proj[name](value); + } + } + + return proj; + }; + + var prototype = (Geo.prototype = Object.create(Transform.prototype)); + prototype.constructor = Geo; + + prototype.transform = function(input) { + log.debug(input, ['geo']); + + var output = this._output, + lon = this.param('lon').accessor, + lat = this.param('lat').accessor, + proj = Geo.d3Projection.call(this); + + function set(t) { + var ll = [lon(t), lat(t)]; + var xy = proj(ll) || [null, null]; + Tuple.set(t, output.x, xy[0]); + Tuple.set(t, output.y, xy[1]); + } + + input.add.forEach(set); + if (this.reevaluate(input)) { + input.mod.forEach(set); + input.rem.forEach(set); + } + + input.fields[output.x] = 1; + input.fields[output.y] = 1; + return input; + }; + + module.exports = Geo; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./Transform":139,"./screen":145,"datalib":26,"vega-dataflow":41,"vega-logging":47}],130:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Geo = require('./Geo'), + Transform = require('./Transform'); + + function GeoPath(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, Geo.Parameters); + Transform.addParameters(this, { + field: {type: 'field', default: null}, + }); + + this._output = { + 'path': 'layout_path' + }; + return this.mutates(true); + } + + var prototype = (GeoPath.prototype = Object.create(Transform.prototype)); + prototype.constructor = GeoPath; + + prototype.transform = function(input) { + log.debug(input, ['geopath']); + + var output = this._output, + geojson = this.param('field').accessor || dl.identity, + proj = Geo.d3Projection.call(this), + path = d3.geo.path().projection(proj); + + function set(t) { + Tuple.set(t, output.path, path(geojson(t))); + } + + input.add.forEach(set); + if (this.reevaluate(input)) { + input.mod.forEach(set); + input.rem.forEach(set); + } + + input.fields[output.path] = 1; + return input; + }; + + module.exports = GeoPath; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./Geo":129,"./Transform":139,"datalib":26,"vega-dataflow":41,"vega-logging":47}],131:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + dl = require('datalib'), + Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Hierarchy(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + // hierarchy parameters + sort: {type: 'array', default: null}, + children: {type: 'field', default: 'children'}, + parent: {type: 'field', default: 'parent'}, + field: {type: 'value', default: null}, + // layout parameters + mode: {type: 'value', default: 'tidy'}, // tidy, cluster, partition + size: {type: 'array', default: require('./screen').size}, + nodesize: {type: 'array', default: null}, + orient: {type: 'value', default: 'cartesian'} + }); + + this._mode = null; + this._output = { + 'x': 'layout_x', + 'y': 'layout_y', + 'width': 'layout_width', + 'height': 'layout_height', + 'depth': 'layout_depth' + }; + return this.mutates(true); + } + + var PARTITION = 'partition'; + + var SEPARATION = { + cartesian: function(a, b) { return (a.parent === b.parent ? 1 : 2); }, + radial: function(a, b) { return (a.parent === b.parent ? 1 : 2) / a.depth; } + }; + + var prototype = (Hierarchy.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Hierarchy; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['hierarchy layout']); + + // get variables + var layout = this._layout, + output = this._output, + mode = this.param('mode'), + sort = this.param('sort'), + nodesz = this.param('nodesize'), + parent = this.param('parent').accessor, + root = data.filter(function(d) { return parent(d) === null; })[0]; + + if (mode !== this._mode) { + this._mode = mode; + if (mode === 'tidy') mode = 'tree'; + layout = (this._layout = d3.layout[mode]()); + } + + input.fields[output.x] = 1; + input.fields[output.y] = 1; + input.fields[output.depth] = 1; + if (mode === PARTITION) { + input.fields[output.width] = 1; + input.fields[output.height] = 1; + layout.value(this.param('field').accessor); + } else { + layout.separation(SEPARATION[this.param('orient')]); + } + + if (nodesz.length && mode !== PARTITION) { + layout.nodeSize(nodesz); + } else { + layout.size(this.param('size')); + } + + layout + .sort(sort.field.length ? dl.comparator(sort.field) : null) + .children(this.param('children').accessor) + .nodes(root); + + // copy layout values to nodes + data.forEach(function(n) { + Tuple.set(n, output.x, n.x); + Tuple.set(n, output.y, n.y); + Tuple.set(n, output.depth, n.depth); + if (mode === PARTITION) { + Tuple.set(n, output.width, n.dx); + Tuple.set(n, output.height, n.dy); + } + }); + + // return changeset + return input; + }; + + module.exports = Hierarchy; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./BatchTransform":119,"./Transform":139,"./screen":145,"datalib":26,"vega-dataflow":41,"vega-logging":47}],132:[function(require,module,exports){ + var dl = require('datalib'), + log = require('vega-logging'), + Tuple = require('vega-dataflow').Tuple, + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Impute(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + groupby: {type: 'array'}, + orderby: {type: 'array'}, + field: {type: 'field'}, + method: {type: 'value', default: 'value'}, + value: {type: 'value', default: 0} + }); + + return this.router(true).produces(true); + } + + var prototype = (Impute.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Impute; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['imputing']); + + var groupby = this.param('groupby'), + orderby = this.param('orderby'), + method = this.param('method'), + value = this.param('value'), + field = this.param('field'), + get = field.accessor, + name = field.field, + prev = this._imputed || [], curr = [], + groups = partition(data, groupby.accessor, orderby.accessor), + domain = groups.domain, + group, i, j, n, m, t; + + function getval(x) { + return x == null ? null : get(x); + } + + for (j=0, m=groups.length; j Math.PI ? ta <= sa : ta > sa; + return 'M' + (sr*sc) + ',' + (sr*ss) + + 'A' + sr + ',' + sr + ' 0 0,' + (sf?1:0) + + ' ' + (sr*tc) + ',' + (sr*ts) + + 'L' + (tr*tc) + ',' + (tr*ts); + } + + function diagonalX(sx, sy, tx, ty) { + var m = (sx + tx) / 2; + return 'M' + sx + ',' + sy + + 'C' + m + ',' + sy + + ' ' + m + ',' + ty + + ' ' + tx + ',' + ty; + } + + function diagonalY(sx, sy, tx, ty) { + var m = (sy + ty) / 2; + return 'M' + sx + ',' + sy + + 'C' + sx + ',' + m + + ' ' + tx + ',' + m + + ' ' + tx + ',' + ty; + } + + function diagonalR(sa, sr, ta, tr) { + var sc = Math.cos(sa), + ss = Math.sin(sa), + tc = Math.cos(ta), + ts = Math.sin(ta), + mr = (sr + tr) / 2; + return 'M' + (sr*sc) + ',' + (sr*ss) + + 'C' + (mr*sc) + ',' + (mr*ss) + + ' ' + (mr*tc) + ',' + (mr*ts) + + ' ' + (tr*tc) + ',' + (tr*ts); + } + + var shapes = { + line: line, + curve: curve, + cornerX: cornerX, + cornerY: cornerY, + cornerR: cornerR, + diagonalX: diagonalX, + diagonalY: diagonalY, + diagonalR: diagonalR + }; + + prototype.transform = function(input) { + log.debug(input, ['linkpath']); + + var output = this._output, + shape = shapes[this.param('shape')] || shapes.line, + sourceX = this.param('sourceX').accessor, + sourceY = this.param('sourceY').accessor, + targetX = this.param('targetX').accessor, + targetY = this.param('targetY').accessor, + tension = this.param('tension'); + + function set(t) { + var path = shape(sourceX(t), sourceY(t), targetX(t), targetY(t), tension); + Tuple.set(t, output.path, path); + } + + input.add.forEach(set); + if (this.reevaluate(input)) { + input.mod.forEach(set); + input.rem.forEach(set); + } + + input.fields[output.path] = 1; + return input; + }; + + module.exports = LinkPath; +},{"./Transform":139,"vega-dataflow":41,"vega-logging":47}],134:[function(require,module,exports){ + var Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Transform = require('./Transform'); + + function Lookup(graph) { + Transform.prototype.init.call(this, graph); + Transform.addParameters(this, { + on: {type: 'data'}, + onKey: {type: 'field', default: null}, + as: {type: 'array'}, + keys: {type: 'array', default: ['data']}, + default: {type: 'value'} + }); + + return this.mutates(true); + } + + var prototype = (Lookup.prototype = Object.create(Transform.prototype)); + prototype.constructor = Lookup; + + prototype.transform = function(input, reset) { + log.debug(input, ['lookup']); + + var on = this.param('on'), + onLast = on.source.last(), + onData = on.source.values(), + onKey = this.param('onKey'), + onF = onKey.field, + keys = this.param('keys'), + get = keys.accessor, + as = this.param('as'), + defaultValue = this.param('default'), + lut = this._lut, + i, v; + + // build lookup table on init, withKey modified, or tuple add/rem + if (lut == null || this._on !== onF || onF && onLast.fields[onF] || + onLast.add.length || onLast.rem.length) + { + if (onF) { // build hash from withKey field + onKey = onKey.accessor; + for (lut={}, i=0; i'} }); + this.router(true); + } + + var prototype = (Sort.prototype = Object.create(Transform.prototype)); + prototype.constructor = Sort; + + prototype.transform = function(input) { + log.debug(input, ['sorting']); + + if (input.add.length || input.mod.length || input.rem.length) { + input.sort = dl.comparator(this.param('by').field); + } + return input; + }; + + module.exports = Sort; +},{"./Transform":139,"datalib":26,"vega-logging":47}],138:[function(require,module,exports){ + var dl = require('datalib'), + Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Stack(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + groupby: {type: 'array'}, + sortby: {type: 'array'}, + field: {type: 'field'}, + offset: {type: 'value', default: 'zero'} + }); + + this._output = { + 'start': 'layout_start', + 'end': 'layout_end', + 'mid': 'layout_mid' + }; + return this.mutates(true); + } + + var prototype = (Stack.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Stack; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['stacking']); + + var groupby = this.param('groupby').accessor, + sortby = dl.comparator(this.param('sortby').field), + field = this.param('field').accessor, + offset = this.param('offset'), + output = this._output; + + // partition, sum, and sort the stack groups + var groups = partition(data, groupby, sortby, field); + + // compute stack layouts per group + for (var i=0, max=groups.max; i max) max = s; + if (sortby != null) g.sort(sortby); + } + groups.max = max; + + return groups; + } + + module.exports = Stack; +},{"./BatchTransform":119,"./Transform":139,"datalib":26,"vega-dataflow":41,"vega-logging":47}],139:[function(require,module,exports){ + var df = require('vega-dataflow'), + Base = df.Node.prototype, // jshint ignore:line + Deps = df.Dependencies, + Parameter = require('./Parameter'); + + function Transform(graph) { + if (graph) Base.init.call(this, graph); + } + + Transform.addParameters = function(proto, params) { + proto._parameters = proto._parameters || {}; + for (var name in params) { + var p = params[name], + param = new Parameter(name, p.type, proto); + + proto._parameters[name] = param; + + if (p.type === 'custom') { + if (p.set) param.set = p.set.bind(param); + if (p.get) param.get = p.get.bind(param); + } + + if (p.hasOwnProperty('default')) param.set(p.default); + } + }; + + var prototype = (Transform.prototype = Object.create(Base)); + prototype.constructor = Transform; + + prototype.param = function(name, value) { + var param = this._parameters[name]; + return (param === undefined) ? this : + (arguments.length === 1) ? param.get() : param.set(value); + }; + +// Perform transformation. Subclasses should override. + prototype.transform = function(input/*, reset */) { + return input; + }; + + prototype.evaluate = function(input) { + // Many transforms store caches that must be invalidated if + // a signal value has changed. + var reset = this._stamp < input.stamp && + this.dependency(Deps.SIGNALS).reduce(function(c, s) { + return c += input.signals[s] ? 1 : 0; + }, 0); + return this.transform(input, reset); + }; + + prototype.output = function(map) { + for (var key in this._output) { + if (map[key] !== undefined) { + this._output[key] = map[key]; + } + } + return this; + }; + + module.exports = Transform; +},{"./Parameter":135,"vega-dataflow":41}],140:[function(require,module,exports){ + var dl = require('datalib'), + Tuple = require('vega-dataflow').Tuple, + log = require('vega-logging'), + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Treeify(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + groupby: {type: 'array'} + }); + + this._output = { + 'children': 'children', + 'parent': 'parent' + }; + return this.router(true).produces(true); + } + + var prototype = (Treeify.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Treeify; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['treeifying']); + + var fields = this.param('groupby').field, + childField = this._output.children, + parentField = this._output.parent, + summary = [{name:'*', ops: ['values'], as: [childField]}], + aggrs = fields.map(function(f) { + return dl.groupby(f).summarize(summary); + }), + prev = this._internal || [], curr = [], i, n; + + function level(index, node, values) { + var vals = aggrs[index].execute(values); + + node[childField] = vals; + vals.forEach(function(n) { + n[parentField] = node; + curr.push(Tuple.ingest(n)); + if (index+1 < fields.length) level(index+1, n, n[childField]); + else n[childField].forEach(function(c) { c[parentField] = n; }); + }); + } + + var root = Tuple.ingest({}); + root[parentField] = null; + curr.push(root); + level(0, root, data); + + // update changeset with internal nodes + for (i=0, n=curr.length; i', default: ['-value']}, + children: {type: 'field', default: 'children'}, + parent: {type: 'field', default: 'parent'}, + field: {type: 'field', default: 'value'}, + // treemap parameters + size: {type: 'array', default: require('./screen').size}, + round: {type: 'value', default: true}, + sticky: {type: 'value', default: false}, + ratio: {type: 'value', default: defaultRatio}, + padding: {type: 'value', default: null}, + mode: {type: 'value', default: 'squarify'} + }); + + this._layout = d3.layout.treemap(); + + this._output = { + 'x': 'layout_x', + 'y': 'layout_y', + 'width': 'layout_width', + 'height': 'layout_height', + 'depth': 'layout_depth', + }; + return this.mutates(true); + } + + var prototype = (Treemap.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Treemap; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['treemap']); + + // get variables + var layout = this._layout, + output = this._output, + sticky = this.param('sticky'), + parent = this.param('parent').accessor, + root = data.filter(function(d) { return parent(d) === null; })[0]; + + // layout.sticky resets state _regardless_ of input value + // so, we perform out own check first + if (layout.sticky() !== sticky) { layout.sticky(sticky); } + + // configure layout + layout + .sort(dl.comparator(this.param('sort').field)) + .children(this.param('children').accessor) + .value(this.param('field').accessor) + .size(this.param('size')) + .round(this.param('round')) + .ratio(this.param('ratio')) + .padding(this.param('padding')) + .mode(this.param('mode')) + .nodes(root); + + // copy layout values to nodes + data.forEach(function(n) { + Tuple.set(n, output.x, n.x); + Tuple.set(n, output.y, n.y); + Tuple.set(n, output.width, n.dx); + Tuple.set(n, output.height, n.dy); + Tuple.set(n, output.depth, n.depth); + }); + + // return changeset + input.fields[output.x] = 1; + input.fields[output.y] = 1; + input.fields[output.width] = 1; + input.fields[output.height] = 1; + input.fields[output.depth] = 1; + return input; + }; + + module.exports = Treemap; + }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./BatchTransform":119,"./Transform":139,"./screen":145,"datalib":26,"vega-dataflow":41,"vega-logging":47}],142:[function(require,module,exports){ + (function (global){ + var d3 = (typeof window !== "undefined" ? window['d3'] : typeof global !== "undefined" ? global['d3'] : null), + Tuple = require('vega-dataflow/src/Tuple'), + log = require('vega-logging'), + Transform = require('./Transform'), + BatchTransform = require('./BatchTransform'); + + function Voronoi(graph) { + BatchTransform.prototype.init.call(this, graph); + Transform.addParameters(this, { + clipExtent: {type: 'array', default: require('./screen').extent}, + x: {type: 'field', default: 'layout_x'}, + y: {type: 'field', default: 'layout_y'} + }); + + this._layout = d3.geom.voronoi(); + this._output = {'path': 'layout_path'}; + + return this.mutates(true); + } + + var prototype = (Voronoi.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Voronoi; + + prototype.batchTransform = function(input, data) { + log.debug(input, ['voronoi']); + + // get variables + var pathname = this._output.path; + + // configure layout + var polygons = this._layout + .clipExtent(this.param('clipExtent')) + .x(this.param('x').accessor) + .y(this.param('y').accessor) + (data); + + // build and assign path strings + for (var i=0; i', default: require('./screen').size}, + text: {type: 'field', default: 'data'}, + rotate: {type: 'field|value', default: 0}, + font: {type: 'field|value', default: {value: 'sans-serif'}}, + fontSize: {type: 'field|value', default: 14}, + fontStyle: {type: 'field|value', default: {value: 'normal'}}, + fontWeight: {type: 'field|value', default: {value: 'normal'}}, + fontScale: {type: 'array', default: [10, 50]}, + padding: {type: 'value', default: 1}, + spiral: {type: 'value', default: 'archimedean'} + }); + + this._layout = d3_cloud().canvas(canvas.instance); + + this._output = { + 'x': 'layout_x', + 'y': 'layout_y', + 'font': 'layout_font', + 'fontSize': 'layout_fontSize', + 'fontStyle': 'layout_fontStyle', + 'fontWeight': 'layout_fontWeight', + 'rotate': 'layout_rotate', + }; + + return this.mutates(true); + } + + var prototype = (Wordcloud.prototype = Object.create(BatchTransform.prototype)); + prototype.constructor = Wordcloud; + + function get(p) { + return (p && p.accessor) || p; + } + + function wrap(tuple) { + var x = Object.create(tuple); + x._tuple = tuple; + return x; + } + + prototype.batchTransform = function(input, data) { + log.debug(input, ['wordcloud']); + + // get variables + var layout = this._layout, + output = this._output, + fontSize = this.param('fontSize'), + range = fontSize.accessor && this.param('fontScale'), + size, scale; + fontSize = fontSize.accessor || d3.functor(fontSize); + + // create font size scaling function as needed + if (range.length) { + scale = d3.scale.sqrt() + .domain(dl.extent(data, size=fontSize)) + .range(range); + fontSize = function(x) { return scale(size(x)); }; + } + + // configure layout + layout + .size(this.param('size')) + .text(get(this.param('text'))) + .padding(this.param('padding')) + .spiral(this.param('spiral')) + .rotate(get(this.param('rotate'))) + .font(get(this.param('font'))) + .fontStyle(get(this.param('fontStyle'))) + .fontWeight(get(this.param('fontWeight'))) + .fontSize(fontSize) + .words(data.map(wrap)) // wrap to avoid tuple writes + .on('end', function(words) { + var size = layout.size(), + dx = size[0] >> 1, + dy = size[1] >> 1, + w, t, i, len; + + for (i=0, len=words.length; i Date: Mon, 7 Mar 2016 09:11:35 +0530 Subject: [PATCH 10/12] Added the doormanager-icon.png --- .../public/images/doormanager-icon.png | Bin 6697 -> 46940 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doormanager-icon.png b/modules/samples/doormanager/component/ui/src/main/resources/jaggeryapps/devicemgt/app/units/cdmf.unit.device.type.doormanager.type-view/public/images/doormanager-icon.png index a44f50fc48a55fdae888184ecb9133e7ff3f057f..0c7744ff42d16a9761778c98749aa50ea93e5cb4 100644 GIT binary patch delta 46467 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 IsB!TB00Bcj_W%F@ literal 6697 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 bATa1N>A@I+6Bf1q=Z)TFBkht)_Ba0rw^AMC From d7de0f0607443e71730d1730b20306bb0a466250 Mon Sep 17 00:00:00 2001 From: Shabirmean Date: Mon, 7 Mar 2016 09:31:12 +0530 Subject: [PATCH 11/12] Adding copy tasks for the portal app specific modifications in the bin.xml --- modules/distribution/src/assembly/bin.xml | 37 +++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/modules/distribution/src/assembly/bin.xml b/modules/distribution/src/assembly/bin.xml index c478eb37..25a2b248 100644 --- a/modules/distribution/src/assembly/bin.xml +++ b/modules/distribution/src/assembly/bin.xml @@ -656,6 +656,20 @@ + + + + src/repository/jaggeryapps/portal/store/carbon.super/gadget + + + ${pom.artifactId}-${pom.version}/repository/deployment/server/jaggeryapps/portal/store/carbon.super/gadget + + + **/* + + + + @@ -719,6 +733,29 @@ 755 + + + src/repository/jaggeryapps/portal/controllers/apis/analytics.jag + ${pom.artifactId}-${pom.version}/repository/deployment/server/jaggeryapps/portal/controllers/apis + + 755 + + + + src/repository/jaggeryapps/portal/js/outputAdapterUiLibrary.js + ${pom.artifactId}-${pom.version}/repository/deployment/server/jaggeryapps/portal/js + + 755 + + + + src/repository/jaggeryapps/portal/templates/gadgets/igviz/js/outputAdapterUiLibrary.js + ${pom.artifactId}-${pom.version}/repository/deployment/server/jaggeryapps/portal/templates/gadgets/igviz/js + + 755 + + + ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/deployment/server/webapps/mdm-android-agent.war From febdc36cba8b94c3ebcaba27947893ebb2865513 Mon Sep 17 00:00:00 2001 From: Charitha Goonetilleke Date: Tue, 8 Mar 2016 13:44:47 +0530 Subject: [PATCH 12/12] Removed commented code and reformat --- modules/distribution/src/assembly/bin.xml | 187 ---------------------- 1 file changed, 187 deletions(-) diff --git a/modules/distribution/src/assembly/bin.xml b/modules/distribution/src/assembly/bin.xml index 25a2b248..d5418883 100644 --- a/modules/distribution/src/assembly/bin.xml +++ b/modules/distribution/src/assembly/bin.xml @@ -59,7 +59,6 @@ **/axis2services/sample01.aar **/axis2services/echo/** **/axis2services/version/** - **/version.txt **/master-datasources.xml **/carbon.xml @@ -167,13 +166,6 @@ 755 - - - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/modules @@ -224,16 +216,6 @@ authenticators.xml - - src/repository/conf/datasources ${pom.artifactId}-${pom.version}/repository/conf/datasources @@ -589,7 +571,6 @@ **/analytics-config.xml **/rdbms-config.xml - **/analytics-data-config.xml **/analytics-eventsink-config.xml @@ -668,27 +649,9 @@ **/* - - - - - - - - ${pom.artifactId}-${pom.version}/lib/endorsed @@ -707,7 +670,6 @@ - src/repository/bin/wso2server.sh ${pom.artifactId}-${pom.version}/bin @@ -718,7 +680,6 @@ ${pom.artifactId}-${pom.version}/bin 755 - src/repository/jaggeryapps/api-store/jagg.jag @@ -732,7 +693,6 @@ 755 - src/repository/jaggeryapps/portal/controllers/apis/analytics.jag @@ -740,14 +700,12 @@ 755 - src/repository/jaggeryapps/portal/js/outputAdapterUiLibrary.js ${pom.artifactId}-${pom.version}/repository/deployment/server/jaggeryapps/portal/js 755 - src/repository/jaggeryapps/portal/templates/gadgets/igviz/js/outputAdapterUiLibrary.js ${pom.artifactId}-${pom.version}/repository/deployment/server/jaggeryapps/portal/templates/gadgets/igviz/js @@ -755,7 +713,6 @@ 755 - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/deployment/server/webapps/mdm-android-agent.war @@ -816,22 +773,6 @@ true 644 - src/repository/conf/tomcat/context.xml ${pom.artifactId}-${pom.version}/repository/conf/tomcat @@ -881,7 +822,6 @@ true 644 - @@ -891,7 +831,6 @@ true 644 - src/repository/conf/event-broker.xml @@ -905,7 +844,6 @@ true 644 - @@ -925,8 +863,6 @@ true 644 - - @@ -956,7 +892,6 @@ 644 - @@ -965,7 +900,6 @@ ${pom.artifactId}-${pom.version}/repository/conf 644 - src/repository/conf/api-manager.xml @@ -981,7 +915,6 @@ true 644 - @@ -991,8 +924,6 @@ true 644 - - @@ -1002,8 +933,6 @@ true 644 - - @@ -1013,7 +942,6 @@ true 644 - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/metrics.properties @@ -1050,7 +978,6 @@ ${pom.artifactId}-${pom.version}/repository/conf/etc/ 644 - @@ -1060,7 +987,6 @@ true 644 - @@ -1070,7 +996,6 @@ true 644 - @@ -1080,7 +1005,6 @@ true 644 - @@ -1090,7 +1014,6 @@ true 644 - @@ -1100,7 +1023,6 @@ true 644 - @@ -1121,7 +1043,6 @@ true 644 - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/claim-config.xml @@ -1131,8 +1052,6 @@ true 644 - - @@ -1142,7 +1061,6 @@ WSO2AM_DB.h2.db 644 - @@ -1152,8 +1070,6 @@ WSO2DM_DB.h2.db 644 - - @@ -1163,8 +1079,6 @@ AndroidSenseDM_DB.h2.db 644 - - @@ -1174,8 +1088,6 @@ ArduinoDM_DB.h2.db 644 - - @@ -1185,8 +1097,6 @@ DigitalDisplayDM_DB.h2.db 644 - - @@ -1196,8 +1106,6 @@ DroneAnalyzerDM_DB.h2.db 644 - - @@ -1207,7 +1115,6 @@ RaspberryPiDM_DB.h2.db 644 - @@ -1217,8 +1124,6 @@ VirtualFireAlarmDM_DB.h2.db 644 - - @@ -1228,7 +1133,6 @@ WSO2MobileAndroid_DB.h2.db 644 - @@ -1238,28 +1142,12 @@ WSO2MobileWindows_DB.h2.db 644 - src/repository/conf/carbon.xml ${pom.artifactId}-${pom.version}/repository/conf/ true - - - - - - - @@ -1270,7 +1158,6 @@ true 644 - src/repository/conf/axis2/axis2.xml @@ -1279,8 +1166,6 @@ true 644 - - src/repository/conf/etc/launch.ini ${pom.artifactId}-${pom.version}/repository/conf/etc/ @@ -1288,16 +1173,6 @@ true 644 - - - - - - - - - - @@ -1308,7 +1183,6 @@ true 644 - @@ -1331,7 +1205,6 @@ ${pom.artifactId}-${pom.version}/lib 644 - @@ -1341,7 +1214,6 @@ true 644 - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/cep/storm/storm.yaml @@ -1350,8 +1222,6 @@ true - - @@ -1361,7 +1231,6 @@ true - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/output-event-adapters.xml @@ -1371,7 +1240,6 @@ true 644 - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/input-event-adapters.xml @@ -1381,7 +1249,6 @@ true 644 - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/data-bridge/data-bridge-config.xml @@ -1412,7 +1279,6 @@ 755 - @@ -1422,7 +1288,6 @@ 755 - @@ -1432,7 +1297,6 @@ 755 - @@ -1442,7 +1306,6 @@ 755 - @@ -1451,43 +1314,6 @@ ${pom.artifactId}-${pom.version}/repository/deployment/server/webapps 644 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/iot/devicemgt-config.xml @@ -1496,7 +1322,6 @@ true 644 - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/iot/devicemgt-config.xsd @@ -1505,7 +1330,6 @@ true 644 - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/iot/devicetype-config.xml @@ -1514,7 +1338,6 @@ true 644 - ../p2-profile-gen/target/wso2carbon-core-${carbon.kernel.version}/repository/conf/iot/devicetype-config.xsd @@ -1523,15 +1346,5 @@ true 644 - - - - - - - - - -