diff --git a/plugins/Stats/StatsPlugin.py b/plugins/Stats/StatsPlugin.py index 9e0c1cbf..7bc09165 100644 --- a/plugins/Stats/StatsPlugin.py +++ b/plugins/Stats/StatsPlugin.py @@ -31,6 +31,7 @@ class UiRequestPlugin(object): def actionStats(self): import gc, sys from Ui import UiRequest + from Crypt import CryptConnection hpy = None if self.get.get("size") == "1": # Calc obj size @@ -47,16 +48,17 @@ class UiRequestPlugin(object): yield """ """ # Memory try: yield "rev%s | " % config.rev - yield "IP external: %s | " % config.ip_external + yield "%s | " % config.ip_external yield "Opened: %s | " % main.file_server.port_opened - yield "Recv: %.2fMB, Sent: %.2fMB | " % (float(main.file_server.bytes_recv)/1024/1024, float(main.file_server.bytes_sent)/1024/1024) + yield "Crypt: %s | " % CryptConnection.manager.crypt_supported + yield "In: %.2fMB, Out: %.2fMB | " % (float(main.file_server.bytes_recv)/1024/1024, float(main.file_server.bytes_sent)/1024/1024) yield "Peerid: %s | " % main.file_server.peer_id import psutil process = psutil.Process(os.getpid()) @@ -64,7 +66,7 @@ class UiRequestPlugin(object): yield "Mem: %.2fMB | " % mem yield "Threads: %s | " % len(process.threads()) yield "CPU: usr %.2fs sys %.2fs | " % process.cpu_times() - yield "Open files: %s | " % len(process.open_files()) + yield "Files: %s | " % len(process.open_files()) yield "Sockets: %s | " % len(process.connections()) yield "Calc size on off" except Exception, err: @@ -73,15 +75,20 @@ class UiRequestPlugin(object): # Connections yield "Connections (%s, total made: %s):
" % (len(main.file_server.connections), main.file_server.last_connection_id) - yield "" - yield "" + yield "
id protocol type ip open ping buffidle open delay sent received last sent waiting version peerid
" + yield "" for connection in main.file_server.connections: + if "cipher" in dir(connection.sock): + cipher = connection.sock.cipher()[0] + else: + cipher = connection.crypt yield self.formatTableRow([ ("%3d", connection.id), ("%s", connection.protocol), ("%s", connection.type), ("%s:%s", (connection.ip, connection.port)), ("%s", connection.handshake.get("port_opened")), + ("%s", (connection.crypt, cipher)), ("%6.3f", connection.last_ping_delay), ("%s", connection.incomplete_buff_recv), ("since", max(connection.last_send_time, connection.last_recv_time)), diff --git a/src/Config.py b/src/Config.py index bd6f245d..ce84483a 100644 --- a/src/Config.py +++ b/src/Config.py @@ -3,8 +3,8 @@ import ConfigParser class Config(object): def __init__(self): - self.version = "0.3.0" - self.rev = 196 + self.version = "0.3.1" + self.rev = 238 self.parser = self.createArguments() argv = sys.argv[:] # Copy command line arguments argv = self.parseConfig(argv) # Add arguments from config file @@ -77,7 +77,7 @@ class Config(object): # PeerPing action = subparsers.add_parser("peerPing", help='Send Ping command to peer') action.add_argument('peer_ip', help='Peer ip') - action.add_argument('peer_port', help='Peer port') + action.add_argument('peer_port', help='Peer port', nargs='?') # PeerGetFile action = subparsers.add_parser("peerGetFile", help='Request and print a file content from peer') @@ -118,8 +118,10 @@ class Config(object): parser.add_argument('--fileserver_port',help='FileServer bind port', default=15441, type=int, metavar='port') parser.add_argument('--disable_udp', help='Disable UDP connections', action='store_true') parser.add_argument('--proxy', help='Socks proxy address', metavar='ip:port') - parser.add_argument('--use_openssl', help='Use OpenSSL liblary for speedup', type='bool', choices=[True, False], default=use_openssl) parser.add_argument('--ip_external', help='External ip (tested on start if None)', metavar='ip') + parser.add_argument('--use_openssl', help='Use OpenSSL liblary for speedup', type='bool', choices=[True, False], default=use_openssl) + parser.add_argument('--disable_encryption', help='Disable connection encryption', action='store_true') + parser.add_argument('--disable_sslcompression', help='Disable SSL compression to save memory', type='bool', choices=[True, False], default=True) parser.add_argument('--coffeescript_compiler', help='Coffeescript compiler for developing', default=coffeescript, metavar='executable_path') diff --git a/src/Connection/Connection.py b/src/Connection/Connection.py index 508ef0d8..f41a53a4 100644 --- a/src/Connection/Connection.py +++ b/src/Connection/Connection.py @@ -4,9 +4,10 @@ import gevent, msgpack from Config import config from Debug import Debug from util import StreamingMsgpack +from Crypt import CryptConnection class Connection(object): - __slots__ = ("sock", "ip", "port", "peer_id", "id", "protocol", "type", "server", "unpacker", "req_id", "handshake", "connected", "event_connected", "closed", "start_time", "last_recv_time", "last_message_time", "last_send_time", "last_sent_time", "incomplete_buff_recv", "bytes_recv", "bytes_sent", "last_ping_delay", "last_req_time", "last_cmd", "name", "updateName", "waiting_requests") + __slots__ = ("sock", "ip", "port", "peer_id", "id", "protocol", "type", "server", "unpacker", "req_id", "handshake", "crypt", "connected", "event_connected", "closed", "start_time", "last_recv_time", "last_message_time", "last_send_time", "last_sent_time", "incomplete_buff_recv", "bytes_recv", "bytes_sent", "last_ping_delay", "last_req_time", "last_cmd", "name", "updateName", "waiting_requests") def __init__(self, server, ip, port, sock=None): self.sock = sock @@ -22,6 +23,8 @@ class Connection(object): self.unpacker = None # Stream incoming socket messages here self.req_id = 0 # Last request id self.handshake = {} # Handshake info got from peer + self.crypt = None # Connection encryption method + self.connected = False self.event_connected = gevent.event.AsyncResult() # Solves on handshake received self.closed = False @@ -76,6 +79,7 @@ class Connection(object): # Handle incoming connection def handleIncomingConnection(self, sock): + self.log("Incoming connection...") self.type = "in" self.messageLoop() @@ -90,10 +94,9 @@ class Connection(object): self.connected = True self.unpacker = msgpack.Unpacker() - sock = self.sock try: while True: - buff = sock.recv(16*1024) + buff = self.sock.recv(16*1024) if not buff: break # Connection closed self.last_recv_time = time.time() self.incomplete_buff_recv += 1 @@ -118,12 +121,32 @@ class Connection(object): "version": config.version, "protocol": "v2", "peer_id": self.server.peer_id, - "fileserver_port": config.fileserver_port, + "fileserver_port": self.server.port, "port_opened": self.server.port_opened, - "rev": config.rev + "rev": config.rev, + "crypt_supported": CryptConnection.manager.crypt_supported, + "crypt": self.crypt } + def setHandshake(self, handshake): + self.handshake = handshake + if handshake.get("port_opened", None) == False: # Not connectable + self.port = 0 + else: + self.port = handshake["fileserver_port"] # Set peer fileserver port + # Check if we can encrypt the connection + if handshake.get("crypt_supported"): + if handshake.get("crypt"): # Recommended crypt by server + crypt = handshake["crypt"] + else: # Select the best supported on both sides + crypt = CryptConnection.manager.selectCrypt(handshake["crypt_supported"]) + + if crypt: + self.crypt = crypt + self.event_connected.set(True) # Mark handshake as done + + # Handle incoming message def handleMessage(self, message): self.last_message_time = time.time() @@ -133,29 +156,31 @@ class Connection(object): del self.waiting_requests[message["to"]] elif message["to"] == 0: # Other peers handshake ping = time.time()-self.start_time - if config.debug_socket: self.log("Got handshake response: %s, ping: %s" % (message, ping)) + if config.debug_socket: self.log("Handshake response: %s, ping: %s" % (message, ping)) self.last_ping_delay = ping - self.handshake = message - if self.handshake.get("port_opened", None) == False: # Not connectable - self.port = 0 - else: - self.port = message["fileserver_port"] # Set peer fileserver port - self.event_connected.set(True) # Mark handshake as done + # Server switched to crypt, lets do it also + if message.get("crypt"): + self.crypt = message["crypt"] + server = (self.type == "in") + self.log("Crypt out connection using: %s (server side: %s)..." % (self.crypt, server)) + self.sock = CryptConnection.manager.wrapSocket(self.sock, self.crypt, server) + self.sock.do_handshake() + self.setHandshake(message) else: self.log("Unknown response: %s" % message) elif message.get("cmd"): # Handhsake request if message["cmd"] == "handshake": - self.handshake = message["params"] - if self.handshake.get("port_opened", None) == False: # Not connectable - self.port = 0 - else: - self.port = self.handshake["fileserver_port"] # Set peer fileserver port - self.event_connected.set(True) # Mark handshake as done if config.debug_socket: self.log("Handshake request: %s" % message) + self.setHandshake(message["params"]) data = self.handshakeInfo() data["cmd"] = "response" data["to"] = message["req_id"] - self.send(data) + self.send(data) # Send response to handshake + # Sent crypt request to client + if self.crypt: + server = (self.type == "in") + self.log("Crypt in connection using: %s (server side: %s)..." % (self.crypt, server)) + self.sock = CryptConnection.manager.wrapSocket(self.sock, self.crypt, server) else: self.server.handleRequest(self, message) else: # Old style response, no req_id definied diff --git a/src/Connection/ConnectionServer.py b/src/Connection/ConnectionServer.py index 186382bb..e862c959 100644 --- a/src/Connection/ConnectionServer.py +++ b/src/Connection/ConnectionServer.py @@ -1,11 +1,12 @@ from gevent.server import StreamServer from gevent.pool import Pool -import socket, os, logging, random, string, time +import socket, os, logging, random, string, time, sys import gevent, msgpack import cStringIO as StringIO from Debug import Debug from Connection import Connection from Config import config +from Crypt import CryptConnection class ConnectionServer: @@ -39,12 +40,13 @@ class ConnectionServer: self.stream_server = StreamServer((ip.replace("*", ""), port), self.handleIncomingConnection, spawn=self.pool, backlog=100) if request_handler: self.handleRequest = request_handler + CryptConnection.manager.loadCerts() def start(self): self.running = True + self.log.debug("Binding to: %s:%s, (msgpack: %s), supported crypt: %s" % (self.ip, self.port, ".".join(map(str, msgpack.version)), CryptConnection.manager.crypt_supported ) ) try: - self.log.debug("Binding to: %s:%s (msgpack: %s)" % (self.ip, self.port, ".".join(map(str, msgpack.version)))) self.stream_server.serve_forever() # Start normal connection server except Exception, err: self.log.info("StreamServer bind error, must be running already: %s" % err) @@ -152,7 +154,6 @@ class ConnectionServer: connection.close() - # -- TESTING -- def testCreateServer(): diff --git a/src/Crypt/CryptConnection.py b/src/Crypt/CryptConnection.py new file mode 100644 index 00000000..9dd33741 --- /dev/null +++ b/src/Crypt/CryptConnection.py @@ -0,0 +1,101 @@ +import sys, logging, os +from Config import config +import gevent +from util import SslPatch + +class CryptConnectionManager: + def __init__(self): + # OpenSSL params + if sys.platform.startswith("win"): + self.openssl_bin = "src\\lib\\opensslVerify\\openssl.exe" + else: + self.openssl_bin = "openssl" + self.openssl_env = {"OPENSSL_CONF": "src/lib/opensslVerify/openssl.cnf"} + + self.crypt_supported = [] # Supported cryptos + + + # Select crypt that supported by both sides + # Return: Name of the crypto + def selectCrypt(self, client_supported): + for crypt in self.crypt_supported: + if crypt in client_supported: + return crypt + return False + + + # Wrap socket for crypt + # Return: wrapped socket + def wrapSocket(self, sock, crypt, server=False): + if crypt == "tls-rsa": + ciphers = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:AES128-GCM-SHA256:AES128-SHA256:HIGH:!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK" + if server: + return gevent.ssl.wrap_socket(sock, server_side=server, keyfile='%s/key-rsa.pem' % config.data_dir, certfile='%s/cert-rsa.pem' % config.data_dir, ciphers=ciphers) + else: + return gevent.ssl.wrap_socket(sock, ciphers=ciphers) + else: + return sock + + + def removeCerts(self): + for file_name in ["cert-rsa.pem", "key-rsa.pem"]: + file_path = "%s/%s" % (config.data_dir, file_name) + if os.path.isfile(file_path): os.unlink(file_path) + + + # Loand and create cert files is necessary + def loadCerts(self): + if config.disable_encryption: return False + + if self.loadSslRsaCert(): + self.crypt_supported.append("tls-rsa") + + + # Try to create RSA server cert + sign for connection encryption + # Return: True on success + def loadSslRsaCert(self): + import subprocess + + if os.path.isfile("%s/cert-rsa.pem" % config.data_dir) and os.path.isfile("%s/key-rsa.pem" % config.data_dir): + return True # Files already exits + + back = subprocess.Popen( + "%s req -x509 -newkey rsa:2048 -sha256 -batch -keyout %s/key-rsa.pem -out %s/cert-rsa.pem -nodes -config %s" % (self.openssl_bin, config.data_dir, config.data_dir, self.openssl_env["OPENSSL_CONF"]), + shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, env=self.openssl_env + ).stdout.read().strip() + logging.debug("Generating RSA cert and key PEM files...%s" % back) + + if os.path.isfile("%s/cert-rsa.pem" % config.data_dir) and os.path.isfile("%s/key-rsa.pem" % config.data_dir): + return True + else: + logging.error("RSA ECC SSL cert generation failed, cert or key files not exits.") + return False + + + # Not used yet: Missing on some platform + def createSslEccCert(self): + return False + import subprocess + + # Create ECC privatekey + back = subprocess.Popen( + "%s ecparam -name prime256v1 -genkey -out %s/key-ecc.pem" % (self.openssl_bin, config.data_dir), + shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, env=self.openssl_env + ).stdout.read().strip() + self.log.debug("Generating ECC privatekey PEM file...%s" % back) + + # Create ECC cert + back = subprocess.Popen( + "%s req -new -key %s/key-ecc.pem -x509 -nodes -out %s/cert-ecc.pem -config %s" % (self.openssl_bin, config.data_dir, config.data_dir, self.openssl_env["OPENSSL_CONF"]), + shell=True, stderr=subprocess.STDOUT, stdout=subprocess.PIPE, env=self.openssl_env + ).stdout.read().strip() + self.log.debug("Generating ECC cert PEM file...%s" % back) + + if os.path.isfile("%s/cert-ecc.pem" % config.data_dir) and os.path.isfile("%s/key-ecc.pem" % config.data_dir): + return True + else: + self.logging.error("ECC SSL cert generation failed, cert or key files not exits.") + return False + + +manager = CryptConnectionManager() \ No newline at end of file diff --git a/src/File/FileServer.py b/src/File/FileServer.py index f3b8338f..45c7b63a 100644 --- a/src/File/FileServer.py +++ b/src/File/FileServer.py @@ -63,6 +63,46 @@ class FileServer(ConnectionServer): def testOpenport(self, port = None): time.sleep(1) # Wait for port open if not port: port = self.port + back = self.testOpenportPortchecker(port) + if back["result"] == True: # Successful port check + return back + else: # Alternative port checker + return self.testOpenportCanyouseeme(port) + + + def testOpenportPortchecker(self, port = None): + self.log.info("Checking port %s using portchecker.co..." % port) + try: + data = urllib2.urlopen("http://portchecker.co/check", "port=%s" % port, timeout=20.0).read() + message = re.match('.*
(.*?)
', data, re.DOTALL).group(1) + message = re.sub("<.*?>", "", message.replace("
", " ").replace(" ", " ").strip()) # Strip http tags + except Exception, err: + message = "Error: %s" % Debug.formatException(err) + if "closed" in message: + self.log.info("[BAD :(] Port closed: %s" % message) + if port == self.port: + self.port_opened = False # Self port, update port_opened status + match = re.match(".*targetIP.*?value=\"(.*?)\"", data, re.DOTALL) # Try find my external ip in message + if match: # Found my ip in message + config.ip_external = match.group(1) + SiteManager.peer_blacklist.append((config.ip_external, self.port)) # Add myself to peer blacklist + else: + config.ip_external = False + return {"result": False, "message": message} + else: + self.log.info("[OK :)] Port open: %s" % message) + if port == self.port: # Self port, update port_opened status + self.port_opened = True + match = re.match(".*targetIP.*?value=\"(.*?)\"", data, re.DOTALL) # Try find my external ip in message + if match: # Found my ip in message + config.ip_external = match.group(1) + SiteManager.peer_blacklist.append((config.ip_external, self.port)) # Add myself to peer blacklist + else: + config.ip_external = False + return {"result": True, "message": message} + + + def testOpenportCanyouseeme(self, port = None): self.log.info("Checking port %s using canyouseeme.org..." % port) try: data = urllib2.urlopen("http://www.canyouseeme.org/", "port=%s" % port, timeout=20.0).read() diff --git a/src/Site/Site.py b/src/Site/Site.py index 07acc786..cb293b89 100644 --- a/src/Site/Site.py +++ b/src/Site/Site.py @@ -313,6 +313,69 @@ class Site: return len(published) + # Copy this site + def clone(self, address, privatekey=None, address_index=None, overwrite=False): + import shutil + new_site = SiteManager.site_manager.need(address, all_file=False) + default_dirs = [] # Dont copy these directories (has -default version) + for dir_name in os.listdir(self.storage.directory): + if "-default" in dir_name: + default_dirs.append(dir_name.replace("-default", "")) + + self.log.debug("Cloning to %s, ignore dirs: %s" % (address, default_dirs)) + + # Copy root content.json + if not new_site.storage.isFile("content.json") and not overwrite: # Content.json not exits yet, create a new one from source site + content_json = self.storage.loadJson("content.json") + del content_json["domain"] + content_json["title"] = "my"+content_json["title"] + content_json["cloned_from"] = self.address + if address_index: content_json["address_index"] = address_index # Site owner's BIP32 index + new_site.storage.writeJson("content.json", content_json) + new_site.content_manager.loadContent("content.json", add_bad_files=False, load_includes=False) + + # Copy files + for content_inner_path, content in self.content_manager.contents.items(): + for file_relative_path in sorted(content["files"].keys()): + file_inner_path = self.content_manager.toDir(content_inner_path)+file_relative_path # Relative to content.json + file_inner_path = file_inner_path.strip("/") # Strip leading / + if file_inner_path.split("/")[0] in default_dirs: # Dont copy directories that has -default postfixed alternative + self.log.debug("[SKIP] %s (has default alternative)" % file_inner_path) + continue + file_path = self.storage.getPath(file_inner_path) + + # Copy the file normally to keep the -default postfixed dir and file to allow cloning later + file_path_dest = new_site.storage.getPath(file_inner_path) + self.log.debug("[COPY] %s to %s..." % (file_inner_path, file_path_dest)) + dest_dir = os.path.dirname(file_path_dest) + if not os.path.isdir(dest_dir): os.makedirs(dest_dir) + shutil.copy(file_path, file_path_dest) + + # If -default in path, create a -default less copy of the file + if "-default" in file_inner_path: + file_path_dest = new_site.storage.getPath(file_inner_path.replace("-default", "")) + if new_site.storage.isFile(file_path_dest) and not overwrite: # Don't overwrite site files with default ones + self.log.debug("[SKIP] Default file: %s (already exits)" % file_inner_path) + continue + self.log.debug("[COPY] Default file: %s to %s..." % (file_inner_path, file_path_dest)) + dest_dir = os.path.dirname(file_path_dest) + if not os.path.isdir(dest_dir): os.makedirs(dest_dir) + shutil.copy(file_path, file_path_dest) + # Sign if content json + if file_path_dest.endswith("/content.json"): + new_site.storage.onUpdated(file_inner_path.replace("-default", "")) + new_site.content_manager.loadContent(file_inner_path.replace("-default", ""), add_bad_files=False, load_includes=False) + if privatekey: new_site.content_manager.sign(file_inner_path.replace("-default", ""), privatekey) + + if privatekey: new_site.content_manager.sign("content.json", privatekey) + + + # Rebuild DB + if new_site.storage.isFile("dbschema.json"): new_site.storage.rebuildDb() + + return new_site + + # Check and download if file not exits def needFile(self, inner_path, update=False, blocking=True, peer=None, priority=0): if self.storage.isFile(inner_path) and not update: # File exits, no need to do anything diff --git a/src/Site/SiteManager.py b/src/Site/SiteManager.py index 0d527109..7a8bdd6f 100644 --- a/src/Site/SiteManager.py +++ b/src/Site/SiteManager.py @@ -12,12 +12,13 @@ TRACKERS = [ #("udp", "www.eddie4.nl", 6969), #("udp", "trackr.sytes.net", 80), #("udp", "tracker4.piratux.com", 6969) - ("http", "exodus.desync.com:80/announce", None), + #("http", "exodus.desync.com:80/announce", None), Off ("http", "tracker.aletorrenty.pl:2710/announce", None), #("http", "torrent.gresille.org/announce", None), # Slow #("http", "announce.torrentsmd.com:6969/announce", None), # Off #("http", "i.bandito.org/announce", None), # Off - ("http", "retracker.telecom.kz/announce", None) + ("http", "retracker.telecom.kz/announce", None), + ("http", "torrent.gresille.org/announce", None), ] diff --git a/src/Site/SiteStorage.py b/src/Site/SiteStorage.py index e41602c7..950368da 100644 --- a/src/Site/SiteStorage.py +++ b/src/Site/SiteStorage.py @@ -22,8 +22,6 @@ class SiteStorage: raise Exception("Directory not exists: %s" % self.directory) - - # Load db from dbschema.json def openDb(self, check=True): schema = self.loadJson("dbschema.json") @@ -55,6 +53,8 @@ class SiteStorage: # Rebuild sql cache def rebuildDb(self, delete_db=True): + self.has_db = self.isFile("dbschema.json") + if not self.has_db: return False self.event_db_busy = gevent.event.AsyncResult() schema = self.loadJson("dbschema.json") db_path = self.getPath(schema["db_file"]) @@ -111,9 +111,6 @@ class SiteStorage: raise err return res - - - # Open file object def open(self, inner_path, mode="rb"): diff --git a/src/Test/BenchmarkSsl.py b/src/Test/BenchmarkSsl.py new file mode 100644 index 00000000..f0f627b9 --- /dev/null +++ b/src/Test/BenchmarkSsl.py @@ -0,0 +1,141 @@ +#!/usr/bin/python2 +from gevent import monkey; monkey.patch_all() +import os, time, sys, socket, ssl +sys.path.append(os.path.abspath("src")) # Imports relative to src dir + +import cStringIO as StringIO +import gevent +from gevent.queue import Queue, Empty, JoinableQueue +from gevent.server import StreamServer +from gevent.pool import Pool +from util import SslPatch + + +# Server +socks = [] +data = os.urandom(1024*100) +data += "\n" + +def handle(sock_raw, addr): + socks.append(sock_raw) + sock = sock_raw + #sock = ctx.wrap_socket(sock, server_side=True) + #if sock_raw.recv( 1, gevent.socket.MSG_PEEK ) == "\x16": + # sock = gevent.ssl.wrap_socket(sock_raw, server_side=True, keyfile='key-cz.pem', certfile='cert-cz.pem', ciphers=ciphers, ssl_version=ssl.PROTOCOL_TLSv1) + #fp = os.fdopen(sock.fileno(), 'rb', 1024*512) + try: + while True: + line = sock.recv(16*1024) + if not line: break + if line == "bye\n": + break + elif line == "gotssl\n": + sock.sendall("yes\n") + sock = gevent.ssl.wrap_socket(sock_raw, server_side=True, keyfile='src/Test/testdata/key-rsa.pem', certfile='src/Test/testdata/cert-rsa.pem', ciphers=ciphers) + else: + sock.sendall(data) + except Exception, err: + print err + try: + sock.shutdown(gevent.socket.SHUT_WR) + sock.close() + except: + pass + socks.remove(sock_raw) + +pool = Pool(1000) # do not accept more than 10000 connections +server = StreamServer(('127.0.0.1', 1234), handle) # +server.start() + + +# Client + + +total_num = 0 +total_bytes = 0 +clipher = None +ciphers = "ECDHE-ECDSA-AES128-GCM-SHA256:ECDH+AES128:ECDHE-RSA-AES128-GCM-SHA256:AES128-GCM-SHA256:AES128-SHA256:HIGH:!aNULL:!eNULL:!EXPORT:!DSS:!DES:!RC4:!3DES:!MD5:!PSK" + +# ctx = ssl.SSLContext(ssl.PROTOCOL_SSLv23) + +def getData(): + global total_num, total_bytes, clipher + data = None + sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + #sock = socket.ssl(s) + #sock = ssl.wrap_socket(sock) + sock.connect(("127.0.0.1", 1234)) + #sock.do_handshake() + #clipher = sock.cipher() + sock.send("gotssl\n") + if sock.recv(128) == "yes\n": + sock = ssl.wrap_socket(sock, ciphers=ciphers) + sock.do_handshake() + clipher = sock.cipher() + + + for req in range(100): + sock.sendall("req\n") + buff = StringIO.StringIO() + data = sock.recv(16*1024) + buff.write(data) + if not data: + break + while not data.endswith("\n"): + data = sock.recv(16*1024) + if not data: break + buff.write(data) + total_num += 1 + total_bytes += buff.tell() + if not data: + print "No data" + + sock.shutdown(gevent.socket.SHUT_WR) + sock.close() + +s = time.time() + +def info(): + import psutil, os + process = psutil.Process(os.getpid()) + while 1: + print total_num, "req", (total_bytes/1024), "kbytes", "transfered in", time.time()-s, "using", clipher, "Mem:", process.get_memory_info()[0] / float(2 ** 20) + time.sleep(1) + +gevent.spawn(info) + +for test in range(10): + clients = [] + for i in range(10): # Thread + clients.append(gevent.spawn(getData)) + gevent.joinall(clients) + + +print total_num, "req", (total_bytes/1024), "kbytes", "transfered in", time.time()-s + +# Separate client/server process: +# 10*10*100: +# Raw: 10000 req 1000009 kbytes transfered in 5.39999985695 +# RSA 2048: 10000 req 1000009 kbytes transfered in 27.7890000343 using ('ECDHE-RSA-AES256-SHA', 'TLSv1/SSLv3', 256) +# ECC: 10000 req 1000009 kbytes transfered in 26.1959998608 using ('ECDHE-ECDSA-AES256-SHA', 'TLSv1/SSLv3', 256) +# ECC: 10000 req 1000009 kbytes transfered in 28.2410001755 using ('ECDHE-ECDSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256) Mem: 13.3828125 +# +# 10*100*10: +# Raw: 10000 req 1000009 kbytes transfered in 7.02700018883 Mem: 14.328125 +# RSA 2048: 10000 req 1000009 kbytes transfered in 44.8860001564 using ('ECDHE-RSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256) Mem: 20.078125 +# ECC: 10000 req 1000009 kbytes transfered in 37.9430000782 using ('ECDHE-ECDSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256) Mem: 20.0234375 +# +# 1*100*100: +# Raw: 10000 req 1000009 kbytes transfered in 4.64400005341 Mem: 14.06640625 +# RSA: 10000 req 1000009 kbytes transfered in 24.2300000191 using ('ECDHE-RSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256) Mem: 19.7734375 +# ECC: 10000 req 1000009 kbytes transfered in 22.8849999905 using ('ECDHE-ECDSA-AES256-GCM-SHA384', 'TLSv1/SSLv3', 256) Mem: 17.8125 +# AES128: 10000 req 1000009 kbytes transfered in 21.2839999199 using ('AES128-GCM-SHA256', 'TLSv1/SSLv3', 128) Mem: 14.1328125 +# ECC+128: 10000 req 1000009 kbytes transfered in 20.496999979 using ('ECDHE-ECDSA-AES128-GCM-SHA256', 'TLSv1/SSLv3', 128) Mem: 14.40234375 +# +# +# Single process: +# 1*100*100 +# RSA: 10000 req 1000009 kbytes transfered in 41.7899999619 using ('ECDHE-RSA-AES128-GCM-SHA256', 'TLSv1/SSLv3', 128) Mem: 26.91015625 +# +# 10*10*100 +# RSA: 10000 req 1000009 kbytes transfered in 40.1640000343 using ('ECDHE-RSA-AES128-GCM-SHA256', 'TLSv1/SSLv3', 128) Mem: 14.94921875 \ No newline at end of file diff --git a/src/Test/test.py b/src/Test/test.py index b1455189..e9874d9c 100644 --- a/src/Test/test.py +++ b/src/Test/test.py @@ -1,6 +1,9 @@ import sys, os, unittest, urllib, time sys.path.append(os.path.abspath("src")) # Imports relative to src dir +from Config import config +config.data_dir = "src/Test/testdata" # Use test data for unittests + from Crypt import CryptBitcoin from Ui import UiRequest @@ -301,11 +304,91 @@ class TestCase(unittest.TestCase): self.assertFalse(site.content_manager.verifyFile("data/users/1J6UrZMkarjVg5ax9W4qThir3BFUikbW6C/content.json", StringIO(json.dumps(signed_content)), ignore_same=False)) + def testClone(self): + from Site import Site + from Site import SiteManager + from User import UserManager + import shutil + + site = Site("1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT") # Privatekey: 5KUh3PvNm5HUWoCfSUfcYvfQ2g3PrRNJWr6Q9eqdBGu23mtMntv + self.assertEqual(site.storage.directory, "src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT") + + # Remove old files + if os.path.isdir("src/Test/testdata/159EGD5srUsMP97UpcLy8AtKQbQLK2AbbL"): + shutil.rmtree("src/Test/testdata/159EGD5srUsMP97UpcLy8AtKQbQLK2AbbL") + self.assertFalse(os.path.isfile("src/Test/testdata/159EGD5srUsMP97UpcLy8AtKQbQLK2AbbL/content.json")) + + # Clone 1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT to 15E5rhcAUD69WbiYsYARh4YHJ4sLm2JEyc + new_site = site.clone("159EGD5srUsMP97UpcLy8AtKQbQLK2AbbL", "5JU2p5h3R7B1WrbaEdEDNZR7YHqRLGcjNcqwqVQzX2H4SuNe2ee", address_index=1) # Privatekey: 5JU2p5h3R7B1WrbaEdEDNZR7YHqRLGcjNcqwqVQzX2H4SuNe2ee + + # Check if clone was successful + self.assertEqual(new_site.address, "159EGD5srUsMP97UpcLy8AtKQbQLK2AbbL") + self.assertTrue(new_site.storage.isFile("content.json")) + self.assertTrue(new_site.storage.isFile("index.html")) + self.assertTrue(new_site.storage.isFile("data/users/content.json")) + self.assertTrue(new_site.storage.isFile("data/zeroblog.db")) + + + # Test re-cloning (updating) + + # Changes in non-data files should be overwritten + new_site.storage.write("index.html", "this will be overwritten") + self.assertEqual(new_site.storage.read("index.html"), "this will be overwritten") + + # Changes in data file should be kept after re-cloning + changed_contentjson = new_site.storage.loadJson("content.json") + changed_contentjson["description"] = "Update Description Test" + new_site.storage.writeJson("content.json", changed_contentjson) + + changed_data = new_site.storage.loadJson("data/data.json") + changed_data["title"] = "UpdateTest" + new_site.storage.writeJson("data/data.json", changed_data) + + # Re-clone the site + site.clone("159EGD5srUsMP97UpcLy8AtKQbQLK2AbbL") + + self.assertEqual(new_site.storage.loadJson("data/data.json")["title"], "UpdateTest") + self.assertEqual(new_site.storage.loadJson("content.json")["description"], "Update Description Test") + self.assertNotEqual(new_site.storage.read("index.html"), "this will be overwritten") + + + def testUserNewsite(self): + from User import UserManager + user = UserManager.user_manager.get() + user.sites = {} # Reset user data + self.assertEqual(user.master_address, "15E5rhcAUD69WbiYsYARh4YHJ4sLm2JEyc") + self.assertEqual(user.getAddressAuthIndex("15E5rhcAUD69WbiYsYARh4YHJ4sLm2JEyc"), 1458664252141532163166741013621928587528255888800826689784628722366466547364755811L) + + address, address_index, site_data = user.getNewSiteData() + self.assertEqual(CryptBitcoin.hdPrivatekey(user.master_seed, address_index), site_data["privatekey"]) # Re-generate privatekey based on address_index + + user.sites = {} # Reset user data + + self.assertNotEqual(user.getSiteData(address)["auth_address"], address) # Site address and auth address is different + self.assertEqual(user.getSiteData(address)["auth_privatekey"], site_data["auth_privatekey"]) # Re-generate auth_privatekey for site + + + + def testSslCert(self): + from Crypt import CryptConnection + # Remove old certs + if os.path.isfile("%s/cert-rsa.pem" % config.data_dir): os.unlink("%s/cert-rsa.pem" % config.data_dir) + if os.path.isfile("%s/key-rsa.pem" % config.data_dir): os.unlink("%s/key-rsa.pem" % config.data_dir) + + CryptConnection.manager.loadCerts() + + self.assertIn("tls-rsa", CryptConnection.manager.crypt_supported) + self.assertEqual(CryptConnection.manager.selectCrypt(["tls-rsa", "unknown"]), "tls-rsa") + self.assertTrue(os.path.isfile("%s/cert-rsa.pem" % config.data_dir)) + self.assertTrue(os.path.isfile("%s/key-rsa.pem" % config.data_dir)) + + + if __name__ == "__main__": import logging - logging.getLogger().setLevel(level=logging.FATAL) - unittest.main(verbosity=2) - #unittest.main(verbosity=2, defaultTest="TestCase.testUserContentCert") + logging.getLogger().setLevel(level=logging.DEBUG) + #unittest.main(verbosity=2) + unittest.main(verbosity=2, defaultTest="TestCase.testClone") diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/content.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/content.json new file mode 100644 index 00000000..e3d7dc0f --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/content.json @@ -0,0 +1,123 @@ +{ + "address": "1BLogC9LN4oPDcruNz3qo1ysa133E9AGg8", + "background-color": "white", + "description": "Blogging platform Demo", + "domain": "Blog.ZeroNetwork.bit", + "files": { + "css/all.css": { + "sha512": "65ddd3a2071a0f48c34783aa3b1bde4424bdea344630af05a237557a62bd55dc", + "size": 112710 + }, + "data-default/data.json": { + "sha512": "3f5c5a220bde41b464ab116cce0bd670dd0b4ff5fe4a73d1dffc4719140038f2", + "size": 196 + }, + "data-default/users/content-default.json": { + "sha512": "0603ce08f7abb92b3840ad0cf40e95ea0b3ed3511b31524d4d70e88adba83daa", + "size": 679 + }, + "data/data.json": { + "sha512": "0f2321c905b761a05c360a389e1de149d952b16097c4ccf8310158356e85fb52", + "size": 31126 + }, + "data/img/autoupdate.png": { + "sha512": "d2b4dc8e0da2861ea051c0c13490a4eccf8933d77383a5b43de447c49d816e71", + "size": 24460 + }, + "data/img/direct_domains.png": { + "sha512": "5f14b30c1852735ab329b22496b1e2ea751cb04704789443ad73a70587c59719", + "size": 16185 + }, + "data/img/domain.png": { + "sha512": "ce87e0831f4d1e95a95d7120ca4d33f8273c6fce9f5bbedf7209396ea0b57b6a", + "size": 11881 + }, + "data/img/memory.png": { + "sha512": "dd56515085b4a79b5809716f76f267ec3a204be3ee0d215591a77bf0f390fa4e", + "size": 12775 + }, + "data/img/multiuser.png": { + "sha512": "88e3f795f9b86583640867897de6efc14e1aa42f93e848ed1645213e6cc210c6", + "size": 29480 + }, + "data/img/progressbar.png": { + "sha512": "23d592ae386ce14158cec34d32a3556771725e331c14d5a4905c59e0fe980ebf", + "size": 13294 + }, + "data/img/slides.png": { + "sha512": "1933db3b90ab93465befa1bd0843babe38173975e306286e08151be9992f767e", + "size": 14439 + }, + "data/img/slots_memory.png": { + "sha512": "82a250e6da909d7f66341e5b5c443353958f86728cd3f06e988b6441e6847c29", + "size": 9488 + }, + "data/img/trayicon.png": { + "sha512": "e7ae65bf280f13fb7175c1293dad7d18f1fcb186ebc9e1e33850cdaccb897b8f", + "size": 19040 + }, + "data/img/zeroblog-comments.png": { + "sha512": "efe4e815a260e555303e5c49e550a689d27a8361f64667bd4a91dbcccb83d2b4", + "size": 24001 + }, + "data/img/zeroid.png": { + "sha512": "b46d541a9e51ba2ddc8a49955b7debbc3b45fd13467d3c20ef104e9d938d052b", + "size": 18875 + }, + "data/img/zeroname.png": { + "sha512": "bab45a1bb2087b64e4f69f756b2ffa5ad39b7fdc48c83609cdde44028a7a155d", + "size": 36031 + }, + "data/img/zerotalk-mark.png": { + "sha512": "a335b2fedeb8d291ca68d3091f567c180628e80f41de4331a5feb19601d078af", + "size": 44862 + }, + "data/img/zerotalk-upvote.png": { + "sha512": "b1ffd7f948b4f99248dde7efe256c2efdfd997f7e876fb9734f986ef2b561732", + "size": 41092 + }, + "data/img/zerotalk.png": { + "sha512": "54d10497a1ffca9a4780092fd1bd158c15f639856d654d2eb33a42f9d8e33cd8", + "size": 26606 + }, + "dbschema.json": { + "sha512": "7b756e8e475d4d6b345a24e2ae14254f5c6f4aa67391a94491a026550fe00df8", + "size": 1529 + }, + "img/loading.gif": { + "sha512": "8a42b98962faea74618113166886be488c09dad10ca47fe97005edc5fb40cc00", + "size": 723 + }, + "img/post/slides.png": { + "sha512": "1933db3b90ab93465befa1bd0843babe38173975e306286e08151be9992f767e", + "size": 14439 + }, + "index.html": { + "sha512": "4989c09b0f8ebcb84200bf39ac387d0cb8387846f44c993c553f5638472dc9c6", + "size": 4665 + }, + "js/all.js": { + "sha512": "034c97535f3c9b3fbebf2dcf61a38711dae762acf1a99168ae7ddc7e265f582c", + "size": 201178 + } + }, + "ignore": "((js|css)/(?!all.(js|css))|data/.*db|data/users/.*/.*)", + "includes": { + "data/users/content.json": { + "signers": [], + "signers_required": 1 + } + }, + "modified": 1433033839.187, + "sign": [ + 23288026089939741768236374425021091801956985530578920099613839712827977534400, + 96520925254285126876579021588512602074631663615139311676453830936350975122022 + ], + "signers_sign": "G7W/oNvczE5nPTFYVOqv8+GOpQd23LS/Dc1Q6xQ1NRDDHlYzmoSE63UQ7Za05kD0rwIYXbuUSr8z8p6RhZmnUs8=", + "signs": { + "1BLogC9LN4oPDcruNz3qo1ysa133E9AGg8": "G9i0Q/ZkhZ0H5O8ofEvXbEgGhwVJYbLxyxOwsGYxgtzIaBjiDg/HKe9l7nPRqDD3/bRG9oPH5kIQd4152vY3lI8=" + }, + "signs_required": 1, + "title": "ZeroBlog", + "zeronet_version": "0.3.0" +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/css/all.css b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/css/all.css new file mode 100644 index 00000000..c2ad65fc --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/css/all.css @@ -0,0 +1,385 @@ + + +/* ---- data/1Hb9rY98TNnA6TYeozJv4w36bqEiBn6x8Y/css/Comments.css ---- */ + + +.comments { margin-bottom: 60px } +.comment { background-color: white; padding: 25px 0px; margin: 1px; border-top: 1px solid #EEE } +.comment .user_name { font-size: 14px; font-weight: bold } +.comment .added { color: #AAA } +.comment .reply { color: #CCC; opacity: 0; -webkit-transition: opacity 0.3s; -moz-transition: opacity 0.3s; -o-transition: opacity 0.3s; -ms-transition: opacity 0.3s; transition: opacity 0.3s ; border: none } +.comment:hover .reply { opacity: 1 } +.comment .reply .icon { opacity: 0.3 } +.comment .reply:hover { border-bottom: none; color: #666 } +.comment .reply:hover .icon { opacity: 1 } +.comment .info { font-size: 12px; color: #AAA; margin-bottom: 7px } +.comment .info .score { margin-left: 5px } +.comment .comment-body { line-height: 1.5em; margin-top: 0.5em; margin-bottom: 0.5em } +.comment .comment-body p { margin-bottom: 0px; margin-top: 0.5em; } +.comment .comment-body p:first-child { margin: 0px; margin-top: 0px; } +.comment .comment-body.editor { margin-top: 0.5em !important; margin-bottom: 0.5em !important } +.comment .comment-body h1, .comment .body h2, .comment .body h3 { font-size: 110% } +.comment .comment-body blockquote { padding: 1px 15px; border-left: 2px solid #E7E7E7; margin: 0px; margin-top: 30px } +.comment .comment-body blockquote:first-child { margin-top: 0px } +.comment .comment-body blockquote p { margin: 0px; color: #999; font-size: 90% } +.comment .comment-body blockquote a { color: #333; font-weight: normal; border-bottom: 0px } +.comment .comment-body blockquote a:hover { border-bottom: 1px solid #999 } +.comment .editable-edit { margin-top: -5px } + +.comment-new { margin-bottom: 5px; border-top: 0px } +.comment-new .button-submit { + margin: 0px; font-weight: normal; padding: 5px 15px; display: inline-block; + background-color: #FFF85F; border-bottom: 2px solid #CDBD1E; font-size: 15px; line-height: 30px +} +.comment-new h2 { margin-bottom: 25px } + +/* Input */ +.comment-new textarea { + line-height: 1.5em; width: 100%; padding: 10px; font-family: 'Roboto', sans-serif; font-size: 16px; + -webkit-transition: border 0.3s; -moz-transition: border 0.3s; -o-transition: border 0.3s; -ms-transition: border 0.3s; transition: border 0.3s ; border: 2px solid #eee; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -o-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box ; overflow-y: auto +} +input.text:focus, textarea:focus { border-color: #5FC0EA; outline: none; background-color: white } + +.comment-nocert textarea { opacity: 0.5; pointer-events: none } +.comment-nocert .info { opacity: 0.1; pointer-events: none } +.comment-nocert .button-submit-comment { opacity: 0.1; pointer-events: none } +.comment-nocert .button.button-certselect { display: inherit } +.button.button-certselect { + position: absolute; left: 50%; white-space: nowrap; -webkit-transform: translateX(-50%); -moz-transform: translateX(-50%); -o-transform: translateX(-50%); -ms-transform: translateX(-50%); transform: translateX(-50%) ; z-index: 99; + margin-top: 13px; background-color: #007AFF; color: white; border-bottom-color: #3543F9; display: none +} +.button.button-certselect:hover { background-color: #3396FF; color: white; border-bottom-color: #5D68FF; } +.button.button-certselect:active { position: absolute; -webkit-transform: translateX(-50%) translateY(1px); -moz-transform: translateX(-50%) translateY(1px); -o-transform: translateX(-50%) translateY(1px); -ms-transform: translateX(-50%) translateY(1px); transform: translateX(-50%) translateY(1px) ; top: auto; } + +.user-size { font-size: 11px; margin-top: 6px; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -o-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box ; text-transform: uppercase; display: inline-block; color: #AAA } +.user-size-used { position: absolute; color: #B10DC9; overflow: hidden; width: 40px; white-space: nowrap } + + + +/* ---- data/1Hb9rY98TNnA6TYeozJv4w36bqEiBn6x8Y/css/ZeroBlog.css ---- */ + + +/* Design based on medium */ + +body { background-color: white; color: #333332; margin: 10px; padding: 0px; font-family: 'Roboto', sans-serif; height: 15000px; overflow: hidden } +body.loaded { height: auto; overflow: auto } +h1, h2, h3, h4 { font-family: 'Roboto', sans-serif; font-weight: normal; margin: 0px; padding: 0px } +h1 { font-size: 32px; line-height: 1.2em; font-weight: bold; letter-spacing: -0.5px; margin-bottom: 5px } +h2 { margin-top: 3em } +h3 { font-size: 24px; margin-top: 2em } +h1 + h2, h2 + h3 { margin-top: inherit } + +p { margin-top: 0.9em; margin-bottom: 0.9em } +hr { margin: 20px 0px; border: none; border-bottom: 1px solid #eee; margin-left: auto; margin-right: auto; width: 120px; } +small { font-size: 80%; color: #999; } + +a { border-bottom: 1px solid #3498db; text-decoration: none; color: black; font-weight: bold } +a.nolink { border-bottom: none } +a:hover { color: #3498db } + +.button { + padding: 5px 10px; margin-left: 10px; background-color: #DDE0E0; border-bottom: 2px solid #999998; background-position: left center; + -webkit-border-radius: 2px; -moz-border-radius: 2px; -o-border-radius: 2px; -ms-border-radius: 2px; border-radius: 2px ; text-decoration: none; -webkit-transition: all 0.5s ease-out; -moz-transition: all 0.5s ease-out; -o-transition: all 0.5s ease-out; -ms-transition: all 0.5s ease-out; transition: all 0.5s ease-out ; color: #333 +} +.button:hover { background-color: #FFF400; border-color: white; border-bottom: 2px solid #4D4D4C; -webkit-transition: none; -moz-transition: none; -o-transition: none; -ms-transition: none; transition: none ; color: inherit } +.button:active { position: relative; top: 1px } + +/*.button-delete { background-color: #e74c3c; border-bottom-color: #A83F34; color: white }*/ +.button-outline { background-color: white; color: #DDD; border: 1px solid #eee } + +.button-delete:hover { background-color: #FF5442; border: 1px solid #FF5442; color: white } +.button-ok:hover { background-color: #27AE60; border: 1px solid #27AE60; color: white } + +.button.loading { + color: rgba(0,0,0,0); background: #999 url(../img/loading.gif) no-repeat center center; + -webkit-transition: all 0.5s ease-out; -moz-transition: all 0.5s ease-out; -o-transition: all 0.5s ease-out; -ms-transition: all 0.5s ease-out; transition: all 0.5s ease-out ; pointer-events: none; border-bottom: 2px solid #666 +} + +.cancel { margin-left: 10px; font-size: 80%; color: #999; } + + +.template { display: none } + +/* Editable */ +.editable { outline: none } +.editable-edit:hover { opacity: 1; border: none; color: #333 } +.editable-edit { + opacity: 0; float: left; margin-top: 0px; margin-left: -40px; padding: 8px 20px; -webkit-transition: all 0.3s; -moz-transition: all 0.3s; -o-transition: all 0.3s; -ms-transition: all 0.3s; transition: all 0.3s ; width: 0px; display: inline-block; padding-right: 0px; + color: rgba(100,100,100,0.5); text-decoration: none; font-size: 18px; font-weight: normal; border: none; +} +/*.editing { white-space: pre-wrap; z-index: 1; position: relative; outline: 10000px solid rgba(255,255,255,0.9) !important; } +.editing p { margin: 0px; padding: 0px }*/ /* IE FIX */ +.editor { width: 100%; display: block; overflow :hidden; resize: none; border: none; -webkit-box-sizing: border-box; -moz-box-sizing: border-box; -o-box-sizing: border-box; -ms-box-sizing: border-box; box-sizing: border-box ; z-index: 900; position: relative } +.editor:focus { border: 0px; outline-offset: 0px } + + +/* -- Editbar -- */ + +.bottombar { + display: none; position: fixed; padding: 10px 20px; opacity: 0; background-color: rgba(255,255,255,0.9); + right: 30px; bottom: 0px; z-index: 999; -webkit-transition: all 0.3s; -moz-transition: all 0.3s; -o-transition: all 0.3s; -ms-transition: all 0.3s; transition: all 0.3s ; transform: translateY(50px) +} +.bottombar.visible { -webkit-transform: translateY(0px); -moz-transform: translateY(0px); -o-transform: translateY(0px); -ms-transform: translateY(0px); transform: translateY(0px) ; opacity: 1 } +.publishbar { z-index: 990} +.publishbar.visible { display: inline-block; } +.editbar { -webkit-perspective: 900px ; -moz-perspective: 900px ; -o-perspective: 900px ; -ms-perspective: 900px ; perspective: 900px } +.markdown-help { + position: absolute; bottom: 30px; -webkit-transform: translateX(0px) rotateY(-40deg); -moz-transform: translateX(0px) rotateY(-40deg); -o-transform: translateX(0px) rotateY(-40deg); -ms-transform: translateX(0px) rotateY(-40deg); transform: translateX(0px) rotateY(-40deg) ; transform-origin: right; right: 0px; + list-style-type: none; background-color: rgba(255,255,255,0.9); padding: 10px; opacity: 0; -webkit-transition: all 0.6s; -moz-transition: all 0.6s; -o-transition: all 0.6s; -ms-transition: all 0.6s; transition: all 0.6s ; display: none +} +.markdown-help.visible { -webkit-transform: none; -moz-transform: none; -o-transform: none; -ms-transform: none; transform: none ; opacity: 1 } +.markdown-help li { margin: 10px 0px } +.markdown-help code { font-size: 100% } +.icon-help { border: 1px solid #EEE; padding: 2px; display: inline-block; width: 17px; text-align: center; font-size: 13px; margin-right: 6px; vertical-align: 1px } +.icon-help.active { background-color: #EEE } + +/* -- Left -- */ + +.left { float: left; position: absolute; width: 170px; padding-left: 60px; padding-right: 20px; margin-top: 60px; text-align: right } +.right { float: left; padding-left: 60px; margin-left: 240px; max-width: 650px; padding-right: 60px; padding-top: 60px } + +.left .avatar { + background-color: #F0F0F0; width: 60px; height: 60px; -webkit-border-radius: 100%; -moz-border-radius: 100%; -o-border-radius: 100%; -ms-border-radius: 100%; border-radius: 100% ; margin-bottom: 10px; + background-position: center center; background-size: 70%; display: inline-block; +} +.left h1 a.nolink { font-family: Tinos; display: inline-block; padding: 1px } +.left h1 a.editable-edit { float: none } +.left h2 { font-size: 15px; font-family: Tinos; line-height: 1.6em; color: #AAA; margin-top: 14px; letter-spacing: 0.2px } +.left ul, .left li { padding: 0px; margin: 0px; list-style-type: none; line-height: 2em } +.left hr { margin-left: 100px; margin-right: 0px; width: auto } +.left .links { width: 230px; margin-left: -60px } +.left .links.editor { text-align: left !important } + +/* -- Post -- */ + +.posts .new { display: none; position: absolute; top: -50px; margin-left: 0px; left: 50%; -webkit-transform: translateX(-50%) ; -moz-transform: translateX(-50%) ; -o-transform: translateX(-50%) ; -ms-transform: translateX(-50%) ; transform: translateX(-50%) } + +.posts, .post-full { display: none; position: relative; } +.page-main .posts { display: block } +.page-post.loaded .post-full { display: block; border-bottom: none } + + +.post { margin-bottom: 50px; padding-bottom: 50px; border-bottom: 1px solid #eee; min-width: 500px } +.post .title a { text-decoration: none; color: inherit; display: inline-block; border-bottom: none; font-weight: inherit } +.posts .title a:visited { color: #666969 } +.post .details { color: #BBB; margin-top: 5px; margin-bottom: 20px } +.post .details .comments-num { border: none; color: #BBB; font-weight: normal; } +.post .details .comments-num .num { border-bottom: 1px solid #eee; color: #000; } +.post .details .comments-num:hover .num { border-bottom: 1px solid #D6A1DE; } +.post .body { font-size: 21.5px; line-height: 1.6; font-family: Tinos; margin-top: 20px } + +.post .body h1 { text-align: center; margin-top: 50px } +.post .body h1:before { content: " "; border-top: 1px solid #EEE; width: 120px; display: block; margin-left: auto; margin-right: auto; margin-bottom: 50px; } + +.post .body p + ul { margin-top: -0.5em } +.post .body li { margin-top: 0.5em; margin-bottom: 0.5em } +.post .body hr:first-of-type { display: none } + +.post .body a img { margin-bottom: -8px } +.post .body img { max-width: 100% } + +code { + background-color: #f5f5f5; border: 1px solid #ccc; padding: 0px 5px; overflow: auto; -webkit-border-radius: 2px; -moz-border-radius: 2px; -o-border-radius: 2px; -ms-border-radius: 2px; border-radius: 2px ; display: inline-block; + color: #444; font-weight: normal; font-size: 60%; vertical-align: text-bottom; border-bottom-width: 2px; +} +.post .body pre { table-layout: fixed; width: auto; display: table; white-space: normal; } +.post .body pre code { padding: 10px 20px; white-space: pre; max-width: 850px } + +blockquote { border-left: 3px solid #333; margin-left: 0px; padding-left: 1em } +/*.post .more { + display: inline-block; border: 1px solid #eee; padding: 10px 25px; -webkit-border-radius: 26px; -moz-border-radius: 26px; -o-border-radius: 26px; -ms-border-radius: 26px; border-radius: 26px ; font-size: 11px; color: #AAA; font-weight: normal; + left: 50%; position: relative; -webkit-transform: translateX(-50%); -moz-transform: translateX(-50%); -o-transform: translateX(-50%); -ms-transform: translateX(-50%); transform: translateX(-50%) ; +}*/ + +.post .more { border: 2px solid #333; padding: 10px 20px; font-size: 15px; margin-top: 30px; display: none; -webkit-transition: all 0.3s ; -moz-transition: all 0.3s ; -o-transition: all 0.3s ; -ms-transition: all 0.3s ; transition: all 0.3s } +.post .more .readmore { } +.post .more:hover { color: white; -webkit-box-shadow: inset 150px 0px 0px 0px #333; -moz-box-shadow: inset 150px 0px 0px 0px #333; -o-box-shadow: inset 150px 0px 0px 0px #333; -ms-box-shadow: inset 150px 0px 0px 0px #333; box-shadow: inset 150px 0px 0px 0px #333 ; } +.post .more:active { color: white; -webkit-box-shadow: inset 150px 0px 0px 0px #AF3BFF; -moz-box-shadow: inset 150px 0px 0px 0px #AF3BFF; -o-box-shadow: inset 150px 0px 0px 0px #AF3BFF; -ms-box-shadow: inset 150px 0px 0px 0px #AF3BFF; box-shadow: inset 150px 0px 0px 0px #AF3BFF ; -webkit-transition: none; -moz-transition: none; -o-transition: none; -ms-transition: none; transition: none ; border-color: #AF3BFF } + + + +/* ---- data/1Hb9rY98TNnA6TYeozJv4w36bqEiBn6x8Y/css/fonts.css ---- */ + + +/* Base64 encoder: http://www.motobit.com/util/base64-decoder-encoder.asp */ +/* Generated by Font Squirrel (http://www.fontsquirrel.com) on January 21, 2015 */ + +@font-face { + font-family: 'Tinos'; + src: url(data:application/x-font-woff;charset=utf-8;base64,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) format('woff'); + font-weight: normal; + font-style: normal; + +} + + +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: 300; + src: + local('Roboto Light'), + url(data:application/x-font-woff;charset=utf-8;base64,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) format('woff'), + url('../font/Roboto-Light.woff') format('woff'); +} + +@font-face { + font-family: 'Roboto'; + font-style: normal; + font-weight: bold; + src: + local('Roboto Medium'), + url(data:application/x-font-woff;charset=utf-8;base64,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) format('woff'), + url(../font/Roboto-Medium.woff) format('woff'); +} + + + +/* ---- data/1Hb9rY98TNnA6TYeozJv4w36bqEiBn6x8Y/css/github.css ---- */ + + +/* + +github.com style (c) Vasily Polovnyov + +*/ + +.hljs { + display: block; + overflow-x: auto; + padding: 0.5em; + color: #333; + background: #f8f8f8; + -webkit-text-size-adjust: none; +} + +.hljs-comment, +.diff .hljs-header, +.hljs-javadoc { + color: #998; + font-style: italic; +} + +.hljs-keyword, +.css .rule .hljs-keyword, +.hljs-winutils, +.nginx .hljs-title, +.hljs-subst, +.hljs-request, +.hljs-status { + color: #333; + font-weight: bold; +} + +.hljs-number, +.hljs-hexcolor, +.ruby .hljs-constant { + color: #008080; +} + +.hljs-string, +.hljs-tag .hljs-value, +.hljs-phpdoc, +.hljs-dartdoc, +.tex .hljs-formula { + color: #d14; +} + +.hljs-title, +.hljs-id, +.scss .hljs-preprocessor { + color: #900; + font-weight: bold; +} + +.hljs-list .hljs-keyword, +.hljs-subst { + font-weight: normal; +} + +.hljs-class .hljs-title, +.hljs-type, +.vhdl .hljs-literal, +.tex .hljs-command { + color: #458; + font-weight: bold; +} + +.hljs-tag, +.hljs-tag .hljs-title, +.hljs-rules .hljs-property, +.django .hljs-tag .hljs-keyword { + color: #000080; + font-weight: normal; +} + +.hljs-attribute, +.hljs-variable, +.lisp .hljs-body { + color: #008080; +} + +.hljs-regexp { + color: #009926; +} + +.hljs-symbol, +.ruby .hljs-symbol .hljs-string, +.lisp .hljs-keyword, +.clojure .hljs-keyword, +.scheme .hljs-keyword, +.tex .hljs-special, +.hljs-prompt { + color: #990073; +} + +.hljs-built_in { + color: #0086b3; +} + +.hljs-preprocessor, +.hljs-pragma, +.hljs-pi, +.hljs-doctype, +.hljs-shebang, +.hljs-cdata { + color: #999; + font-weight: bold; +} + +.hljs-deletion { + background: #fdd; +} + +.hljs-addition { + background: #dfd; +} + +.diff .hljs-change { + background: #0086b3; +} + +.hljs-chunk { + color: #aaa; +} + + + +/* ---- data/1Hb9rY98TNnA6TYeozJv4w36bqEiBn6x8Y/css/icons.css ---- */ + + +.icon { display: inline-block; vertical-align: text-bottom; background-repeat: no-repeat; } +.icon-profile { font-size: 6px; top: 0em; -webkit-border-radius: 0.7em 0.7em 0 0; -moz-border-radius: 0.7em 0.7em 0 0; -o-border-radius: 0.7em 0.7em 0 0; -ms-border-radius: 0.7em 0.7em 0 0; border-radius: 0.7em 0.7em 0 0 ; background: #FFFFFF; width: 1.5em; height: 0.7em; position: relative; display: inline-block; margin-right: 4px } +.icon-profile:before { position: absolute; content: ""; top: -1em; left: 0.38em; width: 0.8em; height: 0.85em; -webkit-border-radius: 50%; -moz-border-radius: 50%; -o-border-radius: 50%; -ms-border-radius: 50%; border-radius: 50% ; background: #FFFFFF; } + +.icon-comment { width: 16px; height: 10px; -webkit-border-radius: 2px; -moz-border-radius: 2px; -o-border-radius: 2px; -ms-border-radius: 2px; border-radius: 2px ; background: #B10DC9; margin-top: 0px; display: inline-block; position: relative; top: -2px; } +.icon-comment:after { left: 9px; border: 2px solid transparent; border-top-color: #B10DC9; border-left-color: #B10DC9; background: transparent; content: ""; display: block; margin-top: 10px; width: 0px; margin-left: 7px; } + +.icon-edit { + width: 16px; height: 16px; background-repeat: no-repeat; background-position: 20px center; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAAOVBMVEUAAAC9w8e9w8e9w8e9w8e/xMi9w8e9w8e+w8e9w8e9w8e9w8e9w8e9w8e9w8e+w8e/xMi9w8e9w8fvY4+KAAAAEnRSTlMASPv3WQbwOTCkt4/psX4YDMWr+RRCAAAAUUlEQVQY06XLORKAMAxDUTs7kA3d/7AYGju0UfffjIgoHkxm0vB5bZyxKHx9eX0FJw0Y4bcXKQ4/CTtS5yqp5GFFOjGpVGl00k1pNDIb3Nv9AHC7BOZC4ZjvAAAAAElFTkSuQmCC+d0ckOwyAMRVGHUOO0gUyd+P8f7WApz4Iki9wFmyOEATrXLZcFp5LrGogPOxKp6zfFf9fZ1/I/cY7YZSS3U6S3XFZJmGBwL+FuJX/F1K0wUUlZyZGlXgXESthTEs4B8fh7xoVUDPGYJnsfkCRarKAgz8cAKbpD6pqDPz3XB8K6HdUEeN9NAAAAAElFTkSuQmCC); +} +.icon-reply { + width: 16px; height: 16px; + background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAIVBMVEUAAABmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYs5FxxAAAAC3RSTlMAgBFwYExAMHgoCDJmUTYAAAA3SURBVAjXY8APGGEMQZgAjCEoKBwEEQCCAoiIh6AQVM1kMaguJhGYOSJQjexiUMbiAChDCclCAOHqBBdHpwQTAAAAAElFTkSuQmCC); +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data-default/data.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data-default/data.json new file mode 100644 index 00000000..41392501 --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data-default/data.json @@ -0,0 +1,10 @@ +{ + "title": "MyZeroBlog", + "description": "My ZeroBlog.", + "links": "- [Source code](https://github.com/HelloZeroNet)", + "next_post_id": 1, + "demo": false, + "modified": 1432515193, + "post": [ + ] +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data-default/users/content-default.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data-default/users/content-default.json new file mode 100644 index 00000000..06bfc9cd --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data-default/users/content-default.json @@ -0,0 +1,25 @@ +{ + "files": {}, + "ignore": ".*", + "modified": 1432466966.003, + "signs": { + "1BLogC9LN4oPDcruNz3qo1ysa133E9AGg8": "HChU28lG4MCnAiui6wDAaVCD4QUrgSy4zZ67+MMHidcUJRkLGnO3j4Eb1N0AWQ86nhSBwoOQf08Rha7gRyTDlAk=" + }, + "user_contents": { + "cert_signers": { + "zeroid.bit": [ "1iD5ZQJMNXu43w1qLB8sfdHVKppVMduGz" ] + }, + "permission_rules": { + ".*": { + "files_allowed": "data.json", + "max_size": 10000 + }, + "bitid/.*@zeroid.bit": { "max_size": 40000 }, + "bitmsg/.*@zeroid.bit": { "max_size": 15000 } + }, + "permissions": { + "banexample@zeroid.bit": false, + "nofish@zeroid.bit": { "max_size": 20000 } + } + } +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/data.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/data.json new file mode 100644 index 00000000..af289e8f --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/data.json @@ -0,0 +1,244 @@ +{ + "title": "ZeroBlog", + "description": "Demo for decentralized, self publishing blogging platform.", + "links": "- [Source code](https://github.com/HelloZeroNet)\n- [Create new blog](?Post:3:How+to+have+a+blog+like+this)", + "next_post_id": 42, + "demo": false, + "modified": 1433033806, + "post": [ + { + "post_id": 41, + "title": "Changelog: May 31, 2015", + "date_published": 1433033779.604, + "body": " - rev194\n - Ugly OpenSSL memory leak fix\n - Added Docker and Vargant files (thanks to n3r0-ch)\n\nZeroBlog\n - Comment editing, Deleting, Replying added\n\nNew official site: http://zeronet.io/" + }, + { + "post_id": 40, + "title": "Trusted authorization providers", + "date_published": 1432549828.319, + "body": "What is it good for?\n\n - It allows you to have multi-user sites without need of a bot that listen to new user registration requests.\n - You can use the same username across sites\n - The site owner can give you (or revoke) permissions based on your ZeroID username\n\nHow does it works?\n\n - You visit an authorization provider site (eg zeroid.bit)\n - You enter the username you want to register and sent the request to the authorization provider site owner (zeroid supports bitmessage and simple http request).\n - The authorization provider process your request and it he finds everything all right (unique username, other anti-spam methods) he sends you a certificate for the username registration.\n - If a site trust your authorization provider you can post your own content (comments, topics, upvotes, etc.) using this certificate without ever contacting the site owner.\n\nWhat sites currently supports ZeroID?\n\n - You can post comments to ZeroBlog using your ZeroID\n - Later, if everyone is updated to 0.3.0 a new ZeroTalk is also planned that supports ZeroID certificates\n\nWhy is it necessary?\n\n - To have some kind of control over the users of your site. (eg. remove misbehaving users)\n\nOther info\n\n - ZeroID is a standard site, anyone can clone it and have his/her own one\n - You can stop seeding ZeroID site after you got your cert" + }, + { + "post_id": 39, + "title": "Changelog: May 25, 2015", + "date_published": 1432511642.167, + "body": "- Version 0.3.0, rev187\n- Trusted authorization provider support: Easier multi-user sites by allowing site owners to define tusted third-party user certificate signers. (more info about it in the next days)\n- `--publish` option to siteSign to publish automatically after the new files signed.\n- `cryptSign` command line command to sign message using private key.\n- New, more stable OpenSSL layer that also works on OSX.\n- New json table format support.\n- DbCursor SELECT parameters bugfix.\n- Faster multi-threaded peer discovery from trackers.\n- New http trackers added.\n- Wait for dbschema.json file to execute query.\n- Handle json import errors.\n- More compact json writeJson storage command output.\n- Workaround to make non target=_top links work.\n- Cleaner UiWebsocket command router.\n- Notify other local users on local file changes.\n- Option to wait file download before execute query.\n- fileRules, certAdd, certSelect, certSet websocket API commands.\n- Allow more file errors on big sites.\n- On stucked downloads skip worker's current file instead of stopping it.\n- NoParallel parameter bugfix.\n- RateLimit interval bugfix.\n- Updater skips non-writeable files.\n- Try to close OpenSSL dll before update.\n\nZeroBlog:\n- Rewritten to use SQL database\n- Commenting on posts (**Please note: The comment publishing and distribution can be slow until most of the clients is not updated to version 0.3.0**)\n\n![comments](data/img/zeroblog-comments.png)\n\nZeroID\n- Sample Trusted authorization provider site with Bitmessage registration support\n\n![comments](data/img/zeroid.png)" + }, + { + "post_id": 38, + "title": "Status report: Trusted authorization providers", + "date_published": 1431286381.226, + "body": "Currently working on a new feature that allows to create multi-user sites more easily. For example it will allows us to have comments on ZeroBlog (without contacting the site owner).\n\nCurrent status:\n\n - Sign/verification process: 90%\n - Sample trusted authorization provider site: 70%\n - ZeroBlog modifications: 30%\n - Authorization UI enhacements: 10%\n - Total progress: 60%\n \nEta.: 1-2weeks\n\n### Update: May 18, 2015:\n\nThings left:\n - More ZeroBlog modifications on commenting interface\n - Bitmessage support in Sample trusted authorization provider site\n - Test everything on multiple platform/browser and machine\n - Total progress: 80%\n\nIf no major flaw discovered it should be out this week." + }, + { + "post_id": 37, + "title": "Changelog: May 3, 2015", + "date_published": 1430652299.794, + "body": " - rev134\n - Removed ZeroMQ dependencies and support (if you are on pre 0.2.0 version please, upgrade)\n - Save CPU and memory on file requests by streaming content directly to socket without loading to memory and encoding with msgpack.\n - Sites updates without re-download all content.json by querying the modified files from peers.\n - Fix urllib memory leak\n - SiteManager testsuite\n - Fix UiServer security testsuite\n - Announce to tracker on site resume\n\nZeroBoard:\n\n - Only last 100 messages loaded by default\n - Typo fix" + }, + { + "post_id": 36, + "title": "Changelog: Apr 29, 2015", + "date_published": 1430388168.315, + "body": " - rev126\n - You can install the \"127.0.0.1:43110-less\" extension from [Chrome Web Store](https://chrome.google.com/webstore/detail/zeronet-protocol/cpkpdcdljfbnepgfejplkhdnopniieop). (thanks to g0ld3nrati0!)\n - You can disable the use of openssl using `--use_openssl False`\n - OpenSSL disabled on OSX because of possible segfault. You can enable it again using `zeronet.py --use_openssl True`,
please [give your feedback](https://github.com/HelloZeroNet/ZeroNet/issues/94)!\n - Update on non existent file bugfix\n - Save 20% memory using Python slots\n\n![Memory save](data/img/slots_memory.png)" + }, + { + "post_id": 35, + "title": "Changelog: Apr 27, 2015", + "date_published": 1430180561.716, + "body": " - Revision 122\n - 40x faster signature verification by using OpenSSL if available\n - Added OpenSSL benchmark: beat my CPU at http://127.0.0.1:43110/Benchmark :)\n - Fixed UiServer socket memory leak" + }, + { + "post_id": 34, + "title": "Slides about ZeroNet", + "date_published": 1430081791.43, + "body": "Topics:\n - ZeroNet cryptography\n - How site downloading works\n - Site updates\n - Multi-user sites\n - Current status of the project / Future plans\n\n\n\n[Any feedback is welcome!](http://127.0.0.1:43110/Talk.ZeroNetwork.bit/?Topic:18@2/Presentation+about+how+ZeroNet+works) \n\nThanks! :)" + }, + { + "post_id": 33, + "title": "Changelog: Apr 24, 2014", + "date_published": 1429873756.187, + "body": " - Revision 120\n - Batched publishing to avoid update flood: Only send one update in every 7 seconds\n - Protection against update flood by adding update queue: Only allows 1 update in every 10 second for the same file\n - Fix stucked notification icon\n - Fix websocket error when writing to not-owned sites" + }, + { + "post_id": 32, + "title": "Changelog: Apr 20, 2014", + "date_published": 1429572874, + "body": " - Revision 115\n - For faster pageload times allow browser cache on css/js/font files\n - Support for experimental chrome extension that allows to browse zeronet sites using `http://talk.zeronetwork.bit` and/or `http://zero/1Name2NXVi1RDPDgf5617UoW7xA6YrhM9F`\n - Allow to browse memory content in /Stats\n - Peers uses Site's logger to save some memory\n - Give not-that-good peers on initial PEX if required\n - Allows more than one `--ui_restrict` ip address\n - Disable ssl monkey patching to avoid ssl error in Debian Jessie\n - Fixed websocket error when writing not-allowed files\n - Fixed bigsite file not found error\n - Fixed loading screen stays on screen even after index.html loaded\n\nZeroHello:\n\n - Site links converted to 127.0.0.1:43110 -less if using chrome extension\n\n![direct domains](data/img/direct_domains.png)" + }, + { + "post_id": 31, + "title": "Changelog: Apr 17, 2014", + "date_published": 1429319617.201, + "body": " - Revision 101\n - Revision numbering between version\n - Allow passive publishing\n - Start Zeronet when Windows starts option to system tray icon\n - Add peer ping time to publish timeout\n - Passive connected peers always get the updates\n - Pex count bugfix\n - Changed the topright button hamburger utf8 character to more supported one and removed click anim\n - Passive peers only need 3 connection\n - Passive connection store on tracker bugfix\n - Not exits file bugfix\n - You can compare your computer speed (bitcoin crypto, sha512, sqlite access) to mine: http://127.0.0.1:43110/Benchmark :)\n\nZeroTalk:\n\n - Only quote the last message\n - Message height bugfix\n\nZeroHello:\n\n - Changed the burger icon to more supported one\n - Added revision display" + }, + { + "post_id": 30, + "title": "Changelog: Apr 16, 2015", + "date_published": 1429135541.581, + "body": "Apr 15:\n\n - Version 0.2.9\n - To get rid of dead ips only send peers over pex that messaged within 2 hour\n - Only ask peers from 2 sources using pex every 20 min\n - Fixed mysterious notification icon disappearings\n - Mark peers as bad if publish is timed out (5s+)" + }, + { + "post_id": 29, + "title": "Changelog: Apr 15, 2015", + "date_published": 1429060414.445, + "body": " - Sexy system tray icon with statistics instead of ugly console. (sorry, Windows only yet)\n - Total sent/received bytes stats\n - Faster connections and publishing by don't send passive peers using PEX and don't store them on trackers\n\n![Tray icon](data/img/trayicon.png)" + }, + { + "post_id": 28, + "title": "Changelog: Apr 14, 2015", + "date_published": 1428973199.042, + "body": " - Experimental socks proxy support (Tested using Tor)\n - Tracker-less peer exchange between peers\n - Http bittorrent tracker support\n - Option to disable udp connections (udp tracker)\n - Other stability/security fixes\n\nTo use ZeroNet over Tor network start it with `zeronet.py --proxy 127.0.0.1:9050 --disable_udp`\n\nIt's still an experimental feature, there is lot work/fine tuning needed to make it work better and more secure (eg. by supporting hidden service peer addresses to allow connection between Tor clients). \nIn this mode you can only access to sites where there is at least one peer with peer exchange support. (client updated to latest commit)\n\nIf no more bug found i'm going to tag it as 0.2.9 in the next days." + }, + { + "post_id": 27, + "title": "Changelog: Apr 9, 2015", + "date_published": 1428626164.266, + "body": " - Packaged windows dependencies for windows to make it easier to install: [ZeroBundle](https://github.com/HelloZeroNet/ZeroBundle)\n - ZeroName site downloaded at startup, so first .bit domain access is faster.\n - Fixed updater bug. (argh)" + }, + { + "post_id": 26, + "title": "Changelog: Apr 7, 2015", + "date_published": 1428454413.286, + "body": " - Fix for big sites confirmation display\n - Total objects in memory stat\n - Memory optimizations\n - Retry bad files in every 20min\n - Load files to db when executing external siteSign command\n - Fix for endless reconnect bug\n \nZeroTalk:\n \n - Added experimental P2P new bot\n - Bumped size limit to 20k for every user :)\n - Reply button\n\nExperimenting/researching possibilities of i2p/tor support (probably using DHT)\n\nAny help/suggestion/idea greatly welcomed: [github issue](https://github.com/HelloZeroNet/ZeroNet/issues/60)" + }, + { + "post_id": 25, + "title": "Changelog: Apr 2, 2015", + "date_published": 1428022346.555, + "body": " - Better passive mode by making sure to keep 5 active connections\n - Site connection and msgpack unpacker stats\n - No more sha1 hash added to content.json (it was only for backward compatibility with old clients)\n - Keep connection logger object to prevent some exception\n - Retry upnp port opening 3 times\n - Publish received content updates to more peers to make sure the better distribution\n\nZeroTalk: \n\n - Changed edit icon to more clear pencil\n - Single line breaks also breaks the line" + }, + { + "post_id": 24, + "title": "Changelog: Mar 29, 2015", + "date_published": 1427758356.109, + "body": " - Version 0.2.8\n - Namecoin (.bit) domain support!\n - Possible to disable backward compatibility with old version to save some memory\n - Faster content publishing (commenting, posting etc.)\n - Display error on internal server errors\n - Better progress bar\n - Crash and bugfixes\n - Removed coppersurfer tracker (its down atm), added eddie4\n - Sorry, the auto updater broken for this version: please overwrite your current `update.py` file with the [latest one from github](https://raw.githubusercontent.com/HelloZeroNet/ZeroNet/master/update.py), run it and restart ZeroNet.\n - Fixed updater\n\n![domain](data/img/domain.png)\n\nZeroName\n\n - New site for resolving namecoin domains and display registered ones\n\n![ZeroName](data/img/zeroname.png)\nZeroHello\n\n - Automatically links to site's domain names if its specificed in content.json `domain` field\n\n" + }, + { + "post_id": 22, + "title": "Changelog: Mar 23, 2015", + "date_published": 1427159576.994, + "body": " - Version 0.2.7\n - Plugin system: Allows extend ZeroNet without modify the core source\n - Comes with 3 plugin:\n - Multiuser: User login/logout based on BIP32 master seed, generate new master seed on visit (disabled by default to enable it just remove the disabled- from the directory name)\n - Stats: /Stats url moved to separate plugin for demonstration reasons\n - DonationMessage: Puts a little donation link to the bottom of every page (disabled by default)\n - Reworked module import system\n - Lazy user auth_address generatation\n - Allow to send prompt dialog to user from server-side\n - Update script remembers plugins enabled/disabled status\n - Multiline notifications\n - Cookie parser\n\nZeroHello in multiuser mode:\n\n - Logout button\n - Identicon generated based on logined user xpub address\n\n![Multiuser](data/img/multiuser.png)" + }, + { + "post_id": 21, + "title": "Changelog: Mar 19, 2015", + "date_published": 1426818095.915, + "body": " - Version 0.2.6\n - SQL database support that allows easier site development and faster page load times\n - Updated [ZeroFrame API Reference](http://zeronet.readthedocs.org/en/latest/site_development/zeroframe_api_reference/)\n - Added description of new [dbschema.json](http://zeronet.readthedocs.org/en/latest/site_development/dbschema_json/) file\n - SiteStorage class for file operations\n - Incoming connection firstchar errorfix\n - dbRebuild and dbQuery commandline actions\n - [Goals donation page](http://zeronet.readthedocs.org/en/latest/zeronet_development/donate/)\n\nZeroTalk\n\n - Rewritten to use SQL queries (falls back nicely to use json files on older version)" + }, + { + "post_id": 20, + "title": "Changelog: Mar 14, 2015", + "date_published": 1426386779.836, + "body": "\n - Save significant amount of memory by remove unused msgpack unpackers\n - Log unhandled exceptions\n - Connection checker error bugfix\n - Working on database support, you can follow the progress on [reddit](http://www.reddit.com/r/zeronet/comments/2yq7e8/a_json_caching_layer_for_quicker_development_and/)\n\n![memory usage](data/img/memory.png)" + }, + { + "post_id": 19, + "title": "Changelog: Mar 10, 2015", + "date_published": 1426041044.008, + "body": " - Fixed ZeroBoard and ZeroTalk registration: It was down last days, sorry, I haven't tested it after recent modifications, but I promise I will from now :)\n - Working hard on documentations, after trying some possibilities, I chosen readthedocs.org: http://zeronet.readthedocs.org\n - The API reference is now up-to-date, documented demo sites working method and also updated other parts\n\n[Please, tell me what you want to see in the docs, Thanks!](/1TaLk3zM7ZRskJvrh3ZNCDVGXvkJusPKQ/?Topic:14@2/New+ZeroNet+documentation)" + }, + { + "post_id": 18, + "title": "Changelog: Mar 8, 2015", + "date_published": 1425865493.306, + "body": " - [Better uPnp Puncher](https://github.com/HelloZeroNet/ZeroNet/blob/master/src/util/UpnpPunch.py), if you have problems with port opening please try this.\n\nZeroTalk: \n - Comment upvoting\n - Topic groups, if you know any other article about ZeroNet please, post [here](/1TaLk3zM7ZRskJvrh3ZNCDVGXvkJusPKQ/?Topics:8@2/Articles+about+ZeroNet)" + }, + { + "post_id": 17, + "title": "Changelog: Mar 5, 2015", + "date_published": 1425606285.111, + "body": " - Connection pinging and timeout\n - Request timeout\n - Verify content at signing (size, allowed files)\n - Smarter coffeescript recompile\n - More detailed stats\n\nZeroTalk: \n - Topic upvote\n - Even more source code realign\n\n![ZeroTalk upvote](data/img/zerotalk-upvote.png)" + }, + { + "post_id": 16, + "title": "Changelog: Mar 1, 2015", + "date_published": 1425259087.503, + "body": "ZeroTalk: \n - Reordered source code to allow more more feature in the future\n - Links starting with http://127.0.0.1:43110/ automatically converted to relative links (proxy support)\n - Comment reply (by clicking on comment's creation date)" + }, + { + "post_id": 15, + "title": "Changelog: Feb 25, 2015", + "date_published": 1424913197.035, + "body": " - Version 0.2.5\n - Pure-python upnp port opener (Thanks to sirMackk!)\n - Site download progress bar\n - We are also on [Gitter chat](https://gitter.im/HelloZeroNet/ZeroNet)\n - More detailed connection statistics (ping, buff, idle, delay, sent, received)\n - First char failed bugfix\n - Webebsocket disconnect on slow connection bugfix\n - Faster site update\n\n![Progressbar](data/img/progressbar.png)\n\nZeroTalk: \n\n - Sort after 100ms idle\n - Colored usernames\n - Limit reload rate to 500ms\n\nZeroHello\n\n - [iframe render fps test](/1EU1tbG9oC1A8jz2ouVwGZyQ5asrNsE4Vr/test/render.html) ([more details on ZeroTalk](/1TaLk3zM7ZRskJvrh3ZNCDVGXvkJusPKQ/?Topic:7@2/Slow+rendering+in+Chrome))\n" + }, + { + "post_id": 14, + "title": "Changelog: Feb 24, 2015", + "date_published": 1424734437.473, + "body": " - Version 0.2.4\n - New, experimental network code and protocol\n - peerPing and peerGetFile commands\n - Connection share and reuse between sites\n - Don't retry bad file more than 3 times in 20 min\n - Multi-threaded include file download\n - Really shuffle peers before publish\n - Simple internal stats page: http://127.0.0.1:43110/Stats\n - Publish bugfix for sites with more then 10 peers\n\n_If someone on very limited resources its recommended to wait some time until most of the peers is updates to new network code, because the backward compatibility is a little bit tricky and using more memory._" + }, + { + "post_id": 13, + "title": "Changelog: Feb 19, 2015", + "date_published": 1424394659.345, + "body": " - Version 0.2.3\n - One click source code download from github, auto unpack and restart \n - Randomize peers before publish and work start\n - Switched to upnpc-shared.exe it has better virustotal reputation (4/53 vs 19/57)\n\n![Autoupdate](data/img/autoupdate.png)\n\nZeroTalk:\n\n - Topics also sorted by topic creation date\n\n_New content and file changes propagation is a bit broken yet. Already working on better network code that also allows passive content publishing. It will be out in 1-2 weeks._" + }, + { + "post_id": 12, + "title": "Changelog: Feb 16, 2015", + "date_published": 1424134864.167, + "body": "Feb 16: \n - Version 0.2.2\n - LocalStorage support using WrapperAPI\n - Bugfix in user management\n\nZeroTalk: \n - Topics ordered by date of last post\n - Mark updated topics since your last visit\n\n![Mark](data/img/zerotalk-mark.png)" + }, + { + "post_id": 11, + "title": "Changelog: Feb 14, 2015", + "date_published": 1423922572.778, + "body": " - Version 0.2.1\n - Site size limit: Default 10MB, asks permission to store more, test it here: [ZeroNet windows requirement](/1ZeroPYmW4BGwmT6Z54jwPgTWpbKXtTra)\n - Browser open wait until UiServer started\n - Peer numbers stored in sites.json for faster warmup\n - Silent WSGIHandler error\n - siteSetLimit WrapperAPI command\n - Grand ADMIN permission to wrapperframe\n\nZeroHello: \n\n - Site modify time also include sub-file changes (ZeroTalk last comment)\n - Better changetime date format" + }, + { + "post_id": 10, + "title": "Changelog: Feb 11, 2015", + "date_published": 1423701015.643, + "body": "ZeroTalk:\n - Link-type posts\n - You can Edit or Delete your previous Comments and Topics\n - [Uploaded source code to github](https://github.com/HelloZeroNet/ZeroTalk)" + }, + { + "post_id": 9, + "title": "Changelog: Feb 10, 2015", + "date_published": 1423532194.094, + "body": " - Progressive publish timeout based on file size\n - Better tracker error log\n - Viewport support in content.json and ZeroFrame API to allow better mobile device layout\n - Escape ZeroFrame notification messages to avoid js injection\n - Allow select all data in QueryJson\n\nZeroTalk:\n - Display topic's comment number and last comment time (requires ZeroNet today's commits from github)\n - Mobile device optimized layout" + }, + { + "post_id": 8, + "title": "Changelog: Feb 9, 2015", + "date_published": 1423522387.728, + "body": " - Version 0.2.0\n - New bitcoin ECC lib (pybitcointools)\n - Hide notify errors\n - Include support for content.json\n - File permissions (signer address, filesize, allowed filenames)\n - Multisig ready, new, Bitcoincore compatible sign format\n - Faster, multi threaded content publishing\n - Multiuser, ready, BIP32 based site auth using bitcoin address/privatekey\n - Simple json file query language\n - Websocket api fileGet support\n\nZeroTalk: \n - [Decentralized forum demo](/1TaLk3zM7ZRskJvrh3ZNCDVGXvkJusPKQ/?Home)\n - Permission request/username registration\n - Everyone has an own file that he able to modify, sign and publish decentralized way, without contacting the site owner\n - Topic creation\n - Per topic commenting\n\n![ZeroTalk screenshot](data/img/zerotalk.png)" + }, + { + "post_id": 7, + "title": "Changelog: Jan 29, 2015", + "date_published": 1422664081.662, + "body": "The default tracker (tracker.pomf.se) is down since yesterday and its resulting some warning messages. To make it disappear please update to latest version from [GitHub](https://github.com/HelloZeroNet/ZeroNet).\n\nZeroNet:\n- Added better tracker error handling\n- Updated alive [trackers list](https://github.com/HelloZeroNet/ZeroNet/blob/master/src/Site/SiteManager.py) (if anyone have more, please [let us know](http://www.reddit.com/r/zeronet/comments/2sgjsp/changelog/co5y07h))\n\nIf you want to stay updated about the project status:
\nWe have created a [@HelloZeronet](https://twitter.com/HelloZeroNet) Twitter account" + }, + { + "post_id": 6, + "title": "Changelog: Jan 27, 2015", + "date_published": 1422394676.432, + "body": "ZeroNet\n* You can use `start.py` to start zeronet and open in browser automatically\n* Send timeout 50sec (workaround for some strange problems until we rewrite the network code without zeromq)\n* Reworked Websocket API to make it unified and allow named and unnamed parameters\n* Reload `content.json` when changed using fileWrite API command\n* Some typo fix\n\nZeroBlog\n* Allow edit post on mainpage\n* Also change blog title in `content.json` when modified using inline editor\n\nZeroHello\n* Update failed warning changed to No peers found when seeding own site." + }, + { + "post_id": 4, + "title": "Changelog: Jan 25, 2015", + "date_published": 1422224700.583, + "body": "ZeroNet\n- Utf-8 site titles fixed\n- Changes in DebugMedia merger to allow faster, node.js based coffeescript compiler\n\nZeroBlog\n- Inline editor rewritten to simple textarea, so copy/paste, undo/redo now working correctly\n- Read more button to folded posts with `---`\n- ZeroBlog running in demo mode, so anyone can try the editing tools\n- Base html tag fixed\n- Markdown cheat-sheet\n- Confirmation if you want to close the browser tab while editing\n\nHow to update your running blog?\n- Backup your `content.json` and `data.json` files\n- Copy the files in the `data/1BLogC9LN4oPDcruNz3qo1ysa133E9AGg8` directory to your site.\n" + }, + { + "post_id": 3, + "title": "How to have a blog like this", + "date_published": 1422140400, + "body": "* Stop ZeroNet\n* Create a new site using `python zeronet.py siteCreate` command\n* Copy all file from **data/1BLogC9LN4oPDcruNz3qo1ysa133E9AGg8** to **data/[Your new site address displayed when executed siteCreate]** directory\n* Delete **data** directory and rename **data-default** to **data** to get a clean, empty site\n* Rename **data/users/content-default.json** file to **data/users/content.json**\n* Execute `zeronet.py siteSign [yoursiteaddress] --inner_path data/users/content.json` to sign commenting rules\n* Start ZeroNet\n* Add/Modify content\n* Click on the `Sign & Publish new content` button\n* Congratulations! Your site is ready to access.\n\n_Note: You have to start commands with `..\\python\\python zeronet.py...` if you downloaded ZeroBundle package_" + }, + { + "post_id": 2, + "title": "Changelog: Jan 24, 2015", + "date_published": 1422105774.057, + "body": "* Version 0.1.6\n* Only serve .html files with wrapper frame\n* Http parameter support in url\n* Customizable background-color for wrapper in content.json\n* New Websocket API commands (only allowed on own sites):\n - fileWrite: Modify site's files in hdd from javascript\n - sitePublish: Sign new content and Publish to peers\n* Prompt value support in ZeroFrame (used for prompting privatekey for publishing in ZeroBlog)\n\n---\n\n## Previous changes:\n\n### Jan 20, 2014\n- Version 0.1.5\n- Detect computer wakeup from sleep and acts as startup (check open port, site changes)\n- Announce interval changed from 10min to 20min\n- Delete site files command support\n- Stop unfinished downloads on pause, delete\n- Confirm dialog support to WrapperApi\n\nZeroHello\n- Site Delete menuitem\n- Browser back button doesn't jumps to top\n\n### Jan 19, 2014:\n- Version 0.1.4\n- WIF compatible new private addresses\n- Proper bitcoin address verification, vanity address support: http://127.0.0.1:43110/1ZEro9ZwiZeEveFhcnubFLiN3v7tDL4bz\n- No hash error on worker kill\n- Have you secured your private key? confirmation\n\n### Jan 18, 2014:\n- Version 0.1.3\n- content.json hashing changed from sha1 to sha512 (trimmed to 256bits) for better security, keep hasing to sha1 for backward compatiblility yet\n- Fixed fileserver_port argument parsing\n- Try to ping peer before asking any command if no communication for 20min\n- Ping timeout / retry\n- Reduce websocket bw usage\n- Separate wrapper_key for websocket auth and auth_key to identify user\n- Removed unnecessary from wrapper iframe url\n\nZeroHello:\n- Compatiblilty with 0.1.3 websocket changes while maintaining backward compatibility\n- Better error report on file update fail\n\nZeroBoard:\n- Support for sha512 hashed auth_key, but keeping md5 key support for older versions yet\n\n### Jan 17, 2014:\n- Version 0.1.2\n- Better error message logging\n- Kill workers on download done\n- Retry on socket error\n- Timestamping console messages\n\n### Jan 16:\n- Version to 0.1.1\n- Version info to websocket api\n- Add publisher's zeronet version to content.json\n- Still chasing network publish problems, added more debug info\n\nZeroHello:\n- Your and the latest ZeroNet version added to top right corner (please update if you dont see it)\n" + }, + { + "post_id": 1, + "title": "ZeroBlog features", + "date_published": 1422105061, + "body": "Initial version (Jan 24, 2014):\n\n* Site avatar generated by site address\n* Distraction-free inline edit: Post title, date, body, Site title, description, links\n* Post format using [markdown](https://github.com/adam-p/markdown-here/wiki/Markdown-Cheatsheet)\n* Code block [syntax highlight](#code-highlight-demos) using [highlight.js](https://highlightjs.org/)\n* Create & Delete post\n* Sign & Publish from web\n* Fold blog post: Content after first `---` won't appear at listing\n* Shareable, friendly post urls\n\n\nTodo:\n\n* ~~Better content editor (contenteditable seemed like a good idea, but tricky support of copy/paste makes it more pain than gain)~~\n* Image upload to post & blog avatar\n* Paging\n* Searching\n* ~~Quick cheat-sheet using markdown~~\n\n---\n\n## Code highlight demos\n### Server-side site publishing (UiWebsocket.py):\n```py\ndef actionSitePublish(self, to, params):\n\tsite = self.site\n\tif not site.settings[\"own\"]: return self.response(to, \"Forbidden, you can only modify your own sites\")\n\n\t# Signing\n\tsite.loadContent(True) # Reload content.json, ignore errors to make it up-to-date\n\tsigned = site.signContent(params[0]) # Sign using private key sent by user\n\tif signed:\n\t\tself.cmd(\"notification\", [\"done\", \"Private key correct, site signed!\", 5000]) # Display message for 5 sec\n\telse:\n\t\tself.cmd(\"notification\", [\"error\", \"Site sign failed: invalid private key.\"])\n\t\tself.response(to, \"Site sign failed\")\n\t\treturn\n\tsite.loadContent(True) # Load new content.json, ignore errors\n\n\t# Publishing\n\tif not site.settings[\"serving\"]: # Enable site if paused\n\t\tsite.settings[\"serving\"] = True\n\t\tsite.saveSettings()\n\t\tsite.announce()\n\n\tpublished = site.publish(5) # Publish to 5 peer\n\n\tif published>0: # Successfuly published\n\t\tself.cmd(\"notification\", [\"done\", \"Site published to %s peers.\" % published, 5000])\n\t\tself.response(to, \"ok\")\n\t\tsite.updateWebsocket() # Send updated site data to local websocket clients\n\telse:\n\t\tif len(site.peers) == 0:\n\t\t\tself.cmd(\"notification\", [\"info\", \"No peers found, but your site is ready to access.\"])\n\t\t\tself.response(to, \"No peers found, but your site is ready to access.\")\n\t\telse:\n\t\t\tself.cmd(\"notification\", [\"error\", \"Site publish failed.\"])\n\t\t\tself.response(to, \"Site publish failed.\")\n```\n\n\n### Client-side site publish (ZeroBlog.coffee)\n```coffee\n# Sign and Publish site\npublish: =>\n\tif not @server_info.ip_external # No port open\n\t\t@cmd \"wrapperNotification\", [\"error\", \"To publish the site please open port #{@server_info.fileserver_port} on your router\"]\n\t\treturn false\n\t@cmd \"wrapperPrompt\", [\"Enter your private key:\", \"password\"], (privatekey) => # Prompt the private key\n\t\t$(\".publishbar .button\").addClass(\"loading\")\n\t\t@cmd \"sitePublish\", [privatekey], (res) =>\n\t\t\t$(\".publishbar .button\").removeClass(\"loading\")\n\t\t\t@log \"Publish result:\", res\n\n\treturn false # Ignore link default event\n```\n\n" + } + ] +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/autoupdate.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/autoupdate.png new file mode 100644 index 00000000..7fa439cc Binary files /dev/null and b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/autoupdate.png differ diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/direct_domains.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/direct_domains.png new file mode 100644 index 00000000..a4eab663 Binary files /dev/null and b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/direct_domains.png differ diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/domain.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/domain.png new file mode 100644 index 00000000..32369cbe Binary files /dev/null and b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/domain.png differ diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/memory.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/memory.png new file mode 100644 index 00000000..81711e87 Binary files /dev/null and b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/memory.png differ diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/multiuser.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/multiuser.png new file mode 100644 index 00000000..3253ec9e Binary files /dev/null and b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/multiuser.png differ diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/progressbar.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/progressbar.png new file mode 100644 index 00000000..7eb921a5 Binary files /dev/null and b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/progressbar.png differ diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/slides.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/slides.png new file mode 100644 index 00000000..f8a174f8 Binary files /dev/null and b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/slides.png differ diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/slots_memory.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/slots_memory.png new file mode 100644 index 00000000..fa23d0b5 Binary files /dev/null and b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/slots_memory.png differ diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/trayicon.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/trayicon.png new file mode 100644 index 00000000..f622557b Binary files /dev/null and b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/trayicon.png differ diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/zeroblog-comments.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/zeroblog-comments.png new file mode 100644 index 00000000..34d3eac6 Binary files /dev/null and b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/zeroblog-comments.png differ diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/zeroid.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/zeroid.png new file mode 100644 index 00000000..014a001b Binary files /dev/null and b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/zeroid.png differ diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/zeroname.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/zeroname.png new file mode 100644 index 00000000..95cc8fad Binary files /dev/null and b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/zeroname.png differ diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/zerotalk-mark.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/zerotalk-mark.png new file mode 100644 index 00000000..c8042ed5 Binary files /dev/null and b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/zerotalk-mark.png differ diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/zerotalk-upvote.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/zerotalk-upvote.png new file mode 100644 index 00000000..b0a7d248 Binary files /dev/null and b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/zerotalk-upvote.png differ diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/zerotalk.png b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/zerotalk.png new file mode 100644 index 00000000..3e2cb5c6 Binary files /dev/null and b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/img/zerotalk.png differ diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json new file mode 100644 index 00000000..bb24e26b --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/content.json @@ -0,0 +1,15 @@ +{ + "cert_auth_type": "web", + "cert_sign": "G4YB7y749GI6mJboyI7cNNfyMwOS0rcVXLmgq8qmCC4TCaRqup3TGWm8hzeru7+B5iXhq19Ruz286bNVKgNbnwU=", + "cert_user_id": "newzeroid@zeroid.bit", + "files": { + "data.json": { + "sha512": "2378ef20379f1db0c3e2a803bfbfda2b68515968b7e311ccc604406168969d34", + "size": 161 + } + }, + "modified": 1432554679.913, + "signs": { + "1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q": "GzX/Ht6ms1dOnqB3kVENvDnxpH+mqA0Zlg3hWy0iwgxpyxWcA4zgmwxcEH41BN9RrvCaxgSd2m1SG1/8qbQPzDY=" + } +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/data.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/data.json new file mode 100644 index 00000000..52acca16 --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/users/1C5sgvWaSgfaTpV5kjBCnCiKtENNMYo69q/data.json @@ -0,0 +1,12 @@ +{ + "next_comment_id": 2, + "comment": [ + { + "comment_id": 1, + "body": "Test me!", + "post_id": 40, + "date_added": 1432554679 + } + ], + "comment_vote": {} +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/content.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/content.json new file mode 100644 index 00000000..9c0812d0 --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/content.json @@ -0,0 +1,15 @@ +{ + "cert_auth_type": "web", + "cert_sign": "HBsTrjTmv+zD1iY93tSci8n9DqdEtYwzxJmRppn4/b+RYktcANGm5tXPOb+Duw3AJcgWDcGUvQVgN1D9QAwIlCw=", + "cert_user_id": "toruser@zeroid.bit", + "files": { + "data.json": { + "sha512": "4868b5e6d70a55d137db71c2e276bda80437e0235ac670962acc238071296b45", + "size": 168 + } + }, + "modified": 1432491109.11, + "signs": { + "1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9": "HMy7ZwwqE0Sk8O+5hTx/ejFW6KtIDbID6fGblCodUTpz4mJZ5GwApBHSVLMYL43vvGT/vKZOiQoJ5tQTeFVbbkk=" + } +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/data.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/data.json new file mode 100644 index 00000000..1a7e9ee0 --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/users/1CjfbrbwtP8Y2QjPy12vpTATkUT7oSiPQ9/data.json @@ -0,0 +1,12 @@ +{ + "next_comment_id": 2, + "comment": [ + { + "comment_id": 1, + "body": "hello from Tor!", + "post_id": 38, + "date_added": 1432491109 + } + ], + "comment_vote": {} +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/users/content.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/users/content.json new file mode 100644 index 00000000..0892ed5f --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/data/users/content.json @@ -0,0 +1,25 @@ +{ + "files": {}, + "ignore": ".*", + "modified": 1432466966.003, + "signs": { + "1BLogC9LN4oPDcruNz3qo1ysa133E9AGg8": "HChU28lG4MCnAiui6wDAaVCD4QUrgSy4zZ67+MMHidcUJRkLGnO3j4Eb1N0AWQ86nhSBwoOQf08Rha7gRyTDlAk=" + }, + "user_contents": { + "cert_signers": { + "zeroid.bit": [ "1iD5ZQJMNXu43w1qLB8sfdHVKppVMduGz" ] + }, + "permission_rules": { + ".*": { + "files_allowed": "data.json", + "max_size": 10000 + }, + "bitid/.*@zeroid.bit": { "max_size": 40000 }, + "bitmsg/.*@zeroid.bit": { "max_size": 15000 } + }, + "permissions": { + "bad@zeroid.bit": false, + "nofish@zeroid.bit": { "max_size": 100000 } + } + } +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/dbschema.json b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/dbschema.json new file mode 100644 index 00000000..dc196a3a --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/dbschema.json @@ -0,0 +1,54 @@ +{ + "db_name": "ZeroID", + "db_file": "data/zeroblog.db", + "version": 2, + "maps": { + "users/.+/data.json": { + "to_table": [ + "comment", + {"node": "comment_vote", "table": "comment_vote", "key_col": "comment_uri", "val_col": "vote"} + ] + }, + "users/.+/content.json": { + "to_keyvalue": [ "cert_user_id" ] + }, + "data.json": { + "to_table": [ "post" ], + "to_keyvalue": [ "title", "description", "links", "next_post_id", "demo", "modified" ] + } + + }, + "tables": { + "comment": { + "cols": [ + ["comment_id", "INTEGER"], + ["post_id", "INTEGER"], + ["body", "TEXT"], + ["date_added", "INTEGER"], + ["json_id", "INTEGER REFERENCES json (json_id)"] + ], + "indexes": ["CREATE UNIQUE INDEX comment_key ON comment(json_id, comment_id)", "CREATE INDEX comment_post_id ON comment(post_id)"], + "schema_changed": 1426195823 + }, + "comment_vote": { + "cols": [ + ["comment_uri", "TEXT"], + ["vote", "INTEGER"], + ["json_id", "INTEGER REFERENCES json (json_id)"] + ], + "indexes": ["CREATE INDEX comment_vote_comment_uri ON comment_vote(comment_uri)", "CREATE INDEX comment_vote_json_id ON comment_vote(json_id)"], + "schema_changed": 1426195822 + }, + "post": { + "cols": [ + ["post_id", "INTEGER"], + ["title", "TEXT"], + ["body", "TEXT"], + ["date_published", "INTEGER"], + ["json_id", "INTEGER REFERENCES json (json_id)"] + ], + "indexes": ["CREATE UNIQUE INDEX post_uri ON post(json_id, post_id)", "CREATE INDEX post_id ON post(post_id)"], + "schema_changed": 1426195823 + } + } +} \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/img/loading.gif b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/img/loading.gif new file mode 100644 index 00000000..27d0aa81 Binary files /dev/null and b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/img/loading.gif differ diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/index.html b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/index.html new file mode 100644 index 00000000..42285031 --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/index.html @@ -0,0 +1,137 @@ + + + + + ZeroBlog Demo + + + + + + + + + + +
+ + ? Editing: Post:21.body Save Delete Cancel +
+ + + + +
+ Content changed Sign & Publish new content +
+ + + + +
+
+

+

+
+ +
+ + + + +
+ + + +
+ Add new post + + +
+

Title

+
+ 21 hours ago · 2 min read + ·
3 comments
+
+
Body
+ Read more +
+ + +
+ + + +
+

Title

+
21 hours ago · 2 min read
+
+ +

0 Comments:

+ +
+
+ Please sign in + ━ + new comment +
+
+
Sign in as...
+ + Submit comment +
+
+
+
+
+
+
+ + +
+ +
+
+ user_name + + ━ + 1 day ago +
Reply
+
+
Body
+
+ +
+
+ + + + +
+ + + +
+ + + + + + \ No newline at end of file diff --git a/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/js/all.js b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/js/all.js new file mode 100644 index 00000000..99eb0c2e --- /dev/null +++ b/src/Test/testdata/1TeSTvb4w2PWE81S2rEELgmX2GCCExQGT/js/all.js @@ -0,0 +1,1892 @@ + + +/* ---- data/1BLogC9LN4oPDcruNz3qo1ysa133E9AGg8/js/lib/00-jquery.min.js ---- */ + + +/*! jQuery v2.1.3 | (c) 2005, 2014 jQuery Foundation, Inc. | jquery.org/license */ +!function(a,b){"object"==typeof module&&"object"==typeof module.exports?module.exports=a.document?b(a,!0):function(a){if(!a.document)throw new Error("jQuery requires a window with a document");return b(a)}:b(a)}("undefined"!=typeof window?window:this,function(a,b){var c=[],d=c.slice,e=c.concat,f=c.push,g=c.indexOf,h={},i=h.toString,j=h.hasOwnProperty,k={},l=a.document,m="2.1.3",n=function(a,b){return new n.fn.init(a,b)},o=/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,p=/^-ms-/,q=/-([\da-z])/gi,r=function(a,b){return b.toUpperCase()};n.fn=n.prototype={jquery:m,constructor:n,selector:"",length:0,toArray:function(){return d.call(this)},get:function(a){return null!=a?0>a?this[a+this.length]:this[a]:d.call(this)},pushStack:function(a){var b=n.merge(this.constructor(),a);return b.prevObject=this,b.context=this.context,b},each:function(a,b){return n.each(this,a,b)},map:function(a){return this.pushStack(n.map(this,function(b,c){return a.call(b,c,b)}))},slice:function(){return this.pushStack(d.apply(this,arguments))},first:function(){return this.eq(0)},last:function(){return this.eq(-1)},eq:function(a){var b=this.length,c=+a+(0>a?b:0);return this.pushStack(c>=0&&b>c?[this[c]]:[])},end:function(){return this.prevObject||this.constructor(null)},push:f,sort:c.sort,splice:c.splice},n.extend=n.fn.extend=function(){var a,b,c,d,e,f,g=arguments[0]||{},h=1,i=arguments.length,j=!1;for("boolean"==typeof g&&(j=g,g=arguments[h]||{},h++),"object"==typeof g||n.isFunction(g)||(g={}),h===i&&(g=this,h--);i>h;h++)if(null!=(a=arguments[h]))for(b in a)c=g[b],d=a[b],g!==d&&(j&&d&&(n.isPlainObject(d)||(e=n.isArray(d)))?(e?(e=!1,f=c&&n.isArray(c)?c:[]):f=c&&n.isPlainObject(c)?c:{},g[b]=n.extend(j,f,d)):void 0!==d&&(g[b]=d));return g},n.extend({expando:"jQuery"+(m+Math.random()).replace(/\D/g,""),isReady:!0,error:function(a){throw new Error(a)},noop:function(){},isFunction:function(a){return"function"===n.type(a)},isArray:Array.isArray,isWindow:function(a){return null!=a&&a===a.window},isNumeric:function(a){return!n.isArray(a)&&a-parseFloat(a)+1>=0},isPlainObject:function(a){return"object"!==n.type(a)||a.nodeType||n.isWindow(a)?!1:a.constructor&&!j.call(a.constructor.prototype,"isPrototypeOf")?!1:!0},isEmptyObject:function(a){var b;for(b in a)return!1;return!0},type:function(a){return null==a?a+"":"object"==typeof a||"function"==typeof a?h[i.call(a)]||"object":typeof a},globalEval:function(a){var b,c=eval;a=n.trim(a),a&&(1===a.indexOf("use strict")?(b=l.createElement("script"),b.text=a,l.head.appendChild(b).parentNode.removeChild(b)):c(a))},camelCase:function(a){return a.replace(p,"ms-").replace(q,r)},nodeName:function(a,b){return a.nodeName&&a.nodeName.toLowerCase()===b.toLowerCase()},each:function(a,b,c){var d,e=0,f=a.length,g=s(a);if(c){if(g){for(;f>e;e++)if(d=b.apply(a[e],c),d===!1)break}else for(e in a)if(d=b.apply(a[e],c),d===!1)break}else if(g){for(;f>e;e++)if(d=b.call(a[e],e,a[e]),d===!1)break}else for(e in a)if(d=b.call(a[e],e,a[e]),d===!1)break;return a},trim:function(a){return null==a?"":(a+"").replace(o,"")},makeArray:function(a,b){var c=b||[];return null!=a&&(s(Object(a))?n.merge(c,"string"==typeof a?[a]:a):f.call(c,a)),c},inArray:function(a,b,c){return null==b?-1:g.call(b,a,c)},merge:function(a,b){for(var c=+b.length,d=0,e=a.length;c>d;d++)a[e++]=b[d];return a.length=e,a},grep:function(a,b,c){for(var d,e=[],f=0,g=a.length,h=!c;g>f;f++)d=!b(a[f],f),d!==h&&e.push(a[f]);return e},map:function(a,b,c){var d,f=0,g=a.length,h=s(a),i=[];if(h)for(;g>f;f++)d=b(a[f],f,c),null!=d&&i.push(d);else for(f in a)d=b(a[f],f,c),null!=d&&i.push(d);return e.apply([],i)},guid:1,proxy:function(a,b){var c,e,f;return"string"==typeof b&&(c=a[b],b=a,a=c),n.isFunction(a)?(e=d.call(arguments,2),f=function(){return a.apply(b||this,e.concat(d.call(arguments)))},f.guid=a.guid=a.guid||n.guid++,f):void 0},now:Date.now,support:k}),n.each("Boolean Number String Function Array Date RegExp Object Error".split(" "),function(a,b){h["[object "+b+"]"]=b.toLowerCase()});function s(a){var b=a.length,c=n.type(a);return"function"===c||n.isWindow(a)?!1:1===a.nodeType&&b?!0:"array"===c||0===b||"number"==typeof b&&b>0&&b-1 in a}var t=function(a){var b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u="sizzle"+1*new Date,v=a.document,w=0,x=0,y=hb(),z=hb(),A=hb(),B=function(a,b){return a===b&&(l=!0),0},C=1<<31,D={}.hasOwnProperty,E=[],F=E.pop,G=E.push,H=E.push,I=E.slice,J=function(a,b){for(var c=0,d=a.length;d>c;c++)if(a[c]===b)return c;return-1},K="checked|selected|async|autofocus|autoplay|controls|defer|disabled|hidden|ismap|loop|multiple|open|readonly|required|scoped",L="[\\x20\\t\\r\\n\\f]",M="(?:\\\\.|[\\w-]|[^\\x00-\\xa0])+",N=M.replace("w","w#"),O="\\["+L+"*("+M+")(?:"+L+"*([*^$|!~]?=)"+L+"*(?:'((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\"|("+N+"))|)"+L+"*\\]",P=":("+M+")(?:\\((('((?:\\\\.|[^\\\\'])*)'|\"((?:\\\\.|[^\\\\\"])*)\")|((?:\\\\.|[^\\\\()[\\]]|"+O+")*)|.*)\\)|)",Q=new RegExp(L+"+","g"),R=new RegExp("^"+L+"+|((?:^|[^\\\\])(?:\\\\.)*)"+L+"+$","g"),S=new RegExp("^"+L+"*,"+L+"*"),T=new RegExp("^"+L+"*([>+~]|"+L+")"+L+"*"),U=new RegExp("="+L+"*([^\\]'\"]*?)"+L+"*\\]","g"),V=new RegExp(P),W=new RegExp("^"+N+"$"),X={ID:new RegExp("^#("+M+")"),CLASS:new RegExp("^\\.("+M+")"),TAG:new RegExp("^("+M.replace("w","w*")+")"),ATTR:new RegExp("^"+O),PSEUDO:new RegExp("^"+P),CHILD:new RegExp("^:(only|first|last|nth|nth-last)-(child|of-type)(?:\\("+L+"*(even|odd|(([+-]|)(\\d*)n|)"+L+"*(?:([+-]|)"+L+"*(\\d+)|))"+L+"*\\)|)","i"),bool:new RegExp("^(?:"+K+")$","i"),needsContext:new RegExp("^"+L+"*[>+~]|:(even|odd|eq|gt|lt|nth|first|last)(?:\\("+L+"*((?:-\\d)?\\d*)"+L+"*\\)|)(?=[^-]|$)","i")},Y=/^(?:input|select|textarea|button)$/i,Z=/^h\d$/i,$=/^[^{]+\{\s*\[native \w/,_=/^(?:#([\w-]+)|(\w+)|\.([\w-]+))$/,ab=/[+~]/,bb=/'|\\/g,cb=new RegExp("\\\\([\\da-f]{1,6}"+L+"?|("+L+")|.)","ig"),db=function(a,b,c){var d="0x"+b-65536;return d!==d||c?b:0>d?String.fromCharCode(d+65536):String.fromCharCode(d>>10|55296,1023&d|56320)},eb=function(){m()};try{H.apply(E=I.call(v.childNodes),v.childNodes),E[v.childNodes.length].nodeType}catch(fb){H={apply:E.length?function(a,b){G.apply(a,I.call(b))}:function(a,b){var c=a.length,d=0;while(a[c++]=b[d++]);a.length=c-1}}}function gb(a,b,d,e){var f,h,j,k,l,o,r,s,w,x;if((b?b.ownerDocument||b:v)!==n&&m(b),b=b||n,d=d||[],k=b.nodeType,"string"!=typeof a||!a||1!==k&&9!==k&&11!==k)return d;if(!e&&p){if(11!==k&&(f=_.exec(a)))if(j=f[1]){if(9===k){if(h=b.getElementById(j),!h||!h.parentNode)return d;if(h.id===j)return d.push(h),d}else if(b.ownerDocument&&(h=b.ownerDocument.getElementById(j))&&t(b,h)&&h.id===j)return d.push(h),d}else{if(f[2])return H.apply(d,b.getElementsByTagName(a)),d;if((j=f[3])&&c.getElementsByClassName)return H.apply(d,b.getElementsByClassName(j)),d}if(c.qsa&&(!q||!q.test(a))){if(s=r=u,w=b,x=1!==k&&a,1===k&&"object"!==b.nodeName.toLowerCase()){o=g(a),(r=b.getAttribute("id"))?s=r.replace(bb,"\\$&"):b.setAttribute("id",s),s="[id='"+s+"'] ",l=o.length;while(l--)o[l]=s+rb(o[l]);w=ab.test(a)&&pb(b.parentNode)||b,x=o.join(",")}if(x)try{return H.apply(d,w.querySelectorAll(x)),d}catch(y){}finally{r||b.removeAttribute("id")}}}return i(a.replace(R,"$1"),b,d,e)}function hb(){var a=[];function b(c,e){return a.push(c+" ")>d.cacheLength&&delete b[a.shift()],b[c+" "]=e}return b}function ib(a){return a[u]=!0,a}function jb(a){var b=n.createElement("div");try{return!!a(b)}catch(c){return!1}finally{b.parentNode&&b.parentNode.removeChild(b),b=null}}function kb(a,b){var c=a.split("|"),e=a.length;while(e--)d.attrHandle[c[e]]=b}function lb(a,b){var c=b&&a,d=c&&1===a.nodeType&&1===b.nodeType&&(~b.sourceIndex||C)-(~a.sourceIndex||C);if(d)return d;if(c)while(c=c.nextSibling)if(c===b)return-1;return a?1:-1}function mb(a){return function(b){var c=b.nodeName.toLowerCase();return"input"===c&&b.type===a}}function nb(a){return function(b){var c=b.nodeName.toLowerCase();return("input"===c||"button"===c)&&b.type===a}}function ob(a){return ib(function(b){return b=+b,ib(function(c,d){var e,f=a([],c.length,b),g=f.length;while(g--)c[e=f[g]]&&(c[e]=!(d[e]=c[e]))})})}function pb(a){return a&&"undefined"!=typeof a.getElementsByTagName&&a}c=gb.support={},f=gb.isXML=function(a){var b=a&&(a.ownerDocument||a).documentElement;return b?"HTML"!==b.nodeName:!1},m=gb.setDocument=function(a){var b,e,g=a?a.ownerDocument||a:v;return g!==n&&9===g.nodeType&&g.documentElement?(n=g,o=g.documentElement,e=g.defaultView,e&&e!==e.top&&(e.addEventListener?e.addEventListener("unload",eb,!1):e.attachEvent&&e.attachEvent("onunload",eb)),p=!f(g),c.attributes=jb(function(a){return a.className="i",!a.getAttribute("className")}),c.getElementsByTagName=jb(function(a){return a.appendChild(g.createComment("")),!a.getElementsByTagName("*").length}),c.getElementsByClassName=$.test(g.getElementsByClassName),c.getById=jb(function(a){return o.appendChild(a).id=u,!g.getElementsByName||!g.getElementsByName(u).length}),c.getById?(d.find.ID=function(a,b){if("undefined"!=typeof b.getElementById&&p){var c=b.getElementById(a);return c&&c.parentNode?[c]:[]}},d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){return a.getAttribute("id")===b}}):(delete d.find.ID,d.filter.ID=function(a){var b=a.replace(cb,db);return function(a){var c="undefined"!=typeof a.getAttributeNode&&a.getAttributeNode("id");return c&&c.value===b}}),d.find.TAG=c.getElementsByTagName?function(a,b){return"undefined"!=typeof b.getElementsByTagName?b.getElementsByTagName(a):c.qsa?b.querySelectorAll(a):void 0}:function(a,b){var c,d=[],e=0,f=b.getElementsByTagName(a);if("*"===a){while(c=f[e++])1===c.nodeType&&d.push(c);return d}return f},d.find.CLASS=c.getElementsByClassName&&function(a,b){return p?b.getElementsByClassName(a):void 0},r=[],q=[],(c.qsa=$.test(g.querySelectorAll))&&(jb(function(a){o.appendChild(a).innerHTML="",a.querySelectorAll("[msallowcapture^='']").length&&q.push("[*^$]="+L+"*(?:''|\"\")"),a.querySelectorAll("[selected]").length||q.push("\\["+L+"*(?:value|"+K+")"),a.querySelectorAll("[id~="+u+"-]").length||q.push("~="),a.querySelectorAll(":checked").length||q.push(":checked"),a.querySelectorAll("a#"+u+"+*").length||q.push(".#.+[+~]")}),jb(function(a){var b=g.createElement("input");b.setAttribute("type","hidden"),a.appendChild(b).setAttribute("name","D"),a.querySelectorAll("[name=d]").length&&q.push("name"+L+"*[*^$|!~]?="),a.querySelectorAll(":enabled").length||q.push(":enabled",":disabled"),a.querySelectorAll("*,:x"),q.push(",.*:")})),(c.matchesSelector=$.test(s=o.matches||o.webkitMatchesSelector||o.mozMatchesSelector||o.oMatchesSelector||o.msMatchesSelector))&&jb(function(a){c.disconnectedMatch=s.call(a,"div"),s.call(a,"[s!='']:x"),r.push("!=",P)}),q=q.length&&new RegExp(q.join("|")),r=r.length&&new RegExp(r.join("|")),b=$.test(o.compareDocumentPosition),t=b||$.test(o.contains)?function(a,b){var c=9===a.nodeType?a.documentElement:a,d=b&&b.parentNode;return a===d||!(!d||1!==d.nodeType||!(c.contains?c.contains(d):a.compareDocumentPosition&&16&a.compareDocumentPosition(d)))}:function(a,b){if(b)while(b=b.parentNode)if(b===a)return!0;return!1},B=b?function(a,b){if(a===b)return l=!0,0;var d=!a.compareDocumentPosition-!b.compareDocumentPosition;return d?d:(d=(a.ownerDocument||a)===(b.ownerDocument||b)?a.compareDocumentPosition(b):1,1&d||!c.sortDetached&&b.compareDocumentPosition(a)===d?a===g||a.ownerDocument===v&&t(v,a)?-1:b===g||b.ownerDocument===v&&t(v,b)?1:k?J(k,a)-J(k,b):0:4&d?-1:1)}:function(a,b){if(a===b)return l=!0,0;var c,d=0,e=a.parentNode,f=b.parentNode,h=[a],i=[b];if(!e||!f)return a===g?-1:b===g?1:e?-1:f?1:k?J(k,a)-J(k,b):0;if(e===f)return lb(a,b);c=a;while(c=c.parentNode)h.unshift(c);c=b;while(c=c.parentNode)i.unshift(c);while(h[d]===i[d])d++;return d?lb(h[d],i[d]):h[d]===v?-1:i[d]===v?1:0},g):n},gb.matches=function(a,b){return gb(a,null,null,b)},gb.matchesSelector=function(a,b){if((a.ownerDocument||a)!==n&&m(a),b=b.replace(U,"='$1']"),!(!c.matchesSelector||!p||r&&r.test(b)||q&&q.test(b)))try{var d=s.call(a,b);if(d||c.disconnectedMatch||a.document&&11!==a.document.nodeType)return d}catch(e){}return gb(b,n,null,[a]).length>0},gb.contains=function(a,b){return(a.ownerDocument||a)!==n&&m(a),t(a,b)},gb.attr=function(a,b){(a.ownerDocument||a)!==n&&m(a);var e=d.attrHandle[b.toLowerCase()],f=e&&D.call(d.attrHandle,b.toLowerCase())?e(a,b,!p):void 0;return void 0!==f?f:c.attributes||!p?a.getAttribute(b):(f=a.getAttributeNode(b))&&f.specified?f.value:null},gb.error=function(a){throw new Error("Syntax error, unrecognized expression: "+a)},gb.uniqueSort=function(a){var b,d=[],e=0,f=0;if(l=!c.detectDuplicates,k=!c.sortStable&&a.slice(0),a.sort(B),l){while(b=a[f++])b===a[f]&&(e=d.push(f));while(e--)a.splice(d[e],1)}return k=null,a},e=gb.getText=function(a){var b,c="",d=0,f=a.nodeType;if(f){if(1===f||9===f||11===f){if("string"==typeof a.textContent)return a.textContent;for(a=a.firstChild;a;a=a.nextSibling)c+=e(a)}else if(3===f||4===f)return a.nodeValue}else while(b=a[d++])c+=e(b);return c},d=gb.selectors={cacheLength:50,createPseudo:ib,match:X,attrHandle:{},find:{},relative:{">":{dir:"parentNode",first:!0}," ":{dir:"parentNode"},"+":{dir:"previousSibling",first:!0},"~":{dir:"previousSibling"}},preFilter:{ATTR:function(a){return a[1]=a[1].replace(cb,db),a[3]=(a[3]||a[4]||a[5]||"").replace(cb,db),"~="===a[2]&&(a[3]=" "+a[3]+" "),a.slice(0,4)},CHILD:function(a){return a[1]=a[1].toLowerCase(),"nth"===a[1].slice(0,3)?(a[3]||gb.error(a[0]),a[4]=+(a[4]?a[5]+(a[6]||1):2*("even"===a[3]||"odd"===a[3])),a[5]=+(a[7]+a[8]||"odd"===a[3])):a[3]&&gb.error(a[0]),a},PSEUDO:function(a){var b,c=!a[6]&&a[2];return X.CHILD.test(a[0])?null:(a[3]?a[2]=a[4]||a[5]||"":c&&V.test(c)&&(b=g(c,!0))&&(b=c.indexOf(")",c.length-b)-c.length)&&(a[0]=a[0].slice(0,b),a[2]=c.slice(0,b)),a.slice(0,3))}},filter:{TAG:function(a){var b=a.replace(cb,db).toLowerCase();return"*"===a?function(){return!0}:function(a){return a.nodeName&&a.nodeName.toLowerCase()===b}},CLASS:function(a){var b=y[a+" "];return b||(b=new RegExp("(^|"+L+")"+a+"("+L+"|$)"))&&y(a,function(a){return b.test("string"==typeof a.className&&a.className||"undefined"!=typeof a.getAttribute&&a.getAttribute("class")||"")})},ATTR:function(a,b,c){return function(d){var e=gb.attr(d,a);return null==e?"!="===b:b?(e+="","="===b?e===c:"!="===b?e!==c:"^="===b?c&&0===e.indexOf(c):"*="===b?c&&e.indexOf(c)>-1:"$="===b?c&&e.slice(-c.length)===c:"~="===b?(" "+e.replace(Q," ")+" ").indexOf(c)>-1:"|="===b?e===c||e.slice(0,c.length+1)===c+"-":!1):!0}},CHILD:function(a,b,c,d,e){var f="nth"!==a.slice(0,3),g="last"!==a.slice(-4),h="of-type"===b;return 1===d&&0===e?function(a){return!!a.parentNode}:function(b,c,i){var j,k,l,m,n,o,p=f!==g?"nextSibling":"previousSibling",q=b.parentNode,r=h&&b.nodeName.toLowerCase(),s=!i&&!h;if(q){if(f){while(p){l=b;while(l=l[p])if(h?l.nodeName.toLowerCase()===r:1===l.nodeType)return!1;o=p="only"===a&&!o&&"nextSibling"}return!0}if(o=[g?q.firstChild:q.lastChild],g&&s){k=q[u]||(q[u]={}),j=k[a]||[],n=j[0]===w&&j[1],m=j[0]===w&&j[2],l=n&&q.childNodes[n];while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if(1===l.nodeType&&++m&&l===b){k[a]=[w,n,m];break}}else if(s&&(j=(b[u]||(b[u]={}))[a])&&j[0]===w)m=j[1];else while(l=++n&&l&&l[p]||(m=n=0)||o.pop())if((h?l.nodeName.toLowerCase()===r:1===l.nodeType)&&++m&&(s&&((l[u]||(l[u]={}))[a]=[w,m]),l===b))break;return m-=e,m===d||m%d===0&&m/d>=0}}},PSEUDO:function(a,b){var c,e=d.pseudos[a]||d.setFilters[a.toLowerCase()]||gb.error("unsupported pseudo: "+a);return e[u]?e(b):e.length>1?(c=[a,a,"",b],d.setFilters.hasOwnProperty(a.toLowerCase())?ib(function(a,c){var d,f=e(a,b),g=f.length;while(g--)d=J(a,f[g]),a[d]=!(c[d]=f[g])}):function(a){return e(a,0,c)}):e}},pseudos:{not:ib(function(a){var b=[],c=[],d=h(a.replace(R,"$1"));return d[u]?ib(function(a,b,c,e){var f,g=d(a,null,e,[]),h=a.length;while(h--)(f=g[h])&&(a[h]=!(b[h]=f))}):function(a,e,f){return b[0]=a,d(b,null,f,c),b[0]=null,!c.pop()}}),has:ib(function(a){return function(b){return gb(a,b).length>0}}),contains:ib(function(a){return a=a.replace(cb,db),function(b){return(b.textContent||b.innerText||e(b)).indexOf(a)>-1}}),lang:ib(function(a){return W.test(a||"")||gb.error("unsupported lang: "+a),a=a.replace(cb,db).toLowerCase(),function(b){var c;do if(c=p?b.lang:b.getAttribute("xml:lang")||b.getAttribute("lang"))return c=c.toLowerCase(),c===a||0===c.indexOf(a+"-");while((b=b.parentNode)&&1===b.nodeType);return!1}}),target:function(b){var c=a.location&&a.location.hash;return c&&c.slice(1)===b.id},root:function(a){return a===o},focus:function(a){return a===n.activeElement&&(!n.hasFocus||n.hasFocus())&&!!(a.type||a.href||~a.tabIndex)},enabled:function(a){return a.disabled===!1},disabled:function(a){return a.disabled===!0},checked:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&!!a.checked||"option"===b&&!!a.selected},selected:function(a){return a.parentNode&&a.parentNode.selectedIndex,a.selected===!0},empty:function(a){for(a=a.firstChild;a;a=a.nextSibling)if(a.nodeType<6)return!1;return!0},parent:function(a){return!d.pseudos.empty(a)},header:function(a){return Z.test(a.nodeName)},input:function(a){return Y.test(a.nodeName)},button:function(a){var b=a.nodeName.toLowerCase();return"input"===b&&"button"===a.type||"button"===b},text:function(a){var b;return"input"===a.nodeName.toLowerCase()&&"text"===a.type&&(null==(b=a.getAttribute("type"))||"text"===b.toLowerCase())},first:ob(function(){return[0]}),last:ob(function(a,b){return[b-1]}),eq:ob(function(a,b,c){return[0>c?c+b:c]}),even:ob(function(a,b){for(var c=0;b>c;c+=2)a.push(c);return a}),odd:ob(function(a,b){for(var c=1;b>c;c+=2)a.push(c);return a}),lt:ob(function(a,b,c){for(var d=0>c?c+b:c;--d>=0;)a.push(d);return a}),gt:ob(function(a,b,c){for(var d=0>c?c+b:c;++db;b++)d+=a[b].value;return d}function sb(a,b,c){var d=b.dir,e=c&&"parentNode"===d,f=x++;return b.first?function(b,c,f){while(b=b[d])if(1===b.nodeType||e)return a(b,c,f)}:function(b,c,g){var h,i,j=[w,f];if(g){while(b=b[d])if((1===b.nodeType||e)&&a(b,c,g))return!0}else while(b=b[d])if(1===b.nodeType||e){if(i=b[u]||(b[u]={}),(h=i[d])&&h[0]===w&&h[1]===f)return j[2]=h[2];if(i[d]=j,j[2]=a(b,c,g))return!0}}}function tb(a){return a.length>1?function(b,c,d){var e=a.length;while(e--)if(!a[e](b,c,d))return!1;return!0}:a[0]}function ub(a,b,c){for(var d=0,e=b.length;e>d;d++)gb(a,b[d],c);return c}function vb(a,b,c,d,e){for(var f,g=[],h=0,i=a.length,j=null!=b;i>h;h++)(f=a[h])&&(!c||c(f,d,e))&&(g.push(f),j&&b.push(h));return g}function wb(a,b,c,d,e,f){return d&&!d[u]&&(d=wb(d)),e&&!e[u]&&(e=wb(e,f)),ib(function(f,g,h,i){var j,k,l,m=[],n=[],o=g.length,p=f||ub(b||"*",h.nodeType?[h]:h,[]),q=!a||!f&&b?p:vb(p,m,a,h,i),r=c?e||(f?a:o||d)?[]:g:q;if(c&&c(q,r,h,i),d){j=vb(r,n),d(j,[],h,i),k=j.length;while(k--)(l=j[k])&&(r[n[k]]=!(q[n[k]]=l))}if(f){if(e||a){if(e){j=[],k=r.length;while(k--)(l=r[k])&&j.push(q[k]=l);e(null,r=[],j,i)}k=r.length;while(k--)(l=r[k])&&(j=e?J(f,l):m[k])>-1&&(f[j]=!(g[j]=l))}}else r=vb(r===g?r.splice(o,r.length):r),e?e(null,g,r,i):H.apply(g,r)})}function xb(a){for(var b,c,e,f=a.length,g=d.relative[a[0].type],h=g||d.relative[" "],i=g?1:0,k=sb(function(a){return a===b},h,!0),l=sb(function(a){return J(b,a)>-1},h,!0),m=[function(a,c,d){var e=!g&&(d||c!==j)||((b=c).nodeType?k(a,c,d):l(a,c,d));return b=null,e}];f>i;i++)if(c=d.relative[a[i].type])m=[sb(tb(m),c)];else{if(c=d.filter[a[i].type].apply(null,a[i].matches),c[u]){for(e=++i;f>e;e++)if(d.relative[a[e].type])break;return wb(i>1&&tb(m),i>1&&rb(a.slice(0,i-1).concat({value:" "===a[i-2].type?"*":""})).replace(R,"$1"),c,e>i&&xb(a.slice(i,e)),f>e&&xb(a=a.slice(e)),f>e&&rb(a))}m.push(c)}return tb(m)}function yb(a,b){var c=b.length>0,e=a.length>0,f=function(f,g,h,i,k){var l,m,o,p=0,q="0",r=f&&[],s=[],t=j,u=f||e&&d.find.TAG("*",k),v=w+=null==t?1:Math.random()||.1,x=u.length;for(k&&(j=g!==n&&g);q!==x&&null!=(l=u[q]);q++){if(e&&l){m=0;while(o=a[m++])if(o(l,g,h)){i.push(l);break}k&&(w=v)}c&&((l=!o&&l)&&p--,f&&r.push(l))}if(p+=q,c&&q!==p){m=0;while(o=b[m++])o(r,s,g,h);if(f){if(p>0)while(q--)r[q]||s[q]||(s[q]=F.call(i));s=vb(s)}H.apply(i,s),k&&!f&&s.length>0&&p+b.length>1&&gb.uniqueSort(i)}return k&&(w=v,j=t),r};return c?ib(f):f}return h=gb.compile=function(a,b){var c,d=[],e=[],f=A[a+" "];if(!f){b||(b=g(a)),c=b.length;while(c--)f=xb(b[c]),f[u]?d.push(f):e.push(f);f=A(a,yb(e,d)),f.selector=a}return f},i=gb.select=function(a,b,e,f){var i,j,k,l,m,n="function"==typeof a&&a,o=!f&&g(a=n.selector||a);if(e=e||[],1===o.length){if(j=o[0]=o[0].slice(0),j.length>2&&"ID"===(k=j[0]).type&&c.getById&&9===b.nodeType&&p&&d.relative[j[1].type]){if(b=(d.find.ID(k.matches[0].replace(cb,db),b)||[])[0],!b)return e;n&&(b=b.parentNode),a=a.slice(j.shift().value.length)}i=X.needsContext.test(a)?0:j.length;while(i--){if(k=j[i],d.relative[l=k.type])break;if((m=d.find[l])&&(f=m(k.matches[0].replace(cb,db),ab.test(j[0].type)&&pb(b.parentNode)||b))){if(j.splice(i,1),a=f.length&&rb(j),!a)return H.apply(e,f),e;break}}}return(n||h(a,o))(f,b,!p,e,ab.test(a)&&pb(b.parentNode)||b),e},c.sortStable=u.split("").sort(B).join("")===u,c.detectDuplicates=!!l,m(),c.sortDetached=jb(function(a){return 1&a.compareDocumentPosition(n.createElement("div"))}),jb(function(a){return a.innerHTML="","#"===a.firstChild.getAttribute("href")})||kb("type|href|height|width",function(a,b,c){return c?void 0:a.getAttribute(b,"type"===b.toLowerCase()?1:2)}),c.attributes&&jb(function(a){return a.innerHTML="",a.firstChild.setAttribute("value",""),""===a.firstChild.getAttribute("value")})||kb("value",function(a,b,c){return c||"input"!==a.nodeName.toLowerCase()?void 0:a.defaultValue}),jb(function(a){return null==a.getAttribute("disabled")})||kb(K,function(a,b,c){var d;return c?void 0:a[b]===!0?b.toLowerCase():(d=a.getAttributeNode(b))&&d.specified?d.value:null}),gb}(a);n.find=t,n.expr=t.selectors,n.expr[":"]=n.expr.pseudos,n.unique=t.uniqueSort,n.text=t.getText,n.isXMLDoc=t.isXML,n.contains=t.contains;var u=n.expr.match.needsContext,v=/^<(\w+)\s*\/?>(?:<\/\1>|)$/,w=/^.[^:#\[\.,]*$/;function x(a,b,c){if(n.isFunction(b))return n.grep(a,function(a,d){return!!b.call(a,d,a)!==c});if(b.nodeType)return n.grep(a,function(a){return a===b!==c});if("string"==typeof b){if(w.test(b))return n.filter(b,a,c);b=n.filter(b,a)}return n.grep(a,function(a){return g.call(b,a)>=0!==c})}n.filter=function(a,b,c){var d=b[0];return c&&(a=":not("+a+")"),1===b.length&&1===d.nodeType?n.find.matchesSelector(d,a)?[d]:[]:n.find.matches(a,n.grep(b,function(a){return 1===a.nodeType}))},n.fn.extend({find:function(a){var b,c=this.length,d=[],e=this;if("string"!=typeof a)return this.pushStack(n(a).filter(function(){for(b=0;c>b;b++)if(n.contains(e[b],this))return!0}));for(b=0;c>b;b++)n.find(a,e[b],d);return d=this.pushStack(c>1?n.unique(d):d),d.selector=this.selector?this.selector+" "+a:a,d},filter:function(a){return this.pushStack(x(this,a||[],!1))},not:function(a){return this.pushStack(x(this,a||[],!0))},is:function(a){return!!x(this,"string"==typeof a&&u.test(a)?n(a):a||[],!1).length}});var y,z=/^(?:\s*(<[\w\W]+>)[^>]*|#([\w-]*))$/,A=n.fn.init=function(a,b){var c,d;if(!a)return this;if("string"==typeof a){if(c="<"===a[0]&&">"===a[a.length-1]&&a.length>=3?[null,a,null]:z.exec(a),!c||!c[1]&&b)return!b||b.jquery?(b||y).find(a):this.constructor(b).find(a);if(c[1]){if(b=b instanceof n?b[0]:b,n.merge(this,n.parseHTML(c[1],b&&b.nodeType?b.ownerDocument||b:l,!0)),v.test(c[1])&&n.isPlainObject(b))for(c in b)n.isFunction(this[c])?this[c](b[c]):this.attr(c,b[c]);return this}return d=l.getElementById(c[2]),d&&d.parentNode&&(this.length=1,this[0]=d),this.context=l,this.selector=a,this}return a.nodeType?(this.context=this[0]=a,this.length=1,this):n.isFunction(a)?"undefined"!=typeof y.ready?y.ready(a):a(n):(void 0!==a.selector&&(this.selector=a.selector,this.context=a.context),n.makeArray(a,this))};A.prototype=n.fn,y=n(l);var B=/^(?:parents|prev(?:Until|All))/,C={children:!0,contents:!0,next:!0,prev:!0};n.extend({dir:function(a,b,c){var d=[],e=void 0!==c;while((a=a[b])&&9!==a.nodeType)if(1===a.nodeType){if(e&&n(a).is(c))break;d.push(a)}return d},sibling:function(a,b){for(var c=[];a;a=a.nextSibling)1===a.nodeType&&a!==b&&c.push(a);return c}}),n.fn.extend({has:function(a){var b=n(a,this),c=b.length;return this.filter(function(){for(var a=0;c>a;a++)if(n.contains(this,b[a]))return!0})},closest:function(a,b){for(var c,d=0,e=this.length,f=[],g=u.test(a)||"string"!=typeof a?n(a,b||this.context):0;e>d;d++)for(c=this[d];c&&c!==b;c=c.parentNode)if(c.nodeType<11&&(g?g.index(c)>-1:1===c.nodeType&&n.find.matchesSelector(c,a))){f.push(c);break}return this.pushStack(f.length>1?n.unique(f):f)},index:function(a){return a?"string"==typeof a?g.call(n(a),this[0]):g.call(this,a.jquery?a[0]:a):this[0]&&this[0].parentNode?this.first().prevAll().length:-1},add:function(a,b){return this.pushStack(n.unique(n.merge(this.get(),n(a,b))))},addBack:function(a){return this.add(null==a?this.prevObject:this.prevObject.filter(a))}});function D(a,b){while((a=a[b])&&1!==a.nodeType);return a}n.each({parent:function(a){var b=a.parentNode;return b&&11!==b.nodeType?b:null},parents:function(a){return n.dir(a,"parentNode")},parentsUntil:function(a,b,c){return n.dir(a,"parentNode",c)},next:function(a){return D(a,"nextSibling")},prev:function(a){return D(a,"previousSibling")},nextAll:function(a){return n.dir(a,"nextSibling")},prevAll:function(a){return n.dir(a,"previousSibling")},nextUntil:function(a,b,c){return n.dir(a,"nextSibling",c)},prevUntil:function(a,b,c){return n.dir(a,"previousSibling",c)},siblings:function(a){return n.sibling((a.parentNode||{}).firstChild,a)},children:function(a){return n.sibling(a.firstChild)},contents:function(a){return a.contentDocument||n.merge([],a.childNodes)}},function(a,b){n.fn[a]=function(c,d){var e=n.map(this,b,c);return"Until"!==a.slice(-5)&&(d=c),d&&"string"==typeof d&&(e=n.filter(d,e)),this.length>1&&(C[a]||n.unique(e),B.test(a)&&e.reverse()),this.pushStack(e)}});var E=/\S+/g,F={};function G(a){var b=F[a]={};return n.each(a.match(E)||[],function(a,c){b[c]=!0}),b}n.Callbacks=function(a){a="string"==typeof a?F[a]||G(a):n.extend({},a);var b,c,d,e,f,g,h=[],i=!a.once&&[],j=function(l){for(b=a.memory&&l,c=!0,g=e||0,e=0,f=h.length,d=!0;h&&f>g;g++)if(h[g].apply(l[0],l[1])===!1&&a.stopOnFalse){b=!1;break}d=!1,h&&(i?i.length&&j(i.shift()):b?h=[]:k.disable())},k={add:function(){if(h){var c=h.length;!function g(b){n.each(b,function(b,c){var d=n.type(c);"function"===d?a.unique&&k.has(c)||h.push(c):c&&c.length&&"string"!==d&&g(c)})}(arguments),d?f=h.length:b&&(e=c,j(b))}return this},remove:function(){return h&&n.each(arguments,function(a,b){var c;while((c=n.inArray(b,h,c))>-1)h.splice(c,1),d&&(f>=c&&f--,g>=c&&g--)}),this},has:function(a){return a?n.inArray(a,h)>-1:!(!h||!h.length)},empty:function(){return h=[],f=0,this},disable:function(){return h=i=b=void 0,this},disabled:function(){return!h},lock:function(){return i=void 0,b||k.disable(),this},locked:function(){return!i},fireWith:function(a,b){return!h||c&&!i||(b=b||[],b=[a,b.slice?b.slice():b],d?i.push(b):j(b)),this},fire:function(){return k.fireWith(this,arguments),this},fired:function(){return!!c}};return k},n.extend({Deferred:function(a){var b=[["resolve","done",n.Callbacks("once memory"),"resolved"],["reject","fail",n.Callbacks("once memory"),"rejected"],["notify","progress",n.Callbacks("memory")]],c="pending",d={state:function(){return c},always:function(){return e.done(arguments).fail(arguments),this},then:function(){var a=arguments;return n.Deferred(function(c){n.each(b,function(b,f){var g=n.isFunction(a[b])&&a[b];e[f[1]](function(){var a=g&&g.apply(this,arguments);a&&n.isFunction(a.promise)?a.promise().done(c.resolve).fail(c.reject).progress(c.notify):c[f[0]+"With"](this===d?c.promise():this,g?[a]:arguments)})}),a=null}).promise()},promise:function(a){return null!=a?n.extend(a,d):d}},e={};return d.pipe=d.then,n.each(b,function(a,f){var g=f[2],h=f[3];d[f[1]]=g.add,h&&g.add(function(){c=h},b[1^a][2].disable,b[2][2].lock),e[f[0]]=function(){return e[f[0]+"With"](this===e?d:this,arguments),this},e[f[0]+"With"]=g.fireWith}),d.promise(e),a&&a.call(e,e),e},when:function(a){var b=0,c=d.call(arguments),e=c.length,f=1!==e||a&&n.isFunction(a.promise)?e:0,g=1===f?a:n.Deferred(),h=function(a,b,c){return function(e){b[a]=this,c[a]=arguments.length>1?d.call(arguments):e,c===i?g.notifyWith(b,c):--f||g.resolveWith(b,c)}},i,j,k;if(e>1)for(i=new Array(e),j=new Array(e),k=new Array(e);e>b;b++)c[b]&&n.isFunction(c[b].promise)?c[b].promise().done(h(b,k,c)).fail(g.reject).progress(h(b,j,i)):--f;return f||g.resolveWith(k,c),g.promise()}});var H;n.fn.ready=function(a){return n.ready.promise().done(a),this},n.extend({isReady:!1,readyWait:1,holdReady:function(a){a?n.readyWait++:n.ready(!0)},ready:function(a){(a===!0?--n.readyWait:n.isReady)||(n.isReady=!0,a!==!0&&--n.readyWait>0||(H.resolveWith(l,[n]),n.fn.triggerHandler&&(n(l).triggerHandler("ready"),n(l).off("ready"))))}});function I(){l.removeEventListener("DOMContentLoaded",I,!1),a.removeEventListener("load",I,!1),n.ready()}n.ready.promise=function(b){return H||(H=n.Deferred(),"complete"===l.readyState?setTimeout(n.ready):(l.addEventListener("DOMContentLoaded",I,!1),a.addEventListener("load",I,!1))),H.promise(b)},n.ready.promise();var J=n.access=function(a,b,c,d,e,f,g){var h=0,i=a.length,j=null==c;if("object"===n.type(c)){e=!0;for(h in c)n.access(a,b,h,c[h],!0,f,g)}else if(void 0!==d&&(e=!0,n.isFunction(d)||(g=!0),j&&(g?(b.call(a,d),b=null):(j=b,b=function(a,b,c){return j.call(n(a),c)})),b))for(;i>h;h++)b(a[h],c,g?d:d.call(a[h],h,b(a[h],c)));return e?a:j?b.call(a):i?b(a[0],c):f};n.acceptData=function(a){return 1===a.nodeType||9===a.nodeType||!+a.nodeType};function K(){Object.defineProperty(this.cache={},0,{get:function(){return{}}}),this.expando=n.expando+K.uid++}K.uid=1,K.accepts=n.acceptData,K.prototype={key:function(a){if(!K.accepts(a))return 0;var b={},c=a[this.expando];if(!c){c=K.uid++;try{b[this.expando]={value:c},Object.defineProperties(a,b)}catch(d){b[this.expando]=c,n.extend(a,b)}}return this.cache[c]||(this.cache[c]={}),c},set:function(a,b,c){var d,e=this.key(a),f=this.cache[e];if("string"==typeof b)f[b]=c;else if(n.isEmptyObject(f))n.extend(this.cache[e],b);else for(d in b)f[d]=b[d];return f},get:function(a,b){var c=this.cache[this.key(a)];return void 0===b?c:c[b]},access:function(a,b,c){var d;return void 0===b||b&&"string"==typeof b&&void 0===c?(d=this.get(a,b),void 0!==d?d:this.get(a,n.camelCase(b))):(this.set(a,b,c),void 0!==c?c:b)},remove:function(a,b){var c,d,e,f=this.key(a),g=this.cache[f];if(void 0===b)this.cache[f]={};else{n.isArray(b)?d=b.concat(b.map(n.camelCase)):(e=n.camelCase(b),b in g?d=[b,e]:(d=e,d=d in g?[d]:d.match(E)||[])),c=d.length;while(c--)delete g[d[c]]}},hasData:function(a){return!n.isEmptyObject(this.cache[a[this.expando]]||{})},discard:function(a){a[this.expando]&&delete this.cache[a[this.expando]]}};var L=new K,M=new K,N=/^(?:\{[\w\W]*\}|\[[\w\W]*\])$/,O=/([A-Z])/g;function P(a,b,c){var d;if(void 0===c&&1===a.nodeType)if(d="data-"+b.replace(O,"-$1").toLowerCase(),c=a.getAttribute(d),"string"==typeof c){try{c="true"===c?!0:"false"===c?!1:"null"===c?null:+c+""===c?+c:N.test(c)?n.parseJSON(c):c}catch(e){}M.set(a,b,c)}else c=void 0;return c}n.extend({hasData:function(a){return M.hasData(a)||L.hasData(a)},data:function(a,b,c){return M.access(a,b,c) +},removeData:function(a,b){M.remove(a,b)},_data:function(a,b,c){return L.access(a,b,c)},_removeData:function(a,b){L.remove(a,b)}}),n.fn.extend({data:function(a,b){var c,d,e,f=this[0],g=f&&f.attributes;if(void 0===a){if(this.length&&(e=M.get(f),1===f.nodeType&&!L.get(f,"hasDataAttrs"))){c=g.length;while(c--)g[c]&&(d=g[c].name,0===d.indexOf("data-")&&(d=n.camelCase(d.slice(5)),P(f,d,e[d])));L.set(f,"hasDataAttrs",!0)}return e}return"object"==typeof a?this.each(function(){M.set(this,a)}):J(this,function(b){var c,d=n.camelCase(a);if(f&&void 0===b){if(c=M.get(f,a),void 0!==c)return c;if(c=M.get(f,d),void 0!==c)return c;if(c=P(f,d,void 0),void 0!==c)return c}else this.each(function(){var c=M.get(this,d);M.set(this,d,b),-1!==a.indexOf("-")&&void 0!==c&&M.set(this,a,b)})},null,b,arguments.length>1,null,!0)},removeData:function(a){return this.each(function(){M.remove(this,a)})}}),n.extend({queue:function(a,b,c){var d;return a?(b=(b||"fx")+"queue",d=L.get(a,b),c&&(!d||n.isArray(c)?d=L.access(a,b,n.makeArray(c)):d.push(c)),d||[]):void 0},dequeue:function(a,b){b=b||"fx";var c=n.queue(a,b),d=c.length,e=c.shift(),f=n._queueHooks(a,b),g=function(){n.dequeue(a,b)};"inprogress"===e&&(e=c.shift(),d--),e&&("fx"===b&&c.unshift("inprogress"),delete f.stop,e.call(a,g,f)),!d&&f&&f.empty.fire()},_queueHooks:function(a,b){var c=b+"queueHooks";return L.get(a,c)||L.access(a,c,{empty:n.Callbacks("once memory").add(function(){L.remove(a,[b+"queue",c])})})}}),n.fn.extend({queue:function(a,b){var c=2;return"string"!=typeof a&&(b=a,a="fx",c--),arguments.lengthx",k.noCloneChecked=!!b.cloneNode(!0).lastChild.defaultValue}();var U="undefined";k.focusinBubbles="onfocusin"in a;var V=/^key/,W=/^(?:mouse|pointer|contextmenu)|click/,X=/^(?:focusinfocus|focusoutblur)$/,Y=/^([^.]*)(?:\.(.+)|)$/;function Z(){return!0}function $(){return!1}function _(){try{return l.activeElement}catch(a){}}n.event={global:{},add:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.get(a);if(r){c.handler&&(f=c,c=f.handler,e=f.selector),c.guid||(c.guid=n.guid++),(i=r.events)||(i=r.events={}),(g=r.handle)||(g=r.handle=function(b){return typeof n!==U&&n.event.triggered!==b.type?n.event.dispatch.apply(a,arguments):void 0}),b=(b||"").match(E)||[""],j=b.length;while(j--)h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o&&(l=n.event.special[o]||{},o=(e?l.delegateType:l.bindType)||o,l=n.event.special[o]||{},k=n.extend({type:o,origType:q,data:d,handler:c,guid:c.guid,selector:e,needsContext:e&&n.expr.match.needsContext.test(e),namespace:p.join(".")},f),(m=i[o])||(m=i[o]=[],m.delegateCount=0,l.setup&&l.setup.call(a,d,p,g)!==!1||a.addEventListener&&a.addEventListener(o,g,!1)),l.add&&(l.add.call(a,k),k.handler.guid||(k.handler.guid=c.guid)),e?m.splice(m.delegateCount++,0,k):m.push(k),n.event.global[o]=!0)}},remove:function(a,b,c,d,e){var f,g,h,i,j,k,l,m,o,p,q,r=L.hasData(a)&&L.get(a);if(r&&(i=r.events)){b=(b||"").match(E)||[""],j=b.length;while(j--)if(h=Y.exec(b[j])||[],o=q=h[1],p=(h[2]||"").split(".").sort(),o){l=n.event.special[o]||{},o=(d?l.delegateType:l.bindType)||o,m=i[o]||[],h=h[2]&&new RegExp("(^|\\.)"+p.join("\\.(?:.*\\.|)")+"(\\.|$)"),g=f=m.length;while(f--)k=m[f],!e&&q!==k.origType||c&&c.guid!==k.guid||h&&!h.test(k.namespace)||d&&d!==k.selector&&("**"!==d||!k.selector)||(m.splice(f,1),k.selector&&m.delegateCount--,l.remove&&l.remove.call(a,k));g&&!m.length&&(l.teardown&&l.teardown.call(a,p,r.handle)!==!1||n.removeEvent(a,o,r.handle),delete i[o])}else for(o in i)n.event.remove(a,o+b[j],c,d,!0);n.isEmptyObject(i)&&(delete r.handle,L.remove(a,"events"))}},trigger:function(b,c,d,e){var f,g,h,i,k,m,o,p=[d||l],q=j.call(b,"type")?b.type:b,r=j.call(b,"namespace")?b.namespace.split("."):[];if(g=h=d=d||l,3!==d.nodeType&&8!==d.nodeType&&!X.test(q+n.event.triggered)&&(q.indexOf(".")>=0&&(r=q.split("."),q=r.shift(),r.sort()),k=q.indexOf(":")<0&&"on"+q,b=b[n.expando]?b:new n.Event(q,"object"==typeof b&&b),b.isTrigger=e?2:3,b.namespace=r.join("."),b.namespace_re=b.namespace?new RegExp("(^|\\.)"+r.join("\\.(?:.*\\.|)")+"(\\.|$)"):null,b.result=void 0,b.target||(b.target=d),c=null==c?[b]:n.makeArray(c,[b]),o=n.event.special[q]||{},e||!o.trigger||o.trigger.apply(d,c)!==!1)){if(!e&&!o.noBubble&&!n.isWindow(d)){for(i=o.delegateType||q,X.test(i+q)||(g=g.parentNode);g;g=g.parentNode)p.push(g),h=g;h===(d.ownerDocument||l)&&p.push(h.defaultView||h.parentWindow||a)}f=0;while((g=p[f++])&&!b.isPropagationStopped())b.type=f>1?i:o.bindType||q,m=(L.get(g,"events")||{})[b.type]&&L.get(g,"handle"),m&&m.apply(g,c),m=k&&g[k],m&&m.apply&&n.acceptData(g)&&(b.result=m.apply(g,c),b.result===!1&&b.preventDefault());return b.type=q,e||b.isDefaultPrevented()||o._default&&o._default.apply(p.pop(),c)!==!1||!n.acceptData(d)||k&&n.isFunction(d[q])&&!n.isWindow(d)&&(h=d[k],h&&(d[k]=null),n.event.triggered=q,d[q](),n.event.triggered=void 0,h&&(d[k]=h)),b.result}},dispatch:function(a){a=n.event.fix(a);var b,c,e,f,g,h=[],i=d.call(arguments),j=(L.get(this,"events")||{})[a.type]||[],k=n.event.special[a.type]||{};if(i[0]=a,a.delegateTarget=this,!k.preDispatch||k.preDispatch.call(this,a)!==!1){h=n.event.handlers.call(this,a,j),b=0;while((f=h[b++])&&!a.isPropagationStopped()){a.currentTarget=f.elem,c=0;while((g=f.handlers[c++])&&!a.isImmediatePropagationStopped())(!a.namespace_re||a.namespace_re.test(g.namespace))&&(a.handleObj=g,a.data=g.data,e=((n.event.special[g.origType]||{}).handle||g.handler).apply(f.elem,i),void 0!==e&&(a.result=e)===!1&&(a.preventDefault(),a.stopPropagation()))}return k.postDispatch&&k.postDispatch.call(this,a),a.result}},handlers:function(a,b){var c,d,e,f,g=[],h=b.delegateCount,i=a.target;if(h&&i.nodeType&&(!a.button||"click"!==a.type))for(;i!==this;i=i.parentNode||this)if(i.disabled!==!0||"click"!==a.type){for(d=[],c=0;h>c;c++)f=b[c],e=f.selector+" ",void 0===d[e]&&(d[e]=f.needsContext?n(e,this).index(i)>=0:n.find(e,this,null,[i]).length),d[e]&&d.push(f);d.length&&g.push({elem:i,handlers:d})}return h]*)\/>/gi,bb=/<([\w:]+)/,cb=/<|&#?\w+;/,db=/<(?:script|style|link)/i,eb=/checked\s*(?:[^=]|=\s*.checked.)/i,fb=/^$|\/(?:java|ecma)script/i,gb=/^true\/(.*)/,hb=/^\s*\s*$/g,ib={option:[1,""],thead:[1,"
id proto type ip open crypt ping buffidle open delay out in last sent waiting version peerid
","
"],col:[2,"","
"],tr:[2,"","
"],td:[3,"","
"],_default:[0,"",""]};ib.optgroup=ib.option,ib.tbody=ib.tfoot=ib.colgroup=ib.caption=ib.thead,ib.th=ib.td;function jb(a,b){return n.nodeName(a,"table")&&n.nodeName(11!==b.nodeType?b:b.firstChild,"tr")?a.getElementsByTagName("tbody")[0]||a.appendChild(a.ownerDocument.createElement("tbody")):a}function kb(a){return a.type=(null!==a.getAttribute("type"))+"/"+a.type,a}function lb(a){var b=gb.exec(a.type);return b?a.type=b[1]:a.removeAttribute("type"),a}function mb(a,b){for(var c=0,d=a.length;d>c;c++)L.set(a[c],"globalEval",!b||L.get(b[c],"globalEval"))}function nb(a,b){var c,d,e,f,g,h,i,j;if(1===b.nodeType){if(L.hasData(a)&&(f=L.access(a),g=L.set(b,f),j=f.events)){delete g.handle,g.events={};for(e in j)for(c=0,d=j[e].length;d>c;c++)n.event.add(b,e,j[e][c])}M.hasData(a)&&(h=M.access(a),i=n.extend({},h),M.set(b,i))}}function ob(a,b){var c=a.getElementsByTagName?a.getElementsByTagName(b||"*"):a.querySelectorAll?a.querySelectorAll(b||"*"):[];return void 0===b||b&&n.nodeName(a,b)?n.merge([a],c):c}function pb(a,b){var c=b.nodeName.toLowerCase();"input"===c&&T.test(a.type)?b.checked=a.checked:("input"===c||"textarea"===c)&&(b.defaultValue=a.defaultValue)}n.extend({clone:function(a,b,c){var d,e,f,g,h=a.cloneNode(!0),i=n.contains(a.ownerDocument,a);if(!(k.noCloneChecked||1!==a.nodeType&&11!==a.nodeType||n.isXMLDoc(a)))for(g=ob(h),f=ob(a),d=0,e=f.length;e>d;d++)pb(f[d],g[d]);if(b)if(c)for(f=f||ob(a),g=g||ob(h),d=0,e=f.length;e>d;d++)nb(f[d],g[d]);else nb(a,h);return g=ob(h,"script"),g.length>0&&mb(g,!i&&ob(a,"script")),h},buildFragment:function(a,b,c,d){for(var e,f,g,h,i,j,k=b.createDocumentFragment(),l=[],m=0,o=a.length;o>m;m++)if(e=a[m],e||0===e)if("object"===n.type(e))n.merge(l,e.nodeType?[e]:e);else if(cb.test(e)){f=f||k.appendChild(b.createElement("div")),g=(bb.exec(e)||["",""])[1].toLowerCase(),h=ib[g]||ib._default,f.innerHTML=h[1]+e.replace(ab,"<$1>")+h[2],j=h[0];while(j--)f=f.lastChild;n.merge(l,f.childNodes),f=k.firstChild,f.textContent=""}else l.push(b.createTextNode(e));k.textContent="",m=0;while(e=l[m++])if((!d||-1===n.inArray(e,d))&&(i=n.contains(e.ownerDocument,e),f=ob(k.appendChild(e),"script"),i&&mb(f),c)){j=0;while(e=f[j++])fb.test(e.type||"")&&c.push(e)}return k},cleanData:function(a){for(var b,c,d,e,f=n.event.special,g=0;void 0!==(c=a[g]);g++){if(n.acceptData(c)&&(e=c[L.expando],e&&(b=L.cache[e]))){if(b.events)for(d in b.events)f[d]?n.event.remove(c,d):n.removeEvent(c,d,b.handle);L.cache[e]&&delete L.cache[e]}delete M.cache[c[M.expando]]}}}),n.fn.extend({text:function(a){return J(this,function(a){return void 0===a?n.text(this):this.empty().each(function(){(1===this.nodeType||11===this.nodeType||9===this.nodeType)&&(this.textContent=a)})},null,a,arguments.length)},append:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.appendChild(a)}})},prepend:function(){return this.domManip(arguments,function(a){if(1===this.nodeType||11===this.nodeType||9===this.nodeType){var b=jb(this,a);b.insertBefore(a,b.firstChild)}})},before:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this)})},after:function(){return this.domManip(arguments,function(a){this.parentNode&&this.parentNode.insertBefore(a,this.nextSibling)})},remove:function(a,b){for(var c,d=a?n.filter(a,this):this,e=0;null!=(c=d[e]);e++)b||1!==c.nodeType||n.cleanData(ob(c)),c.parentNode&&(b&&n.contains(c.ownerDocument,c)&&mb(ob(c,"script")),c.parentNode.removeChild(c));return this},empty:function(){for(var a,b=0;null!=(a=this[b]);b++)1===a.nodeType&&(n.cleanData(ob(a,!1)),a.textContent="");return this},clone:function(a,b){return a=null==a?!1:a,b=null==b?a:b,this.map(function(){return n.clone(this,a,b)})},html:function(a){return J(this,function(a){var b=this[0]||{},c=0,d=this.length;if(void 0===a&&1===b.nodeType)return b.innerHTML;if("string"==typeof a&&!db.test(a)&&!ib[(bb.exec(a)||["",""])[1].toLowerCase()]){a=a.replace(ab,"<$1>");try{for(;d>c;c++)b=this[c]||{},1===b.nodeType&&(n.cleanData(ob(b,!1)),b.innerHTML=a);b=0}catch(e){}}b&&this.empty().append(a)},null,a,arguments.length)},replaceWith:function(){var a=arguments[0];return this.domManip(arguments,function(b){a=this.parentNode,n.cleanData(ob(this)),a&&a.replaceChild(b,this)}),a&&(a.length||a.nodeType)?this:this.remove()},detach:function(a){return this.remove(a,!0)},domManip:function(a,b){a=e.apply([],a);var c,d,f,g,h,i,j=0,l=this.length,m=this,o=l-1,p=a[0],q=n.isFunction(p);if(q||l>1&&"string"==typeof p&&!k.checkClone&&eb.test(p))return this.each(function(c){var d=m.eq(c);q&&(a[0]=p.call(this,c,d.html())),d.domManip(a,b)});if(l&&(c=n.buildFragment(a,this[0].ownerDocument,!1,this),d=c.firstChild,1===c.childNodes.length&&(c=d),d)){for(f=n.map(ob(c,"script"),kb),g=f.length;l>j;j++)h=c,j!==o&&(h=n.clone(h,!0,!0),g&&n.merge(f,ob(h,"script"))),b.call(this[j],h,j);if(g)for(i=f[f.length-1].ownerDocument,n.map(f,lb),j=0;g>j;j++)h=f[j],fb.test(h.type||"")&&!L.access(h,"globalEval")&&n.contains(i,h)&&(h.src?n._evalUrl&&n._evalUrl(h.src):n.globalEval(h.textContent.replace(hb,"")))}return this}}),n.each({appendTo:"append",prependTo:"prepend",insertBefore:"before",insertAfter:"after",replaceAll:"replaceWith"},function(a,b){n.fn[a]=function(a){for(var c,d=[],e=n(a),g=e.length-1,h=0;g>=h;h++)c=h===g?this:this.clone(!0),n(e[h])[b](c),f.apply(d,c.get());return this.pushStack(d)}});var qb,rb={};function sb(b,c){var d,e=n(c.createElement(b)).appendTo(c.body),f=a.getDefaultComputedStyle&&(d=a.getDefaultComputedStyle(e[0]))?d.display:n.css(e[0],"display");return e.detach(),f}function tb(a){var b=l,c=rb[a];return c||(c=sb(a,b),"none"!==c&&c||(qb=(qb||n("