diff --git a/cli/sdncon/ui/__init__.py b/cli/sdncon/ui/__init__.py
new file mode 100755
index 0000000..9ab2783
--- /dev/null
+++ b/cli/sdncon/ui/__init__.py
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html
+#
+# 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.
+#
+
diff --git a/cli/sdncon/ui/scripts/__init__.py b/cli/sdncon/ui/scripts/__init__.py
new file mode 100755
index 0000000..9ab2783
--- /dev/null
+++ b/cli/sdncon/ui/scripts/__init__.py
@@ -0,0 +1,16 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html
+#
+# 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.
+#
+
diff --git a/cli/sdncon/ui/scripts/buildtopology.py b/cli/sdncon/ui/scripts/buildtopology.py
new file mode 100755
index 0000000..2d7e940
--- /dev/null
+++ b/cli/sdncon/ui/scripts/buildtopology.py
@@ -0,0 +1,124 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html
+#
+# 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.
+#
+#
+# Build a simple JSON of the topology for use in the ForceDirected 
+# Visualization in the InfoVis Toolkit
+#
+
+#Importing modules
+import re
+import sys
+import time
+import json
+import urllib2
+import switchalias
+from sdncon.rest.views import do_switches, do_model_list, do_instance, do_device, do_links
+
+def build_topology_data(request):
+    
+    # Query JSON from API and load into dictionary
+    switches = json.loads(do_switches(request).content)
+    devices = json.loads(do_device(request).content)
+    links = json.loads(do_links(request).content)
+    aliasDict = switchalias.aliasDict(request)
+    
+    # Dictionaries
+    parsedswitch = []
+    parseddevices = []
+    parsedlinks = []
+    
+    # Step through master 'switches' list, extract entry for each dictionary.
+    for index_switches,value1_switches in enumerate(switches):
+      tempdict = {}
+    
+      # get needed entries in 'switches'
+      tempdict['dpid'] = value1_switches.get('dpid','')
+      tempdict['inetAddress'] = value1_switches.get('inetAddress','')
+      
+      # append to final sorted output.
+      parsedswitch.append(tempdict)
+     
+    # Step through master 'device' list, extract entry for each dictionary.
+    for index_devices,value1_devices in enumerate(devices):
+      tempdict = {}
+    
+      # get needed entries in 'devices'
+      for index_mac,value_mac in enumerate(value1_devices['mac']):
+        tempdict['mac'] = value_mac
+      tempdict['ipv4'] = value1_devices.get('ipv4','Unknown')
+      for index_switch2,value_switch2 in enumerate(value1_devices['attachmentPoint']):
+        switchconnlist = []
+        switchtempdict = {}
+        if value_switch2.get('switchDPID', 'UNKNOWN') != '':
+          if value_switch2.get('port', 'UNKNOWN') != '':
+            switchtempdict['port'] = value_switch2['port']
+            switchtempdict['DPID'] = value_switch2['switchDPID']
+            switchconnlist.append(switchtempdict)
+            tempdict['attachments'] = switchconnlist
+      # append to final sorted output.
+      parseddevices.append(tempdict)
+    
+    
+    # Step through master 'links' list, extract entry for each dictionary.
+    for index_links,value1_links in enumerate(links):
+      tempdict = {}
+    
+      # get needed entries in 'links'
+      tempdict['src-switch'] = value1_links.get('src-switch','')
+      tempdict['src-port'] = value1_links.get('src-port','')
+      tempdict['src-port-state'] = value1_links.get('src-port-state','')
+      tempdict['dst-switch'] = value1_links.get('dst-switch','')
+      tempdict['dst-port'] = value1_links.get('dst-port','')
+      tempdict['dst-port-state'] = value1_links.get('dst-port-state','')
+    
+      # append to final sorted output.
+      parsedlinks.append(tempdict)
+    
+    #Begin puting the data in the JSON list
+    jsonoutput = []
+    result = ''
+    
+    
+    # Print switches by themselves to handle orphaned switches.
+    for index_switch,value_switch in enumerate(parsedswitch):
+      adjacenciestmp = []
+      datatmp = {}
+      
+      datatmp = { '$color': '#f15922', '$type': 'square', '$dim': '10'}
+      jsonoutput.append({'adjacencies': [], 'data': datatmp, 'id': value_switch['dpid'], 'name': aliasDict.get(value_switch['dpid'], value_switch['dpid'])})
+    
+    
+    # Determine host -> Switch links
+    for index_devices,value_devices in enumerate(parseddevices):
+      adjacenciestmp = []
+      datatmp = {}
+      
+      for index_adj,value_adj in enumerate(value_devices.get('attachments', '')):
+        adjacenciestmp.append({'nodeTo': str(value_adj['DPID']), 'nodeFrom': value_devices['mac'], 'data': { '$color': '#fdb813', '$lineWidth': '3' }})
+      datatmp = { '$color': '#fdb813', '$type': 'circle', '$dim': '10'}
+      jsonoutput.append({'adjacencies': adjacenciestmp, 'data': datatmp, 'id': value_devices['mac'], 'name': value_devices['mac']})
+    
+    # Determine Switch -> Switch links
+    for index_link,value_link in enumerate(parsedlinks):
+      adjacenciestmp = []
+      datatmp = {}
+      adjacenciestmp.append({'nodeTo': str(value_link['src-switch']), 'nodeFrom': value_link['dst-switch'], 'data': { '$color': '#f15922', '$lineWidth': '3' }})
+      datatmp = { '$color': '#f15922', '$type': 'square', '$dim': '10'}
+      jsonoutput.append({'adjacencies': adjacenciestmp, 'data': datatmp, 'id': value_link['dst-switch'], 'name': aliasDict.get(value_link['dst-switch'], value_link['dst-switch'])})
+    
+    result += 'var json =' + json.dumps(jsonoutput, sort_keys=True, indent=4, separators=(',', ': ')) + ';'
+    return result 
\ No newline at end of file
diff --git a/cli/sdncon/ui/scripts/showhost.py b/cli/sdncon/ui/scripts/showhost.py
new file mode 100755
index 0000000..9c72fb5
--- /dev/null
+++ b/cli/sdncon/ui/scripts/showhost.py
@@ -0,0 +1,106 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html
+#
+# 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.
+#
+#
+# Python script for querying API and displaying connected hosts in a table
+#
+#
+
+#Importing modules
+import re
+import sys
+import time
+import datetime
+import json
+import urllib2
+import switchalias
+from sdncon.rest.views import do_switches, do_model_list, do_instance, do_device
+
+def show_host_data(request):
+
+    # Query JSON from API and load into dictionary
+    switches = json.loads(do_switches(request).content)
+    switchdevices = json.loads(do_device(request).content)
+    
+    # Dictionaries
+    sorteddict = []
+    aliasDict = switchalias.aliasDict(request)
+    unsortdict = []
+     
+    # Step through master 'device' list, extract entry for each dictionary.
+    for index_devices,value1_devices in enumerate(switchdevices):
+      tempdict = {}
+      tempswitchdict = {}
+    
+      # get needed entries in 'devices'
+      tempdict['mac'] = value1_devices.get('mac','')
+      tempdict['entityClass'] = value1_devices.get('entityClass','')
+      tempdict['vlan'] = value1_devices.get('vlan','')
+      tempdict['ipv4'] = value1_devices.get('ipv4','Unknown')
+      tempdict['switch'] = value1_devices.get('attachmentPoint','')
+      tempdict['lastSeen'] = value1_devices.get('lastSeen','')
+    
+      # append to final sorted output.
+      unsortdict.append(tempdict)
+    
+    
+    sorteddict = sorted(unsortdict, key=lambda elem: "%s" % (elem['mac']))
+    
+    #print sorteddict
+    #print time.strftime('%Y-%m-%d %H:%M:%S %Z', time.gmtime(sorteddict[0]['connectedSince'] / float(1000)))
+    
+    result = ''
+    # Print table output
+    result += '<table id="showdeviceoutput" >'
+    result += '<tbody style="border-top: 0px;">'
+    result += '<tr><td>ID</td><td>MAC Address</td><td>Address Space</td><td>VLAN</td><td>IP</td><td>Switch</td><td>Last Seen</td></tr>'
+    for index_output,value_output in enumerate(sorteddict):
+        result += '<tr>'
+        result += '  <td>' + str(index_output + 1) + '</td>'
+        result += '  <td>'
+        for tmp_index,tmp_value in enumerate(value_output['mac']):
+            if tmp_index > 0:
+              result += ', ',
+            result += str(tmp_value)
+        result += '</td>'
+        result += '  <td>' + value_output.get('entityClass','') + '</td>'
+        result += '  <td>'
+        for tmp_index,tmp_value in enumerate(value_output['vlan']):
+            if tmp_index > 0:
+              result += ', ',
+            result += str(tmp_value)
+        result += '</td>'
+        result += '  <td>'
+        for tmp_index,tmp_value in enumerate(value_output['ipv4']):
+            if tmp_index > 0:
+              result += ', ',
+            result += str(tmp_value)
+        result += '</td>'
+        result += '  <td>'
+        for tmp_index,tmp_value in enumerate(value_output['switch']):
+            if tmp_index > 0:
+              result += ', ',
+            result += aliasDict.get(tmp_value.get('switchDPID', 'UNKNOWN'), tmp_value.get('switchDPID', 'UNKNOWN')) + ' Port ' + str(tmp_value.get('port', 'UNKNOWN'))
+        result += '</td>'
+        delta = round(time.time(),0) - (round(value_output.get('lastSeen',time.time()) / int(1000)))
+        if delta <= 0:
+          result += '  <td> Now </td>'
+        else:
+          result += '  <td>' + str(datetime.timedelta(seconds=delta))  + '</td>'
+        result += '</tr>'
+    result += '</tbody>'
+    result += '</table>'  
+    return result
diff --git a/cli/sdncon/ui/scripts/showlink.py b/cli/sdncon/ui/scripts/showlink.py
new file mode 100755
index 0000000..4a91d50
--- /dev/null
+++ b/cli/sdncon/ui/scripts/showlink.py
@@ -0,0 +1,87 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html
+#
+# 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.
+#
+#
+# Python script to query link states from REST API
+#
+#
+
+#Importing modules
+import re
+import sys
+import time
+import json
+import urllib2
+import switchalias
+from sdncon.rest.views import do_switches, do_model_list, do_instance, do_device, do_links
+
+
+def show_link_data(request):
+
+    # Query JSON from API and load into dictionary
+    switches = json.loads(do_switches(request).content)
+    switchlinks = json.loads(do_links(request).content)
+    
+    # Dictionaries
+    sorteddict = []
+    aliasDict = switchalias.aliasDict(request)
+    unsortdict = []
+    statedict = {0: 'FORWARDING', 1: 'DOWN', 2: 'FORWARD', 3: 'BLOCK', 4: 'MASK'}
+     
+    # Step through master 'links' list, extract entry for each dictionary.
+    for index_links,value1_links in enumerate(switchlinks):
+        tempdict = {}
+        tempswitchdict = {}
+      
+        # get needed entries in 'links'
+        tempdict['src-switch'] = value1_links.get('src-switch','')
+        tempdict['src-port'] = value1_links.get('src-port','')
+        tempdict['src-port-state'] = value1_links.get('src-port-state','')
+        tempdict['dst-switch'] = value1_links.get('dst-switch','')
+        tempdict['dst-port'] = value1_links.get('dst-port','')
+        tempdict['dst-port-state'] = value1_links.get('dst-port-state','')
+        tempdict['type'] = value1_links.get('type','')
+      
+        # append to final sorted output.
+        unsortdict.append(tempdict)
+    
+    
+    sorteddict = sorted(unsortdict, key=lambda elem: "%s %02d" % (elem['src-switch'], elem['src-port']))
+    
+    result = ''
+    # Print table output
+    result += '<table id="showlinkoutput" >'
+    result += '<tbody>'
+    result += '<tr><td>ID</td><td>Source Switch</td><td>Source Port</td><td>Source Port State</td><td>Destination Switch</td><td>Destination Port</td><td>Destination Port State</td><td>Connection Type</td></tr>'
+    for index_output,value_output in enumerate(sorteddict):
+        result += '<tr>'
+        result += '  <td>' + str(index_output + 1) + '</td>'
+        result += '  <td>' 
+        result += aliasDict.get(value_output.get('src-switch', 'UNKNOWN'), value_output.get('src-switch', 'UNKNOWN'))
+        result += '</td>'
+        result += '  <td>' + str(value_output.get('src-port','')) + '</td>'
+        result += '  <td>' + statedict.get(value_output.get('src-port-state',0),'DOWN') + '</td>'
+        result += '  <td>' 
+        result += aliasDict.get(value_output.get('dst-switch', 'UNKNOWN'), value_output.get('dst-switch', 'UNKNOWN'))
+        result += '</td>'
+        result += '  <td>' + str(value_output.get('dst-port','')) + '</td>'
+        result += '  <td>' + statedict.get(value_output.get('dst-port-state',0),'DOWN') + '</td>'
+        result += '  <td>' + value_output.get('type','') + '</td>'
+        result += '</tr>'
+    result += '</tbody>'
+    result += '</table>'
+    return result
+  
diff --git a/cli/sdncon/ui/scripts/showswitch.py b/cli/sdncon/ui/scripts/showswitch.py
new file mode 100755
index 0000000..8b8317e
--- /dev/null
+++ b/cli/sdncon/ui/scripts/showswitch.py
@@ -0,0 +1,88 @@
+#!/usr/bin/python
+#
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html
+#
+# 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.
+#
+# Python script for querying REST API and displaying connected switches in
+# a table 
+#
+
+#Importing modules
+import re
+import sys
+import time
+import json
+import urllib2
+from sdncon.rest.views import do_switches, do_model_list, do_instance
+
+def show_switch_data(request):
+    
+    switches = json.loads(do_switches(request).content)
+    switchaliases = json.loads(do_instance(request, 'switch-alias').content)
+    switchconfig = json.loads(do_instance(request, "switch-config").content)
+
+    # Dictionaries
+    sorteddict = []
+     
+    # Step through master 'switches' list, extract entry for each dictionary.
+    for index_switches,value1_switches in enumerate(switches):
+      tempdict = {}
+      tempaliasdict = {}
+      tempconfigdict = {}
+    
+      # get needed entries in 'switches'
+      tempdict['dpid'] = value1_switches.get('dpid','')
+      tempdict['inetAddress'] = value1_switches.get('inetAddress','')
+      tempdict['connectedSince'] = value1_switches.get('connectedSince','')
+    
+      # get related entries in other JSON queries
+      for index_switchaliases,value1_switchaliases in enumerate(switchaliases):
+        if value1_switchaliases['switch'] == value1_switches['dpid']:
+          tempaliasdict['alias'] = value1_switchaliases.get('id','')
+      tempdict['alias'] = tempaliasdict.get('alias','')
+    
+      for index_switchconfig,value1_switchconfig in enumerate(switchconfig):
+        if value1_switchconfig['dpid'] == value1_switches['dpid']:
+          tempconfigdict['core-switch'] = value1_switchconfig.get('core-switch','')
+          tempconfigdict['tunnel-termination'] = value1_switchconfig.get('tunnel-termination','')
+      tempdict['core-switch'] = tempconfigdict.get('core-switch','')
+      tempdict['tunnel-termination'] = tempconfigdict.get('tunnel-termination','')
+      
+      # append to final sorted output.
+      sorteddict.append(tempdict)
+    sorteddict.reverse()
+    
+    result = ''
+    # Print table output
+    result += '<table id="showswitchoutput">'
+    result += '<tbody>'
+    result += '<tr><td>ID</td><td>Alias</td><td>Switch DPID</td><td>IP Address</td><td>Connected Since</td></tr>'
+    for index_output,value_output in enumerate(sorteddict):
+      formatIPresult = re.search('/(.*):',value_output['inetAddress'])
+      result += '<tr>'
+      result += '  <td>' + str(index_output + 1) + '</td>'
+      result += '  <td>' + value_output.get('alias','') + '</td>'
+      result += '  <td>' + value_output.get('dpid','') + '</td>'
+      result += '  <td>' + formatIPresult.group(1) + '</td>'
+      if value_output['connectedSince'] != '':
+        result += '  <td>' + time.strftime('%Y-%m-%d %H:%M:%S %Z', time.gmtime(value_output['connectedSince'] / float(1000))) + '</td>'
+      else:
+        result += '  <td>Disconnected</td>'
+      result += '</tr>'
+    result += '</tbody>'
+    result += '</table>'
+    
+    return result
+
diff --git a/cli/sdncon/ui/scripts/showtunnel.py b/cli/sdncon/ui/scripts/showtunnel.py
new file mode 100755
index 0000000..a8c0545
--- /dev/null
+++ b/cli/sdncon/ui/scripts/showtunnel.py
@@ -0,0 +1,82 @@
+#!/usr/bin/python
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html
+#
+# 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.
+#
+#
+# Python script to query tunnel states from REST API
+#
+#
+
+#Importing modules
+import re
+import sys
+import time
+import json
+import urllib2
+import switchalias
+from sdncon.rest.views import do_sdnplatform_tunnel_manager
+
+def show_tunnel_data(request):
+
+    # Query JSON from API and load into dictionary
+    tunnels = json.loads(do_sdnplatform_tunnel_manager(request,'all').content)
+    
+    # Dictionaries
+    sorteddict = []
+    aliasDict = switchalias.aliasDict(request)
+    unsortdict = []
+    statedict = {0: 'FORWARDING', 1: 'DOWN', 2: 'FORWARD', 3: 'BLOCK', 4: 'MASK'}
+     
+    # Step through master 'tunnels' list, extract entry for each dictionary.
+    for index_tunnels,value1_tunnels in tunnels.iteritems():
+      tempdict = {}
+      temptunneldict = {}
+    
+      # get needed entries in 'links' 
+      tempdict['dpid'] = value1_tunnels.get('hexDpid','')
+      tempdict['tunnelEnabled'] = value1_tunnels.get('tunnelEnabled','')
+      tempdict['tunnelIPAddr'] = value1_tunnels.get('tunnelIPAddr','')
+      tempdict['tunnelActive'] = value1_tunnels.get('tunnelActive','')
+      tempdict['tunnelState'] = value1_tunnels.get('tunnelState','')
+      tempdict['tunnelIf'] = value1_tunnels.get('tunnelEndPointIntfName','')
+      tempdict['tunnelCapable'] = value1_tunnels.get('tunnelCapable','')
+      # append to final sorted output.
+      if value1_tunnels.get('tunnelCapable',''):
+        unsortdict.append(tempdict)
+    
+    sorteddict = sorted(unsortdict, key=lambda elem: "%s %s" % (elem['dpid'], elem['tunnelIPAddr']))
+    
+    result = ''
+    # Print table output
+    result += '<table id="showtunneloutput" >'
+    result += '<tbody>'
+    result += '<tr><td>ID</td><td>Switch</td><td>Tunnel Source IP</td><td>Tunnel Interface</td><td>Tunnel Enabled</td><td>Tunnel State</td></tr>'
+    
+    for index_output,value_output in enumerate(sorteddict):
+      result += '<tr>'
+      result += '  <td>' + str(index_output + 1) + '</td>'
+      result += '  <td>' 
+      result += aliasDict.get(value_output.get('dpid', 'UNKNOWN'), value_output.get('dpid', 'UNKNOWN'))
+      result += '</td>'
+      result += '  <td>' + str(value_output.get('tunnelIPAddr','')) + '</td>'
+      result += '  <td>' + value_output.get('tunnelIf','UNKNOWN') + '</td>'
+      result += '  <td>' + str(value_output.get('tunnelActive','')) + '</td>'
+      result += '  <td>' + value_output.get('tunnelState','') + '</td>'
+      result += '</tr>'
+    result += '</tbody>'
+    result += '</table>'
+    return result
+    
+      
\ No newline at end of file
diff --git a/cli/sdncon/ui/scripts/switchalias.py b/cli/sdncon/ui/scripts/switchalias.py
new file mode 100755
index 0000000..768cf60
--- /dev/null
+++ b/cli/sdncon/ui/scripts/switchalias.py
@@ -0,0 +1,42 @@
+#!/usr/bin/python
+#
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html
+#
+# 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.
+#
+# Query REST API, return dictionary with alias to DPID mappings. 
+#
+
+#Importing modules
+import re
+import sys
+import json
+import urllib2
+from sdncon.rest.views import do_instance
+
+def aliasDict(request):
+  
+  # Query JSON from API and load into dictionary
+  rawdict = json.loads(do_instance(request, 'switch-alias').content)
+
+  # Dictionaries
+  aliasdict = {}
+ 
+  # Step through master 'alias' list, extract entry for each dictionary.
+  for index_query,value1_query in enumerate(rawdict):
+
+    # get needed entries in 'alias'
+    aliasdict[value1_query.get('switch','ERR')] = value1_query.get('id',' ')
+
+  return aliasdict
diff --git a/cli/sdncon/ui/static/css/table.css b/cli/sdncon/ui/static/css/table.css
new file mode 100755
index 0000000..4cd9f4d
--- /dev/null
+++ b/cli/sdncon/ui/static/css/table.css
@@ -0,0 +1,213 @@
+/*
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html
+#
+# 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.
+#
+
+dynamic table CSS, edited for 2 tables */
+
+.dynamictable {
+	margin:0px;padding:0px;
+        border-top: 0px;
+	/*border:1px solid #e5e5e5;*/
+	width:100%;
+        float: left;
+        position:relative;
+	
+	-moz-border-radius-bottomleft:5px;
+	-webkit-border-bottom-left-radius:5px;
+	border-bottom-left-radius:5px;
+	
+	-moz-border-radius-bottomright:5px;
+	-webkit-border-bottom-right-radius:5px;
+	border-bottom-right-radius:5px;
+	
+	/*-moz-border-radius-topright:5px;
+	-webkit-border-top-right-radius:5px;
+	border-top-right-radius:5px;
+	
+	-moz-border-radius-topleft:5px;
+	-webkit-border-top-left-radius:5px;
+	border-top-left-radius:5px;*/
+}.dynamictable table{
+	width:100%;
+	margin:0px;padding:0px;
+	border-collapse: collapse;
+	border-spacing: 0px;
+}.dynamictable tr:last-child td:last-child {
+	-moz-border-radius-bottomright:5px;
+	-webkit-border-bottom-right-radius:5px;
+	border-bottom-right-radius:5px;
+}
+.dynamictable table tr:first-child td:first-child {
+/*	-moz-border-radius-topleft:5px;
+	-webkit-border-top-left-radius:5px;
+	border-top-left-radius:5px;*/
+}
+.dynamictable table tr:first-child td:last-child {
+/*	-moz-border-radius-topright:5px;
+	-webkit-border-top-right-radius:5px;
+	border-top-right-radius:5px;*/
+}.dynamictable tr:last-child td:first-child{
+	-moz-border-radius-bottomleft:5px;
+	-webkit-border-bottom-left-radius:5px;
+	border-bottom-left-radius:5px;
+}.dynamictable tr:hover td{
+	
+}
+.dynamictable tr:nth-child(odd){ background-color:#e5e5e5; }
+.dynamictable tr:nth-child(even)    { background-color:#ffffff; }.dynamictable td{
+	vertical-align:middle;
+	
+	
+	border-width:0px 1px 1px 0px;
+	text-align:center;
+	padding:7px;
+	font-size:12px;
+	font-family:Helvetica;
+	font-weight:normal;
+	color:#4d4d4f;
+}.dynamictable tr:last-child td{
+	border-width:0px 1px 0px 0px;
+}.dynamictable tr td:last-child{
+	border-width:0px 0px 1px 0px;
+}.dynamictable tr:last-child td:last-child{
+	border-width:0px 0px 0px 0px;
+}
+.dynamictable tr:first-child td{
+		background:-o-linear-gradient(bottom, #fdb813 5%, #fdb813 100%);	background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #fdb813), color-stop(1, #fdb813) );
+	background:-moz-linear-gradient( center top, #fdb813 5%, #fdb813 100% );
+	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#fdb813", endColorstr="#fdb813");	background: -o-linear-gradient(top,#fdb813,fdb813);
+
+	background-color:#fdb813;
+	/*border:0px solid #e5e5e5;*/
+	text-align:center;
+	border-width:0px 0px 1px 1px;
+	font-size:14px;
+	font-family:Helvetica;
+	font-weight:bold;
+	color:#ffffff;
+}
+.dynamictable tr:first-child:hover td{
+	background:-o-linear-gradient(bottom, #fdb813 5%, #fdb813 100%);	background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #fdb813), color-stop(1, #fdb813) );
+	background:-moz-linear-gradient( center top, #fdb813 5%, #fdb813 100% );
+	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#fdb813", endColorstr="#fdb813");	background: -o-linear-gradient(top,#fdb813,fdb813);
+
+	background-color:#fdb813;
+}
+.dynamictable tr:first-child td:first-child{
+	border-width:0px 0px 1px 0px;
+}
+.dynamictable tr:first-child td:last-child{
+	border-width:0px 0px 1px 1px;
+}
+
+/* begin dynamictable 2 */
+
+.dynamictable2 {
+	margin:0px;padding:0px;
+        border-top: 0px;
+	/*border:1px solid #e5e5e5;*/
+	width:100%;
+        float: left;
+        position:relative;
+	
+	-moz-border-radius-bottomleft:5px;
+	-webkit-border-bottom-left-radius:5px;
+	border-bottom-left-radius:5px;
+	
+	-moz-border-radius-bottomright:5px;
+	-webkit-border-bottom-right-radius:5px;
+	border-bottom-right-radius:5px;
+	
+	-moz-border-radius-topright:5px;
+	-webkit-border-top-right-radius:5px;
+	border-top-right-radius:5px;
+	
+	-moz-border-radius-topleft:5px;
+	-webkit-border-top-left-radius:5px;
+	border-top-left-radius:5px;
+}.dynamictable2 table{
+	width:100%;
+	margin:0px;padding:0px;
+	border-collapse: collapse;
+	border-spacing: 0px;
+}.dynamictable2 tr:last-child td:last-child {
+	-moz-border-radius-bottomright:5px;
+	-webkit-border-bottom-right-radius:5px;
+	border-bottom-right-radius:5px;
+}
+.dynamictable2 table tr:first-child td:first-child {
+	-moz-border-radius-topleft:5px;
+	-webkit-border-top-left-radius:5px;
+	border-top-left-radius:5px;
+}
+.dynamictable2 table tr:first-child td:last-child {
+	-moz-border-radius-topright:5px;
+	-webkit-border-top-right-radius:5px;
+	border-top-right-radius:5px;
+}.dynamictable2 tr:last-child td:first-child{
+	-moz-border-radius-bottomleft:5px;
+	-webkit-border-bottom-left-radius:5px;
+	border-bottom-left-radius:5px;
+}.dynamictable2 tr:hover td{
+	
+}
+.dynamictable2 tr:nth-child(odd){ background-color:#f5f5f5; }
+.dynamictable2 tr:nth-child(even)    { background-color:#ffffff; }.dynamictable2 td{
+	vertical-align:middle;
+	
+	
+	border-width:0px 1px 1px 0px;
+	text-align:center;
+	padding:7px;
+	font-size:12px;
+	font-family:Helvetica;
+	font-weight:normal;
+	color:#4d4d4f;
+}.dynamictable2 tr:last-child td{
+	border-width:0px 1px 0px 0px;
+}.dynamictable2 tr td:last-child{
+	border-width:0px 0px 1px 0px;
+}.dynamictable2 tr:last-child td:last-child{
+	border-width:0px 0px 0px 0px;
+}
+.dynamictable2 tr:first-child td{
+		background:-o-linear-gradient(bottom, #fdb813 5%, #fdb813 100%);	background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #fdb813), color-stop(1, #fdb813) );
+	background:-moz-linear-gradient( center top, #fdb813 5%, #fdb813 100% );
+	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#fdb813", endColorstr="#fdb813");	background: -o-linear-gradient(top,#fdb813,fdb813);
+
+	background-color:#fdb813;
+	/*border:0px solid #e5e5e5;*/
+	text-align:center;
+	border-width:0px 0px 1px 1px;
+	font-size:14px;
+	font-family:Helvetica;
+	font-weight:bold;
+	color:#ffffff;
+}
+.dynamictable2 tr:first-child:hover td{
+	background:-o-linear-gradient(bottom, #fdb813 5%, #fdb813 100%);	background:-webkit-gradient( linear, left top, left bottom, color-stop(0.05, #fdb813), color-stop(1, #fdb813) );
+	background:-moz-linear-gradient( center top, #fdb813 5%, #fdb813 100% );
+	filter:progid:DXImageTransform.Microsoft.gradient(startColorstr="#fdb813", endColorstr="#fdb813");	background: -o-linear-gradient(top,#fdb813,fdb813);
+
+	background-color:#fdb813;
+}
+.dynamictable2 tr:first-child td:first-child{
+	border-width:0px 0px 1px 0px;
+}
+.dynamictable2 tr:first-child td:last-child{
+	border-width:0px 0px 1px 1px;
+}
+
diff --git a/cli/sdncon/ui/static/css/thirdparty/images/animated-overlay.gif b/cli/sdncon/ui/static/css/thirdparty/images/animated-overlay.gif
new file mode 100755
index 0000000..d441f75
--- /dev/null
+++ b/cli/sdncon/ui/static/css/thirdparty/images/animated-overlay.gif
Binary files differ
diff --git a/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_100_FFFFFF_40x100.png b/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_100_FFFFFF_40x100.png
new file mode 100755
index 0000000..a986cc9
--- /dev/null
+++ b/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_100_FFFFFF_40x100.png
Binary files differ
diff --git a/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_45_e5e5e5_40x100.png b/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_45_e5e5e5_40x100.png
new file mode 100755
index 0000000..4164ac5
--- /dev/null
+++ b/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_45_e5e5e5_40x100.png
Binary files differ
diff --git a/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_50_00a0df_40x100.png b/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_50_00a0df_40x100.png
new file mode 100755
index 0000000..c3b2c5e
--- /dev/null
+++ b/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_50_00a0df_40x100.png
Binary files differ
diff --git a/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_50_fdb813_40x100.png b/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_50_fdb813_40x100.png
new file mode 100755
index 0000000..a9358e4
--- /dev/null
+++ b/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_50_fdb813_40x100.png
Binary files differ
diff --git a/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_55_999999_40x100.png b/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_55_999999_40x100.png
new file mode 100755
index 0000000..8149aa2
--- /dev/null
+++ b/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_55_999999_40x100.png
Binary files differ
diff --git a/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_75_aaaaaa_40x100.png b/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_75_aaaaaa_40x100.png
new file mode 100755
index 0000000..f63adca
--- /dev/null
+++ b/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_75_aaaaaa_40x100.png
Binary files differ
diff --git a/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_75_e5e5e5_40x100.png b/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_75_e5e5e5_40x100.png
new file mode 100755
index 0000000..ae411be
--- /dev/null
+++ b/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_flat_75_e5e5e5_40x100.png
Binary files differ
diff --git a/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_glass_55_f8da4e_1x400.png b/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_glass_55_f8da4e_1x400.png
new file mode 100755
index 0000000..0bf80ae
--- /dev/null
+++ b/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_glass_55_f8da4e_1x400.png
Binary files differ
diff --git a/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_gloss-wave_45_e14f1c_500x100.png b/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_gloss-wave_45_e14f1c_500x100.png
new file mode 100755
index 0000000..dc9f8af
--- /dev/null
+++ b/cli/sdncon/ui/static/css/thirdparty/images/ui-bg_gloss-wave_45_e14f1c_500x100.png
Binary files differ
diff --git a/cli/sdncon/ui/static/css/thirdparty/images/ui-icons_4d4d4f_256x240.png b/cli/sdncon/ui/static/css/thirdparty/images/ui-icons_4d4d4f_256x240.png
new file mode 100755
index 0000000..8662d52
--- /dev/null
+++ b/cli/sdncon/ui/static/css/thirdparty/images/ui-icons_4d4d4f_256x240.png
Binary files differ
diff --git a/cli/sdncon/ui/static/css/thirdparty/images/ui-icons_f47d20_256x240.png b/cli/sdncon/ui/static/css/thirdparty/images/ui-icons_f47d20_256x240.png
new file mode 100755
index 0000000..e48647c
--- /dev/null
+++ b/cli/sdncon/ui/static/css/thirdparty/images/ui-icons_f47d20_256x240.png
Binary files differ
diff --git a/cli/sdncon/ui/static/css/thirdparty/images/ui-icons_f7a50d_256x240.png b/cli/sdncon/ui/static/css/thirdparty/images/ui-icons_f7a50d_256x240.png
new file mode 100755
index 0000000..e084802
--- /dev/null
+++ b/cli/sdncon/ui/static/css/thirdparty/images/ui-icons_f7a50d_256x240.png
Binary files differ
diff --git a/cli/sdncon/ui/static/css/thirdparty/images/ui-icons_fcd113_256x240.png b/cli/sdncon/ui/static/css/thirdparty/images/ui-icons_fcd113_256x240.png
new file mode 100755
index 0000000..dd51951
--- /dev/null
+++ b/cli/sdncon/ui/static/css/thirdparty/images/ui-icons_fcd113_256x240.png
Binary files differ
diff --git a/cli/sdncon/ui/static/css/thirdparty/jquery-ui-1.10.2.custom.css b/cli/sdncon/ui/static/css/thirdparty/jquery-ui-1.10.2.custom.css
new file mode 100755
index 0000000..bc07f1d
--- /dev/null
+++ b/cli/sdncon/ui/static/css/thirdparty/jquery-ui-1.10.2.custom.css
@@ -0,0 +1,523 @@
+/*! jQuery UI - v1.10.2 - 2013-04-05
+* http://jqueryui.com
+* Includes: jquery.ui.core.css, jquery.ui.tabs.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Helvetica%2CArial%2Csans-serif%3B&fwDefault=normal&fsDefault=14&cornerRadius=5px&bgColorHeader=%23e5e5e5&bgTextureHeader=flat&bgImgOpacityHeader=75&borderColorHeader=%23e5e5e5&fcHeader=%234d4d4f&iconColorHeader=%234d4d4f&bgColorContent=%23FFFFFF&bgTextureContent=flat&bgImgOpacityContent=100&borderColorContent=%23e5e5e5&fcContent=%234d4d4f&iconColorContent=%23f47d20&bgColorDefault=%23e5e5e5&bgTextureDefault=flat&bgImgOpacityDefault=45&borderColorDefault=%23e5e5e5&fcDefault=%234d4d4d&iconColorDefault=%234d4d4f&bgColorHover=%23e5e5e5&bgTextureHover=flat&bgImgOpacityHover=75&borderColorHover=%234d4d4f&fcHover=%23fdb813&iconColorHover=%23f47d20&bgColorActive=%23fdb813&bgTextureActive=flat&bgImgOpacityActive=50&borderColorActive=%23e5e5e5&fcActive=%23ffffff&iconColorActive=%23f47d20&bgColorHighlight=%23f8da4e&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=%23fcd113&fcHighlight=%23915608&iconColorHighlight=%23f7a50d&bgColorError=%23e14f1c&bgTextureError=gloss_wave&bgImgOpacityError=45&borderColorError=%23cd0a0a&fcError=%23ffffff&iconColorError=%23fcd113&bgColorOverlay=%23aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=75&opacityOverlay=30&bgColorShadow=%23999999&bgTextureShadow=flat&bgImgOpacityShadow=55&opacityShadow=45&thicknessShadow=0px&offsetTopShadow=5px&offsetLeftShadow=5px&cornerRadiusShadow=5px&tr%26ffDefault=Helvetica%2CArial%2Csans-serif
+* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
+
+/* Layout helpers
+----------------------------------*/
+.ui-helper-hidden {
+	display: none;
+}
+.ui-helper-hidden-accessible {
+	border: 0;
+	clip: rect(0 0 0 0);
+	height: 1px;
+	margin: -1px;
+	overflow: hidden;
+	padding: 0;
+	position: absolute;
+	width: 1px;
+}
+.ui-helper-reset {
+	margin: 0;
+	padding: 0;
+	border: 0;
+	outline: 0;
+	line-height: 1.3;
+	text-decoration: none;
+	font-size: 100%;
+	list-style: none;
+}
+.ui-helper-clearfix:before,
+.ui-helper-clearfix:after {
+	content: "";
+	display: table;
+	border-collapse: collapse;
+}
+.ui-helper-clearfix:after {
+	clear: both;
+}
+.ui-helper-clearfix {
+	min-height: 0; /* support: IE7 */
+}
+.ui-helper-zfix {
+	width: 100%;
+	height: 100%;
+	top: 0;
+	left: 0;
+	position: absolute;
+	opacity: 0;
+	filter:Alpha(Opacity=0);
+}
+
+.ui-front {
+	z-index: 100;
+}
+
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-disabled {
+	cursor: default !important;
+}
+
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+	display: block;
+	text-indent: -99999px;
+	overflow: hidden;
+	background-repeat: no-repeat;
+}
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Overlays */
+.ui-widget-overlay {
+	position: fixed;
+	top: 0;
+	left: 0;
+	width: 100%;
+	height: 100%;
+}
+.ui-tabs {
+	position: relative;/* position: relative prevents IE scroll bug (element with position: relative inside container with overflow: auto appear as "fixed") */
+	padding: .2em;
+}
+.ui-tabs .ui-tabs-nav {
+	margin: 0;
+	padding: .2em .2em 0;
+}
+.ui-tabs .ui-tabs-nav li {
+	list-style: none;
+	float: left;
+	position: relative;
+	top: 0;
+	margin: 1px .2em 0 0;
+	border-bottom-width: 0;
+	padding: 0;
+	white-space: nowrap;
+}
+.ui-tabs .ui-tabs-nav li a {
+	float: left;
+	padding: .5em 1em;
+	text-decoration: none;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active {
+	margin-bottom: -1px;
+	padding-bottom: 1px;
+}
+.ui-tabs .ui-tabs-nav li.ui-tabs-active a,
+.ui-tabs .ui-tabs-nav li.ui-state-disabled a,
+.ui-tabs .ui-tabs-nav li.ui-tabs-loading a {
+	cursor: text;
+}
+.ui-tabs .ui-tabs-nav li a, /* first selector in group seems obsolete, but required to overcome bug in Opera applying cursor: text overall if defined elsewhere... */
+.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a {
+	cursor: pointer;
+}
+.ui-tabs .ui-tabs-panel {
+	display: block;
+	border-width: 0;
+	/*padding: 1em 1.4em;*/
+	background: none;
+}
+
+/* Component containers
+----------------------------------*/
+.ui-widget {
+	font-family: Helvetica,Arial,sans-serif;;
+	font-size: 14;
+}
+.ui-widget .ui-widget {
+	font-size: 1em;
+}
+.ui-widget input,
+.ui-widget select,
+.ui-widget textarea,
+.ui-widget button {
+	font-family: Helvetica,Arial,sans-serif;;
+	font-size: 1em;
+}
+.ui-widget-content {
+	/*border: 1px solid #e5e5e5;*/
+	background: #FFFFFF url(images/ui-bg_flat_100_FFFFFF_40x100.png) 50% 50% repeat-x;
+	color: #4d4d4f;
+}
+.ui-widget-content a {
+	color: #4d4d4f;
+}
+.ui-widget-header {
+	border: 1px solid #e5e5e5;
+	background: #e5e5e5 url(images/ui-bg_flat_75_e5e5e5_40x100.png) 50% 50% repeat-x;
+	color: #4d4d4f;
+	font-weight: bold;
+}
+.ui-widget-header a {
+	color: #4d4d4f;
+}
+
+/* Interaction states
+----------------------------------*/
+.ui-state-default,
+.ui-widget-content .ui-state-default,
+.ui-widget-header .ui-state-default {
+	border: 1px solid #e5e5e5;
+	background: #e5e5e5 url(images/ui-bg_flat_45_e5e5e5_40x100.png) 50% 50% repeat-x;
+	font-weight: normal;
+	color: #4d4d4d;
+}
+.ui-state-default a,
+.ui-state-default a:link,
+.ui-state-default a:visited {
+	color: #4d4d4d;
+	text-decoration: none;
+}
+.ui-state-hover,
+.ui-widget-content .ui-state-hover,
+.ui-widget-header .ui-state-hover,
+.ui-state-focus,
+.ui-widget-content .ui-state-focus,
+.ui-widget-header .ui-state-focus {
+	border: 1px solid #4d4d4f;
+	background: #e5e5e5 url(images/ui-bg_flat_75_e5e5e5_40x100.png) 50% 50% repeat-x;
+	font-weight: normal;
+	color: #fdb813;
+}
+.ui-state-hover a,
+.ui-state-hover a:hover,
+.ui-state-hover a:link,
+.ui-state-hover a:visited {
+	color: #fdb813;
+	text-decoration: none;
+}
+.ui-state-active,
+.ui-widget-content .ui-state-active,
+.ui-widget-header .ui-state-active {
+	border: 1px solid #e5e5e5;
+	background: #fdb813 url(images/ui-bg_flat_50_fdb813_40x100.png) 50% 50% repeat-x;
+	font-weight: normal;
+	color: #ffffff;
+}
+.ui-state-active a,
+.ui-state-active a:link,
+.ui-state-active a:visited {
+	color: #ffffff;
+	text-decoration: none;
+}
+
+/* Interaction Cues
+----------------------------------*/
+.ui-state-highlight,
+.ui-widget-content .ui-state-highlight,
+.ui-widget-header .ui-state-highlight {
+	border: 1px solid #fcd113;
+	background: #f8da4e url(images/ui-bg_glass_55_f8da4e_1x400.png) 50% 50% repeat-x;
+	color: #915608;
+}
+.ui-state-highlight a,
+.ui-widget-content .ui-state-highlight a,
+.ui-widget-header .ui-state-highlight a {
+	color: #915608;
+}
+.ui-state-error,
+.ui-widget-content .ui-state-error,
+.ui-widget-header .ui-state-error {
+	border: 1px solid #cd0a0a;
+	background: #e14f1c url(images/ui-bg_gloss-wave_45_e14f1c_500x100.png) 50% top repeat-x;
+	color: #ffffff;
+}
+.ui-state-error a,
+.ui-widget-content .ui-state-error a,
+.ui-widget-header .ui-state-error a {
+	color: #ffffff;
+}
+.ui-state-error-text,
+.ui-widget-content .ui-state-error-text,
+.ui-widget-header .ui-state-error-text {
+	color: #ffffff;
+}
+.ui-priority-primary,
+.ui-widget-content .ui-priority-primary,
+.ui-widget-header .ui-priority-primary {
+	font-weight: bold;
+}
+.ui-priority-secondary,
+.ui-widget-content .ui-priority-secondary,
+.ui-widget-header .ui-priority-secondary {
+	opacity: .7;
+	filter:Alpha(Opacity=70);
+	font-weight: normal;
+}
+.ui-state-disabled,
+.ui-widget-content .ui-state-disabled,
+.ui-widget-header .ui-state-disabled {
+	opacity: .35;
+	filter:Alpha(Opacity=35);
+	background-image: none;
+}
+.ui-state-disabled .ui-icon {
+	filter:Alpha(Opacity=35); /* For IE8 - See #6059 */
+}
+
+/* Icons
+----------------------------------*/
+
+/* states and images */
+.ui-icon {
+	width: 16px;
+	height: 16px;
+}
+.ui-icon,
+.ui-widget-content .ui-icon {
+	background-image: url(images/ui-icons_f47d20_256x240.png);
+}
+.ui-widget-header .ui-icon {
+	background-image: url(images/ui-icons_4d4d4f_256x240.png);
+}
+.ui-state-default .ui-icon {
+	background-image: url(images/ui-icons_4d4d4f_256x240.png);
+}
+.ui-state-hover .ui-icon,
+.ui-state-focus .ui-icon {
+	background-image: url(images/ui-icons_f47d20_256x240.png);
+}
+.ui-state-active .ui-icon {
+	background-image: url(images/ui-icons_f47d20_256x240.png);
+}
+.ui-state-highlight .ui-icon {
+	background-image: url(images/ui-icons_f7a50d_256x240.png);
+}
+.ui-state-error .ui-icon,
+.ui-state-error-text .ui-icon {
+	background-image: url(images/ui-icons_fcd113_256x240.png);
+}
+
+/* positioning */
+.ui-icon-blank { background-position: 16px 16px; }
+.ui-icon-carat-1-n { background-position: 0 0; }
+.ui-icon-carat-1-ne { background-position: -16px 0; }
+.ui-icon-carat-1-e { background-position: -32px 0; }
+.ui-icon-carat-1-se { background-position: -48px 0; }
+.ui-icon-carat-1-s { background-position: -64px 0; }
+.ui-icon-carat-1-sw { background-position: -80px 0; }
+.ui-icon-carat-1-w { background-position: -96px 0; }
+.ui-icon-carat-1-nw { background-position: -112px 0; }
+.ui-icon-carat-2-n-s { background-position: -128px 0; }
+.ui-icon-carat-2-e-w { background-position: -144px 0; }
+.ui-icon-triangle-1-n { background-position: 0 -16px; }
+.ui-icon-triangle-1-ne { background-position: -16px -16px; }
+.ui-icon-triangle-1-e { background-position: -32px -16px; }
+.ui-icon-triangle-1-se { background-position: -48px -16px; }
+.ui-icon-triangle-1-s { background-position: -64px -16px; }
+.ui-icon-triangle-1-sw { background-position: -80px -16px; }
+.ui-icon-triangle-1-w { background-position: -96px -16px; }
+.ui-icon-triangle-1-nw { background-position: -112px -16px; }
+.ui-icon-triangle-2-n-s { background-position: -128px -16px; }
+.ui-icon-triangle-2-e-w { background-position: -144px -16px; }
+.ui-icon-arrow-1-n { background-position: 0 -32px; }
+.ui-icon-arrow-1-ne { background-position: -16px -32px; }
+.ui-icon-arrow-1-e { background-position: -32px -32px; }
+.ui-icon-arrow-1-se { background-position: -48px -32px; }
+.ui-icon-arrow-1-s { background-position: -64px -32px; }
+.ui-icon-arrow-1-sw { background-position: -80px -32px; }
+.ui-icon-arrow-1-w { background-position: -96px -32px; }
+.ui-icon-arrow-1-nw { background-position: -112px -32px; }
+.ui-icon-arrow-2-n-s { background-position: -128px -32px; }
+.ui-icon-arrow-2-ne-sw { background-position: -144px -32px; }
+.ui-icon-arrow-2-e-w { background-position: -160px -32px; }
+.ui-icon-arrow-2-se-nw { background-position: -176px -32px; }
+.ui-icon-arrowstop-1-n { background-position: -192px -32px; }
+.ui-icon-arrowstop-1-e { background-position: -208px -32px; }
+.ui-icon-arrowstop-1-s { background-position: -224px -32px; }
+.ui-icon-arrowstop-1-w { background-position: -240px -32px; }
+.ui-icon-arrowthick-1-n { background-position: 0 -48px; }
+.ui-icon-arrowthick-1-ne { background-position: -16px -48px; }
+.ui-icon-arrowthick-1-e { background-position: -32px -48px; }
+.ui-icon-arrowthick-1-se { background-position: -48px -48px; }
+.ui-icon-arrowthick-1-s { background-position: -64px -48px; }
+.ui-icon-arrowthick-1-sw { background-position: -80px -48px; }
+.ui-icon-arrowthick-1-w { background-position: -96px -48px; }
+.ui-icon-arrowthick-1-nw { background-position: -112px -48px; }
+.ui-icon-arrowthick-2-n-s { background-position: -128px -48px; }
+.ui-icon-arrowthick-2-ne-sw { background-position: -144px -48px; }
+.ui-icon-arrowthick-2-e-w { background-position: -160px -48px; }
+.ui-icon-arrowthick-2-se-nw { background-position: -176px -48px; }
+.ui-icon-arrowthickstop-1-n { background-position: -192px -48px; }
+.ui-icon-arrowthickstop-1-e { background-position: -208px -48px; }
+.ui-icon-arrowthickstop-1-s { background-position: -224px -48px; }
+.ui-icon-arrowthickstop-1-w { background-position: -240px -48px; }
+.ui-icon-arrowreturnthick-1-w { background-position: 0 -64px; }
+.ui-icon-arrowreturnthick-1-n { background-position: -16px -64px; }
+.ui-icon-arrowreturnthick-1-e { background-position: -32px -64px; }
+.ui-icon-arrowreturnthick-1-s { background-position: -48px -64px; }
+.ui-icon-arrowreturn-1-w { background-position: -64px -64px; }
+.ui-icon-arrowreturn-1-n { background-position: -80px -64px; }
+.ui-icon-arrowreturn-1-e { background-position: -96px -64px; }
+.ui-icon-arrowreturn-1-s { background-position: -112px -64px; }
+.ui-icon-arrowrefresh-1-w { background-position: -128px -64px; }
+.ui-icon-arrowrefresh-1-n { background-position: -144px -64px; }
+.ui-icon-arrowrefresh-1-e { background-position: -160px -64px; }
+.ui-icon-arrowrefresh-1-s { background-position: -176px -64px; }
+.ui-icon-arrow-4 { background-position: 0 -80px; }
+.ui-icon-arrow-4-diag { background-position: -16px -80px; }
+.ui-icon-extlink { background-position: -32px -80px; }
+.ui-icon-newwin { background-position: -48px -80px; }
+.ui-icon-refresh { background-position: -64px -80px; }
+.ui-icon-shuffle { background-position: -80px -80px; }
+.ui-icon-transfer-e-w { background-position: -96px -80px; }
+.ui-icon-transferthick-e-w { background-position: -112px -80px; }
+.ui-icon-folder-collapsed { background-position: 0 -96px; }
+.ui-icon-folder-open { background-position: -16px -96px; }
+.ui-icon-document { background-position: -32px -96px; }
+.ui-icon-document-b { background-position: -48px -96px; }
+.ui-icon-note { background-position: -64px -96px; }
+.ui-icon-mail-closed { background-position: -80px -96px; }
+.ui-icon-mail-open { background-position: -96px -96px; }
+.ui-icon-suitcase { background-position: -112px -96px; }
+.ui-icon-comment { background-position: -128px -96px; }
+.ui-icon-person { background-position: -144px -96px; }
+.ui-icon-print { background-position: -160px -96px; }
+.ui-icon-trash { background-position: -176px -96px; }
+.ui-icon-locked { background-position: -192px -96px; }
+.ui-icon-unlocked { background-position: -208px -96px; }
+.ui-icon-bookmark { background-position: -224px -96px; }
+.ui-icon-tag { background-position: -240px -96px; }
+.ui-icon-home { background-position: 0 -112px; }
+.ui-icon-flag { background-position: -16px -112px; }
+.ui-icon-calendar { background-position: -32px -112px; }
+.ui-icon-cart { background-position: -48px -112px; }
+.ui-icon-pencil { background-position: -64px -112px; }
+.ui-icon-clock { background-position: -80px -112px; }
+.ui-icon-disk { background-position: -96px -112px; }
+.ui-icon-calculator { background-position: -112px -112px; }
+.ui-icon-zoomin { background-position: -128px -112px; }
+.ui-icon-zoomout { background-position: -144px -112px; }
+.ui-icon-search { background-position: -160px -112px; }
+.ui-icon-wrench { background-position: -176px -112px; }
+.ui-icon-gear { background-position: -192px -112px; }
+.ui-icon-heart { background-position: -208px -112px; }
+.ui-icon-star { background-position: -224px -112px; }
+.ui-icon-link { background-position: -240px -112px; }
+.ui-icon-cancel { background-position: 0 -128px; }
+.ui-icon-plus { background-position: -16px -128px; }
+.ui-icon-plusthick { background-position: -32px -128px; }
+.ui-icon-minus { background-position: -48px -128px; }
+.ui-icon-minusthick { background-position: -64px -128px; }
+.ui-icon-close { background-position: -80px -128px; }
+.ui-icon-closethick { background-position: -96px -128px; }
+.ui-icon-key { background-position: -112px -128px; }
+.ui-icon-lightbulb { background-position: -128px -128px; }
+.ui-icon-scissors { background-position: -144px -128px; }
+.ui-icon-clipboard { background-position: -160px -128px; }
+.ui-icon-copy { background-position: -176px -128px; }
+.ui-icon-contact { background-position: -192px -128px; }
+.ui-icon-image { background-position: -208px -128px; }
+.ui-icon-video { background-position: -224px -128px; }
+.ui-icon-script { background-position: -240px -128px; }
+.ui-icon-alert { background-position: 0 -144px; }
+.ui-icon-info { background-position: -16px -144px; }
+.ui-icon-notice { background-position: -32px -144px; }
+.ui-icon-help { background-position: -48px -144px; }
+.ui-icon-check { background-position: -64px -144px; }
+.ui-icon-bullet { background-position: -80px -144px; }
+.ui-icon-radio-on { background-position: -96px -144px; }
+.ui-icon-radio-off { background-position: -112px -144px; }
+.ui-icon-pin-w { background-position: -128px -144px; }
+.ui-icon-pin-s { background-position: -144px -144px; }
+.ui-icon-play { background-position: 0 -160px; }
+.ui-icon-pause { background-position: -16px -160px; }
+.ui-icon-seek-next { background-position: -32px -160px; }
+.ui-icon-seek-prev { background-position: -48px -160px; }
+.ui-icon-seek-end { background-position: -64px -160px; }
+.ui-icon-seek-start { background-position: -80px -160px; }
+/* ui-icon-seek-first is deprecated, use ui-icon-seek-start instead */
+.ui-icon-seek-first { background-position: -80px -160px; }
+.ui-icon-stop { background-position: -96px -160px; }
+.ui-icon-eject { background-position: -112px -160px; }
+.ui-icon-volume-off { background-position: -128px -160px; }
+.ui-icon-volume-on { background-position: -144px -160px; }
+.ui-icon-power { background-position: 0 -176px; }
+.ui-icon-signal-diag { background-position: -16px -176px; }
+.ui-icon-signal { background-position: -32px -176px; }
+.ui-icon-battery-0 { background-position: -48px -176px; }
+.ui-icon-battery-1 { background-position: -64px -176px; }
+.ui-icon-battery-2 { background-position: -80px -176px; }
+.ui-icon-battery-3 { background-position: -96px -176px; }
+.ui-icon-circle-plus { background-position: 0 -192px; }
+.ui-icon-circle-minus { background-position: -16px -192px; }
+.ui-icon-circle-close { background-position: -32px -192px; }
+.ui-icon-circle-triangle-e { background-position: -48px -192px; }
+.ui-icon-circle-triangle-s { background-position: -64px -192px; }
+.ui-icon-circle-triangle-w { background-position: -80px -192px; }
+.ui-icon-circle-triangle-n { background-position: -96px -192px; }
+.ui-icon-circle-arrow-e { background-position: -112px -192px; }
+.ui-icon-circle-arrow-s { background-position: -128px -192px; }
+.ui-icon-circle-arrow-w { background-position: -144px -192px; }
+.ui-icon-circle-arrow-n { background-position: -160px -192px; }
+.ui-icon-circle-zoomin { background-position: -176px -192px; }
+.ui-icon-circle-zoomout { background-position: -192px -192px; }
+.ui-icon-circle-check { background-position: -208px -192px; }
+.ui-icon-circlesmall-plus { background-position: 0 -208px; }
+.ui-icon-circlesmall-minus { background-position: -16px -208px; }
+.ui-icon-circlesmall-close { background-position: -32px -208px; }
+.ui-icon-squaresmall-plus { background-position: -48px -208px; }
+.ui-icon-squaresmall-minus { background-position: -64px -208px; }
+.ui-icon-squaresmall-close { background-position: -80px -208px; }
+.ui-icon-grip-dotted-vertical { background-position: 0 -224px; }
+.ui-icon-grip-dotted-horizontal { background-position: -16px -224px; }
+.ui-icon-grip-solid-vertical { background-position: -32px -224px; }
+.ui-icon-grip-solid-horizontal { background-position: -48px -224px; }
+.ui-icon-gripsmall-diagonal-se { background-position: -64px -224px; }
+.ui-icon-grip-diagonal-se { background-position: -80px -224px; }
+
+
+/* Misc visuals
+----------------------------------*/
+
+/* Corner radius */
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-left,
+.ui-corner-tl {
+	border-top-left-radius: 5px;
+}
+.ui-corner-all,
+.ui-corner-top,
+.ui-corner-right,
+.ui-corner-tr {
+	border-top-right-radius: 5px;
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-left,
+.ui-corner-bl {
+/*	border-bottom-left-radius: 5px;*/
+}
+.ui-corner-all,
+.ui-corner-bottom,
+.ui-corner-right,
+.ui-corner-br {
+/*	border-bottom-right-radius: 5px;*/
+}
+
+/* Overlays */
+.ui-widget-overlay {
+	background: #aaaaaa url(images/ui-bg_flat_75_aaaaaa_40x100.png) 50% 50% repeat-x;
+	opacity: .3;
+	filter: Alpha(Opacity=30);
+}
+.ui-widget-shadow {
+	margin: 5px 0 0 5px;
+	padding: 0px;
+	background: #999999 url(images/ui-bg_flat_55_999999_40x100.png) 50% 50% repeat-x;
+	opacity: .45;
+	filter: Alpha(Opacity=45);
+	border-radius: 5px;
+}
diff --git a/cli/sdncon/ui/static/css/thirdparty/jquery-ui-1.10.2.custom.min.css b/cli/sdncon/ui/static/css/thirdparty/jquery-ui-1.10.2.custom.min.css
new file mode 100755
index 0000000..b26eb9d
--- /dev/null
+++ b/cli/sdncon/ui/static/css/thirdparty/jquery-ui-1.10.2.custom.min.css
@@ -0,0 +1,5 @@
+/*! jQuery UI - v1.10.2 - 2013-04-05
+* http://jqueryui.com
+* Includes: jquery.ui.core.css, jquery.ui.tabs.css
+* To view and modify this theme, visit http://jqueryui.com/themeroller/?ffDefault=Helvetica%2CArial%2Csans-serif%3B&fwDefault=normal&fsDefault=14&cornerRadius=5px&bgColorHeader=%23e5e5e5&bgTextureHeader=flat&bgImgOpacityHeader=75&borderColorHeader=%23e5e5e5&fcHeader=%234d4d4f&iconColorHeader=%234d4d4f&bgColorContent=%23FFFFFF&bgTextureContent=flat&bgImgOpacityContent=100&borderColorContent=%23e5e5e5&fcContent=%234d4d4f&iconColorContent=%23f47d20&bgColorDefault=%23e5e5e5&bgTextureDefault=flat&bgImgOpacityDefault=45&borderColorDefault=%23e5e5e5&fcDefault=%234d4d4d&iconColorDefault=%234d4d4f&bgColorHover=%23e5e5e5&bgTextureHover=flat&bgImgOpacityHover=75&borderColorHover=%234d4d4f&fcHover=%23fdb813&iconColorHover=%23f47d20&bgColorActive=%23fdb813&bgTextureActive=flat&bgImgOpacityActive=50&borderColorActive=%23e5e5e5&fcActive=%23ffffff&iconColorActive=%23f47d20&bgColorHighlight=%23f8da4e&bgTextureHighlight=glass&bgImgOpacityHighlight=55&borderColorHighlight=%23fcd113&fcHighlight=%23915608&iconColorHighlight=%23f7a50d&bgColorError=%23e14f1c&bgTextureError=gloss_wave&bgImgOpacityError=45&borderColorError=%23cd0a0a&fcError=%23ffffff&iconColorError=%23fcd113&bgColorOverlay=%23aaaaaa&bgTextureOverlay=flat&bgImgOpacityOverlay=75&opacityOverlay=30&bgColorShadow=%23999999&bgTextureShadow=flat&bgImgOpacityShadow=55&opacityShadow=45&thicknessShadow=0px&offsetTopShadow=5px&offsetLeftShadow=5px&cornerRadiusShadow=5px&tr%26ffDefault=Helvetica%2CArial%2Csans-serif
+* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */.ui-helper-hidden{display:none}.ui-helper-hidden-accessible{border:0;clip:rect(0 0 0 0);height:1px;margin:-1px;overflow:hidden;padding:0;position:absolute;width:1px}.ui-helper-reset{margin:0;padding:0;border:0;outline:0;line-height:1.3;text-decoration:none;font-size:100%;list-style:none}.ui-helper-clearfix:before,.ui-helper-clearfix:after{content:"";display:table;border-collapse:collapse}.ui-helper-clearfix:after{clear:both}.ui-helper-clearfix{min-height:0}.ui-helper-zfix{width:100%;height:100%;top:0;left:0;position:absolute;opacity:0;filter:Alpha(Opacity=0)}.ui-front{z-index:100}.ui-state-disabled{cursor:default!important}.ui-icon{display:block;text-indent:-99999px;overflow:hidden;background-repeat:no-repeat}.ui-widget-overlay{position:fixed;top:0;left:0;width:100%;height:100%}.ui-tabs{position:relative;padding:.2em}.ui-tabs .ui-tabs-nav{margin:0;padding:.2em .2em 0}.ui-tabs .ui-tabs-nav li{list-style:none;float:left;position:relative;top:0;margin:1px .2em 0 0;border-bottom-width:0;padding:0;white-space:nowrap}.ui-tabs .ui-tabs-nav li a{float:left;padding:.5em 1em;text-decoration:none}.ui-tabs .ui-tabs-nav li.ui-tabs-active{margin-bottom:-1px;padding-bottom:1px}.ui-tabs .ui-tabs-nav li.ui-tabs-active a,.ui-tabs .ui-tabs-nav li.ui-state-disabled a,.ui-tabs .ui-tabs-nav li.ui-tabs-loading a{cursor:text}.ui-tabs .ui-tabs-nav li a,.ui-tabs-collapsible .ui-tabs-nav li.ui-tabs-active a{cursor:pointer}.ui-tabs .ui-tabs-panel{display:block;border-width:0;padding:1em 1.4em;background:0}.ui-widget{font-family:Helvetica,Arial,sans-serif;;font-size:14}.ui-widget .ui-widget{font-size:1em}.ui-widget input,.ui-widget select,.ui-widget textarea,.ui-widget button{font-family:Helvetica,Arial,sans-serif;;font-size:1em}.ui-widget-content{border:1px solid #e5e5e5;background:#FFF url(images/ui-bg_flat_100_FFFFFF_40x100.png) 50% 50% repeat-x;color:#4d4d4f}.ui-widget-content a{color:#4d4d4f}.ui-widget-header{border:1px solid #e5e5e5;background:#e5e5e5 url(images/ui-bg_flat_75_e5e5e5_40x100.png) 50% 50% repeat-x;color:#4d4d4f;font-weight:bold}.ui-widget-header a{color:#4d4d4f}.ui-state-default,.ui-widget-content .ui-state-default,.ui-widget-header .ui-state-default{border:1px solid #e5e5e5;background:#e5e5e5 url(images/ui-bg_flat_45_e5e5e5_40x100.png) 50% 50% repeat-x;font-weight:normal;color:#4d4d4d}.ui-state-default a,.ui-state-default a:link,.ui-state-default a:visited{color:#4d4d4d;text-decoration:none}.ui-state-hover,.ui-widget-content .ui-state-hover,.ui-widget-header .ui-state-hover,.ui-state-focus,.ui-widget-content .ui-state-focus,.ui-widget-header .ui-state-focus{border:1px solid #4d4d4f;background:#e5e5e5 url(images/ui-bg_flat_75_e5e5e5_40x100.png) 50% 50% repeat-x;font-weight:normal;color:#fdb813}.ui-state-hover a,.ui-state-hover a:hover,.ui-state-hover a:link,.ui-state-hover a:visited{color:#fdb813;text-decoration:none}.ui-state-active,.ui-widget-content .ui-state-active,.ui-widget-header .ui-state-active{border:1px solid #e5e5e5;background:#fdb813 url(images/ui-bg_flat_50_fdb813_40x100.png) 50% 50% repeat-x;font-weight:normal;color:#fff}.ui-state-active a,.ui-state-active a:link,.ui-state-active a:visited{color:#fff;text-decoration:none}.ui-state-highlight,.ui-widget-content .ui-state-highlight,.ui-widget-header .ui-state-highlight{border:1px solid #fcd113;background:#f8da4e url(images/ui-bg_glass_55_f8da4e_1x400.png) 50% 50% repeat-x;color:#915608}.ui-state-highlight a,.ui-widget-content .ui-state-highlight a,.ui-widget-header .ui-state-highlight a{color:#915608}.ui-state-error,.ui-widget-content .ui-state-error,.ui-widget-header .ui-state-error{border:1px solid #cd0a0a;background:#e14f1c url(images/ui-bg_gloss-wave_45_e14f1c_500x100.png) 50% top repeat-x;color:#fff}.ui-state-error a,.ui-widget-content .ui-state-error a,.ui-widget-header .ui-state-error a{color:#fff}.ui-state-error-text,.ui-widget-content .ui-state-error-text,.ui-widget-header .ui-state-error-text{color:#fff}.ui-priority-primary,.ui-widget-content .ui-priority-primary,.ui-widget-header .ui-priority-primary{font-weight:bold}.ui-priority-secondary,.ui-widget-content .ui-priority-secondary,.ui-widget-header .ui-priority-secondary{opacity:.7;filter:Alpha(Opacity=70);font-weight:normal}.ui-state-disabled,.ui-widget-content .ui-state-disabled,.ui-widget-header .ui-state-disabled{opacity:.35;filter:Alpha(Opacity=35);background-image:none}.ui-state-disabled .ui-icon{filter:Alpha(Opacity=35)}.ui-icon{width:16px;height:16px}.ui-icon,.ui-widget-content .ui-icon{background-image:url(images/ui-icons_f47d20_256x240.png)}.ui-widget-header .ui-icon{background-image:url(images/ui-icons_4d4d4f_256x240.png)}.ui-state-default .ui-icon{background-image:url(images/ui-icons_4d4d4f_256x240.png)}.ui-state-hover .ui-icon,.ui-state-focus .ui-icon{background-image:url(images/ui-icons_f47d20_256x240.png)}.ui-state-active .ui-icon{background-image:url(images/ui-icons_f47d20_256x240.png)}.ui-state-highlight .ui-icon{background-image:url(images/ui-icons_f7a50d_256x240.png)}.ui-state-error .ui-icon,.ui-state-error-text .ui-icon{background-image:url(images/ui-icons_fcd113_256x240.png)}.ui-icon-blank{background-position:16px 16px}.ui-icon-carat-1-n{background-position:0 0}.ui-icon-carat-1-ne{background-position:-16px 0}.ui-icon-carat-1-e{background-position:-32px 0}.ui-icon-carat-1-se{background-position:-48px 0}.ui-icon-carat-1-s{background-position:-64px 0}.ui-icon-carat-1-sw{background-position:-80px 0}.ui-icon-carat-1-w{background-position:-96px 0}.ui-icon-carat-1-nw{background-position:-112px 0}.ui-icon-carat-2-n-s{background-position:-128px 0}.ui-icon-carat-2-e-w{background-position:-144px 0}.ui-icon-triangle-1-n{background-position:0 -16px}.ui-icon-triangle-1-ne{background-position:-16px -16px}.ui-icon-triangle-1-e{background-position:-32px -16px}.ui-icon-triangle-1-se{background-position:-48px -16px}.ui-icon-triangle-1-s{background-position:-64px -16px}.ui-icon-triangle-1-sw{background-position:-80px -16px}.ui-icon-triangle-1-w{background-position:-96px -16px}.ui-icon-triangle-1-nw{background-position:-112px -16px}.ui-icon-triangle-2-n-s{background-position:-128px -16px}.ui-icon-triangle-2-e-w{background-position:-144px -16px}.ui-icon-arrow-1-n{background-position:0 -32px}.ui-icon-arrow-1-ne{background-position:-16px -32px}.ui-icon-arrow-1-e{background-position:-32px -32px}.ui-icon-arrow-1-se{background-position:-48px -32px}.ui-icon-arrow-1-s{background-position:-64px -32px}.ui-icon-arrow-1-sw{background-position:-80px -32px}.ui-icon-arrow-1-w{background-position:-96px -32px}.ui-icon-arrow-1-nw{background-position:-112px -32px}.ui-icon-arrow-2-n-s{background-position:-128px -32px}.ui-icon-arrow-2-ne-sw{background-position:-144px -32px}.ui-icon-arrow-2-e-w{background-position:-160px -32px}.ui-icon-arrow-2-se-nw{background-position:-176px -32px}.ui-icon-arrowstop-1-n{background-position:-192px -32px}.ui-icon-arrowstop-1-e{background-position:-208px -32px}.ui-icon-arrowstop-1-s{background-position:-224px -32px}.ui-icon-arrowstop-1-w{background-position:-240px -32px}.ui-icon-arrowthick-1-n{background-position:0 -48px}.ui-icon-arrowthick-1-ne{background-position:-16px -48px}.ui-icon-arrowthick-1-e{background-position:-32px -48px}.ui-icon-arrowthick-1-se{background-position:-48px -48px}.ui-icon-arrowthick-1-s{background-position:-64px -48px}.ui-icon-arrowthick-1-sw{background-position:-80px -48px}.ui-icon-arrowthick-1-w{background-position:-96px -48px}.ui-icon-arrowthick-1-nw{background-position:-112px -48px}.ui-icon-arrowthick-2-n-s{background-position:-128px -48px}.ui-icon-arrowthick-2-ne-sw{background-position:-144px -48px}.ui-icon-arrowthick-2-e-w{background-position:-160px -48px}.ui-icon-arrowthick-2-se-nw{background-position:-176px -48px}.ui-icon-arrowthickstop-1-n{background-position:-192px -48px}.ui-icon-arrowthickstop-1-e{background-position:-208px -48px}.ui-icon-arrowthickstop-1-s{background-position:-224px -48px}.ui-icon-arrowthickstop-1-w{background-position:-240px -48px}.ui-icon-arrowreturnthick-1-w{background-position:0 -64px}.ui-icon-arrowreturnthick-1-n{background-position:-16px -64px}.ui-icon-arrowreturnthick-1-e{background-position:-32px -64px}.ui-icon-arrowreturnthick-1-s{background-position:-48px -64px}.ui-icon-arrowreturn-1-w{background-position:-64px -64px}.ui-icon-arrowreturn-1-n{background-position:-80px -64px}.ui-icon-arrowreturn-1-e{background-position:-96px -64px}.ui-icon-arrowreturn-1-s{background-position:-112px -64px}.ui-icon-arrowrefresh-1-w{background-position:-128px -64px}.ui-icon-arrowrefresh-1-n{background-position:-144px -64px}.ui-icon-arrowrefresh-1-e{background-position:-160px -64px}.ui-icon-arrowrefresh-1-s{background-position:-176px -64px}.ui-icon-arrow-4{background-position:0 -80px}.ui-icon-arrow-4-diag{background-position:-16px -80px}.ui-icon-extlink{background-position:-32px -80px}.ui-icon-newwin{background-position:-48px -80px}.ui-icon-refresh{background-position:-64px -80px}.ui-icon-shuffle{background-position:-80px -80px}.ui-icon-transfer-e-w{background-position:-96px -80px}.ui-icon-transferthick-e-w{background-position:-112px -80px}.ui-icon-folder-collapsed{background-position:0 -96px}.ui-icon-folder-open{background-position:-16px -96px}.ui-icon-document{background-position:-32px -96px}.ui-icon-document-b{background-position:-48px -96px}.ui-icon-note{background-position:-64px -96px}.ui-icon-mail-closed{background-position:-80px -96px}.ui-icon-mail-open{background-position:-96px -96px}.ui-icon-suitcase{background-position:-112px -96px}.ui-icon-comment{background-position:-128px -96px}.ui-icon-person{background-position:-144px -96px}.ui-icon-print{background-position:-160px -96px}.ui-icon-trash{background-position:-176px -96px}.ui-icon-locked{background-position:-192px -96px}.ui-icon-unlocked{background-position:-208px -96px}.ui-icon-bookmark{background-position:-224px -96px}.ui-icon-tag{background-position:-240px -96px}.ui-icon-home{background-position:0 -112px}.ui-icon-flag{background-position:-16px -112px}.ui-icon-calendar{background-position:-32px -112px}.ui-icon-cart{background-position:-48px -112px}.ui-icon-pencil{background-position:-64px -112px}.ui-icon-clock{background-position:-80px -112px}.ui-icon-disk{background-position:-96px -112px}.ui-icon-calculator{background-position:-112px -112px}.ui-icon-zoomin{background-position:-128px -112px}.ui-icon-zoomout{background-position:-144px -112px}.ui-icon-search{background-position:-160px -112px}.ui-icon-wrench{background-position:-176px -112px}.ui-icon-gear{background-position:-192px -112px}.ui-icon-heart{background-position:-208px -112px}.ui-icon-star{background-position:-224px -112px}.ui-icon-link{background-position:-240px -112px}.ui-icon-cancel{background-position:0 -128px}.ui-icon-plus{background-position:-16px -128px}.ui-icon-plusthick{background-position:-32px -128px}.ui-icon-minus{background-position:-48px -128px}.ui-icon-minusthick{background-position:-64px -128px}.ui-icon-close{background-position:-80px -128px}.ui-icon-closethick{background-position:-96px -128px}.ui-icon-key{background-position:-112px -128px}.ui-icon-lightbulb{background-position:-128px -128px}.ui-icon-scissors{background-position:-144px -128px}.ui-icon-clipboard{background-position:-160px -128px}.ui-icon-copy{background-position:-176px -128px}.ui-icon-contact{background-position:-192px -128px}.ui-icon-image{background-position:-208px -128px}.ui-icon-video{background-position:-224px -128px}.ui-icon-script{background-position:-240px -128px}.ui-icon-alert{background-position:0 -144px}.ui-icon-info{background-position:-16px -144px}.ui-icon-notice{background-position:-32px -144px}.ui-icon-help{background-position:-48px -144px}.ui-icon-check{background-position:-64px -144px}.ui-icon-bullet{background-position:-80px -144px}.ui-icon-radio-on{background-position:-96px -144px}.ui-icon-radio-off{background-position:-112px -144px}.ui-icon-pin-w{background-position:-128px -144px}.ui-icon-pin-s{background-position:-144px -144px}.ui-icon-play{background-position:0 -160px}.ui-icon-pause{background-position:-16px -160px}.ui-icon-seek-next{background-position:-32px -160px}.ui-icon-seek-prev{background-position:-48px -160px}.ui-icon-seek-end{background-position:-64px -160px}.ui-icon-seek-start{background-position:-80px -160px}.ui-icon-seek-first{background-position:-80px -160px}.ui-icon-stop{background-position:-96px -160px}.ui-icon-eject{background-position:-112px -160px}.ui-icon-volume-off{background-position:-128px -160px}.ui-icon-volume-on{background-position:-144px -160px}.ui-icon-power{background-position:0 -176px}.ui-icon-signal-diag{background-position:-16px -176px}.ui-icon-signal{background-position:-32px -176px}.ui-icon-battery-0{background-position:-48px -176px}.ui-icon-battery-1{background-position:-64px -176px}.ui-icon-battery-2{background-position:-80px -176px}.ui-icon-battery-3{background-position:-96px -176px}.ui-icon-circle-plus{background-position:0 -192px}.ui-icon-circle-minus{background-position:-16px -192px}.ui-icon-circle-close{background-position:-32px -192px}.ui-icon-circle-triangle-e{background-position:-48px -192px}.ui-icon-circle-triangle-s{background-position:-64px -192px}.ui-icon-circle-triangle-w{background-position:-80px -192px}.ui-icon-circle-triangle-n{background-position:-96px -192px}.ui-icon-circle-arrow-e{background-position:-112px -192px}.ui-icon-circle-arrow-s{background-position:-128px -192px}.ui-icon-circle-arrow-w{background-position:-144px -192px}.ui-icon-circle-arrow-n{background-position:-160px -192px}.ui-icon-circle-zoomin{background-position:-176px -192px}.ui-icon-circle-zoomout{background-position:-192px -192px}.ui-icon-circle-check{background-position:-208px -192px}.ui-icon-circlesmall-plus{background-position:0 -208px}.ui-icon-circlesmall-minus{background-position:-16px -208px}.ui-icon-circlesmall-close{background-position:-32px -208px}.ui-icon-squaresmall-plus{background-position:-48px -208px}.ui-icon-squaresmall-minus{background-position:-64px -208px}.ui-icon-squaresmall-close{background-position:-80px -208px}.ui-icon-grip-dotted-vertical{background-position:0 -224px}.ui-icon-grip-dotted-horizontal{background-position:-16px -224px}.ui-icon-grip-solid-vertical{background-position:-32px -224px}.ui-icon-grip-solid-horizontal{background-position:-48px -224px}.ui-icon-gripsmall-diagonal-se{background-position:-64px -224px}.ui-icon-grip-diagonal-se{background-position:-80px -224px}.ui-corner-all,.ui-corner-top,.ui-corner-left,.ui-corner-tl{border-top-left-radius:5px}.ui-corner-all,.ui-corner-top,.ui-corner-right,.ui-corner-tr{border-top-right-radius:5px}.ui-corner-all,.ui-corner-bottom,.ui-corner-left,.ui-corner-bl{border-bottom-left-radius:5px}.ui-corner-all,.ui-corner-bottom,.ui-corner-right,.ui-corner-br{border-bottom-right-radius:5px}.ui-widget-overlay{background:#aaa url(images/ui-bg_flat_75_aaaaaa_40x100.png) 50% 50% repeat-x;opacity:.3;filter:Alpha(Opacity=30)}.ui-widget-shadow{margin:5px 0 0 5px;padding:0;background:#999 url(images/ui-bg_flat_55_999999_40x100.png) 50% 50% repeat-x;opacity:.45;filter:Alpha(Opacity=45);border-radius:5px}
diff --git a/cli/sdncon/ui/static/favicon.ico b/cli/sdncon/ui/static/favicon.ico
new file mode 100755
index 0000000..6eee6ff
--- /dev/null
+++ b/cli/sdncon/ui/static/favicon.ico
Binary files differ
diff --git a/cli/sdncon/ui/static/images/logo_opendaylight.png b/cli/sdncon/ui/static/images/logo_opendaylight.png
new file mode 100755
index 0000000..103520b
--- /dev/null
+++ b/cli/sdncon/ui/static/images/logo_opendaylight.png
Binary files differ
diff --git a/cli/sdncon/ui/static/images/refresh.png b/cli/sdncon/ui/static/images/refresh.png
new file mode 100755
index 0000000..798cbf5
--- /dev/null
+++ b/cli/sdncon/ui/static/images/refresh.png
Binary files differ
diff --git a/cli/sdncon/ui/static/js/thirdparty/jit.js b/cli/sdncon/ui/static/js/thirdparty/jit.js
new file mode 100755
index 0000000..9bf6e9e
--- /dev/null
+++ b/cli/sdncon/ui/static/js/thirdparty/jit.js
@@ -0,0 +1,17163 @@
+/*
+Copyright (c) 2011 Sencha Inc. - Author: Nicolas Garcia Belmonte (http://philogb.github.com/)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+ */
+ (function () { 
+
+/*
+  File: Core.js
+
+ */
+
+/*
+ Object: $jit
+ 
+ Defines the namespace for all library Classes and Objects. 
+ This variable is the *only* global variable defined in the Toolkit. 
+ There are also other interesting properties attached to this variable described below.
+ */
+window.$jit = function(w) {
+  w = w || window;
+  for(var k in $jit) {
+    if($jit[k].$extend) {
+      w[k] = $jit[k];
+    }
+  }
+};
+
+$jit.version = '2.0.1';
+/*
+  Object: $jit.id
+  
+  Works just like *document.getElementById*
+  
+  Example:
+  (start code js)
+  var element = $jit.id('elementId');
+  (end code)
+
+*/
+
+/*
+ Object: $jit.util
+ 
+ Contains utility functions.
+ 
+ Some of the utility functions and the Class system were based in the MooTools Framework 
+ <http://mootools.net>. Copyright (c) 2006-2010 Valerio Proietti, <http://mad4milk.net/>. 
+ MIT license <http://mootools.net/license.txt>.
+ 
+ These methods are generally also implemented in DOM manipulation frameworks like JQuery, MooTools and Prototype.
+ I'd suggest you to use the functions from those libraries instead of using these, since their functions 
+ are widely used and tested in many different platforms/browsers. Use these functions only if you have to.
+ 
+ */
+var $ = function(d) {
+  return document.getElementById(d);
+};
+
+$.empty = function() {
+};
+
+/*
+  Method: extend
+  
+  Augment an object by appending another object's properties.
+  
+  Parameters:
+  
+  original - (object) The object to be extended.
+  extended - (object) An object which properties are going to be appended to the original object.
+  
+  Example:
+  (start code js)
+  $jit.util.extend({ 'a': 1, 'b': 2 }, { 'b': 3, 'c': 4 }); //{ 'a':1, 'b': 3, 'c': 4 }
+  (end code)
+*/
+$.extend = function(original, extended) {
+  for ( var key in (extended || {}))
+    original[key] = extended[key];
+  return original;
+};
+
+$.lambda = function(value) {
+  return (typeof value == 'function') ? value : function() {
+    return value;
+  };
+};
+
+$.time = Date.now || function() {
+  return +new Date;
+};
+
+/*
+  Method: splat
+  
+  Returns an array wrapping *obj* if *obj* is not an array. Returns *obj* otherwise.
+  
+  Parameters:
+  
+  obj - (mixed) The object to be wrapped in an array.
+  
+  Example:
+  (start code js)
+  $jit.util.splat(3);   //[3]
+  $jit.util.splat([3]); //[3]
+  (end code)
+*/
+$.splat = function(obj) {
+  var type = $.type(obj);
+  return type ? ((type != 'array') ? [ obj ] : obj) : [];
+};
+
+$.type = function(elem) {
+  var type = $.type.s.call(elem).match(/^\[object\s(.*)\]$/)[1].toLowerCase();
+  if(type != 'object') return type;
+  if(elem && elem.$$family) return elem.$$family;
+  return (elem && elem.nodeName && elem.nodeType == 1)? 'element' : type;
+};
+$.type.s = Object.prototype.toString;
+
+/*
+  Method: each
+  
+  Iterates through an iterable applying *f*.
+  
+  Parameters:
+  
+  iterable - (array) The original array.
+  fn - (function) The function to apply to the array elements.
+  
+  Example:
+  (start code js)
+  $jit.util.each([3, 4, 5], function(n) { alert('number ' + n); });
+  (end code)
+*/
+$.each = function(iterable, fn) {
+  var type = $.type(iterable);
+  if (type == 'object') {
+    for ( var key in iterable)
+      fn(iterable[key], key);
+  } else {
+    for ( var i = 0, l = iterable.length; i < l; i++)
+      fn(iterable[i], i);
+  }
+};
+
+$.indexOf = function(array, item) {
+  if(Array.indexOf) return array.indexOf(item);
+  for(var i=0,l=array.length; i<l; i++) {
+    if(array[i] === item) return i;
+  }
+  return -1;
+};
+
+/*
+  Method: map
+  
+  Maps or collects an array by applying *f*.
+  
+  Parameters:
+  
+  array - (array) The original array.
+  f - (function) The function to apply to the array elements.
+  
+  Example:
+  (start code js)
+  $jit.util.map([3, 4, 5], function(n) { return n*n; }); //[9, 16, 25]
+  (end code)
+*/
+$.map = function(array, f) {
+  var ans = [];
+  $.each(array, function(elem, i) {
+    ans.push(f(elem, i));
+  });
+  return ans;
+};
+
+/*
+  Method: reduce
+  
+  Iteratively applies the binary function *f* storing the result in an accumulator.
+  
+  Parameters:
+  
+  array - (array) The original array.
+  f - (function) The function to apply to the array elements.
+  opt - (optional|mixed) The starting value for the acumulator.
+  
+  Example:
+  (start code js)
+  $jit.util.reduce([3, 4, 5], function(x, y) { return x + y; }, 0); //12
+  (end code)
+*/
+$.reduce = function(array, f, opt) {
+  var l = array.length;
+  if(l==0) return opt;
+  var acum = arguments.length == 3? opt : array[--l];
+  while(l--) {
+    acum = f(acum, array[l]);
+  }
+  return acum;
+};
+
+/*
+  Method: merge
+  
+  Merges n-objects and their sub-objects creating a new, fresh object.
+  
+  Parameters:
+  
+  An arbitrary number of objects.
+  
+  Example:
+  (start code js)
+  $jit.util.merge({ 'a': 1, 'b': 2 }, { 'b': 3, 'c': 4 }); //{ 'a':1, 'b': 3, 'c': 4 }
+  (end code)
+*/
+$.merge = function() {
+  var mix = {};
+  for ( var i = 0, l = arguments.length; i < l; i++) {
+    var object = arguments[i];
+    if ($.type(object) != 'object')
+      continue;
+    for ( var key in object) {
+      var op = object[key], mp = mix[key];
+      mix[key] = (mp && $.type(op) == 'object' && $.type(mp) == 'object') ? $
+          .merge(mp, op) : $.unlink(op);
+    }
+  }
+  return mix;
+};
+
+$.unlink = function(object) {
+  var unlinked;
+  switch ($.type(object)) {
+  case 'object':
+    unlinked = {};
+    for ( var p in object)
+      unlinked[p] = $.unlink(object[p]);
+    break;
+  case 'array':
+    unlinked = [];
+    for ( var i = 0, l = object.length; i < l; i++)
+      unlinked[i] = $.unlink(object[i]);
+    break;
+  default:
+    return object;
+  }
+  return unlinked;
+};
+
+$.zip = function() {
+  if(arguments.length === 0) return [];
+  for(var j=0, ans=[], l=arguments.length, ml=arguments[0].length; j<ml; j++) {
+    for(var i=0, row=[]; i<l; i++) {
+      row.push(arguments[i][j]);
+    }
+    ans.push(row);
+  }
+  return ans;
+};
+
+/*
+  Method: rgbToHex
+  
+  Converts an RGB array into a Hex string.
+  
+  Parameters:
+  
+  srcArray - (array) An array with R, G and B values
+  
+  Example:
+  (start code js)
+  $jit.util.rgbToHex([255, 255, 255]); //'#ffffff'
+  (end code)
+*/
+$.rgbToHex = function(srcArray, array) {
+  if (srcArray.length < 3)
+    return null;
+  if (srcArray.length == 4 && srcArray[3] == 0 && !array)
+    return 'transparent';
+  var hex = [];
+  for ( var i = 0; i < 3; i++) {
+    var bit = (srcArray[i] - 0).toString(16);
+    hex.push(bit.length == 1 ? '0' + bit : bit);
+  }
+  return array ? hex : '#' + hex.join('');
+};
+
+/*
+  Method: hexToRgb
+  
+  Converts an Hex color string into an RGB array.
+  
+  Parameters:
+  
+  hex - (string) A color hex string.
+  
+  Example:
+  (start code js)
+  $jit.util.hexToRgb('#fff'); //[255, 255, 255]
+  (end code)
+*/
+$.hexToRgb = function(hex) {
+  if (hex.length != 7) {
+    hex = hex.match(/^#?(\w{1,2})(\w{1,2})(\w{1,2})$/);
+    hex.shift();
+    if (hex.length != 3)
+      return null;
+    var rgb = [];
+    for ( var i = 0; i < 3; i++) {
+      var value = hex[i];
+      if (value.length == 1)
+        value += value;
+      rgb.push(parseInt(value, 16));
+    }
+    return rgb;
+  } else {
+    hex = parseInt(hex.slice(1), 16);
+    return [ hex >> 16, hex >> 8 & 0xff, hex & 0xff ];
+  }
+};
+
+$.destroy = function(elem) {
+  $.clean(elem);
+  if (elem.parentNode)
+    elem.parentNode.removeChild(elem);
+  if (elem.clearAttributes)
+    elem.clearAttributes();
+};
+
+$.clean = function(elem) {
+  for (var ch = elem.childNodes, i = 0, l = ch.length; i < l; i++) {
+    $.destroy(ch[i]);
+  }
+};
+
+/*
+  Method: addEvent
+  
+  Cross-browser add event listener.
+  
+  Parameters:
+  
+  obj - (obj) The Element to attach the listener to.
+  type - (string) The listener type. For example 'click', or 'mousemove'.
+  fn - (function) The callback function to be used when the event is fired.
+  
+  Example:
+  (start code js)
+  $jit.util.addEvent(elem, 'click', function(){ alert('hello'); });
+  (end code)
+*/
+$.addEvent = function(obj, type, fn) {
+  if (obj.addEventListener)
+    obj.addEventListener(type, fn, false);
+  else
+    obj.attachEvent('on' + type, fn);
+};
+
+$.addEvents = function(obj, typeObj) {
+  for(var type in typeObj) {
+    $.addEvent(obj, type, typeObj[type]);
+  }
+};
+
+$.hasClass = function(obj, klass) {
+  return (' ' + obj.className + ' ').indexOf(' ' + klass + ' ') > -1;
+};
+
+$.addClass = function(obj, klass) {
+  if (!$.hasClass(obj, klass))
+    obj.className = (obj.className + " " + klass);
+};
+
+$.removeClass = function(obj, klass) {
+  obj.className = obj.className.replace(new RegExp(
+      '(^|\\s)' + klass + '(?:\\s|$)'), '$1');
+};
+
+$.getPos = function(elem) {
+  var offset = getOffsets(elem);
+  var scroll = getScrolls(elem);
+  return {
+    x: offset.x - scroll.x,
+    y: offset.y - scroll.y
+  };
+
+  function getOffsets(elem) {
+    var position = {
+      x: 0,
+      y: 0
+    };
+    while (elem && !isBody(elem)) {
+      position.x += elem.offsetLeft;
+      position.y += elem.offsetTop;
+      elem = elem.offsetParent;
+    }
+    return position;
+  }
+
+  function getScrolls(elem) {
+    var position = {
+      x: 0,
+      y: 0
+    };
+    while (elem && !isBody(elem)) {
+      position.x += elem.scrollLeft;
+      position.y += elem.scrollTop;
+      elem = elem.parentNode;
+    }
+    return position;
+  }
+
+  function isBody(element) {
+    return (/^(?:body|html)$/i).test(element.tagName);
+  }
+};
+
+$.event = {
+  get: function(e, win) {
+    win = win || window;
+    return e || win.event;
+  },
+  getWheel: function(e) {
+    return e.wheelDelta? e.wheelDelta / 120 : -(e.detail || 0) / 3;
+  },
+  isRightClick: function(e) {
+    return (e.which == 3 || e.button == 2);
+  },
+  getPos: function(e, win) {
+    // get mouse position
+    win = win || window;
+    e = e || win.event;
+    var doc = win.document;
+    doc = doc.documentElement || doc.body;
+    //TODO(nico): make touch event handling better
+    if(e.touches && e.touches.length) {
+      e = e.touches[0];
+    }
+    var page = {
+      x: e.pageX || (e.clientX + doc.scrollLeft),
+      y: e.pageY || (e.clientY + doc.scrollTop)
+    };
+    return page;
+  },
+  stop: function(e) {
+    if (e.stopPropagation) e.stopPropagation();
+    e.cancelBubble = true;
+    if (e.preventDefault) e.preventDefault();
+    else e.returnValue = false;
+  }
+};
+
+$jit.util = $jit.id = $;
+
+var Class = function(properties) {
+  properties = properties || {};
+  var klass = function() {
+    for ( var key in this) {
+      if (typeof this[key] != 'function')
+        this[key] = $.unlink(this[key]);
+    }
+    this.constructor = klass;
+    if (Class.prototyping)
+      return this;
+    var instance = this.initialize ? this.initialize.apply(this, arguments)
+        : this;
+    //typize
+    this.$$family = 'class';
+    return instance;
+  };
+
+  for ( var mutator in Class.Mutators) {
+    if (!properties[mutator])
+      continue;
+    properties = Class.Mutators[mutator](properties, properties[mutator]);
+    delete properties[mutator];
+  }
+
+  $.extend(klass, this);
+  klass.constructor = Class;
+  klass.prototype = properties;
+  return klass;
+};
+
+Class.Mutators = {
+
+  Implements: function(self, klasses) {
+    $.each($.splat(klasses), function(klass) {
+      Class.prototyping = klass;
+      var instance = (typeof klass == 'function') ? new klass : klass;
+      for ( var prop in instance) {
+        if (!(prop in self)) {
+          self[prop] = instance[prop];
+        }
+      }
+      delete Class.prototyping;
+    });
+    return self;
+  }
+
+};
+
+$.extend(Class, {
+
+  inherit: function(object, properties) {
+    for ( var key in properties) {
+      var override = properties[key];
+      var previous = object[key];
+      var type = $.type(override);
+      if (previous && type == 'function') {
+        if (override != previous) {
+          Class.override(object, key, override);
+        }
+      } else if (type == 'object') {
+        object[key] = $.merge(previous, override);
+      } else {
+        object[key] = override;
+      }
+    }
+    return object;
+  },
+
+  override: function(object, name, method) {
+    var parent = Class.prototyping;
+    if (parent && object[name] != parent[name])
+      parent = null;
+    var override = function() {
+      var previous = this.parent;
+      this.parent = parent ? parent[name] : object[name];
+      var value = method.apply(this, arguments);
+      this.parent = previous;
+      return value;
+    };
+    object[name] = override;
+  }
+
+});
+
+Class.prototype.implement = function() {
+  var proto = this.prototype;
+  $.each(Array.prototype.slice.call(arguments || []), function(properties) {
+    Class.inherit(proto, properties);
+  });
+  return this;
+};
+
+$jit.Class = Class;
+
+/*
+  Object: $jit.json
+  
+  Provides JSON utility functions.
+  
+  Most of these functions are JSON-tree traversal and manipulation functions.
+*/
+$jit.json = {
+  /*
+     Method: prune
+  
+     Clears all tree nodes having depth greater than maxLevel.
+  
+     Parameters:
+  
+        tree - (object) A JSON tree object. For more information please see <Loader.loadJSON>.
+        maxLevel - (number) An integer specifying the maximum level allowed for this tree. All nodes having depth greater than max level will be deleted.
+
+  */
+  prune: function(tree, maxLevel) {
+    this.each(tree, function(elem, i) {
+      if (i == maxLevel && elem.children) {
+        delete elem.children;
+        elem.children = [];
+      }
+    });
+  },
+  /*
+     Method: getParent
+  
+     Returns the parent node of the node having _id_ as id.
+  
+     Parameters:
+  
+        tree - (object) A JSON tree object. See also <Loader.loadJSON>.
+        id - (string) The _id_ of the child node whose parent will be returned.
+
+    Returns:
+
+        A tree JSON node if any, or false otherwise.
+  
+  */
+  getParent: function(tree, id) {
+    if (tree.id == id)
+      return false;
+    var ch = tree.children;
+    if (ch && ch.length > 0) {
+      for ( var i = 0; i < ch.length; i++) {
+        if (ch[i].id == id)
+          return tree;
+        else {
+          var ans = this.getParent(ch[i], id);
+          if (ans)
+            return ans;
+        }
+      }
+    }
+    return false;
+  },
+  /*
+     Method: getSubtree
+  
+     Returns the subtree that matches the given id.
+  
+     Parameters:
+  
+        tree - (object) A JSON tree object. See also <Loader.loadJSON>.
+        id - (string) A node *unique* identifier.
+  
+     Returns:
+  
+        A subtree having a root node matching the given id. Returns null if no subtree matching the id is found.
+
+  */
+  getSubtree: function(tree, id) {
+    if (tree.id == id)
+      return tree;
+    for ( var i = 0, ch = tree.children; ch && i < ch.length; i++) {
+      var t = this.getSubtree(ch[i], id);
+      if (t != null)
+        return t;
+    }
+    return null;
+  },
+  /*
+     Method: eachLevel
+  
+      Iterates on tree nodes with relative depth less or equal than a specified level.
+  
+     Parameters:
+  
+        tree - (object) A JSON tree or subtree. See also <Loader.loadJSON>.
+        initLevel - (number) An integer specifying the initial relative level. Usually zero.
+        toLevel - (number) An integer specifying a top level. This method will iterate only through nodes with depth less than or equal this number.
+        action - (function) A function that receives a node and an integer specifying the actual level of the node.
+          
+    Example:
+   (start code js)
+     $jit.json.eachLevel(tree, 0, 3, function(node, depth) {
+        alert(node.name + ' ' + depth);
+     });
+   (end code)
+  */
+  eachLevel: function(tree, initLevel, toLevel, action) {
+    if (initLevel <= toLevel) {
+      action(tree, initLevel);
+      if(!tree.children) return;
+      for ( var i = 0, ch = tree.children; i < ch.length; i++) {
+        this.eachLevel(ch[i], initLevel + 1, toLevel, action);
+      }
+    }
+  },
+  /*
+     Method: each
+  
+      A JSON tree iterator.
+  
+     Parameters:
+  
+        tree - (object) A JSON tree or subtree. See also <Loader.loadJSON>.
+        action - (function) A function that receives a node.
+
+    Example:
+    (start code js)
+      $jit.json.each(tree, function(node) {
+        alert(node.name);
+      });
+    (end code)
+          
+  */
+  each: function(tree, action) {
+    this.eachLevel(tree, 0, Number.MAX_VALUE, action);
+  }
+};
+
+
+/*
+     An object containing multiple type of transformations. 
+*/
+
+$jit.Trans = {
+  $extend: true,
+  
+  linear: function(p){
+    return p;
+  }
+};
+
+var Trans = $jit.Trans;
+
+(function(){
+
+  var makeTrans = function(transition, params){
+    params = $.splat(params);
+    return $.extend(transition, {
+      easeIn: function(pos){
+        return transition(pos, params);
+      },
+      easeOut: function(pos){
+        return 1 - transition(1 - pos, params);
+      },
+      easeInOut: function(pos){
+        return (pos <= 0.5)? transition(2 * pos, params) / 2 : (2 - transition(
+            2 * (1 - pos), params)) / 2;
+      }
+    });
+  };
+
+  var transitions = {
+
+    Pow: function(p, x){
+      return Math.pow(p, x[0] || 6);
+    },
+
+    Expo: function(p){
+      return Math.pow(2, 8 * (p - 1));
+    },
+
+    Circ: function(p){
+      return 1 - Math.sin(Math.acos(p));
+    },
+
+    Sine: function(p){
+      return 1 - Math.sin((1 - p) * Math.PI / 2);
+    },
+
+    Back: function(p, x){
+      x = x[0] || 1.618;
+      return Math.pow(p, 2) * ((x + 1) * p - x);
+    },
+
+    Bounce: function(p){
+      var value;
+      for ( var a = 0, b = 1; 1; a += b, b /= 2) {
+        if (p >= (7 - 4 * a) / 11) {
+          value = b * b - Math.pow((11 - 6 * a - 11 * p) / 4, 2);
+          break;
+        }
+      }
+      return value;
+    },
+
+    Elastic: function(p, x){
+      return Math.pow(2, 10 * --p)
+          * Math.cos(20 * p * Math.PI * (x[0] || 1) / 3);
+    }
+
+  };
+
+  $.each(transitions, function(val, key){
+    Trans[key] = makeTrans(val);
+  });
+
+  $.each( [
+      'Quad', 'Cubic', 'Quart', 'Quint'
+  ], function(elem, i){
+    Trans[elem] = makeTrans(function(p){
+      return Math.pow(p, [
+        i + 2
+      ]);
+    });
+  });
+
+})();
+
+/*
+   A Class that can perform animations for generic objects.
+
+   If you are looking for animation transitions please take a look at the <Trans> object.
+
+   Used by:
+
+   <Graph.Plot>
+   
+   Based on:
+   
+   The Animation class is based in the MooTools Framework <http://mootools.net>. Copyright (c) 2006-2009 Valerio Proietti, <http://mad4milk.net/>. MIT license <http://mootools.net/license.txt>.
+
+*/
+
+var Animation = new Class( {
+
+  initialize: function(options){
+    this.setOptions(options);
+  },
+
+  setOptions: function(options){
+    var opt = {
+      duration: 2500,
+      fps: 40,
+      transition: Trans.Quart.easeInOut,
+      compute: $.empty,
+      complete: $.empty,
+      link: 'ignore'
+    };
+    this.opt = $.merge(opt, options || {});
+    return this;
+  },
+
+  step: function(){
+    var time = $.time(), opt = this.opt;
+    if (time < this.time + opt.duration) {
+      var delta = opt.transition((time - this.time) / opt.duration);
+      opt.compute(delta);
+    } else {
+      this.timer = clearInterval(this.timer);
+      opt.compute(1);
+      opt.complete();
+    }
+  },
+
+  start: function(){
+    if (!this.check())
+      return this;
+    this.time = 0;
+    this.startTimer();
+    return this;
+  },
+
+  startTimer: function(){
+    var that = this, fps = this.opt.fps;
+    if (this.timer)
+      return false;
+    this.time = $.time() - this.time;
+    this.timer = setInterval((function(){
+      that.step();
+    }), Math.round(1000 / fps));
+    return true;
+  },
+
+  pause: function(){
+    this.stopTimer();
+    return this;
+  },
+
+  resume: function(){
+    this.startTimer();
+    return this;
+  },
+
+  stopTimer: function(){
+    if (!this.timer)
+      return false;
+    this.time = $.time() - this.time;
+    this.timer = clearInterval(this.timer);
+    return true;
+  },
+
+  check: function(){
+    if (!this.timer)
+      return true;
+    if (this.opt.link == 'cancel') {
+      this.stopTimer();
+      return true;
+    }
+    return false;
+  }
+});
+
+
+var Options = function() {
+  var args = arguments;
+  for(var i=0, l=args.length, ans={}; i<l; i++) {
+    var opt = Options[args[i]];
+    if(opt.$extend) {
+      $.extend(ans, opt);
+    } else {
+      ans[args[i]] = opt;  
+    }
+  }
+  return ans;
+};
+
+/*
+ * File: Options.AreaChart.js
+ *
+*/
+
+/*
+  Object: Options.AreaChart
+  
+  <AreaChart> options. 
+  Other options included in the AreaChart are <Options.Canvas>, <Options.Label>, <Options.Margin>, <Options.Tips> and <Options.Events>.
+  
+  Syntax:
+  
+  (start code js)
+
+  Options.AreaChart = {
+    animate: true,
+    labelOffset: 3,
+    type: 'stacked',
+    selectOnHover: true,
+    showAggregates: true,
+    showLabels: true,
+    filterOnClick: false,
+    restoreOnRightClick: false
+  };
+  
+  (end code)
+  
+  Example:
+  
+  (start code js)
+
+  var areaChart = new $jit.AreaChart({
+    animate: true,
+    type: 'stacked:gradient',
+    selectOnHover: true,
+    filterOnClick: true,
+    restoreOnRightClick: true
+  });
+  
+  (end code)
+
+  Parameters:
+  
+  animate - (boolean) Default's *true*. Whether to add animated transitions when filtering/restoring stacks.
+  labelOffset - (number) Default's *3*. Adds margin between the label and the default place where it should be drawn.
+  type - (string) Default's *'stacked'*. Stack style. Posible values are 'stacked', 'stacked:gradient' to add gradients.
+  selectOnHover - (boolean) Default's *true*. If true, it will add a mark to the hovered stack.
+  showAggregates - (boolean, function) Default's *true*. Display the values of the stacks. Can also be a function that returns *true* or *false* to display or filter some values. That same function can also return a string with the formatted value.
+  showLabels - (boolean, function) Default's *true*. Display the name of the slots. Can also be a function that returns *true* or *false* to display or not each label.
+  filterOnClick - (boolean) Default's *true*. Select the clicked stack by hiding all other stacks.
+  restoreOnRightClick - (boolean) Default's *true*. Show all stacks by right clicking.
+  
+*/
+  
+Options.AreaChart = {
+  $extend: true,
+
+  animate: true,
+  labelOffset: 3, // label offset
+  type: 'stacked', // gradient
+  Tips: {
+    enable: false,
+    onShow: $.empty,
+    onHide: $.empty
+  },
+  Events: {
+    enable: false,
+    onClick: $.empty
+  },
+  selectOnHover: true,
+  showAggregates: true,
+  showLabels: true,
+  filterOnClick: false,
+  restoreOnRightClick: false
+};
+
+/*
+ * File: Options.Margin.js
+ *
+*/
+
+/*
+  Object: Options.Margin
+  
+  Canvas drawing margins. 
+  
+  Syntax:
+  
+  (start code js)
+
+  Options.Margin = {
+    top: 0,
+    left: 0,
+    right: 0,
+    bottom: 0
+  };
+  
+  (end code)
+  
+  Example:
+  
+  (start code js)
+
+  var viz = new $jit.Viz({
+    Margin: {
+      right: 10,
+      bottom: 20
+    }
+  });
+  
+  (end code)
+
+  Parameters:
+  
+  top - (number) Default's *0*. Top margin.
+  left - (number) Default's *0*. Left margin.
+  right - (number) Default's *0*. Right margin.
+  bottom - (number) Default's *0*. Bottom margin.
+  
+*/
+
+Options.Margin = {
+  $extend: false,
+  
+  top: 0,
+  left: 0,
+  right: 0,
+  bottom: 0
+};
+
+/*
+ * File: Options.Canvas.js
+ *
+*/
+
+/*
+  Object: Options.Canvas
+  
+  These are Canvas general options, like where to append it in the DOM, its dimensions, background, 
+  and other more advanced options.
+  
+  Syntax:
+  
+  (start code js)
+
+  Options.Canvas = {
+    injectInto: 'id',
+    type: '2D', //'3D'
+    width: false,
+    height: false,
+    useCanvas: false,
+    withLabels: true,
+    background: false
+  };  
+  (end code)
+  
+  Example:
+  
+  (start code js)
+  var viz = new $jit.Viz({
+    injectInto: 'someContainerId',
+    width: 500,
+    height: 700
+  });
+  (end code)
+  
+  Parameters:
+  
+  injectInto - *required* (string|element) The id of the DOM container for the visualization. It can also be an Element provided that it has an id.
+  type - (string) Context type. Default's 2D but can be 3D for webGL enabled browsers.
+  width - (number) Default's to the *container's offsetWidth*. The width of the canvas.
+  height - (number) Default's to the *container's offsetHeight*. The height of the canvas.
+  useCanvas - (boolean|object) Default's *false*. You can pass another <Canvas> instance to be used by the visualization.
+  withLabels - (boolean) Default's *true*. Whether to use a label container for the visualization.
+  background - (boolean|object) Default's *false*. An object containing information about the rendering of a background canvas.
+*/
+
+Options.Canvas = {
+    $extend: true,
+    
+    injectInto: 'id',
+    type: '2D',
+    width: false,
+    height: false,
+    useCanvas: false,
+    withLabels: true,
+    background: false,
+    
+    Scene: {
+      Lighting: {
+        enable: false,
+        ambient: [1, 1, 1],
+        directional: {
+          direction: { x: -100, y: -100, z: -100 },
+          color: [0.5, 0.3, 0.1]
+        }
+      }
+    }
+};
+
+/*
+ * File: Options.Tree.js
+ *
+*/
+
+/*
+  Object: Options.Tree
+  
+  Options related to (strict) Tree layout algorithms. These options are used by the <ST> visualization.
+  
+  Syntax:
+  
+  (start code js)
+  Options.Tree = {
+    orientation: "left",
+    subtreeOffset: 8,
+    siblingOffset: 5,
+    indent:10,
+    multitree: false,
+    align:"center"
+  };
+  (end code)
+  
+  Example:
+  
+  (start code js)
+  var st = new $jit.ST({
+    orientation: 'left',
+    subtreeOffset: 1,
+    siblingOFfset: 5,
+    multitree: true
+  });
+  (end code)
+
+  Parameters:
+    
+  subtreeOffset - (number) Default's 8. Separation offset between subtrees.
+  siblingOffset - (number) Default's 5. Separation offset between siblings.
+  orientation - (string) Default's 'left'. Tree orientation layout. Possible values are 'left', 'top', 'right', 'bottom'.
+  align - (string) Default's *center*. Whether the tree alignment is 'left', 'center' or 'right'.
+  indent - (number) Default's 10. Used when *align* is left or right and shows an indentation between parent and children.
+  multitree - (boolean) Default's *false*. Used with the node $orn data property for creating multitrees.
+     
+*/
+Options.Tree = {
+    $extend: true,
+    
+    orientation: "left",
+    subtreeOffset: 8,
+    siblingOffset: 5,
+    indent:10,
+    multitree: false,
+    align:"center"
+};
+
+
+/*
+ * File: Options.Node.js
+ *
+*/
+
+/*
+  Object: Options.Node
+
+  Provides Node rendering options for Tree and Graph based visualizations.
+
+  Syntax:
+    
+  (start code js)
+  Options.Node = {
+    overridable: false,
+    type: 'circle',
+    color: '#ccb',
+    alpha: 1,
+    dim: 3,
+    height: 20,
+    width: 90,
+    autoHeight: false,
+    autoWidth: false,
+    lineWidth: 1,
+    transform: true,
+    align: "center",
+    angularWidth:1,
+    span:1,
+    CanvasStyles: {}
+  };
+  (end code)
+  
+  Example:
+  
+  (start code js)
+  var viz = new $jit.Viz({
+    Node: {
+      overridable: true,
+      width: 30,
+      autoHeight: true,
+      type: 'rectangle'
+    }
+  });
+  (end code)
+  
+  Parameters:
+
+  overridable - (boolean) Default's *false*. Determine whether or not general node properties can be overridden by a particular <Graph.Node>.
+  type - (string) Default's *circle*. Node's shape. Node built-in types include 'circle', 'rectangle', 'square', 'ellipse', 'triangle', 'star'. The default Node type might vary in each visualization. You can also implement (non built-in) custom Node types into your visualizations.
+  color - (string) Default's *#ccb*. Node color.
+  alpha - (number) Default's *1*. The Node's alpha value. *1* is for full opacity.
+  dim - (number) Default's *3*. An extra parameter used by 'circle', 'square', 'triangle' and 'star' node types. Depending on each shape, this parameter can set the radius of a circle, half the length of the side of a square, half the base and half the height of a triangle or the length of a side of a star (concave decagon).
+  height - (number) Default's *20*. Used by 'rectangle' and 'ellipse' node types. The height of the node shape.
+  width - (number) Default's *90*. Used by 'rectangle' and 'ellipse' node types. The width of the node shape.
+  autoHeight - (boolean) Default's *false*. Whether to set an auto height for the node depending on the content of the Node's label.
+  autoWidth - (boolean) Default's *false*. Whether to set an auto width for the node depending on the content of the Node's label.
+  lineWidth - (number) Default's *1*. Used only by some Node shapes. The line width of the strokes of a node.
+  transform - (boolean) Default's *true*. Only used by the <Hypertree> visualization. Whether to scale the nodes according to the moebius transformation.
+  align - (string) Default's *center*. Possible values are 'center', 'left' or 'right'. Used only by the <ST> visualization, these parameters are used for aligning nodes when some of they dimensions vary.
+  angularWidth - (number) Default's *1*. Used in radial layouts (like <RGraph> or <Sunburst> visualizations). The amount of relative 'space' set for a node.
+  span - (number) Default's *1*. Used in radial layouts (like <RGraph> or <Sunburst> visualizations). The angle span amount set for a node.
+  CanvasStyles - (object) Default's an empty object (i.e. {}). Attach any other canvas specific property that you'd set to the canvas context before plotting a Node.
+
+*/
+Options.Node = {
+  $extend: false,
+  
+  overridable: false,
+  type: 'circle',
+  color: '#ccb',
+  alpha: 1,
+  dim: 3,
+  height: 20,
+  width: 90,
+  autoHeight: false,
+  autoWidth: false,
+  lineWidth: 1,
+  transform: true,
+  align: "center",
+  angularWidth:1,
+  span:1,
+  //Raw canvas styles to be
+  //applied to the context instance
+  //before plotting a node
+  CanvasStyles: {}
+};
+
+
+/*
+ * File: Options.Edge.js
+ *
+*/
+
+/*
+  Object: Options.Edge
+
+  Provides Edge rendering options for Tree and Graph based visualizations.
+
+  Syntax:
+    
+  (start code js)
+  Options.Edge = {
+    overridable: false,
+    type: 'line',
+    color: '#ccb',
+    lineWidth: 1,
+    dim:15,
+    alpha: 1,
+    CanvasStyles: {}
+  };
+  (end code)
+  
+  Example:
+  
+  (start code js)
+  var viz = new $jit.Viz({
+    Edge: {
+      overridable: true,
+      type: 'line',
+      color: '#fff',
+      CanvasStyles: {
+        shadowColor: '#ccc',
+        shadowBlur: 10
+      }
+    }
+  });
+  (end code)
+  
+  Parameters:
+    
+   overridable - (boolean) Default's *false*. Determine whether or not general edges properties can be overridden by a particular <Graph.Adjacence>.
+   type - (string) Default's 'line'. Edge styles include 'line', 'hyperline', 'arrow'. The default Edge type might vary in each visualization. You can also implement custom Edge types.
+   color - (string) Default's '#ccb'. Edge color.
+   lineWidth - (number) Default's *1*. Line/Edge width.
+   alpha - (number) Default's *1*. The Edge's alpha value. *1* is for full opacity.
+   dim - (number) Default's *15*. An extra parameter used by other complex shapes such as quadratic, bezier or arrow, to determine the shape's diameter.
+   epsilon - (number) Default's *7*. Only used when using *enableForEdges* in <Options.Events>. This dimension is used to create an area for the line where the contains method for the edge returns *true*.
+   CanvasStyles - (object) Default's an empty object (i.e. {}). Attach any other canvas specific property that you'd set to the canvas context before plotting an Edge.
+
+  See also:
+   
+   If you want to know more about how to customize Node/Edge data per element, in the JSON or programmatically, take a look at this article.
+*/
+Options.Edge = {
+  $extend: false,
+  
+  overridable: false,
+  type: 'line',
+  color: '#ccb',
+  lineWidth: 1,
+  dim:15,
+  alpha: 1,
+  epsilon: 7,
+
+  //Raw canvas styles to be
+  //applied to the context instance
+  //before plotting an edge
+  CanvasStyles: {}
+};
+
+
+/*
+ * File: Options.Fx.js
+ *
+*/
+
+/*
+  Object: Options.Fx
+
+  Provides animation options like duration of the animations, frames per second and animation transitions.  
+
+  Syntax:
+  
+  (start code js)
+    Options.Fx = {
+      fps:40,
+      duration: 2500,
+      transition: $jit.Trans.Quart.easeInOut,
+      clearCanvas: true
+    };
+  (end code)
+  
+  Example:
+  
+  (start code js)
+  var viz = new $jit.Viz({
+    duration: 1000,
+    fps: 35,
+    transition: $jit.Trans.linear
+  });
+  (end code)
+  
+  Parameters:
+  
+  clearCanvas - (boolean) Default's *true*. Whether to clear the frame/canvas when the viz is plotted or animated.
+  duration - (number) Default's *2500*. Duration of the animation in milliseconds.
+  fps - (number) Default's *40*. Frames per second.
+  transition - (object) Default's *$jit.Trans.Quart.easeInOut*. The transition used for the animations. See below for a more detailed explanation.
+  
+  Object: $jit.Trans
+  
+  This object is used for specifying different animation transitions in all visualizations.
+
+  There are many different type of animation transitions.
+
+  linear:
+
+  Displays a linear transition
+
+  >Trans.linear
+  
+  (see Linear.png)
+
+  Quad:
+
+  Displays a Quadratic transition.
+
+  >Trans.Quad.easeIn
+  >Trans.Quad.easeOut
+  >Trans.Quad.easeInOut
+  
+ (see Quad.png)
+
+ Cubic:
+
+ Displays a Cubic transition.
+
+ >Trans.Cubic.easeIn
+ >Trans.Cubic.easeOut
+ >Trans.Cubic.easeInOut
+
+ (see Cubic.png)
+
+ Quart:
+
+ Displays a Quartetic transition.
+
+ >Trans.Quart.easeIn
+ >Trans.Quart.easeOut
+ >Trans.Quart.easeInOut
+
+ (see Quart.png)
+
+ Quint:
+
+ Displays a Quintic transition.
+
+ >Trans.Quint.easeIn
+ >Trans.Quint.easeOut
+ >Trans.Quint.easeInOut
+
+ (see Quint.png)
+
+ Expo:
+
+ Displays an Exponential transition.
+
+ >Trans.Expo.easeIn
+ >Trans.Expo.easeOut
+ >Trans.Expo.easeInOut
+
+ (see Expo.png)
+
+ Circ:
+
+ Displays a Circular transition.
+
+ >Trans.Circ.easeIn
+ >Trans.Circ.easeOut
+ >Trans.Circ.easeInOut
+
+ (see Circ.png)
+
+ Sine:
+
+ Displays a Sineousidal transition.
+
+ >Trans.Sine.easeIn
+ >Trans.Sine.easeOut
+ >Trans.Sine.easeInOut
+
+ (see Sine.png)
+
+ Back:
+
+ >Trans.Back.easeIn
+ >Trans.Back.easeOut
+ >Trans.Back.easeInOut
+
+ (see Back.png)
+
+ Bounce:
+
+ Bouncy transition.
+
+ >Trans.Bounce.easeIn
+ >Trans.Bounce.easeOut
+ >Trans.Bounce.easeInOut
+
+ (see Bounce.png)
+
+ Elastic:
+
+ Elastic curve.
+
+ >Trans.Elastic.easeIn
+ >Trans.Elastic.easeOut
+ >Trans.Elastic.easeInOut
+
+ (see Elastic.png)
+ 
+ Based on:
+     
+ Easing and Transition animation methods are based in the MooTools Framework <http://mootools.net>. Copyright (c) 2006-2010 Valerio Proietti, <http://mad4milk.net/>. MIT license <http://mootools.net/license.txt>.
+
+
+*/
+Options.Fx = {
+  $extend: true,
+  
+  fps:40,
+  duration: 2500,
+  transition: $jit.Trans.Quart.easeInOut,
+  clearCanvas: true
+};
+
+/*
+ * File: Options.Label.js
+ *
+*/
+/*
+  Object: Options.Label
+
+  Provides styling for Labels such as font size, family, etc. Also sets Node labels as HTML, SVG or Native canvas elements.  
+
+  Syntax:
+  
+  (start code js)
+    Options.Label = {
+      overridable: false,
+      type: 'HTML', //'SVG', 'Native'
+      style: ' ',
+      size: 10,
+      family: 'sans-serif',
+      textAlign: 'center',
+      textBaseline: 'alphabetic',
+      color: '#fff'
+    };
+  (end code)
+  
+  Example:
+  
+  (start code js)
+  var viz = new $jit.Viz({
+    Label: {
+      type: 'Native',
+      size: 11,
+      color: '#ccc'
+    }
+  });
+  (end code)
+  
+  Parameters:
+    
+  overridable - (boolean) Default's *false*. Determine whether or not general label properties can be overridden by a particular <Graph.Node>.
+  type - (string) Default's *HTML*. The type for the labels. Can be 'HTML', 'SVG' or 'Native' canvas labels.
+  style - (string) Default's *empty string*. Can be 'italic' or 'bold'. This parameter is only taken into account when using 'Native' canvas labels. For DOM based labels the className *node* is added to the DOM element for styling via CSS. You can also use <Options.Controller> methods to style individual labels.
+  size - (number) Default's *10*. The font's size. This parameter is only taken into account when using 'Native' canvas labels. For DOM based labels the className *node* is added to the DOM element for styling via CSS. You can also use <Options.Controller> methods to style individual labels.
+  family - (string) Default's *sans-serif*. The font's family. This parameter is only taken into account when using 'Native' canvas labels. For DOM based labels the className *node* is added to the DOM element for styling via CSS. You can also use <Options.Controller> methods to style individual labels.
+  color - (string) Default's *#fff*. The font's color. This parameter is only taken into account when using 'Native' canvas labels. For DOM based labels the className *node* is added to the DOM element for styling via CSS. You can also use <Options.Controller> methods to style individual labels.
+*/
+Options.Label = {
+  $extend: false,
+  
+  overridable: false,
+  type: 'HTML', //'SVG', 'Native'
+  style: ' ',
+  size: 10,
+  family: 'sans-serif',
+  textAlign: 'center',
+  textBaseline: 'alphabetic',
+  color: '#fff'
+};
+
+
+/*
+ * File: Options.Tips.js
+ *
+ */
+
+/*
+  Object: Options.Tips
+  
+  Tips options
+  
+  Syntax:
+    
+  (start code js)
+  Options.Tips = {
+    enable: false,
+    type: 'auto',
+    offsetX: 20,
+    offsetY: 20,
+    onShow: $.empty,
+    onHide: $.empty
+  };
+  (end code)
+  
+  Example:
+  
+  (start code js)
+  var viz = new $jit.Viz({
+    Tips: {
+      enable: true,
+      type: 'Native',
+      offsetX: 10,
+      offsetY: 10,
+      onShow: function(tip, node) {
+        tip.innerHTML = node.name;
+      }
+    }
+  });
+  (end code)
+
+  Parameters:
+
+  enable - (boolean) Default's *false*. If *true*, a tooltip will be shown when a node is hovered. The tooltip is a div DOM element having "tip" as CSS class. 
+  type - (string) Default's *auto*. Defines where to attach the MouseEnter/Leave tooltip events. Possible values are 'Native' to attach them to the canvas or 'HTML' to attach them to DOM label elements (if defined). 'auto' sets this property to the value of <Options.Label>'s *type* property.
+  offsetX - (number) Default's *20*. An offset added to the current tooltip x-position (which is the same as the current mouse position). Default's 20.
+  offsetY - (number) Default's *20*. An offset added to the current tooltip y-position (which is the same as the current mouse position). Default's 20.
+  onShow(tip, node) - This callack is used right before displaying a tooltip. The first formal parameter is the tip itself (which is a DivElement). The second parameter may be a <Graph.Node> for graph based visualizations or an object with label, value properties for charts.
+  onHide() - This callack is used when hiding a tooltip.
+
+*/
+Options.Tips = {
+  $extend: false,
+  
+  enable: false,
+  type: 'auto',
+  offsetX: 20,
+  offsetY: 20,
+  force: false,
+  onShow: $.empty,
+  onHide: $.empty
+};
+
+
+/*
+ * File: Options.NodeStyles.js
+ *
+ */
+
+/*
+  Object: Options.NodeStyles
+  
+  Apply different styles when a node is hovered or selected.
+  
+  Syntax:
+    
+  (start code js)
+  Options.NodeStyles = {
+    enable: false,
+    type: 'auto',
+    stylesHover: false,
+    stylesClick: false
+  };
+  (end code)
+  
+  Example:
+  
+  (start code js)
+  var viz = new $jit.Viz({
+    NodeStyles: {
+      enable: true,
+      type: 'Native',
+      stylesHover: {
+        dim: 30,
+        color: '#fcc'
+      },
+      duration: 600
+    }
+  });
+  (end code)
+
+  Parameters:
+  
+  enable - (boolean) Default's *false*. Whether to enable this option.
+  type - (string) Default's *auto*. Use this to attach the hover/click events in the nodes or the nodes labels (if they have been defined as DOM elements: 'HTML' or 'SVG', see <Options.Label> for more details). The default 'auto' value will set NodeStyles to the same type defined for <Options.Label>.
+  stylesHover - (boolean|object) Default's *false*. An object with node styles just like the ones defined for <Options.Node> or *false* otherwise.
+  stylesClick - (boolean|object) Default's *false*. An object with node styles just like the ones defined for <Options.Node> or *false* otherwise.
+*/
+
+Options.NodeStyles = {
+  $extend: false,
+  
+  enable: false,
+  type: 'auto',
+  stylesHover: false,
+  stylesClick: false
+};
+
+
+/*
+ * File: Options.Events.js
+ *
+*/
+
+/*
+  Object: Options.Events
+  
+  Configuration for adding mouse/touch event handlers to Nodes.
+  
+  Syntax:
+  
+  (start code js)
+  Options.Events = {
+    enable: false,
+    enableForEdges: false,
+    type: 'auto',
+    onClick: $.empty,
+    onRightClick: $.empty,
+    onMouseMove: $.empty,
+    onMouseEnter: $.empty,
+    onMouseLeave: $.empty,
+    onDragStart: $.empty,
+    onDragMove: $.empty,
+    onDragCancel: $.empty,
+    onDragEnd: $.empty,
+    onTouchStart: $.empty,
+    onTouchMove: $.empty,
+    onTouchEnd: $.empty,
+    onTouchCancel: $.empty,
+    onMouseWheel: $.empty
+  };
+  (end code)
+  
+  Example:
+  
+  (start code js)
+  var viz = new $jit.Viz({
+    Events: {
+      enable: true,
+      onClick: function(node, eventInfo, e) {
+        viz.doSomething();
+      },
+      onMouseEnter: function(node, eventInfo, e) {
+        viz.canvas.getElement().style.cursor = 'pointer';
+      },
+      onMouseLeave: function(node, eventInfo, e) {
+        viz.canvas.getElement().style.cursor = '';
+      }
+    }
+  });
+  (end code)
+  
+  Parameters:
+  
+  enable - (boolean) Default's *false*. Whether to enable the Event system.
+  enableForEdges - (boolean) Default's *false*. Whether to track events also in arcs. If *true* the same callbacks -described below- are used for nodes *and* edges. A simple duck type check for edges is to check for *node.nodeFrom*.
+  type - (string) Default's 'auto'. Whether to attach the events onto the HTML labels (via event delegation) or to use the custom 'Native' canvas Event System of the library. 'auto' is set when you let the <Options.Label> *type* parameter decide this.
+  onClick(node, eventInfo, e) - Triggered when a user performs a click in the canvas. *node* is the <Graph.Node> clicked or false if no node has been clicked. *e* is the grabbed event (should return the native event in a cross-browser manner). *eventInfo* is an object containing useful methods like *getPos* to get the mouse position relative to the canvas. 
+  onRightClick(node, eventInfo, e) - Triggered when a user performs a right click in the canvas. *node* is the <Graph.Node> right clicked or false if no node has been clicked. *e* is the grabbed event (should return the native event in a cross-browser manner). *eventInfo* is an object containing useful methods like *getPos* to get the mouse position relative to the canvas. 
+  onMouseMove(node, eventInfo, e) - Triggered when the user moves the mouse. *node* is the <Graph.Node> under the cursor as it's moving over the canvas or false if no node has been clicked. *e* is the grabbed event (should return the native event in a cross-browser manner).  *eventInfo* is an object containing useful methods like *getPos* to get the mouse position relative to the canvas.
+  onMouseEnter(node, eventInfo, e) - Triggered when a user moves the mouse over a node. *node* is the <Graph.Node> that the mouse just entered. *e* is the grabbed event (should return the native event in a cross-browser manner). *eventInfo* is an object containing useful methods like *getPos* to get the mouse position relative to the canvas. 
+  onMouseLeave(node, eventInfo, e) - Triggered when the user mouse-outs a node. *node* is the <Graph.Node> 'mouse-outed'. *e* is the grabbed event (should return the native event in a cross-browser manner). *eventInfo* is an object containing useful methods like *getPos* to get the mouse position relative to the canvas. 
+  onDragStart(node, eventInfo, e) - Triggered when the user mouse-downs over a node. *node* is the <Graph.Node> being pressed. *e* is the grabbed event (should return the native event in a cross-browser manner). *eventInfo* is an object containing useful methods like *getPos* to get the mouse position relative to the canvas. 
+  onDragMove(node, eventInfo, e) - Triggered when a user, after pressing the mouse button over a node, moves the mouse around. *node* is the <Graph.Node> being dragged. *e* is the grabbed event (should return the native event in a cross-browser manner). *eventInfo* is an object containing useful methods like *getPos* to get the mouse position relative to the canvas. 
+  onDragEnd(node, eventInfo, e) - Triggered when a user finished dragging a node. *node* is the <Graph.Node> being dragged. *e* is the grabbed event (should return the native event in a cross-browser manner). *eventInfo* is an object containing useful methods like *getPos* to get the mouse position relative to the canvas. 
+  onDragCancel(node, eventInfo, e) - Triggered when the user releases the mouse button over a <Graph.Node> that wasn't dragged (i.e. the user didn't perform any mouse movement after pressing the mouse button). *node* is the <Graph.Node> being dragged. *e* is the grabbed event (should return the native event in a cross-browser manner). *eventInfo* is an object containing useful methods like *getPos* to get the mouse position relative to the canvas. 
+  onTouchStart(node, eventInfo, e) - Behaves just like onDragStart. 
+  onTouchMove(node, eventInfo, e) - Behaves just like onDragMove. 
+  onTouchEnd(node, eventInfo, e) - Behaves just like onDragEnd. 
+  onTouchCancel(node, eventInfo, e) - Behaves just like onDragCancel.
+  onMouseWheel(delta, e) - Triggered when the user uses the mouse scroll over the canvas. *delta* is 1 or -1 depending on the sense of the mouse scroll.
+*/
+
+Options.Events = {
+  $extend: false,
+  
+  enable: false,
+  enableForEdges: false,
+  type: 'auto',
+  onClick: $.empty,
+  onRightClick: $.empty,
+  onMouseMove: $.empty,
+  onMouseEnter: $.empty,
+  onMouseLeave: $.empty,
+  onDragStart: $.empty,
+  onDragMove: $.empty,
+  onDragCancel: $.empty,
+  onDragEnd: $.empty,
+  onTouchStart: $.empty,
+  onTouchMove: $.empty,
+  onTouchEnd: $.empty,
+  onMouseWheel: $.empty
+};
+
+/*
+ * File: Options.Navigation.js
+ *
+*/
+
+/*
+  Object: Options.Navigation
+  
+  Panning and zooming options for Graph/Tree based visualizations. These options are implemented 
+  by all visualizations except charts (<AreaChart>, <BarChart> and <PieChart>).
+  
+  Syntax:
+  
+  (start code js)
+
+  Options.Navigation = {
+    enable: false,
+    type: 'auto',
+    panning: false, //true, 'avoid nodes'
+    zooming: false
+  };
+  
+  (end code)
+  
+  Example:
+    
+  (start code js)
+  var viz = new $jit.Viz({
+    Navigation: {
+      enable: true,
+      panning: 'avoid nodes',
+      zooming: 20
+    }
+  });
+  (end code)
+  
+  Parameters:
+  
+  enable - (boolean) Default's *false*. Whether to enable Navigation capabilities.
+  type - (string) Default's 'auto'. Whether to attach the navigation events onto the HTML labels (via event delegation) or to use the custom 'Native' canvas Event System of the library. When 'auto' set when you let the <Options.Label> *type* parameter decide this.
+  panning - (boolean|string) Default's *false*. Set this property to *true* if you want to add Drag and Drop panning support to the visualization. You can also set this parameter to 'avoid nodes' to enable DnD panning but disable it if the DnD is taking place over a node. This is useful when some other events like Drag & Drop for nodes are added to <Graph.Nodes>.
+  zooming - (boolean|number) Default's *false*. Set this property to a numeric value to turn mouse-scroll zooming on. The number will be proportional to the mouse-scroll sensitivity.
+  
+*/
+
+Options.Navigation = {
+  $extend: false,
+  
+  enable: false,
+  type: 'auto',
+  panning: false, //true | 'avoid nodes'
+  zooming: false
+};
+
+/*
+ * File: Options.Controller.js
+ *
+*/
+
+/*
+  Object: Options.Controller
+  
+  Provides controller methods. Controller methods are callback functions that get called at different stages 
+  of the animation, computing or plotting of the visualization.
+  
+  Implemented by:
+    
+  All visualizations except charts (<AreaChart>, <BarChart> and <PieChart>).
+  
+  Syntax:
+  
+  (start code js)
+
+  Options.Controller = {
+    onBeforeCompute: $.empty,
+    onAfterCompute:  $.empty,
+    onCreateLabel:   $.empty,
+    onPlaceLabel:    $.empty,
+    onComplete:      $.empty,
+    onBeforePlotLine:$.empty,
+    onAfterPlotLine: $.empty,
+    onBeforePlotNode:$.empty,
+    onAfterPlotNode: $.empty,
+    request:         false
+  };
+  
+  (end code)
+  
+  Example:
+    
+  (start code js)
+  var viz = new $jit.Viz({
+    onBeforePlotNode: function(node) {
+      if(node.selected) {
+        node.setData('color', '#ffc');
+      } else {
+        node.removeData('color');
+      }
+    },
+    onBeforePlotLine: function(adj) {
+      if(adj.nodeFrom.selected && adj.nodeTo.selected) {
+        adj.setData('color', '#ffc');
+      } else {
+        adj.removeData('color');
+      }
+    },
+    onAfterCompute: function() {
+      alert("computed!");
+    }
+  });
+  (end code)
+  
+  Parameters:
+
+   onBeforeCompute(node) - This method is called right before performing all computations and animations. The selected <Graph.Node> is passed as parameter.
+   onAfterCompute() - This method is triggered after all animations or computations ended.
+   onCreateLabel(domElement, node) - This method receives a new label DIV element as first parameter, and the corresponding <Graph.Node> as second parameter. This method will only be called once for each label. This method is useful when adding events or styles to the labels used by the JIT.
+   onPlaceLabel(domElement, node) - This method receives a label DIV element as first parameter and the corresponding <Graph.Node> as second parameter. This method is called each time a label has been placed in the visualization, for example at each step of an animation, and thus it allows you to update the labels properties, such as size or position. Note that onPlaceLabel will be triggered after updating the labels positions. That means that, for example, the left and top css properties are already updated to match the nodes positions. Width and height properties are not set however.
+   onBeforePlotNode(node) - This method is triggered right before plotting each <Graph.Node>. This method is useful for changing a node style right before plotting it.
+   onAfterPlotNode(node) - This method is triggered right after plotting each <Graph.Node>.
+   onBeforePlotLine(adj) - This method is triggered right before plotting a <Graph.Adjacence>. This method is useful for adding some styles to a particular edge before being plotted.
+   onAfterPlotLine(adj) - This method is triggered right after plotting a <Graph.Adjacence>.
+
+    *Used in <ST>, <TM.Base> and <Icicle> visualizations*
+    
+    request(nodeId, level, onComplete) - This method is used for buffering information into the visualization. When clicking on an empty node, the visualization will make a request for this node's subtrees, specifying a given level for this subtree (defined by _levelsToShow_). Once the request is completed, the onComplete callback should be called with the given result. This is useful to provide on-demand information into the visualizations withought having to load the entire information from start. The parameters used by this method are _nodeId_, which is the id of the root of the subtree to request, _level_ which is the depth of the subtree to be requested (0 would mean just the root node). _onComplete_ is an object having the callback method _onComplete.onComplete(json)_ that should be called once the json has been retrieved.  
+ 
+ */
+Options.Controller = {
+  $extend: true,
+  
+  onBeforeCompute: $.empty,
+  onAfterCompute:  $.empty,
+  onCreateLabel:   $.empty,
+  onPlaceLabel:    $.empty,
+  onComplete:      $.empty,
+  onBeforePlotLine:$.empty,
+  onAfterPlotLine: $.empty,
+  onBeforePlotNode:$.empty,
+  onAfterPlotNode: $.empty,
+  request:         false
+};
+
+
+/*
+ * File: Extras.js
+ * 
+ * Provides Extras such as Tips and Style Effects.
+ * 
+ * Description:
+ * 
+ * Provides the <Tips> and <NodeStyles> classes and functions.
+ *
+ */
+
+/*
+ * Manager for mouse events (clicking and mouse moving).
+ * 
+ * This class is used for registering objects implementing onClick
+ * and onMousemove methods. These methods are called when clicking or
+ * moving the mouse around  the Canvas.
+ * For now, <Tips> and <NodeStyles> are classes implementing these methods.
+ * 
+ */
+var ExtrasInitializer = {
+  initialize: function(className, viz) {
+    this.viz = viz;
+    this.canvas = viz.canvas;
+    this.config = viz.config[className];
+    this.nodeTypes = viz.fx.nodeTypes;
+    var type = this.config.type;
+    this.dom = type == 'auto'? (viz.config.Label.type != 'Native') : (type != 'Native');
+    this.labelContainer = this.dom && viz.labels.getLabelContainer();
+    this.isEnabled() && this.initializePost();
+  },
+  initializePost: $.empty,
+  setAsProperty: $.lambda(false),
+  isEnabled: function() {
+    return this.config.enable;
+  },
+  isLabel: function(e, win, group) {
+    e = $.event.get(e, win);
+    var labelContainer = this.labelContainer,
+        target = e.target || e.srcElement,
+        related = e.relatedTarget;
+    if(group) {
+      return related && related == this.viz.canvas.getCtx().canvas 
+          && !!target && this.isDescendantOf(target, labelContainer);
+    } else {
+      return this.isDescendantOf(target, labelContainer);
+    }
+  },
+  isDescendantOf: function(elem, par) {
+    while(elem && elem.parentNode) {
+      if(elem.parentNode == par)
+        return elem;
+      elem = elem.parentNode;
+    }
+    return false;
+  }
+};
+
+var EventsInterface = {
+  onMouseUp: $.empty,
+  onMouseDown: $.empty,
+  onMouseMove: $.empty,
+  onMouseOver: $.empty,
+  onMouseOut: $.empty,
+  onMouseWheel: $.empty,
+  onTouchStart: $.empty,
+  onTouchMove: $.empty,
+  onTouchEnd: $.empty,
+  onTouchCancel: $.empty
+};
+
+var MouseEventsManager = new Class({
+  initialize: function(viz) {
+    this.viz = viz;
+    this.canvas = viz.canvas;
+    this.node = false;
+    this.edge = false;
+    this.registeredObjects = [];
+    this.attachEvents();
+  },
+  
+  attachEvents: function() {
+    var htmlCanvas = this.canvas.getElement(), 
+        that = this;
+    htmlCanvas.oncontextmenu = $.lambda(false);
+    $.addEvents(htmlCanvas, {
+      'mouseup': function(e, win) {
+        var event = $.event.get(e, win);
+        that.handleEvent('MouseUp', e, win, 
+            that.makeEventObject(e, win), 
+            $.event.isRightClick(event));
+      },
+      'mousedown': function(e, win) {
+        var event = $.event.get(e, win);
+        that.handleEvent('MouseDown', e, win, that.makeEventObject(e, win), 
+            $.event.isRightClick(event));
+      },
+      'mousemove': function(e, win) {
+        that.handleEvent('MouseMove', e, win, that.makeEventObject(e, win));
+      },
+      'mouseover': function(e, win) {
+        that.handleEvent('MouseOver', e, win, that.makeEventObject(e, win));
+      },
+      'mouseout': function(e, win) {
+        that.handleEvent('MouseOut', e, win, that.makeEventObject(e, win));
+      },
+      'touchstart': function(e, win) {
+        that.handleEvent('TouchStart', e, win, that.makeEventObject(e, win));
+      },
+      'touchmove': function(e, win) {
+        that.handleEvent('TouchMove', e, win, that.makeEventObject(e, win));
+      },
+      'touchend': function(e, win) {
+        that.handleEvent('TouchEnd', e, win, that.makeEventObject(e, win));
+      }
+    });
+    //attach mousewheel event
+    var handleMouseWheel = function(e, win) {
+      var event = $.event.get(e, win);
+      var wheel = $.event.getWheel(event);
+      that.handleEvent('MouseWheel', e, win, wheel);
+    };
+    //TODO(nico): this is a horrible check for non-gecko browsers!
+    if(!document.getBoxObjectFor && window.mozInnerScreenX == null) {
+      $.addEvent(htmlCanvas, 'mousewheel', handleMouseWheel);
+    } else {
+      htmlCanvas.addEventListener('DOMMouseScroll', handleMouseWheel, false);
+    }
+  },
+  
+  register: function(obj) {
+    this.registeredObjects.push(obj);
+  },
+  
+  handleEvent: function() {
+    var args = Array.prototype.slice.call(arguments),
+        type = args.shift();
+    for(var i=0, regs=this.registeredObjects, l=regs.length; i<l; i++) {
+      regs[i]['on' + type].apply(regs[i], args);
+    }
+  },
+  
+  makeEventObject: function(e, win) {
+    var that = this,
+        graph = this.viz.graph,
+        fx = this.viz.fx,
+        ntypes = fx.nodeTypes,
+        etypes = fx.edgeTypes;
+    return {
+      pos: false,
+      node: false,
+      edge: false,
+      contains: false,
+      getNodeCalled: false,
+      getEdgeCalled: false,
+      getPos: function() {
+        //TODO(nico): check why this can't be cache anymore when using edge detection
+        //if(this.pos) return this.pos;
+        var canvas = that.viz.canvas,
+            s = canvas.getSize(),
+            p = canvas.getPos(),
+            ox = canvas.translateOffsetX,
+            oy = canvas.translateOffsetY,
+            sx = canvas.scaleOffsetX,
+            sy = canvas.scaleOffsetY,
+            pos = $.event.getPos(e, win);
+        this.pos = {
+          x: (pos.x - p.x - s.width/2 - ox) * 1/sx,
+          y: (pos.y - p.y - s.height/2 - oy) * 1/sy
+        };
+        return this.pos;
+      },
+      getNode: function() {
+        if(this.getNodeCalled) return this.node;
+        this.getNodeCalled = true;
+        for(var id in graph.nodes) {
+          var n = graph.nodes[id],
+              geom = n && ntypes[n.getData('type')],
+              contains = geom && geom.contains && geom.contains.call(fx, n, this.getPos());
+          if(contains) {
+            this.contains = contains;
+            return that.node = this.node = n;
+          }
+        }
+        return that.node = this.node = false;
+      },
+      getEdge: function() {
+        if(this.getEdgeCalled) return this.edge;
+        this.getEdgeCalled = true;
+        var hashset = {};
+        for(var id in graph.edges) {
+          var edgeFrom = graph.edges[id];
+          hashset[id] = true;
+          for(var edgeId in edgeFrom) {
+            if(edgeId in hashset) continue;
+            var e = edgeFrom[edgeId],
+                geom = e && etypes[e.getData('type')],
+                contains = geom && geom.contains && geom.contains.call(fx, e, this.getPos());
+            if(contains) {
+              this.contains = contains;
+              return that.edge = this.edge = e;
+            }
+          }
+        }
+        return that.edge = this.edge = false;
+      },
+      getContains: function() {
+        if(this.getNodeCalled) return this.contains;
+        this.getNode();
+        return this.contains;
+      }
+    };
+  }
+});
+
+/* 
+ * Provides the initialization function for <NodeStyles> and <Tips> implemented 
+ * by all main visualizations.
+ *
+ */
+var Extras = {
+  initializeExtras: function() {
+    var mem = new MouseEventsManager(this), that = this;
+    $.each(['NodeStyles', 'Tips', 'Navigation', 'Events'], function(k) {
+      var obj = new Extras.Classes[k](k, that);
+      if(obj.isEnabled()) {
+        mem.register(obj);
+      }
+      if(obj.setAsProperty()) {
+        that[k.toLowerCase()] = obj;
+      }
+    });
+  }   
+};
+
+Extras.Classes = {};
+/*
+  Class: Events
+   
+  This class defines an Event API to be accessed by the user.
+  The methods implemented are the ones defined in the <Options.Events> object.
+*/
+
+Extras.Classes.Events = new Class({
+  Implements: [ExtrasInitializer, EventsInterface],
+  
+  initializePost: function() {
+    this.fx = this.viz.fx;
+    this.ntypes = this.viz.fx.nodeTypes;
+    this.etypes = this.viz.fx.edgeTypes;
+    
+    this.hovered = false;
+    this.pressed = false;
+    this.touched = false;
+
+    this.touchMoved = false;
+    this.moved = false;
+    
+  },
+  
+  setAsProperty: $.lambda(true),
+  
+  onMouseUp: function(e, win, event, isRightClick) {
+    var evt = $.event.get(e, win);
+    if(!this.moved) {
+      if(isRightClick) {
+        this.config.onRightClick(this.hovered, event, evt);
+      } else {
+        this.config.onClick(this.pressed, event, evt);
+      }
+    }
+    if(this.pressed) {
+      if(this.moved) {
+        this.config.onDragEnd(this.pressed, event, evt);
+      } else {
+        this.config.onDragCancel(this.pressed, event, evt);
+      }
+      this.pressed = this.moved = false;
+    }
+  },
+
+  onMouseOut: function(e, win, event) {
+   //mouseout a label
+   var evt = $.event.get(e, win), label;
+   if(this.dom && (label = this.isLabel(e, win, true))) {
+     this.config.onMouseLeave(this.viz.graph.getNode(label.id),
+                              event, evt);
+     this.hovered = false;
+     return;
+   }
+   //mouseout canvas
+   var rt = evt.relatedTarget,
+       canvasWidget = this.canvas.getElement();
+   while(rt && rt.parentNode) {
+     if(canvasWidget == rt.parentNode) return;
+     rt = rt.parentNode;
+   }
+   if(this.hovered) {
+     this.config.onMouseLeave(this.hovered,
+         event, evt);
+     this.hovered = false;
+   }
+  },
+  
+  onMouseOver: function(e, win, event) {
+    //mouseover a label
+    var evt = $.event.get(e, win), label;
+    if(this.dom && (label = this.isLabel(e, win, true))) {
+      this.hovered = this.viz.graph.getNode(label.id);
+      this.config.onMouseEnter(this.hovered,
+                               event, evt);
+    }
+  },
+  
+  onMouseMove: function(e, win, event) {
+   var label, evt = $.event.get(e, win);
+   if(this.pressed) {
+     this.moved = true;
+     this.config.onDragMove(this.pressed, event, evt);
+     return;
+   }
+   if(this.dom) {
+     this.config.onMouseMove(this.hovered,
+         event, evt);
+   } else {
+     if(this.hovered) {
+       var hn = this.hovered;
+       var geom = hn.nodeFrom? this.etypes[hn.getData('type')] : this.ntypes[hn.getData('type')];
+       var contains = geom && geom.contains 
+         && geom.contains.call(this.fx, hn, event.getPos());
+       if(contains) {
+         this.config.onMouseMove(hn, event, evt);
+         return;
+       } else {
+         this.config.onMouseLeave(hn, event, evt);
+         this.hovered = false;
+       }
+     }
+     if(this.hovered = (event.getNode() || (this.config.enableForEdges && event.getEdge()))) {
+       this.config.onMouseEnter(this.hovered, event, evt);
+     } else {
+       this.config.onMouseMove(false, event, evt);
+     }
+   }
+  },
+  
+  onMouseWheel: function(e, win, delta) {
+    this.config.onMouseWheel(delta, $.event.get(e, win));
+  },
+  
+  onMouseDown: function(e, win, event) {
+    var evt = $.event.get(e, win), label;
+    if(this.dom) {
+      if(label = this.isLabel(e, win)) {
+        this.pressed = this.viz.graph.getNode(label.id);
+      }
+    } else {
+      this.pressed = event.getNode() || (this.config.enableForEdges && event.getEdge());
+    }
+    this.pressed && this.config.onDragStart(this.pressed, event, evt);
+  },
+  
+  onTouchStart: function(e, win, event) {
+    var evt = $.event.get(e, win), label;
+    if(this.dom && (label = this.isLabel(e, win))) {
+      this.touched = this.viz.graph.getNode(label.id);
+    } else {
+      this.touched = event.getNode() || (this.config.enableForEdges && event.getEdge());
+    }
+    this.touched && this.config.onTouchStart(this.touched, event, evt);
+  },
+  
+  onTouchMove: function(e, win, event) {
+    var evt = $.event.get(e, win);
+    if(this.touched) {
+      this.touchMoved = true;
+      this.config.onTouchMove(this.touched, event, evt);
+    }
+  },
+  
+  onTouchEnd: function(e, win, event) {
+    var evt = $.event.get(e, win);
+    if(this.touched) {
+      if(this.touchMoved) {
+        this.config.onTouchEnd(this.touched, event, evt);
+      } else {
+        this.config.onTouchCancel(this.touched, event, evt);
+      }
+      this.touched = this.touchMoved = false;
+    }
+  }
+});
+
+/*
+   Class: Tips
+    
+   A class containing tip related functions. This class is used internally.
+   
+   Used by:
+   
+   <ST>, <Sunburst>, <Hypertree>, <RGraph>, <TM>, <ForceDirected>, <Icicle>
+   
+   See also:
+   
+   <Options.Tips>
+*/
+
+Extras.Classes.Tips = new Class({
+  Implements: [ExtrasInitializer, EventsInterface],
+  
+  initializePost: function() {
+    //add DOM tooltip
+    if(document.body) {
+      var tip = $('_tooltip') || document.createElement('div');
+      tip.id = '_tooltip';
+      tip.className = 'tip';
+      $.extend(tip.style, {
+        position: 'absolute',
+        display: 'none',
+        zIndex: 13000
+      });
+      document.body.appendChild(tip);
+      this.tip = tip;
+      this.node = false;
+    }
+  },
+  
+  setAsProperty: $.lambda(true),
+  
+  onMouseOut: function(e, win) {
+    //mouseout a label
+    var evt = $.event.get(e, win);
+    if(this.dom && this.isLabel(e, win, true)) {
+      this.hide(true);
+      return;
+    }
+    //mouseout canvas
+    var rt = e.relatedTarget,
+        canvasWidget = this.canvas.getElement();
+    while(rt && rt.parentNode) {
+      if(canvasWidget == rt.parentNode) return;
+      rt = rt.parentNode;
+    }
+    this.hide(false);
+  },
+  
+  onMouseOver: function(e, win) {
+    //mouseover a label
+    var label;
+    if(this.dom && (label = this.isLabel(e, win, false))) {
+      this.node = this.viz.graph.getNode(label.id);
+      this.config.onShow(this.tip, this.node, label);
+    }
+  },
+  
+  onMouseMove: function(e, win, opt) {
+    if(this.dom && this.isLabel(e, win)) {
+      this.setTooltipPosition($.event.getPos(e, win));
+    }
+    if(!this.dom) {
+      var node = opt.getNode();
+      if(!node) {
+        this.hide(true);
+        return;
+      }
+      if(this.config.force || !this.node || this.node.id != node.id) {
+        this.node = node;
+        this.config.onShow(this.tip, node, opt.getContains());
+      }
+      this.setTooltipPosition($.event.getPos(e, win));
+    }
+  },
+  
+  setTooltipPosition: function(pos) {
+    var tip = this.tip, 
+        style = tip.style, 
+        cont = this.config;
+    style.display = '';
+    //get window dimensions
+    var win = {
+      'height': document.body.clientHeight,
+      'width': document.body.clientWidth
+    };
+    //get tooltip dimensions
+    var obj = {
+      'width': tip.offsetWidth,
+      'height': tip.offsetHeight  
+    };
+    //set tooltip position
+    var x = cont.offsetX, y = cont.offsetY;
+    style.top = ((pos.y + y + obj.height > win.height)?  
+        (pos.y - obj.height - y) : pos.y + y) + 'px';
+    style.left = ((pos.x + obj.width + x > win.width)? 
+        (pos.x - obj.width - x) : pos.x + x) + 'px';
+  },
+  
+  hide: function(triggerCallback) {
+    this.tip.style.display = 'none';
+    triggerCallback && this.config.onHide();
+  }
+});
+
+/*
+  Class: NodeStyles
+   
+  Change node styles when clicking or hovering a node. This class is used internally.
+  
+  Used by:
+  
+  <ST>, <Sunburst>, <Hypertree>, <RGraph>, <TM>, <ForceDirected>, <Icicle>
+  
+  See also:
+  
+  <Options.NodeStyles>
+*/
+Extras.Classes.NodeStyles = new Class({
+  Implements: [ExtrasInitializer, EventsInterface],
+  
+  initializePost: function() {
+    this.fx = this.viz.fx;
+    this.types = this.viz.fx.nodeTypes;
+    this.nStyles = this.config;
+    this.nodeStylesOnHover = this.nStyles.stylesHover;
+    this.nodeStylesOnClick = this.nStyles.stylesClick;
+    this.hoveredNode = false;
+    this.fx.nodeFxAnimation = new Animation();
+    
+    this.down = false;
+    this.move = false;
+  },
+  
+  onMouseOut: function(e, win) {
+    this.down = this.move = false;
+    if(!this.hoveredNode) return;
+    //mouseout a label
+    if(this.dom && this.isLabel(e, win, true)) {
+      this.toggleStylesOnHover(this.hoveredNode, false);
+    }
+    //mouseout canvas
+    var rt = e.relatedTarget,
+        canvasWidget = this.canvas.getElement();
+    while(rt && rt.parentNode) {
+      if(canvasWidget == rt.parentNode) return;
+      rt = rt.parentNode;
+    }
+    this.toggleStylesOnHover(this.hoveredNode, false);
+    this.hoveredNode = false;
+  },
+  
+  onMouseOver: function(e, win) {
+    //mouseover a label
+    var label;
+    if(this.dom && (label = this.isLabel(e, win, true))) {
+      var node = this.viz.graph.getNode(label.id);
+      if(node.selected) return;
+      this.hoveredNode = node;
+      this.toggleStylesOnHover(this.hoveredNode, true);
+    }
+  },
+  
+  onMouseDown: function(e, win, event, isRightClick) {
+    if(isRightClick) return;
+    var label;
+    if(this.dom && (label = this.isLabel(e, win))) {
+      this.down = this.viz.graph.getNode(label.id);
+    } else if(!this.dom) {
+      this.down = event.getNode();
+    }
+    this.move = false;
+  },
+  
+  onMouseUp: function(e, win, event, isRightClick) {
+    if(isRightClick) return;
+    if(!this.move) {
+      this.onClick(event.getNode());
+    }
+    this.down = this.move = false;
+  },
+  
+  getRestoredStyles: function(node, type) {
+    var restoredStyles = {}, 
+        nStyles = this['nodeStylesOn' + type];
+    for(var prop in nStyles) {
+      restoredStyles[prop] = node.styles['$' + prop];
+    }
+    return restoredStyles;
+  },
+  
+  toggleStylesOnHover: function(node, set) {
+    if(this.nodeStylesOnHover) {
+      this.toggleStylesOn('Hover', node, set);
+    }
+  },
+
+  toggleStylesOnClick: function(node, set) {
+    if(this.nodeStylesOnClick) {
+      this.toggleStylesOn('Click', node, set);
+    }
+  },
+  
+  toggleStylesOn: function(type, node, set) {
+    var viz = this.viz;
+    var nStyles = this.nStyles;
+    if(set) {
+      var that = this;
+      if(!node.styles) {
+        node.styles = $.merge(node.data, {});
+      }
+      for(var s in this['nodeStylesOn' + type]) {
+        var $s = '$' + s;
+        if(!($s in node.styles)) {
+            node.styles[$s] = node.getData(s); 
+        }
+      }
+      viz.fx.nodeFx($.extend({
+        'elements': {
+          'id': node.id,
+          'properties': that['nodeStylesOn' + type]
+         },
+         transition: Trans.Quart.easeOut,
+         duration:300,
+         fps:40
+      }, this.config));
+    } else {
+      var restoredStyles = this.getRestoredStyles(node, type);
+      viz.fx.nodeFx($.extend({
+        'elements': {
+          'id': node.id,
+          'properties': restoredStyles
+         },
+         transition: Trans.Quart.easeOut,
+         duration:300,
+         fps:40
+      }, this.config));
+    }
+  },
+
+  onClick: function(node) {
+    if(!node) return;
+    var nStyles = this.nodeStylesOnClick;
+    if(!nStyles) return;
+    //if the node is selected then unselect it
+    if(node.selected) {
+      this.toggleStylesOnClick(node, false);
+      delete node.selected;
+    } else {
+      //unselect all selected nodes...
+      this.viz.graph.eachNode(function(n) {
+        if(n.selected) {
+          for(var s in nStyles) {
+            n.setData(s, n.styles['$' + s], 'end');
+          }
+          delete n.selected;
+        }
+      });
+      //select clicked node
+      this.toggleStylesOnClick(node, true);
+      node.selected = true;
+      delete node.hovered;
+      this.hoveredNode = false;
+    }
+  },
+  
+  onMouseMove: function(e, win, event) {
+    //if mouse button is down and moving set move=true
+    if(this.down) this.move = true;
+    //already handled by mouseover/out
+    if(this.dom && this.isLabel(e, win)) return;
+    var nStyles = this.nodeStylesOnHover;
+    if(!nStyles) return;
+    
+    if(!this.dom) {
+      if(this.hoveredNode) {
+        var geom = this.types[this.hoveredNode.getData('type')];
+        var contains = geom && geom.contains && geom.contains.call(this.fx, 
+            this.hoveredNode, event.getPos());
+        if(contains) return;
+      }
+      var node = event.getNode();
+      //if no node is being hovered then just exit
+      if(!this.hoveredNode && !node) return;
+      //if the node is hovered then exit
+      if(node.hovered) return;
+      //select hovered node
+      if(node && !node.selected) {
+        //check if an animation is running and exit it
+        this.fx.nodeFxAnimation.stopTimer();
+        //unselect all hovered nodes...
+        this.viz.graph.eachNode(function(n) {
+          if(n.hovered && !n.selected) {
+            for(var s in nStyles) {
+              n.setData(s, n.styles['$' + s], 'end');
+            }
+            delete n.hovered;
+          }
+        });
+        //select hovered node
+        node.hovered = true;
+        this.hoveredNode = node;
+        this.toggleStylesOnHover(node, true);
+      } else if(this.hoveredNode && !this.hoveredNode.selected) {
+        //check if an animation is running and exit it
+        this.fx.nodeFxAnimation.stopTimer();
+        //unselect hovered node
+        this.toggleStylesOnHover(this.hoveredNode, false);
+        delete this.hoveredNode.hovered;
+        this.hoveredNode = false;
+      }
+    }
+  }
+});
+
+Extras.Classes.Navigation = new Class({
+  Implements: [ExtrasInitializer, EventsInterface],
+  
+  initializePost: function() {
+    this.pos = false;
+    this.pressed = false;
+  },
+  
+  onMouseWheel: function(e, win, scroll) {
+    if(!this.config.zooming) return;
+    $.event.stop($.event.get(e, win));
+    var val = this.config.zooming / 1000,
+        ans = 1 + scroll * val;
+    this.canvas.scale(ans, ans);
+  },
+  
+  onMouseDown: function(e, win, eventInfo) {
+    if(!this.config.panning) return;
+    if(this.config.panning == 'avoid nodes' && (this.dom? this.isLabel(e, win) : eventInfo.getNode())) return;
+    this.pressed = true;
+    this.pos = eventInfo.getPos();
+    var canvas = this.canvas,
+        ox = canvas.translateOffsetX,
+        oy = canvas.translateOffsetY,
+        sx = canvas.scaleOffsetX,
+        sy = canvas.scaleOffsetY;
+    this.pos.x *= sx;
+    this.pos.x += ox;
+    this.pos.y *= sy;
+    this.pos.y += oy;
+  },
+  
+  onMouseMove: function(e, win, eventInfo) {
+    if(!this.config.panning) return;
+    if(!this.pressed) return;
+    if(this.config.panning == 'avoid nodes' && (this.dom? this.isLabel(e, win) : eventInfo.getNode())) return;
+    var thispos = this.pos, 
+        currentPos = eventInfo.getPos(),
+        canvas = this.canvas,
+        ox = canvas.translateOffsetX,
+        oy = canvas.translateOffsetY,
+        sx = canvas.scaleOffsetX,
+        sy = canvas.scaleOffsetY;
+    currentPos.x *= sx;
+    currentPos.y *= sy;
+    currentPos.x += ox;
+    currentPos.y += oy;
+    var x = currentPos.x - thispos.x,
+        y = currentPos.y - thispos.y;
+    this.pos = currentPos;
+    this.canvas.translate(x * 1/sx, y * 1/sy);
+  },
+  
+  onMouseUp: function(e, win, eventInfo, isRightClick) {
+    if(!this.config.panning) return;
+    this.pressed = false;
+  }
+});
+
+
+/*
+ * File: Canvas.js
+ *
+ */
+
+/*
+ Class: Canvas
+ 
+ 	A canvas widget used by all visualizations. The canvas object can be accessed by doing *viz.canvas*. If you want to 
+ 	know more about <Canvas> options take a look at <Options.Canvas>.
+ 
+ A canvas widget is a set of DOM elements that wrap the native canvas DOM Element providing a consistent API and behavior 
+ across all browsers. It can also include Elements to add DOM (SVG or HTML) label support to all visualizations.
+ 
+ Example:
+ 
+ Suppose we have this HTML
+ 
+ (start code xml)
+ 	<div id="infovis"></div>
+ (end code)
+ 
+ Now we create a new Visualization
+ 
+ (start code js)
+ 	var viz = new $jit.Viz({
+ 		//Where to inject the canvas. Any div container will do.
+ 		'injectInto':'infovis',
+		 //width and height for canvas. 
+		 //Default's to the container offsetWidth and Height.
+		 'width': 900,
+		 'height':500
+	 });
+ (end code)
+
+ The generated HTML will look like this
+ 
+ (start code xml)
+ <div id="infovis">
+ 	<div id="infovis-canvaswidget" style="position:relative;">
+ 	<canvas id="infovis-canvas" width=900 height=500
+ 	style="position:absolute; top:0; left:0; width:900px; height:500px;" />
+ 	<div id="infovis-label"
+ 	style="overflow:visible; position:absolute; top:0; left:0; width:900px; height:0px">
+ 	</div>
+ 	</div>
+ </div>
+ (end code)
+ 
+ As you can see, the generated HTML consists of a canvas DOM Element of id *infovis-canvas* and a div label container
+ of id *infovis-label*, wrapped in a main div container of id *infovis-canvaswidget*.
+ */
+
+var Canvas;
+(function() {
+  //check for native canvas support
+  var canvasType = typeof HTMLCanvasElement,
+      supportsCanvas = (canvasType == 'object' || canvasType == 'function');
+  //create element function
+  function $E(tag, props) {
+    var elem = document.createElement(tag);
+    for(var p in props) {
+      if(typeof props[p] == "object") {
+        $.extend(elem[p], props[p]);
+      } else {
+        elem[p] = props[p];
+      }
+    }
+    if (tag == "canvas" && !supportsCanvas && G_vmlCanvasManager) {
+      elem = G_vmlCanvasManager.initElement(document.body.appendChild(elem));
+    }
+    return elem;
+  }
+  //canvas widget which we will call just Canvas
+  $jit.Canvas = Canvas = new Class({
+    canvases: [],
+    pos: false,
+    element: false,
+    labelContainer: false,
+    translateOffsetX: 0,
+    translateOffsetY: 0,
+    scaleOffsetX: 1,
+    scaleOffsetY: 1,
+    
+    initialize: function(viz, opt) {
+      this.viz = viz;
+      this.opt = this.config = opt;
+      var id = $.type(opt.injectInto) == 'string'? 
+          opt.injectInto:opt.injectInto.id,
+          type = opt.type,
+          idLabel = id + "-label", 
+          wrapper = $(id),
+          width = opt.width || wrapper.offsetWidth,
+          height = opt.height || wrapper.offsetHeight;
+      this.id = id;
+      //canvas options
+      var canvasOptions = {
+        injectInto: id,
+        width: width,
+        height: height
+      };
+      //create main wrapper
+      this.element = $E('div', {
+        'id': id + '-canvaswidget',
+        'style': {
+          'position': 'relative',
+          'width': width + 'px',
+          'height': height + 'px'
+        }
+      });
+      //create label container
+      this.labelContainer = this.createLabelContainer(opt.Label.type, 
+          idLabel, canvasOptions);
+      //create primary canvas
+      this.canvases.push(new Canvas.Base[type]({
+        config: $.extend({idSuffix: '-canvas'}, canvasOptions),
+        plot: function(base) {
+          viz.fx.plot();
+        },
+        resize: function() {
+          viz.refresh();
+        }
+      }));
+      //create secondary canvas
+      var back = opt.background;
+      if(back) {
+        var backCanvas = new Canvas.Background[back.type](viz, $.extend(back, canvasOptions));
+        this.canvases.push(new Canvas.Base[type](backCanvas));
+      }
+      //insert canvases
+      var len = this.canvases.length;
+      while(len--) {
+        this.element.appendChild(this.canvases[len].canvas);
+        if(len > 0) {
+          this.canvases[len].plot();
+        }
+      }
+      this.element.appendChild(this.labelContainer);
+      wrapper.appendChild(this.element);
+      //Update canvas position when the page is scrolled.
+      var timer = null, that = this;
+      $.addEvent(window, 'scroll', function() {
+        clearTimeout(timer);
+        timer = setTimeout(function() {
+          that.getPos(true); //update canvas position
+        }, 500);
+      });
+    },
+    /*
+      Method: getCtx
+      
+      Returns the main canvas context object
+      
+      Example:
+      
+      (start code js)
+       var ctx = canvas.getCtx();
+       //Now I can use the native canvas context
+       //and for example change some canvas styles
+       ctx.globalAlpha = 1;
+      (end code)
+    */
+    getCtx: function(i) {
+      return this.canvases[i || 0].getCtx();
+    },
+    /*
+      Method: getConfig
+      
+      Returns the current Configuration for this Canvas Widget.
+      
+      Example:
+      
+      (start code js)
+       var config = canvas.getConfig();
+      (end code)
+    */
+    getConfig: function() {
+      return this.opt;
+    },
+    /*
+      Method: getElement
+
+      Returns the main Canvas DOM wrapper
+      
+      Example:
+      
+      (start code js)
+       var wrapper = canvas.getElement();
+       //Returns <div id="infovis-canvaswidget" ... >...</div> as element
+      (end code)
+    */
+    getElement: function() {
+      return this.element;
+    },
+    /*
+      Method: getSize
+      
+      Returns canvas dimensions.
+      
+      Returns:
+      
+      An object with *width* and *height* properties.
+      
+      Example:
+      (start code js)
+      canvas.getSize(); //returns { width: 900, height: 500 }
+      (end code)
+    */
+    getSize: function(i) {
+      return this.canvases[i || 0].getSize();
+    },
+    /*
+      Method: resize
+      
+      Resizes the canvas.
+      
+      Parameters:
+      
+      width - New canvas width.
+      height - New canvas height.
+      
+      Example:
+      
+      (start code js)
+       canvas.resize(width, height);
+      (end code)
+    
+    */
+    resize: function(width, height) {
+      this.getPos(true);
+      this.translateOffsetX = this.translateOffsetY = 0;
+      this.scaleOffsetX = this.scaleOffsetY = 1;
+      for(var i=0, l=this.canvases.length; i<l; i++) {
+        this.canvases[i].resize(width, height);
+      }
+      var style = this.element.style;
+      style.width = width + 'px';
+      style.height = height + 'px';
+      if(this.labelContainer)
+        this.labelContainer.style.width = width + 'px';
+    },
+    /*
+      Method: translate
+      
+      Applies a translation to the canvas.
+      
+      Parameters:
+      
+      x - (number) x offset.
+      y - (number) y offset.
+      disablePlot - (boolean) Default's *false*. Set this to *true* if you don't want to refresh the visualization.
+      
+      Example:
+      
+      (start code js)
+       canvas.translate(30, 30);
+      (end code)
+    
+    */
+    translate: function(x, y, disablePlot) {
+      this.translateOffsetX += x*this.scaleOffsetX;
+      this.translateOffsetY += y*this.scaleOffsetY;
+      for(var i=0, l=this.canvases.length; i<l; i++) {
+        this.canvases[i].translate(x, y, disablePlot);
+      }
+    },
+    /*
+      Method: scale
+      
+      Scales the canvas.
+      
+      Parameters:
+      
+      x - (number) scale value.
+      y - (number) scale value.
+      disablePlot - (boolean) Default's *false*. Set this to *true* if you don't want to refresh the visualization.
+      
+      Example:
+      
+      (start code js)
+       canvas.scale(0.5, 0.5);
+      (end code)
+    
+    */
+    scale: function(x, y, disablePlot) {
+      var px = this.scaleOffsetX * x,
+          py = this.scaleOffsetY * y;
+      var dx = this.translateOffsetX * (x -1) / px,
+          dy = this.translateOffsetY * (y -1) / py;
+      this.scaleOffsetX = px;
+      this.scaleOffsetY = py;
+      for(var i=0, l=this.canvases.length; i<l; i++) {
+        this.canvases[i].scale(x, y, true);
+      }
+      this.translate(dx, dy, false);
+    },
+    /*
+      Method: getPos
+      
+      Returns the canvas position as an *x, y* object.
+      
+      Parameters:
+      
+      force - (boolean) Default's *false*. Set this to *true* if you want to recalculate the position without using any cache information.
+      
+      Returns:
+      
+      An object with *x* and *y* properties.
+      
+      Example:
+      (start code js)
+      canvas.getPos(true); //returns { x: 900, y: 500 }
+      (end code)
+    */
+    getPos: function(force){
+      if(force || !this.pos) {
+        return this.pos = $.getPos(this.getElement());
+      }
+      return this.pos;
+    },
+    /*
+       Method: clear
+       
+       Clears the canvas.
+    */
+    clear: function(i){
+      this.canvases[i||0].clear();
+    },
+    
+    path: function(type, action){
+      var ctx = this.canvases[0].getCtx();
+      ctx.beginPath();
+      action(ctx);
+      ctx[type]();
+      ctx.closePath();
+    },
+    
+    createLabelContainer: function(type, idLabel, dim) {
+      var NS = 'http://www.w3.org/2000/svg';
+      if(type == 'HTML' || type == 'Native') {
+        return $E('div', {
+          'id': idLabel,
+          'style': {
+            'overflow': 'visible',
+            'position': 'absolute',
+            'top': 0,
+            'left': 0,
+            'width': dim.width + 'px',
+            'height': 0
+          }
+        });
+      } else if(type == 'SVG') {
+        var svgContainer = document.createElementNS(NS, 'svg:svg');
+        svgContainer.setAttribute("width", dim.width);
+        svgContainer.setAttribute('height', dim.height);
+        var style = svgContainer.style;
+        style.position = 'absolute';
+        style.left = style.top = '0px';
+        var labelContainer = document.createElementNS(NS, 'svg:g');
+        labelContainer.setAttribute('width', dim.width);
+        labelContainer.setAttribute('height', dim.height);
+        labelContainer.setAttribute('x', 0);
+        labelContainer.setAttribute('y', 0);
+        labelContainer.setAttribute('id', idLabel);
+        svgContainer.appendChild(labelContainer);
+        return svgContainer;
+      }
+    }
+  });
+  //base canvas wrapper
+  Canvas.Base = {};
+  Canvas.Base['2D'] = new Class({
+    translateOffsetX: 0,
+    translateOffsetY: 0,
+    scaleOffsetX: 1,
+    scaleOffsetY: 1,
+
+    initialize: function(viz) {
+      this.viz = viz;
+      this.opt = viz.config;
+      this.size = false;
+      this.createCanvas();
+      this.translateToCenter();
+    },
+    createCanvas: function() {
+      var opt = this.opt,
+          width = opt.width,
+          height = opt.height;
+      this.canvas = $E('canvas', {
+        'id': opt.injectInto + opt.idSuffix,
+        'width': width,
+        'height': height,
+        'style': {
+          'position': 'absolute',
+          'top': 0,
+          'left': 0,
+          'width': width + 'px',
+          'height': height + 'px'
+        }
+      });
+    },
+    getCtx: function() {
+      if(!this.ctx) 
+        return this.ctx = this.canvas.getContext('2d');
+      return this.ctx;
+    },
+    getSize: function() {
+      if(this.size) return this.size;
+      var canvas = this.canvas;
+      return this.size = {
+        width: canvas.width,
+        height: canvas.height
+      };
+    },
+    translateToCenter: function(ps) {
+      var size = this.getSize(),
+          width = ps? (size.width - ps.width - this.translateOffsetX*2) : size.width;
+          height = ps? (size.height - ps.height - this.translateOffsetY*2) : size.height;
+      var ctx = this.getCtx();
+      ps && ctx.scale(1/this.scaleOffsetX, 1/this.scaleOffsetY);
+      ctx.translate(width/2, height/2);
+    },
+    resize: function(width, height) {
+      var size = this.getSize(),
+          canvas = this.canvas,
+          styles = canvas.style;
+      this.size = false;
+      canvas.width = width;
+      canvas.height = height;
+      styles.width = width + "px";
+      styles.height = height + "px";
+      //small ExCanvas fix
+      if(!supportsCanvas) {
+        this.translateToCenter(size);
+      } else {
+        this.translateToCenter();
+      }
+      this.translateOffsetX =
+        this.translateOffsetY = 0;
+      this.scaleOffsetX = 
+        this.scaleOffsetY = 1;
+      this.clear();
+      this.viz.resize(width, height, this);
+    },
+    translate: function(x, y, disablePlot) {
+      var sx = this.scaleOffsetX,
+          sy = this.scaleOffsetY;
+      this.translateOffsetX += x*sx;
+      this.translateOffsetY += y*sy;
+      this.getCtx().translate(x, y);
+      !disablePlot && this.plot();
+    },
+    scale: function(x, y, disablePlot) {
+      this.scaleOffsetX *= x;
+      this.scaleOffsetY *= y;
+      this.getCtx().scale(x, y);
+      !disablePlot && this.plot();
+    },
+    clear: function(){
+      var size = this.getSize(),
+          ox = this.translateOffsetX,
+          oy = this.translateOffsetY,
+          sx = this.scaleOffsetX,
+          sy = this.scaleOffsetY;
+      this.getCtx().clearRect((-size.width / 2 - ox) * 1/sx, 
+                              (-size.height / 2 - oy) * 1/sy, 
+                              size.width * 1/sx, size.height * 1/sy);
+    },
+    plot: function() {
+      this.clear();
+      this.viz.plot(this);
+    }
+  });
+  //background canvases
+  //TODO(nico): document this!
+  Canvas.Background = {};
+  Canvas.Background.Circles = new Class({
+    initialize: function(viz, options) {
+      this.viz = viz;
+      this.config = $.merge({
+        idSuffix: '-bkcanvas',
+        levelDistance: 100,
+        numberOfCircles: 6,
+        CanvasStyles: {},
+        offset: 0
+      }, options);
+    },
+    resize: function(width, height, base) {
+      this.plot(base);
+    },
+    plot: function(base) {
+      var canvas = base.canvas,
+          ctx = base.getCtx(),
+          conf = this.config,
+          styles = conf.CanvasStyles;
+      //set canvas styles
+      for(var s in styles) ctx[s] = styles[s];
+      var n = conf.numberOfCircles,
+          rho = conf.levelDistance;
+      for(var i=1; i<=n; i++) {
+        ctx.beginPath();
+        ctx.arc(0, 0, rho * i, 0, 2 * Math.PI, false);
+        ctx.stroke();
+        ctx.closePath();
+      }
+      //TODO(nico): print labels too!
+    }
+  });
+})();
+
+
+/*
+ * File: Polar.js
+ * 
+ * Defines the <Polar> class.
+ *
+ * Description:
+ *
+ * The <Polar> class, just like the <Complex> class, is used by the <Hypertree>, <ST> and <RGraph> as a 2D point representation.
+ *
+ * See also:
+ *
+ * <http://en.wikipedia.org/wiki/Polar_coordinates>
+ *
+*/
+
+/*
+   Class: Polar
+
+   A multi purpose polar representation.
+
+   Description:
+ 
+   The <Polar> class, just like the <Complex> class, is used by the <Hypertree>, <ST> and <RGraph> as a 2D point representation.
+ 
+   See also:
+ 
+   <http://en.wikipedia.org/wiki/Polar_coordinates>
+ 
+   Parameters:
+
+      theta - An angle.
+      rho - The norm.
+*/
+
+var Polar = function(theta, rho) {
+  this.theta = theta || 0;
+  this.rho = rho || 0;
+};
+
+$jit.Polar = Polar;
+
+Polar.prototype = {
+    /*
+       Method: getc
+    
+       Returns a complex number.
+    
+       Parameters:
+
+       simple - _optional_ If *true*, this method will return only an object holding x and y properties and not a <Complex> instance. Default's *false*.
+
+      Returns:
+    
+          A complex number.
+    */
+    getc: function(simple) {
+        return this.toComplex(simple);
+    },
+
+    /*
+       Method: getp
+    
+       Returns a <Polar> representation.
+    
+       Returns:
+    
+          A variable in polar coordinates.
+    */
+    getp: function() {
+        return this;
+    },
+
+
+    /*
+       Method: set
+    
+       Sets a number.
+
+       Parameters:
+
+       v - A <Complex> or <Polar> instance.
+    
+    */
+    set: function(v) {
+        v = v.getp();
+        this.theta = v.theta; this.rho = v.rho;
+    },
+
+    /*
+       Method: setc
+    
+       Sets a <Complex> number.
+
+       Parameters:
+
+       x - A <Complex> number real part.
+       y - A <Complex> number imaginary part.
+    
+    */
+    setc: function(x, y) {
+        this.rho = Math.sqrt(x * x + y * y);
+        this.theta = Math.atan2(y, x);
+        if(this.theta < 0) this.theta += Math.PI * 2;
+    },
+
+    /*
+       Method: setp
+    
+       Sets a polar number.
+
+       Parameters:
+
+       theta - A <Polar> number angle property.
+       rho - A <Polar> number rho property.
+    
+    */
+    setp: function(theta, rho) {
+        this.theta = theta; 
+        this.rho = rho;
+    },
+
+    /*
+       Method: clone
+    
+       Returns a copy of the current object.
+    
+       Returns:
+    
+          A copy of the real object.
+    */
+    clone: function() {
+        return new Polar(this.theta, this.rho);
+    },
+
+    /*
+       Method: toComplex
+    
+        Translates from polar to cartesian coordinates and returns a new <Complex> instance.
+    
+        Parameters:
+
+        simple - _optional_ If *true* this method will only return an object with x and y properties (and not the whole <Complex> instance). Default's *false*.
+ 
+        Returns:
+    
+          A new <Complex> instance.
+    */
+    toComplex: function(simple) {
+        var x = Math.cos(this.theta) * this.rho;
+        var y = Math.sin(this.theta) * this.rho;
+        if(simple) return { 'x': x, 'y': y};
+        return new Complex(x, y);
+    },
+
+    /*
+       Method: add
+    
+        Adds two <Polar> instances.
+    
+       Parameters:
+
+       polar - A <Polar> number.
+
+       Returns:
+    
+          A new Polar instance.
+    */
+    add: function(polar) {
+        return new Polar(this.theta + polar.theta, this.rho + polar.rho);
+    },
+    
+    /*
+       Method: scale
+    
+        Scales a polar norm.
+    
+        Parameters:
+
+        number - A scale factor.
+        
+        Returns:
+    
+          A new Polar instance.
+    */
+    scale: function(number) {
+        return new Polar(this.theta, this.rho * number);
+    },
+    
+    /*
+       Method: equals
+    
+       Comparison method.
+
+       Returns *true* if the theta and rho properties are equal.
+
+       Parameters:
+
+       c - A <Polar> number.
+
+       Returns:
+
+       *true* if the theta and rho parameters for these objects are equal. *false* otherwise.
+    */
+    equals: function(c) {
+        return this.theta == c.theta && this.rho == c.rho;
+    },
+    
+    /*
+       Method: $add
+    
+        Adds two <Polar> instances affecting the current object.
+    
+       Paramters:
+
+       polar - A <Polar> instance.
+
+       Returns:
+    
+          The changed object.
+    */
+    $add: function(polar) {
+        this.theta = this.theta + polar.theta; this.rho += polar.rho;
+        return this;
+    },
+
+    /*
+       Method: $madd
+    
+        Adds two <Polar> instances affecting the current object. The resulting theta angle is modulo 2pi.
+    
+       Parameters:
+
+       polar - A <Polar> instance.
+
+       Returns:
+    
+          The changed object.
+    */
+    $madd: function(polar) {
+        this.theta = (this.theta + polar.theta) % (Math.PI * 2); this.rho += polar.rho;
+        return this;
+    },
+
+    
+    /*
+       Method: $scale
+    
+        Scales a polar instance affecting the object.
+    
+      Parameters:
+
+      number - A scaling factor.
+
+      Returns:
+    
+          The changed object.
+    */
+    $scale: function(number) {
+        this.rho *= number;
+        return this;
+    },
+    
+    /*
+      Method: isZero
+   
+      Returns *true* if the number is zero.
+   
+   */
+    isZero: function () {
+      var almostZero = 0.0001, abs = Math.abs;
+      return abs(this.theta) < almostZero && abs(this.rho) < almostZero;
+    },
+
+    /*
+       Method: interpolate
+    
+        Calculates a polar interpolation between two points at a given delta moment.
+
+        Parameters:
+      
+        elem - A <Polar> instance.
+        delta - A delta factor ranging [0, 1].
+    
+       Returns:
+    
+          A new <Polar> instance representing an interpolation between _this_ and _elem_
+    */
+    interpolate: function(elem, delta) {
+        var pi = Math.PI, pi2 = pi * 2;
+        var ch = function(t) {
+            var a =  (t < 0)? (t % pi2) + pi2 : t % pi2;
+            return a;
+        };
+        var tt = this.theta, et = elem.theta;
+        var sum, diff = Math.abs(tt - et);
+        if(diff == pi) {
+          if(tt > et) {
+            sum = ch((et + ((tt - pi2) - et) * delta)) ;
+          } else {
+            sum = ch((et - pi2 + (tt - (et)) * delta));
+          }
+        } else if(diff >= pi) {
+          if(tt > et) {
+            sum = ch((et + ((tt - pi2) - et) * delta)) ;
+          } else {
+            sum = ch((et - pi2 + (tt - (et - pi2)) * delta));
+          }
+        } else {  
+          sum = ch((et + (tt - et) * delta)) ;
+        }
+        var r = (this.rho - elem.rho) * delta + elem.rho;
+        return {
+          'theta': sum,
+          'rho': r
+        };
+    }
+};
+
+
+var $P = function(a, b) { return new Polar(a, b); };
+
+Polar.KER = $P(0, 0);
+
+
+
+/*
+ * File: Complex.js
+ * 
+ * Defines the <Complex> class.
+ *
+ * Description:
+ *
+ * The <Complex> class, just like the <Polar> class, is used by the <Hypertree>, <ST> and <RGraph> as a 2D point representation.
+ *
+ * See also:
+ *
+ * <http://en.wikipedia.org/wiki/Complex_number>
+ *
+*/
+
+/*
+   Class: Complex
+    
+   A multi-purpose Complex Class with common methods.
+ 
+   Description:
+ 
+   The <Complex> class, just like the <Polar> class, is used by the <Hypertree>, <ST> and <RGraph> as a 2D point representation.
+ 
+   See also:
+ 
+   <http://en.wikipedia.org/wiki/Complex_number>
+
+   Parameters:
+
+   x - _optional_ A Complex number real part.
+   y - _optional_ A Complex number imaginary part.
+ 
+*/
+
+var Complex = function(x, y) {
+  this.x = x || 0;
+  this.y = y || 0;
+};
+
+$jit.Complex = Complex;
+
+Complex.prototype = {
+    /*
+       Method: getc
+    
+       Returns a complex number.
+    
+       Returns:
+    
+          A complex number.
+    */
+    getc: function() {
+        return this;
+    },
+
+    /*
+       Method: getp
+    
+       Returns a <Polar> representation of this number.
+    
+       Parameters:
+
+       simple - _optional_ If *true*, this method will return only an object holding theta and rho properties and not a <Polar> instance. Default's *false*.
+
+       Returns:
+    
+          A variable in <Polar> coordinates.
+    */
+    getp: function(simple) {
+        return this.toPolar(simple);
+    },
+
+
+    /*
+       Method: set
+    
+       Sets a number.
+
+       Parameters:
+
+       c - A <Complex> or <Polar> instance.
+    
+    */
+    set: function(c) {
+      c = c.getc(true);
+      this.x = c.x; 
+      this.y = c.y;
+    },
+
+    /*
+       Method: setc
+    
+       Sets a complex number.
+
+       Parameters:
+
+       x - A <Complex> number Real part.
+       y - A <Complex> number Imaginary part.
+    
+    */
+    setc: function(x, y) {
+        this.x = x; 
+        this.y = y;
+    },
+
+    /*
+       Method: setp
+    
+       Sets a polar number.
+
+       Parameters:
+
+       theta - A <Polar> number theta property.
+       rho - A <Polar> number rho property.
+    
+    */
+    setp: function(theta, rho) {
+        this.x = Math.cos(theta) * rho;
+        this.y = Math.sin(theta) * rho;
+    },
+
+    /*
+       Method: clone
+    
+       Returns a copy of the current object.
+    
+       Returns:
+    
+          A copy of the real object.
+    */
+    clone: function() {
+        return new Complex(this.x, this.y);
+    },
+
+    /*
+       Method: toPolar
+    
+       Transforms cartesian to polar coordinates.
+    
+       Parameters:
+
+       simple - _optional_ If *true* this method will only return an object with theta and rho properties (and not the whole <Polar> instance). Default's *false*.
+       
+       Returns:
+    
+          A new <Polar> instance.
+    */
+    
+    toPolar: function(simple) {
+        var rho = this.norm();
+        var atan = Math.atan2(this.y, this.x);
+        if(atan < 0) atan += Math.PI * 2;
+        if(simple) return { 'theta': atan, 'rho': rho };
+        return new Polar(atan, rho);
+    },
+    /*
+       Method: norm
+    
+       Calculates a <Complex> number norm.
+    
+       Returns:
+    
+          A real number representing the complex norm.
+    */
+    norm: function () {
+        return Math.sqrt(this.squaredNorm());
+    },
+    
+    /*
+       Method: squaredNorm
+    
+       Calculates a <Complex> number squared norm.
+    
+       Returns:
+    
+          A real number representing the complex squared norm.
+    */
+    squaredNorm: function () {
+        return this.x*this.x + this.y*this.y;
+    },
+
+    /*
+       Method: add
+    
+       Returns the result of adding two complex numbers.
+       
+       Does not alter the original object.
+
+       Parameters:
+    
+          pos - A <Complex> instance.
+    
+       Returns:
+    
+         The result of adding two complex numbers.
+    */
+    add: function(pos) {
+        return new Complex(this.x + pos.x, this.y + pos.y);
+    },
+
+    /*
+       Method: prod
+    
+       Returns the result of multiplying two <Complex> numbers.
+       
+       Does not alter the original object.
+
+       Parameters:
+    
+          pos - A <Complex> instance.
+    
+       Returns:
+    
+         The result of multiplying two complex numbers.
+    */
+    prod: function(pos) {
+        return new Complex(this.x*pos.x - this.y*pos.y, this.y*pos.x + this.x*pos.y);
+    },
+
+    /*
+       Method: conjugate
+    
+       Returns the conjugate of this <Complex> number.
+
+       Does not alter the original object.
+
+       Returns:
+    
+         The conjugate of this <Complex> number.
+    */
+    conjugate: function() {
+        return new Complex(this.x, -this.y);
+    },
+
+
+    /*
+       Method: scale
+    
+       Returns the result of scaling a <Complex> instance.
+       
+       Does not alter the original object.
+
+       Parameters:
+    
+          factor - A scale factor.
+    
+       Returns:
+    
+         The result of scaling this complex to a factor.
+    */
+    scale: function(factor) {
+        return new Complex(this.x * factor, this.y * factor);
+    },
+
+    /*
+       Method: equals
+    
+       Comparison method.
+
+       Returns *true* if both real and imaginary parts are equal.
+
+       Parameters:
+
+       c - A <Complex> instance.
+
+       Returns:
+
+       A boolean instance indicating if both <Complex> numbers are equal.
+    */
+    equals: function(c) {
+        return this.x == c.x && this.y == c.y;
+    },
+
+    /*
+       Method: $add
+    
+       Returns the result of adding two <Complex> numbers.
+       
+       Alters the original object.
+
+       Parameters:
+    
+          pos - A <Complex> instance.
+    
+       Returns:
+    
+         The result of adding two complex numbers.
+    */
+    $add: function(pos) {
+        this.x += pos.x; this.y += pos.y;
+        return this;    
+    },
+    
+    /*
+       Method: $prod
+    
+       Returns the result of multiplying two <Complex> numbers.
+       
+       Alters the original object.
+
+       Parameters:
+    
+          pos - A <Complex> instance.
+    
+       Returns:
+    
+         The result of multiplying two complex numbers.
+    */
+    $prod:function(pos) {
+        var x = this.x, y = this.y;
+        this.x = x*pos.x - y*pos.y;
+        this.y = y*pos.x + x*pos.y;
+        return this;
+    },
+    
+    /*
+       Method: $conjugate
+    
+       Returns the conjugate for this <Complex>.
+       
+       Alters the original object.
+
+       Returns:
+    
+         The conjugate for this complex.
+    */
+    $conjugate: function() {
+        this.y = -this.y;
+        return this;
+    },
+    
+    /*
+       Method: $scale
+    
+       Returns the result of scaling a <Complex> instance.
+       
+       Alters the original object.
+
+       Parameters:
+    
+          factor - A scale factor.
+    
+       Returns:
+    
+         The result of scaling this complex to a factor.
+    */
+    $scale: function(factor) {
+        this.x *= factor; this.y *= factor;
+        return this;
+    },
+    
+    /*
+       Method: $div
+    
+       Returns the division of two <Complex> numbers.
+       
+       Alters the original object.
+
+       Parameters:
+    
+          pos - A <Complex> number.
+    
+       Returns:
+    
+         The result of scaling this complex to a factor.
+    */
+    $div: function(pos) {
+        var x = this.x, y = this.y;
+        var sq = pos.squaredNorm();
+        this.x = x * pos.x + y * pos.y; this.y = y * pos.x - x * pos.y;
+        return this.$scale(1 / sq);
+    },
+
+    /*
+      Method: isZero
+   
+      Returns *true* if the number is zero.
+   
+   */
+    isZero: function () {
+      var almostZero = 0.0001, abs = Math.abs;
+      return abs(this.x) < almostZero && abs(this.y) < almostZero;
+    }
+};
+
+var $C = function(a, b) { return new Complex(a, b); };
+
+Complex.KER = $C(0, 0);
+
+
+
+/*
+ * File: Graph.js
+ *
+*/
+
+/*
+ Class: Graph
+
+ A Graph Class that provides useful manipulation functions. You can find more manipulation methods in the <Graph.Util> object.
+
+ An instance of this class can be accessed by using the *graph* parameter of any tree or graph visualization.
+ 
+ Example:
+
+ (start code js)
+   //create new visualization
+   var viz = new $jit.Viz(options);
+   //load JSON data
+   viz.loadJSON(json);
+   //access model
+   viz.graph; //<Graph> instance
+ (end code)
+ 
+ Implements:
+ 
+ The following <Graph.Util> methods are implemented in <Graph>
+ 
+  - <Graph.Util.getNode>
+  - <Graph.Util.eachNode>
+  - <Graph.Util.computeLevels>
+  - <Graph.Util.eachBFS>
+  - <Graph.Util.clean>
+  - <Graph.Util.getClosestNodeToPos>
+  - <Graph.Util.getClosestNodeToOrigin>
+ 
+*/  
+
+$jit.Graph = new Class({
+
+  initialize: function(opt, Node, Edge, Label) {
+    var innerOptions = {
+    'klass': Complex,
+    'Node': {}
+    };
+    this.Node = Node;
+    this.Edge = Edge;
+    this.Label = Label;
+    this.opt = $.merge(innerOptions, opt || {});
+    this.nodes = {};
+    this.edges = {};
+    
+    //add nodeList methods
+    var that = this;
+    this.nodeList = {};
+    for(var p in Accessors) {
+      that.nodeList[p] = (function(p) {
+        return function() {
+          var args = Array.prototype.slice.call(arguments);
+          that.eachNode(function(n) {
+            n[p].apply(n, args);
+          });
+        };
+      })(p);
+    }
+
+ },
+
+/*
+     Method: getNode
+    
+     Returns a <Graph.Node> by *id*.
+
+     Parameters:
+
+     id - (string) A <Graph.Node> id.
+
+     Example:
+
+     (start code js)
+       var node = graph.getNode('nodeId');
+     (end code)
+*/  
+ getNode: function(id) {
+    if(this.hasNode(id)) return this.nodes[id];
+    return false;
+ },
+
+ /*
+     Method: get
+    
+     An alias for <Graph.Util.getNode>. Returns a node by *id*.
+    
+     Parameters:
+    
+     id - (string) A <Graph.Node> id.
+    
+     Example:
+    
+     (start code js)
+       var node = graph.get('nodeId');
+     (end code)
+*/  
+  get: function(id) {
+    return this.getNode(id);
+  },
+
+ /*
+   Method: getByName
+  
+   Returns a <Graph.Node> by *name*.
+  
+   Parameters:
+  
+   name - (string) A <Graph.Node> name.
+  
+   Example:
+  
+   (start code js)
+     var node = graph.getByName('someName');
+   (end code)
+  */  
+  getByName: function(name) {
+    for(var id in this.nodes) {
+      var n = this.nodes[id];
+      if(n.name == name) return n;
+    }
+    return false;
+  },
+
+/*
+   Method: getAdjacence
+  
+   Returns a <Graph.Adjacence> object connecting nodes with ids *id* and *id2*.
+
+   Parameters:
+
+   id - (string) A <Graph.Node> id.
+   id2 - (string) A <Graph.Node> id.
+*/  
+  getAdjacence: function (id, id2) {
+    if(id in this.edges) {
+      return this.edges[id][id2];
+    }
+    return false;
+ },
+
+    /*
+     Method: addNode
+    
+     Adds a node.
+     
+     Parameters:
+    
+      obj - An object with the properties described below
+
+      id - (string) A node id
+      name - (string) A node's name
+      data - (object) A node's data hash
+
+    See also:
+    <Graph.Node>
+
+  */  
+  addNode: function(obj) { 
+   if(!this.nodes[obj.id]) {  
+     var edges = this.edges[obj.id] = {};
+     this.nodes[obj.id] = new Graph.Node($.extend({
+        'id': obj.id,
+        'name': obj.name,
+        'data': $.merge(obj.data || {}, {}),
+        'adjacencies': edges 
+      }, this.opt.Node), 
+      this.opt.klass, 
+      this.Node, 
+      this.Edge,
+      this.Label);
+    }
+    return this.nodes[obj.id];
+  },
+  
+    /*
+     Method: addAdjacence
+    
+     Connects nodes specified by *obj* and *obj2*. If not found, nodes are created.
+     
+     Parameters:
+    
+      obj - (object) A <Graph.Node> object.
+      obj2 - (object) Another <Graph.Node> object.
+      data - (object) A data object. Used to store some extra information in the <Graph.Adjacence> object created.
+
+    See also:
+
+    <Graph.Node>, <Graph.Adjacence>
+    */  
+  addAdjacence: function (obj, obj2, data) {
+    if(!this.hasNode(obj.id)) { this.addNode(obj); }
+    if(!this.hasNode(obj2.id)) { this.addNode(obj2); }
+    obj = this.nodes[obj.id]; obj2 = this.nodes[obj2.id];
+    if(!obj.adjacentTo(obj2)) {
+      var adjsObj = this.edges[obj.id] = this.edges[obj.id] || {};
+      var adjsObj2 = this.edges[obj2.id] = this.edges[obj2.id] || {};
+      adjsObj[obj2.id] = adjsObj2[obj.id] = new Graph.Adjacence(obj, obj2, data, this.Edge, this.Label);
+      return adjsObj[obj2.id];
+    }
+    return this.edges[obj.id][obj2.id];
+ },
+
+    /*
+     Method: removeNode
+    
+     Removes a <Graph.Node> matching the specified *id*.
+
+     Parameters:
+
+     id - (string) A node's id.
+
+    */  
+  removeNode: function(id) {
+    if(this.hasNode(id)) {
+      delete this.nodes[id];
+      var adjs = this.edges[id];
+      for(var to in adjs) {
+        delete this.edges[to][id];
+      }
+      delete this.edges[id];
+    }
+  },
+  
+/*
+     Method: removeAdjacence
+    
+     Removes a <Graph.Adjacence> matching *id1* and *id2*.
+
+     Parameters:
+
+     id1 - (string) A <Graph.Node> id.
+     id2 - (string) A <Graph.Node> id.
+*/  
+  removeAdjacence: function(id1, id2) {
+    delete this.edges[id1][id2];
+    delete this.edges[id2][id1];
+  },
+
+   /*
+     Method: hasNode
+    
+     Returns a boolean indicating if the node belongs to the <Graph> or not.
+     
+     Parameters:
+    
+        id - (string) Node id.
+   */  
+  hasNode: function(id) {
+    return id in this.nodes;
+  },
+  
+  /*
+    Method: empty
+
+    Empties the Graph
+
+  */
+  empty: function() { this.nodes = {}; this.edges = {};}
+
+});
+
+var Graph = $jit.Graph;
+
+/*
+ Object: Accessors
+ 
+ Defines a set of methods for data, canvas and label styles manipulation implemented by <Graph.Node> and <Graph.Adjacence> instances.
+ 
+ */
+var Accessors;
+
+(function () {
+  var getDataInternal = function(prefix, prop, type, force, prefixConfig) {
+    var data;
+    type = type || 'current';
+    prefix = "$" + (prefix ? prefix + "-" : "");
+
+    if(type == 'current') {
+      data = this.data;
+    } else if(type == 'start') {
+      data = this.startData;
+    } else if(type == 'end') {
+      data = this.endData;
+    }
+
+    var dollar = prefix + prop;
+
+    if(force) {
+      return data[dollar];
+    }
+
+    if(!this.Config.overridable)
+      return prefixConfig[prop] || 0;
+
+    return (dollar in data) ?
+      data[dollar] : ((dollar in this.data) ? this.data[dollar] : (prefixConfig[prop] || 0));
+  }
+
+  var setDataInternal = function(prefix, prop, value, type) {
+    type = type || 'current';
+    prefix = '$' + (prefix ? prefix + '-' : '');
+
+    var data;
+
+    if(type == 'current') {
+      data = this.data;
+    } else if(type == 'start') {
+      data = this.startData;
+    } else if(type == 'end') {
+      data = this.endData;
+    }
+
+    data[prefix + prop] = value;
+  }
+
+  var removeDataInternal = function(prefix, properties) {
+    prefix = '$' + (prefix ? prefix + '-' : '');
+    var that = this;
+    $.each(properties, function(prop) {
+      var pref = prefix + prop;
+      delete that.data[pref];
+      delete that.endData[pref];
+      delete that.startData[pref];
+    });
+  }
+
+  Accessors = {
+    /*
+    Method: getData
+
+    Returns the specified data value property.
+    This is useful for querying special/reserved <Graph.Node> data properties
+    (i.e dollar prefixed properties).
+
+    Parameters:
+
+      prop  - (string) The name of the property. The dollar sign is not needed. For
+              example *getData(width)* will return *data.$width*.
+      type  - (string) The type of the data property queried. Default's "current". You can access *start* and *end* 
+              data properties also. These properties are used when making animations.
+      force - (boolean) Whether to obtain the true value of the property (equivalent to
+              *data.$prop*) or to check for *node.overridable = true* first.
+
+    Returns:
+
+      The value of the dollar prefixed property or the global Node/Edge property
+      value if *overridable=false*
+
+    Example:
+    (start code js)
+     node.getData('width'); //will return node.data.$width if Node.overridable=true;
+    (end code)
+    */
+    getData: function(prop, type, force) {
+      return getDataInternal.call(this, "", prop, type, force, this.Config);
+    },
+
+
+    /*
+    Method: setData
+
+    Sets the current data property with some specific value.
+    This method is only useful for reserved (dollar prefixed) properties.
+
+    Parameters:
+
+      prop  - (string) The name of the property. The dollar sign is not necessary. For
+              example *setData(width)* will set *data.$width*.
+      value - (mixed) The value to store.
+      type  - (string) The type of the data property to store. Default's "current" but
+              can also be "start" or "end".
+
+    Example:
+    
+    (start code js)
+     node.setData('width', 30);
+    (end code)
+    
+    If we were to make an animation of a node/edge width then we could do
+    
+    (start code js)
+      var node = viz.getNode('nodeId');
+      //set start and end values
+      node.setData('width', 10, 'start');
+      node.setData('width', 30, 'end');
+      //will animate nodes width property
+      viz.fx.animate({
+        modes: ['node-property:width'],
+        duration: 1000
+      });
+    (end code)
+    */
+    setData: function(prop, value, type) {
+      setDataInternal.call(this, "", prop, value, type);
+    },
+
+    /*
+    Method: setDataset
+
+    Convenience method to set multiple data values at once.
+    
+    Parameters:
+    
+    types - (array|string) A set of 'current', 'end' or 'start' values.
+    obj - (object) A hash containing the names and values of the properties to be altered.
+
+    Example:
+    (start code js)
+      node.setDataset(['current', 'end'], {
+        'width': [100, 5],
+        'color': ['#fff', '#ccc']
+      });
+      //...or also
+      node.setDataset('end', {
+        'width': 5,
+        'color': '#ccc'
+      });
+    (end code)
+    
+    See also: 
+    
+    <Accessors.setData>
+    
+    */
+    setDataset: function(types, obj) {
+      types = $.splat(types);
+      for(var attr in obj) {
+        for(var i=0, val = $.splat(obj[attr]), l=types.length; i<l; i++) {
+          this.setData(attr, val[i], types[i]);
+        }
+      }
+    },
+    
+    /*
+    Method: removeData
+
+    Remove data properties.
+
+    Parameters:
+
+    One or more property names as arguments. The dollar sign is not needed.
+
+    Example:
+    (start code js)
+    node.removeData('width'); //now the default width value is returned
+    (end code)
+    */
+    removeData: function() {
+      removeDataInternal.call(this, "", Array.prototype.slice.call(arguments));
+    },
+
+    /*
+    Method: getCanvasStyle
+
+    Returns the specified canvas style data value property. This is useful for
+    querying special/reserved <Graph.Node> canvas style data properties (i.e.
+    dollar prefixed properties that match with $canvas-<name of canvas style>).
+
+    Parameters:
+
+      prop  - (string) The name of the property. The dollar sign is not needed. For
+              example *getCanvasStyle(shadowBlur)* will return *data[$canvas-shadowBlur]*.
+      type  - (string) The type of the data property queried. Default's *current*. You can access *start* and *end* 
+              data properties also.
+              
+    Example:
+    (start code js)
+      node.getCanvasStyle('shadowBlur');
+    (end code)
+    
+    See also:
+    
+    <Accessors.getData>
+    */
+    getCanvasStyle: function(prop, type, force) {
+      return getDataInternal.call(
+          this, 'canvas', prop, type, force, this.Config.CanvasStyles);
+    },
+
+    /*
+    Method: setCanvasStyle
+
+    Sets the canvas style data property with some specific value.
+    This method is only useful for reserved (dollar prefixed) properties.
+    
+    Parameters:
+    
+    prop - (string) Name of the property. Can be any canvas property like 'shadowBlur', 'shadowColor', 'strokeStyle', etc.
+    value - (mixed) The value to set to the property.
+    type - (string) Default's *current*. Whether to set *start*, *current* or *end* type properties.
+    
+    Example:
+    
+    (start code js)
+     node.setCanvasStyle('shadowBlur', 30);
+    (end code)
+    
+    If we were to make an animation of a node/edge shadowBlur canvas style then we could do
+    
+    (start code js)
+      var node = viz.getNode('nodeId');
+      //set start and end values
+      node.setCanvasStyle('shadowBlur', 10, 'start');
+      node.setCanvasStyle('shadowBlur', 30, 'end');
+      //will animate nodes canvas style property for nodes
+      viz.fx.animate({
+        modes: ['node-style:shadowBlur'],
+        duration: 1000
+      });
+    (end code)
+    
+    See also:
+    
+    <Accessors.setData>.
+    */
+    setCanvasStyle: function(prop, value, type) {
+      setDataInternal.call(this, 'canvas', prop, value, type);
+    },
+
+    /*
+    Method: setCanvasStyles
+
+    Convenience method to set multiple styles at once.
+
+    Parameters:
+    
+    types - (array|string) A set of 'current', 'end' or 'start' values.
+    obj - (object) A hash containing the names and values of the properties to be altered.
+
+    See also:
+    
+    <Accessors.setDataset>.
+    */
+    setCanvasStyles: function(types, obj) {
+      types = $.splat(types);
+      for(var attr in obj) {
+        for(var i=0, val = $.splat(obj[attr]), l=types.length; i<l; i++) {
+          this.setCanvasStyle(attr, val[i], types[i]);
+        }
+      }
+    },
+
+    /*
+    Method: removeCanvasStyle
+
+    Remove canvas style properties from data.
+
+    Parameters:
+    
+    A variable number of canvas style strings.
+
+    See also:
+    
+    <Accessors.removeData>.
+    */
+    removeCanvasStyle: function() {
+      removeDataInternal.call(this, 'canvas', Array.prototype.slice.call(arguments));
+    },
+
+    /*
+    Method: getLabelData
+
+    Returns the specified label data value property. This is useful for
+    querying special/reserved <Graph.Node> label options (i.e.
+    dollar prefixed properties that match with $label-<name of label style>).
+
+    Parameters:
+
+      prop  - (string) The name of the property. The dollar sign prefix is not needed. For
+              example *getLabelData(size)* will return *data[$label-size]*.
+      type  - (string) The type of the data property queried. Default's *current*. You can access *start* and *end* 
+              data properties also.
+              
+    See also:
+    
+    <Accessors.getData>.
+    */
+    getLabelData: function(prop, type, force) {
+      return getDataInternal.call(
+          this, 'label', prop, type, force, this.Label);
+    },
+
+    /*
+    Method: setLabelData
+
+    Sets the current label data with some specific value.
+    This method is only useful for reserved (dollar prefixed) properties.
+
+    Parameters:
+    
+    prop - (string) Name of the property. Can be any canvas property like 'shadowBlur', 'shadowColor', 'strokeStyle', etc.
+    value - (mixed) The value to set to the property.
+    type - (string) Default's *current*. Whether to set *start*, *current* or *end* type properties.
+    
+    Example:
+    
+    (start code js)
+     node.setLabelData('size', 30);
+    (end code)
+    
+    If we were to make an animation of a node label size then we could do
+    
+    (start code js)
+      var node = viz.getNode('nodeId');
+      //set start and end values
+      node.setLabelData('size', 10, 'start');
+      node.setLabelData('size', 30, 'end');
+      //will animate nodes label size
+      viz.fx.animate({
+        modes: ['label-property:size'],
+        duration: 1000
+      });
+    (end code)
+    
+    See also:
+    
+    <Accessors.setData>.
+    */
+    setLabelData: function(prop, value, type) {
+      setDataInternal.call(this, 'label', prop, value, type);
+    },
+
+    /*
+    Method: setLabelDataset
+
+    Convenience function to set multiple label data at once.
+
+    Parameters:
+    
+    types - (array|string) A set of 'current', 'end' or 'start' values.
+    obj - (object) A hash containing the names and values of the properties to be altered.
+
+    See also:
+    
+    <Accessors.setDataset>.
+    */
+    setLabelDataset: function(types, obj) {
+      types = $.splat(types);
+      for(var attr in obj) {
+        for(var i=0, val = $.splat(obj[attr]), l=types.length; i<l; i++) {
+          this.setLabelData(attr, val[i], types[i]);
+        }
+      }
+    },
+
+    /*
+    Method: removeLabelData
+
+    Remove label properties from data.
+    
+    Parameters:
+    
+    A variable number of label property strings.
+
+    See also:
+    
+    <Accessors.removeData>.
+    */
+    removeLabelData: function() {
+      removeDataInternal.call(this, 'label', Array.prototype.slice.call(arguments));
+    }
+  };
+})();
+
+/*
+     Class: Graph.Node
+
+     A <Graph> node.
+     
+     Implements:
+     
+     <Accessors> methods.
+     
+     The following <Graph.Util> methods are implemented by <Graph.Node>
+     
+    - <Graph.Util.eachAdjacency>
+    - <Graph.Util.eachLevel>
+    - <Graph.Util.eachSubgraph>
+    - <Graph.Util.eachSubnode>
+    - <Graph.Util.anySubnode>
+    - <Graph.Util.getSubnodes>
+    - <Graph.Util.getParents>
+    - <Graph.Util.isDescendantOf>     
+*/
+Graph.Node = new Class({
+    
+  initialize: function(opt, klass, Node, Edge, Label) {
+    var innerOptions = {
+      'id': '',
+      'name': '',
+      'data': {},
+      'startData': {},
+      'endData': {},
+      'adjacencies': {},
+
+      'selected': false,
+      'drawn': false,
+      'exist': false,
+
+      'angleSpan': {
+        'begin': 0,
+        'end' : 0
+      },
+
+      'pos': new klass,
+      'startPos': new klass,
+      'endPos': new klass
+    };
+    
+    $.extend(this, $.extend(innerOptions, opt));
+    this.Config = this.Node = Node;
+    this.Edge = Edge;
+    this.Label = Label;
+  },
+
+    /*
+       Method: adjacentTo
+    
+       Indicates if the node is adjacent to the node specified by id
+
+       Parameters:
+    
+          id - (string) A node id.
+    
+       Example:
+       (start code js)
+        node.adjacentTo('nodeId') == true;
+       (end code)
+    */
+    adjacentTo: function(node) {
+        return node.id in this.adjacencies;
+    },
+
+    /*
+       Method: getAdjacency
+    
+       Returns a <Graph.Adjacence> object connecting the current <Graph.Node> and the node having *id* as id.
+
+       Parameters:
+    
+          id - (string) A node id.
+    */  
+    getAdjacency: function(id) {
+        return this.adjacencies[id];
+    },
+
+    /*
+      Method: getPos
+   
+      Returns the position of the node.
+  
+      Parameters:
+   
+         type - (string) Default's *current*. Possible values are "start", "end" or "current".
+   
+      Returns:
+   
+        A <Complex> or <Polar> instance.
+  
+      Example:
+      (start code js)
+       var pos = node.getPos('end');
+      (end code)
+   */
+   getPos: function(type) {
+       type = type || "current";
+       if(type == "current") {
+         return this.pos;
+       } else if(type == "end") {
+         return this.endPos;
+       } else if(type == "start") {
+         return this.startPos;
+       }
+   },
+   /*
+     Method: setPos
+  
+     Sets the node's position.
+  
+     Parameters:
+  
+        value - (object) A <Complex> or <Polar> instance.
+        type - (string) Default's *current*. Possible values are "start", "end" or "current".
+  
+     Example:
+     (start code js)
+      node.setPos(new $jit.Complex(0, 0), 'end');
+     (end code)
+  */
+  setPos: function(value, type) {
+      type = type || "current";
+      var pos;
+      if(type == "current") {
+        pos = this.pos;
+      } else if(type == "end") {
+        pos = this.endPos;
+      } else if(type == "start") {
+        pos = this.startPos;
+      }
+      pos.set(value);
+  }
+});
+
+Graph.Node.implement(Accessors);
+
+/*
+     Class: Graph.Adjacence
+
+     A <Graph> adjacence (or edge) connecting two <Graph.Nodes>.
+     
+     Implements:
+     
+     <Accessors> methods.
+
+     See also:
+
+     <Graph>, <Graph.Node>
+
+     Properties:
+     
+      nodeFrom - A <Graph.Node> connected by this edge.
+      nodeTo - Another  <Graph.Node> connected by this edge.
+      data - Node data property containing a hash (i.e {}) with custom options.
+*/
+Graph.Adjacence = new Class({
+  
+  initialize: function(nodeFrom, nodeTo, data, Edge, Label) {
+    this.nodeFrom = nodeFrom;
+    this.nodeTo = nodeTo;
+    this.data = data || {};
+    this.startData = {};
+    this.endData = {};
+    this.Config = this.Edge = Edge;
+    this.Label = Label;
+  }
+});
+
+Graph.Adjacence.implement(Accessors);
+
+/*
+   Object: Graph.Util
+
+   <Graph> traversal and processing utility object.
+   
+   Note:
+   
+   For your convenience some of these methods have also been appended to <Graph> and <Graph.Node> classes.
+*/
+Graph.Util = {
+    /*
+       filter
+    
+       For internal use only. Provides a filtering function based on flags.
+    */
+    filter: function(param) {
+        if(!param || !($.type(param) == 'string')) return function() { return true; };
+        var props = param.split(" ");
+        return function(elem) {
+            for(var i=0; i<props.length; i++) { 
+              if(elem[props[i]]) { 
+                return false; 
+              }
+            }
+            return true;
+        };
+    },
+    /*
+       Method: getNode
+    
+       Returns a <Graph.Node> by *id*.
+       
+       Also implemented by:
+       
+       <Graph>
+
+       Parameters:
+
+       graph - (object) A <Graph> instance.
+       id - (string) A <Graph.Node> id.
+
+       Example:
+
+       (start code js)
+         $jit.Graph.Util.getNode(graph, 'nodeid');
+         //or...
+         graph.getNode('nodeid');
+       (end code)
+    */
+    getNode: function(graph, id) {
+        return graph.nodes[id];
+    },
+    
+    /*
+       Method: eachNode
+    
+       Iterates over <Graph> nodes performing an *action*.
+       
+       Also implemented by:
+       
+       <Graph>.
+
+       Parameters:
+
+       graph - (object) A <Graph> instance.
+       action - (function) A callback function having a <Graph.Node> as first formal parameter.
+
+       Example:
+       (start code js)
+         $jit.Graph.Util.eachNode(graph, function(node) {
+          alert(node.name);
+         });
+         //or...
+         graph.eachNode(function(node) {
+           alert(node.name);
+         });
+       (end code)
+    */
+    eachNode: function(graph, action, flags) {
+        var filter = this.filter(flags);
+        for(var i in graph.nodes) {
+          if(filter(graph.nodes[i])) action(graph.nodes[i]);
+        } 
+    },
+    
+    /*
+      Method: each
+   
+      Iterates over <Graph> nodes performing an *action*. It's an alias for <Graph.Util.eachNode>.
+      
+      Also implemented by:
+      
+      <Graph>.
+  
+      Parameters:
+  
+      graph - (object) A <Graph> instance.
+      action - (function) A callback function having a <Graph.Node> as first formal parameter.
+  
+      Example:
+      (start code js)
+        $jit.Graph.Util.each(graph, function(node) {
+         alert(node.name);
+        });
+        //or...
+        graph.each(function(node) {
+          alert(node.name);
+        });
+      (end code)
+   */
+   each: function(graph, action, flags) {
+      this.eachNode(graph, action, flags); 
+   },
+
+ /*
+       Method: eachAdjacency
+    
+       Iterates over <Graph.Node> adjacencies applying the *action* function.
+       
+       Also implemented by:
+       
+       <Graph.Node>.
+
+       Parameters:
+
+       node - (object) A <Graph.Node>.
+       action - (function) A callback function having <Graph.Adjacence> as first formal parameter.
+
+       Example:
+       (start code js)
+         $jit.Graph.Util.eachAdjacency(node, function(adj) {
+          alert(adj.nodeTo.name);
+         });
+         //or...
+         node.eachAdjacency(function(adj) {
+           alert(adj.nodeTo.name);
+         });
+       (end code)
+    */
+    eachAdjacency: function(node, action, flags) {
+        var adj = node.adjacencies, filter = this.filter(flags);
+        for(var id in adj) {
+          var a = adj[id];
+          if(filter(a)) {
+            if(a.nodeFrom != node) {
+              var tmp = a.nodeFrom;
+              a.nodeFrom = a.nodeTo;
+              a.nodeTo = tmp;
+            }
+            action(a, id);
+          }
+        }
+    },
+
+     /*
+       Method: computeLevels
+    
+       Performs a BFS traversal setting the correct depth for each node.
+        
+       Also implemented by:
+       
+       <Graph>.
+       
+       Note:
+       
+       The depth of each node can then be accessed by 
+       >node._depth
+
+       Parameters:
+
+       graph - (object) A <Graph>.
+       id - (string) A starting node id for the BFS traversal.
+       startDepth - (optional|number) A minimum depth value. Default's 0.
+
+    */
+    computeLevels: function(graph, id, startDepth, flags) {
+        startDepth = startDepth || 0;
+        var filter = this.filter(flags);
+        this.eachNode(graph, function(elem) {
+            elem._flag = false;
+            elem._depth = -1;
+        }, flags);
+        var root = graph.getNode(id);
+        root._depth = startDepth;
+        var queue = [root];
+        while(queue.length != 0) {
+            var node = queue.pop();
+            node._flag = true;
+            this.eachAdjacency(node, function(adj) {
+                var n = adj.nodeTo;
+                if(n._flag == false && filter(n)) {
+                    if(n._depth < 0) n._depth = node._depth + 1 + startDepth;
+                    queue.unshift(n);
+                }
+            }, flags);
+        }
+    },
+
+    /*
+       Method: eachBFS
+    
+       Performs a BFS traversal applying *action* to each <Graph.Node>.
+       
+       Also implemented by:
+       
+       <Graph>.
+
+       Parameters:
+
+       graph - (object) A <Graph>.
+       id - (string) A starting node id for the BFS traversal.
+       action - (function) A callback function having a <Graph.Node> as first formal parameter.
+
+       Example:
+       (start code js)
+         $jit.Graph.Util.eachBFS(graph, 'mynodeid', function(node) {
+          alert(node.name);
+         });
+         //or...
+         graph.eachBFS('mynodeid', function(node) {
+           alert(node.name);
+         });
+       (end code)
+    */
+    eachBFS: function(graph, id, action, flags) {
+        var filter = this.filter(flags);
+        this.clean(graph);
+        var queue = [graph.getNode(id)];
+        while(queue.length != 0) {
+            var node = queue.pop();
+            node._flag = true;
+            action(node, node._depth);
+            this.eachAdjacency(node, function(adj) {
+                var n = adj.nodeTo;
+                if(n._flag == false && filter(n)) {
+                    n._flag = true;
+                    queue.unshift(n);
+                }
+            }, flags);
+        }
+    },
+    
+    /*
+       Method: eachLevel
+    
+       Iterates over a node's subgraph applying *action* to the nodes of relative depth between *levelBegin* and *levelEnd*.
+       
+       Also implemented by:
+       
+       <Graph.Node>.
+
+       Parameters:
+       
+       node - (object) A <Graph.Node>.
+       levelBegin - (number) A relative level value.
+       levelEnd - (number) A relative level value.
+       action - (function) A callback function having a <Graph.Node> as first formal parameter.
+
+    */
+    eachLevel: function(node, levelBegin, levelEnd, action, flags) {
+        var d = node._depth, filter = this.filter(flags), that = this;
+        levelEnd = levelEnd === false? Number.MAX_VALUE -d : levelEnd;
+        (function loopLevel(node, levelBegin, levelEnd) {
+            var d = node._depth;
+            if(d >= levelBegin && d <= levelEnd && filter(node)) action(node, d);
+            if(d < levelEnd) {
+                that.eachAdjacency(node, function(adj) {
+                    var n = adj.nodeTo;
+                    if(n._depth > d) loopLevel(n, levelBegin, levelEnd);
+                });
+            }
+        })(node, levelBegin + d, levelEnd + d);      
+    },
+
+    /*
+       Method: eachSubgraph
+    
+       Iterates over a node's children recursively.
+       
+       Also implemented by:
+       
+       <Graph.Node>.
+
+       Parameters:
+       node - (object) A <Graph.Node>.
+       action - (function) A callback function having a <Graph.Node> as first formal parameter.
+
+       Example:
+       (start code js)
+         $jit.Graph.Util.eachSubgraph(node, function(node) {
+           alert(node.name);
+         });
+         //or...
+         node.eachSubgraph(function(node) {
+           alert(node.name);
+         });
+       (end code)
+    */
+    eachSubgraph: function(node, action, flags) {
+      this.eachLevel(node, 0, false, action, flags);
+    },
+
+    /*
+       Method: eachSubnode
+    
+       Iterates over a node's children (without deeper recursion).
+       
+       Also implemented by:
+       
+       <Graph.Node>.
+       
+       Parameters:
+       node - (object) A <Graph.Node>.
+       action - (function) A callback function having a <Graph.Node> as first formal parameter.
+
+       Example:
+       (start code js)
+         $jit.Graph.Util.eachSubnode(node, function(node) {
+          alert(node.name);
+         });
+         //or...
+         node.eachSubnode(function(node) {
+           alert(node.name);
+         });
+       (end code)
+    */
+    eachSubnode: function(node, action, flags) {
+        this.eachLevel(node, 1, 1, action, flags);
+    },
+
+    /*
+       Method: anySubnode
+    
+       Returns *true* if any subnode matches the given condition.
+       
+       Also implemented by:
+       
+       <Graph.Node>.
+
+       Parameters:
+       node - (object) A <Graph.Node>.
+       cond - (function) A callback function returning a Boolean instance. This function has as first formal parameter a <Graph.Node>.
+
+       Example:
+       (start code js)
+         $jit.Graph.Util.anySubnode(node, function(node) { return node.name == "mynodename"; });
+         //or...
+         node.anySubnode(function(node) { return node.name == 'mynodename'; });
+       (end code)
+    */
+    anySubnode: function(node, cond, flags) {
+      var flag = false;
+      cond = cond || $.lambda(true);
+      var c = $.type(cond) == 'string'? function(n) { return n[cond]; } : cond;
+      this.eachSubnode(node, function(elem) {
+        if(c(elem)) flag = true;
+      }, flags);
+      return flag;
+    },
+  
+    /*
+       Method: getSubnodes
+    
+       Collects all subnodes for a specified node. 
+       The *level* parameter filters nodes having relative depth of *level* from the root node. 
+       
+       Also implemented by:
+       
+       <Graph.Node>.
+
+       Parameters:
+       node - (object) A <Graph.Node>.
+       level - (optional|number) Default's *0*. A starting relative depth for collecting nodes.
+
+       Returns:
+       An array of nodes.
+
+    */
+    getSubnodes: function(node, level, flags) {
+        var ans = [], that = this;
+        level = level || 0;
+        var levelStart, levelEnd;
+        if($.type(level) == 'array') {
+            levelStart = level[0];
+            levelEnd = level[1];
+        } else {
+            levelStart = level;
+            levelEnd = Number.MAX_VALUE - node._depth;
+        }
+        this.eachLevel(node, levelStart, levelEnd, function(n) {
+            ans.push(n);
+        }, flags);
+        return ans;
+    },
+  
+  
+    /*
+       Method: getParents
+    
+       Returns an Array of <Graph.Nodes> which are parents of the given node.
+       
+       Also implemented by:
+       
+       <Graph.Node>.
+
+       Parameters:
+       node - (object) A <Graph.Node>.
+
+       Returns:
+       An Array of <Graph.Nodes>.
+
+       Example:
+       (start code js)
+         var pars = $jit.Graph.Util.getParents(node);
+         //or...
+         var pars = node.getParents();
+         
+         if(pars.length > 0) {
+           //do stuff with parents
+         }
+       (end code)
+    */
+    getParents: function(node) {
+        var ans = [];
+        this.eachAdjacency(node, function(adj) {
+            var n = adj.nodeTo;
+            if(n._depth < node._depth) ans.push(n);
+        });
+        return ans;
+    },
+    
+    /*
+    Method: isDescendantOf
+ 
+    Returns a boolean indicating if some node is descendant of the node with the given id. 
+
+    Also implemented by:
+    
+    <Graph.Node>.
+    
+    
+    Parameters:
+    node - (object) A <Graph.Node>.
+    id - (string) A <Graph.Node> id.
+
+    Example:
+    (start code js)
+      $jit.Graph.Util.isDescendantOf(node, "nodeid"); //true|false
+      //or...
+      node.isDescendantOf('nodeid');//true|false
+    (end code)
+ */
+ isDescendantOf: function(node, id) {
+    if(node.id == id) return true;
+    var pars = this.getParents(node), ans = false;
+    for ( var i = 0; !ans && i < pars.length; i++) {
+    ans = ans || this.isDescendantOf(pars[i], id);
+  }
+    return ans;
+ },
+
+ /*
+     Method: clean
+  
+     Cleans flags from nodes.
+
+     Also implemented by:
+     
+     <Graph>.
+     
+     Parameters:
+     graph - A <Graph> instance.
+  */
+  clean: function(graph) { this.eachNode(graph, function(elem) { elem._flag = false; }); },
+  
+  /* 
+    Method: getClosestNodeToOrigin 
+  
+    Returns the closest node to the center of canvas.
+  
+    Also implemented by:
+    
+    <Graph>.
+    
+    Parameters:
+   
+     graph - (object) A <Graph> instance.
+     prop - (optional|string) Default's 'current'. A <Graph.Node> position property. Possible properties are 'start', 'current' or 'end'.
+  
+  */
+  getClosestNodeToOrigin: function(graph, prop, flags) {
+   return this.getClosestNodeToPos(graph, Polar.KER, prop, flags);
+  },
+  
+  /* 
+    Method: getClosestNodeToPos
+  
+    Returns the closest node to the given position.
+  
+    Also implemented by:
+    
+    <Graph>.
+    
+    Parameters:
+   
+     graph - (object) A <Graph> instance.
+     pos - (object) A <Complex> or <Polar> instance.
+     prop - (optional|string) Default's *current*. A <Graph.Node> position property. Possible properties are 'start', 'current' or 'end'.
+  
+  */
+  getClosestNodeToPos: function(graph, pos, prop, flags) {
+   var node = null;
+   prop = prop || 'current';
+   pos = pos && pos.getc(true) || Complex.KER;
+   var distance = function(a, b) {
+     var d1 = a.x - b.x, d2 = a.y - b.y;
+     return d1 * d1 + d2 * d2;
+   };
+   this.eachNode(graph, function(elem) {
+     node = (node == null || distance(elem.getPos(prop).getc(true), pos) < distance(
+         node.getPos(prop).getc(true), pos)) ? elem : node;
+   }, flags);
+   return node;
+  } 
+};
+
+//Append graph methods to <Graph>
+$.each(['get', 'getNode', 'each', 'eachNode', 'computeLevels', 'eachBFS', 'clean', 'getClosestNodeToPos', 'getClosestNodeToOrigin'], function(m) {
+  Graph.prototype[m] = function() {
+    return Graph.Util[m].apply(Graph.Util, [this].concat(Array.prototype.slice.call(arguments)));
+  };
+});
+
+//Append node methods to <Graph.Node>
+$.each(['eachAdjacency', 'eachLevel', 'eachSubgraph', 'eachSubnode', 'anySubnode', 'getSubnodes', 'getParents', 'isDescendantOf'], function(m) {
+  Graph.Node.prototype[m] = function() {
+    return Graph.Util[m].apply(Graph.Util, [this].concat(Array.prototype.slice.call(arguments)));
+  };
+});
+
+/*
+ * File: Graph.Op.js
+ *
+*/
+
+/*
+   Object: Graph.Op
+
+   Perform <Graph> operations like adding/removing <Graph.Nodes> or <Graph.Adjacences>, 
+   morphing a <Graph> into another <Graph>, contracting or expanding subtrees, etc.
+
+*/
+Graph.Op = {
+
+    options: {
+      type: 'nothing',
+      duration: 2000,
+      hideLabels: true,
+      fps:30
+    },
+    
+    initialize: function(viz) {
+      this.viz = viz;
+    },
+
+    /*
+       Method: removeNode
+    
+       Removes one or more <Graph.Nodes> from the visualization. 
+       It can also perform several animations like fading sequentially, fading concurrently, iterating or replotting.
+
+       Parameters:
+    
+        node - (string|array) The node's id. Can also be an array having many ids.
+        opt - (object) Animation options. It's an object with optional properties described below
+        type - (string) Default's *nothing*. Type of the animation. Can be "nothing", "replot", "fade:seq",  "fade:con" or "iter".
+        duration - Described in <Options.Fx>.
+        fps - Described in <Options.Fx>.
+        transition - Described in <Options.Fx>.
+        hideLabels - (boolean) Default's *true*. Hide labels during the animation.
+   
+      Example:
+      (start code js)
+        var viz = new $jit.Viz(options);
+        viz.op.removeNode('nodeId', {
+          type: 'fade:seq',
+          duration: 1000,
+          hideLabels: false,
+          transition: $jit.Trans.Quart.easeOut
+        });
+        //or also
+        viz.op.removeNode(['someId', 'otherId'], {
+          type: 'fade:con',
+          duration: 1500
+        });
+      (end code)
+    */
+  
+    removeNode: function(node, opt) {
+        var viz = this.viz;
+        var options = $.merge(this.options, viz.controller, opt);
+        var n = $.splat(node);
+        var i, that, nodeObj;
+        switch(options.type) {
+            case 'nothing':
+                for(i=0; i<n.length; i++) viz.graph.removeNode(n[i]);
+                break;
+            
+            case 'replot':
+                this.removeNode(n, { type: 'nothing' });
+                viz.labels.clearLabels();
+                viz.refresh(true);
+                break;
+            
+            case 'fade:seq': case 'fade':
+                that = this;
+                //set alpha to 0 for nodes to remove.
+                for(i=0; i<n.length; i++) {
+                    nodeObj = viz.graph.getNode(n[i]);
+                    nodeObj.setData('alpha', 0, 'end');
+                }
+                viz.fx.animate($.merge(options, {
+                    modes: ['node-property:alpha'],
+                    onComplete: function() {
+                        that.removeNode(n, { type: 'nothing' });
+                        viz.labels.clearLabels();
+                        viz.reposition();
+                        viz.fx.animate($.merge(options, {
+                            modes: ['linear']
+                        }));
+                    }
+                }));
+                break;
+            
+            case 'fade:con':
+                that = this;
+                //set alpha to 0 for nodes to remove. Tag them for being ignored on computing positions.
+                for(i=0; i<n.length; i++) {
+                    nodeObj = viz.graph.getNode(n[i]);
+                    nodeObj.setData('alpha', 0, 'end');
+                    nodeObj.ignore = true;
+                }
+                viz.reposition();
+                viz.fx.animate($.merge(options, {
+                    modes: ['node-property:alpha', 'linear'],
+                    onComplete: function() {
+                        that.removeNode(n, { type: 'nothing' });
+                        options.onComplete && options.onComplete();
+                    }
+                }));
+                break;
+            
+            case 'iter':
+                that = this;
+                viz.fx.sequence({
+                    condition: function() { return n.length != 0; },
+                    step: function() { that.removeNode(n.shift(), { type: 'nothing' });  viz.labels.clearLabels(); },
+                    onComplete: function() { options.onComplete && options.onComplete(); },
+                    duration: Math.ceil(options.duration / n.length)
+                });
+                break;
+                
+            default: this.doError();
+        }
+    },
+    
+    /*
+       Method: removeEdge
+    
+       Removes one or more <Graph.Adjacences> from the visualization. 
+       It can also perform several animations like fading sequentially, fading concurrently, iterating or replotting.
+
+       Parameters:
+    
+       vertex - (array) An array having two strings which are the ids of the nodes connected by this edge (i.e ['id1', 'id2']). Can also be a two dimensional array holding many edges (i.e [['id1', 'id2'], ['id3', 'id4'], ...]).
+       opt - (object) Animation options. It's an object with optional properties described below
+       type - (string) Default's *nothing*. Type of the animation. Can be "nothing", "replot", "fade:seq",  "fade:con" or "iter".
+       duration - Described in <Options.Fx>.
+       fps - Described in <Options.Fx>.
+       transition - Described in <Options.Fx>.
+       hideLabels - (boolean) Default's *true*. Hide labels during the animation.
+   
+      Example:
+      (start code js)
+        var viz = new $jit.Viz(options);
+        viz.op.removeEdge(['nodeId', 'otherId'], {
+          type: 'fade:seq',
+          duration: 1000,
+          hideLabels: false,
+          transition: $jit.Trans.Quart.easeOut
+        });
+        //or also
+        viz.op.removeEdge([['someId', 'otherId'], ['id3', 'id4']], {
+          type: 'fade:con',
+          duration: 1500
+        });
+      (end code)
+    
+    */
+    removeEdge: function(vertex, opt) {
+        var viz = this.viz;
+        var options = $.merge(this.options, viz.controller, opt);
+        var v = ($.type(vertex[0]) == 'string')? [vertex] : vertex;
+        var i, that, adj;
+        switch(options.type) {
+            case 'nothing':
+                for(i=0; i<v.length; i++)   viz.graph.removeAdjacence(v[i][0], v[i][1]);
+                break;
+            
+            case 'replot':
+                this.removeEdge(v, { type: 'nothing' });
+                viz.refresh(true);
+                break;
+            
+            case 'fade:seq': case 'fade':
+                that = this;
+                //set alpha to 0 for edges to remove.
+                for(i=0; i<v.length; i++) {
+                    adj = viz.graph.getAdjacence(v[i][0], v[i][1]);
+                    if(adj) {
+                        adj.setData('alpha', 0,'end');
+                    }
+                }
+                viz.fx.animate($.merge(options, {
+                    modes: ['edge-property:alpha'],
+                    onComplete: function() {
+                        that.removeEdge(v, { type: 'nothing' });
+                        viz.reposition();
+                        viz.fx.animate($.merge(options, {
+                            modes: ['linear']
+                        }));
+                    }
+                }));
+                break;
+            
+            case 'fade:con':
+                that = this;
+                //set alpha to 0 for nodes to remove. Tag them for being ignored when computing positions.
+                for(i=0; i<v.length; i++) {
+                    adj = viz.graph.getAdjacence(v[i][0], v[i][1]);
+                    if(adj) {
+                        adj.setData('alpha',0 ,'end');
+                        adj.ignore = true;
+                    }
+                }
+                viz.reposition();
+                viz.fx.animate($.merge(options, {
+                    modes: ['edge-property:alpha', 'linear'],
+                    onComplete: function() {
+                        that.removeEdge(v, { type: 'nothing' });
+                        options.onComplete && options.onComplete();
+                    }
+                }));
+                break;
+            
+            case 'iter':
+                that = this;
+                viz.fx.sequence({
+                    condition: function() { return v.length != 0; },
+                    step: function() { that.removeEdge(v.shift(), { type: 'nothing' }); viz.labels.clearLabels(); },
+                    onComplete: function() { options.onComplete(); },
+                    duration: Math.ceil(options.duration / v.length)
+                });
+                break;
+                
+            default: this.doError();
+        }
+    },
+    
+    /*
+       Method: sum
+    
+       Adds a new graph to the visualization. 
+       The JSON graph (or tree) must at least have a common node with the current graph plotted by the visualization. 
+       The resulting graph can be defined as follows <http://mathworld.wolfram.com/GraphSum.html>
+
+       Parameters:
+    
+       json - (object) A json tree or graph structure. See also <Loader.loadJSON>.
+       opt - (object) Animation options. It's an object with optional properties described below
+       type - (string) Default's *nothing*. Type of the animation. Can be "nothing", "replot", "fade:seq",  "fade:con".
+       duration - Described in <Options.Fx>.
+       fps - Described in <Options.Fx>.
+       transition - Described in <Options.Fx>.
+       hideLabels - (boolean) Default's *true*. Hide labels during the animation.
+   
+      Example:
+      (start code js)
+        //...json contains a tree or graph structure...
+
+        var viz = new $jit.Viz(options);
+        viz.op.sum(json, {
+          type: 'fade:seq',
+          duration: 1000,
+          hideLabels: false,
+          transition: $jit.Trans.Quart.easeOut
+        });
+        //or also
+        viz.op.sum(json, {
+          type: 'fade:con',
+          duration: 1500
+        });
+      (end code)
+    
+    */
+    sum: function(json, opt) {
+        var viz = this.viz;
+        var options = $.merge(this.options, viz.controller, opt), root = viz.root;
+        var graph;
+        viz.root = opt.id || viz.root;
+        switch(options.type) {
+            case 'nothing':
+                graph = viz.construct(json);
+                graph.eachNode(function(elem) {
+                    elem.eachAdjacency(function(adj) {
+                        viz.graph.addAdjacence(adj.nodeFrom, adj.nodeTo, adj.data);
+                    });
+                });
+                break;
+            
+            case 'replot':
+                viz.refresh(true);
+                this.sum(json, { type: 'nothing' });
+                viz.refresh(true);
+                break;
+            
+            case 'fade:seq': case 'fade': case 'fade:con':
+                that = this;
+                graph = viz.construct(json);
+
+                //set alpha to 0 for nodes to add.
+                var fadeEdges = this.preprocessSum(graph);
+                var modes = !fadeEdges? ['node-property:alpha'] : ['node-property:alpha', 'edge-property:alpha'];
+                viz.reposition();
+                if(options.type != 'fade:con') {
+                    viz.fx.animate($.merge(options, {
+                        modes: ['linear'],
+                        onComplete: function() {
+                            viz.fx.animate($.merge(options, {
+                                modes: modes,
+                                onComplete: function() {
+                                    options.onComplete();
+                                }
+                            }));
+                        }
+                    }));
+                } else {
+                    viz.graph.eachNode(function(elem) {
+                        if (elem.id != root && elem.pos.isZero()) {
+                          elem.pos.set(elem.endPos); 
+                          elem.startPos.set(elem.endPos);
+                        }
+                    });
+                    viz.fx.animate($.merge(options, {
+                        modes: ['linear'].concat(modes)
+                    }));
+                }
+                break;
+
+            default: this.doError();
+        }
+    },
+    
+    /*
+       Method: morph
+    
+       This method will transform the current visualized graph into the new JSON representation passed in the method. 
+       The JSON object must at least have the root node in common with the current visualized graph.
+
+       Parameters:
+    
+       json - (object) A json tree or graph structure. See also <Loader.loadJSON>.
+       opt - (object) Animation options. It's an object with optional properties described below
+       type - (string) Default's *nothing*. Type of the animation. Can be "nothing", "replot", "fade:con".
+       duration - Described in <Options.Fx>.
+       fps - Described in <Options.Fx>.
+       transition - Described in <Options.Fx>.
+       hideLabels - (boolean) Default's *true*. Hide labels during the animation.
+       id - (string) The shared <Graph.Node> id between both graphs.
+       
+       extraModes - (optional|object) When morphing with an animation, dollar prefixed data parameters are added to 
+                    *endData* and not *data* itself. This way you can animate dollar prefixed parameters during your morphing operation. 
+                    For animating these extra-parameters you have to specify an object that has animation groups as keys and animation 
+                    properties as values, just like specified in <Graph.Plot.animate>.
+   
+      Example:
+      (start code js)
+        //...json contains a tree or graph structure...
+
+        var viz = new $jit.Viz(options);
+        viz.op.morph(json, {
+          type: 'fade',
+          duration: 1000,
+          hideLabels: false,
+          transition: $jit.Trans.Quart.easeOut
+        });
+        //or also
+        viz.op.morph(json, {
+          type: 'fade',
+          duration: 1500
+        });
+        //if the json data contains dollar prefixed params
+        //like $width or $height these too can be animated
+        viz.op.morph(json, {
+          type: 'fade',
+          duration: 1500
+        }, {
+          'node-property': ['width', 'height']
+        });
+      (end code)
+    
+    */
+    morph: function(json, opt, extraModes) {
+        extraModes = extraModes || {};
+        var viz = this.viz;
+        var options = $.merge(this.options, viz.controller, opt), root = viz.root;
+        var graph;
+        //TODO(nico) this hack makes morphing work with the Hypertree. 
+        //Need to check if it has been solved and this can be removed.
+        viz.root = opt.id || viz.root;
+        switch(options.type) {
+            case 'nothing':
+                graph = viz.construct(json);
+                graph.eachNode(function(elem) {
+                  var nodeExists = viz.graph.hasNode(elem.id);  
+                  elem.eachAdjacency(function(adj) {
+                    var adjExists = !!viz.graph.getAdjacence(adj.nodeFrom.id, adj.nodeTo.id);
+                    viz.graph.addAdjacence(adj.nodeFrom, adj.nodeTo, adj.data);
+                    //Update data properties if the node existed
+                    if(adjExists) {
+                      var addedAdj = viz.graph.getAdjacence(adj.nodeFrom.id, adj.nodeTo.id);
+                      for(var prop in (adj.data || {})) {
+                        addedAdj.data[prop] = adj.data[prop];
+                      }
+                    }
+                  });
+                  //Update data properties if the node existed
+                  if(nodeExists) {
+                    var addedNode = viz.graph.getNode(elem.id);
+                    for(var prop in (elem.data || {})) {
+                      addedNode.data[prop] = elem.data[prop];
+                    }
+                  }
+                });
+                viz.graph.eachNode(function(elem) {
+                    elem.eachAdjacency(function(adj) {
+                        if(!graph.getAdjacence(adj.nodeFrom.id, adj.nodeTo.id)) {
+                            viz.graph.removeAdjacence(adj.nodeFrom.id, adj.nodeTo.id);
+                        }
+                    });
+                    if(!graph.hasNode(elem.id)) viz.graph.removeNode(elem.id);
+                });
+                
+                break;
+            
+            case 'replot':
+                viz.labels.clearLabels(true);
+                this.morph(json, { type: 'nothing' });
+                viz.refresh(true);
+                viz.refresh(true);
+                break;
+                
+            case 'fade:seq': case 'fade': case 'fade:con':
+                that = this;
+                graph = viz.construct(json);
+                //preprocessing for nodes to delete.
+                //get node property modes to interpolate
+                var nodeModes = ('node-property' in extraModes) 
+                  && $.map($.splat(extraModes['node-property']), 
+                      function(n) { return '$' + n; });
+                viz.graph.eachNode(function(elem) {
+                  var graphNode = graph.getNode(elem.id);   
+                  if(!graphNode) {
+                      elem.setData('alpha', 1);
+                      elem.setData('alpha', 1, 'start');
+                      elem.setData('alpha', 0, 'end');
+                      elem.ignore = true;
+                    } else {
+                      //Update node data information
+                      var graphNodeData = graphNode.data;
+                      for(var prop in graphNodeData) {
+                        if(nodeModes && ($.indexOf(nodeModes, prop) > -1)) {
+                          elem.endData[prop] = graphNodeData[prop];
+                        } else {
+                          elem.data[prop] = graphNodeData[prop];
+                        }
+                      }
+                    }
+                }); 
+                viz.graph.eachNode(function(elem) {
+                    if(elem.ignore) return;
+                    elem.eachAdjacency(function(adj) {
+                        if(adj.nodeFrom.ignore || adj.nodeTo.ignore) return;
+                        var nodeFrom = graph.getNode(adj.nodeFrom.id);
+                        var nodeTo = graph.getNode(adj.nodeTo.id);
+                        if(!nodeFrom.adjacentTo(nodeTo)) {
+                            var adj = viz.graph.getAdjacence(nodeFrom.id, nodeTo.id);
+                            fadeEdges = true;
+                            adj.setData('alpha', 1);
+                            adj.setData('alpha', 1, 'start');
+                            adj.setData('alpha', 0, 'end');
+                        }
+                    });
+                }); 
+                //preprocessing for adding nodes.
+                var fadeEdges = this.preprocessSum(graph);
+
+                var modes = !fadeEdges? ['node-property:alpha'] : 
+                                        ['node-property:alpha', 
+                                         'edge-property:alpha'];
+                //Append extra node-property animations (if any)
+                modes[0] = modes[0] + (('node-property' in extraModes)? 
+                    (':' + $.splat(extraModes['node-property']).join(':')) : '');
+                //Append extra edge-property animations (if any)
+                modes[1] = (modes[1] || 'edge-property:alpha') + (('edge-property' in extraModes)? 
+                    (':' + $.splat(extraModes['edge-property']).join(':')) : '');
+                //Add label-property animations (if any)
+                if('label-property' in extraModes) {
+                  modes.push('label-property:' + $.splat(extraModes['label-property']).join(':'))
+                }
+                //only use reposition if its implemented.
+                if (viz.reposition) {
+                  viz.reposition();
+                } else {
+                  viz.compute('end');
+                }
+                viz.graph.eachNode(function(elem) {
+                    if (elem.id != root && elem.pos.getp().equals(Polar.KER)) {
+                      elem.pos.set(elem.endPos); elem.startPos.set(elem.endPos);
+                    }
+                });
+                viz.fx.animate($.merge(options, {
+                    modes: [extraModes.position || 'polar'].concat(modes),
+                    onComplete: function() {
+                        viz.graph.eachNode(function(elem) {
+                            if(elem.ignore) viz.graph.removeNode(elem.id);
+                        });
+                        viz.graph.eachNode(function(elem) {
+                            elem.eachAdjacency(function(adj) {
+                                if(adj.ignore) viz.graph.removeAdjacence(adj.nodeFrom.id, adj.nodeTo.id);
+                            });
+                        });
+                        options.onComplete();
+                    }
+                }));
+                break;
+
+            default:;
+        }
+    },
+
+    
+  /*
+    Method: contract
+ 
+    Collapses the subtree of the given node. The node will have a _collapsed=true_ property.
+    
+    Parameters:
+ 
+    node - (object) A <Graph.Node>.
+    opt - (object) An object containing options described below
+    type - (string) Whether to 'replot' or 'animate' the contraction.
+   
+    There are also a number of Animation options. For more information see <Options.Fx>.
+
+    Example:
+    (start code js)
+     var viz = new $jit.Viz(options);
+     viz.op.contract(node, {
+       type: 'animate',
+       duration: 1000,
+       hideLabels: true,
+       transition: $jit.Trans.Quart.easeOut
+     });
+   (end code)
+ 
+   */
+    contract: function(node, opt) {
+      var viz = this.viz;
+      if(node.collapsed || !node.anySubnode($.lambda(true))) return;
+      opt = $.merge(this.options, viz.config, opt || {}, {
+        'modes': ['node-property:alpha:span', 'linear']
+      });
+      node.collapsed = true;
+      (function subn(n) {
+        n.eachSubnode(function(ch) {
+          ch.ignore = true;
+          ch.setData('alpha', 0, opt.type == 'animate'? 'end' : 'current');
+          subn(ch);
+        });
+      })(node);
+      if(opt.type == 'animate') {
+        viz.compute('end');
+        if(viz.rotated) {
+          viz.rotate(viz.rotated, 'none', {
+            'property':'end'
+          });
+        }
+        (function subn(n) {
+          n.eachSubnode(function(ch) {
+            ch.setPos(node.getPos('end'), 'end');
+            subn(ch);
+          });
+        })(node);
+        viz.fx.animate(opt);
+      } else if(opt.type == 'replot'){
+        viz.refresh();
+      }
+    },
+    
+    /*
+    Method: expand
+ 
+    Expands the previously contracted subtree. The given node must have the _collapsed=true_ property.
+    
+    Parameters:
+ 
+    node - (object) A <Graph.Node>.
+    opt - (object) An object containing options described below
+    type - (string) Whether to 'replot' or 'animate'.
+     
+    There are also a number of Animation options. For more information see <Options.Fx>.
+
+    Example:
+    (start code js)
+      var viz = new $jit.Viz(options);
+      viz.op.expand(node, {
+        type: 'animate',
+        duration: 1000,
+        hideLabels: true,
+        transition: $jit.Trans.Quart.easeOut
+      });
+    (end code)
+ 
+   */
+    expand: function(node, opt) {
+      if(!('collapsed' in node)) return;
+      var viz = this.viz;
+      opt = $.merge(this.options, viz.config, opt || {}, {
+        'modes': ['node-property:alpha:span', 'linear']
+      });
+      delete node.collapsed;
+      (function subn(n) {
+        n.eachSubnode(function(ch) {
+          delete ch.ignore;
+          ch.setData('alpha', 1, opt.type == 'animate'? 'end' : 'current');
+          subn(ch);
+        });
+      })(node);
+      if(opt.type == 'animate') {
+        viz.compute('end');
+        if(viz.rotated) {
+          viz.rotate(viz.rotated, 'none', {
+            'property':'end'
+          });
+        }
+        viz.fx.animate(opt);
+      } else if(opt.type == 'replot'){
+        viz.refresh();
+      }
+    },
+
+    preprocessSum: function(graph) {
+        var viz = this.viz;
+        graph.eachNode(function(elem) {
+            if(!viz.graph.hasNode(elem.id)) {
+                viz.graph.addNode(elem);
+                var n = viz.graph.getNode(elem.id);
+                n.setData('alpha', 0);
+                n.setData('alpha', 0, 'start');
+                n.setData('alpha', 1, 'end');
+            }
+        }); 
+        var fadeEdges = false;
+        graph.eachNode(function(elem) {
+            elem.eachAdjacency(function(adj) {
+                var nodeFrom = viz.graph.getNode(adj.nodeFrom.id);
+                var nodeTo = viz.graph.getNode(adj.nodeTo.id);
+                if(!nodeFrom.adjacentTo(nodeTo)) {
+                    var adj = viz.graph.addAdjacence(nodeFrom, nodeTo, adj.data);
+                    if(nodeFrom.startAlpha == nodeFrom.endAlpha 
+                    && nodeTo.startAlpha == nodeTo.endAlpha) {
+                        fadeEdges = true;
+                        adj.setData('alpha', 0);
+                        adj.setData('alpha', 0, 'start');
+                        adj.setData('alpha', 1, 'end');
+                    } 
+                }
+            });
+        }); 
+        return fadeEdges;
+    }
+};
+
+
+
+/*
+   File: Helpers.js
+ 
+   Helpers are objects that contain rendering primitives (like rectangles, ellipses, etc), for plotting nodes and edges.
+   Helpers also contain implementations of the *contains* method, a method returning a boolean indicating whether the mouse
+   position is over the rendered shape.
+   
+   Helpers are very useful when implementing new NodeTypes, since you can access them through *this.nodeHelper* and 
+   *this.edgeHelper* <Graph.Plot> properties, providing you with simple primitives and mouse-position check functions.
+   
+   Example:
+   (start code js)
+   //implement a new node type
+   $jit.Viz.Plot.NodeTypes.implement({
+     'customNodeType': {
+       'render': function(node, canvas) {
+         this.nodeHelper.circle.render ...
+       },
+       'contains': function(node, pos) {
+         this.nodeHelper.circle.contains ...
+       }
+     }
+   });
+   //implement an edge type
+   $jit.Viz.Plot.EdgeTypes.implement({
+     'customNodeType': {
+       'render': function(node, canvas) {
+         this.edgeHelper.circle.render ...
+       },
+       //optional
+       'contains': function(node, pos) {
+         this.edgeHelper.circle.contains ...
+       }
+     }
+   });
+   (end code)
+
+*/
+
+/*
+   Object: NodeHelper
+   
+   Contains rendering and other type of primitives for simple shapes.
+ */
+var NodeHelper = {
+  'none': {
+    'render': $.empty,
+    'contains': $.lambda(false)
+  },
+  /*
+   Object: NodeHelper.circle
+   */
+  'circle': {
+    /*
+     Method: render
+     
+     Renders a circle into the canvas.
+     
+     Parameters:
+     
+     type - (string) Possible options are 'fill' or 'stroke'.
+     pos - (object) An *x*, *y* object with the position of the center of the circle.
+     radius - (number) The radius of the circle to be rendered.
+     canvas - (object) A <Canvas> instance.
+     
+     Example:
+     (start code js)
+     NodeHelper.circle.render('fill', { x: 10, y: 30 }, 30, viz.canvas);
+     (end code)
+     */
+    'render': function(type, pos, radius, canvas){
+      var ctx = canvas.getCtx();
+      ctx.beginPath();
+      ctx.arc(pos.x, pos.y, radius, 0, Math.PI * 2, true);
+      ctx.closePath();
+      ctx[type]();
+    },
+    /*
+    Method: contains
+    
+    Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
+    
+    Parameters:
+    
+    npos - (object) An *x*, *y* object with the <Graph.Node> position.
+    pos - (object) An *x*, *y* object with the position to check.
+    radius - (number) The radius of the rendered circle.
+    
+    Example:
+    (start code js)
+    NodeHelper.circle.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, 30); //true
+    (end code)
+    */
+    'contains': function(npos, pos, radius){
+      var diffx = npos.x - pos.x, 
+          diffy = npos.y - pos.y, 
+          diff = diffx * diffx + diffy * diffy;
+      return diff <= radius * radius;
+    }
+  },
+  /*
+  Object: NodeHelper.ellipse
+  */
+  'ellipse': {
+    /*
+    Method: render
+    
+    Renders an ellipse into the canvas.
+    
+    Parameters:
+    
+    type - (string) Possible options are 'fill' or 'stroke'.
+    pos - (object) An *x*, *y* object with the position of the center of the ellipse.
+    width - (number) The width of the ellipse.
+    height - (number) The height of the ellipse.
+    canvas - (object) A <Canvas> instance.
+    
+    Example:
+    (start code js)
+    NodeHelper.ellipse.render('fill', { x: 10, y: 30 }, 30, 40, viz.canvas);
+    (end code)
+    */
+    'render': function(type, pos, width, height, canvas){
+      var ctx = canvas.getCtx(),
+          scalex = 1,
+          scaley = 1,
+          scaleposx = 1,
+          scaleposy = 1,
+          radius = 0;
+
+      if (width > height) {
+          radius = width / 2;
+          scaley = height / width;
+          scaleposy = width / height;
+      } else {
+          radius = height / 2;
+          scalex = width / height;
+          scaleposx = height / width;
+      }
+
+      ctx.save();
+      ctx.scale(scalex, scaley);
+      ctx.beginPath();
+      ctx.arc(pos.x * scaleposx, pos.y * scaleposy, radius, 0, Math.PI * 2, true);
+      ctx.closePath();
+      ctx[type]();
+      ctx.restore();
+    },
+    /*
+    Method: contains
+    
+    Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
+    
+    Parameters:
+    
+    npos - (object) An *x*, *y* object with the <Graph.Node> position.
+    pos - (object) An *x*, *y* object with the position to check.
+    width - (number) The width of the rendered ellipse.
+    height - (number) The height of the rendered ellipse.
+    
+    Example:
+    (start code js)
+    NodeHelper.ellipse.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, 30, 40);
+    (end code)
+    */
+    'contains': function(npos, pos, width, height){
+      var radius = 0,
+          scalex = 1,
+          scaley = 1,
+          diffx = 0,
+          diffy = 0,
+          diff = 0;
+
+      if (width > height) {
+	      radius = width / 2;
+	      scaley = height / width;
+      } else {
+          radius = height / 2;
+          scalex = width / height;
+      }
+
+      diffx = (npos.x - pos.x) * (1 / scalex);
+      diffy = (npos.y - pos.y) * (1 / scaley);
+      diff = diffx * diffx + diffy * diffy;
+      return diff <= radius * radius;
+    }
+  },
+  /*
+  Object: NodeHelper.square
+  */
+  'square': {
+    /*
+    Method: render
+    
+    Renders a square into the canvas.
+    
+    Parameters:
+    
+    type - (string) Possible options are 'fill' or 'stroke'.
+    pos - (object) An *x*, *y* object with the position of the center of the square.
+    dim - (number) The radius (or half-diameter) of the square.
+    canvas - (object) A <Canvas> instance.
+    
+    Example:
+    (start code js)
+    NodeHelper.square.render('stroke', { x: 10, y: 30 }, 40, viz.canvas);
+    (end code)
+    */
+    'render': function(type, pos, dim, canvas){
+      canvas.getCtx()[type + "Rect"](pos.x - dim, pos.y - dim, 2*dim, 2*dim);
+    },
+    /*
+    Method: contains
+    
+    Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
+    
+    Parameters:
+    
+    npos - (object) An *x*, *y* object with the <Graph.Node> position.
+    pos - (object) An *x*, *y* object with the position to check.
+    dim - (number) The radius (or half-diameter) of the square.
+    
+    Example:
+    (start code js)
+    NodeHelper.square.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, 30);
+    (end code)
+    */
+    'contains': function(npos, pos, dim){
+      return Math.abs(pos.x - npos.x) <= dim && Math.abs(pos.y - npos.y) <= dim;
+    }
+  },
+  /*
+  Object: NodeHelper.rectangle
+  */
+  'rectangle': {
+    /*
+    Method: render
+    
+    Renders a rectangle into the canvas.
+    
+    Parameters:
+    
+    type - (string) Possible options are 'fill' or 'stroke'.
+    pos - (object) An *x*, *y* object with the position of the center of the rectangle.
+    width - (number) The width of the rectangle.
+    height - (number) The height of the rectangle.
+    canvas - (object) A <Canvas> instance.
+    
+    Example:
+    (start code js)
+    NodeHelper.rectangle.render('fill', { x: 10, y: 30 }, 30, 40, viz.canvas);
+    (end code)
+    */
+    'render': function(type, pos, width, height, canvas){
+      canvas.getCtx()[type + "Rect"](pos.x - width / 2, pos.y - height / 2, 
+                                      width, height);
+    },
+    /*
+    Method: contains
+    
+    Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
+    
+    Parameters:
+    
+    npos - (object) An *x*, *y* object with the <Graph.Node> position.
+    pos - (object) An *x*, *y* object with the position to check.
+    width - (number) The width of the rendered rectangle.
+    height - (number) The height of the rendered rectangle.
+    
+    Example:
+    (start code js)
+    NodeHelper.rectangle.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, 30, 40);
+    (end code)
+    */
+    'contains': function(npos, pos, width, height){
+      return Math.abs(pos.x - npos.x) <= width / 2
+          && Math.abs(pos.y - npos.y) <= height / 2;
+    }
+  },
+  /*
+  Object: NodeHelper.triangle
+  */
+  'triangle': {
+    /*
+    Method: render
+    
+    Renders a triangle into the canvas.
+    
+    Parameters:
+    
+    type - (string) Possible options are 'fill' or 'stroke'.
+    pos - (object) An *x*, *y* object with the position of the center of the triangle.
+    dim - (number) Half the base and half the height of the triangle.
+    canvas - (object) A <Canvas> instance.
+    
+    Example:
+    (start code js)
+    NodeHelper.triangle.render('stroke', { x: 10, y: 30 }, 40, viz.canvas);
+    (end code)
+    */
+    'render': function(type, pos, dim, canvas){
+      var ctx = canvas.getCtx(), 
+          c1x = pos.x, 
+          c1y = pos.y - dim, 
+          c2x = c1x - dim, 
+          c2y = pos.y + dim, 
+          c3x = c1x + dim, 
+          c3y = c2y;
+      ctx.beginPath();
+      ctx.moveTo(c1x, c1y);
+      ctx.lineTo(c2x, c2y);
+      ctx.lineTo(c3x, c3y);
+      ctx.closePath();
+      ctx[type]();
+    },
+    /*
+    Method: contains
+    
+    Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
+    
+    Parameters:
+    
+    npos - (object) An *x*, *y* object with the <Graph.Node> position.
+    pos - (object) An *x*, *y* object with the position to check.
+    dim - (number) Half the base and half the height of the triangle.
+    
+    Example:
+    (start code js)
+    NodeHelper.triangle.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, 30);
+    (end code)
+    */
+    'contains': function(npos, pos, dim) {
+      return NodeHelper.circle.contains(npos, pos, dim);
+    }
+  },
+  /*
+  Object: NodeHelper.star
+  */
+  'star': {
+    /*
+    Method: render
+    
+    Renders a star (concave decagon) into the canvas.
+    
+    Parameters:
+    
+    type - (string) Possible options are 'fill' or 'stroke'.
+    pos - (object) An *x*, *y* object with the position of the center of the star.
+    dim - (number) The length of a side of a concave decagon.
+    canvas - (object) A <Canvas> instance.
+    
+    Example:
+    (start code js)
+    NodeHelper.star.render('stroke', { x: 10, y: 30 }, 40, viz.canvas);
+    (end code)
+    */
+    'render': function(type, pos, dim, canvas){
+      var ctx = canvas.getCtx(), 
+          pi5 = Math.PI / 5;
+      ctx.save();
+      ctx.translate(pos.x, pos.y);
+      ctx.beginPath();
+      ctx.moveTo(dim, 0);
+      for (var i = 0; i < 9; i++) {
+        ctx.rotate(pi5);
+        if (i % 2 == 0) {
+          ctx.lineTo((dim / 0.525731) * 0.200811, 0);
+        } else {
+          ctx.lineTo(dim, 0);
+        }
+      }
+      ctx.closePath();
+      ctx[type]();
+      ctx.restore();
+    },
+    /*
+    Method: contains
+    
+    Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
+    
+    Parameters:
+    
+    npos - (object) An *x*, *y* object with the <Graph.Node> position.
+    pos - (object) An *x*, *y* object with the position to check.
+    dim - (number) The length of a side of a concave decagon.
+    
+    Example:
+    (start code js)
+    NodeHelper.star.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, 30);
+    (end code)
+    */
+    'contains': function(npos, pos, dim) {
+      return NodeHelper.circle.contains(npos, pos, dim);
+    }
+  }
+};
+
+/*
+  Object: EdgeHelper
+  
+  Contains rendering primitives for simple edge shapes.
+*/
+var EdgeHelper = {
+  /*
+    Object: EdgeHelper.line
+  */
+  'line': {
+      /*
+      Method: render
+      
+      Renders a line into the canvas.
+      
+      Parameters:
+      
+      from - (object) An *x*, *y* object with the starting position of the line.
+      to - (object) An *x*, *y* object with the ending position of the line.
+      canvas - (object) A <Canvas> instance.
+      
+      Example:
+      (start code js)
+      EdgeHelper.line.render({ x: 10, y: 30 }, { x: 10, y: 50 }, viz.canvas);
+      (end code)
+      */
+      'render': function(from, to, canvas){
+        var ctx = canvas.getCtx();
+        ctx.beginPath();
+        ctx.moveTo(from.x, from.y);
+        ctx.lineTo(to.x, to.y);
+        ctx.stroke();
+      },
+      /*
+      Method: contains
+      
+      Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
+      
+      Parameters:
+      
+      posFrom - (object) An *x*, *y* object with a <Graph.Node> position.
+      posTo - (object) An *x*, *y* object with a <Graph.Node> position.
+      pos - (object) An *x*, *y* object with the position to check.
+      epsilon - (number) The dimension of the shape.
+      
+      Example:
+      (start code js)
+      EdgeHelper.line.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, { x: 15, y: 35 }, 30);
+      (end code)
+      */
+      'contains': function(posFrom, posTo, pos, epsilon) {
+        var min = Math.min, 
+            max = Math.max,
+            minPosX = min(posFrom.x, posTo.x),
+            maxPosX = max(posFrom.x, posTo.x),
+            minPosY = min(posFrom.y, posTo.y),
+            maxPosY = max(posFrom.y, posTo.y);
+        
+        if(pos.x >= minPosX && pos.x <= maxPosX 
+            && pos.y >= minPosY && pos.y <= maxPosY) {
+          if(Math.abs(posTo.x - posFrom.x) <= epsilon) {
+            return true;
+          }
+          var dist = (posTo.y - posFrom.y) / (posTo.x - posFrom.x) * (pos.x - posFrom.x) + posFrom.y;
+          return Math.abs(dist - pos.y) <= epsilon;
+        }
+        return false;
+      }
+    },
+  /*
+    Object: EdgeHelper.arrow
+  */
+  'arrow': {
+      /*
+      Method: render
+      
+      Renders an arrow into the canvas.
+      
+      Parameters:
+      
+      from - (object) An *x*, *y* object with the starting position of the arrow.
+      to - (object) An *x*, *y* object with the ending position of the arrow.
+      dim - (number) The dimension of the arrow.
+      swap - (boolean) Whether to set the arrow pointing to the starting position or the ending position.
+      canvas - (object) A <Canvas> instance.
+      
+      Example:
+      (start code js)
+      EdgeHelper.arrow.render({ x: 10, y: 30 }, { x: 10, y: 50 }, 13, false, viz.canvas);
+      (end code)
+      */
+    'render': function(from, to, dim, swap, canvas){
+        var ctx = canvas.getCtx();
+        // invert edge direction
+        if (swap) {
+          var tmp = from;
+          from = to;
+          to = tmp;
+        }
+        var vect = new Complex(to.x - from.x, to.y - from.y);
+        vect.$scale(dim / vect.norm());
+        var intermediatePoint = new Complex(to.x - vect.x, to.y - vect.y),
+            normal = new Complex(-vect.y / 2, vect.x / 2),
+            v1 = intermediatePoint.add(normal), 
+            v2 = intermediatePoint.$add(normal.$scale(-1));
+        
+        ctx.beginPath();
+        ctx.moveTo(from.x, from.y);
+        ctx.lineTo(to.x, to.y);
+        ctx.stroke();
+        ctx.beginPath();
+        ctx.moveTo(v1.x, v1.y);
+        ctx.lineTo(v2.x, v2.y);
+        ctx.lineTo(to.x, to.y);
+        ctx.closePath();
+        ctx.fill();
+    },
+    /*
+    Method: contains
+    
+    Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
+    
+    Parameters:
+    
+    posFrom - (object) An *x*, *y* object with a <Graph.Node> position.
+    posTo - (object) An *x*, *y* object with a <Graph.Node> position.
+    pos - (object) An *x*, *y* object with the position to check.
+    epsilon - (number) The dimension of the shape.
+    
+    Example:
+    (start code js)
+    EdgeHelper.arrow.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, { x: 15, y: 35 }, 30);
+    (end code)
+    */
+    'contains': function(posFrom, posTo, pos, epsilon) {
+      return EdgeHelper.line.contains(posFrom, posTo, pos, epsilon);
+    }
+  },
+  /*
+    Object: EdgeHelper.hyperline
+  */
+  'hyperline': {
+    /*
+    Method: render
+    
+    Renders a hyperline into the canvas. A hyperline are the lines drawn for the <Hypertree> visualization.
+    
+    Parameters:
+    
+    from - (object) An *x*, *y* object with the starting position of the hyperline. *x* and *y* must belong to [0, 1).
+    to - (object) An *x*, *y* object with the ending position of the hyperline. *x* and *y* must belong to [0, 1).
+    r - (number) The scaling factor.
+    canvas - (object) A <Canvas> instance.
+    
+    Example:
+    (start code js)
+    EdgeHelper.hyperline.render({ x: 10, y: 30 }, { x: 10, y: 50 }, 100, viz.canvas);
+    (end code)
+    */
+    'render': function(from, to, r, canvas){
+      var ctx = canvas.getCtx();  
+      var centerOfCircle = computeArcThroughTwoPoints(from, to);
+      if (centerOfCircle.a > 1000 || centerOfCircle.b > 1000
+          || centerOfCircle.ratio < 0) {
+        ctx.beginPath();
+        ctx.moveTo(from.x * r, from.y * r);
+        ctx.lineTo(to.x * r, to.y * r);
+        ctx.stroke();
+      } else {
+        var angleBegin = Math.atan2(to.y - centerOfCircle.y, to.x
+            - centerOfCircle.x);
+        var angleEnd = Math.atan2(from.y - centerOfCircle.y, from.x
+            - centerOfCircle.x);
+        var sense = sense(angleBegin, angleEnd);
+        ctx.beginPath();
+        ctx.arc(centerOfCircle.x * r, centerOfCircle.y * r, centerOfCircle.ratio
+            * r, angleBegin, angleEnd, sense);
+        ctx.stroke();
+      }
+      /*      
+        Calculates the arc parameters through two points.
+        
+        More information in <http://en.wikipedia.org/wiki/Poincar%C3%A9_disc_model#Analytic_geometry_constructions_in_the_hyperbolic_plane> 
+      
+        Parameters:
+      
+        p1 - A <Complex> instance.
+        p2 - A <Complex> instance.
+        scale - The Disk's diameter.
+      
+        Returns:
+      
+        An object containing some arc properties.
+      */
+      function computeArcThroughTwoPoints(p1, p2){
+        var aDen = (p1.x * p2.y - p1.y * p2.x), bDen = aDen;
+        var sq1 = p1.squaredNorm(), sq2 = p2.squaredNorm();
+        // Fall back to a straight line
+        if (aDen == 0)
+          return {
+            x: 0,
+            y: 0,
+            ratio: -1
+          };
+    
+        var a = (p1.y * sq2 - p2.y * sq1 + p1.y - p2.y) / aDen;
+        var b = (p2.x * sq1 - p1.x * sq2 + p2.x - p1.x) / bDen;
+        var x = -a / 2;
+        var y = -b / 2;
+        var squaredRatio = (a * a + b * b) / 4 - 1;
+        // Fall back to a straight line
+        if (squaredRatio < 0)
+          return {
+            x: 0,
+            y: 0,
+            ratio: -1
+          };
+        var ratio = Math.sqrt(squaredRatio);
+        var out = {
+          x: x,
+          y: y,
+          ratio: ratio > 1000? -1 : ratio,
+          a: a,
+          b: b
+        };
+    
+        return out;
+      }
+      /*      
+        Sets angle direction to clockwise (true) or counterclockwise (false). 
+         
+        Parameters: 
+      
+           angleBegin - Starting angle for drawing the arc. 
+           angleEnd - The HyperLine will be drawn from angleBegin to angleEnd. 
+      
+        Returns: 
+      
+           A Boolean instance describing the sense for drawing the HyperLine. 
+      */
+      function sense(angleBegin, angleEnd){
+        return (angleBegin < angleEnd)? ((angleBegin + Math.PI > angleEnd)? false
+            : true) : ((angleEnd + Math.PI > angleBegin)? true : false);
+      }
+    },
+    /*
+    Method: contains
+    
+    Not Implemented
+    
+    Returns *true* if *pos* is contained in the area of the shape. Returns *false* otherwise.
+    
+    Parameters:
+    
+    posFrom - (object) An *x*, *y* object with a <Graph.Node> position.
+    posTo - (object) An *x*, *y* object with a <Graph.Node> position.
+    pos - (object) An *x*, *y* object with the position to check.
+    epsilon - (number) The dimension of the shape.
+    
+    Example:
+    (start code js)
+    EdgeHelper.hyperline.contains({ x: 10, y: 30 }, { x: 15, y: 35 }, { x: 15, y: 35 }, 30);
+    (end code)
+    */
+    'contains': $.lambda(false)
+  }
+};
+
+
+/*
+ * File: Graph.Plot.js
+ */
+
+/*
+   Object: Graph.Plot
+
+   <Graph> rendering and animation methods.
+   
+   Properties:
+   
+   nodeHelper - <NodeHelper> object.
+   edgeHelper - <EdgeHelper> object.
+*/
+Graph.Plot = {
+    //Default initializer
+    initialize: function(viz, klass){
+      this.viz = viz;
+      this.config = viz.config;
+      this.node = viz.config.Node;
+      this.edge = viz.config.Edge;
+      this.animation = new Animation;
+      this.nodeTypes = new klass.Plot.NodeTypes;
+      this.edgeTypes = new klass.Plot.EdgeTypes;
+      this.labels = viz.labels;
+   },
+
+    //Add helpers
+    nodeHelper: NodeHelper,
+    edgeHelper: EdgeHelper,
+    
+    Interpolator: {
+        //node/edge property parsers
+        'map': {
+          'border': 'color',
+          'color': 'color',
+          'width': 'number',
+          'height': 'number',
+          'dim': 'number',
+          'alpha': 'number',
+          'lineWidth': 'number',
+          'angularWidth':'number',
+          'span':'number',
+          'valueArray':'array-number',
+          'dimArray':'array-number'
+          //'colorArray':'array-color'
+        },
+        
+        //canvas specific parsers
+        'canvas': {
+          'globalAlpha': 'number',
+          'fillStyle': 'color',
+          'strokeStyle': 'color',
+          'lineWidth': 'number',
+          'shadowBlur': 'number',
+          'shadowColor': 'color',
+          'shadowOffsetX': 'number',
+          'shadowOffsetY': 'number',
+          'miterLimit': 'number'
+        },
+  
+        //label parsers
+        'label': {
+          'size': 'number',
+          'color': 'color'
+        },
+  
+        //Number interpolator
+        'compute': function(from, to, delta) {
+          return from + (to - from) * delta;
+        },
+        
+        //Position interpolators
+        'moebius': function(elem, props, delta, vector) {
+          var v = vector.scale(-delta);  
+          if(v.norm() < 1) {
+              var x = v.x, y = v.y;
+              var ans = elem.startPos
+                .getc().moebiusTransformation(v);
+              elem.pos.setc(ans.x, ans.y);
+              v.x = x; v.y = y;
+            }           
+        },
+
+        'linear': function(elem, props, delta) {
+            var from = elem.startPos.getc(true);
+            var to = elem.endPos.getc(true);
+            elem.pos.setc(this.compute(from.x, to.x, delta), 
+                          this.compute(from.y, to.y, delta));
+        },
+
+        'polar': function(elem, props, delta) {
+          var from = elem.startPos.getp(true);
+          var to = elem.endPos.getp();
+          var ans = to.interpolate(from, delta);
+          elem.pos.setp(ans.theta, ans.rho);
+        },
+        
+        //Graph's Node/Edge interpolators
+        'number': function(elem, prop, delta, getter, setter) {
+          var from = elem[getter](prop, 'start');
+          var to = elem[getter](prop, 'end');
+          elem[setter](prop, this.compute(from, to, delta));
+        },
+
+        'color': function(elem, prop, delta, getter, setter) {
+          var from = $.hexToRgb(elem[getter](prop, 'start'));
+          var to = $.hexToRgb(elem[getter](prop, 'end'));
+          var comp = this.compute;
+          var val = $.rgbToHex([parseInt(comp(from[0], to[0], delta)),
+                                parseInt(comp(from[1], to[1], delta)),
+                                parseInt(comp(from[2], to[2], delta))]);
+          
+          elem[setter](prop, val);
+        },
+        
+        'array-number': function(elem, prop, delta, getter, setter) {
+          var from = elem[getter](prop, 'start'),
+              to = elem[getter](prop, 'end'),
+              cur = [];
+          for(var i=0, l=from.length; i<l; i++) {
+            var fromi = from[i], toi = to[i];
+            if(fromi.length) {
+              for(var j=0, len=fromi.length, curi=[]; j<len; j++) {
+                curi.push(this.compute(fromi[j], toi[j], delta));
+              }
+              cur.push(curi);
+            } else {
+              cur.push(this.compute(fromi, toi, delta));
+            }
+          }
+          elem[setter](prop, cur);
+        },
+        
+        'node': function(elem, props, delta, map, getter, setter) {
+          map = this[map];
+          if(props) {
+            var len = props.length;
+            for(var i=0; i<len; i++) {
+              var pi = props[i];
+              this[map[pi]](elem, pi, delta, getter, setter);
+            }
+          } else {
+            for(var pi in map) {
+              this[map[pi]](elem, pi, delta, getter, setter);
+            }
+          }
+        },
+        
+        'edge': function(elem, props, delta, mapKey, getter, setter) {
+            var adjs = elem.adjacencies;
+            for(var id in adjs) this['node'](adjs[id], props, delta, mapKey, getter, setter);
+        },
+        
+        'node-property': function(elem, props, delta) {
+          this['node'](elem, props, delta, 'map', 'getData', 'setData');
+        },
+        
+        'edge-property': function(elem, props, delta) {
+          this['edge'](elem, props, delta, 'map', 'getData', 'setData');  
+        },
+
+        'label-property': function(elem, props, delta) {
+          this['node'](elem, props, delta, 'label', 'getLabelData', 'setLabelData');
+        },
+        
+        'node-style': function(elem, props, delta) {
+          this['node'](elem, props, delta, 'canvas', 'getCanvasStyle', 'setCanvasStyle');
+        },
+        
+        'edge-style': function(elem, props, delta) {
+          this['edge'](elem, props, delta, 'canvas', 'getCanvasStyle', 'setCanvasStyle');  
+        }
+    },
+    
+  
+    /*
+       sequence
+    
+       Iteratively performs an action while refreshing the state of the visualization.
+
+       Parameters:
+
+       options - (object) An object containing some sequence options described below
+       condition - (function) A function returning a boolean instance in order to stop iterations.
+       step - (function) A function to execute on each step of the iteration.
+       onComplete - (function) A function to execute when the sequence finishes.
+       duration - (number) Duration (in milliseconds) of each step.
+
+      Example:
+       (start code js)
+        var rg = new $jit.RGraph(options);
+        var i = 0;
+        rg.fx.sequence({
+          condition: function() {
+           return i == 10;
+          },
+          step: function() {
+            alert(i++);
+          },
+          onComplete: function() {
+           alert('done!');
+          }
+        });
+       (end code)
+
+    */
+    sequence: function(options) {
+        var that = this;
+        options = $.merge({
+          condition: $.lambda(false),
+          step: $.empty,
+          onComplete: $.empty,
+          duration: 200
+        }, options || {});
+
+        var interval = setInterval(function() {
+          if(options.condition()) {
+            options.step();
+          } else {
+            clearInterval(interval);
+            options.onComplete();
+          }
+          that.viz.refresh(true);
+        }, options.duration);
+    },
+    
+    /*
+      prepare
+ 
+      Prepare graph position and other attribute values before performing an Animation. 
+      This method is used internally by the Toolkit.
+      
+      See also:
+       
+       <Animation>, <Graph.Plot.animate>
+
+    */
+    prepare: function(modes) {
+      var graph = this.viz.graph,
+          accessors = {
+            'node-property': {
+              'getter': 'getData',
+              'setter': 'setData'
+            },
+            'edge-property': {
+              'getter': 'getData',
+              'setter': 'setData'
+            },
+            'node-style': {
+              'getter': 'getCanvasStyle',
+              'setter': 'setCanvasStyle'
+            },
+            'edge-style': {
+              'getter': 'getCanvasStyle',
+              'setter': 'setCanvasStyle'
+            }
+          };
+
+      //parse modes
+      var m = {};
+      if($.type(modes) == 'array') {
+        for(var i=0, len=modes.length; i < len; i++) {
+          var elems = modes[i].split(':');
+          m[elems.shift()] = elems;
+        }
+      } else {
+        for(var p in modes) {
+          if(p == 'position') {
+            m[modes.position] = [];
+          } else {
+            m[p] = $.splat(modes[p]);
+          }
+        }
+      }
+      
+      graph.eachNode(function(node) { 
+        node.startPos.set(node.pos);
+        $.each(['node-property', 'node-style'], function(p) {
+          if(p in m) {
+            var prop = m[p];
+            for(var i=0, l=prop.length; i < l; i++) {
+              node[accessors[p].setter](prop[i], node[accessors[p].getter](prop[i]), 'start');
+            }
+          }
+        });
+        $.each(['edge-property', 'edge-style'], function(p) {
+          if(p in m) {
+            var prop = m[p];
+            node.eachAdjacency(function(adj) {
+              for(var i=0, l=prop.length; i < l; i++) {
+                adj[accessors[p].setter](prop[i], adj[accessors[p].getter](prop[i]), 'start');
+              }
+            });
+          }
+        });
+      });
+      return m;
+    },
+    
+    /*
+       Method: animate
+    
+       Animates a <Graph> by interpolating some <Graph.Node>, <Graph.Adjacence> or <Graph.Label> properties.
+
+       Parameters:
+
+       opt - (object) Animation options. The object properties are described below
+       duration - (optional) Described in <Options.Fx>.
+       fps - (optional) Described in <Options.Fx>.
+       hideLabels - (optional|boolean) Whether to hide labels during the animation.
+       modes - (required|object) An object with animation modes (described below).
+
+       Animation modes:
+       
+       Animation modes are strings representing different node/edge and graph properties that you'd like to animate. 
+       They are represented by an object that has as keys main categories of properties to animate and as values a list 
+       of these specific properties. The properties are described below
+       
+       position - Describes the way nodes' positions must be interpolated. Possible values are 'linear', 'polar' or 'moebius'.
+       node-property - Describes which Node properties will be interpolated. These properties can be any of the ones defined in <Options.Node>.
+       edge-property - Describes which Edge properties will be interpolated. These properties can be any the ones defined in <Options.Edge>.
+       label-property - Describes which Label properties will be interpolated. These properties can be any of the ones defined in <Options.Label> like color or size.
+       node-style - Describes which Node Canvas Styles will be interpolated. These are specific canvas properties like fillStyle, strokeStyle, lineWidth, shadowBlur, shadowColor, shadowOffsetX, shadowOffsetY, etc.
+       edge-style - Describes which Edge Canvas Styles will be interpolated. These are specific canvas properties like fillStyle, strokeStyle, lineWidth, shadowBlur, shadowColor, shadowOffsetX, shadowOffsetY, etc.
+
+       Example:
+       (start code js)
+       var viz = new $jit.Viz(options);
+       //...tweak some Data, CanvasStyles or LabelData properties...
+       viz.fx.animate({
+         modes: {
+           'position': 'linear',
+           'node-property': ['width', 'height'],
+           'node-style': 'shadowColor',
+           'label-property': 'size'
+         },
+         hideLabels: false
+       });
+       //...can also be written like this...
+       viz.fx.animate({
+         modes: ['linear',
+                 'node-property:width:height',
+                 'node-style:shadowColor',
+                 'label-property:size'],
+         hideLabels: false
+       });
+       (end code)
+    */
+    animate: function(opt, versor) {
+      opt = $.merge(this.viz.config, opt || {});
+      var that = this,
+          viz = this.viz,
+          graph  = viz.graph,
+          interp = this.Interpolator,
+          animation =  opt.type === 'nodefx'? this.nodeFxAnimation : this.animation;
+      //prepare graph values
+      var m = this.prepare(opt.modes);
+      
+      //animate
+      if(opt.hideLabels) this.labels.hideLabels(true);
+      animation.setOptions($.extend(opt, {
+        $animating: false,
+        compute: function(delta) {
+          graph.eachNode(function(node) { 
+            for(var p in m) {
+              interp[p](node, m[p], delta, versor);
+            }
+          });
+          that.plot(opt, this.$animating, delta);
+          this.$animating = true;
+        },
+        complete: function() {
+          if(opt.hideLabels) that.labels.hideLabels(false);
+          that.plot(opt);
+          opt.onComplete();
+          //TODO(nico): This shouldn't be here!
+          //opt.onAfterCompute();
+        }       
+      })).start();
+    },
+    
+    /*
+      nodeFx
+   
+      Apply animation to node properties like color, width, height, dim, etc.
+  
+      Parameters:
+  
+      options - Animation options. This object properties is described below
+      elements - The Elements to be transformed. This is an object that has a properties
+      
+      (start code js)
+      'elements': {
+        //can also be an array of ids
+        'id': 'id-of-node-to-transform',
+        //properties to be modified. All properties are optional.
+        'properties': {
+          'color': '#ccc', //some color
+          'width': 10, //some width
+          'height': 10, //some height
+          'dim': 20, //some dim
+          'lineWidth': 10 //some line width
+        } 
+      }
+      (end code)
+      
+      - _reposition_ Whether to recalculate positions and add a motion animation. 
+      This might be used when changing _width_ or _height_ properties in a <Layouts.Tree> like layout. Default's *false*.
+      
+      - _onComplete_ A method that is called when the animation completes.
+      
+      ...and all other <Graph.Plot.animate> options like _duration_, _fps_, _transition_, etc.
+  
+      Example:
+      (start code js)
+       var rg = new RGraph(canvas, config); //can be also Hypertree or ST
+       rg.fx.nodeFx({
+         'elements': {
+           'id':'mynodeid',
+           'properties': {
+             'color':'#ccf'
+           },
+           'transition': Trans.Quart.easeOut
+         }
+       });
+      (end code)    
+   */
+   nodeFx: function(opt) {
+     var viz = this.viz,
+         graph  = viz.graph,
+         animation = this.nodeFxAnimation,
+         options = $.merge(this.viz.config, {
+           'elements': {
+             'id': false,
+             'properties': {}
+           },
+           'reposition': false
+         });
+     opt = $.merge(options, opt || {}, {
+       onBeforeCompute: $.empty,
+       onAfterCompute: $.empty
+     });
+     //check if an animation is running
+     animation.stopTimer();
+     var props = opt.elements.properties;
+     //set end values for nodes
+     if(!opt.elements.id) {
+       graph.eachNode(function(n) {
+         for(var prop in props) {
+           n.setData(prop, props[prop], 'end');
+         }
+       });
+     } else {
+       var ids = $.splat(opt.elements.id);
+       $.each(ids, function(id) {
+         var n = graph.getNode(id);
+         if(n) {
+           for(var prop in props) {
+             n.setData(prop, props[prop], 'end');
+           }
+         }
+       });
+     }
+     //get keys
+     var propnames = [];
+     for(var prop in props) propnames.push(prop);
+     //add node properties modes
+     var modes = ['node-property:' + propnames.join(':')];
+     //set new node positions
+     if(opt.reposition) {
+       modes.push('linear');
+       viz.compute('end');
+     }
+     //animate
+     this.animate($.merge(opt, {
+       modes: modes,
+       type: 'nodefx'
+     }));
+   },
+
+    
+    /*
+       Method: plot
+    
+       Plots a <Graph>.
+
+       Parameters:
+
+       opt - (optional) Plotting options. Most of them are described in <Options.Fx>.
+
+       Example:
+
+       (start code js)
+       var viz = new $jit.Viz(options);
+       viz.fx.plot(); 
+       (end code)
+
+    */
+   plot: function(opt, animating) {
+     var viz = this.viz, 
+         aGraph = viz.graph, 
+         canvas = viz.canvas, 
+         id = viz.root, 
+         that = this, 
+         ctx = canvas.getCtx(), 
+         min = Math.min,
+         opt = opt || this.viz.controller;
+     
+     opt.clearCanvas && canvas.clear();
+       
+     var root = aGraph.getNode(id);
+     if(!root) return;
+     
+     var T = !!root.visited;
+     aGraph.eachNode(function(node) {
+       var nodeAlpha = node.getData('alpha');
+       node.eachAdjacency(function(adj) {
+         var nodeTo = adj.nodeTo;
+         if(!!nodeTo.visited === T && node.drawn && nodeTo.drawn) {
+           !animating && opt.onBeforePlotLine(adj);
+           that.plotLine(adj, canvas, animating);
+           !animating && opt.onAfterPlotLine(adj);
+         }
+       });
+       if(node.drawn) {
+         !animating && opt.onBeforePlotNode(node);
+         that.plotNode(node, canvas, animating);
+         !animating && opt.onAfterPlotNode(node);
+       }
+       if(!that.labelsHidden && opt.withLabels) {
+         if(node.drawn && nodeAlpha >= 0.95) {
+           that.labels.plotLabel(canvas, node, opt);
+         } else {
+           that.labels.hideLabel(node, false);
+         }
+       }
+       node.visited = !T;
+     });
+    },
+
+  /*
+      Plots a Subtree.
+   */
+   plotTree: function(node, opt, animating) {
+       var that = this, 
+       viz = this.viz, 
+       canvas = viz.canvas,
+       config = this.config,
+       ctx = canvas.getCtx();
+       var nodeAlpha = node.getData('alpha');
+       node.eachSubnode(function(elem) {
+         if(opt.plotSubtree(node, elem) && elem.exist && elem.drawn) {
+             var adj = node.getAdjacency(elem.id);
+             !animating && opt.onBeforePlotLine(adj);
+             that.plotLine(adj, canvas, animating);
+             !animating && opt.onAfterPlotLine(adj);
+             that.plotTree(elem, opt, animating);
+         }
+       });
+       if(node.drawn) {
+           !animating && opt.onBeforePlotNode(node);
+           this.plotNode(node, canvas, animating);
+           !animating && opt.onAfterPlotNode(node);
+           if(!opt.hideLabels && opt.withLabels && nodeAlpha >= 0.95) 
+               this.labels.plotLabel(canvas, node, opt);
+           else 
+               this.labels.hideLabel(node, false);
+       } else {
+           this.labels.hideLabel(node, true);
+       }
+   },
+
+  /*
+       Method: plotNode
+    
+       Plots a <Graph.Node>.
+
+       Parameters:
+       
+       node - (object) A <Graph.Node>.
+       canvas - (object) A <Canvas> element.
+
+    */
+    plotNode: function(node, canvas, animating) {
+        var f = node.getData('type'), 
+            ctxObj = this.node.CanvasStyles;
+        if(f != 'none') {
+          var width = node.getData('lineWidth'),
+              color = node.getData('color'),
+              alpha = node.getData('alpha'),
+              ctx = canvas.getCtx();
+          ctx.save();
+          ctx.lineWidth = width;
+          ctx.fillStyle = ctx.strokeStyle = color;
+          ctx.globalAlpha = alpha;
+          
+          for(var s in ctxObj) {
+            ctx[s] = node.getCanvasStyle(s);
+          }
+
+          this.nodeTypes[f].render.call(this, node, canvas, animating);
+          ctx.restore();
+        }
+    },
+    
+    /*
+       Method: plotLine
+    
+       Plots a <Graph.Adjacence>.
+
+       Parameters:
+
+       adj - (object) A <Graph.Adjacence>.
+       canvas - (object) A <Canvas> instance.
+
+    */
+    plotLine: function(adj, canvas, animating) {
+      var f = adj.getData('type'),
+          ctxObj = this.edge.CanvasStyles;
+      if(f != 'none') {
+        var width = adj.getData('lineWidth'),
+            color = adj.getData('color'),
+            ctx = canvas.getCtx(),
+            nodeFrom = adj.nodeFrom,
+            nodeTo = adj.nodeTo;
+        
+        ctx.save();
+        ctx.lineWidth = width;
+        ctx.fillStyle = ctx.strokeStyle = color;
+        ctx.globalAlpha = Math.min(nodeFrom.getData('alpha'), 
+            nodeTo.getData('alpha'), 
+            adj.getData('alpha'));
+        
+        for(var s in ctxObj) {
+          ctx[s] = adj.getCanvasStyle(s);
+        }
+
+        this.edgeTypes[f].render.call(this, adj, canvas, animating);
+        ctx.restore();
+      }
+    }    
+  
+};
+
+/*
+  Object: Graph.Plot3D
+  
+  <Graph> 3D rendering and animation methods.
+  
+  Properties:
+  
+  nodeHelper - <NodeHelper> object.
+  edgeHelper - <EdgeHelper> object.
+
+*/
+Graph.Plot3D = $.merge(Graph.Plot, {
+  Interpolator: {
+    'linear': function(elem, props, delta) {
+      var from = elem.startPos.getc(true);
+      var to = elem.endPos.getc(true);
+      elem.pos.setc(this.compute(from.x, to.x, delta), 
+                    this.compute(from.y, to.y, delta),
+                    this.compute(from.z, to.z, delta));
+    }
+  },
+  
+  plotNode: function(node, canvas) {
+    if(node.getData('type') == 'none') return;
+    this.plotElement(node, canvas, {
+      getAlpha: function() {
+        return node.getData('alpha');
+      }
+    });
+  },
+  
+  plotLine: function(adj, canvas) {
+    if(adj.getData('type') == 'none') return;
+    this.plotElement(adj, canvas, {
+      getAlpha: function() {
+        return Math.min(adj.nodeFrom.getData('alpha'),
+                        adj.nodeTo.getData('alpha'),
+                        adj.getData('alpha'));
+      }
+    });
+  },
+  
+  plotElement: function(elem, canvas, opt) {
+    var gl = canvas.getCtx(),
+        viewMatrix = new Matrix4,
+        lighting = canvas.config.Scene.Lighting,
+        wcanvas = canvas.canvases[0],
+        program = wcanvas.program,
+        camera = wcanvas.camera;
+    
+    if(!elem.geometry) {
+      elem.geometry = new O3D[elem.getData('type')];
+    }
+    elem.geometry.update(elem);
+    if(!elem.webGLVertexBuffer) {
+      var vertices = [],
+          faces = [],
+          normals = [],
+          vertexIndex = 0,
+          geom = elem.geometry;
+      
+      for(var i=0, vs=geom.vertices, fs=geom.faces, fsl=fs.length; i<fsl; i++) {
+        var face = fs[i],
+            v1 = vs[face.a],
+            v2 = vs[face.b],
+            v3 = vs[face.c],
+            v4 = face.d? vs[face.d] : false,
+            n = face.normal;
+        
+        vertices.push(v1.x, v1.y, v1.z);
+        vertices.push(v2.x, v2.y, v2.z);
+        vertices.push(v3.x, v3.y, v3.z);
+        if(v4) vertices.push(v4.x, v4.y, v4.z);
+            
+        normals.push(n.x, n.y, n.z);
+        normals.push(n.x, n.y, n.z);
+        normals.push(n.x, n.y, n.z);
+        if(v4) normals.push(n.x, n.y, n.z);
+            
+        faces.push(vertexIndex, vertexIndex +1, vertexIndex +2);
+        if(v4) {
+          faces.push(vertexIndex, vertexIndex +2, vertexIndex +3);
+          vertexIndex += 4;
+        } else {
+          vertexIndex += 3;
+        }
+      }
+      //create and store vertex data
+      elem.webGLVertexBuffer = gl.createBuffer();
+      gl.bindBuffer(gl.ARRAY_BUFFER, elem.webGLVertexBuffer);
+      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
+      //create and store faces index data
+      elem.webGLFaceBuffer = gl.createBuffer();
+      gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elem.webGLFaceBuffer);
+      gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, new Uint16Array(faces), gl.STATIC_DRAW);
+      elem.webGLFaceCount = faces.length;
+      //calculate vertex normals and store them
+      elem.webGLNormalBuffer = gl.createBuffer();
+      gl.bindBuffer(gl.ARRAY_BUFFER, elem.webGLNormalBuffer);
+      gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(normals), gl.STATIC_DRAW);
+    }
+    viewMatrix.multiply(camera.matrix, elem.geometry.matrix);
+    //send matrix data
+    gl.uniformMatrix4fv(program.viewMatrix, false, viewMatrix.flatten());
+    gl.uniformMatrix4fv(program.projectionMatrix, false, camera.projectionMatrix.flatten());
+    //send normal matrix for lighting
+    var normalMatrix = Matrix4.makeInvert(viewMatrix);
+    normalMatrix.$transpose();
+    gl.uniformMatrix4fv(program.normalMatrix, false, normalMatrix.flatten());
+    //send color data
+    var color = $.hexToRgb(elem.getData('color'));
+    color.push(opt.getAlpha());
+    gl.uniform4f(program.color, color[0] / 255, color[1] / 255, color[2] / 255, color[3]);
+    //send lighting data
+    gl.uniform1i(program.enableLighting, lighting.enable);
+    if(lighting.enable) {
+      //set ambient light color
+      if(lighting.ambient) {
+        var acolor = lighting.ambient;
+        gl.uniform3f(program.ambientColor, acolor[0], acolor[1], acolor[2]);
+      }
+      //set directional light
+      if(lighting.directional) {
+        var dir = lighting.directional,
+            color = dir.color,
+            pos = dir.direction,
+            vd = new Vector3(pos.x, pos.y, pos.z).normalize().$scale(-1);
+        gl.uniform3f(program.lightingDirection, vd.x, vd.y, vd.z);
+        gl.uniform3f(program.directionalColor, color[0], color[1], color[2]);
+      }
+    }
+    //send vertices data
+    gl.bindBuffer(gl.ARRAY_BUFFER, elem.webGLVertexBuffer);
+    gl.vertexAttribPointer(program.position, 3, gl.FLOAT, false, 0, 0);
+    //send normals data
+    gl.bindBuffer(gl.ARRAY_BUFFER, elem.webGLNormalBuffer);
+    gl.vertexAttribPointer(program.normal, 3, gl.FLOAT, false, 0, 0);
+    //draw!
+    gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, elem.webGLFaceBuffer );
+    gl.drawElements(gl.TRIANGLES, elem.webGLFaceCount, gl.UNSIGNED_SHORT, 0);
+  }
+});
+
+
+/*
+ * File: Graph.Label.js
+ *
+*/
+
+/*
+   Object: Graph.Label
+
+   An interface for plotting/hiding/showing labels.
+
+   Description:
+
+   This is a generic interface for plotting/hiding/showing labels.
+   The <Graph.Label> interface is implemented in multiple ways to provide
+   different label types.
+
+   For example, the Graph.Label interface is implemented as <Graph.Label.HTML> to provide
+   HTML label elements. Also we provide the <Graph.Label.SVG> interface for SVG type labels. 
+   The <Graph.Label.Native> interface implements these methods with the native Canvas text rendering functions.
+   
+   All subclasses (<Graph.Label.HTML>, <Graph.Label.SVG> and <Graph.Label.Native>) implement the method plotLabel.
+*/
+
+Graph.Label = {};
+
+/*
+   Class: Graph.Label.Native
+
+   Implements labels natively, using the Canvas text API.
+*/
+Graph.Label.Native = new Class({
+    initialize: function(viz) {
+      this.viz = viz;
+    },
+
+    /*
+       Method: plotLabel
+
+       Plots a label for a given node.
+
+       Parameters:
+
+       canvas - (object) A <Canvas> instance.
+       node - (object) A <Graph.Node>.
+       controller - (object) A configuration object.
+       
+       Example:
+       
+       (start code js)
+       var viz = new $jit.Viz(options);
+       var node = viz.graph.getNode('nodeId');
+       viz.labels.plotLabel(viz.canvas, node, viz.config);
+       (end code)
+    */
+    plotLabel: function(canvas, node, controller) {
+      var ctx = canvas.getCtx();
+      var pos = node.pos.getc(true);
+
+      ctx.font = node.getLabelData('style') + ' ' + node.getLabelData('size') + 'px ' + node.getLabelData('family');
+      ctx.textAlign = node.getLabelData('textAlign');
+      ctx.fillStyle = ctx.strokeStyle = node.getLabelData('color');
+      ctx.textBaseline = node.getLabelData('textBaseline');
+
+      this.renderLabel(canvas, node, controller);
+    },
+
+    /*
+       renderLabel
+
+       Does the actual rendering of the label in the canvas. The default
+       implementation renders the label close to the position of the node, this
+       method should be overriden to position the labels differently.
+
+       Parameters:
+
+       canvas - A <Canvas> instance.
+       node - A <Graph.Node>.
+       controller - A configuration object. See also <Hypertree>, <RGraph>, <ST>.
+    */
+    renderLabel: function(canvas, node, controller) {
+      var ctx = canvas.getCtx();
+      var pos = node.pos.getc(true);
+      ctx.fillText(node.name, pos.x, pos.y + node.getData("height") / 2);
+    },
+
+    hideLabel: $.empty,
+    hideLabels: $.empty
+});
+
+/*
+   Class: Graph.Label.DOM
+
+   Abstract Class implementing some DOM label methods.
+
+   Implemented by:
+
+   <Graph.Label.HTML> and <Graph.Label.SVG>.
+
+*/
+Graph.Label.DOM = new Class({
+    //A flag value indicating if node labels are being displayed or not.
+    labelsHidden: false,
+    //Label container
+    labelContainer: false,
+    //Label elements hash.
+    labels: {},
+
+    /*
+       Method: getLabelContainer
+
+       Lazy fetcher for the label container.
+
+       Returns:
+
+       The label container DOM element.
+
+       Example:
+
+      (start code js)
+        var viz = new $jit.Viz(options);
+        var labelContainer = viz.labels.getLabelContainer();
+        alert(labelContainer.innerHTML);
+      (end code)
+    */
+    getLabelContainer: function() {
+      return this.labelContainer ?
+        this.labelContainer :
+        this.labelContainer = document.getElementById(this.viz.config.labelContainer);
+    },
+
+    /*
+       Method: getLabel
+
+       Lazy fetcher for the label element.
+
+       Parameters:
+
+       id - (string) The label id (which is also a <Graph.Node> id).
+
+       Returns:
+
+       The label element.
+
+       Example:
+
+      (start code js)
+        var viz = new $jit.Viz(options);
+        var label = viz.labels.getLabel('someid');
+        alert(label.innerHTML);
+      (end code)
+
+    */
+    getLabel: function(id) {
+      return (id in this.labels && this.labels[id] != null) ?
+        this.labels[id] :
+        this.labels[id] = document.getElementById(id);
+    },
+
+    /*
+       Method: hideLabels
+
+       Hides all labels (by hiding the label container).
+
+       Parameters:
+
+       hide - (boolean) A boolean value indicating if the label container must be hidden or not.
+
+       Example:
+       (start code js)
+        var viz = new $jit.Viz(options);
+        rg.labels.hideLabels(true);
+       (end code)
+
+    */
+    hideLabels: function (hide) {
+      var container = this.getLabelContainer();
+      if(hide)
+        container.style.display = 'none';
+      else
+        container.style.display = '';
+      this.labelsHidden = hide;
+    },
+
+    /*
+       Method: clearLabels
+
+       Clears the label container.
+
+       Useful when using a new visualization with the same canvas element/widget.
+
+       Parameters:
+
+       force - (boolean) Forces deletion of all labels.
+
+       Example:
+       (start code js)
+        var viz = new $jit.Viz(options);
+        viz.labels.clearLabels();
+        (end code)
+    */
+    clearLabels: function(force) {
+      for(var id in this.labels) {
+        if (force || !this.viz.graph.hasNode(id)) {
+          this.disposeLabel(id);
+          delete this.labels[id];
+        }
+      }
+    },
+
+    /*
+       Method: disposeLabel
+
+       Removes a label.
+
+       Parameters:
+
+       id - (string) A label id (which generally is also a <Graph.Node> id).
+
+       Example:
+       (start code js)
+        var viz = new $jit.Viz(options);
+        viz.labels.disposeLabel('labelid');
+       (end code)
+    */
+    disposeLabel: function(id) {
+      var elem = this.getLabel(id);
+      if(elem && elem.parentNode) {
+        elem.parentNode.removeChild(elem);
+      }
+    },
+
+    /*
+       Method: hideLabel
+
+       Hides the corresponding <Graph.Node> label.
+
+       Parameters:
+
+       node - (object) A <Graph.Node>. Can also be an array of <Graph.Nodes>.
+       show - (boolean) If *true*, nodes will be shown. Otherwise nodes will be hidden.
+
+       Example:
+       (start code js)
+        var rg = new $jit.Viz(options);
+        viz.labels.hideLabel(viz.graph.getNode('someid'), false);
+       (end code)
+    */
+    hideLabel: function(node, show) {
+      node = $.splat(node);
+      var st = show ? "" : "none", lab, that = this;
+      $.each(node, function(n) {
+        var lab = that.getLabel(n.id);
+        if (lab) {
+          lab.style.display = st;
+        }
+      });
+    },
+
+    /*
+       fitsInCanvas
+
+       Returns _true_ or _false_ if the label for the node is contained in the canvas dom element or not.
+
+       Parameters:
+
+       pos - A <Complex> instance (I'm doing duck typing here so any object with _x_ and _y_ parameters will do).
+       canvas - A <Canvas> instance.
+
+       Returns:
+
+       A boolean value specifying if the label is contained in the <Canvas> DOM element or not.
+
+    */
+    fitsInCanvas: function(pos, canvas) {
+      var size = canvas.getSize();
+      if(pos.x >= size.width || pos.x < 0
+         || pos.y >= size.height || pos.y < 0) return false;
+       return true;
+    }
+});
+
+/*
+   Class: Graph.Label.HTML
+
+   Implements HTML labels.
+
+   Extends:
+
+   All <Graph.Label.DOM> methods.
+
+*/
+Graph.Label.HTML = new Class({
+    Implements: Graph.Label.DOM,
+
+    /*
+       Method: plotLabel
+
+       Plots a label for a given node.
+
+       Parameters:
+
+       canvas - (object) A <Canvas> instance.
+       node - (object) A <Graph.Node>.
+       controller - (object) A configuration object.
+       
+      Example:
+       
+       (start code js)
+       var viz = new $jit.Viz(options);
+       var node = viz.graph.getNode('nodeId');
+       viz.labels.plotLabel(viz.canvas, node, viz.config);
+       (end code)
+
+
+    */
+    plotLabel: function(canvas, node, controller) {
+      var id = node.id, tag = this.getLabel(id);
+
+      if(!tag && !(tag = document.getElementById(id))) {
+        tag = document.createElement('div');
+        var container = this.getLabelContainer();
+        tag.id = id;
+        tag.className = 'node';
+        tag.style.position = 'absolute';
+        controller.onCreateLabel(tag, node);
+        container.appendChild(tag);
+        this.labels[node.id] = tag;
+      }
+
+      this.placeLabel(tag, node, controller);
+    }
+});
+
+/*
+   Class: Graph.Label.SVG
+
+   Implements SVG labels.
+
+   Extends:
+
+   All <Graph.Label.DOM> methods.
+*/
+Graph.Label.SVG = new Class({
+    Implements: Graph.Label.DOM,
+
+    /*
+       Method: plotLabel
+
+       Plots a label for a given node.
+
+       Parameters:
+
+       canvas - (object) A <Canvas> instance.
+       node - (object) A <Graph.Node>.
+       controller - (object) A configuration object.
+       
+       Example:
+       
+       (start code js)
+       var viz = new $jit.Viz(options);
+       var node = viz.graph.getNode('nodeId');
+       viz.labels.plotLabel(viz.canvas, node, viz.config);
+       (end code)
+
+
+    */
+    plotLabel: function(canvas, node, controller) {
+      var id = node.id, tag = this.getLabel(id);
+      if(!tag && !(tag = document.getElementById(id))) {
+        var ns = 'http://www.w3.org/2000/svg';
+          tag = document.createElementNS(ns, 'svg:text');
+        var tspan = document.createElementNS(ns, 'svg:tspan');
+        tag.appendChild(tspan);
+        var container = this.getLabelContainer();
+        tag.setAttribute('id', id);
+        tag.setAttribute('class', 'node');
+        container.appendChild(tag);
+        controller.onCreateLabel(tag, node);
+        this.labels[node.id] = tag;
+      }
+      this.placeLabel(tag, node, controller);
+    }
+});
+
+
+
+Graph.Geom = new Class({
+
+  initialize: function(viz) {
+    this.viz = viz;
+    this.config = viz.config;
+    this.node = viz.config.Node;
+    this.edge = viz.config.Edge;
+  },
+  /*
+    Applies a translation to the tree.
+  
+    Parameters:
+  
+    pos - A <Complex> number specifying translation vector.
+    prop - A <Graph.Node> position property ('pos', 'start' or 'end').
+  
+    Example:
+  
+    (start code js)
+      st.geom.translate(new Complex(300, 100), 'end');
+    (end code)
+  */  
+  translate: function(pos, prop) {
+     prop = $.splat(prop);
+     this.viz.graph.eachNode(function(elem) {
+         $.each(prop, function(p) { elem.getPos(p).$add(pos); });
+     });
+  },
+  /*
+    Hides levels of the tree until it properly fits in canvas.
+  */  
+  setRightLevelToShow: function(node, canvas, callback) {
+     var level = this.getRightLevelToShow(node, canvas), 
+         fx = this.viz.labels,
+         opt = $.merge({
+           execShow:true,
+           execHide:true,
+           onHide: $.empty,
+           onShow: $.empty
+         }, callback || {});
+     node.eachLevel(0, this.config.levelsToShow, function(n) {
+         var d = n._depth - node._depth;
+         if(d > level) {
+             opt.onHide(n);
+             if(opt.execHide) {
+               n.drawn = false; 
+               n.exist = false;
+               fx.hideLabel(n, false);
+             }
+         } else {
+             opt.onShow(n);
+             if(opt.execShow) {
+               n.exist = true;
+             }
+         }
+     });
+     node.drawn= true;
+  },
+  /*
+    Returns the right level to show for the current tree in order to fit in canvas.
+  */  
+  getRightLevelToShow: function(node, canvas) {
+     var config = this.config;
+     var level = config.levelsToShow;
+     var constrained = config.constrained;
+     if(!constrained) return level;
+     while(!this.treeFitsInCanvas(node, canvas, level) && level > 1) { level-- ; }
+     return level;
+  }
+});
+
+/*
+ * File: Loader.js
+ * 
+ */
+
+/*
+   Object: Loader
+
+   Provides methods for loading and serving JSON data.
+*/
+var Loader = {
+     construct: function(json) {
+        var isGraph = ($.type(json) == 'array');
+        var ans = new Graph(this.graphOptions, this.config.Node, this.config.Edge, this.config.Label);
+        if(!isGraph) 
+            //make tree
+            (function (ans, json) {
+                ans.addNode(json);
+                if(json.children) {
+                  for(var i=0, ch = json.children; i<ch.length; i++) {
+                    ans.addAdjacence(json, ch[i]);
+                    arguments.callee(ans, ch[i]);
+                  }
+                }
+            })(ans, json);
+        else
+            //make graph
+            (function (ans, json) {
+                var getNode = function(id) {
+                  for(var i=0, l=json.length; i<l; i++) {
+                    if(json[i].id == id) {
+                      return json[i];
+                    }
+                  }
+                  // The node was not defined in the JSON
+                  // Let's create it
+                  var newNode = {
+                		"id" : id,
+                		"name" : id
+                	};
+                  return ans.addNode(newNode);
+                };
+
+                for(var i=0, l=json.length; i<l; i++) {
+                  ans.addNode(json[i]);
+                  var adj = json[i].adjacencies;
+                  if (adj) {
+                    for(var j=0, lj=adj.length; j<lj; j++) {
+                      var node = adj[j], data = {};
+                      if(typeof adj[j] != 'string') {
+                        data = $.merge(node.data, {});
+                        node = node.nodeTo;
+                      }
+                      ans.addAdjacence(json[i], getNode(node), data);
+                    }
+                  }
+                }
+            })(ans, json);
+
+        return ans;
+    },
+
+    /*
+     Method: loadJSON
+    
+     Loads a JSON structure to the visualization. The JSON structure can be a JSON *tree* or *graph* structure.
+     
+      A JSON tree or graph structure consists of nodes, each having as properties
+       
+       id - (string) A unique identifier for the node
+       name - (string) A node's name
+       data - (object) The data optional property contains a hash (i.e {}) 
+       where you can store all the information you want about this node.
+        
+      For JSON *Tree* structures, there's an extra optional property *children* of type Array which contains the node's children.
+      
+      Example:
+
+      (start code js)
+        var json = {  
+          "id": "aUniqueIdentifier",  
+          "name": "usually a nodes name",  
+          "data": {
+            "some key": "some value",
+            "some other key": "some other value"
+           },  
+          "children": [ *other nodes or empty* ]  
+        };  
+      (end code)
+        
+        JSON *Graph* structures consist of an array of nodes, each specifying the nodes to which the current node is connected. 
+        For JSON *Graph* structures, the *children* property is replaced by the *adjacencies* property.
+        
+        There are two types of *Graph* structures, *simple* and *extended* graph structures.
+        
+        For *simple* Graph structures, the adjacencies property contains an array of strings, each specifying the 
+        id of the node connected to the main node.
+        
+        Example:
+        
+        (start code js)
+        var json = [  
+          {  
+            "id": "aUniqueIdentifier",  
+            "name": "usually a nodes name",  
+            "data": {
+              "some key": "some value",
+              "some other key": "some other value"
+             },  
+            "adjacencies": ["anotherUniqueIdentifier", "yetAnotherUniqueIdentifier", 'etc']  
+          },
+
+          'other nodes go here...' 
+        ];          
+        (end code)
+        
+        For *extended Graph structures*, the adjacencies property contains an array of Adjacency objects that have as properties
+        
+        nodeTo - (string) The other node connected by this adjacency.
+        data - (object) A data property, where we can store custom key/value information.
+        
+        Example:
+        
+        (start code js)
+        var json = [  
+          {  
+            "id": "aUniqueIdentifier",  
+            "name": "usually a nodes name",  
+            "data": {
+              "some key": "some value",
+              "some other key": "some other value"
+             },  
+            "adjacencies": [  
+            {  
+              nodeTo:"aNodeId",  
+              data: {} //put whatever you want here  
+            },
+            'other adjacencies go here...'  
+          },
+
+          'other nodes go here...' 
+        ];          
+        (end code)
+       
+       About the data property:
+       
+       As described before, you can store custom data in the *data* property of JSON *nodes* and *adjacencies*. 
+       You can use almost any string as key for the data object. Some keys though are reserved by the toolkit, and 
+       have special meanings. This is the case for keys starting with a dollar sign, for example, *$width*.
+       
+       For JSON *node* objects, adding dollar prefixed properties that match the names of the options defined in 
+       <Options.Node> will override the general value for that option with that particular value. For this to work 
+       however, you do have to set *overridable = true* in <Options.Node>.
+       
+       The same thing is true for JSON adjacencies. Dollar prefixed data properties will alter values set in <Options.Edge> 
+       if <Options.Edge> has *overridable = true*.
+       
+       When loading JSON data into TreeMaps, the *data* property must contain a value for the *$area* key, 
+       since this is the value which will be taken into account when creating the layout. 
+       The same thing goes for the *$color* parameter.
+       
+       In JSON Nodes you can use also *$label-* prefixed properties to refer to <Options.Label> properties. For example, 
+       *$label-size* will refer to <Options.Label> size property. Also, in JSON nodes and adjacencies you can set 
+       canvas specific properties individually by using the *$canvas-* prefix. For example, *$canvas-shadowBlur* will refer 
+       to the *shadowBlur* property.
+       
+       These properties can also be accessed after loading the JSON data from <Graph.Nodes> and <Graph.Adjacences> 
+       by using <Accessors>. For more information take a look at the <Graph> and <Accessors> documentation.
+       
+       Finally, these properties can also be used to create advanced animations like with <Options.NodeStyles>. For more 
+       information about creating animations please take a look at the <Graph.Plot> and <Graph.Plot.animate> documentation.
+       
+       loadJSON Parameters:
+    
+        json - A JSON Tree or Graph structure.
+        i - For Graph structures only. Sets the indexed node as root for the visualization.
+
+    */
+    loadJSON: function(json, i) {
+      this.json = json;
+      //if they're canvas labels erase them.
+      if(this.labels && this.labels.clearLabels) {
+        this.labels.clearLabels(true);
+      }
+      this.graph = this.construct(json);
+      if($.type(json) != 'array'){
+        this.root = json.id;
+      } else {
+        this.root = json[i? i : 0].id;
+      }
+    },
+    
+    /*
+      Method: toJSON
+   
+      Returns a JSON tree/graph structure from the visualization's <Graph>. 
+      See <Loader.loadJSON> for the graph formats available.
+      
+      See also:
+      
+      <Loader.loadJSON>
+      
+      Parameters:
+      
+      type - (string) Default's "tree". The type of the JSON structure to be returned. 
+      Possible options are "tree" or "graph".
+    */    
+    toJSON: function(type) {
+      type = type || "tree";
+      if(type == 'tree') {
+        var ans = {};
+        var rootNode = this.graph.getNode(this.root);
+        var ans = (function recTree(node) {
+          var ans = {};
+          ans.id = node.id;
+          ans.name = node.name;
+          ans.data = node.data;
+          var ch =[];
+          node.eachSubnode(function(n) {
+            ch.push(recTree(n));
+          });
+          ans.children = ch;
+          return ans;
+        })(rootNode);
+        return ans;
+      } else {
+        var ans = [];
+        var T = !!this.graph.getNode(this.root).visited;
+        this.graph.eachNode(function(node) {
+          var ansNode = {};
+          ansNode.id = node.id;
+          ansNode.name = node.name;
+          ansNode.data = node.data;
+          var adjs = [];
+          node.eachAdjacency(function(adj) {
+            var nodeTo = adj.nodeTo;
+            if(!!nodeTo.visited === T) {
+              var ansAdj = {};
+              ansAdj.nodeTo = nodeTo.id;
+              ansAdj.data = adj.data;
+              adjs.push(ansAdj);
+            }
+          });
+          ansNode.adjacencies = adjs;
+          ans.push(ansNode);
+          node.visited = !T;
+        });
+        return ans;
+      }
+    }
+};
+
+
+
+/*
+ * File: Layouts.js
+ * 
+ * Implements base Tree and Graph layouts.
+ *
+ * Description:
+ *
+ * Implements base Tree and Graph layouts like Radial, Tree, etc.
+ * 
+ */
+
+/*
+ * Object: Layouts
+ * 
+ * Parent object for common layouts.
+ *
+ */
+var Layouts = $jit.Layouts = {};
+
+
+//Some util shared layout functions are defined here.
+var NodeDim = {
+  label: null,
+  
+  compute: function(graph, prop, opt) {
+    this.initializeLabel(opt);
+    var label = this.label, style = label.style;
+    graph.eachNode(function(n) {
+      var autoWidth  = n.getData('autoWidth'),
+          autoHeight = n.getData('autoHeight');
+      if(autoWidth || autoHeight) {
+        //delete dimensions since these are
+        //going to be overridden now.
+        delete n.data.$width;
+        delete n.data.$height;
+        delete n.data.$dim;
+        
+        var width  = n.getData('width'),
+            height = n.getData('height');
+        //reset label dimensions
+        style.width  = autoWidth? 'auto' : width + 'px';
+        style.height = autoHeight? 'auto' : height + 'px';
+        
+        //TODO(nico) should let the user choose what to insert here.
+        label.innerHTML = n.name;
+        
+        var offsetWidth  = label.offsetWidth,
+            offsetHeight = label.offsetHeight;
+        var type = n.getData('type');
+        if($.indexOf(['circle', 'square', 'triangle', 'star'], type) === -1) {
+          n.setData('width', offsetWidth);
+          n.setData('height', offsetHeight);
+        } else {
+          var dim = offsetWidth > offsetHeight? offsetWidth : offsetHeight;
+          n.setData('width', dim);
+          n.setData('height', dim);
+          n.setData('dim', dim); 
+        }
+      }
+    });
+  },
+  
+  initializeLabel: function(opt) {
+    if(!this.label) {
+      this.label = document.createElement('div');
+      document.body.appendChild(this.label);
+    }
+    this.setLabelStyles(opt);
+  },
+  
+  setLabelStyles: function(opt) {
+    $.extend(this.label.style, {
+      'visibility': 'hidden',
+      'position': 'absolute',
+      'width': 'auto',
+      'height': 'auto'
+    });
+    this.label.className = 'jit-autoadjust-label';
+  }
+};
+
+
+/*
+ * Class: Layouts.Tree
+ * 
+ * Implements a Tree Layout.
+ * 
+ * Implemented By:
+ * 
+ * <ST>
+ * 
+ * Inspired by:
+ * 
+ * Drawing Trees (Andrew J. Kennedy) <http://research.microsoft.com/en-us/um/people/akenn/fun/drawingtrees.pdf>
+ * 
+ */
+Layouts.Tree = (function() {
+  //Layout functions
+  var slice = Array.prototype.slice;
+
+  /*
+     Calculates the max width and height nodes for a tree level
+  */  
+  function getBoundaries(graph, config, level, orn, prop) {
+    var dim = config.Node;
+    var multitree = config.multitree;
+    if (dim.overridable) {
+      var w = -1, h = -1;
+      graph.eachNode(function(n) {
+        if (n._depth == level
+            && (!multitree || ('$orn' in n.data) && n.data.$orn == orn)) {
+          var dw = n.getData('width', prop);
+          var dh = n.getData('height', prop);
+          w = (w < dw) ? dw : w;
+          h = (h < dh) ? dh : h;
+        }
+      });
+      return {
+        'width' : w < 0 ? dim.width : w,
+        'height' : h < 0 ? dim.height : h
+      };
+    } else {
+      return dim;
+    }
+  }
+
+
+  function movetree(node, prop, val, orn) {
+    var p = (orn == "left" || orn == "right") ? "y" : "x";
+    node.getPos(prop)[p] += val;
+  }
+
+
+  function moveextent(extent, val) {
+    var ans = [];
+    $.each(extent, function(elem) {
+      elem = slice.call(elem);
+      elem[0] += val;
+      elem[1] += val;
+      ans.push(elem);
+    });
+    return ans;
+  }
+
+
+  function merge(ps, qs) {
+    if (ps.length == 0)
+      return qs;
+    if (qs.length == 0)
+      return ps;
+    var p = ps.shift(), q = qs.shift();
+    return [ [ p[0], q[1] ] ].concat(merge(ps, qs));
+  }
+
+
+  function mergelist(ls, def) {
+    def = def || [];
+    if (ls.length == 0)
+      return def;
+    var ps = ls.pop();
+    return mergelist(ls, merge(ps, def));
+  }
+
+
+  function fit(ext1, ext2, subtreeOffset, siblingOffset, i) {
+    if (ext1.length <= i || ext2.length <= i)
+      return 0;
+
+    var p = ext1[i][1], q = ext2[i][0];
+    return Math.max(fit(ext1, ext2, subtreeOffset, siblingOffset, ++i)
+        + subtreeOffset, p - q + siblingOffset);
+  }
+
+
+  function fitlistl(es, subtreeOffset, siblingOffset) {
+    function $fitlistl(acc, es, i) {
+      if (es.length <= i)
+        return [];
+      var e = es[i], ans = fit(acc, e, subtreeOffset, siblingOffset, 0);
+      return [ ans ].concat($fitlistl(merge(acc, moveextent(e, ans)), es, ++i));
+    }
+    ;
+    return $fitlistl( [], es, 0);
+  }
+
+
+  function fitlistr(es, subtreeOffset, siblingOffset) {
+    function $fitlistr(acc, es, i) {
+      if (es.length <= i)
+        return [];
+      var e = es[i], ans = -fit(e, acc, subtreeOffset, siblingOffset, 0);
+      return [ ans ].concat($fitlistr(merge(moveextent(e, ans), acc), es, ++i));
+    }
+    ;
+    es = slice.call(es);
+    var ans = $fitlistr( [], es.reverse(), 0);
+    return ans.reverse();
+  }
+
+
+  function fitlist(es, subtreeOffset, siblingOffset, align) {
+    var esl = fitlistl(es, subtreeOffset, siblingOffset), esr = fitlistr(es,
+        subtreeOffset, siblingOffset);
+
+    if (align == "left")
+      esr = esl;
+    else if (align == "right")
+      esl = esr;
+
+    for ( var i = 0, ans = []; i < esl.length; i++) {
+      ans[i] = (esl[i] + esr[i]) / 2;
+    }
+    return ans;
+  }
+
+
+  function design(graph, node, prop, config, orn) {
+    var multitree = config.multitree;
+    var auxp = [ 'x', 'y' ], auxs = [ 'width', 'height' ];
+    var ind = +(orn == "left" || orn == "right");
+    var p = auxp[ind], notp = auxp[1 - ind];
+
+    var cnode = config.Node;
+    var s = auxs[ind], nots = auxs[1 - ind];
+
+    var siblingOffset = config.siblingOffset;
+    var subtreeOffset = config.subtreeOffset;
+    var align = config.align;
+
+    function $design(node, maxsize, acum) {
+      var sval = node.getData(s, prop);
+      var notsval = maxsize
+          || (node.getData(nots, prop));
+
+      var trees = [], extents = [], chmaxsize = false;
+      var chacum = notsval + config.levelDistance;
+      node.eachSubnode(function(n) {
+            if (n.exist
+                && (!multitree || ('$orn' in n.data) && n.data.$orn == orn)) {
+
+              if (!chmaxsize)
+                chmaxsize = getBoundaries(graph, config, n._depth, orn, prop);
+
+              var s = $design(n, chmaxsize[nots], acum + chacum);
+              trees.push(s.tree);
+              extents.push(s.extent);
+            }
+          });
+      var positions = fitlist(extents, subtreeOffset, siblingOffset, align);
+      for ( var i = 0, ptrees = [], pextents = []; i < trees.length; i++) {
+        movetree(trees[i], prop, positions[i], orn);
+        pextents.push(moveextent(extents[i], positions[i]));
+      }
+      var resultextent = [ [ -sval / 2, sval / 2 ] ]
+          .concat(mergelist(pextents));
+      node.getPos(prop)[p] = 0;
+
+      if (orn == "top" || orn == "left") {
+        node.getPos(prop)[notp] = acum;
+      } else {
+        node.getPos(prop)[notp] = -acum;
+      }
+
+      return {
+        tree : node,
+        extent : resultextent
+      };
+    }
+
+    $design(node, false, 0);
+  }
+
+
+  return new Class({
+    /*
+    Method: compute
+    
+    Computes nodes' positions.
+
+     */
+    compute : function(property, computeLevels) {
+      var prop = property || 'start';
+      var node = this.graph.getNode(this.root);
+      $.extend(node, {
+        'drawn' : true,
+        'exist' : true,
+        'selected' : true
+      });
+      NodeDim.compute(this.graph, prop, this.config);
+      if (!!computeLevels || !("_depth" in node)) {
+        this.graph.computeLevels(this.root, 0, "ignore");
+      }
+      
+      this.computePositions(node, prop);
+    },
+
+    computePositions : function(node, prop) {
+      var config = this.config;
+      var multitree = config.multitree;
+      var align = config.align;
+      var indent = align !== 'center' && config.indent;
+      var orn = config.orientation;
+      var orns = multitree ? [ 'top', 'right', 'bottom', 'left' ] : [ orn ];
+      var that = this;
+      $.each(orns, function(orn) {
+        //calculate layout
+          design(that.graph, node, prop, that.config, orn, prop);
+          var i = [ 'x', 'y' ][+(orn == "left" || orn == "right")];
+          //absolutize
+          (function red(node) {
+            node.eachSubnode(function(n) {
+              if (n.exist
+                  && (!multitree || ('$orn' in n.data) && n.data.$orn == orn)) {
+
+                n.getPos(prop)[i] += node.getPos(prop)[i];
+                if (indent) {
+                  n.getPos(prop)[i] += align == 'left' ? indent : -indent;
+                }
+                red(n);
+              }
+            });
+          })(node);
+        });
+    }
+  });
+  
+})();
+
+/*
+ * File: Spacetree.js
+ */
+
+/*
+   Class: ST
+   
+  A Tree layout with advanced contraction and expansion animations.
+     
+  Inspired by:
+ 
+  SpaceTree: Supporting Exploration in Large Node Link Tree, Design Evolution and Empirical Evaluation (Catherine Plaisant, Jesse Grosjean, Benjamin B. Bederson) 
+  <http://hcil.cs.umd.edu/trs/2002-05/2002-05.pdf>
+  
+  Drawing Trees (Andrew J. Kennedy) <http://research.microsoft.com/en-us/um/people/akenn/fun/drawingtrees.pdf>
+  
+  Note:
+ 
+  This visualization was built and engineered from scratch, taking only the papers as inspiration, and only shares some features with the visualization described in those papers.
+ 
+  Implements:
+  
+  All <Loader> methods
+  
+  Constructor Options:
+  
+  Inherits options from
+  
+  - <Options.Canvas>
+  - <Options.Controller>
+  - <Options.Tree>
+  - <Options.Node>
+  - <Options.Edge>
+  - <Options.Label>
+  - <Options.Events>
+  - <Options.Tips>
+  - <Options.NodeStyles>
+  - <Options.Navigation>
+  
+  Additionally, there are other parameters and some default values changed
+  
+  constrained - (boolean) Default's *true*. Whether to show the entire tree when loaded or just the number of levels specified by _levelsToShow_.
+  levelsToShow - (number) Default's *2*. The number of levels to show for a subtree. This number is relative to the selected node.
+  levelDistance - (number) Default's *30*. The distance between two consecutive levels of the tree.
+  Node.type - Described in <Options.Node>. Default's set to *rectangle*.
+  offsetX - (number) Default's *0*. The x-offset distance from the selected node to the center of the canvas.
+  offsetY - (number) Default's *0*. The y-offset distance from the selected node to the center of the canvas.
+  duration - Described in <Options.Fx>. It's default value has been changed to *700*.
+  
+  Instance Properties:
+  
+  canvas - Access a <Canvas> instance.
+  graph - Access a <Graph> instance.
+  op - Access a <ST.Op> instance.
+  fx - Access a <ST.Plot> instance.
+  labels - Access a <ST.Label> interface implementation.
+
+ */
+
+$jit.ST= (function() {
+    // Define some private methods first...
+    // Nodes in path
+    var nodesInPath = [];
+    // Nodes to contract
+    function getNodesToHide(node) {
+      node = node || this.clickedNode;
+      if(!this.config.constrained) {
+        return [];
+      }
+      var Geom = this.geom;
+      var graph = this.graph;
+      var canvas = this.canvas;
+      var level = node._depth, nodeArray = [];
+  	  graph.eachNode(function(n) {
+          if(n.exist && !n.selected) {
+              if(n.isDescendantOf(node.id)) {
+                if(n._depth <= level) nodeArray.push(n);
+              } else {
+                nodeArray.push(n);
+              }
+          }
+  	  });
+  	  var leafLevel = Geom.getRightLevelToShow(node, canvas);
+  	  node.eachLevel(leafLevel, leafLevel, function(n) {
+          if(n.exist && !n.selected) nodeArray.push(n);
+  	  });
+  	    
+  	  for (var i = 0; i < nodesInPath.length; i++) {
+  	    var n = this.graph.getNode(nodesInPath[i]);
+  	    if(!n.isDescendantOf(node.id)) {
+  	      nodeArray.push(n);
+  	    }
+  	  } 
+  	  return nodeArray;       
+    };
+    // Nodes to expand
+     function getNodesToShow(node) {
+        var nodeArray = [], config = this.config;
+        node = node || this.clickedNode;
+        this.clickedNode.eachLevel(0, config.levelsToShow, function(n) {
+            if(config.multitree && !('$orn' in n.data) 
+            		&& n.anySubnode(function(ch){ return ch.exist && !ch.drawn; })) {
+            	nodeArray.push(n);
+            } else if(n.drawn && !n.anySubnode("drawn")) {
+              nodeArray.push(n);
+            }
+        });
+        return nodeArray;
+     };
+    // Now define the actual class.
+    return new Class({
+    
+        Implements: [Loader, Extras, Layouts.Tree],
+        
+        initialize: function(controller) {            
+          var $ST = $jit.ST;
+          
+          var config= {
+                levelsToShow: 2,
+                levelDistance: 30,
+                constrained: true,                
+                Node: {
+                  type: 'rectangle'
+                },
+                duration: 700,
+                offsetX: 0,
+                offsetY: 0
+            };
+            
+            this.controller = this.config = $.merge(
+                Options("Canvas", "Fx", "Tree", "Node", "Edge", "Controller", 
+                    "Tips", "NodeStyles", "Events", "Navigation", "Label"), config, controller);
+
+            var canvasConfig = this.config;
+            if(canvasConfig.useCanvas) {
+              this.canvas = canvasConfig.useCanvas;
+              this.config.labelContainer = this.canvas.id + '-label';
+            } else {
+              if(canvasConfig.background) {
+                canvasConfig.background = $.merge({
+                  type: 'Circles'
+                }, canvasConfig.background);
+              }
+              this.canvas = new Canvas(this, canvasConfig);
+              this.config.labelContainer = (typeof canvasConfig.injectInto == 'string'? canvasConfig.injectInto : canvasConfig.injectInto.id) + '-label';
+            }
+
+            this.graphOptions = {
+                'klass': Complex
+            };
+            this.graph = new Graph(this.graphOptions, this.config.Node, this.config.Edge);
+            this.labels = new $ST.Label[canvasConfig.Label.type](this);
+            this.fx = new $ST.Plot(this, $ST);
+            this.op = new $ST.Op(this);
+            this.group = new $ST.Group(this);
+            this.geom = new $ST.Geom(this);
+            this.clickedNode=  null;
+            // initialize extras
+            this.initializeExtras();
+        },
+    
+        /*
+         Method: plot
+        
+         Plots the <ST>. This is a shortcut to *fx.plot*.
+
+        */  
+        plot: function() { this.fx.plot(this.controller); },
+    
+      
+        /*
+         Method: switchPosition
+        
+         Switches the tree orientation.
+
+         Parameters:
+
+        pos - (string) The new tree orientation. Possible values are "top", "left", "right" and "bottom".
+        method - (string) Set this to "animate" if you want to animate the tree when switching its position. You can also set this parameter to "replot" to just replot the subtree.
+        onComplete - (optional|object) This callback is called once the "switching" animation is complete.
+
+         Example:
+
+         (start code js)
+           st.switchPosition("right", "animate", {
+            onComplete: function() {
+              alert('completed!');
+            } 
+           });
+         (end code)
+        */  
+        switchPosition: function(pos, method, onComplete) {
+          var Geom = this.geom, Plot = this.fx, that = this;
+          if(!Plot.busy) {
+              Plot.busy = true;
+              this.contract({
+                  onComplete: function() {
+                      Geom.switchOrientation(pos);
+                      that.compute('end', false);
+                      Plot.busy = false;
+                      if(method == 'animate') {
+                    	  that.onClick(that.clickedNode.id, onComplete);  
+                      } else if(method == 'replot') {
+                    	  that.select(that.clickedNode.id, onComplete);
+                      }
+                  }
+              }, pos);
+          }
+        },
+
+        /*
+        Method: switchAlignment
+       
+        Switches the tree alignment.
+
+        Parameters:
+
+       align - (string) The new tree alignment. Possible values are "left", "center" and "right".
+       method - (string) Set this to "animate" if you want to animate the tree after aligning its position. You can also set this parameter to "replot" to just replot the subtree.
+       onComplete - (optional|object) This callback is called once the "switching" animation is complete.
+
+        Example:
+
+        (start code js)
+          st.switchAlignment("right", "animate", {
+           onComplete: function() {
+             alert('completed!');
+           } 
+          });
+        (end code)
+       */  
+       switchAlignment: function(align, method, onComplete) {
+        this.config.align = align;
+        if(method == 'animate') {
+        	this.select(this.clickedNode.id, onComplete);
+        } else if(method == 'replot') {
+        	this.onClick(this.clickedNode.id, onComplete);	
+        }
+       },
+
+       /*
+        Method: addNodeInPath
+       
+        Adds a node to the current path as selected node. The selected node will be visible (as in non-collapsed) at all times.
+        
+
+        Parameters:
+
+       id - (string) A <Graph.Node> id.
+
+        Example:
+
+        (start code js)
+          st.addNodeInPath("nodeId");
+        (end code)
+       */  
+       addNodeInPath: function(id) {
+           nodesInPath.push(id);
+           this.select((this.clickedNode && this.clickedNode.id) || this.root);
+       },       
+
+       /*
+       Method: clearNodesInPath
+      
+       Removes all nodes tagged as selected by the <ST.addNodeInPath> method.
+       
+       See also:
+       
+       <ST.addNodeInPath>
+     
+       Example:
+
+       (start code js)
+         st.clearNodesInPath();
+       (end code)
+      */  
+       clearNodesInPath: function(id) {
+           nodesInPath.length = 0;
+           this.select((this.clickedNode && this.clickedNode.id) || this.root);
+       },
+        
+       /*
+         Method: refresh
+        
+         Computes positions and plots the tree.
+         
+       */
+       refresh: function() {
+           this.reposition();
+           this.select((this.clickedNode && this.clickedNode.id) || this.root);
+       },    
+
+       reposition: function() {
+            this.graph.computeLevels(this.root, 0, "ignore");
+             this.geom.setRightLevelToShow(this.clickedNode, this.canvas);
+            this.graph.eachNode(function(n) {
+                if(n.exist) n.drawn = true;
+            });
+            this.compute('end');
+        },
+        
+        requestNodes: function(node, onComplete) {
+          var handler = $.merge(this.controller, onComplete), 
+          lev = this.config.levelsToShow;
+          if(handler.request) {
+              var leaves = [], d = node._depth;
+              node.eachLevel(0, lev, function(n) {
+                  if(n.drawn && 
+                   !n.anySubnode()) {
+                   leaves.push(n);
+                   n._level = lev - (n._depth - d);
+                  }
+              });
+              this.group.requestNodes(leaves, handler);
+          }
+            else
+              handler.onComplete();
+        },
+     
+        contract: function(onComplete, switched) {
+          var orn  = this.config.orientation;
+          var Geom = this.geom, Group = this.group;
+          if(switched) Geom.switchOrientation(switched);
+          var nodes = getNodesToHide.call(this);
+          if(switched) Geom.switchOrientation(orn);
+          Group.contract(nodes, $.merge(this.controller, onComplete));
+        },
+      
+         move: function(node, onComplete) {
+            this.compute('end', false);
+            var move = onComplete.Move, offset = {
+                'x': move.offsetX,
+                'y': move.offsetY 
+            };
+            if(move.enable) {
+                this.geom.translate(node.endPos.add(offset).$scale(-1), "end");
+            }
+            this.fx.animate($.merge(this.controller, { modes: ['linear'] }, onComplete));
+         },
+      
+        expand: function (node, onComplete) {
+            var nodeArray = getNodesToShow.call(this, node);
+            this.group.expand(nodeArray, $.merge(this.controller, onComplete));
+        },
+    
+        selectPath: function(node) {
+          var that = this;
+          this.graph.eachNode(function(n) { n.selected = false; }); 
+          function path(node) {
+              if(node == null || node.selected) return;
+              node.selected = true;
+              $.each(that.group.getSiblings([node])[node.id], 
+              function(n) { 
+                   n.exist = true; 
+                   n.drawn = true; 
+              });    
+              var parents = node.getParents();
+              parents = (parents.length > 0)? parents[0] : null;
+              path(parents);
+          };
+          for(var i=0, ns = [node.id].concat(nodesInPath); i < ns.length; i++) {
+              path(this.graph.getNode(ns[i]));
+          }
+        },
+      
+        /*
+        Method: setRoot
+     
+         Switches the current root node. Changes the topology of the Tree.
+     
+        Parameters:
+           id - (string) The id of the node to be set as root.
+           method - (string) Set this to "animate" if you want to animate the tree after adding the subtree. You can also set this parameter to "replot" to just replot the subtree.
+           onComplete - (optional|object) An action to perform after the animation (if any).
+ 
+        Example:
+
+        (start code js)
+          st.setRoot('nodeId', 'animate', {
+             onComplete: function() {
+               alert('complete!');
+             }
+          });
+        (end code)
+     */
+     setRoot: function(id, method, onComplete) {
+        	if(this.busy) return;
+        	this.busy = true;
+          var that = this, canvas = this.canvas;
+        	var rootNode = this.graph.getNode(this.root);
+        	var clickedNode = this.graph.getNode(id);
+        	function $setRoot() {
+            	if(this.config.multitree && clickedNode.data.$orn) {
+            		var orn = clickedNode.data.$orn;
+            		var opp = {
+            				'left': 'right',
+            				'right': 'left',
+            				'top': 'bottom',
+            				'bottom': 'top'
+            		}[orn];
+            		rootNode.data.$orn = opp;
+            		(function tag(rootNode) {
+                		rootNode.eachSubnode(function(n) {
+                			if(n.id != id) {
+                				n.data.$orn = opp;
+                				tag(n);
+                			}
+                		});
+            		})(rootNode);
+            		delete clickedNode.data.$orn;
+            	}
+            	this.root = id;
+            	this.clickedNode = clickedNode;
+            	this.graph.computeLevels(this.root, 0, "ignore");
+            	this.geom.setRightLevelToShow(clickedNode, canvas, {
+            	  execHide: false,
+            	  onShow: function(node) {
+            	    if(!node.drawn) {
+                    node.drawn = true;
+                    node.setData('alpha', 1, 'end');
+                    node.setData('alpha', 0);
+                    node.pos.setc(clickedNode.pos.x, clickedNode.pos.y);
+            	    }
+            	  }
+            	});
+              this.compute('end');
+              this.busy = true;
+              this.fx.animate({
+                modes: ['linear', 'node-property:alpha'],
+                onComplete: function() {
+                  that.busy = false;
+                  that.onClick(id, {
+                    onComplete: function() {
+                      onComplete && onComplete.onComplete();
+                    }
+                  });
+                }
+              });
+        	}
+
+        	// delete previous orientations (if any)
+        	delete rootNode.data.$orns;
+
+        	if(method == 'animate') {
+        	  $setRoot.call(this);
+        	  that.selectPath(clickedNode);
+        	} else if(method == 'replot') {
+        		$setRoot.call(this);
+        		this.select(this.root);
+        	}
+     },
+
+     /*
+           Method: addSubtree
+        
+            Adds a subtree.
+        
+           Parameters:
+              subtree - (object) A JSON Tree object. See also <Loader.loadJSON>.
+              method - (string) Set this to "animate" if you want to animate the tree after adding the subtree. You can also set this parameter to "replot" to just replot the subtree.
+              onComplete - (optional|object) An action to perform after the animation (if any).
+    
+           Example:
+
+           (start code js)
+             st.addSubtree(json, 'animate', {
+                onComplete: function() {
+                  alert('complete!');
+                }
+             });
+           (end code)
+        */
+        addSubtree: function(subtree, method, onComplete) {
+            if(method == 'replot') {
+                this.op.sum(subtree, $.extend({ type: 'replot' }, onComplete || {}));
+            } else if (method == 'animate') {
+                this.op.sum(subtree, $.extend({ type: 'fade:seq' }, onComplete || {}));
+            }
+        },
+    
+        /*
+           Method: removeSubtree
+        
+            Removes a subtree.
+        
+           Parameters:
+              id - (string) The _id_ of the subtree to be removed.
+              removeRoot - (boolean) Default's *false*. Remove the root of the subtree or only its subnodes.
+              method - (string) Set this to "animate" if you want to animate the tree after removing the subtree. You can also set this parameter to "replot" to just replot the subtree.
+              onComplete - (optional|object) An action to perform after the animation (if any).
+
+          Example:
+
+          (start code js)
+            st.removeSubtree('idOfSubtreeToBeRemoved', false, 'animate', {
+              onComplete: function() {
+                alert('complete!');
+              }
+            });
+          (end code)
+    
+        */
+        removeSubtree: function(id, removeRoot, method, onComplete) {
+            var node = this.graph.getNode(id), subids = [];
+            node.eachLevel(+!removeRoot, false, function(n) {
+                subids.push(n.id);
+            });
+            if(method == 'replot') {
+                this.op.removeNode(subids, $.extend({ type: 'replot' }, onComplete || {}));
+            } else if (method == 'animate') {
+                this.op.removeNode(subids, $.extend({ type: 'fade:seq'}, onComplete || {}));
+            }
+        },
+    
+        /*
+           Method: select
+        
+            Selects a node in the <ST> without performing an animation. Useful when selecting 
+            nodes which are currently hidden or deep inside the tree.
+
+          Parameters:
+            id - (string) The id of the node to select.
+            onComplete - (optional|object) an onComplete callback.
+
+          Example:
+          (start code js)
+            st.select('mynodeid', {
+              onComplete: function() {
+                alert('complete!');
+              }
+            });
+          (end code)
+        */
+        select: function(id, onComplete) {
+            var group = this.group, geom = this.geom;
+            var node=  this.graph.getNode(id), canvas = this.canvas;
+            var root  = this.graph.getNode(this.root);
+            var complete = $.merge(this.controller, onComplete);
+            var that = this;
+    
+            complete.onBeforeCompute(node);
+            this.selectPath(node);
+            this.clickedNode= node;
+            this.requestNodes(node, {
+                onComplete: function(){
+                    group.hide(group.prepare(getNodesToHide.call(that)), complete);
+                    geom.setRightLevelToShow(node, canvas);
+                    that.compute("current");
+                    that.graph.eachNode(function(n) { 
+                        var pos = n.pos.getc(true);
+                        n.startPos.setc(pos.x, pos.y);
+                        n.endPos.setc(pos.x, pos.y);
+                        n.visited = false; 
+                    });
+                    var offset = { x: complete.offsetX, y: complete.offsetY };
+                    that.geom.translate(node.endPos.add(offset).$scale(-1), ["start", "current", "end"]);
+                    group.show(getNodesToShow.call(that));              
+                    that.plot();
+                    complete.onAfterCompute(that.clickedNode);
+                    complete.onComplete();
+                }
+            });     
+        },
+    
+      /*
+         Method: onClick
+    
+        Animates the <ST> to center the node specified by *id*.
+            
+        Parameters:
+        
+        id - (string) A node id.
+        options - (optional|object) A group of options and callbacks described below.
+        onComplete - (object) An object callback called when the animation finishes.
+        Move - (object) An object that has as properties _offsetX_ or _offsetY_ for adding some offset position to the centered node.
+
+        Example:
+
+        (start code js)
+          st.onClick('mynodeid', {
+	          Move: {
+	          	enable: true,
+	            offsetX: 30,
+	            offsetY: 5
+	          },
+	          onComplete: function() {
+	              alert('yay!');
+	          }
+          });
+        (end code)
+    
+        */    
+      onClick: function (id, options) {
+        var canvas = this.canvas, that = this, Geom = this.geom, config = this.config;
+        var innerController = {
+            Move: {
+        	    enable: true,
+              offsetX: config.offsetX || 0,
+              offsetY: config.offsetY || 0  
+            },
+            setRightLevelToShowConfig: false,
+            onBeforeRequest: $.empty,
+            onBeforeContract: $.empty,
+            onBeforeMove: $.empty,
+            onBeforeExpand: $.empty
+        };
+        var complete = $.merge(this.controller, innerController, options);
+        
+        if(!this.busy) {
+            this.busy = true;
+            var node = this.graph.getNode(id);
+            this.selectPath(node, this.clickedNode);
+           	this.clickedNode = node;
+            complete.onBeforeCompute(node);
+            complete.onBeforeRequest(node);
+            this.requestNodes(node, {
+                onComplete: function() {
+                    complete.onBeforeContract(node);
+                    that.contract({
+                        onComplete: function() {
+                            Geom.setRightLevelToShow(node, canvas, complete.setRightLevelToShowConfig);
+                            complete.onBeforeMove(node);
+                            that.move(node, {
+                                Move: complete.Move,
+                                onComplete: function() {
+                                    complete.onBeforeExpand(node);
+                                    that.expand(node, {
+                                        onComplete: function() {
+                                            that.busy = false;
+                                            complete.onAfterCompute(id);
+                                            complete.onComplete();
+                                        }
+                                    }); // expand
+                                }
+                            }); // move
+                        }
+                    });// contract
+                }
+            });// request
+        }
+      }
+    });
+
+})();
+
+$jit.ST.$extend = true;
+
+/*
+   Class: ST.Op
+    
+   Custom extension of <Graph.Op>.
+
+   Extends:
+
+   All <Graph.Op> methods
+   
+   See also:
+   
+   <Graph.Op>
+
+*/
+$jit.ST.Op = new Class({
+
+  Implements: Graph.Op
+    
+});
+
+/*
+    
+     Performs operations on group of nodes.
+
+*/
+$jit.ST.Group = new Class({
+    
+    initialize: function(viz) {
+        this.viz = viz;
+        this.canvas = viz.canvas;
+        this.config = viz.config;
+        this.animation = new Animation;
+        this.nodes = null;
+    },
+    
+    /*
+    
+       Calls the request method on the controller to request a subtree for each node. 
+    */
+    requestNodes: function(nodes, controller) {
+        var counter = 0, len = nodes.length, nodeSelected = {};
+        var complete = function() { controller.onComplete(); };
+        var viz = this.viz;
+        if(len == 0) complete();
+        for(var i=0; i<len; i++) {
+            nodeSelected[nodes[i].id] = nodes[i];
+            controller.request(nodes[i].id, nodes[i]._level, {
+                onComplete: function(nodeId, data) {
+                    if(data && data.children) {
+                        data.id = nodeId;
+                        viz.op.sum(data, { type: 'nothing' });
+                    }
+                    if(++counter == len) {
+                        viz.graph.computeLevels(viz.root, 0);
+                        complete();
+                    }
+                }
+            });
+        }
+    },
+    
+    /*
+    
+       Collapses group of nodes. 
+    */
+    contract: function(nodes, controller) {
+        var viz = this.viz;
+        var that = this;
+
+        nodes = this.prepare(nodes);
+        this.animation.setOptions($.merge(controller, {
+            $animating: false,
+            compute: function(delta) {
+              if(delta == 1) delta = 0.99;
+              that.plotStep(1 - delta, controller, this.$animating);
+              this.$animating = 'contract';
+            },
+            
+            complete: function() {
+                that.hide(nodes, controller);
+            }       
+        })).start();
+    },
+    
+    hide: function(nodes, controller) {
+        var viz = this.viz;
+        for(var i=0; i<nodes.length; i++) {
+            // TODO nodes are requested on demand, but not
+            // deleted when hidden. Would that be a good feature?
+            // Currently that feature is buggy, so I'll turn it off
+            // Actually this feature is buggy because trimming should take
+            // place onAfterCompute and not right after collapsing nodes.
+            if (true || !controller || !controller.request) {
+                nodes[i].eachLevel(1, false, function(elem){
+                    if (elem.exist) {
+                        $.extend(elem, {
+                            'drawn': false,
+                            'exist': false
+                        });
+                    }
+                });
+            } else {
+                var ids = [];
+                nodes[i].eachLevel(1, false, function(n) {
+                    ids.push(n.id);
+                });
+                viz.op.removeNode(ids, { 'type': 'nothing' });
+                viz.labels.clearLabels();
+            }
+        }
+        controller.onComplete();
+    },    
+    
+
+    /*
+       Expands group of nodes. 
+    */
+    expand: function(nodes, controller) {
+        var that = this;
+        this.show(nodes);
+        this.animation.setOptions($.merge(controller, {
+            $animating: false,
+            compute: function(delta) {
+                that.plotStep(delta, controller, this.$animating);
+                this.$animating = 'expand';
+            },
+            
+            complete: function() {
+                that.plotStep(undefined, controller, false);
+                controller.onComplete();
+            }       
+        })).start();
+        
+    },
+    
+    show: function(nodes) {
+        var config = this.config;
+        this.prepare(nodes);
+        $.each(nodes, function(n) {
+        	// check for root nodes if multitree
+        	if(config.multitree && !('$orn' in n.data)) {
+        		delete n.data.$orns;
+        		var orns = ' ';
+        		n.eachSubnode(function(ch) {
+        			if(('$orn' in ch.data) 
+        					&& orns.indexOf(ch.data.$orn) < 0 
+        					&& ch.exist && !ch.drawn) {
+        				orns += ch.data.$orn + ' ';
+        			}
+        		});
+        		n.data.$orns = orns;
+        	}
+            n.eachLevel(0, config.levelsToShow, function(n) {
+            	if(n.exist) n.drawn = true;
+            });     
+        });
+    },
+    
+    prepare: function(nodes) {
+        this.nodes = this.getNodesWithChildren(nodes);
+        return this.nodes;
+    },
+    
+    /*
+       Filters an array of nodes leaving only nodes with children.
+    */
+    getNodesWithChildren: function(nodes) {
+        var ans = [], config = this.config, root = this.viz.root;
+        nodes.sort(function(a, b) { return (a._depth <= b._depth) - (a._depth >= b._depth); });
+        for(var i=0; i<nodes.length; i++) {
+            if(nodes[i].anySubnode("exist")) {
+            	for (var j = i+1, desc = false; !desc && j < nodes.length; j++) {
+                    if(!config.multitree || '$orn' in nodes[j].data) {
+                		desc = desc || nodes[i].isDescendantOf(nodes[j].id);                    	
+                    }
+                }
+                if(!desc) ans.push(nodes[i]);
+            }
+        }
+        return ans;
+    },
+    
+    plotStep: function(delta, controller, animating) {
+        var viz = this.viz,
+        config = this.config,
+        canvas = viz.canvas, 
+        ctx = canvas.getCtx(),
+        nodes = this.nodes;
+        var i, node;
+        // hide nodes that are meant to be collapsed/expanded
+        var nds = {};
+        for(i=0; i<nodes.length; i++) {
+          node = nodes[i];
+          nds[node.id] = [];
+          var root = config.multitree && !('$orn' in node.data);
+          var orns = root && node.data.$orns;
+          node.eachSubgraph(function(n) { 
+            // TODO(nico): Cleanup
+        	  // special check for root node subnodes when
+        	  // multitree is checked.
+        	  if(root && orns && orns.indexOf(n.data.$orn) > 0 
+        			  && n.drawn) {
+        		  n.drawn = false;
+                  nds[node.id].push(n);
+              } else if((!root || !orns) && n.drawn) {
+                n.drawn = false;
+                nds[node.id].push(n);
+              }
+            });	
+            node.drawn = true;
+        }
+        // plot the whole (non-scaled) tree
+        if(nodes.length > 0) viz.fx.plot();
+        // show nodes that were previously hidden
+        for(i in nds) {
+          $.each(nds[i], function(n) { n.drawn = true; });
+        }
+        // plot each scaled subtree
+        for(i=0; i<nodes.length; i++) {
+          node = nodes[i];
+          ctx.save();
+          viz.fx.plotSubtree(node, controller, delta, animating);                
+          ctx.restore();
+        }
+      },
+
+      getSiblings: function(nodes) {
+        var siblings = {};
+        $.each(nodes, function(n) {
+            var par = n.getParents();
+            if (par.length == 0) {
+                siblings[n.id] = [n];
+            } else {
+                var ans = [];
+                par[0].eachSubnode(function(sn) {
+                    ans.push(sn);
+                });
+                siblings[n.id] = ans;
+            }
+        });
+        return siblings;
+    }
+});
+
+/*
+   ST.Geom
+
+   Performs low level geometrical computations.
+
+   Access:
+
+   This instance can be accessed with the _geom_ parameter of the st instance created.
+
+   Example:
+
+   (start code js)
+    var st = new ST(canvas, config);
+    st.geom.translate //or can also call any other <ST.Geom> method
+   (end code)
+
+*/
+
+$jit.ST.Geom = new Class({
+    Implements: Graph.Geom,
+    /*
+       Changes the tree current orientation to the one specified.
+
+       You should usually use <ST.switchPosition> instead.
+    */  
+    switchOrientation: function(orn) {
+    	this.config.orientation = orn;
+    },
+
+    /*
+       Makes a value dispatch according to the current layout
+       Works like a CSS property, either _top-right-bottom-left_ or _top|bottom - left|right_.
+     */
+    dispatch: function() {
+    	  // TODO(nico) should store Array.prototype.slice.call somewhere.
+        var args = Array.prototype.slice.call(arguments);
+        var s = args.shift(), len = args.length;
+        var val = function(a) { return typeof a == 'function'? a() : a; };
+        if(len == 2) {
+            return (s == "top" || s == "bottom")? val(args[0]) : val(args[1]);
+        } else if(len == 4) {
+            switch(s) {
+                case "top": return val(args[0]);
+                case "right": return val(args[1]);
+                case "bottom": return val(args[2]);
+                case "left": return val(args[3]);
+            }
+        }
+        return undefined;
+    },
+
+    /*
+       Returns label height or with, depending on the tree current orientation.
+    */  
+    getSize: function(n, invert) {
+        var data = n.data, config = this.config;
+        var siblingOffset = config.siblingOffset;
+        var s = (config.multitree 
+        		&& ('$orn' in data) 
+        		&& data.$orn) || config.orientation;
+        var w = n.getData('width') + siblingOffset;
+        var h = n.getData('height') + siblingOffset;
+        if(!invert)
+            return this.dispatch(s, h, w);
+        else
+            return this.dispatch(s, w, h);
+    },
+    
+    /*
+       Calculates a subtree base size. This is an utility function used by _getBaseSize_
+    */  
+    getTreeBaseSize: function(node, level, leaf) {
+        var size = this.getSize(node, true), baseHeight = 0, that = this;
+        if(leaf(level, node)) return size;
+        if(level === 0) return 0;
+        node.eachSubnode(function(elem) {
+            baseHeight += that.getTreeBaseSize(elem, level -1, leaf);
+        });
+        return (size > baseHeight? size : baseHeight) + this.config.subtreeOffset;
+    },
+
+
+    /*
+       getEdge
+       
+       Returns a Complex instance with the begin or end position of the edge to be plotted.
+
+       Parameters:
+
+       node - A <Graph.Node> that is connected to this edge.
+       type - Returns the begin or end edge position. Possible values are 'begin' or 'end'.
+
+       Returns:
+
+       A <Complex> number specifying the begin or end position.
+    */  
+    getEdge: function(node, type, s) {
+    	var $C = function(a, b) { 
+          return function(){
+            return node.pos.add(new Complex(a, b));
+          }; 
+        };
+        var dim = this.node;
+        var w = node.getData('width');
+        var h = node.getData('height');
+
+        if(type == 'begin') {
+            if(dim.align == "center") {
+                return this.dispatch(s, $C(0, h/2), $C(-w/2, 0),
+                                     $C(0, -h/2),$C(w/2, 0));
+            } else if(dim.align == "left") {
+                return this.dispatch(s, $C(0, h), $C(0, 0),
+                                     $C(0, 0), $C(w, 0));
+            } else if(dim.align == "right") {
+                return this.dispatch(s, $C(0, 0), $C(-w, 0),
+                                     $C(0, -h),$C(0, 0));
+            } else throw "align: not implemented";
+            
+            
+        } else if(type == 'end') {
+            if(dim.align == "center") {
+                return this.dispatch(s, $C(0, -h/2), $C(w/2, 0),
+                                     $C(0, h/2),  $C(-w/2, 0));
+            } else if(dim.align == "left") {
+                return this.dispatch(s, $C(0, 0), $C(w, 0),
+                                     $C(0, h), $C(0, 0));
+            } else if(dim.align == "right") {
+                return this.dispatch(s, $C(0, -h),$C(0, 0),
+                                     $C(0, 0), $C(-w, 0));
+            } else throw "align: not implemented";
+        }
+    },
+
+    /*
+       Adjusts the tree position due to canvas scaling or translation.
+    */  
+    getScaledTreePosition: function(node, scale) {
+        var dim = this.node;
+        var w = node.getData('width');
+        var h = node.getData('height');
+        var s = (this.config.multitree 
+        		&& ('$orn' in node.data) 
+        		&& node.data.$orn) || this.config.orientation;
+
+        var $C = function(a, b) { 
+          return function(){
+            return node.pos.add(new Complex(a, b)).$scale(1 - scale);
+          }; 
+        };
+        if(dim.align == "left") {
+            return this.dispatch(s, $C(0, h), $C(0, 0),
+                                 $C(0, 0), $C(w, 0));
+        } else if(dim.align == "center") {
+            return this.dispatch(s, $C(0, h / 2), $C(-w / 2, 0),
+                                 $C(0, -h / 2),$C(w / 2, 0));
+        } else if(dim.align == "right") {
+            return this.dispatch(s, $C(0, 0), $C(-w, 0),
+                                 $C(0, -h),$C(0, 0));
+        } else throw "align: not implemented";
+    },
+
+    /*
+       treeFitsInCanvas
+       
+       Returns a Boolean if the current subtree fits in canvas.
+
+       Parameters:
+
+       node - A <Graph.Node> which is the current root of the subtree.
+       canvas - The <Canvas> object.
+       level - The depth of the subtree to be considered.
+    */  
+    treeFitsInCanvas: function(node, canvas, level) {
+        var csize = canvas.getSize();
+        var s = (this.config.multitree 
+        		&& ('$orn' in node.data) 
+        		&& node.data.$orn) || this.config.orientation;
+
+        var size = this.dispatch(s, csize.width, csize.height);
+        var baseSize = this.getTreeBaseSize(node, level, function(level, node) { 
+          return level === 0 || !node.anySubnode();
+        });
+        return (baseSize < size);
+    }
+});
+
+/*
+  Class: ST.Plot
+  
+  Custom extension of <Graph.Plot>.
+
+  Extends:
+
+  All <Graph.Plot> methods
+  
+  See also:
+  
+  <Graph.Plot>
+
+*/
+$jit.ST.Plot = new Class({
+    
+    Implements: Graph.Plot,
+    
+    /*
+       Plots a subtree from the spacetree.
+    */
+    plotSubtree: function(node, opt, scale, animating) {
+        var viz = this.viz, canvas = viz.canvas, config = viz.config;
+        scale = Math.min(Math.max(0.001, scale), 1);
+        if(scale >= 0) {
+            node.drawn = false;     
+            var ctx = canvas.getCtx();
+            var diff = viz.geom.getScaledTreePosition(node, scale);
+            ctx.translate(diff.x, diff.y);
+            ctx.scale(scale, scale);
+        }
+        this.plotTree(node, $.merge(opt, {
+          'withLabels': true,
+          'hideLabels': !!scale,
+          'plotSubtree': function(n, ch) {
+            var root = config.multitree && !('$orn' in node.data);
+            var orns = root && node.getData('orns');
+            return !root || orns.indexOf(node.getData('orn')) > -1;
+          }
+        }), animating);
+        if(scale >= 0) node.drawn = true;
+    },   
+   
+    /*
+        Method: getAlignedPos
+        
+        Returns a *x, y* object with the position of the top/left corner of a <ST> node.
+        
+        Parameters:
+        
+        pos - (object) A <Graph.Node> position.
+        width - (number) The width of the node.
+        height - (number) The height of the node.
+        
+     */
+    getAlignedPos: function(pos, width, height) {
+        var nconfig = this.node;
+        var square, orn;
+        if(nconfig.align == "center") {
+            square = {
+                x: pos.x - width / 2,
+                y: pos.y - height / 2
+            };
+        } else if (nconfig.align == "left") {
+            orn = this.config.orientation;
+            if(orn == "bottom" || orn == "top") {
+                square = {
+                    x: pos.x - width / 2,
+                    y: pos.y
+                };
+            } else {
+                square = {
+                    x: pos.x,
+                    y: pos.y - height / 2
+                };
+            }
+        } else if(nconfig.align == "right") {
+            orn = this.config.orientation;
+            if(orn == "bottom" || orn == "top") {
+                square = {
+                    x: pos.x - width / 2,
+                    y: pos.y - height
+                };
+            } else {
+                square = {
+                    x: pos.x - width,
+                    y: pos.y - height / 2
+                };
+            }
+        } else throw "align: not implemented";
+        
+        return square;
+    },
+    
+    getOrientation: function(adj) {
+    	var config = this.config;
+    	var orn = config.orientation;
+
+    	if(config.multitree) {
+        	var nodeFrom = adj.nodeFrom;
+        	var nodeTo = adj.nodeTo;
+    		orn = (('$orn' in nodeFrom.data) 
+        		&& nodeFrom.data.$orn) 
+        		|| (('$orn' in nodeTo.data) 
+        		&& nodeTo.data.$orn);
+    	}
+
+    	return orn; 
+    }
+});
+
+/*
+  Class: ST.Label
+
+  Custom extension of <Graph.Label>. 
+  Contains custom <Graph.Label.SVG>, <Graph.Label.HTML> and <Graph.Label.Native> extensions.
+
+  Extends:
+
+  All <Graph.Label> methods and subclasses.
+
+  See also:
+
+  <Graph.Label>, <Graph.Label.Native>, <Graph.Label.HTML>, <Graph.Label.SVG>.
+ */ 
+$jit.ST.Label = {};
+
+/*
+   ST.Label.Native
+
+   Custom extension of <Graph.Label.Native>.
+
+   Extends:
+
+   All <Graph.Label.Native> methods
+
+   See also:
+
+   <Graph.Label.Native>
+*/
+$jit.ST.Label.Native = new Class({
+  Implements: Graph.Label.Native,
+
+  renderLabel: function(canvas, node, controller) {
+    var ctx = canvas.getCtx(),
+        coord = node.pos.getc(true),
+        width = node.getData('width'),
+        height = node.getData('height'),
+        pos = this.viz.fx.getAlignedPos(coord, width, height);
+    ctx.fillText(node.name, pos.x + width / 2, pos.y + height / 2);
+  }
+});
+
+$jit.ST.Label.DOM = new Class({
+  Implements: Graph.Label.DOM,
+
+  /* 
+      placeLabel
+
+      Overrides abstract method placeLabel in <Graph.Plot>.
+
+      Parameters:
+
+      tag - A DOM label element.
+      node - A <Graph.Node>.
+      controller - A configuration/controller object passed to the visualization.
+     
+    */
+    placeLabel: function(tag, node, controller) {
+        var pos = node.pos.getc(true), 
+            config = this.viz.config, 
+            dim = config.Node, 
+            canvas = this.viz.canvas,
+            w = node.getData('width'),
+            h = node.getData('height'),
+            radius = canvas.getSize(),
+            labelPos, orn;
+        
+        var ox = canvas.translateOffsetX,
+            oy = canvas.translateOffsetY,
+            sx = canvas.scaleOffsetX,
+            sy = canvas.scaleOffsetY,
+            posx = pos.x * sx + ox,
+            posy = pos.y * sy + oy;
+
+        if(dim.align == "center") {
+            labelPos= {
+                x: Math.round(posx - w / 2 + radius.width/2),
+                y: Math.round(posy - h / 2 + radius.height/2)
+            };
+        } else if (dim.align == "left") {
+            orn = config.orientation;
+            if(orn == "bottom" || orn == "top") {
+                labelPos= {
+                    x: Math.round(posx - w / 2 + radius.width/2),
+                    y: Math.round(posy + radius.height/2)
+                };
+            } else {
+                labelPos= {
+                    x: Math.round(posx + radius.width/2),
+                    y: Math.round(posy - h / 2 + radius.height/2)
+                };
+            }
+        } else if(dim.align == "right") {
+            orn = config.orientation;
+            if(orn == "bottom" || orn == "top") {
+                labelPos= {
+                    x: Math.round(posx - w / 2 + radius.width/2),
+                    y: Math.round(posy - h + radius.height/2)
+                };
+            } else {
+                labelPos= {
+                    x: Math.round(posx - w + radius.width/2),
+                    y: Math.round(posy - h / 2 + radius.height/2)
+                };
+            }
+        } else throw "align: not implemented";
+
+        var style = tag.style;
+        style.left = labelPos.x + 'px';
+        style.top  = labelPos.y + 'px';
+        style.display = this.fitsInCanvas(labelPos, canvas)? '' : 'none';
+        controller.onPlaceLabel(tag, node);
+    }
+});
+
+/*
+  ST.Label.SVG
+
+  Custom extension of <Graph.Label.SVG>.
+
+  Extends:
+
+  All <Graph.Label.SVG> methods
+
+  See also:
+
+  <Graph.Label.SVG>
+*/
+$jit.ST.Label.SVG = new Class({
+  Implements: [$jit.ST.Label.DOM, Graph.Label.SVG],
+
+  initialize: function(viz) {
+    this.viz = viz;
+  }
+});
+
+/*
+   ST.Label.HTML
+
+   Custom extension of <Graph.Label.HTML>.
+
+   Extends:
+
+   All <Graph.Label.HTML> methods.
+
+   See also:
+
+   <Graph.Label.HTML>
+
+*/
+$jit.ST.Label.HTML = new Class({
+  Implements: [$jit.ST.Label.DOM, Graph.Label.HTML],
+
+  initialize: function(viz) {
+    this.viz = viz;
+  }
+});
+
+
+/*
+  Class: ST.Plot.NodeTypes
+
+  This class contains a list of <Graph.Node> built-in types. 
+  Node types implemented are 'none', 'circle', 'rectangle', 'ellipse' and 'square'.
+
+  You can add your custom node types, customizing your visualization to the extreme.
+
+  Example:
+
+  (start code js)
+    ST.Plot.NodeTypes.implement({
+      'mySpecialType': {
+        'render': function(node, canvas) {
+          //print your custom node to canvas
+        },
+        //optional
+        'contains': function(node, pos) {
+          //return true if pos is inside the node or false otherwise
+        }
+      }
+    });
+  (end code)
+
+*/
+$jit.ST.Plot.NodeTypes = new Class({
+  'none': {
+    'render': $.empty,
+    'contains': $.lambda(false)
+  },
+  'circle': {
+    'render': function(node, canvas) {
+      var dim  = node.getData('dim'),
+          pos = this.getAlignedPos(node.pos.getc(true), dim, dim),
+          dim2 = dim/2;
+      this.nodeHelper.circle.render('fill', {x:pos.x+dim2, y:pos.y+dim2}, dim2, canvas);
+    },
+    'contains': function(node, pos) {
+      var dim  = node.getData('dim'),
+          npos = this.getAlignedPos(node.pos.getc(true), dim, dim),
+          dim2 = dim/2;
+      this.nodeHelper.circle.contains({x:npos.x+dim2, y:npos.y+dim2}, pos, dim2);
+    }
+  },
+  'square': {
+    'render': function(node, canvas) {
+      var dim  = node.getData('dim'),
+          dim2 = dim/2,
+          pos = this.getAlignedPos(node.pos.getc(true), dim, dim);
+      this.nodeHelper.square.render('fill', {x:pos.x+dim2, y:pos.y+dim2}, dim2, canvas);
+    },
+    'contains': function(node, pos) {
+      var dim  = node.getData('dim'),
+          npos = this.getAlignedPos(node.pos.getc(true), dim, dim),
+          dim2 = dim/2;
+      this.nodeHelper.square.contains({x:npos.x+dim2, y:npos.y+dim2}, pos, dim2);
+    }
+  },
+  'ellipse': {
+    'render': function(node, canvas) {
+      var width = node.getData('width'),
+          height = node.getData('height'),
+          pos = this.getAlignedPos(node.pos.getc(true), width, height);
+      this.nodeHelper.ellipse.render('fill', {x:pos.x+width/2, y:pos.y+height/2}, width, height, canvas);
+    },
+    'contains': function(node, pos) {
+      var width = node.getData('width'),
+          height = node.getData('height'),
+          npos = this.getAlignedPos(node.pos.getc(true), width, height);
+      this.nodeHelper.ellipse.contains({x:npos.x+width/2, y:npos.y+height/2}, pos, width, height);
+    }
+  },
+  'rectangle': {
+    'render': function(node, canvas) {
+      var width = node.getData('width'),
+          height = node.getData('height'),
+          pos = this.getAlignedPos(node.pos.getc(true), width, height);
+      this.nodeHelper.rectangle.render('fill', {x:pos.x+width/2, y:pos.y+height/2}, width, height, canvas);
+    },
+    'contains': function(node, pos) {
+      var width = node.getData('width'),
+          height = node.getData('height'),
+          npos = this.getAlignedPos(node.pos.getc(true), width, height);
+      this.nodeHelper.rectangle.contains({x:npos.x+width/2, y:npos.y+height/2}, pos, width, height);
+    }
+  }
+});
+
+/*
+  Class: ST.Plot.EdgeTypes
+
+  This class contains a list of <Graph.Adjacence> built-in types. 
+  Edge types implemented are 'none', 'line', 'arrow', 'quadratic:begin', 'quadratic:end', 'bezier'.
+
+  You can add your custom edge types, customizing your visualization to the extreme.
+
+  Example:
+
+  (start code js)
+    ST.Plot.EdgeTypes.implement({
+      'mySpecialType': {
+        'render': function(adj, canvas) {
+          //print your custom edge to canvas
+        },
+        //optional
+        'contains': function(adj, pos) {
+          //return true if pos is inside the arc or false otherwise
+        }
+      }
+    });
+  (end code)
+
+*/
+$jit.ST.Plot.EdgeTypes = new Class({
+    'none': $.empty,
+    'line': {
+      'render': function(adj, canvas) {
+        var orn = this.getOrientation(adj),
+            nodeFrom = adj.nodeFrom, 
+            nodeTo = adj.nodeTo,
+            rel = nodeFrom._depth < nodeTo._depth,
+            from = this.viz.geom.getEdge(rel? nodeFrom:nodeTo, 'begin', orn),
+            to =  this.viz.geom.getEdge(rel? nodeTo:nodeFrom, 'end', orn);
+        this.edgeHelper.line.render(from, to, canvas);
+      },
+      'contains': function(adj, pos) {
+        var orn = this.getOrientation(adj),
+            nodeFrom = adj.nodeFrom, 
+            nodeTo = adj.nodeTo,
+            rel = nodeFrom._depth < nodeTo._depth,
+            from = this.viz.geom.getEdge(rel? nodeFrom:nodeTo, 'begin', orn),
+            to =  this.viz.geom.getEdge(rel? nodeTo:nodeFrom, 'end', orn);
+        return this.edgeHelper.line.contains(from, to, pos, this.edge.epsilon);
+      }
+    },
+     'arrow': {
+       'render': function(adj, canvas) {
+         var orn = this.getOrientation(adj),
+             node = adj.nodeFrom, 
+             child = adj.nodeTo,
+             dim = adj.getData('dim'),
+             from = this.viz.geom.getEdge(node, 'begin', orn),
+             to = this.viz.geom.getEdge(child, 'end', orn),
+             direction = adj.data.$direction,
+             inv = (direction && direction.length>1 && direction[0] != node.id);
+         this.edgeHelper.arrow.render(from, to, dim, inv, canvas);
+       },
+       'contains': function(adj, pos) {
+         var orn = this.getOrientation(adj),
+             nodeFrom = adj.nodeFrom, 
+             nodeTo = adj.nodeTo,
+             rel = nodeFrom._depth < nodeTo._depth,
+             from = this.viz.geom.getEdge(rel? nodeFrom:nodeTo, 'begin', orn),
+             to =  this.viz.geom.getEdge(rel? nodeTo:nodeFrom, 'end', orn);
+         return this.edgeHelper.arrow.contains(from, to, pos, this.edge.epsilon);
+       }
+     },
+    'quadratic:begin': {
+       'render': function(adj, canvas) {
+          var orn = this.getOrientation(adj);
+          var nodeFrom = adj.nodeFrom, 
+              nodeTo = adj.nodeTo,
+              rel = nodeFrom._depth < nodeTo._depth,
+              begin = this.viz.geom.getEdge(rel? nodeFrom:nodeTo, 'begin', orn),
+              end =  this.viz.geom.getEdge(rel? nodeTo:nodeFrom, 'end', orn),
+              dim = adj.getData('dim'),
+              ctx = canvas.getCtx();
+          ctx.beginPath();
+          ctx.moveTo(begin.x, begin.y);
+          switch(orn) {
+            case "left":
+              ctx.quadraticCurveTo(begin.x + dim, begin.y, end.x, end.y);
+              break;
+            case "right":
+              ctx.quadraticCurveTo(begin.x - dim, begin.y, end.x, end.y);
+              break;
+            case "top":
+              ctx.quadraticCurveTo(begin.x, begin.y + dim, end.x, end.y);
+              break;
+            case "bottom":
+              ctx.quadraticCurveTo(begin.x, begin.y - dim, end.x, end.y);
+              break;
+          }
+          ctx.stroke();
+        }
+     },
+    'quadratic:end': {
+       'render': function(adj, canvas) {
+          var orn = this.getOrientation(adj);
+          var nodeFrom = adj.nodeFrom, 
+              nodeTo = adj.nodeTo,
+              rel = nodeFrom._depth < nodeTo._depth,
+              begin = this.viz.geom.getEdge(rel? nodeFrom:nodeTo, 'begin', orn),
+              end =  this.viz.geom.getEdge(rel? nodeTo:nodeFrom, 'end', orn),
+              dim = adj.getData('dim'),
+              ctx = canvas.getCtx();
+          ctx.beginPath();
+          ctx.moveTo(begin.x, begin.y);
+          switch(orn) {
+            case "left":
+              ctx.quadraticCurveTo(end.x - dim, end.y, end.x, end.y);
+              break;
+            case "right":
+              ctx.quadraticCurveTo(end.x + dim, end.y, end.x, end.y);
+              break;
+            case "top":
+              ctx.quadraticCurveTo(end.x, end.y - dim, end.x, end.y);
+              break;
+            case "bottom":
+              ctx.quadraticCurveTo(end.x, end.y + dim, end.x, end.y);
+              break;
+          }
+          ctx.stroke();
+       }
+     },
+    'bezier': {
+       'render': function(adj, canvas) {
+         var orn = this.getOrientation(adj),
+             nodeFrom = adj.nodeFrom, 
+             nodeTo = adj.nodeTo,
+             rel = nodeFrom._depth < nodeTo._depth,
+             begin = this.viz.geom.getEdge(rel? nodeFrom:nodeTo, 'begin', orn),
+             end =  this.viz.geom.getEdge(rel? nodeTo:nodeFrom, 'end', orn),
+             dim = adj.getData('dim'),
+             ctx = canvas.getCtx();
+         ctx.beginPath();
+         ctx.moveTo(begin.x, begin.y);
+         switch(orn) {
+           case "left":
+             ctx.bezierCurveTo(begin.x + dim, begin.y, end.x - dim, end.y, end.x, end.y);
+             break;
+           case "right":
+             ctx.bezierCurveTo(begin.x - dim, begin.y, end.x + dim, end.y, end.x, end.y);
+             break;
+           case "top":
+             ctx.bezierCurveTo(begin.x, begin.y + dim, end.x, end.y - dim, end.x, end.y);
+             break;
+           case "bottom":
+             ctx.bezierCurveTo(begin.x, begin.y - dim, end.x, end.y + dim, end.x, end.y);
+             break;
+         }
+         ctx.stroke();
+       }
+    }
+});
+
+
+
+/*
+ * File: AreaChart.js
+ *
+*/
+
+$jit.ST.Plot.NodeTypes.implement({
+  'areachart-stacked' : {
+    'render' : function(node, canvas) {
+      var pos = node.pos.getc(true), 
+          width = node.getData('width'),
+          height = node.getData('height'),
+          algnPos = this.getAlignedPos(pos, width, height),
+          x = algnPos.x, y = algnPos.y,
+          stringArray = node.getData('stringArray'),
+          dimArray = node.getData('dimArray'),
+          valArray = node.getData('valueArray'),
+          valLeft = $.reduce(valArray, function(x, y) { return x + y[0]; }, 0),
+          valRight = $.reduce(valArray, function(x, y) { return x + y[1]; }, 0),
+          colorArray = node.getData('colorArray'),
+          colorLength = colorArray.length,
+          config = node.getData('config'),
+          gradient = node.getData('gradient'),
+          showLabels = config.showLabels,
+          aggregates = config.showAggregates,
+          label = config.Label,
+          prev = node.getData('prev');
+
+      var ctx = canvas.getCtx(), border = node.getData('border');
+      if (colorArray && dimArray && stringArray) {
+        for (var i=0, l=dimArray.length, acumLeft=0, acumRight=0, valAcum=0; i<l; i++) {
+          ctx.fillStyle = ctx.strokeStyle = colorArray[i % colorLength];
+          ctx.save();
+          if(gradient && (dimArray[i][0] > 0 || dimArray[i][1] > 0)) {
+            var h1 = acumLeft + dimArray[i][0],
+                h2 = acumRight + dimArray[i][1],
+                alpha = Math.atan((h2 - h1) / width),
+                delta = 55;
+            var linear = ctx.createLinearGradient(x + width/2, 
+                y - (h1 + h2)/2,
+                x + width/2 + delta * Math.sin(alpha),
+                y - (h1 + h2)/2 + delta * Math.cos(alpha));
+            var color = $.rgbToHex($.map($.hexToRgb(colorArray[i % colorLength].slice(1)), 
+                function(v) { return (v * 0.85) >> 0; }));
+            linear.addColorStop(0, colorArray[i % colorLength]);
+            linear.addColorStop(1, color);
+            ctx.fillStyle = linear;
+          }
+          ctx.beginPath();
+          ctx.moveTo(x, y - acumLeft);
+          ctx.lineTo(x + width, y - acumRight);
+          ctx.lineTo(x + width, y - acumRight - dimArray[i][1]);
+          ctx.lineTo(x, y - acumLeft - dimArray[i][0]);
+          ctx.lineTo(x, y - acumLeft);
+          ctx.fill();
+          ctx.restore();
+          if(border) {
+            var strong = border.name == stringArray[i];
+            var perc = strong? 0.7 : 0.8;
+            var color = $.rgbToHex($.map($.hexToRgb(colorArray[i % colorLength].slice(1)), 
+                function(v) { return (v * perc) >> 0; }));
+            ctx.strokeStyle = color;
+            ctx.lineWidth = strong? 4 : 1;
+            ctx.save();
+            ctx.beginPath();
+            if(border.index === 0) {
+              ctx.moveTo(x, y - acumLeft);
+              ctx.lineTo(x, y - acumLeft - dimArray[i][0]);
+            } else {
+              ctx.moveTo(x + width, y - acumRight);
+              ctx.lineTo(x + width, y - acumRight - dimArray[i][1]);
+            }
+            ctx.stroke();
+            ctx.restore();
+          }
+          acumLeft += (dimArray[i][0] || 0);
+          acumRight += (dimArray[i][1] || 0);
+          
+          if(dimArray[i][0] > 0)
+            valAcum += (valArray[i][0] || 0);
+        }
+        if(prev && label.type == 'Native') {
+          ctx.save();
+          ctx.beginPath();
+          ctx.fillStyle = ctx.strokeStyle = label.color;
+          ctx.font = label.style + ' ' + label.size + 'px ' + label.family;
+          ctx.textAlign = 'center';
+          ctx.textBaseline = 'middle';
+          var aggValue = aggregates(node.name, valLeft, valRight, node, valAcum);
+          if(aggValue !== false) {
+            ctx.fillText(aggValue !== true? aggValue : valAcum, x, y - acumLeft - config.labelOffset - label.size/2, width);
+          }
+          if(showLabels(node.name, valLeft, valRight, node)) {
+            ctx.fillText(node.name, x, y + label.size/2 + config.labelOffset);
+          }
+          ctx.restore();
+        }
+      }
+    },
+    'contains': function(node, mpos) {
+      var pos = node.pos.getc(true), 
+          width = node.getData('width'),
+          height = node.getData('height'),
+          algnPos = this.getAlignedPos(pos, width, height),
+          x = algnPos.x, y = algnPos.y,
+          dimArray = node.getData('dimArray'),
+          rx = mpos.x - x;
+      //bounding box check
+      if(mpos.x < x || mpos.x > x + width
+        || mpos.y > y || mpos.y < y - height) {
+        return false;
+      }
+      //deep check
+      for(var i=0, l=dimArray.length, lAcum=y, rAcum=y; i<l; i++) {
+        var dimi = dimArray[i];
+        lAcum -= dimi[0];
+        rAcum -= dimi[1];
+        var intersec = lAcum + (rAcum - lAcum) * rx / width;
+        if(mpos.y >= intersec) {
+          var index = +(rx > width/2);
+          return {
+            'name': node.getData('stringArray')[i],
+            'color': node.getData('colorArray')[i],
+            'value': node.getData('valueArray')[i][index],
+            'index': index
+          };
+        }
+      }
+      return false;
+    }
+  }
+});
+
+/*
+  Class: AreaChart
+  
+  A visualization that displays stacked area charts.
+  
+  Constructor Options:
+  
+  See <Options.AreaChart>.
+
+*/
+$jit.AreaChart = new Class({
+  st: null,
+  colors: ["#416D9C", "#70A35E", "#EBB056", "#C74243", "#83548B", "#909291", "#557EAA"],
+  selected: {},
+  busy: false,
+  
+  initialize: function(opt) {
+    this.controller = this.config = 
+      $.merge(Options("Canvas", "Margin", "Label", "AreaChart"), {
+        Label: { type: 'Native' }
+      }, opt);
+    //set functions for showLabels and showAggregates
+    var showLabels = this.config.showLabels,
+        typeLabels = $.type(showLabels),
+        showAggregates = this.config.showAggregates,
+        typeAggregates = $.type(showAggregates);
+    this.config.showLabels = typeLabels == 'function'? showLabels : $.lambda(showLabels);
+    this.config.showAggregates = typeAggregates == 'function'? showAggregates : $.lambda(showAggregates);
+    
+    this.initializeViz();
+  },
+  
+  initializeViz: function() {
+    var config = this.config,
+        that = this,
+        nodeType = config.type.split(":")[0],
+        nodeLabels = {};
+
+    var delegate = new $jit.ST({
+      injectInto: config.injectInto,
+      width: config.width,
+      height: config.height,
+      orientation: "bottom",
+      levelDistance: 0,
+      siblingOffset: 0,
+      subtreeOffset: 0,
+      withLabels: config.Label.type != 'Native',
+      useCanvas: config.useCanvas,
+      Label: {
+        type: config.Label.type
+      },
+      Node: {
+        overridable: true,
+        type: 'areachart-' + nodeType,
+        align: 'left',
+        width: 1,
+        height: 1
+      },
+      Edge: {
+        type: 'none'
+      },
+      Tips: {
+        enable: config.Tips.enable,
+        type: 'Native',
+        force: true,
+        onShow: function(tip, node, contains) {
+          var elem = contains;
+          config.Tips.onShow(tip, elem, node);
+        }
+      },
+      Events: {
+        enable: true,
+        type: 'Native',
+        onClick: function(node, eventInfo, evt) {
+          if(!config.filterOnClick && !config.Events.enable) return;
+          var elem = eventInfo.getContains();
+          if(elem) config.filterOnClick && that.filter(elem.name);
+          config.Events.enable && config.Events.onClick(elem, eventInfo, evt);
+        },
+        onRightClick: function(node, eventInfo, evt) {
+          if(!config.restoreOnRightClick) return;
+          that.restore();
+        },
+        onMouseMove: function(node, eventInfo, evt) {
+          if(!config.selectOnHover) return;
+          if(node) {
+            var elem = eventInfo.getContains();
+            that.select(node.id, elem.name, elem.index);
+          } else {
+            that.select(false, false, false);
+          }
+        }
+      },
+      onCreateLabel: function(domElement, node) {
+        var labelConf = config.Label,
+            valueArray = node.getData('valueArray'),
+            acumLeft = $.reduce(valueArray, function(x, y) { return x + y[0]; }, 0),
+            acumRight = $.reduce(valueArray, function(x, y) { return x + y[1]; }, 0);
+        if(node.getData('prev')) {
+          var nlbs = {
+            wrapper: document.createElement('div'),
+            aggregate: document.createElement('div'),
+            label: document.createElement('div')
+          };
+          var wrapper = nlbs.wrapper,
+              label = nlbs.label,
+              aggregate = nlbs.aggregate,
+              wrapperStyle = wrapper.style,
+              labelStyle = label.style,
+              aggregateStyle = aggregate.style;
+          //store node labels
+          nodeLabels[node.id] = nlbs;
+          //append labels
+          wrapper.appendChild(label);
+          wrapper.appendChild(aggregate);
+          if(!config.showLabels(node.name, acumLeft, acumRight, node)) {
+            label.style.display = 'none';
+          }
+          if(!config.showAggregates(node.name, acumLeft, acumRight, node)) {
+            aggregate.style.display = 'none';
+          }
+          wrapperStyle.position = 'relative';
+          wrapperStyle.overflow = 'visible';
+          wrapperStyle.fontSize = labelConf.size + 'px';
+          wrapperStyle.fontFamily = labelConf.family;
+          wrapperStyle.color = labelConf.color;
+          wrapperStyle.textAlign = 'center';
+          aggregateStyle.position = labelStyle.position = 'absolute';
+          
+          domElement.style.width = node.getData('width') + 'px';
+          domElement.style.height = node.getData('height') + 'px';
+          label.innerHTML = node.name;
+          
+          domElement.appendChild(wrapper);
+        }
+      },
+      onPlaceLabel: function(domElement, node) {
+        if(!node.getData('prev')) return;
+        var labels = nodeLabels[node.id],
+            wrapperStyle = labels.wrapper.style,
+            labelStyle = labels.label.style,
+            aggregateStyle = labels.aggregate.style,
+            width = node.getData('width'),
+            height = node.getData('height'),
+            dimArray = node.getData('dimArray'),
+            valArray = node.getData('valueArray'),
+            acumLeft = $.reduce(valArray, function(x, y) { return x + y[0]; }, 0),
+            acumRight = $.reduce(valArray, function(x, y) { return x + y[1]; }, 0),
+            font = parseInt(wrapperStyle.fontSize, 10),
+            domStyle = domElement.style;
+        
+        if(dimArray && valArray) {
+          if(config.showLabels(node.name, acumLeft, acumRight, node)) {
+            labelStyle.display = '';
+          } else {
+            labelStyle.display = 'none';
+          }
+          var aggValue = config.showAggregates(node.name, acumLeft, acumRight, node);
+          if(aggValue !== false) {
+            aggregateStyle.display = '';
+          } else {
+            aggregateStyle.display = 'none';
+          }
+          wrapperStyle.width = aggregateStyle.width = labelStyle.width = domElement.style.width = width + 'px';
+          aggregateStyle.left = labelStyle.left = -width/2 + 'px';
+          for(var i=0, l=valArray.length, acum=0, leftAcum=0; i<l; i++) {
+            if(dimArray[i][0] > 0) {
+              acum+= valArray[i][0];
+              leftAcum+= dimArray[i][0];
+            }
+          }
+          aggregateStyle.top = (-font - config.labelOffset) + 'px';
+          labelStyle.top = (config.labelOffset + leftAcum) + 'px';
+          domElement.style.top = parseInt(domElement.style.top, 10) - leftAcum + 'px';
+          domElement.style.height = wrapperStyle.height = leftAcum + 'px';
+          labels.aggregate.innerHTML = aggValue !== true? aggValue : acum;
+        }
+      }
+    });
+    
+    var size = delegate.canvas.getSize(),
+        margin = config.Margin;
+    delegate.config.offsetY = -size.height/2 + margin.bottom 
+      + (config.showLabels && (config.labelOffset + config.Label.size));
+    delegate.config.offsetX = (margin.right - margin.left)/2;
+    this.delegate = delegate;
+    this.canvas = this.delegate.canvas;
+  },
+  
+ /*
+  Method: loadJSON
+ 
+  Loads JSON data into the visualization. 
+  
+  Parameters:
+  
+  json - The JSON data format. This format is described in <http://blog.thejit.org/2010/04/24/new-javascript-infovis-toolkit-visualizations/#json-data-format>.
+  
+  Example:
+  (start code js)
+  var areaChart = new $jit.AreaChart(options);
+  areaChart.loadJSON(json);
+  (end code)
+ */  
+  loadJSON: function(json) {
+    var prefix = $.time(), 
+        ch = [], 
+        delegate = this.delegate,
+        name = $.splat(json.label), 
+        color = $.splat(json.color || this.colors),
+        config = this.config,
+        gradient = !!config.type.split(":")[1],
+        animate = config.animate;
+    
+    for(var i=0, values=json.values, l=values.length; i<l-1; i++) {
+      var val = values[i], prev = values[i-1], next = values[i+1];
+      var valLeft = $.splat(values[i].values), valRight = $.splat(values[i+1].values);
+      var valArray = $.zip(valLeft, valRight);
+      var acumLeft = 0, acumRight = 0;
+      ch.push({
+        'id': prefix + val.label,
+        'name': val.label,
+        'data': {
+          'value': valArray,
+          '$valueArray': valArray,
+          '$colorArray': color,
+          '$stringArray': name,
+          '$next': next.label,
+          '$prev': prev? prev.label:false,
+          '$config': config,
+          '$gradient': gradient
+        },
+        'children': []
+      });
+    }
+    var root = {
+      'id': prefix + '$root',
+      'name': '',
+      'data': {
+        '$type': 'none',
+        '$width': 1,
+        '$height': 1
+      },
+      'children': ch
+    };
+    delegate.loadJSON(root);
+    
+    this.normalizeDims();
+    delegate.compute();
+    delegate.select(delegate.root);
+    if(animate) {
+      delegate.fx.animate({
+        modes: ['node-property:height:dimArray'],
+        duration:1500
+      });
+    }
+  },
+  
+ /*
+  Method: updateJSON
+ 
+  Use this method when updating values for the current JSON data. If the items specified by the JSON data already exist in the graph then their values will be updated.
+  
+  Parameters:
+  
+  json - (object) JSON data to be updated. The JSON format corresponds to the one described in <AreaChart.loadJSON>.
+  onComplete - (object) A callback object to be called when the animation transition when updating the data end.
+  
+  Example:
+  
+  (start code js)
+  areaChart.updateJSON(json, {
+    onComplete: function() {
+      alert('update complete!');
+    }
+  });
+  (end code)
+ */  
+  updateJSON: function(json, onComplete) {
+    if(this.busy) return;
+    this.busy = true;
+    
+    var delegate = this.delegate,
+        graph = delegate.graph,
+        labels = json.label && $.splat(json.label),
+        values = json.values,
+        animate = this.config.animate,
+        that = this,
+        hashValues = {};
+
+    //convert the whole thing into a hash
+    for (var i = 0, l = values.length; i < l; i++) {
+      hashValues[values[i].label] = values[i];
+    }
+  
+    graph.eachNode(function(n) {
+      var v = hashValues[n.name],
+          stringArray = n.getData('stringArray'),
+          valArray = n.getData('valueArray'),
+          next = n.getData('next');
+      
+      if (v) {
+        v.values = $.splat(v.values);
+        $.each(valArray, function(a, i) {
+          a[0] = v.values[i];
+          if(labels) stringArray[i] = labels[i];
+        });
+        n.setData('valueArray', valArray);
+      }
+     
+      if(next) {
+        v = hashValues[next];
+        if(v) {
+          $.each(valArray, function(a, i) {
+            a[1] = v.values[i];
+          });
+        }
+      }
+    });
+    this.normalizeDims();
+    delegate.compute();
+    delegate.select(delegate.root);
+    if(animate) {
+      delegate.fx.animate({
+        modes: ['node-property:height:dimArray'],
+        duration:1500,
+        onComplete: function() {
+          that.busy = false;
+          onComplete && onComplete.onComplete();
+        }
+      });
+    }
+  },
+  
+/*
+  Method: filter
+ 
+  Filter selected stacks, collapsing all other stacks. You can filter multiple stacks at the same time.
+  
+  Parameters:
+  
+  filters - (array) An array of strings with the name of the stacks to be filtered.
+  callback - (object) An object with an *onComplete* callback method. 
+  
+  Example:
+  
+  (start code js)
+  areaChart.filter(['label A', 'label C'], {
+      onComplete: function() {
+          console.log('done!');
+      }
+  });
+  (end code)
+  
+  See also:
+  
+  <AreaChart.restore>.
+ */  
+  filter: function(filters, callback) {
+    if(this.busy) return;
+    this.busy = true;
+    if(this.config.Tips.enable) this.delegate.tips.hide();
+    this.select(false, false, false);
+    var args = $.splat(filters);
+    var rt = this.delegate.graph.getNode(this.delegate.root);
+    var that = this;
+    this.normalizeDims();
+    rt.eachAdjacency(function(adj) {
+      var n = adj.nodeTo, 
+          dimArray = n.getData('dimArray', 'end'),
+          stringArray = n.getData('stringArray');
+      n.setData('dimArray', $.map(dimArray, function(d, i) {
+        return ($.indexOf(args, stringArray[i]) > -1)? d:[0, 0];
+      }), 'end');
+    });
+    this.delegate.fx.animate({
+      modes: ['node-property:dimArray'],
+      duration:1500,
+      onComplete: function() {
+        that.busy = false;
+        callback && callback.onComplete();
+      }
+    });
+  },
+  
+  /*
+  Method: restore
+ 
+  Sets all stacks that could have been filtered visible.
+  
+  Example:
+  
+  (start code js)
+  areaChart.restore();
+  (end code)
+  
+  See also:
+  
+  <AreaChart.filter>.
+ */  
+  restore: function(callback) {
+    if(this.busy) return;
+    this.busy = true;
+    if(this.config.Tips.enable) this.delegate.tips.hide();
+    this.select(false, false, false);
+    this.normalizeDims();
+    var that = this;
+    this.delegate.fx.animate({
+      modes: ['node-property:height:dimArray'],
+      duration:1500,
+      onComplete: function() {
+        that.busy = false;
+        callback && callback.onComplete();
+      }
+    });
+  },
+  //adds the little brown bar when hovering the node
+  select: function(id, name, index) {
+    if(!this.config.selectOnHover) return;
+    var s = this.selected;
+    if(s.id != id || s.name != name 
+        || s.index != index) {
+      s.id = id;
+      s.name = name;
+      s.index = index;
+      this.delegate.graph.eachNode(function(n) {
+        n.setData('border', false);
+      });
+      if(id) {
+        var n = this.delegate.graph.getNode(id);
+        n.setData('border', s);
+        var link = index === 0? 'prev':'next';
+        link = n.getData(link);
+        if(link) {
+          n = this.delegate.graph.getByName(link);
+          if(n) {
+            n.setData('border', {
+              name: name,
+              index: 1-index
+            });
+          }
+        }
+      }
+      this.delegate.plot();
+    }
+  },
+  
+  /*
+    Method: getLegend
+   
+    Returns an object containing as keys the legend names and as values hex strings with color values.
+    
+    Example:
+    
+    (start code js)
+    var legend = areaChart.getLegend();
+    (end code)
+ */  
+  getLegend: function() {
+    var legend = {};
+    var n;
+    this.delegate.graph.getNode(this.delegate.root).eachAdjacency(function(adj) {
+      n = adj.nodeTo;
+    });
+    var colors = n.getData('colorArray'),
+        len = colors.length;
+    $.each(n.getData('stringArray'), function(s, i) {
+      legend[s] = colors[i % len];
+    });
+    return legend;
+  },
+  
+  /*
+    Method: getMaxValue
+   
+    Returns the maximum accumulated value for the stacks. This method is used for normalizing the graph heights according to the canvas height.
+    
+    Example:
+    
+    (start code js)
+    var ans = areaChart.getMaxValue();
+    (end code)
+    
+    In some cases it could be useful to override this method to normalize heights for a group of AreaCharts, like when doing small multiples.
+    
+    Example:
+    
+    (start code js)
+    //will return 100 for all AreaChart instances,
+    //displaying all of them with the same scale
+    $jit.AreaChart.implement({
+      'getMaxValue': function() {
+        return 100;
+      }
+    });
+    (end code)
+    
+*/  
+  getMaxValue: function() {
+    var maxValue = 0;
+    this.delegate.graph.eachNode(function(n) {
+      var valArray = n.getData('valueArray'),
+          acumLeft = 0, acumRight = 0;
+      $.each(valArray, function(v) { 
+        acumLeft += +v[0];
+        acumRight += +v[1];
+      });
+      var acum = acumRight>acumLeft? acumRight:acumLeft;
+      maxValue = maxValue>acum? maxValue:acum;
+    });
+    return maxValue;
+  },
+  
+  normalizeDims: function() {
+    //number of elements
+    var root = this.delegate.graph.getNode(this.delegate.root), l=0;
+    root.eachAdjacency(function() {
+      l++;
+    });
+    var maxValue = this.getMaxValue() || 1,
+        size = this.delegate.canvas.getSize(),
+        config = this.config,
+        margin = config.Margin,
+        labelOffset = config.labelOffset + config.Label.size,
+        fixedDim = (size.width - (margin.left + margin.right)) / l,
+        animate = config.animate,
+        height = size.height - (margin.top + margin.bottom) - (config.showAggregates && labelOffset) 
+          - (config.showLabels && labelOffset);
+    this.delegate.graph.eachNode(function(n) {
+      var acumLeft = 0, acumRight = 0, animateValue = [];
+      $.each(n.getData('valueArray'), function(v) {
+        acumLeft += +v[0];
+        acumRight += +v[1];
+        animateValue.push([0, 0]);
+      });
+      var acum = acumRight>acumLeft? acumRight:acumLeft;
+      n.setData('width', fixedDim);
+      if(animate) {
+        n.setData('height', acum * height / maxValue, 'end');
+        n.setData('dimArray', $.map(n.getData('valueArray'), function(n) { 
+          return [n[0] * height / maxValue, n[1] * height / maxValue]; 
+        }), 'end');
+        var dimArray = n.getData('dimArray');
+        if(!dimArray) {
+          n.setData('dimArray', animateValue);
+        }
+      } else {
+        n.setData('height', acum * height / maxValue);
+        n.setData('dimArray', $.map(n.getData('valueArray'), function(n) { 
+          return [n[0] * height / maxValue, n[1] * height / maxValue]; 
+        }));
+      }
+    });
+  }
+});
+
+
+/*
+ * File: Options.BarChart.js
+ *
+*/
+
+/*
+  Object: Options.BarChart
+  
+  <BarChart> options. 
+  Other options included in the BarChart are <Options.Canvas>, <Options.Label>, <Options.Margin>, <Options.Tips> and <Options.Events>.
+  
+  Syntax:
+  
+  (start code js)
+
+  Options.BarChart = {
+    animate: true,
+    labelOffset: 3,
+    barsOffset: 0,
+    type: 'stacked',
+    hoveredColor: '#9fd4ff',
+    orientation: 'horizontal',
+    showAggregates: true,
+    showLabels: true
+  };
+  
+  (end code)
+  
+  Example:
+  
+  (start code js)
+
+  var barChart = new $jit.BarChart({
+    animate: true,
+    barsOffset: 10,
+    type: 'stacked:gradient'
+  });
+  
+  (end code)
+
+  Parameters:
+  
+  animate - (boolean) Default's *true*. Whether to add animated transitions when filtering/restoring stacks.
+  offset - (number) Default's *25*. Adds margin between the visualization and the canvas.
+  labelOffset - (number) Default's *3*. Adds margin between the label and the default place where it should be drawn.
+  barsOffset - (number) Default's *0*. Separation between bars.
+  type - (string) Default's *'stacked'*. Stack or grouped styles. Posible values are 'stacked', 'grouped', 'stacked:gradient', 'grouped:gradient' to add gradients.
+  hoveredColor - (boolean|string) Default's *'#9fd4ff'*. Sets the selected color for a hovered bar stack.
+  orientation - (string) Default's 'horizontal'. Sets the direction of the bars. Possible options are 'vertical' or 'horizontal'.
+  showAggregates - (boolean, function) Default's *true*. Display the sum the values of each bar. Can also be a function that returns *true* or *false* to display the value of the bar or not. That same function can also return a string with the formatted data to be added.
+  showLabels - (boolean, function) Default's *true*. Display the name of the slots. Can also be a function that returns *true* or *false* for each bar to decide whether to show the label or not.
+  
+*/
+
+Options.BarChart = {
+  $extend: true,
+  
+  animate: true,
+  type: 'stacked', //stacked, grouped, : gradient
+  labelOffset: 3, //label offset
+  barsOffset: 0, //distance between bars
+  hoveredColor: '#9fd4ff',
+  orientation: 'horizontal',
+  showAggregates: true,
+  showLabels: true,
+  Tips: {
+    enable: false,
+    onShow: $.empty,
+    onHide: $.empty
+  },
+  Events: {
+    enable: false,
+    onClick: $.empty
+  }
+};
+
+/*
+ * File: BarChart.js
+ *
+*/
+
+$jit.ST.Plot.NodeTypes.implement({
+  'barchart-stacked' : {
+    'render' : function(node, canvas) {
+      var pos = node.pos.getc(true), 
+          width = node.getData('width'),
+          height = node.getData('height'),
+          algnPos = this.getAlignedPos(pos, width, height),
+          x = algnPos.x, y = algnPos.y,
+          dimArray = node.getData('dimArray'),
+          valueArray = node.getData('valueArray'),
+          colorArray = node.getData('colorArray'),
+          colorLength = colorArray.length,
+          stringArray = node.getData('stringArray');
+
+      var ctx = canvas.getCtx(),
+          opt = {},
+          border = node.getData('border'),
+          gradient = node.getData('gradient'),
+          config = node.getData('config'),
+          horz = config.orientation == 'horizontal',
+          aggregates = config.showAggregates,
+          showLabels = config.showLabels,
+          label = config.Label;
+      
+      if (colorArray && dimArray && stringArray) {
+        for (var i=0, l=dimArray.length, acum=0, valAcum=0; i<l; i++) {
+          ctx.fillStyle = ctx.strokeStyle = colorArray[i % colorLength];
+          if(gradient) {
+            var linear;
+            if(horz) {
+              linear = ctx.createLinearGradient(x + acum + dimArray[i]/2, y, 
+                  x + acum + dimArray[i]/2, y + height);
+            } else {
+              linear = ctx.createLinearGradient(x, y - acum - dimArray[i]/2, 
+                  x + width, y - acum- dimArray[i]/2);
+            }
+            var color = $.rgbToHex($.map($.hexToRgb(colorArray[i % colorLength].slice(1)), 
+                function(v) { return (v * 0.5) >> 0; }));
+            linear.addColorStop(0, color);
+            linear.addColorStop(0.5, colorArray[i % colorLength]);
+            linear.addColorStop(1, color);
+            ctx.fillStyle = linear;
+          }
+          if(horz) {
+            ctx.fillRect(x + acum, y, dimArray[i], height);
+          } else {
+            ctx.fillRect(x, y - acum - dimArray[i], width, dimArray[i]);
+          }
+          if(border && border.name == stringArray[i]) {
+            opt.acum = acum;
+            opt.dimValue = dimArray[i];
+          }
+          acum += (dimArray[i] || 0);
+          valAcum += (valueArray[i] || 0);
+        }
+        if(border) {
+          ctx.save();
+          ctx.lineWidth = 2;
+          ctx.strokeStyle = border.color;
+          if(horz) {
+            ctx.strokeRect(x + opt.acum + 1, y + 1, opt.dimValue -2, height - 2);
+          } else {
+            ctx.strokeRect(x + 1, y - opt.acum - opt.dimValue + 1, width -2, opt.dimValue -2);
+          }
+          ctx.restore();
+        }
+        if(label.type == 'Native') {
+          ctx.save();
+          ctx.fillStyle = ctx.strokeStyle = label.color;
+          ctx.font = label.style + ' ' + label.size + 'px ' + label.family;
+          ctx.textBaseline = 'middle';
+          var aggValue = aggregates(node.name, valAcum, node);
+          if(aggValue !== false) {
+            aggValue = aggValue !== true? aggValue : valAcum;
+            if(horz) {
+              ctx.textAlign = 'right';
+              ctx.fillText(aggValue, x + acum - config.labelOffset, y + height/2);
+            } else {
+              ctx.textAlign = 'center';
+              ctx.fillText(aggValue, x + width/2, y - height - label.size/2 - config.labelOffset);
+            }
+          }
+          if(showLabels(node.name, valAcum, node)) {
+            if(horz) {
+              ctx.textAlign = 'center';
+              ctx.translate(x - config.labelOffset - label.size/2, y + height/2);
+              ctx.rotate(Math.PI / 2);
+              ctx.fillText(node.name, 0, 0);
+            } else {
+              ctx.textAlign = 'center';
+              ctx.fillText(node.name, x + width/2, y + label.size/2 + config.labelOffset);
+            }
+          }
+          ctx.restore();
+        }
+      }
+    },
+    'contains': function(node, mpos) {
+      var pos = node.pos.getc(true), 
+          width = node.getData('width'),
+          height = node.getData('height'),
+          algnPos = this.getAlignedPos(pos, width, height),
+          x = algnPos.x, y = algnPos.y,
+          dimArray = node.getData('dimArray'),
+          config = node.getData('config'),
+          rx = mpos.x - x,
+          horz = config.orientation == 'horizontal';
+      //bounding box check
+      if(horz) {
+        if(mpos.x < x || mpos.x > x + width
+            || mpos.y > y + height || mpos.y < y) {
+            return false;
+          }
+      } else {
+        if(mpos.x < x || mpos.x > x + width
+            || mpos.y > y || mpos.y < y - height) {
+            return false;
+          }
+      }
+      //deep check
+      for(var i=0, l=dimArray.length, acum=(horz? x:y); i<l; i++) {
+        var dimi = dimArray[i];
+        if(horz) {
+          acum += dimi;
+          var intersec = acum;
+          if(mpos.x <= intersec) {
+            return {
+              'name': node.getData('stringArray')[i],
+              'color': node.getData('colorArray')[i],
+              'value': node.getData('valueArray')[i],
+              'label': node.name
+            };
+          }
+        } else {
+          acum -= dimi;
+          var intersec = acum;
+          if(mpos.y >= intersec) {
+            return {
+              'name': node.getData('stringArray')[i],
+              'color': node.getData('colorArray')[i],
+              'value': node.getData('valueArray')[i],
+              'label': node.name
+            };
+          }
+        }
+      }
+      return false;
+    }
+  },
+  'barchart-grouped' : {
+    'render' : function(node, canvas) {
+      var pos = node.pos.getc(true), 
+          width = node.getData('width'),
+          height = node.getData('height'),
+          algnPos = this.getAlignedPos(pos, width, height),
+          x = algnPos.x, y = algnPos.y,
+          dimArray = node.getData('dimArray'),
+          valueArray = node.getData('valueArray'),
+          valueLength = valueArray.length,
+          colorArray = node.getData('colorArray'),
+          colorLength = colorArray.length,
+          stringArray = node.getData('stringArray'); 
+
+      var ctx = canvas.getCtx(),
+          opt = {},
+          border = node.getData('border'),
+          gradient = node.getData('gradient'),
+          config = node.getData('config'),
+          horz = config.orientation == 'horizontal',
+          aggregates = config.showAggregates,
+          showLabels = config.showLabels,
+          label = config.Label,
+          fixedDim = (horz? height : width) / valueLength;
+      
+      if (colorArray && dimArray && stringArray) {
+        for (var i=0, l=valueLength, acum=0, valAcum=0; i<l; i++) {
+          ctx.fillStyle = ctx.strokeStyle = colorArray[i % colorLength];
+          if(gradient) {
+            var linear;
+            if(horz) {
+              linear = ctx.createLinearGradient(x + dimArray[i]/2, y + fixedDim * i, 
+                  x + dimArray[i]/2, y + fixedDim * (i + 1));
+            } else {
+              linear = ctx.createLinearGradient(x + fixedDim * i, y - dimArray[i]/2, 
+                  x + fixedDim * (i + 1), y - dimArray[i]/2);
+            }
+            var color = $.rgbToHex($.map($.hexToRgb(colorArray[i % colorLength].slice(1)), 
+                function(v) { return (v * 0.5) >> 0; }));
+            linear.addColorStop(0, color);
+            linear.addColorStop(0.5, colorArray[i % colorLength]);
+            linear.addColorStop(1, color);
+            ctx.fillStyle = linear;
+          }
+          if(horz) {
+            ctx.fillRect(x, y + fixedDim * i, dimArray[i], fixedDim);
+          } else {
+            ctx.fillRect(x + fixedDim * i, y - dimArray[i], fixedDim, dimArray[i]);
+          }
+          if(border && border.name == stringArray[i]) {
+            opt.acum = fixedDim * i;
+            opt.dimValue = dimArray[i];
+          }
+          acum += (dimArray[i] || 0);
+          valAcum += (valueArray[i] || 0);
+        }
+        if(border) {
+          ctx.save();
+          ctx.lineWidth = 2;
+          ctx.strokeStyle = border.color;
+          if(horz) {
+            ctx.strokeRect(x + 1, y + opt.acum + 1, opt.dimValue -2, fixedDim - 2);
+          } else {
+            ctx.strokeRect(x + opt.acum + 1, y - opt.dimValue + 1, fixedDim -2, opt.dimValue -2);
+          }
+          ctx.restore();
+        }
+        if(label.type == 'Native') {
+          ctx.save();
+          ctx.fillStyle = ctx.strokeStyle = label.color;
+          ctx.font = label.style + ' ' + label.size + 'px ' + label.family;
+          ctx.textBaseline = 'middle';
+          var aggValue = aggregates(node.name, valAcum, node);
+          if(aggValue !== false) {
+            aggValue = aggValue !== true? aggValue : valAcum;
+            if(horz) {
+              ctx.textAlign = 'right';
+              ctx.fillText(aggValue, x + Math.max.apply(null, dimArray) - config.labelOffset, y + height/2);
+            } else {
+              ctx.textAlign = 'center';
+              ctx.fillText(aggValue, x + width/2, y - Math.max.apply(null, dimArray) - label.size/2 - config.labelOffset);
+            }
+          }
+          if(showLabels(node.name, valAcum, node)) {
+            if(horz) {
+              ctx.textAlign = 'center';
+              ctx.translate(x - config.labelOffset - label.size/2, y + height/2);
+              ctx.rotate(Math.PI / 2);
+              ctx.fillText(node.name, 0, 0);
+            } else {
+              ctx.textAlign = 'center';
+              ctx.fillText(node.name, x + width/2, y + label.size/2 + config.labelOffset);
+            }
+          }
+          ctx.restore();
+        }
+      }
+    },
+    'contains': function(node, mpos) {
+      var pos = node.pos.getc(true), 
+          width = node.getData('width'),
+          height = node.getData('height'),
+          algnPos = this.getAlignedPos(pos, width, height),
+          x = algnPos.x, y = algnPos.y,
+          dimArray = node.getData('dimArray'),
+          len = dimArray.length,
+          config = node.getData('config'),
+          rx = mpos.x - x,
+          horz = config.orientation == 'horizontal',
+          fixedDim = (horz? height : width) / len;
+      //bounding box check
+      if(horz) {
+        if(mpos.x < x || mpos.x > x + width
+            || mpos.y > y + height || mpos.y < y) {
+            return false;
+          }
+      } else {
+        if(mpos.x < x || mpos.x > x + width
+            || mpos.y > y || mpos.y < y - height) {
+            return false;
+          }
+      }
+      //deep check
+      for(var i=0, l=dimArray.length; i<l; i++) {
+        var dimi = dimArray[i];
+        if(horz) {
+          var limit = y + fixedDim * i;
+          if(mpos.x <= x+ dimi && mpos.y >= limit && mpos.y <= limit + fixedDim) {
+            return {
+              'name': node.getData('stringArray')[i],
+              'color': node.getData('colorArray')[i],
+              'value': node.getData('valueArray')[i],
+              'label': node.name
+            };
+          }
+        } else {
+          var limit = x + fixedDim * i;
+          if(mpos.x >= limit && mpos.x <= limit + fixedDim && mpos.y >= y - dimi) {
+            return {
+              'name': node.getData('stringArray')[i],
+              'color': node.getData('colorArray')[i],
+              'value': node.getData('valueArray')[i],
+              'label': node.name
+            };
+          }
+        }
+      }
+      return false;
+    }
+  }
+});
+
+/*
+  Class: BarChart
+  
+  A visualization that displays stacked bar charts.
+  
+  Constructor Options:
+  
+  See <Options.BarChart>.
+
+*/
+$jit.BarChart = new Class({
+  st: null,
+  colors: ["#416D9C", "#70A35E", "#EBB056", "#C74243", "#83548B", "#909291", "#557EAA"],
+  selected: {},
+  busy: false,
+  
+  initialize: function(opt) {
+    this.controller = this.config = 
+      $.merge(Options("Canvas", "Margin", "Label", "BarChart"), {
+        Label: { type: 'Native' }
+      }, opt);
+    //set functions for showLabels and showAggregates
+    var showLabels = this.config.showLabels,
+        typeLabels = $.type(showLabels),
+        showAggregates = this.config.showAggregates,
+        typeAggregates = $.type(showAggregates);
+    this.config.showLabels = typeLabels == 'function'? showLabels : $.lambda(showLabels);
+    this.config.showAggregates = typeAggregates == 'function'? showAggregates : $.lambda(showAggregates);
+    
+    this.initializeViz();
+  },
+  
+  initializeViz: function() {
+    var config = this.config, that = this;
+    var nodeType = config.type.split(":")[0],
+        horz = config.orientation == 'horizontal',
+        nodeLabels = {};
+    
+    var delegate = new $jit.ST({
+      injectInto: config.injectInto,
+      width: config.width,
+      height: config.height,
+      orientation: horz? 'left' : 'bottom',
+      levelDistance: 0,
+      siblingOffset: config.barsOffset,
+      subtreeOffset: 0,
+      withLabels: config.Label.type != 'Native',      
+      useCanvas: config.useCanvas,
+      Label: {
+        type: config.Label.type
+      },
+      Node: {
+        overridable: true,
+        type: 'barchart-' + nodeType,
+        align: 'left',
+        width: 1,
+        height: 1
+      },
+      Edge: {
+        type: 'none'
+      },
+      Tips: {
+        enable: config.Tips.enable,
+        type: 'Native',
+        force: true,
+        onShow: function(tip, node, contains) {
+          var elem = contains;
+          config.Tips.onShow(tip, elem, node);
+        }
+      },
+      Events: {
+        enable: true,
+        type: 'Native',
+        onClick: function(node, eventInfo, evt) {
+          if(!config.Events.enable) return;
+          var elem = eventInfo.getContains();
+          config.Events.onClick(elem, eventInfo, evt);
+        },
+        onMouseMove: function(node, eventInfo, evt) {
+          if(!config.hoveredColor) return;
+          if(node) {
+            var elem = eventInfo.getContains();
+            that.select(node.id, elem.name, elem.index);
+          } else {
+            that.select(false, false, false);
+          }
+        }
+      },
+      onCreateLabel: function(domElement, node) {
+        var labelConf = config.Label,
+            valueArray = node.getData('valueArray'),
+            acum = $.reduce(valueArray, function(x, y) { return x + y; }, 0);
+        var nlbs = {
+          wrapper: document.createElement('div'),
+          aggregate: document.createElement('div'),
+          label: document.createElement('div')
+        };
+        var wrapper = nlbs.wrapper,
+            label = nlbs.label,
+            aggregate = nlbs.aggregate,
+            wrapperStyle = wrapper.style,
+            labelStyle = label.style,
+            aggregateStyle = aggregate.style;
+        //store node labels
+        nodeLabels[node.id] = nlbs;
+        //append labels
+        wrapper.appendChild(label);
+        wrapper.appendChild(aggregate);
+        if(!config.showLabels(node.name, acum, node)) {
+          labelStyle.display = 'none';
+        }
+        if(!config.showAggregates(node.name, acum, node)) {
+          aggregateStyle.display = 'none';
+        }
+        wrapperStyle.position = 'relative';
+        wrapperStyle.overflow = 'visible';
+        wrapperStyle.fontSize = labelConf.size + 'px';
+        wrapperStyle.fontFamily = labelConf.family;
+        wrapperStyle.color = labelConf.color;
+        wrapperStyle.textAlign = 'center';
+        aggregateStyle.position = labelStyle.position = 'absolute';
+        
+        domElement.style.width = node.getData('width') + 'px';
+        domElement.style.height = node.getData('height') + 'px';
+        aggregateStyle.left = labelStyle.left =  '0px';
+
+        label.innerHTML = node.name;
+        
+        domElement.appendChild(wrapper);
+      },
+      onPlaceLabel: function(domElement, node) {
+        if(!nodeLabels[node.id]) return;
+        var labels = nodeLabels[node.id],
+            wrapperStyle = labels.wrapper.style,
+            labelStyle = labels.label.style,
+            aggregateStyle = labels.aggregate.style,
+            grouped = config.type.split(':')[0] == 'grouped',
+            horz = config.orientation == 'horizontal',
+            dimArray = node.getData('dimArray'),
+            valArray = node.getData('valueArray'),
+            width = (grouped && horz)? Math.max.apply(null, dimArray) : node.getData('width'),
+            height = (grouped && !horz)? Math.max.apply(null, dimArray) : node.getData('height'),
+            font = parseInt(wrapperStyle.fontSize, 10),
+            domStyle = domElement.style;
+            
+        
+        if(dimArray && valArray) {
+          wrapperStyle.width = aggregateStyle.width = labelStyle.width = domElement.style.width = width + 'px';
+          for(var i=0, l=valArray.length, acum=0; i<l; i++) {
+            if(dimArray[i] > 0) {
+              acum+= valArray[i];
+            }
+          }
+          if(config.showLabels(node.name, acum, node)) {
+            labelStyle.display = '';
+          } else {
+            labelStyle.display = 'none';
+          }
+          var aggValue = config.showAggregates(node.name, acum, node);
+          if(aggValue !== false) {
+            aggregateStyle.display = '';
+          } else {
+            aggregateStyle.display = 'none';
+          }
+          if(config.orientation == 'horizontal') {
+            aggregateStyle.textAlign = 'right';
+            labelStyle.textAlign = 'left';
+            labelStyle.textIndex = aggregateStyle.textIndent = config.labelOffset + 'px';
+            aggregateStyle.top = labelStyle.top = (height-font)/2 + 'px';
+            domElement.style.height = wrapperStyle.height = height + 'px';
+          } else {
+            aggregateStyle.top = (-font - config.labelOffset) + 'px';
+            labelStyle.top = (config.labelOffset + height) + 'px';
+            domElement.style.top = parseInt(domElement.style.top, 10) - height + 'px';
+            domElement.style.height = wrapperStyle.height = height + 'px';
+          }
+          labels.aggregate.innerHTML = aggValue !== true? aggValue : acum;
+        }
+      }
+    });
+    
+    var size = delegate.canvas.getSize(),
+        margin = config.Margin;
+    if(horz) {
+      delegate.config.offsetX = size.width/2 - margin.left
+        - (config.showLabels && (config.labelOffset + config.Label.size));    
+      delegate.config.offsetY = (margin.bottom - margin.top)/2;
+    } else {
+      delegate.config.offsetY = -size.height/2 + margin.bottom 
+        + (config.showLabels && (config.labelOffset + config.Label.size));
+      delegate.config.offsetX = (margin.right - margin.left)/2;
+    }
+    this.delegate = delegate;
+    this.canvas = this.delegate.canvas;
+  },
+  
+  /*
+    Method: loadJSON
+   
+    Loads JSON data into the visualization. 
+    
+    Parameters:
+    
+    json - The JSON data format. This format is described in <http://blog.thejit.org/2010/04/24/new-javascript-infovis-toolkit-visualizations/#json-data-format>.
+    
+    Example:
+    (start code js)
+    var barChart = new $jit.BarChart(options);
+    barChart.loadJSON(json);
+    (end code)
+ */  
+  loadJSON: function(json) {
+    if(this.busy) return;
+    this.busy = true;
+    
+    var prefix = $.time(), 
+        ch = [], 
+        delegate = this.delegate,
+        name = $.splat(json.label), 
+        color = $.splat(json.color || this.colors),
+        config = this.config,
+        gradient = !!config.type.split(":")[1],
+        animate = config.animate,
+        horz = config.orientation == 'horizontal',
+        that = this;
+    
+    for(var i=0, values=json.values, l=values.length; i<l; i++) {
+      var val = values[i]
+      var valArray = $.splat(values[i].values);
+      var acum = 0;
+      ch.push({
+        'id': prefix + val.label,
+        'name': val.label,
+        'data': {
+          'value': valArray,
+          '$valueArray': valArray,
+          '$colorArray': color,
+          '$stringArray': name,
+          '$gradient': gradient,
+          '$config': config
+        },
+        'children': []
+      });
+    }
+    var root = {
+      'id': prefix + '$root',
+      'name': '',
+      'data': {
+        '$type': 'none',
+        '$width': 1,
+        '$height': 1
+      },
+      'children': ch
+    };
+    delegate.loadJSON(root);
+    
+    this.normalizeDims();
+    delegate.compute();
+    delegate.select(delegate.root);
+    if(animate) {
+      if(horz) {
+        delegate.fx.animate({
+          modes: ['node-property:width:dimArray'],
+          duration:1500,
+          onComplete: function() {
+            that.busy = false;
+          }
+        });
+      } else {
+        delegate.fx.animate({
+          modes: ['node-property:height:dimArray'],
+          duration:1500,
+          onComplete: function() {
+            that.busy = false;
+          }
+        });
+      }
+    } else {
+      this.busy = false;
+    }
+  },
+  
+  /*
+    Method: updateJSON
+   
+    Use this method when updating values for the current JSON data. If the items specified by the JSON data already exist in the graph then their values will be updated.
+    
+    Parameters:
+    
+    json - (object) JSON data to be updated. The JSON format corresponds to the one described in <BarChart.loadJSON>.
+    onComplete - (object) A callback object to be called when the animation transition when updating the data end.
+    
+    Example:
+    
+    (start code js)
+    barChart.updateJSON(json, {
+      onComplete: function() {
+        alert('update complete!');
+      }
+    });
+    (end code)
+ */  
+  updateJSON: function(json, onComplete) {
+    if(this.busy) return;
+    this.busy = true;
+    this.select(false, false, false);
+    var delegate = this.delegate;
+    var graph = delegate.graph;
+    var values = json.values;
+    var animate = this.config.animate;
+    var that = this;
+    var horz = this.config.orientation == 'horizontal';
+    $.each(values, function(v) {
+      var n = graph.getByName(v.label);
+      if(n) {
+        n.setData('valueArray', $.splat(v.values));
+        if(json.label) {
+          n.setData('stringArray', $.splat(json.label));
+        }
+      }
+    });
+    this.normalizeDims();
+    delegate.compute();
+    delegate.select(delegate.root);
+    if(animate) {
+      if(horz) {
+        delegate.fx.animate({
+          modes: ['node-property:width:dimArray'],
+          duration:1500,
+          onComplete: function() {
+            that.busy = false;
+            onComplete && onComplete.onComplete();
+          }
+        });
+      } else {
+        delegate.fx.animate({
+          modes: ['node-property:height:dimArray'],
+          duration:1500,
+          onComplete: function() {
+            that.busy = false;
+            onComplete && onComplete.onComplete();
+          }
+        });
+      }
+    }
+  },
+  
+  //adds the little brown bar when hovering the node
+  select: function(id, name) {
+    if(!this.config.hoveredColor) return;
+    var s = this.selected;
+    if(s.id != id || s.name != name) {
+      s.id = id;
+      s.name = name;
+      s.color = this.config.hoveredColor;
+      this.delegate.graph.eachNode(function(n) {
+        if(id == n.id) {
+          n.setData('border', s);
+        } else {
+          n.setData('border', false);
+        }
+      });
+      this.delegate.plot();
+    }
+  },
+  
+  /*
+    Method: getLegend
+   
+    Returns an object containing as keys the legend names and as values hex strings with color values.
+    
+    Example:
+    
+    (start code js)
+    var legend = barChart.getLegend();
+    (end code)
+  */  
+  getLegend: function() {
+    var legend = {};
+    var n;
+    this.delegate.graph.getNode(this.delegate.root).eachAdjacency(function(adj) {
+      n = adj.nodeTo;
+    });
+    var colors = n.getData('colorArray'),
+        len = colors.length;
+    $.each(n.getData('stringArray'), function(s, i) {
+      legend[s] = colors[i % len];
+    });
+    return legend;
+  },
+  
+  /*
+    Method: getMaxValue
+   
+    Returns the maximum accumulated value for the stacks. This method is used for normalizing the graph heights according to the canvas height.
+    
+    Example:
+    
+    (start code js)
+    var ans = barChart.getMaxValue();
+    (end code)
+    
+    In some cases it could be useful to override this method to normalize heights for a group of BarCharts, like when doing small multiples.
+    
+    Example:
+    
+    (start code js)
+    //will return 100 for all BarChart instances,
+    //displaying all of them with the same scale
+    $jit.BarChart.implement({
+      'getMaxValue': function() {
+        return 100;
+      }
+    });
+    (end code)
+    
+  */  
+  getMaxValue: function() {
+    var maxValue = 0, stacked = this.config.type.split(':')[0] == 'stacked';
+    this.delegate.graph.eachNode(function(n) {
+      var valArray = n.getData('valueArray'),
+          acum = 0;
+      if(!valArray) return;
+      if(stacked) {
+        $.each(valArray, function(v) { 
+          acum += +v;
+        });
+      } else {
+        acum = Math.max.apply(null, valArray);
+      }
+      maxValue = maxValue>acum? maxValue:acum;
+    });
+    return maxValue;
+  },
+  
+  setBarType: function(type) {
+    this.config.type = type;
+    this.delegate.config.Node.type = 'barchart-' + type.split(':')[0];
+  },
+  
+  normalizeDims: function() {
+    //number of elements
+    var root = this.delegate.graph.getNode(this.delegate.root), l=0;
+    root.eachAdjacency(function() {
+      l++;
+    });
+    var maxValue = this.getMaxValue() || 1,
+        size = this.delegate.canvas.getSize(),
+        config = this.config,
+        margin = config.Margin,
+        marginWidth = margin.left + margin.right,
+        marginHeight = margin.top + margin.bottom,
+        horz = config.orientation == 'horizontal',
+        fixedDim = (size[horz? 'height':'width'] - (horz? marginHeight:marginWidth) - (l -1) * config.barsOffset) / l,
+        animate = config.animate,
+        height = size[horz? 'width':'height'] - (horz? marginWidth:marginHeight) 
+          - (!horz && config.showAggregates && (config.Label.size + config.labelOffset))
+          - (config.showLabels && (config.Label.size + config.labelOffset)),
+        dim1 = horz? 'height':'width',
+        dim2 = horz? 'width':'height';
+    this.delegate.graph.eachNode(function(n) {
+      var acum = 0, animateValue = [];
+      $.each(n.getData('valueArray'), function(v) {
+        acum += +v;
+        animateValue.push(0);
+      });
+      n.setData(dim1, fixedDim);
+      if(animate) {
+        n.setData(dim2, acum * height / maxValue, 'end');
+        n.setData('dimArray', $.map(n.getData('valueArray'), function(n) { 
+          return n * height / maxValue; 
+        }), 'end');
+        var dimArray = n.getData('dimArray');
+        if(!dimArray) {
+          n.setData('dimArray', animateValue);
+        }
+      } else {
+        n.setData(dim2, acum * height / maxValue);
+        n.setData('dimArray', $.map(n.getData('valueArray'), function(n) { 
+          return n * height / maxValue; 
+        }));
+      }
+    });
+  }
+});
+
+
+/*
+ * File: Options.PieChart.js
+ *
+*/
+/*
+  Object: Options.PieChart
+  
+  <PieChart> options. 
+  Other options included in the PieChart are <Options.Canvas>, <Options.Label>, <Options.Tips> and <Options.Events>.
+  
+  Syntax:
+  
+  (start code js)
+
+  Options.PieChart = {
+    animate: true,
+    offset: 25,
+    sliceOffset:0,
+    labelOffset: 3,
+    type: 'stacked',
+    hoveredColor: '#9fd4ff',
+    showLabels: true,
+    resizeLabels: false,
+    updateHeights: false
+  };  
+
+  (end code)
+  
+  Example:
+  
+  (start code js)
+
+  var pie = new $jit.PieChart({
+    animate: true,
+    sliceOffset: 5,
+    type: 'stacked:gradient'
+  });  
+
+  (end code)
+  
+  Parameters:
+  
+  animate - (boolean) Default's *true*. Whether to add animated transitions when plotting/updating the visualization.
+  offset - (number) Default's *25*. Adds margin between the visualization and the canvas.
+  sliceOffset - (number) Default's *0*. Separation between the center of the canvas and each pie slice.
+  labelOffset - (number) Default's *3*. Adds margin between the label and the default place where it should be drawn.
+  type - (string) Default's *'stacked'*. Stack style. Posible values are 'stacked', 'stacked:gradient' to add gradients.
+  hoveredColor - (boolean|string) Default's *'#9fd4ff'*. Sets the selected color for a hovered pie stack.
+  showLabels - (boolean) Default's *true*. Display the name of the slots.
+  resizeLabels - (boolean|number) Default's *false*. Resize the pie labels according to their stacked values. Set a number for *resizeLabels* to set a font size minimum.
+  updateHeights - (boolean) Default's *false*. Only for mono-valued (most common) pie charts. Resize the height of the pie slices according to their current values.
+
+*/
+Options.PieChart = {
+  $extend: true,
+
+  animate: true,
+  offset: 25, // page offset
+  sliceOffset:0,
+  labelOffset: 3, // label offset
+  type: 'stacked', // gradient
+  hoveredColor: '#9fd4ff',
+  Events: {
+    enable: false,
+    onClick: $.empty
+  },
+  Tips: {
+    enable: false,
+    onShow: $.empty,
+    onHide: $.empty
+  },
+  showLabels: true,
+  resizeLabels: false,
+  
+  //only valid for mono-valued datasets
+  updateHeights: false
+};
+
+/*
+ * Class: Layouts.Radial
+ * 
+ * Implements a Radial Layout.
+ * 
+ * Implemented By:
+ * 
+ * <RGraph>, <Hypertree>
+ * 
+ */
+Layouts.Radial = new Class({
+
+  /*
+   * Method: compute
+   * 
+   * Computes nodes' positions.
+   * 
+   * Parameters:
+   * 
+   * property - _optional_ A <Graph.Node> position property to store the new
+   * positions. Possible values are 'pos', 'end' or 'start'.
+   * 
+   */
+  compute : function(property) {
+    var prop = $.splat(property || [ 'current', 'start', 'end' ]);
+    NodeDim.compute(this.graph, prop, this.config);
+    this.graph.computeLevels(this.root, 0, "ignore");
+    var lengthFunc = this.createLevelDistanceFunc(); 
+    this.computeAngularWidths(prop);
+    this.computePositions(prop, lengthFunc);
+  },
+
+  /*
+   * computePositions
+   * 
+   * Performs the main algorithm for computing node positions.
+   */
+  computePositions : function(property, getLength) {
+    var propArray = property;
+    var graph = this.graph;
+    var root = graph.getNode(this.root);
+    var parent = this.parent;
+    var config = this.config;
+
+    for ( var i=0, l=propArray.length; i < l; i++) {
+      var pi = propArray[i];
+      root.setPos($P(0, 0), pi);
+      root.setData('span', Math.PI * 2, pi);
+    }
+
+    root.angleSpan = {
+      begin : 0,
+      end : 2 * Math.PI
+    };
+
+    graph.eachBFS(this.root, function(elem) {
+      var angleSpan = elem.angleSpan.end - elem.angleSpan.begin;
+      var angleInit = elem.angleSpan.begin;
+      var len = getLength(elem);
+      //Calculate the sum of all angular widths
+      var totalAngularWidths = 0, subnodes = [], maxDim = {};
+      elem.eachSubnode(function(sib) {
+        totalAngularWidths += sib._treeAngularWidth;
+        //get max dim
+        for ( var i=0, l=propArray.length; i < l; i++) {
+          var pi = propArray[i], dim = sib.getData('dim', pi);
+          maxDim[pi] = (pi in maxDim)? (dim > maxDim[pi]? dim : maxDim[pi]) : dim;
+        }
+        subnodes.push(sib);
+      }, "ignore");
+      //Maintain children order
+      //Second constraint for <http://bailando.sims.berkeley.edu/papers/infovis01.htm>
+      if (parent && parent.id == elem.id && subnodes.length > 0
+          && subnodes[0].dist) {
+        subnodes.sort(function(a, b) {
+          return (a.dist >= b.dist) - (a.dist <= b.dist);
+        });
+      }
+      //Calculate nodes positions.
+      for (var k = 0, ls=subnodes.length; k < ls; k++) {
+        var child = subnodes[k];
+        if (!child._flag) {
+          var angleProportion = child._treeAngularWidth / totalAngularWidths * angleSpan;
+          var theta = angleInit + angleProportion / 2;
+
+          for ( var i=0, l=propArray.length; i < l; i++) {
+            var pi = propArray[i];
+            child.setPos($P(theta, len), pi);
+            child.setData('span', angleProportion, pi);
+            child.setData('dim-quotient', child.getData('dim', pi) / maxDim[pi], pi);
+          }
+
+          child.angleSpan = {
+            begin : angleInit,
+            end : angleInit + angleProportion
+          };
+          angleInit += angleProportion;
+        }
+      }
+    }, "ignore");
+  },
+
+  /*
+   * Method: setAngularWidthForNodes
+   * 
+   * Sets nodes angular widths.
+   */
+  setAngularWidthForNodes : function(prop) {
+    this.graph.eachBFS(this.root, function(elem, i) {
+      var diamValue = elem.getData('angularWidth', prop[0]) || 5;
+      elem._angularWidth = diamValue / i;
+    }, "ignore");
+  },
+
+  /*
+   * Method: setSubtreesAngularWidth
+   * 
+   * Sets subtrees angular widths.
+   */
+  setSubtreesAngularWidth : function() {
+    var that = this;
+    this.graph.eachNode(function(elem) {
+      that.setSubtreeAngularWidth(elem);
+    }, "ignore");
+  },
+
+  /*
+   * Method: setSubtreeAngularWidth
+   * 
+   * Sets the angular width for a subtree.
+   */
+  setSubtreeAngularWidth : function(elem) {
+    var that = this, nodeAW = elem._angularWidth, sumAW = 0;
+    elem.eachSubnode(function(child) {
+      that.setSubtreeAngularWidth(child);
+      sumAW += child._treeAngularWidth;
+    }, "ignore");
+    elem._treeAngularWidth = Math.max(nodeAW, sumAW);
+  },
+
+  /*
+   * Method: computeAngularWidths
+   * 
+   * Computes nodes and subtrees angular widths.
+   */
+  computeAngularWidths : function(prop) {
+    this.setAngularWidthForNodes(prop);
+    this.setSubtreesAngularWidth();
+  }
+
+});
+
+
+/*
+ * File: Sunburst.js
+ */
+
+/*
+   Class: Sunburst
+      
+   A radial space filling tree visualization.
+   
+   Inspired by:
+ 
+   Sunburst <http://www.cc.gatech.edu/gvu/ii/sunburst/>.
+   
+   Note:
+   
+   This visualization was built and engineered from scratch, taking only the paper as inspiration, and only shares some features with the visualization described in the paper.
+   
+  Implements:
+  
+  All <Loader> methods
+  
+   Constructor Options:
+   
+   Inherits options from
+   
+   - <Options.Canvas>
+   - <Options.Controller>
+   - <Options.Node>
+   - <Options.Edge>
+   - <Options.Label>
+   - <Options.Events>
+   - <Options.Tips>
+   - <Options.NodeStyles>
+   - <Options.Navigation>
+   
+   Additionally, there are other parameters and some default values changed
+   
+   interpolation - (string) Default's *linear*. Describes the way nodes are interpolated. Possible values are 'linear' and 'polar'.
+   levelDistance - (number) Default's *100*. The distance between levels of the tree. 
+   Node.type - Described in <Options.Node>. Default's to *multipie*.
+   Node.height - Described in <Options.Node>. Default's *0*.
+   Edge.type - Described in <Options.Edge>. Default's *none*.
+   Label.textAlign - Described in <Options.Label>. Default's *start*.
+   Label.textBaseline - Described in <Options.Label>. Default's *middle*.
+     
+   Instance Properties:
+
+   canvas - Access a <Canvas> instance.
+   graph - Access a <Graph> instance.
+   op - Access a <Sunburst.Op> instance.
+   fx - Access a <Sunburst.Plot> instance.
+   labels - Access a <Sunburst.Label> interface implementation.   
+
+*/
+
+$jit.Sunburst = new Class({
+
+  Implements: [ Loader, Extras, Layouts.Radial ],
+
+  initialize: function(controller) {
+    var $Sunburst = $jit.Sunburst;
+
+    var config = {
+      interpolation: 'linear',
+      levelDistance: 100,
+      Node: {
+        'type': 'multipie',
+        'height':0
+      },
+      Edge: {
+        'type': 'none'
+      },
+      Label: {
+        textAlign: 'start',
+        textBaseline: 'middle'
+      }
+    };
+
+    this.controller = this.config = $.merge(Options("Canvas", "Node", "Edge",
+        "Fx", "Tips", "NodeStyles", "Events", "Navigation", "Controller", "Label"), config, controller);
+
+    var canvasConfig = this.config;
+    if(canvasConfig.useCanvas) {
+      this.canvas = canvasConfig.useCanvas;
+      this.config.labelContainer = this.canvas.id + '-label';
+    } else {
+      if(canvasConfig.background) {
+        canvasConfig.background = $.merge({
+          type: 'Circles'
+        }, canvasConfig.background);
+      }
+      this.canvas = new Canvas(this, canvasConfig);
+      this.config.labelContainer = (typeof canvasConfig.injectInto == 'string'? canvasConfig.injectInto : canvasConfig.injectInto.id) + '-label';
+    }
+
+    this.graphOptions = {
+      'klass': Polar,
+      'Node': {
+        'selected': false,
+        'exist': true,
+        'drawn': true
+      }
+    };
+    this.graph = new Graph(this.graphOptions, this.config.Node,
+        this.config.Edge);
+    this.labels = new $Sunburst.Label[canvasConfig.Label.type](this);
+    this.fx = new $Sunburst.Plot(this, $Sunburst);
+    this.op = new $Sunburst.Op(this);
+    this.json = null;
+    this.root = null;
+    this.rotated = null;
+    this.busy = false;
+    // initialize extras
+    this.initializeExtras();
+  },
+
+  /* 
+  
+    createLevelDistanceFunc 
+  
+    Returns the levelDistance function used for calculating a node distance 
+    to its origin. This function returns a function that is computed 
+    per level and not per node, such that all nodes with the same depth will have the 
+    same distance to the origin. The resulting function gets the 
+    parent node as parameter and returns a float.
+
+   */
+  createLevelDistanceFunc: function() {
+    var ld = this.config.levelDistance;
+    return function(elem) {
+      return (elem._depth + 1) * ld;
+    };
+  },
+
+  /* 
+     Method: refresh 
+     
+     Computes positions and plots the tree.
+
+   */
+  refresh: function() {
+    this.compute();
+    this.plot();
+  },
+
+  /*
+   reposition
+  
+   An alias for computing new positions to _endPos_
+
+   See also:
+
+   <Sunburst.compute>
+   
+  */
+  reposition: function() {
+    this.compute('end');
+  },
+
+  /*
+  Method: rotate
+  
+  Rotates the graph so that the selected node is horizontal on the right.
+
+  Parameters:
+  
+  node - (object) A <Graph.Node>.
+  method - (string) Whether to perform an animation or just replot the graph. Possible values are "replot" or "animate".
+  opt - (object) Configuration options merged with this visualization configuration options.
+  
+  See also:
+
+  <Sunburst.rotateAngle>
+  
+  */
+  rotate: function(node, method, opt) {
+    var theta = node.getPos(opt.property || 'current').getp(true).theta;
+    this.rotated = node;
+    this.rotateAngle(-theta, method, opt);
+  },
+
+  /*
+  Method: rotateAngle
+  
+  Rotates the graph of an angle theta.
+  
+   Parameters:
+   
+   node - (object) A <Graph.Node>.
+   method - (string) Whether to perform an animation or just replot the graph. Possible values are "replot" or "animate".
+   opt - (object) Configuration options merged with this visualization configuration options.
+   
+   See also:
+
+   <Sunburst.rotate>
+  
+  */
+  rotateAngle: function(theta, method, opt) {
+    var that = this;
+    var options = $.merge(this.config, opt || {}, {
+      modes: [ 'polar' ]
+    });
+    var prop = opt.property || (method === "animate" ? 'end' : 'current');
+    if(method === 'animate') {
+      this.fx.animation.pause();
+    }
+    this.graph.eachNode(function(n) {
+      var p = n.getPos(prop);
+      p.theta += theta;
+      if (p.theta < 0) {
+        p.theta += Math.PI * 2;
+      }
+    });
+    if (method == 'animate') {
+      this.fx.animate(options);
+    } else if (method == 'replot') {
+      this.fx.plot();
+      this.busy = false;
+    }
+  },
+
+  /*
+   Method: plot
+  
+   Plots the Sunburst. This is a shortcut to *fx.plot*.
+  */
+  plot: function() {
+    this.fx.plot();
+  }
+});
+
+$jit.Sunburst.$extend = true;
+
+(function(Sunburst) {
+
+  /*
+     Class: Sunburst.Op
+
+     Custom extension of <Graph.Op>.
+
+     Extends:
+
+     All <Graph.Op> methods
+     
+     See also:
+     
+     <Graph.Op>
+
+  */
+  Sunburst.Op = new Class( {
+
+    Implements: Graph.Op
+
+  });
+
+  /*
+     Class: Sunburst.Plot
+
+    Custom extension of <Graph.Plot>.
+  
+    Extends:
+  
+    All <Graph.Plot> methods
+    
+    See also:
+    
+    <Graph.Plot>
+  
+  */
+  Sunburst.Plot = new Class( {
+
+    Implements: Graph.Plot
+
+  });
+
+  /*
+    Class: Sunburst.Label
+
+    Custom extension of <Graph.Label>. 
+    Contains custom <Graph.Label.SVG>, <Graph.Label.HTML> and <Graph.Label.Native> extensions.
+  
+    Extends:
+  
+    All <Graph.Label> methods and subclasses.
+  
+    See also:
+  
+    <Graph.Label>, <Graph.Label.Native>, <Graph.Label.HTML>, <Graph.Label.SVG>.
+  
+   */
+  Sunburst.Label = {};
+
+  /*
+     Sunburst.Label.Native
+
+     Custom extension of <Graph.Label.Native>.
+
+     Extends:
+
+     All <Graph.Label.Native> methods
+
+     See also:
+
+     <Graph.Label.Native>
+  */
+  Sunburst.Label.Native = new Class( {
+    Implements: Graph.Label.Native,
+
+    initialize: function(viz) {
+      this.viz = viz;
+      this.label = viz.config.Label;
+      this.config = viz.config;
+    },
+
+    renderLabel: function(canvas, node, controller) {
+      var span = node.getData('span');
+      if(span < Math.PI /2 && Math.tan(span) * 
+          this.config.levelDistance * node._depth < 10) {
+        return;
+      }
+      var ctx = canvas.getCtx();
+      var measure = ctx.measureText(node.name);
+      if (node.id == this.viz.root) {
+        var x = -measure.width / 2, y = 0, thetap = 0;
+        var ld = 0;
+      } else {
+        var indent = 5;
+        var ld = controller.levelDistance - indent;
+        var clone = node.pos.clone();
+        clone.rho += indent;
+        var p = clone.getp(true);
+        var ct = clone.getc(true);
+        var x = ct.x, y = ct.y;
+        // get angle in degrees
+        var pi = Math.PI;
+        var cond = (p.theta > pi / 2 && p.theta < 3 * pi / 2);
+        var thetap = cond ? p.theta + pi : p.theta;
+        if (cond) {
+          x -= Math.abs(Math.cos(p.theta) * measure.width);
+          y += Math.sin(p.theta) * measure.width;
+        } else if (node.id == this.viz.root) {
+          x -= measure.width / 2;
+        }
+      }
+      ctx.save();
+      ctx.translate(x, y);
+      ctx.rotate(thetap);
+      ctx.fillText(node.name, 0, 0);
+      ctx.restore();
+    }
+  });
+
+  /*
+     Sunburst.Label.SVG
+
+    Custom extension of <Graph.Label.SVG>.
+  
+    Extends:
+  
+    All <Graph.Label.SVG> methods
+  
+    See also:
+  
+    <Graph.Label.SVG>
+  
+  */
+  Sunburst.Label.SVG = new Class( {
+    Implements: Graph.Label.SVG,
+
+    initialize: function(viz) {
+      this.viz = viz;
+    },
+
+    /* 
+       placeLabel
+
+       Overrides abstract method placeLabel in <Graph.Plot>.
+
+       Parameters:
+
+       tag - A DOM label element.
+       node - A <Graph.Node>.
+       controller - A configuration/controller object passed to the visualization.
+      
+     */
+    placeLabel: function(tag, node, controller) {
+      var pos = node.pos.getc(true), viz = this.viz, canvas = this.viz.canvas;
+      var radius = canvas.getSize();
+      var labelPos = {
+        x: Math.round(pos.x + radius.width / 2),
+        y: Math.round(pos.y + radius.height / 2)
+      };
+      tag.setAttribute('x', labelPos.x);
+      tag.setAttribute('y', labelPos.y);
+
+      var bb = tag.getBBox();
+      if (bb) {
+        // center the label
+    var x = tag.getAttribute('x');
+    var y = tag.getAttribute('y');
+    // get polar coordinates
+    var p = node.pos.getp(true);
+    // get angle in degrees
+    var pi = Math.PI;
+    var cond = (p.theta > pi / 2 && p.theta < 3 * pi / 2);
+    if (cond) {
+      tag.setAttribute('x', x - bb.width);
+      tag.setAttribute('y', y - bb.height);
+    } else if (node.id == viz.root) {
+      tag.setAttribute('x', x - bb.width / 2);
+    }
+
+    var thetap = cond ? p.theta + pi : p.theta;
+    if(node._depth)
+      tag.setAttribute('transform', 'rotate(' + thetap * 360 / (2 * pi) + ' ' + x
+          + ' ' + y + ')');
+  }
+
+  controller.onPlaceLabel(tag, node);
+}
+  });
+
+  /*
+     Sunburst.Label.HTML
+
+     Custom extension of <Graph.Label.HTML>.
+
+     Extends:
+
+     All <Graph.Label.HTML> methods.
+
+     See also:
+
+     <Graph.Label.HTML>
+
+  */
+  Sunburst.Label.HTML = new Class( {
+    Implements: Graph.Label.HTML,
+
+    initialize: function(viz) {
+      this.viz = viz;
+    },
+    /* 
+       placeLabel
+
+       Overrides abstract method placeLabel in <Graph.Plot>.
+
+       Parameters:
+
+       tag - A DOM label element.
+       node - A <Graph.Node>.
+       controller - A configuration/controller object passed to the visualization.
+      
+     */
+    placeLabel: function(tag, node, controller) {
+      var pos = node.pos.clone(), 
+          canvas = this.viz.canvas,
+          height = node.getData('height'),
+          ldist = ((height || node._depth == 0)? height : this.viz.config.levelDistance) /2,
+          radius = canvas.getSize();
+      pos.rho += ldist;
+      pos = pos.getc(true);
+      
+      var labelPos = {
+        x: Math.round(pos.x + radius.width / 2),
+        y: Math.round(pos.y + radius.height / 2)
+      };
+
+      var style = tag.style;
+      style.left = labelPos.x + 'px';
+      style.top = labelPos.y + 'px';
+      style.display = this.fitsInCanvas(labelPos, canvas) ? '' : 'none';
+
+      controller.onPlaceLabel(tag, node);
+    }
+  });
+
+  /*
+    Class: Sunburst.Plot.NodeTypes
+
+    This class contains a list of <Graph.Node> built-in types. 
+    Node types implemented are 'none', 'pie', 'multipie', 'gradient-pie' and 'gradient-multipie'.
+
+    You can add your custom node types, customizing your visualization to the extreme.
+
+    Example:
+
+    (start code js)
+      Sunburst.Plot.NodeTypes.implement({
+        'mySpecialType': {
+          'render': function(node, canvas) {
+            //print your custom node to canvas
+          },
+          //optional
+          'contains': function(node, pos) {
+            //return true if pos is inside the node or false otherwise
+          }
+        }
+      });
+    (end code)
+
+  */
+  Sunburst.Plot.NodeTypes = new Class( {
+    'none': {
+      'render': $.empty,
+      'contains': $.lambda(false),
+      'anglecontains': function(node, pos) {
+        var span = node.getData('span') / 2, theta = node.pos.theta;
+        var begin = theta - span, end = theta + span;
+        if (begin < 0)
+          begin += Math.PI * 2;
+        var atan = Math.atan2(pos.y, pos.x);
+        if (atan < 0)
+          atan += Math.PI * 2;
+        if (begin > end) {
+          return (atan > begin && atan <= Math.PI * 2) || atan < end;
+        } else {
+          return atan > begin && atan < end;
+        }
+      }
+    },
+
+    'pie': {
+      'render': function(node, canvas) {
+        var span = node.getData('span') / 2, theta = node.pos.theta;
+        var begin = theta - span, end = theta + span;
+        var polarNode = node.pos.getp(true);
+        var polar = new Polar(polarNode.rho, begin);
+        var p1coord = polar.getc(true);
+        polar.theta = end;
+        var p2coord = polar.getc(true);
+
+        var ctx = canvas.getCtx();
+        ctx.beginPath();
+        ctx.moveTo(0, 0);
+        ctx.lineTo(p1coord.x, p1coord.y);
+        ctx.moveTo(0, 0);
+        ctx.lineTo(p2coord.x, p2coord.y);
+        ctx.moveTo(0, 0);
+        ctx.arc(0, 0, polarNode.rho * node.getData('dim-quotient'), begin, end,
+            false);
+        ctx.fill();
+      },
+      'contains': function(node, pos) {
+        if (this.nodeTypes['none'].anglecontains.call(this, node, pos)) {
+          var rho = Math.sqrt(pos.x * pos.x + pos.y * pos.y);
+          var ld = this.config.levelDistance, d = node._depth;
+          return (rho <= ld * d);
+        }
+        return false;
+      }
+    },
+    'multipie': {
+      'render': function(node, canvas) {
+        var height = node.getData('height');
+        var ldist = height? height : this.config.levelDistance;
+        var span = node.getData('span') / 2, theta = node.pos.theta;
+        var begin = theta - span, end = theta + span;
+        var polarNode = node.pos.getp(true);
+
+        var polar = new Polar(polarNode.rho, begin);
+        var p1coord = polar.getc(true);
+
+        polar.theta = end;
+        var p2coord = polar.getc(true);
+
+        polar.rho += ldist;
+        var p3coord = polar.getc(true);
+
+        polar.theta = begin;
+        var p4coord = polar.getc(true);
+
+        var ctx = canvas.getCtx();
+        ctx.moveTo(0, 0);
+        ctx.beginPath();
+        ctx.arc(0, 0, polarNode.rho, begin, end, false);
+        ctx.arc(0, 0, polarNode.rho + ldist, end, begin, true);
+        ctx.moveTo(p1coord.x, p1coord.y);
+        ctx.lineTo(p4coord.x, p4coord.y);
+        ctx.moveTo(p2coord.x, p2coord.y);
+        ctx.lineTo(p3coord.x, p3coord.y);
+        ctx.fill();
+
+        if (node.collapsed) {
+          ctx.save();
+          ctx.lineWidth = 2;
+          ctx.moveTo(0, 0);
+          ctx.beginPath();
+          ctx.arc(0, 0, polarNode.rho + ldist + 5, end - 0.01, begin + 0.01,
+              true);
+          ctx.stroke();
+          ctx.restore();
+        }
+      },
+      'contains': function(node, pos) {
+        if (this.nodeTypes['none'].anglecontains.call(this, node, pos)) {
+          var rho = Math.sqrt(pos.x * pos.x + pos.y * pos.y);
+          var height = node.getData('height');
+          var ldist = height? height : this.config.levelDistance;
+          var ld = this.config.levelDistance, d = node._depth;
+          return (rho >= ld * d) && (rho <= (ld * d + ldist));
+        }
+        return false;
+      }
+    },
+
+    'gradient-multipie': {
+      'render': function(node, canvas) {
+        var ctx = canvas.getCtx();
+        var height = node.getData('height');
+        var ldist = height? height : this.config.levelDistance;
+        var radialGradient = ctx.createRadialGradient(0, 0, node.getPos().rho,
+            0, 0, node.getPos().rho + ldist);
+
+        var colorArray = $.hexToRgb(node.getData('color')), ans = [];
+        $.each(colorArray, function(i) {
+          ans.push(parseInt(i * 0.5, 10));
+        });
+        var endColor = $.rgbToHex(ans);
+        radialGradient.addColorStop(0, endColor);
+        radialGradient.addColorStop(1, node.getData('color'));
+        ctx.fillStyle = radialGradient;
+        this.nodeTypes['multipie'].render.call(this, node, canvas);
+      },
+      'contains': function(node, pos) {
+        return this.nodeTypes['multipie'].contains.call(this, node, pos);
+      }
+    },
+
+    'gradient-pie': {
+      'render': function(node, canvas) {
+        var ctx = canvas.getCtx();
+        var radialGradient = ctx.createRadialGradient(0, 0, 0, 0, 0, node
+            .getPos().rho);
+
+        var colorArray = $.hexToRgb(node.getData('color')), ans = [];
+        $.each(colorArray, function(i) {
+          ans.push(parseInt(i * 0.5, 10));
+        });
+        var endColor = $.rgbToHex(ans);
+        radialGradient.addColorStop(1, endColor);
+        radialGradient.addColorStop(0, node.getData('color'));
+        ctx.fillStyle = radialGradient;
+        this.nodeTypes['pie'].render.call(this, node, canvas);
+      },
+      'contains': function(node, pos) {
+        return this.nodeTypes['pie'].contains.call(this, node, pos);
+      }
+    }
+  });
+
+  /*
+    Class: Sunburst.Plot.EdgeTypes
+
+    This class contains a list of <Graph.Adjacence> built-in types. 
+    Edge types implemented are 'none', 'line' and 'arrow'.
+  
+    You can add your custom edge types, customizing your visualization to the extreme.
+  
+    Example:
+  
+    (start code js)
+      Sunburst.Plot.EdgeTypes.implement({
+        'mySpecialType': {
+          'render': function(adj, canvas) {
+            //print your custom edge to canvas
+          },
+          //optional
+          'contains': function(adj, pos) {
+            //return true if pos is inside the arc or false otherwise
+          }
+        }
+      });
+    (end code)
+  
+  */
+  Sunburst.Plot.EdgeTypes = new Class({
+    'none': $.empty,
+    'line': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true);
+        this.edgeHelper.line.render(from, to, canvas);
+      },
+      'contains': function(adj, pos) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true);
+        return this.edgeHelper.line.contains(from, to, pos, this.edge.epsilon);
+      }
+    },
+    'arrow': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true),
+            dim = adj.getData('dim'),
+            direction = adj.data.$direction,
+            inv = (direction && direction.length>1 && direction[0] != adj.nodeFrom.id);
+        this.edgeHelper.arrow.render(from, to, dim, inv, canvas);
+      },
+      'contains': function(adj, pos) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true);
+        return this.edgeHelper.arrow.contains(from, to, pos, this.edge.epsilon);
+      }
+    },
+    'hyperline': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(),
+            to = adj.nodeTo.pos.getc(),
+            dim = Math.max(from.norm(), to.norm());
+        this.edgeHelper.hyperline.render(from.$scale(1/dim), to.$scale(1/dim), dim, canvas);
+      },
+      'contains': $.lambda(false) //TODO(nico): Implement this!
+    }
+  });
+
+})($jit.Sunburst);
+
+
+/*
+ * File: PieChart.js
+ *
+*/
+
+$jit.Sunburst.Plot.NodeTypes.implement({
+  'piechart-stacked' : {
+    'render' : function(node, canvas) {
+      var pos = node.pos.getp(true),
+          dimArray = node.getData('dimArray'),
+          valueArray = node.getData('valueArray'),
+          colorArray = node.getData('colorArray'),
+          colorLength = colorArray.length,
+          stringArray = node.getData('stringArray'),
+          span = node.getData('span') / 2,
+          theta = node.pos.theta,
+          begin = theta - span,
+          end = theta + span,
+          polar = new Polar;
+    
+      var ctx = canvas.getCtx(), 
+          opt = {},
+          gradient = node.getData('gradient'),
+          border = node.getData('border'),
+          config = node.getData('config'),
+          showLabels = config.showLabels,
+          resizeLabels = config.resizeLabels,
+          label = config.Label;
+
+      var xpos = config.sliceOffset * Math.cos((begin + end) /2);
+      var ypos = config.sliceOffset * Math.sin((begin + end) /2);
+
+      if (colorArray && dimArray && stringArray) {
+        for (var i=0, l=dimArray.length, acum=0, valAcum=0; i<l; i++) {
+          var dimi = dimArray[i], colori = colorArray[i % colorLength];
+          if(dimi <= 0) continue;
+          ctx.fillStyle = ctx.strokeStyle = colori;
+          if(gradient && dimi) {
+            var radialGradient = ctx.createRadialGradient(xpos, ypos, acum + config.sliceOffset,
+                xpos, ypos, acum + dimi + config.sliceOffset);
+            var colorRgb = $.hexToRgb(colori), 
+                ans = $.map(colorRgb, function(i) { return (i * 0.8) >> 0; }),
+                endColor = $.rgbToHex(ans);
+
+            radialGradient.addColorStop(0, colori);
+            radialGradient.addColorStop(0.5, colori);
+            radialGradient.addColorStop(1, endColor);
+            ctx.fillStyle = radialGradient;
+          }
+          
+          polar.rho = acum + config.sliceOffset;
+          polar.theta = begin;
+          var p1coord = polar.getc(true);
+          polar.theta = end;
+          var p2coord = polar.getc(true);
+          polar.rho += dimi;
+          var p3coord = polar.getc(true);
+          polar.theta = begin;
+          var p4coord = polar.getc(true);
+
+          ctx.beginPath();
+          //fixing FF arc method + fill
+          ctx.arc(xpos, ypos, acum + .01, begin, end, false);
+          ctx.arc(xpos, ypos, acum + dimi + .01, end, begin, true);
+          ctx.fill();
+          if(border && border.name == stringArray[i]) {
+            opt.acum = acum;
+            opt.dimValue = dimArray[i];
+            opt.begin = begin;
+            opt.end = end;
+          }
+          acum += (dimi || 0);
+          valAcum += (valueArray[i] || 0);
+        }
+        if(border) {
+          ctx.save();
+          ctx.globalCompositeOperation = "source-over";
+          ctx.lineWidth = 2;
+          ctx.strokeStyle = border.color;
+          var s = begin < end? 1 : -1;
+          ctx.beginPath();
+          //fixing FF arc method + fill
+          ctx.arc(xpos, ypos, opt.acum + .01 + 1, opt.begin, opt.end, false);
+          ctx.arc(xpos, ypos, opt.acum + opt.dimValue + .01 - 1, opt.end, opt.begin, true);
+          ctx.closePath();
+          ctx.stroke();
+          ctx.restore();
+        }
+        if(showLabels && label.type == 'Native') {
+          ctx.save();
+          ctx.fillStyle = ctx.strokeStyle = label.color;
+          var scale = resizeLabels? node.getData('normalizedDim') : 1,
+              fontSize = (label.size * scale) >> 0;
+          fontSize = fontSize < +resizeLabels? +resizeLabels : fontSize;
+          
+          ctx.font = label.style + ' ' + fontSize + 'px ' + label.family;
+          ctx.textBaseline = 'middle';
+          ctx.textAlign = 'center';
+          
+          polar.rho = acum + config.labelOffset + config.sliceOffset;
+          polar.theta = node.pos.theta;
+          var cart = polar.getc(true);
+          
+          ctx.fillText(node.name, cart.x, cart.y);
+          ctx.restore();
+        }
+      }
+    },
+    'contains': function(node, pos) {
+      if (this.nodeTypes['none'].anglecontains.call(this, node, pos)) {
+        var rho = Math.sqrt(pos.x * pos.x + pos.y * pos.y);
+        var ld = this.config.levelDistance, d = node._depth;
+        var config = node.getData('config');
+        if(rho <=ld * d + config.sliceOffset) {
+          var dimArray = node.getData('dimArray');
+          for(var i=0,l=dimArray.length,acum=config.sliceOffset; i<l; i++) {
+            var dimi = dimArray[i];
+            if(rho >= acum && rho <= acum + dimi) {
+              return {
+                name: node.getData('stringArray')[i],
+                color: node.getData('colorArray')[i],
+                value: node.getData('valueArray')[i],
+                label: node.name
+              };
+            }
+            acum += dimi;
+          }
+        }
+        return false;
+        
+      }
+      return false;
+    }
+  }
+});
+
+/*
+  Class: PieChart
+  
+  A visualization that displays stacked bar charts.
+  
+  Constructor Options:
+  
+  See <Options.PieChart>.
+
+*/
+$jit.PieChart = new Class({
+  sb: null,
+  colors: ["#416D9C", "#70A35E", "#EBB056", "#C74243", "#83548B", "#909291", "#557EAA"],
+  selected: {},
+  busy: false,
+  
+  initialize: function(opt) {
+    this.controller = this.config = 
+      $.merge(Options("Canvas", "PieChart", "Label"), {
+        Label: { type: 'Native' }
+      }, opt);
+    this.initializeViz();
+  },
+  
+  initializeViz: function() {
+    var config = this.config, that = this;
+    var nodeType = config.type.split(":")[0];
+    var delegate = new $jit.Sunburst({
+      injectInto: config.injectInto,
+      width: config.width,
+      height: config.height,
+      useCanvas: config.useCanvas,
+      withLabels: config.Label.type != 'Native',
+      Label: {
+        type: config.Label.type
+      },
+      Node: {
+        overridable: true,
+        type: 'piechart-' + nodeType,
+        width: 1,
+        height: 1
+      },
+      Edge: {
+        type: 'none'
+      },
+      Tips: {
+        enable: config.Tips.enable,
+        type: 'Native',
+        force: true,
+        onShow: function(tip, node, contains) {
+          var elem = contains;
+          config.Tips.onShow(tip, elem, node);
+        }
+      },
+      Events: {
+        enable: true,
+        type: 'Native',
+        onClick: function(node, eventInfo, evt) {
+          if(!config.Events.enable) return;
+          var elem = eventInfo.getContains();
+          config.Events.onClick(elem, eventInfo, evt);
+        },
+        onMouseMove: function(node, eventInfo, evt) {
+          if(!config.hoveredColor) return;
+          if(node) {
+            var elem = eventInfo.getContains();
+            that.select(node.id, elem.name, elem.index);
+          } else {
+            that.select(false, false, false);
+          }
+        }
+      },
+      onCreateLabel: function(domElement, node) {
+        var labelConf = config.Label;
+        if(config.showLabels) {
+          var style = domElement.style;
+          style.fontSize = labelConf.size + 'px';
+          style.fontFamily = labelConf.family;
+          style.color = labelConf.color;
+          style.textAlign = 'center';
+          domElement.innerHTML = node.name;
+        }
+      },
+      onPlaceLabel: function(domElement, node) {
+        if(!config.showLabels) return;
+        var pos = node.pos.getp(true),
+            dimArray = node.getData('dimArray'),
+            span = node.getData('span') / 2,
+            theta = node.pos.theta,
+            begin = theta - span,
+            end = theta + span,
+            polar = new Polar;
+      
+        var showLabels = config.showLabels,
+            resizeLabels = config.resizeLabels,
+            label = config.Label;
+        
+        if (dimArray) {
+          for (var i=0, l=dimArray.length, acum=0; i<l; i++) {
+            acum += dimArray[i];
+          }
+          var scale = resizeLabels? node.getData('normalizedDim') : 1,
+              fontSize = (label.size * scale) >> 0;
+          fontSize = fontSize < +resizeLabels? +resizeLabels : fontSize;
+          domElement.style.fontSize = fontSize + 'px';
+          polar.rho = acum + config.labelOffset + config.sliceOffset;
+          polar.theta = (begin + end) / 2;
+          var pos = polar.getc(true);
+          var radius = that.canvas.getSize();
+          var labelPos = {
+            x: Math.round(pos.x + radius.width / 2),
+            y: Math.round(pos.y + radius.height / 2)
+          };
+          domElement.style.left = labelPos.x + 'px';
+          domElement.style.top = labelPos.y + 'px';
+        }
+      }
+    });
+    
+    var size = delegate.canvas.getSize(),
+        min = Math.min;
+    delegate.config.levelDistance = min(size.width, size.height)/2 
+      - config.offset - config.sliceOffset;
+    this.delegate = delegate;
+    this.canvas = this.delegate.canvas;
+    this.canvas.getCtx().globalCompositeOperation = 'lighter';
+  },
+  
+  /*
+    Method: loadJSON
+   
+    Loads JSON data into the visualization. 
+    
+    Parameters:
+    
+    json - The JSON data format. This format is described in <http://blog.thejit.org/2010/04/24/new-javascript-infovis-toolkit-visualizations/#json-data-format>.
+    
+    Example:
+    (start code js)
+    var pieChart = new $jit.PieChart(options);
+    pieChart.loadJSON(json);
+    (end code)
+  */  
+  loadJSON: function(json) {
+    var prefix = $.time(), 
+        ch = [], 
+        delegate = this.delegate,
+        name = $.splat(json.label),
+        nameLength = name.length,
+        color = $.splat(json.color || this.colors),
+        colorLength = color.length,
+        config = this.config,
+        gradient = !!config.type.split(":")[1],
+        animate = config.animate,
+        mono = nameLength == 1;
+    
+    for(var i=0, values=json.values, l=values.length; i<l; i++) {
+      var val = values[i];
+      var valArray = $.splat(val.values);
+      ch.push({
+        'id': prefix + val.label,
+        'name': val.label,
+        'data': {
+          'value': valArray,
+          '$valueArray': valArray,
+          '$colorArray': mono? $.splat(color[i % colorLength]) : color,
+          '$stringArray': name,
+          '$gradient': gradient,
+          '$config': config,
+          '$angularWidth': $.reduce(valArray, function(x,y){return x+y;})
+        },
+        'children': []
+      });
+    }
+    var root = {
+      'id': prefix + '$root',
+      'name': '',
+      'data': {
+        '$type': 'none',
+        '$width': 1,
+        '$height': 1
+      },
+      'children': ch
+    };
+    delegate.loadJSON(root);
+    
+    this.normalizeDims();
+    delegate.refresh();
+    if(animate) {
+      delegate.fx.animate({
+        modes: ['node-property:dimArray'],
+        duration:1500
+      });
+    }
+  },
+  
+  /*
+    Method: updateJSON
+   
+    Use this method when updating values for the current JSON data. If the items specified by the JSON data already exist in the graph then their values will be updated.
+    
+    Parameters:
+    
+    json - (object) JSON data to be updated. The JSON format corresponds to the one described in <PieChart.loadJSON>.
+    onComplete - (object) A callback object to be called when the animation transition when updating the data end.
+    
+    Example:
+    
+    (start code js)
+    pieChart.updateJSON(json, {
+      onComplete: function() {
+        alert('update complete!');
+      }
+    });
+    (end code)
+  */  
+  updateJSON: function(json, onComplete) {
+    if(this.busy) return;
+    this.busy = true;
+    
+    var delegate = this.delegate;
+    var graph = delegate.graph;
+    var values = json.values;
+    var animate = this.config.animate;
+    var that = this;
+    $.each(values, function(v) {
+      var n = graph.getByName(v.label),
+          vals = $.splat(v.values);
+      if(n) {
+        n.setData('valueArray', vals);
+        n.setData('angularWidth', $.reduce(vals, function(x,y){return x+y;}));
+        if(json.label) {
+          n.setData('stringArray', $.splat(json.label));
+        }
+      }
+    });
+    this.normalizeDims();
+    if(animate) {
+      delegate.compute('end');
+      delegate.fx.animate({
+        modes: ['node-property:dimArray:span', 'linear'],
+        duration:1500,
+        onComplete: function() {
+          that.busy = false;
+          onComplete && onComplete.onComplete();
+        }
+      });
+    } else {
+      delegate.refresh();
+    }
+  },
+    
+  //adds the little brown bar when hovering the node
+  select: function(id, name) {
+    if(!this.config.hoveredColor) return;
+    var s = this.selected;
+    if(s.id != id || s.name != name) {
+      s.id = id;
+      s.name = name;
+      s.color = this.config.hoveredColor;
+      this.delegate.graph.eachNode(function(n) {
+        if(id == n.id) {
+          n.setData('border', s);
+        } else {
+          n.setData('border', false);
+        }
+      });
+      this.delegate.plot();
+    }
+  },
+  
+  /*
+    Method: getLegend
+   
+    Returns an object containing as keys the legend names and as values hex strings with color values.
+    
+    Example:
+    
+    (start code js)
+    var legend = pieChart.getLegend();
+    (end code)
+  */  
+  getLegend: function() {
+    var legend = {};
+    var n;
+    this.delegate.graph.getNode(this.delegate.root).eachAdjacency(function(adj) {
+      n = adj.nodeTo;
+    });
+    var colors = n.getData('colorArray'),
+        len = colors.length;
+    $.each(n.getData('stringArray'), function(s, i) {
+      legend[s] = colors[i % len];
+    });
+    return legend;
+  },
+  
+  /*
+    Method: getMaxValue
+   
+    Returns the maximum accumulated value for the stacks. This method is used for normalizing the graph heights according to the canvas height.
+    
+    Example:
+    
+    (start code js)
+    var ans = pieChart.getMaxValue();
+    (end code)
+    
+    In some cases it could be useful to override this method to normalize heights for a group of PieCharts, like when doing small multiples.
+    
+    Example:
+    
+    (start code js)
+    //will return 100 for all PieChart instances,
+    //displaying all of them with the same scale
+    $jit.PieChart.implement({
+      'getMaxValue': function() {
+        return 100;
+      }
+    });
+    (end code)
+    
+  */  
+  getMaxValue: function() {
+    var maxValue = 0;
+    this.delegate.graph.eachNode(function(n) {
+      var valArray = n.getData('valueArray'),
+          acum = 0;
+      $.each(valArray, function(v) { 
+        acum += +v;
+      });
+      maxValue = maxValue>acum? maxValue:acum;
+    });
+    return maxValue;
+  },
+  
+  normalizeDims: function() {
+    //number of elements
+    var root = this.delegate.graph.getNode(this.delegate.root), l=0;
+    root.eachAdjacency(function() {
+      l++;
+    });
+    var maxValue = this.getMaxValue() || 1,
+        config = this.config,
+        animate = config.animate,
+        rho = this.delegate.config.levelDistance;
+    this.delegate.graph.eachNode(function(n) {
+      var acum = 0, animateValue = [];
+      $.each(n.getData('valueArray'), function(v) {
+        acum += +v;
+        animateValue.push(1);
+      });
+      var stat = (animateValue.length == 1) && !config.updateHeights;
+      if(animate) {
+        n.setData('dimArray', $.map(n.getData('valueArray'), function(n) { 
+          return stat? rho: (n * rho / maxValue); 
+        }), 'end');
+        var dimArray = n.getData('dimArray');
+        if(!dimArray) {
+          n.setData('dimArray', animateValue);
+        }
+      } else {
+        n.setData('dimArray', $.map(n.getData('valueArray'), function(n) { 
+          return stat? rho : (n * rho / maxValue); 
+        }));
+      }
+      n.setData('normalizedDim', acum / maxValue);
+    });
+  }
+});
+
+
+/*
+ * Class: Layouts.TM
+ * 
+ * Implements TreeMaps layouts (SliceAndDice, Squarified, Strip).
+ * 
+ * Implemented By:
+ * 
+ * <TM>
+ * 
+ */
+Layouts.TM = {};
+
+Layouts.TM.SliceAndDice = new Class({
+  compute: function(prop) {
+    var root = this.graph.getNode(this.clickedNode && this.clickedNode.id || this.root);
+    this.controller.onBeforeCompute(root);
+    var size = this.canvas.getSize(),
+        config = this.config,
+        width = size.width,
+        height = size.height;
+    this.graph.computeLevels(this.root, 0, "ignore");
+    //set root position and dimensions
+    root.getPos(prop).setc(-width/2, -height/2);
+    root.setData('width', width, prop);
+    root.setData('height', height + config.titleHeight, prop);
+    this.computePositions(root, root, this.layout.orientation, prop);
+    this.controller.onAfterCompute(root);
+  },
+  
+  computePositions: function(par, ch, orn, prop) {
+    //compute children areas
+    var totalArea = 0;
+    par.eachSubnode(function(n) {
+      totalArea += n.getData('area', prop);
+    });
+    
+    var config = this.config,
+        offst = config.offset,
+        width  = par.getData('width', prop),
+        height = Math.max(par.getData('height', prop) - config.titleHeight, 0),
+        fact = par == ch? 1 : (ch.getData('area', prop) / totalArea);
+
+    var otherSize, size, dim, pos, pos2, posth, pos2th;
+    var horizontal = (orn == "h");
+    if(horizontal) {
+      orn = 'v';
+      otherSize = height;
+      size = width * fact;
+      dim = 'height';
+      pos = 'y';
+      pos2 = 'x';
+      posth = config.titleHeight;
+      pos2th = 0;
+    } else {
+      orn = 'h';    
+      otherSize = height * fact;
+      size = width;
+      dim = 'width';
+      pos = 'x';
+      pos2 = 'y';
+      posth = 0;
+      pos2th = config.titleHeight;
+    }
+    var cpos = ch.getPos(prop);
+    ch.setData('width', size, prop);
+    ch.setData('height', otherSize, prop);
+    var offsetSize = 0, tm = this;
+    ch.eachSubnode(function(n) {
+      var p = n.getPos(prop);
+      p[pos] = offsetSize + cpos[pos] + posth;
+      p[pos2] = cpos[pos2] + pos2th;
+      tm.computePositions(ch, n, orn, prop);
+      offsetSize += n.getData(dim, prop);
+    });
+  }
+
+});
+
+Layouts.TM.Area = {
+ /*
+    Method: compute
+ 
+   Called by loadJSON to calculate recursively all node positions and lay out the tree.
+ 
+    Parameters:
+
+       json - A JSON tree. See also <Loader.loadJSON>.
+       coord - A coordinates object specifying width, height, left and top style properties.
+ */
+ compute: function(prop) {
+    prop = prop || "current";
+    var root = this.graph.getNode(this.clickedNode && this.clickedNode.id || this.root);
+    this.controller.onBeforeCompute(root);
+    var config = this.config,
+        size = this.canvas.getSize(),
+        width = size.width,
+        height = size.height,
+        offst = config.offset,
+        offwdth = width - offst,
+        offhght = height - offst;
+    this.graph.computeLevels(this.root, 0, "ignore");
+    //set root position and dimensions
+    root.getPos(prop).setc(-width/2, -height/2);
+    root.setData('width', width, prop);
+    root.setData('height', height, prop);
+    //create a coordinates object
+    var coord = {
+        'top': -height/2 + config.titleHeight,
+        'left': -width/2,
+        'width': offwdth,
+        'height': offhght - config.titleHeight
+    };
+    this.computePositions(root, coord, prop);
+    this.controller.onAfterCompute(root);
+ }, 
+ 
+ /*
+    Method: computeDim
+ 
+   Computes dimensions and positions of a group of nodes
+   according to a custom layout row condition. 
+ 
+    Parameters:
+
+       tail - An array of nodes.  
+       initElem - An array of nodes (containing the initial node to be laid).
+       w - A fixed dimension where nodes will be layed out.
+       coord - A coordinates object specifying width, height, left and top style properties.
+       comp - A custom comparison function
+ */
+ computeDim: function(tail, initElem, w, coord, comp, prop) {
+   if(tail.length + initElem.length == 1) {
+     var l = (tail.length == 1)? tail : initElem;
+     this.layoutLast(l, w, coord, prop);
+     return;
+   }
+   if(tail.length >= 2 && initElem.length == 0) {
+     initElem = [tail.shift()];
+   }
+   if(tail.length == 0) {
+     if(initElem.length > 0) this.layoutRow(initElem, w, coord, prop);
+     return;
+   }
+   var c = tail[0];
+   if(comp(initElem, w) >= comp([c].concat(initElem), w)) {
+     this.computeDim(tail.slice(1), initElem.concat([c]), w, coord, comp, prop);
+   } else {
+     var newCoords = this.layoutRow(initElem, w, coord, prop);
+     this.computeDim(tail, [], newCoords.dim, newCoords, comp, prop);
+   }
+ },
+
+ 
+ /*
+    Method: worstAspectRatio
+ 
+   Calculates the worst aspect ratio of a group of rectangles. 
+       
+    See also:
+       
+       <http://en.wikipedia.org/wiki/Aspect_ratio>
+   
+    Parameters:
+
+     ch - An array of nodes.  
+     w  - The fixed dimension where rectangles are being laid out.
+
+    Returns:
+ 
+        The worst aspect ratio.
+
+
+ */
+ worstAspectRatio: function(ch, w) {
+   if(!ch || ch.length == 0) return Number.MAX_VALUE;
+   var areaSum = 0, maxArea = 0, minArea = Number.MAX_VALUE;
+   for(var i=0, l=ch.length; i<l; i++) {
+     var area = ch[i]._area;
+     areaSum += area; 
+     minArea = minArea < area? minArea : area;
+     maxArea = maxArea > area? maxArea : area; 
+   }
+   var sqw = w * w, sqAreaSum = areaSum * areaSum;
+   return Math.max(sqw * maxArea / sqAreaSum,
+           sqAreaSum / (sqw * minArea));
+ },
+ 
+ /*
+    Method: avgAspectRatio
+ 
+   Calculates the average aspect ratio of a group of rectangles. 
+       
+       See also:
+       
+       <http://en.wikipedia.org/wiki/Aspect_ratio>
+   
+    Parameters:
+
+     ch - An array of nodes.  
+       w - The fixed dimension where rectangles are being laid out.
+
+    Returns:
+ 
+        The average aspect ratio.
+
+
+ */
+ avgAspectRatio: function(ch, w) {
+   if(!ch || ch.length == 0) return Number.MAX_VALUE;
+   var arSum = 0;
+   for(var i=0, l=ch.length; i<l; i++) {
+     var area = ch[i]._area;
+     var h = area / w;
+     arSum += w > h? w / h : h / w;
+   }
+   return arSum / l;
+ },
+
+ /*
+    layoutLast
+ 
+   Performs the layout of the last computed sibling.
+ 
+    Parameters:
+
+       ch - An array of nodes.  
+       w - A fixed dimension where nodes will be layed out.
+     coord - A coordinates object specifying width, height, left and top style properties.
+ */
+ layoutLast: function(ch, w, coord, prop) {
+   var child = ch[0];
+   child.getPos(prop).setc(coord.left, coord.top);
+   child.setData('width', coord.width, prop);
+   child.setData('height', coord.height, prop);
+ }
+};
+
+
+Layouts.TM.Squarified = new Class({
+ Implements: Layouts.TM.Area,
+ 
+ computePositions: function(node, coord, prop) {
+   var config = this.config, 
+       max = Math.max;
+   
+   if (coord.width >= coord.height) 
+     this.layout.orientation = 'h';
+   else
+     this.layout.orientation = 'v';
+   
+   var ch = node.getSubnodes([1, 1], "ignore");
+   if(ch.length > 0) {
+     this.processChildrenLayout(node, ch, coord, prop);
+     for(var i=0, l=ch.length; i<l; i++) {
+       var chi = ch[i], 
+           offst = config.offset,
+           height = max(chi.getData('height', prop) - offst - config.titleHeight, 0),
+           width = max(chi.getData('width', prop) - offst, 0),
+           chipos = chi.getPos(prop);
+
+       coord = {
+         'width': width,
+         'height': height,
+         'top': chipos.y + config.titleHeight,
+         'left': chipos.x
+       };
+       this.computePositions(chi, coord, prop);
+     }
+   }
+ },
+
+ /*
+    Method: processChildrenLayout
+ 
+   Computes children real areas and other useful parameters for performing the Squarified algorithm.
+ 
+    Parameters:
+
+       par - The parent node of the json subtree.  
+       ch - An Array of nodes
+     coord - A coordinates object specifying width, height, left and top style properties.
+ */
+ processChildrenLayout: function(par, ch, coord, prop) {
+   //compute children real areas
+   var parentArea = coord.width * coord.height;
+   var i, l=ch.length, totalChArea=0, chArea = [];
+   for(i=0; i<l; i++) {
+     chArea[i] = parseFloat(ch[i].getData('area', prop));
+     totalChArea += chArea[i];
+   }
+   for(i=0; i<l; i++) {
+     ch[i]._area = parentArea * chArea[i] / totalChArea;
+   }
+   var minimumSideValue = this.layout.horizontal()? coord.height : coord.width;
+   ch.sort(function(a, b) { 
+     var diff = b._area - a._area; 
+     return diff? diff : (b.id == a.id? 0 : (b.id < a.id? 1 : -1)); 
+   });
+   var initElem = [ch[0]];
+   var tail = ch.slice(1);
+   this.squarify(tail, initElem, minimumSideValue, coord, prop);
+ },
+
+ /*
+   Method: squarify
+ 
+   Performs an heuristic method to calculate div elements sizes in order to have a good aspect ratio.
+ 
+    Parameters:
+
+       tail - An array of nodes.  
+       initElem - An array of nodes, containing the initial node to be laid out.
+       w - A fixed dimension where nodes will be laid out.
+       coord - A coordinates object specifying width, height, left and top style properties.
+ */
+ squarify: function(tail, initElem, w, coord, prop) {
+   this.computeDim(tail, initElem, w, coord, this.worstAspectRatio, prop);
+ },
+ 
+ /*
+    Method: layoutRow
+ 
+   Performs the layout of an array of nodes.
+ 
+    Parameters:
+
+       ch - An array of nodes.  
+       w - A fixed dimension where nodes will be laid out.
+       coord - A coordinates object specifying width, height, left and top style properties.
+ */
+ layoutRow: function(ch, w, coord, prop) {
+   if(this.layout.horizontal()) {
+     return this.layoutV(ch, w, coord, prop);
+   } else {
+     return this.layoutH(ch, w, coord, prop);
+   }
+ },
+ 
+ layoutV: function(ch, w, coord, prop) {
+   var totalArea = 0, rnd = function(x) { return x; }; 
+   $.each(ch, function(elem) { totalArea += elem._area; });
+   var width = rnd(totalArea / w), top =  0; 
+   for(var i=0, l=ch.length; i<l; i++) {
+     var h = rnd(ch[i]._area / width);
+     var chi = ch[i];
+     chi.getPos(prop).setc(coord.left, coord.top + top);
+     chi.setData('width', width, prop);
+     chi.setData('height', h, prop);
+     top += h;
+   }
+   var ans = {
+     'height': coord.height,
+     'width': coord.width - width,
+     'top': coord.top,
+     'left': coord.left + width
+   };
+   //take minimum side value.
+   ans.dim = Math.min(ans.width, ans.height);
+   if(ans.dim != ans.height) this.layout.change();
+   return ans;
+ },
+ 
+ layoutH: function(ch, w, coord, prop) {
+   var totalArea = 0; 
+   $.each(ch, function(elem) { totalArea += elem._area; });
+   var height = totalArea / w,
+       top = coord.top, 
+       left = 0;
+   
+   for(var i=0, l=ch.length; i<l; i++) {
+     var chi = ch[i];
+     var w = chi._area / height;
+     chi.getPos(prop).setc(coord.left + left, top);
+     chi.setData('width', w, prop);
+     chi.setData('height', height, prop);
+     left += w;
+   }
+   var ans = {
+     'height': coord.height - height,
+     'width': coord.width,
+     'top': coord.top + height,
+     'left': coord.left
+   };
+   ans.dim = Math.min(ans.width, ans.height);
+   if(ans.dim != ans.width) this.layout.change();
+   return ans;
+ }
+});
+
+Layouts.TM.Strip = new Class({
+  Implements: Layouts.TM.Area,
+
+    /*
+      Method: compute
+    
+     Called by loadJSON to calculate recursively all node positions and lay out the tree.
+    
+      Parameters:
+    
+         json - A JSON subtree. See also <Loader.loadJSON>. 
+       coord - A coordinates object specifying width, height, left and top style properties.
+    */
+    computePositions: function(node, coord, prop) {
+     var  ch = node.getSubnodes([1, 1], "ignore"), 
+          config = this.config,
+          max = Math.max;
+     if(ch.length > 0) {
+       this.processChildrenLayout(node, ch, coord, prop);
+       for(var i=0, l=ch.length; i<l; i++) {
+         var chi = ch[i];
+         var offst = config.offset,
+             height = max(chi.getData('height', prop) - offst - config.titleHeight, 0),
+             width  = max(chi.getData('width', prop)  - offst, 0);
+         var chipos = chi.getPos(prop);
+         coord = {
+           'width': width,
+           'height': height,
+           'top': chipos.y + config.titleHeight,
+           'left': chipos.x
+         };
+         this.computePositions(chi, coord, prop);
+       }
+     }
+    },
+    
+    /*
+      Method: processChildrenLayout
+    
+     Computes children real areas and other useful parameters for performing the Strip algorithm.
+    
+      Parameters:
+    
+         par - The parent node of the json subtree.  
+         ch - An Array of nodes
+         coord - A coordinates object specifying width, height, left and top style properties.
+    */
+    processChildrenLayout: function(par, ch, coord, prop) {
+     //compute children real areas
+      var parentArea = coord.width * coord.height;
+      var i, l=ch.length, totalChArea=0, chArea = [];
+      for(i=0; i<l; i++) {
+        chArea[i] = +ch[i].getData('area', prop);
+        totalChArea += chArea[i];
+      }
+      for(i=0; i<l; i++) {
+        ch[i]._area = parentArea * chArea[i] / totalChArea;
+      }
+     var side = this.layout.horizontal()? coord.width : coord.height;
+     var initElem = [ch[0]];
+     var tail = ch.slice(1);
+     this.stripify(tail, initElem, side, coord, prop);
+    },
+    
+    /*
+      Method: stripify
+    
+     Performs an heuristic method to calculate div elements sizes in order to have 
+     a good compromise between aspect ratio and order.
+    
+      Parameters:
+    
+         tail - An array of nodes.  
+         initElem - An array of nodes.
+         w - A fixed dimension where nodes will be layed out.
+       coord - A coordinates object specifying width, height, left and top style properties.
+    */
+    stripify: function(tail, initElem, w, coord, prop) {
+     this.computeDim(tail, initElem, w, coord, this.avgAspectRatio, prop);
+    },
+    
+    /*
+      Method: layoutRow
+    
+     Performs the layout of an array of nodes.
+    
+      Parameters:
+    
+         ch - An array of nodes.  
+         w - A fixed dimension where nodes will be laid out.
+         coord - A coordinates object specifying width, height, left and top style properties.
+    */
+    layoutRow: function(ch, w, coord, prop) {
+     if(this.layout.horizontal()) {
+       return this.layoutH(ch, w, coord, prop);
+     } else {
+       return this.layoutV(ch, w, coord, prop);
+     }
+    },
+    
+    layoutV: function(ch, w, coord, prop) {
+     var totalArea = 0; 
+     $.each(ch, function(elem) { totalArea += elem._area; });
+     var width = totalArea / w, top =  0; 
+     for(var i=0, l=ch.length; i<l; i++) {
+       var chi = ch[i];
+       var h = chi._area / width;
+       chi.getPos(prop).setc(coord.left, 
+           coord.top + (w - h - top));
+       chi.setData('width', width, prop);
+       chi.setData('height', h, prop);
+       top += h;
+     }
+    
+     return {
+       'height': coord.height,
+       'width': coord.width - width,
+       'top': coord.top,
+       'left': coord.left + width,
+       'dim': w
+     };
+    },
+    
+    layoutH: function(ch, w, coord, prop) {
+     var totalArea = 0; 
+     $.each(ch, function(elem) { totalArea += elem._area; });
+     var height = totalArea / w,
+         top = coord.height - height, 
+         left = 0;
+     
+     for(var i=0, l=ch.length; i<l; i++) {
+       var chi = ch[i];
+       var s = chi._area / height;
+       chi.getPos(prop).setc(coord.left + left, coord.top + top);
+       chi.setData('width', s, prop);
+       chi.setData('height', height, prop);
+       left += s;
+     }
+     return {
+       'height': coord.height - height,
+       'width': coord.width,
+       'top': coord.top,
+       'left': coord.left,
+       'dim': w
+     };
+    }
+ });
+
+
+/*
+ * Class: Layouts.Icicle
+ *
+ * Implements the icicle tree layout.
+ *
+ * Implemented By:
+ *
+ * <Icicle>
+ *
+ */
+
+Layouts.Icicle = new Class({
+ /*
+  * Method: compute
+  *
+  * Called by loadJSON to calculate all node positions.
+  *
+  * Parameters:
+  *
+  * posType - The nodes' position to compute. Either "start", "end" or
+  *            "current". Defaults to "current".
+  */
+  compute: function(posType) {
+    posType = posType || "current";
+
+    var root = this.graph.getNode(this.root),
+        config = this.config,
+        size = this.canvas.getSize(),
+        width = size.width,
+        height = size.height,
+        offset = config.offset,
+        levelsToShow = config.constrained ? config.levelsToShow : Number.MAX_VALUE;
+
+    this.controller.onBeforeCompute(root);
+
+    Graph.Util.computeLevels(this.graph, root.id, 0, "ignore");
+
+    var treeDepth = 0;
+
+    Graph.Util.eachLevel(root, 0, false, function (n, d) { if(d > treeDepth) treeDepth = d; });
+
+    var startNode = this.graph.getNode(this.clickedNode && this.clickedNode.id || root.id);
+    var maxDepth = Math.min(treeDepth, levelsToShow-1);
+    var initialDepth = startNode._depth;
+    if(this.layout.horizontal()) {
+      this.computeSubtree(startNode, -width/2, -height/2, width/(maxDepth+1), height, initialDepth, maxDepth, posType);
+    } else {
+      this.computeSubtree(startNode, -width/2, -height/2, width, height/(maxDepth+1), initialDepth, maxDepth, posType);
+    }
+  },
+
+  computeSubtree: function (root, x, y, width, height, initialDepth, maxDepth, posType) {
+    root.getPos(posType).setc(x, y);
+    root.setData('width', width, posType);
+    root.setData('height', height, posType);
+
+    var nodeLength, prevNodeLength = 0, totalDim = 0;
+    var children = Graph.Util.getSubnodes(root, [1, 1], 'ignore'); // next level from this node
+
+    if(!children.length)
+      return;
+
+    $.each(children, function(e) { totalDim += e.getData('dim'); });
+
+    for(var i=0, l=children.length; i < l; i++) {
+      if(this.layout.horizontal()) {
+        nodeLength = height * children[i].getData('dim') / totalDim;
+        this.computeSubtree(children[i], x+width, y, width, nodeLength, initialDepth, maxDepth, posType);
+        y += nodeLength;
+      } else {
+        nodeLength = width * children[i].getData('dim') / totalDim;
+        this.computeSubtree(children[i], x, y+height, nodeLength, height, initialDepth, maxDepth, posType);
+        x += nodeLength;
+      }
+    }
+  }
+});
+
+
+
+/*
+ * File: Icicle.js
+ *
+*/
+
+/*
+  Class: Icicle
+  
+  Icicle space filling visualization.
+  
+  Implements:
+  
+  All <Loader> methods
+  
+  Constructor Options:
+  
+  Inherits options from
+  
+  - <Options.Canvas>
+  - <Options.Controller>
+  - <Options.Node>
+  - <Options.Edge>
+  - <Options.Label>
+  - <Options.Events>
+  - <Options.Tips>
+  - <Options.NodeStyles>
+  - <Options.Navigation>
+  
+  Additionally, there are other parameters and some default values changed
+
+  orientation - (string) Default's *h*. Whether to set horizontal or vertical layouts. Possible values are 'h' and 'v'.
+  offset - (number) Default's *2*. Boxes offset.
+  constrained - (boolean) Default's *false*. Whether to show the entire tree when loaded or just the number of levels specified by _levelsToShow_.
+  levelsToShow - (number) Default's *3*. The number of levels to show for a subtree. This number is relative to the selected node.
+  animate - (boolean) Default's *false*. Whether to animate transitions.
+  Node.type - Described in <Options.Node>. Default's *rectangle*.
+  Label.type - Described in <Options.Label>. Default's *Native*.
+  duration - Described in <Options.Fx>. Default's *700*.
+  fps - Described in <Options.Fx>. Default's *45*.
+  
+  Instance Properties:
+  
+  canvas - Access a <Canvas> instance.
+  graph - Access a <Graph> instance.
+  op - Access a <Icicle.Op> instance.
+  fx - Access a <Icicle.Plot> instance.
+  labels - Access a <Icicle.Label> interface implementation.
+
+*/
+
+$jit.Icicle = new Class({
+  Implements: [ Loader, Extras, Layouts.Icicle ],
+
+  layout: {
+    orientation: "h",
+    vertical: function(){
+      return this.orientation == "v";
+    },
+    horizontal: function(){
+      return this.orientation == "h";
+    },
+    change: function(){
+      this.orientation = this.vertical()? "h" : "v";
+    }
+  },
+
+  initialize: function(controller) {
+    var config = {
+      animate: false,
+      orientation: "h",
+      offset: 2,
+      levelsToShow: Number.MAX_VALUE,
+      constrained: false,
+      Node: {
+        type: 'rectangle',
+        overridable: true
+      },
+      Edge: {
+        type: 'none'
+      },
+      Label: {
+        type: 'Native'
+      },
+      duration: 700,
+      fps: 45
+    };
+
+    var opts = Options("Canvas", "Node", "Edge", "Fx", "Tips", "NodeStyles",
+                       "Events", "Navigation", "Controller", "Label");
+    this.controller = this.config = $.merge(opts, config, controller);
+    this.layout.orientation = this.config.orientation;
+
+    var canvasConfig = this.config;
+    if (canvasConfig.useCanvas) {
+      this.canvas = canvasConfig.useCanvas;
+      this.config.labelContainer = this.canvas.id + '-label';
+    } else {
+      this.canvas = new Canvas(this, canvasConfig);
+      this.config.labelContainer = (typeof canvasConfig.injectInto == 'string'? canvasConfig.injectInto : canvasConfig.injectInto.id) + '-label';
+    }
+
+    this.graphOptions = {
+      'klass': Complex,
+      'Node': {
+        'selected': false,
+        'exist': true,
+        'drawn': true
+      }
+    };
+
+    this.graph = new Graph(
+      this.graphOptions, this.config.Node, this.config.Edge, this.config.Label);
+
+    this.labels = new $jit.Icicle.Label[this.config.Label.type](this);
+    this.fx = new $jit.Icicle.Plot(this, $jit.Icicle);
+    this.op = new $jit.Icicle.Op(this);
+    this.group = new $jit.Icicle.Group(this);
+    this.clickedNode = null;
+
+    this.initializeExtras();
+  },
+
+  /* 
+    Method: refresh 
+    
+    Computes positions and plots the tree.
+  */
+  refresh: function(){
+    var labelType = this.config.Label.type;
+    if(labelType != 'Native') {
+      var that = this;
+      this.graph.eachNode(function(n) { that.labels.hideLabel(n, false); });
+    }
+    this.compute();
+    this.plot();
+  },
+
+  /* 
+    Method: plot 
+    
+    Plots the Icicle visualization. This is a shortcut to *fx.plot*. 
+  
+   */
+  plot: function(){
+    this.fx.plot(this.config);
+  },
+
+  /* 
+    Method: enter 
+    
+    Sets the node as root.
+    
+     Parameters:
+     
+     node - (object) A <Graph.Node>.
+  
+   */
+  enter: function (node) {
+    if (this.busy)
+      return;
+    this.busy = true;
+
+    var that = this,
+        config = this.config;
+
+    var callback = {
+      onComplete: function() {
+        //compute positions of newly inserted nodes
+        if(config.request)
+          that.compute();
+
+        if(config.animate) {
+          that.graph.nodeList.setDataset(['current', 'end'], {
+            'alpha': [1, 0] //fade nodes
+          });
+
+          Graph.Util.eachSubgraph(node, function(n) {
+            n.setData('alpha', 1, 'end');
+          }, "ignore");
+
+          that.fx.animate({
+            duration: 500,
+            modes:['node-property:alpha'],
+            onComplete: function() {
+              that.clickedNode = node;
+              that.compute('end');
+
+              that.fx.animate({
+                modes:['linear', 'node-property:width:height'],
+                duration: 1000,
+                onComplete: function() {
+                  that.busy = false;
+                  that.clickedNode = node;
+                }
+              });
+            }
+          });
+        } else {
+          that.clickedNode = node;
+          that.busy = false;
+          that.refresh();
+        }
+      }
+    };
+
+    if(config.request) {
+      this.requestNodes(clickedNode, callback);
+    } else {
+      callback.onComplete();
+    }
+  },
+
+  /* 
+    Method: out 
+    
+    Sets the parent node of the current selected node as root.
+  
+   */
+  out: function(){
+    if(this.busy)
+      return;
+
+    var that = this,
+        GUtil = Graph.Util,
+        config = this.config,
+        graph = this.graph,
+        parents = GUtil.getParents(graph.getNode(this.clickedNode && this.clickedNode.id || this.root)),
+        parent = parents[0],
+        clickedNode = parent,
+        previousClickedNode = this.clickedNode;
+
+    this.busy = true;
+    this.events.hoveredNode = false;
+
+    if(!parent) {
+      this.busy = false;
+      return;
+    }
+
+    //final plot callback
+    callback = {
+      onComplete: function() {
+        that.clickedNode = parent;
+        if(config.request) {
+          that.requestNodes(parent, {
+            onComplete: function() {
+              that.compute();
+              that.plot();
+              that.busy = false;
+            }
+          });
+        } else {
+          that.compute();
+          that.plot();
+          that.busy = false;
+        }
+      }
+    };
+
+    //animate node positions
+    if(config.animate) {
+      this.clickedNode = clickedNode;
+      this.compute('end');
+      //animate the visible subtree only
+      this.clickedNode = previousClickedNode;
+      this.fx.animate({
+        modes:['linear', 'node-property:width:height'],
+        duration: 1000,
+        onComplete: function() {
+          //animate the parent subtree
+          that.clickedNode = clickedNode;
+          //change nodes alpha
+          graph.nodeList.setDataset(['current', 'end'], {
+            'alpha': [0, 1]
+          });
+          GUtil.eachSubgraph(previousClickedNode, function(node) {
+            node.setData('alpha', 1);
+          }, "ignore");
+          that.fx.animate({
+            duration: 500,
+            modes:['node-property:alpha'],
+            onComplete: function() {
+              callback.onComplete();
+            }
+          });
+        }
+      });
+    } else {
+      callback.onComplete();
+    }
+  },
+  requestNodes: function(node, onComplete){
+    var handler = $.merge(this.controller, onComplete),
+        levelsToShow = this.config.constrained ? this.config.levelsToShow : Number.MAX_VALUE;
+
+    if (handler.request) {
+      var leaves = [], d = node._depth;
+      Graph.Util.eachLevel(node, 0, levelsToShow, function(n){
+        if (n.drawn && !Graph.Util.anySubnode(n)) {
+          leaves.push(n);
+          n._level = n._depth - d;
+          if (this.config.constrained)
+            n._level = levelsToShow - n._level;
+
+        }
+      });
+      this.group.requestNodes(leaves, handler);
+    } else {
+      handler.onComplete();
+    }
+  }
+});
+
+/*
+  Class: Icicle.Op
+  
+  Custom extension of <Graph.Op>.
+  
+  Extends:
+  
+  All <Graph.Op> methods
+  
+  See also:
+  
+  <Graph.Op>
+  
+  */
+$jit.Icicle.Op = new Class({
+
+  Implements: Graph.Op
+
+});
+
+/*
+ * Performs operations on group of nodes.
+ */
+$jit.Icicle.Group = new Class({
+
+  initialize: function(viz){
+    this.viz = viz;
+    this.canvas = viz.canvas;
+    this.config = viz.config;
+  },
+
+  /*
+   * Calls the request method on the controller to request a subtree for each node.
+   */
+  requestNodes: function(nodes, controller){
+    var counter = 0, len = nodes.length, nodeSelected = {};
+    var complete = function(){
+      controller.onComplete();
+    };
+    var viz = this.viz;
+    if (len == 0)
+      complete();
+    for(var i = 0; i < len; i++) {
+      nodeSelected[nodes[i].id] = nodes[i];
+      controller.request(nodes[i].id, nodes[i]._level, {
+        onComplete: function(nodeId, data){
+          if (data && data.children) {
+            data.id = nodeId;
+            viz.op.sum(data, {
+              type: 'nothing'
+            });
+          }
+          if (++counter == len) {
+            Graph.Util.computeLevels(viz.graph, viz.root, 0);
+            complete();
+          }
+        }
+      });
+    }
+  }
+});
+
+/*
+  Class: Icicle.Plot
+  
+  Custom extension of <Graph.Plot>.
+  
+  Extends:
+  
+  All <Graph.Plot> methods
+  
+  See also:
+  
+  <Graph.Plot>
+  
+  */
+$jit.Icicle.Plot = new Class({
+  Implements: Graph.Plot,
+
+  plot: function(opt, animating){
+    opt = opt || this.viz.controller;
+    var viz = this.viz,
+        graph = viz.graph,
+        root = graph.getNode(viz.clickedNode && viz.clickedNode.id || viz.root),
+        initialDepth = root._depth;
+
+    viz.canvas.clear();
+    this.plotTree(root, $.merge(opt, {
+      'withLabels': true,
+      'hideLabels': false,
+      'plotSubtree': function(root, node) {
+        return !viz.config.constrained ||
+               (node._depth - initialDepth < viz.config.levelsToShow);
+      }
+    }), animating);
+  }
+});
+
+/*
+  Class: Icicle.Label
+  
+  Custom extension of <Graph.Label>. 
+  Contains custom <Graph.Label.SVG>, <Graph.Label.HTML> and <Graph.Label.Native> extensions.
+  
+  Extends:
+  
+  All <Graph.Label> methods and subclasses.
+  
+  See also:
+  
+  <Graph.Label>, <Graph.Label.Native>, <Graph.Label.HTML>, <Graph.Label.SVG>.
+  
+  */
+$jit.Icicle.Label = {};
+
+/*
+  Icicle.Label.Native
+  
+  Custom extension of <Graph.Label.Native>.
+  
+  Extends:
+  
+  All <Graph.Label.Native> methods
+  
+  See also:
+  
+  <Graph.Label.Native>
+
+  */
+$jit.Icicle.Label.Native = new Class({
+  Implements: Graph.Label.Native,
+
+  renderLabel: function(canvas, node, controller) {
+    var ctx = canvas.getCtx(),
+        width = node.getData('width'),
+        height = node.getData('height'),
+        size = node.getLabelData('size'),
+        m = ctx.measureText(node.name);
+
+    // Guess as much as possible if the label will fit in the node
+    if(height < (size * 1.5) || width < m.width)
+      return;
+
+    var pos = node.pos.getc(true);
+    ctx.fillText(node.name,
+                 pos.x + width / 2,
+                 pos.y + height / 2);
+  }
+});
+
+/*
+  Icicle.Label.SVG
+  
+  Custom extension of <Graph.Label.SVG>.
+  
+  Extends:
+  
+  All <Graph.Label.SVG> methods
+  
+  See also:
+  
+  <Graph.Label.SVG>
+*/
+$jit.Icicle.Label.SVG = new Class( {
+  Implements: Graph.Label.SVG,
+
+  initialize: function(viz){
+    this.viz = viz;
+  },
+
+  /*
+    placeLabel
+   
+    Overrides abstract method placeLabel in <Graph.Plot>.
+   
+    Parameters:
+   
+    tag - A DOM label element.
+    node - A <Graph.Node>.
+    controller - A configuration/controller object passed to the visualization.
+   */
+  placeLabel: function(tag, node, controller){
+    var pos = node.pos.getc(true), canvas = this.viz.canvas;
+    var radius = canvas.getSize();
+    var labelPos = {
+      x: Math.round(pos.x + radius.width / 2),
+      y: Math.round(pos.y + radius.height / 2)
+    };
+    tag.setAttribute('x', labelPos.x);
+    tag.setAttribute('y', labelPos.y);
+
+    controller.onPlaceLabel(tag, node);
+  }
+});
+
+/*
+  Icicle.Label.HTML
+  
+  Custom extension of <Graph.Label.HTML>.
+  
+  Extends:
+  
+  All <Graph.Label.HTML> methods.
+  
+  See also:
+  
+  <Graph.Label.HTML>
+  
+  */
+$jit.Icicle.Label.HTML = new Class( {
+  Implements: Graph.Label.HTML,
+
+  initialize: function(viz){
+    this.viz = viz;
+  },
+
+  /*
+    placeLabel
+   
+    Overrides abstract method placeLabel in <Graph.Plot>.
+   
+    Parameters:
+   
+    tag - A DOM label element.
+    node - A <Graph.Node>.
+    controller - A configuration/controller object passed to the visualization.
+   */
+  placeLabel: function(tag, node, controller){
+    var pos = node.pos.getc(true), canvas = this.viz.canvas;
+    var radius = canvas.getSize();
+    var labelPos = {
+      x: Math.round(pos.x + radius.width / 2),
+      y: Math.round(pos.y + radius.height / 2)
+    };
+
+    var style = tag.style;
+    style.left = labelPos.x + 'px';
+    style.top = labelPos.y + 'px';
+    style.display = '';
+
+    controller.onPlaceLabel(tag, node);
+  }
+});
+
+/*
+  Class: Icicle.Plot.NodeTypes
+  
+  This class contains a list of <Graph.Node> built-in types. 
+  Node types implemented are 'none', 'rectangle'.
+  
+  You can add your custom node types, customizing your visualization to the extreme.
+  
+  Example:
+  
+  (start code js)
+    Icicle.Plot.NodeTypes.implement({
+      'mySpecialType': {
+        'render': function(node, canvas) {
+          //print your custom node to canvas
+        },
+        //optional
+        'contains': function(node, pos) {
+          //return true if pos is inside the node or false otherwise
+        }
+      }
+    });
+  (end code)
+  
+  */
+$jit.Icicle.Plot.NodeTypes = new Class( {
+  'none': {
+    'render': $.empty
+  },
+
+  'rectangle': {
+    'render': function(node, canvas, animating) {
+      var config = this.viz.config;
+      var offset = config.offset;
+      var width = node.getData('width');
+      var height = node.getData('height');
+      var border = node.getData('border');
+      var pos = node.pos.getc(true);
+      var posx = pos.x + offset / 2, posy = pos.y + offset / 2;
+      var ctx = canvas.getCtx();
+      
+      if(width - offset < 2 || height - offset < 2) return;
+      
+      if(config.cushion) {
+        var color = node.getData('color');
+        var lg = ctx.createRadialGradient(posx + (width - offset)/2, 
+                                          posy + (height - offset)/2, 1, 
+                                          posx + (width-offset)/2, posy + (height-offset)/2, 
+                                          width < height? height : width);
+        var colorGrad = $.rgbToHex($.map($.hexToRgb(color), 
+            function(r) { return r * 0.3 >> 0; }));
+        lg.addColorStop(0, color);
+        lg.addColorStop(1, colorGrad);
+        ctx.fillStyle = lg;
+      }
+
+      if (border) {
+        ctx.strokeStyle = border;
+        ctx.lineWidth = 3;
+      }
+
+      ctx.fillRect(posx, posy, Math.max(0, width - offset), Math.max(0, height - offset));
+      border && ctx.strokeRect(pos.x, pos.y, width, height);
+    },
+
+    'contains': function(node, pos) {
+      if(this.viz.clickedNode && !$jit.Graph.Util.isDescendantOf(node, this.viz.clickedNode.id)) return false;
+      var npos = node.pos.getc(true),
+          width = node.getData('width'),
+          height = node.getData('height');
+      return this.nodeHelper.rectangle.contains({x: npos.x + width/2, y: npos.y + height/2}, pos, width, height);
+    }
+  }
+});
+
+$jit.Icicle.Plot.EdgeTypes = new Class( {
+  'none': $.empty
+});
+
+
+
+/*
+ * File: Layouts.ForceDirected.js
+ *
+*/
+
+/*
+ * Class: Layouts.ForceDirected
+ * 
+ * Implements a Force Directed Layout.
+ * 
+ * Implemented By:
+ * 
+ * <ForceDirected>
+ * 
+ * Credits:
+ * 
+ * Marcus Cobden <http://marcuscobden.co.uk>
+ * 
+ */
+Layouts.ForceDirected = new Class({
+
+  getOptions: function(random) {
+    var s = this.canvas.getSize();
+    var w = s.width, h = s.height;
+    //count nodes
+    var count = 0;
+    this.graph.eachNode(function(n) { 
+      count++;
+    });
+    var k2 = w * h / count, k = Math.sqrt(k2);
+    var l = this.config.levelDistance;
+    
+    return {
+      width: w,
+      height: h,
+      tstart: w * 0.1,
+      nodef: function(x) { return k2 / (x || 1); },
+      edgef: function(x) { return /* x * x / k; */ k * (x - l); }
+    };
+  },
+  
+  compute: function(property, incremental) {
+    var prop = $.splat(property || ['current', 'start', 'end']);
+    var opt = this.getOptions();
+    NodeDim.compute(this.graph, prop, this.config);
+    this.graph.computeLevels(this.root, 0, "ignore");
+    this.graph.eachNode(function(n) {
+      $.each(prop, function(p) {
+        var pos = n.getPos(p);
+        if(pos.equals(Complex.KER)) {
+          pos.x = opt.width/5 * (Math.random() - 0.5);
+          pos.y = opt.height/5 * (Math.random() - 0.5);
+        }
+        //initialize disp vector
+        n.disp = {};
+        $.each(prop, function(p) {
+          n.disp[p] = $C(0, 0);
+        });
+      });
+    });
+    this.computePositions(prop, opt, incremental);
+  },
+  
+  computePositions: function(property, opt, incremental) {
+    var times = this.config.iterations, i = 0, that = this;
+    if(incremental) {
+      (function iter() {
+        for(var total=incremental.iter, j=0; j<total; j++) {
+          opt.t = opt.tstart;
+          if(times) opt.t *= (1 - i++/(times -1));
+          that.computePositionStep(property, opt);
+          if(times && i >= times) {
+            incremental.onComplete();
+            return;
+          }
+        }
+        incremental.onStep(Math.round(i / (times -1) * 100));
+        setTimeout(iter, 1);
+      })();
+    } else {
+      for(; i < times; i++) {
+        opt.t = opt.tstart * (1 - i/(times -1));
+        this.computePositionStep(property, opt);
+      }
+    }
+  },
+  
+  computePositionStep: function(property, opt) {
+    var graph = this.graph;
+    var min = Math.min, max = Math.max;
+    var dpos = $C(0, 0);
+    //calculate repulsive forces
+    graph.eachNode(function(v) {
+      //initialize disp
+      $.each(property, function(p) {
+        v.disp[p].x = 0; v.disp[p].y = 0;
+      });
+      graph.eachNode(function(u) {
+        if(u.id != v.id) {
+          $.each(property, function(p) {
+            var vp = v.getPos(p), up = u.getPos(p);
+            dpos.x = vp.x - up.x;
+            dpos.y = vp.y - up.y;
+            var norm = dpos.norm() || 1;
+            v.disp[p].$add(dpos
+                .$scale(opt.nodef(norm) / norm));
+          });
+        }
+      });
+    });
+    //calculate attractive forces
+    var T = !!graph.getNode(this.root).visited;
+    graph.eachNode(function(node) {
+      node.eachAdjacency(function(adj) {
+        var nodeTo = adj.nodeTo;
+        if(!!nodeTo.visited === T) {
+          $.each(property, function(p) {
+            var vp = node.getPos(p), up = nodeTo.getPos(p);
+            dpos.x = vp.x - up.x;
+            dpos.y = vp.y - up.y;
+            var norm = dpos.norm() || 1;
+            node.disp[p].$add(dpos.$scale(-opt.edgef(norm) / norm));
+            nodeTo.disp[p].$add(dpos.$scale(-1));
+          });
+        }
+      });
+      node.visited = !T;
+    });
+    //arrange positions to fit the canvas
+    var t = opt.t, w2 = opt.width / 2, h2 = opt.height / 2;
+    graph.eachNode(function(u) {
+      $.each(property, function(p) {
+        var disp = u.disp[p];
+        var norm = disp.norm() || 1;
+        var p = u.getPos(p);
+        p.$add($C(disp.x * min(Math.abs(disp.x), t) / norm, 
+            disp.y * min(Math.abs(disp.y), t) / norm));
+        p.x = min(w2, max(-w2, p.x));
+        p.y = min(h2, max(-h2, p.y));
+      });
+    });
+  }
+});
+
+/*
+ * File: ForceDirected.js
+ */
+
+/*
+   Class: ForceDirected
+      
+   A visualization that lays graphs using a Force-Directed layout algorithm.
+   
+   Inspired by:
+  
+   Force-Directed Drawing Algorithms (Stephen G. Kobourov) <http://www.cs.brown.edu/~rt/gdhandbook/chapters/force-directed.pdf>
+   
+  Implements:
+  
+  All <Loader> methods
+  
+   Constructor Options:
+   
+   Inherits options from
+   
+   - <Options.Canvas>
+   - <Options.Controller>
+   - <Options.Node>
+   - <Options.Edge>
+   - <Options.Label>
+   - <Options.Events>
+   - <Options.Tips>
+   - <Options.NodeStyles>
+   - <Options.Navigation>
+   
+   Additionally, there are two parameters
+   
+   levelDistance - (number) Default's *50*. The natural length desired for the edges.
+   iterations - (number) Default's *50*. The number of iterations for the spring layout simulation. Depending on the browser's speed you could set this to a more 'interesting' number, like *200*. 
+     
+   Instance Properties:
+
+   canvas - Access a <Canvas> instance.
+   graph - Access a <Graph> instance.
+   op - Access a <ForceDirected.Op> instance.
+   fx - Access a <ForceDirected.Plot> instance.
+   labels - Access a <ForceDirected.Label> interface implementation.
+
+*/
+
+$jit.ForceDirected = new Class( {
+
+  Implements: [ Loader, Extras, Layouts.ForceDirected ],
+
+  initialize: function(controller) {
+    var $ForceDirected = $jit.ForceDirected;
+
+    var config = {
+      iterations: 50,
+      levelDistance: 50
+    };
+
+    this.controller = this.config = $.merge(Options("Canvas", "Node", "Edge",
+        "Fx", "Tips", "NodeStyles", "Events", "Navigation", "Controller", "Label"), config, controller);
+
+    var canvasConfig = this.config;
+    if(canvasConfig.useCanvas) {
+      this.canvas = canvasConfig.useCanvas;
+      this.config.labelContainer = this.canvas.id + '-label';
+    } else {
+      if(canvasConfig.background) {
+        canvasConfig.background = $.merge({
+          type: 'Circles'
+        }, canvasConfig.background);
+      }
+      this.canvas = new Canvas(this, canvasConfig);
+      this.config.labelContainer = (typeof canvasConfig.injectInto == 'string'? canvasConfig.injectInto : canvasConfig.injectInto.id) + '-label';
+    }
+
+    this.graphOptions = {
+      'klass': Complex,
+      'Node': {
+        'selected': false,
+        'exist': true,
+        'drawn': true
+      }
+    };
+    this.graph = new Graph(this.graphOptions, this.config.Node,
+        this.config.Edge);
+    this.labels = new $ForceDirected.Label[canvasConfig.Label.type](this);
+    this.fx = new $ForceDirected.Plot(this, $ForceDirected);
+    this.op = new $ForceDirected.Op(this);
+    this.json = null;
+    this.busy = false;
+    // initialize extras
+    this.initializeExtras();
+  },
+
+  /* 
+    Method: refresh 
+    
+    Computes positions and plots the tree.
+  */
+  refresh: function() {
+    this.compute();
+    this.plot();
+  },
+
+  reposition: function() {
+    this.compute('end');
+  },
+
+/*
+  Method: computeIncremental
+  
+  Performs the Force Directed algorithm incrementally.
+  
+  Description:
+  
+  ForceDirected algorithms can perform many computations and lead to JavaScript taking too much time to complete. 
+  This method splits the algorithm into smaller parts allowing the user to track the evolution of the algorithm and 
+  avoiding browser messages such as "This script is taking too long to complete".
+  
+  Parameters:
+  
+  opt - (object) The object properties are described below
+  
+  iter - (number) Default's *20*. Split the algorithm into pieces of _iter_ iterations. For example, if the _iterations_ configuration property 
+  of your <ForceDirected> class is 100, then you could set _iter_ to 20 to split the main algorithm into 5 smaller pieces.
+  
+  property - (string) Default's *end*. Whether to update starting, current or ending node positions. Possible values are 'end', 'start', 'current'. 
+  You can also set an array of these properties. If you'd like to keep the current node positions but to perform these 
+  computations for final animation positions then you can just choose 'end'.
+  
+  onStep - (function) A callback function called when each "small part" of the algorithm completed. This function gets as first formal 
+  parameter a percentage value.
+  
+  onComplete - A callback function called when the algorithm completed.
+  
+  Example:
+  
+  In this example I calculate the end positions and then animate the graph to those positions
+  
+  (start code js)
+  var fd = new $jit.ForceDirected(...);
+  fd.computeIncremental({
+    iter: 20,
+    property: 'end',
+    onStep: function(perc) {
+      Log.write("loading " + perc + "%");
+    },
+    onComplete: function() {
+      Log.write("done");
+      fd.animate();
+    }
+  });
+  (end code)
+  
+  In this example I calculate all positions and (re)plot the graph
+  
+  (start code js)
+  var fd = new ForceDirected(...);
+  fd.computeIncremental({
+    iter: 20,
+    property: ['end', 'start', 'current'],
+    onStep: function(perc) {
+      Log.write("loading " + perc + "%");
+    },
+    onComplete: function() {
+      Log.write("done");
+      fd.plot();
+    }
+  });
+  (end code)
+  
+  */
+  computeIncremental: function(opt) {
+    opt = $.merge( {
+      iter: 20,
+      property: 'end',
+      onStep: $.empty,
+      onComplete: $.empty
+    }, opt || {});
+
+    this.config.onBeforeCompute(this.graph.getNode(this.root));
+    this.compute(opt.property, opt);
+  },
+
+  /*
+    Method: plot
+   
+    Plots the ForceDirected graph. This is a shortcut to *fx.plot*.
+   */
+  plot: function() {
+    this.fx.plot();
+  },
+
+  /*
+     Method: animate
+    
+     Animates the graph from the current positions to the 'end' node positions.
+  */
+  animate: function(opt) {
+    this.fx.animate($.merge( {
+      modes: [ 'linear' ]
+    }, opt || {}));
+  }
+});
+
+$jit.ForceDirected.$extend = true;
+
+(function(ForceDirected) {
+
+  /*
+     Class: ForceDirected.Op
+     
+     Custom extension of <Graph.Op>.
+
+     Extends:
+
+     All <Graph.Op> methods
+     
+     See also:
+     
+     <Graph.Op>
+
+  */
+  ForceDirected.Op = new Class( {
+
+    Implements: Graph.Op
+
+  });
+
+  /*
+    Class: ForceDirected.Plot
+    
+    Custom extension of <Graph.Plot>.
+  
+    Extends:
+  
+    All <Graph.Plot> methods
+    
+    See also:
+    
+    <Graph.Plot>
+  
+  */
+  ForceDirected.Plot = new Class( {
+
+    Implements: Graph.Plot
+
+  });
+
+  /*
+    Class: ForceDirected.Label
+    
+    Custom extension of <Graph.Label>. 
+    Contains custom <Graph.Label.SVG>, <Graph.Label.HTML> and <Graph.Label.Native> extensions.
+  
+    Extends:
+  
+    All <Graph.Label> methods and subclasses.
+  
+    See also:
+  
+    <Graph.Label>, <Graph.Label.Native>, <Graph.Label.HTML>, <Graph.Label.SVG>.
+  
+  */
+  ForceDirected.Label = {};
+
+  /*
+     ForceDirected.Label.Native
+     
+     Custom extension of <Graph.Label.Native>.
+
+     Extends:
+
+     All <Graph.Label.Native> methods
+
+     See also:
+
+     <Graph.Label.Native>
+
+  */
+  ForceDirected.Label.Native = new Class( {
+    Implements: Graph.Label.Native
+  });
+
+  /*
+    ForceDirected.Label.SVG
+    
+    Custom extension of <Graph.Label.SVG>.
+  
+    Extends:
+  
+    All <Graph.Label.SVG> methods
+  
+    See also:
+  
+    <Graph.Label.SVG>
+  
+  */
+  ForceDirected.Label.SVG = new Class( {
+    Implements: Graph.Label.SVG,
+
+    initialize: function(viz) {
+      this.viz = viz;
+    },
+
+    /* 
+       placeLabel
+
+       Overrides abstract method placeLabel in <Graph.Label>.
+
+       Parameters:
+
+       tag - A DOM label element.
+       node - A <Graph.Node>.
+       controller - A configuration/controller object passed to the visualization.
+      
+     */
+    placeLabel: function(tag, node, controller) {
+      var pos = node.pos.getc(true), 
+          canvas = this.viz.canvas,
+          ox = canvas.translateOffsetX,
+          oy = canvas.translateOffsetY,
+          sx = canvas.scaleOffsetX,
+          sy = canvas.scaleOffsetY,
+          radius = canvas.getSize();
+      var labelPos = {
+        x: Math.round(pos.x * sx + ox + radius.width / 2),
+        y: Math.round(pos.y * sy + oy + radius.height / 2)
+      };
+      tag.setAttribute('x', labelPos.x);
+      tag.setAttribute('y', labelPos.y);
+
+      controller.onPlaceLabel(tag, node);
+    }
+  });
+
+  /*
+     ForceDirected.Label.HTML
+     
+     Custom extension of <Graph.Label.HTML>.
+
+     Extends:
+
+     All <Graph.Label.HTML> methods.
+
+     See also:
+
+     <Graph.Label.HTML>
+
+  */
+  ForceDirected.Label.HTML = new Class( {
+    Implements: Graph.Label.HTML,
+
+    initialize: function(viz) {
+      this.viz = viz;
+    },
+    /* 
+       placeLabel
+
+       Overrides abstract method placeLabel in <Graph.Plot>.
+
+       Parameters:
+
+       tag - A DOM label element.
+       node - A <Graph.Node>.
+       controller - A configuration/controller object passed to the visualization.
+      
+     */
+    placeLabel: function(tag, node, controller) {
+      var pos = node.pos.getc(true), 
+          canvas = this.viz.canvas,
+          ox = canvas.translateOffsetX,
+          oy = canvas.translateOffsetY,
+          sx = canvas.scaleOffsetX,
+          sy = canvas.scaleOffsetY,
+          radius = canvas.getSize();
+      var labelPos = {
+        x: Math.round(pos.x * sx + ox + radius.width / 2),
+        y: Math.round(pos.y * sy + oy + radius.height / 2)
+      };
+      var style = tag.style;
+      style.left = labelPos.x + 'px';
+      style.top = labelPos.y + 'px';
+      style.display = this.fitsInCanvas(labelPos, canvas) ? '' : 'none';
+
+      controller.onPlaceLabel(tag, node);
+    }
+  });
+
+  /*
+    Class: ForceDirected.Plot.NodeTypes
+
+    This class contains a list of <Graph.Node> built-in types. 
+    Node types implemented are 'none', 'circle', 'triangle', 'rectangle', 'star', 'ellipse' and 'square'.
+
+    You can add your custom node types, customizing your visualization to the extreme.
+
+    Example:
+
+    (start code js)
+      ForceDirected.Plot.NodeTypes.implement({
+        'mySpecialType': {
+          'render': function(node, canvas) {
+            //print your custom node to canvas
+          },
+          //optional
+          'contains': function(node, pos) {
+            //return true if pos is inside the node or false otherwise
+          }
+        }
+      });
+    (end code)
+
+  */
+  ForceDirected.Plot.NodeTypes = new Class({
+    'none': {
+      'render': $.empty,
+      'contains': $.lambda(false)
+    },
+    'circle': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        this.nodeHelper.circle.render('fill', pos, dim, canvas);
+      },
+      'contains': function(node, pos){
+        var npos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        return this.nodeHelper.circle.contains(npos, pos, dim);
+      }
+    },
+    'ellipse': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            width = node.getData('width'), 
+            height = node.getData('height');
+        this.nodeHelper.ellipse.render('fill', pos, width, height, canvas);
+        },
+      'contains': function(node, pos){
+        var npos = node.pos.getc(true), 
+            width = node.getData('width'), 
+            height = node.getData('height');
+        return this.nodeHelper.ellipse.contains(npos, pos, width, height);
+      }
+    },
+    'square': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        this.nodeHelper.square.render('fill', pos, dim, canvas);
+      },
+      'contains': function(node, pos){
+        var npos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        return this.nodeHelper.square.contains(npos, pos, dim);
+      }
+    },
+    'rectangle': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            width = node.getData('width'), 
+            height = node.getData('height');
+        this.nodeHelper.rectangle.render('fill', pos, width, height, canvas);
+      },
+      'contains': function(node, pos){
+        var npos = node.pos.getc(true), 
+            width = node.getData('width'), 
+            height = node.getData('height');
+        return this.nodeHelper.rectangle.contains(npos, pos, width, height);
+      }
+    },
+    'triangle': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        this.nodeHelper.triangle.render('fill', pos, dim, canvas);
+      },
+      'contains': function(node, pos) {
+        var npos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        return this.nodeHelper.triangle.contains(npos, pos, dim);
+      }
+    },
+    'star': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true),
+            dim = node.getData('dim');
+        this.nodeHelper.star.render('fill', pos, dim, canvas);
+      },
+      'contains': function(node, pos) {
+        var npos = node.pos.getc(true),
+            dim = node.getData('dim');
+        return this.nodeHelper.star.contains(npos, pos, dim);
+      }
+    }
+  });
+
+  /*
+    Class: ForceDirected.Plot.EdgeTypes
+  
+    This class contains a list of <Graph.Adjacence> built-in types. 
+    Edge types implemented are 'none', 'line' and 'arrow'.
+  
+    You can add your custom edge types, customizing your visualization to the extreme.
+  
+    Example:
+  
+    (start code js)
+      ForceDirected.Plot.EdgeTypes.implement({
+        'mySpecialType': {
+          'render': function(adj, canvas) {
+            //print your custom edge to canvas
+          },
+          //optional
+          'contains': function(adj, pos) {
+            //return true if pos is inside the arc or false otherwise
+          }
+        }
+      });
+    (end code)
+  
+  */
+  ForceDirected.Plot.EdgeTypes = new Class({
+    'none': $.empty,
+    'line': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true);
+        this.edgeHelper.line.render(from, to, canvas);
+      },
+      'contains': function(adj, pos) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true);
+        return this.edgeHelper.line.contains(from, to, pos, this.edge.epsilon);
+      }
+    },
+    'arrow': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true),
+            dim = adj.getData('dim'),
+            direction = adj.data.$direction,
+            inv = (direction && direction.length>1 && direction[0] != adj.nodeFrom.id);
+        this.edgeHelper.arrow.render(from, to, dim, inv, canvas);
+      },
+      'contains': function(adj, pos) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true);
+        return this.edgeHelper.arrow.contains(from, to, pos, this.edge.epsilon);
+      }
+    }
+  });
+
+})($jit.ForceDirected);
+
+
+/*
+ * File: Treemap.js
+ *
+*/
+
+$jit.TM = {};
+
+var TM = $jit.TM;
+
+$jit.TM.$extend = true;
+
+/*
+  Class: TM.Base
+  
+  Abstract class providing base functionality for <TM.Squarified>, <TM.Strip> and <TM.SliceAndDice> visualizations.
+  
+  Implements:
+  
+  All <Loader> methods
+  
+  Constructor Options:
+  
+  Inherits options from
+  
+  - <Options.Canvas>
+  - <Options.Controller>
+  - <Options.Node>
+  - <Options.Edge>
+  - <Options.Label>
+  - <Options.Events>
+  - <Options.Tips>
+  - <Options.NodeStyles>
+  - <Options.Navigation>
+  
+  Additionally, there are other parameters and some default values changed
+
+  orientation - (string) Default's *h*. Whether to set horizontal or vertical layouts. Possible values are 'h' and 'v'.
+  titleHeight - (number) Default's *13*. The height of the title rectangle for inner (non-leaf) nodes.
+  offset - (number) Default's *2*. Boxes offset.
+  constrained - (boolean) Default's *false*. Whether to show the entire tree when loaded or just the number of levels specified by _levelsToShow_.
+  levelsToShow - (number) Default's *3*. The number of levels to show for a subtree. This number is relative to the selected node.
+  animate - (boolean) Default's *false*. Whether to animate transitions.
+  Node.type - Described in <Options.Node>. Default's *rectangle*.
+  duration - Described in <Options.Fx>. Default's *700*.
+  fps - Described in <Options.Fx>. Default's *45*.
+  
+  Instance Properties:
+  
+  canvas - Access a <Canvas> instance.
+  graph - Access a <Graph> instance.
+  op - Access a <TM.Op> instance.
+  fx - Access a <TM.Plot> instance.
+  labels - Access a <TM.Label> interface implementation.
+
+  Inspired by:
+  
+  Squarified Treemaps (Mark Bruls, Kees Huizing, and Jarke J. van Wijk) <http://www.win.tue.nl/~vanwijk/stm.pdf>
+  
+  Tree visualization with tree-maps: 2-d space-filling approach (Ben Shneiderman) <http://hcil.cs.umd.edu/trs/91-03/91-03.html>
+  
+   Note:
+   
+   This visualization was built and engineered from scratch, taking only the paper as inspiration, and only shares some features with the visualization described in the paper.
+
+*/
+TM.Base = {
+  layout: {
+    orientation: "h",
+    vertical: function(){
+      return this.orientation == "v";
+    },
+    horizontal: function(){
+      return this.orientation == "h";
+    },
+    change: function(){
+      this.orientation = this.vertical()? "h" : "v";
+    }
+  },
+
+  initialize: function(controller){
+    var config = {
+      orientation: "h",
+      titleHeight: 13,
+      offset: 2,
+      levelsToShow: 0,
+      constrained: false,
+      animate: false,
+      Node: {
+        type: 'rectangle',
+        overridable: true,
+        //we all know why this is not zero,
+        //right, Firefox?
+        width: 3,
+        height: 3,
+        color: '#444'
+      },
+      Label: {
+        textAlign: 'center',
+        textBaseline: 'top'
+      },
+      Edge: {
+        type: 'none'
+      },
+      duration: 700,
+      fps: 45
+    };
+
+    this.controller = this.config = $.merge(Options("Canvas", "Node", "Edge",
+        "Fx", "Controller", "Tips", "NodeStyles", "Events", "Navigation", "Label"), config, controller);
+    this.layout.orientation = this.config.orientation;
+
+    var canvasConfig = this.config;
+    if (canvasConfig.useCanvas) {
+      this.canvas = canvasConfig.useCanvas;
+      this.config.labelContainer = this.canvas.id + '-label';
+    } else {
+      if(canvasConfig.background) {
+        canvasConfig.background = $.merge({
+          type: 'Circles'
+        }, canvasConfig.background);
+      }
+      this.canvas = new Canvas(this, canvasConfig);
+      this.config.labelContainer = (typeof canvasConfig.injectInto == 'string'? canvasConfig.injectInto : canvasConfig.injectInto.id) + '-label';
+    }
+
+    this.graphOptions = {
+      'klass': Complex,
+      'Node': {
+        'selected': false,
+        'exist': true,
+        'drawn': true
+      }
+    };
+    this.graph = new Graph(this.graphOptions, this.config.Node,
+        this.config.Edge);
+    this.labels = new TM.Label[canvasConfig.Label.type](this);
+    this.fx = new TM.Plot(this);
+    this.op = new TM.Op(this);
+    this.group = new TM.Group(this);
+    this.geom = new TM.Geom(this);
+    this.clickedNode = null;
+    this.busy = false;
+    // initialize extras
+    this.initializeExtras();
+  },
+
+  /* 
+    Method: refresh 
+    
+    Computes positions and plots the tree.
+  */
+  refresh: function(){
+    if(this.busy) return;
+    this.busy = true;
+    var that = this;
+    if(this.config.animate) {
+      this.compute('end');
+      this.config.levelsToShow > 0 && this.geom.setRightLevelToShow(this.graph.getNode(this.clickedNode 
+          && this.clickedNode.id || this.root));
+      this.fx.animate($.merge(this.config, {
+        modes: ['linear', 'node-property:width:height'],
+        onComplete: function() {
+          that.busy = false;
+        }
+      }));
+    } else {
+      var labelType = this.config.Label.type;
+      if(labelType != 'Native') {
+        var that = this;
+        this.graph.eachNode(function(n) { that.labels.hideLabel(n, false); });
+      }
+      this.busy = false;
+      this.compute();
+      this.config.levelsToShow > 0 && this.geom.setRightLevelToShow(this.graph.getNode(this.clickedNode 
+          && this.clickedNode.id || this.root));
+      this.plot();
+    }
+  },
+
+  /* 
+    Method: plot 
+    
+    Plots the TreeMap. This is a shortcut to *fx.plot*. 
+  
+   */
+  plot: function(){
+    this.fx.plot();
+  },
+
+  /* 
+  Method: leaf 
+  
+  Returns whether the node is a leaf.
+  
+   Parameters:
+   
+   n - (object) A <Graph.Node>.
+
+ */
+  leaf: function(n){
+    return n.getSubnodes([
+        1, 1
+    ], "ignore").length == 0;
+  },
+  
+  /* 
+  Method: enter 
+  
+  Sets the node as root.
+  
+   Parameters:
+   
+   n - (object) A <Graph.Node>.
+
+ */
+  enter: function(n){
+    if(this.busy) return;
+    this.busy = true;
+    
+    var that = this,
+        config = this.config,
+        graph = this.graph,
+        clickedNode = n,
+        previousClickedNode = this.clickedNode;
+
+    var callback = {
+      onComplete: function() {
+        //ensure that nodes are shown for that level
+        if(config.levelsToShow > 0) {
+          that.geom.setRightLevelToShow(n);
+        }
+        //compute positions of newly inserted nodes
+        if(config.levelsToShow > 0 || config.request) that.compute();
+        if(config.animate) {
+          //fade nodes
+          graph.nodeList.setData('alpha', 0, 'end');
+          n.eachSubgraph(function(n) {
+            n.setData('alpha', 1, 'end');
+          }, "ignore");
+          that.fx.animate({
+            duration: 500,
+            modes:['node-property:alpha'],
+            onComplete: function() {
+              //compute end positions
+              that.clickedNode = clickedNode;
+              that.compute('end');
+              //animate positions
+              //TODO(nico) commenting this line didn't seem to throw errors...
+              that.clickedNode = previousClickedNode;
+              that.fx.animate({
+                modes:['linear', 'node-property:width:height'],
+                duration: 1000,
+                onComplete: function() { 
+                  that.busy = false;
+                  //TODO(nico) check comment above
+                  that.clickedNode = clickedNode;
+                }
+              });
+            }
+          });
+        } else {
+          that.busy = false;
+          that.clickedNode = n;
+          that.refresh();
+        }
+      }
+    };
+    if(config.request) {
+      this.requestNodes(clickedNode, callback);
+    } else {
+      callback.onComplete();
+    }
+  },
+
+  /* 
+  Method: out 
+  
+  Sets the parent node of the current selected node as root.
+
+ */
+  out: function(){
+    if(this.busy) return;
+    this.busy = true;
+    this.events.hoveredNode = false;
+    var that = this,
+        config = this.config,
+        graph = this.graph,
+        parents = graph.getNode(this.clickedNode 
+            && this.clickedNode.id || this.root).getParents(),
+        parent = parents[0],
+        clickedNode = parent,
+        previousClickedNode = this.clickedNode;
+    
+    //if no parents return
+    if(!parent) {
+      this.busy = false;
+      return;
+    }
+    //final plot callback
+    callback = {
+      onComplete: function() {
+        that.clickedNode = parent;
+        if(config.request) {
+          that.requestNodes(parent, {
+            onComplete: function() {
+              that.compute();
+              that.plot();
+              that.busy = false;
+            }
+          });
+        } else {
+          that.compute();
+          that.plot();
+          that.busy = false;
+        }
+      }
+    };
+    //prune tree
+    if (config.levelsToShow > 0)
+      this.geom.setRightLevelToShow(parent);
+    //animate node positions
+    if(config.animate) {
+      this.clickedNode = clickedNode;
+      this.compute('end');
+      //animate the visible subtree only
+      this.clickedNode = previousClickedNode;
+      this.fx.animate({
+        modes:['linear', 'node-property:width:height'],
+        duration: 1000,
+        onComplete: function() {
+          //animate the parent subtree
+          that.clickedNode = clickedNode;
+          //change nodes alpha
+          graph.eachNode(function(n) {
+            n.setDataset(['current', 'end'], {
+              'alpha': [0, 1]
+            });
+          }, "ignore");
+          previousClickedNode.eachSubgraph(function(node) {
+            node.setData('alpha', 1);
+          }, "ignore");
+          that.fx.animate({
+            duration: 500,
+            modes:['node-property:alpha'],
+            onComplete: function() {
+              callback.onComplete();
+            }
+          });
+        }
+      });
+    } else {
+      callback.onComplete();
+    }
+  },
+
+  requestNodes: function(node, onComplete){
+    var handler = $.merge(this.controller, onComplete), 
+        lev = this.config.levelsToShow;
+    if (handler.request) {
+      var leaves = [], d = node._depth;
+      node.eachLevel(0, lev, function(n){
+        var nodeLevel = lev - (n._depth - d);
+        if (n.drawn && !n.anySubnode() && nodeLevel > 0) {
+          leaves.push(n);
+          n._level = nodeLevel;
+        }
+      });
+      this.group.requestNodes(leaves, handler);
+    } else {
+      handler.onComplete();
+    }
+  },
+  
+  reposition: function() {
+    this.compute('end');
+  }
+};
+
+/*
+  Class: TM.Op
+  
+  Custom extension of <Graph.Op>.
+  
+  Extends:
+  
+  All <Graph.Op> methods
+  
+  See also:
+  
+  <Graph.Op>
+  
+  */
+TM.Op = new Class({
+  Implements: Graph.Op,
+
+  initialize: function(viz){
+    this.viz = viz;
+  }
+});
+
+//extend level methods of Graph.Geom
+TM.Geom = new Class({
+  Implements: Graph.Geom,
+  
+  getRightLevelToShow: function() {
+    return this.viz.config.levelsToShow;
+  },
+  
+  setRightLevelToShow: function(node) {
+    var level = this.getRightLevelToShow(), 
+        fx = this.viz.labels;
+    node.eachLevel(0, level+1, function(n) {
+      var d = n._depth - node._depth;
+      if(d > level) {
+        n.drawn = false; 
+        n.exist = false;
+        n.ignore = true;
+        fx.hideLabel(n, false);
+      } else {
+        n.drawn = true;
+        n.exist = true;
+        delete n.ignore;
+      }
+    });
+    node.drawn = true;
+    delete node.ignore;
+  }
+});
+
+/*
+
+Performs operations on group of nodes.
+
+*/
+TM.Group = new Class( {
+
+  initialize: function(viz){
+    this.viz = viz;
+    this.canvas = viz.canvas;
+    this.config = viz.config;
+  },
+
+  /*
+  
+    Calls the request method on the controller to request a subtree for each node. 
+  */
+  requestNodes: function(nodes, controller){
+    var counter = 0, len = nodes.length, nodeSelected = {};
+    var complete = function(){
+      controller.onComplete();
+    };
+    var viz = this.viz;
+    if (len == 0)
+      complete();
+    for ( var i = 0; i < len; i++) {
+      nodeSelected[nodes[i].id] = nodes[i];
+      controller.request(nodes[i].id, nodes[i]._level, {
+        onComplete: function(nodeId, data){
+          if (data && data.children) {
+            data.id = nodeId;
+            viz.op.sum(data, {
+              type: 'nothing'
+            });
+          }
+          if (++counter == len) {
+            viz.graph.computeLevels(viz.root, 0);
+            complete();
+          }
+        }
+      });
+    }
+  }
+});
+
+/*
+  Class: TM.Plot
+  
+  Custom extension of <Graph.Plot>.
+  
+  Extends:
+  
+  All <Graph.Plot> methods
+  
+  See also:
+  
+  <Graph.Plot>
+  
+  */
+TM.Plot = new Class({
+
+  Implements: Graph.Plot,
+
+  initialize: function(viz){
+    this.viz = viz;
+    this.config = viz.config;
+    this.node = this.config.Node;
+    this.edge = this.config.Edge;
+    this.animation = new Animation;
+    this.nodeTypes = new TM.Plot.NodeTypes;
+    this.edgeTypes = new TM.Plot.EdgeTypes;
+    this.labels = viz.labels;
+  },
+
+  plot: function(opt, animating){
+    var viz = this.viz, 
+        graph = viz.graph;
+    viz.canvas.clear();
+    this.plotTree(graph.getNode(viz.clickedNode && viz.clickedNode.id || viz.root), $.merge(viz.config, opt || {}, {
+      'withLabels': true,
+      'hideLabels': false,
+      'plotSubtree': function(n, ch){
+        return n.anySubnode("exist");
+      }
+    }), animating);
+  }
+});
+
+/*
+  Class: TM.Label
+  
+  Custom extension of <Graph.Label>. 
+  Contains custom <Graph.Label.SVG>, <Graph.Label.HTML> and <Graph.Label.Native> extensions.
+
+  Extends:
+
+  All <Graph.Label> methods and subclasses.
+
+  See also:
+
+  <Graph.Label>, <Graph.Label.Native>, <Graph.Label.HTML>, <Graph.Label.SVG>.
+  
+*/
+TM.Label = {};
+
+/*
+ TM.Label.Native
+
+ Custom extension of <Graph.Label.Native>.
+
+ Extends:
+
+ All <Graph.Label.Native> methods
+
+ See also:
+
+ <Graph.Label.Native>
+*/
+TM.Label.Native = new Class({
+  Implements: Graph.Label.Native,
+
+  initialize: function(viz) {
+    this.config = viz.config;
+    this.leaf = viz.leaf;
+  },
+  
+  renderLabel: function(canvas, node, controller){
+    if(!this.leaf(node) && !this.config.titleHeight) return;
+    var pos = node.pos.getc(true), 
+        ctx = canvas.getCtx(),
+        width = node.getData('width'),
+        height = node.getData('height'),
+        x = pos.x + width/2,
+        y = pos.y;
+        
+    ctx.fillText(node.name, x, y, width);
+  }
+});
+
+/*
+ TM.Label.SVG
+
+  Custom extension of <Graph.Label.SVG>.
+
+  Extends:
+
+  All <Graph.Label.SVG> methods
+
+  See also:
+
+  <Graph.Label.SVG>
+*/
+TM.Label.SVG = new Class( {
+  Implements: Graph.Label.SVG,
+
+  initialize: function(viz){
+    this.viz = viz;
+    this.leaf = viz.leaf;
+    this.config = viz.config;
+  },
+
+  /* 
+  placeLabel
+
+  Overrides abstract method placeLabel in <Graph.Plot>.
+
+  Parameters:
+
+  tag - A DOM label element.
+  node - A <Graph.Node>.
+  controller - A configuration/controller object passed to the visualization.
+  
+  */
+  placeLabel: function(tag, node, controller){
+    var pos = node.pos.getc(true), 
+        canvas = this.viz.canvas,
+        ox = canvas.translateOffsetX,
+        oy = canvas.translateOffsetY,
+        sx = canvas.scaleOffsetX,
+        sy = canvas.scaleOffsetY,
+        radius = canvas.getSize();
+    var labelPos = {
+      x: Math.round(pos.x * sx + ox + radius.width / 2),
+      y: Math.round(pos.y * sy + oy + radius.height / 2)
+    };
+    tag.setAttribute('x', labelPos.x);
+    tag.setAttribute('y', labelPos.y);
+
+    if(!this.leaf(node) && !this.config.titleHeight) {
+      tag.style.display = 'none';
+    }
+    controller.onPlaceLabel(tag, node);
+  }
+});
+
+/*
+ TM.Label.HTML
+
+ Custom extension of <Graph.Label.HTML>.
+
+ Extends:
+
+ All <Graph.Label.HTML> methods.
+
+ See also:
+
+ <Graph.Label.HTML>
+
+*/
+TM.Label.HTML = new Class( {
+  Implements: Graph.Label.HTML,
+
+  initialize: function(viz){
+    this.viz = viz;
+    this.leaf = viz.leaf;
+    this.config = viz.config;
+  },
+
+  /* 
+    placeLabel
+  
+    Overrides abstract method placeLabel in <Graph.Plot>.
+  
+    Parameters:
+  
+    tag - A DOM label element.
+    node - A <Graph.Node>.
+    controller - A configuration/controller object passed to the visualization.
+  
+  */
+  placeLabel: function(tag, node, controller){
+    var pos = node.pos.getc(true), 
+        canvas = this.viz.canvas,
+        ox = canvas.translateOffsetX,
+        oy = canvas.translateOffsetY,
+        sx = canvas.scaleOffsetX,
+        sy = canvas.scaleOffsetY,
+        radius = canvas.getSize();
+    var labelPos = {
+      x: Math.round(pos.x * sx + ox + radius.width / 2),
+      y: Math.round(pos.y * sy + oy + radius.height / 2)
+    };
+
+    var style = tag.style;
+    style.left = labelPos.x + 'px';
+    style.top = labelPos.y + 'px';
+    style.width = node.getData('width') * sx + 'px';
+    style.height = node.getData('height') * sy + 'px';
+    style.zIndex = node._depth * 100;
+    style.display = '';
+
+    if(!this.leaf(node) && !this.config.titleHeight) {
+      tag.style.display = 'none';
+    }
+    controller.onPlaceLabel(tag, node);
+  }
+});
+
+/*
+  Class: TM.Plot.NodeTypes
+
+  This class contains a list of <Graph.Node> built-in types. 
+  Node types implemented are 'none', 'rectangle'.
+
+  You can add your custom node types, customizing your visualization to the extreme.
+
+  Example:
+
+  (start code js)
+    TM.Plot.NodeTypes.implement({
+      'mySpecialType': {
+        'render': function(node, canvas) {
+          //print your custom node to canvas
+        },
+        //optional
+        'contains': function(node, pos) {
+          //return true if pos is inside the node or false otherwise
+        }
+      }
+    });
+  (end code)
+
+*/
+TM.Plot.NodeTypes = new Class( {
+  'none': {
+    'render': $.empty
+  },
+
+  'rectangle': {
+    'render': function(node, canvas, animating){
+      var leaf = this.viz.leaf(node),
+          config = this.config,
+          offst = config.offset,
+          titleHeight = config.titleHeight,
+          pos = node.pos.getc(true),
+          width = node.getData('width'),
+          height = node.getData('height'),
+          border = node.getData('border'),
+          ctx = canvas.getCtx(),
+          posx = pos.x + offst / 2, 
+          posy = pos.y + offst / 2;
+      if(width <= offst || height <= offst) return;
+      if (leaf) {
+        if(config.cushion) {
+          var lg = ctx.createRadialGradient(posx + (width-offst)/2, posy + (height-offst)/2, 1, 
+              posx + (width-offst)/2, posy + (height-offst)/2, width < height? height : width);
+          var color = node.getData('color');
+          var colorGrad = $.rgbToHex($.map($.hexToRgb(color), 
+              function(r) { return r * 0.2 >> 0; }));
+          lg.addColorStop(0, color);
+          lg.addColorStop(1, colorGrad);
+          ctx.fillStyle = lg;
+        }
+        ctx.fillRect(posx, posy, width - offst, height - offst);
+        if(border) {
+          ctx.save();
+          ctx.strokeStyle = border;
+          ctx.strokeRect(posx, posy, width - offst, height - offst);
+          ctx.restore();
+        }
+      } else if(titleHeight > 0){
+        ctx.fillRect(pos.x + offst / 2, pos.y + offst / 2, width - offst,
+            titleHeight - offst);
+        if(border) {
+          ctx.save();
+          ctx.strokeStyle = border;
+          ctx.strokeRect(pos.x + offst / 2, pos.y + offst / 2, width - offst,
+              height - offst);
+          ctx.restore();
+        }
+      }
+    },
+    'contains': function(node, pos) {
+      if(this.viz.clickedNode && !node.isDescendantOf(this.viz.clickedNode.id) || node.ignore) return false;
+      var npos = node.pos.getc(true),
+          width = node.getData('width'), 
+          leaf = this.viz.leaf(node),
+          height = leaf? node.getData('height') : this.config.titleHeight;
+      return this.nodeHelper.rectangle.contains({x: npos.x + width/2, y: npos.y + height/2}, pos, width, height);
+    }
+  }
+});
+
+TM.Plot.EdgeTypes = new Class( {
+  'none': $.empty
+});
+
+/*
+  Class: TM.SliceAndDice
+  
+  A slice and dice TreeMap visualization.
+  
+  Implements:
+  
+  All <TM.Base> methods and properties.
+*/
+TM.SliceAndDice = new Class( {
+  Implements: [
+      Loader, Extras, TM.Base, Layouts.TM.SliceAndDice
+  ]
+});
+
+/*
+  Class: TM.Squarified
+  
+  A squarified TreeMap visualization.
+
+  Implements:
+  
+  All <TM.Base> methods and properties.
+*/
+TM.Squarified = new Class( {
+  Implements: [
+      Loader, Extras, TM.Base, Layouts.TM.Squarified
+  ]
+});
+
+/*
+  Class: TM.Strip
+  
+  A strip TreeMap visualization.
+
+  Implements:
+  
+  All <TM.Base> methods and properties.
+*/
+TM.Strip = new Class( {
+  Implements: [
+      Loader, Extras, TM.Base, Layouts.TM.Strip
+  ]
+});
+
+
+/*
+ * File: RGraph.js
+ *
+ */
+
+/*
+   Class: RGraph
+   
+   A radial graph visualization with advanced animations.
+   
+   Inspired by:
+ 
+   Animated Exploration of Dynamic Graphs with Radial Layout (Ka-Ping Yee, Danyel Fisher, Rachna Dhamija, Marti Hearst) <http://bailando.sims.berkeley.edu/papers/infovis01.htm>
+   
+   Note:
+   
+   This visualization was built and engineered from scratch, taking only the paper as inspiration, and only shares some features with the visualization described in the paper.
+   
+  Implements:
+  
+  All <Loader> methods
+  
+   Constructor Options:
+   
+   Inherits options from
+   
+   - <Options.Canvas>
+   - <Options.Controller>
+   - <Options.Node>
+   - <Options.Edge>
+   - <Options.Label>
+   - <Options.Events>
+   - <Options.Tips>
+   - <Options.NodeStyles>
+   - <Options.Navigation>
+   
+   Additionally, there are other parameters and some default values changed
+   
+   interpolation - (string) Default's *linear*. Describes the way nodes are interpolated. Possible values are 'linear' and 'polar'.
+   levelDistance - (number) Default's *100*. The distance between levels of the tree. 
+     
+   Instance Properties:
+
+   canvas - Access a <Canvas> instance.
+   graph - Access a <Graph> instance.
+   op - Access a <RGraph.Op> instance.
+   fx - Access a <RGraph.Plot> instance.
+   labels - Access a <RGraph.Label> interface implementation.   
+*/
+
+$jit.RGraph = new Class( {
+
+  Implements: [
+      Loader, Extras, Layouts.Radial
+  ],
+
+  initialize: function(controller){
+    var $RGraph = $jit.RGraph;
+
+    var config = {
+      interpolation: 'linear',
+      levelDistance: 100
+    };
+
+    this.controller = this.config = $.merge(Options("Canvas", "Node", "Edge",
+        "Fx", "Controller", "Tips", "NodeStyles", "Events", "Navigation", "Label"), config, controller);
+
+    var canvasConfig = this.config;
+    if(canvasConfig.useCanvas) {
+      this.canvas = canvasConfig.useCanvas;
+      this.config.labelContainer = this.canvas.id + '-label';
+    } else {
+      if(canvasConfig.background) {
+        canvasConfig.background = $.merge({
+          type: 'Circles'
+        }, canvasConfig.background);
+      }
+      this.canvas = new Canvas(this, canvasConfig);
+      this.config.labelContainer = (typeof canvasConfig.injectInto == 'string'? canvasConfig.injectInto : canvasConfig.injectInto.id) + '-label';
+    }
+
+    this.graphOptions = {
+      'klass': Polar,
+      'Node': {
+        'selected': false,
+        'exist': true,
+        'drawn': true
+      }
+    };
+    this.graph = new Graph(this.graphOptions, this.config.Node,
+        this.config.Edge);
+    this.labels = new $RGraph.Label[canvasConfig.Label.type](this);
+    this.fx = new $RGraph.Plot(this, $RGraph);
+    this.op = new $RGraph.Op(this);
+    this.json = null;
+    this.root = null;
+    this.busy = false;
+    this.parent = false;
+    // initialize extras
+    this.initializeExtras();
+  },
+
+  /* 
+  
+    createLevelDistanceFunc 
+  
+    Returns the levelDistance function used for calculating a node distance 
+    to its origin. This function returns a function that is computed 
+    per level and not per node, such that all nodes with the same depth will have the 
+    same distance to the origin. The resulting function gets the 
+    parent node as parameter and returns a float.
+
+   */
+  createLevelDistanceFunc: function(){
+    var ld = this.config.levelDistance;
+    return function(elem){
+      return (elem._depth + 1) * ld;
+    };
+  },
+
+  /* 
+     Method: refresh 
+     
+     Computes positions and plots the tree.
+
+   */
+  refresh: function(){
+    this.compute();
+    this.plot();
+  },
+
+  reposition: function(){
+    this.compute('end');
+  },
+
+  /*
+   Method: plot
+  
+   Plots the RGraph. This is a shortcut to *fx.plot*.
+  */
+  plot: function(){
+    this.fx.plot();
+  },
+  /*
+   getNodeAndParentAngle
+  
+   Returns the _parent_ of the given node, also calculating its angle span.
+  */
+  getNodeAndParentAngle: function(id){
+    var theta = false;
+    var n = this.graph.getNode(id);
+    var ps = n.getParents();
+    var p = (ps.length > 0)? ps[0] : false;
+    if (p) {
+      var posParent = p.pos.getc(), posChild = n.pos.getc();
+      var newPos = posParent.add(posChild.scale(-1));
+      theta = Math.atan2(newPos.y, newPos.x);
+      if (theta < 0)
+        theta += 2 * Math.PI;
+    }
+    return {
+      parent: p,
+      theta: theta
+    };
+  },
+  /*
+   tagChildren
+  
+   Enumerates the children in order to maintain child ordering (second constraint of the paper).
+  */
+  tagChildren: function(par, id){
+    if (par.angleSpan) {
+      var adjs = [];
+      par.eachAdjacency(function(elem){
+        adjs.push(elem.nodeTo);
+      }, "ignore");
+      var len = adjs.length;
+      for ( var i = 0; i < len && id != adjs[i].id; i++)
+        ;
+      for ( var j = (i + 1) % len, k = 0; id != adjs[j].id; j = (j + 1) % len) {
+        adjs[j].dist = k++;
+      }
+    }
+  },
+  /* 
+  Method: onClick 
+  
+  Animates the <RGraph> to center the node specified by *id*.
+
+   Parameters:
+
+   id - A <Graph.Node> id.
+   opt - (optional|object) An object containing some extra properties described below
+   hideLabels - (boolean) Default's *true*. Hide labels when performing the animation.
+
+   Example:
+
+   (start code js)
+     rgraph.onClick('someid');
+     //or also...
+     rgraph.onClick('someid', {
+      hideLabels: false
+     });
+    (end code)
+    
+  */
+  onClick: function(id, opt){
+    if (this.root != id && !this.busy) {
+      this.busy = true;
+      this.root = id;
+      var that = this;
+      this.controller.onBeforeCompute(this.graph.getNode(id));
+      var obj = this.getNodeAndParentAngle(id);
+
+      // second constraint
+      this.tagChildren(obj.parent, id);
+      this.parent = obj.parent;
+      this.compute('end');
+
+      // first constraint
+      var thetaDiff = obj.theta - obj.parent.endPos.theta;
+      this.graph.eachNode(function(elem){
+        elem.endPos.set(elem.endPos.getp().add($P(thetaDiff, 0)));
+      });
+
+      var mode = this.config.interpolation;
+      opt = $.merge( {
+        onComplete: $.empty
+      }, opt || {});
+
+      this.fx.animate($.merge( {
+        hideLabels: true,
+        modes: [
+          mode
+        ]
+      }, opt, {
+        onComplete: function(){
+          that.busy = false;
+          opt.onComplete();
+        }
+      }));
+    }
+  }
+});
+
+$jit.RGraph.$extend = true;
+
+(function(RGraph){
+
+  /*
+     Class: RGraph.Op
+     
+     Custom extension of <Graph.Op>.
+
+     Extends:
+
+     All <Graph.Op> methods
+     
+     See also:
+     
+     <Graph.Op>
+
+  */
+  RGraph.Op = new Class( {
+
+    Implements: Graph.Op
+
+  });
+
+  /*
+     Class: RGraph.Plot
+    
+    Custom extension of <Graph.Plot>.
+  
+    Extends:
+  
+    All <Graph.Plot> methods
+    
+    See also:
+    
+    <Graph.Plot>
+  
+  */
+  RGraph.Plot = new Class( {
+
+    Implements: Graph.Plot
+
+  });
+
+  /*
+    Object: RGraph.Label
+
+    Custom extension of <Graph.Label>. 
+    Contains custom <Graph.Label.SVG>, <Graph.Label.HTML> and <Graph.Label.Native> extensions.
+  
+    Extends:
+  
+    All <Graph.Label> methods and subclasses.
+  
+    See also:
+  
+    <Graph.Label>, <Graph.Label.Native>, <Graph.Label.HTML>, <Graph.Label.SVG>.
+  
+   */
+  RGraph.Label = {};
+
+  /*
+     RGraph.Label.Native
+
+     Custom extension of <Graph.Label.Native>.
+
+     Extends:
+
+     All <Graph.Label.Native> methods
+
+     See also:
+
+     <Graph.Label.Native>
+
+  */
+  RGraph.Label.Native = new Class( {
+    Implements: Graph.Label.Native
+  });
+
+  /*
+     RGraph.Label.SVG
+    
+    Custom extension of <Graph.Label.SVG>.
+  
+    Extends:
+  
+    All <Graph.Label.SVG> methods
+  
+    See also:
+  
+    <Graph.Label.SVG>
+  
+  */
+  RGraph.Label.SVG = new Class( {
+    Implements: Graph.Label.SVG,
+
+    initialize: function(viz){
+      this.viz = viz;
+    },
+
+    /* 
+       placeLabel
+
+       Overrides abstract method placeLabel in <Graph.Plot>.
+
+       Parameters:
+
+       tag - A DOM label element.
+       node - A <Graph.Node>.
+       controller - A configuration/controller object passed to the visualization.
+      
+     */
+    placeLabel: function(tag, node, controller){
+      var pos = node.pos.getc(true), 
+          canvas = this.viz.canvas,
+          ox = canvas.translateOffsetX,
+          oy = canvas.translateOffsetY,
+          sx = canvas.scaleOffsetX,
+          sy = canvas.scaleOffsetY,
+          radius = canvas.getSize();
+      var labelPos = {
+        x: Math.round(pos.x * sx + ox + radius.width / 2),
+        y: Math.round(pos.y * sy + oy + radius.height / 2)
+      };
+      tag.setAttribute('x', labelPos.x);
+      tag.setAttribute('y', labelPos.y);
+
+      controller.onPlaceLabel(tag, node);
+    }
+  });
+
+  /*
+     RGraph.Label.HTML
+
+     Custom extension of <Graph.Label.HTML>.
+
+     Extends:
+
+     All <Graph.Label.HTML> methods.
+
+     See also:
+
+     <Graph.Label.HTML>
+
+  */
+  RGraph.Label.HTML = new Class( {
+    Implements: Graph.Label.HTML,
+
+    initialize: function(viz){
+      this.viz = viz;
+    },
+    /* 
+       placeLabel
+
+       Overrides abstract method placeLabel in <Graph.Plot>.
+
+       Parameters:
+
+       tag - A DOM label element.
+       node - A <Graph.Node>.
+       controller - A configuration/controller object passed to the visualization.
+      
+     */
+    placeLabel: function(tag, node, controller){
+      var pos = node.pos.getc(true), 
+          canvas = this.viz.canvas,
+          ox = canvas.translateOffsetX,
+          oy = canvas.translateOffsetY,
+          sx = canvas.scaleOffsetX,
+          sy = canvas.scaleOffsetY,
+          radius = canvas.getSize();
+      var labelPos = {
+        x: Math.round(pos.x * sx + ox + radius.width / 2),
+        y: Math.round(pos.y * sy + oy + radius.height / 2)
+      };
+
+      var style = tag.style;
+      style.left = labelPos.x + 'px';
+      style.top = labelPos.y + 'px';
+      style.display = this.fitsInCanvas(labelPos, canvas)? '' : 'none';
+
+      controller.onPlaceLabel(tag, node);
+    }
+  });
+
+  /*
+    Class: RGraph.Plot.NodeTypes
+
+    This class contains a list of <Graph.Node> built-in types. 
+    Node types implemented are 'none', 'circle', 'triangle', 'rectangle', 'star', 'ellipse' and 'square'.
+
+    You can add your custom node types, customizing your visualization to the extreme.
+
+    Example:
+
+    (start code js)
+      RGraph.Plot.NodeTypes.implement({
+        'mySpecialType': {
+          'render': function(node, canvas) {
+            //print your custom node to canvas
+          },
+          //optional
+          'contains': function(node, pos) {
+            //return true if pos is inside the node or false otherwise
+          }
+        }
+      });
+    (end code)
+
+  */
+  RGraph.Plot.NodeTypes = new Class({
+    'none': {
+      'render': $.empty,
+      'contains': $.lambda(false)
+    },
+    'circle': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        this.nodeHelper.circle.render('fill', pos, dim, canvas);
+      },
+      'contains': function(node, pos){
+        var npos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        return this.nodeHelper.circle.contains(npos, pos, dim);
+      }
+    },
+    'ellipse': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            width = node.getData('width'), 
+            height = node.getData('height');
+        this.nodeHelper.ellipse.render('fill', pos, width, height, canvas);
+        },
+      'contains': function(node, pos){
+        var npos = node.pos.getc(true), 
+            width = node.getData('width'), 
+            height = node.getData('height');
+        return this.nodeHelper.ellipse.contains(npos, pos, width, height);
+      }
+    },
+    'square': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        this.nodeHelper.square.render('fill', pos, dim, canvas);
+      },
+      'contains': function(node, pos){
+        var npos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        return this.nodeHelper.square.contains(npos, pos, dim);
+      }
+    },
+    'rectangle': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            width = node.getData('width'), 
+            height = node.getData('height');
+        this.nodeHelper.rectangle.render('fill', pos, width, height, canvas);
+      },
+      'contains': function(node, pos){
+        var npos = node.pos.getc(true), 
+            width = node.getData('width'), 
+            height = node.getData('height');
+        return this.nodeHelper.rectangle.contains(npos, pos, width, height);
+      }
+    },
+    'triangle': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        this.nodeHelper.triangle.render('fill', pos, dim, canvas);
+      },
+      'contains': function(node, pos) {
+        var npos = node.pos.getc(true), 
+            dim = node.getData('dim');
+        return this.nodeHelper.triangle.contains(npos, pos, dim);
+      }
+    },
+    'star': {
+      'render': function(node, canvas){
+        var pos = node.pos.getc(true),
+            dim = node.getData('dim');
+        this.nodeHelper.star.render('fill', pos, dim, canvas);
+      },
+      'contains': function(node, pos) {
+        var npos = node.pos.getc(true),
+            dim = node.getData('dim');
+        return this.nodeHelper.star.contains(npos, pos, dim);
+      }
+    }
+  });
+
+  /*
+    Class: RGraph.Plot.EdgeTypes
+
+    This class contains a list of <Graph.Adjacence> built-in types. 
+    Edge types implemented are 'none', 'line' and 'arrow'.
+  
+    You can add your custom edge types, customizing your visualization to the extreme.
+  
+    Example:
+  
+    (start code js)
+      RGraph.Plot.EdgeTypes.implement({
+        'mySpecialType': {
+          'render': function(adj, canvas) {
+            //print your custom edge to canvas
+          },
+          //optional
+          'contains': function(adj, pos) {
+            //return true if pos is inside the arc or false otherwise
+          }
+        }
+      });
+    (end code)
+  
+  */
+  RGraph.Plot.EdgeTypes = new Class({
+    'none': $.empty,
+    'line': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true);
+        this.edgeHelper.line.render(from, to, canvas);
+      },
+      'contains': function(adj, pos) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true);
+        return this.edgeHelper.line.contains(from, to, pos, this.edge.epsilon);
+      }
+    },
+    'arrow': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true),
+            dim = adj.getData('dim'),
+            direction = adj.data.$direction,
+            inv = (direction && direction.length>1 && direction[0] != adj.nodeFrom.id);
+        this.edgeHelper.arrow.render(from, to, dim, inv, canvas);
+      },
+      'contains': function(adj, pos) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true);
+        return this.edgeHelper.arrow.contains(from, to, pos, this.edge.epsilon);
+      }
+    }
+  });
+
+})($jit.RGraph);
+
+
+/*
+ * File: Hypertree.js
+ * 
+*/
+
+/* 
+     Complex 
+     
+     A multi-purpose Complex Class with common methods. Extended for the Hypertree. 
+ 
+*/
+/* 
+   moebiusTransformation 
+ 
+   Calculates a moebius transformation for this point / complex. 
+    For more information go to: 
+        http://en.wikipedia.org/wiki/Moebius_transformation. 
+ 
+   Parameters: 
+ 
+      c - An initialized Complex instance representing a translation Vector. 
+*/
+
+Complex.prototype.moebiusTransformation = function(c) {
+  var num = this.add(c);
+  var den = c.$conjugate().$prod(this);
+  den.x++;
+  return num.$div(den);
+};
+
+/* 
+    moebiusTransformation 
+     
+    Calculates a moebius transformation for the hyperbolic tree. 
+     
+    <http://en.wikipedia.org/wiki/Moebius_transformation> 
+      
+     Parameters: 
+     
+        graph - A <Graph> instance.
+        pos - A <Complex>.
+        prop - A property array.
+        theta - Rotation angle. 
+        startPos - _optional_ start position. 
+*/
+Graph.Util.moebiusTransformation = function(graph, pos, prop, startPos, flags) {
+  this.eachNode(graph, function(elem) {
+    for ( var i = 0; i < prop.length; i++) {
+      var p = pos[i].scale(-1), property = startPos ? startPos : prop[i];
+      elem.getPos(prop[i]).set(elem.getPos(property).getc().moebiusTransformation(p));
+    }
+  }, flags);
+};
+
+/* 
+   Class: Hypertree 
+   
+   A Hyperbolic Tree/Graph visualization.
+   
+   Inspired by:
+ 
+   A Focus+Context Technique Based on Hyperbolic Geometry for Visualizing Large Hierarchies (John Lamping, Ramana Rao, and Peter Pirolli). 
+   <http://www.cs.tau.ac.il/~asharf/shrek/Projects/HypBrowser/startree-chi95.pdf>
+ 
+  Note:
+ 
+  This visualization was built and engineered from scratch, taking only the paper as inspiration, and only shares some features with the Hypertree described in the paper.
+
+  Implements:
+  
+  All <Loader> methods
+  
+  Constructor Options:
+  
+  Inherits options from
+  
+  - <Options.Canvas>
+  - <Options.Controller>
+  - <Options.Node>
+  - <Options.Edge>
+  - <Options.Label>
+  - <Options.Events>
+  - <Options.Tips>
+  - <Options.NodeStyles>
+  - <Options.Navigation>
+  
+  Additionally, there are other parameters and some default values changed
+  
+  radius - (string|number) Default's *auto*. The radius of the disc to plot the <Hypertree> in. 'auto' will take the smaller value from the width and height canvas dimensions. You can also set this to a custom value, for example *250*.
+  offset - (number) Default's *0*. A number in the range [0, 1) that will be substracted to each node position to make a more compact <Hypertree>. This will avoid placing nodes too far from each other when a there's a selected node.
+  fps - Described in <Options.Fx>. It's default value has been changed to *35*.
+  duration - Described in <Options.Fx>. It's default value has been changed to *1500*.
+  Edge.type - Described in <Options.Edge>. It's default value has been changed to *hyperline*. 
+  
+  Instance Properties:
+  
+  canvas - Access a <Canvas> instance.
+  graph - Access a <Graph> instance.
+  op - Access a <Hypertree.Op> instance.
+  fx - Access a <Hypertree.Plot> instance.
+  labels - Access a <Hypertree.Label> interface implementation.
+
+*/
+
+$jit.Hypertree = new Class( {
+
+  Implements: [ Loader, Extras, Layouts.Radial ],
+
+  initialize: function(controller) {
+    var $Hypertree = $jit.Hypertree;
+
+    var config = {
+      radius: "auto",
+      offset: 0,
+      Edge: {
+        type: 'hyperline'
+      },
+      duration: 1500,
+      fps: 35
+    };
+    this.controller = this.config = $.merge(Options("Canvas", "Node", "Edge",
+        "Fx", "Tips", "NodeStyles", "Events", "Navigation", "Controller", "Label"), config, controller);
+
+    var canvasConfig = this.config;
+    if(canvasConfig.useCanvas) {
+      this.canvas = canvasConfig.useCanvas;
+      this.config.labelContainer = this.canvas.id + '-label';
+    } else {
+      if(canvasConfig.background) {
+        canvasConfig.background = $.merge({
+          type: 'Circles'
+        }, canvasConfig.background);
+      }
+      this.canvas = new Canvas(this, canvasConfig);
+      this.config.labelContainer = (typeof canvasConfig.injectInto == 'string'? canvasConfig.injectInto : canvasConfig.injectInto.id) + '-label';
+    }
+
+    this.graphOptions = {
+      'klass': Polar,
+      'Node': {
+        'selected': false,
+        'exist': true,
+        'drawn': true
+      }
+    };
+    this.graph = new Graph(this.graphOptions, this.config.Node,
+        this.config.Edge);
+    this.labels = new $Hypertree.Label[canvasConfig.Label.type](this);
+    this.fx = new $Hypertree.Plot(this, $Hypertree);
+    this.op = new $Hypertree.Op(this);
+    this.json = null;
+    this.root = null;
+    this.busy = false;
+    // initialize extras
+    this.initializeExtras();
+  },
+
+  /* 
+  
+  createLevelDistanceFunc 
+
+  Returns the levelDistance function used for calculating a node distance 
+  to its origin. This function returns a function that is computed 
+  per level and not per node, such that all nodes with the same depth will have the 
+  same distance to the origin. The resulting function gets the 
+  parent node as parameter and returns a float.
+
+  */
+  createLevelDistanceFunc: function() {
+    // get max viz. length.
+    var r = this.getRadius();
+    // get max depth.
+    var depth = 0, max = Math.max, config = this.config;
+    this.graph.eachNode(function(node) {
+      depth = max(node._depth, depth);
+    }, "ignore");
+    depth++;
+    // node distance generator
+    var genDistFunc = function(a) {
+      return function(node) {
+        node.scale = r;
+        var d = node._depth + 1;
+        var acum = 0, pow = Math.pow;
+        while (d) {
+          acum += pow(a, d--);
+        }
+        return acum - config.offset;
+      };
+    };
+    // estimate better edge length.
+    for ( var i = 0.51; i <= 1; i += 0.01) {
+      var valSeries = (1 - Math.pow(i, depth)) / (1 - i);
+      if (valSeries >= 2) { return genDistFunc(i - 0.01); }
+    }
+    return genDistFunc(0.75);
+  },
+
+  /* 
+    Method: getRadius 
+    
+    Returns the current radius of the visualization. If *config.radius* is *auto* then it 
+    calculates the radius by taking the smaller size of the <Canvas> widget.
+    
+    See also:
+    
+    <Canvas.getSize>
+   
+  */
+  getRadius: function() {
+    var rad = this.config.radius;
+    if (rad !== "auto") { return rad; }
+    var s = this.canvas.getSize();
+    return Math.min(s.width, s.height) / 2;
+  },
+
+  /* 
+    Method: refresh 
+    
+    Computes positions and plots the tree.
+
+    Parameters:
+
+    reposition - (optional|boolean) Set this to *true* to force all positions (current, start, end) to match.
+
+   */
+  refresh: function(reposition) {
+    if (reposition) {
+      this.reposition();
+      this.graph.eachNode(function(node) {
+        node.startPos.rho = node.pos.rho = node.endPos.rho;
+        node.startPos.theta = node.pos.theta = node.endPos.theta;
+      });
+    } else {
+      this.compute();
+    }
+    this.plot();
+  },
+
+  /* 
+   reposition 
+   
+   Computes nodes' positions and restores the tree to its previous position.
+
+   For calculating nodes' positions the root must be placed on its origin. This method does this 
+     and then attemps to restore the hypertree to its previous position.
+    
+  */
+  reposition: function() {
+    this.compute('end');
+    var vector = this.graph.getNode(this.root).pos.getc().scale(-1);
+    Graph.Util.moebiusTransformation(this.graph, [ vector ], [ 'end' ],
+        'end', "ignore");
+    this.graph.eachNode(function(node) {
+      if (node.ignore) {
+        node.endPos.rho = node.pos.rho;
+        node.endPos.theta = node.pos.theta;
+      }
+    });
+  },
+
+  /* 
+   Method: plot 
+   
+   Plots the <Hypertree>. This is a shortcut to *fx.plot*. 
+
+  */
+  plot: function() {
+    this.fx.plot();
+  },
+
+  /* 
+   Method: onClick 
+   
+   Animates the <Hypertree> to center the node specified by *id*.
+
+   Parameters:
+
+   id - A <Graph.Node> id.
+   opt - (optional|object) An object containing some extra properties described below
+   hideLabels - (boolean) Default's *true*. Hide labels when performing the animation.
+
+   Example:
+
+   (start code js)
+     ht.onClick('someid');
+     //or also...
+     ht.onClick('someid', {
+      hideLabels: false
+     });
+    (end code)
+    
+  */
+  onClick: function(id, opt) {
+    var pos = this.graph.getNode(id).pos.getc(true);
+    this.move(pos, opt);
+  },
+
+  /* 
+   Method: move 
+
+   Translates the tree to the given position. 
+
+   Parameters:
+
+   pos - (object) A *x, y* coordinate object where x, y in [0, 1), to move the tree to.
+   opt - This object has been defined in <Hypertree.onClick>
+   
+   Example:
+   
+   (start code js)
+     ht.move({ x: 0, y: 0.7 }, {
+       hideLabels: false
+     });
+   (end code)
+
+  */
+  move: function(pos, opt) {
+    var versor = $C(pos.x, pos.y);
+    if (this.busy === false && versor.norm() < 1) {
+      this.busy = true;
+      var root = this.graph.getClosestNodeToPos(versor), that = this;
+      this.graph.computeLevels(root.id, 0);
+      this.controller.onBeforeCompute(root);
+      opt = $.merge( {
+        onComplete: $.empty
+      }, opt || {});
+      this.fx.animate($.merge( {
+        modes: [ 'moebius' ],
+        hideLabels: true
+      }, opt, {
+        onComplete: function() {
+          that.busy = false;
+          opt.onComplete();
+        }
+      }), versor);
+    }
+  }
+});
+
+$jit.Hypertree.$extend = true;
+
+(function(Hypertree) {
+
+  /* 
+     Class: Hypertree.Op 
+   
+     Custom extension of <Graph.Op>.
+
+     Extends:
+
+     All <Graph.Op> methods
+     
+     See also:
+     
+     <Graph.Op>
+
+  */
+  Hypertree.Op = new Class( {
+
+    Implements: Graph.Op
+
+  });
+
+  /* 
+     Class: Hypertree.Plot 
+   
+    Custom extension of <Graph.Plot>.
+  
+    Extends:
+  
+    All <Graph.Plot> methods
+    
+    See also:
+    
+    <Graph.Plot>
+  
+  */
+  Hypertree.Plot = new Class( {
+
+    Implements: Graph.Plot
+
+  });
+
+  /*
+    Object: Hypertree.Label
+
+    Custom extension of <Graph.Label>. 
+    Contains custom <Graph.Label.SVG>, <Graph.Label.HTML> and <Graph.Label.Native> extensions.
+  
+    Extends:
+  
+    All <Graph.Label> methods and subclasses.
+  
+    See also:
+  
+    <Graph.Label>, <Graph.Label.Native>, <Graph.Label.HTML>, <Graph.Label.SVG>.
+
+   */
+  Hypertree.Label = {};
+
+  /*
+     Hypertree.Label.Native
+
+     Custom extension of <Graph.Label.Native>.
+
+     Extends:
+
+     All <Graph.Label.Native> methods
+
+     See also:
+
+     <Graph.Label.Native>
+
+  */
+  Hypertree.Label.Native = new Class( {
+    Implements: Graph.Label.Native,
+
+    initialize: function(viz) {
+      this.viz = viz;
+    },
+
+    renderLabel: function(canvas, node, controller) {
+      var ctx = canvas.getCtx();
+      var coord = node.pos.getc(true);
+      var s = this.viz.getRadius();
+      ctx.fillText(node.name, coord.x * s, coord.y * s);
+    }
+  });
+
+  /*
+     Hypertree.Label.SVG
+
+    Custom extension of <Graph.Label.SVG>.
+  
+    Extends:
+  
+    All <Graph.Label.SVG> methods
+  
+    See also:
+  
+    <Graph.Label.SVG>
+  
+  */
+  Hypertree.Label.SVG = new Class( {
+    Implements: Graph.Label.SVG,
+
+    initialize: function(viz) {
+      this.viz = viz;
+    },
+
+    /* 
+       placeLabel
+
+       Overrides abstract method placeLabel in <Graph.Plot>.
+
+       Parameters:
+
+       tag - A DOM label element.
+       node - A <Graph.Node>.
+       controller - A configuration/controller object passed to the visualization.
+      
+     */
+    placeLabel: function(tag, node, controller) {
+      var pos = node.pos.getc(true), 
+          canvas = this.viz.canvas,
+          ox = canvas.translateOffsetX,
+          oy = canvas.translateOffsetY,
+          sx = canvas.scaleOffsetX,
+          sy = canvas.scaleOffsetY,
+          radius = canvas.getSize(),
+          r = this.viz.getRadius();
+      var labelPos = {
+        x: Math.round((pos.x * sx) * r + ox + radius.width / 2),
+        y: Math.round((pos.y * sy) * r + oy + radius.height / 2)
+      };
+      tag.setAttribute('x', labelPos.x);
+      tag.setAttribute('y', labelPos.y);
+      controller.onPlaceLabel(tag, node);
+    }
+  });
+
+  /*
+     Hypertree.Label.HTML
+
+     Custom extension of <Graph.Label.HTML>.
+
+     Extends:
+
+     All <Graph.Label.HTML> methods.
+
+     See also:
+
+     <Graph.Label.HTML>
+
+  */
+  Hypertree.Label.HTML = new Class( {
+    Implements: Graph.Label.HTML,
+
+    initialize: function(viz) {
+      this.viz = viz;
+    },
+    /* 
+       placeLabel
+
+       Overrides abstract method placeLabel in <Graph.Plot>.
+
+       Parameters:
+
+       tag - A DOM label element.
+       node - A <Graph.Node>.
+       controller - A configuration/controller object passed to the visualization.
+      
+     */
+    placeLabel: function(tag, node, controller) {
+      var pos = node.pos.getc(true), 
+          canvas = this.viz.canvas,
+          ox = canvas.translateOffsetX,
+          oy = canvas.translateOffsetY,
+          sx = canvas.scaleOffsetX,
+          sy = canvas.scaleOffsetY,
+          radius = canvas.getSize(),
+          r = this.viz.getRadius();
+      var labelPos = {
+        x: Math.round((pos.x * sx) * r + ox + radius.width / 2),
+        y: Math.round((pos.y * sy) * r + oy + radius.height / 2)
+      };
+      var style = tag.style;
+      style.left = labelPos.x + 'px';
+      style.top = labelPos.y + 'px';
+      style.display = this.fitsInCanvas(labelPos, canvas) ? '' : 'none';
+
+      controller.onPlaceLabel(tag, node);
+    }
+  });
+
+  /*
+    Class: Hypertree.Plot.NodeTypes
+
+    This class contains a list of <Graph.Node> built-in types. 
+    Node types implemented are 'none', 'circle', 'triangle', 'rectangle', 'star', 'ellipse' and 'square'.
+
+    You can add your custom node types, customizing your visualization to the extreme.
+
+    Example:
+
+    (start code js)
+      Hypertree.Plot.NodeTypes.implement({
+        'mySpecialType': {
+          'render': function(node, canvas) {
+            //print your custom node to canvas
+          },
+          //optional
+          'contains': function(node, pos) {
+            //return true if pos is inside the node or false otherwise
+          }
+        }
+      });
+    (end code)
+
+  */
+  Hypertree.Plot.NodeTypes = new Class({
+    'none': {
+      'render': $.empty,
+      'contains': $.lambda(false)
+    },
+    'circle': {
+      'render': function(node, canvas) {
+        var nconfig = this.node,
+            dim = node.getData('dim'),
+            p = node.pos.getc();
+        dim = nconfig.transform? dim * (1 - p.squaredNorm()) : dim;
+        p.$scale(node.scale);
+        if (dim > 0.2) {
+          this.nodeHelper.circle.render('fill', p, dim, canvas);
+        }
+      },
+      'contains': function(node, pos) {
+        var dim = node.getData('dim'),
+            npos = node.pos.getc().$scale(node.scale);
+        return this.nodeHelper.circle.contains(npos, pos, dim);
+      }
+    },
+    'ellipse': {
+      'render': function(node, canvas) {
+        var pos = node.pos.getc().$scale(node.scale),
+            width = node.getData('width'),
+            height = node.getData('height');
+        this.nodeHelper.ellipse.render('fill', pos, width, height, canvas);
+      },
+      'contains': function(node, pos) {
+        var width = node.getData('width'),
+            height = node.getData('height'),
+            npos = node.pos.getc().$scale(node.scale);
+        return this.nodeHelper.circle.contains(npos, pos, width, height);
+      }
+    },
+    'square': {
+      'render': function(node, canvas) {
+        var nconfig = this.node,
+            dim = node.getData('dim'),
+            p = node.pos.getc();
+        dim = nconfig.transform? dim * (1 - p.squaredNorm()) : dim;
+        p.$scale(node.scale);
+        if (dim > 0.2) {
+          this.nodeHelper.square.render('fill', p, dim, canvas);
+        }
+      },
+      'contains': function(node, pos) {
+        var dim = node.getData('dim'),
+            npos = node.pos.getc().$scale(node.scale);
+        return this.nodeHelper.square.contains(npos, pos, dim);
+      }
+    },
+    'rectangle': {
+      'render': function(node, canvas) {
+        var nconfig = this.node,
+            width = node.getData('width'),
+            height = node.getData('height'),
+            pos = node.pos.getc();
+        width = nconfig.transform? width * (1 - pos.squaredNorm()) : width;
+        height = nconfig.transform? height * (1 - pos.squaredNorm()) : height;
+        pos.$scale(node.scale);
+        if (width > 0.2 && height > 0.2) {
+          this.nodeHelper.rectangle.render('fill', pos, width, height, canvas);
+        }
+      },
+      'contains': function(node, pos) {
+        var width = node.getData('width'),
+            height = node.getData('height'),
+            npos = node.pos.getc().$scale(node.scale);
+        return this.nodeHelper.rectangle.contains(npos, pos, width, height);
+      }
+    },
+    'triangle': {
+      'render': function(node, canvas) {
+        var nconfig = this.node,
+            dim = node.getData('dim'),
+            p = node.pos.getc();
+        dim = nconfig.transform? dim * (1 - p.squaredNorm()) : dim;
+        p.$scale(node.scale);
+        if (dim > 0.2) {
+          this.nodeHelper.triangle.render('fill', p, dim, canvas);
+        }
+      },
+      'contains': function(node, pos) {
+        var dim = node.getData('dim'),
+            npos = node.pos.getc().$scale(node.scale);
+        return this.nodeHelper.triangle.contains(npos, pos, dim);
+      }
+    },
+    'star': {
+      'render': function(node, canvas) {
+        var nconfig = this.node,
+            dim = node.getData('dim'),
+            p = node.pos.getc();
+        dim = nconfig.transform? dim * (1 - p.squaredNorm()) : dim;
+        p.$scale(node.scale);
+        if (dim > 0.2) {
+          this.nodeHelper.star.render('fill', p, dim, canvas);
+        }
+      },
+      'contains': function(node, pos) {
+        var dim = node.getData('dim'),
+            npos = node.pos.getc().$scale(node.scale);
+        return this.nodeHelper.star.contains(npos, pos, dim);
+      }
+    }
+  });
+
+  /*
+   Class: Hypertree.Plot.EdgeTypes
+
+    This class contains a list of <Graph.Adjacence> built-in types. 
+    Edge types implemented are 'none', 'line', 'arrow' and 'hyperline'.
+  
+    You can add your custom edge types, customizing your visualization to the extreme.
+  
+    Example:
+  
+    (start code js)
+      Hypertree.Plot.EdgeTypes.implement({
+        'mySpecialType': {
+          'render': function(adj, canvas) {
+            //print your custom edge to canvas
+          },
+          //optional
+          'contains': function(adj, pos) {
+            //return true if pos is inside the arc or false otherwise
+          }
+        }
+      });
+    (end code)
+  
+  */
+  Hypertree.Plot.EdgeTypes = new Class({
+    'none': $.empty,
+    'line': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(true),
+          to = adj.nodeTo.pos.getc(true),
+          r = adj.nodeFrom.scale;
+          this.edgeHelper.line.render({x:from.x*r, y:from.y*r}, {x:to.x*r, y:to.y*r}, canvas);
+      },
+      'contains': function(adj, pos) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true),
+            r = adj.nodeFrom.scale;
+            this.edgeHelper.line.contains({x:from.x*r, y:from.y*r}, {x:to.x*r, y:to.y*r}, pos, this.edge.epsilon);
+      }
+    },
+    'arrow': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true),
+            r = adj.nodeFrom.scale,
+            dim = adj.getData('dim'),
+            direction = adj.data.$direction,
+            inv = (direction && direction.length>1 && direction[0] != adj.nodeFrom.id);
+        this.edgeHelper.arrow.render({x:from.x*r, y:from.y*r}, {x:to.x*r, y:to.y*r}, dim, inv, canvas);
+      },
+      'contains': function(adj, pos) {
+        var from = adj.nodeFrom.pos.getc(true),
+            to = adj.nodeTo.pos.getc(true),
+            r = adj.nodeFrom.scale;
+        this.edgeHelper.arrow.contains({x:from.x*r, y:from.y*r}, {x:to.x*r, y:to.y*r}, pos, this.edge.epsilon);
+      }
+    },
+    'hyperline': {
+      'render': function(adj, canvas) {
+        var from = adj.nodeFrom.pos.getc(),
+            to = adj.nodeTo.pos.getc(),
+            dim = this.viz.getRadius();
+        this.edgeHelper.hyperline.render(from, to, dim, canvas);
+      },
+      'contains': $.lambda(false)
+    }
+  });
+
+})($jit.Hypertree);
+
+
+
+
+ })();
\ No newline at end of file
diff --git a/cli/sdncon/ui/static/js/thirdparty/jquery-1.9.1.js b/cli/sdncon/ui/static/js/thirdparty/jquery-1.9.1.js
new file mode 100755
index 0000000..e2c203f
--- /dev/null
+++ b/cli/sdncon/ui/static/js/thirdparty/jquery-1.9.1.js
@@ -0,0 +1,9597 @@
+/*!
+ * jQuery JavaScript Library v1.9.1
+ * http://jquery.com/
+ *
+ * Includes Sizzle.js
+ * http://sizzlejs.com/
+ *
+ * Copyright 2005, 2012 jQuery Foundation, Inc. and other contributors
+ * Released under the MIT license
+ * http://jquery.org/license
+ *
+ * Date: 2013-2-4
+ */
+(function( window, undefined ) {
+
+// Can't do this because several apps including ASP.NET trace
+// the stack via arguments.caller.callee and Firefox dies if
+// you try to trace through "use strict" call chains. (#13335)
+// Support: Firefox 18+
+//"use strict";
+var
+	// The deferred used on DOM ready
+	readyList,
+
+	// A central reference to the root jQuery(document)
+	rootjQuery,
+
+	// Support: IE<9
+	// For `typeof node.method` instead of `node.method !== undefined`
+	core_strundefined = typeof undefined,
+
+	// Use the correct document accordingly with window argument (sandbox)
+	document = window.document,
+	location = window.location,
+
+	// Map over jQuery in case of overwrite
+	_jQuery = window.jQuery,
+
+	// Map over the $ in case of overwrite
+	_$ = window.$,
+
+	// [[Class]] -> type pairs
+	class2type = {},
+
+	// List of deleted data cache ids, so we can reuse them
+	core_deletedIds = [],
+
+	core_version = "1.9.1",
+
+	// Save a reference to some core methods
+	core_concat = core_deletedIds.concat,
+	core_push = core_deletedIds.push,
+	core_slice = core_deletedIds.slice,
+	core_indexOf = core_deletedIds.indexOf,
+	core_toString = class2type.toString,
+	core_hasOwn = class2type.hasOwnProperty,
+	core_trim = core_version.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 splitting on whitespace
+	core_rnotwhite = /\S+/g,
+
+	// 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 <tag> to avoid XSS via location.hash (#9521)
+	// Strict HTML recognition (#11290: must start with <)
+	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+(?:[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
+	completed = function( event ) {
+
+		// readyState === "complete" is good enough for us to call the dom ready in oldIE
+		if ( document.addEventListener || event.type === "load" || document.readyState === "complete" ) {
+			detach();
+			jQuery.ready();
+		}
+	},
+	// Clean-up method for dom ready events
+	detach = function() {
+		if ( document.addEventListener ) {
+			document.removeEventListener( "DOMContentLoaded", completed, false );
+			window.removeEventListener( "load", completed, false );
+
+		} else {
+			document.detachEvent( "onreadystatechange", completed );
+			window.detachEvent( "onload", completed );
+		}
+	};
+
+jQuery.fn = jQuery.prototype = {
+	// The current version of jQuery being used
+	jquery: core_version,
+
+	constructor: jQuery,
+	init: function( selector, context, rootjQuery ) {
+		var match, elem;
+
+		// HANDLE: $(""), $(null), $(undefined), $(false)
+		if ( !selector ) {
+			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;
+
+					// scripts is true for back-compat
+					jQuery.merge( this, jQuery.parseHTML(
+						match[1],
+						context && context.nodeType ? context.ownerDocument || context : document,
+						true
+					) );
+
+					// HANDLE: $(html, props)
+					if ( rsingleTag.test( match[1] ) && jQuery.isPlainObject( context ) ) {
+						for ( match in context ) {
+							// Properties of context are called as methods if possible
+							if ( jQuery.isFunction( this[ match ] ) ) {
+								this[ match ]( context[ match ] );
+
+							// ...and otherwise set as attributes
+							} else {
+								this.attr( match, context[ match ] );
+							}
+						}
+					}
+
+					return this;
+
+				// 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: $(DOMElement)
+		} else if ( selector.nodeType ) {
+			this.context = this[0] = selector;
+			this.length = 1;
+			return this;
+
+		// 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 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 ) {
+
+		// 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;
+
+		// 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;
+	},
+
+	slice: function() {
+		return this.pushStack( core_slice.apply( this, arguments ) );
+	},
+
+	first: function() {
+		return this.eq( 0 );
+	},
+
+	last: function() {
+		return this.eq( -1 );
+	},
+
+	eq: function( i ) {
+		var len = this.length,
+			j = +i + ( i < 0 ? len : 0 );
+		return this.pushStack( j >= 0 && j < len ? [ this[j] ] : [] );
+	},
+
+	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 src, copyIsArray, copy, name, options, 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 );
+		}
+
+		// 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 ) {
+		if ( obj == null ) {
+			return String( obj );
+		}
+		return typeof obj === "object" || typeof obj === "function" ?
+			class2type[ core_toString.call(obj) ] || "object" :
+			typeof obj;
+	},
+
+	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
+	// keepScripts (optional): If true, will include scripts passed in the html string
+	parseHTML: function( data, context, keepScripts ) {
+		if ( !data || typeof data !== "string" ) {
+			return null;
+		}
+		if ( typeof context === "boolean" ) {
+			keepScripts = context;
+			context = false;
+		}
+		context = context || document;
+
+		var parsed = rsingleTag.exec( data ),
+			scripts = !keepScripts && [];
+
+		// Single tag
+		if ( parsed ) {
+			return [ context.createElement( parsed[1] ) ];
+		}
+
+		parsed = jQuery.buildFragment( [ data ], context, scripts );
+		if ( scripts ) {
+			jQuery( scripts ).remove();
+		}
+		return jQuery.merge( [], parsed.childNodes );
+	},
+
+	parseJSON: function( data ) {
+		// Attempt to parse using the native JSON parser first
+		if ( window.JSON && window.JSON.parse ) {
+			return window.JSON.parse( data );
+		}
+
+		if ( data === null ) {
+			return data;
+		}
+
+		if ( typeof data === "string" ) {
+
+			// Make sure leading/trailing whitespace is removed (IE can't handle it)
+			data = jQuery.trim( data );
+
+			if ( 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 && jQuery.trim( 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 value,
+			i = 0,
+			length = obj.length,
+			isArray = isArraylike( obj );
+
+		if ( args ) {
+			if ( isArray ) {
+				for ( ; i < length; i++ ) {
+					value = callback.apply( obj[ i ], args );
+
+					if ( value === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( i in obj ) {
+					value = callback.apply( obj[ i ], args );
+
+					if ( value === false ) {
+						break;
+					}
+				}
+			}
+
+		// A special, fast, case for the most common use of each
+		} else {
+			if ( isArray ) {
+				for ( ; i < length; i++ ) {
+					value = callback.call( obj[ i ], i, obj[ i ] );
+
+					if ( value === false ) {
+						break;
+					}
+				}
+			} else {
+				for ( i in obj ) {
+					value = callback.call( obj[ i ], i, obj[ i ] );
+
+					if ( value === 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 ret = results || [];
+
+		if ( arr != null ) {
+			if ( isArraylike( Object(arr) ) ) {
+				jQuery.merge( ret,
+					typeof arr === "string" ?
+					[ arr ] : arr
+				);
+			} else {
+				core_push.call( 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,
+			i = 0,
+			length = elems.length,
+			isArray = isArraylike( elems ),
+			ret = [];
+
+		// 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 ( i in elems ) {
+				value = callback( elems[ i ], i, arg );
+
+				if ( value != null ) {
+					ret[ ret.length ] = value;
+				}
+			}
+		}
+
+		// Flatten any nested arrays
+		return core_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 args, proxy, tmp;
+
+		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 || this, 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, raw ) {
+		var i = 0,
+			length = elems.length,
+			bulk = key == null;
+
+		// Sets many values
+		if ( jQuery.type( key ) === "object" ) {
+			chainable = true;
+			for ( i in key ) {
+				jQuery.access( elems, fn, i, key[i], true, emptyGet, raw );
+			}
+
+		// Sets one value
+		} else if ( value !== undefined ) {
+			chainable = true;
+
+			if ( !jQuery.isFunction( value ) ) {
+				raw = true;
+			}
+
+			if ( bulk ) {
+				// Bulk operations run against the entire set
+				if ( raw ) {
+					fn.call( elems, value );
+					fn = null;
+
+				// ...except when executing function values
+				} else {
+					bulk = fn;
+					fn = function( elem, key, value ) {
+						return bulk.call( jQuery( elem ), value );
+					};
+				}
+			}
+
+			if ( fn ) {
+				for ( ; i < length; i++ ) {
+					fn( elems[i], key, raw ? value : value.call( elems[i], i, fn( elems[i], key ) ) );
+				}
+			}
+		}
+
+		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 );
+
+		// Standards-based browsers support DOMContentLoaded
+		} else if ( document.addEventListener ) {
+			// Use the handy event callback
+			document.addEventListener( "DOMContentLoaded", completed, false );
+
+			// A fallback to window.onload, that will always work
+			window.addEventListener( "load", completed, false );
+
+		// If IE event model is used
+		} else {
+			// Ensure firing before onload, maybe late but safe also for iframes
+			document.attachEvent( "onreadystatechange", completed );
+
+			// A fallback to window.onload, that will always work
+			window.attachEvent( "onload", completed );
+
+			// 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 );
+						}
+
+						// detach all dom ready events
+						detach();
+
+						// 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 Error".split(" "), function(i, name) {
+	class2type[ "[object " + name + "]" ] = name.toLowerCase();
+});
+
+function isArraylike( obj ) {
+	var length = obj.length,
+		type = jQuery.type( obj );
+
+	if ( jQuery.isWindow( obj ) ) {
+		return false;
+	}
+
+	if ( obj.nodeType === 1 && length ) {
+		return true;
+	}
+
+	return type === "array" || type !== "function" &&
+		( length === 0 ||
+		typeof length === "number" && length > 0 && ( length - 1 ) in obj );
+}
+
+// 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.match( core_rnotwhite ) || [], 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 // Flag to know if list is currently firing
+		firing,
+		// Last fire value (for non-forgettable lists)
+		memory,
+		// Flag to know if list was already fired
+		fired,
+		// End of the loop when firing
+		firingLength,
+		// Index of currently firing callback (modified by remove if needed)
+		firingIndex,
+		// First callback to fire (used internally by add and fireWith)
+		firingStart,
+		// 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;
+			},
+			// Check if a given callback is in the list.
+			// If no argument is given, return whether or not list has callbacks attached.
+			has: function( fn ) {
+				return fn ? jQuery.inArray( fn, list ) > -1 : !!( list && list.length );
+			},
+			// 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 = jQuery.isFunction( fns[ i ] ) && fns[ i ];
+							// deferred[ done | fail | progress ] for forwarding actions to newDefer
+							deferred[ tuple[1] ](function() {
+								var returned = fn && 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 === promise ? newDefer.promise() : this, fn ? [ returned ] : arguments );
+								}
+							});
+						});
+						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 ]
+			deferred[ tuple[0] ] = function() {
+				deferred[ tuple[0] + "With" ]( this === deferred ? promise : this, arguments );
+				return this;
+			};
+			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,
+		input, select, fragment,
+		opt, eventName, isSupported, i,
+		div = document.createElement("div");
+
+	// Setup
+	div.setAttribute( "className", "t" );
+	div.innerHTML = "  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>";
+
+	// 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 = {
+		// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
+		getSetAttribute: div.className !== "t",
+
+		// 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,
+
+		// Check the default checkbox/radio value ("" on WebKit; "on" elsewhere)
+		checkOn: !!input.value,
+
+		// 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,
+
+		// 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></:nav>",
+
+		// jQuery.support.boxModel DEPRECATED in 1.8 since we don't support Quirks Mode
+		boxModel: document.compatMode === "CSS1Compat",
+
+		// Will be defined later
+		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;
+
+	// Support: IE<9
+	try {
+		delete div.test;
+	} catch( e ) {
+		support.deleteExpando = false;
+	}
+
+	// Check if we can trust getAttribute("value")
+	input = document.createElement("input");
+	input.setAttribute( "value", "" );
+	support.input = input.getAttribute( "value" ) === "";
+
+	// Check if an input maintains its value after becoming a radio
+	input.value = "t";
+	input.setAttribute( "type", "radio" );
+	support.radioValue = input.value === "t";
+
+	// #11217 - WebKit loses check when the name is after the checked attribute
+	input.setAttribute( "checked", "t" );
+	input.setAttribute( "name", "t" );
+
+	fragment = document.createDocumentFragment();
+	fragment.appendChild( input );
+
+	// Check if a disconnected checkbox will retain its checked
+	// value of true after appended to the DOM (IE6/7)
+	support.appendChecked = input.checked;
+
+	// WebKit doesn't clone checked state correctly in fragments
+	support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
+
+	// Support: IE<9
+	// Opera does not clone events (and typeof div.attachEvent === undefined).
+	// IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
+	if ( div.attachEvent ) {
+		div.attachEvent( "onclick", function() {
+			support.noCloneEvent = false;
+		});
+
+		div.cloneNode( true ).click();
+	}
+
+	// Support: IE<9 (lack submit/change bubble), Firefox 17+ (lack focusin event)
+	// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP), test/csp.php
+	for ( i in { submit: true, change: true, focusin: true }) {
+		div.setAttribute( eventName = "on" + i, "t" );
+
+		support[ i + "Bubbles" ] = eventName in window || div.attributes[ eventName ].expando === false;
+	}
+
+	div.style.backgroundClip = "content-box";
+	div.cloneNode( true ).style.backgroundClip = "";
+	support.clearCloneStyle = div.style.backgroundClip === "content-box";
+
+	// Run tests that need a body at doc ready
+	jQuery(function() {
+		var container, marginDiv, tds,
+			divReset = "padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",
+			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 = "border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px";
+
+		body.appendChild( container ).appendChild( div );
+
+		// Support: IE8
+		// 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).
+		div.innerHTML = "<table><tr><td></td><td>t</td></tr></table>";
+		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";
+
+		// Support: IE8
+		// Check if empty table cells still have offsetWidth/Height
+		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 );
+
+		// Use 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. (#3333)
+			// Fails in WebKit before Feb 2011 nightlies
+			// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
+			marginDiv = div.appendChild( document.createElement("div") );
+			marginDiv.style.cssText = div.style.cssText = divReset;
+			marginDiv.style.marginRight = marginDiv.style.width = "0";
+			div.style.width = "1px";
+
+			support.reliableMarginRight =
+				!parseFloat( ( window.getComputedStyle( marginDiv, null ) || {} ).marginRight );
+		}
+
+		if ( typeof div.style.zoom !== core_strundefined ) {
+			// Support: IE<8
+			// Check if natively block-level elements act like inline-block
+			// elements when setting their display to 'inline' and giving
+			// them layout
+			div.innerHTML = "";
+			div.style.cssText = divReset + "width:1px;padding:1px;display:inline;zoom:1";
+			support.inlineBlockNeedsLayout = ( div.offsetWidth === 3 );
+
+			// Support: IE6
+			// Check if elements with layout shrink-wrap their children
+			div.style.display = "block";
+			div.innerHTML = "<div></div>";
+			div.firstChild.style.width = "5px";
+			support.shrinkWrapBlocks = ( div.offsetWidth !== 3 );
+
+			if ( support.inlineBlockNeedsLayout ) {
+				// Prevent IE 6 from affecting layout for positioned elements #11048
+				// Prevent IE from shrinking the body in IE 7 mode #12869
+				// Support: IE<8
+				body.style.zoom = 1;
+			}
+		}
+
+		body.removeChild( container );
+
+		// Null elements to avoid leaks in IE
+		container = div = tds = marginDiv = null;
+	});
+
+	// Null elements to avoid leaks in IE
+	all = select = fragment = opt = a = input = null;
+
+	return support;
+})();
+
+var rbrace = /(?:\{[\s\S]*\}|\[[\s\S]*\])$/,
+	rmultiDash = /([A-Z])/g;
+
+function internalData( 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 = core_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;
+}
+
+function internalRemoveData( elem, name, pvt ) {
+	if ( !jQuery.acceptData( elem ) ) {
+		return;
+	}
+
+	var i, l, thisCache,
+		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(" ");
+					}
+				}
+			} else {
+				// If "name" is an array of keys...
+				// When data is initially created, via ("key", "val") signature,
+				// keys will be converted to camelCase.
+				// Since there is no way to tell _how_ a key was added, remove
+				// both plain key and camelCase key. #12786
+				// This will only penalize the array argument path.
+				name = name.concat( jQuery.map( name, jQuery.camelCase ) );
+			}
+
+			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;
+	}
+}
+
+jQuery.extend({
+	cache: {},
+
+	// Unique for each copy of jQuery on the page
+	// Non-digits removed to match rinlinejQuery
+	expando: "jQuery" + ( core_version + 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 ) {
+		return internalData( elem, name, data );
+	},
+
+	removeData: function( elem, name ) {
+		return internalRemoveData( elem, name );
+	},
+
+	// For internal use only.
+	_data: function( elem, name, data ) {
+		return internalData( elem, name, data, true );
+	},
+
+	_removeData: function( elem, name ) {
+		return internalRemoveData( elem, name, true );
+	},
+
+	// A method for determining if a DOM node can handle the data expando
+	acceptData: function( elem ) {
+		// Do not set data on non-element because it will not be cleared (#8335).
+		if ( elem.nodeType && elem.nodeType !== 1 && elem.nodeType !== 9 ) {
+			return false;
+		}
+
+		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 attrs, name,
+			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" ) ) {
+					attrs = elem.attributes;
+					for ( ; i < attrs.length; i++ ) {
+						name = attrs[i].name;
+
+						if ( !name.indexOf( "data-" ) ) {
+							name = jQuery.camelCase( name.slice(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 );
+			});
+		}
+
+		return jQuery.access( this, function( value ) {
+
+			if ( value === undefined ) {
+				// Try to fetch any internally stored data first
+				return elem ? dataAttr( elem, key, jQuery.data( elem, key ) ) : null;
+			}
+
+			this.each(function() {
+				jQuery.data( this, key, value );
+			});
+		}, null, value, arguments.length > 1, null, true );
+	},
+
+	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--;
+		}
+
+		hooks.cur = fn;
+		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" );
+				jQuery._removeData( elem, key );
+			})
+		});
+	}
+});
+
+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,
+	rclass = /[\t\r\n]/g,
+	rreturn = /\r/g,
+	rfocusable = /^(?:input|select|textarea|button|object)$/i,
+	rclickable = /^(?:a|area)$/i,
+	rboolean = /^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,
+	ruseDefault = /^(?:checked|selected)$/i,
+	getSetAttribute = jQuery.support.getSetAttribute,
+	getSetInput = jQuery.support.input;
+
+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 classes, elem, cur, clazz, j,
+			i = 0,
+			len = this.length,
+			proceed = typeof value === "string" && value;
+
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function( j ) {
+				jQuery( this ).addClass( value.call( this, j, this.className ) );
+			});
+		}
+
+		if ( proceed ) {
+			// The disjunction here is for better compressibility (see removeClass)
+			classes = ( value || "" ).match( core_rnotwhite ) || [];
+
+			for ( ; i < len; i++ ) {
+				elem = this[ i ];
+				cur = elem.nodeType === 1 && ( elem.className ?
+					( " " + elem.className + " " ).replace( rclass, " " ) :
+					" "
+				);
+
+				if ( cur ) {
+					j = 0;
+					while ( (clazz = classes[j++]) ) {
+						if ( cur.indexOf( " " + clazz + " " ) < 0 ) {
+							cur += clazz + " ";
+						}
+					}
+					elem.className = jQuery.trim( cur );
+
+				}
+			}
+		}
+
+		return this;
+	},
+
+	removeClass: function( value ) {
+		var classes, elem, cur, clazz, j,
+			i = 0,
+			len = this.length,
+			proceed = arguments.length === 0 || typeof value === "string" && value;
+
+		if ( jQuery.isFunction( value ) ) {
+			return this.each(function( j ) {
+				jQuery( this ).removeClass( value.call( this, j, this.className ) );
+			});
+		}
+		if ( proceed ) {
+			classes = ( value || "" ).match( core_rnotwhite ) || [];
+
+			for ( ; i < len; i++ ) {
+				elem = this[ i ];
+				// This expression is here for better compressibility (see addClass)
+				cur = elem.nodeType === 1 && ( elem.className ?
+					( " " + elem.className + " " ).replace( rclass, " " ) :
+					""
+				);
+
+				if ( cur ) {
+					j = 0;
+					while ( (clazz = classes[j++]) ) {
+						// Remove *all* instances
+						while ( cur.indexOf( " " + clazz + " " ) >= 0 ) {
+							cur = cur.replace( " " + clazz + " ", " " );
+						}
+					}
+					elem.className = value ? jQuery.trim( cur ) : "";
+				}
+			}
+		}
+
+		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.match( core_rnotwhite ) || [];
+
+				while ( (className = classNames[ i++ ]) ) {
+					// check each className given, space separated list
+					state = isBool ? state : !self.hasClass( className );
+					self[ state ? "addClass" : "removeClass" ]( className );
+				}
+
+			// Toggle whole class name
+			} else if ( type === core_strundefined || type === "boolean" ) {
+				if ( this.className ) {
+					// store className if set
+					jQuery._data( this, "__className__", this.className );
+				}
+
+				// If the element has a class name or if we're passed "false",
+				// then remove the whole classname (if there was one, the above saved it).
+				// Otherwise bring back whatever was previously saved (if anything),
+				// falling back to the empty string if nothing was stored.
+				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 ret, hooks, 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;
+			}
+		}
+	},
+
+	attr: function( elem, name, value ) {
+		var hooks, notxml, ret,
+			nType = elem.nodeType;
+
+		// don't get/set attributes on text, comment and attribute nodes
+		if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
+			return;
+		}
+
+		// Fallback to prop when attributes are not supported
+		if ( typeof elem.getAttribute === core_strundefined ) {
+			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 );
+
+			} else if ( hooks && notxml && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
+				return ret;
+
+			} else {
+				elem.setAttribute( name, value + "" );
+				return value;
+			}
+
+		} else if ( hooks && notxml && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
+			return ret;
+
+		} else {
+
+			// In IE9+, Flash objects don't have .getAttribute (#12945)
+			// Support: IE9+
+			if ( typeof elem.getAttribute !== core_strundefined ) {
+				ret =  elem.getAttribute( name );
+			}
+
+			// Non-existent attributes return null, we normalize to undefined
+			return ret == null ?
+				undefined :
+				ret;
+		}
+	},
+
+	removeAttr: function( elem, value ) {
+		var name, propName,
+			i = 0,
+			attrNames = value && value.match( core_rnotwhite );
+
+		if ( attrNames && elem.nodeType === 1 ) {
+			while ( (name = attrNames[i++]) ) {
+				propName = jQuery.propFix[ name ] || name;
+
+				// Boolean attributes get special treatment (#10870)
+				if ( rboolean.test( name ) ) {
+					// Set corresponding property to false for boolean attributes
+					// Also clear defaultChecked/defaultSelected (if appropriate) for IE<8
+					if ( !getSetAttribute && ruseDefault.test( name ) ) {
+						elem[ jQuery.camelCase( "default-" + name ) ] =
+							elem[ propName ] = false;
+					} else {
+						elem[ propName ] = false;
+					}
+
+				// See #9699 for explanation of this approach (setting first, then removal)
+				} else {
+					jQuery.attr( elem, name, "" );
+				}
+
+				elem.removeAttribute( getSetAttribute ? name : propName );
+			}
+		}
+	},
+
+	attrHooks: {
+		type: {
+			set: function( elem, value ) {
+				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 default in case type is set after value during creation
+					var val = elem.value;
+					elem.setAttribute( "type", value );
+					if ( val ) {
+						elem.value = val;
+					}
+					return 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 ) {
+		var
+			// Use .prop to determine if this attribute is understood as boolean
+			prop = jQuery.prop( elem, name ),
+
+			// Fetch it accordingly
+			attr = typeof prop === "boolean" && elem.getAttribute( name ),
+			detail = typeof prop === "boolean" ?
+
+				getSetInput && getSetAttribute ?
+					attr != null :
+					// oldIE fabricates an empty string for missing boolean attributes
+					// and conflates checked/selected into attroperties
+					ruseDefault.test( name ) ?
+						elem[ jQuery.camelCase( "default-" + name ) ] :
+						!!attr :
+
+				// fetch an attribute node for properties not recognized as boolean
+				elem.getAttributeNode( name );
+
+		return detail && detail.value !== false ?
+			name.toLowerCase() :
+			undefined;
+	},
+	set: function( elem, value, name ) {
+		if ( value === false ) {
+			// Remove boolean attributes when set to false
+			jQuery.removeAttr( elem, name );
+		} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
+			// IE<8 needs the *property* name
+			elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
+
+		// Use defaultChecked and defaultSelected for oldIE
+		} else {
+			elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
+		}
+
+		return name;
+	}
+};
+
+// fix oldIE value attroperty
+if ( !getSetInput || !getSetAttribute ) {
+	jQuery.attrHooks.value = {
+		get: function( elem, name ) {
+			var ret = elem.getAttributeNode( name );
+			return jQuery.nodeName( elem, "input" ) ?
+
+				// Ignore the value *property* by using defaultValue
+				elem.defaultValue :
+
+				ret && ret.specified ? ret.value : undefined;
+		},
+		set: function( elem, value, name ) {
+			if ( jQuery.nodeName( elem, "input" ) ) {
+				// Does not return so that setAttribute is also used
+				elem.defaultValue = value;
+			} else {
+				// Use nodeHook if defined (#1954); otherwise setAttribute is fine
+				return nodeHook && nodeHook.set( elem, value, name );
+			}
+		}
+	};
+}
+
+// IE6/7 do not support getting/setting some attributes with get/setAttribute
+if ( !getSetAttribute ) {
+
+	// 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 = elem.getAttributeNode( name );
+			return ret && ( name === "id" || name === "name" || name === "coords" ? 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 ) {
+				elem.setAttributeNode(
+					(ret = elem.ownerDocument.createAttribute( name ))
+				);
+			}
+
+			ret.value = value += "";
+
+			// Break association with cloned elements by also using setAttribute (#9646)
+			return name === "value" || value === elem.getAttribute( name ) ?
+				value :
+				undefined;
+		}
+	};
+
+	// 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 ) {
+			nodeHook.set( elem, value === "" ? false : value, name );
+		}
+	};
+
+	// 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;
+				}
+			}
+		});
+	});
+}
+
+
+// Some attributes require a special call on IE
+// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
+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;
+			}
+		});
+	});
+
+	// href/src property should get the full normalized URL (#10299/#12915)
+	jQuery.each([ "href", "src" ], function( i, name ) {
+		jQuery.propHooks[ name ] = {
+			get: function( elem ) {
+				return elem.getAttribute( name, 4 );
+			}
+		};
+	});
+}
+
+if ( !jQuery.support.style ) {
+	jQuery.attrHooks.style = {
+		get: function( elem ) {
+			// Return undefined in the case of empty string
+			// Note: IE uppercases css property names, but if we were to .toLowerCase()
+			// .cssText, that would destroy case senstitivity in URL's, like in "background"
+			return elem.style.cssText || 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 = /^(?:input|select|textarea)$/i,
+	rkeyEvent = /^key/,
+	rmouseEvent = /^(?:mouse|contextmenu)|click/,
+	rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
+	rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
+
+function returnTrue() {
+	return true;
+}
+
+function returnFalse() {
+	return false;
+}
+
+/*
+ * Helper functions for managing events -- not part of the public interface.
+ * Props to Dean Edwards' addEvent library for many of the ideas.
+ */
+jQuery.event = {
+
+	global: {},
+
+	add: function( elem, types, handler, data, selector ) {
+		var tmp, events, t, handleObjIn,
+			special, eventHandle, handleObj,
+			handlers, type, namespaces, origType,
+			elemData = jQuery._data( elem );
+
+		// Don't attach events to noData or text/comment nodes (but allow plain objects)
+		if ( !elemData ) {
+			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
+		if ( !(events = elemData.events) ) {
+			events = elemData.events = {};
+		}
+		if ( !(eventHandle = elemData.handle) ) {
+			eventHandle = elemData.handle = 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 !== core_strundefined && (!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 = ( types || "" ).match( core_rnotwhite ) || [""];
+		t = types.length;
+		while ( t-- ) {
+			tmp = rtypenamespace.exec( types[t] ) || [];
+			type = origType = tmp[1];
+			namespaces = ( tmp[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: origType,
+				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
+			if ( !(handlers = events[ type ]) ) {
+				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;
+	},
+
+	// Detach an event or set of events from an element
+	remove: function( elem, types, handler, selector, mappedTypes ) {
+		var j, handleObj, tmp,
+			origCount, t, events,
+			special, handlers, type,
+			namespaces, origType,
+			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 = ( types || "" ).match( core_rnotwhite ) || [""];
+		t = types.length;
+		while ( t-- ) {
+			tmp = rtypenamespace.exec( types[t] ) || [];
+			type = origType = tmp[1];
+			namespaces = ( tmp[2] || "" ).split( "." ).sort();
+
+			// 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;
+			handlers = events[ type ] || [];
+			tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
+
+			// Remove matching events
+			origCount = j = handlers.length;
+			while ( j-- ) {
+				handleObj = handlers[ j ];
+
+				if ( ( mappedTypes || origType === handleObj.origType ) &&
+					( !handler || handler.guid === handleObj.guid ) &&
+					( !tmp || tmp.test( handleObj.namespace ) ) &&
+					( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
+					handlers.splice( j, 1 );
+
+					if ( handleObj.selector ) {
+						handlers.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 ( origCount && !handlers.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" );
+		}
+	},
+
+	trigger: function( event, data, elem, onlyHandlers ) {
+		var handle, ontype, cur,
+			bubbleType, special, tmp, i,
+			eventPath = [ elem || document ],
+			type = core_hasOwn.call( event, "type" ) ? event.type : event,
+			namespaces = core_hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
+
+		cur = tmp = elem = elem || document;
+
+		// Don't do events on text and comment nodes
+		if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
+			return;
+		}
+
+		// 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 ) {
+			// Namespaced trigger; create a regexp to match event type in handle()
+			namespaces = type.split(".");
+			type = namespaces.shift();
+			namespaces.sort();
+		}
+		ontype = type.indexOf(":") < 0 && "on" + type;
+
+		// Caller can pass in a jQuery.Event object, Object, or just an event type string
+		event = event[ jQuery.expando ] ?
+			event :
+			new jQuery.Event( type, typeof event === "object" && event );
+
+		event.isTrigger = true;
+		event.namespace = namespaces.join(".");
+		event.namespace_re = event.namespace ?
+			new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
+			null;
+
+		// 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 ?
+			[ event ] :
+			jQuery.makeArray( data, [ event ] );
+
+		// Allow special events to draw outside the lines
+		special = jQuery.event.special[ type ] || {};
+		if ( !onlyHandlers && 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)
+		if ( !onlyHandlers && !special.noBubble && !jQuery.isWindow( elem ) ) {
+
+			bubbleType = special.delegateType || type;
+			if ( !rfocusMorph.test( bubbleType + type ) ) {
+				cur = cur.parentNode;
+			}
+			for ( ; cur; cur = cur.parentNode ) {
+				eventPath.push( cur );
+				tmp = cur;
+			}
+
+			// Only add window if we got to document (e.g., not plain obj or detached DOM)
+			if ( tmp === (elem.ownerDocument || document) ) {
+				eventPath.push( tmp.defaultView || tmp.parentWindow || window );
+			}
+		}
+
+		// Fire handlers on the event path
+		i = 0;
+		while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
+
+			event.type = i > 1 ?
+				bubbleType :
+				special.bindType || type;
+
+			// jQuery handler
+			handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
+			if ( handle ) {
+				handle.apply( cur, data );
+			}
+
+			// Native 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)
+				if ( ontype && elem[ type ] && !jQuery.isWindow( elem ) ) {
+
+					// Don't re-trigger an onFOO event when we call its FOO() method
+					tmp = elem[ ontype ];
+
+					if ( tmp ) {
+						elem[ ontype ] = null;
+					}
+
+					// Prevent re-triggering of the same event, since we already bubbled it above
+					jQuery.event.triggered = type;
+					try {
+						elem[ type ]();
+					} catch ( e ) {
+						// IE<9 dies on focus/blur to hidden element (#1486,#12518)
+						// only reproducible on winXP IE8 native, not IE9 in IE8 mode
+					}
+					jQuery.event.triggered = undefined;
+
+					if ( tmp ) {
+						elem[ ontype ] = tmp;
+					}
+				}
+			}
+		}
+
+		return event.result;
+	},
+
+	dispatch: function( event ) {
+
+		// Make a writable jQuery.Event from the native event object
+		event = jQuery.event.fix( event );
+
+		var i, ret, handleObj, matched, j,
+			handlerQueue = [],
+			args = core_slice.call( arguments ),
+			handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
+			special = jQuery.event.special[ event.type ] || {};
+
+		// 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
+		handlerQueue = jQuery.event.handlers.call( this, event, handlers );
+
+		// Run delegates first; they may want to stop propagation beneath us
+		i = 0;
+		while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
+			event.currentTarget = matched.elem;
+
+			j = 0;
+			while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
+
+				// Triggered event must either 1) have no namespace, or
+				// 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
+				if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
+
+					event.handleObj = handleObj;
+					event.data = handleObj.data;
+
+					ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
+							.apply( matched.elem, args );
+
+					if ( ret !== undefined ) {
+						if ( (event.result = 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;
+	},
+
+	handlers: function( event, handlers ) {
+		var sel, handleObj, matches, i,
+			handlerQueue = [],
+			delegateCount = handlers.delegateCount,
+			cur = event.target;
+
+		// Find delegate handlers
+		// Black-hole SVG <use> instance trees (#13180)
+		// Avoid non-left-click bubbling in Firefox (#3861)
+		if ( delegateCount && cur.nodeType && (!event.button || event.type !== "click") ) {
+
+			for ( ; cur != this; cur = cur.parentNode || this ) {
+
+				// Don't check non-elements (#13208)
+				// Don't process clicks on disabled elements (#6911, #8165, #11382, #11764)
+				if ( cur.nodeType === 1 && (cur.disabled !== true || event.type !== "click") ) {
+					matches = [];
+					for ( i = 0; i < delegateCount; i++ ) {
+						handleObj = handlers[ i ];
+
+						// Don't conflict with Object.prototype properties (#13203)
+						sel = handleObj.selector + " ";
+
+						if ( matches[ sel ] === undefined ) {
+							matches[ sel ] = handleObj.needsContext ?
+								jQuery( sel, this ).index( cur ) >= 0 :
+								jQuery.find( sel, this, null, [ cur ] ).length;
+						}
+						if ( matches[ sel ] ) {
+							matches.push( handleObj );
+						}
+					}
+					if ( matches.length ) {
+						handlerQueue.push({ elem: cur, handlers: matches });
+					}
+				}
+			}
+		}
+
+		// Add the remaining (directly-bound) handlers
+		if ( delegateCount < handlers.length ) {
+			handlerQueue.push({ elem: this, handlers: handlers.slice( delegateCount ) });
+		}
+
+		return handlerQueue;
+	},
+
+	fix: function( event ) {
+		if ( event[ jQuery.expando ] ) {
+			return event;
+		}
+
+		// Create a writable copy of the event object and normalize some properties
+		var i, prop, copy,
+			type = event.type,
+			originalEvent = event,
+			fixHook = this.fixHooks[ type ];
+
+		if ( !fixHook ) {
+			this.fixHooks[ type ] = fixHook =
+				rmouseEvent.test( type ) ? this.mouseHooks :
+				rkeyEvent.test( type ) ? this.keyHooks :
+				{};
+		}
+		copy = fixHook.props ? this.props.concat( fixHook.props ) : this.props;
+
+		event = new jQuery.Event( originalEvent );
+
+		i = copy.length;
+		while ( i-- ) {
+			prop = copy[ i ];
+			event[ prop ] = originalEvent[ prop ];
+		}
+
+		// Support: IE<9
+		// Fix target property (#1925)
+		if ( !event.target ) {
+			event.target = originalEvent.srcElement || document;
+		}
+
+		// Support: Chrome 23+, Safari?
+		// Target should not be a text node (#504, #13143)
+		if ( event.target.nodeType === 3 ) {
+			event.target = event.target.parentNode;
+		}
+
+		// Support: IE<9
+		// For mouse/key events, metaKey==false if it's undefined (#3368, #11328)
+		event.metaKey = !!event.metaKey;
+
+		return fixHook.filter ? fixHook.filter( event, originalEvent ) : event;
+	},
+
+	// Includes some event props shared by KeyEvent and MouseEvent
+	props: "altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),
+
+	fixHooks: {},
+
+	keyHooks: {
+		props: "char charCode key keyCode".split(" "),
+		filter: function( 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 body, eventDoc, doc,
+				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;
+		}
+	},
+
+	special: {
+		load: {
+			// Prevent triggered image.load events from bubbling to window.load
+			noBubble: true
+		},
+		click: {
+			// For checkbox, fire native event so checked state will be right
+			trigger: function() {
+				if ( jQuery.nodeName( this, "input" ) && this.type === "checkbox" && this.click ) {
+					this.click();
+					return false;
+				}
+			}
+		},
+		focus: {
+			// Fire native event if possible so blur/focus sequence is correct
+			trigger: function() {
+				if ( this !== document.activeElement && this.focus ) {
+					try {
+						this.focus();
+						return false;
+					} catch ( e ) {
+						// Support: IE<9
+						// If we error on focus to hidden element (#1486, #12518),
+						// let .trigger() run the handlers
+					}
+				}
+			},
+			delegateType: "focusin"
+		},
+		blur: {
+			trigger: function() {
+				if ( this === document.activeElement && this.blur ) {
+					this.blur();
+					return false;
+				}
+			},
+			delegateType: "focusout"
+		},
+
+		beforeunload: {
+			postDispatch: function( event ) {
+
+				// Even when returnValue equals to undefined Firefox will still show alert
+				if ( event.result !== undefined ) {
+					event.originalEvent.returnValue = event.result;
+				}
+			}
+		}
+	},
+
+	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();
+		}
+	}
+};
+
+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 ] === core_strundefined ) {
+				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;
+};
+
+// 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 = {
+	isDefaultPrevented: returnFalse,
+	isPropagationStopped: returnFalse,
+	isImmediatePropagationStopped: returnFalse,
+
+	preventDefault: function() {
+		var e = this.originalEvent;
+
+		this.isDefaultPrevented = returnTrue;
+		if ( !e ) {
+			return;
+		}
+
+		// If preventDefault exists, run it on the original event
+		if ( e.preventDefault ) {
+			e.preventDefault();
+
+		// Support: IE
+		// Otherwise set the returnValue property of the original event to false
+		} else {
+			e.returnValue = false;
+		}
+	},
+	stopPropagation: function() {
+		var e = this.originalEvent;
+
+		this.isPropagationStopped = returnTrue;
+		if ( !e ) {
+			return;
+		}
+		// If stopPropagation exists, run it on the original event
+		if ( e.stopPropagation ) {
+			e.stopPropagation();
+		}
+
+		// Support: IE
+		// Set the cancelBubble property of the original event to true
+		e.cancelBubble = true;
+	},
+	stopImmediatePropagation: function() {
+		this.isImmediatePropagationStopped = returnTrue;
+		this.stopPropagation();
+	}
+};
+
+// 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;
+
+			// 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, "submitBubbles" ) ) {
+					jQuery.event.add( form, "submit._submit", function( event ) {
+						event._submit_bubble = true;
+					});
+					jQuery._data( form, "submitBubbles", 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, "changeBubbles" ) ) {
+					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, "changeBubbles", 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 type, origFn;
+
+		// Types can be a map of types/handlers
+		if ( typeof types === "object" ) {
+			// ( types-Object, selector, data )
+			if ( typeof selector !== "string" ) {
+				// ( 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 );
+	},
+
+	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 ) {
+		var elem = this[0];
+		if ( elem ) {
+			return jQuery.event.trigger( type, data, elem, true );
+		}
+	}
+});
+/*!
+ * Sizzle CSS Selector Engine
+ * Copyright 2012 jQuery Foundation and other contributors
+ * Released under the MIT license
+ * http://sizzlejs.com/
+ */
+(function( window, undefined ) {
+
+var i,
+	cachedruns,
+	Expr,
+	getText,
+	isXML,
+	compile,
+	hasDuplicate,
+	outermostContext,
+
+	// Local document vars
+	setDocument,
+	document,
+	docElem,
+	documentIsXML,
+	rbuggyQSA,
+	rbuggyMatches,
+	matches,
+	contains,
+	sortOrder,
+
+	// Instance-specific data
+	expando = "sizzle" + -(new Date()),
+	preferredDoc = window.document,
+	support = {},
+	dirruns = 0,
+	done = 0,
+	classCache = createCache(),
+	tokenCache = createCache(),
+	compilerCache = createCache(),
+
+	// General-purpose constants
+	strundefined = typeof undefined,
+	MAX_NEGATIVE = 1 << 31,
+
+	// Array methods
+	arr = [],
+	pop = arr.pop,
+	push = arr.push,
+	slice = arr.slice,
+	// Use a stripped-down indexOf if we can't use a native one
+	indexOf = arr.indexOf || function( elem ) {
+		var i = 0,
+			len = this.length;
+		for ( ; i < len; i++ ) {
+			if ( this[i] === elem ) {
+				return i;
+			}
+		}
+		return -1;
+	},
+
+
+	// Regular expressions
+
+	// 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 quoted,
+	//   then not containing pseudos/brackets,
+	//   then attribute selectors/non-parenthetical expressions,
+	//   then anything else
+	// These preferences are here to reduce the number of selectors
+	//   needing tokenize in the PSEUDO preFilter
+	pseudos = ":(" + characterEncoding + ")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|" + attributes.replace( 3, 8 ) + ")*)|.*)\\)|)",
+
+	// 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 ),
+	ridentifier = new RegExp( "^" + identifier + "$" ),
+
+	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 ),
+		"CHILD": new RegExp( "^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\(" + whitespace +
+			"*(even|odd|(([+-]|)(\\d*)n|)" + whitespace + "*(?:([+-]|)" + whitespace +
+			"*(\\d+)|))" + whitespace + "*\\)|)", "i" ),
+		// For use in libraries implementing .is()
+		// We use this for POS matching in `select`
+		"needsContext": new RegExp( "^" + whitespace + "*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\(" +
+			whitespace + "*((?:-\\d)?\\d*)" + whitespace + "*\\)|)(?=[^-]|$)", "i" )
+	},
+
+	rsibling = /[\x20\t\r\n\f]*[+~]/,
+
+	rnative = /^[^{]+\{\s*\[native code/,
+
+	// Easily-parseable/retrievable ID or TAG or CLASS selectors
+	rquickExpr = /^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,
+
+	rinputs = /^(?:input|select|textarea|button)$/i,
+	rheader = /^h\d$/i,
+
+	rescape = /'|\\/g,
+	rattributeQuotes = /\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,
+
+	// CSS escapes http://www.w3.org/TR/CSS21/syndata.html#escaped-characters
+	runescape = /\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,
+	funescape = function( _, escaped ) {
+		var high = "0x" + escaped - 0x10000;
+		// NaN means non-codepoint
+		return high !== high ?
+			escaped :
+			// BMP codepoint
+			high < 0 ?
+				String.fromCharCode( high + 0x10000 ) :
+				// Supplemental Plane codepoint (surrogate pair)
+				String.fromCharCode( high >> 10 | 0xD800, high & 0x3FF | 0xDC00 );
+	};
+
+// Use a stripped-down slice if we can't use a native one
+try {
+	slice.call( preferredDoc.documentElement.childNodes, 0 )[0].nodeType;
+} catch ( e ) {
+	slice = function( i ) {
+		var elem,
+			results = [];
+		while ( (elem = this[i++]) ) {
+			results.push( elem );
+		}
+		return results;
+	};
+}
+
+/**
+ * For feature detection
+ * @param {Function} fn The function to test for native support
+ */
+function isNative( fn ) {
+	return rnative.test( fn + "" );
+}
+
+/**
+ * Create key-value caches of limited size
+ * @returns {Function(string, Object)} Returns the Object data after storing it on itself with
+ *	property name the (space-suffixed) string and (if the cache is larger than Expr.cacheLength)
+ *	deleting the oldest entry
+ */
+function createCache() {
+	var cache,
+		keys = [];
+
+	return (cache = function( key, value ) {
+		// Use (key + " ") to avoid collision with native prototype properties (see Issue #157)
+		if ( keys.push( key += " " ) > Expr.cacheLength ) {
+			// Only keep the most recent entries
+			delete cache[ keys.shift() ];
+		}
+		return (cache[ key ] = value);
+	});
+}
+
+/**
+ * Mark a function for special use by Sizzle
+ * @param {Function} fn The function to mark
+ */
+function markFunction( fn ) {
+	fn[ expando ] = true;
+	return fn;
+}
+
+/**
+ * Support testing using an element
+ * @param {Function} fn Passed the created div and expects a boolean result
+ */
+function assert( fn ) {
+	var div = document.createElement("div");
+
+	try {
+		return fn( div );
+	} catch (e) {
+		return false;
+	} finally {
+		// release memory in IE
+		div = null;
+	}
+}
+
+function Sizzle( selector, context, results, seed ) {
+	var match, elem, m, nodeType,
+		// QSA vars
+		i, groups, old, nid, newContext, newSelector;
+
+	if ( ( context ? context.ownerDocument || context : preferredDoc ) !== document ) {
+		setDocument( context );
+	}
+
+	context = context || document;
+	results = results || [];
+
+	if ( !selector || typeof selector !== "string" ) {
+		return results;
+	}
+
+	if ( (nodeType = context.nodeType) !== 1 && nodeType !== 9 ) {
+		return [];
+	}
+
+	if ( !documentIsXML && !seed ) {
+
+		// Shortcuts
+		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]) && support.getByClassName && context.getElementsByClassName ) {
+				push.apply( results, slice.call(context.getElementsByClassName( m ), 0) );
+				return results;
+			}
+		}
+
+		// QSA path
+		if ( support.qsa && !rbuggyQSA.test(selector) ) {
+			old = true;
+			nid = expando;
+			newContext = context;
+			newSelector = 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 ( 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 + toSelector( groups[i] );
+				}
+				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");
+					}
+				}
+			}
+		}
+	}
+
+	// All others
+	return select( selector.replace( rtrim, "$1" ), context, results, seed );
+}
+
+/**
+ * Detect xml
+ * @param {Element|Object} elem An element or a document
+ */
+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;
+};
+
+/**
+ * Sets document-related variables once based on the current document
+ * @param {Element|Object} [doc] An element or document object to use to set the document
+ * @returns {Object} Returns the current document
+ */
+setDocument = Sizzle.setDocument = function( node ) {
+	var doc = node ? node.ownerDocument || node : preferredDoc;
+
+	// If no document and documentElement is available, return
+	if ( doc === document || doc.nodeType !== 9 || !doc.documentElement ) {
+		return document;
+	}
+
+	// Set our document
+	document = doc;
+	docElem = doc.documentElement;
+
+	// Support tests
+	documentIsXML = isXML( doc );
+
+	// Check if getElementsByTagName("*") returns only elements
+	support.tagNameNoComments = assert(function( div ) {
+		div.appendChild( doc.createComment("") );
+		return !div.getElementsByTagName("*").length;
+	});
+
+	// Check if attributes should be retrieved by attribute nodes
+	support.attributes = assert(function( div ) {
+		div.innerHTML = "<select></select>";
+		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
+	support.getByClassName = assert(function( div ) {
+		// Opera can't find a second classname (in 9.6)
+		div.innerHTML = "<div class='hidden e'></div><div class='hidden'></div>";
+		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
+	support.getByName = assert(function( div ) {
+		// Inject content
+		div.id = expando + 0;
+		div.innerHTML = "<a name='" + expando + "'></a><div name='" + expando + "'></div>";
+		docElem.insertBefore( div, docElem.firstChild );
+
+		// Test
+		var pass = doc.getElementsByName &&
+			// buggy browsers will return fewer than the correct 2
+			doc.getElementsByName( expando ).length === 2 +
+			// buggy browsers will return more than the correct 0
+			doc.getElementsByName( expando + 0 ).length;
+		support.getIdNotName = !doc.getElementById( expando );
+
+		// Cleanup
+		docElem.removeChild( div );
+
+		return pass;
+	});
+
+	// IE6/7 return modified attributes
+	Expr.attrHandle = assert(function( div ) {
+		div.innerHTML = "<a href='#'></a>";
+		return div.firstChild && typeof div.firstChild.getAttribute !== strundefined &&
+			div.firstChild.getAttribute("href") === "#";
+	}) ?
+		{} :
+		{
+			"href": function( elem ) {
+				return elem.getAttribute( "href", 2 );
+			},
+			"type": function( elem ) {
+				return elem.getAttribute("type");
+			}
+		};
+
+	// ID find and filter
+	if ( support.getIdNotName ) {
+		Expr.find["ID"] = function( id, context ) {
+			if ( typeof context.getElementById !== strundefined && !documentIsXML ) {
+				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] : [];
+			}
+		};
+		Expr.filter["ID"] = function( id ) {
+			var attrId = id.replace( runescape, funescape );
+			return function( elem ) {
+				return elem.getAttribute("id") === attrId;
+			};
+		};
+	} else {
+		Expr.find["ID"] = function( id, context ) {
+			if ( typeof context.getElementById !== strundefined && !documentIsXML ) {
+				var m = context.getElementById( id );
+
+				return m ?
+					m.id === id || typeof m.getAttributeNode !== strundefined && m.getAttributeNode("id").value === id ?
+						[m] :
+						undefined :
+					[];
+			}
+		};
+		Expr.filter["ID"] =  function( id ) {
+			var attrId = id.replace( runescape, funescape );
+			return function( elem ) {
+				var node = typeof elem.getAttributeNode !== strundefined && elem.getAttributeNode("id");
+				return node && node.value === attrId;
+			};
+		};
+	}
+
+	// Tag
+	Expr.find["TAG"] = support.tagNameNoComments ?
+		function( tag, context ) {
+			if ( typeof context.getElementsByTagName !== strundefined ) {
+				return context.getElementsByTagName( tag );
+			}
+		} :
+		function( tag, context ) {
+			var elem,
+				tmp = [],
+				i = 0,
+				results = context.getElementsByTagName( tag );
+
+			// Filter out possible comments
+			if ( tag === "*" ) {
+				while ( (elem = results[i++]) ) {
+					if ( elem.nodeType === 1 ) {
+						tmp.push( elem );
+					}
+				}
+
+				return tmp;
+			}
+			return results;
+		};
+
+	// Name
+	Expr.find["NAME"] = support.getByName && function( tag, context ) {
+		if ( typeof context.getElementsByName !== strundefined ) {
+			return context.getElementsByName( name );
+		}
+	};
+
+	// Class
+	Expr.find["CLASS"] = support.getByClassName && function( className, context ) {
+		if ( typeof context.getElementsByClassName !== strundefined && !documentIsXML ) {
+			return context.getElementsByClassName( className );
+		}
+	};
+
+	// QSA and matchesSelector support
+
+	// matchesSelector(:active) reports false when true (IE9/Opera 11.5)
+	rbuggyMatches = [];
+
+	// 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" ];
+
+	if ( (support.qsa = isNative(doc.querySelectorAll)) ) {
+		// 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 = "<select><option selected=''></option></select>";
+
+			// 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 and will not see later tests
+			if ( !div.querySelectorAll(":checked").length ) {
+				rbuggyQSA.push(":checked");
+			}
+		});
+
+		assert(function( div ) {
+
+			// Opera 10-12/IE8 - ^= $= *= and empty values
+			// Should not select anything
+			div.innerHTML = "<input type='hidden' i=''/>";
+			if ( div.querySelectorAll("[i^='']").length ) {
+				rbuggyQSA.push( "[*^$]=" + whitespace + "*(?:\"\"|'')" );
+			}
+
+			// FF 3.5 - :enabled/:disabled and hidden elements (hidden elements are still enabled)
+			// IE8 throws error here and will not see later tests
+			if ( !div.querySelectorAll(":enabled").length ) {
+				rbuggyQSA.push( ":enabled", ":disabled" );
+			}
+
+			// Opera 10-11 does not throw on post-comma invalid pseudos
+			div.querySelectorAll("*,:x");
+			rbuggyQSA.push(",.*:");
+		});
+	}
+
+	if ( (support.matchesSelector = isNative( (matches = docElem.matchesSelector ||
+		docElem.mozMatchesSelector ||
+		docElem.webkitMatchesSelector ||
+		docElem.oMatchesSelector ||
+		docElem.msMatchesSelector) )) ) {
+
+		assert(function( div ) {
+			// Check to see if it's possible to do matchesSelector
+			// on a disconnected node (IE 9)
+			support.disconnectedMatch = matches.call( div, "div" );
+
+			// This should fail with an exception
+			// Gecko does not error, returns false instead
+			matches.call( div, "[s!='']:x" );
+			rbuggyMatches.push( "!=", pseudos );
+		});
+	}
+
+	rbuggyQSA = new RegExp( rbuggyQSA.join("|") );
+	rbuggyMatches = new RegExp( rbuggyMatches.join("|") );
+
+	// Element contains another
+	// Purposefully does not implement inclusive descendent
+	// As in, an element does not contain itself
+	contains = isNative(docElem.contains) || docElem.compareDocumentPosition ?
+		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 ) :
+					a.compareDocumentPosition && a.compareDocumentPosition( bup ) & 16
+			));
+		} :
+		function( a, b ) {
+			if ( b ) {
+				while ( (b = b.parentNode) ) {
+					if ( b === a ) {
+						return true;
+					}
+				}
+			}
+			return false;
+		};
+
+	// Document order sorting
+	sortOrder = docElem.compareDocumentPosition ?
+	function( a, b ) {
+		var compare;
+
+		if ( a === b ) {
+			hasDuplicate = true;
+			return 0;
+		}
+
+		if ( (compare = b.compareDocumentPosition && a.compareDocumentPosition && a.compareDocumentPosition( b )) ) {
+			if ( compare & 1 || a.parentNode && a.parentNode.nodeType === 11 ) {
+				if ( a === doc || contains( preferredDoc, a ) ) {
+					return -1;
+				}
+				if ( b === doc || contains( preferredDoc, b ) ) {
+					return 1;
+				}
+				return 0;
+			}
+			return compare & 4 ? -1 : 1;
+		}
+
+		return a.compareDocumentPosition ? -1 : 1;
+	} :
+	function( a, b ) {
+		var cur,
+			i = 0,
+			aup = a.parentNode,
+			bup = b.parentNode,
+			ap = [ a ],
+			bp = [ b ];
+
+		// Exit early if the nodes are identical
+		if ( a === b ) {
+			hasDuplicate = true;
+			return 0;
+
+		// Parentless nodes are either documents or disconnected
+		} else if ( !aup || !bup ) {
+			return a === doc ? -1 :
+				b === doc ? 1 :
+				aup ? -1 :
+				bup ? 1 :
+				0;
+
+		// If the nodes are siblings, we can do a quick check
+		} else if ( aup === bup ) {
+			return siblingCheck( a, b );
+		}
+
+		// Otherwise we need full lists of their ancestors for comparison
+		cur = a;
+		while ( (cur = cur.parentNode) ) {
+			ap.unshift( cur );
+		}
+		cur = b;
+		while ( (cur = cur.parentNode) ) {
+			bp.unshift( cur );
+		}
+
+		// Walk down the tree looking for a discrepancy
+		while ( ap[i] === bp[i] ) {
+			i++;
+		}
+
+		return i ?
+			// Do a sibling check if the nodes have a common ancestor
+			siblingCheck( ap[i], bp[i] ) :
+
+			// Otherwise nodes in our document sort first
+			ap[i] === preferredDoc ? -1 :
+			bp[i] === preferredDoc ? 1 :
+			0;
+	};
+
+	// Always assume the presence of duplicates if sort doesn't
+	// pass them to our comparison function (as in Google Chrome).
+	hasDuplicate = false;
+	[0, 0].sort( sortOrder );
+	support.detectDuplicates = hasDuplicate;
+
+	return document;
+};
+
+Sizzle.matches = function( expr, elements ) {
+	return Sizzle( expr, null, null, elements );
+};
+
+Sizzle.matchesSelector = function( elem, expr ) {
+	// Set document vars if needed
+	if ( ( elem.ownerDocument || elem ) !== document ) {
+		setDocument( elem );
+	}
+
+	// Make sure that attribute selectors are quoted
+	expr = expr.replace( rattributeQuotes, "='$1']" );
+
+	// rbuggyQSA always contains :focus, so no need for an existence check
+	if ( support.matchesSelector && !documentIsXML && (!rbuggyMatches || !rbuggyMatches.test(expr)) && !rbuggyQSA.test(expr) ) {
+		try {
+			var ret = matches.call( elem, expr );
+
+			// IE 9's matchesSelector returns false on disconnected nodes
+			if ( ret || support.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, document, null, [elem] ).length > 0;
+};
+
+Sizzle.contains = function( context, elem ) {
+	// Set document vars if needed
+	if ( ( context.ownerDocument || context ) !== document ) {
+		setDocument( context );
+	}
+	return contains( context, elem );
+};
+
+Sizzle.attr = function( elem, name ) {
+	var val;
+
+	// Set document vars if needed
+	if ( ( elem.ownerDocument || elem ) !== document ) {
+		setDocument( elem );
+	}
+
+	if ( !documentIsXML ) {
+		name = name.toLowerCase();
+	}
+	if ( (val = Expr.attrHandle[ name ]) ) {
+		return val( elem );
+	}
+	if ( documentIsXML || support.attributes ) {
+		return elem.getAttribute( name );
+	}
+	return ( (val = elem.getAttributeNode( name )) || elem.getAttribute( name ) ) && elem[ name ] === true ?
+		name :
+		val && val.specified ? val.value : null;
+};
+
+Sizzle.error = function( msg ) {
+	throw new Error( "Syntax error, unrecognized expression: " + msg );
+};
+
+// Document sorting and removing duplicates
+Sizzle.uniqueSort = function( results ) {
+	var elem,
+		duplicates = [],
+		i = 1,
+		j = 0;
+
+	// Unless we *know* we can detect duplicates, assume their presence
+	hasDuplicate = !support.detectDuplicates;
+	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;
+};
+
+function siblingCheck( a, b ) {
+	var cur = b && a,
+		diff = cur && ( ~b.sourceIndex || MAX_NEGATIVE ) - ( ~a.sourceIndex || MAX_NEGATIVE );
+
+	// Use IE sourceIndex if available on both nodes
+	if ( diff ) {
+		return diff;
+	}
+
+	// Check if b follows a
+	if ( cur ) {
+		while ( (cur = cur.nextSibling) ) {
+			if ( cur === b ) {
+				return -1;
+			}
+		}
+	}
+
+	return a ? 1 : -1;
+}
+
+// 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 no nodeType, this is expected to be an array
+		for ( ; (node = elem[i]); i++ ) {
+			// Do not traverse comment nodes
+			ret += getText( node );
+		}
+	} else 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
+
+	return ret;
+};
+
+Expr = Sizzle.selectors = {
+
+	// Can be adjusted by the user
+	cacheLength: 50,
+
+	createPseudo: markFunction,
+
+	match: matchExpr,
+
+	find: {},
+
+	relative: {
+		">": { dir: "parentNode", first: true },
+		" ": { dir: "parentNode" },
+		"+": { dir: "previousSibling", first: true },
+		"~": { dir: "previousSibling" }
+	},
+
+	preFilter: {
+		"ATTR": function( match ) {
+			match[1] = match[1].replace( runescape, funescape );
+
+			// Move the given value to match[3] whether quoted or unquoted
+			match[3] = ( match[4] || match[5] || "" ).replace( runescape, funescape );
+
+			if ( match[2] === "~=" ) {
+				match[3] = " " + match[3] + " ";
+			}
+
+			return match.slice( 0, 4 );
+		},
+
+		"CHILD": function( match ) {
+			/* matches from matchExpr["CHILD"]
+				1 type (only|nth|...)
+				2 what (child|of-type)
+				3 argument (even|odd|\d*|\d*n([+-]\d+)?|...)
+				4 xn-component of xn+y argument ([+-]?\d*n|)
+				5 sign of xn-component
+				6 x of xn-component
+				7 sign of y-component
+				8 y of y-component
+			*/
+			match[1] = match[1].toLowerCase();
+
+			if ( match[1].slice( 0, 3 ) === "nth" ) {
+				// nth-* requires argument
+				if ( !match[3] ) {
+					Sizzle.error( match[0] );
+				}
+
+				// numeric x and y parameters for Expr.filter.CHILD
+				// remember that false/true cast respectively to 0/1
+				match[4] = +( match[4] ? match[5] + (match[6] || 1) : 2 * ( match[3] === "even" || match[3] === "odd" ) );
+				match[5] = +( ( match[7] + match[8] ) || match[3] === "odd" );
+
+			// other types prohibit arguments
+			} else if ( match[3] ) {
+				Sizzle.error( match[0] );
+			}
+
+			return match;
+		},
+
+		"PSEUDO": function( match ) {
+			var excess,
+				unquoted = !match[5] && match[2];
+
+			if ( matchExpr["CHILD"].test( match[0] ) ) {
+				return null;
+			}
+
+			// Accept quoted arguments as-is
+			if ( match[4] ) {
+				match[2] = match[4];
+
+			// Strip excess characters from unquoted arguments
+			} else if ( unquoted && 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
+				match[0] = match[0].slice( 0, excess );
+				match[2] = unquoted.slice( 0, excess );
+			}
+
+			// Return only captures needed by the pseudo filter method (type and argument)
+			return match.slice( 0, 3 );
+		}
+	},
+
+	filter: {
+
+		"TAG": function( nodeName ) {
+			if ( nodeName === "*" ) {
+				return function() { return true; };
+			}
+
+			nodeName = nodeName.replace( runescape, funescape ).toLowerCase();
+			return function( elem ) {
+				return elem.nodeName && elem.nodeName.toLowerCase() === nodeName;
+			};
+		},
+
+		"CLASS": function( className ) {
+			var pattern = classCache[ 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 ) {
+				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.slice( -check.length ) === check :
+					operator === "~=" ? ( " " + result + " " ).indexOf( check ) > -1 :
+					operator === "|=" ? result === check || result.slice( 0, check.length + 1 ) === check + "-" :
+					false;
+			};
+		},
+
+		"CHILD": function( type, what, argument, first, last ) {
+			var simple = type.slice( 0, 3 ) !== "nth",
+				forward = type.slice( -4 ) !== "last",
+				ofType = what === "of-type";
+
+			return first === 1 && last === 0 ?
+
+				// Shortcut for :nth-*(n)
+				function( elem ) {
+					return !!elem.parentNode;
+				} :
+
+				function( elem, context, xml ) {
+					var cache, outerCache, node, diff, nodeIndex, start,
+						dir = simple !== forward ? "nextSibling" : "previousSibling",
+						parent = elem.parentNode,
+						name = ofType && elem.nodeName.toLowerCase(),
+						useCache = !xml && !ofType;
+
+					if ( parent ) {
+
+						// :(first|last|only)-(child|of-type)
+						if ( simple ) {
+							while ( dir ) {
+								node = elem;
+								while ( (node = node[ dir ]) ) {
+									if ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) {
+										return false;
+									}
+								}
+								// Reverse direction for :only-* (if we haven't yet done so)
+								start = dir = type === "only" && !start && "nextSibling";
+							}
+							return true;
+						}
+
+						start = [ forward ? parent.firstChild : parent.lastChild ];
+
+						// non-xml :nth-child(...) stores cache data on `parent`
+						if ( forward && useCache ) {
+							// Seek `elem` from a previously-cached index
+							outerCache = parent[ expando ] || (parent[ expando ] = {});
+							cache = outerCache[ type ] || [];
+							nodeIndex = cache[0] === dirruns && cache[1];
+							diff = cache[0] === dirruns && cache[2];
+							node = nodeIndex && parent.childNodes[ nodeIndex ];
+
+							while ( (node = ++nodeIndex && node && node[ dir ] ||
+
+								// Fallback to seeking `elem` from the start
+								(diff = nodeIndex = 0) || start.pop()) ) {
+
+								// When found, cache indexes on `parent` and break
+								if ( node.nodeType === 1 && ++diff && node === elem ) {
+									outerCache[ type ] = [ dirruns, nodeIndex, diff ];
+									break;
+								}
+							}
+
+						// Use previously-cached element index if available
+						} else if ( useCache && (cache = (elem[ expando ] || (elem[ expando ] = {}))[ type ]) && cache[0] === dirruns ) {
+							diff = cache[1];
+
+						// xml :nth-child(...) or :nth-last-child(...) or :nth(-last)?-of-type(...)
+						} else {
+							// Use the same loop as above to seek `elem` from the start
+							while ( (node = ++nodeIndex && node && node[ dir ] ||
+								(diff = nodeIndex = 0) || start.pop()) ) {
+
+								if ( ( ofType ? node.nodeName.toLowerCase() === name : node.nodeType === 1 ) && ++diff ) {
+									// Cache the index of each encountered element
+									if ( useCache ) {
+										(node[ expando ] || (node[ expando ] = {}))[ type ] = [ dirruns, diff ];
+									}
+
+									if ( node === elem ) {
+										break;
+									}
+								}
+							}
+						}
+
+						// Incorporate the offset, then check against cycle size
+						diff -= last;
+						return diff === first || ( diff % first === 0 && diff / first >= 0 );
+					}
+				};
+		},
+
+		"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: {
+		// Potentially complex 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;
+			};
+		}),
+
+		// "Whether an element is represented by a :lang() selector
+		// is based solely on the element's language value
+		// being equal to the identifier C,
+		// or beginning with the identifier C immediately followed by "-".
+		// The matching of C against the element's language value is performed case-insensitively.
+		// The identifier C does not have to be a valid language name."
+		// http://www.w3.org/TR/selectors/#lang-pseudo
+		"lang": markFunction( function( lang ) {
+			// lang value must be a valid identifider
+			if ( !ridentifier.test(lang || "") ) {
+				Sizzle.error( "unsupported lang: " + lang );
+			}
+			lang = lang.replace( runescape, funescape ).toLowerCase();
+			return function( elem ) {
+				var elemLang;
+				do {
+					if ( (elemLang = documentIsXML ?
+						elem.getAttribute("xml:lang") || elem.getAttribute("lang") :
+						elem.lang) ) {
+
+						elemLang = elemLang.toLowerCase();
+						return elemLang === lang || elemLang.indexOf( lang + "-" ) === 0;
+					}
+				} while ( (elem = elem.parentNode) && elem.nodeType === 1 );
+				return false;
+			};
+		}),
+
+		// Miscellaneous
+		"target": function( elem ) {
+			var hash = window.location && window.location.hash;
+			return hash && hash.slice( 1 ) === elem.id;
+		},
+
+		"root": function( elem ) {
+			return elem === docElem;
+		},
+
+		"focus": function( elem ) {
+			return elem === document.activeElement && (!document.hasFocus || document.hasFocus()) && !!(elem.type || elem.href || ~elem.tabIndex);
+		},
+
+		// Boolean properties
+		"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;
+		},
+
+		// Contents
+		"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 "?")
+			for ( elem = elem.firstChild; elem; elem = elem.nextSibling ) {
+				if ( elem.nodeName > "@" || elem.nodeType === 3 || elem.nodeType === 4 ) {
+					return false;
+				}
+			}
+			return true;
+		},
+
+		"parent": function( elem ) {
+			return !Expr.pseudos["empty"]( elem );
+		},
+
+		// Element/input types
+		"header": function( elem ) {
+			return rheader.test( elem.nodeName );
+		},
+
+		"input": function( elem ) {
+			return rinputs.test( elem.nodeName );
+		},
+
+		"button": function( elem ) {
+			var name = elem.nodeName.toLowerCase();
+			return name === "input" && elem.type === "button" || name === "button";
+		},
+
+		"text": function( elem ) {
+			var 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" &&
+				elem.type === "text" &&
+				( (attr = elem.getAttribute("type")) == null || attr.toLowerCase() === elem.type );
+		},
+
+		// Position-in-collection
+		"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 ) {
+			var i = 0;
+			for ( ; i < length; i += 2 ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		}),
+
+		"odd": createPositionalPseudo(function( matchIndexes, length ) {
+			var i = 1;
+			for ( ; i < length; i += 2 ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		}),
+
+		"lt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+			var i = argument < 0 ? argument + length : argument;
+			for ( ; --i >= 0; ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		}),
+
+		"gt": createPositionalPseudo(function( matchIndexes, length, argument ) {
+			var i = argument < 0 ? argument + length : argument;
+			for ( ; ++i < length; ) {
+				matchIndexes.push( i );
+			}
+			return matchIndexes;
+		})
+	}
+};
+
+// Add button/input type pseudos
+for ( i in { radio: true, checkbox: true, file: true, password: true, image: true } ) {
+	Expr.pseudos[ i ] = createInputPseudo( i );
+}
+for ( i in { submit: true, reset: true } ) {
+	Expr.pseudos[ i ] = createButtonPseudo( i );
+}
+
+function tokenize( selector, parseOnly ) {
+	var matched, match, tokens, type,
+		soFar, groups, preFilters,
+		cached = tokenCache[ 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 )) ) {
+			matched = match.shift();
+			tokens.push( {
+				value: matched,
+				// Cast descendant combinators to space
+				type: match[0].replace( rtrim, " " )
+			} );
+			soFar = soFar.slice( matched.length );
+		}
+
+		// Filters
+		for ( type in Expr.filter ) {
+			if ( (match = matchExpr[ type ].exec( soFar )) && (!preFilters[ type ] ||
+				(match = preFilters[ type ]( match ))) ) {
+				matched = match.shift();
+				tokens.push( {
+					value: matched,
+					type: type,
+					matches: match
+				} );
+				soFar = soFar.slice( matched.length );
+			}
+		}
+
+		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 toSelector( tokens ) {
+	var i = 0,
+		len = tokens.length,
+		selector = "";
+	for ( ; i < len; i++ ) {
+		selector += tokens[i].value;
+	}
+	return selector;
+}
+
+function addCombinator( matcher, combinator, base ) {
+	var dir = combinator.dir,
+		checkNonElements = base && dir === "parentNode",
+		doneName = done++;
+
+	return combinator.first ?
+		// Check against closest ancestor/preceding element
+		function( elem, context, xml ) {
+			while ( (elem = elem[ dir ]) ) {
+				if ( elem.nodeType === 1 || checkNonElements ) {
+					return matcher( elem, context, xml );
+				}
+			}
+		} :
+
+		// Check against all ancestor/preceding elements
+		function( elem, context, xml ) {
+			var data, cache, outerCache,
+				dirkey = dirruns + " " + doneName;
+
+			// We can't set arbitrary data on XML nodes, so they don't benefit from dir caching
+			if ( xml ) {
+				while ( (elem = elem[ dir ]) ) {
+					if ( elem.nodeType === 1 || checkNonElements ) {
+						if ( matcher( elem, context, xml ) ) {
+							return true;
+						}
+					}
+				}
+			} else {
+				while ( (elem = elem[ dir ]) ) {
+					if ( elem.nodeType === 1 || checkNonElements ) {
+						outerCache = elem[ expando ] || (elem[ expando ] = {});
+						if ( (cache = outerCache[ dir ]) && cache[0] === dirkey ) {
+							if ( (data = cache[1]) === true || data === cachedruns ) {
+								return data === true;
+							}
+						} else {
+							cache = outerCache[ dir ] = [ dirkey ];
+							cache[1] = matcher( elem, context, xml ) || cachedruns;
+							if ( cache[1] === true ) {
+								return true;
+							}
+						}
+					}
+				}
+			}
+		};
+}
+
+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 && toSelector( tokens.slice( 0, i - 1 ) ).replace( rtrim, "$1" ),
+					matcher,
+					i < j && matcherFromTokens( tokens.slice( i, j ) ),
+					j < len && matcherFromTokens( (tokens = tokens.slice( j )) ),
+					j < len && toSelector( tokens )
+				);
+			}
+			matchers.push( matcher );
+		}
+	}
+
+	return elementMatcher( matchers );
+}
+
+function matcherFromGroupMatchers( elementMatchers, setMatchers ) {
+	// A counter to specify which element is currently being matched
+	var matcherCachedRuns = 0,
+		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 ),
+				// Use integer dirruns iff this is the outermost matcher
+				dirrunsUnique = (dirruns += contextBackup == null ? 1 : Math.random() || 0.1);
+
+			if ( outermost ) {
+				outermostContext = context !== document && context;
+				cachedruns = matcherCachedRuns;
+			}
+
+			// Add elements passing elementMatchers directly to results
+			// Keep `i` a string if there are no elements so `matchedCount` will be "00" below
+			for ( ; (elem = elems[i]) != null; i++ ) {
+				if ( byElement && elem ) {
+					j = 0;
+					while ( (matcher = elementMatchers[j++]) ) {
+						if ( matcher( elem, context, xml ) ) {
+							results.push( elem );
+							break;
+						}
+					}
+					if ( outermost ) {
+						dirruns = dirrunsUnique;
+						cachedruns = ++matcherCachedRuns;
+					}
+				}
+
+				// 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 ) {
+				j = 0;
+				while ( (matcher = setMatchers[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;
+		};
+
+	return bySet ?
+		markFunction( superMatcher ) :
+		superMatcher;
+}
+
+compile = Sizzle.compile = function( selector, group /* Internal Use Only */ ) {
+	var i,
+		setMatchers = [],
+		elementMatchers = [],
+		cached = compilerCache[ 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 ) {
+	var i, tokens, token, type, find,
+		match = tokenize( selector );
+
+	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 && !documentIsXML &&
+					Expr.relative[ tokens[1].type ] ) {
+
+				context = Expr.find["ID"]( token.matches[0].replace( runescape, funescape ), context )[0];
+				if ( !context ) {
+					return results;
+				}
+
+				selector = selector.slice( tokens.shift().value.length );
+			}
+
+			// Fetch a seed set for right-to-left matching
+			i = matchExpr["needsContext"].test( selector ) ? 0 : tokens.length;
+			while ( 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( runescape, funescape ),
+						rsibling.test( tokens[0].type ) && context.parentNode || context
+					)) ) {
+
+						// If seed is empty or no tokens remain, we can return early
+						tokens.splice( i, 1 );
+						selector = seed.length && toSelector( tokens );
+						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,
+		documentIsXML,
+		results,
+		rsibling.test( selector )
+	);
+	return results;
+}
+
+// Deprecated
+Expr.pseudos["nth"] = Expr.pseudos["eq"];
+
+// Easy API for creating new setFilters
+function setFilters() {}
+Expr.filters = setFilters.prototype = Expr.pseudos;
+Expr.setFilters = new setFilters();
+
+// Initialize with the default document
+setDocument();
+
+// 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, ret, self,
+			len = this.length;
+
+		if ( typeof selector !== "string" ) {
+			self = this;
+			return this.pushStack( jQuery( selector ).filter(function() {
+				for ( i = 0; i < len; i++ ) {
+					if ( jQuery.contains( self[ i ], this ) ) {
+						return true;
+					}
+				}
+			}) );
+		}
+
+		ret = [];
+		for ( i = 0; i < len; i++ ) {
+			jQuery.find( selector, this[ i ], ret );
+		}
+
+		// Needed because $( selector, context ) becomes $( context ).find( selector )
+		ret = this.pushStack( len > 1 ? jQuery.unique( ret ) : ret );
+		ret.selector = ( this.selector ? this.selector + " " : "" ) + selector;
+		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) );
+	},
+
+	filter: function( selector ) {
+		return this.pushStack( winnow(this, selector, true) );
+	},
+
+	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;
+			}
+		}
+
+		return this.pushStack( ret.length > 1 ? jQuery.unique( ret ) : ret );
+	},
+
+	// 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.first().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( jQuery.unique(all) );
+	},
+
+	addBack: function( selector ) {
+		return this.add( selector == null ?
+			this.prevObject : this.prevObject.filter(selector)
+		);
+	}
+});
+
+jQuery.fn.andSelf = jQuery.fn.addBack;
+
+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 );
+	};
+});
+
+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 ) {
+			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 ) {
+		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,
+	rnoshimcache = new RegExp("<(?:" + nodeNames + ")[\\s/>]", "i"),
+	rleadingWhitespace = /^\s+/,
+	rxhtmlTag = /<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,
+	rtagName = /<([\w:]+)/,
+	rtbody = /<tbody/i,
+	rhtml = /<|&#?\w+;/,
+	rnoInnerhtml = /<(?:script|style|link)/i,
+	manipulation_rcheckableType = /^(?:checkbox|radio)$/i,
+	// checked="checked" or checked
+	rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i,
+	rscriptType = /^$|\/(?:java|ecma)script/i,
+	rscriptTypeMasked = /^true\/(.*)/,
+	rcleanScript = /^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,
+
+	// We have to close these tags to support XHTML (#13200)
+	wrapMap = {
+		option: [ 1, "<select multiple='multiple'>", "</select>" ],
+		legend: [ 1, "<fieldset>", "</fieldset>" ],
+		area: [ 1, "<map>", "</map>" ],
+		param: [ 1, "<object>", "</object>" ],
+		thead: [ 1, "<table>", "</table>" ],
+		tr: [ 2, "<table><tbody>", "</tbody></table>" ],
+		col: [ 2, "<table><tbody></tbody><colgroup>", "</colgroup></table>" ],
+		td: [ 3, "<table><tbody><tr>", "</tr></tbody></table>" ],
+
+		// 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.
+		_default: jQuery.support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X<div>", "</div>"  ]
+	},
+	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;
+
+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.nodeType === 9 ) {
+				this.appendChild( elem );
+			}
+		});
+	},
+
+	prepend: function() {
+		return this.domManip(arguments, true, function( elem ) {
+			if ( this.nodeType === 1 || this.nodeType === 11 || this.nodeType === 9 ) {
+				this.insertBefore( elem, this.firstChild );
+			}
+		});
+	},
+
+	before: function() {
+		return this.domManip( arguments, false, function( elem ) {
+			if ( this.parentNode ) {
+				this.parentNode.insertBefore( elem, this );
+			}
+		});
+	},
+
+	after: function() {
+		return this.domManip( arguments, false, function( elem ) {
+			if ( this.parentNode ) {
+				this.parentNode.insertBefore( elem, this.nextSibling );
+			}
+		});
+	},
+
+	// 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 > 0 ) {
+				if ( !keepData && elem.nodeType === 1 ) {
+					jQuery.cleanData( getAll( elem ) );
+				}
+
+				if ( elem.parentNode ) {
+					if ( keepData && jQuery.contains( elem.ownerDocument, elem ) ) {
+						setGlobalEval( getAll( elem, "script" ) );
+					}
+					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( getAll( elem, false ) );
+			}
+
+			// Remove any remaining nodes
+			while ( elem.firstChild ) {
+				elem.removeChild( elem.firstChild );
+			}
+
+			// If this is a select, ensure that it displays empty (#12336)
+			// Support: IE<9
+			if ( elem.options && jQuery.nodeName( elem, "select" ) ) {
+				elem.options.length = 0;
+			}
+		}
+
+		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></$2>" );
+
+				try {
+					for (; i < l; i++ ) {
+						// Remove element nodes and prevent memory leaks
+						elem = this[i] || {};
+						if ( elem.nodeType === 1 ) {
+							jQuery.cleanData( getAll( elem, false ) );
+							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 ) {
+		var isFunc = jQuery.isFunction( value );
+
+		// 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 ( !isFunc && typeof value !== "string" ) {
+			value = jQuery( value ).not( this ).detach();
+		}
+
+		return this.domManip( [ value ], true, function( elem ) {
+			var next = this.nextSibling,
+				parent = this.parentNode;
+
+			if ( parent ) {
+				jQuery( this ).remove();
+				parent.insertBefore( elem, next );
+			}
+		});
+	},
+
+	detach: function( selector ) {
+		return this.remove( selector, true );
+	},
+
+	domManip: function( args, table, callback ) {
+
+		// Flatten any nested arrays
+		args = core_concat.apply( [], args );
+
+		var first, node, hasScripts,
+			scripts, doc, fragment,
+			i = 0,
+			l = this.length,
+			set = this,
+			iNoClone = l - 1,
+			value = args[0],
+			isFunction = jQuery.isFunction( value );
+
+		// We can't cloneNode fragments that contain checked, in WebKit
+		if ( isFunction || !( l <= 1 || typeof value !== "string" || jQuery.support.checkClone || !rchecked.test( value ) ) ) {
+			return this.each(function( index ) {
+				var self = set.eq( index );
+				if ( isFunction ) {
+					args[0] = value.call( this, index, table ? self.html() : undefined );
+				}
+				self.domManip( args, table, callback );
+			});
+		}
+
+		if ( l ) {
+			fragment = jQuery.buildFragment( args, this[ 0 ].ownerDocument, false, this );
+			first = fragment.firstChild;
+
+			if ( fragment.childNodes.length === 1 ) {
+				fragment = first;
+			}
+
+			if ( first ) {
+				table = table && jQuery.nodeName( first, "tr" );
+				scripts = jQuery.map( getAll( fragment, "script" ), disableScript );
+				hasScripts = scripts.length;
+
+				// Use the original fragment for the last item instead of the first because it can end up
+				// being emptied incorrectly in certain situations (#8070).
+				for ( ; i < l; i++ ) {
+					node = fragment;
+
+					if ( i !== iNoClone ) {
+						node = jQuery.clone( node, true, true );
+
+						// Keep references to cloned scripts for later restoration
+						if ( hasScripts ) {
+							jQuery.merge( scripts, getAll( node, "script" ) );
+						}
+					}
+
+					callback.call(
+						table && jQuery.nodeName( this[i], "table" ) ?
+							findOrAppend( this[i], "tbody" ) :
+							this[i],
+						node,
+						i
+					);
+				}
+
+				if ( hasScripts ) {
+					doc = scripts[ scripts.length - 1 ].ownerDocument;
+
+					// Reenable scripts
+					jQuery.map( scripts, restoreScript );
+
+					// Evaluate executable scripts on first document insertion
+					for ( i = 0; i < hasScripts; i++ ) {
+						node = scripts[ i ];
+						if ( rscriptType.test( node.type || "" ) &&
+							!jQuery._data( node, "globalEval" ) && jQuery.contains( doc, node ) ) {
+
+							if ( node.src ) {
+								// Hope ajax is available...
+								jQuery.ajax({
+									url: node.src,
+									type: "GET",
+									dataType: "script",
+									async: false,
+									global: false,
+									"throws": true
+								});
+							} else {
+								jQuery.globalEval( ( node.text || node.textContent || node.innerHTML || "" ).replace( rcleanScript, "" ) );
+							}
+						}
+					}
+				}
+
+				// Fix #11809: Avoid leaking memory
+				fragment = first = null;
+			}
+		}
+
+		return this;
+	}
+});
+
+function findOrAppend( elem, tag ) {
+	return elem.getElementsByTagName( tag )[0] || elem.appendChild( elem.ownerDocument.createElement( tag ) );
+}
+
+// Replace/restore the type attribute of script elements for safe DOM manipulation
+function disableScript( elem ) {
+	var attr = elem.getAttributeNode("type");
+	elem.type = ( attr && attr.specified ) + "/" + elem.type;
+	return elem;
+}
+function restoreScript( elem ) {
+	var match = rscriptTypeMasked.exec( elem.type );
+	if ( match ) {
+		elem.type = match[1];
+	} else {
+		elem.removeAttribute("type");
+	}
+	return elem;
+}
+
+// Mark scripts as having already been evaluated
+function setGlobalEval( elems, refElements ) {
+	var elem,
+		i = 0;
+	for ( ; (elem = elems[i]) != null; i++ ) {
+		jQuery._data( elem, "globalEval", !refElements || jQuery._data( refElements[i], "globalEval" ) );
+	}
+}
+
+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 fixCloneNodeIssues( src, dest ) {
+	var nodeName, e, data;
+
+	// We do not need to do anything for non-Elements
+	if ( dest.nodeType !== 1 ) {
+		return;
+	}
+
+	nodeName = dest.nodeName.toLowerCase();
+
+	// IE6-8 copies events bound via attachEvent when using cloneNode.
+	if ( !jQuery.support.noCloneEvent && dest[ jQuery.expando ] ) {
+		data = jQuery._data( dest );
+
+		for ( e in data.events ) {
+			jQuery.removeEvent( dest, e, data.handle );
+		}
+
+		// Event data gets referenced instead of copied if the expando gets copied too
+		dest.removeAttribute( jQuery.expando );
+	}
+
+	// IE blanks contents when cloning scripts, and tries to evaluate newly-set text
+	if ( nodeName === "script" && dest.text !== src.text ) {
+		disableScript( dest ).text = src.text;
+		restoreScript( dest );
+
+	// IE6-10 improperly clones children of object elements using classid.
+	// IE10 throws NoModificationAllowedError if parent is null, #12132.
+	} else if ( nodeName === "object" ) {
+		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" && manipulation_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.defaultSelected = 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;
+	}
+}
+
+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 ),
+			last = insert.length - 1;
+
+		for ( ; i <= last; i++ ) {
+			elems = i === last ? this : this.clone(true);
+			jQuery( insert[i] )[ original ]( elems );
+
+			// Modern browsers can apply jQuery collections as arrays, but oldIE needs a .get()
+			core_push.apply( ret, elems.get() );
+		}
+
+		return this.pushStack( ret );
+	};
+});
+
+function getAll( context, tag ) {
+	var elems, elem,
+		i = 0,
+		found = typeof context.getElementsByTagName !== core_strundefined ? context.getElementsByTagName( tag || "*" ) :
+			typeof context.querySelectorAll !== core_strundefined ? context.querySelectorAll( tag || "*" ) :
+			undefined;
+
+	if ( !found ) {
+		for ( found = [], elems = context.childNodes || context; (elem = elems[i]) != null; i++ ) {
+			if ( !tag || jQuery.nodeName( elem, tag ) ) {
+				found.push( elem );
+			} else {
+				jQuery.merge( found, getAll( elem, tag ) );
+			}
+		}
+	}
+
+	return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
+		jQuery.merge( [ context ], found ) :
+		found;
+}
+
+// Used in buildFragment, fixes the defaultChecked property
+function fixDefaultChecked( elem ) {
+	if ( manipulation_rcheckableType.test( elem.type ) ) {
+		elem.defaultChecked = elem.checked;
+	}
+}
+
+jQuery.extend({
+	clone: function( elem, dataAndEvents, deepDataAndEvents ) {
+		var destElements, node, clone, i, srcElements,
+			inPage = jQuery.contains( elem.ownerDocument, elem );
+
+		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) ) {
+
+			// We eschew Sizzle here for performance reasons: http://jsperf.com/getall-vs-sizzle/2
+			destElements = getAll( clone );
+			srcElements = getAll( elem );
+
+			// Fix all IE cloning issues
+			for ( i = 0; (node = srcElements[i]) != null; ++i ) {
+				// Ensure that the destination node is not null; Fixes #9587
+				if ( destElements[i] ) {
+					fixCloneNodeIssues( node, destElements[i] );
+				}
+			}
+		}
+
+		// Copy the events from the original to the clone
+		if ( dataAndEvents ) {
+			if ( deepDataAndEvents ) {
+				srcElements = srcElements || getAll( elem );
+				destElements = destElements || getAll( clone );
+
+				for ( i = 0; (node = srcElements[i]) != null; i++ ) {
+					cloneCopyEvent( node, destElements[i] );
+				}
+			} else {
+				cloneCopyEvent( elem, clone );
+			}
+		}
+
+		// Preserve script evaluation history
+		destElements = getAll( clone, "script" );
+		if ( destElements.length > 0 ) {
+			setGlobalEval( destElements, !inPage && getAll( elem, "script" ) );
+		}
+
+		destElements = srcElements = node = null;
+
+		// Return the cloned set
+		return clone;
+	},
+
+	buildFragment: function( elems, context, scripts, selection ) {
+		var j, elem, contains,
+			tmp, tag, tbody, wrap,
+			l = elems.length,
+
+			// Ensure a safe fragment
+			safe = createSafeFragment( context ),
+
+			nodes = [],
+			i = 0;
+
+		for ( ; i < l; i++ ) {
+			elem = elems[ i ];
+
+			if ( elem || elem === 0 ) {
+
+				// Add nodes directly
+				if ( jQuery.type( elem ) === "object" ) {
+					jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
+
+				// Convert non-html into a text node
+				} else if ( !rhtml.test( elem ) ) {
+					nodes.push( context.createTextNode( elem ) );
+
+				// Convert html into DOM nodes
+				} else {
+					tmp = tmp || safe.appendChild( context.createElement("div") );
+
+					// Deserialize a standard representation
+					tag = ( rtagName.exec( elem ) || ["", ""] )[1].toLowerCase();
+					wrap = wrapMap[ tag ] || wrapMap._default;
+
+					tmp.innerHTML = wrap[1] + elem.replace( rxhtmlTag, "<$1></$2>" ) + wrap[2];
+
+					// Descend through wrappers to the right content
+					j = wrap[0];
+					while ( j-- ) {
+						tmp = tmp.lastChild;
+					}
+
+					// Manually add leading whitespace removed by IE
+					if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+						nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[0] ) );
+					}
+
+					// Remove IE's autoinserted <tbody> from table fragments
+					if ( !jQuery.support.tbody ) {
+
+						// String was a <table>, *may* have spurious <tbody>
+						elem = tag === "table" && !rtbody.test( elem ) ?
+							tmp.firstChild :
+
+							// String was a bare <thead> or <tfoot>
+							wrap[1] === "<table>" && !rtbody.test( elem ) ?
+								tmp :
+								0;
+
+						j = elem && elem.childNodes.length;
+						while ( j-- ) {
+							if ( jQuery.nodeName( (tbody = elem.childNodes[j]), "tbody" ) && !tbody.childNodes.length ) {
+								elem.removeChild( tbody );
+							}
+						}
+					}
+
+					jQuery.merge( nodes, tmp.childNodes );
+
+					// Fix #12392 for WebKit and IE > 9
+					tmp.textContent = "";
+
+					// Fix #12392 for oldIE
+					while ( tmp.firstChild ) {
+						tmp.removeChild( tmp.firstChild );
+					}
+
+					// Remember the top-level container for proper cleanup
+					tmp = safe.lastChild;
+				}
+			}
+		}
+
+		// Fix #11356: Clear elements from fragment
+		if ( tmp ) {
+			safe.removeChild( tmp );
+		}
+
+		// Reset defaultChecked for any radios and checkboxes
+		// about to be appended to the DOM in IE 6/7 (#8060)
+		if ( !jQuery.support.appendChecked ) {
+			jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
+		}
+
+		i = 0;
+		while ( (elem = nodes[ i++ ]) ) {
+
+			// #4087 - If origin and destination elements are the same, and this is
+			// that element, do not do anything
+			if ( selection && jQuery.inArray( elem, selection ) !== -1 ) {
+				continue;
+			}
+
+			contains = jQuery.contains( elem.ownerDocument, elem );
+
+			// Append to fragment
+			tmp = getAll( safe.appendChild( elem ), "script" );
+
+			// Preserve script evaluation history
+			if ( contains ) {
+				setGlobalEval( tmp );
+			}
+
+			// Capture executables
+			if ( scripts ) {
+				j = 0;
+				while ( (elem = tmp[ j++ ]) ) {
+					if ( rscriptType.test( elem.type || "" ) ) {
+						scripts.push( elem );
+					}
+				}
+			}
+		}
+
+		tmp = null;
+
+		return safe;
+	},
+
+	cleanData: function( elems, /* internal */ acceptData ) {
+		var elem, type, id, data,
+			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 ( typeof elem.removeAttribute !== core_strundefined ) {
+							elem.removeAttribute( internalKey );
+
+						} else {
+							elem[ internalKey ] = null;
+						}
+
+						core_deletedIds.push( id );
+					}
+				}
+			}
+		}
+	}
+});
+var iframe, getStyles, curCSS,
+	ralpha = /alpha\([^)]*\)/i,
+	ropacity = /opacity\s*=\s*([^)]*)/,
+	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" ];
+
+// 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 ) {
+	// isHidden might be called from jQuery#filter function;
+	// in that case, element will be second argument
+	elem = el || elem;
+	return jQuery.css( elem, "display" ) === "none" || !jQuery.contains( elem.ownerDocument, elem );
+}
+
+function showHide( elements, show ) {
+	var display, elem, hidden,
+		values = [],
+		index = 0,
+		length = elements.length;
+
+	for ( ; index < length; index++ ) {
+		elem = elements[ index ];
+		if ( !elem.style ) {
+			continue;
+		}
+
+		values[ index ] = jQuery._data( elem, "olddisplay" );
+		display = elem.style.display;
+		if ( show ) {
+			// Reset the inline display of this element to learn if it is
+			// being hidden by cascaded rules or not
+			if ( !values[ index ] && 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 {
+
+			if ( !values[ index ] ) {
+				hidden = isHidden( elem );
+
+				if ( display && display !== "none" || !hidden ) {
+					jQuery._data( elem, "olddisplay", hidden ? display : jQuery.css( elem, "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 ) {
+			var len, styles,
+				map = {},
+				i = 0;
+
+			if ( jQuery.isArray( name ) ) {
+				styles = getStyles( elem );
+				len = name.length;
+
+				for ( ; i < len; i++ ) {
+					map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
+				}
+
+				return map;
+			}
+
+			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 ) {
+		var bool = typeof state === "boolean";
+
+		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: {
+		"columnCount": true,
+		"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";
+			}
+
+			// Fixes #8908, it can be done more correctly by specifing setters in cssHooks,
+			// but it would mean to define eight (for every problematic property) identical functions
+			if ( !jQuery.support.clearCloneStyle && value === "" && name.indexOf("background") === 0 ) {
+				style[ name ] = "inherit";
+			}
+
+			// 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, extra, styles ) {
+		var num, val, 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, styles );
+		}
+
+		//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 ( extra === "" || extra ) {
+			num = parseFloat( val );
+			return extra === true || 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, args ) {
+		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.apply( elem, args || [] );
+
+		// Revert the old values
+		for ( name in options ) {
+			elem.style[ name ] = old[ name ];
+		}
+
+		return ret;
+	}
+});
+
+// NOTE: we've included the "window" in window.getComputedStyle
+// because jsdom on node.js will break without it.
+if ( window.getComputedStyle ) {
+	getStyles = function( elem ) {
+		return window.getComputedStyle( elem, null );
+	};
+
+	curCSS = function( elem, name, _computed ) {
+		var width, minWidth, maxWidth,
+			computed = _computed || getStyles( elem ),
+
+			// getPropertyValue is only needed for .css('filter') in IE9, see #12537
+			ret = computed ? computed.getPropertyValue( name ) || computed[ name ] : undefined,
+			style = elem.style;
+
+		if ( computed ) {
+
+			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 ) ) {
+
+				// Remember the original values
+				width = style.width;
+				minWidth = style.minWidth;
+				maxWidth = style.maxWidth;
+
+				// Put in the new values to get a computed value out
+				style.minWidth = style.maxWidth = style.width = ret;
+				ret = computed.width;
+
+				// Revert the changed values
+				style.width = width;
+				style.minWidth = minWidth;
+				style.maxWidth = maxWidth;
+			}
+		}
+
+		return ret;
+	};
+} else if ( document.documentElement.currentStyle ) {
+	getStyles = function( elem ) {
+		return elem.currentStyle;
+	};
+
+	curCSS = function( elem, name, _computed ) {
+		var left, rs, rsLeft,
+			computed = _computed || getStyles( elem ),
+			ret = computed ? computed[ name ] : undefined,
+			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;
+			rs = elem.runtimeStyle;
+			rsLeft = rs && rs.left;
+
+			// Put in the new values to get a computed value out
+			if ( rsLeft ) {
+				rs.left = elem.currentStyle.left;
+			}
+			style.left = name === "fontSize" ? "1em" : ret;
+			ret = style.pixelLeft + "px";
+
+			// Revert the changed values
+			style.left = left;
+			if ( rsLeft ) {
+				rs.left = rsLeft;
+			}
+		}
+
+		return ret === "" ? "auto" : ret;
+	};
+}
+
+function setPositiveNumber( elem, value, subtract ) {
+	var matches = rnumsplit.exec( value );
+	return matches ?
+		// Guard against undefined "subtract", e.g., when used as in cssHooks
+		Math.max( 0, matches[ 1 ] - ( subtract || 0 ) ) + ( matches[ 2 ] || "px" ) :
+		value;
+}
+
+function augmentWidthOrHeight( elem, name, extra, isBorderBox, styles ) {
+	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" ) {
+			val += jQuery.css( elem, extra + cssExpand[ i ], true, styles );
+		}
+
+		if ( isBorderBox ) {
+			// border-box includes padding, so remove it if we want content
+			if ( extra === "content" ) {
+				val -= jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+			}
+
+			// at this point, extra isn't border nor margin, so remove border
+			if ( extra !== "margin" ) {
+				val -= jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+			}
+		} else {
+			// at this point, extra isn't content, so add padding
+			val += jQuery.css( elem, "padding" + cssExpand[ i ], true, styles );
+
+			// at this point, extra isn't content nor padding, so add border
+			if ( extra !== "padding" ) {
+				val += jQuery.css( elem, "border" + cssExpand[ i ] + "Width", true, styles );
+			}
+		}
+	}
+
+	return val;
+}
+
+function getWidthOrHeight( elem, name, extra ) {
+
+	// Start with offset property, which is equivalent to the border-box value
+	var valueIsBorderBox = true,
+		val = name === "width" ? elem.offsetWidth : elem.offsetHeight,
+		styles = getStyles( elem ),
+		isBorderBox = jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "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, styles );
+		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,
+			styles
+		)
+	) + "px";
+}
+
+// Try to determine the default display value of an element
+function css_defaultDisplay( nodeName ) {
+	var doc = document,
+		display = elemdisplay[ nodeName ];
+
+	if ( !display ) {
+		display = actualDisplay( nodeName, doc );
+
+		// If the simple way fails, read from inside an iframe
+		if ( display === "none" || !display ) {
+			// Use the already-created iframe if possible
+			iframe = ( iframe ||
+				jQuery("<iframe frameborder='0' width='0' height='0'/>")
+				.css( "cssText", "display:block !important" )
+			).appendTo( doc.documentElement );
+
+			// Always write a new HTML skeleton so Webkit and Firefox don't choke on reuse
+			doc = ( iframe[0].contentWindow || iframe[0].contentDocument ).document;
+			doc.write("<!doctype html><html><body>");
+			doc.close();
+
+			display = actualDisplay( nodeName, doc );
+			iframe.detach();
+		}
+
+		// Store the correct default display
+		elemdisplay[ nodeName ] = display;
+	}
+
+	return display;
+}
+
+// Called ONLY from within css_defaultDisplay
+function actualDisplay( name, doc ) {
+	var elem = jQuery( doc.createElement( name ) ).appendTo( doc.body ),
+		display = jQuery.css( elem[0], "display" );
+	elem.remove();
+	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
+				return elem.offsetWidth === 0 && rdisplayswap.test( jQuery.css( elem, "display" ) ) ?
+					jQuery.swap( elem, cssShow, function() {
+						return getWidthOrHeight( elem, name, extra );
+					}) :
+					getWidthOrHeight( elem, name, extra );
+			}
+		},
+
+		set: function( elem, value, extra ) {
+			var styles = extra && getStyles( elem );
+			return setPositiveNumber( elem, value, extra ?
+				augmentWidthOrHeight(
+					elem,
+					name,
+					extra,
+					jQuery.support.boxSizing && jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
+					styles
+				) : 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 === "", then remove inline opacity #12685
+			if ( ( value >= 1 || value === "" ) &&
+					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 is no filter style applied in a css rule or unset inline opacity, we are done
+				if ( value === "" || 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 ) {
+				if ( 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" },
+						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 ) {
+						computed = curCSS( elem, prop );
+						// if curCSS returns percentage, fallback to offset
+						return rnumnonpx.test( computed ) ?
+							jQuery( elem ).position()[ prop ] + "px" :
+							computed;
+					}
+				}
+			};
+		});
+	}
+
+});
+
+if ( jQuery.expr && jQuery.expr.filters ) {
+	jQuery.expr.filters.hidden = function( elem ) {
+		// Support: Opera <= 12.12
+		// Opera reports offsetWidths and offsetHeights less than zero on some elements
+		return elem.offsetWidth <= 0 && elem.offsetHeight <= 0 ||
+			(!jQuery.support.reliableHiddenOffsets && ((elem.style && elem.style.display) || jQuery.css( 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 = 0,
+				expanded = {},
+
+				// assumes a single number if not a string
+				parts = typeof value === "string" ? value.split(" ") : [ value ];
+
+			for ( ; 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,
+	rsubmitterTypes = /^(?:submit|button|image|reset|file)$/i,
+	rsubmittable = /^(?:input|select|textarea|keygen)/i;
+
+jQuery.fn.extend({
+	serialize: function() {
+		return jQuery.param( this.serializeArray() );
+	},
+	serializeArray: function() {
+		return this.map(function(){
+			// Can add propHook for "elements" to filter or add form elements
+			var elements = jQuery.prop( this, "elements" );
+			return elements ? jQuery.makeArray( elements ) : this;
+		})
+		.filter(function(){
+			var type = this.type;
+			// Use .is(":disabled") so that fieldset[disabled] works
+			return this.name && !jQuery( this ).is( ":disabled" ) &&
+				rsubmittable.test( this.nodeName ) && !rsubmitterTypes.test( type ) &&
+				( this.checked || !manipulation_rcheckableType.test( type ) );
+		})
+		.map(function( i, elem ){
+			var val = jQuery( this ).val();
+
+			return val == null ?
+				null :
+				jQuery.isArray( val ) ?
+					jQuery.map( val, function( val ){
+						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 {
+				// Item is non-scalar (array or object), encode its numeric index.
+				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 );
+	}
+}
+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 ) {
+		return arguments.length > 0 ?
+			this.on( name, null, data, fn ) :
+			this.trigger( name );
+	};
+});
+
+jQuery.fn.hover = function( fnOver, fnOut ) {
+	return this.mouseenter( fnOver ).mouseleave( fnOut || fnOver );
+};
+var
+	// Document location
+	ajaxLocParts,
+	ajaxLocation,
+	ajax_nonce = jQuery.now(),
+
+	ajax_rquery = /\?/,
+	rhash = /#.*$/,
+	rts = /([?&])_=[^&]*/,
+	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 = /^\/\//,
+	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 = "*/".concat("*");
+
+// #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,
+			i = 0,
+			dataTypes = dataTypeExpression.toLowerCase().match( core_rnotwhite ) || [];
+
+		if ( jQuery.isFunction( func ) ) {
+			// For each dataType in the dataTypeExpression
+			while ( (dataType = dataTypes[i++]) ) {
+				// Prepend if requested
+				if ( dataType[0] === "+" ) {
+					dataType = dataType.slice( 1 ) || "*";
+					(structure[ dataType ] = structure[ dataType ] || []).unshift( func );
+
+				// Otherwise append
+				} else {
+					(structure[ dataType ] = structure[ dataType ] || []).push( func );
+				}
+			}
+		}
+	};
+}
+
+// Base inspection function for prefilters and transports
+function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR ) {
+
+	var inspected = {},
+		seekingTransport = ( structure === transports );
+
+	function inspect( dataType ) {
+		var selected;
+		inspected[ dataType ] = true;
+		jQuery.each( structure[ dataType ] || [], function( _, prefilterOrFactory ) {
+			var dataTypeOrTransport = prefilterOrFactory( options, originalOptions, jqXHR );
+			if( typeof dataTypeOrTransport === "string" && !seekingTransport && !inspected[ dataTypeOrTransport ] ) {
+				options.dataTypes.unshift( dataTypeOrTransport );
+				inspect( dataTypeOrTransport );
+				return false;
+			} else if ( seekingTransport ) {
+				return !( selected = dataTypeOrTransport );
+			}
+		});
+		return selected;
+	}
+
+	return inspect( options.dataTypes[ 0 ] ) || !inspected[ "*" ] && inspect( "*" );
+}
+
+// A special extend for ajax options
+// that takes "flat" options (not to be deep extended)
+// Fixes #9887
+function ajaxExtend( target, src ) {
+	var deep, key,
+		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 );
+	}
+
+	return target;
+}
+
+jQuery.fn.load = function( url, params, callback ) {
+	if ( typeof url !== "string" && _load ) {
+		return _load.apply( this, arguments );
+	}
+
+	var selector, response, type,
+		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";
+	}
+
+	// If we have elements to modify, make the request
+	if ( self.length > 0 ) {
+		jQuery.ajax({
+			url: url,
+
+			// if "type" variable is undefined, then "GET" method will be used
+			type: type,
+			dataType: "html",
+			data: params
+		}).done(function( responseText ) {
+
+			// Save response for use in complete callback
+			response = arguments;
+
+			self.html( selector ?
+
+				// If a selector was specified, locate the right elements in a dummy div
+				// Exclude scripts to avoid IE 'Permission Denied' errors
+				jQuery("<div>").append( jQuery.parseHTML( responseText ) ).find( selector ) :
+
+				// Otherwise use the full result
+				responseText );
+
+		}).complete( callback && function( jqXHR, status ) {
+			self.each( callback, response || [ jqXHR.responseText, status, jqXHR ] );
+		});
+	}
+
+	return this;
+};
+
+// Attach a bunch of functions for handling common AJAX events
+jQuery.each( [ "ajaxStart", "ajaxStop", "ajaxComplete", "ajaxError", "ajaxSuccess", "ajaxSend" ], function( i, type ){
+	jQuery.fn[ type ] = function( fn ){
+		return this.on( type, fn );
+	};
+});
+
+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({
+			url: url,
+			type: method,
+			dataType: type,
+			data: data,
+			success: callback
+		});
+	};
+});
+
+jQuery.extend({
+
+	// Counter for holding the number of active queries
+	active: 0,
+
+	// Last-Modified header cache for next request
+	lastModified: {},
+	etag: {},
+
+	ajaxSettings: {
+		url: ajaxLocation,
+		type: "GET",
+		isLocal: rlocalProtocol.test( ajaxLocParts[ 1 ] ),
+		global: true,
+		processData: true,
+		async: true,
+		contentType: "application/x-www-form-urlencoded; charset=UTF-8",
+		/*
+		timeout: 0,
+		data: null,
+		dataType: null,
+		username: null,
+		password: null,
+		cache: null,
+		throws: false,
+		traditional: false,
+		headers: {},
+		*/
+
+		accepts: {
+			"*": allTypes,
+			text: "text/plain",
+			html: "text/html",
+			xml: "application/xml, text/xml",
+			json: "application/json, text/javascript"
+		},
+
+		contents: {
+			xml: /xml/,
+			html: /html/,
+			json: /json/
+		},
+
+		responseFields: {
+			xml: "responseXML",
+			text: "responseText"
+		},
+
+		// Data converters
+		// Keys separate source (or catchall "*") and destination types with a single space
+		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: {
+			url: true,
+			context: true
+		}
+	},
+
+	// 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 ) {
+		return settings ?
+
+			// Building a settings object
+			ajaxExtend( ajaxExtend( target, jQuery.ajaxSettings ), settings ) :
+
+			// Extending ajaxSettings
+			ajaxExtend( jQuery.ajaxSettings, target );
+	},
+
+	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 // Cross-domain detection vars
+			parts,
+			// Loop variable
+			i,
+			// URL without anti-cache param
+			cacheURL,
+			// Response headers as string
+			responseHeadersString,
+			// timeout handle
+			timeoutTimer,
+
+			// To know if global events are to be dispatched
+			fireGlobals,
+
+			transport,
+			// Response headers
+			responseHeaders,
+			// Create the final options object
+			s = jQuery.ajaxSetup( {}, options ),
+			// Callbacks context
+			callbackContext = s.context || s,
+			// Context for global events is callbackContext if it is a DOM node or jQuery collection
+			globalEventContext = s.context && ( callbackContext.nodeType || callbackContext.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,
+
+				// 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 == null ? null : match;
+				},
+
+				// Raw string
+				getAllResponseHeaders: function() {
+					return state === 2 ? responseHeadersString : null;
+				},
+
+				// Caches the header
+				setRequestHeader: function( name, value ) {
+					var lname = name.toLowerCase();
+					if ( !state ) {
+						name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name;
+						requestHeaders[ name ] = value;
+					}
+					return this;
+				},
+
+				// Overrides response content-type header
+				overrideMimeType: function( type ) {
+					if ( !state ) {
+						s.mimeType = type;
+					}
+					return this;
+				},
+
+				// Status-dependent callbacks
+				statusCode: function( map ) {
+					var code;
+					if ( map ) {
+						if ( state < 2 ) {
+							for ( code in map ) {
+								// Lazy-add the new callback in a way that preserves old ones
+								statusCode[ code ] = [ statusCode[ code ], map[ code ] ];
+							}
+						} else {
+							// Execute the appropriate callbacks
+							jqXHR.always( map[ jqXHR.status ] );
+						}
+					}
+					return this;
+				},
+
+				// Cancel the request
+				abort: function( statusText ) {
+					var finalText = statusText || strAbort;
+					if ( transport ) {
+						transport.abort( finalText );
+					}
+					done( 0, finalText );
+					return this;
+				}
+			};
+
+		// Attach deferreds
+		deferred.promise( jqXHR ).complete = completeDeferred.add;
+		jqXHR.success = jqXHR.done;
+		jqXHR.error = jqXHR.fail;
+
+		// Remove hash character (#7531: and string promotion)
+		// Add protocol if not provided (#5866: IE7 issue with protocol-less urls)
+		// Handle falsy url in the settings object (#10093: consistency with old signature)
+		// We also use the url parameter if available
+		s.url = ( ( url || s.url || ajaxLocation ) + "" ).replace( rhash, "" ).replace( rprotocol, ajaxLocParts[ 1 ] + "//" );
+
+		// Alias method option to type as per ticket #12004
+		s.type = options.method || options.type || s.method || s.type;
+
+		// Extract dataTypes list
+		s.dataTypes = jQuery.trim( s.dataType || "*" ).toLowerCase().match( core_rnotwhite ) || [""];
+
+		// 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;
+
+		// Watch for a new set of requests
+		if ( fireGlobals && jQuery.active++ === 0 ) {
+			jQuery.event.trigger("ajaxStart");
+		}
+
+		// Uppercase the type
+		s.type = s.type.toUpperCase();
+
+		// Determine if request has content
+		s.hasContent = !rnoContent.test( s.type );
+
+		// Save the URL in case we're toying with the If-Modified-Since
+		// and/or If-None-Match header later on
+		cacheURL = s.url;
+
+		// More options handling for requests with no content
+		if ( !s.hasContent ) {
+
+			// If data is available, append data to url
+			if ( s.data ) {
+				cacheURL = ( s.url += ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + s.data );
+				// #9682: remove data so that it's not used in an eventual retry
+				delete s.data;
+			}
+
+			// Add anti-cache in url if needed
+			if ( s.cache === false ) {
+				s.url = rts.test( cacheURL ) ?
+
+					// If there is already a '_' parameter, set its value
+					cacheURL.replace( rts, "$1_=" + ajax_nonce++ ) :
+
+					// Otherwise add one to the end
+					cacheURL + ( ajax_rquery.test( cacheURL ) ? "&" : "?" ) + "_=" + ajax_nonce++;
+			}
+		}
+
+		// Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode.
+		if ( s.ifModified ) {
+			if ( jQuery.lastModified[ cacheURL ] ) {
+				jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ cacheURL ] );
+			}
+			if ( jQuery.etag[ cacheURL ] ) {
+				jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ cacheURL ] );
+			}
+		}
+
+		// 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 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;
+				}
+			}
+		}
+
+		// Callback for when everything is done
+		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[ cacheURL ] = modified;
+					}
+					modified = jqXHR.getResponseHeader("etag");
+					if ( modified ) {
+						jQuery.etag[ cacheURL ] = modified;
+					}
+				}
+
+				// if no content
+				if ( status === 204 ) {
+					isSuccess = true;
+					statusText = "nocontent";
+
+				// if not modified
+				} else if ( status === 304 ) {
+					isSuccess = true;
+					statusText = "notmodified";
+
+				// If we have data, let's convert it
+				} 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 ( status || !statusText ) {
+					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( isSuccess ? "ajaxSuccess" : "ajaxError",
+					[ 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");
+				}
+			}
+		}
+
+		return jqXHR;
+	},
+
+	getScript: function( url, callback ) {
+		return jQuery.get( url, undefined, callback, "script" );
+	},
+
+	getJSON: function( url, data, callback ) {
+		return jQuery.get( url, data, callback, "json" );
+	}
+});
+
+/* 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 firstDataType, ct, finalDataType, type,
+		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 conv2, current, conv, tmp,
+		converters = {},
+		i = 0,
+		// Work with a copy of dataTypes in case we need to modify it for conversion
+		dataTypes = s.dataTypes.slice(),
+		prev = dataTypes[ 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 };
+}
+// Install script dataType
+jQuery.ajaxSetup({
+	accepts: {
+		script: "text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"
+	},
+	contents: {
+		script: /(?:java|ecma)script/
+	},
+	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 || jQuery("head")[0] || document.documentElement;
+
+		return {
+
+			send: function( _, callback ) {
+
+				script = document.createElement("script");
+
+				script.async = true;
+
+				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 ( script.parentNode ) {
+							script.parentNode.removeChild( script );
+						}
+
+						// Dereference the script
+						script = null;
+
+						// Callback if not abort
+						if ( !isAbort ) {
+							callback( 200, "success" );
+						}
+					}
+				};
+
+				// Circumvent IE6 bugs with base elements (#2709 and #4378) by prepending
+				// Use native DOM manipulation to avoid our domManip AJAX trickery
+				head.insertBefore( script, head.firstChild );
+			},
+
+			abort: function() {
+				if ( script ) {
+					script.onload( undefined, true );
+				}
+			}
+		};
+	}
+});
+var oldCallbacks = [],
+	rjsonp = /(=)\?(?=&|$)|\?\?/;
+
+// Default jsonp settings
+jQuery.ajaxSetup({
+	jsonp: "callback",
+	jsonpCallback: function() {
+		var callback = oldCallbacks.pop() || ( jQuery.expando + "_" + ( ajax_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,
+		jsonProp = s.jsonp !== false && ( rjsonp.test( s.url ) ?
+			"url" :
+			typeof s.data === "string" && !( s.contentType || "" ).indexOf("application/x-www-form-urlencoded") && rjsonp.test( s.data ) && "data"
+		);
+
+	// Handle iff the expected data type is "jsonp" or we have a parameter to set
+	if ( jsonProp || s.dataTypes[ 0 ] === "jsonp" ) {
+
+		// Get callback name, remembering preexisting value associated with it
+		callbackName = s.jsonpCallback = jQuery.isFunction( s.jsonpCallback ) ?
+			s.jsonpCallback() :
+			s.jsonpCallback;
+
+		// Insert callback into url or form data
+		if ( jsonProp ) {
+			s[ jsonProp ] = s[ jsonProp ].replace( rjsonp, "$1" + callbackName );
+		} else if ( s.jsonp !== false ) {
+			s.url += ( ajax_rquery.test( s.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
+		overwritten = window[ callbackName ];
+		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";
+	}
+});
+var xhrCallbacks, xhrSupported,
+	xhrId = 0,
+	// #5280: Internet Explorer will keep connections alive if we don't abort on unload
+	xhrOnUnloadAbort = window.ActiveXObject && function() {
+		// Abort all pending requests
+		var key;
+		for ( key in xhrCallbacks ) {
+			xhrCallbacks[ key ]( undefined, true );
+		}
+	};
+
+// 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
+xhrSupported = jQuery.ajaxSettings.xhr();
+jQuery.support.cors = !!xhrSupported && ( "withCredentials" in xhrSupported );
+xhrSupported = jQuery.support.ajax = !!xhrSupported;
+
+// Create transport if the browser can provide an xhr
+if ( xhrSupported ) {
+
+	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( err ) {}
+
+					// 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, responseHeaders, statusText, responses;
+
+						// 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 {
+									responses = {};
+									status = xhr.status;
+									responseHeaders = xhr.getAllResponseHeaders();
+
+									// When requesting binary data, IE6-9 will throw an exception
+									// on any attempt to access responseText (#11426)
+									if ( typeof xhr.responseText === "string" ) {
+										responses.text = xhr.responseText;
+									}
+
+									// 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 );
+					} 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( undefined, true );
+					}
+				}
+			};
+		}
+	});
+}
+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;
+	});
+	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,
+		stopped,
+		index = 0,
+		length = animationPrefilters.length,
+		deferred = jQuery.Deferred().always( function() {
+			// don't match elem in the :animated selector
+			delete tick.elem;
+		}),
+		tick = function() {
+			if ( stopped ) {
+				return false;
+			}
+			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 ) {
+				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;
+				if ( stopped ) {
+					return this;
+				}
+				stopped = true;
+				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, {
+			elem: elem,
+			anim: animation,
+			queue: animation.opts.queue
+		})
+	);
+
+	// 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 value, name, index, easing, 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 ) {
+	/*jshint validthis:true */
+	var prop, index, length,
+		value, 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.always(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" );
+			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 an empty string as a 3rd 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, "" );
+			// 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" ?
+			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 );
+				doAnimation.finish = function() {
+					anim.stop( true );
+				};
+				// Empty animations, or finishing resolves immediately
+				if ( empty || jQuery._data( this, "finish" ) ) {
+					anim.stop( true );
+				}
+			};
+			doAnimation.finish = doAnimation;
+
+		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 );
+			}
+		});
+	},
+	finish: function( type ) {
+		if ( type !== false ) {
+			type = type || "fx";
+		}
+		return this.each(function() {
+			var index,
+				data = jQuery._data( this ),
+				queue = data[ type + "queue" ],
+				hooks = data[ type + "queueHooks" ],
+				timers = jQuery.timers,
+				length = queue ? queue.length : 0;
+
+			// enable finishing flag on private data
+			data.finish = true;
+
+			// empty the queue first
+			jQuery.queue( this, type, [] );
+
+			if ( hooks && hooks.cur && hooks.cur.finish ) {
+				hooks.cur.finish.call( this );
+			}
+
+			// look for any active animations, and finish them
+			for ( index = timers.length; index--; ) {
+				if ( timers[ index ].elem === this && timers[ index ].queue === type ) {
+					timers[ index ].anim.stop( true );
+					timers.splice( index, 1 );
+				}
+			}
+
+			// look for any animations in the old queue and finish them
+			for ( index = 0; index < length; index++ ) {
+				if ( queue[ index ] && queue[ index ].finish ) {
+					queue[ index ].finish.call( this );
+				}
+			}
+
+			// turn off finishing flag
+			delete data.finish;
+		});
+	}
+});
+
+// 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 ) ) {
+		jQuery.fx.start();
+	}
+};
+
+jQuery.fx.interval = 13;
+
+jQuery.fx.start = function() {
+	if ( !timerId ) {
+		timerId = setInterval( jQuery.fx.tick, jQuery.fx.interval );
+	}
+};
+
+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;
+	};
+}
+jQuery.fn.offset = function( options ) {
+	if ( arguments.length ) {
+		return options === undefined ?
+			this :
+			this.each(function( i ) {
+				jQuery.offset.setOffset( this, options, i );
+			});
+	}
+
+	var docElem, win,
+		box = { top: 0, left: 0 },
+		elem = this[ 0 ],
+		doc = elem && elem.ownerDocument;
+
+	if ( !doc ) {
+		return;
+	}
+
+	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 !== core_strundefined ) {
+		box = elem.getBoundingClientRect();
+	}
+	win = getWindow( doc );
+	return {
+		top: box.top  + ( win.pageYOffset || docElem.scrollTop )  - ( docElem.clientTop  || 0 ),
+		left: box.left + ( win.pageXOffset || docElem.scrollLeft ) - ( docElem.clientLeft || 0 )
+	};
+};
+
+jQuery.offset = {
+
+	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 offsetParent, offset,
+			parentOffset = { top: 0, left: 0 },
+			elem = this[ 0 ];
+
+		// fixed elements are offset from window (parentOffset = {top:0, left: 0}, because it is it's only offset parent
+		if ( jQuery.css( elem, "position" ) === "fixed" ) {
+			// we assume that getBoundingClientRect is available when computed position is fixed
+			offset = elem.getBoundingClientRect();
+		} else {
+			// Get *real* offsetParent
+			offsetParent = this.offsetParent();
+
+			// Get correct offsets
+			offset = this.offset();
+			if ( !jQuery.nodeName( offsetParent[ 0 ], "html" ) ) {
+				parentOffset = offsetParent.offset();
+			}
+
+			// Add offsetParent borders
+			parentOffset.top  += jQuery.css( offsetParent[ 0 ], "borderTopWidth", true );
+			parentOffset.left += jQuery.css( offsetParent[ 0 ], "borderLeftWidth", true );
+		}
+
+		// Subtract parent offsets and 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
+		return {
+			top:  offset.top  - parentOffset.top - jQuery.css( elem, "marginTop", true ),
+			left: offset.left - parentOffset.left - jQuery.css( elem, "marginLeft", true)
+		};
+	},
+
+	offsetParent: function() {
+		return this.map(function() {
+			var offsetParent = this.offsetParent || document.documentElement;
+			while ( offsetParent && ( !jQuery.nodeName( offsetParent, "html" ) && jQuery.css( offsetParent, "position") === "static" ) ) {
+				offsetParent = offsetParent.offsetParent;
+			}
+			return offsetParent || document.documentElement;
+		});
+	}
+});
+
+
+// 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, extra ) :
+
+					// Set width or height on the element
+					jQuery.style( elem, type, value, extra );
+			}, type, chainable ? margin : undefined, chainable, null );
+		};
+	});
+});
+// Limit scope pollution from any deprecated API
+// (function() {
+
+// })();
+// 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/cli/sdncon/ui/static/js/thirdparty/jquery-1.9.1.min.js b/cli/sdncon/ui/static/js/thirdparty/jquery-1.9.1.min.js
new file mode 100755
index 0000000..006e953
--- /dev/null
+++ b/cli/sdncon/ui/static/js/thirdparty/jquery-1.9.1.min.js
@@ -0,0 +1,5 @@
+/*! jQuery v1.9.1 | (c) 2005, 2012 jQuery Foundation, Inc. | jquery.org/license
+//@ sourceMappingURL=jquery.min.map
+*/(function(e,t){var n,r,i=typeof t,o=e.document,a=e.location,s=e.jQuery,u=e.$,l={},c=[],p="1.9.1",f=c.concat,d=c.push,h=c.slice,g=c.indexOf,m=l.toString,y=l.hasOwnProperty,v=p.trim,b=function(e,t){return new b.fn.init(e,t,r)},x=/[+-]?(?:\d*\.|)\d+(?:[eE][+-]?\d+|)/.source,w=/\S+/g,T=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,N=/^(?:(<[\w\W]+>)[^>]*|#([\w-]*))$/,C=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,k=/^[\],:{}\s]*$/,E=/(?:^|:|,)(?:\s*\[)+/g,S=/\\(?:["\\\/bfnrt]|u[\da-fA-F]{4})/g,A=/"[^"\\\r\n]*"|true|false|null|-?(?:\d+\.|)\d+(?:[eE][+-]?\d+|)/g,j=/^-ms-/,D=/-([\da-z])/gi,L=function(e,t){return t.toUpperCase()},H=function(e){(o.addEventListener||"load"===e.type||"complete"===o.readyState)&&(q(),b.ready())},q=function(){o.addEventListener?(o.removeEventListener("DOMContentLoaded",H,!1),e.removeEventListener("load",H,!1)):(o.detachEvent("onreadystatechange",H),e.detachEvent("onload",H))};b.fn=b.prototype={jquery:p,constructor:b,init:function(e,n,r){var i,a;if(!e)return this;if("string"==typeof e){if(i="<"===e.charAt(0)&&">"===e.charAt(e.length-1)&&e.length>=3?[null,e,null]:N.exec(e),!i||!i[1]&&n)return!n||n.jquery?(n||r).find(e):this.constructor(n).find(e);if(i[1]){if(n=n instanceof b?n[0]:n,b.merge(this,b.parseHTML(i[1],n&&n.nodeType?n.ownerDocument||n:o,!0)),C.test(i[1])&&b.isPlainObject(n))for(i in n)b.isFunction(this[i])?this[i](n[i]):this.attr(i,n[i]);return this}if(a=o.getElementById(i[2]),a&&a.parentNode){if(a.id!==i[2])return r.find(e);this.length=1,this[0]=a}return this.context=o,this.selector=e,this}return e.nodeType?(this.context=this[0]=e,this.length=1,this):b.isFunction(e)?r.ready(e):(e.selector!==t&&(this.selector=e.selector,this.context=e.context),b.makeArray(e,this))},selector:"",length:0,size:function(){return this.length},toArray:function(){return h.call(this)},get:function(e){return null==e?this.toArray():0>e?this[this.length+e]:this[e]},pushStack:function(e){var t=b.merge(this.constructor(),e);return t.prevObject=this,t.context=this.context,t},each:function(e,t){return b.each(this,e,t)},ready:function(e){return b.ready.promise().done(e),this},slice:function(){return this.pushStack(h.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(e){var t=this.length,n=+e+(0>e?t:0);return this.pushStack(n>=0&&t>n?[this[n]]:[])},map:function(e){return this.pushStack(b.map(this,function(t,n){return e.call(t,n,t)}))},end:function(){return this.prevObject||this.constructor(null)},push:d,sort:[].sort,splice:[].splice},b.fn.init.prototype=b.fn,b.extend=b.fn.extend=function(){var e,n,r,i,o,a,s=arguments[0]||{},u=1,l=arguments.length,c=!1;for("boolean"==typeof s&&(c=s,s=arguments[1]||{},u=2),"object"==typeof s||b.isFunction(s)||(s={}),l===u&&(s=this,--u);l>u;u++)if(null!=(o=arguments[u]))for(i in o)e=s[i],r=o[i],s!==r&&(c&&r&&(b.isPlainObject(r)||(n=b.isArray(r)))?(n?(n=!1,a=e&&b.isArray(e)?e:[]):a=e&&b.isPlainObject(e)?e:{},s[i]=b.extend(c,a,r)):r!==t&&(s[i]=r));return s},b.extend({noConflict:function(t){return e.$===b&&(e.$=u),t&&e.jQuery===b&&(e.jQuery=s),b},isReady:!1,readyWait:1,holdReady:function(e){e?b.readyWait++:b.ready(!0)},ready:function(e){if(e===!0?!--b.readyWait:!b.isReady){if(!o.body)return setTimeout(b.ready);b.isReady=!0,e!==!0&&--b.readyWait>0||(n.resolveWith(o,[b]),b.fn.trigger&&b(o).trigger("ready").off("ready"))}},isFunction:function(e){return"function"===b.type(e)},isArray:Array.isArray||function(e){return"array"===b.type(e)},isWindow:function(e){return null!=e&&e==e.window},isNumeric:function(e){return!isNaN(parseFloat(e))&&isFinite(e)},type:function(e){return null==e?e+"":"object"==typeof e||"function"==typeof e?l[m.call(e)]||"object":typeof e},isPlainObject:function(e){if(!e||"object"!==b.type(e)||e.nodeType||b.isWindow(e))return!1;try{if(e.constructor&&!y.call(e,"constructor")&&!y.call(e.constructor.prototype,"isPrototypeOf"))return!1}catch(n){return!1}var r;for(r in e);return r===t||y.call(e,r)},isEmptyObject:function(e){var t;for(t in e)return!1;return!0},error:function(e){throw Error(e)},parseHTML:function(e,t,n){if(!e||"string"!=typeof e)return null;"boolean"==typeof t&&(n=t,t=!1),t=t||o;var r=C.exec(e),i=!n&&[];return r?[t.createElement(r[1])]:(r=b.buildFragment([e],t,i),i&&b(i).remove(),b.merge([],r.childNodes))},parseJSON:function(n){return e.JSON&&e.JSON.parse?e.JSON.parse(n):null===n?n:"string"==typeof n&&(n=b.trim(n),n&&k.test(n.replace(S,"@").replace(A,"]").replace(E,"")))?Function("return "+n)():(b.error("Invalid JSON: "+n),t)},parseXML:function(n){var r,i;if(!n||"string"!=typeof n)return null;try{e.DOMParser?(i=new DOMParser,r=i.parseFromString(n,"text/xml")):(r=new ActiveXObject("Microsoft.XMLDOM"),r.async="false",r.loadXML(n))}catch(o){r=t}return r&&r.documentElement&&!r.getElementsByTagName("parsererror").length||b.error("Invalid XML: "+n),r},noop:function(){},globalEval:function(t){t&&b.trim(t)&&(e.execScript||function(t){e.eval.call(e,t)})(t)},camelCase:function(e){return e.replace(j,"ms-").replace(D,L)},nodeName:function(e,t){return e.nodeName&&e.nodeName.toLowerCase()===t.toLowerCase()},each:function(e,t,n){var r,i=0,o=e.length,a=M(e);if(n){if(a){for(;o>i;i++)if(r=t.apply(e[i],n),r===!1)break}else for(i in e)if(r=t.apply(e[i],n),r===!1)break}else if(a){for(;o>i;i++)if(r=t.call(e[i],i,e[i]),r===!1)break}else for(i in e)if(r=t.call(e[i],i,e[i]),r===!1)break;return e},trim:v&&!v.call("\ufeff\u00a0")?function(e){return null==e?"":v.call(e)}:function(e){return null==e?"":(e+"").replace(T,"")},makeArray:function(e,t){var n=t||[];return null!=e&&(M(Object(e))?b.merge(n,"string"==typeof e?[e]:e):d.call(n,e)),n},inArray:function(e,t,n){var r;if(t){if(g)return g.call(t,e,n);for(r=t.length,n=n?0>n?Math.max(0,r+n):n:0;r>n;n++)if(n in t&&t[n]===e)return n}return-1},merge:function(e,n){var r=n.length,i=e.length,o=0;if("number"==typeof r)for(;r>o;o++)e[i++]=n[o];else while(n[o]!==t)e[i++]=n[o++];return e.length=i,e},grep:function(e,t,n){var r,i=[],o=0,a=e.length;for(n=!!n;a>o;o++)r=!!t(e[o],o),n!==r&&i.push(e[o]);return i},map:function(e,t,n){var r,i=0,o=e.length,a=M(e),s=[];if(a)for(;o>i;i++)r=t(e[i],i,n),null!=r&&(s[s.length]=r);else for(i in e)r=t(e[i],i,n),null!=r&&(s[s.length]=r);return f.apply([],s)},guid:1,proxy:function(e,n){var r,i,o;return"string"==typeof n&&(o=e[n],n=e,e=o),b.isFunction(e)?(r=h.call(arguments,2),i=function(){return e.apply(n||this,r.concat(h.call(arguments)))},i.guid=e.guid=e.guid||b.guid++,i):t},access:function(e,n,r,i,o,a,s){var u=0,l=e.length,c=null==r;if("object"===b.type(r)){o=!0;for(u in r)b.access(e,n,u,r[u],!0,a,s)}else if(i!==t&&(o=!0,b.isFunction(i)||(s=!0),c&&(s?(n.call(e,i),n=null):(c=n,n=function(e,t,n){return c.call(b(e),n)})),n))for(;l>u;u++)n(e[u],r,s?i:i.call(e[u],u,n(e[u],r)));return o?e:c?n.call(e):l?n(e[0],r):a},now:function(){return(new Date).getTime()}}),b.ready.promise=function(t){if(!n)if(n=b.Deferred(),"complete"===o.readyState)setTimeout(b.ready);else if(o.addEventListener)o.addEventListener("DOMContentLoaded",H,!1),e.addEventListener("load",H,!1);else{o.attachEvent("onreadystatechange",H),e.attachEvent("onload",H);var r=!1;try{r=null==e.frameElement&&o.documentElement}catch(i){}r&&r.doScroll&&function a(){if(!b.isReady){try{r.doScroll("left")}catch(e){return setTimeout(a,50)}q(),b.ready()}}()}return n.promise(t)},b.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(e,t){l["[object "+t+"]"]=t.toLowerCase()});function M(e){var t=e.length,n=b.type(e);return b.isWindow(e)?!1:1===e.nodeType&&t?!0:"array"===n||"function"!==n&&(0===t||"number"==typeof t&&t>0&&t-1 in e)}r=b(o);var _={};function F(e){var t=_[e]={};return b.each(e.match(w)||[],function(e,n){t[n]=!0}),t}b.Callbacks=function(e){e="string"==typeof e?_[e]||F(e):b.extend({},e);var n,r,i,o,a,s,u=[],l=!e.once&&[],c=function(t){for(r=e.memory&&t,i=!0,a=s||0,s=0,o=u.length,n=!0;u&&o>a;a++)if(u[a].apply(t[0],t[1])===!1&&e.stopOnFalse){r=!1;break}n=!1,u&&(l?l.length&&c(l.shift()):r?u=[]:p.disable())},p={add:function(){if(u){var t=u.length;(function i(t){b.each(t,function(t,n){var r=b.type(n);"function"===r?e.unique&&p.has(n)||u.push(n):n&&n.length&&"string"!==r&&i(n)})})(arguments),n?o=u.length:r&&(s=t,c(r))}return this},remove:function(){return u&&b.each(arguments,function(e,t){var r;while((r=b.inArray(t,u,r))>-1)u.splice(r,1),n&&(o>=r&&o--,a>=r&&a--)}),this},has:function(e){return e?b.inArray(e,u)>-1:!(!u||!u.length)},empty:function(){return u=[],this},disable:function(){return u=l=r=t,this},disabled:function(){return!u},lock:function(){return l=t,r||p.disable(),this},locked:function(){return!l},fireWith:function(e,t){return t=t||[],t=[e,t.slice?t.slice():t],!u||i&&!l||(n?l.push(t):c(t)),this},fire:function(){return p.fireWith(this,arguments),this},fired:function(){return!!i}};return p},b.extend({Deferred:function(e){var t=[["resolve","done",b.Callbacks("once memory"),"resolved"],["reject","fail",b.Callbacks("once memory"),"rejected"],["notify","progress",b.Callbacks("memory")]],n="pending",r={state:function(){return n},always:function(){return i.done(arguments).fail(arguments),this},then:function(){var e=arguments;return b.Deferred(function(n){b.each(t,function(t,o){var a=o[0],s=b.isFunction(e[t])&&e[t];i[o[1]](function(){var e=s&&s.apply(this,arguments);e&&b.isFunction(e.promise)?e.promise().done(n.resolve).fail(n.reject).progress(n.notify):n[a+"With"](this===r?n.promise():this,s?[e]:arguments)})}),e=null}).promise()},promise:function(e){return null!=e?b.extend(e,r):r}},i={};return r.pipe=r.then,b.each(t,function(e,o){var a=o[2],s=o[3];r[o[1]]=a.add,s&&a.add(function(){n=s},t[1^e][2].disable,t[2][2].lock),i[o[0]]=function(){return i[o[0]+"With"](this===i?r:this,arguments),this},i[o[0]+"With"]=a.fireWith}),r.promise(i),e&&e.call(i,i),i},when:function(e){var t=0,n=h.call(arguments),r=n.length,i=1!==r||e&&b.isFunction(e.promise)?r:0,o=1===i?e:b.Deferred(),a=function(e,t,n){return function(r){t[e]=this,n[e]=arguments.length>1?h.call(arguments):r,n===s?o.notifyWith(t,n):--i||o.resolveWith(t,n)}},s,u,l;if(r>1)for(s=Array(r),u=Array(r),l=Array(r);r>t;t++)n[t]&&b.isFunction(n[t].promise)?n[t].promise().done(a(t,l,n)).fail(o.reject).progress(a(t,u,s)):--i;return i||o.resolveWith(l,n),o.promise()}}),b.support=function(){var t,n,r,a,s,u,l,c,p,f,d=o.createElement("div");if(d.setAttribute("className","t"),d.innerHTML="  <link/><table></table><a href='/a'>a</a><input type='checkbox'/>",n=d.getElementsByTagName("*"),r=d.getElementsByTagName("a")[0],!n||!r||!n.length)return{};s=o.createElement("select"),l=s.appendChild(o.createElement("option")),a=d.getElementsByTagName("input")[0],r.style.cssText="top:1px;float:left;opacity:.5",t={getSetAttribute:"t"!==d.className,leadingWhitespace:3===d.firstChild.nodeType,tbody:!d.getElementsByTagName("tbody").length,htmlSerialize:!!d.getElementsByTagName("link").length,style:/top/.test(r.getAttribute("style")),hrefNormalized:"/a"===r.getAttribute("href"),opacity:/^0.5/.test(r.style.opacity),cssFloat:!!r.style.cssFloat,checkOn:!!a.value,optSelected:l.selected,enctype:!!o.createElement("form").enctype,html5Clone:"<:nav></:nav>"!==o.createElement("nav").cloneNode(!0).outerHTML,boxModel:"CSS1Compat"===o.compatMode,deleteExpando:!0,noCloneEvent:!0,inlineBlockNeedsLayout:!1,shrinkWrapBlocks:!1,reliableMarginRight:!0,boxSizingReliable:!0,pixelPosition:!1},a.checked=!0,t.noCloneChecked=a.cloneNode(!0).checked,s.disabled=!0,t.optDisabled=!l.disabled;try{delete d.test}catch(h){t.deleteExpando=!1}a=o.createElement("input"),a.setAttribute("value",""),t.input=""===a.getAttribute("value"),a.value="t",a.setAttribute("type","radio"),t.radioValue="t"===a.value,a.setAttribute("checked","t"),a.setAttribute("name","t"),u=o.createDocumentFragment(),u.appendChild(a),t.appendChecked=a.checked,t.checkClone=u.cloneNode(!0).cloneNode(!0).lastChild.checked,d.attachEvent&&(d.attachEvent("onclick",function(){t.noCloneEvent=!1}),d.cloneNode(!0).click());for(f in{submit:!0,change:!0,focusin:!0})d.setAttribute(c="on"+f,"t"),t[f+"Bubbles"]=c in e||d.attributes[c].expando===!1;return d.style.backgroundClip="content-box",d.cloneNode(!0).style.backgroundClip="",t.clearCloneStyle="content-box"===d.style.backgroundClip,b(function(){var n,r,a,s="padding:0;margin:0;border:0;display:block;box-sizing:content-box;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;",u=o.getElementsByTagName("body")[0];u&&(n=o.createElement("div"),n.style.cssText="border:0;width:0;height:0;position:absolute;top:0;left:-9999px;margin-top:1px",u.appendChild(n).appendChild(d),d.innerHTML="<table><tr><td></td><td>t</td></tr></table>",a=d.getElementsByTagName("td"),a[0].style.cssText="padding:0;margin:0;border:0;display:none",p=0===a[0].offsetHeight,a[0].style.display="",a[1].style.display="none",t.reliableHiddenOffsets=p&&0===a[0].offsetHeight,d.innerHTML="",d.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%;",t.boxSizing=4===d.offsetWidth,t.doesNotIncludeMarginInBodyOffset=1!==u.offsetTop,e.getComputedStyle&&(t.pixelPosition="1%"!==(e.getComputedStyle(d,null)||{}).top,t.boxSizingReliable="4px"===(e.getComputedStyle(d,null)||{width:"4px"}).width,r=d.appendChild(o.createElement("div")),r.style.cssText=d.style.cssText=s,r.style.marginRight=r.style.width="0",d.style.width="1px",t.reliableMarginRight=!parseFloat((e.getComputedStyle(r,null)||{}).marginRight)),typeof d.style.zoom!==i&&(d.innerHTML="",d.style.cssText=s+"width:1px;padding:1px;display:inline;zoom:1",t.inlineBlockNeedsLayout=3===d.offsetWidth,d.style.display="block",d.innerHTML="<div></div>",d.firstChild.style.width="5px",t.shrinkWrapBlocks=3!==d.offsetWidth,t.inlineBlockNeedsLayout&&(u.style.zoom=1)),u.removeChild(n),n=d=a=r=null)}),n=s=u=l=r=a=null,t}();var O=/(?:\{[\s\S]*\}|\[[\s\S]*\])$/,B=/([A-Z])/g;function P(e,n,r,i){if(b.acceptData(e)){var o,a,s=b.expando,u="string"==typeof n,l=e.nodeType,p=l?b.cache:e,f=l?e[s]:e[s]&&s;if(f&&p[f]&&(i||p[f].data)||!u||r!==t)return f||(l?e[s]=f=c.pop()||b.guid++:f=s),p[f]||(p[f]={},l||(p[f].toJSON=b.noop)),("object"==typeof n||"function"==typeof n)&&(i?p[f]=b.extend(p[f],n):p[f].data=b.extend(p[f].data,n)),o=p[f],i||(o.data||(o.data={}),o=o.data),r!==t&&(o[b.camelCase(n)]=r),u?(a=o[n],null==a&&(a=o[b.camelCase(n)])):a=o,a}}function R(e,t,n){if(b.acceptData(e)){var r,i,o,a=e.nodeType,s=a?b.cache:e,u=a?e[b.expando]:b.expando;if(s[u]){if(t&&(o=n?s[u]:s[u].data)){b.isArray(t)?t=t.concat(b.map(t,b.camelCase)):t in o?t=[t]:(t=b.camelCase(t),t=t in o?[t]:t.split(" "));for(r=0,i=t.length;i>r;r++)delete o[t[r]];if(!(n?$:b.isEmptyObject)(o))return}(n||(delete s[u].data,$(s[u])))&&(a?b.cleanData([e],!0):b.support.deleteExpando||s!=s.window?delete s[u]:s[u]=null)}}}b.extend({cache:{},expando:"jQuery"+(p+Math.random()).replace(/\D/g,""),noData:{embed:!0,object:"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000",applet:!0},hasData:function(e){return e=e.nodeType?b.cache[e[b.expando]]:e[b.expando],!!e&&!$(e)},data:function(e,t,n){return P(e,t,n)},removeData:function(e,t){return R(e,t)},_data:function(e,t,n){return P(e,t,n,!0)},_removeData:function(e,t){return R(e,t,!0)},acceptData:function(e){if(e.nodeType&&1!==e.nodeType&&9!==e.nodeType)return!1;var t=e.nodeName&&b.noData[e.nodeName.toLowerCase()];return!t||t!==!0&&e.getAttribute("classid")===t}}),b.fn.extend({data:function(e,n){var r,i,o=this[0],a=0,s=null;if(e===t){if(this.length&&(s=b.data(o),1===o.nodeType&&!b._data(o,"parsedAttrs"))){for(r=o.attributes;r.length>a;a++)i=r[a].name,i.indexOf("data-")||(i=b.camelCase(i.slice(5)),W(o,i,s[i]));b._data(o,"parsedAttrs",!0)}return s}return"object"==typeof e?this.each(function(){b.data(this,e)}):b.access(this,function(n){return n===t?o?W(o,e,b.data(o,e)):null:(this.each(function(){b.data(this,e,n)}),t)},null,n,arguments.length>1,null,!0)},removeData:function(e){return this.each(function(){b.removeData(this,e)})}});function W(e,n,r){if(r===t&&1===e.nodeType){var i="data-"+n.replace(B,"-$1").toLowerCase();if(r=e.getAttribute(i),"string"==typeof r){try{r="true"===r?!0:"false"===r?!1:"null"===r?null:+r+""===r?+r:O.test(r)?b.parseJSON(r):r}catch(o){}b.data(e,n,r)}else r=t}return r}function $(e){var t;for(t in e)if(("data"!==t||!b.isEmptyObject(e[t]))&&"toJSON"!==t)return!1;return!0}b.extend({queue:function(e,n,r){var i;return e?(n=(n||"fx")+"queue",i=b._data(e,n),r&&(!i||b.isArray(r)?i=b._data(e,n,b.makeArray(r)):i.push(r)),i||[]):t},dequeue:function(e,t){t=t||"fx";var n=b.queue(e,t),r=n.length,i=n.shift(),o=b._queueHooks(e,t),a=function(){b.dequeue(e,t)};"inprogress"===i&&(i=n.shift(),r--),o.cur=i,i&&("fx"===t&&n.unshift("inprogress"),delete o.stop,i.call(e,a,o)),!r&&o&&o.empty.fire()},_queueHooks:function(e,t){var n=t+"queueHooks";return b._data(e,n)||b._data(e,n,{empty:b.Callbacks("once memory").add(function(){b._removeData(e,t+"queue"),b._removeData(e,n)})})}}),b.fn.extend({queue:function(e,n){var r=2;return"string"!=typeof e&&(n=e,e="fx",r--),r>arguments.length?b.queue(this[0],e):n===t?this:this.each(function(){var t=b.queue(this,e,n);b._queueHooks(this,e),"fx"===e&&"inprogress"!==t[0]&&b.dequeue(this,e)})},dequeue:function(e){return this.each(function(){b.dequeue(this,e)})},delay:function(e,t){return e=b.fx?b.fx.speeds[e]||e:e,t=t||"fx",this.queue(t,function(t,n){var r=setTimeout(t,e);n.stop=function(){clearTimeout(r)}})},clearQueue:function(e){return this.queue(e||"fx",[])},promise:function(e,n){var r,i=1,o=b.Deferred(),a=this,s=this.length,u=function(){--i||o.resolveWith(a,[a])};"string"!=typeof e&&(n=e,e=t),e=e||"fx";while(s--)r=b._data(a[s],e+"queueHooks"),r&&r.empty&&(i++,r.empty.add(u));return u(),o.promise(n)}});var I,z,X=/[\t\r\n]/g,U=/\r/g,V=/^(?:input|select|textarea|button|object)$/i,Y=/^(?:a|area)$/i,J=/^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,G=/^(?:checked|selected)$/i,Q=b.support.getSetAttribute,K=b.support.input;b.fn.extend({attr:function(e,t){return b.access(this,b.attr,e,t,arguments.length>1)},removeAttr:function(e){return this.each(function(){b.removeAttr(this,e)})},prop:function(e,t){return b.access(this,b.prop,e,t,arguments.length>1)},removeProp:function(e){return e=b.propFix[e]||e,this.each(function(){try{this[e]=t,delete this[e]}catch(n){}})},addClass:function(e){var t,n,r,i,o,a=0,s=this.length,u="string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).addClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):" ")){o=0;while(i=t[o++])0>r.indexOf(" "+i+" ")&&(r+=i+" ");n.className=b.trim(r)}return this},removeClass:function(e){var t,n,r,i,o,a=0,s=this.length,u=0===arguments.length||"string"==typeof e&&e;if(b.isFunction(e))return this.each(function(t){b(this).removeClass(e.call(this,t,this.className))});if(u)for(t=(e||"").match(w)||[];s>a;a++)if(n=this[a],r=1===n.nodeType&&(n.className?(" "+n.className+" ").replace(X," "):"")){o=0;while(i=t[o++])while(r.indexOf(" "+i+" ")>=0)r=r.replace(" "+i+" "," ");n.className=e?b.trim(r):""}return this},toggleClass:function(e,t){var n=typeof e,r="boolean"==typeof t;return b.isFunction(e)?this.each(function(n){b(this).toggleClass(e.call(this,n,this.className,t),t)}):this.each(function(){if("string"===n){var o,a=0,s=b(this),u=t,l=e.match(w)||[];while(o=l[a++])u=r?u:!s.hasClass(o),s[u?"addClass":"removeClass"](o)}else(n===i||"boolean"===n)&&(this.className&&b._data(this,"__className__",this.className),this.className=this.className||e===!1?"":b._data(this,"__className__")||"")})},hasClass:function(e){var t=" "+e+" ",n=0,r=this.length;for(;r>n;n++)if(1===this[n].nodeType&&(" "+this[n].className+" ").replace(X," ").indexOf(t)>=0)return!0;return!1},val:function(e){var n,r,i,o=this[0];{if(arguments.length)return i=b.isFunction(e),this.each(function(n){var o,a=b(this);1===this.nodeType&&(o=i?e.call(this,n,a.val()):e,null==o?o="":"number"==typeof o?o+="":b.isArray(o)&&(o=b.map(o,function(e){return null==e?"":e+""})),r=b.valHooks[this.type]||b.valHooks[this.nodeName.toLowerCase()],r&&"set"in r&&r.set(this,o,"value")!==t||(this.value=o))});if(o)return r=b.valHooks[o.type]||b.valHooks[o.nodeName.toLowerCase()],r&&"get"in r&&(n=r.get(o,"value"))!==t?n:(n=o.value,"string"==typeof n?n.replace(U,""):null==n?"":n)}}}),b.extend({valHooks:{option:{get:function(e){var t=e.attributes.value;return!t||t.specified?e.value:e.text}},select:{get:function(e){var t,n,r=e.options,i=e.selectedIndex,o="select-one"===e.type||0>i,a=o?null:[],s=o?i+1:r.length,u=0>i?s:o?i:0;for(;s>u;u++)if(n=r[u],!(!n.selected&&u!==i||(b.support.optDisabled?n.disabled:null!==n.getAttribute("disabled"))||n.parentNode.disabled&&b.nodeName(n.parentNode,"optgroup"))){if(t=b(n).val(),o)return t;a.push(t)}return a},set:function(e,t){var n=b.makeArray(t);return b(e).find("option").each(function(){this.selected=b.inArray(b(this).val(),n)>=0}),n.length||(e.selectedIndex=-1),n}}},attr:function(e,n,r){var o,a,s,u=e.nodeType;if(e&&3!==u&&8!==u&&2!==u)return typeof e.getAttribute===i?b.prop(e,n,r):(a=1!==u||!b.isXMLDoc(e),a&&(n=n.toLowerCase(),o=b.attrHooks[n]||(J.test(n)?z:I)),r===t?o&&a&&"get"in o&&null!==(s=o.get(e,n))?s:(typeof e.getAttribute!==i&&(s=e.getAttribute(n)),null==s?t:s):null!==r?o&&a&&"set"in o&&(s=o.set(e,r,n))!==t?s:(e.setAttribute(n,r+""),r):(b.removeAttr(e,n),t))},removeAttr:function(e,t){var n,r,i=0,o=t&&t.match(w);if(o&&1===e.nodeType)while(n=o[i++])r=b.propFix[n]||n,J.test(n)?!Q&&G.test(n)?e[b.camelCase("default-"+n)]=e[r]=!1:e[r]=!1:b.attr(e,n,""),e.removeAttribute(Q?n:r)},attrHooks:{type:{set:function(e,t){if(!b.support.radioValue&&"radio"===t&&b.nodeName(e,"input")){var n=e.value;return e.setAttribute("type",t),n&&(e.value=n),t}}}},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(e,n,r){var i,o,a,s=e.nodeType;if(e&&3!==s&&8!==s&&2!==s)return a=1!==s||!b.isXMLDoc(e),a&&(n=b.propFix[n]||n,o=b.propHooks[n]),r!==t?o&&"set"in o&&(i=o.set(e,r,n))!==t?i:e[n]=r:o&&"get"in o&&null!==(i=o.get(e,n))?i:e[n]},propHooks:{tabIndex:{get:function(e){var n=e.getAttributeNode("tabindex");return n&&n.specified?parseInt(n.value,10):V.test(e.nodeName)||Y.test(e.nodeName)&&e.href?0:t}}}}),z={get:function(e,n){var r=b.prop(e,n),i="boolean"==typeof r&&e.getAttribute(n),o="boolean"==typeof r?K&&Q?null!=i:G.test(n)?e[b.camelCase("default-"+n)]:!!i:e.getAttributeNode(n);return o&&o.value!==!1?n.toLowerCase():t},set:function(e,t,n){return t===!1?b.removeAttr(e,n):K&&Q||!G.test(n)?e.setAttribute(!Q&&b.propFix[n]||n,n):e[b.camelCase("default-"+n)]=e[n]=!0,n}},K&&Q||(b.attrHooks.value={get:function(e,n){var r=e.getAttributeNode(n);return b.nodeName(e,"input")?e.defaultValue:r&&r.specified?r.value:t},set:function(e,n,r){return b.nodeName(e,"input")?(e.defaultValue=n,t):I&&I.set(e,n,r)}}),Q||(I=b.valHooks.button={get:function(e,n){var r=e.getAttributeNode(n);return r&&("id"===n||"name"===n||"coords"===n?""!==r.value:r.specified)?r.value:t},set:function(e,n,r){var i=e.getAttributeNode(r);return i||e.setAttributeNode(i=e.ownerDocument.createAttribute(r)),i.value=n+="","value"===r||n===e.getAttribute(r)?n:t}},b.attrHooks.contenteditable={get:I.get,set:function(e,t,n){I.set(e,""===t?!1:t,n)}},b.each(["width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{set:function(e,r){return""===r?(e.setAttribute(n,"auto"),r):t}})})),b.support.hrefNormalized||(b.each(["href","src","width","height"],function(e,n){b.attrHooks[n]=b.extend(b.attrHooks[n],{get:function(e){var r=e.getAttribute(n,2);return null==r?t:r}})}),b.each(["href","src"],function(e,t){b.propHooks[t]={get:function(e){return e.getAttribute(t,4)}}})),b.support.style||(b.attrHooks.style={get:function(e){return e.style.cssText||t},set:function(e,t){return e.style.cssText=t+""}}),b.support.optSelected||(b.propHooks.selected=b.extend(b.propHooks.selected,{get:function(e){var t=e.parentNode;return t&&(t.selectedIndex,t.parentNode&&t.parentNode.selectedIndex),null}})),b.support.enctype||(b.propFix.enctype="encoding"),b.support.checkOn||b.each(["radio","checkbox"],function(){b.valHooks[this]={get:function(e){return null===e.getAttribute("value")?"on":e.value}}}),b.each(["radio","checkbox"],function(){b.valHooks[this]=b.extend(b.valHooks[this],{set:function(e,n){return b.isArray(n)?e.checked=b.inArray(b(e).val(),n)>=0:t}})});var Z=/^(?:input|select|textarea)$/i,et=/^key/,tt=/^(?:mouse|contextmenu)|click/,nt=/^(?:focusinfocus|focusoutblur)$/,rt=/^([^.]*)(?:\.(.+)|)$/;function it(){return!0}function ot(){return!1}b.event={global:{},add:function(e,n,r,o,a){var s,u,l,c,p,f,d,h,g,m,y,v=b._data(e);if(v){r.handler&&(c=r,r=c.handler,a=c.selector),r.guid||(r.guid=b.guid++),(u=v.events)||(u=v.events={}),(f=v.handle)||(f=v.handle=function(e){return typeof b===i||e&&b.event.triggered===e.type?t:b.event.dispatch.apply(f.elem,arguments)},f.elem=e),n=(n||"").match(w)||[""],l=n.length;while(l--)s=rt.exec(n[l])||[],g=y=s[1],m=(s[2]||"").split(".").sort(),p=b.event.special[g]||{},g=(a?p.delegateType:p.bindType)||g,p=b.event.special[g]||{},d=b.extend({type:g,origType:y,data:o,handler:r,guid:r.guid,selector:a,needsContext:a&&b.expr.match.needsContext.test(a),namespace:m.join(".")},c),(h=u[g])||(h=u[g]=[],h.delegateCount=0,p.setup&&p.setup.call(e,o,m,f)!==!1||(e.addEventListener?e.addEventListener(g,f,!1):e.attachEvent&&e.attachEvent("on"+g,f))),p.add&&(p.add.call(e,d),d.handler.guid||(d.handler.guid=r.guid)),a?h.splice(h.delegateCount++,0,d):h.push(d),b.event.global[g]=!0;e=null}},remove:function(e,t,n,r,i){var o,a,s,u,l,c,p,f,d,h,g,m=b.hasData(e)&&b._data(e);if(m&&(c=m.events)){t=(t||"").match(w)||[""],l=t.length;while(l--)if(s=rt.exec(t[l])||[],d=g=s[1],h=(s[2]||"").split(".").sort(),d){p=b.event.special[d]||{},d=(r?p.delegateType:p.bindType)||d,f=c[d]||[],s=s[2]&&RegExp("(^|\\.)"+h.join("\\.(?:.*\\.|)")+"(\\.|$)"),u=o=f.length;while(o--)a=f[o],!i&&g!==a.origType||n&&n.guid!==a.guid||s&&!s.test(a.namespace)||r&&r!==a.selector&&("**"!==r||!a.selector)||(f.splice(o,1),a.selector&&f.delegateCount--,p.remove&&p.remove.call(e,a));u&&!f.length&&(p.teardown&&p.teardown.call(e,h,m.handle)!==!1||b.removeEvent(e,d,m.handle),delete c[d])}else for(d in c)b.event.remove(e,d+t[l],n,r,!0);b.isEmptyObject(c)&&(delete m.handle,b._removeData(e,"events"))}},trigger:function(n,r,i,a){var s,u,l,c,p,f,d,h=[i||o],g=y.call(n,"type")?n.type:n,m=y.call(n,"namespace")?n.namespace.split("."):[];if(l=f=i=i||o,3!==i.nodeType&&8!==i.nodeType&&!nt.test(g+b.event.triggered)&&(g.indexOf(".")>=0&&(m=g.split("."),g=m.shift(),m.sort()),u=0>g.indexOf(":")&&"on"+g,n=n[b.expando]?n:new b.Event(g,"object"==typeof n&&n),n.isTrigger=!0,n.namespace=m.join("."),n.namespace_re=n.namespace?RegExp("(^|\\.)"+m.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,n.result=t,n.target||(n.target=i),r=null==r?[n]:b.makeArray(r,[n]),p=b.event.special[g]||{},a||!p.trigger||p.trigger.apply(i,r)!==!1)){if(!a&&!p.noBubble&&!b.isWindow(i)){for(c=p.delegateType||g,nt.test(c+g)||(l=l.parentNode);l;l=l.parentNode)h.push(l),f=l;f===(i.ownerDocument||o)&&h.push(f.defaultView||f.parentWindow||e)}d=0;while((l=h[d++])&&!n.isPropagationStopped())n.type=d>1?c:p.bindType||g,s=(b._data(l,"events")||{})[n.type]&&b._data(l,"handle"),s&&s.apply(l,r),s=u&&l[u],s&&b.acceptData(l)&&s.apply&&s.apply(l,r)===!1&&n.preventDefault();if(n.type=g,!(a||n.isDefaultPrevented()||p._default&&p._default.apply(i.ownerDocument,r)!==!1||"click"===g&&b.nodeName(i,"a")||!b.acceptData(i)||!u||!i[g]||b.isWindow(i))){f=i[u],f&&(i[u]=null),b.event.triggered=g;try{i[g]()}catch(v){}b.event.triggered=t,f&&(i[u]=f)}return n.result}},dispatch:function(e){e=b.event.fix(e);var n,r,i,o,a,s=[],u=h.call(arguments),l=(b._data(this,"events")||{})[e.type]||[],c=b.event.special[e.type]||{};if(u[0]=e,e.delegateTarget=this,!c.preDispatch||c.preDispatch.call(this,e)!==!1){s=b.event.handlers.call(this,e,l),n=0;while((o=s[n++])&&!e.isPropagationStopped()){e.currentTarget=o.elem,a=0;while((i=o.handlers[a++])&&!e.isImmediatePropagationStopped())(!e.namespace_re||e.namespace_re.test(i.namespace))&&(e.handleObj=i,e.data=i.data,r=((b.event.special[i.origType]||{}).handle||i.handler).apply(o.elem,u),r!==t&&(e.result=r)===!1&&(e.preventDefault(),e.stopPropagation()))}return c.postDispatch&&c.postDispatch.call(this,e),e.result}},handlers:function(e,n){var r,i,o,a,s=[],u=n.delegateCount,l=e.target;if(u&&l.nodeType&&(!e.button||"click"!==e.type))for(;l!=this;l=l.parentNode||this)if(1===l.nodeType&&(l.disabled!==!0||"click"!==e.type)){for(o=[],a=0;u>a;a++)i=n[a],r=i.selector+" ",o[r]===t&&(o[r]=i.needsContext?b(r,this).index(l)>=0:b.find(r,this,null,[l]).length),o[r]&&o.push(i);o.length&&s.push({elem:l,handlers:o})}return n.length>u&&s.push({elem:this,handlers:n.slice(u)}),s},fix:function(e){if(e[b.expando])return e;var t,n,r,i=e.type,a=e,s=this.fixHooks[i];s||(this.fixHooks[i]=s=tt.test(i)?this.mouseHooks:et.test(i)?this.keyHooks:{}),r=s.props?this.props.concat(s.props):this.props,e=new b.Event(a),t=r.length;while(t--)n=r[t],e[n]=a[n];return e.target||(e.target=a.srcElement||o),3===e.target.nodeType&&(e.target=e.target.parentNode),e.metaKey=!!e.metaKey,s.filter?s.filter(e,a):e},props:"altKey bubbles cancelable ctrlKey currentTarget eventPhase metaKey relatedTarget shiftKey target timeStamp view which".split(" "),fixHooks:{},keyHooks:{props:"char charCode key keyCode".split(" "),filter:function(e,t){return null==e.which&&(e.which=null!=t.charCode?t.charCode:t.keyCode),e}},mouseHooks:{props:"button buttons clientX clientY fromElement offsetX offsetY pageX pageY screenX screenY toElement".split(" "),filter:function(e,n){var r,i,a,s=n.button,u=n.fromElement;return null==e.pageX&&null!=n.clientX&&(i=e.target.ownerDocument||o,a=i.documentElement,r=i.body,e.pageX=n.clientX+(a&&a.scrollLeft||r&&r.scrollLeft||0)-(a&&a.clientLeft||r&&r.clientLeft||0),e.pageY=n.clientY+(a&&a.scrollTop||r&&r.scrollTop||0)-(a&&a.clientTop||r&&r.clientTop||0)),!e.relatedTarget&&u&&(e.relatedTarget=u===e.target?n.toElement:u),e.which||s===t||(e.which=1&s?1:2&s?3:4&s?2:0),e}},special:{load:{noBubble:!0},click:{trigger:function(){return b.nodeName(this,"input")&&"checkbox"===this.type&&this.click?(this.click(),!1):t}},focus:{trigger:function(){if(this!==o.activeElement&&this.focus)try{return this.focus(),!1}catch(e){}},delegateType:"focusin"},blur:{trigger:function(){return this===o.activeElement&&this.blur?(this.blur(),!1):t},delegateType:"focusout"},beforeunload:{postDispatch:function(e){e.result!==t&&(e.originalEvent.returnValue=e.result)}}},simulate:function(e,t,n,r){var i=b.extend(new b.Event,n,{type:e,isSimulated:!0,originalEvent:{}});r?b.event.trigger(i,null,t):b.event.dispatch.call(t,i),i.isDefaultPrevented()&&n.preventDefault()}},b.removeEvent=o.removeEventListener?function(e,t,n){e.removeEventListener&&e.removeEventListener(t,n,!1)}:function(e,t,n){var r="on"+t;e.detachEvent&&(typeof e[r]===i&&(e[r]=null),e.detachEvent(r,n))},b.Event=function(e,n){return this instanceof b.Event?(e&&e.type?(this.originalEvent=e,this.type=e.type,this.isDefaultPrevented=e.defaultPrevented||e.returnValue===!1||e.getPreventDefault&&e.getPreventDefault()?it:ot):this.type=e,n&&b.extend(this,n),this.timeStamp=e&&e.timeStamp||b.now(),this[b.expando]=!0,t):new b.Event(e,n)},b.Event.prototype={isDefaultPrevented:ot,isPropagationStopped:ot,isImmediatePropagationStopped:ot,preventDefault:function(){var e=this.originalEvent;this.isDefaultPrevented=it,e&&(e.preventDefault?e.preventDefault():e.returnValue=!1)},stopPropagation:function(){var e=this.originalEvent;this.isPropagationStopped=it,e&&(e.stopPropagation&&e.stopPropagation(),e.cancelBubble=!0)},stopImmediatePropagation:function(){this.isImmediatePropagationStopped=it,this.stopPropagation()}},b.each({mouseenter:"mouseover",mouseleave:"mouseout"},function(e,t){b.event.special[e]={delegateType:t,bindType:t,handle:function(e){var n,r=this,i=e.relatedTarget,o=e.handleObj;
+return(!i||i!==r&&!b.contains(r,i))&&(e.type=o.origType,n=o.handler.apply(this,arguments),e.type=t),n}}}),b.support.submitBubbles||(b.event.special.submit={setup:function(){return b.nodeName(this,"form")?!1:(b.event.add(this,"click._submit keypress._submit",function(e){var n=e.target,r=b.nodeName(n,"input")||b.nodeName(n,"button")?n.form:t;r&&!b._data(r,"submitBubbles")&&(b.event.add(r,"submit._submit",function(e){e._submit_bubble=!0}),b._data(r,"submitBubbles",!0))}),t)},postDispatch:function(e){e._submit_bubble&&(delete e._submit_bubble,this.parentNode&&!e.isTrigger&&b.event.simulate("submit",this.parentNode,e,!0))},teardown:function(){return b.nodeName(this,"form")?!1:(b.event.remove(this,"._submit"),t)}}),b.support.changeBubbles||(b.event.special.change={setup:function(){return Z.test(this.nodeName)?(("checkbox"===this.type||"radio"===this.type)&&(b.event.add(this,"propertychange._change",function(e){"checked"===e.originalEvent.propertyName&&(this._just_changed=!0)}),b.event.add(this,"click._change",function(e){this._just_changed&&!e.isTrigger&&(this._just_changed=!1),b.event.simulate("change",this,e,!0)})),!1):(b.event.add(this,"beforeactivate._change",function(e){var t=e.target;Z.test(t.nodeName)&&!b._data(t,"changeBubbles")&&(b.event.add(t,"change._change",function(e){!this.parentNode||e.isSimulated||e.isTrigger||b.event.simulate("change",this.parentNode,e,!0)}),b._data(t,"changeBubbles",!0))}),t)},handle:function(e){var n=e.target;return this!==n||e.isSimulated||e.isTrigger||"radio"!==n.type&&"checkbox"!==n.type?e.handleObj.handler.apply(this,arguments):t},teardown:function(){return b.event.remove(this,"._change"),!Z.test(this.nodeName)}}),b.support.focusinBubbles||b.each({focus:"focusin",blur:"focusout"},function(e,t){var n=0,r=function(e){b.event.simulate(t,e.target,b.event.fix(e),!0)};b.event.special[t]={setup:function(){0===n++&&o.addEventListener(e,r,!0)},teardown:function(){0===--n&&o.removeEventListener(e,r,!0)}}}),b.fn.extend({on:function(e,n,r,i,o){var a,s;if("object"==typeof e){"string"!=typeof n&&(r=r||n,n=t);for(a in e)this.on(a,n,r,e[a],o);return this}if(null==r&&null==i?(i=n,r=n=t):null==i&&("string"==typeof n?(i=r,r=t):(i=r,r=n,n=t)),i===!1)i=ot;else if(!i)return this;return 1===o&&(s=i,i=function(e){return b().off(e),s.apply(this,arguments)},i.guid=s.guid||(s.guid=b.guid++)),this.each(function(){b.event.add(this,e,i,r,n)})},one:function(e,t,n,r){return this.on(e,t,n,r,1)},off:function(e,n,r){var i,o;if(e&&e.preventDefault&&e.handleObj)return i=e.handleObj,b(e.delegateTarget).off(i.namespace?i.origType+"."+i.namespace:i.origType,i.selector,i.handler),this;if("object"==typeof e){for(o in e)this.off(o,n,e[o]);return this}return(n===!1||"function"==typeof n)&&(r=n,n=t),r===!1&&(r=ot),this.each(function(){b.event.remove(this,e,r,n)})},bind:function(e,t,n){return this.on(e,null,t,n)},unbind:function(e,t){return this.off(e,null,t)},delegate:function(e,t,n,r){return this.on(t,e,n,r)},undelegate:function(e,t,n){return 1===arguments.length?this.off(e,"**"):this.off(t,e||"**",n)},trigger:function(e,t){return this.each(function(){b.event.trigger(e,t,this)})},triggerHandler:function(e,n){var r=this[0];return r?b.event.trigger(e,n,r,!0):t}}),function(e,t){var n,r,i,o,a,s,u,l,c,p,f,d,h,g,m,y,v,x="sizzle"+-new Date,w=e.document,T={},N=0,C=0,k=it(),E=it(),S=it(),A=typeof t,j=1<<31,D=[],L=D.pop,H=D.push,q=D.slice,M=D.indexOf||function(e){var t=0,n=this.length;for(;n>t;t++)if(this[t]===e)return t;return-1},_="[\\x20\\t\\r\\n\\f]",F="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",O=F.replace("w","w#"),B="([*^$|!~]?=)",P="\\["+_+"*("+F+")"+_+"*(?:"+B+_+"*(?:(['\"])((?:\\\\.|[^\\\\])*?)\\3|("+O+")|)|)"+_+"*\\]",R=":("+F+")(?:\\(((['\"])((?:\\\\.|[^\\\\])*?)\\3|((?:\\\\.|[^\\\\()[\\]]|"+P.replace(3,8)+")*)|.*)\\)|)",W=RegExp("^"+_+"+|((?:^|[^\\\\])(?:\\\\.)*)"+_+"+$","g"),$=RegExp("^"+_+"*,"+_+"*"),I=RegExp("^"+_+"*([\\x20\\t\\r\\n\\f>+~])"+_+"*"),z=RegExp(R),X=RegExp("^"+O+"$"),U={ID:RegExp("^#("+F+")"),CLASS:RegExp("^\\.("+F+")"),NAME:RegExp("^\\[name=['\"]?("+F+")['\"]?\\]"),TAG:RegExp("^("+F.replace("w","w*")+")"),ATTR:RegExp("^"+P),PSEUDO:RegExp("^"+R),CHILD:RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+_+"*(even|odd|(([+-]|)(\\d*)n|)"+_+"*(?:([+-]|)"+_+"*(\\d+)|))"+_+"*\\)|)","i"),needsContext:RegExp("^"+_+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+_+"*((?:-\\d)?\\d*)"+_+"*\\)|)(?=[^-]|$)","i")},V=/[\x20\t\r\n\f]*[+~]/,Y=/^[^{]+\{\s*\[native code/,J=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,G=/^(?:input|select|textarea|button)$/i,Q=/^h\d$/i,K=/'|\\/g,Z=/\=[\x20\t\r\n\f]*([^'"\]]*)[\x20\t\r\n\f]*\]/g,et=/\\([\da-fA-F]{1,6}[\x20\t\r\n\f]?|.)/g,tt=function(e,t){var n="0x"+t-65536;return n!==n?t:0>n?String.fromCharCode(n+65536):String.fromCharCode(55296|n>>10,56320|1023&n)};try{q.call(w.documentElement.childNodes,0)[0].nodeType}catch(nt){q=function(e){var t,n=[];while(t=this[e++])n.push(t);return n}}function rt(e){return Y.test(e+"")}function it(){var e,t=[];return e=function(n,r){return t.push(n+=" ")>i.cacheLength&&delete e[t.shift()],e[n]=r}}function ot(e){return e[x]=!0,e}function at(e){var t=p.createElement("div");try{return e(t)}catch(n){return!1}finally{t=null}}function st(e,t,n,r){var i,o,a,s,u,l,f,g,m,v;if((t?t.ownerDocument||t:w)!==p&&c(t),t=t||p,n=n||[],!e||"string"!=typeof e)return n;if(1!==(s=t.nodeType)&&9!==s)return[];if(!d&&!r){if(i=J.exec(e))if(a=i[1]){if(9===s){if(o=t.getElementById(a),!o||!o.parentNode)return n;if(o.id===a)return n.push(o),n}else if(t.ownerDocument&&(o=t.ownerDocument.getElementById(a))&&y(t,o)&&o.id===a)return n.push(o),n}else{if(i[2])return H.apply(n,q.call(t.getElementsByTagName(e),0)),n;if((a=i[3])&&T.getByClassName&&t.getElementsByClassName)return H.apply(n,q.call(t.getElementsByClassName(a),0)),n}if(T.qsa&&!h.test(e)){if(f=!0,g=x,m=t,v=9===s&&e,1===s&&"object"!==t.nodeName.toLowerCase()){l=ft(e),(f=t.getAttribute("id"))?g=f.replace(K,"\\$&"):t.setAttribute("id",g),g="[id='"+g+"'] ",u=l.length;while(u--)l[u]=g+dt(l[u]);m=V.test(e)&&t.parentNode||t,v=l.join(",")}if(v)try{return H.apply(n,q.call(m.querySelectorAll(v),0)),n}catch(b){}finally{f||t.removeAttribute("id")}}}return wt(e.replace(W,"$1"),t,n,r)}a=st.isXML=function(e){var t=e&&(e.ownerDocument||e).documentElement;return t?"HTML"!==t.nodeName:!1},c=st.setDocument=function(e){var n=e?e.ownerDocument||e:w;return n!==p&&9===n.nodeType&&n.documentElement?(p=n,f=n.documentElement,d=a(n),T.tagNameNoComments=at(function(e){return e.appendChild(n.createComment("")),!e.getElementsByTagName("*").length}),T.attributes=at(function(e){e.innerHTML="<select></select>";var t=typeof e.lastChild.getAttribute("multiple");return"boolean"!==t&&"string"!==t}),T.getByClassName=at(function(e){return e.innerHTML="<div class='hidden e'></div><div class='hidden'></div>",e.getElementsByClassName&&e.getElementsByClassName("e").length?(e.lastChild.className="e",2===e.getElementsByClassName("e").length):!1}),T.getByName=at(function(e){e.id=x+0,e.innerHTML="<a name='"+x+"'></a><div name='"+x+"'></div>",f.insertBefore(e,f.firstChild);var t=n.getElementsByName&&n.getElementsByName(x).length===2+n.getElementsByName(x+0).length;return T.getIdNotName=!n.getElementById(x),f.removeChild(e),t}),i.attrHandle=at(function(e){return e.innerHTML="<a href='#'></a>",e.firstChild&&typeof e.firstChild.getAttribute!==A&&"#"===e.firstChild.getAttribute("href")})?{}:{href:function(e){return e.getAttribute("href",2)},type:function(e){return e.getAttribute("type")}},T.getIdNotName?(i.find.ID=function(e,t){if(typeof t.getElementById!==A&&!d){var n=t.getElementById(e);return n&&n.parentNode?[n]:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){return e.getAttribute("id")===t}}):(i.find.ID=function(e,n){if(typeof n.getElementById!==A&&!d){var r=n.getElementById(e);return r?r.id===e||typeof r.getAttributeNode!==A&&r.getAttributeNode("id").value===e?[r]:t:[]}},i.filter.ID=function(e){var t=e.replace(et,tt);return function(e){var n=typeof e.getAttributeNode!==A&&e.getAttributeNode("id");return n&&n.value===t}}),i.find.TAG=T.tagNameNoComments?function(e,n){return typeof n.getElementsByTagName!==A?n.getElementsByTagName(e):t}:function(e,t){var n,r=[],i=0,o=t.getElementsByTagName(e);if("*"===e){while(n=o[i++])1===n.nodeType&&r.push(n);return r}return o},i.find.NAME=T.getByName&&function(e,n){return typeof n.getElementsByName!==A?n.getElementsByName(name):t},i.find.CLASS=T.getByClassName&&function(e,n){return typeof n.getElementsByClassName===A||d?t:n.getElementsByClassName(e)},g=[],h=[":focus"],(T.qsa=rt(n.querySelectorAll))&&(at(function(e){e.innerHTML="<select><option selected=''></option></select>",e.querySelectorAll("[selected]").length||h.push("\\["+_+"*(?:checked|disabled|ismap|multiple|readonly|selected|value)"),e.querySelectorAll(":checked").length||h.push(":checked")}),at(function(e){e.innerHTML="<input type='hidden' i=''/>",e.querySelectorAll("[i^='']").length&&h.push("[*^$]="+_+"*(?:\"\"|'')"),e.querySelectorAll(":enabled").length||h.push(":enabled",":disabled"),e.querySelectorAll("*,:x"),h.push(",.*:")})),(T.matchesSelector=rt(m=f.matchesSelector||f.mozMatchesSelector||f.webkitMatchesSelector||f.oMatchesSelector||f.msMatchesSelector))&&at(function(e){T.disconnectedMatch=m.call(e,"div"),m.call(e,"[s!='']:x"),g.push("!=",R)}),h=RegExp(h.join("|")),g=RegExp(g.join("|")),y=rt(f.contains)||f.compareDocumentPosition?function(e,t){var n=9===e.nodeType?e.documentElement:e,r=t&&t.parentNode;return e===r||!(!r||1!==r.nodeType||!(n.contains?n.contains(r):e.compareDocumentPosition&&16&e.compareDocumentPosition(r)))}:function(e,t){if(t)while(t=t.parentNode)if(t===e)return!0;return!1},v=f.compareDocumentPosition?function(e,t){var r;return e===t?(u=!0,0):(r=t.compareDocumentPosition&&e.compareDocumentPosition&&e.compareDocumentPosition(t))?1&r||e.parentNode&&11===e.parentNode.nodeType?e===n||y(w,e)?-1:t===n||y(w,t)?1:0:4&r?-1:1:e.compareDocumentPosition?-1:1}:function(e,t){var r,i=0,o=e.parentNode,a=t.parentNode,s=[e],l=[t];if(e===t)return u=!0,0;if(!o||!a)return e===n?-1:t===n?1:o?-1:a?1:0;if(o===a)return ut(e,t);r=e;while(r=r.parentNode)s.unshift(r);r=t;while(r=r.parentNode)l.unshift(r);while(s[i]===l[i])i++;return i?ut(s[i],l[i]):s[i]===w?-1:l[i]===w?1:0},u=!1,[0,0].sort(v),T.detectDuplicates=u,p):p},st.matches=function(e,t){return st(e,null,null,t)},st.matchesSelector=function(e,t){if((e.ownerDocument||e)!==p&&c(e),t=t.replace(Z,"='$1']"),!(!T.matchesSelector||d||g&&g.test(t)||h.test(t)))try{var n=m.call(e,t);if(n||T.disconnectedMatch||e.document&&11!==e.document.nodeType)return n}catch(r){}return st(t,p,null,[e]).length>0},st.contains=function(e,t){return(e.ownerDocument||e)!==p&&c(e),y(e,t)},st.attr=function(e,t){var n;return(e.ownerDocument||e)!==p&&c(e),d||(t=t.toLowerCase()),(n=i.attrHandle[t])?n(e):d||T.attributes?e.getAttribute(t):((n=e.getAttributeNode(t))||e.getAttribute(t))&&e[t]===!0?t:n&&n.specified?n.value:null},st.error=function(e){throw Error("Syntax error, unrecognized expression: "+e)},st.uniqueSort=function(e){var t,n=[],r=1,i=0;if(u=!T.detectDuplicates,e.sort(v),u){for(;t=e[r];r++)t===e[r-1]&&(i=n.push(r));while(i--)e.splice(n[i],1)}return e};function ut(e,t){var n=t&&e,r=n&&(~t.sourceIndex||j)-(~e.sourceIndex||j);if(r)return r;if(n)while(n=n.nextSibling)if(n===t)return-1;return e?1:-1}function lt(e){return function(t){var n=t.nodeName.toLowerCase();return"input"===n&&t.type===e}}function ct(e){return function(t){var n=t.nodeName.toLowerCase();return("input"===n||"button"===n)&&t.type===e}}function pt(e){return ot(function(t){return t=+t,ot(function(n,r){var i,o=e([],n.length,t),a=o.length;while(a--)n[i=o[a]]&&(n[i]=!(r[i]=n[i]))})})}o=st.getText=function(e){var t,n="",r=0,i=e.nodeType;if(i){if(1===i||9===i||11===i){if("string"==typeof e.textContent)return e.textContent;for(e=e.firstChild;e;e=e.nextSibling)n+=o(e)}else if(3===i||4===i)return e.nodeValue}else for(;t=e[r];r++)n+=o(t);return n},i=st.selectors={cacheLength:50,createPseudo:ot,match:U,find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(e){return e[1]=e[1].replace(et,tt),e[3]=(e[4]||e[5]||"").replace(et,tt),"~="===e[2]&&(e[3]=" "+e[3]+" "),e.slice(0,4)},CHILD:function(e){return e[1]=e[1].toLowerCase(),"nth"===e[1].slice(0,3)?(e[3]||st.error(e[0]),e[4]=+(e[4]?e[5]+(e[6]||1):2*("even"===e[3]||"odd"===e[3])),e[5]=+(e[7]+e[8]||"odd"===e[3])):e[3]&&st.error(e[0]),e},PSEUDO:function(e){var t,n=!e[5]&&e[2];return U.CHILD.test(e[0])?null:(e[4]?e[2]=e[4]:n&&z.test(n)&&(t=ft(n,!0))&&(t=n.indexOf(")",n.length-t)-n.length)&&(e[0]=e[0].slice(0,t),e[2]=n.slice(0,t)),e.slice(0,3))}},filter:{TAG:function(e){return"*"===e?function(){return!0}:(e=e.replace(et,tt).toLowerCase(),function(t){return t.nodeName&&t.nodeName.toLowerCase()===e})},CLASS:function(e){var t=k[e+" "];return t||(t=RegExp("(^|"+_+")"+e+"("+_+"|$)"))&&k(e,function(e){return t.test(e.className||typeof e.getAttribute!==A&&e.getAttribute("class")||"")})},ATTR:function(e,t,n){return function(r){var i=st.attr(r,e);return null==i?"!="===t:t?(i+="","="===t?i===n:"!="===t?i!==n:"^="===t?n&&0===i.indexOf(n):"*="===t?n&&i.indexOf(n)>-1:"$="===t?n&&i.slice(-n.length)===n:"~="===t?(" "+i+" ").indexOf(n)>-1:"|="===t?i===n||i.slice(0,n.length+1)===n+"-":!1):!0}},CHILD:function(e,t,n,r,i){var o="nth"!==e.slice(0,3),a="last"!==e.slice(-4),s="of-type"===t;return 1===r&&0===i?function(e){return!!e.parentNode}:function(t,n,u){var l,c,p,f,d,h,g=o!==a?"nextSibling":"previousSibling",m=t.parentNode,y=s&&t.nodeName.toLowerCase(),v=!u&&!s;if(m){if(o){while(g){p=t;while(p=p[g])if(s?p.nodeName.toLowerCase()===y:1===p.nodeType)return!1;h=g="only"===e&&!h&&"nextSibling"}return!0}if(h=[a?m.firstChild:m.lastChild],a&&v){c=m[x]||(m[x]={}),l=c[e]||[],d=l[0]===N&&l[1],f=l[0]===N&&l[2],p=d&&m.childNodes[d];while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if(1===p.nodeType&&++f&&p===t){c[e]=[N,d,f];break}}else if(v&&(l=(t[x]||(t[x]={}))[e])&&l[0]===N)f=l[1];else while(p=++d&&p&&p[g]||(f=d=0)||h.pop())if((s?p.nodeName.toLowerCase()===y:1===p.nodeType)&&++f&&(v&&((p[x]||(p[x]={}))[e]=[N,f]),p===t))break;return f-=i,f===r||0===f%r&&f/r>=0}}},PSEUDO:function(e,t){var n,r=i.pseudos[e]||i.setFilters[e.toLowerCase()]||st.error("unsupported pseudo: "+e);return r[x]?r(t):r.length>1?(n=[e,e,"",t],i.setFilters.hasOwnProperty(e.toLowerCase())?ot(function(e,n){var i,o=r(e,t),a=o.length;while(a--)i=M.call(e,o[a]),e[i]=!(n[i]=o[a])}):function(e){return r(e,0,n)}):r}},pseudos:{not:ot(function(e){var t=[],n=[],r=s(e.replace(W,"$1"));return r[x]?ot(function(e,t,n,i){var o,a=r(e,null,i,[]),s=e.length;while(s--)(o=a[s])&&(e[s]=!(t[s]=o))}):function(e,i,o){return t[0]=e,r(t,null,o,n),!n.pop()}}),has:ot(function(e){return function(t){return st(e,t).length>0}}),contains:ot(function(e){return function(t){return(t.textContent||t.innerText||o(t)).indexOf(e)>-1}}),lang:ot(function(e){return X.test(e||"")||st.error("unsupported lang: "+e),e=e.replace(et,tt).toLowerCase(),function(t){var n;do if(n=d?t.getAttribute("xml:lang")||t.getAttribute("lang"):t.lang)return n=n.toLowerCase(),n===e||0===n.indexOf(e+"-");while((t=t.parentNode)&&1===t.nodeType);return!1}}),target:function(t){var n=e.location&&e.location.hash;return n&&n.slice(1)===t.id},root:function(e){return e===f},focus:function(e){return e===p.activeElement&&(!p.hasFocus||p.hasFocus())&&!!(e.type||e.href||~e.tabIndex)},enabled:function(e){return e.disabled===!1},disabled:function(e){return e.disabled===!0},checked:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&!!e.checked||"option"===t&&!!e.selected},selected:function(e){return e.parentNode&&e.parentNode.selectedIndex,e.selected===!0},empty:function(e){for(e=e.firstChild;e;e=e.nextSibling)if(e.nodeName>"@"||3===e.nodeType||4===e.nodeType)return!1;return!0},parent:function(e){return!i.pseudos.empty(e)},header:function(e){return Q.test(e.nodeName)},input:function(e){return G.test(e.nodeName)},button:function(e){var t=e.nodeName.toLowerCase();return"input"===t&&"button"===e.type||"button"===t},text:function(e){var t;return"input"===e.nodeName.toLowerCase()&&"text"===e.type&&(null==(t=e.getAttribute("type"))||t.toLowerCase()===e.type)},first:pt(function(){return[0]}),last:pt(function(e,t){return[t-1]}),eq:pt(function(e,t,n){return[0>n?n+t:n]}),even:pt(function(e,t){var n=0;for(;t>n;n+=2)e.push(n);return e}),odd:pt(function(e,t){var n=1;for(;t>n;n+=2)e.push(n);return e}),lt:pt(function(e,t,n){var r=0>n?n+t:n;for(;--r>=0;)e.push(r);return e}),gt:pt(function(e,t,n){var r=0>n?n+t:n;for(;t>++r;)e.push(r);return e})}};for(n in{radio:!0,checkbox:!0,file:!0,password:!0,image:!0})i.pseudos[n]=lt(n);for(n in{submit:!0,reset:!0})i.pseudos[n]=ct(n);function ft(e,t){var n,r,o,a,s,u,l,c=E[e+" "];if(c)return t?0:c.slice(0);s=e,u=[],l=i.preFilter;while(s){(!n||(r=$.exec(s)))&&(r&&(s=s.slice(r[0].length)||s),u.push(o=[])),n=!1,(r=I.exec(s))&&(n=r.shift(),o.push({value:n,type:r[0].replace(W," ")}),s=s.slice(n.length));for(a in i.filter)!(r=U[a].exec(s))||l[a]&&!(r=l[a](r))||(n=r.shift(),o.push({value:n,type:a,matches:r}),s=s.slice(n.length));if(!n)break}return t?s.length:s?st.error(e):E(e,u).slice(0)}function dt(e){var t=0,n=e.length,r="";for(;n>t;t++)r+=e[t].value;return r}function ht(e,t,n){var i=t.dir,o=n&&"parentNode"===i,a=C++;return t.first?function(t,n,r){while(t=t[i])if(1===t.nodeType||o)return e(t,n,r)}:function(t,n,s){var u,l,c,p=N+" "+a;if(s){while(t=t[i])if((1===t.nodeType||o)&&e(t,n,s))return!0}else while(t=t[i])if(1===t.nodeType||o)if(c=t[x]||(t[x]={}),(l=c[i])&&l[0]===p){if((u=l[1])===!0||u===r)return u===!0}else if(l=c[i]=[p],l[1]=e(t,n,s)||r,l[1]===!0)return!0}}function gt(e){return e.length>1?function(t,n,r){var i=e.length;while(i--)if(!e[i](t,n,r))return!1;return!0}:e[0]}function mt(e,t,n,r,i){var o,a=[],s=0,u=e.length,l=null!=t;for(;u>s;s++)(o=e[s])&&(!n||n(o,r,i))&&(a.push(o),l&&t.push(s));return a}function yt(e,t,n,r,i,o){return r&&!r[x]&&(r=yt(r)),i&&!i[x]&&(i=yt(i,o)),ot(function(o,a,s,u){var l,c,p,f=[],d=[],h=a.length,g=o||xt(t||"*",s.nodeType?[s]:s,[]),m=!e||!o&&t?g:mt(g,f,e,s,u),y=n?i||(o?e:h||r)?[]:a:m;if(n&&n(m,y,s,u),r){l=mt(y,d),r(l,[],s,u),c=l.length;while(c--)(p=l[c])&&(y[d[c]]=!(m[d[c]]=p))}if(o){if(i||e){if(i){l=[],c=y.length;while(c--)(p=y[c])&&l.push(m[c]=p);i(null,y=[],l,u)}c=y.length;while(c--)(p=y[c])&&(l=i?M.call(o,p):f[c])>-1&&(o[l]=!(a[l]=p))}}else y=mt(y===a?y.splice(h,y.length):y),i?i(null,a,y,u):H.apply(a,y)})}function vt(e){var t,n,r,o=e.length,a=i.relative[e[0].type],s=a||i.relative[" "],u=a?1:0,c=ht(function(e){return e===t},s,!0),p=ht(function(e){return M.call(t,e)>-1},s,!0),f=[function(e,n,r){return!a&&(r||n!==l)||((t=n).nodeType?c(e,n,r):p(e,n,r))}];for(;o>u;u++)if(n=i.relative[e[u].type])f=[ht(gt(f),n)];else{if(n=i.filter[e[u].type].apply(null,e[u].matches),n[x]){for(r=++u;o>r;r++)if(i.relative[e[r].type])break;return yt(u>1&&gt(f),u>1&&dt(e.slice(0,u-1)).replace(W,"$1"),n,r>u&&vt(e.slice(u,r)),o>r&&vt(e=e.slice(r)),o>r&&dt(e))}f.push(n)}return gt(f)}function bt(e,t){var n=0,o=t.length>0,a=e.length>0,s=function(s,u,c,f,d){var h,g,m,y=[],v=0,b="0",x=s&&[],w=null!=d,T=l,C=s||a&&i.find.TAG("*",d&&u.parentNode||u),k=N+=null==T?1:Math.random()||.1;for(w&&(l=u!==p&&u,r=n);null!=(h=C[b]);b++){if(a&&h){g=0;while(m=e[g++])if(m(h,u,c)){f.push(h);break}w&&(N=k,r=++n)}o&&((h=!m&&h)&&v--,s&&x.push(h))}if(v+=b,o&&b!==v){g=0;while(m=t[g++])m(x,y,u,c);if(s){if(v>0)while(b--)x[b]||y[b]||(y[b]=L.call(f));y=mt(y)}H.apply(f,y),w&&!s&&y.length>0&&v+t.length>1&&st.uniqueSort(f)}return w&&(N=k,l=T),x};return o?ot(s):s}s=st.compile=function(e,t){var n,r=[],i=[],o=S[e+" "];if(!o){t||(t=ft(e)),n=t.length;while(n--)o=vt(t[n]),o[x]?r.push(o):i.push(o);o=S(e,bt(i,r))}return o};function xt(e,t,n){var r=0,i=t.length;for(;i>r;r++)st(e,t[r],n);return n}function wt(e,t,n,r){var o,a,u,l,c,p=ft(e);if(!r&&1===p.length){if(a=p[0]=p[0].slice(0),a.length>2&&"ID"===(u=a[0]).type&&9===t.nodeType&&!d&&i.relative[a[1].type]){if(t=i.find.ID(u.matches[0].replace(et,tt),t)[0],!t)return n;e=e.slice(a.shift().value.length)}o=U.needsContext.test(e)?0:a.length;while(o--){if(u=a[o],i.relative[l=u.type])break;if((c=i.find[l])&&(r=c(u.matches[0].replace(et,tt),V.test(a[0].type)&&t.parentNode||t))){if(a.splice(o,1),e=r.length&&dt(a),!e)return H.apply(n,q.call(r,0)),n;break}}}return s(e,p)(r,t,d,n,V.test(e)),n}i.pseudos.nth=i.pseudos.eq;function Tt(){}i.filters=Tt.prototype=i.pseudos,i.setFilters=new Tt,c(),st.attr=b.attr,b.find=st,b.expr=st.selectors,b.expr[":"]=b.expr.pseudos,b.unique=st.uniqueSort,b.text=st.getText,b.isXMLDoc=st.isXML,b.contains=st.contains}(e);var at=/Until$/,st=/^(?:parents|prev(?:Until|All))/,ut=/^.[^:#\[\.,]*$/,lt=b.expr.match.needsContext,ct={children:!0,contents:!0,next:!0,prev:!0};b.fn.extend({find:function(e){var t,n,r,i=this.length;if("string"!=typeof e)return r=this,this.pushStack(b(e).filter(function(){for(t=0;i>t;t++)if(b.contains(r[t],this))return!0}));for(n=[],t=0;i>t;t++)b.find(e,this[t],n);return n=this.pushStack(i>1?b.unique(n):n),n.selector=(this.selector?this.selector+" ":"")+e,n},has:function(e){var t,n=b(e,this),r=n.length;return this.filter(function(){for(t=0;r>t;t++)if(b.contains(this,n[t]))return!0})},not:function(e){return this.pushStack(ft(this,e,!1))},filter:function(e){return this.pushStack(ft(this,e,!0))},is:function(e){return!!e&&("string"==typeof e?lt.test(e)?b(e,this.context).index(this[0])>=0:b.filter(e,this).length>0:this.filter(e).length>0)},closest:function(e,t){var n,r=0,i=this.length,o=[],a=lt.test(e)||"string"!=typeof e?b(e,t||this.context):0;for(;i>r;r++){n=this[r];while(n&&n.ownerDocument&&n!==t&&11!==n.nodeType){if(a?a.index(n)>-1:b.find.matchesSelector(n,e)){o.push(n);break}n=n.parentNode}}return this.pushStack(o.length>1?b.unique(o):o)},index:function(e){return e?"string"==typeof e?b.inArray(this[0],b(e)):b.inArray(e.jquery?e[0]:e,this):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(e,t){var n="string"==typeof e?b(e,t):b.makeArray(e&&e.nodeType?[e]:e),r=b.merge(this.get(),n);return this.pushStack(b.unique(r))},addBack:function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}}),b.fn.andSelf=b.fn.addBack;function pt(e,t){do e=e[t];while(e&&1!==e.nodeType);return e}b.each({parent:function(e){var t=e.parentNode;return t&&11!==t.nodeType?t:null},parents:function(e){return b.dir(e,"parentNode")},parentsUntil:function(e,t,n){return b.dir(e,"parentNode",n)},next:function(e){return pt(e,"nextSibling")},prev:function(e){return pt(e,"previousSibling")},nextAll:function(e){return b.dir(e,"nextSibling")},prevAll:function(e){return b.dir(e,"previousSibling")},nextUntil:function(e,t,n){return b.dir(e,"nextSibling",n)},prevUntil:function(e,t,n){return b.dir(e,"previousSibling",n)},siblings:function(e){return b.sibling((e.parentNode||{}).firstChild,e)},children:function(e){return b.sibling(e.firstChild)},contents:function(e){return b.nodeName(e,"iframe")?e.contentDocument||e.contentWindow.document:b.merge([],e.childNodes)}},function(e,t){b.fn[e]=function(n,r){var i=b.map(this,t,n);return at.test(e)||(r=n),r&&"string"==typeof r&&(i=b.filter(r,i)),i=this.length>1&&!ct[e]?b.unique(i):i,this.length>1&&st.test(e)&&(i=i.reverse()),this.pushStack(i)}}),b.extend({filter:function(e,t,n){return n&&(e=":not("+e+")"),1===t.length?b.find.matchesSelector(t[0],e)?[t[0]]:[]:b.find.matches(e,t)},dir:function(e,n,r){var i=[],o=e[n];while(o&&9!==o.nodeType&&(r===t||1!==o.nodeType||!b(o).is(r)))1===o.nodeType&&i.push(o),o=o[n];return i},sibling:function(e,t){var n=[];for(;e;e=e.nextSibling)1===e.nodeType&&e!==t&&n.push(e);return n}});function ft(e,t,n){if(t=t||0,b.isFunction(t))return b.grep(e,function(e,r){var i=!!t.call(e,r,e);return i===n});if(t.nodeType)return b.grep(e,function(e){return e===t===n});if("string"==typeof t){var r=b.grep(e,function(e){return 1===e.nodeType});if(ut.test(t))return b.filter(t,r,!n);t=b.filter(t,r)}return b.grep(e,function(e){return b.inArray(e,t)>=0===n})}function dt(e){var t=ht.split("|"),n=e.createDocumentFragment();if(n.createElement)while(t.length)n.createElement(t.pop());return n}var ht="abbr|article|aside|audio|bdi|canvas|data|datalist|details|figcaption|figure|footer|header|hgroup|mark|meter|nav|output|progress|section|summary|time|video",gt=/ jQuery\d+="(?:null|\d+)"/g,mt=RegExp("<(?:"+ht+")[\\s/>]","i"),yt=/^\s+/,vt=/<(?!area|br|col|embed|hr|img|input|link|meta|param)(([\w:]+)[^>]*)\/>/gi,bt=/<([\w:]+)/,xt=/<tbody/i,wt=/<|&#?\w+;/,Tt=/<(?:script|style|link)/i,Nt=/^(?:checkbox|radio)$/i,Ct=/checked\s*(?:[^=]|=\s*.checked.)/i,kt=/^$|\/(?:java|ecma)script/i,Et=/^true\/(.*)/,St=/^\s*<!(?:\[CDATA\[|--)|(?:\]\]|--)>\s*$/g,At={option:[1,"<select multiple='multiple'>","</select>"],legend:[1,"<fieldset>","</fieldset>"],area:[1,"<map>","</map>"],param:[1,"<object>","</object>"],thead:[1,"<table>","</table>"],tr:[2,"<table><tbody>","</tbody></table>"],col:[2,"<table><tbody></tbody><colgroup>","</colgroup></table>"],td:[3,"<table><tbody><tr>","</tr></tbody></table>"],_default:b.support.htmlSerialize?[0,"",""]:[1,"X<div>","</div>"]},jt=dt(o),Dt=jt.appendChild(o.createElement("div"));At.optgroup=At.option,At.tbody=At.tfoot=At.colgroup=At.caption=At.thead,At.th=At.td,b.fn.extend({text:function(e){return b.access(this,function(e){return e===t?b.text(this):this.empty().append((this[0]&&this[0].ownerDocument||o).createTextNode(e))},null,e,arguments.length)},wrapAll:function(e){if(b.isFunction(e))return this.each(function(t){b(this).wrapAll(e.call(this,t))});if(this[0]){var t=b(e,this[0].ownerDocument).eq(0).clone(!0);this[0].parentNode&&t.insertBefore(this[0]),t.map(function(){var e=this;while(e.firstChild&&1===e.firstChild.nodeType)e=e.firstChild;return e}).append(this)}return this},wrapInner:function(e){return b.isFunction(e)?this.each(function(t){b(this).wrapInner(e.call(this,t))}):this.each(function(){var t=b(this),n=t.contents();n.length?n.wrapAll(e):t.append(e)})},wrap:function(e){var t=b.isFunction(e);return this.each(function(n){b(this).wrapAll(t?e.call(this,n):e)})},unwrap:function(){return this.parent().each(function(){b.nodeName(this,"body")||b(this).replaceWith(this.childNodes)}).end()},append:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.appendChild(e)})},prepend:function(){return this.domManip(arguments,!0,function(e){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&this.insertBefore(e,this.firstChild)})},before:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this)})},after:function(){return this.domManip(arguments,!1,function(e){this.parentNode&&this.parentNode.insertBefore(e,this.nextSibling)})},remove:function(e,t){var n,r=0;for(;null!=(n=this[r]);r++)(!e||b.filter(e,[n]).length>0)&&(t||1!==n.nodeType||b.cleanData(Ot(n)),n.parentNode&&(t&&b.contains(n.ownerDocument,n)&&Mt(Ot(n,"script")),n.parentNode.removeChild(n)));return this},empty:function(){var e,t=0;for(;null!=(e=this[t]);t++){1===e.nodeType&&b.cleanData(Ot(e,!1));while(e.firstChild)e.removeChild(e.firstChild);e.options&&b.nodeName(e,"select")&&(e.options.length=0)}return this},clone:function(e,t){return e=null==e?!1:e,t=null==t?e:t,this.map(function(){return b.clone(this,e,t)})},html:function(e){return b.access(this,function(e){var n=this[0]||{},r=0,i=this.length;if(e===t)return 1===n.nodeType?n.innerHTML.replace(gt,""):t;if(!("string"!=typeof e||Tt.test(e)||!b.support.htmlSerialize&&mt.test(e)||!b.support.leadingWhitespace&&yt.test(e)||At[(bt.exec(e)||["",""])[1].toLowerCase()])){e=e.replace(vt,"<$1></$2>");try{for(;i>r;r++)n=this[r]||{},1===n.nodeType&&(b.cleanData(Ot(n,!1)),n.innerHTML=e);n=0}catch(o){}}n&&this.empty().append(e)},null,e,arguments.length)},replaceWith:function(e){var t=b.isFunction(e);return t||"string"==typeof e||(e=b(e).not(this).detach()),this.domManip([e],!0,function(e){var t=this.nextSibling,n=this.parentNode;n&&(b(this).remove(),n.insertBefore(e,t))})},detach:function(e){return this.remove(e,!0)},domManip:function(e,n,r){e=f.apply([],e);var i,o,a,s,u,l,c=0,p=this.length,d=this,h=p-1,g=e[0],m=b.isFunction(g);if(m||!(1>=p||"string"!=typeof g||b.support.checkClone)&&Ct.test(g))return this.each(function(i){var o=d.eq(i);m&&(e[0]=g.call(this,i,n?o.html():t)),o.domManip(e,n,r)});if(p&&(l=b.buildFragment(e,this[0].ownerDocument,!1,this),i=l.firstChild,1===l.childNodes.length&&(l=i),i)){for(n=n&&b.nodeName(i,"tr"),s=b.map(Ot(l,"script"),Ht),a=s.length;p>c;c++)o=l,c!==h&&(o=b.clone(o,!0,!0),a&&b.merge(s,Ot(o,"script"))),r.call(n&&b.nodeName(this[c],"table")?Lt(this[c],"tbody"):this[c],o,c);if(a)for(u=s[s.length-1].ownerDocument,b.map(s,qt),c=0;a>c;c++)o=s[c],kt.test(o.type||"")&&!b._data(o,"globalEval")&&b.contains(u,o)&&(o.src?b.ajax({url:o.src,type:"GET",dataType:"script",async:!1,global:!1,"throws":!0}):b.globalEval((o.text||o.textContent||o.innerHTML||"").replace(St,"")));l=i=null}return this}});function Lt(e,t){return e.getElementsByTagName(t)[0]||e.appendChild(e.ownerDocument.createElement(t))}function Ht(e){var t=e.getAttributeNode("type");return e.type=(t&&t.specified)+"/"+e.type,e}function qt(e){var t=Et.exec(e.type);return t?e.type=t[1]:e.removeAttribute("type"),e}function Mt(e,t){var n,r=0;for(;null!=(n=e[r]);r++)b._data(n,"globalEval",!t||b._data(t[r],"globalEval"))}function _t(e,t){if(1===t.nodeType&&b.hasData(e)){var n,r,i,o=b._data(e),a=b._data(t,o),s=o.events;if(s){delete a.handle,a.events={};for(n in s)for(r=0,i=s[n].length;i>r;r++)b.event.add(t,n,s[n][r])}a.data&&(a.data=b.extend({},a.data))}}function Ft(e,t){var n,r,i;if(1===t.nodeType){if(n=t.nodeName.toLowerCase(),!b.support.noCloneEvent&&t[b.expando]){i=b._data(t);for(r in i.events)b.removeEvent(t,r,i.handle);t.removeAttribute(b.expando)}"script"===n&&t.text!==e.text?(Ht(t).text=e.text,qt(t)):"object"===n?(t.parentNode&&(t.outerHTML=e.outerHTML),b.support.html5Clone&&e.innerHTML&&!b.trim(t.innerHTML)&&(t.innerHTML=e.innerHTML)):"input"===n&&Nt.test(e.type)?(t.defaultChecked=t.checked=e.checked,t.value!==e.value&&(t.value=e.value)):"option"===n?t.defaultSelected=t.selected=e.defaultSelected:("input"===n||"textarea"===n)&&(t.defaultValue=e.defaultValue)}}b.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(e,t){b.fn[e]=function(e){var n,r=0,i=[],o=b(e),a=o.length-1;for(;a>=r;r++)n=r===a?this:this.clone(!0),b(o[r])[t](n),d.apply(i,n.get());return this.pushStack(i)}});function Ot(e,n){var r,o,a=0,s=typeof e.getElementsByTagName!==i?e.getElementsByTagName(n||"*"):typeof e.querySelectorAll!==i?e.querySelectorAll(n||"*"):t;if(!s)for(s=[],r=e.childNodes||e;null!=(o=r[a]);a++)!n||b.nodeName(o,n)?s.push(o):b.merge(s,Ot(o,n));return n===t||n&&b.nodeName(e,n)?b.merge([e],s):s}function Bt(e){Nt.test(e.type)&&(e.defaultChecked=e.checked)}b.extend({clone:function(e,t,n){var r,i,o,a,s,u=b.contains(e.ownerDocument,e);if(b.support.html5Clone||b.isXMLDoc(e)||!mt.test("<"+e.nodeName+">")?o=e.cloneNode(!0):(Dt.innerHTML=e.outerHTML,Dt.removeChild(o=Dt.firstChild)),!(b.support.noCloneEvent&&b.support.noCloneChecked||1!==e.nodeType&&11!==e.nodeType||b.isXMLDoc(e)))for(r=Ot(o),s=Ot(e),a=0;null!=(i=s[a]);++a)r[a]&&Ft(i,r[a]);if(t)if(n)for(s=s||Ot(e),r=r||Ot(o),a=0;null!=(i=s[a]);a++)_t(i,r[a]);else _t(e,o);return r=Ot(o,"script"),r.length>0&&Mt(r,!u&&Ot(e,"script")),r=s=i=null,o},buildFragment:function(e,t,n,r){var i,o,a,s,u,l,c,p=e.length,f=dt(t),d=[],h=0;for(;p>h;h++)if(o=e[h],o||0===o)if("object"===b.type(o))b.merge(d,o.nodeType?[o]:o);else if(wt.test(o)){s=s||f.appendChild(t.createElement("div")),u=(bt.exec(o)||["",""])[1].toLowerCase(),c=At[u]||At._default,s.innerHTML=c[1]+o.replace(vt,"<$1></$2>")+c[2],i=c[0];while(i--)s=s.lastChild;if(!b.support.leadingWhitespace&&yt.test(o)&&d.push(t.createTextNode(yt.exec(o)[0])),!b.support.tbody){o="table"!==u||xt.test(o)?"<table>"!==c[1]||xt.test(o)?0:s:s.firstChild,i=o&&o.childNodes.length;while(i--)b.nodeName(l=o.childNodes[i],"tbody")&&!l.childNodes.length&&o.removeChild(l)
+}b.merge(d,s.childNodes),s.textContent="";while(s.firstChild)s.removeChild(s.firstChild);s=f.lastChild}else d.push(t.createTextNode(o));s&&f.removeChild(s),b.support.appendChecked||b.grep(Ot(d,"input"),Bt),h=0;while(o=d[h++])if((!r||-1===b.inArray(o,r))&&(a=b.contains(o.ownerDocument,o),s=Ot(f.appendChild(o),"script"),a&&Mt(s),n)){i=0;while(o=s[i++])kt.test(o.type||"")&&n.push(o)}return s=null,f},cleanData:function(e,t){var n,r,o,a,s=0,u=b.expando,l=b.cache,p=b.support.deleteExpando,f=b.event.special;for(;null!=(n=e[s]);s++)if((t||b.acceptData(n))&&(o=n[u],a=o&&l[o])){if(a.events)for(r in a.events)f[r]?b.event.remove(n,r):b.removeEvent(n,r,a.handle);l[o]&&(delete l[o],p?delete n[u]:typeof n.removeAttribute!==i?n.removeAttribute(u):n[u]=null,c.push(o))}}});var Pt,Rt,Wt,$t=/alpha\([^)]*\)/i,It=/opacity\s*=\s*([^)]*)/,zt=/^(top|right|bottom|left)$/,Xt=/^(none|table(?!-c[ea]).+)/,Ut=/^margin/,Vt=RegExp("^("+x+")(.*)$","i"),Yt=RegExp("^("+x+")(?!px)[a-z%]+$","i"),Jt=RegExp("^([+-])=("+x+")","i"),Gt={BODY:"block"},Qt={position:"absolute",visibility:"hidden",display:"block"},Kt={letterSpacing:0,fontWeight:400},Zt=["Top","Right","Bottom","Left"],en=["Webkit","O","Moz","ms"];function tn(e,t){if(t in e)return t;var n=t.charAt(0).toUpperCase()+t.slice(1),r=t,i=en.length;while(i--)if(t=en[i]+n,t in e)return t;return r}function nn(e,t){return e=t||e,"none"===b.css(e,"display")||!b.contains(e.ownerDocument,e)}function rn(e,t){var n,r,i,o=[],a=0,s=e.length;for(;s>a;a++)r=e[a],r.style&&(o[a]=b._data(r,"olddisplay"),n=r.style.display,t?(o[a]||"none"!==n||(r.style.display=""),""===r.style.display&&nn(r)&&(o[a]=b._data(r,"olddisplay",un(r.nodeName)))):o[a]||(i=nn(r),(n&&"none"!==n||!i)&&b._data(r,"olddisplay",i?n:b.css(r,"display"))));for(a=0;s>a;a++)r=e[a],r.style&&(t&&"none"!==r.style.display&&""!==r.style.display||(r.style.display=t?o[a]||"":"none"));return e}b.fn.extend({css:function(e,n){return b.access(this,function(e,n,r){var i,o,a={},s=0;if(b.isArray(n)){for(o=Rt(e),i=n.length;i>s;s++)a[n[s]]=b.css(e,n[s],!1,o);return a}return r!==t?b.style(e,n,r):b.css(e,n)},e,n,arguments.length>1)},show:function(){return rn(this,!0)},hide:function(){return rn(this)},toggle:function(e){var t="boolean"==typeof e;return this.each(function(){(t?e:nn(this))?b(this).show():b(this).hide()})}}),b.extend({cssHooks:{opacity:{get:function(e,t){if(t){var n=Wt(e,"opacity");return""===n?"1":n}}}},cssNumber:{columnCount:!0,fillOpacity:!0,fontWeight:!0,lineHeight:!0,opacity:!0,orphans:!0,widows:!0,zIndex:!0,zoom:!0},cssProps:{"float":b.support.cssFloat?"cssFloat":"styleFloat"},style:function(e,n,r,i){if(e&&3!==e.nodeType&&8!==e.nodeType&&e.style){var o,a,s,u=b.camelCase(n),l=e.style;if(n=b.cssProps[u]||(b.cssProps[u]=tn(l,u)),s=b.cssHooks[n]||b.cssHooks[u],r===t)return s&&"get"in s&&(o=s.get(e,!1,i))!==t?o:l[n];if(a=typeof r,"string"===a&&(o=Jt.exec(r))&&(r=(o[1]+1)*o[2]+parseFloat(b.css(e,n)),a="number"),!(null==r||"number"===a&&isNaN(r)||("number"!==a||b.cssNumber[u]||(r+="px"),b.support.clearCloneStyle||""!==r||0!==n.indexOf("background")||(l[n]="inherit"),s&&"set"in s&&(r=s.set(e,r,i))===t)))try{l[n]=r}catch(c){}}},css:function(e,n,r,i){var o,a,s,u=b.camelCase(n);return n=b.cssProps[u]||(b.cssProps[u]=tn(e.style,u)),s=b.cssHooks[n]||b.cssHooks[u],s&&"get"in s&&(a=s.get(e,!0,r)),a===t&&(a=Wt(e,n,i)),"normal"===a&&n in Kt&&(a=Kt[n]),""===r||r?(o=parseFloat(a),r===!0||b.isNumeric(o)?o||0:a):a},swap:function(e,t,n,r){var i,o,a={};for(o in t)a[o]=e.style[o],e.style[o]=t[o];i=n.apply(e,r||[]);for(o in t)e.style[o]=a[o];return i}}),e.getComputedStyle?(Rt=function(t){return e.getComputedStyle(t,null)},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s.getPropertyValue(n)||s[n]:t,l=e.style;return s&&(""!==u||b.contains(e.ownerDocument,e)||(u=b.style(e,n)),Yt.test(u)&&Ut.test(n)&&(i=l.width,o=l.minWidth,a=l.maxWidth,l.minWidth=l.maxWidth=l.width=u,u=s.width,l.width=i,l.minWidth=o,l.maxWidth=a)),u}):o.documentElement.currentStyle&&(Rt=function(e){return e.currentStyle},Wt=function(e,n,r){var i,o,a,s=r||Rt(e),u=s?s[n]:t,l=e.style;return null==u&&l&&l[n]&&(u=l[n]),Yt.test(u)&&!zt.test(n)&&(i=l.left,o=e.runtimeStyle,a=o&&o.left,a&&(o.left=e.currentStyle.left),l.left="fontSize"===n?"1em":u,u=l.pixelLeft+"px",l.left=i,a&&(o.left=a)),""===u?"auto":u});function on(e,t,n){var r=Vt.exec(t);return r?Math.max(0,r[1]-(n||0))+(r[2]||"px"):t}function an(e,t,n,r,i){var o=n===(r?"border":"content")?4:"width"===t?1:0,a=0;for(;4>o;o+=2)"margin"===n&&(a+=b.css(e,n+Zt[o],!0,i)),r?("content"===n&&(a-=b.css(e,"padding"+Zt[o],!0,i)),"margin"!==n&&(a-=b.css(e,"border"+Zt[o]+"Width",!0,i))):(a+=b.css(e,"padding"+Zt[o],!0,i),"padding"!==n&&(a+=b.css(e,"border"+Zt[o]+"Width",!0,i)));return a}function sn(e,t,n){var r=!0,i="width"===t?e.offsetWidth:e.offsetHeight,o=Rt(e),a=b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,o);if(0>=i||null==i){if(i=Wt(e,t,o),(0>i||null==i)&&(i=e.style[t]),Yt.test(i))return i;r=a&&(b.support.boxSizingReliable||i===e.style[t]),i=parseFloat(i)||0}return i+an(e,t,n||(a?"border":"content"),r,o)+"px"}function un(e){var t=o,n=Gt[e];return n||(n=ln(e,t),"none"!==n&&n||(Pt=(Pt||b("<iframe frameborder='0' width='0' height='0'/>").css("cssText","display:block !important")).appendTo(t.documentElement),t=(Pt[0].contentWindow||Pt[0].contentDocument).document,t.write("<!doctype html><html><body>"),t.close(),n=ln(e,t),Pt.detach()),Gt[e]=n),n}function ln(e,t){var n=b(t.createElement(e)).appendTo(t.body),r=b.css(n[0],"display");return n.remove(),r}b.each(["height","width"],function(e,n){b.cssHooks[n]={get:function(e,r,i){return r?0===e.offsetWidth&&Xt.test(b.css(e,"display"))?b.swap(e,Qt,function(){return sn(e,n,i)}):sn(e,n,i):t},set:function(e,t,r){var i=r&&Rt(e);return on(e,t,r?an(e,n,r,b.support.boxSizing&&"border-box"===b.css(e,"boxSizing",!1,i),i):0)}}}),b.support.opacity||(b.cssHooks.opacity={get:function(e,t){return It.test((t&&e.currentStyle?e.currentStyle.filter:e.style.filter)||"")?.01*parseFloat(RegExp.$1)+"":t?"1":""},set:function(e,t){var n=e.style,r=e.currentStyle,i=b.isNumeric(t)?"alpha(opacity="+100*t+")":"",o=r&&r.filter||n.filter||"";n.zoom=1,(t>=1||""===t)&&""===b.trim(o.replace($t,""))&&n.removeAttribute&&(n.removeAttribute("filter"),""===t||r&&!r.filter)||(n.filter=$t.test(o)?o.replace($t,i):o+" "+i)}}),b(function(){b.support.reliableMarginRight||(b.cssHooks.marginRight={get:function(e,n){return n?b.swap(e,{display:"inline-block"},Wt,[e,"marginRight"]):t}}),!b.support.pixelPosition&&b.fn.position&&b.each(["top","left"],function(e,n){b.cssHooks[n]={get:function(e,r){return r?(r=Wt(e,n),Yt.test(r)?b(e).position()[n]+"px":r):t}}})}),b.expr&&b.expr.filters&&(b.expr.filters.hidden=function(e){return 0>=e.offsetWidth&&0>=e.offsetHeight||!b.support.reliableHiddenOffsets&&"none"===(e.style&&e.style.display||b.css(e,"display"))},b.expr.filters.visible=function(e){return!b.expr.filters.hidden(e)}),b.each({margin:"",padding:"",border:"Width"},function(e,t){b.cssHooks[e+t]={expand:function(n){var r=0,i={},o="string"==typeof n?n.split(" "):[n];for(;4>r;r++)i[e+Zt[r]+t]=o[r]||o[r-2]||o[0];return i}},Ut.test(e)||(b.cssHooks[e+t].set=on)});var cn=/%20/g,pn=/\[\]$/,fn=/\r?\n/g,dn=/^(?:submit|button|image|reset|file)$/i,hn=/^(?:input|select|textarea|keygen)/i;b.fn.extend({serialize:function(){return b.param(this.serializeArray())},serializeArray:function(){return this.map(function(){var e=b.prop(this,"elements");return e?b.makeArray(e):this}).filter(function(){var e=this.type;return this.name&&!b(this).is(":disabled")&&hn.test(this.nodeName)&&!dn.test(e)&&(this.checked||!Nt.test(e))}).map(function(e,t){var n=b(this).val();return null==n?null:b.isArray(n)?b.map(n,function(e){return{name:t.name,value:e.replace(fn,"\r\n")}}):{name:t.name,value:n.replace(fn,"\r\n")}}).get()}}),b.param=function(e,n){var r,i=[],o=function(e,t){t=b.isFunction(t)?t():null==t?"":t,i[i.length]=encodeURIComponent(e)+"="+encodeURIComponent(t)};if(n===t&&(n=b.ajaxSettings&&b.ajaxSettings.traditional),b.isArray(e)||e.jquery&&!b.isPlainObject(e))b.each(e,function(){o(this.name,this.value)});else for(r in e)gn(r,e[r],n,o);return i.join("&").replace(cn,"+")};function gn(e,t,n,r){var i;if(b.isArray(t))b.each(t,function(t,i){n||pn.test(e)?r(e,i):gn(e+"["+("object"==typeof i?t:"")+"]",i,n,r)});else if(n||"object"!==b.type(t))r(e,t);else for(i in t)gn(e+"["+i+"]",t[i],n,r)}b.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(e,t){b.fn[t]=function(e,n){return arguments.length>0?this.on(t,null,e,n):this.trigger(t)}}),b.fn.hover=function(e,t){return this.mouseenter(e).mouseleave(t||e)};var mn,yn,vn=b.now(),bn=/\?/,xn=/#.*$/,wn=/([?&])_=[^&]*/,Tn=/^(.*?):[ \t]*([^\r\n]*)\r?$/gm,Nn=/^(?:about|app|app-storage|.+-extension|file|res|widget):$/,Cn=/^(?:GET|HEAD)$/,kn=/^\/\//,En=/^([\w.+-]+:)(?:\/\/([^\/?#:]*)(?::(\d+)|)|)/,Sn=b.fn.load,An={},jn={},Dn="*/".concat("*");try{yn=a.href}catch(Ln){yn=o.createElement("a"),yn.href="",yn=yn.href}mn=En.exec(yn.toLowerCase())||[];function Hn(e){return function(t,n){"string"!=typeof t&&(n=t,t="*");var r,i=0,o=t.toLowerCase().match(w)||[];if(b.isFunction(n))while(r=o[i++])"+"===r[0]?(r=r.slice(1)||"*",(e[r]=e[r]||[]).unshift(n)):(e[r]=e[r]||[]).push(n)}}function qn(e,n,r,i){var o={},a=e===jn;function s(u){var l;return o[u]=!0,b.each(e[u]||[],function(e,u){var c=u(n,r,i);return"string"!=typeof c||a||o[c]?a?!(l=c):t:(n.dataTypes.unshift(c),s(c),!1)}),l}return s(n.dataTypes[0])||!o["*"]&&s("*")}function Mn(e,n){var r,i,o=b.ajaxSettings.flatOptions||{};for(i in n)n[i]!==t&&((o[i]?e:r||(r={}))[i]=n[i]);return r&&b.extend(!0,e,r),e}b.fn.load=function(e,n,r){if("string"!=typeof e&&Sn)return Sn.apply(this,arguments);var i,o,a,s=this,u=e.indexOf(" ");return u>=0&&(i=e.slice(u,e.length),e=e.slice(0,u)),b.isFunction(n)?(r=n,n=t):n&&"object"==typeof n&&(a="POST"),s.length>0&&b.ajax({url:e,type:a,dataType:"html",data:n}).done(function(e){o=arguments,s.html(i?b("<div>").append(b.parseHTML(e)).find(i):e)}).complete(r&&function(e,t){s.each(r,o||[e.responseText,t,e])}),this},b.each(["ajaxStart","ajaxStop","ajaxComplete","ajaxError","ajaxSuccess","ajaxSend"],function(e,t){b.fn[t]=function(e){return this.on(t,e)}}),b.each(["get","post"],function(e,n){b[n]=function(e,r,i,o){return b.isFunction(r)&&(o=o||i,i=r,r=t),b.ajax({url:e,type:n,dataType:o,data:r,success:i})}}),b.extend({active:0,lastModified:{},etag:{},ajaxSettings:{url:yn,type:"GET",isLocal:Nn.test(mn[1]),global:!0,processData:!0,async:!0,contentType:"application/x-www-form-urlencoded; charset=UTF-8",accepts:{"*":Dn,text:"text/plain",html:"text/html",xml:"application/xml, text/xml",json:"application/json, text/javascript"},contents:{xml:/xml/,html:/html/,json:/json/},responseFields:{xml:"responseXML",text:"responseText"},converters:{"* text":e.String,"text html":!0,"text json":b.parseJSON,"text xml":b.parseXML},flatOptions:{url:!0,context:!0}},ajaxSetup:function(e,t){return t?Mn(Mn(e,b.ajaxSettings),t):Mn(b.ajaxSettings,e)},ajaxPrefilter:Hn(An),ajaxTransport:Hn(jn),ajax:function(e,n){"object"==typeof e&&(n=e,e=t),n=n||{};var r,i,o,a,s,u,l,c,p=b.ajaxSetup({},n),f=p.context||p,d=p.context&&(f.nodeType||f.jquery)?b(f):b.event,h=b.Deferred(),g=b.Callbacks("once memory"),m=p.statusCode||{},y={},v={},x=0,T="canceled",N={readyState:0,getResponseHeader:function(e){var t;if(2===x){if(!c){c={};while(t=Tn.exec(a))c[t[1].toLowerCase()]=t[2]}t=c[e.toLowerCase()]}return null==t?null:t},getAllResponseHeaders:function(){return 2===x?a:null},setRequestHeader:function(e,t){var n=e.toLowerCase();return x||(e=v[n]=v[n]||e,y[e]=t),this},overrideMimeType:function(e){return x||(p.mimeType=e),this},statusCode:function(e){var t;if(e)if(2>x)for(t in e)m[t]=[m[t],e[t]];else N.always(e[N.status]);return this},abort:function(e){var t=e||T;return l&&l.abort(t),k(0,t),this}};if(h.promise(N).complete=g.add,N.success=N.done,N.error=N.fail,p.url=((e||p.url||yn)+"").replace(xn,"").replace(kn,mn[1]+"//"),p.type=n.method||n.type||p.method||p.type,p.dataTypes=b.trim(p.dataType||"*").toLowerCase().match(w)||[""],null==p.crossDomain&&(r=En.exec(p.url.toLowerCase()),p.crossDomain=!(!r||r[1]===mn[1]&&r[2]===mn[2]&&(r[3]||("http:"===r[1]?80:443))==(mn[3]||("http:"===mn[1]?80:443)))),p.data&&p.processData&&"string"!=typeof p.data&&(p.data=b.param(p.data,p.traditional)),qn(An,p,n,N),2===x)return N;u=p.global,u&&0===b.active++&&b.event.trigger("ajaxStart"),p.type=p.type.toUpperCase(),p.hasContent=!Cn.test(p.type),o=p.url,p.hasContent||(p.data&&(o=p.url+=(bn.test(o)?"&":"?")+p.data,delete p.data),p.cache===!1&&(p.url=wn.test(o)?o.replace(wn,"$1_="+vn++):o+(bn.test(o)?"&":"?")+"_="+vn++)),p.ifModified&&(b.lastModified[o]&&N.setRequestHeader("If-Modified-Since",b.lastModified[o]),b.etag[o]&&N.setRequestHeader("If-None-Match",b.etag[o])),(p.data&&p.hasContent&&p.contentType!==!1||n.contentType)&&N.setRequestHeader("Content-Type",p.contentType),N.setRequestHeader("Accept",p.dataTypes[0]&&p.accepts[p.dataTypes[0]]?p.accepts[p.dataTypes[0]]+("*"!==p.dataTypes[0]?", "+Dn+"; q=0.01":""):p.accepts["*"]);for(i in p.headers)N.setRequestHeader(i,p.headers[i]);if(p.beforeSend&&(p.beforeSend.call(f,N,p)===!1||2===x))return N.abort();T="abort";for(i in{success:1,error:1,complete:1})N[i](p[i]);if(l=qn(jn,p,n,N)){N.readyState=1,u&&d.trigger("ajaxSend",[N,p]),p.async&&p.timeout>0&&(s=setTimeout(function(){N.abort("timeout")},p.timeout));try{x=1,l.send(y,k)}catch(C){if(!(2>x))throw C;k(-1,C)}}else k(-1,"No Transport");function k(e,n,r,i){var c,y,v,w,T,C=n;2!==x&&(x=2,s&&clearTimeout(s),l=t,a=i||"",N.readyState=e>0?4:0,r&&(w=_n(p,N,r)),e>=200&&300>e||304===e?(p.ifModified&&(T=N.getResponseHeader("Last-Modified"),T&&(b.lastModified[o]=T),T=N.getResponseHeader("etag"),T&&(b.etag[o]=T)),204===e?(c=!0,C="nocontent"):304===e?(c=!0,C="notmodified"):(c=Fn(p,w),C=c.state,y=c.data,v=c.error,c=!v)):(v=C,(e||!C)&&(C="error",0>e&&(e=0))),N.status=e,N.statusText=(n||C)+"",c?h.resolveWith(f,[y,C,N]):h.rejectWith(f,[N,C,v]),N.statusCode(m),m=t,u&&d.trigger(c?"ajaxSuccess":"ajaxError",[N,p,c?y:v]),g.fireWith(f,[N,C]),u&&(d.trigger("ajaxComplete",[N,p]),--b.active||b.event.trigger("ajaxStop")))}return N},getScript:function(e,n){return b.get(e,t,n,"script")},getJSON:function(e,t,n){return b.get(e,t,n,"json")}});function _n(e,n,r){var i,o,a,s,u=e.contents,l=e.dataTypes,c=e.responseFields;for(s in c)s in r&&(n[c[s]]=r[s]);while("*"===l[0])l.shift(),o===t&&(o=e.mimeType||n.getResponseHeader("Content-Type"));if(o)for(s in u)if(u[s]&&u[s].test(o)){l.unshift(s);break}if(l[0]in r)a=l[0];else{for(s in r){if(!l[0]||e.converters[s+" "+l[0]]){a=s;break}i||(i=s)}a=a||i}return a?(a!==l[0]&&l.unshift(a),r[a]):t}function Fn(e,t){var n,r,i,o,a={},s=0,u=e.dataTypes.slice(),l=u[0];if(e.dataFilter&&(t=e.dataFilter(t,e.dataType)),u[1])for(i in e.converters)a[i.toLowerCase()]=e.converters[i];for(;r=u[++s];)if("*"!==r){if("*"!==l&&l!==r){if(i=a[l+" "+r]||a["* "+r],!i)for(n in a)if(o=n.split(" "),o[1]===r&&(i=a[l+" "+o[0]]||a["* "+o[0]])){i===!0?i=a[n]:a[n]!==!0&&(r=o[0],u.splice(s--,0,r));break}if(i!==!0)if(i&&e["throws"])t=i(t);else try{t=i(t)}catch(c){return{state:"parsererror",error:i?c:"No conversion from "+l+" to "+r}}}l=r}return{state:"success",data:t}}b.ajaxSetup({accepts:{script:"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript"},contents:{script:/(?:java|ecma)script/},converters:{"text script":function(e){return b.globalEval(e),e}}}),b.ajaxPrefilter("script",function(e){e.cache===t&&(e.cache=!1),e.crossDomain&&(e.type="GET",e.global=!1)}),b.ajaxTransport("script",function(e){if(e.crossDomain){var n,r=o.head||b("head")[0]||o.documentElement;return{send:function(t,i){n=o.createElement("script"),n.async=!0,e.scriptCharset&&(n.charset=e.scriptCharset),n.src=e.url,n.onload=n.onreadystatechange=function(e,t){(t||!n.readyState||/loaded|complete/.test(n.readyState))&&(n.onload=n.onreadystatechange=null,n.parentNode&&n.parentNode.removeChild(n),n=null,t||i(200,"success"))},r.insertBefore(n,r.firstChild)},abort:function(){n&&n.onload(t,!0)}}}});var On=[],Bn=/(=)\?(?=&|$)|\?\?/;b.ajaxSetup({jsonp:"callback",jsonpCallback:function(){var e=On.pop()||b.expando+"_"+vn++;return this[e]=!0,e}}),b.ajaxPrefilter("json jsonp",function(n,r,i){var o,a,s,u=n.jsonp!==!1&&(Bn.test(n.url)?"url":"string"==typeof n.data&&!(n.contentType||"").indexOf("application/x-www-form-urlencoded")&&Bn.test(n.data)&&"data");return u||"jsonp"===n.dataTypes[0]?(o=n.jsonpCallback=b.isFunction(n.jsonpCallback)?n.jsonpCallback():n.jsonpCallback,u?n[u]=n[u].replace(Bn,"$1"+o):n.jsonp!==!1&&(n.url+=(bn.test(n.url)?"&":"?")+n.jsonp+"="+o),n.converters["script json"]=function(){return s||b.error(o+" was not called"),s[0]},n.dataTypes[0]="json",a=e[o],e[o]=function(){s=arguments},i.always(function(){e[o]=a,n[o]&&(n.jsonpCallback=r.jsonpCallback,On.push(o)),s&&b.isFunction(a)&&a(s[0]),s=a=t}),"script"):t});var Pn,Rn,Wn=0,$n=e.ActiveXObject&&function(){var e;for(e in Pn)Pn[e](t,!0)};function In(){try{return new e.XMLHttpRequest}catch(t){}}function zn(){try{return new e.ActiveXObject("Microsoft.XMLHTTP")}catch(t){}}b.ajaxSettings.xhr=e.ActiveXObject?function(){return!this.isLocal&&In()||zn()}:In,Rn=b.ajaxSettings.xhr(),b.support.cors=!!Rn&&"withCredentials"in Rn,Rn=b.support.ajax=!!Rn,Rn&&b.ajaxTransport(function(n){if(!n.crossDomain||b.support.cors){var r;return{send:function(i,o){var a,s,u=n.xhr();if(n.username?u.open(n.type,n.url,n.async,n.username,n.password):u.open(n.type,n.url,n.async),n.xhrFields)for(s in n.xhrFields)u[s]=n.xhrFields[s];n.mimeType&&u.overrideMimeType&&u.overrideMimeType(n.mimeType),n.crossDomain||i["X-Requested-With"]||(i["X-Requested-With"]="XMLHttpRequest");try{for(s in i)u.setRequestHeader(s,i[s])}catch(l){}u.send(n.hasContent&&n.data||null),r=function(e,i){var s,l,c,p;try{if(r&&(i||4===u.readyState))if(r=t,a&&(u.onreadystatechange=b.noop,$n&&delete Pn[a]),i)4!==u.readyState&&u.abort();else{p={},s=u.status,l=u.getAllResponseHeaders(),"string"==typeof u.responseText&&(p.text=u.responseText);try{c=u.statusText}catch(f){c=""}s||!n.isLocal||n.crossDomain?1223===s&&(s=204):s=p.text?200:404}}catch(d){i||o(-1,d)}p&&o(s,c,p,l)},n.async?4===u.readyState?setTimeout(r):(a=++Wn,$n&&(Pn||(Pn={},b(e).unload($n)),Pn[a]=r),u.onreadystatechange=r):r()},abort:function(){r&&r(t,!0)}}}});var Xn,Un,Vn=/^(?:toggle|show|hide)$/,Yn=RegExp("^(?:([+-])=|)("+x+")([a-z%]*)$","i"),Jn=/queueHooks$/,Gn=[nr],Qn={"*":[function(e,t){var n,r,i=this.createTween(e,t),o=Yn.exec(t),a=i.cur(),s=+a||0,u=1,l=20;if(o){if(n=+o[2],r=o[3]||(b.cssNumber[e]?"":"px"),"px"!==r&&s){s=b.css(i.elem,e,!0)||n||1;do u=u||".5",s/=u,b.style(i.elem,e,s+r);while(u!==(u=i.cur()/a)&&1!==u&&--l)}i.unit=r,i.start=s,i.end=o[1]?s+(o[1]+1)*n:n}return i}]};function Kn(){return setTimeout(function(){Xn=t}),Xn=b.now()}function Zn(e,t){b.each(t,function(t,n){var r=(Qn[t]||[]).concat(Qn["*"]),i=0,o=r.length;for(;o>i;i++)if(r[i].call(e,t,n))return})}function er(e,t,n){var r,i,o=0,a=Gn.length,s=b.Deferred().always(function(){delete u.elem}),u=function(){if(i)return!1;var t=Xn||Kn(),n=Math.max(0,l.startTime+l.duration-t),r=n/l.duration||0,o=1-r,a=0,u=l.tweens.length;for(;u>a;a++)l.tweens[a].run(o);return s.notifyWith(e,[l,o,n]),1>o&&u?n:(s.resolveWith(e,[l]),!1)},l=s.promise({elem:e,props:b.extend({},t),opts:b.extend(!0,{specialEasing:{}},n),originalProperties:t,originalOptions:n,startTime:Xn||Kn(),duration:n.duration,tweens:[],createTween:function(t,n){var r=b.Tween(e,l.opts,t,n,l.opts.specialEasing[t]||l.opts.easing);return l.tweens.push(r),r},stop:function(t){var n=0,r=t?l.tweens.length:0;if(i)return this;for(i=!0;r>n;n++)l.tweens[n].run(1);return t?s.resolveWith(e,[l,t]):s.rejectWith(e,[l,t]),this}}),c=l.props;for(tr(c,l.opts.specialEasing);a>o;o++)if(r=Gn[o].call(l,e,c,l.opts))return r;return Zn(l,c),b.isFunction(l.opts.start)&&l.opts.start.call(e,l),b.fx.timer(b.extend(u,{elem:e,anim:l,queue:l.opts.queue})),l.progress(l.opts.progress).done(l.opts.done,l.opts.complete).fail(l.opts.fail).always(l.opts.always)}function tr(e,t){var n,r,i,o,a;for(i in e)if(r=b.camelCase(i),o=t[r],n=e[i],b.isArray(n)&&(o=n[1],n=e[i]=n[0]),i!==r&&(e[r]=n,delete e[i]),a=b.cssHooks[r],a&&"expand"in a){n=a.expand(n),delete e[r];for(i in n)i in e||(e[i]=n[i],t[i]=o)}else t[r]=o}b.Animation=b.extend(er,{tweener:function(e,t){b.isFunction(e)?(t=e,e=["*"]):e=e.split(" ");var n,r=0,i=e.length;for(;i>r;r++)n=e[r],Qn[n]=Qn[n]||[],Qn[n].unshift(t)},prefilter:function(e,t){t?Gn.unshift(e):Gn.push(e)}});function nr(e,t,n){var r,i,o,a,s,u,l,c,p,f=this,d=e.style,h={},g=[],m=e.nodeType&&nn(e);n.queue||(c=b._queueHooks(e,"fx"),null==c.unqueued&&(c.unqueued=0,p=c.empty.fire,c.empty.fire=function(){c.unqueued||p()}),c.unqueued++,f.always(function(){f.always(function(){c.unqueued--,b.queue(e,"fx").length||c.empty.fire()})})),1===e.nodeType&&("height"in t||"width"in t)&&(n.overflow=[d.overflow,d.overflowX,d.overflowY],"inline"===b.css(e,"display")&&"none"===b.css(e,"float")&&(b.support.inlineBlockNeedsLayout&&"inline"!==un(e.nodeName)?d.zoom=1:d.display="inline-block")),n.overflow&&(d.overflow="hidden",b.support.shrinkWrapBlocks||f.always(function(){d.overflow=n.overflow[0],d.overflowX=n.overflow[1],d.overflowY=n.overflow[2]}));for(i in t)if(a=t[i],Vn.exec(a)){if(delete t[i],u=u||"toggle"===a,a===(m?"hide":"show"))continue;g.push(i)}if(o=g.length){s=b._data(e,"fxshow")||b._data(e,"fxshow",{}),"hidden"in s&&(m=s.hidden),u&&(s.hidden=!m),m?b(e).show():f.done(function(){b(e).hide()}),f.done(function(){var t;b._removeData(e,"fxshow");for(t in h)b.style(e,t,h[t])});for(i=0;o>i;i++)r=g[i],l=f.createTween(r,m?s[r]:0),h[r]=s[r]||b.style(e,r),r in s||(s[r]=l.start,m&&(l.end=l.start,l.start="width"===r||"height"===r?1:0))}}function rr(e,t,n,r,i){return new rr.prototype.init(e,t,n,r,i)}b.Tween=rr,rr.prototype={constructor:rr,init:function(e,t,n,r,i,o){this.elem=e,this.prop=n,this.easing=i||"swing",this.options=t,this.start=this.now=this.cur(),this.end=r,this.unit=o||(b.cssNumber[n]?"":"px")},cur:function(){var e=rr.propHooks[this.prop];return e&&e.get?e.get(this):rr.propHooks._default.get(this)},run:function(e){var t,n=rr.propHooks[this.prop];return this.pos=t=this.options.duration?b.easing[this.easing](e,this.options.duration*e,0,1,this.options.duration):e,this.now=(this.end-this.start)*t+this.start,this.options.step&&this.options.step.call(this.elem,this.now,this),n&&n.set?n.set(this):rr.propHooks._default.set(this),this}},rr.prototype.init.prototype=rr.prototype,rr.propHooks={_default:{get:function(e){var t;return null==e.elem[e.prop]||e.elem.style&&null!=e.elem.style[e.prop]?(t=b.css(e.elem,e.prop,""),t&&"auto"!==t?t:0):e.elem[e.prop]},set:function(e){b.fx.step[e.prop]?b.fx.step[e.prop](e):e.elem.style&&(null!=e.elem.style[b.cssProps[e.prop]]||b.cssHooks[e.prop])?b.style(e.elem,e.prop,e.now+e.unit):e.elem[e.prop]=e.now}}},rr.propHooks.scrollTop=rr.propHooks.scrollLeft={set:function(e){e.elem.nodeType&&e.elem.parentNode&&(e.elem[e.prop]=e.now)}},b.each(["toggle","show","hide"],function(e,t){var n=b.fn[t];b.fn[t]=function(e,r,i){return null==e||"boolean"==typeof e?n.apply(this,arguments):this.animate(ir(t,!0),e,r,i)}}),b.fn.extend({fadeTo:function(e,t,n,r){return this.filter(nn).css("opacity",0).show().end().animate({opacity:t},e,n,r)},animate:function(e,t,n,r){var i=b.isEmptyObject(e),o=b.speed(t,n,r),a=function(){var t=er(this,b.extend({},e),o);a.finish=function(){t.stop(!0)},(i||b._data(this,"finish"))&&t.stop(!0)};return a.finish=a,i||o.queue===!1?this.each(a):this.queue(o.queue,a)},stop:function(e,n,r){var i=function(e){var t=e.stop;delete e.stop,t(r)};return"string"!=typeof e&&(r=n,n=e,e=t),n&&e!==!1&&this.queue(e||"fx",[]),this.each(function(){var t=!0,n=null!=e&&e+"queueHooks",o=b.timers,a=b._data(this);if(n)a[n]&&a[n].stop&&i(a[n]);else for(n in a)a[n]&&a[n].stop&&Jn.test(n)&&i(a[n]);for(n=o.length;n--;)o[n].elem!==this||null!=e&&o[n].queue!==e||(o[n].anim.stop(r),t=!1,o.splice(n,1));(t||!r)&&b.dequeue(this,e)})},finish:function(e){return e!==!1&&(e=e||"fx"),this.each(function(){var t,n=b._data(this),r=n[e+"queue"],i=n[e+"queueHooks"],o=b.timers,a=r?r.length:0;for(n.finish=!0,b.queue(this,e,[]),i&&i.cur&&i.cur.finish&&i.cur.finish.call(this),t=o.length;t--;)o[t].elem===this&&o[t].queue===e&&(o[t].anim.stop(!0),o.splice(t,1));for(t=0;a>t;t++)r[t]&&r[t].finish&&r[t].finish.call(this);delete n.finish})}});function ir(e,t){var n,r={height:e},i=0;for(t=t?1:0;4>i;i+=2-t)n=Zt[i],r["margin"+n]=r["padding"+n]=e;return t&&(r.opacity=r.width=e),r}b.each({slideDown:ir("show"),slideUp:ir("hide"),slideToggle:ir("toggle"),fadeIn:{opacity:"show"},fadeOut:{opacity:"hide"},fadeToggle:{opacity:"toggle"}},function(e,t){b.fn[e]=function(e,n,r){return this.animate(t,e,n,r)}}),b.speed=function(e,t,n){var r=e&&"object"==typeof e?b.extend({},e):{complete:n||!n&&t||b.isFunction(e)&&e,duration:e,easing:n&&t||t&&!b.isFunction(t)&&t};return r.duration=b.fx.off?0:"number"==typeof r.duration?r.duration:r.duration in b.fx.speeds?b.fx.speeds[r.duration]:b.fx.speeds._default,(null==r.queue||r.queue===!0)&&(r.queue="fx"),r.old=r.complete,r.complete=function(){b.isFunction(r.old)&&r.old.call(this),r.queue&&b.dequeue(this,r.queue)},r},b.easing={linear:function(e){return e},swing:function(e){return.5-Math.cos(e*Math.PI)/2}},b.timers=[],b.fx=rr.prototype.init,b.fx.tick=function(){var e,n=b.timers,r=0;for(Xn=b.now();n.length>r;r++)e=n[r],e()||n[r]!==e||n.splice(r--,1);n.length||b.fx.stop(),Xn=t},b.fx.timer=function(e){e()&&b.timers.push(e)&&b.fx.start()},b.fx.interval=13,b.fx.start=function(){Un||(Un=setInterval(b.fx.tick,b.fx.interval))},b.fx.stop=function(){clearInterval(Un),Un=null},b.fx.speeds={slow:600,fast:200,_default:400},b.fx.step={},b.expr&&b.expr.filters&&(b.expr.filters.animated=function(e){return b.grep(b.timers,function(t){return e===t.elem}).length}),b.fn.offset=function(e){if(arguments.length)return e===t?this:this.each(function(t){b.offset.setOffset(this,e,t)});var n,r,o={top:0,left:0},a=this[0],s=a&&a.ownerDocument;if(s)return n=s.documentElement,b.contains(n,a)?(typeof a.getBoundingClientRect!==i&&(o=a.getBoundingClientRect()),r=or(s),{top:o.top+(r.pageYOffset||n.scrollTop)-(n.clientTop||0),left:o.left+(r.pageXOffset||n.scrollLeft)-(n.clientLeft||0)}):o},b.offset={setOffset:function(e,t,n){var r=b.css(e,"position");"static"===r&&(e.style.position="relative");var i=b(e),o=i.offset(),a=b.css(e,"top"),s=b.css(e,"left"),u=("absolute"===r||"fixed"===r)&&b.inArray("auto",[a,s])>-1,l={},c={},p,f;u?(c=i.position(),p=c.top,f=c.left):(p=parseFloat(a)||0,f=parseFloat(s)||0),b.isFunction(t)&&(t=t.call(e,n,o)),null!=t.top&&(l.top=t.top-o.top+p),null!=t.left&&(l.left=t.left-o.left+f),"using"in t?t.using.call(e,l):i.css(l)}},b.fn.extend({position:function(){if(this[0]){var e,t,n={top:0,left:0},r=this[0];return"fixed"===b.css(r,"position")?t=r.getBoundingClientRect():(e=this.offsetParent(),t=this.offset(),b.nodeName(e[0],"html")||(n=e.offset()),n.top+=b.css(e[0],"borderTopWidth",!0),n.left+=b.css(e[0],"borderLeftWidth",!0)),{top:t.top-n.top-b.css(r,"marginTop",!0),left:t.left-n.left-b.css(r,"marginLeft",!0)}}},offsetParent:function(){return this.map(function(){var e=this.offsetParent||o.documentElement;while(e&&!b.nodeName(e,"html")&&"static"===b.css(e,"position"))e=e.offsetParent;return e||o.documentElement})}}),b.each({scrollLeft:"pageXOffset",scrollTop:"pageYOffset"},function(e,n){var r=/Y/.test(n);b.fn[e]=function(i){return b.access(this,function(e,i,o){var a=or(e);return o===t?a?n in a?a[n]:a.document.documentElement[i]:e[i]:(a?a.scrollTo(r?b(a).scrollLeft():o,r?o:b(a).scrollTop()):e[i]=o,t)},e,i,arguments.length,null)}});function or(e){return b.isWindow(e)?e:9===e.nodeType?e.defaultView||e.parentWindow:!1}b.each({Height:"height",Width:"width"},function(e,n){b.each({padding:"inner"+e,content:n,"":"outer"+e},function(r,i){b.fn[i]=function(i,o){var a=arguments.length&&(r||"boolean"!=typeof i),s=r||(i===!0||o===!0?"margin":"border");return b.access(this,function(n,r,i){var o;return b.isWindow(n)?n.document.documentElement["client"+e]:9===n.nodeType?(o=n.documentElement,Math.max(n.body["scroll"+e],o["scroll"+e],n.body["offset"+e],o["offset"+e],o["client"+e])):i===t?b.css(n,r,s):b.style(n,r,i,s)},n,a?i:t,a,null)}})}),e.jQuery=e.$=b,"function"==typeof define&&define.amd&&define.amd.jQuery&&define("jquery",[],function(){return b})})(window);
\ No newline at end of file
diff --git a/cli/sdncon/ui/static/js/thirdparty/jquery-ui-1.10.2.custom.js b/cli/sdncon/ui/static/js/thirdparty/jquery-ui-1.10.2.custom.js
new file mode 100755
index 0000000..8bdb846
--- /dev/null
+++ b/cli/sdncon/ui/static/js/thirdparty/jquery-ui-1.10.2.custom.js
@@ -0,0 +1,1658 @@
+/*! jQuery UI - v1.10.2 - 2013-04-05
+* http://jqueryui.com
+* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.tabs.js
+* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
+
+(function( $, undefined ) {
+
+var uuid = 0,
+	runiqueId = /^ui-id-\d+$/;
+
+// $.ui might exist from components with no dependencies, e.g., $.ui.position
+$.ui = $.ui || {};
+
+$.extend( $.ui, {
+	version: "1.10.2",
+
+	keyCode: {
+		BACKSPACE: 8,
+		COMMA: 188,
+		DELETE: 46,
+		DOWN: 40,
+		END: 35,
+		ENTER: 13,
+		ESCAPE: 27,
+		HOME: 36,
+		LEFT: 37,
+		NUMPAD_ADD: 107,
+		NUMPAD_DECIMAL: 110,
+		NUMPAD_DIVIDE: 111,
+		NUMPAD_ENTER: 108,
+		NUMPAD_MULTIPLY: 106,
+		NUMPAD_SUBTRACT: 109,
+		PAGE_DOWN: 34,
+		PAGE_UP: 33,
+		PERIOD: 190,
+		RIGHT: 39,
+		SPACE: 32,
+		TAB: 9,
+		UP: 38
+	}
+});
+
+// plugins
+$.fn.extend({
+	focus: (function( orig ) {
+		return function( delay, fn ) {
+			return typeof delay === "number" ?
+				this.each(function() {
+					var elem = this;
+					setTimeout(function() {
+						$( elem ).focus();
+						if ( fn ) {
+							fn.call( elem );
+						}
+					}, delay );
+				}) :
+				orig.apply( this, arguments );
+		};
+	})( $.fn.focus ),
+
+	scrollParent: function() {
+		var scrollParent;
+		if (($.ui.ie && (/(static|relative)/).test(this.css("position"))) || (/absolute/).test(this.css("position"))) {
+			scrollParent = this.parents().filter(function() {
+				return (/(relative|absolute|fixed)/).test($.css(this,"position")) && (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
+			}).eq(0);
+		} else {
+			scrollParent = this.parents().filter(function() {
+				return (/(auto|scroll)/).test($.css(this,"overflow")+$.css(this,"overflow-y")+$.css(this,"overflow-x"));
+			}).eq(0);
+		}
+
+		return (/fixed/).test(this.css("position")) || !scrollParent.length ? $(document) : scrollParent;
+	},
+
+	zIndex: function( zIndex ) {
+		if ( zIndex !== undefined ) {
+			return this.css( "zIndex", zIndex );
+		}
+
+		if ( this.length ) {
+			var elem = $( this[ 0 ] ), position, value;
+			while ( elem.length && elem[ 0 ] !== document ) {
+				// Ignore z-index if position is set to a value where z-index is ignored by the browser
+				// This makes behavior of this function consistent across browsers
+				// WebKit always returns auto if the element is positioned
+				position = elem.css( "position" );
+				if ( position === "absolute" || position === "relative" || position === "fixed" ) {
+					// IE returns 0 when zIndex is not specified
+					// other browsers return a string
+					// we ignore the case of nested elements with an explicit value of 0
+					// <div style="z-index: -10;"><div style="z-index: 0;"></div></div>
+					value = parseInt( elem.css( "zIndex" ), 10 );
+					if ( !isNaN( value ) && value !== 0 ) {
+						return value;
+					}
+				}
+				elem = elem.parent();
+			}
+		}
+
+		return 0;
+	},
+
+	uniqueId: function() {
+		return this.each(function() {
+			if ( !this.id ) {
+				this.id = "ui-id-" + (++uuid);
+			}
+		});
+	},
+
+	removeUniqueId: function() {
+		return this.each(function() {
+			if ( runiqueId.test( this.id ) ) {
+				$( this ).removeAttr( "id" );
+			}
+		});
+	}
+});
+
+// selectors
+function focusable( element, isTabIndexNotNaN ) {
+	var map, mapName, img,
+		nodeName = element.nodeName.toLowerCase();
+	if ( "area" === nodeName ) {
+		map = element.parentNode;
+		mapName = map.name;
+		if ( !element.href || !mapName || map.nodeName.toLowerCase() !== "map" ) {
+			return false;
+		}
+		img = $( "img[usemap=#" + mapName + "]" )[0];
+		return !!img && visible( img );
+	}
+	return ( /input|select|textarea|button|object/.test( nodeName ) ?
+		!element.disabled :
+		"a" === nodeName ?
+			element.href || isTabIndexNotNaN :
+			isTabIndexNotNaN) &&
+		// the element and all of its ancestors must be visible
+		visible( element );
+}
+
+function visible( element ) {
+	return $.expr.filters.visible( element ) &&
+		!$( element ).parents().addBack().filter(function() {
+			return $.css( this, "visibility" ) === "hidden";
+		}).length;
+}
+
+$.extend( $.expr[ ":" ], {
+	data: $.expr.createPseudo ?
+		$.expr.createPseudo(function( dataName ) {
+			return function( elem ) {
+				return !!$.data( elem, dataName );
+			};
+		}) :
+		// support: jQuery <1.8
+		function( elem, i, match ) {
+			return !!$.data( elem, match[ 3 ] );
+		},
+
+	focusable: function( element ) {
+		return focusable( element, !isNaN( $.attr( element, "tabindex" ) ) );
+	},
+
+	tabbable: function( element ) {
+		var tabIndex = $.attr( element, "tabindex" ),
+			isTabIndexNaN = isNaN( tabIndex );
+		return ( isTabIndexNaN || tabIndex >= 0 ) && focusable( element, !isTabIndexNaN );
+	}
+});
+
+// support: jQuery <1.8
+if ( !$( "<a>" ).outerWidth( 1 ).jquery ) {
+	$.each( [ "Width", "Height" ], function( i, name ) {
+		var side = name === "Width" ? [ "Left", "Right" ] : [ "Top", "Bottom" ],
+			type = name.toLowerCase(),
+			orig = {
+				innerWidth: $.fn.innerWidth,
+				innerHeight: $.fn.innerHeight,
+				outerWidth: $.fn.outerWidth,
+				outerHeight: $.fn.outerHeight
+			};
+
+		function reduce( elem, size, border, margin ) {
+			$.each( side, function() {
+				size -= parseFloat( $.css( elem, "padding" + this ) ) || 0;
+				if ( border ) {
+					size -= parseFloat( $.css( elem, "border" + this + "Width" ) ) || 0;
+				}
+				if ( margin ) {
+					size -= parseFloat( $.css( elem, "margin" + this ) ) || 0;
+				}
+			});
+			return size;
+		}
+
+		$.fn[ "inner" + name ] = function( size ) {
+			if ( size === undefined ) {
+				return orig[ "inner" + name ].call( this );
+			}
+
+			return this.each(function() {
+				$( this ).css( type, reduce( this, size ) + "px" );
+			});
+		};
+
+		$.fn[ "outer" + name] = function( size, margin ) {
+			if ( typeof size !== "number" ) {
+				return orig[ "outer" + name ].call( this, size );
+			}
+
+			return this.each(function() {
+				$( this).css( type, reduce( this, size, true, margin ) + "px" );
+			});
+		};
+	});
+}
+
+// support: jQuery <1.8
+if ( !$.fn.addBack ) {
+	$.fn.addBack = function( selector ) {
+		return this.add( selector == null ?
+			this.prevObject : this.prevObject.filter( selector )
+		);
+	};
+}
+
+// support: jQuery 1.6.1, 1.6.2 (http://bugs.jquery.com/ticket/9413)
+if ( $( "<a>" ).data( "a-b", "a" ).removeData( "a-b" ).data( "a-b" ) ) {
+	$.fn.removeData = (function( removeData ) {
+		return function( key ) {
+			if ( arguments.length ) {
+				return removeData.call( this, $.camelCase( key ) );
+			} else {
+				return removeData.call( this );
+			}
+		};
+	})( $.fn.removeData );
+}
+
+
+
+
+
+// deprecated
+$.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
+
+$.support.selectstart = "onselectstart" in document.createElement( "div" );
+$.fn.extend({
+	disableSelection: function() {
+		return this.bind( ( $.support.selectstart ? "selectstart" : "mousedown" ) +
+			".ui-disableSelection", function( event ) {
+				event.preventDefault();
+			});
+	},
+
+	enableSelection: function() {
+		return this.unbind( ".ui-disableSelection" );
+	}
+});
+
+$.extend( $.ui, {
+	// $.ui.plugin is deprecated.  Use the proxy pattern instead.
+	plugin: {
+		add: function( module, option, set ) {
+			var i,
+				proto = $.ui[ module ].prototype;
+			for ( i in set ) {
+				proto.plugins[ i ] = proto.plugins[ i ] || [];
+				proto.plugins[ i ].push( [ option, set[ i ] ] );
+			}
+		},
+		call: function( instance, name, args ) {
+			var i,
+				set = instance.plugins[ name ];
+			if ( !set || !instance.element[ 0 ].parentNode || instance.element[ 0 ].parentNode.nodeType === 11 ) {
+				return;
+			}
+
+			for ( i = 0; i < set.length; i++ ) {
+				if ( instance.options[ set[ i ][ 0 ] ] ) {
+					set[ i ][ 1 ].apply( instance.element, args );
+				}
+			}
+		}
+	},
+
+	// only used by resizable
+	hasScroll: function( el, a ) {
+
+		//If overflow is hidden, the element might have extra content, but the user wants to hide it
+		if ( $( el ).css( "overflow" ) === "hidden") {
+			return false;
+		}
+
+		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
+			has = false;
+
+		if ( el[ scroll ] > 0 ) {
+			return true;
+		}
+
+		// TODO: determine which cases actually cause this to happen
+		// if the element doesn't have the scroll set, see if it's possible to
+		// set the scroll
+		el[ scroll ] = 1;
+		has = ( el[ scroll ] > 0 );
+		el[ scroll ] = 0;
+		return has;
+	}
+});
+
+})( jQuery );
+(function( $, undefined ) {
+
+var uuid = 0,
+	slice = Array.prototype.slice,
+	_cleanData = $.cleanData;
+$.cleanData = function( elems ) {
+	for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) {
+		try {
+			$( elem ).triggerHandler( "remove" );
+		// http://bugs.jquery.com/ticket/8235
+		} catch( e ) {}
+	}
+	_cleanData( elems );
+};
+
+$.widget = function( name, base, prototype ) {
+	var fullName, existingConstructor, constructor, basePrototype,
+		// proxiedPrototype allows the provided prototype to remain unmodified
+		// so that it can be used as a mixin for multiple widgets (#8876)
+		proxiedPrototype = {},
+		namespace = name.split( "." )[ 0 ];
+
+	name = name.split( "." )[ 1 ];
+	fullName = namespace + "-" + name;
+
+	if ( !prototype ) {
+		prototype = base;
+		base = $.Widget;
+	}
+
+	// create selector for plugin
+	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
+		return !!$.data( elem, fullName );
+	};
+
+	$[ namespace ] = $[ namespace ] || {};
+	existingConstructor = $[ namespace ][ name ];
+	constructor = $[ namespace ][ name ] = function( options, element ) {
+		// allow instantiation without "new" keyword
+		if ( !this._createWidget ) {
+			return new constructor( options, element );
+		}
+
+		// allow instantiation without initializing for simple inheritance
+		// must use "new" keyword (the code above always passes args)
+		if ( arguments.length ) {
+			this._createWidget( options, element );
+		}
+	};
+	// extend with the existing constructor to carry over any static properties
+	$.extend( constructor, existingConstructor, {
+		version: prototype.version,
+		// copy the object used to create the prototype in case we need to
+		// redefine the widget later
+		_proto: $.extend( {}, prototype ),
+		// track widgets that inherit from this widget in case this widget is
+		// redefined after a widget inherits from it
+		_childConstructors: []
+	});
+
+	basePrototype = new base();
+	// we need to make the options hash a property directly on the new instance
+	// otherwise we'll modify the options hash on the prototype that we're
+	// inheriting from
+	basePrototype.options = $.widget.extend( {}, basePrototype.options );
+	$.each( prototype, function( prop, value ) {
+		if ( !$.isFunction( value ) ) {
+			proxiedPrototype[ prop ] = value;
+			return;
+		}
+		proxiedPrototype[ prop ] = (function() {
+			var _super = function() {
+					return base.prototype[ prop ].apply( this, arguments );
+				},
+				_superApply = function( args ) {
+					return base.prototype[ prop ].apply( this, args );
+				};
+			return function() {
+				var __super = this._super,
+					__superApply = this._superApply,
+					returnValue;
+
+				this._super = _super;
+				this._superApply = _superApply;
+
+				returnValue = value.apply( this, arguments );
+
+				this._super = __super;
+				this._superApply = __superApply;
+
+				return returnValue;
+			};
+		})();
+	});
+	constructor.prototype = $.widget.extend( basePrototype, {
+		// TODO: remove support for widgetEventPrefix
+		// always use the name + a colon as the prefix, e.g., draggable:start
+		// don't prefix for widgets that aren't DOM-based
+		widgetEventPrefix: existingConstructor ? basePrototype.widgetEventPrefix : name
+	}, proxiedPrototype, {
+		constructor: constructor,
+		namespace: namespace,
+		widgetName: name,
+		widgetFullName: fullName
+	});
+
+	// If this widget is being redefined then we need to find all widgets that
+	// are inheriting from it and redefine all of them so that they inherit from
+	// the new version of this widget. We're essentially trying to replace one
+	// level in the prototype chain.
+	if ( existingConstructor ) {
+		$.each( existingConstructor._childConstructors, function( i, child ) {
+			var childPrototype = child.prototype;
+
+			// redefine the child widget using the same prototype that was
+			// originally used, but inherit from the new version of the base
+			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor, child._proto );
+		});
+		// remove the list of existing child constructors from the old constructor
+		// so the old child constructors can be garbage collected
+		delete existingConstructor._childConstructors;
+	} else {
+		base._childConstructors.push( constructor );
+	}
+
+	$.widget.bridge( name, constructor );
+};
+
+$.widget.extend = function( target ) {
+	var input = slice.call( arguments, 1 ),
+		inputIndex = 0,
+		inputLength = input.length,
+		key,
+		value;
+	for ( ; inputIndex < inputLength; inputIndex++ ) {
+		for ( key in input[ inputIndex ] ) {
+			value = input[ inputIndex ][ key ];
+			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
+				// Clone objects
+				if ( $.isPlainObject( value ) ) {
+					target[ key ] = $.isPlainObject( target[ key ] ) ?
+						$.widget.extend( {}, target[ key ], value ) :
+						// Don't extend strings, arrays, etc. with objects
+						$.widget.extend( {}, value );
+				// Copy everything else by reference
+				} else {
+					target[ key ] = value;
+				}
+			}
+		}
+	}
+	return target;
+};
+
+$.widget.bridge = function( name, object ) {
+	var fullName = object.prototype.widgetFullName || name;
+	$.fn[ name ] = function( options ) {
+		var isMethodCall = typeof options === "string",
+			args = slice.call( arguments, 1 ),
+			returnValue = this;
+
+		// allow multiple hashes to be passed on init
+		options = !isMethodCall && args.length ?
+			$.widget.extend.apply( null, [ options ].concat(args) ) :
+			options;
+
+		if ( isMethodCall ) {
+			this.each(function() {
+				var methodValue,
+					instance = $.data( this, fullName );
+				if ( !instance ) {
+					return $.error( "cannot call methods on " + name + " prior to initialization; " +
+						"attempted to call method '" + options + "'" );
+				}
+				if ( !$.isFunction( instance[options] ) || options.charAt( 0 ) === "_" ) {
+					return $.error( "no such method '" + options + "' for " + name + " widget instance" );
+				}
+				methodValue = instance[ options ].apply( instance, args );
+				if ( methodValue !== instance && methodValue !== undefined ) {
+					returnValue = methodValue && methodValue.jquery ?
+						returnValue.pushStack( methodValue.get() ) :
+						methodValue;
+					return false;
+				}
+			});
+		} else {
+			this.each(function() {
+				var instance = $.data( this, fullName );
+				if ( instance ) {
+					instance.option( options || {} )._init();
+				} else {
+					$.data( this, fullName, new object( options, this ) );
+				}
+			});
+		}
+
+		return returnValue;
+	};
+};
+
+$.Widget = function( /* options, element */ ) {};
+$.Widget._childConstructors = [];
+
+$.Widget.prototype = {
+	widgetName: "widget",
+	widgetEventPrefix: "",
+	defaultElement: "<div>",
+	options: {
+		disabled: false,
+
+		// callbacks
+		create: null
+	},
+	_createWidget: function( options, element ) {
+		element = $( element || this.defaultElement || this )[ 0 ];
+		this.element = $( element );
+		this.uuid = uuid++;
+		this.eventNamespace = "." + this.widgetName + this.uuid;
+		this.options = $.widget.extend( {},
+			this.options,
+			this._getCreateOptions(),
+			options );
+
+		this.bindings = $();
+		this.hoverable = $();
+		this.focusable = $();
+
+		if ( element !== this ) {
+			$.data( element, this.widgetFullName, this );
+			this._on( true, this.element, {
+				remove: function( event ) {
+					if ( event.target === element ) {
+						this.destroy();
+					}
+				}
+			});
+			this.document = $( element.style ?
+				// element within the document
+				element.ownerDocument :
+				// element is window or document
+				element.document || element );
+			this.window = $( this.document[0].defaultView || this.document[0].parentWindow );
+		}
+
+		this._create();
+		this._trigger( "create", null, this._getCreateEventData() );
+		this._init();
+	},
+	_getCreateOptions: $.noop,
+	_getCreateEventData: $.noop,
+	_create: $.noop,
+	_init: $.noop,
+
+	destroy: function() {
+		this._destroy();
+		// we can probably remove the unbind calls in 2.0
+		// all event bindings should go through this._on()
+		this.element
+			.unbind( this.eventNamespace )
+			// 1.9 BC for #7810
+			// TODO remove dual storage
+			.removeData( this.widgetName )
+			.removeData( this.widgetFullName )
+			// support: jquery <1.6.3
+			// http://bugs.jquery.com/ticket/9413
+			.removeData( $.camelCase( this.widgetFullName ) );
+		this.widget()
+			.unbind( this.eventNamespace )
+			.removeAttr( "aria-disabled" )
+			.removeClass(
+				this.widgetFullName + "-disabled " +
+				"ui-state-disabled" );
+
+		// clean up events and states
+		this.bindings.unbind( this.eventNamespace );
+		this.hoverable.removeClass( "ui-state-hover" );
+		this.focusable.removeClass( "ui-state-focus" );
+	},
+	_destroy: $.noop,
+
+	widget: function() {
+		return this.element;
+	},
+
+	option: function( key, value ) {
+		var options = key,
+			parts,
+			curOption,
+			i;
+
+		if ( arguments.length === 0 ) {
+			// don't return a reference to the internal hash
+			return $.widget.extend( {}, this.options );
+		}
+
+		if ( typeof key === "string" ) {
+			// handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
+			options = {};
+			parts = key.split( "." );
+			key = parts.shift();
+			if ( parts.length ) {
+				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
+				for ( i = 0; i < parts.length - 1; i++ ) {
+					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
+					curOption = curOption[ parts[ i ] ];
+				}
+				key = parts.pop();
+				if ( value === undefined ) {
+					return curOption[ key ] === undefined ? null : curOption[ key ];
+				}
+				curOption[ key ] = value;
+			} else {
+				if ( value === undefined ) {
+					return this.options[ key ] === undefined ? null : this.options[ key ];
+				}
+				options[ key ] = value;
+			}
+		}
+
+		this._setOptions( options );
+
+		return this;
+	},
+	_setOptions: function( options ) {
+		var key;
+
+		for ( key in options ) {
+			this._setOption( key, options[ key ] );
+		}
+
+		return this;
+	},
+	_setOption: function( key, value ) {
+		this.options[ key ] = value;
+
+		if ( key === "disabled" ) {
+			this.widget()
+				.toggleClass( this.widgetFullName + "-disabled ui-state-disabled", !!value )
+				.attr( "aria-disabled", value );
+			this.hoverable.removeClass( "ui-state-hover" );
+			this.focusable.removeClass( "ui-state-focus" );
+		}
+
+		return this;
+	},
+
+	enable: function() {
+		return this._setOption( "disabled", false );
+	},
+	disable: function() {
+		return this._setOption( "disabled", true );
+	},
+
+	_on: function( suppressDisabledCheck, element, handlers ) {
+		var delegateElement,
+			instance = this;
+
+		// no suppressDisabledCheck flag, shuffle arguments
+		if ( typeof suppressDisabledCheck !== "boolean" ) {
+			handlers = element;
+			element = suppressDisabledCheck;
+			suppressDisabledCheck = false;
+		}
+
+		// no element argument, shuffle and use this.element
+		if ( !handlers ) {
+			handlers = element;
+			element = this.element;
+			delegateElement = this.widget();
+		} else {
+			// accept selectors, DOM elements
+			element = delegateElement = $( element );
+			this.bindings = this.bindings.add( element );
+		}
+
+		$.each( handlers, function( event, handler ) {
+			function handlerProxy() {
+				// allow widgets to customize the disabled handling
+				// - disabled as an array instead of boolean
+				// - disabled class as method for disabling individual parts
+				if ( !suppressDisabledCheck &&
+						( instance.options.disabled === true ||
+							$( this ).hasClass( "ui-state-disabled" ) ) ) {
+					return;
+				}
+				return ( typeof handler === "string" ? instance[ handler ] : handler )
+					.apply( instance, arguments );
+			}
+
+			// copy the guid so direct unbinding works
+			if ( typeof handler !== "string" ) {
+				handlerProxy.guid = handler.guid =
+					handler.guid || handlerProxy.guid || $.guid++;
+			}
+
+			var match = event.match( /^(\w+)\s*(.*)$/ ),
+				eventName = match[1] + instance.eventNamespace,
+				selector = match[2];
+			if ( selector ) {
+				delegateElement.delegate( selector, eventName, handlerProxy );
+			} else {
+				element.bind( eventName, handlerProxy );
+			}
+		});
+	},
+
+	_off: function( element, eventName ) {
+		eventName = (eventName || "").split( " " ).join( this.eventNamespace + " " ) + this.eventNamespace;
+		element.unbind( eventName ).undelegate( eventName );
+	},
+
+	_delay: function( handler, delay ) {
+		function handlerProxy() {
+			return ( typeof handler === "string" ? instance[ handler ] : handler )
+				.apply( instance, arguments );
+		}
+		var instance = this;
+		return setTimeout( handlerProxy, delay || 0 );
+	},
+
+	_hoverable: function( element ) {
+		this.hoverable = this.hoverable.add( element );
+		this._on( element, {
+			mouseenter: function( event ) {
+				$( event.currentTarget ).addClass( "ui-state-hover" );
+			},
+			mouseleave: function( event ) {
+				$( event.currentTarget ).removeClass( "ui-state-hover" );
+			}
+		});
+	},
+
+	_focusable: function( element ) {
+		this.focusable = this.focusable.add( element );
+		this._on( element, {
+			focusin: function( event ) {
+				$( event.currentTarget ).addClass( "ui-state-focus" );
+			},
+			focusout: function( event ) {
+				$( event.currentTarget ).removeClass( "ui-state-focus" );
+			}
+		});
+	},
+
+	_trigger: function( type, event, data ) {
+		var prop, orig,
+			callback = this.options[ type ];
+
+		data = data || {};
+		event = $.Event( event );
+		event.type = ( type === this.widgetEventPrefix ?
+			type :
+			this.widgetEventPrefix + type ).toLowerCase();
+		// the original event may come from any element
+		// so we need to reset the target on the new event
+		event.target = this.element[ 0 ];
+
+		// copy original event properties over to the new event
+		orig = event.originalEvent;
+		if ( orig ) {
+			for ( prop in orig ) {
+				if ( !( prop in event ) ) {
+					event[ prop ] = orig[ prop ];
+				}
+			}
+		}
+
+		this.element.trigger( event, data );
+		return !( $.isFunction( callback ) &&
+			callback.apply( this.element[0], [ event ].concat( data ) ) === false ||
+			event.isDefaultPrevented() );
+	}
+};
+
+$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
+	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
+		if ( typeof options === "string" ) {
+			options = { effect: options };
+		}
+		var hasOptions,
+			effectName = !options ?
+				method :
+				options === true || typeof options === "number" ?
+					defaultEffect :
+					options.effect || defaultEffect;
+		options = options || {};
+		if ( typeof options === "number" ) {
+			options = { duration: options };
+		}
+		hasOptions = !$.isEmptyObject( options );
+		options.complete = callback;
+		if ( options.delay ) {
+			element.delay( options.delay );
+		}
+		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
+			element[ method ]( options );
+		} else if ( effectName !== method && element[ effectName ] ) {
+			element[ effectName ]( options.duration, options.easing, callback );
+		} else {
+			element.queue(function( next ) {
+				$( this )[ method ]();
+				if ( callback ) {
+					callback.call( element[ 0 ] );
+				}
+				next();
+			});
+		}
+	};
+});
+
+})( jQuery );
+(function( $, undefined ) {
+
+var tabId = 0,
+	rhash = /#.*$/;
+
+function getNextTabId() {
+	return ++tabId;
+}
+
+function isLocal( anchor ) {
+	return anchor.hash.length > 1 &&
+		decodeURIComponent( anchor.href.replace( rhash, "" ) ) ===
+			decodeURIComponent( location.href.replace( rhash, "" ) );
+}
+
+$.widget( "ui.tabs", {
+	version: "1.10.2",
+	delay: 300,
+	options: {
+		active: null,
+		collapsible: false,
+		event: "click",
+		heightStyle: "content",
+		hide: null,
+		show: null,
+
+		// callbacks
+		activate: null,
+		beforeActivate: null,
+		beforeLoad: null,
+		load: null
+	},
+
+	_create: function() {
+		var that = this,
+			options = this.options;
+
+		this.running = false;
+
+		this.element
+			.addClass( "ui-tabs ui-widget ui-widget-content ui-corner-all" )
+			.toggleClass( "ui-tabs-collapsible", options.collapsible )
+			// Prevent users from focusing disabled tabs via click
+			.delegate( ".ui-tabs-nav > li", "mousedown" + this.eventNamespace, function( event ) {
+				if ( $( this ).is( ".ui-state-disabled" ) ) {
+					event.preventDefault();
+				}
+			})
+			// support: IE <9
+			// Preventing the default action in mousedown doesn't prevent IE
+			// from focusing the element, so if the anchor gets focused, blur.
+			// We don't have to worry about focusing the previously focused
+			// element since clicking on a non-focusable element should focus
+			// the body anyway.
+			.delegate( ".ui-tabs-anchor", "focus" + this.eventNamespace, function() {
+				if ( $( this ).closest( "li" ).is( ".ui-state-disabled" ) ) {
+					this.blur();
+				}
+			});
+
+		this._processTabs();
+		options.active = this._initialActive();
+
+		// Take disabling tabs via class attribute from HTML
+		// into account and update option properly.
+		if ( $.isArray( options.disabled ) ) {
+			options.disabled = $.unique( options.disabled.concat(
+				$.map( this.tabs.filter( ".ui-state-disabled" ), function( li ) {
+					return that.tabs.index( li );
+				})
+			) ).sort();
+		}
+
+		// check for length avoids error when initializing empty list
+		if ( this.options.active !== false && this.anchors.length ) {
+			this.active = this._findActive( options.active );
+		} else {
+			this.active = $();
+		}
+
+		this._refresh();
+
+		if ( this.active.length ) {
+			this.load( options.active );
+		}
+	},
+
+	_initialActive: function() {
+		var active = this.options.active,
+			collapsible = this.options.collapsible,
+			locationHash = location.hash.substring( 1 );
+
+		if ( active === null ) {
+			// check the fragment identifier in the URL
+			if ( locationHash ) {
+				this.tabs.each(function( i, tab ) {
+					if ( $( tab ).attr( "aria-controls" ) === locationHash ) {
+						active = i;
+						return false;
+					}
+				});
+			}
+
+			// check for a tab marked active via a class
+			if ( active === null ) {
+				active = this.tabs.index( this.tabs.filter( ".ui-tabs-active" ) );
+			}
+
+			// no active tab, set to false
+			if ( active === null || active === -1 ) {
+				active = this.tabs.length ? 0 : false;
+			}
+		}
+
+		// handle numbers: negative, out of range
+		if ( active !== false ) {
+			active = this.tabs.index( this.tabs.eq( active ) );
+			if ( active === -1 ) {
+				active = collapsible ? false : 0;
+			}
+		}
+
+		// don't allow collapsible: false and active: false
+		if ( !collapsible && active === false && this.anchors.length ) {
+			active = 0;
+		}
+
+		return active;
+	},
+
+	_getCreateEventData: function() {
+		return {
+			tab: this.active,
+			panel: !this.active.length ? $() : this._getPanelForTab( this.active )
+		};
+	},
+
+	_tabKeydown: function( event ) {
+		/*jshint maxcomplexity:15*/
+		var focusedTab = $( this.document[0].activeElement ).closest( "li" ),
+			selectedIndex = this.tabs.index( focusedTab ),
+			goingForward = true;
+
+		if ( this._handlePageNav( event ) ) {
+			return;
+		}
+
+		switch ( event.keyCode ) {
+			case $.ui.keyCode.RIGHT:
+			case $.ui.keyCode.DOWN:
+				selectedIndex++;
+				break;
+			case $.ui.keyCode.UP:
+			case $.ui.keyCode.LEFT:
+				goingForward = false;
+				selectedIndex--;
+				break;
+			case $.ui.keyCode.END:
+				selectedIndex = this.anchors.length - 1;
+				break;
+			case $.ui.keyCode.HOME:
+				selectedIndex = 0;
+				break;
+			case $.ui.keyCode.SPACE:
+				// Activate only, no collapsing
+				event.preventDefault();
+				clearTimeout( this.activating );
+				this._activate( selectedIndex );
+				return;
+			case $.ui.keyCode.ENTER:
+				// Toggle (cancel delayed activation, allow collapsing)
+				event.preventDefault();
+				clearTimeout( this.activating );
+				// Determine if we should collapse or activate
+				this._activate( selectedIndex === this.options.active ? false : selectedIndex );
+				return;
+			default:
+				return;
+		}
+
+		// Focus the appropriate tab, based on which key was pressed
+		event.preventDefault();
+		clearTimeout( this.activating );
+		selectedIndex = this._focusNextTab( selectedIndex, goingForward );
+
+		// Navigating with control key will prevent automatic activation
+		if ( !event.ctrlKey ) {
+			// Update aria-selected immediately so that AT think the tab is already selected.
+			// Otherwise AT may confuse the user by stating that they need to activate the tab,
+			// but the tab will already be activated by the time the announcement finishes.
+			focusedTab.attr( "aria-selected", "false" );
+			this.tabs.eq( selectedIndex ).attr( "aria-selected", "true" );
+
+			this.activating = this._delay(function() {
+				this.option( "active", selectedIndex );
+			}, this.delay );
+		}
+	},
+
+	_panelKeydown: function( event ) {
+		if ( this._handlePageNav( event ) ) {
+			return;
+		}
+
+		// Ctrl+up moves focus to the current tab
+		if ( event.ctrlKey && event.keyCode === $.ui.keyCode.UP ) {
+			event.preventDefault();
+			this.active.focus();
+		}
+	},
+
+	// Alt+page up/down moves focus to the previous/next tab (and activates)
+	_handlePageNav: function( event ) {
+		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_UP ) {
+			this._activate( this._focusNextTab( this.options.active - 1, false ) );
+			return true;
+		}
+		if ( event.altKey && event.keyCode === $.ui.keyCode.PAGE_DOWN ) {
+			this._activate( this._focusNextTab( this.options.active + 1, true ) );
+			return true;
+		}
+	},
+
+	_findNextTab: function( index, goingForward ) {
+		var lastTabIndex = this.tabs.length - 1;
+
+		function constrain() {
+			if ( index > lastTabIndex ) {
+				index = 0;
+			}
+			if ( index < 0 ) {
+				index = lastTabIndex;
+			}
+			return index;
+		}
+
+		while ( $.inArray( constrain(), this.options.disabled ) !== -1 ) {
+			index = goingForward ? index + 1 : index - 1;
+		}
+
+		return index;
+	},
+
+	_focusNextTab: function( index, goingForward ) {
+		index = this._findNextTab( index, goingForward );
+		this.tabs.eq( index ).focus();
+		return index;
+	},
+
+	_setOption: function( key, value ) {
+		if ( key === "active" ) {
+			// _activate() will handle invalid values and update this.options
+			this._activate( value );
+			return;
+		}
+
+		if ( key === "disabled" ) {
+			// don't use the widget factory's disabled handling
+			this._setupDisabled( value );
+			return;
+		}
+
+		this._super( key, value);
+
+		if ( key === "collapsible" ) {
+			this.element.toggleClass( "ui-tabs-collapsible", value );
+			// Setting collapsible: false while collapsed; open first panel
+			if ( !value && this.options.active === false ) {
+				this._activate( 0 );
+			}
+		}
+
+		if ( key === "event" ) {
+			this._setupEvents( value );
+		}
+
+		if ( key === "heightStyle" ) {
+			this._setupHeightStyle( value );
+		}
+	},
+
+	_tabId: function( tab ) {
+		return tab.attr( "aria-controls" ) || "ui-tabs-" + getNextTabId();
+	},
+
+	_sanitizeSelector: function( hash ) {
+		return hash ? hash.replace( /[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g, "\\$&" ) : "";
+	},
+
+	refresh: function() {
+		var options = this.options,
+			lis = this.tablist.children( ":has(a[href])" );
+
+		// get disabled tabs from class attribute from HTML
+		// this will get converted to a boolean if needed in _refresh()
+		options.disabled = $.map( lis.filter( ".ui-state-disabled" ), function( tab ) {
+			return lis.index( tab );
+		});
+
+		this._processTabs();
+
+		// was collapsed or no tabs
+		if ( options.active === false || !this.anchors.length ) {
+			options.active = false;
+			this.active = $();
+		// was active, but active tab is gone
+		} else if ( this.active.length && !$.contains( this.tablist[ 0 ], this.active[ 0 ] ) ) {
+			// all remaining tabs are disabled
+			if ( this.tabs.length === options.disabled.length ) {
+				options.active = false;
+				this.active = $();
+			// activate previous tab
+			} else {
+				this._activate( this._findNextTab( Math.max( 0, options.active - 1 ), false ) );
+			}
+		// was active, active tab still exists
+		} else {
+			// make sure active index is correct
+			options.active = this.tabs.index( this.active );
+		}
+
+		this._refresh();
+	},
+
+	_refresh: function() {
+		this._setupDisabled( this.options.disabled );
+		this._setupEvents( this.options.event );
+		this._setupHeightStyle( this.options.heightStyle );
+
+		this.tabs.not( this.active ).attr({
+			"aria-selected": "false",
+			tabIndex: -1
+		});
+		this.panels.not( this._getPanelForTab( this.active ) )
+			.hide()
+			.attr({
+				"aria-expanded": "false",
+				"aria-hidden": "true"
+			});
+
+		// Make sure one tab is in the tab order
+		if ( !this.active.length ) {
+			this.tabs.eq( 0 ).attr( "tabIndex", 0 );
+		} else {
+			this.active
+				.addClass( "ui-tabs-active ui-state-active" )
+				.attr({
+					"aria-selected": "true",
+					tabIndex: 0
+				});
+			this._getPanelForTab( this.active )
+				.show()
+				.attr({
+					"aria-expanded": "true",
+					"aria-hidden": "false"
+				});
+		}
+	},
+
+	_processTabs: function() {
+		var that = this;
+
+		this.tablist = this._getList()
+			.addClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
+			.attr( "role", "tablist" );
+
+		this.tabs = this.tablist.find( "> li:has(a[href])" )
+			.addClass( "ui-state-default ui-corner-top" )
+			.attr({
+				role: "tab",
+				tabIndex: -1
+			});
+
+		this.anchors = this.tabs.map(function() {
+				return $( "a", this )[ 0 ];
+			})
+			.addClass( "ui-tabs-anchor" )
+			.attr({
+				role: "presentation",
+				tabIndex: -1
+			});
+
+		this.panels = $();
+
+		this.anchors.each(function( i, anchor ) {
+			var selector, panel, panelId,
+				anchorId = $( anchor ).uniqueId().attr( "id" ),
+				tab = $( anchor ).closest( "li" ),
+				originalAriaControls = tab.attr( "aria-controls" );
+
+			// inline tab
+			if ( isLocal( anchor ) ) {
+				selector = anchor.hash;
+				panel = that.element.find( that._sanitizeSelector( selector ) );
+			// remote tab
+			} else {
+				panelId = that._tabId( tab );
+				selector = "#" + panelId;
+				panel = that.element.find( selector );
+				if ( !panel.length ) {
+					panel = that._createPanel( panelId );
+					panel.insertAfter( that.panels[ i - 1 ] || that.tablist );
+				}
+				panel.attr( "aria-live", "polite" );
+			}
+
+			if ( panel.length) {
+				that.panels = that.panels.add( panel );
+			}
+			if ( originalAriaControls ) {
+				tab.data( "ui-tabs-aria-controls", originalAriaControls );
+			}
+			tab.attr({
+				"aria-controls": selector.substring( 1 ),
+				"aria-labelledby": anchorId
+			});
+			panel.attr( "aria-labelledby", anchorId );
+		});
+
+		this.panels
+			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
+			.attr( "role", "tabpanel" );
+	},
+
+	// allow overriding how to find the list for rare usage scenarios (#7715)
+	_getList: function() {
+		return this.element.find( "ol,ul" ).eq( 0 );
+	},
+
+	_createPanel: function( id ) {
+		return $( "<div>" )
+			.attr( "id", id )
+			.addClass( "ui-tabs-panel ui-widget-content ui-corner-bottom" )
+			.data( "ui-tabs-destroy", true );
+	},
+
+	_setupDisabled: function( disabled ) {
+		if ( $.isArray( disabled ) ) {
+			if ( !disabled.length ) {
+				disabled = false;
+			} else if ( disabled.length === this.anchors.length ) {
+				disabled = true;
+			}
+		}
+
+		// disable tabs
+		for ( var i = 0, li; ( li = this.tabs[ i ] ); i++ ) {
+			if ( disabled === true || $.inArray( i, disabled ) !== -1 ) {
+				$( li )
+					.addClass( "ui-state-disabled" )
+					.attr( "aria-disabled", "true" );
+			} else {
+				$( li )
+					.removeClass( "ui-state-disabled" )
+					.removeAttr( "aria-disabled" );
+			}
+		}
+
+		this.options.disabled = disabled;
+	},
+
+	_setupEvents: function( event ) {
+		var events = {
+			click: function( event ) {
+				event.preventDefault();
+			}
+		};
+		if ( event ) {
+			$.each( event.split(" "), function( index, eventName ) {
+				events[ eventName ] = "_eventHandler";
+			});
+		}
+
+		this._off( this.anchors.add( this.tabs ).add( this.panels ) );
+		this._on( this.anchors, events );
+		this._on( this.tabs, { keydown: "_tabKeydown" } );
+		this._on( this.panels, { keydown: "_panelKeydown" } );
+
+		this._focusable( this.tabs );
+		this._hoverable( this.tabs );
+	},
+
+	_setupHeightStyle: function( heightStyle ) {
+		var maxHeight,
+			parent = this.element.parent();
+
+		if ( heightStyle === "fill" ) {
+			maxHeight = parent.height();
+			maxHeight -= this.element.outerHeight() - this.element.height();
+
+			this.element.siblings( ":visible" ).each(function() {
+				var elem = $( this ),
+					position = elem.css( "position" );
+
+				if ( position === "absolute" || position === "fixed" ) {
+					return;
+				}
+				maxHeight -= elem.outerHeight( true );
+			});
+
+			this.element.children().not( this.panels ).each(function() {
+				maxHeight -= $( this ).outerHeight( true );
+			});
+
+			this.panels.each(function() {
+				$( this ).height( Math.max( 0, maxHeight -
+					$( this ).innerHeight() + $( this ).height() ) );
+			})
+			.css( "overflow", "auto" );
+		} else if ( heightStyle === "auto" ) {
+			maxHeight = 0;
+			this.panels.each(function() {
+				maxHeight = Math.max( maxHeight, $( this ).height( "" ).height() );
+			}).height( maxHeight );
+		}
+	},
+
+	_eventHandler: function( event ) {
+		var options = this.options,
+			active = this.active,
+			anchor = $( event.currentTarget ),
+			tab = anchor.closest( "li" ),
+			clickedIsActive = tab[ 0 ] === active[ 0 ],
+			collapsing = clickedIsActive && options.collapsible,
+			toShow = collapsing ? $() : this._getPanelForTab( tab ),
+			toHide = !active.length ? $() : this._getPanelForTab( active ),
+			eventData = {
+				oldTab: active,
+				oldPanel: toHide,
+				newTab: collapsing ? $() : tab,
+				newPanel: toShow
+			};
+
+		event.preventDefault();
+
+		if ( tab.hasClass( "ui-state-disabled" ) ||
+				// tab is already loading
+				tab.hasClass( "ui-tabs-loading" ) ||
+				// can't switch durning an animation
+				this.running ||
+				// click on active header, but not collapsible
+				( clickedIsActive && !options.collapsible ) ||
+				// allow canceling activation
+				( this._trigger( "beforeActivate", event, eventData ) === false ) ) {
+			return;
+		}
+
+		options.active = collapsing ? false : this.tabs.index( tab );
+
+		this.active = clickedIsActive ? $() : tab;
+		if ( this.xhr ) {
+			this.xhr.abort();
+		}
+
+		if ( !toHide.length && !toShow.length ) {
+			$.error( "jQuery UI Tabs: Mismatching fragment identifier." );
+		}
+
+		if ( toShow.length ) {
+			this.load( this.tabs.index( tab ), event );
+		}
+		this._toggle( event, eventData );
+	},
+
+	// handles show/hide for selecting tabs
+	_toggle: function( event, eventData ) {
+		var that = this,
+			toShow = eventData.newPanel,
+			toHide = eventData.oldPanel;
+
+		this.running = true;
+
+		function complete() {
+			that.running = false;
+			that._trigger( "activate", event, eventData );
+		}
+
+		function show() {
+			eventData.newTab.closest( "li" ).addClass( "ui-tabs-active ui-state-active" );
+
+			if ( toShow.length && that.options.show ) {
+				that._show( toShow, that.options.show, complete );
+			} else {
+				toShow.show();
+				complete();
+			}
+		}
+
+		// start out by hiding, then showing, then completing
+		if ( toHide.length && this.options.hide ) {
+			this._hide( toHide, this.options.hide, function() {
+				eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
+				show();
+			});
+		} else {
+			eventData.oldTab.closest( "li" ).removeClass( "ui-tabs-active ui-state-active" );
+			toHide.hide();
+			show();
+		}
+
+		toHide.attr({
+			"aria-expanded": "false",
+			"aria-hidden": "true"
+		});
+		eventData.oldTab.attr( "aria-selected", "false" );
+		// If we're switching tabs, remove the old tab from the tab order.
+		// If we're opening from collapsed state, remove the previous tab from the tab order.
+		// If we're collapsing, then keep the collapsing tab in the tab order.
+		if ( toShow.length && toHide.length ) {
+			eventData.oldTab.attr( "tabIndex", -1 );
+		} else if ( toShow.length ) {
+			this.tabs.filter(function() {
+				return $( this ).attr( "tabIndex" ) === 0;
+			})
+			.attr( "tabIndex", -1 );
+		}
+
+		toShow.attr({
+			"aria-expanded": "true",
+			"aria-hidden": "false"
+		});
+		eventData.newTab.attr({
+			"aria-selected": "true",
+			tabIndex: 0
+		});
+	},
+
+	_activate: function( index ) {
+		var anchor,
+			active = this._findActive( index );
+
+		// trying to activate the already active panel
+		if ( active[ 0 ] === this.active[ 0 ] ) {
+			return;
+		}
+
+		// trying to collapse, simulate a click on the current active header
+		if ( !active.length ) {
+			active = this.active;
+		}
+
+		anchor = active.find( ".ui-tabs-anchor" )[ 0 ];
+		this._eventHandler({
+			target: anchor,
+			currentTarget: anchor,
+			preventDefault: $.noop
+		});
+	},
+
+	_findActive: function( index ) {
+		return index === false ? $() : this.tabs.eq( index );
+	},
+
+	_getIndex: function( index ) {
+		// meta-function to give users option to provide a href string instead of a numerical index.
+		if ( typeof index === "string" ) {
+			index = this.anchors.index( this.anchors.filter( "[href$='" + index + "']" ) );
+		}
+
+		return index;
+	},
+
+	_destroy: function() {
+		if ( this.xhr ) {
+			this.xhr.abort();
+		}
+
+		this.element.removeClass( "ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible" );
+
+		this.tablist
+			.removeClass( "ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all" )
+			.removeAttr( "role" );
+
+		this.anchors
+			.removeClass( "ui-tabs-anchor" )
+			.removeAttr( "role" )
+			.removeAttr( "tabIndex" )
+			.removeUniqueId();
+
+		this.tabs.add( this.panels ).each(function() {
+			if ( $.data( this, "ui-tabs-destroy" ) ) {
+				$( this ).remove();
+			} else {
+				$( this )
+					.removeClass( "ui-state-default ui-state-active ui-state-disabled " +
+						"ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel" )
+					.removeAttr( "tabIndex" )
+					.removeAttr( "aria-live" )
+					.removeAttr( "aria-busy" )
+					.removeAttr( "aria-selected" )
+					.removeAttr( "aria-labelledby" )
+					.removeAttr( "aria-hidden" )
+					.removeAttr( "aria-expanded" )
+					.removeAttr( "role" );
+			}
+		});
+
+		this.tabs.each(function() {
+			var li = $( this ),
+				prev = li.data( "ui-tabs-aria-controls" );
+			if ( prev ) {
+				li
+					.attr( "aria-controls", prev )
+					.removeData( "ui-tabs-aria-controls" );
+			} else {
+				li.removeAttr( "aria-controls" );
+			}
+		});
+
+		this.panels.show();
+
+		if ( this.options.heightStyle !== "content" ) {
+			this.panels.css( "height", "" );
+		}
+	},
+
+	enable: function( index ) {
+		var disabled = this.options.disabled;
+		if ( disabled === false ) {
+			return;
+		}
+
+		if ( index === undefined ) {
+			disabled = false;
+		} else {
+			index = this._getIndex( index );
+			if ( $.isArray( disabled ) ) {
+				disabled = $.map( disabled, function( num ) {
+					return num !== index ? num : null;
+				});
+			} else {
+				disabled = $.map( this.tabs, function( li, num ) {
+					return num !== index ? num : null;
+				});
+			}
+		}
+		this._setupDisabled( disabled );
+	},
+
+	disable: function( index ) {
+		var disabled = this.options.disabled;
+		if ( disabled === true ) {
+			return;
+		}
+
+		if ( index === undefined ) {
+			disabled = true;
+		} else {
+			index = this._getIndex( index );
+			if ( $.inArray( index, disabled ) !== -1 ) {
+				return;
+			}
+			if ( $.isArray( disabled ) ) {
+				disabled = $.merge( [ index ], disabled ).sort();
+			} else {
+				disabled = [ index ];
+			}
+		}
+		this._setupDisabled( disabled );
+	},
+
+	load: function( index, event ) {
+		index = this._getIndex( index );
+		var that = this,
+			tab = this.tabs.eq( index ),
+			anchor = tab.find( ".ui-tabs-anchor" ),
+			panel = this._getPanelForTab( tab ),
+			eventData = {
+				tab: tab,
+				panel: panel
+			};
+
+		// not remote
+		if ( isLocal( anchor[ 0 ] ) ) {
+			return;
+		}
+
+		this.xhr = $.ajax( this._ajaxSettings( anchor, event, eventData ) );
+
+		// support: jQuery <1.8
+		// jQuery <1.8 returns false if the request is canceled in beforeSend,
+		// but as of 1.8, $.ajax() always returns a jqXHR object.
+		if ( this.xhr && this.xhr.statusText !== "canceled" ) {
+			tab.addClass( "ui-tabs-loading" );
+			panel.attr( "aria-busy", "true" );
+
+			this.xhr
+				.success(function( response ) {
+					// support: jQuery <1.8
+					// http://bugs.jquery.com/ticket/11778
+					setTimeout(function() {
+						panel.html( response );
+						that._trigger( "load", event, eventData );
+					}, 1 );
+				})
+				.complete(function( jqXHR, status ) {
+					// support: jQuery <1.8
+					// http://bugs.jquery.com/ticket/11778
+					setTimeout(function() {
+						if ( status === "abort" ) {
+							that.panels.stop( false, true );
+						}
+
+						tab.removeClass( "ui-tabs-loading" );
+						panel.removeAttr( "aria-busy" );
+
+						if ( jqXHR === that.xhr ) {
+							delete that.xhr;
+						}
+					}, 1 );
+				});
+		}
+	},
+
+	_ajaxSettings: function( anchor, event, eventData ) {
+		var that = this;
+		return {
+			url: anchor.attr( "href" ),
+			beforeSend: function( jqXHR, settings ) {
+				return that._trigger( "beforeLoad", event,
+					$.extend( { jqXHR : jqXHR, ajaxSettings: settings }, eventData ) );
+			}
+		};
+	},
+
+	_getPanelForTab: function( tab ) {
+		var id = $( tab ).attr( "aria-controls" );
+		return this.element.find( this._sanitizeSelector( "#" + id ) );
+	}
+});
+
+})( jQuery );
diff --git a/cli/sdncon/ui/static/js/thirdparty/jquery-ui-1.10.2.custom.min.js b/cli/sdncon/ui/static/js/thirdparty/jquery-ui-1.10.2.custom.min.js
new file mode 100755
index 0000000..af3ec73
--- /dev/null
+++ b/cli/sdncon/ui/static/js/thirdparty/jquery-ui-1.10.2.custom.min.js
@@ -0,0 +1,6 @@
+/*! jQuery UI - v1.10.2 - 2013-04-05
+* http://jqueryui.com
+* Includes: jquery.ui.core.js, jquery.ui.widget.js, jquery.ui.tabs.js
+* Copyright 2013 jQuery Foundation and other contributors Licensed MIT */
+
+(function(e,t){function i(t,i){var a,n,r,o=t.nodeName.toLowerCase();return"area"===o?(a=t.parentNode,n=a.name,t.href&&n&&"map"===a.nodeName.toLowerCase()?(r=e("img[usemap=#"+n+"]")[0],!!r&&s(r)):!1):(/input|select|textarea|button|object/.test(o)?!t.disabled:"a"===o?t.href||i:i)&&s(t)}function s(t){return e.expr.filters.visible(t)&&!e(t).parents().addBack().filter(function(){return"hidden"===e.css(this,"visibility")}).length}var a=0,n=/^ui-id-\d+$/;e.ui=e.ui||{},e.extend(e.ui,{version:"1.10.2",keyCode:{BACKSPACE:8,COMMA:188,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,NUMPAD_ADD:107,NUMPAD_DECIMAL:110,NUMPAD_DIVIDE:111,NUMPAD_ENTER:108,NUMPAD_MULTIPLY:106,NUMPAD_SUBTRACT:109,PAGE_DOWN:34,PAGE_UP:33,PERIOD:190,RIGHT:39,SPACE:32,TAB:9,UP:38}}),e.fn.extend({focus:function(t){return function(i,s){return"number"==typeof i?this.each(function(){var t=this;setTimeout(function(){e(t).focus(),s&&s.call(t)},i)}):t.apply(this,arguments)}}(e.fn.focus),scrollParent:function(){var t;return t=e.ui.ie&&/(static|relative)/.test(this.css("position"))||/absolute/.test(this.css("position"))?this.parents().filter(function(){return/(relative|absolute|fixed)/.test(e.css(this,"position"))&&/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0):this.parents().filter(function(){return/(auto|scroll)/.test(e.css(this,"overflow")+e.css(this,"overflow-y")+e.css(this,"overflow-x"))}).eq(0),/fixed/.test(this.css("position"))||!t.length?e(document):t},zIndex:function(i){if(i!==t)return this.css("zIndex",i);if(this.length)for(var s,a,n=e(this[0]);n.length&&n[0]!==document;){if(s=n.css("position"),("absolute"===s||"relative"===s||"fixed"===s)&&(a=parseInt(n.css("zIndex"),10),!isNaN(a)&&0!==a))return a;n=n.parent()}return 0},uniqueId:function(){return this.each(function(){this.id||(this.id="ui-id-"+ ++a)})},removeUniqueId:function(){return this.each(function(){n.test(this.id)&&e(this).removeAttr("id")})}}),e.extend(e.expr[":"],{data:e.expr.createPseudo?e.expr.createPseudo(function(t){return function(i){return!!e.data(i,t)}}):function(t,i,s){return!!e.data(t,s[3])},focusable:function(t){return i(t,!isNaN(e.attr(t,"tabindex")))},tabbable:function(t){var s=e.attr(t,"tabindex"),a=isNaN(s);return(a||s>=0)&&i(t,!a)}}),e("<a>").outerWidth(1).jquery||e.each(["Width","Height"],function(i,s){function a(t,i,s,a){return e.each(n,function(){i-=parseFloat(e.css(t,"padding"+this))||0,s&&(i-=parseFloat(e.css(t,"border"+this+"Width"))||0),a&&(i-=parseFloat(e.css(t,"margin"+this))||0)}),i}var n="Width"===s?["Left","Right"]:["Top","Bottom"],r=s.toLowerCase(),o={innerWidth:e.fn.innerWidth,innerHeight:e.fn.innerHeight,outerWidth:e.fn.outerWidth,outerHeight:e.fn.outerHeight};e.fn["inner"+s]=function(i){return i===t?o["inner"+s].call(this):this.each(function(){e(this).css(r,a(this,i)+"px")})},e.fn["outer"+s]=function(t,i){return"number"!=typeof t?o["outer"+s].call(this,t):this.each(function(){e(this).css(r,a(this,t,!0,i)+"px")})}}),e.fn.addBack||(e.fn.addBack=function(e){return this.add(null==e?this.prevObject:this.prevObject.filter(e))}),e("<a>").data("a-b","a").removeData("a-b").data("a-b")&&(e.fn.removeData=function(t){return function(i){return arguments.length?t.call(this,e.camelCase(i)):t.call(this)}}(e.fn.removeData)),e.ui.ie=!!/msie [\w.]+/.exec(navigator.userAgent.toLowerCase()),e.support.selectstart="onselectstart"in document.createElement("div"),e.fn.extend({disableSelection:function(){return this.bind((e.support.selectstart?"selectstart":"mousedown")+".ui-disableSelection",function(e){e.preventDefault()})},enableSelection:function(){return this.unbind(".ui-disableSelection")}}),e.extend(e.ui,{plugin:{add:function(t,i,s){var a,n=e.ui[t].prototype;for(a in s)n.plugins[a]=n.plugins[a]||[],n.plugins[a].push([i,s[a]])},call:function(e,t,i){var s,a=e.plugins[t];if(a&&e.element[0].parentNode&&11!==e.element[0].parentNode.nodeType)for(s=0;a.length>s;s++)e.options[a[s][0]]&&a[s][1].apply(e.element,i)}},hasScroll:function(t,i){if("hidden"===e(t).css("overflow"))return!1;var s=i&&"left"===i?"scrollLeft":"scrollTop",a=!1;return t[s]>0?!0:(t[s]=1,a=t[s]>0,t[s]=0,a)}})})(jQuery);(function(e,t){var i=0,s=Array.prototype.slice,n=e.cleanData;e.cleanData=function(t){for(var i,s=0;null!=(i=t[s]);s++)try{e(i).triggerHandler("remove")}catch(a){}n(t)},e.widget=function(i,s,n){var a,r,o,h,l={},u=i.split(".")[0];i=i.split(".")[1],a=u+"-"+i,n||(n=s,s=e.Widget),e.expr[":"][a.toLowerCase()]=function(t){return!!e.data(t,a)},e[u]=e[u]||{},r=e[u][i],o=e[u][i]=function(e,i){return this._createWidget?(arguments.length&&this._createWidget(e,i),t):new o(e,i)},e.extend(o,r,{version:n.version,_proto:e.extend({},n),_childConstructors:[]}),h=new s,h.options=e.widget.extend({},h.options),e.each(n,function(i,n){return e.isFunction(n)?(l[i]=function(){var e=function(){return s.prototype[i].apply(this,arguments)},t=function(e){return s.prototype[i].apply(this,e)};return function(){var i,s=this._super,a=this._superApply;return this._super=e,this._superApply=t,i=n.apply(this,arguments),this._super=s,this._superApply=a,i}}(),t):(l[i]=n,t)}),o.prototype=e.widget.extend(h,{widgetEventPrefix:r?h.widgetEventPrefix:i},l,{constructor:o,namespace:u,widgetName:i,widgetFullName:a}),r?(e.each(r._childConstructors,function(t,i){var s=i.prototype;e.widget(s.namespace+"."+s.widgetName,o,i._proto)}),delete r._childConstructors):s._childConstructors.push(o),e.widget.bridge(i,o)},e.widget.extend=function(i){for(var n,a,r=s.call(arguments,1),o=0,h=r.length;h>o;o++)for(n in r[o])a=r[o][n],r[o].hasOwnProperty(n)&&a!==t&&(i[n]=e.isPlainObject(a)?e.isPlainObject(i[n])?e.widget.extend({},i[n],a):e.widget.extend({},a):a);return i},e.widget.bridge=function(i,n){var a=n.prototype.widgetFullName||i;e.fn[i]=function(r){var o="string"==typeof r,h=s.call(arguments,1),l=this;return r=!o&&h.length?e.widget.extend.apply(null,[r].concat(h)):r,o?this.each(function(){var s,n=e.data(this,a);return n?e.isFunction(n[r])&&"_"!==r.charAt(0)?(s=n[r].apply(n,h),s!==n&&s!==t?(l=s&&s.jquery?l.pushStack(s.get()):s,!1):t):e.error("no such method '"+r+"' for "+i+" widget instance"):e.error("cannot call methods on "+i+" prior to initialization; "+"attempted to call method '"+r+"'")}):this.each(function(){var t=e.data(this,a);t?t.option(r||{})._init():e.data(this,a,new n(r,this))}),l}},e.Widget=function(){},e.Widget._childConstructors=[],e.Widget.prototype={widgetName:"widget",widgetEventPrefix:"",defaultElement:"<div>",options:{disabled:!1,create:null},_createWidget:function(t,s){s=e(s||this.defaultElement||this)[0],this.element=e(s),this.uuid=i++,this.eventNamespace="."+this.widgetName+this.uuid,this.options=e.widget.extend({},this.options,this._getCreateOptions(),t),this.bindings=e(),this.hoverable=e(),this.focusable=e(),s!==this&&(e.data(s,this.widgetFullName,this),this._on(!0,this.element,{remove:function(e){e.target===s&&this.destroy()}}),this.document=e(s.style?s.ownerDocument:s.document||s),this.window=e(this.document[0].defaultView||this.document[0].parentWindow)),this._create(),this._trigger("create",null,this._getCreateEventData()),this._init()},_getCreateOptions:e.noop,_getCreateEventData:e.noop,_create:e.noop,_init:e.noop,destroy:function(){this._destroy(),this.element.unbind(this.eventNamespace).removeData(this.widgetName).removeData(this.widgetFullName).removeData(e.camelCase(this.widgetFullName)),this.widget().unbind(this.eventNamespace).removeAttr("aria-disabled").removeClass(this.widgetFullName+"-disabled "+"ui-state-disabled"),this.bindings.unbind(this.eventNamespace),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")},_destroy:e.noop,widget:function(){return this.element},option:function(i,s){var n,a,r,o=i;if(0===arguments.length)return e.widget.extend({},this.options);if("string"==typeof i)if(o={},n=i.split("."),i=n.shift(),n.length){for(a=o[i]=e.widget.extend({},this.options[i]),r=0;n.length-1>r;r++)a[n[r]]=a[n[r]]||{},a=a[n[r]];if(i=n.pop(),s===t)return a[i]===t?null:a[i];a[i]=s}else{if(s===t)return this.options[i]===t?null:this.options[i];o[i]=s}return this._setOptions(o),this},_setOptions:function(e){var t;for(t in e)this._setOption(t,e[t]);return this},_setOption:function(e,t){return this.options[e]=t,"disabled"===e&&(this.widget().toggleClass(this.widgetFullName+"-disabled ui-state-disabled",!!t).attr("aria-disabled",t),this.hoverable.removeClass("ui-state-hover"),this.focusable.removeClass("ui-state-focus")),this},enable:function(){return this._setOption("disabled",!1)},disable:function(){return this._setOption("disabled",!0)},_on:function(i,s,n){var a,r=this;"boolean"!=typeof i&&(n=s,s=i,i=!1),n?(s=a=e(s),this.bindings=this.bindings.add(s)):(n=s,s=this.element,a=this.widget()),e.each(n,function(n,o){function h(){return i||r.options.disabled!==!0&&!e(this).hasClass("ui-state-disabled")?("string"==typeof o?r[o]:o).apply(r,arguments):t}"string"!=typeof o&&(h.guid=o.guid=o.guid||h.guid||e.guid++);var l=n.match(/^(\w+)\s*(.*)$/),u=l[1]+r.eventNamespace,c=l[2];c?a.delegate(c,u,h):s.bind(u,h)})},_off:function(e,t){t=(t||"").split(" ").join(this.eventNamespace+" ")+this.eventNamespace,e.unbind(t).undelegate(t)},_delay:function(e,t){function i(){return("string"==typeof e?s[e]:e).apply(s,arguments)}var s=this;return setTimeout(i,t||0)},_hoverable:function(t){this.hoverable=this.hoverable.add(t),this._on(t,{mouseenter:function(t){e(t.currentTarget).addClass("ui-state-hover")},mouseleave:function(t){e(t.currentTarget).removeClass("ui-state-hover")}})},_focusable:function(t){this.focusable=this.focusable.add(t),this._on(t,{focusin:function(t){e(t.currentTarget).addClass("ui-state-focus")},focusout:function(t){e(t.currentTarget).removeClass("ui-state-focus")}})},_trigger:function(t,i,s){var n,a,r=this.options[t];if(s=s||{},i=e.Event(i),i.type=(t===this.widgetEventPrefix?t:this.widgetEventPrefix+t).toLowerCase(),i.target=this.element[0],a=i.originalEvent)for(n in a)n in i||(i[n]=a[n]);return this.element.trigger(i,s),!(e.isFunction(r)&&r.apply(this.element[0],[i].concat(s))===!1||i.isDefaultPrevented())}},e.each({show:"fadeIn",hide:"fadeOut"},function(t,i){e.Widget.prototype["_"+t]=function(s,n,a){"string"==typeof n&&(n={effect:n});var r,o=n?n===!0||"number"==typeof n?i:n.effect||i:t;n=n||{},"number"==typeof n&&(n={duration:n}),r=!e.isEmptyObject(n),n.complete=a,n.delay&&s.delay(n.delay),r&&e.effects&&e.effects.effect[o]?s[t](n):o!==t&&s[o]?s[o](n.duration,n.easing,a):s.queue(function(i){e(this)[t](),a&&a.call(s[0]),i()})}})})(jQuery);(function(t,e){function i(){return++n}function s(t){return t.hash.length>1&&decodeURIComponent(t.href.replace(a,""))===decodeURIComponent(location.href.replace(a,""))}var n=0,a=/#.*$/;t.widget("ui.tabs",{version:"1.10.2",delay:300,options:{active:null,collapsible:!1,event:"click",heightStyle:"content",hide:null,show:null,activate:null,beforeActivate:null,beforeLoad:null,load:null},_create:function(){var e=this,i=this.options;this.running=!1,this.element.addClass("ui-tabs ui-widget ui-widget-content ui-corner-all").toggleClass("ui-tabs-collapsible",i.collapsible).delegate(".ui-tabs-nav > li","mousedown"+this.eventNamespace,function(e){t(this).is(".ui-state-disabled")&&e.preventDefault()}).delegate(".ui-tabs-anchor","focus"+this.eventNamespace,function(){t(this).closest("li").is(".ui-state-disabled")&&this.blur()}),this._processTabs(),i.active=this._initialActive(),t.isArray(i.disabled)&&(i.disabled=t.unique(i.disabled.concat(t.map(this.tabs.filter(".ui-state-disabled"),function(t){return e.tabs.index(t)}))).sort()),this.active=this.options.active!==!1&&this.anchors.length?this._findActive(i.active):t(),this._refresh(),this.active.length&&this.load(i.active)},_initialActive:function(){var i=this.options.active,s=this.options.collapsible,n=location.hash.substring(1);return null===i&&(n&&this.tabs.each(function(s,a){return t(a).attr("aria-controls")===n?(i=s,!1):e}),null===i&&(i=this.tabs.index(this.tabs.filter(".ui-tabs-active"))),(null===i||-1===i)&&(i=this.tabs.length?0:!1)),i!==!1&&(i=this.tabs.index(this.tabs.eq(i)),-1===i&&(i=s?!1:0)),!s&&i===!1&&this.anchors.length&&(i=0),i},_getCreateEventData:function(){return{tab:this.active,panel:this.active.length?this._getPanelForTab(this.active):t()}},_tabKeydown:function(i){var s=t(this.document[0].activeElement).closest("li"),n=this.tabs.index(s),a=!0;if(!this._handlePageNav(i)){switch(i.keyCode){case t.ui.keyCode.RIGHT:case t.ui.keyCode.DOWN:n++;break;case t.ui.keyCode.UP:case t.ui.keyCode.LEFT:a=!1,n--;break;case t.ui.keyCode.END:n=this.anchors.length-1;break;case t.ui.keyCode.HOME:n=0;break;case t.ui.keyCode.SPACE:return i.preventDefault(),clearTimeout(this.activating),this._activate(n),e;case t.ui.keyCode.ENTER:return i.preventDefault(),clearTimeout(this.activating),this._activate(n===this.options.active?!1:n),e;default:return}i.preventDefault(),clearTimeout(this.activating),n=this._focusNextTab(n,a),i.ctrlKey||(s.attr("aria-selected","false"),this.tabs.eq(n).attr("aria-selected","true"),this.activating=this._delay(function(){this.option("active",n)},this.delay))}},_panelKeydown:function(e){this._handlePageNav(e)||e.ctrlKey&&e.keyCode===t.ui.keyCode.UP&&(e.preventDefault(),this.active.focus())},_handlePageNav:function(i){return i.altKey&&i.keyCode===t.ui.keyCode.PAGE_UP?(this._activate(this._focusNextTab(this.options.active-1,!1)),!0):i.altKey&&i.keyCode===t.ui.keyCode.PAGE_DOWN?(this._activate(this._focusNextTab(this.options.active+1,!0)),!0):e},_findNextTab:function(e,i){function s(){return e>n&&(e=0),0>e&&(e=n),e}for(var n=this.tabs.length-1;-1!==t.inArray(s(),this.options.disabled);)e=i?e+1:e-1;return e},_focusNextTab:function(t,e){return t=this._findNextTab(t,e),this.tabs.eq(t).focus(),t},_setOption:function(t,i){return"active"===t?(this._activate(i),e):"disabled"===t?(this._setupDisabled(i),e):(this._super(t,i),"collapsible"===t&&(this.element.toggleClass("ui-tabs-collapsible",i),i||this.options.active!==!1||this._activate(0)),"event"===t&&this._setupEvents(i),"heightStyle"===t&&this._setupHeightStyle(i),e)},_tabId:function(t){return t.attr("aria-controls")||"ui-tabs-"+i()},_sanitizeSelector:function(t){return t?t.replace(/[!"$%&'()*+,.\/:;<=>?@\[\]\^`{|}~]/g,"\\$&"):""},refresh:function(){var e=this.options,i=this.tablist.children(":has(a[href])");e.disabled=t.map(i.filter(".ui-state-disabled"),function(t){return i.index(t)}),this._processTabs(),e.active!==!1&&this.anchors.length?this.active.length&&!t.contains(this.tablist[0],this.active[0])?this.tabs.length===e.disabled.length?(e.active=!1,this.active=t()):this._activate(this._findNextTab(Math.max(0,e.active-1),!1)):e.active=this.tabs.index(this.active):(e.active=!1,this.active=t()),this._refresh()},_refresh:function(){this._setupDisabled(this.options.disabled),this._setupEvents(this.options.event),this._setupHeightStyle(this.options.heightStyle),this.tabs.not(this.active).attr({"aria-selected":"false",tabIndex:-1}),this.panels.not(this._getPanelForTab(this.active)).hide().attr({"aria-expanded":"false","aria-hidden":"true"}),this.active.length?(this.active.addClass("ui-tabs-active ui-state-active").attr({"aria-selected":"true",tabIndex:0}),this._getPanelForTab(this.active).show().attr({"aria-expanded":"true","aria-hidden":"false"})):this.tabs.eq(0).attr("tabIndex",0)},_processTabs:function(){var e=this;this.tablist=this._getList().addClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").attr("role","tablist"),this.tabs=this.tablist.find("> li:has(a[href])").addClass("ui-state-default ui-corner-top").attr({role:"tab",tabIndex:-1}),this.anchors=this.tabs.map(function(){return t("a",this)[0]}).addClass("ui-tabs-anchor").attr({role:"presentation",tabIndex:-1}),this.panels=t(),this.anchors.each(function(i,n){var a,o,r,h=t(n).uniqueId().attr("id"),l=t(n).closest("li"),u=l.attr("aria-controls");s(n)?(a=n.hash,o=e.element.find(e._sanitizeSelector(a))):(r=e._tabId(l),a="#"+r,o=e.element.find(a),o.length||(o=e._createPanel(r),o.insertAfter(e.panels[i-1]||e.tablist)),o.attr("aria-live","polite")),o.length&&(e.panels=e.panels.add(o)),u&&l.data("ui-tabs-aria-controls",u),l.attr({"aria-controls":a.substring(1),"aria-labelledby":h}),o.attr("aria-labelledby",h)}),this.panels.addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").attr("role","tabpanel")},_getList:function(){return this.element.find("ol,ul").eq(0)},_createPanel:function(e){return t("<div>").attr("id",e).addClass("ui-tabs-panel ui-widget-content ui-corner-bottom").data("ui-tabs-destroy",!0)},_setupDisabled:function(e){t.isArray(e)&&(e.length?e.length===this.anchors.length&&(e=!0):e=!1);for(var i,s=0;i=this.tabs[s];s++)e===!0||-1!==t.inArray(s,e)?t(i).addClass("ui-state-disabled").attr("aria-disabled","true"):t(i).removeClass("ui-state-disabled").removeAttr("aria-disabled");this.options.disabled=e},_setupEvents:function(e){var i={click:function(t){t.preventDefault()}};e&&t.each(e.split(" "),function(t,e){i[e]="_eventHandler"}),this._off(this.anchors.add(this.tabs).add(this.panels)),this._on(this.anchors,i),this._on(this.tabs,{keydown:"_tabKeydown"}),this._on(this.panels,{keydown:"_panelKeydown"}),this._focusable(this.tabs),this._hoverable(this.tabs)},_setupHeightStyle:function(e){var i,s=this.element.parent();"fill"===e?(i=s.height(),i-=this.element.outerHeight()-this.element.height(),this.element.siblings(":visible").each(function(){var e=t(this),s=e.css("position");"absolute"!==s&&"fixed"!==s&&(i-=e.outerHeight(!0))}),this.element.children().not(this.panels).each(function(){i-=t(this).outerHeight(!0)}),this.panels.each(function(){t(this).height(Math.max(0,i-t(this).innerHeight()+t(this).height()))}).css("overflow","auto")):"auto"===e&&(i=0,this.panels.each(function(){i=Math.max(i,t(this).height("").height())}).height(i))},_eventHandler:function(e){var i=this.options,s=this.active,n=t(e.currentTarget),a=n.closest("li"),o=a[0]===s[0],r=o&&i.collapsible,h=r?t():this._getPanelForTab(a),l=s.length?this._getPanelForTab(s):t(),u={oldTab:s,oldPanel:l,newTab:r?t():a,newPanel:h};e.preventDefault(),a.hasClass("ui-state-disabled")||a.hasClass("ui-tabs-loading")||this.running||o&&!i.collapsible||this._trigger("beforeActivate",e,u)===!1||(i.active=r?!1:this.tabs.index(a),this.active=o?t():a,this.xhr&&this.xhr.abort(),l.length||h.length||t.error("jQuery UI Tabs: Mismatching fragment identifier."),h.length&&this.load(this.tabs.index(a),e),this._toggle(e,u))},_toggle:function(e,i){function s(){a.running=!1,a._trigger("activate",e,i)}function n(){i.newTab.closest("li").addClass("ui-tabs-active ui-state-active"),o.length&&a.options.show?a._show(o,a.options.show,s):(o.show(),s())}var a=this,o=i.newPanel,r=i.oldPanel;this.running=!0,r.length&&this.options.hide?this._hide(r,this.options.hide,function(){i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),n()}):(i.oldTab.closest("li").removeClass("ui-tabs-active ui-state-active"),r.hide(),n()),r.attr({"aria-expanded":"false","aria-hidden":"true"}),i.oldTab.attr("aria-selected","false"),o.length&&r.length?i.oldTab.attr("tabIndex",-1):o.length&&this.tabs.filter(function(){return 0===t(this).attr("tabIndex")}).attr("tabIndex",-1),o.attr({"aria-expanded":"true","aria-hidden":"false"}),i.newTab.attr({"aria-selected":"true",tabIndex:0})},_activate:function(e){var i,s=this._findActive(e);s[0]!==this.active[0]&&(s.length||(s=this.active),i=s.find(".ui-tabs-anchor")[0],this._eventHandler({target:i,currentTarget:i,preventDefault:t.noop}))},_findActive:function(e){return e===!1?t():this.tabs.eq(e)},_getIndex:function(t){return"string"==typeof t&&(t=this.anchors.index(this.anchors.filter("[href$='"+t+"']"))),t},_destroy:function(){this.xhr&&this.xhr.abort(),this.element.removeClass("ui-tabs ui-widget ui-widget-content ui-corner-all ui-tabs-collapsible"),this.tablist.removeClass("ui-tabs-nav ui-helper-reset ui-helper-clearfix ui-widget-header ui-corner-all").removeAttr("role"),this.anchors.removeClass("ui-tabs-anchor").removeAttr("role").removeAttr("tabIndex").removeUniqueId(),this.tabs.add(this.panels).each(function(){t.data(this,"ui-tabs-destroy")?t(this).remove():t(this).removeClass("ui-state-default ui-state-active ui-state-disabled ui-corner-top ui-corner-bottom ui-widget-content ui-tabs-active ui-tabs-panel").removeAttr("tabIndex").removeAttr("aria-live").removeAttr("aria-busy").removeAttr("aria-selected").removeAttr("aria-labelledby").removeAttr("aria-hidden").removeAttr("aria-expanded").removeAttr("role")}),this.tabs.each(function(){var e=t(this),i=e.data("ui-tabs-aria-controls");i?e.attr("aria-controls",i).removeData("ui-tabs-aria-controls"):e.removeAttr("aria-controls")}),this.panels.show(),"content"!==this.options.heightStyle&&this.panels.css("height","")},enable:function(i){var s=this.options.disabled;s!==!1&&(i===e?s=!1:(i=this._getIndex(i),s=t.isArray(s)?t.map(s,function(t){return t!==i?t:null}):t.map(this.tabs,function(t,e){return e!==i?e:null})),this._setupDisabled(s))},disable:function(i){var s=this.options.disabled;if(s!==!0){if(i===e)s=!0;else{if(i=this._getIndex(i),-1!==t.inArray(i,s))return;s=t.isArray(s)?t.merge([i],s).sort():[i]}this._setupDisabled(s)}},load:function(e,i){e=this._getIndex(e);var n=this,a=this.tabs.eq(e),o=a.find(".ui-tabs-anchor"),r=this._getPanelForTab(a),h={tab:a,panel:r};s(o[0])||(this.xhr=t.ajax(this._ajaxSettings(o,i,h)),this.xhr&&"canceled"!==this.xhr.statusText&&(a.addClass("ui-tabs-loading"),r.attr("aria-busy","true"),this.xhr.success(function(t){setTimeout(function(){r.html(t),n._trigger("load",i,h)},1)}).complete(function(t,e){setTimeout(function(){"abort"===e&&n.panels.stop(!1,!0),a.removeClass("ui-tabs-loading"),r.removeAttr("aria-busy"),t===n.xhr&&delete n.xhr},1)})))},_ajaxSettings:function(e,i,s){var n=this;return{url:e.attr("href"),beforeSend:function(e,a){return n._trigger("beforeLoad",i,t.extend({jqXHR:e,ajaxSettings:a},s))}}},_getPanelForTab:function(e){var i=t(e).attr("aria-controls");return this.element.find(this._sanitizeSelector("#"+i))}})})(jQuery);
\ No newline at end of file
diff --git a/cli/sdncon/ui/static/js/topology.js b/cli/sdncon/ui/static/js/topology.js
new file mode 100755
index 0000000..7ebfc43
--- /dev/null
+++ b/cli/sdncon/ui/static/js/topology.js
@@ -0,0 +1,192 @@
+/*
+Copyright (c) 2013 Sencha Inc. - Author: Nicolas Garcia Belmonte (http://philogb.github.com/)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+ */
+/*
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html
+#
+# 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.
+#
+*/
+
+//
+// ForceDirected example1.js Javascript
+//
+// Slightly modified for use in rendering a simple network diagram topology
+//
+
+var labelType, useGradients, nativeTextSupport, animate;
+
+(function() {
+  var ua = navigator.userAgent,
+      iStuff = ua.match(/iPhone/i) || ua.match(/iPad/i),
+      typeOfCanvas = typeof HTMLCanvasElement,
+      nativeCanvasSupport = (typeOfCanvas == 'object' || typeOfCanvas == 'function'),
+      textSupport = nativeCanvasSupport 
+        && (typeof document.createElement('canvas').getContext('2d').fillText == 'function');
+  //I'm setting this based on the fact that ExCanvas provides text support for IE
+  //and that as of today iPhone/iPad current text support is lame
+  labelType = (!nativeCanvasSupport || (textSupport && !iStuff))? 'Native' : 'HTML';
+  nativeTextSupport = labelType == 'Native';
+  useGradients = nativeCanvasSupport;
+  animate = !(iStuff || !nativeCanvasSupport);
+})();
+
+var Log = {
+  elem: false,
+  write: function(text){
+    if (!this.elem) 
+      this.elem = document.getElementById('log');
+    this.elem.innerHTML = text;
+    this.elem.style.left = (500 - this.elem.offsetWidth / 2) + 'px';
+  }
+};
+
+
+  // init data
+   var json = loadTopologyJSON();
+  // end
+  // init ForceDirected
+   var fd = new $jit.ForceDirected({
+    //id of the visualization container
+    injectInto: 'infovis',
+    //force height
+    height: 900,
+    //Enable zooming and panning
+    //by scrolling and DnD
+    Navigation: {
+      enable: true,
+      //Enable panning events only if we're dragging the empty
+      //canvas (and not a node).
+      panning: 'avoid nodes',
+      zooming: 10 //zoom speed. higher is more sensible
+    },
+    // Change node and edge styles such as
+    // color and width.
+    // These properties are also set per node
+    // with dollar prefixed data-properties in the
+    // JSON structure.
+    Node: {
+      overridable: true
+    },
+    Edge: {
+      overridable: true,
+      color: '#23A4FF',
+      lineWidth: 0.4
+    },
+    //Native canvas text styling
+    Label: {
+      type: labelType, //Native or HTML
+      size: 10,
+      color: '#000000',
+      style: 'bold'
+    },
+    //Add Tips
+    Tips: {
+      enable: true,
+      onShow: function(tip, node) {
+        if(!node) return;
+        // Build the relations list as a tooltip.
+        // This is done by traversing the clicked node connections.
+        var html = "<div class=\"dynamictable2\"> <table> <tr><td>" + node.name + " links:</td></tr><tr><td>",
+            list = [];
+        node.eachAdjacency(function(adj){
+          list.push(adj.nodeTo.name);
+        });
+        //append connections information
+        tip.innerHTML = html + list.join("</td></tr><tr><td>") + "</td></tr></table></div>";
+      }
+    },
+    // Add node events
+    Events: {
+      enable: true,
+      type: 'Native',
+      //Change cursor style when hovering a node
+      onMouseEnter: function() {
+        fd.canvas.getElement().style.cursor = 'move';
+      },
+      onMouseLeave: function() {
+        fd.canvas.getElement().style.cursor = '';
+      },
+      //Update node positions when dragged
+      onDragMove: function(node, eventInfo, e) {
+          var pos = eventInfo.getPos();
+          node.pos.setc(pos.x, pos.y);
+          fd.plot();
+      },
+      //Implement the same handler for touchscreens
+      onTouchMove: function(node, eventInfo, e) {
+        $jit.util.event.stop(e); //stop default touchmove event
+        this.onDragMove(node, eventInfo, e);
+      },
+      //No node click-handler for now
+      //onClick: function(node) {
+      //}
+    },
+    //Number of iterations for the FD algorithm
+    iterations: 10,
+    //Edge length
+    levelDistance: 130,
+    // Add text to the labels. This method is only triggered
+    // on label creation and only for DOM labels (not native canvas ones).
+    onCreateLabel: function(domElement, node){
+      domElement.innerHTML = node.name;
+      var style = domElement.style;
+      style.fontSize = "0.8em";
+      style.color = "#ddd";
+    },
+    // Change node styles when DOM labels are placed
+    // or moved.
+    onPlaceLabel: function(domElement, node){
+      var style = domElement.style;
+      var left = parseInt(style.left);
+      var top = parseInt(style.top);
+      var w = domElement.offsetWidth;
+      style.left = (left - w / 2) + 'px';
+      style.top = (top + 10) + 'px';
+      style.display = '';
+    }
+  });
+  // load JSON data.
+  fd.loadJSON(json);
+  // compute positions incrementally and animate.
+  fd.computeIncremental({
+    iter: 40,
+    property: 'end',
+    onStep: function(perc){
+      Log.write(perc + '% loaded...');
+    },
+    onComplete: function(){
+      Log.write('done');
+    }
+  });
+  // end
diff --git a/cli/sdncon/ui/templates/base.html b/cli/sdncon/ui/templates/base.html
new file mode 100755
index 0000000..04e58a1
--- /dev/null
+++ b/cli/sdncon/ui/templates/base.html
@@ -0,0 +1,14 @@
+<!DOCTYPE html>
+<html lang="en">
+	<head> 
+		<link rel="shortcut icon" href="static/favicon.ico" type="image/vnd.microsoft.icon">
+		<link href="static/css/thirdparty/jquery-ui-1.10.2.custom.css" rel="stylesheet">
+		<title>Open Daylight SDN Controller Platform Dashboard</title>
+		<link type="text/css" rel="stylesheet" href="static/css/table.css" media="all">
+    </head>
+
+	<body>
+				{% block content %}
+				{% endblock %}
+	</body>
+</html>
\ No newline at end of file
diff --git a/cli/sdncon/ui/templates/index.html b/cli/sdncon/ui/templates/index.html
new file mode 100755
index 0000000..50f63b5
--- /dev/null
+++ b/cli/sdncon/ui/templates/index.html
@@ -0,0 +1,184 @@
+<!-- 
+
+ Copyright (c) 2013 Big Switch Networks, Inc.
+
+ Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html
+
+ 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.
+
+ Web UI home
+
+-->
+
+{% extends "base.html" %}
+{% block content %}
+
+		<div id="skip-link">
+		</div>
+		<div id="page">
+			<header id="header" role="banner">
+			<div class="page-width"><div class="page-width-inner clearfix">
+					<div id="site-logo" style="margin: 15px; display: table;">
+						<div style="float: left; width: 100%;">
+							<img src="static/images/logo_opendaylight.png" border="0" style="margin: 0px; padding: 5px;">
+						</div>
+						<div style="float: left;">
+							<span class="title header-processed" id="page-title" style="color: #3f3f40; font-family: sans-serif, Arial Unicode MS, Arial; font-weight: 100; font-size: 40px; margin-bottom: 0px; margin-top: 0px; height: 40px; display: table-cell; vertical-align: middle; width: 100%; position: static; padding-left: 30px;">SDN Controller Platform Dashboard</span>
+						</div>
+					</div>
+					<div id="tagline">
+						<div class="region region-tagline">
+							<div id="block-block-9" class="block block-block first last odd">
+								<div class="block-content clearfix">
+								</div>
+							</div>
+						</div>
+					</div>
+
+			</div></div>
+			</header>
+			<div id="main" class="clearfix">
+				<div class="page-width"><div class="page-width-inner clearfix" style="margin:50px; margin-top: 0px;">
+						<a id="main-content"></a> 
+						<div id="tabs">
+							<ul>
+								<li><a href="#tabs-1">Switches</a></li>
+								<li><a href="#tabs-2">Inter-Switch Links</a></li>
+								<li><a href="#tabs-3">Hosts</a></li>
+								<li><a href="#tabs-4">Tunnels</a></li>
+								<li><a href="#tabs-5">Topology</a></li>
+								<span class="refresh" onClick="refreshTable(99);" style="float: right; padding: .6em; position: relative; z-index:1;"><img src="images/refresh.png" border="0"></span>
+							</ul>
+							<div id="tabs-1">
+								<div id="switchTableHolder" class="dynamictable">
+								</div>
+							</div>
+							<div style="clear: both;"></div>
+							<div id="tabs-2">
+								<div id="linkTableHolder" class="dynamictable">
+								</div>
+							</div>
+							<div style="clear: both;"></div>
+							<div id="tabs-3">
+								<div id="deviceTableHolder" class="dynamictable">
+								</div>
+							</div>
+							<div id="tabs-4">
+								<div id="tunnelTableHolder" class="dynamictable">
+								</div>
+							</div>
+							<div style="clear: both;"></div>
+							<div id="tabs-5">
+								<div id="TopologyTableHolder" class="dynamictable" style="border: 1px #e5e5e5;">
+									<div id="container">
+										<div id="center-container" style="background-color: #e5e5e5; border-bottom-right-radius: 5px; border-bottom-left-radius: 5px;">
+											<div id="infovis"></div>    
+										</div>
+										<div id="log" style="display: none;"></div>
+									</div>
+								</div>
+								<div style="text-align: justify; -ms-text-justify: distribute-all-lines; text-justify: distribute-all-lines;">
+
+									<div style="width: 100%; display: inline-block"></div>
+
+								</div>
+
+								<div style="clear: both;"></div>
+
+							</div>
+
+							<!-- Main content inner-->
+
+						</div>
+				</div></div>
+				<footer id="footer" role="contentinfo">
+				<div class="page-width"><div class="page-width-inner clearfix">  <div class="region region-footer">
+							<div id="block-p6-helper-footer" class="block block-p6-helper first last odd">
+
+
+								<div class="block-content clearfix">
+									<span id="ui-footer-statement" style="font-family: Helvetica, Arial, sans-serif; font-size: 11px; padding-left: 45;"><center>&nbsp; &#169;2013 OpenDaylight, A Linux Foundation Collaborative Project. All Rights Reserved.</center></span>  </div>
+							</div>
+						</div>
+				</div></div>
+				</footer>
+
+				<div id="dumpingground" style="display: none;"></div> 
+
+
+				<!-- /#page -->
+                <script src="static/js/thirdparty/jit.js"></script>
+                <script src="static/js/thirdparty/jquery-1.9.1.min.js"></script>  
+                <script src="static/js/thirdparty/jquery-ui-1.10.2.custom.min.js"></script>
+				<script type="text/javascript">
+
+					$(document).ready(function(){
+							refreshTable(99);
+							});
+$(function() {
+		$( "#tabs" ).tabs({
+activate: function( event, ui ) { refreshTable(ui.newTab.id); }
+});
+		// Hover states on the static widgets
+		$( "#dialog-link, #icons li" ).hover(
+			function() {
+			$( this ).addClass( "ui-state-hover" );
+			},
+			function() {
+			$( this ).removeClass( "ui-state-hover" );
+			}
+			);
+		});
+
+
+function refreshTable(choice){
+	switch(choice) {
+		case 0:
+			$('#switchTableHolder').load('ui/show_switch');
+			break;
+		case 1:
+			$('#linkTableHolder').load('ui/show_link');
+			break;
+		case 2:
+			$('#deviceTableHolder').load('ui/show_host');
+			break;
+		case 3:
+			$('#tunnelTableHolder').load('ui/show_tunnel');
+			break;
+		case 4:
+			var tmpJSON = loadTopologyJSON();
+			fd.loadJSON(tmpJSON);
+			fd.refresh();
+			break;
+		default:
+			$('#switchTableHolder').load('ui/show_switch');
+			$('#linkTableHolder').load('ui/show_link');
+			$('#deviceTableHolder').load('ui/show_host');
+			$('#tunnelTableHolder').load('ui/show_tunnel');
+			var tmpJSON = loadTopologyJSON();
+			fd.loadJSON(tmpJSON);
+			fd.refresh();
+			break;
+	}
+	//setTimeout(refreshTable, 5000);
+}
+    function loadTopologyJSON(){
+        var request = new XMLHttpRequest( );
+        request.open("GET", "ui/build_topology", false);
+        request.send(null);
+        var jsonFILE = request.response;
+        eval(jsonFILE);
+        return(json);
+    }
+    </script>
+<script language="javascript" type="text/javascript" src="static/js/topology.js"></script>
+
+{% endblock %}
diff --git a/cli/sdncon/ui/test.py b/cli/sdncon/ui/test.py
new file mode 100755
index 0000000..888d07b
--- /dev/null
+++ b/cli/sdncon/ui/test.py
@@ -0,0 +1,12 @@
+from showswitch import show_switch_data
+import json, urllib2
+
+def main():
+    request = None
+    print show_switch_data(None)
+
+    #url = 'http://localhost:8000/rest/v1/model/switch-alias/'
+    #print json.load(urllib2.urlopen(url))
+
+if __name__ == "__main__":
+    main()
\ No newline at end of file
diff --git a/cli/sdncon/ui/views.py b/cli/sdncon/ui/views.py
new file mode 100755
index 0000000..3b7a911
--- /dev/null
+++ b/cli/sdncon/ui/views.py
@@ -0,0 +1,66 @@
+#
+# Copyright (c) 2013 Big Switch Networks, Inc.
+#
+# Licensed under the Eclipse Public License, Version 1.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.eclipse.org/legal/epl-v10.html
+#
+# 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.
+#
+
+#  Views for the web UI
+#
+
+from django.shortcuts import render_to_response, render
+from django.utils import simplejson
+from django.http import HttpResponse
+from django.contrib.auth.decorators import login_required
+from django.contrib.auth.models import User
+from django.template import RequestContext
+from django.template.loader import render_to_string
+from sdncon.apploader import AppLoader, AppLister
+from sdncon.clusterAdmin.utils import conditionally, isCloudBuild
+from sdncon.clusterAdmin.models import Customer, Cluster, CustomerUser
+from scripts.showswitch import show_switch_data
+from scripts.buildtopology import build_topology_data
+from scripts.showlink import show_link_data
+from scripts.showtunnel import show_tunnel_data
+from scripts.showhost import show_host_data
+import os
+
+
+JSON_CONTENT_TYPE = 'application/json'
+
+# --- View for the root page of any application
+def index(request):
+    return render_to_response('ui/templates/index.html')
+
+def show_switch(request):
+    html = show_switch_data(request)
+    return HttpResponse(html)
+
+def show_link(request):
+    html = show_link_data(request)
+    return HttpResponse(html)
+
+def show_host(request):
+    html = show_host_data(request)
+    return HttpResponse(html)
+
+def show_tunnel(request):
+    html = show_tunnel_data(request)
+    return HttpResponse(html)
+
+
+def build_topology(request):
+    html = build_topology_data(request)
+    return HttpResponse(html)
+
+
+   
